fixed connection events and proeprty editor

This commit is contained in:
tamat
2016-10-03 19:42:54 +02:00
parent dcf4930466
commit 01fe7011bd
29 changed files with 3749 additions and 3963 deletions

File diff suppressed because it is too large Load Diff

138
build/litegraph.min.js vendored
View File

@@ -29,14 +29,14 @@ LGraph.prototype.connectionChange=function(a){this.updateExecutionOrder();if(thi
LGraph.prototype.setDirtyCanvas=function(a,b){this.sendActionToCanvas("setDirty",[a,b])};LGraph.prototype.serialize=function(){for(var a=[],b=0,c=this._nodes.length;b<c;++b)a.push(this._nodes[b].serialize());for(b in this.links)c=this.links[b],c.data=null,delete c._last_time;return{iteration:this.iteration,frame:this.frame,last_node_id:this.last_node_id,last_link_id:this.last_link_id,links:LiteGraph.cloneObject(this.links),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=[];d=0;for(var f=c.length;d<f;++d){var g=c[d],h=LiteGraph.createNode(g.type,g.title);h?(h.id=g.id,this.add(h,!0),h.configure(g)):(LiteGraph.debug&&console.log("Node not found: "+g.type),e=!0)}this.updateExecutionOrder();this.setDirtyCanvas(!0,!0);return e};LGraph.prototype.onNodeTrace=function(a,b,c){};function LGraphNode(a){this._ctor()}
LGraphNode.prototype._ctor=function(a){this.title=a||"Unnamed";this.size=[LiteGraph.NODE_WIDTH,60];this.graph=null;this._pos=new Float32Array(10,10);Object.defineProperty(this,"pos",{set:function(a){!a||2>!a.length||(this._pos[0]=a[0],this._pos[1]=a[1])},get:function(){return this._pos},enumerable:!0});this.id=-1;this.type=null;this.inputs=[];this.outputs=[];this.connections=[];this.properties={};this.properties_info=[];this.data=null;this.flags={}};
LGraphNode.prototype.configure=function(a){for(var b in a)if("console"!=b)if("properties"==b)for(var c in a.properties){if(this.properties[c]=a.properties[c],this.onPropertyChanged)this.onPropertyChanged(c,a.properties[c])}else null!=a[b]&&("object"==typeof a[b]?this[b]&&this[b].configure?this[b].configure(a[b]):this[b]=LiteGraph.cloneObject(a[b],this[b]):this[b]=a[b]);if(this.onConnectionsChange)this.onConnectionsChange();for(var d in this.inputs)c=this.inputs[d],c.link&&c.link.length&&(a=c.link,
"object"==typeof a&&(c.link=a[0],this.graph.links[a[0]]={id:a[0],origin_id:a[1],origin_slot:a[2],target_id:a[3],target_slot:a[4]}));for(d in this.outputs)if(c=this.outputs[d],c.links&&0!=c.links.length)for(b in c.links)a=c.links[b],"object"==typeof a&&(c.links[b]=a[0])};
LGraphNode.prototype.configure=function(a){for(var b in a)if("console"!=b)if("properties"==b)for(var c in a.properties){if(this.properties[c]=a.properties[c],this.onPropertyChanged)this.onPropertyChanged(c,a.properties[c])}else null!=a[b]&&("object"==typeof a[b]?this[b]&&this[b].configure?this[b].configure(a[b]):this[b]=LiteGraph.cloneObject(a[b],this[b]):this[b]=a[b]);if(this.onConnectionsChange)this.onConnectionsChange();for(var d in this.inputs){var e=this.inputs[d];e.link&&e.link.length&&(c=e.link,
"object"==typeof c&&(e.link=c[0],this.graph.links[c[0]]={id:c[0],origin_id:c[1],origin_slot:c[2],target_id:c[3],target_slot:c[4]}))}for(d in this.outputs)if(e=this.outputs[d],e.links&&0!=e.links.length)for(b in e.links)c=e.links[b],"object"==typeof c&&(e.links[b]=c[0]);if(this.onConfigured)this.onConfigured(a)};
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,mode:this.mode};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.clone=function(){var a=LiteGraph.createNode(this.type),b=LiteGraph.cloneObject(this.serialize());if(b.inputs)for(var c=0;c<b.inputs.length;++c)b.inputs[c].link=null;if(b.outputs)for(c=0;c<b.outputs.length;++c)b.outputs[c].links&&(b.outputs[c].links.length=0);delete b.id;a.configure(b);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]].data=b};
LGraphNode.prototype.getInputData=function(a,b){if(this.inputs&&!(a>=this.inputs.length||null==this.inputs[a].link)){var c=this.graph.links[this.inputs[a].link];if(!b)return c.data;var d=this.graph.getNodeById(c.origin_id);if(!d)return c.data;if(d.updateOutputData)d.updateOutputData(c.origin_slot);else if(d.onExecute)d.onExecute();return c.data}};LGraphNode.prototype.isInputConnected=function(a){return this.inputs?a<this.inputs.length&&null!=this.inputs[a].link:!1};
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].target_id));return b}return null};
LGraphNode.prototype.getInputInfo=function(a){return this.inputs?a<this.inputs.length?this.inputs[a]:null:null};LGraphNode.prototype.getInputNode=function(a){return!this.inputs||a>=this.inputs.length?null:(a=this.inputs[a])&&a.link?this.graph.getNodeById(a.link.origin_id):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].target_id));return b}return null};
LGraphNode.prototype.trigger=function(a,b){if(this.outputs&&this.outputs.length){this.graph&&(this.graph._last_trigger_time=LiteGraph.getTime());for(var c=0;c<this.outputs.length;++c){var d=this.outputs[c];if(!(d.type!==LiteGraph.EVENT||a&&d.name!=a)&&(d=d.links)&&d.length)for(var e=0;e<d.length;++e){var f=this.graph.links[d[e]];if(f){var g=this.graph.getNodeById(f.target_id);if(g)if(f._last_time=LiteGraph.getTime(),f=g.inputs[f.target_slot],g.onAction)g.onAction(f.name,b);else if(g.mode===LiteGraph.ON_TRIGGER&&
g.onExecute)g.onExecute(b)}}}}};LGraphNode.prototype.addProperty=function(a,b,c,d){c={name:a,type:c,default_value:b};if(d)for(var e in d)c[e]=d[e];this.properties_info||(this.properties_info=[]);this.properties_info.push(c);this.properties||(this.properties={});this.properties[a]=b;return c};
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);if(this.onOutputAdded)this.onOutputAdded(a);this.size=this.computeSize();return a};
@@ -50,11 +50,12 @@ LGraphNode.prototype.getSlotInPosition=function(a,b){if(this.inputs)for(var c=0,
LGraphNode.prototype.findInputSlot=function(a){if(!this.inputs)return-1;for(var b=0,c=this.inputs.length;b<c;++b)if(a==this.inputs[b].name)return b;return-1};LGraphNode.prototype.findOutputSlot=function(a){if(!this.outputs)return-1;for(var b=0,c=this.outputs.length;b<c;++b)if(a==this.outputs[b].name)return b;return-1};
LGraphNode.prototype.connect=function(a,b,c){c=c||0;if(a.constructor===String){if(a=this.findOutputSlot(a),-1==a)return LiteGraph.debug&&console.log("Connect: Error, no slot of name "+a),!1}else if(!this.outputs||a>=this.outputs.length)return LiteGraph.debug&&console.log("Connect: Error, slot number not found"),!1;b&&b.constructor===Number&&(b=this.graph.getNodeById(b));if(!b)throw"Node not found";if(b==this)return!1;if(c.constructor===String){if(c=b.findInputSlot(c),-1==c)return LiteGraph.debug&&
console.log("Connect: Error, no slot of name "+c),!1}else{if(c===LiteGraph.EVENT)return!1;if(!b.inputs||c>=b.inputs.length)return LiteGraph.debug&&console.log("Connect: Error, slot number not found"),!1}null!=b.inputs[c].link&&b.disconnectInput(c);this.setDirtyCanvas(!1,!0);this.graph.connectionChange(this);var d=this.outputs[a];if(b.onConnectInput&&!1===b.onConnectInput(c,d.type,d))return!1;if(LiteGraph.isValidConnection(d.type,b.inputs[c].type)){var e={id:this.graph.last_link_id++,origin_id:this.id,
origin_slot:a,target_id:b.id,target_slot:c};this.graph.links[e.id]=e;null==d.links&&(d.links=[]);d.links.push(e.id);b.inputs[c].link=e.id;if(this.onConnectionsChange)this.onConnectionsChange(LiteGraph.OUTPUT,a);if(b.onConnectionsChange)b.onConnectionsChange(LiteGraph.OUTPUT,c)}this.setDirtyCanvas(!1,!0);this.graph.connectionChange(this);return!0};
origin_slot:a,target_id:b.id,target_slot:c};this.graph.links[e.id]=e;null==d.links&&(d.links=[]);d.links.push(e.id);b.inputs[c].link=e.id;if(this.onConnectionsChange)this.onConnectionsChange(LiteGraph.OUTPUT,a,!0,e);if(b.onConnectionsChange)b.onConnectionsChange(LiteGraph.INPUT,c,!0,e)}this.setDirtyCanvas(!1,!0);this.graph.connectionChange(this);return!0};
LGraphNode.prototype.disconnectOutput=function(a,b){if(a.constructor===String){if(a=this.findOutputSlot(a),-1==a)return LiteGraph.debug&&console.log("Connect: Error, no slot of name "+a),!1}else if(!this.outputs||a>=this.outputs.length)return LiteGraph.debug&&console.log("Connect: Error, slot number not found"),!1;var c=this.outputs[a];if(!c.links||0==c.links.length)return!1;if(b){b.constructor===Number&&(b=this.graph.getNodeById(b));if(!b)throw"Target Node not found";for(var d=0,e=c.links.length;d<
e;d++){var f=c.links[d],g=this.graph.links[f];if(g.target_id==b.id){c.links.splice(d,1);b.inputs[g.target_slot].link=null;delete this.graph.links[f];break}}}else{d=0;for(e=c.links.length;d<e;d++){f=c.links[d];g=this.graph.links[f];if(b=this.graph.getNodeById(g.target_id))b.inputs[g.target_slot].link=null;delete this.graph.links[f]}c.links=null}this.setDirtyCanvas(!1,!0);this.graph.connectionChange(this);return!0};
LGraphNode.prototype.disconnectInput=function(a){if(a.constructor===String){if(a=this.findInputSlot(a),-1==a)return LiteGraph.debug&&console.log("Connect: Error, no slot of name "+a),!1}else if(!this.inputs||a>=this.inputs.length)return LiteGraph.debug&&console.log("Connect: Error, slot number not found"),!1;if(!this.inputs[a])return!1;var b=this.inputs[a].link;this.inputs[a].link=null;if(b=this.graph.links[b]){a=this.graph.getNodeById(b.origin_id);if(!a)return!1;var c=a.outputs[b.origin_slot];if(!c||
!c.links||0==c.links.length)return!1;for(var d=0,e=c.links.length;d<e;d++)if(b=c.links[d],b=this.graph.links[b],b.target_id==this.id){c.links.splice(d,1);break}if(this.onConnectionsChange)this.onConnectionsChange(LiteGraph.OUTPUT);if(a.onConnectionsChange)a.onConnectionsChange(LiteGraph.INPUT)}this.setDirtyCanvas(!1,!0);this.graph.connectionChange(this);return!0};
e;d++){var f=c.links[d],g=this.graph.links[f];if(g.target_id==b.id){c.links.splice(d,1);b.inputs[g.target_slot].link=null;delete this.graph.links[f];if(b.onConnectionsChange)b.onConnectionsChange(LiteGraph.INPUT,g.target_slot,!1,g);if(this.onConnectionsChange)this.onConnectionsChange(LiteGraph.OUTPUT,a,!1,g);break}}}else{d=0;for(e=c.links.length;d<e;d++){f=c.links[d];g=this.graph.links[f];if(b=this.graph.getNodeById(g.target_id))b.inputs[g.target_slot].link=null;delete this.graph.links[f];if(b.onConnectionsChange)b.onConnectionsChange(LiteGraph.INPUT,
g.target_slot,!1,g);if(this.onConnectionsChange)this.onConnectionsChange(LiteGraph.OUTPUT,a,!1,g)}c.links=null}this.setDirtyCanvas(!1,!0);this.graph.connectionChange(this);return!0};
LGraphNode.prototype.disconnectInput=function(a){if(a.constructor===String){if(a=this.findInputSlot(a),-1==a)return LiteGraph.debug&&console.log("Connect: Error, no slot of name "+a),!1}else if(!this.inputs||a>=this.inputs.length)return LiteGraph.debug&&console.log("Connect: Error, slot number not found"),!1;if(!this.inputs[a])return!1;var b=this.inputs[a].link;this.inputs[a].link=null;if(b=this.graph.links[b]){var c=this.graph.getNodeById(b.origin_id);if(!c)return!1;var d=c.outputs[b.origin_slot];
if(!d||!d.links||0==d.links.length)return!1;for(var e=0,f=d.links.length;e<f;e++)if(b=d.links[e],b=this.graph.links[b],b.target_id==this.id){d.links.splice(e,1);break}if(this.onConnectionsChange)this.onConnectionsChange(LiteGraph.INPUT,a,!1,b);if(c.onConnectionsChange)c.onConnectionsChange(LiteGraph.OUTPUT,e,!1,b)}this.setDirtyCanvas(!1,!0);this.graph.connectionChange(this);return!0};
LGraphNode.prototype.getConnectionPos=function(a,b){return this.flags.collapsed?a?[this.pos[0],this.pos[1]-0.5*LiteGraph.NODE_TITLE_HEIGHT]:[this.pos[0]+LiteGraph.NODE_COLLAPSED_WIDTH,this.pos[1]-0.5*LiteGraph.NODE_TITLE_HEIGHT]:a&&-1==b?[this.pos[0]+10,this.pos[1]+10]:a&&this.inputs.length>b&&this.inputs[b].pos?[this.pos[0]+this.inputs[b].pos[0],this.pos[1]+this.inputs[b].pos[1]]:!a&&this.outputs.length>b&&this.outputs[b].pos?[this.pos[0]+this.outputs[b].pos[0],this.pos[1]+this.outputs[b].pos[1]]:
a?[this.pos[0],this.pos[1]+10+b*LiteGraph.NODE_SLOT_HEIGHT]:[this.pos[0]+this.size[0]+1,this.pos[1]+10+b*LiteGraph.NODE_SLOT_HEIGHT]};LGraphNode.prototype.alignToGrid=function(){this.pos[0]=LiteGraph.CANVAS_GRID_SIZE*Math.round(this.pos[0]/LiteGraph.CANVAS_GRID_SIZE);this.pos[1]=LiteGraph.CANVAS_GRID_SIZE*Math.round(this.pos[1]/LiteGraph.CANVAS_GRID_SIZE)};
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};
@@ -75,11 +76,11 @@ this._ondrop_callback),this.canvas.removeEventListener("dragenter",this._doRetur
LGraphCanvas.getFileExtension=function(a){var b=a.indexOf("?");-1!=b&&(a=a.substr(0,b));b=a.lastIndexOf(".");return-1==b?"":a.substr(b+1).toLowerCase()};LGraphCanvas.prototype.enableWebGL=function(){if(void 0===typeof GL)throw"litegl.js must be included to use a WebGL canvas";if(void 0===typeof enableWebGLCanvas)throw"webglCanvas.js must be included to use this feature";this.gl=this.ctx=enableWebGLCanvas(this.canvas);this.ctx.webgl=!0;this.bgcanvas=this.canvas;this.bgctx=this.gl};
LGraphCanvas.prototype.setDirty=function(a,b){a&&(this.dirty_canvas=!0);b&&(this.dirty_bgcanvas=!0)};LGraphCanvas.prototype.getCanvasWindow=function(){if(!this.canvas)return window;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,!0);b.document.addEventListener("mouseup",this._mouseup_callback,!0);var c=this.graph.getNodeOnPos(a.canvasX,a.canvasY,this.visible_nodes);LiteGraph.closeAllContextualMenus(b);if(1==a.which){if(!(a.shiftKey||c&&this.selected_nodes[c.id])){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=
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,!0);b.document.addEventListener("mouseup",this._mouseup_callback,!0);var c=this.graph.getNodeOnPos(a.canvasX,a.canvasY,this.visible_nodes);LiteGraph.closeAllContextMenus(b);if(1==a.which){if(!(a.shiftKey||c&&this.selected_nodes[c.id])){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)&&null!==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)}!f&&isInsideRectangle(a.canvasX,a.canvasY,c.pos[0],c.pos[1]-LiteGraph.NODE_TITLE_HEIGHT,
LiteGraph.NODE_TITLE_HEIGHT,LiteGraph.NODE_TITLE_HEIGHT)&&(c.collapse(),f=!0);if(!f){e=!1;if(300>LiteGraph.getTime()-this.last_mouseclick&&this.selected_nodes[c.id]){if(c.onDblClick)c.onDblClick(a);this.processNodeDblClicked(c);e=!0}c.onMouseDown&&c.onMouseDown(a,[a.canvasX-c.pos[0],a.canvasY-c.pos[1]])?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=LiteGraph.getTime();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();if(this.onMouseDown)this.onMouseDown(a);return!1}};
!0)}else 2!=a.which&&3==a.which&&this.processContextMenu(c,a);this.last_mouse[0]=a.localX;this.last_mouse[1]=a.localY;this.last_mouseclick=LiteGraph.getTime();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();if(this.onMouseDown)this.onMouseDown(a);return!1}};
LGraphCanvas.prototype.processMouseMove=function(a){this.autoresize&&this.resize();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);for(var b=this.graph.getNodeOnPos(a.canvasX,a.canvasY,this.visible_nodes),
d=0,e=this.graph._nodes.length;d<e;++d)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&&(e=this._highlight_input||[0,0],!this.isOverNodeBox(b,a.canvasX,a.canvasY))){var f=
this.isOverNodeInput(b,a.canvasX,a.canvasY,e);-1!=f&&b.inputs[f]?LiteGraph.isValidConnection(this.connecting_output.type,b.inputs[f].type)&&(this._highlight_input=e):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);
@@ -131,47 +132,49 @@ LGraphCanvas.prototype.renderLink=function(a,b,c,d,e,f){if(this.highquality_rend
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 n=LiteGraph.createContextualMenu(h,{event:b,callback:function(a,b){var c=LiteGraph.getNodeTypesInCategory(a.value),d=[],k;for(k in c)d.push({content:c[k].title,value:c[k].type});LiteGraph.createContextualMenu(d,{event:b,
callback:f,from:n},g);return!1},from:c},g);return!1};LGraphCanvas.onMenuCollapseAll=function(){};LGraphCanvas.onMenuNodeEdit=function(){};
LGraphCanvas.showMenuNodeInputs=function(a,b,c){function d(b,c,d){a&&(b.callback&&b.callback.call(e,a,b,c,d),b.value&&a.addInput(b.value[0],b.value[1],b.value[2]))}if(a){var e=this,f=this.getCanvasWindow(),g=a.optional_inputs;a.onGetInputs&&(g=a.onGetInputs());var h=[];if(g)for(var k in g){var n=g[k],l=n[0];n[2]&&n[2].label&&(l=n[2].label);h.push({content:l,value:n})}this.onMenuNodeInputs&&(h=this.onMenuNodeInputs(h));if(h.length)return LiteGraph.createContextualMenu(h,{event:b,callback:d,from:c},
f),!1}};
LGraphCanvas.showMenuNodeOutputs=function(a,b,c){function d(b,g,k){if(a&&(b.callback&&b.callback.call(e,a,b,g,k),b.value))if(k=b.value[1],!k||k.constructor!==Object&&k.constructor!==Array)a.addOutput(b.value[0],b.value[1],b.value[2]);else{b=[];for(var h in k)b.push({content:h,value:k[h]});LiteGraph.createContextualMenu(b,{event:g,callback:d,from:c});return!1}}if(a){var e=this,f=this.getCanvasWindow(),g=a.optional_outputs;a.onGetOutputs&&(g=a.onGetOutputs());var h=[];if(g)for(var k in g){var n=g[k];
if(!n)h.push(null);else if(-1==a.findOutputSlot(n[0])){var l=n[0];n[2]&&n[2].label&&(l=n[2].label);l={content:l,value:n};n[1]==LiteGraph.EVENT&&(l.className="event");h.push(l)}}this.onMenuNodeOutputs&&(h=this.onMenuNodeOutputs(h));if(h.length)return LiteGraph.createContextualMenu(h,{event:b,callback:d,from:c},f),!1}};
LGraphCanvas.onShowMenuNodeProperties=function(a,b,c){function d(b,c,d){a&&e.showEditPropertyValue(a,b.value,{event:c})}if(a&&a.properties){var e=this,f=this.getCanvasWindow(),g=[],h;for(h in a.properties)g.push({content:"<span class='property_name'>"+h+"</span><span class='property_value'>"+(void 0!==a.properties[h]?a.properties[h]:" ")+"</span>",value:h});if(g.length)return LiteGraph.createContextualMenu(g,{event:b,callback:d,from:c},f),!1}};
LGraphCanvas.prototype.showEditPropertyValue=function(a,b,c){function d(){e(q.value)}function e(c){a.properties[b]="number"==typeof a.properties[b]?Number(c):c;l.parentNode.removeChild(l);a.setDirtyCanvas(!0,!0)}if(a&&void 0!==a.properties[b]){c=c||{};var f="string";null!==a.properties[b]&&(f=typeof a.properties[b]);var g=null;a.getPropertyInfo&&(g=a.getPropertyInfo(b));g.type&&(f=g.type);var h="";if("string"==f||"number"==f)h="<input autofocus type='text' class='value'/>";else if("enum"==f&&g.values){var h=
"<select autofocus type='text' class='value'>",k;for(k in g.values)var n=g.values.constructor===Array?g.values[k]:k,h=h+("<option value='"+n+"' "+(n==a.properties[b]?"selected":"")+">"+g.values[k]+"</option>");h+="</select>"}var l=document.createElement("div");l.className="graphdialog";l.innerHTML="<span class='name'>"+b+"</span>"+h+"<button>OK</button>";if("enum"==f&&g.values){var q=l.querySelector("select");q.addEventListener("change",function(a){e(a.options[a.selectedIndex].value)})}else q=l.querySelector("input"),
q.value=void 0!==a.properties[b]?a.properties[b]:"",q.addEventListener("keydown",function(a){13==a.keyCode&&(d(),a.preventDefault(),a.stopPropagation())});f=this.canvas.getClientRects()[0];h=g=-20;f&&(g-=f.left,h-=f.top);c.event?(l.style.left=c.event.pageX+g+"px",l.style.top=c.event.pageY+h+"px"):(l.style.left=0.5*this.canvas.width+g+"px",l.style.top=0.5*this.canvas.height+h+"px");l.querySelector("button").addEventListener("click",d);this.canvas.parentNode.appendChild(l)}};
LGraphCanvas.onMenuNodeCollapse=function(a){a.flags.collapsed=!a.flags.collapsed;a.setDirtyCanvas(!0,!0)};LGraphCanvas.onMenuNodePin=function(a){a.pin()};LGraphCanvas.onMenuNodeMode=function(a,b,c){LiteGraph.createContextualMenu(["Always","On Event","Never"],{event:b,callback:function(b){if(a)switch(b){case "On Event":a.mode=LiteGraph.ON_EVENT;break;case "Never":a.mode=LiteGraph.NEVER;break;default:a.mode=LiteGraph.ALWAYS}},from:c});return!1};
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.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 n=LiteGraph.createContextMenu(h,{event:b,callback:function(a,b){var c=LiteGraph.getNodeTypesInCategory(a.value),d=[],h;for(h in c)d.push({content:c[h].title,value:c[h].type});LiteGraph.createContextMenu(d,{event:b,callback:f,
from:n},g);return!1},from:c},g);return!1};LGraphCanvas.onMenuCollapseAll=function(){};LGraphCanvas.onMenuNodeEdit=function(){};
LGraphCanvas.showMenuNodeInputs=function(a,b,c){function d(b,c,d){a&&(b.callback&&b.callback.call(e,a,b,c,d),b.value&&a.addInput(b.value[0],b.value[1],b.value[2]))}if(a){var e=this,f=this.getCanvasWindow(),g=a.optional_inputs;a.onGetInputs&&(g=a.onGetInputs());var h=[];if(g)for(var k in g){var n=g[k],l=n[0];n[2]&&n[2].label&&(l=n[2].label);h.push({content:l,value:n})}this.onMenuNodeInputs&&(h=this.onMenuNodeInputs(h));if(h.length)return LiteGraph.createContextMenu(h,{event:b,callback:d,from:c},f),
!1}};
LGraphCanvas.showMenuNodeOutputs=function(a,b,c){function d(b,g,h){if(a&&(b.callback&&b.callback.call(e,a,b,g,h),b.value))if(h=b.value[1],!h||h.constructor!==Object&&h.constructor!==Array)a.addOutput(b.value[0],b.value[1],b.value[2]);else{b=[];for(var k in h)b.push({content:k,value:h[k]});LiteGraph.createContextMenu(b,{event:g,callback:d,from:c});return!1}}if(a){var e=this,f=this.getCanvasWindow(),g=a.optional_outputs;a.onGetOutputs&&(g=a.onGetOutputs());var h=[];if(g)for(var k in g){var n=g[k];if(!n)h.push(null);
else if(-1==a.findOutputSlot(n[0])){var l=n[0];n[2]&&n[2].label&&(l=n[2].label);l={content:l,value:n};n[1]==LiteGraph.EVENT&&(l.className="event");h.push(l)}}this.onMenuNodeOutputs&&(h=this.onMenuNodeOutputs(h));if(h.length)return LiteGraph.createContextMenu(h,{event:b,callback:d,from:c},f),!1}};
LGraphCanvas.onShowMenuNodeProperties=function(a,b,c){function d(b,c,d){a&&e.showEditPropertyValue(a,b.value,{event:c})}if(a&&a.properties){var e=this,f=this.getCanvasWindow(),g=[],h;for(h in a.properties)g.push({content:"<span class='property_name'>"+h+"</span><span class='property_value'>"+(void 0!==a.properties[h]?a.properties[h]:" ")+"</span>",value:h});if(g.length)return LiteGraph.createContextMenu(g,{event:b,callback:d,from:c},f),!1}};
LGraphCanvas.prototype.showEditPropertyValue=function(a,b,c){function d(){e(q.value)}function e(c){"number"==typeof a.properties[b]&&(c=Number(c));a.properties[b]=c;if(a.onPropertyChanged)a.onPropertyChanged(b,c);l.parentNode.removeChild(l);a.setDirtyCanvas(!0,!0)}if(a&&void 0!==a.properties[b]){c=c||{};var f="string";null!==a.properties[b]&&(f=typeof a.properties[b]);var g=null;a.getPropertyInfo&&(g=a.getPropertyInfo(b));if(a.properties_info)for(var h=0;h<a.properties_info.length;++h)if(a.properties_info[h].name==
b){g=a.properties_info[h];break}void 0!==g&&null!==g&&g.type&&(f=g.type);var k="";if("string"==f||"number"==f)k="<input autofocus type='text' class='value'/>";else if("enum"==f&&g.values){k="<select autofocus type='text' class='value'>";for(h in g.values)var n=g.values.constructor===Array?g.values[h]:h,k=k+("<option value='"+n+"' "+(n==a.properties[b]?"selected":"")+">"+g.values[h]+"</option>");k+="</select>"}else"boolean"==f&&(k="<input autofocus type='checkbox' class='value' "+(a.properties[b]?
"checked":"")+"/>");var l=document.createElement("div");l.className="graphdialog";l.innerHTML="<span class='name'>"+b+"</span>"+k+"<button>OK</button>";if("enum"==f&&g.values){var q=l.querySelector("select");q.addEventListener("change",function(a){e(a.target.value)})}else if("boolean"==f)(q=l.querySelector("input"))&&q.addEventListener("click",function(a){e(!!q.checked)});else if(q=l.querySelector("input"))q.value=void 0!==a.properties[b]?a.properties[b]:"",q.addEventListener("keydown",function(a){13==
a.keyCode&&(d(),a.preventDefault(),a.stopPropagation())});f=this.canvas.getClientRects()[0];h=g=-20;f&&(g-=f.left,h-=f.top);c.event?(l.style.left=c.event.pageX+g+"px",l.style.top=c.event.pageY+h+"px"):(l.style.left=0.5*this.canvas.width+g+"px",l.style.top=0.5*this.canvas.height+h+"px");l.querySelector("button").addEventListener("click",d);this.canvas.parentNode.appendChild(l)}};LGraphCanvas.onMenuNodeCollapse=function(a){a.flags.collapsed=!a.flags.collapsed;a.setDirtyCanvas(!0,!0)};
LGraphCanvas.onMenuNodePin=function(a){a.pin()};LGraphCanvas.onMenuNodeMode=function(a,b,c){LiteGraph.createContextMenu(["Always","On Event","Never"],{event:b,callback:function(b){if(a)switch(b){case "On Event":a.mode=LiteGraph.ON_EVENT;break;case "Never":a.mode=LiteGraph.NEVER;break;default:a.mode=LiteGraph.ALWAYS}},from:c});return!1};
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.createContextMenu(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.createContextMenu(["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(){var a=null;this.getMenuOptions?a=this.getMenuOptions():(a=[{content:"Add Node",is_menu:!0,callback:LGraphCanvas.onMenuAdd}],this._graph_stack&&0<this._graph_stack.length&&(a=[{content:"Close subgraph",callback:this.closeSubgraph.bind(this)},null].concat(a)));if(this.getExtraMenuOptions){var b=this.getExtraMenuOptions(this,a);b&&(a=a.concat(b))}return a};
LGraphCanvas.prototype.getNodeMenuOptions=function(a){var b=null,b=a.getMenuOptions?a.getMenuOptions(this):[{content:"Inputs",is_menu:!0,disabled:!0,callback:LGraphCanvas.showMenuNodeInputs},{content:"Outputs",is_menu:!0,disabled:!0,callback:LGraphCanvas.showMenuNodeOutputs},null,{content:"Properties",is_menu:!0,callback:LGraphCanvas.onShowMenuNodeProperties},null,{content:"Mode",is_menu:!0,callback:LGraphCanvas.onMenuNodeMode},{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];if(a.getExtraMenuOptions){var c=a.getExtraMenuOptions(this);c&&(c.push(null),b=c.concat(b))}!1!==a.clonable&&b.push({content:"Clone",callback:LGraphCanvas.onMenuNodeClone});!1!==a.removable&&b.push(null,{content:"Remove",callback:LGraphCanvas.onMenuNodeRemove});a.onGetInputs&&(c=a.onGetInputs())&&c.length&&(b[0].disabled=
!1);a.onGetOutputs&&(a=a.onGetOutputs())&&a.length&&(b[1].disabled=!1);return b};
LGraphCanvas.prototype.processContextualMenu=function(a,b){var c=this,d=this.getCanvasWindow(),e=null,f={event:b,callback:function(d,e){if(d)if(d==g)d.input?a.removeInput(g.slot):d.output&&a.removeOutput(g.slot);else if(d.callback)return d.callback.call(c,a,e,h,c,b)}},g=null;a&&(g=a.getSlotInPosition(b.canvasX,b.canvasY));g?(e=g.locked?["Cannot remove"]:{"Remove Slot":g},f.title=g.input?g.input.type:g.output.type,g.input&&g.input.type==LiteGraph.EVENT&&(f.title="Event")):e=a?this.getNodeMenuOptions(a):
this.getCanvasMenuOptions();if(e)var h=LiteGraph.createContextualMenu(e,f,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)};
LGraphCanvas.prototype.processContextMenu=function(a,b){var c=this,d=this.getCanvasWindow(),e=null,f={event:b,callback:function(d,e){if(d)if(d==g)d.input?a.removeInput(g.slot):d.output&&a.removeOutput(g.slot);else if(d.callback)return d.callback.call(c,a,e,h,c,b)}},g=null;a&&(g=a.getSlotInPosition(b.canvasX,b.canvasY));g?(e=g.locked?["Cannot remove"]:{"Remove Slot":g},f.title=g.input?g.input.type:g.output.type,g.input&&g.input.type==LiteGraph.EVENT&&(f.title="Event")):e=a?this.getNodeMenuOptions(a):
this.getCanvasMenuOptions();if(e)var h=LiteGraph.createContextMenu(e,f,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}
function num2hex(a){for(var b="#",c,d,e=0;3>e;e++)c=a[e]/16,d=a[e]%16,b+="0123456789ABCDEF".charAt(c)+"0123456789ABCDEF".charAt(d);return b}
LiteGraph.createContextualMenu=function(a,b,c){function d(a){var d=!0;b.callback&&(a=b.callback.call(g,this.data,a),void 0!==a&&(d=a));d&&LiteGraph.closeAllContextualMenus(c)}this.options=b=b||{};c=c||window;if(b.from){var e=document.querySelectorAll(".graphcontextualmenu"),f;for(f in e)e[f].previousSibling==b.from&&e[f].closeMenu()}else LiteGraph.closeAllContextualMenus(c);var g=c.document.createElement("div");g.className="graphcontextualmenu graphmenubar-panel";this.root=g;e=g.style;e.minWidth=
"100px";e.minHeight="20px";e.position="fixed";e.top="100px";e.left="100px";e.color="#AAF";e.padding="2px";e.borderBottom="2px solid #AAF";e.backgroundColor="#444";b.title&&(e=document.createElement("div"),e.className="graphcontextualmenu-title",e.innerHTML=b.title,g.appendChild(e));g.addEventListener("contextmenu",function(a){a.preventDefault();return!1});for(var h in a)f=a[h],e=c.document.createElement("div"),e.className="graphmenu-entry",null==f?e.className+=" separator":(f.is_menu&&(e.className+=
" submenu"),f.disabled&&(e.className+=" disabled"),f.className&&(e.className+=" "+f.className),e.style.cursor="pointer",e.dataset.value="string"==typeof f?f:f.value,e.data=f,e.innerHTML="string"==typeof f?a.constructor==Array?a[h]:h:f.content?f.content:h,e.addEventListener("click",d)),g.appendChild(e);g.addEventListener("mouseover",function(a){this.mouse_inside=!0});g.addEventListener("mouseout",function(a){for(a=a.relatedTarget||a.toElement;a!=this&&a!=c.document;)a=a.parentNode;a!=this&&(this.mouse_inside=
LiteGraph.createContextMenu=function(a,b,c){function d(a){var d=!0;b.callback&&(a=b.callback.call(g,this.data,a),void 0!==a&&(d=a));d&&LiteGraph.closeAllContextMenus(c)}this.options=b=b||{};c=c||window;if(b.from){var e=document.querySelectorAll(".graphcontextmenu"),f;for(f in e)e[f].previousSibling==b.from&&e[f].closeMenu()}else LiteGraph.closeAllContextMenus(c);var g=c.document.createElement("div");g.className="graphcontextmenu graphmenubar-panel";this.root=g;e=g.style;e.minWidth="100px";e.minHeight=
"20px";e.position="fixed";e.top="100px";e.left="100px";e.color="#AAF";e.padding="2px";e.borderBottom="2px solid #AAF";e.backgroundColor="#444";e.zIndex=10;b.title&&(e=document.createElement("div"),e.className="graphcontextmenu-title",e.innerHTML=b.title,g.appendChild(e));g.addEventListener("contextmenu",function(a){a.preventDefault();return!1});for(var h in a)f=a[h],e=c.document.createElement("div"),e.className="graphmenu-entry",null==f?e.className+=" separator":(f.is_menu&&(e.className+=" submenu"),
f.disabled&&(e.className+=" disabled"),f.className&&(e.className+=" "+f.className),e.style.cursor="pointer",e.dataset.value="string"==typeof f?f:f.value,e.data=f,e.innerHTML="string"==typeof f?a.constructor==Array?a[h]:h:f.content?f.content:h,e.addEventListener("click",d)),g.appendChild(e);g.addEventListener("mouseover",function(a){this.mouse_inside=!0});g.addEventListener("mouseout",function(a){for(a=a.relatedTarget||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(g);a=g.getClientRects()[0];b.from&&(b.from.block_close=!0);f=b.left||0;h=b.top||0;b.event&&(f=b.event.pageX-10,h=b.event.pageY-10,b.left&&(f=b.left),e=c.document.body.getClientRects()[0],b.from&&(f=b.from.getClientRects()[0],f=f.left+f.width),f>e.width-a.width-10&&(f=e.width-a.width-10),h>e.height-a.height-10&&(h=e.height-a.height-10));g.style.left=f+"px";g.style.top=h+"px";g.closeMenu=function(){b.from&&(b.from.block_close=!1,b.from.mouse_inside||
b.from.closeMenu());this.parentNode&&c.document.body.removeChild(this)};return g};LiteGraph.closeAllContextualMenus=function(a){a=a||window;a=a.document.querySelectorAll(".graphcontextualmenu");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])}};
b.from.closeMenu());this.parentNode&&c.document.body.removeChild(this)};return g};LiteGraph.closeAllContextMenus=function(a){a=a||window;a=a.document.querySelectorAll(".graphcontextmenu");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 b)a.hasOwnProperty(c)||(a[c]=b[c]);if(b.prototype)for(c in b.prototype)b.prototype.hasOwnProperty(c)&&!a.prototype.hasOwnProperty(c)&&(b.prototype.__lookupGetter__(c)?a.prototype.__defineGetter__(c,b.prototype.__lookupGetter__(c)):a.prototype[c]=b.prototype[c],b.prototype.__lookupSetter__(c)&&a.prototype.__defineSetter__(c,b.prototype.__lookupSetter__(c)))};
window.requestAnimationFrame||(window.requestAnimationFrame=window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(a){window.setTimeout(a,1E3/60)});
(function(){function a(){this.size=[120,60];this.subgraph=new LGraph;this.subgraph._subgraph_node=this;this.subgraph._is_subgraph=!0;this.subgraph.onGlobalInputAdded=this.onSubgraphNewGlobalInput.bind(this);this.subgraph.onGlobalInputRenamed=this.onSubgraphRenamedGlobalInput.bind(this);this.subgraph.onGlobalInputTypeChanged=this.onSubgraphTypeChangeGlobalInput.bind(this);this.subgraph.onGlobalOutputAdded=this.onSubgraphNewGlobalOutput.bind(this);this.subgraph.onGlobalOutputRenamed=this.onSubgraphRenamedGlobalOutput.bind(this);
this.subgraph.onGlobalOutputTypeChanged=this.onSubgraphTypeChangeGlobalOutput.bind(this);this.bgcolor="#940"}function b(){var a="input_"+(1E3*Math.random()).toFixed();this.addOutput(a,null);this.properties={name:a,type:null};var b=this;Object.defineProperty(this.properties,"name",{get:function(){return a},set:function(c){if(""!=c){var d=b.getOutputInfo(0);d.name!=c&&(d.name=c,b.graph&&b.graph.renameGlobalInput(a,c),a=c)}},enumerable:!0});Object.defineProperty(this.properties,"type",{get:function(){return b.outputs[0].type},
set:function(c){b.outputs[0].type=c;b.graph&&b.graph.changeGlobalInputType(a,b.outputs[0].type)},enumerable:!0})}function c(){var a="output_"+(1E3*Math.random()).toFixed();this.addInput(a,null);this.properties={name:a,type:null};var b=this;Object.defineProperty(this.properties,"name",{get:function(){return a},set:function(c){if(""!=c){var d=b.getInputInfo(0);d.name!=c&&(d.name=c,b.graph&&b.graph.renameGlobalOutput(a,c),a=c)}},enumerable:!0});Object.defineProperty(this.properties,"type",{get:function(){return b.inputs[0].type},
set:function(c){b.inputs[0].type=c;b.graph&&b.graph.changeGlobalInputType(a,b.inputs[0].type)},enumerable:!0})}function d(){this.addOutput("value","number");this.addProperty("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.addProperty("value","")}function f(){this.mode=LiteGraph.ON_EVENT;this.size=[60,20];this.addProperty("msg","");this.addInput("log",LiteGraph.EVENT);this.addInput("msg",
0)}a.title="Subgraph";a.desc="Graph inside a node";a.prototype.onSubgraphNewGlobalInput=function(a,b){this.addInput(a,b)};a.prototype.onSubgraphRenamedGlobalInput=function(a,b){var c=this.findInputSlot(a);-1!=c&&(this.getInputInfo(c).name=b)};a.prototype.onSubgraphTypeChangeGlobalInput=function(a,b){var c=this.findInputSlot(a);-1!=c&&(this.getInputInfo(c).type=b)};a.prototype.onSubgraphNewGlobalOutput=function(a,b){this.addOutput(a,b)};a.prototype.onSubgraphRenamedGlobalOutput=function(a,b){var c=
this.findOutputSlot(a);-1!=c&&(this.getOutputInfo(c).name=b)};a.prototype.onSubgraphTypeChangeGlobalOutput=function(a,b){var c=this.findOutputSlot(a);-1!=c&&(this.getOutputInfo(c).type=b)};a.prototype.getExtraMenuOptions=function(a){var b=this;return[{content:"Open",callback:function(){a.openSubgraph(b.subgraph)}}]};a.prototype.onExecute=function(){if(this.inputs)for(var a=0;a<this.inputs.length;a++){var b=this.inputs[a],c=this.getInputData(a);this.subgraph.setGlobalInputData(b.name,c)}this.subgraph.runStep();
if(this.outputs)for(a=0;a<this.outputs.length;a++)c=this.subgraph.getGlobalOutputData(this.outputs[a].name),this.setOutputData(a,c)};a.prototype.configure=function(a){LGraphNode.prototype.configure.call(this,a)};a.prototype.serialize=function(){var a=LGraphNode.prototype.serialize.call(this);a.subgraph=this.subgraph.serialize();return a};a.prototype.clone=function(){var a=LiteGraph.createNode(this.type),b=this.serialize();delete b.id;delete b.inputs;delete b.outputs;a.configure(b);return a};LiteGraph.registerNodeType("graph/subgraph",
a);b.title="Input";b.desc="Input of the graph";b.prototype.onAdded=function(){this.graph.addGlobalInput(this.properties.name,this.properties.type)};b.prototype.onExecute=function(){var a=this.graph.global_inputs[this.properties.name];a&&this.setOutputData(0,a.value)};LiteGraph.registerNodeType("graph/input",b);c.title="Ouput";c.desc="Output of the graph";c.prototype.onAdded=function(){this.graph.addGlobalOutput(this.properties.name,this.properties.type)};c.prototype.onExecute=function(){this.graph.setGlobalOutputData(this.properties.name,
this.getInputData(0))};LiteGraph.registerNodeType("graph/output",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.properties.value.constructor===Number?this.inputs[0].label=this.properties.value.toFixed(3):((a=this.properties.value)&&a.length&&(a=Array.prototype.slice.call(a).join(",")),this.inputs[0].label=a))};LiteGraph.registerNodeType("basic/watch",
e);f.title="Console";f.desc="Show value inside the console";f.prototype.onAction=function(a,b){"log"==a?console.log(b):"warn"==a?console.warn(b):"error"==a&&console.error(b)};f.prototype.onExecute=function(){var a=this.getInputData(0);null!==a&&(this.properties.msg=a);console.log(a)};f.prototype.onGetInputs=function(){return[["log",LiteGraph.ACTION],["warn",LiteGraph.ACTION],["error",LiteGraph.ACTION]]};LiteGraph.registerNodeType("basic/console",f)})();
(function(){function a(){this.addOutput("in ms","number");this.addOutput("in sec","number")}function b(){this.size=[120,60];this.subgraph=new LGraph;this.subgraph._subgraph_node=this;this.subgraph._is_subgraph=!0;this.subgraph.onGlobalInputAdded=this.onSubgraphNewGlobalInput.bind(this);this.subgraph.onGlobalInputRenamed=this.onSubgraphRenamedGlobalInput.bind(this);this.subgraph.onGlobalInputTypeChanged=this.onSubgraphTypeChangeGlobalInput.bind(this);this.subgraph.onGlobalOutputAdded=this.onSubgraphNewGlobalOutput.bind(this);
this.subgraph.onGlobalOutputRenamed=this.onSubgraphRenamedGlobalOutput.bind(this);this.subgraph.onGlobalOutputTypeChanged=this.onSubgraphTypeChangeGlobalOutput.bind(this);this.bgcolor="#940"}function c(){var a="input_"+(1E3*Math.random()).toFixed();this.addOutput(a,null);this.properties={name:a,type:null};var b=this;Object.defineProperty(this.properties,"name",{get:function(){return a},set:function(c){if(""!=c){var d=b.getOutputInfo(0);d.name!=c&&(d.name=c,b.graph&&b.graph.renameGlobalInput(a,c),
a=c)}},enumerable:!0});Object.defineProperty(this.properties,"type",{get:function(){return b.outputs[0].type},set:function(c){b.outputs[0].type=c;b.graph&&b.graph.changeGlobalInputType(a,b.outputs[0].type)},enumerable:!0})}function d(){var a="output_"+(1E3*Math.random()).toFixed();this.addInput(a,null);this.properties={name:a,type:null};var b=this;Object.defineProperty(this.properties,"name",{get:function(){return a},set:function(c){if(""!=c){var d=b.getInputInfo(0);d.name!=c&&(d.name=c,b.graph&&
b.graph.renameGlobalOutput(a,c),a=c)}},enumerable:!0});Object.defineProperty(this.properties,"type",{get:function(){return b.inputs[0].type},set:function(c){b.inputs[0].type=c;b.graph&&b.graph.changeGlobalInputType(a,b.inputs[0].type)},enumerable:!0})}function e(){this.addOutput("value","number");this.addProperty("value",1);this.editable={property:"value",type:"number"}}function f(){this.size=[60,20];this.addInput("value",0,{label:""});this.addOutput("value",0,{label:""});this.addProperty("value",
"")}function g(){this.mode=LiteGraph.ON_EVENT;this.size=[60,20];this.addProperty("msg","");this.addInput("log",LiteGraph.EVENT);this.addInput("msg",0)}a.title="Time";a.desc="Time";a.prototype.onExecute=function(){this.setOutputData(0,1E3*this.graph.globaltime);this.setOutputData(1,this.graph.globaltime)};LiteGraph.registerNodeType("basic/time",a);b.title="Subgraph";b.desc="Graph inside a node";b.prototype.onSubgraphNewGlobalInput=function(a,b){this.addInput(a,b)};b.prototype.onSubgraphRenamedGlobalInput=
function(a,b){var c=this.findInputSlot(a);-1!=c&&(this.getInputInfo(c).name=b)};b.prototype.onSubgraphTypeChangeGlobalInput=function(a,b){var c=this.findInputSlot(a);-1!=c&&(this.getInputInfo(c).type=b)};b.prototype.onSubgraphNewGlobalOutput=function(a,b){this.addOutput(a,b)};b.prototype.onSubgraphRenamedGlobalOutput=function(a,b){var c=this.findOutputSlot(a);-1!=c&&(this.getOutputInfo(c).name=b)};b.prototype.onSubgraphTypeChangeGlobalOutput=function(a,b){var c=this.findOutputSlot(a);-1!=c&&(this.getOutputInfo(c).type=
b)};b.prototype.getExtraMenuOptions=function(a){var b=this;return[{content:"Open",callback:function(){a.openSubgraph(b.subgraph)}}]};b.prototype.onExecute=function(){if(this.inputs)for(var a=0;a<this.inputs.length;a++){var b=this.inputs[a],c=this.getInputData(a);this.subgraph.setGlobalInputData(b.name,c)}this.subgraph.runStep();if(this.outputs)for(a=0;a<this.outputs.length;a++)c=this.subgraph.getGlobalOutputData(this.outputs[a].name),this.setOutputData(a,c)};b.prototype.configure=function(a){LGraphNode.prototype.configure.call(this,
a)};b.prototype.serialize=function(){var a=LGraphNode.prototype.serialize.call(this);a.subgraph=this.subgraph.serialize();return a};b.prototype.clone=function(){var a=LiteGraph.createNode(this.type),b=this.serialize();delete b.id;delete b.inputs;delete b.outputs;a.configure(b);return a};LiteGraph.registerNodeType("graph/subgraph",b);c.title="Input";c.desc="Input of the graph";c.prototype.onAdded=function(){this.graph.addGlobalInput(this.properties.name,this.properties.type)};c.prototype.onExecute=
function(){var a=this.graph.global_inputs[this.properties.name];a&&this.setOutputData(0,a.value)};LiteGraph.registerNodeType("graph/input",c);d.title="Ouput";d.desc="Output of the graph";d.prototype.onAdded=function(){this.graph.addGlobalOutput(this.properties.name,this.properties.type)};d.prototype.onExecute=function(){this.graph.setGlobalOutputData(this.properties.name,this.getInputData(0))};LiteGraph.registerNodeType("graph/output",d);e.title="Const";e.desc="Constant value";e.prototype.setValue=
function(a){"string"==typeof a&&(a=parseFloat(a));this.properties.value=a;this.setDirtyCanvas(!0)};e.prototype.onExecute=function(){this.setOutputData(0,parseFloat(this.properties.value))};e.prototype.onDrawBackground=function(a){this.outputs[0].label=this.properties.value.toFixed(3)};e.prototype.onWidget=function(a,b){"value"==b.name&&this.setValue(b.value)};LiteGraph.registerNodeType("basic/const",e);f.title="Watch";f.desc="Show value of input";f.prototype.onExecute=function(){this.properties.value=
this.getInputData(0);this.setOutputData(0,this.properties.value)};f.prototype.onDrawBackground=function(a){this.inputs[0]&&null!=this.properties.value&&(this.properties.value.constructor===Number?this.inputs[0].label=this.properties.value.toFixed(3):((a=this.properties.value)&&a.length&&(a=Array.prototype.slice.call(a).join(",")),this.inputs[0].label=a))};LiteGraph.registerNodeType("basic/watch",f);g.title="Console";g.desc="Show value inside the console";g.prototype.onAction=function(a,b){"log"==
a?console.log(b):"warn"==a?console.warn(b):"error"==a&&console.error(b)};g.prototype.onExecute=function(){var a=this.getInputData(0);null!==a&&(this.properties.msg=a);console.log(a)};g.prototype.onGetInputs=function(){return[["log",LiteGraph.ACTION],["warn",LiteGraph.ACTION],["error",LiteGraph.ACTION]]};LiteGraph.registerNodeType("basic/console",g)})();
(function(){function a(){this.size=[60,20];this.addProperty("time",1E3);this.addInput("event",LiteGraph.ACTION);this.addOutput("on_time",LiteGraph.EVENT);this._pending=[]}a.title="Delay";a.desc="Delays one event";a.prototype.onAction=function(a,c){this._pending.push([this.properties.time,c])};a.prototype.onExecute=function(){for(var a=1E3*this.graph.elapsed_time,c=0;c<this._pending.length;++c){var d=this._pending[c];d[0]-=a;0<d[0]||(this._pending.splice(c,1),--c,this.trigger(null,d[1]))}};a.prototype.onGetInputs=
function(){return[["event",LiteGraph.ACTION]]};LiteGraph.registerNodeType("events/delay",a)})();
(function(){function a(){this.addOutput("clicked",LiteGraph.EVENT);this.addProperty("text","");this.addProperty("font","40px Arial");this.addProperty("message","");this.size=[64,84]}function b(){this.addOutput("","number");this.size=[64,84];this.properties={min:0,max:1,value:0.5,wcolor:"#7AF",size:50}}function c(){this.size=[160,26];this.addOutput("","number");this.properties={wcolor:"#7AF",min:0,max:1,value:0.5}}function d(){this.size=[160,26];this.addInput("","number");this.properties={min:0,max:1,
@@ -182,16 +185,16 @@ b.prototype.onDrawImageKnob=function(a){if(this.imgfg&&this.imgfg.width){var b=0
b.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"}};b.prototype.onDrawForeground=function(a){this.onDrawImageKnob(a)};b.prototype.onExecute=function(){this.setOutputData(0,this.properties.value);this.boxcolor=colorToString([this.value,this.value,this.value])};b.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}};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-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)}};b.prototype.onMouseUp=function(a){this.oldmouse&&(this.oldmouse=null,this.captureInput(!1))};b.prototype.onMouseLeave=function(a){};b.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)};b.prototype.onPropertyChange=function(a,b){if("wcolor"==a)this.properties[a]=
this.properties.min+(this.properties.max-this.properties.min)*this.value;this.oldmouse=a;this.setDirtyCanvas(!0)}};b.prototype.onMouseUp=function(a){this.oldmouse&&(this.oldmouse=null,this.captureInput(!1))};b.prototype.onMouseLeave=function(a){};b.prototype.onWidget=function(a,b){if("increase"==b.name)this.onPropertyChanged("size",this.properties.size+10);else if("decrease"==b.name)this.onPropertyChanged("size",this.properties.size-10)};b.prototype.onPropertyChanged=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",b);c.title="H.Slider";c.desc="Linear slider controller";c.prototype.onInit=function(){this.value=0.5;this.imgfg=this.loadImage("imgs/slider_fg.png")};c.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())};c.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))};c.prototype.onDrawForeground=function(a){this.onDrawImage(a)};c.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])};c.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};c.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)}};c.prototype.onMouseUp=function(a){this.oldmouse=null;this.captureInput(!1)};c.prototype.onMouseLeave=function(a){};c.prototype.onPropertyChange=function(a,b){if("wcolor"==a)this.properties[a]=b;else return!1;return!0};
a.canvasY-this.pos[1]];this.captureInput(!0);return!0};c.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)}};c.prototype.onMouseUp=function(a){this.oldmouse=null;this.captureInput(!1)};c.prototype.onMouseLeave=function(a){};c.prototype.onPropertyChanged=function(a,b){if("wcolor"==a)this.properties[a]=b;else return!1;return!0};
LiteGraph.registerNodeType("widget/hslider",c);d.title="Progress";d.desc="Shows data in linear progress";d.prototype.onExecute=function(){var a=this.getInputData(0);void 0!=a&&(this.properties.value=a)};d.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",
d);e.title="Text";e.desc="Shows the input value";e.widgets=[{name:"resize",text:"Resize box",type:"button"},{name:"led_text",text:"LED",type:"minibutton"},{name:"normal_text",text:"Normal",type:"minibutton"}];e.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"};e.prototype.onExecute=function(){var a=this.getInputData(0);this.properties.value=null!=a?a:"";this.setDirtyCanvas(!0)};e.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)}};e.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))};e.prototype.onPropertyChange=function(a,b){this.properties[a]=b;this.str="number"==typeof b?b.toFixed(3):b;return!0};LiteGraph.registerNodeType("widget/text",e);f.title="Panel";f.desc="Non interactive panel";f.widgets=[{name:"update",text:"Update",type:"button"}];f.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,
"Arial",this.setDirtyCanvas(!0))};e.prototype.onPropertyChanged=function(a,b){this.properties[a]=b;this.str="number"==typeof b?b.toFixed(3):b;return!0};LiteGraph.registerNodeType("widget/text",e);f.title="Panel";f.desc="Non interactive panel";f.widgets=[{name:"update",text:"Update",type:"button"}];f.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))};f.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())};f.prototype.onWidget=function(a,b){"update"==b.name&&(this.lineargradient=null,this.setDirtyCanvas(!0))};LiteGraph.registerNodeType("widget/panel",f)})();
(function(){function a(){this.addOutput("left_x_axis","number");this.addOutput("left_y_axis","number");this.properties={}}a.title="Gamepad";a.desc="gets the input of the gamepad";a.prototype.onExecute=function(){var a=this.getGamepad();if(this.outputs)for(var c=0;c<this.outputs.length;c++){var d=this.outputs[c],e=null;if(a)switch(d.name){case "left_axis":e=[a.xbox.axes.lx,a.xbox.axes.ly];break;case "right_axis":e=[a.xbox.axes.rx,a.xbox.axes.ry];break;case "left_x_axis":e=a.xbox.axes.lx;break;case "left_y_axis":e=
@@ -236,19 +239,19 @@ p))})();function Selector(){this.addInput("sel","boolean");this.addOutput("value
Selector.prototype.onExecute=function(){var a=this.getInputData(0);if(void 0!==a){for(var b=1;b<this.inputs.length;b++){var c=this.inputs[b],d=this.getInputData(b);void 0!==d&&(this.properties[c.name]=d)}b=this.properties.A;c=this.properties.B;this.setOutputData(0,a?b:c)}};Selector.prototype.onGetInputs=function(){return[["A",0],["B",0]]};LiteGraph.registerNodeType("logic/selector",Selector);
(function(){function a(){this.inputs=[];this.addOutput("frame","image");this.properties={url:""}}function b(){this.addInput("f","number");this.addOutput("Color","color");this.properties={colorA:"#444444",colorB:"#44AAFF",colorC:"#44FFAA",colorD:"#FFFFFF"}}function c(){this.addInput("","image");this.size=[200,200]}function d(){this.addInputs([["img1","image"],["img2","image"],["fade","number"]]);this.addInput("","image");this.properties={fade:0.5,width:512,height:512}}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="Image";a.desc="Image loader";a.widgets=[{name:"load",text:"Load",type:"button"}];a.prototype.onAdded=function(){""!=this.properties.url&&null==this.img&&this.loadImage(this.properties.url)};
a.prototype.onDrawBackground=function(a){this.img&&5<this.size[0]&&5<this.size[1]&&a.drawImage(this.img,0,0,this.size[0],this.size[1])};a.prototype.onExecute=function(){this.img||(this.boxcolor="#000");this.img&&this.img.width?this.setOutputData(0,this.img):this.setOutputData(0,null);this.img&&this.img.dirty&&(this.img.dirty=!1)};a.prototype.onPropertyChange=function(a,b){this.properties[a]=b;"url"==a&&""!=b&&this.loadImage(b);return!0};a.prototype.onDropFile=function(a,b){var c=new Image;c.src=a;
this.img=c};a.prototype.loadImage=function(a){if(""==a)this.img=null;else{this.img=document.createElement("img");a=name;"http://"==a.substr(0,7)&&LiteGraph.proxy&&(a=LiteGraph.proxy+a.substr(7));this.img.src=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)}}};a.prototype.onWidget=function(a,b){"load"==b.name&&this.loadImage(this.properties.url)};LiteGraph.registerNodeType("graphics/image",
a.prototype.onDrawBackground=function(a){this.img&&5<this.size[0]&&5<this.size[1]&&a.drawImage(this.img,0,0,this.size[0],this.size[1])};a.prototype.onExecute=function(){this.img||(this.boxcolor="#000");this.img&&this.img.width?this.setOutputData(0,this.img):this.setOutputData(0,null);this.img&&this.img.dirty&&(this.img.dirty=!1)};a.prototype.onPropertyChanged=function(a,b){this.properties[a]=b;"url"==a&&""!=b&&this.loadImage(b);return!0};a.prototype.onDropFile=function(a,b){var c=new Image;c.src=
a;this.img=c};a.prototype.loadImage=function(a){if(""==a)this.img=null;else{this.img=document.createElement("img");a=name;"http://"==a.substr(0,7)&&LiteGraph.proxy&&(a=LiteGraph.proxy+a.substr(7));this.img.src=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)}}};a.prototype.onWidget=function(a,b){"load"==b.name&&this.loadImage(this.properties.url)};LiteGraph.registerNodeType("graphics/image",
a);b.title="Palette";b.desc="Generates a color";b.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",b);c.title="Frame";c.desc="Frame viewerew";c.widgets=[{name:"resize",text:"Resize box",type:"button"},{name:"view",text:"View Image",type:"button"}];c.prototype.onDrawBackground=function(a){this.frame&&a.drawImage(this.frame,
0,0,this.size[0],this.size[1])};c.prototype.onExecute=function(){this.frame=this.getInputData(0);this.setDirtyCanvas(!0)};c.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()};c.prototype.show=function(){showElement&&this.frame&&showElement(this.frame)};LiteGraph.registerNodeType("graphics/frame",
c);d.title="Image fade";d.desc="Fades between images";d.widgets=[{name:"resizeA",text:"Resize to A",type:"button"},{name:"resizeB",text:"Resize to B",type:"button"}];d.prototype.onAdded=function(){this.createCanvas();var a=this.canvas.getContext("2d");a.fillStyle="#000";a.fillRect(0,0,this.properties.width,this.properties.height)};d.prototype.createCanvas=function(){this.canvas=document.createElement("canvas");this.canvas.width=this.properties.width;this.canvas.height=this.properties.height};d.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",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",d);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",
e.prototype.onPropertyChanged=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",d);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.addEventListener("ended",function(a){b.trace("Ended.");this.play()})};f.prototype.onPropertyChanged=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){console.log("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.onRemoved=function(){this._webcam_stream&&(this._webcam_stream.stop(),this._video=this._webcam_stream=null)};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.height=this._video.videoHeight,this.setOutputData(0,this._video))};g.prototype.getExtraMenuOptions=function(a){var b=this;return[{content:b.properties.show?"Hide Frame":"Show Frame",callback:function(){b.properties.show=!b.properties.show}}]};g.prototype.onDrawBackground=function(a){this.flags.collapsed||20>=this.size[1]||!this.properties.show||!this._video||(a.save(),a.drawImage(this._video,0,0,this.size[0],this.size[1]),
@@ -268,8 +271,8 @@ function(){this.addInput("Texture","Texture");this.addOutput("","Texture");this.
LGraphTextureOperation.widgets_info={uvcode:{widget:"textarea",height:100},pixelcode:{widget:"textarea",height:100},precision:{widget:"combo",values:LGraphTexture.MODE_VALUES}};LGraphTextureOperation.title="Operation";LGraphTextureOperation.desc="Texture shader operation";LGraphTextureOperation.prototype.getExtraMenuOptions=function(a){var b=this;return[{content:b.properties.show?"Hide Texture":"Show Texture",callback:function(){b.properties.show=!b.properties.show}}]};LGraphTextureOperation.prototype.onDrawBackground=
function(a){this.flags.collapsed||20>=this.size[1]||!this.properties.show||!this._tex||this._tex.gl!=a||(a.save(),a.drawImage(this._tex,0,0,this.size[0],this.size[1]),a.restore())};LGraphTextureOperation.prototype.onExecute=function(){var a=this.getInputData(0);if(this.isOutputConnected(0))if(this.properties.precision===LGraphTexture.PASS_THROUGH)this.setOutputData(0,a);else{var b=this.getInputData(1);if(this.properties.uvcode||this.properties.pixelcode){var c=512,d=512;a?(c=a.width,d=a.height):b&&
(c=b.width,d=b.height);this._tex=a||this._tex?LGraphTexture.getTargetTexture(a||this._tex,this._tex,this.properties.precision):new GL.Texture(c,d,{type:this.precision===LGraphTexture.LOW?gl.UNSIGNED_BYTE:gl.HIGH_PRECISION_FORMAT,format:gl.RGBA,filter:gl.LINEAR});var e="";this.properties.uvcode&&(e="uv = "+this.properties.uvcode,-1!=this.properties.uvcode.indexOf(";")&&(e=this.properties.uvcode));var f="";this.properties.pixelcode&&(f="result = "+this.properties.pixelcode,-1!=this.properties.pixelcode.indexOf(";")&&
(f=this.properties.pixelcode));var g=this._shader;if(!g||this._shader_code!=e+"|"+f){try{this._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphTextureOperation.pixel_shader,{UV_CODE:e,PIXEL_CODE:f}),this.boxcolor="#00FF00"}catch(h){console.log("Error compiling shader: ",h);this.boxcolor="#FF0000";return}this._shader_code=e+"|"+f;g=this._shader}if(g){this.boxcolor="green";var k=this.getInputData(2);null!=k?this.properties.value=k:k=parseFloat(this.properties.value);var n=this.graph.getTime();
this._tex.drawTo(function(){gl.disable(gl.DEPTH_TEST);gl.disable(gl.CULL_FACE);gl.disable(gl.BLEND);a&&a.bind(0);b&&b.bind(1);var e=Mesh.getScreenQuad();g.uniforms({u_texture:0,u_textureB:1,value:k,texSize:[c,d],time:n}).draw(e)});this.setOutputData(0,this._tex)}else this.boxcolor="red"}}};LGraphTextureOperation.pixel_shader="precision highp float;\n\t\t\t\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform sampler2D u_textureB;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform vec2 texSize;\n\t\t\tuniform float time;\n\t\t\tuniform float value;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tvec2 uv = v_coord;\n\t\t\t\tUV_CODE;\n\t\t\t\tvec3 color = texture2D(u_texture, uv).rgb;\n\t\t\t\tvec3 colorB = texture2D(u_textureB, uv).rgb;\n\t\t\t\tvec3 result = color;\n\t\t\t\tfloat alpha = 1.0;\n\t\t\t\tPIXEL_CODE;\n\t\t\t\tgl_FragColor = vec4(result, alpha);\n\t\t\t}\n\t\t\t";
(f=this.properties.pixelcode));var g=this._shader;if(!g||this._shader_code!=e+"|"+f){try{this._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphTextureOperation.pixel_shader,{UV_CODE:e,PIXEL_CODE:f}),this.boxcolor="#00FF00"}catch(h){console.log("Error compiling shader: ",h);this.boxcolor="#FF0000";return}this.boxcolor="#FF0000";this._shader_code=e+"|"+f;g=this._shader}if(g){this.boxcolor="green";var k=this.getInputData(2);null!=k?this.properties.value=k:k=parseFloat(this.properties.value);var n=
this.graph.getTime();this._tex.drawTo(function(){gl.disable(gl.DEPTH_TEST);gl.disable(gl.CULL_FACE);gl.disable(gl.BLEND);a&&a.bind(0);b&&b.bind(1);var e=Mesh.getScreenQuad();g.uniforms({u_texture:0,u_textureB:1,value:k,texSize:[c,d],time:n}).draw(e)});this.setOutputData(0,this._tex)}else this.boxcolor="red"}}};LGraphTextureOperation.pixel_shader="precision highp float;\n\t\t\t\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform sampler2D u_textureB;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform vec2 texSize;\n\t\t\tuniform float time;\n\t\t\tuniform float value;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tvec2 uv = v_coord;\n\t\t\t\tUV_CODE;\n\t\t\t\tvec4 color4 = texture2D(u_texture, uv);\n\t\t\t\tvec3 color = color4.rgb;\n\t\t\t\tvec4 color4B = texture2D(u_textureB, uv);\n\t\t\t\tvec3 colorB = color4B.rgb;\n\t\t\t\tvec3 result = color;\n\t\t\t\tfloat alpha = 1.0;\n\t\t\t\tPIXEL_CODE;\n\t\t\t\tgl_FragColor = vec4(result, alpha);\n\t\t\t}\n\t\t\t";
LiteGraph.registerNodeType("texture/operation",LGraphTextureOperation);var LGraphTextureShader=function(){this.addOutput("Texture","Texture");this.properties={code:"",width:512,height:512};this.properties.code="\nvoid main() {\n vec2 uv = coord;\n vec3 color = vec3(0.0);\n//your code here\n\ngl_FragColor = vec4(color, 1.0);\n}\n"};LGraphTextureShader.title="Shader";LGraphTextureShader.desc="Texture shader";LGraphTextureShader.widgets_info={code:{type:"code"},precision:{widget:"combo",values:LGraphTexture.MODE_VALUES}};
LGraphTextureShader.prototype.onExecute=function(){if(this.isOutputConnected(0)){if(this._shader_code!=this.properties.code)if(this._shader_code=this.properties.code,this._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphTextureShader.pixel_shader+this.properties.code))this.boxcolor="green";else{this.boxcolor="red";return}this._tex&&this._tex.width==this.properties.width&&this._tex.height==this.properties.height||(this._tex=new GL.Texture(this.properties.width,this.properties.height,{format:gl.RGBA,
filter:gl.LINEAR}));var a=this._tex,b=this._shader,c=this.graph.getTime();a.drawTo(function(){b.uniforms({texSize:[a.width,a.height],time:c}).draw(Mesh.getScreenQuad())});this.setOutputData(0,this._tex)}};LGraphTextureShader.pixel_shader="precision highp float;\n\t\t\t\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform float time;\n\t\t\t";LiteGraph.registerNodeType("texture/shader",LGraphTextureShader);var LGraphTextureScaleOffset=function(){this.addInput("in","Texture");this.addInput("scale","vec2");this.addInput("offset",
@@ -318,12 +321,15 @@ LiteGraph.registerNodeType("texture/depth_range",LGraphTextureDepthRange);var LG
"Blur a texture";LGraphTextureBlur.max_iterations=20;LGraphTextureBlur.prototype.onExecute=function(){var a=this.getInputData(0);if(a&&this.isOutputConnected(0)){var b=this._temp_texture;b&&b.width==a.width&&b.height==a.height&&b.type==a.type||(this._temp_texture=new GL.Texture(a.width,a.height,{type:a.type,format:gl.RGBA,filter:gl.LINEAR}),this._final_texture=new GL.Texture(a.width,a.height,{type:a.type,format:gl.RGBA,filter:gl.LINEAR}));b=this.properties.iterations;this.isInputConnected(1)&&(b=
this.getInputData(1),this.properties.iterations=b);b=Math.min(Math.floor(b),LGraphTextureBlur.max_iterations);if(0==b)this.setOutputData(0,a);else{var c=this.properties.intensity;this.isInputConnected(2)&&(c=this.getInputData(2),this.properties.intensity=c);var d=LiteGraph.camera_aspect;d||void 0===window.gl||(d=gl.canvas.height/gl.canvas.width);d||(d=1);for(var d=this.properties.preserve_aspect?d:1,e=this.properties.scale||[1,1],f=0;f<b;++f)a.applyBlur(d*e[0]*f,e[1]*f,c,this._temp_texture,this._final_texture),
a=this._final_texture;this.setOutputData(0,this._final_texture)}}};LGraphTextureBlur.pixel_shader="precision highp float;\n\t\t\tprecision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform vec2 u_offset;\n\t\t\tuniform float u_intensity;\n\t\t\tvoid main() {\n\t\t\t vec4 sum = vec4(0.0);\n\t\t\t vec4 center = texture2D(u_texture, v_coord);\n\t\t\t sum += texture2D(u_texture, v_coord + u_offset * -4.0) * 0.05/0.98;\n\t\t\t sum += texture2D(u_texture, v_coord + u_offset * -3.0) * 0.09/0.98;\n\t\t\t sum += texture2D(u_texture, v_coord + u_offset * -2.0) * 0.12/0.98;\n\t\t\t sum += texture2D(u_texture, v_coord + u_offset * -1.0) * 0.15/0.98;\n\t\t\t sum += center * 0.16/0.98;\n\t\t\t sum += texture2D(u_texture, v_coord + u_offset * 4.0) * 0.05/0.98;\n\t\t\t sum += texture2D(u_texture, v_coord + u_offset * 3.0) * 0.09/0.98;\n\t\t\t sum += texture2D(u_texture, v_coord + u_offset * 2.0) * 0.12/0.98;\n\t\t\t sum += texture2D(u_texture, v_coord + u_offset * 1.0) * 0.15/0.98;\n\t\t\t gl_FragColor = u_intensity * sum;\n\t\t\t /*gl_FragColor.a = center.a*/;\n\t\t\t}\n\t\t\t";
LiteGraph.registerNodeType("texture/blur",LGraphTextureBlur);var LGraphTextureWebcam=function(){this.addOutput("Webcam","Texture");this.properties={texture_name:""}};LGraphTextureWebcam.title="Webcam";LGraphTextureWebcam.desc="Webcam texture";LGraphTextureWebcam.prototype.openStream=function(){function a(a){trace("Webcam rejected",a);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}};LGraphTextureWebcam.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)})};LGraphTextureWebcam.prototype.onRemoved=function(){this._webcam_stream&&(this._webcam_stream.stop(),
LiteGraph.registerNodeType("texture/blur",LGraphTextureBlur);var LGraphTextureWebcam=function(){this.addOutput("Webcam","Texture");this.properties={texture_name:""}};LGraphTextureWebcam.title="Webcam";LGraphTextureWebcam.desc="Webcam texture";LGraphTextureWebcam.prototype.openStream=function(){function a(a){console.log("Webcam rejected",a);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;var b=this;navigator.getUserMedia({video:!0},this.streamReady.bind(this),a)}};LGraphTextureWebcam.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)})};LGraphTextureWebcam.prototype.onRemoved=function(){this._webcam_stream&&(this._webcam_stream.stop(),
this._video=this._webcam_stream=null)};LGraphTextureWebcam.prototype.onDrawBackground=function(a){this.flags.collapsed||20>=this.size[1]||!this._video||(a.save(),a.webgl?this._temp_texture&&a.drawImage(this._temp_texture,0,0,this.size[0],this.size[1]):(a.translate(0,this.size[1]),a.scale(1,-1),a.drawImage(this._video,0,0,this.size[0],this.size[1])),a.restore())};LGraphTextureWebcam.prototype.onExecute=function(){null!=this._webcam_stream||this._waiting_confirmation||this.openStream();if(this._video&&
this._video.videoWidth){var a=this._video.videoWidth,b=this._video.videoHeight,c=this._temp_texture;c&&c.width==a&&c.height==b||(this._temp_texture=new GL.Texture(a,b,{format:gl.RGB,filter:gl.LINEAR}));this._temp_texture.uploadImage(this._video);this.properties.texture_name&&(LGraphTexture.getTexturesContainer()[this.properties.texture_name]=this._temp_texture);this.setOutputData(0,this._temp_texture)}};LiteGraph.registerNodeType("texture/webcam",LGraphTextureWebcam);var LGraphCubemap=function(){this.addOutput("Cubemap",
"Cubemap");this.properties={name:""};this.size=[LGraphTexture.image_preview_size,LGraphTexture.image_preview_size]};LGraphCubemap.prototype.onDropFile=function(a,b,c){a?(this._drop_texture="string"==typeof a?GL.Texture.fromURL(a):GL.Texture.fromDDSInMemory(a),this.properties.name=b):(this._drop_texture=null,this.properties.name="")};LGraphCubemap.prototype.onExecute=function(){if(this._drop_texture)this.setOutputData(0,this._drop_texture);else if(this.properties.name){var a=LGraphTexture.getTexture(this.properties.name);
a&&(this._last_tex=a,this.setOutputData(0,a))}};LGraphCubemap.prototype.onDrawBackground=function(a){this.flags.collapsed||20>=this.size[1]||a.webgl&&(gl.meshes.cube||(gl.meshes.cube=GL.Mesh.cube({size:1})))};LiteGraph.registerNodeType("texture/cubemap",LGraphCubemap)}
this._video.videoWidth){var a=this._video.videoWidth,b=this._video.videoHeight,c=this._temp_texture;c&&c.width==a&&c.height==b||(this._temp_texture=new GL.Texture(a,b,{format:gl.RGB,filter:gl.LINEAR}));this._temp_texture.uploadImage(this._video);this.properties.texture_name&&(LGraphTexture.getTexturesContainer()[this.properties.texture_name]=this._temp_texture);this.setOutputData(0,this._temp_texture)}};LiteGraph.registerNodeType("texture/webcam",LGraphTextureWebcam);var LGraphTextureMatte=function(){this.addInput("in",
"Texture");this.addOutput("out","Texture");this.properties={key_color:vec3.fromValues(0,1,0),threshold:0.8,slope:0.2,precision:LGraphTexture.DEFAULT};LGraphTextureMatte._shader||(LGraphTextureMatte._shader=new GL.Shader(GL.Shader.SCREEN_VERTEX_SHADER,LGraphTextureMatte.pixel_shader))};LGraphTextureMatte.title="Matte";LGraphTextureMatte.desc="Extracts background";LGraphTextureMatte.widgets_info={key_color:{widget:"color"},precision:{widget:"combo",values:LGraphTexture.MODE_VALUES}};LGraphTextureMatte.prototype.onExecute=
function(){if(this.isOutputConnected(0)){var a=this.getInputData(0);if(this.properties.precision===LGraphTexture.PASS_THROUGH)this.setOutputData(0,a);else if(a){this._tex=LGraphTexture.getTargetTexture(a,this._tex,this.properties.precision);gl.disable(gl.BLEND);gl.disable(gl.DEPTH_TEST);this._uniforms||(this._uniforms={u_texture:0,u_key_color:this.properties.key_color,u_threshold:1,u_slope:1});var b=this._uniforms,c=Mesh.getScreenQuad(),d=LGraphTextureMatte._shader;b.u_key_color=this.properties.key_color;
b.u_threshold=this.properties.threshold;b.u_slope=this.properties.slope;this._tex.drawTo(function(){a.bind(0);d.uniforms(b).draw(c)});this.setOutputData(0,this._tex)}}};LGraphTextureMatte.pixel_shader="precision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform vec3 u_key_color;\n\t\t\tuniform float u_threshold;\n\t\t\tuniform float u_slope;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tvec3 color = texture2D( u_texture, v_coord ).xyz;\n\t\t\t\tfloat diff = length( normalize(color) - normalize(u_key_color) );\n\t\t\t\tfloat edge = u_threshold * (1.0 - u_slope);\n\t\t\t\tfloat alpha = smoothstep( edge, u_threshold, diff);\n\t\t\t\tgl_FragColor = vec4( color, alpha );\n\t\t\t}";
LiteGraph.registerNodeType("texture/matte",LGraphTextureMatte);var LGraphCubemap=function(){this.addOutput("Cubemap","Cubemap");this.properties={name:""};this.size=[LGraphTexture.image_preview_size,LGraphTexture.image_preview_size]};LGraphCubemap.prototype.onDropFile=function(a,b,c){a?(this._drop_texture="string"==typeof a?GL.Texture.fromURL(a):GL.Texture.fromDDSInMemory(a),this.properties.name=b):(this._drop_texture=null,this.properties.name="")};LGraphCubemap.prototype.onExecute=function(){if(this._drop_texture)this.setOutputData(0,
this._drop_texture);else if(this.properties.name){var a=LGraphTexture.getTexture(this.properties.name);a&&(this._last_tex=a,this.setOutputData(0,a))}};LGraphCubemap.prototype.onDrawBackground=function(a){this.flags.collapsed||20>=this.size[1]||a.webgl&&(gl.meshes.cube||(gl.meshes.cube=GL.Mesh.cube({size:1})))};LiteGraph.registerNodeType("texture/cubemap",LGraphCubemap)}
if("undefined"!=typeof LiteGraph){var LGraphFXLens=function(){this.addInput("Texture","Texture");this.addInput("Aberration","number");this.addInput("Distortion","number");this.addInput("Blur","number");this.addOutput("Texture","Texture");this.properties={aberration:1,distortion:1,blur:1,precision:LGraphTexture.DEFAULT};LGraphFXLens._shader||(LGraphFXLens._shader=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,LGraphFXLens.pixel_shader))};LGraphFXLens.title="Lens";LGraphFXLens.desc="Camera Lens distortion";
LGraphFXLens.widgets_info={precision:{widget:"combo",values:LGraphTexture.MODE_VALUES}};LGraphFXLens.prototype.onExecute=function(){var a=this.getInputData(0);if(this.properties.precision===LGraphTexture.PASS_THROUGH)this.setOutputData(0,a);else if(a){this._tex=LGraphTexture.getTargetTexture(a,this._tex,this.properties.precision);var b=this.properties.aberration;this.isInputConnected(1)&&(b=this.getInputData(1),this.properties.aberration=b);var c=this.properties.distortion;this.isInputConnected(2)&&
(c=this.getInputData(2),this.properties.distortion=c);var d=this.properties.blur;this.isInputConnected(3)&&(d=this.getInputData(3),this.properties.blur=d);gl.disable(gl.BLEND);gl.disable(gl.DEPTH_TEST);var e=Mesh.getScreenQuad(),f=LGraphFXLens._shader;this._tex.drawTo(function(){a.bind(0);f.uniforms({u_texture:0,u_aberration:b,u_distortion:c,u_blur:d}).draw(e)});this.setOutputData(0,this._tex)}};LGraphFXLens.pixel_shader="precision highp float;\n\t\t\tprecision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform vec2 u_camera_planes;\n\t\t\tuniform float u_aberration;\n\t\t\tuniform float u_distortion;\n\t\t\tuniform float u_blur;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tvec2 coord = v_coord;\n\t\t\t\tfloat dist = distance(vec2(0.5), coord);\n\t\t\t\tvec2 dist_coord = coord - vec2(0.5);\n\t\t\t\tfloat percent = 1.0 + ((0.5 - dist) / 0.5) * u_distortion;\n\t\t\t\tdist_coord *= percent;\n\t\t\t\tcoord = dist_coord + vec2(0.5);\n\t\t\t\tvec4 color = texture2D(u_texture,coord, u_blur * dist);\n\t\t\t\tcolor.r = texture2D(u_texture,vec2(0.5) + dist_coord * (1.0+0.01*u_aberration), u_blur * dist ).r;\n\t\t\t\tcolor.b = texture2D(u_texture,vec2(0.5) + dist_coord * (1.0-0.01*u_aberration), u_blur * dist ).b;\n\t\t\t\tgl_FragColor = color;\n\t\t\t}\n\t\t\t";
@@ -337,8 +343,8 @@ a.height]}).draw(k,gl.POINTS)});this.setOutputData(0,this._temp_texture)}}else t
LGraphFXBokeh._second_pixel_shader="precision highp float;\n\t\t\tvarying vec4 v_color;\n\t\t\tuniform sampler2D u_shape;\n\t\t\tuniform float u_alpha;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tvec4 color = texture2D( u_shape, gl_PointCoord );\n\t\t\t\tcolor *= v_color * u_alpha;\n\t\t\t\tgl_FragColor = color;\n\t\t\t}\n";LiteGraph.registerNodeType("fx/bokeh",LGraphFXBokeh);window.LGraphFXBokeh=LGraphFXBokeh;var LGraphFXGeneric=function(){this.addInput("Texture","Texture");this.addInput("value1","number");
this.addInput("value2","number");this.addOutput("Texture","Texture");this.properties={fx:"halftone",value1:1,value2:1,precision:LGraphTexture.DEFAULT}};LGraphFXGeneric.title="FX";LGraphFXGeneric.desc="applies an FX from a list";LGraphFXGeneric.widgets_info={fx:{widget:"combo",values:["halftone","pixelate","lowpalette","noise","gamma"]},precision:{widget:"combo",values:LGraphTexture.MODE_VALUES}};LGraphFXGeneric.shaders={};LGraphFXGeneric.prototype.onExecute=function(){if(this.isOutputConnected(0)){var a=
this.getInputData(0);if(this.properties.precision===LGraphTexture.PASS_THROUGH)this.setOutputData(0,a);else if(a){this._tex=LGraphTexture.getTargetTexture(a,this._tex,this.properties.precision);var b=this.properties.value1;this.isInputConnected(1)&&(b=this.getInputData(1),this.properties.value1=b);var c=this.properties.value2;this.isInputConnected(2)&&(c=this.getInputData(2),this.properties.value2=c);var d=this.properties.fx,e=LGraphFXGeneric.shaders[d];if(!e){var f=LGraphFXGeneric["pixel_shader_"+
d];if(!f)return;e=LGraphFXGeneric.shaders[d]=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,f)}gl.disable(gl.BLEND);gl.disable(gl.DEPTH_TEST);var g=Mesh.getScreenQuad(),h=null;"noise"==d&&(h=LGraphTexture.getNoiseTexture());this._tex.drawTo(function(){a.bind(0);"noise"==d&&h.bind(1);e.uniforms({u_texture:0,u_noise:1,u_size:[a.width,a.height],u_rand:[Math.random(),Math.random()],u_value1:b,u_value2:c,u_camera_planes:[LS.Renderer._current_camera.near,LS.Renderer._current_camera.far]}).draw(g)});this.setOutputData(0,
this._tex)}}};LGraphFXGeneric.pixel_shader_halftone="precision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform vec2 u_camera_planes;\n\t\t\tuniform vec2 u_size;\n\t\t\tuniform float u_value1;\n\t\t\tuniform float u_value2;\n\t\t\t\n\t\t\tfloat pattern() {\n\t\t\t\tfloat s = sin(u_value1 * 3.1415), c = cos(u_value1 * 3.1415);\n\t\t\t\tvec2 tex = v_coord * u_size.xy;\n\t\t\t\tvec2 point = vec2(\n\t\t\t\t c * tex.x - s * tex.y ,\n\t\t\t\t s * tex.x + c * tex.y \n\t\t\t\t) * u_value2;\n\t\t\t\treturn (sin(point.x) * sin(point.y)) * 4.0;\n\t\t\t}\n\t\t\tvoid main() {\n\t\t\t\tvec4 color = texture2D(u_texture, v_coord);\n\t\t\t\tfloat average = (color.r + color.g + color.b) / 3.0;\n\t\t\t\tgl_FragColor = vec4(vec3(average * 10.0 - 5.0 + pattern()), color.a);\n\t\t\t}\n";
d];if(!f)return;e=LGraphFXGeneric.shaders[d]=new GL.Shader(Shader.SCREEN_VERTEX_SHADER,f)}gl.disable(gl.BLEND);gl.disable(gl.DEPTH_TEST);var g=Mesh.getScreenQuad();camera_planes=window.LS&&LS.Renderer._current_camera?[LS.Renderer._current_camera.near,LS.Renderer._current_camera.far]:[1,100];var h=null;"noise"==d&&(h=LGraphTexture.getNoiseTexture());this._tex.drawTo(function(){a.bind(0);"noise"==d&&h.bind(1);e.uniforms({u_texture:0,u_noise:1,u_size:[a.width,a.height],u_rand:[Math.random(),Math.random()],
u_value1:b,u_value2:c,u_camera_planes:camera_planes}).draw(g)});this.setOutputData(0,this._tex)}}};LGraphFXGeneric.pixel_shader_halftone="precision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform vec2 u_camera_planes;\n\t\t\tuniform vec2 u_size;\n\t\t\tuniform float u_value1;\n\t\t\tuniform float u_value2;\n\t\t\t\n\t\t\tfloat pattern() {\n\t\t\t\tfloat s = sin(u_value1 * 3.1415), c = cos(u_value1 * 3.1415);\n\t\t\t\tvec2 tex = v_coord * u_size.xy;\n\t\t\t\tvec2 point = vec2(\n\t\t\t\t c * tex.x - s * tex.y ,\n\t\t\t\t s * tex.x + c * tex.y \n\t\t\t\t) * u_value2;\n\t\t\t\treturn (sin(point.x) * sin(point.y)) * 4.0;\n\t\t\t}\n\t\t\tvoid main() {\n\t\t\t\tvec4 color = texture2D(u_texture, v_coord);\n\t\t\t\tfloat average = (color.r + color.g + color.b) / 3.0;\n\t\t\t\tgl_FragColor = vec4(vec3(average * 10.0 - 5.0 + pattern()), color.a);\n\t\t\t}\n";
LGraphFXGeneric.pixel_shader_pixelate="precision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform vec2 u_camera_planes;\n\t\t\tuniform vec2 u_size;\n\t\t\tuniform float u_value1;\n\t\t\tuniform float u_value2;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tvec2 coord = vec2( floor(v_coord.x * u_value1) / u_value1, floor(v_coord.y * u_value2) / u_value2 );\n\t\t\t\tvec4 color = texture2D(u_texture, coord);\n\t\t\t\tgl_FragColor = color;\n\t\t\t}\n";LGraphFXGeneric.pixel_shader_lowpalette=
"precision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform vec2 u_camera_planes;\n\t\t\tuniform vec2 u_size;\n\t\t\tuniform float u_value1;\n\t\t\tuniform float u_value2;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tvec4 color = texture2D(u_texture, v_coord);\n\t\t\t\tgl_FragColor = floor(color * u_value1) / u_value1;\n\t\t\t}\n";LGraphFXGeneric.pixel_shader_noise="precision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform sampler2D u_noise;\n\t\t\tuniform vec2 u_size;\n\t\t\tuniform float u_value1;\n\t\t\tuniform float u_value2;\n\t\t\tuniform vec2 u_rand;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tvec4 color = texture2D(u_texture, v_coord);\n\t\t\t\tvec3 noise = texture2D(u_noise, v_coord * vec2(u_size.x / 512.0, u_size.y / 512.0) + u_rand).xyz - vec3(0.5);\n\t\t\t\tgl_FragColor = vec4( color.xyz + noise * u_value1, color.a );\n\t\t\t}\n";
LGraphFXGeneric.pixel_shader_gamma="precision highp float;\n\t\t\tvarying vec2 v_coord;\n\t\t\tuniform sampler2D u_texture;\n\t\t\tuniform float u_value1;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tvec4 color = texture2D(u_texture, v_coord);\n\t\t\t\tfloat gamma = 1.0 / u_value1;\n\t\t\t\tgl_FragColor = vec4( pow( color.xyz, vec3(gamma) ), color.a );\n\t\t\t}\n";LiteGraph.registerNodeType("fx/generic",LGraphFXGeneric);window.LGraphFXGeneric=LGraphFXGeneric;var LGraphFXVigneting=function(){this.addInput("Tex.",
@@ -364,3 +370,21 @@ function(){return[["on_midi",LiteGraph.EVENT]]};LiteGraph.registerNodeType("midi
g);h.title="MIDIEvent";h.desc="Create a MIDI Event";h.prototype.onAction=function(a,c){"assign"==a?(this.properties.channel=c.channel,this.properties.cmd=c.cmd,this.properties.value1=c.data[1],this.properties.value2=c.data[2]):(c=new b,c.channel=this.properties.channel,this.properties.cmd&&this.properties.cmd.constructor===String?c.setCommandFromString(this.properties.cmd):c.cmd=this.properties.cmd,c.data[0]=c.cmd|c.channel,c.data[1]=Number(this.properties.value1),c.data[2]=Number(this.properties.value2),
this.trigger("on_midi",c))};h.prototype.onExecute=function(){var a=this.properties;if(this.outputs)for(var c=0;c<this.outputs.length;++c){var d=null;switch(this.outputs[c].name){case "midi":d=new b;d.setup([a.cmd,a.value1,a.value2]);d.channel=a.channel;break;case "command":d=a.cmd;break;case "note":d=a.cmd==b.NOTEON||a.cmd==b.NOTEOFF?a.value1:NULL;break;case "velocity":d=a.cmd==b.NOTEON?a.value2:NULL;break;case "pitch":d=a.cmd==b.NOTEON?b.computePitch(a.value1):null;break;case "pitchbend":d=a.cmd==
b.PITCHBEND?b.computePitchBend(a.value1,a.value2):null;break;default:continue}null!==d&&this.setOutputData(c,d)}};h.prototype.onPropertyChanged=function(a,c){"cmd"==a&&(this.properties.cmd=b.computeCommandFromString(c))};h.prototype.onGetOutputs=function(){return[["midi","midi"],["on_midi",LiteGraph.EVENT],["command","number"],["note","number"],["velocity","number"],["pitch","number"],["pitchbend","number"]]};LiteGraph.registerNodeType("midi/event",h)})(window);
(function(a){function b(){this.properties={src:"demodata/audio.wav",gain:0.5,loop:!0};this._loading_audio=!1;this._audio_buffer=null;this._audionodes=[];this.addOutput("out","audio");this.addInput("gain","number");this.audionode=b.getAudioContext().createGain();this.audionode.graphnode=this;this.audionode.gain.value=this.properties.gain;this.properties.src&&this.loadSound(this.properties.src)}function c(){this.properties={fftSize:2048,minDecibels:-100,maxDecibels:-10,smoothingTimeConstant:0.5};this.audionode=
b.getAudioContext().createAnalyser();this.audionode.graphnode=this;this.audionode.fftSize=this.properties.fftSize;this.audionode.minDecibels=this.properties.minDecibels;this.audionode.maxDecibels=this.properties.maxDecibels;this.audionode.smoothingTimeConstant=this.properties.smoothingTimeConstant;this.addInput("in","audio");this.addOutput("freqs","FFT");this._time_bin=this._freq_bin=null}function d(a){a.prototype.onPropertyChanged=function(a,b){void 0!==this.audionode[a]&&(void 0!==this.audionode[a].value?
this.audionode[a].value=b:this.audionode[a]=b)};a.prototype.onConnectionsChange=function(a,c,d,e){a==LiteGraph.OUTPUT&&(a=null,e&&(a=this.graph.getNodeById(e.target_id)),a&&(d?a.connectAudioToSlot?a.connectAudioToSlot(this.audionode,e.target_slot):b.connect(this.audionode,a.audionode):a.disconnectAudioFromSlot?a.disconnectAudioFromSlot(this.audionode,e.target_slot):b.disconnect(this.audionode,a.audionode)))}}function e(){this.properties={gain:1};this.audionode=b.getAudioContext().createGain();this.addInput("in",
"audio");this.addInput("gain","number");this.addOutput("out","audio")}function f(){this.properties={gain1:0.5,gain2:0.5};this.audionode=b.getAudioContext().createGain();this.audionode1=b.getAudioContext().createGain();this.audionode1.gain.value=this.properties.gain1;this.audionode2=b.getAudioContext().createGain();this.audionode2.gain.value=this.properties.gain2;this.audionode1.connect(this.audionode);this.audionode2.connect(this.audionode);this.addInput("in1","audio");this.addInput("in1 gain","number");
this.addInput("in2","audio");this.addInput("in2 gain","number");this.addOutput("out","audio")}function g(){this.properties={time:5};this.audionode=b.getAudioContext().createDelay(this.properties.time);this.addInput("in","audio");this.addOutput("out","audio")}function h(){this.properties={frequency:350,detune:0,Q:1};this.addProperty("type","lowpass","enum",{values:"lowpass highpass bandpass lowshelf highshelf peaking notch allpass".split(" ")});this.audionode=b.getAudioContext().createBiquadFilter();
this.addInput("in","audio");this.addOutput("out","audio")}function k(){this.audionode=b.getAudioContext().destination;this.addInput("in","audio")}function n(){this.addInput("freqs","FFT");this.size=[300,200];this._last_buffer=null}b.getAudioContext=function(){if(!this._audio_context){window.AudioContext=window.AudioContext||window.webkitAudioContext;if(!window.AudioContext)return console.error("AudioContext not supported by browser"),null;this._audio_context=new AudioContext;this._audio_context.onmessage=
function(a){console.log("msg",a)};this._audio_context.onended=function(a){console.log("ended",a)};this._audio_context.oncomplete=function(a){console.log("complete",a)}}"suspended"==this._audio_context.state&&this._audio_context.resume();return this._audio_context};b.connect=function(a,b){a.connect(b)};b.disconnect=function(a,b){a.disconnect(b)};b.prototype.onAdded=function(a){if(a.status===LGraph.STATUS_RUNNING)this.onStart()};b.prototype.onStart=function(){this._audio_buffer&&this.playBuffer(this._audio_buffer)};
b.prototype.onStop=function(){this.stopAllSounds()};b.prototype.onRemoved=function(){this.stopAllSounds()};b.prototype.stopAllSounds=function(){for(var a=0;a<this._audionodes.length;++a)this._audionodes[a].stop();this._audionodes.length=0};b.prototype.onExecute=function(){var a=this.getInputData(0);void 0!==a&&(this.audionode.gain.value=a)};b.prototype.onAction=function(a){this._audio_buffer&&("Play"==a?this.playBuffer(this._audio_buffer):"Stop"==a&&this.stopAllSounds())};b.prototype.onPropertyChanged=
function(a,b){"src"==a?this.loadSound(b):"gain"==a&&(this.audionode.gain.value=b)};b.prototype.playBuffer=function(a){var c=this,d=b.getAudioContext().createBufferSource();d.graphnode=this;d.buffer=a;d.loop=this.properties.loop;this._audionodes.push(d);d.connect(this.audionode);this._audionodes.push(d);d.onended=function(){console.log("ended!");c.trigger("ended");var a=c._audionodes.indexOf(d);-1!=a&&c._audionodes.splice(a,1)};d.start();return d};b.prototype.onConnectionsChange=function(a,c,d,e){a==
LiteGraph.OUTPUT&&(a=null,e&&(a=this.graph.getNodeById(e.target_id)),a&&(d?a.connectAudioToSlot?a.connectAudioToSlot(this.audionode,e.target_slot):b.connect(this.audionode,a.audionode):a.disconnectAudioFromSlot?a.disconnectAudioFromSlot(this.audionode,e.target_slot):b.disconnect(this.audionode,a.audionode)))};b.prototype.loadSound=function(a){function c(a){console.log("Audio loading sample error:",a)}var d=this;this._request&&(this._request.abort(),this._request=null);this._audio_buffer=null;this._loading_audio=
!1;if(a){var e=new XMLHttpRequest;e.open("GET",a,!0);e.responseType="arraybuffer";this._loading_audio=!0;this._request=e;var f=b.getAudioContext();e.onload=function(){f.decodeAudioData(e.response,function(a){d._audio_buffer=a;d._loading_audio=!1;if(d.graph&&d.graph.status===LGraph.STATUS_RUNNING)d.onStart()},c)};e.send()}};b.prototype.onGetInputs=function(){return[["Play",LiteGraph.ACTION],["Stop",LiteGraph.ACTION]]};b.prototype.onGetOutputs=function(){return[["ended",LiteGraph.EVENT]]};b.title="Source";
b.desc="Plays audio";LiteGraph.registerNodeType("audio/source",b);a.LGAudio=b;c.prototype.onPropertyChanged=function(a,b){this.audionode[a]=b};c.prototype.onExecute=function(){if(this.isOutputConnected(0)){var a=this.audionode.frequencyBinCount;this._freq_bin&&this._freq_bin.length==a||(this._freq_bin=new Uint8Array(a));this.audionode.getByteFrequencyData(this._freq_bin);this.setOutputData(0,this._freq_bin)}for(a=1;a<this.inputs.length;++a){var b=this.inputs[a],c=this.getInputData(a);void 0!==c&&
(this.audionode[b.name].value=c)}};c.prototype.onGetInputs=function(){return[["minDecibels","number"],["maxDecibels","number"],["smoothingTimeConstant","number"]]};c.title="Analyser";c.desc="Audio Analyser";LiteGraph.registerNodeType("audio/analyser",c);e.prototype.onExecute=function(){if(this.inputs&&this.inputs.length)for(var a=1;a<this.inputs.length;++a){var b=this.inputs[a],c=this.getInputData(a);void 0!==c&&(this.audionode[b.name].value=c)}};d(e);e.title="Gain";e.desc="Audio gain";LiteGraph.registerNodeType("audio/gain",
e);f.prototype.connectAudioToSlot=function(a,c){0==c?b.connect(a,this.audionode1):2==c&&b.connect(a,this.audionode2)};f.prototype.disconnectAudioFromSlot=function(a,c){0==c?b.disconnect(a,this.audionode1):2==c&&b.disconnect(a,this.audionode2)};f.prototype.onExecute=function(){if(this.inputs&&this.inputs.length)for(var a=1;a<this.inputs.length;++a)if("audio"!=this.inputs[a].type){var b=this.getInputData(a);void 0!==b&&(1==a?this.audionode1.gain.value=b:3==a&&(this.audionode2.gain.value=b))}};d(f);
f.title="Mixer";f.desc="Audio mixer";LiteGraph.registerNodeType("audio/mixer",f);d(g);g.prototype.onPropertyChanged=function(a,c){if("time"==a){500<c&&(c=500);0>c&&(c=0);var d=this.getInputNode(0),e=this.getOutputNodes(0);d&&d.audionode.disconnect(this.audionode);if(e)for(var f=0;f<e.length;++f)this.audionode.disconnect(e[f].audionode);this.audionode=b.getAudioContext().createDelay(c);d&&d.audionode.connect(this.audionode);if(e)for(f=0;f<e.length;++f)this.audionode.connect(e[f].audionode)}};g.title=
"Delay";g.desc="Audio delay";LiteGraph.registerNodeType("audio/delay",g);h.prototype.onExecute=function(){if(this.inputs&&this.inputs.length)for(var a=1;a<this.inputs.length;++a){var b=this.inputs[a],c=this.getInputData(a);void 0!==c&&(this.audionode[b.name].value=c)}};h.prototype.onGetInputs=function(){return[["frequency","number"],["detune","number"],["Q","number"]]};d(h);h.title="BiquadFilter";h.desc="Audio filter";LiteGraph.registerNodeType("audio/biquadfilter",h);k.title="Destination";k.desc=
"Audio output";LiteGraph.registerNodeType("audio/destination",k);n.prototype.onExecute=function(){this._last_buffer=this.getInputData(0)};n.prototype.onDrawForeground=function(a){if(this._last_buffer){var b=this._last_buffer,c=b.length/this.size[0],d=this.size[1];a.fillStyle="black";a.fillRect(0,0,this.size[0],this.size[1]);a.strokeStyle="white";a.beginPath();for(var e=0,f=0;f<b.length;f+=c)a.moveTo(e,d),a.lineTo(e,d-b[f|0]/255*d),e++;a.stroke()}};n.title="Visualization";n.desc="Audio Visualization";
LiteGraph.registerNodeType("audio/visualization",n)})(window);

View File

@@ -7,13 +7,13 @@
-webkit-user-select: none;
}
.graphcontextualmenu {
.graphcontextmenu {
padding: 4px;
min-width: 100px;
}
.graphcontextualmenu-title {
.graphcontextmenu-title {
color: #DDE;
background-color: #222;
margin: 0;

BIN
demo/demodata/audio.wav Normal file

Binary file not shown.

View File

@@ -24,6 +24,7 @@
<script type="text/javascript" src="../src/nodes/image.js"></script>
<script type="text/javascript" src="../src/nodes/input.js"></script>
<script type="text/javascript" src="../src/nodes/midi.js"></script>
<script type="text/javascript" src="../src/nodes/audio.js"></script>
<script type="text/javascript" src="demo.js"></script>
<script type="text/javascript" src="code.js"></script>

View File

@@ -7,6 +7,7 @@ YUI.add("yuidoc-meta", function(Y) {
"LiteGraph"
],
"modules": [],
"allModules": []
"allModules": [],
"elements": []
} };
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@@ -98,7 +98,7 @@ code, kbd, pre, samp {
line-height: 1.35;
}
p code, p kbd, p samp {
p code, p kbd, p samp, li code {
background: #FCFBFA;
border: 1px solid #EFEEED;
padding: 0 3px;

BIN
doc/assets/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 740 B

View File

@@ -14,6 +14,10 @@ Y.APIFilter = Y.Base.create('apiFilter', Y.Base, [Y.AutoCompleteBase], {
}
});
if (this.get('queryType') === 'elements') {
name = '&lt;' + name + '&gt;';
}
return name;
}
@@ -24,7 +28,7 @@ Y.APIFilter = Y.Base.create('apiFilter', Y.Base, [Y.AutoCompleteBase], {
value: 'phraseMatch'
},
// May be set to "classes" or "modules".
// May be set to "classes", "elements" or "modules".
queryType: {
value: 'classes'
},

View File

@@ -6,6 +6,7 @@ var Lang = Y.Lang,
APIList = Y.namespace('APIList'),
classesNode = Y.one('#api-classes'),
elementsNode = Y.one('#api-elements'),
inputNode = Y.one('#api-filter'),
modulesNode = Y.one('#api-modules'),
tabviewNode = Y.one('#api-tabview'),
@@ -97,7 +98,9 @@ tabview.get('panelNode').all('a').each(function (link) {
// -- Private Functions --------------------------------------------------------
function getFilterResultNode() {
return filter.get('queryType') === 'classes' ? classesNode : modulesNode;
var queryType = filter.get('queryType');
return queryType === 'classes' ? classesNode
: queryType === 'elements' ? elementsNode : modulesNode;
}
// -- Event Handlers -----------------------------------------------------------
@@ -105,7 +108,7 @@ function onFilterResults(e) {
var frag = Y.one(Y.config.doc.createDocumentFragment()),
resultNode = getFilterResultNode(),
typePlural = filter.get('queryType'),
typeSingular = typePlural === 'classes' ? 'class' : 'module';
typeSingular = typePlural === 'classes' ? 'class' : typePlural === 'elements' ? 'element' : 'module';
if (e.results.length) {
YArray.each(e.results, function (result) {
@@ -181,6 +184,7 @@ function onTabSelectionChange(e) {
};
switch (name) {
case 'elements':// fallthru
case 'classes': // fallthru
case 'modules':
filter.setAttrs({

View File

@@ -43,6 +43,12 @@ pjax = new Y.Pjax({
callbacks: defaultRoute
},
// -- /elements/* -------------------------------------------------------
{
path : '/elements/:element.html*',
callbacks: defaultRoute
},
// -- /classes/* -------------------------------------------------------
{
path : '/classes/:class.html*',
@@ -167,7 +173,7 @@ pjax.initLineNumbers = function () {
};
pjax.initRoot = function () {
var terminators = /^(?:classes|files|modules)$/,
var terminators = /^(?:classes|files|elements|modules)$/,
parts = pjax._getPathRoot().split('/'),
root = [],
i, len, part;
@@ -284,7 +290,7 @@ pjax.handleClasses = function (req, res, next) {
var status = res.ioResponse.status;
// Handles success and local filesystem XHRs.
if (!status || (status >= 200 && status < 300)) {
if (res.ioResponse.readyState === 4 && (!status || (status >= 200 && status < 300))) {
pjax.initClassTabView();
}
@@ -295,7 +301,7 @@ pjax.handleFiles = function (req, res, next) {
var status = res.ioResponse.status;
// Handles success and local filesystem XHRs.
if (!status || (status >= 200 && status < 300)) {
if (res.ioResponse.readyState === 4 && (!status || (status >= 200 && status < 300))) {
pjax.initLineNumbers();
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@
<link rel="stylesheet" href="http://yui.yahooapis.com/3.9.1/build/cssgrids/cssgrids-min.css">
<link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
<link rel="stylesheet" href="../assets/css/main.css" id="site_styles">
<link rel="shortcut icon" type="image/png" href="../assets/favicon.png">
<link rel="icon" href="../assets/favicon.ico">
<script src="http://yui.yahooapis.com/combo?3.9.1/build/yui/yui-min.js"></script>
</head>
<body class="yui3-skin-sam">
@@ -14,9 +14,7 @@
<div id="doc">
<div id="hd" class="yui3-g header">
<div class="yui3-u-3-4">
<h1><img src="../assets/css/logo.png" title=""></h1>
<h1><img src="../assets/css/logo.png" title="" width="117" height="52"></h1>
</div>
<div class="yui3-u-1-4 version">
<em>API Docs for: </em>
@@ -27,285 +25,246 @@
<div class="yui3-u-1-4">
<div id="docs-sidebar" class="sidebar apidocs">
<div id="api-list">
<h2 class="off-left">APIs</h2>
<div id="api-tabview" class="tabview">
<ul class="tabs">
<li><a href="#api-classes">Classes</a></li>
<li><a href="#api-modules">Modules</a></li>
</ul>
<div id="api-tabview-filter">
<input type="search" id="api-filter" placeholder="Type to filter APIs">
</div>
<div id="api-tabview-panel">
<ul id="api-classes" class="apis classes">
<li><a href="../classes/LGraph.html">LGraph</a></li>
<li><a href="../classes/LGraphCanvas.html">LGraphCanvas</a></li>
<li><a href="../classes/LGraphNode.html">LGraphNode</a></li>
<li><a href="../classes/LiteGraph.html">LiteGraph</a></li>
</ul>
<ul id="api-modules" class="apis modules">
</ul>
</div>
</div>
</div>
<h2 class="off-left">APIs</h2>
<div id="api-tabview" class="tabview">
<ul class="tabs">
<li><a href="#api-classes">Classes</a></li>
<li><a href="#api-modules">Modules</a></li>
</ul>
<div id="api-tabview-filter">
<input type="search" id="api-filter" placeholder="Type to filter APIs">
</div>
<div id="api-tabview-panel">
<ul id="api-classes" class="apis classes">
<li><a href="../classes/LGraph.html">LGraph</a></li>
<li><a href="../classes/LGraphCanvas.html">LGraphCanvas</a></li>
<li><a href="../classes/LGraphNode.html">LGraphNode</a></li>
<li><a href="../classes/LiteGraph.html">LiteGraph</a></li>
</ul>
<ul id="api-modules" class="apis modules">
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="yui3-u-3-4">
<div id="api-options">
Show:
<label for="api-show-inherited">
<input type="checkbox" id="api-show-inherited" checked>
Inherited
</label>
<label for="api-show-protected">
<input type="checkbox" id="api-show-protected">
Protected
</label>
<label for="api-show-private">
<input type="checkbox" id="api-show-private">
Private
</label>
<label for="api-show-deprecated">
<input type="checkbox" id="api-show-deprecated">
Deprecated
</label>
</div>
Show:
<label for="api-show-inherited">
<input type="checkbox" id="api-show-inherited" checked>
Inherited
</label>
<label for="api-show-protected">
<input type="checkbox" id="api-show-protected">
Protected
</label>
<label for="api-show-private">
<input type="checkbox" id="api-show-private">
Private
</label>
<label for="api-show-deprecated">
<input type="checkbox" id="api-show-deprecated">
Deprecated
</label>
</div>
<div class="apidocs">
<div id="docs-main">
<div class="content">
<h1>LiteGraph Class</h1>
<h1>LiteGraph Class</h1>
<div class="box meta">
<div class="foundat">
Defined in: <a href="../files/.._src_litegraph.js.html#l6"><code>..&#x2F;src&#x2F;litegraph.js:6</code></a>
</div>
</div>
<div class="box intro">
<p>The Global Scope. It contains all the registered node classes.</p>
</div>
<div class="constructor">
<h2>Constructor</h2>
<div id="method_LiteGraph" class="method item">
<div id="method_LiteGraph" class="method item">
<h3 class="name"><code>LiteGraph</code></h3>
<span class="paren">()</span>
<div class="meta">
<p>
Defined in
<a href="../files/.._src_litegraph.js.html#l6"><code>..&#x2F;src&#x2F;litegraph.js:6</code></a>
</p>
</div>
<div class="description">
</div>
</div>
</div>
<div id="classdocs" class="tabview">
<ul class="api-class-tabs">
<li class="api-class-tab index"><a href="#index">Index</a></li>
<li class="api-class-tab methods"><a href="#methods">Methods</a></li>
</ul>
<div>
<div id="index" class="api-class-tabpanel index">
<h2 class="off-left">Item Index</h2>
<div class="index-section methods">
<h3>Methods</h3>
<ul class="index-list methods">
<li class="index-item method">
<a href="#method_addNodeMethod">addNodeMethod</a>
</li>
<li class="index-item method">
<a href="#method_createNode">createNode</a>
</li>
<li class="index-item method">
<a href="#method_getNodeType">getNodeType</a>
</li>
<li class="index-item method">
<a href="#method_getNodeType">getNodeType</a>
</li>
<li class="index-item method">
<a href="#method_getNodeTypesCategories">getNodeTypesCategories</a>
</li>
<li class="index-item method">
<a href="#method_registerNodeType">registerNodeType</a>
</li>
</ul>
</div>
</div>
<div id="methods" class="api-class-tabpanel">
<h2 class="off-left">Methods</h2>
<div id="method_createNode" class="method item">
<h3 class="name"><code>createNode</code></h3>
<div id="method_addNodeMethod" class="method item">
<h3 class="name"><code>addNodeMethod</code></h3>
<div class="args">
<span class="paren">(</span><ul class="args-list inline commas">
<li class="arg">
<code>type</code>
<code>func</code>
</li>
<li class="arg">
<code>name</code>
</li>
<li class="arg">
<code>options</code>
</li>
</ul><span class="paren">)</span>
</div>
<div class="meta">
<p>
Defined in
<a href="../files/.._src_litegraph.js.html#l71"><code>..&#x2F;src&#x2F;litegraph.js:71</code></a>
<a href="../files/.._src_litegraph.js.html#l86"><code>..&#x2F;src&#x2F;litegraph.js:86</code></a>
</p>
</div>
<div class="description">
<p>Adds this method to all nodetypes, existing and to be created
(You can add it to LGraphNode.prototype but then existing node types wont have it)</p>
</div>
<div class="params">
<h4>Parameters:</h4>
<ul class="params-list">
<li class="param">
<code class="param-name">func</code>
<span class="type">Function</span>
<div class="param-description">
</div>
</li>
</ul>
</div>
</div>
<div id="method_createNode" class="method item">
<h3 class="name"><code>createNode</code></h3>
<div class="args">
<span class="paren">(</span><ul class="args-list inline commas">
<li class="arg">
<code>type</code>
</li>
<li class="arg">
<code>name</code>
</li>
<li class="arg">
<code>options</code>
</li>
</ul><span class="paren">)</span>
</div>
<div class="meta">
<p>
Defined in
<a href="../files/.._src_litegraph.js.html#l99"><code>..&#x2F;src&#x2F;litegraph.js:99</code></a>
</p>
</div>
<div class="description">
@@ -313,124 +272,78 @@
</div>
<div class="params">
<h4>Parameters:</h4>
<ul class="params-list">
<li class="param">
<code class="param-name">type</code>
<span class="type">String</span>
<div class="param-description">
<p>full name of the node class. p.e. &quot;math/sin&quot;</p>
</div>
</li>
<li class="param">
<code class="param-name">name</code>
<span class="type">String</span>
<div class="param-description">
<p>a name to distinguish from other nodes</p>
</div>
</li>
<li class="param">
<code class="param-name">options</code>
<span class="type">Object</span>
<div class="param-description">
<p>to set options</p>
</div>
</li>
</ul>
</div>
</div>
<div id="method_getNodeType" class="method item">
<div id="method_getNodeType" class="method item">
<h3 class="name"><code>getNodeType</code></h3>
<div class="args">
<span class="paren">(</span><ul class="args-list inline commas">
<li class="arg">
<code>type</code>
</li>
</ul><span class="paren">)</span>
</div>
<span class="returns-inline">
<span class="type">Class</span>
</span>
<div class="meta">
<p>
Defined in
<a href="../files/.._src_litegraph.js.html#l112"><code>..&#x2F;src&#x2F;litegraph.js:112</code></a>
<a href="../files/.._src_litegraph.js.html#l142"><code>..&#x2F;src&#x2F;litegraph.js:142</code></a>
</p>
</div>
<div class="description">
@@ -438,106 +351,65 @@
</div>
<div class="params">
<h4>Parameters:</h4>
<ul class="params-list">
<li class="param">
<code class="param-name">type</code>
<span class="type">String</span>
<div class="param-description">
<p>full name of the node class. p.e. &quot;math/sin&quot;</p>
</div>
</li>
</ul>
</div>
<div class="returns">
<h4>Returns:</h4>
<div class="returns-description">
<span class="type">Class</span>:
<p>the node class</p>
</div>
</div>
</div>
<div id="method_getNodeType" class="method item">
<div id="method_getNodeType" class="method item">
<h3 class="name"><code>getNodeType</code></h3>
<div class="args">
<span class="paren">(</span><ul class="args-list inline commas">
<li class="arg">
<code>category</code>
</li>
</ul><span class="paren">)</span>
</div>
<span class="returns-inline">
<span class="type">Array</span>
</span>
<div class="meta">
<p>
Defined in
<a href="../files/.._src_litegraph.js.html#l125"><code>..&#x2F;src&#x2F;litegraph.js:125</code></a>
<a href="../files/.._src_litegraph.js.html#l155"><code>..&#x2F;src&#x2F;litegraph.js:155</code></a>
</p>
</div>
<div class="description">
@@ -545,96 +417,59 @@
</div>
<div class="params">
<h4>Parameters:</h4>
<ul class="params-list">
<li class="param">
<code class="param-name">category</code>
<span class="type">String</span>
<div class="param-description">
<p>category name</p>
</div>
</li>
</ul>
</div>
<div class="returns">
<h4>Returns:</h4>
<div class="returns-description">
<span class="type">Array</span>:
<p>array with all the node classes</p>
</div>
</div>
</div>
<div id="method_getNodeTypesCategories" class="method item">
<div id="method_getNodeTypesCategories" class="method item">
<h3 class="name"><code>getNodeTypesCategories</code></h3>
<span class="paren">()</span>
<span class="returns-inline">
<span class="type">Array</span>
</span>
<div class="meta">
<p>
Defined in
<a href="../files/.._src_litegraph.js.html#l147"><code>..&#x2F;src&#x2F;litegraph.js:147</code></a>
<a href="../files/.._src_litegraph.js.html#l177"><code>..&#x2F;src&#x2F;litegraph.js:177</code></a>
</p>
</div>
<div class="description">
@@ -642,84 +477,48 @@
</div>
<div class="returns">
<h4>Returns:</h4>
<div class="returns-description">
<span class="type">Array</span>:
<p>array with all the names of the categories</p>
</div>
</div>
</div>
<div id="method_registerNodeType" class="method item">
<div id="method_registerNodeType" class="method item">
<h3 class="name"><code>registerNodeType</code></h3>
<div class="args">
<span class="paren">(</span><ul class="args-list inline commas">
<li class="arg">
<code>type</code>
</li>
<li class="arg">
<code>base_class</code>
</li>
</ul><span class="paren">)</span>
</div>
<div class="meta">
<p>
Defined in
<a href="../files/.._src_litegraph.js.html#l38"><code>..&#x2F;src&#x2F;litegraph.js:38</code></a>
<a href="../files/.._src_litegraph.js.html#l49"><code>..&#x2F;src&#x2F;litegraph.js:49</code></a>
</p>
</div>
<div class="description">
@@ -727,65 +526,44 @@
</div>
<div class="params">
<h4>Parameters:</h4>
<ul class="params-list">
<li class="param">
<code class="param-name">type</code>
<span class="type">String</span>
<div class="param-description">
<p>name of the node and path</p>
</div>
</li>
<li class="param">
<code class="param-name">base_class</code>
<span class="type">Class</span>
<div class="param-description">
<p>class containing the structure of a node</p>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -38,7 +38,7 @@
"plugin_for": [],
"extension_for": [],
"file": "../src/litegraph.js",
"line": 234,
"line": 274,
"description": "LGraph is the class that contain a full graph. We instantiate one and add nodes to it, and then we can run the execution loop.",
"is_constructor": 1
},
@@ -51,7 +51,7 @@
"plugin_for": [],
"extension_for": [],
"file": "../src/litegraph.js",
"line": 1166,
"line": 1244,
"description": "Base Class for all the node type classes",
"params": [
{
@@ -70,7 +70,7 @@
"plugin_for": [],
"extension_for": [],
"file": "../src/litegraph.js",
"line": 2551,
"line": 2819,
"description": "marks as dirty the canvas, this way it will be rendered again",
"is_constructor": 1,
"params": [
@@ -83,15 +83,21 @@
"name": "graph",
"description": "[optional]",
"type": "LGraph"
},
{
"name": "options",
"description": "[optional] { skip_rendering, autoresize }",
"type": "Object"
}
],
"itemtype": "method"
}
},
"elements": {},
"classitems": [
{
"file": "../src/litegraph.js",
"line": 38,
"line": 49,
"description": "Register a node class so it can be listed when the user wants to create a new one",
"itemtype": "method",
"name": "registerNodeType",
@@ -111,7 +117,22 @@
},
{
"file": "../src/litegraph.js",
"line": 71,
"line": 86,
"description": "Adds this method to all nodetypes, existing and to be created\n(You can add it to LGraphNode.prototype but then existing node types wont have it)",
"itemtype": "method",
"name": "addNodeMethod",
"params": [
{
"name": "func",
"description": "",
"type": "Function"
}
],
"class": "LiteGraph"
},
{
"file": "../src/litegraph.js",
"line": 99,
"description": "Create a node of a given type with a name. The node is not attached to any graph yet.",
"itemtype": "method",
"name": "createNode",
@@ -136,7 +157,7 @@
},
{
"file": "../src/litegraph.js",
"line": 112,
"line": 142,
"description": "Returns a registered node type with a given name",
"itemtype": "method",
"name": "getNodeType",
@@ -155,7 +176,7 @@
},
{
"file": "../src/litegraph.js",
"line": 125,
"line": 155,
"description": "Returns a list of node types matching one category",
"itemtype": "method",
"name": "getNodeType",
@@ -174,7 +195,7 @@
},
{
"file": "../src/litegraph.js",
"line": 147,
"line": 177,
"description": "Returns a list with all the node type categories",
"itemtype": "method",
"name": "getNodeTypesCategories",
@@ -186,7 +207,7 @@
},
{
"file": "../src/litegraph.js",
"line": 258,
"line": 298,
"description": "Removes all nodes from this graph",
"itemtype": "method",
"name": "clear",
@@ -194,7 +215,7 @@
},
{
"file": "../src/litegraph.js",
"line": 303,
"line": 343,
"description": "Attach Canvas to this graph",
"itemtype": "method",
"name": "attachCanvas",
@@ -209,7 +230,7 @@
},
{
"file": "../src/litegraph.js",
"line": 322,
"line": 362,
"description": "Detach Canvas from this graph",
"itemtype": "method",
"name": "detachCanvas",
@@ -224,7 +245,7 @@
},
{
"file": "../src/litegraph.js",
"line": 336,
"line": 380,
"description": "Starts running this graph every interval milliseconds.",
"itemtype": "method",
"name": "start",
@@ -239,7 +260,7 @@
},
{
"file": "../src/litegraph.js",
"line": 363,
"line": 407,
"description": "Stops the execution loop of the graph",
"itemtype": "method",
"name": "stop execution",
@@ -247,7 +268,7 @@
},
{
"file": "../src/litegraph.js",
"line": 385,
"line": 429,
"description": "Run N steps (cycles) of the graph",
"itemtype": "method",
"name": "runStep",
@@ -262,7 +283,7 @@
},
{
"file": "../src/litegraph.js",
"line": 429,
"line": 485,
"description": "Updates the graph execution order according to relevance of the nodes (nodes with only outputs have more relevance than\nnodes with only inputs.",
"itemtype": "method",
"name": "updateExecutionOrder",
@@ -270,7 +291,7 @@
},
{
"file": "../src/litegraph.js",
"line": 527,
"line": 583,
"description": "Returns the amount of time the graph has been running in milliseconds",
"itemtype": "method",
"name": "getTime",
@@ -282,7 +303,7 @@
},
{
"file": "../src/litegraph.js",
"line": 538,
"line": 594,
"description": "Returns the amount of time accumulated using the fixedtime_lapse var. This is used in context where the time increments should be constant",
"itemtype": "method",
"name": "getFixedTime",
@@ -294,7 +315,7 @@
},
{
"file": "../src/litegraph.js",
"line": 549,
"line": 605,
"description": "Returns the amount of time it took to compute the latest iteration. Take into account that this number could be not correct\nif the nodes are using graphical actions",
"itemtype": "method",
"name": "getElapsedTime",
@@ -306,7 +327,7 @@
},
{
"file": "../src/litegraph.js",
"line": 561,
"line": 617,
"description": "Sends an event to all the nodes, useful to trigger stuff",
"itemtype": "method",
"name": "sendEventToAllNodes",
@@ -326,7 +347,7 @@
},
{
"file": "../src/litegraph.js",
"line": 596,
"line": 660,
"description": "Adds a new node instasnce to this graph",
"itemtype": "method",
"name": "add",
@@ -341,7 +362,7 @@
},
{
"file": "../src/litegraph.js",
"line": 645,
"line": 709,
"description": "Removes a node from the graph",
"itemtype": "method",
"name": "remove",
@@ -356,7 +377,7 @@
},
{
"file": "../src/litegraph.js",
"line": 711,
"line": 778,
"description": "Returns a node by its id.",
"itemtype": "method",
"name": "getNodeById",
@@ -371,7 +392,7 @@
},
{
"file": "../src/litegraph.js",
"line": 723,
"line": 790,
"description": "Returns a list of nodes that matches a class",
"itemtype": "method",
"name": "findNodesByClass",
@@ -390,7 +411,7 @@
},
{
"file": "../src/litegraph.js",
"line": 739,
"line": 806,
"description": "Returns a list of nodes that matches a type",
"itemtype": "method",
"name": "findNodesByType",
@@ -409,7 +430,7 @@
},
{
"file": "../src/litegraph.js",
"line": 756,
"line": 823,
"description": "Returns a list of nodes that matches a name",
"itemtype": "method",
"name": "findNodesByName",
@@ -428,7 +449,7 @@
},
{
"file": "../src/litegraph.js",
"line": 772,
"line": 839,
"description": "Returns the top-most node in this position of the canvas",
"itemtype": "method",
"name": "getNodeOnPos",
@@ -457,7 +478,7 @@
},
{
"file": "../src/litegraph.js",
"line": 959,
"line": 1026,
"description": "Assigns a value to all the nodes that matches this name. This is used to create global variables of the node that\ncan be easily accesed from the outside of the graph",
"itemtype": "method",
"name": "setInputData",
@@ -477,7 +498,7 @@
},
{
"file": "../src/litegraph.js",
"line": 974,
"line": 1041,
"description": "Returns the value of the first node with this name. This is used to access global variables of the graph from the outside",
"itemtype": "method",
"name": "setInputData",
@@ -496,7 +517,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1011,
"line": 1081,
"description": "returns if the graph is in live mode",
"itemtype": "method",
"name": "isLive",
@@ -504,7 +525,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1044,
"line": 1118,
"description": "Creates a Object containing all the info about this graph, it can be serialized",
"itemtype": "method",
"name": "serialize",
@@ -516,7 +537,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1077,
"line": 1154,
"description": "Configure a graph from a JSON string",
"itemtype": "method",
"name": "configure",
@@ -531,7 +552,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1217,
"line": 1297,
"description": "configure a node from an object containing the serialized info",
"itemtype": "method",
"name": "configure",
@@ -539,7 +560,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1276,
"line": 1366,
"description": "serialize the content",
"itemtype": "method",
"name": "serialize",
@@ -547,7 +568,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1330,
"line": 1436,
"description": "serialize and stringify",
"itemtype": "method",
"name": "toString",
@@ -555,7 +576,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1342,
"line": 1448,
"description": "get the title string",
"itemtype": "method",
"name": "getTitle",
@@ -563,7 +584,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1355,
"line": 1461,
"description": "sets the output data",
"itemtype": "method",
"name": "setOutputData",
@@ -583,7 +604,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1376,
"line": 1482,
"description": "retrieves the input data (data traveling through the connection) from one slot",
"itemtype": "method",
"name": "getInputData",
@@ -602,7 +623,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1391,
"line": 1514,
"description": "tells you if there is a connection in one input slot",
"itemtype": "method",
"name": "isInputConnected",
@@ -621,7 +642,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1404,
"line": 1527,
"description": "tells you info about an input connection (which node, type, etc)",
"itemtype": "method",
"name": "getInputInfo",
@@ -640,7 +661,26 @@
},
{
"file": "../src/litegraph.js",
"line": 1420,
"line": 1542,
"description": "returns the node connected in the input slot",
"itemtype": "method",
"name": "getInputNode",
"params": [
{
"name": "slot",
"description": "",
"type": "Number"
}
],
"return": {
"description": "node or null",
"type": "LGraphNode"
},
"class": "LGraphNode"
},
{
"file": "../src/litegraph.js",
"line": 1561,
"description": "tells you info about an output connection (which node, type, etc)",
"itemtype": "method",
"name": "getOutputInfo",
@@ -659,7 +699,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1436,
"line": 1577,
"description": "tells you if there is a connection in one output slot",
"itemtype": "method",
"name": "isOutputConnected",
@@ -678,7 +718,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1449,
"line": 1590,
"description": "retrieves all the nodes connected to this output slot",
"itemtype": "method",
"name": "getOutputNodes",
@@ -697,7 +737,57 @@
},
{
"file": "../src/litegraph.js",
"line": 1478,
"line": 1610,
"description": "Triggers an event in this node, this will trigger any output with the same name",
"itemtype": "method",
"name": "trigger",
"params": [
{
"name": "event",
"description": "name ( \"on_play\", ... ) if action is equivalent to false then the event is send to all",
"type": "String"
},
{
"name": "param",
"description": "",
"type": "*"
}
],
"class": "LGraphNode"
},
{
"file": "../src/litegraph.js",
"line": 1660,
"description": "add a new property to this node",
"itemtype": "method",
"name": "addProperty",
"params": [
{
"name": "name",
"description": "",
"type": "String"
},
{
"name": "default_value",
"description": "",
"type": "*"
},
{
"name": "type",
"description": "string defining the output type (\"vec3\",\"number\",...)",
"type": "String"
},
{
"name": "extra_info",
"description": "this can be used to have special properties of the property (like values, etc)",
"type": "Object"
}
],
"class": "LGraphNode"
},
{
"file": "../src/litegraph.js",
"line": 1686,
"description": "add a new output slot to use in this node",
"itemtype": "method",
"name": "addOutput",
@@ -722,7 +812,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1499,
"line": 1709,
"description": "add a new output slot to use in this node",
"itemtype": "method",
"name": "addOutputs",
@@ -737,7 +827,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1524,
"line": 1734,
"description": "remove an existing output slot",
"itemtype": "method",
"name": "removeOutput",
@@ -752,7 +842,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1538,
"line": 1748,
"description": "add a new input slot to use in this node",
"itemtype": "method",
"name": "addInput",
@@ -777,7 +867,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1561,
"line": 1772,
"description": "add several new input slots in this node",
"itemtype": "method",
"name": "addInputs",
@@ -792,7 +882,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1586,
"line": 1797,
"description": "remove an existing input slot",
"itemtype": "method",
"name": "removeInput",
@@ -807,7 +897,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1600,
"line": 1811,
"description": "add an special connection to this node (used for special kinds of graphs)",
"itemtype": "method",
"name": "addConnection",
@@ -837,7 +927,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1613,
"line": 1832,
"description": "computes the size of a node according to its inputs and output slots",
"itemtype": "method",
"name": "computeSize",
@@ -856,7 +946,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1664,
"line": 1883,
"description": "returns the bounding of the object, used for rendering purposes",
"itemtype": "method",
"name": "getBounding",
@@ -868,7 +958,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1674,
"line": 1893,
"description": "checks if a point is inside the shape of a node",
"itemtype": "method",
"name": "isPointInsideNode",
@@ -892,7 +982,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1698,
"line": 1917,
"description": "checks if a point is inside a node slot, and returns info about which slot",
"itemtype": "method",
"name": "getSlotInPosition",
@@ -916,7 +1006,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1729,
"line": 1948,
"description": "returns the input slot with a given name (used for dynamic slots), -1 if not found",
"itemtype": "method",
"name": "findInputSlot",
@@ -935,7 +1025,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1744,
"line": 1963,
"description": "returns the output slot with a given name (used for dynamic slots), -1 if not found",
"itemtype": "method",
"name": "findOutputSlot",
@@ -954,7 +1044,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1759,
"line": 1978,
"description": "connect this node output to the input of another node",
"itemtype": "method",
"name": "connect",
@@ -971,7 +1061,7 @@
},
{
"name": "target_slot",
"description": "the input slot of the target node (could be the number of the slot or the string with the name of the slot)",
"description": "the input slot of the target node (could be the number of the slot or the string with the name of the slot, or -1 to connect a trigger)",
"type": "Number_or_string"
}
],
@@ -983,7 +1073,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1855,
"line": 2095,
"description": "disconnect one output to an specific node",
"itemtype": "method",
"name": "disconnectOutput",
@@ -1007,7 +1097,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1927,
"line": 2178,
"description": "disconnect one input",
"itemtype": "method",
"name": "disconnectInput",
@@ -1026,7 +1116,7 @@
},
{
"file": "../src/litegraph.js",
"line": 1989,
"line": 2246,
"description": "returns the center of a connection point in canvas coords",
"itemtype": "method",
"name": "getConnectionPos",
@@ -1050,7 +1140,7 @@
},
{
"file": "../src/litegraph.js",
"line": 2121,
"line": 2380,
"description": "Collapse the node to make it smaller on the canvas",
"itemtype": "method",
"name": "collapse",
@@ -1058,7 +1148,7 @@
},
{
"file": "../src/litegraph.js",
"line": 2134,
"line": 2393,
"description": "Forces the node to do not move or realign on Z",
"itemtype": "method",
"name": "pin",
@@ -1066,7 +1156,7 @@
},
{
"file": "../src/litegraph.js",
"line": 2192,
"line": 2481,
"description": "clears all the data inside",
"itemtype": "method",
"name": "clear",
@@ -1074,7 +1164,7 @@
},
{
"file": "../src/litegraph.js",
"line": 2248,
"line": 2516,
"description": "assigns a graph, you can reasign graphs to the same canvas",
"itemtype": "method",
"name": "setGraph",
@@ -1089,7 +1179,7 @@
},
{
"file": "../src/litegraph.js",
"line": 2279,
"line": 2547,
"description": "opens a graph contained inside a node in the current graph",
"itemtype": "method",
"name": "openSubgraph",
@@ -1104,7 +1194,7 @@
},
{
"file": "../src/litegraph.js",
"line": 2306,
"line": 2574,
"description": "closes a subgraph contained inside a node",
"itemtype": "method",
"name": "closeSubgraph",
@@ -1119,7 +1209,7 @@
},
{
"file": "../src/litegraph.js",
"line": 2321,
"line": 2589,
"description": "assigns a canvas",
"itemtype": "method",
"name": "setCanvas",
@@ -1134,7 +1224,7 @@
},
{
"file": "../src/litegraph.js",
"line": 2567,
"line": 2835,
"description": "Used to attach the canvas in a popup",
"itemtype": "method",
"name": "getCanvasWindow",
@@ -1146,7 +1236,7 @@
},
{
"file": "../src/litegraph.js",
"line": 2579,
"line": 2849,
"description": "starts rendering the content of the canvas when needed",
"itemtype": "method",
"name": "startRendering",
@@ -1154,7 +1244,7 @@
},
{
"file": "../src/litegraph.js",
"line": 2602,
"line": 2872,
"description": "stops rendering the content of the canvas (to save resources)",
"itemtype": "method",
"name": "stopRendering",

10
doc/elements/index.html Normal file
View File

@@ -0,0 +1,10 @@
<!doctype html>
<html>
<head>
<title>Redirector</title>
<meta http-equiv="refresh" content="0;url=../">
</head>
<body>
<a href="../">Click here to redirect</a>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@
<link rel="stylesheet" href="http://yui.yahooapis.com/3.9.1/build/cssgrids/cssgrids-min.css">
<link rel="stylesheet" href="./assets/vendor/prettify/prettify-min.css">
<link rel="stylesheet" href="./assets/css/main.css" id="site_styles">
<link rel="shortcut icon" type="image/png" href="./assets/favicon.png">
<link rel="icon" href="./assets/favicon.ico">
<script src="http://yui.yahooapis.com/combo?3.9.1/build/yui/yui-min.js"></script>
</head>
<body class="yui3-skin-sam">
@@ -14,9 +14,7 @@
<div id="doc">
<div id="hd" class="yui3-g header">
<div class="yui3-u-3-4">
<h1><img src="./assets/css/logo.png" title=""></h1>
<h1><img src="./assets/css/logo.png" title="" width="117" height="52"></h1>
</div>
<div class="yui3-u-1-4 version">
<em>API Docs for: </em>
@@ -27,68 +25,61 @@
<div class="yui3-u-1-4">
<div id="docs-sidebar" class="sidebar apidocs">
<div id="api-list">
<h2 class="off-left">APIs</h2>
<div id="api-tabview" class="tabview">
<ul class="tabs">
<li><a href="#api-classes">Classes</a></li>
<li><a href="#api-modules">Modules</a></li>
</ul>
<div id="api-tabview-filter">
<input type="search" id="api-filter" placeholder="Type to filter APIs">
</div>
<div id="api-tabview-panel">
<ul id="api-classes" class="apis classes">
<li><a href="./classes/LGraph.html">LGraph</a></li>
<li><a href="./classes/LGraphCanvas.html">LGraphCanvas</a></li>
<li><a href="./classes/LGraphNode.html">LGraphNode</a></li>
<li><a href="./classes/LiteGraph.html">LiteGraph</a></li>
</ul>
<ul id="api-modules" class="apis modules">
</ul>
</div>
</div>
</div>
<h2 class="off-left">APIs</h2>
<div id="api-tabview" class="tabview">
<ul class="tabs">
<li><a href="#api-classes">Classes</a></li>
<li><a href="#api-modules">Modules</a></li>
</ul>
<div id="api-tabview-filter">
<input type="search" id="api-filter" placeholder="Type to filter APIs">
</div>
<div id="api-tabview-panel">
<ul id="api-classes" class="apis classes">
<li><a href="./classes/LGraph.html">LGraph</a></li>
<li><a href="./classes/LGraphCanvas.html">LGraphCanvas</a></li>
<li><a href="./classes/LGraphNode.html">LGraphNode</a></li>
<li><a href="./classes/LiteGraph.html">LiteGraph</a></li>
</ul>
<ul id="api-modules" class="apis modules">
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="yui3-u-3-4">
<div id="api-options">
Show:
<label for="api-show-inherited">
<input type="checkbox" id="api-show-inherited" checked>
Inherited
</label>
<label for="api-show-protected">
<input type="checkbox" id="api-show-protected">
Protected
</label>
<label for="api-show-private">
<input type="checkbox" id="api-show-private">
Private
</label>
<label for="api-show-deprecated">
<input type="checkbox" id="api-show-deprecated">
Deprecated
</label>
</div>
Show:
<label for="api-show-inherited">
<input type="checkbox" id="api-show-inherited" checked>
Inherited
</label>
<label for="api-show-protected">
<input type="checkbox" id="api-show-protected">
Protected
</label>
<label for="api-show-private">
<input type="checkbox" id="api-show-private">
Private
</label>
<label for="api-show-deprecated">
<input type="checkbox" id="api-show-deprecated">
Deprecated
</label>
</div>
<div class="apidocs">
<div id="docs-main">
<div class="content">
<div class="apidocs">
<div class="apidocs">
<div id="docs-main" class="content">
<p>
Browse to a module or class using the sidebar to view its API documentation.
@@ -109,7 +100,6 @@
</div>
</div>
</div>
</div>

View File

@@ -1218,8 +1218,8 @@ LGraph.prototype.onNodeTrace = function(node, msg, color)
supported callbacks:
+ onAdded: when added to graph
+ onRemoved: when removed from graph
+ onStart: when starts playing
+ onStop: when stops playing
+ onStart: when the graph starts playing
+ onStop: when the graph stops playing
+ onDrawForeground: render the inside widgets inside the node
+ onDrawBackground: render the background area inside the node (only in edit mode)
+ onMouseDown
@@ -1359,6 +1359,8 @@ LGraphNode.prototype.configure = function(info)
}
}
if( this.onConfigured )
this.onConfigured( info );
}
/**
@@ -1537,6 +1539,24 @@ LGraphNode.prototype.getInputInfo = function(slot)
return null;
}
/**
* returns the node connected in the input slot
* @method getInputNode
* @param {number} slot
* @return {LGraphNode} node or null
*/
LGraphNode.prototype.getInputNode = function( slot )
{
if(!this.inputs)
return null;
if(slot >= this.inputs.length)
return null;
var input = this.inputs[slot];
if(!input || !input.link)
return null;
return this.graph.getNodeById( input.link.origin_id );
}
/**
* tells you info about an output connection (which node, type, etc)
@@ -1963,7 +1983,7 @@ LGraphNode.prototype.findOutputSlot = function(name)
* @param {number_or_string} target_slot the input slot of the target node (could be the number of the slot or the string with the name of the slot, or -1 to connect a trigger)
* @return {boolean} if it was connected succesfully
*/
LGraphNode.prototype.connect = function( slot, node, target_slot )
LGraphNode.prototype.connect = function( slot, target_node, target_slot )
{
target_slot = target_slot || 0;
@@ -1985,20 +2005,19 @@ LGraphNode.prototype.connect = function( slot, node, target_slot )
return false;
}
if(node && node.constructor === Number)
node = this.graph.getNodeById( node );
if(!node)
if(target_node && target_node.constructor === Number)
target_node = this.graph.getNodeById( target_node );
if(!target_node)
throw("Node not found");
//avoid loopback
if(node == this)
if(target_node == this)
return false;
//if( node.constructor != LGraphNode ) throw ("LGraphNode.connect: node is not of type LGraphNode");
//you can specify the slot by name
if(target_slot.constructor === String)
{
target_slot = node.findInputSlot(target_slot);
target_slot = target_node.findInputSlot( target_slot );
if(target_slot == -1)
{
if(LiteGraph.debug)
@@ -2011,13 +2030,13 @@ LGraphNode.prototype.connect = function( slot, node, target_slot )
//search for first slot with event?
/*
//create input for trigger
var input = node.addInput("onTrigger", LiteGraph.EVENT );
target_slot = node.inputs.length - 1; //last one is the one created
node.mode = LiteGraph.ON_TRIGGER;
var input = target_node.addInput("onTrigger", LiteGraph.EVENT );
target_slot = target_node.inputs.length - 1; //last one is the one created
target_node.mode = LiteGraph.ON_TRIGGER;
*/
return false;
}
else if( !node.inputs || target_slot >= node.inputs.length )
else if( !target_node.inputs || target_slot >= target_node.inputs.length )
{
if(LiteGraph.debug)
console.log("Connect: Error, slot number not found");
@@ -2025,8 +2044,8 @@ LGraphNode.prototype.connect = function( slot, node, target_slot )
}
//if there is something already plugged there, disconnect
if(node.inputs[ target_slot ].link != null )
node.disconnectInput( target_slot );
if(target_node.inputs[ target_slot ].link != null )
target_node.disconnectInput( target_slot );
//why here??
this.setDirtyCanvas(false,true);
@@ -2035,36 +2054,36 @@ LGraphNode.prototype.connect = function( slot, node, target_slot )
var output = this.outputs[slot];
//allows nodes to block connection
if(node.onConnectInput)
if( node.onConnectInput( target_slot, output.type, output ) === false)
if(target_node.onConnectInput)
if( target_node.onConnectInput( target_slot, output.type, output ) === false)
return false;
var input = node.inputs[target_slot];
var input = target_node.inputs[target_slot];
if( LiteGraph.isValidConnection( output.type, input.type) )
{
var link = {
var link_info = {
id: this.graph.last_link_id++,
origin_id: this.id,
origin_slot: slot,
target_id: node.id,
target_id: target_node.id,
target_slot: target_slot
};
//add to graph links list
this.graph.links[ link.id ] = link;
this.graph.links[ link_info.id ] = link_info;
//connect in output
if( output.links == null )
output.links = [];
output.links.push( link.id );
output.links.push( link_info.id );
//connect in input
node.inputs[target_slot].link = link.id;
target_node.inputs[target_slot].link = link_info.id;
if(this.onConnectionsChange)
this.onConnectionsChange( LiteGraph.OUTPUT, slot );
if(node.onConnectionsChange)
node.onConnectionsChange( LiteGraph.OUTPUT, target_slot );
this.onConnectionsChange( LiteGraph.OUTPUT, slot, true, link_info ); //link_info has been created now, so its updated
if(target_node.onConnectionsChange)
target_node.onConnectionsChange( LiteGraph.INPUT, target_slot, true, link_info );
}
this.setDirtyCanvas(false,true);
@@ -2080,7 +2099,7 @@ LGraphNode.prototype.connect = function( slot, node, target_slot )
* @param {LGraphNode} target_node the target node to which this slot is connected [Optional, if not target_node is specified all nodes will be disconnected]
* @return {boolean} if it was disconnected succesfully
*/
LGraphNode.prototype.disconnectOutput = function(slot, target_node)
LGraphNode.prototype.disconnectOutput = function( slot, target_node )
{
if( slot.constructor === String )
{
@@ -2123,6 +2142,10 @@ LGraphNode.prototype.disconnectOutput = function(slot, target_node)
output.links.splice(i,1); //remove here
target_node.inputs[ link_info.target_slot ].link = null; //remove there
delete this.graph.links[ link_id ]; //remove the link from the links pool
if(target_node.onConnectionsChange)
target_node.onConnectionsChange( LiteGraph.INPUT, link_info.target_slot, false, link_info ); //link_info hasnt been modified so its ok
if(this.onConnectionsChange)
this.onConnectionsChange( LiteGraph.OUTPUT, slot, false, link_info );
break;
}
}
@@ -2138,10 +2161,15 @@ LGraphNode.prototype.disconnectOutput = function(slot, target_node)
if(target_node)
target_node.inputs[ link_info.target_slot ].link = null; //remove other side link
delete this.graph.links[ link_id ]; //remove the link from the links pool
if(target_node.onConnectionsChange)
target_node.onConnectionsChange( LiteGraph.INPUT, link_info.target_slot, false, link_info ); //link_info hasnt been modified so its ok
if(this.onConnectionsChange)
this.onConnectionsChange( LiteGraph.OUTPUT, slot, false, link_info );
}
output.links = null;
}
this.setDirtyCanvas(false,true);
this.graph.connectionChange( this );
return true;
@@ -2153,7 +2181,7 @@ LGraphNode.prototype.disconnectOutput = function(slot, target_node)
* @param {number_or_string} slot (could be the number of the slot or the string with the name of the slot)
* @return {boolean} if it was disconnected succesfully
*/
LGraphNode.prototype.disconnectInput = function(slot)
LGraphNode.prototype.disconnectInput = function( slot )
{
//seek for the output slot
if( slot.constructor === String )
@@ -2184,15 +2212,15 @@ LGraphNode.prototype.disconnectInput = function(slot)
var link_info = this.graph.links[ link_id ];
if( link_info )
{
var node = this.graph.getNodeById( link_info.origin_id );
if(!node)
var target_node = this.graph.getNodeById( link_info.origin_id );
if(!target_node)
return false;
var output = node.outputs[ link_info.origin_slot ];
var output = target_node.outputs[ link_info.origin_slot ];
if(!output || !output.links || output.links.length == 0)
return false;
//check outputs
//search in the inputs list for this link
for(var i = 0, l = output.links.length; i < l; i++)
{
var link_id = output.links[i];
@@ -2204,10 +2232,10 @@ LGraphNode.prototype.disconnectInput = function(slot)
}
}
if(this.onConnectionsChange)
this.onConnectionsChange( LiteGraph.OUTPUT );
if(node.onConnectionsChange)
node.onConnectionsChange( LiteGraph.INPUT);
if( this.onConnectionsChange )
this.onConnectionsChange( LiteGraph.INPUT, slot, false, link_info );
if( target_node.onConnectionsChange )
target_node.onConnectionsChange( LiteGraph.OUTPUT, i, false, link_info );
}
this.setDirtyCanvas(false,true);
@@ -2878,7 +2906,7 @@ LGraphCanvas.prototype.processMouseDown = function(e)
var n = this.graph.getNodeOnPos( e.canvasX, e.canvasY, this.visible_nodes );
var skip_dragging = false;
LiteGraph.closeAllContextualMenus( ref_window );
LiteGraph.closeAllContextMenus( ref_window );
if(e.which == 1) //left button mouse
{
@@ -3012,7 +3040,7 @@ LGraphCanvas.prototype.processMouseDown = function(e)
}
else if (e.which == 3) //right button
{
this.processContextualMenu(n,e);
this.processContextMenu(n,e);
}
//TODO
@@ -4586,7 +4614,7 @@ LGraphCanvas.onMenuAdd = function(node, e, prev_menu, canvas, first_event )
if(values[i])
entries[ i ] = { value: values[i], content: values[i] , is_menu: true };
var menu = LiteGraph.createContextualMenu(entries, {event: e, callback: inner_clicked, from: prev_menu}, ref_window);
var menu = LiteGraph.createContextMenu(entries, {event: e, callback: inner_clicked, from: prev_menu}, ref_window);
function inner_clicked(v, e)
{
@@ -4596,7 +4624,7 @@ LGraphCanvas.onMenuAdd = function(node, e, prev_menu, canvas, first_event )
for(var i in node_types)
values.push( { content: node_types[i].title, value: node_types[i].type });
LiteGraph.createContextualMenu(values, {event: e, callback: inner_create, from: menu}, ref_window);
LiteGraph.createContextMenu(values, {event: e, callback: inner_create, from: menu}, ref_window);
return false;
}
@@ -4653,7 +4681,7 @@ LGraphCanvas.showMenuNodeInputs = function(node, e, prev_menu)
if(!entries.length)
return;
var menu = LiteGraph.createContextualMenu(entries, {event: e, callback: inner_clicked, from: prev_menu}, ref_window);
var menu = LiteGraph.createContextMenu(entries, {event: e, callback: inner_clicked, from: prev_menu}, ref_window);
function inner_clicked(v, e, prev)
{
@@ -4710,7 +4738,7 @@ LGraphCanvas.showMenuNodeOutputs = function(node, e, prev_menu)
if(!entries.length)
return;
var menu = LiteGraph.createContextualMenu(entries, {event: e, callback: inner_clicked, from: prev_menu}, ref_window);
var menu = LiteGraph.createContextMenu(entries, {event: e, callback: inner_clicked, from: prev_menu}, ref_window);
function inner_clicked( v, e, prev )
{
@@ -4730,7 +4758,7 @@ LGraphCanvas.showMenuNodeOutputs = function(node, e, prev_menu)
var entries = [];
for(var i in value)
entries.push({content: i, value: value[i]});
LiteGraph.createContextualMenu(entries, {event: e, callback: inner_clicked, from: prev_menu});
LiteGraph.createContextMenu(entries, {event: e, callback: inner_clicked, from: prev_menu});
return false;
}
else
@@ -4757,7 +4785,7 @@ LGraphCanvas.onShowMenuNodeProperties = function(node,e, prev_menu)
if(!entries.length)
return;
var menu = LiteGraph.createContextualMenu(entries, {event: e, callback: inner_clicked, from: prev_menu},ref_window);
var menu = LiteGraph.createContextMenu(entries, {event: e, callback: inner_clicked, from: prev_menu},ref_window);
function inner_clicked( v, e, prev )
{
@@ -4785,7 +4813,19 @@ LGraphCanvas.prototype.showEditPropertyValue = function( node, property, options
var info = null;
if(node.getPropertyInfo)
info = node.getPropertyInfo(property);
if(info.type)
if(node.properties_info)
{
for(var i = 0; i < node.properties_info.length; ++i)
{
if( node.properties_info[i].name == property )
{
info = node.properties_info[i];
break;
}
}
}
if(info !== undefined && info !== null && info.type )
type = info.type;
var input_html = "";
@@ -4802,6 +4842,10 @@ LGraphCanvas.prototype.showEditPropertyValue = function( node, property, options
}
input_html += "</select>";
}
else if(type == "boolean")
{
input_html = "<input autofocus type='checkbox' class='value' "+(node.properties[property] ? "checked" : "")+"/>";
}
var dialog = document.createElement("div");
@@ -4812,21 +4856,35 @@ LGraphCanvas.prototype.showEditPropertyValue = function( node, property, options
{
var input = dialog.querySelector("select");
input.addEventListener("change", function(e){
var index = e.target.value;
setValue( e.options[e.selectedIndex].value );
setValue( e.target.value );
//var index = e.target.value;
//setValue( e.options[e.selectedIndex].value );
});
}
else if(type == "boolean")
{
var input = dialog.querySelector("input");
if(input)
{
input.addEventListener("click", function(e){
setValue( !!input.checked );
});
}
}
else
{
var input = dialog.querySelector("input");
input.value = node.properties[ property ] !== undefined ? node.properties[ property ] : "";
input.addEventListener("keydown", function(e){
if(e.keyCode != 13)
return;
inner();
e.preventDefault();
e.stopPropagation();
});
if(input)
{
input.value = node.properties[ property ] !== undefined ? node.properties[ property ] : "";
input.addEventListener("keydown", function(e){
if(e.keyCode != 13)
return;
inner();
e.preventDefault();
e.stopPropagation();
});
}
}
var rect = this.canvas.getClientRects()[0];
@@ -4863,9 +4921,11 @@ LGraphCanvas.prototype.showEditPropertyValue = function( node, property, options
function setValue(value)
{
if(typeof( node.properties[ property ] ) == "number")
node.properties[ property ] = Number(value);
else
node.properties[ property ] = value;
value = Number(value);
node.properties[ property ] = value;
if(node.onPropertyChanged)
node.onPropertyChanged( property, value );
dialog.parentNode.removeChild( dialog );
node.setDirtyCanvas(true,true);
}
@@ -4884,7 +4944,7 @@ LGraphCanvas.onMenuNodePin = function(node)
LGraphCanvas.onMenuNodeMode = function(node, e, prev_menu)
{
LiteGraph.createContextualMenu(["Always","On Event","Never"], {event: e, callback: inner_clicked, from: prev_menu});
LiteGraph.createContextMenu(["Always","On Event","Never"], {event: e, callback: inner_clicked, from: prev_menu});
function inner_clicked(v)
{
@@ -4912,7 +4972,7 @@ LGraphCanvas.onMenuNodeColors = function(node, e, prev_menu)
var value = {value:i, content:"<span style='display: block; color:"+color.color+"; background-color:"+color.bgcolor+"'>"+i+"</span>"};
values.push(value);
}
LiteGraph.createContextualMenu(values, {event: e, callback: inner_clicked, from: prev_menu});
LiteGraph.createContextMenu(values, {event: e, callback: inner_clicked, from: prev_menu});
function inner_clicked(v)
{
@@ -4931,7 +4991,7 @@ LGraphCanvas.onMenuNodeColors = function(node, e, prev_menu)
LGraphCanvas.onMenuNodeShapes = function(node,e)
{
LiteGraph.createContextualMenu(["box","round"], {event: e, callback: inner_clicked});
LiteGraph.createContextMenu(["box","round"], {event: e, callback: inner_clicked});
function inner_clicked(v)
{
@@ -5046,7 +5106,7 @@ LGraphCanvas.prototype.getNodeMenuOptions = function(node)
return options;
}
LGraphCanvas.prototype.processContextualMenu = function(node, event)
LGraphCanvas.prototype.processContextMenu = function(node, event)
{
var that = this;
var win = this.getCanvasWindow();
@@ -5074,7 +5134,7 @@ LGraphCanvas.prototype.processContextualMenu = function(node, event)
if(!menu_info)
return;
var menu = LiteGraph.createContextualMenu( menu_info, options, win);
var menu = LiteGraph.createContextMenu( menu_info, options, win);
function inner_option_clicked(v,e)
{
@@ -5220,7 +5280,7 @@ function num2hex(triplet) {
/* LiteGraph GUI elements *************************************/
LiteGraph.createContextualMenu = function(values,options, ref_window)
LiteGraph.createContextMenu = function(values,options, ref_window)
{
options = options || {};
this.options = options;
@@ -5229,10 +5289,10 @@ LiteGraph.createContextualMenu = function(values,options, ref_window)
ref_window = ref_window || window;
if (!options.from)
LiteGraph.closeAllContextualMenus( ref_window );
LiteGraph.closeAllContextMenus( ref_window );
else {
//closing submenus
var menus = document.querySelectorAll(".graphcontextualmenu");
var menus = document.querySelectorAll(".graphcontextmenu");
for (var key in menus) {
if (menus[key].previousSibling == options.from)
menus[key].closeMenu();
@@ -5240,7 +5300,7 @@ LiteGraph.createContextualMenu = function(values,options, ref_window)
}
var root = ref_window.document.createElement("div");
root.className = "graphcontextualmenu graphmenubar-panel";
root.className = "graphcontextmenu graphmenubar-panel";
this.root = root;
var style = root.style;
@@ -5254,12 +5314,13 @@ LiteGraph.createContextualMenu = function(values,options, ref_window)
style.padding = "2px";
style.borderBottom = "2px solid #AAF";
style.backgroundColor = "#444";
style.zIndex = 10;
//title
if(options.title)
{
var element = document.createElement("div");
element.className = "graphcontextualmenu-title";
element.className = "graphcontextmenu-title";
element.innerHTML = options.title;
root.appendChild(element);
}
@@ -5367,7 +5428,7 @@ LiteGraph.createContextualMenu = function(values,options, ref_window)
}
if(close)
LiteGraph.closeAllContextualMenus( ref_window );
LiteGraph.closeAllContextMenus( ref_window );
//root.closeMenu();
}
@@ -5386,11 +5447,11 @@ LiteGraph.createContextualMenu = function(values,options, ref_window)
return root;
}
LiteGraph.closeAllContextualMenus = function( ref_window )
LiteGraph.closeAllContextMenus = function( ref_window )
{
ref_window = ref_window || window;
var elements = ref_window.document.querySelectorAll(".graphcontextualmenu");
var elements = ref_window.document.querySelectorAll(".graphcontextmenu");
if(!elements.length) return;
var result = [];

646
src/nodes/audio.js Normal file
View File

@@ -0,0 +1,646 @@
//not tested nor finished
(function( global )
{
function LGAudio()
{
this.properties = {
src: "demodata/audio.wav",
gain: 0.5,
loop: true
};
this._loading_audio = false;
this._audio_buffer = null;
this._audionodes = [];
this.addOutput( "out", "audio" );
this.addInput( "gain", "number" );
//init context
var context = LGAudio.getAudioContext();
//create gain node
this.audionode = context.createGain();
this.audionode.graphnode = this;
this.audionode.gain.value = this.properties.gain;
//debug
if(this.properties.src)
this.loadSound( this.properties.src );
}
LGAudio.getAudioContext = function()
{
if(!this._audio_context)
{
window.AudioContext = window.AudioContext || window.webkitAudioContext;
if(!window.AudioContext)
{
console.error("AudioContext not supported by browser");
return null;
}
this._audio_context = new AudioContext();
this._audio_context.onmessage = function(msg) { console.log("msg",msg);};
this._audio_context.onended = function(msg) { console.log("ended",msg);};
this._audio_context.oncomplete = function(msg) { console.log("complete",msg);};
}
//in case it crashes
if(this._audio_context.state == "suspended")
this._audio_context.resume();
return this._audio_context;
}
LGAudio.connect = function( audionodeA, audionodeB )
{
audionodeA.connect( audionodeB );
/*
if(!nodeA.outputs)
nodeA.outputs = [];
nodeA.outputs.push( nodeB );
if(!nodeB.inputs)
nodeB.inputs = [];
nodeB.inputs.push( nodeA );
*/
}
LGAudio.disconnect = function( audionodeA, audionodeB )
{
audionodeA.disconnect( audionodeB );
/*
if(nodeA.outputs)
{
var index = nodeA.outputs.indexOf( nodeB );
if(index != -1)
nodeA.outputs.splice(index,1);
}
if(nodeB.inputs)
{
var index = nodeB.inputs.indexOf( nodeA );
if(index != -1)
nodeB.inputs.splice(index,1);
}
*/
}
LGAudio.prototype.onAdded = function(graph)
{
if(graph.status === LGraph.STATUS_RUNNING)
this.onStart();
}
LGAudio.prototype.onStart = function()
{
if(!this._audio_buffer)
return;
this.playBuffer( this._audio_buffer );
}
LGAudio.prototype.onStop = function()
{
this.stopAllSounds();
}
LGAudio.prototype.onRemoved = function()
{
this.stopAllSounds();
}
LGAudio.prototype.stopAllSounds = function()
{
//iterate and stop
for(var i = 0; i < this._audionodes.length; ++i )
{
this._audionodes[i].stop();
//this._audionodes[i].disconnect( this.audionode );
}
this._audionodes.length = 0;
}
LGAudio.prototype.onExecute = function()
{
var v = this.getInputData(0);
if( v !== undefined )
this.audionode.gain.value = v;
}
LGAudio.prototype.onAction = function(event)
{
if(this._audio_buffer)
{
if(event == "Play")
this.playBuffer(this._audio_buffer);
else if(event == "Stop")
this.stopAllSounds();
}
}
LGAudio.prototype.onPropertyChanged = function( name, value )
{
if( name == "src" )
this.loadSound( value );
else if(name == "gain")
this.audionode.gain.value = value;
}
LGAudio.prototype.playBuffer = function( buffer )
{
var that = this;
var context = LGAudio.getAudioContext();
//create a new audionode (this is mandatory, AudioAPI doesnt like to reuse old ones)
var audionode = context.createBufferSource(); //create a AudioBufferSourceNode
audionode.graphnode = this;
audionode.buffer = buffer;
audionode.loop = this.properties.loop;
this._audionodes.push( audionode );
audionode.connect( this.audionode ); //connect to gain
this._audionodes.push( audionode );
audionode.onended = function()
{
console.log("ended!");
that.trigger("ended");
//remove
var index = that._audionodes.indexOf( audionode );
if(index != -1)
that._audionodes.splice(index,1);
}
audionode.start();
return audionode;
}
LGAudio.prototype.onConnectionsChange = function( connection, slot, connected, link_info )
{
//only process the outputs events
if(connection != LiteGraph.OUTPUT)
return;
var target_node = null;
if( link_info )
target_node = this.graph.getNodeById( link_info.target_id );
if( !target_node )
return;
if( connected )
{
if(target_node.connectAudioToSlot)
target_node.connectAudioToSlot( this.audionode, link_info.target_slot );
else
LGAudio.connect( this.audionode, target_node.audionode );
}
else
{
if(target_node.disconnectAudioFromSlot)
target_node.disconnectAudioFromSlot( this.audionode, link_info.target_slot );
else
LGAudio.disconnect( this.audionode, target_node.audionode );
}
}
LGAudio.prototype.loadSound = function( url )
{
var that = this;
//kill previous load
if(this._request)
{
this._request.abort();
this._request = null;
}
this._audio_buffer = null;
this._loading_audio = false;
if(!url)
return;
//load new sample
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
this._loading_audio = true;
this._request = request;
var context = LGAudio.getAudioContext();
// Decode asynchronously
request.onload = function() {
context.decodeAudioData( request.response, function(buffer) {
that._audio_buffer = buffer;
that._loading_audio = false;
//if is playing, then play it
if(that.graph && that.graph.status === LGraph.STATUS_RUNNING)
that.onStart();
}, onError);
}
request.send();
function onError(err)
{
console.log("Audio loading sample error:",err);
}
}
LGAudio.prototype.onGetInputs = function()
{
return [["Play",LiteGraph.ACTION],["Stop",LiteGraph.ACTION]];
}
LGAudio.prototype.onGetOutputs = function()
{
return [["ended",LiteGraph.EVENT]];
}
LGAudio.title = "Source";
LGAudio.desc = "Plays audio";
LiteGraph.registerNodeType("audio/source", LGAudio);
global.LGAudio = LGAudio;
//*****************************************************
function LGAudioAnalyser()
{
this.properties = {
fftSize: 2048,
minDecibels: -100,
maxDecibels: -10,
smoothingTimeConstant: 0.5
};
var context = LGAudio.getAudioContext();
this.audionode = context.createAnalyser();
this.audionode.graphnode = this;
this.audionode.fftSize = this.properties.fftSize;
this.audionode.minDecibels = this.properties.minDecibels;
this.audionode.maxDecibels = this.properties.maxDecibels;
this.audionode.smoothingTimeConstant = this.properties.smoothingTimeConstant;
this.addInput("in","audio");
this.addOutput("freqs","FFT");
//this.addOutput("time","freq");
this._freq_bin = null;
this._time_bin = null;
}
LGAudioAnalyser.prototype.onPropertyChanged = function(name, value)
{
this.audionode[ name ] = value;
}
LGAudioAnalyser.prototype.onExecute = function()
{
if(this.isOutputConnected(0))
{
//send FFT
var bufferLength = this.audionode.frequencyBinCount;
if( !this._freq_bin || this._freq_bin.length != bufferLength )
this._freq_bin = new Uint8Array( bufferLength );
this.audionode.getByteFrequencyData( this._freq_bin );
this.setOutputData(0,this._freq_bin);
}
//properties
for(var i = 1; i < this.inputs.length; ++i)
{
var input = this.inputs[i];
var v = this.getInputData(i);
if (v !== undefined)
this.audionode[ input.name ].value = v;
}
//time domain
//this.audionode.getFloatTimeDomainData( dataArray );
}
LGAudioAnalyser.prototype.onGetInputs = function()
{
return [["minDecibels","number"],["maxDecibels","number"],["smoothingTimeConstant","number"]];
}
LGAudioAnalyser.title = "Analyser";
LGAudioAnalyser.desc = "Audio Analyser";
LiteGraph.registerNodeType( "audio/analyser", LGAudioAnalyser );
//*****************************************************
//this function helps creating wrappers to existing classes
function createAudioNodeWrapper( class_object )
{
class_object.prototype.onPropertyChanged = function(name, value)
{
if( this.audionode[ name ] === undefined )
return;
if( this.audionode[ name ].value !== undefined )
this.audionode[ name ].value = value;
else
this.audionode[ name ] = value;
}
class_object.prototype.onConnectionsChange = function( connection, slot, connected, link_info )
{
//only process the outputs events
if(connection != LiteGraph.OUTPUT)
return;
var target_node = null;
if( link_info )
target_node = this.graph.getNodeById( link_info.target_id );
if( !target_node )
return;
if( connected )
{
if(target_node.connectAudioToSlot)
target_node.connectAudioToSlot( this.audionode, link_info.target_slot );
else
LGAudio.connect( this.audionode, target_node.audionode );
}
else
{
if(target_node.disconnectAudioFromSlot)
target_node.disconnectAudioFromSlot( this.audionode, link_info.target_slot );
else
LGAudio.disconnect( this.audionode, target_node.audionode );
}
}
}
//*****************************************************
function LGAudioGain()
{
//default
this.properties = {
gain: 1
};
this.audionode = LGAudio.getAudioContext().createGain();
this.addInput("in","audio");
this.addInput("gain","number");
this.addOutput("out","audio");
}
LGAudioGain.prototype.onExecute = function()
{
if(!this.inputs || !this.inputs.length)
return;
for(var i = 1; i < this.inputs.length; ++i)
{
var input = this.inputs[i];
var v = this.getInputData(i);
if(v !== undefined)
this.audionode[ input.name ].value = v;
}
}
createAudioNodeWrapper( LGAudioGain );
LGAudioGain.title = "Gain";
LGAudioGain.desc = "Audio gain";
LiteGraph.registerNodeType("audio/gain", LGAudioGain);
function LGAudioMixer()
{
//default
this.properties = {
gain1: 0.5,
gain2: 0.5
};
this.audionode = LGAudio.getAudioContext().createGain();
this.audionode1 = LGAudio.getAudioContext().createGain();
this.audionode1.gain.value = this.properties.gain1;
this.audionode2 = LGAudio.getAudioContext().createGain();
this.audionode2.gain.value = this.properties.gain2;
this.audionode1.connect( this.audionode );
this.audionode2.connect( this.audionode );
this.addInput("in1","audio");
this.addInput("in1 gain","number");
this.addInput("in2","audio");
this.addInput("in2 gain","number");
this.addOutput("out","audio");
}
LGAudioMixer.prototype.connectAudioToSlot = function( audionode, slot )
{
if(slot == 0)
LGAudio.connect( audionode, this.audionode1 );
else if(slot == 2)
LGAudio.connect( audionode, this.audionode2 );
}
LGAudioMixer.prototype.disconnectAudioFromSlot = function( audionode, slot )
{
if(slot == 0)
LGAudio.disconnect( audionode, this.audionode1 );
else if(slot == 2)
LGAudio.disconnect( audionode, this.audionode2 );
}
LGAudioMixer.prototype.onExecute = function()
{
if(!this.inputs || !this.inputs.length)
return;
for(var i = 1; i < this.inputs.length; ++i)
{
var input = this.inputs[i];
if(input.type == "audio")
continue;
var v = this.getInputData(i);
if(v === undefined)
continue;
if(i == 1)
this.audionode1.gain.value = v;
else if(i == 3)
this.audionode2.gain.value = v;
}
}
createAudioNodeWrapper( LGAudioMixer );
LGAudioMixer.title = "Mixer";
LGAudioMixer.desc = "Audio mixer";
LiteGraph.registerNodeType("audio/mixer", LGAudioMixer);
function LGAudioDelay()
{
//default
this.properties = {
time: 5
};
this.audionode = LGAudio.getAudioContext().createDelay( this.properties.time );
this.addInput("in","audio");
this.addOutput("out","audio");
}
createAudioNodeWrapper( LGAudioDelay );
LGAudioDelay.prototype.onPropertyChanged = function( name, value )
{
if(name == "time")
{
if(value > 500)
value = 500;
if(value < 0)
value = 0;
var input_node = this.getInputNode(0);
var output_nodes = this.getOutputNodes(0);
if(input_node)
input_node.audionode.disconnect( this.audionode );
if(output_nodes)
{
for(var i = 0; i < output_nodes.length; ++i)
this.audionode.disconnect( output_nodes[i].audionode );
}
this.audionode = LGAudio.getAudioContext().createDelay( value );
if(input_node)
input_node.audionode.connect( this.audionode );
if(output_nodes)
{
for(var i = 0; i < output_nodes.length; ++i)
this.audionode.connect( output_nodes[i].audionode );
}
}
}
LGAudioDelay.title = "Delay";
LGAudioDelay.desc = "Audio delay";
LiteGraph.registerNodeType("audio/delay", LGAudioDelay);
function LGAudioBiquadFilter()
{
//default
this.properties = {
frequency: 350,
detune: 0,
Q: 1
};
this.addProperty("type","lowpass","enum",{values:["lowpass","highpass","bandpass","lowshelf","highshelf","peaking","notch","allpass"]});
//create node
this.audionode = LGAudio.getAudioContext().createBiquadFilter();
//slots
this.addInput("in","audio");
this.addOutput("out","audio");
}
LGAudioBiquadFilter.prototype.onExecute = function()
{
if(!this.inputs || !this.inputs.length)
return;
for(var i = 1; i < this.inputs.length; ++i)
{
var input = this.inputs[i];
var v = this.getInputData(i);
if(v !== undefined)
this.audionode[ input.name ].value = v;
}
}
LGAudioBiquadFilter.prototype.onGetInputs = function()
{
return [["frequency","number"],["detune","number"],["Q","number"]];
}
createAudioNodeWrapper( LGAudioBiquadFilter );
LGAudioBiquadFilter.title = "BiquadFilter";
LGAudioBiquadFilter.desc = "Audio filter";
LiteGraph.registerNodeType("audio/biquadfilter", LGAudioBiquadFilter);
//*****************************************************
function LGAudioDestination()
{
this.audionode = LGAudio.getAudioContext().destination;
this.addInput("in","audio");
}
LGAudioDestination.title = "Destination";
LGAudioDestination.desc = "Audio output";
LiteGraph.registerNodeType("audio/destination", LGAudioDestination);
//EXTRA
function LGAudioVisualization()
{
this.addInput("freqs","FFT");
this.size = [300,200];
this._last_buffer = null;
}
LGAudioVisualization.prototype.onExecute = function()
{
this._last_buffer = this.getInputData(0);
}
LGAudioVisualization.prototype.onDrawForeground = function(ctx)
{
if(!this._last_buffer)
return;
var buffer = this._last_buffer;
var delta = buffer.length / this.size[0];
var h = this.size[1];
ctx.fillStyle = "black";
ctx.fillRect(0,0,this.size[0],this.size[1]);
ctx.strokeStyle = "white";
ctx.beginPath();
var x = 0;
for(var i = 0; i < buffer.length; i+= delta)
{
ctx.moveTo(x,h);
ctx.lineTo(x,h - (buffer[i|0]/255) * h);
x++;
}
ctx.stroke();
}
LGAudioVisualization.title = "Visualization";
LGAudioVisualization.desc = "Audio Visualization";
LiteGraph.registerNodeType("audio/visualization", LGAudioVisualization);
})( window );

View File

@@ -2,6 +2,25 @@
(function(){
//Constant
function Time()
{
this.addOutput("in ms","number");
this.addOutput("in sec","number");
}
Time.title = "Time";
Time.desc = "Time";
Time.prototype.onExecute = function()
{
this.setOutputData(0, this.graph.globaltime * 1000 );
this.setOutputData(1, this.graph.globaltime );
}
LiteGraph.registerNodeType("basic/time", Time);
//Subgraph: a node that contains a graph
function Subgraph()
{

View File

@@ -61,7 +61,7 @@ if(typeof(LiteGraph) != "undefined")
gl.disable( gl.DEPTH_TEST );
var mesh = Mesh.getScreenQuad();
var shader = LGraphFXLens._shader;
var camera = LS.Renderer._current_camera;
//var camera = LS.Renderer._current_camera;
this._tex.drawTo( function() {
tex.bind(0);
@@ -375,7 +375,11 @@ if(typeof(LiteGraph) != "undefined")
gl.disable( gl.BLEND );
gl.disable( gl.DEPTH_TEST );
var mesh = Mesh.getScreenQuad();
var camera = LS.Renderer._current_camera;
var camera = window.LS ? LS.Renderer._current_camera : null;
if(camera)
camera_planes = [LS.Renderer._current_camera.near, LS.Renderer._current_camera.far];
else
camera_planes = [1,100];
var noise = null;
if(fx == "noise")
@@ -386,7 +390,7 @@ if(typeof(LiteGraph) != "undefined")
if(fx == "noise")
noise.bind(1);
shader.uniforms({u_texture:0, u_noise:1, u_size: [tex.width, tex.height], u_rand:[ Math.random(), Math.random() ], u_value1: value1, u_value2: value2, u_camera_planes: [LS.Renderer._current_camera.near, LS.Renderer._current_camera.far] })
shader.uniforms({u_texture:0, u_noise:1, u_size: [tex.width, tex.height], u_rand:[ Math.random(), Math.random() ], u_value1: value1, u_value2: value2, u_camera_planes: camera_planes })
.draw(mesh);
});

View File

@@ -494,6 +494,8 @@ if(typeof(LiteGraph) != "undefined")
this.boxcolor = "#FF0000";
return;
}
this.boxcolor = "#FF0000";
this._shader_code = (uvcode + "|" + pixelcode);
shader = this._shader;
}
@@ -539,8 +541,10 @@ if(typeof(LiteGraph) != "undefined")
void main() {\n\
vec2 uv = v_coord;\n\
UV_CODE;\n\
vec3 color = texture2D(u_texture, uv).rgb;\n\
vec3 colorB = texture2D(u_textureB, uv).rgb;\n\
vec4 color4 = texture2D(u_texture, uv);\n\
vec3 color = color4.rgb;\n\
vec4 color4B = texture2D(u_textureB, uv);\n\
vec3 colorB = color4B.rgb;\n\
vec3 result = color;\n\
float alpha = 1.0;\n\
PIXEL_CODE;\n\
@@ -1846,13 +1850,13 @@ if(typeof(LiteGraph) != "undefined")
}
this._waiting_confirmation = true;
var that = this;
// Not showing vendor prefixes.
navigator.getUserMedia({video: true}, this.streamReady.bind(this), onFailSoHard);
var that = this;
function onFailSoHard(e) {
trace('Webcam rejected', e);
console.log('Webcam rejected', e);
that._webcam_stream = false;
that.box_color = "red";
};
@@ -1942,7 +1946,84 @@ if(typeof(LiteGraph) != "undefined")
LiteGraph.registerNodeType("texture/webcam", LGraphTextureWebcam );
//Cubemap reader
function LGraphTextureMatte()
{
this.addInput("in","Texture");
this.addOutput("out","Texture");
this.properties = { key_color: vec3.fromValues(0.,1.,0.), threshold: 0.8, slope: 0.2, precision: LGraphTexture.DEFAULT };
if(!LGraphTextureMatte._shader)
LGraphTextureMatte._shader = new GL.Shader( GL.Shader.SCREEN_VERTEX_SHADER, LGraphTextureMatte.pixel_shader );
}
LGraphTextureMatte.title = "Matte";
LGraphTextureMatte.desc = "Extracts background";
LGraphTextureMatte.widgets_info = {
"key_color": { widget:"color" },
"precision": { widget:"combo", values: LGraphTexture.MODE_VALUES }
};
LGraphTextureMatte.prototype.onExecute = function()
{
if(!this.isOutputConnected(0))
return; //saves work
var tex = this.getInputData(0);
if(this.properties.precision === LGraphTexture.PASS_THROUGH )
{
this.setOutputData(0,tex);
return;
}
if(!tex)
return;
this._tex = LGraphTexture.getTargetTexture( tex, this._tex, this.properties.precision );
gl.disable( gl.BLEND );
gl.disable( gl.DEPTH_TEST );
if(!this._uniforms)
this._uniforms = { u_texture: 0, u_key_color: this.properties.key_color, u_threshold: 1, u_slope: 1 };
var uniforms = this._uniforms;
var mesh = Mesh.getScreenQuad();
var shader = LGraphTextureMatte._shader;
uniforms.u_key_color = this.properties.key_color;
uniforms.u_threshold = this.properties.threshold;
uniforms.u_slope = this.properties.slope;
this._tex.drawTo( function() {
tex.bind(0);
shader.uniforms( uniforms ).draw( mesh );
});
this.setOutputData( 0, this._tex );
}
LGraphTextureMatte.pixel_shader = "precision highp float;\n\
varying vec2 v_coord;\n\
uniform sampler2D u_texture;\n\
uniform vec3 u_key_color;\n\
uniform float u_threshold;\n\
uniform float u_slope;\n\
\n\
void main() {\n\
vec3 color = texture2D( u_texture, v_coord ).xyz;\n\
float diff = length( normalize(color) - normalize(u_key_color) );\n\
float edge = u_threshold * (1.0 - u_slope);\n\
float alpha = smoothstep( edge, u_threshold, diff);\n\
gl_FragColor = vec4( color, alpha );\n\
}";
LiteGraph.registerNodeType("texture/matte", LGraphTextureMatte );
//***********************************
//Cubemap reader (to pass a cubemap to a node that requires cubemaps and no images)
function LGraphCubemap()
{
this.addOutput("Cubemap","Cubemap");

View File

@@ -42,7 +42,7 @@ GraphicsImage.prototype.onExecute = function()
this.img.dirty = false;
}
GraphicsImage.prototype.onPropertyChange = function(name,value)
GraphicsImage.prototype.onPropertyChanged = function(name,value)
{
this.properties[name] = value;
if (name == "url" && value != "")
@@ -401,7 +401,7 @@ ImageCrop.prototype.onExecute = function()
this.setOutputData(0,null);
}
ImageCrop.prototype.onPropertyChange = function(name,value)
ImageCrop.prototype.onPropertyChanged = function(name,value)
{
this.properties[name] = value;
@@ -524,7 +524,7 @@ ImageVideo.prototype.loadVideo = function(url)
//document.body.appendChild(this.video);
}
ImageVideo.prototype.onPropertyChange = function(name,value)
ImageVideo.prototype.onPropertyChanged = function(name,value)
{
this.properties[name] = value;
if (name == "url" && value != "")

View File

@@ -213,12 +213,12 @@
WidgetKnob.prototype.onWidget = function(e,widget)
{
if(widget.name=="increase")
this.onPropertyChange("size", this.properties.size + 10);
this.onPropertyChanged("size", this.properties.size + 10);
else if(widget.name=="decrease")
this.onPropertyChange("size", this.properties.size - 10);
this.onPropertyChanged("size", this.properties.size - 10);
}
WidgetKnob.prototype.onPropertyChange = function(name,value)
WidgetKnob.prototype.onPropertyChanged = function(name,value)
{
if(name=="wcolor")
this.properties[name] = value;
@@ -351,7 +351,7 @@
//this.oldmouse = null;
}
WidgetHSlider.prototype.onPropertyChange = function(name,value)
WidgetHSlider.prototype.onPropertyChanged = function(name,value)
{
if(name=="wcolor")
this.properties[name] = value;
@@ -604,7 +604,7 @@
}
},
onPropertyChange: function(name,value)
onPropertyChanged: function(name,value)
{
this.properties[name] = value;
return true;
@@ -703,7 +703,7 @@
}
}
WidgetText.prototype.onPropertyChange = function(name,value)
WidgetText.prototype.onPropertyChanged = function(name,value)
{
this.properties[name] = value;
this.str = typeof(value) == 'number' ? value.toFixed(3) : value;

View File

@@ -9,3 +9,4 @@
../src/nodes/gltextures.js
../src/nodes/glfx.js
../src/nodes/midi.js
../src/nodes/audio.js