diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..75f51c0f Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore index 1a517801..9d69e313 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,3 @@ node_modules -examples/**/dist - -.DS_Store -yarn.lock - -.temp -.vscode - -# Jest -coverage \ No newline at end of file +examples/*/dist +examples/*/*/dist \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..6f3a2913 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "liveServer.settings.port": 5501 +} \ No newline at end of file diff --git a/_old/_oldGraph.ts b/Graph.ts similarity index 85% rename from _old/_oldGraph.ts rename to Graph.ts index 7066c290..0c342e25 100644 --- a/_old/_oldGraph.ts +++ b/Graph.ts @@ -43,7 +43,7 @@ export function parseFunctionFromText(method='') { // go-here-do-that utilities. Create an object node tree and make it do... things // same setup as sequencer but object/array/tag only (no functions), and can add arbitrary properties to mutate on objects // or propagate to children/parents with utility calls that get added to the objects -//Joshua Brewster and Garrett Flynn LGPLv3.0 +//Joshua Brewster and Garrett Flynn AGPLv3.0 export type OperatorType = ( //can be async ...args:any //input arguments, e.g. output from another node @@ -62,11 +62,11 @@ export type Tree = { //properties input on GraphNode or add, or for children export type GraphNodeProperties = { tag?:string, //generated if not specified, or use to get another node by tag instead of generating a new one - operator?:string|OperatorType|((...args)=>any|void), //Operator to handle I/O on this node. Returned inputs can propagate according to below settings + operator?:OperatorType|((...args)=>any|void), //Operator to handle I/O on this node. Returned inputs can propagate according to below settings forward?:boolean, //pass output to child nodes backward?:boolean, //pass output to parent node children?:{[key:string]:string|boolean|undefined|GraphNodeProperties|GraphNode|Graph}//string|GraphNodeProperties|GraphNode|(GraphNodeProperties|GraphNode|string)[], //child node(s), can be tags of other nodes, properties objects like this, or GraphNodes, or null - parent?:GraphNode|Graph|string, //parent graph node + parent?:GraphNode|Graph, //parent graph node branch?:{ //based on the operator result, automatically do something [label:string]:{ //apply any label for your own indexing if:any|((output:any)=>boolean), //if this value, or pass a callback that returns true/false @@ -77,18 +77,7 @@ export type GraphNodeProperties = { delay?:false|number, //ms delay to fire the node repeat?:false|number, // set repeat as an integer to repeat the input n times, cmd will be the number of times the operation has been repeated recursive?:false|number, //or set recursive with an integer to pass the output back in as the next input n times, cmd will be the number of times the operation has been repeated - reactive?:boolean | - ((self:GraphNode)=>void) | - { - "self"?:(self:GraphNode,prop:any,node:any,key:string)=>void, - "parent"?:(self:GraphNode,prop:any,node:any,key:string)=>void, - "children"?:(self:GraphNode,prop:any,node:any,key:string)=>void, - "self."?:(self:GraphNode,prop:any,node:any,key:string)=>void - "parent."?:(self:GraphNode,prop:any,node:any,key:string)=>void, - "children."?:(self:GraphNode,prop:any,node:any,key:string)=>void, - "[tag]."?:(self:GraphNode,prop:any,node:any,key:string)=>void, - [key:string]:(self:GraphNode,prop:any,node:any,key:string)=>void - }, //use a local state object to trigger state subscriptions, using the node's _unique tag to subscribe + reactive?:boolean|((_state:{[key:string]:any})=>void), //use a local state object to trigger state subscriptions, using the node's _unique tag to subscribe frame?:boolean, //true or false. If repeating or recursing, execute on requestAnimationFrame? Careful mixing this with animate:true animate?:boolean, //true or false, run the operation on an animationFrame loop? loop?:false|number, //milliseconds or false, run the operation on a loop? @@ -112,7 +101,7 @@ export class EventHandler { data={} triggers={} - constructor(data?:{[key:string]:any}) { if(typeof data === 'object') this.data = data; } + constructor() {} setState = (updateObj:{[key:string]:any}) => { Object.assign(this.data, updateObj); @@ -178,13 +167,8 @@ export const state = new EventHandler(); //const restrictedKeys = ['_state', 'graph'] // added to GraphNode and Graph -function addLocalState(props?) { - if(!props) props = this._initial; - if(!props) return; - if(!this._state) { - this._state = {}; - this._events = new EventHandler(this._state); - } +function addLocalState(props) { + if(!this._state) this._state = {}; for (let k in props) { if (k === '_state' || k === 'graph') continue; // else if (!(k in this._initial)) continue @@ -196,16 +180,15 @@ function addLocalState(props?) { this._state[k]; }, set: (v) => { - if(this.state.triggers[this._unique]) - this.setState({[this._unique]:this}); //trigger subscriptions, if any - this._events.setState({[k]:v}); //this will update _state and trigger local key subscriptions + this._state[k] = v; + if(this.state.triggers[this._unique]) this.setState({[this._unique]:this._state}); //trigger subscriptions, if any }, enumerable: true, configurable: true }); } } -} + } @@ -227,20 +210,7 @@ export class GraphNode { animation = undefined; //animation function, uses operator if undefined (with cmd 'animate') forward:boolean = true; /// propagate outputs to children? backward:boolean = false; //propagate outputs to parents? - reactive:boolean | - ((self:GraphNode)=>void) | - { - "self"?:(self:GraphNode,prop:any,node:any,key:string)=>void, - "parent"?:(self:GraphNode,prop:any,node:any,key:string)=>void, - "children"?:(self:GraphNode,prop:any,node:any,key:string)=>void, - "self.x"?:(self:GraphNode,prop:any,node:any,key:string)=>void, - "parent.x"?:(self:GraphNode,prop:any,node:any,key:string)=>void, - "children.x"?:(self:GraphNode,prop:any,node:any,key:string)=>void, - "[tag].x"?:(self:GraphNode,prop:any,node:any,key:string)=>void, - [key:string]:(self:GraphNode,prop:any,node:any,key:string)=>void - } = false; //does the node proxy custom props through a local _state? Subscribe by the _unique id or pass a callback in GraphNodeProperties - _events?:EventHandler; - + reactive: boolean|((_state:{[key:string]:any})=>void) = false; //does the node proxy custom props through a local _state? Subscribe by the _unique id or pass a callback in GraphNodeProperties runSync:boolean = false; firstRun:boolean = true; DEBUGNODE:boolean = false; //prints a console.time and console.timeEnd on each runOp call @@ -256,15 +226,11 @@ export class GraphNode { ) { + + + if(typeof properties === 'function') { //pass a function instead of properties to set up a functional graph quickly properties = { operator:properties as any }; - if((properties.operator as Function).name) properties.tag = (properties.operator as Function).name; - } else if (typeof properties.operator === 'string') { - if(graph) { - let n = graph.get(properties.operator); - if(n) properties.operator = n.operator; - if(!properties.tag && (properties.operator as Function).name) properties.tag = (properties.operator as Function).name; - } } if(typeof properties === 'object') { @@ -346,7 +312,7 @@ export class GraphNode { if(hasnode) { //this.merge(hasnode) if(this.reactive) { - this.addLocalState(hasnode._initial); + this.addLocalState(hasnode); } if(!this.source) this.source = hasnode; @@ -417,6 +383,13 @@ export class GraphNode { } + if(this.reactive) { + addLocalState(properties); + if(typeof this.reactive === 'function') { + this.state.subscribeTrigger(this._unique,this.reactive); + } + } + if(typeof parent === 'object') { this.parent=parent; if(parent instanceof GraphNode || parent instanceof Graph) parent.nodes.set(this.tag,this); //parentNode should get a mapped version with the original tag still @@ -436,64 +409,6 @@ export class GraphNode { if(this.parent instanceof GraphNode || this.parent instanceof Graph) this.checkNodesHaveChildMapped(this.parent, this); - - - if(this.reactive) { - this.addLocalState(properties); - if(typeof this.reactive === 'function') { - this.state.subscribeTrigger(this._unique,this.reactive); - } - else if(typeof this.reactive === 'object') { - for(const key in this.reactive) { - if(typeof (this.reactive as any)[key] === 'function') { - if(key.includes('.')) { - let split = key.split('.'); - if(split[0] === 'self') { - if(!this._state) this.addLocalState(); - (this.reactive as any)[key] = this._events.subscribeTrigger(key,(this.reactive as any)[key]) - } else if(split[0] === 'parent' && this.parent) { - if(!this.parent._state) this.addLocalState(); - (this.reactive as any)[key] = this.parent._events.subscribeTrigger(key,(this.reactive as any)[key]) - } else if(split[0] === 'children') { - let subs = {}; - for(const k in this.children) { - if(this.children[k]?.state) { - if(!this.children[k]._state) this.children[k].addLocalState(); - subs[k] = this.children[k]._events.subscribeTrigger(key,(this.reactive as any)[key]); - } - } - (this.reactive as any)[key] = subs; - } else if(this.nodes.get(split[0])) { - if(!this.nodes.get(key)._state) this.nodes.get(key).addLocalState(); - (this.reactive as any)[key] = this.nodes.get(key)._events.subscribeTrigger(key,(this.reactive as any)[key]); - } - } else { - if(key === 'self') { - if(!this._state) this.parent.addLocalState(); - (this.reactive as any)[key] = this.state.subscribeTrigger(this._unique,(this.reactive as any)[key]); - } else if (key === 'parent' && this.parent) { - if(!this.parent._state) this.parent.addLocalState(); - (this.reactive as any)[key] = this.parent.state.subscribeTrigger(this.parent._unique,(this.reactive as any)[key]); - } else if (key === 'children' && this.children) { - let subs = {}; - for(const k in this.children) { - if(this.children[k]?.state) { - if(!this.children[k]._state) this.children[k].addLocalState(); - subs[k] = this.children[k].state.subscribeTrigger(this.children[k]._unique,(this.reactive as any)[key]); - } - } - (this.reactive as any)[key] = subs; - } else if(this.nodes.get(key)) { - if(!this.nodes.get(key)._state) this.nodes.get(key).addLocalState(); - (this.reactive as any)[key] = this.nodes.get(key).state.subscribeTrigger(this.nodes.get(key)._unique,(this.reactive as any)[key]); - } - } - } - } - } - } - - if(typeof this.oncreate === 'function') this.oncreate(this); if(!this.firstRun) this.firstRun = true; if(this.animation && !this.animate) this.animate = true; @@ -531,13 +446,9 @@ export class GraphNode { } //set an operator using our operator types or any arbitrary function :D //this is the i/o handler, or the 'main' function for this node to propagate results. The origin is the node the data was propagated from - setOperator = (operator:OperatorType|string) => { - if(typeof operator === 'string') { - if(this.graph && this.graph.get(operator)) operator = this.graph.get(operator).operator; - else if(this.nodes.get(operator)) operator = this.nodes.get(operator); - } + setOperator = (operator:OperatorType) => { if(typeof operator !== 'function') return operator; - this.operator = operator.bind(this); // operator is always bound to this class instance (arrow functions are still correctly scoped) + this.operator = operator.bind(this); // operator is always bound to this class instance return operator; } @@ -862,6 +773,32 @@ export class GraphNode { } return n; } + + remove = (n:string|GraphNode) => { + if(typeof n === 'string') n = this.nodes.get(n); + if((n as GraphNode)?.tag) { + this.nodes.delete((n as GraphNode).tag); + if(this.children[(n as GraphNode).tag]) delete this.children[(n as GraphNode).tag]; + if(this.graph) { + this.graph.nodes.delete((n as GraphNode).tag); + this.graph.nNodes = this.graph.nodes.size; + } + this.nodes.forEach((n:GraphNode) => { + if(n.nodes.get((n as GraphNode).tag)) { + n.nodes.delete((n as GraphNode).tag); + if(n.children[(n as GraphNode).tag]) delete n.children[(n as GraphNode).tag]; + if(n.parent?.tag === (n as GraphNode).tag) delete n.parent; + } + }); + + if((n as GraphNode).ondelete) (n as GraphNode).ondelete(n); + } + + if(typeof this._state === 'object') { + this.state.unsubscribeTrigger(this._unique); + } + } + //append a node as a child to a parent node (this by default) append = (n:string|GraphNode, parentNode=this) => { if(typeof n === 'string') n = this.nodes.get(n); @@ -965,7 +902,27 @@ export class GraphNode { } return Object.assign(baseprops,uniqueprops) } - else return Object.assign(baseprops,this._initial); + else + return { + tag:n.tag, + operator:n.operator, + graph:n.graph, + children:n.children, //will return the original prototypes kept in this._initial if they exist + parent:n.parent, + forward:n.forward, + backward:n.bacward, + loop:n.loop, + animate:n.animate, + frame:n.frame, + delay:n.delay, + recursive:n.recursive, + repeat:n.repeat, + branch:n.branch, + oncreate:n.oncreate, + reactive:n.reactive, + DEBUGNODE:n.DEBUGNODE, + ...this._initial + }; } setProps = (props:GraphNodeProperties={}) => { @@ -984,98 +941,53 @@ export class GraphNode { } - - remove = (n:string|GraphNode) => { - if(typeof n === 'string') n = this.nodes.get(n); - if(n instanceof GraphNode) { - this.nodes.delete((n as GraphNode).tag); - if(this.children[(n as GraphNode).tag]) delete this.children[(n as GraphNode).tag]; - if(n.graph) { - n.graph.nodes.delete((n as GraphNode).tag); - n.graph.nNodes = n.graph.nodes.size; - } - this.nodes.forEach((nd:GraphNode) => { - if(nd.nodes.get((n as GraphNode).tag)) { - nd.nodes.delete((n as GraphNode).tag); - if(nd.children[(n as GraphNode).tag]) delete nd.children[(n as GraphNode).tag]; - if(nd.parent?.tag === (n as GraphNode).tag) delete nd.parent; - } - }); - - - n.cleanup(); - - } - - } - - cleanup = () => { - - this.stopNode(); - - if(typeof this._state === 'object') { - this.state.unsubscribeTrigger(this._unique); - } - - if(typeof this.reactive === 'object') { - for(const key in this.reactive as any) { - if(typeof (this.reactive as any)[key] === 'function') { - if(key.includes('.')) { - let split = key.split('.'); - if(split[0] === 'self' && this._events) { - this._events.unsubscribeTrigger(key,(this.reactive as any)[key]) - } else if(split[0] === 'parent' && this.parent?._events) { - this.parent._events.unsubscribeTrigger(key,(this.reactive as any)[key]) - } else if(split[0] === 'children') { - let subs = (this.reactive as any)[key]; - for(const k in this.children) { - if(this.children[k]?._events) { - this.children[k]._events.unsubscribeTrigger(key,subs[k]); - } - } - } else if(this.nodes.get(split[0])?._events) { - this.nodes.get(key)._events.unsubscribeTrigger(key,(this.reactive as any)[key]); - } - } else { - if(key === 'self') { - (this.reactive as any)[key] = this.state.unsubscribeTrigger(this._unique,(this.reactive as any)[key]); - } else if (key === 'parent' && this.parent?.state) { - (this.reactive as any)[key] = this.parent.state.unsubscribeTrigger(this.parent._unique,(this.reactive as any)[key]); - } else if (key === 'children' && this.children) { - let subs = (this.reactive as any)[key]; - for(const k in this.children) { - if(this.children[k]?.state) { - this.children[k].state.unsubscribeTrigger(this.children[k]._unique,subs[k]); - } - } - } else if(this.nodes.get(key)?.state) { - this.nodes.get(key).state.unsubscribeTrigger(this.nodes.get(key)._unique,(this.reactive as any)[key]); - } - } - } - } - } - - if(this.ondelete) this.ondelete(this); - } - removeTree = (n:GraphNode|string) => { //stop and dereference nodes to garbage collect them - if(typeof n === 'string') n = this.nodes.get(n) as GraphNode; + if(n)if(typeof n === 'string') n = this.nodes.get(n); if((n as GraphNode)?.nodes) { let checked = {}; const recursivelyRemove = (node) => { if(typeof node.children === 'object' && !checked[node.tag]) { checked[node.tag] = true; for(const key in node.children) { - this.remove(node.children[key]) - - recursivelyRemove(node.children[key]); + if(node.children[key].stopNode) + node.children[key].stopNode(); + if(node.children[key].tag) { + if(this.nodes.get(node.children[key].tag)) + this.nodes.delete(node.children[key].tag); + + this.nodes.forEach((n) => { + if(n.nodes.get(node.children[key].tag)) + n.nodes.delete(node.children[key].tag); + if(n.children[key] instanceof GraphNode) + delete n.children[key]; + }); + recursivelyRemove(node.children[key]); + } } } } + if((n as GraphNode).stopNode) + (n as GraphNode).stopNode(); if((n as GraphNode).tag) { - this.remove(n); + this.nodes.delete((n as GraphNode).tag); + if(this.children[(n as GraphNode).tag]) + delete this.children[(n as GraphNode).tag]; + if(this.parent?.tag === (n as GraphNode).tag) + delete this.parent; + if(this[(n as GraphNode).tag] instanceof GraphNode) + delete this[(n as GraphNode).tag]; + this.nodes.forEach((n) => { + if((n as GraphNode)?.tag) { + if(n.nodes.get((n as GraphNode).tag)) n.nodes.delete((n as GraphNode).tag); + if(n.children[(n as GraphNode).tag] instanceof GraphNode) + delete n.children[(n as GraphNode).tag]; + } + }); recursivelyRemove(n); + if(this.graph) + this.graph.removeTree(n, checked); //remove from parent graph too + else if((n as GraphNode).ondelete) + (n as GraphNode).ondelete(n); } } } @@ -1258,7 +1170,6 @@ export class Graph { state=new EventHandler(); reactive:boolean|((_state:{[key:string]:any})=>void) _initial:any; - _events?:EventHandler; //_state: any = {}; _unique=`${Math.random()}`; //mostly-guaranteed unique id @@ -1415,50 +1326,65 @@ export class Graph { } removeTree = (n:string|GraphNode, checked?:any) => { - if(n)if(typeof n === 'string') n = this.nodes.get(n); + if(typeof n === 'string') n = this.nodes.get(n); if((n as GraphNode)?.nodes) { if(!checked) checked = {}; - const recursivelyRemove = (node) => { - if(typeof node.children === 'object' && !checked[node.tag]) { + const recursivelyRemove = (node:GraphNode) => { + if(node.children && !checked[node.tag]) { checked[node.tag] = true; - for(const key in node.children) { - if(node.children[key] instanceof GraphNode) { - this.remove(node.children[key]); - recursivelyRemove(node.children[key]); + if(Array.isArray(node.children)) { + node.children.forEach((c)=>{ + if(c.stopNode) c.stopNode(); + if(c.tag) { + if(this.nodes.get(c.tag)) this.nodes.delete(c.tag); + } + this.nodes.forEach((n) => { + if(n.nodes.get(c.tag)) n.nodes.delete(c.tag); + }); + recursivelyRemove(c); + }) + } + else if(typeof node.children === 'object') { + if(node.stopNode) node.stopNode(); + if(node.tag) { + if(this.nodes.get(node.tag)) this.nodes.delete(node.tag); } + this.nodes.forEach((n) => { + if(n.nodes.get(node.tag)) n.nodes.delete(node.tag); + }); + recursivelyRemove(node); } } } - if((n as GraphNode).stopNode) - (n as GraphNode).stopNode(); + if((n as GraphNode).stopNode) (n as GraphNode).stopNode(); if((n as GraphNode).tag) { - this.remove(n); - recursivelyRemove(n); + this.nodes.delete((n as GraphNode).tag); + this.nodes.forEach((n) => { + if(n.nodes.get((n as GraphNode).tag)) n.nodes.delete((n as GraphNode).tag); + }); + this.nNodes = this.nodes.size; + recursivelyRemove(n as GraphNode); } + if((n as GraphNode).ondelete) (n as GraphNode).ondelete(n); } + return n; } remove = (n:string|GraphNode) => { if(typeof n === 'string') n = this.nodes.get(n); - if(n instanceof GraphNode) { - if(n.stopNode) n.stopNode(); - if(n?.tag) { - if(this.nodes.get(n.tag)) { - this.nodes.delete(n.tag); - n.cleanup(); - if(this.parent?.tag === n.tag) - delete this.parent; - if(this[n.tag] instanceof GraphNode) - delete this[n.tag]; - this.nodes.forEach((nd) => { - if((nd as GraphNode)?.tag) { - if(nd.nodes.get((n as GraphNode).tag)) nd.nodes.delete((n as GraphNode).tag); - if(nd.children?.[(n as GraphNode).tag] instanceof GraphNode) - delete nd.children[(n as GraphNode).tag]; - } + if((n as GraphNode)?.nodes) { + if((n as GraphNode).stopNode) (n as GraphNode).stopNode(); + if((n as GraphNode)?.tag) { + if(this.nodes.get((n as GraphNode).tag)) + { + this.nodes.delete((n as GraphNode).tag); + //if(this.graph) this.graph.nodes.delete(node.tag); + this.nodes.forEach((n) => { + if(n.nodes.get((n as GraphNode).tag)) n.nodes.delete((n as GraphNode).tag); }); } } + if((n as GraphNode).ondelete) (n as GraphNode).ondelete(n); } return n; } diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 0ccc0781..00000000 --- a/LICENSE +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. \ No newline at end of file diff --git a/README.md b/README.md index f9f6f4c3..5e572ca2 100644 --- a/README.md +++ b/README.md @@ -1,88 +1,108 @@ + # graphscript [![Npm package version](https://img.shields.io/npm/v/graphscript)](https://npmjs.com/package/graphscript) [![Npm package monthly downloads](https://badgen.net/npm/dm/graphscript)](https://npmjs.ccom/package/graphscript) -[![License: LGPL v3](https://img.shields.io/badge/license-LGPL_v3-blue.svg)](https://www.gnu.org/licenses/LGPL-3.0) +[![License: AGPL v3](https://img.shields.io/badge/license-AGPL_v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0) +[![Discord](https://img.shields.io/badge/community-discord-7289da.svg?sanitize=true)](https://discord.gg/CDxskSh9ZB)

-
+
For happy code!

-## This API is still under construction -There's plenty of working tools available already. However, we are randomly breaking/finding old broken code and improving things constantly as we push out a model we feel can be competitive. 100% FOSS! - -Also, we are going to turn this spec into something that supports a visual editor for games and applications built right into VSCode: [Notes](https://docs.google.com/document/d/18EZ1UgztDTi5w7B8xdgAWzMF2TDoZubMnkuVbW-y4cU/edit?usp=sharing ) -
-**GraphScript** is a highly customizable, high performance library for creating complex full stack software and library architectures. It's based around graphs hierarchies, event systems, and microservices, with an intuitive composition and node/function indexing tree system for rapid development. -

- -Check out the code in [examples](./examples) for very clear, compelling implementatons that flex our rapidly evolving feature sets. Get in touch at brewster.joshua1@gmail.com if you'd like to contribute and see this evolve. - -## Core Concepts -**graphscript** is organized by the basic principles of graph theory: - -1. **Graph:** These are contained in a shared scope. -2. **Nodes:** There is a hierarchy of objects. -3. **Connections:** Within each shared scope, properties can be linked in order to react to each other. - -Beyond these basic concepts, nodes can be direct proxies for generic javascript functions, objects or class instances from any libraries, enabling an intuitive frontend/backend hierarchical organization scheme that can plug right in as an event system for existing object-oriented programs. - -### Graphs and Graph Nodes -See [Graphs and GraphNodes](./docs/Graph.md) for more information. - -The basic connectivity framework. You can design entire apps or modules as nested object (or scope) associations with the graph node properties and event system. We've demonstrated dozens of modules in the examples and throughout the source code. Just dump them in a Graph and you can quickly build event systems with a clear readable hierarchy. This isn't a rigid system as you'll see in the [examples](./examples/). Add more GraphScript properties (which we distinguish with a *__*) using **loaders** to customize node instantiation behaviors e.g. for spawning a multithreaded app from a fairly simple hierarchical definition for the desired i/o scheme. - -### Services -See [Services](./docs/Service.md) for more information. - -This forms a microservices layer on top of the graph system. It makes it easier to communicate between separate graphs that track their own properties. We've implemented all kinds of protocols (HTTP, WebRTC, WSS, Event Sources, End-to-End encryption, etc) on top of this to demonstrate the convenience of a graph-based event system for software pipelining. - -[Included Services](./docs/Service.md#included-services) contains a reference of the services included in the main graphscript packages. - -## Packages - -### `graphscript`: A GraphScript distribution for browsers (~211kb) -#### Package Features -- Graphs, Services -- Web Workers, including convenient canvas renderer multithreading and MessageChannel pipelining -- WebRTC -- WebSockets -- Event Sources -- Session system for syncing data across connections (e.g. for game servers) -- Router for creating user systems and connection routing by user assocation. -- End 2 End encryption (via `sjcl`) - -### `graphscript-node`: A GraphScript build for Node.js (~238Kb) -#### Package Features -- Graphs, Services -- Experimental pure nodejs HTTP/HTTPS server for rapid prototyping. Tie requests to graph node properties or use a simple page templating system. -- Websocket server and Websockets (via `ws`) -- Server-Sent Events (via `better-sse`) -- Child-Processes (still need to add a polyfill for web workers) -- Session system for syncing data across connections (e.g. for game servers) -- Router for creating user systems and connection routing by user assocation. -- End 2 End encryption (via `sjcl`) - - -### `graphscript-core` : (~26kb) -#### Package Features -- A minimal GraphScript distribution featuring only Graphs, the EventHandler, and the base loaders. Should work in browser and node.js - -### `graphscript-services`: A collection of additional GraphScript services and general bloat. -#### Package Features -- User database system made for use with Mongoose/MongoDB. Includes dozens of boilerplate data structures for a simple query system with optional user permissions and access token verification. -- Entity Component System - a semi out-of-date but functional ECS format. -- WebGL plotter, can handle millions of points. -- Node templates (e.g. for use with the remoteGraphRoutes) for receiving data from sensors and stuff. - -#### Extras - - `graphscript-services.gpu`: Experimental `gpu.js` plugin. ~500kb, use it with workers for best results. - - `graphscript-services.storage`: Some BrowserFS, CSV, and Google Drive utilities. Not very complete. - -### Contributing - -Want to see this API improve faster? Please contribute or create issues and offer perspective. This repo is mostly a labor of love by Josh, with Garrett swooping in to reality check the actual utility of it from time to time. We want this to API to give you open web super powers, so we can all move on to building much more interesting end products as a community, as well as get more students, engineers, and researchers working in a collaborative development environment. This is the future! Down with knowledge and tool hoarding! - -### See also: -- [`device-decoder`](https://github.com/joshbrew/device-decoder) - Complex Browser USB and Browser or Native Mobile Bluetooth driver set that is by-default multithreaded using our web worker system. You can use the worker system to create fully-threaded pipelines from the device codec without touching the main thread. +> **Note:** **graphscript** is a core library of the [Brains@Play Framework](https://github.com/brainsatplay/brainsatplay) + + + +`npm i graphscript` ~230kb dist + +For node.js +`npm i graphscript-node` ~280 dist + +Core only (only core classes plus unsafe and router services which are minimal) ~47kb dist +`npm i graphscript-core` + +For additional services (currently gpu.js service and the compiled worker dataurl as `gsworker` (or use `graphscript/dist/Worker`)) +`npm i graphscript-services` + +# READMEs: + +## * [Graphs and GraphNodes](https://github.com/brainsatplay/graphscript/blob/master/docs/Graph.md) +## * [Services](https://github.com/brainsatplay/graphscript/blob/master/docs/Service.md) + * * [Included Services](https://github.com/brainsatplay/graphscript/blob/master/docs/Service.md#included-services) + +(WIP) + + +## Acknowledgments +This library is maintained by [Garrett Flynn](https://github.com/garrettmflynn) and [Joshua Brewster](https://github.com/joshbrew), who use contract work and community contributions through [Open Collective](https://opencollective.com/brainsatplay) to support themselves. + +### Backers +[Support us with a monthly donation](https://opencollective.com/brainsatplay#backer) and help us continue our activities! + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +### Sponsors + +[Become a sponsor](https://opencollective.com/brainsatplay#sponsor) and get your logo here with a link to your site! + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/___package.json b/___package.json index 50c712c3..d2367aea 100644 --- a/___package.json +++ b/___package.json @@ -1,6 +1,6 @@ { "name": "graphscript-core", - "version": "0.3.2", + "version": "0.1.37", "description": "Comprehensive acyclic-graph based application architecture with microservices and networking.", "main": "dist/index.core.js", "module": "dist/index.core.esm.js", @@ -21,7 +21,7 @@ "esbuild" ], "author": "Joshua Brewster", - "license": "LGPL-3.0-or-later", + "license": "AGPL-3.0-or-later", "dependencies": {}, "nodemonConfig": { "env": { diff --git a/__package.json b/__package.json index f9e4ebad..94bcdc86 100644 --- a/__package.json +++ b/__package.json @@ -1,6 +1,6 @@ { "name": "graphscript-node", - "version": "0.3.2", + "version": "0.1.37", "description": "Comprehensive acyclic-graph based application architecture with microservices and networking", "main": "dist/index.node.js", "types": "dist/index.node.d.ts", @@ -20,13 +20,13 @@ "esbuild" ], "author": "Joshua Brewster", - "license": "LGPL-3.0-or-later", + "license": "AGPL-3.0-or-later", "dependencies": { - "better-sse": "~0.10.0", - "brainsatplay-math": "~0.1.0", + "better-sse": "~0.8.0", + "brainsatplay-math": "~0.0.22", "bson-objectid": "~2.0.3", "web-worker": "~1.2.0", - "ws": "~8.14.2" + "ws": "~8.8.1" }, "nodemonConfig": { "env": { diff --git a/_old/FunctionTree.ts b/_old/FunctionTree.ts deleted file mode 100644 index 31fd577f..00000000 --- a/_old/FunctionTree.ts +++ /dev/null @@ -1,209 +0,0 @@ -import { EventHandler } from "../services/EventHandler"; - - -export type FunctionNode = { - operator:Function|string, - children?:{[key:string]:Function|FunctionNode}, - [key:string]:any -}; - -export type FunctionTreeProps = {[key:string]:FunctionNode|Function} - -//micro graph tree execution without the flow logic except for automatic propagation to {children:{[key:string]:Function|MessengerNode}} -export class FunctionTree { - - routes:{[key:string]:FunctionNode|Function}; - nodes:Map=new Map(); - _returnServiceMessage?:boolean; - state?:EventHandler; - - constructor(options:{ - routes:{[key:string]:FunctionNode|Function}, - state:EventHandler, - returnMessageFormat?:boolean - }) { - this.routes = options.routes; - if(options.returnMessageFormat) this._returnServiceMessage = options.returnMessageFormat; - if(options.state) this.state = options.state; - } - - load = ( - roots:FunctionTreeProps, - transform?:(node:FunctionNode, key:string, parent:{[key:string]:FunctionNode|Function}|FunctionNode,tree:FunctionTreeProps)=>Function|FunctionNode //we could run a callback with each route (or a callback that calls a series of callbacks :P) for additional setup powers - ) => { - const setRoute = (rt:any,key:string,parent:{[key:string]:FunctionNode|Function}|FunctionNode) => { - if((typeof rt === 'string' || rt == true) && typeof parent?.children === 'object') { //we are using a tag - setTimeout(()=>{ - if(typeof rt === 'string') rt = this.nodes.get(rt); - else if(rt === true) rt = this.nodes.get(key); - (parent.children as any)[key] = rt; - if(rt) { - if(typeof rt === 'object'){ - rt = Object.assign({},rt); //copy the route - } - if(typeof parent.tag === 'string') { - rt.tag = parent.tag+'.'+key; - } - if(transform) { - let r = transform(rt,key,parent,roots); //run some callback on the route - if(r) rt = r; //can replace the route if it returns something - } - this.nodes.set(rt.tag,rt); - } - },0.001) - } else { - - if(transform) { - let r = transform(rt,key,parent,roots); //run some callback on the route - if(r) rt = r; //can replace the route if it returns something - } - - if(typeof rt === 'function') { - rt = {operator:rt}; - if(rt.name) { - if(typeof parent.tag === 'string') { - rt.tag = parent.tag+'.'+rt.name; - } - else rt.tag = rt.name; - } - } - if(typeof rt === 'object') { - if(typeof rt.__operator === 'string') { - rt.__operator = this.nodes.get(rt.operator); - if(typeof rt.__operater === 'object') rt.__operator = rt.__operator.__operator; - } if(typeof rt.__operator === 'function') { - rt.__operator.bind(rt); //bind non-arrow functions to the object's 'this' context - if(!rt.tag) { - if(typeof parent.tag === 'string') rt.tag = parent.tag+'.'+(rt.__operator as Function).name; - else rt.tag = (rt.__operator as Function).name; - - } - } else if(rt.tag) { - rt.operator = this.nodes.get(rt.tag); //get the node which could be a function or object - if(typeof rt.operator === 'object') rt.operator = rt.operator; //if object grab the operator - } - if(!rt.tag) { - if(typeof parent.tag === 'string') rt.tag = parent.tag+'.'+key; - else rt.tag = key; - } - - if(typeof rt?.__children === 'object') { - for(const key in rt.children) { - setRoute(rt.children[key],key,parent); - } - } - - if(rt.tag) this.nodes.set(rt.tag,rt); - } //MessengerNode/GraphNodeProperties - } - } - - for(const nm in roots) { - setRoute(roots[nm],nm,roots); - } - } - - //receiving a service message which tells which route to execute next via an object property, used for remote control between classes, - // which can be on separate threads and servers, we are just organizing the way we talk to each other - receive = (data:{route:string, args:any}) => { - if(data?.route) { - if(Array.isArray(data.args)) { - return this.run(data.route,...data.args); - } else return this.run(data.route,data.args); - } //that's it! The functions handle worker communication internally - } - - //running functions and children without any of the flow and state logic so pure input/output with the option to resolve service messages to receive on other messengers - run = (fn:string|Function|FunctionNode, ...args:any) => { - if(typeof fn === 'string') { - fn = this.nodes.get(fn) as any; - } - if(typeof fn === 'function') { - let r = fn(...args); - - if(r instanceof Promise) { - return new Promise((res) => { - r.then((rr) => { - if(this.state && (fn as Function).name) {this.state.setState({[(fn as Function).name]:rr})}; - if(this._returnServiceMessage) res({route:(fn as Function).name, args:rr}); - else res(rr); - }) - }); - } else { - if(this.state && (fn as Function).name) {this.state.setState({[(fn as Function).name]:r})} - if(this._returnServiceMessage) return {route:(fn as Function).name, args:r}; - else return r; - } - } else if(typeof fn === 'object') { - if(typeof fn?.__operator === 'function') { - let r = fn.__operator(...args); - if(r instanceof Promise) { - return new Promise((res) => { - r.then((rr) => { - if((fn as FunctionNode).__children) { - for(const key in (fn as FunctionNode).__children) { - this.run(((fn as FunctionNode).__children as any)[key] as Function|FunctionNode, rr); - } - } - if(this.state && (fn as FunctionNode).tag) {this.state.setState({[(fn as FunctionNode).tag]:rr})} - else if(this.state && ((fn as FunctionNode)._operator as Function).name) {this.state.setState({[((fn as FunctionNode).__operator as Function).name]:rr})} - - if(this._returnServiceMessage) res({route:(fn as Function).name, args:rr}); - else res(rr); - }); - }); - - } else { - if(fn.__children) { - for(const key in fn.__children) { - this.run(fn.__children[key] as Function|FunctionNode, r); - } - if(this.state && (fn as FunctionNode).tag) {this.state.setState({[(fn as FunctionNode).tag]:r});} - else if(this.state && ((fn as FunctionNode).__operator as Function).name) {this.state.setState({[((fn as FunctionNode).__operator as Function).name]:r});} - } - } - if(this._returnServiceMessage) return {route:fn.__operator.name, args:r}; - return r; - } - } - } - - subscribe = (node:string,callback:(res:any)=>void|string) => { - if(!this.state) return; - if(typeof callback === 'string' && this.nodes.get(callback)) { - return this.state.subscribeEvent(node, (r)=>{ this.run(callback,r); }) - } - else if(typeof callback === 'function') return this.state.subscribeEvent(node,callback); - } - - unsubscribe =(node:string,sub:number) => { - if(!this.state) return; - this.state.unsubscribeEvent(node,sub); - } - -} - - -/* - -let t = new FunctionTree({ - routes:{ - 'add':(a=3,b=2)=>{return a+b;} - 'multiply':(a=3,b=2)=>{return a*b}, - 'sequence:{ - __operator:'multiply', - __children:{ - 'add':true - } - } - }, - -}); - -t.subscribe('sequence.add',(result)=>{console.log(result);}); - -t.run('add',3,4); -t.run('sequence',3,4); //should log the subscription - - -*/ \ No newline at end of file diff --git a/dist/Graph.d.ts b/dist/Graph.d.ts new file mode 100644 index 00000000..52ffa873 --- /dev/null +++ b/dist/Graph.d.ts @@ -0,0 +1,214 @@ +export declare function parseFunctionFromText(method?: string): any; +export declare type OperatorType = (//can be async +...args: any) => any | void; +export declare type Tree = { + [key: string]: //the key becomes the node tag on the graph + GraphNode | Graph | //for graphs, pass an input object to the operator like so: e.g. to run a node in the graph: node.run({run:[arg1,arg2]}) + GraphNodeProperties | OperatorType | ((...args: any[]) => any | void) | ({ + aliases: string[]; + } & GraphNodeProperties); +}; +export declare type GraphNodeProperties = { + tag?: string; + operator?: OperatorType | ((...args: any[]) => any | void); + forward?: boolean; + backward?: boolean; + children?: { + [key: string]: string | boolean | undefined | GraphNodeProperties | GraphNode | Graph; + }; + parent?: GraphNode | Graph; + branch?: { + [label: string]: { + if: any | ((output: any) => boolean); + then: string | ((...operator_result: any[]) => any) | GraphNode; + }; + }; + tree?: Tree; + delay?: false | number; + repeat?: false | number; + recursive?: false | number; + reactive?: boolean | ((_state: { + [key: string]: any; + }) => void); + frame?: boolean; + animate?: boolean; + loop?: false | number; + animation?: OperatorType; + looper?: OperatorType; + oncreate?: (self: GraphNode | any, ...args: any[]) => void; + ondelete?: (self: GraphNode | any, ...args: any[]) => void; + DEBUGNODE?: boolean; + [key: string]: any; +}; +export declare class EventHandler { + pushToState: {}; + data: {}; + triggers: {}; + constructor(); + setState: (updateObj: { + [key: string]: any; + }) => {}; + subscribeTrigger: (key: string, onchange: (res: any) => void) => number; + unsubscribeTrigger: (key: string, sub?: number) => boolean; + subscribeTriggerOnce: (key: string, onchange: (res: any) => void) => void; +} +export declare const state: EventHandler; +/** + * Creates new instance of a GraphNode + * The methods of this class can be referenced in the operator after setup for more complex functionality + * + * ```typescript + * const graph = new GraphNode({custom: 1, operator: (input) => console.log(input, self.custom)}); + * ``` + */ +declare function addLocalState(props: any): void; +export declare class GraphNode { + nodes: Map; + _initial: { + [key: string]: any; + }; + _unique: string; + tag: string; + parent: GraphNode | Graph; + children: any; + graph: Graph; + state: EventHandler; + isLooping: boolean; + isAnimating: boolean; + looper: any; + animation: any; + forward: boolean; + backward: boolean; + reactive: boolean | ((_state: { + [key: string]: any; + }) => void); + runSync: boolean; + firstRun: boolean; + DEBUGNODE: boolean; + source: Graph | GraphNode; + tree: Tree; + [key: string]: any; + constructor(properties?: GraphNodeProperties | Graph | OperatorType | ((...args: any[]) => any | void), parent?: GraphNode | Graph | string, graph?: Graph); + addLocalState: typeof addLocalState; + operator: OperatorType; + runOp: (...args: any[]) => any; + setOperator: (operator: OperatorType) => OperatorType; + /** + * Runs the graph node and passes output to connected nodes + * + * ```typescript + * const res = await node.run(arg1, arg2, arg3); + * ``` + */ + runAsync: (...args: any[]) => Promise; + transformArgs: (args: any[], self?: GraphNode) => any[]; + isRunSync: () => boolean; + run: (...args: any[]) => any; + runParent: (n: GraphNode, ...args: any[]) => Promise; + runChildren: (n: GraphNode, ...args: any[]) => Promise; + runBranch: (n: GraphNode, output: any) => Promise; + runAnimation: (animation?: OperatorType, args?: any[]) => void; + runLoop: (loop?: OperatorType, args?: any[], timeout?: number) => void; + setParent: (parent: GraphNode) => void; + setChildren: (children: GraphNode | GraphNode[]) => void; + add: (n?: GraphNodeProperties | OperatorType | ((...args: any[]) => any | void)) => GraphNode | GraphNodeProperties; + remove: (n: string | GraphNode) => void; + append: (n: string | GraphNode, parentNode?: this) => void; + subscribe: (callback: string | GraphNode | ((res: any) => void), tag?: string) => number; + unsubscribe: (sub?: number, tag?: string) => boolean; + subscribeState: (callback: string | GraphNode | ((res: any) => void)) => number; + addChildren: (children: { + [key: string]: string | boolean | GraphNode | Graph | GraphNodeProperties; + }) => void; + callParent: (...args: any[]) => any; + callChildren: (...args: any[]) => any; + getProps: (n?: this, getInitial?: boolean) => { + tag: string; + operator: OperatorType; + graph: Graph; + children: any; + parent: GraphNode | Graph; + forward: boolean; + backward: any; + loop: any; + animate: any; + frame: any; + delay: any; + recursive: any; + repeat: any; + branch: any; + oncreate: any; + reactive: boolean | ((_state: { + [key: string]: any; + }) => void); + DEBUGNODE: boolean; + }; + setProps: (props?: GraphNodeProperties) => void; + removeTree: (n: GraphNode | string) => void; + checkNodesHaveChildMapped: (n: GraphNode | Graph, child: GraphNode, checked?: {}) => void; + convertChildrenToNodes: (n?: GraphNode) => any; + stopLooping: (n?: GraphNode) => void; + stopAnimating: (n?: GraphNode) => void; + stopNode: (n?: GraphNode) => void; + subscribeNode: (n: GraphNode | string) => number; + print: (n?: string | GraphNode, printChildren?: boolean, nodesPrinted?: any[]) => any; + reconstruct: (json: string | { + [x: string]: any; + }) => GraphNode | GraphNodeProperties; + setState: (data: { + [key: string]: any; + }) => void; + DEBUGNODES: (debugging?: boolean) => void; +} +export declare class Graph { + nNodes: number; + tag: string; + nodes: Map; + state: EventHandler; + reactive: boolean | ((_state: { + [key: string]: any; + }) => void); + _initial: any; + _unique: string; + tree: Tree; + [key: string]: any; + constructor(tree?: Tree, tag?: string, props?: { + [key: string]: any; + }); + addLocalState: typeof addLocalState; + add: (n?: GraphNode | GraphNodeProperties | OperatorType | ((...args: any[]) => any | void)) => GraphNode | GraphNodeProperties; + setTree: (tree?: Tree) => void; + get: (tag: string) => any; + set: (n: GraphNode) => Map; + run: (n: string | GraphNode, ...args: any[]) => any; + runAsync: (n: string | GraphNode, ...args: any[]) => Promise; + removeTree: (n: string | GraphNode, checked?: any) => string | GraphNode; + remove: (n: string | GraphNode) => string | GraphNode; + append: (n: GraphNode, parentNode: GraphNode) => void; + callParent: (n: GraphNode, ...args: any[]) => Promise; + callChildren: (n: GraphNode, ...args: any[]) => Promise; + subscribe: (n: string | GraphNode, callback: string | GraphNode | ((res: any) => void)) => number; + unsubscribe: (tag: string, sub?: number) => boolean; + subscribeState: (callback: string | GraphNode | ((res: any) => void)) => number; + subscribeNode: (inputNode: string | GraphNode, outputNode: GraphNode | string) => number; + stopNode: (n: string | GraphNode) => void; + print: (n?: GraphNode, printChildren?: boolean) => any; + reconstruct: (json: string | { + [x: string]: any; + }) => GraphNode | GraphNodeProperties; + create: (operator: OperatorType, parentNode: GraphNode, props: GraphNodeProperties) => GraphNode; + setState: (data: { + [key: string]: any; + }) => void; + DEBUGNODES: (debugging?: boolean) => void; +} +export declare function reconstructNode(json: string | { + [x: string]: any; +}, parentNode: any, graph: any): GraphNode; +export declare function reconstructObject(json?: string | { + [x: string]: any; +}): any; +export declare const stringifyWithCircularRefs: (obj: any, space?: any) => string; +export declare const stringifyFast: (obj: any, space?: any) => string; +export declare function createNode(operator: OperatorType, parentNode: GraphNode, props: GraphNodeProperties, graph: Graph): GraphNode; +export {}; diff --git a/dist/index.core.d.ts b/dist/index.core.d.ts index b1cd8270..af267584 100644 --- a/dist/index.core.d.ts +++ b/dist/index.core.d.ts @@ -1,3 +1,4 @@ -export * from './src/core/Graph'; -export * from './src/core/EventHandler'; -export * from './src/loaders'; +export * from './Graph'; +export * from './services/Service'; +export * from './services/unsafe/Unsafe.service'; +export * from './services/router/Router'; diff --git a/dist/index.core.esm.js b/dist/index.core.esm.js index d8e31763..ed969be7 100644 --- a/dist/index.core.esm.js +++ b/dist/index.core.esm.js @@ -1 +1,2 @@ -var x=class{data={};triggers={};ctr=0;constructor(e){typeof e=="object"&&(this.data=e)}setState=e=>{Object.assign(this.data,e);let t=Object.getOwnPropertyNames(e);for(let n of t)this.triggerEvent(n,this.data[n]);if(this.triggers[G]){let n=s=>{s(e)},i=this.triggers[G].length;for(let s=i-1;s>=0;s--)n(this.triggers[G][s].onchange)}return this.data};setValue=(e,t)=>{this.data[e]=t,this.triggerEvent(e,t)};triggerEvent=(e,t)=>{if(this.triggers[e]){let n=s=>{s.onchange(t)},i=this.triggers[e].length;for(let s=i-1;s>=0;s--)n(this.triggers[e][s])}};subscribeState=e=>this.subscribeEvent(G,e);unsubscribeState=e=>this.unsubscribeEvent(G,e);subscribeEvent=(e,t,n,i)=>{if(e){n&&i&&!this.triggers[e]&&Object.defineProperty(this.data,e,{get:()=>n[i],set:r=>{n[i]=r},enumerable:!0,configurable:!0}),this.triggers[e]||(this.triggers[e]=[]);let s=this.ctr;return this.ctr++,this.triggers[e].push({sub:s,onchange:t}),s}else return};unsubscribeEvent=(e,t)=>{let n=this.triggers[e];if(n)if(t===void 0)delete this.triggers[e],delete this.data[e];else{let i,s=n.find((r,o)=>{if(r.sub===t)return i=o,!0});return s&&n.splice(i,1),Object.keys(n).length===0&&(delete this.triggers[e],delete this.data[e]),this.onRemoved&&this.onRemoved(s),!0}};subscribeEventOnce=(e,t)=>{let n,i=s=>{t(s),this.unsubscribeEvent(e,n)};return n=this.subscribeEvent(e,i),n};getEvent=(e,t)=>{if(typeof t!="number")return this.triggers[e];for(let n in this.triggers[e])if(this.triggers[e][n].sub===t)return this.triggers[e][n]};getSnapshot=()=>{let e={};for(let t in this.data)e[t]=this.data[t]};onRemoved},G="*s";var F=new x,w=class extends Function{__bound;__call;constructor(){return super("return this.__bound.__call.apply(this.__bound, arguments)"),this.__bound=this.bind(this),this.__bound}},p=class _{__node={tag:`node${Math.floor(Math.random()*1e15)}`,unique:`${Math.floor(Math.random()*1e15)}`,state:F};__children;__parent;__operator;__listeners;__props;__args;constructor(e,t,n){if(this.__setProperties(e,t,n),typeof e=="function"||e?.__callable){let i=new w;i.__call=(...r)=>this.__operator(...r);let s=new Proxy(i,{get:(r,o,l)=>Reflect.has(this,o)?Reflect.get(this,o,l):Reflect.get(r,o,l),set:(r,o,l,f)=>Reflect.has(this,o)?Reflect.set(this,o,l,f):Reflect.set(r,o,l,f)});return Object.setPrototypeOf(s,this),s}}get __graph(){return this.__node?.graph}set __graph(e){this.__node.graph=e}__setProperties=(e,t,n)=>{if((()=>{let s=e;typeof e=="function"?P(e)?e=new e:e={__operator:e,__node:{forward:!0,tag:e.name}}:typeof e=="string"&&n?.get(e)&&(e=n.get(e)),"__node"in e||(e.__node={}),e.__node.initial||(e.__node.initial=s)})(),typeof e=="object"){let s=()=>{e.__node?.state?this.__node.state=e.__node.state:n&&(e.__node.state=n.__node.state)},r=()=>{e.__props&&(typeof e.__props=="function"&&(e.__props=new e.__props),typeof e.__props=="object"&&this.__proxyObject(e.__props))},o=()=>{e.__node.tag||(e.__operator?.name?e.__node.tag=e.__operator.name:e.__node.tag=`node${Math.floor(Math.random()*1e15)}`)},l=()=>{typeof e.__node=="string"?n?.get(e.__node.tag)?e=n.get(e.__node.tag):e.__node={}:e.__node||(e.__node={}),n&&(e.__node.graph=n),e instanceof y&&(e.__node.source=e)},f=()=>{if(!e.__parent&&t&&(e.__parent=t),t?.__node&&!(t instanceof y||e instanceof y)&&(e.__node.tag=t.__node.tag+"."+e.__node.tag),t instanceof y&&e instanceof y&&(e.__node.loaders&&Object.assign(t.__node.loaders?t.__node.loaders:{},e.__node.loaders),t.__node.mapGraphs)){e.__node.nodes.forEach(h=>{t.set(e.__node.tag+"."+h.__node.tag,h)});let u=()=>{e.__node.nodes.forEach(h=>{t.__node.nodes.delete(e.__node.tag+"."+h.__node.tag)})};this.__addOndisconnected(u)}},a=()=>{if(typeof e.default=="function"&&!e.__operator&&(e.__operator=e.default),e.__operator){if(typeof e.__operator=="string"&&n){let u=n.get(e.__operator);u&&(e.__operator=u.__operator),!e.__node.tag&&e.__operator.name&&(e.__node.tag=e.__operator.name)}typeof e.__operator=="function"&&(e.__operator=this.__setOperator(e.__operator)),e.default&&(e.default=e.__operator)}},d=()=>{e.__node=Object.assign(this.__node,e.__node);let u=Object.getOwnPropertyNames(e).filter(h=>{if(!O[h])return!0});for(let h of u)h in e&&h!=="name"&&(this[h]=e[h])},c=()=>{this.__onconnected&&(typeof this.__onconnected=="function"?this.__onconnected=this.__onconnected.bind(this):Array.isArray(this.__onconnected)&&(this.__onconnected=this.__onconnected.map(u=>u.bind(this))),typeof this.__ondisconnected=="function"?this.__ondisconnected=this.__ondisconnected.bind(this):Array.isArray(this.__ondisconnected)&&(this.__ondisconnected=this.__ondisconnected.map(u=>u.bind(this))))};s(),o(),r(),l(),f(),d(),c(),a()}};__subscribe=(e,t,n,i,s,r,o)=>{let l=(a,d=(u,h)=>h||u,c=e)=>{let u;if(r){let b=A(c,r,this.__node.graph);c=b.__callback,u=b.__args}let h=this.__node.state.subscribeEvent(a,c,this,t),g=this.__node.state.getEvent(a,h);return this.__listeners||(this.__listeners={}),this.__listeners[a]=this.__node.state.triggers[a],g&&(g.source=this.__node.tag,t&&(g.key=t),g.target=d(e,i),s&&(g.tkey=s),n&&(g.subInput=n),r&&(g.arguments=u,g.__args=r),o&&(g.__callback=o),g.node=this,g.graph=this.__node.graph),h},f=a=>{let d=this.__node.graph.get(a);if(!d&&a.includes(".")){i=a.substring(0,a.lastIndexOf("."));let c=this.__node.graph.get(a.substring(0,i));s=a.lastIndexOf(".")+1,c&&typeof c[t]=="function"&&(a=(...u)=>c[s](...u))}else d.__operator&&(a=d.__operator,s="__operator");return a};if(t){if((!this.__node.localState||!this.__node.localState[t])&&this.__addLocalState(this,t),typeof e=="string"){if(o=this.__node.tag+"."+e,s=e,i){if(this.__node.graph?.get(i)){let c=this.__node.graph?.get(i);if(typeof c[e]=="function"){let u=c[e];e=(...h)=>{u(...h)}}else{let u=e;e=g=>{c[u]=g}}}}else if(typeof this[e]=="function"){let c=this[e];e=(...u)=>{c(...u)}}else this.__node.graph?.get(e)&&(e=f(e));if(typeof e!="function")return}let a,d=n?this.__node.unique+"."+t+"input":this.__node.unique+"."+t;return typeof e=="function"&&!e?.__node?a=l(d,(c,u)=>u||c,e):e?.__node&&(a=l(d,(c,u)=>u||c.__node.unique,(...c)=>{e.__operator&&e.__operator(...c)})),a}else{if(typeof e=="string"&&(o=e,i||(i=e),this.__node.graph.get(e)&&(e=this.__node.graph.get(e)),s="__operator",typeof e!="object"))return;let a,d=n?this.__node.unique+"input":this.__node.unique;return typeof e=="function"&&!e?.__node?a=l(d,(c,u)=>u||c,e):e?.__node&&(a=l(d,(c,u)=>u||c.__node.unique,(...c)=>{e.__operator&&e.__operator(...c)})),a}};__unsubscribe=(e,t,n)=>t?this.__node.state.unsubscribeEvent(n?this.__node.unique+"."+t+"input":this.__node.unique+"."+t,e):this.__node.state.unsubscribeEvent(n?this.__node.unique+"input":this.__node.unique,e);__setOperator=e=>{e=e.bind(this),this.__args&&this.__node.graph&&(e=A(e,this.__args,this.__node.graph).__callback);let t=`${this.__node.unique}input`;if(this.__operator=(...n)=>{this.__node.state.triggers[t]&&this.__node.state.setValue(t,n);let i=e(...n);return this.__node.state.triggers[this.__node.unique]&&(typeof i?.then=="function"?i.then(s=>{s!==void 0&&this.__node.state.setValue(this.__node.unique,s)}).catch(console.error):i!==void 0&&this.__node.state.setValue(this.__node.unique,i)),i},this.__parent instanceof _&&!this.__subscribedToParent&&this.__parent.__operator){let n=this.__parent.__subscribe(this),i=()=>{this.__parent?.__unsubscribe(n),delete this.__subscribedToParent};this.__addOndisconnected(i),this.__subscribedToParent=!0}return this.__operator};__addLocalState=(e,t)=>{if(!e)return;this.__node.localState||(this.__node.localState={});let n=this.__node.localState,i=(s,r)=>{let o=this.__node.unique+"."+r,l=`${o}input`,f,a,d,c;if(typeof s[r]=="function"&&r!=="__operator")this.__props?.[r]?d=this.__props:d=n,f=()=>d[r],a=u=>{this.__props?.[r]||(u=u.bind(this)),d[r]=(...h)=>{this.__node.state.triggers[l]&&this.__node.state.setValue(l,h);let g=u(...h);return this.__node.state.triggers[o]&&(typeof g?.then=="function"?g.then(b=>{this.__node.state.triggerEvent(o,b)}).catch(console.error):this.__node.state.triggerEvent(o,g)),g}},n[r]=s[r].bind(this),c={get:f,set:a,enumerable:!0,configurable:!0};else if(r!=="__graph"){let u,h,g;this.__props?.[r]?g=this.__props:g=n,u=()=>g[r],h=b=>{g[r]=b,this.__node.state.triggers[o]&&this.__node.state.triggerEvent(o,b)},n[r]=s[r],c={get:u,set:h,enumerable:!0,configurable:!0}}if(Object.defineProperty(s,r,c),typeof this.__node.initial=="object"){let u=Object.getOwnPropertyDescriptor(this.__node.initial,r);(u===void 0||u?.configurable)&&Object.defineProperty(this.__node.initial,r,c)}};if(t)i(e,t);else for(let s in e)i(e,s)};__proxyObject=e=>{let t=q(e);for(let n of t){let i={get:()=>e[n],set:s=>{e[n]=s},enumerable:!0,configurable:!0};if(Object.defineProperty(this,n,i),typeof this.__node.initial=="object"){let s=Object.getOwnPropertyDescriptor(this.__node.initial,n);(s===void 0||s?.configurable)&&Object.defineProperty(this.__node.initial,n,i)}}};__addOnconnected(e){e=e.bind(this),Array.isArray(this.__onconnected)?this.__onconnected.push(e):typeof this.__onconnected=="function"?this.__onconnected=[e,this.__onconnected]:this.__onconnected=e}__addOndisconnected(e){e=e.bind(this),Array.isArray(this.__ondisconnected)?this.__ondisconnected.push(e):typeof this.__ondisconnected=="function"?this.__ondisconnected=[e,this.__ondisconnected]:this.__ondisconnected=e}__callConnected(e=this){if(typeof this.__onconnected=="function")this.__onconnected(this);else if(Array.isArray(this.__onconnected)){let t=n=>{n(this)};this.__onconnected.forEach(t)}}__callDisconnected(e=this){if(typeof this.__ondisconnected=="function")this.__ondisconnected(this);else if(Array.isArray(this.__ondisconnected)){let t=n=>{n(this)};this.__ondisconnected.forEach(t)}}},y=class _{__node={tag:`graph${Math.floor(Math.random()*1e15)}`,unique:`${Math.random()}`,nodes:new Map,state:F,roots:{}};constructor(e){this.init(e)}init=e=>{if(e){let t=Object.assign({},e);delete t.roots,N(this.__node,t),e.roots&&this.load(e.roots)}};load=(e,t=!1)=>{function n(r,o,l=!0,f=!0){if(f){r||(r={});for(let a in o)!a.startsWith("__")&&o[a]&&typeof o[a]=="object"?(r[a]=o[a],o[a]?.__children&&n({},o[a].__children,!1,!1)):typeof o[a]=="function"&&(r[a]=o[a]);n(r,o,!0,!1)}else if(o?.__children&&!l)o.__children?.constructor.name==="Object"?r.__children?.constructor.name==="Object"?r.__children=n(r.__children,o.__children,!0,!1):r.__children=n({},o.__children,!0,!1):r.__children=o.__children;else if(l)for(let a in o)!a.startsWith("__")&&o[a]&&typeof o[a]=="object"?(r[a]=Object.assign({},o[a]),o[a]?.__children&&(r[a].__children=n({},o[a].__children,!1,!1))):typeof o[a]=="function"&&(r[a]=o[a]);return r}this.__node.roots=n(this.__node.roots?this.__node.roots:{},e);let i=Object.assign({},e);i.__node&&delete i.__node;let s=this.recursiveSet(i,this,void 0,e,t);if(e.__node){if(!e.__node.tag)e.__node._tag=`roots${Math.floor(Math.random()*1e15)}`;else if(!this.get(e.__node.tag)){let r=new p(e,this,this);this.set(r.__node.tag,r),this.runLoaders(r,this,e,e.__node.tag),r.__listeners&&(s[r.__node.tag]=r.__listeners)}}else e.__listeners&&this.setListeners(e.__listeners);return this.setListeners(s),i};setLoaders=(e,t)=>(t?this.__node.loaders=e:Object.assign(this.__node.loaders,e),this.__node.loaders);runLoaders=(e,t,n,i)=>{for(let s in this.__node.loaders)typeof this.__node.loaders[s]=="object"?(this.__node.loaders[s].init&&this.__node.loaders[s](e,t,this,this.__node.roots,n,i),this.__node.loaders[s].connected&&e.__addOnconnected(this.__node.loaders[s].connect),this.__node.loaders[s].disconnected&&e.__addOndisconnected(this.__node.loaders[s].disconnect)):typeof this.__node.loaders[s]=="function"&&this.__node.loaders[s](e,t,this,this.__node.roots,n,i)};add=(e,t,n=!0)=>{let i={};typeof t=="string"&&(t=this.get(t));let s;if(typeof e=="function"?P(e)?e.prototype instanceof p?(e=e.prototype.constructor(e,t,this),s=!0):e=new e:e={__operator:e,__callable:!0}:typeof e=="string"&&(e=this.__node.roots[e]),!e)return;if(!s){let l=Object.getOwnPropertyNames(e),f=Object.getOwnPropertyNames(Object.getPrototypeOf(e));l.push(...f),l=l.filter(d=>!O.includes(d));let a={};for(let d of l)a[d]=e[d];e=a}if(e.__node||(e.__node={}),e.__node.initial=e,typeof e=="object"&&this.get(e.__node.tag))if(n)this.remove(e.__node.tag,!0);else return;else if(e.__node.tag&&this.get(e.__node.tag))return this.get(e.__node.tag);let r,o=N({},e,2);if(s?r=e:r=new p(e,t,this),this.set(r.__node.tag,r),this.runLoaders(r,t,e,r.__node.tag),this.__node.roots[r.__node.tag]=o,r.__children&&(r.__children=Object.assign({},r.__children),this.recursiveSet(r.__children,r,i,r.__children)),r.__listeners){i[r.__node.tag]=Object.assign({},r.__listeners);for(let l in r.__listeners){let f=r.__listeners[l];r[l]&&(delete i[r.__node.tag][l],i[r.__node.tag][r.__node.tag+"."+l]=f),typeof f=="string"&&(r.__children?.[f]?i[r.__node.tag][l]=r.__node.tag+"."+f:t instanceof p&&(t.__node.tag===f||t.__node.tag.includes(".")&&t.__node.tag.split(".").pop()===f)&&(i[r.__node.tag][l]=t.__node.tag))}}return this.setListeners(i),r.__callConnected(),r};recursiveSet=(e,t,n={},i,s=!1)=>{let r=Object.getOwnPropertyNames(i).filter(l=>!O.includes(l)),o=Object.getOwnPropertyNames(Object.getPrototypeOf(i)).filter(l=>!O.includes(l));r.push(...o);for(let l of r){if(l.includes("__"))continue;let f=i[l];if(Array.isArray(f))continue;let a;if(typeof f=="function"?P(f)?(f=new f,f instanceof p&&(f=f.prototype.constructor(f,t,this),a=!0)):f={__operator:f,__callable:!0}:typeof f=="string"?this.__node.nodes.get(f)?f=this.__node.nodes.get(f):f=this.__node.roots[f]:typeof f=="boolean"&&(this.__node.nodes.get(l)?f=this.__node.nodes.get(l):f=this.__node.roots[l]),f&&typeof f=="object"){if(!a&&!(f instanceof p)){let h=Object.getOwnPropertyNames(f).filter(m=>!O.includes(m)),g=Object.getOwnPropertyNames(Object.getPrototypeOf(f)).filter(m=>!O.includes(m));g.splice(g.indexOf("constructor"),1),h.push(...g);let b={};for(let m of h)b[m]=f[m];f=b}if(f.__node||(f.__node={}),f.__node.tag||(f.__node.tag=l),f.__node.initial||(f.__node.initial=e[l]),s&&this.get(f.__node.tag))this.remove(f.__node.tag,!0);else if(this.get(f.__node.tag)&&!(!(t instanceof _)&&t?.__node)||t?.__node&&this.get(t.__node.tag+"."+f.__node.tag))continue;let d,c=!1,u=N({},f,2);if(a||f instanceof p?d=f:(d=new p(f,t,this),c=!0),!c&&f instanceof p&&!a&&t instanceof p){let h=this.subscribe(t.__node.tag,d.__node.tag),g=b=>{this.unsubscribe(t.__node.tag,h)};d.__addOndisconnected(g)}else if(d){if(this.set(d.__node.tag,d),this.runLoaders(d,t,e[l],l),e[l]=d,this.__node.roots[d.__node.tag]=u,d.__children&&(d.__children=Object.assign({},d.__children),this.recursiveSet(d.__children,d,n,d.__children)),d.__listeners){n[d.__node.tag]=Object.assign({},d.__listeners);for(let h in d.__listeners){let g=d.__listeners[h],b=h;d[h]&&(delete n[d.__node.tag][h],b=d.__node.tag+"."+h,n[d.__node.tag][b]=g),typeof g=="string"&&(d.__children?.[g]?n[d.__node.tag][b]=d.__node.tag+"."+g:t instanceof p&&(t.__node.tag===g||t.__node.tag.includes(".")&&t.__node.tag.split(".").pop()===g)&&(n[d.__node.tag][b]=t.__node.tag))}}d.__callConnected()}}}return n};remove=(e,t=!0)=>{if(this.unsubscribe(e),typeof e=="string"&&(e=this.get(e)),e instanceof p){this.delete(e.__node.tag),delete this.__node.roots[e.__node.tag],t&&this.clearListeners(e),e.__callDisconnected();let n=i=>{for(let s in i)this.unsubscribe(i[s]),this.delete(i[s].__node.tag),delete this.__node.roots[i[s].__node.tag],this.delete(s),delete this.__node.roots[s],i[s].__node.tag=i[s].__node.tag.substring(i[s].__node.tag.lastIndexOf(".")+1),t&&this.clearListeners(i[s]),i[s].__callDisconnected(),i[s].__children&&n(i[s].__children)};e.__children&&n(e.__children)}return e?.__node.tag&&e?.__parent&&(delete e?.__parent,e.__node.tag=e.__node.tag.substring(e.__node.tag.indexOf(".")+1)),e?.__node.graph&&(e.__node.graph=void 0),e};run=(e,...t)=>{if(typeof e=="string"){let n=this.get(e);if(!n&&e.includes(".")){if(n=this.get(e.substring(0,e.lastIndexOf("."))),typeof n?.[e.substring(e.lastIndexOf(".")+1)]=="function")return n[e.substring(e.lastIndexOf(".")+1)](...t)}else if(n?.__operator)return n.__operator(...t)}if(e?.__operator)return e?.__operator(...t)};setListeners=e=>{for(let t in e){let n=this.get(t);if(typeof e[t]=="object")for(let i in e[t]){let s=this.get(i),r;if(typeof e[t][i]!="object")e[t][i]={__callback:e[t][i]};else if(!e[t][i].__callback)for(let o in e[t][i]){typeof e[t][i][o]!="object"&&(e[t][i][o]={__callback:e[t][i][o]},n.__operator&&(e[t][i][o].__callback===!0||typeof e[t][i][o].__callback>"u")&&(e[t][i][o].__callback=n.__operator));let l=this.get(o);if(l)r=this.subscribe(l,e[t][i][o].__callback,e[t][i][o].__args,void 0,e[t][i][o].subInput,t);else{let f=i.substring(0,i.lastIndexOf("."));if(l=this.get(f),l){let a=i.substring(i.lastIndexOf(".")+1);r=this.subscribe(l,e[t][i][o].__callback,e[t][i][o].__args,a,e[t][i][o].subInput,t)}}}if("__callback"in e[t][i])if(n&&((e[t][i].__callback===!0||typeof e[t][i].__callback>"u")&&(e[t][i].__callback=n.__operator),typeof e[t][i].__callback=="function"&&(e[t][i].__callback=e[t][i].__callback.bind(n))),s)r=this.subscribe(s,e[t][i].__callback,e[t][i].__args,void 0,e[t][i].subInput,t);else{let o=i.substring(0,i.lastIndexOf("."));s=this.get(o),s&&(r=this.subscribe(s,e[t][i].__callback,e[t][i].__args,i.substring(i.lastIndexOf(".")+1),e[t][i].subInput,t))}}}};clearListeners=(e,t)=>{if(typeof e=="string"&&(e=this.get(e)),e?.__listeners)for(let n in e.__listeners){if(t&&n!==t||typeof e.__listeners[n]?.sub!="number")continue;let i=this.get(n);if(i)if(typeof!e.__listeners[n]?.__callback=="number")for(let s in e.__listeners[n])e.__listeners[n][s]?.sub&&(this.unsubscribe(i,e.__listeners[n][s].sub,void 0,e.__listeners[n][s].subInput),e.__listeners[n][s].sub=void 0);else typeof e.__listeners[n]?.sub=="number"&&(this.unsubscribe(i,e.__listeners[n].sub,void 0,e.__listeners[n].subInput),e.__listeners[n].sub=void 0);else if(i=this.get(n.substring(0,n.lastIndexOf("."))),i)if(typeof e.__listeners[n]=="object"&&!e.__listeners[n]?.__callback)for(let s in e.__listeners[n])typeof e.__listeners[n][s]?.sub=="number"&&(this.unsubscribe(i,e.__listeners[n][s].sub,n.substring(n.lastIndexOf(".")+1),e.__listeners[n][s].subInput),e.__listeners[n][s].sub=void 0);else typeof e.__listeners[n]?.sub=="number"&&(this.unsubscribe(i,e.__listeners[n].sub,n.substring(n.lastIndexOf(".")+1),e.__listeners[n].subInput),e.__listeners[n].sub=void 0)}};get=e=>this.__node.nodes.get(e);getByUnique=e=>Array.from(this.__node.nodes.values()).find(t=>{if(t.__node.unique===e)return!0});set=(e,t)=>this.__node.nodes.set(e,t);delete=e=>this.__node.nodes.delete(e);list=()=>Array.from(this.__node.nodes.keys());getListener=(e,t,n)=>{let i=this.get(e);if(i){let s=i.__node.unique;return t&&(s+="."+t),this.__node.state.getEvent(s,n)}};getProps=(e,t)=>{if(typeof e=="string"&&(e=this.get(e)),e instanceof p){let n;if(t)n=Object.assign({},this.__node.roots[e.__node.tag]);else{n=Object.assign({},e);for(let i in n)i.includes("__")&&delete n[i]}}};subscribe=(e,t,n,i,s,r,o)=>{let l=e;typeof e=="string"&&(l=this.get(e),!l&&e.includes(".")&&(l=this.get(e.substring(0,e.lastIndexOf("."))),i=e.substring(e.lastIndexOf(".")+1))),r instanceof p&&(r=r.__node.tag);let f;if(typeof t=="string"){f=t;let d=c=>{if(this.get(c)?.__operator){let u=this.get(c);r=c,c=function(...h){return u.__operator(...h)}}else if(c.includes(".")){r=c.substring(0,c.lastIndexOf("."));let u=this.get(r),h=c.substring(c.lastIndexOf(".")+1);o=h,typeof u[h]=="function"?u[h]instanceof p?c=u[h]:c=function(...g){return u[h](...g)}:c=function(g){return u[h]=g,u[h]}}return c};if(r){let c=this.get(r);typeof c?.[t]=="function"?(o=t,t=function(...u){return c[i](...u)}):c?.[i]?(o=i,c[i]instanceof p?t=c[i]:t=function(u){return c[i]=u,c[i]}):t=d(t)}else t=d(t)}let a;if(l instanceof p){let d=()=>{a=l.__subscribe(t,i,s,r,o,n,f);let c=()=>{a!==void 0&&l.__unsubscribe(a,i,s),a=void 0};l.__addOndisconnected(()=>{c(),l.__addOnconnected(()=>{a===void 0&&l.__node.graph.__node.tag===this.__node.tag&&d()})}),typeof t=="string"&&this.get(t)&&(t=this.get(t)),t instanceof p&&t.__addOndisconnected(()=>{c()})};d()}else if(typeof e=="string"){let d=this.get(e);if(d){if(t instanceof p&&t.__operator){let c=()=>{a=d.__subscribe(t.__operator,i,s,r,o,n,f);let u=()=>{a!==void 0&&d.__unsubscribe(a,i,s)};d.__addOndisconnected(()=>{u(),d.__addOnconnected(()=>{a===void 0&&d.__node.graph.__node.tag===this.__node.tag&&c()})}),t.__addOndisconnected(u)};c()}else if(typeof t=="function"||typeof t=="string"){let c=()=>{a=d.__subscribe(t,i,s,r,o,n,f);let u=()=>{a!==void 0&&d.__unsubscribe(a,i,s),a=void 0};d.__addOndisconnected(()=>{u(),d.__addOnconnected(()=>{a===void 0&&d.__node.graph.__node.tag===this.__node.tag&&c()})}),typeof t=="string"&&this.get(t)&&this.get(t).__addOndisconnected(u)};c()}}else typeof t=="string"&&(t=this.__node.nodes.get(t).__operator),typeof t=="function"&&!t?.__node&&(a=this.__node.state.subscribeEvent(e,t))}return a};unsubscribe=(e,t,n,i)=>e instanceof p?e.__unsubscribe(t,n,i):this.get(e)?.__unsubscribe(t,n,i);setState=e=>{this.__node.state.setState(e)}};function N(_,e,t=1/0,n=0){for(let i in e)e[i]?.constructor.name==="Object"&&n{if(e.get(_)?.__operator){let t=e.get(_);return(...n)=>{t.__operator(...n)}}else if(_.includes(".")){let t=_.split("."),n=t.pop(),i=t.join("."),s=e.get(i);return typeof e.get(i)?.[n]=="function"?(...r)=>s[n](...r):()=>s[n]}else if(e.get(_)){let t=e.get(_);return()=>t}else{let t=_;return()=>t}},A=(_,e,t)=>{let n=[],i=(r,o)=>{if(r==="__output"||r==="__input"||r==="__callback")n[o]={__callback:l=>l,__args:void 0,idx:o};else if(typeof r=="string")n[o]={__callback:j(r,t),__args:void 0,idx:o};else if(typeof r=="function"){let l=r;n[o]={__callback:(...f)=>l(...f),__args:void 0,idx:o}}else if(typeof r=="object"&&(r.__input||r.__callback)){let l=function(f){let a=f.__input?f.__input:f.__callback;if(typeof f.__input=="string"&&(a={__callback:j(f.__input,t),__args:void 0,idx:o}),f.__args){let d=A(a,f.__args,t);a={__callback:d.__callback,__args:d.__args,idx:o}}else a={__callback:a,__args:void 0,idx:o};if(f.__output){let d=f.__output;if(typeof f.__output=="string"?d={__callback:j(d,t),__args:void 0,idx:o}:typeof r.__output=="object"&&(d=l(d)),typeof d?.__callback=="function"){let c=a.__callback,u=d.__callback;a={__callback:(...h)=>u(c(...h)),__args:d.__args,idx:o}}}return a};n[o]=l(r)}else{let l=r;n[o]={__callback:()=>l,__args:void 0,idx:o}}};e.forEach(i),typeof _=="string"&&(_={__callback:j(_,t),__args:void 0});let s=typeof _=="function"?_:_.__callback;return _=function(...r){let o=f=>f.__callback(...r);return s(...n.map(o))},{__callback:_,__args:n}},O=Object.getOwnPropertyNames(Object.getPrototypeOf({}));var S=(_,e,t)=>{_.__node.backward&&e instanceof p&&t.setListeners({[e.__node.tag]:{[_.__node.tag]:e}})},I=(_,e,t)=>{if(_.__operator){let n=Math.random();if(_.__node.loops||(_.__node.loops={}),typeof _.__node.delay=="number"){let i=_.__operator;_.__setOperator((...s)=>new Promise((r,o)=>{_.__node.loops[n]=setTimeout(async()=>{r(await i(...s))},_.__node.delay)}))}else if(_.__node.frame===!0){let i=_.__operator;_.__setOperator((...s)=>new Promise((r,o)=>{_.__node.loops[n]=requestAnimationFrame(async()=>{r(await i(...s))})}))}if(typeof _.__node.repeat=="number"||typeof _.__node.recursive=="number"){let i=_.__operator;_.__setOperator(async(...s)=>{let r=_.__node.repeat?_.__node.repeat:_.__node.recursive,o,l=async(f,...a)=>{for(;f>0;){if(_.__node.delay||_.__node.frame){i(...a).then(async d=>{_.__node.recursive?await l(f,d):await l(f,...a)});break}else o=await i(...s);f--}};return await l(r,...s),o})}if(_.__node.loop&&typeof _.__node.loop=="number"){let i=_.__operator,s=_.__node.loop;_.__setOperator((...o)=>{if("looping"in _.__node||(_.__node.looping=!0),_.__node.looping){let l=performance.now();i(...o),_.__node.loops[n]=setTimeout(()=>{let a=performance.now()-l-_.__node.loop;a>0?s=_.__node.loop-a:s=_.__node.loop,s<=0&&(s=_.__node.loop),_.__operator(...o)},s)}}),_.__node.looping&&_.__operator();let r=o=>{o.__node.looping&&(o.__node.looping=!1),o.__node.loops[n]&&(clearTimeout(o.__node.loops[n]),cancelAnimationFrame(o.__node.loops[n]))};_.__addOndisconnected(r)}}},v=(_,e,t)=>{if(_.__node.animate===!0||_.__animation){let n=_.__operator;_.__setOperator((...s)=>{"animating"in _.__node||(_.__node.animating=!0),_.__node.animating&&(typeof _.__animation=="function"?_.__animation(...s):n(...s),_.__node.animationFrame=requestAnimationFrame(()=>{_.__operator(...s)}))}),(_.__node.animating||(!("animating"in _.__node)||_.__node.animating)&&_.__animation)&&setTimeout(()=>{_.__node.animationFrame=requestAnimationFrame(_.__operator)},10);let i=s=>{s.__node.animating&&(s.__node.animating=!1),s.__node.animationFrame&&cancelAnimationFrame(s.__node.animationFrame)};_.__addOndisconnected(i)}},M=(_,e,t)=>{if(typeof _.__branch=="object"&&_.__operator&&!_.__branchApplied){let n=_.__operator;_.__branchApplied=!0,_.__operator=(...i)=>{let s=n(...i);for(let r in _.__branch){let o=()=>{typeof _.__branch[r].then=="function"?_.__branch[r].then(s):_.__branch[r].then instanceof p&&_.__branch[r].then.__operator?_.__branch[r].then.__operator(s):s=_.__branch[r].then};typeof _.__branch[r].if=="function"?_.__branch[r].if(s)==!0&&o():_.__branch[r].if===s&&o()}return s}}if(_.__listeners){for(let n in _.__listeners)if(typeof _.__listeners[n]=="object"&&_.__listeners[n].branch&&!_.__listeners[n].branchApplied){let i=_.__listeners[n].callback;_.__listeners[n].branchApplied=!0,_.__listeners.callback=s=>{let r=()=>{typeof _.__listeners[n].branch.then=="function"?s=_.__listeners[n].branch.then(s):_.__listeners[n].branch.then instanceof p&&_.__listeners[n].branch.then.__operator?s=_.__listeners[n].branch.then.__operator(s):s=_.__listeners[n].branch.then};return typeof _.__listeners[n].branch.if=="function"?_.__listeners[n].branch.if(s)&&r():_.__listeners[n].branch.if===s&&r(),i(s)}}}},R=(_,e,t)=>{if(_.__listeners)for(let n in _.__listeners)typeof _.__listeners[n]=="object"&&_.__listeners[n].oncreate&&_.__listeners[n].callback(_.__listeners[n].oncreate)},T=(_,e,t)=>{if(_.__listeners)for(let n in _.__listeners)typeof _.__listeners[n]=="object"&&typeof _.__listeners[n].binding=="object"&&(_.__listeners.callback=_.__listeners.callback.bind(_.__listeners[n].binding))},$=(_,e,t)=>{if(_.__listeners){for(let n in _.__listeners)if(typeof _.__listeners[n]=="object"&&typeof _.__listeners[n].transform=="function"&&!_.__listeners[n].transformApplied){let i=_.__listeners[n].callback;_.__listeners[n].transformApplied=!0,_.__listeners.callback=s=>(s=_.__listeners[n].transform(s),i(s))}}},C=(_,e,t)=>{_.post&&!_.__operator?_.__setOperator(_.post):!_.__operator&&typeof _.get=="function"&&_.__setOperator(_.get),!_.get&&_.__operator,_.aliases&&_.aliases.forEach(n=>{t.set(n,_);let i=s=>{t.__node.nodes.delete(n)};_.__addOndisconnected(i)}),typeof t.__node.roots?.[_.__node.tag]=="object"&&_.get&&(t.__node.roots[_.__node.tag].get=_.get)},J={backprop:S,loop:I,animate:v,branching:M,triggerListenerOncreate:R,bindListener:T,transformListenerResult:$,substitute__operator:C};export{w as Callable,x as EventHandler,y as Graph,p as GraphNode,v as animate,S as backprop,T as bindListener,M as branching,q as getAllProperties,j as getCallbackFromString,W as instanceObject,L as isFunction,P as isNativeClass,J as loaders,I as loop,F as state,C as substitute__operator,$ as transformListenerResult,R as triggerListenerOncreate,A as wrapArgs}; +function C(c=""){let t=n=>n.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i,"$2$3$4"),r=(n=>{let a=n.indexOf("=>")+1;return a<=0&&(a=n.indexOf("){")),a<=0&&(a=n.indexOf(") {")),n.slice(0,n.indexOf("{",a)+1)})(c),i=t(c),s;if(r.includes("function")){let n=r.split("(")[1].split(")")[0];s=new Function(n,i)}else if(r.substring(0,6)===i.substring(0,6)){let n=r.split("(")[1].split(")")[0];s=new Function(n,i.substring(i.indexOf("{")+1,i.length-1))}else try{s=(0,eval)(r+i+"}")}catch{}return s}var O=class{constructor(){this.pushToState={};this.data={};this.triggers={};this.setState=t=>{Object.assign(this.data,t);for(let e of Object.getOwnPropertyNames(t))this.triggers[e]&&this.triggers[e].forEach(r=>r.onchange(this.data[e]));return this.data};this.subscribeTrigger=(t,e)=>{if(t){this.triggers[t]||(this.triggers[t]=[]);let r=this.triggers[t].length;return this.triggers[t].push({idx:r,onchange:e}),this.triggers[t].length-1}else return};this.unsubscribeTrigger=(t,e)=>{let r=this.triggers[t];if(r)if(!e)delete this.triggers[t];else{let i;return r.find((n,a)=>{if(n.idx===e)return i=a,!0})&&r.splice(i,1),!0}};this.subscribeTriggerOnce=(t,e)=>{let r,i=s=>{e(s),this.unsubscribeTrigger(t,r)};r=this.subscribeTrigger(t,i)}}},R=new O;function S(c){this._state||(this._state={});for(let t in c)t==="_state"||t==="graph"||(this._state[t]=c[t],t in this?this[t]=c[t]:Object.defineProperty(this,t,{get:()=>{this._state[t]},set:e=>{this._state[t]=e,this.state.triggers[this._unique]&&this.setState({[this._unique]:this._state})},enumerable:!0,configurable:!0}))}var y=class{constructor(t={},e,r){this.nodes=new Map;this._initial={};this._unique=`${Math.random()}`;this.state=R;this.isLooping=!1;this.isAnimating=!1;this.looper=void 0;this.animation=void 0;this.forward=!0;this.backward=!1;this.reactive=!1;this.runSync=!1;this.firstRun=!0;this.DEBUGNODE=!1;this.addLocalState=S;this.operator=(...t)=>t;this.runOp=(...t)=>{this.DEBUGNODE&&console.time(this.tag);let e=this.operator(...t);return e instanceof Promise?e.then(r=>(r!==void 0&&this.setState({[this.tag]:r}),this.DEBUGNODE&&(console.timeEnd(this.tag),e!==void 0&&console.log(`${this.tag} result:`,e)),r)):(e!==void 0&&this.setState({[this.tag]:e}),this.DEBUGNODE&&(console.timeEnd(this.tag),e!==void 0&&console.log(`${this.tag} result:`,e))),e};this.setOperator=t=>(typeof t!="function"||(this.operator=t.bind(this)),t);this.runAsync=(...t)=>new Promise((e,r)=>{e(this.run(...t))});this.transformArgs=(t=[])=>t;this.isRunSync=()=>!(this.children&&this.forward||this.parent&&this.backward||this.repeat||this.delay||this.frame||this.recursive||this.branch);this.run=(...t)=>{if(typeof this.transformArgs=="function"&&(t=this.transformArgs(t,this)),!(this.firstRun&&(this.firstRun=!1,this.runSync=this.isRunSync(),this.animate&&!this.isAnimating&&this.runAnimation(this.animation,t),this.loop&&typeof this.loop=="number"&&!this.isLooping&&this.runLoop(this.looper,t),this.loop||this.animate)))return this.runSync?this.runOp(...t):new Promise(async e=>{if(this){let r=(s,n=0,...a)=>new Promise(async o=>{n++;let f=await s.runOp(...a);if(s.repeat){for(;n{o(await r(s,n,...a))},s.delay);break}else if(s.frame&&window?.requestAnimationFrame){requestAnimationFrame(async()=>{o(await r(s,n,...a))});break}else f=await s.runOp(...a);n++}if(n===s.repeat){o(f);return}}else if(s.recursive){for(;n{o(await r(s,n,...f))},s.delay);break}else if(s.frame&&window?.requestAnimationFrame){requestAnimationFrame(async()=>{o(await r(s,n,...f))});break}else f=await s.runOp(...f);n++}if(n===s.recursive){o(f);return}}else{o(f);return}}),i=async()=>{let s=await r(this,void 0,...t);return s!==void 0&&(this.backward&&this.parent instanceof y&&(Array.isArray(s)?await this.runParent(this,...s):await this.runParent(this,s)),this.children&&this.forward&&(Array.isArray(s)?await this.runChildren(this,...s):await this.runChildren(this,s)),this.branch&&this.runBranch(this,s)),s};this.delay?setTimeout(async()=>{e(await i())},this.delay):this.frame&&window?.requestAnimationFrame?requestAnimationFrame(async()=>{e(await i())}):e(await i())}else e(void 0)})};this.runParent=async(t,...e)=>{t.backward&&t.parent&&(typeof t.parent=="string"&&(t.graph&&t.graph?.get(t.parent)?(t.parent=t.graph,t.parent&&this.nodes.set(t.parent.tag,t.parent)):t.parent=this.nodes.get(t.parent)),t.parent instanceof y&&await t.parent.run(...e))};this.runChildren=async(t,...e)=>{if(typeof t.children=="object")for(let r in t.children)typeof t.children[r]=="string"?(t.graph&&t.graph?.get(t.children[r])&&(t.children[r]=t.graph.get(t.children[r]),t.nodes.get(t.children[r].tag)||t.nodes.set(t.children[r].tag,t.children[r])),!t.children[r]&&t.nodes.get(t.children[r])&&(t.children[r]=t.nodes.get(t.children[r]))):(typeof t.children[r]>"u"||t.children[r]===!0)&&(t.graph&&t.graph?.get(r)&&(t.children[r]=t.graph.get(r),t.nodes.get(t.children[r].tag)||t.nodes.set(t.children[r].tag,t.children[r])),!t.children[r]&&t.nodes.get(r)&&(t.children[r]=t.nodes.get(r))),t.children[r]?.runOp&&await t.children[r].run(...e)};this.runBranch=async(t,e)=>{if(t.branch){let r=Object.keys(t.branch);await Promise.all(r.map(async i=>{typeof t.branch[i].if=="object"&&(t.branch[i].if=A(t.branch[i].if));let s=!1;return typeof t.branch[i].if=="function"?s=t.branch[i].if(e):typeof e=="object"?A(e)===t.branch[i].if&&(s=!0):e===t.branch[i].if&&(s=!0),s&&(t.branch[i].then.run?Array.isArray(e)?await t.branch[i].then.run(...e):await t.branch[i].then.run(...e):typeof t.branch[i].then=="function"?Array.isArray(e)?await t.branch[i].then(...e):await t.branch[i].then(e):typeof t.branch[i].then=="string"&&(t.graph?t.branch[i].then=t.graph.nodes.get(t.branch[i].then):t.branch[i].then=t.nodes.get(t.branch[i].then),t.branch[i].then.run&&(Array.isArray(e)?await t.branch[i].then.run(...e):await t.branch[i].then.run(...e)))),s}))}};this.runAnimation=(t=this.animation,e=[])=>{if(this.animation=t,t||(this.animation=this.operator),this.animate&&!this.isAnimating&&"requestAnimationFrame"in window){this.isAnimating=!0;let r=async()=>{if(this.isAnimating){this.DEBUGNODE&&console.time(this.tag);let i=this.animation.call(this,...e);i instanceof Promise&&(i=await i),this.DEBUGNODE&&(console.timeEnd(this.tag),i!==void 0&&console.log(`${this.tag} result:`,i)),i!==void 0&&(this.tag&&this.setState({[this.tag]:i}),this.backward&&this.parent?.run&&(Array.isArray(i)?await this.runParent(this,...i):await this.runParent(this,i)),this.children&&this.forward&&(Array.isArray(i)?await this.runChildren(this,...i):await this.runChildren(this,i)),this.branch&&this.runBranch(this,i),this.setState({[this.tag]:i})),requestAnimationFrame(r)}};requestAnimationFrame(r)}};this.runLoop=(t=this.looper,e=[],r=this.loop)=>{if(this.looper=t,t||(this.looper=this.operator),typeof r=="number"&&!this.isLooping){this.isLooping=!0;let i=async()=>{if(this.isLooping){this.DEBUGNODE&&console.time(this.tag);let s=this.looper.call(this,...e);s instanceof Promise&&(s=await s),this.DEBUGNODE&&(console.timeEnd(this.tag),s!==void 0&&console.log(`${this.tag} result:`,s)),s!==void 0&&(this.tag&&this.setState({[this.tag]:s}),this.backward&&this.parent?.run&&(Array.isArray(s)?await this.runParent(this,...s):await this.runParent(this,s)),this.children&&this.forward&&(Array.isArray(s)?await this.runChildren(this,...s):await this.runChildren(this,s)),this.branch&&this.runBranch(this,s),this.setState({[this.tag]:s})),setTimeout(async()=>{await i()},r)}};i()}};this.setParent=t=>{this.parent=t,this.backward&&(this.runSync=!1)};this.setChildren=t=>{this.children=t,this.forward&&(this.runSync=!1)};this.add=(t={})=>(typeof t=="function"&&(t={operator:t}),t?.node instanceof y&&(t=t.node),t instanceof y||(t=new y(t.node??t,this,this.graph)),this.nodes.set(t.tag,t),this.graph&&(this.graph.nodes.set(t.tag,t),this.graph.nNodes=this.graph.nodes.size),t);this.remove=t=>{typeof t=="string"&&(t=this.nodes.get(t)),t?.tag&&(this.nodes.delete(t.tag),this.children[t.tag]&&delete this.children[t.tag],this.graph&&(this.graph.nodes.delete(t.tag),this.graph.nNodes=this.graph.nodes.size),this.nodes.forEach(e=>{e.nodes.get(e.tag)&&(e.nodes.delete(e.tag),e.children[e.tag]&&delete e.children[e.tag],e.parent?.tag===e.tag&&delete e.parent)}),t.ondelete&&t.ondelete(t)),typeof this._state=="object"&&this.state.unsubscribeTrigger(this._unique)};this.append=(t,e=this)=>{typeof t=="string"&&(t=this.nodes.get(t)),t?.nodes&&(e.addChildren(t),t.forward&&(t.runSync=!1))};this.subscribe=(t,e=this.tag)=>{if(typeof t=="string"&&(this.graph?t=this.graph.get(t):t=this.nodes.get(t)),typeof t=="function")return this.state.subscribeTrigger(e,t);if(t)return this.state.subscribeTrigger(e,r=>{t.run(r)})};this.unsubscribe=(t,e=this.tag)=>this.state.unsubscribeTrigger(e,t);this.subscribeState=t=>{if(this.reactive){if(typeof t=="string"&&(this.graph?t=this.graph.get(t):t=this.nodes.get(t)),typeof t=="function")return this.state.subscribeTrigger(this._unique,t);if(t)return this.state.subscribeTrigger(this._unique,e=>{t.run(e)})}else return};this.addChildren=t=>{this.children||(this.children={}),typeof t=="object"&&Object.assign(this.children,t),this.convertChildrenToNodes(),this.forward&&(this.runSync=!1)};this.callParent=(...t)=>{if(typeof this.parent=="string"&&(this.graph&&this.graph?.get(this.parent)?(this.parent=this.graph,this.parent&&this.nodes.set(this.parent.tag,this.parent)):this.parent=this.nodes.get(this.parent)),typeof this.parent?.operator=="function")return this.parent.runOp(...t)};this.callChildren=(...t)=>{let e;if(typeof this.children=="object")for(let r in this.children)this.children[r]?.runOp&&this.children[r].runOp(...t);return e};this.getProps=(t=this,e=!0)=>{let r={tag:t.tag,operator:t.operator,graph:t.graph,children:t.children,parent:t.parent,forward:t.forward,backward:t.bacward,loop:t.loop,animate:t.animate,frame:t.frame,delay:t.delay,recursive:t.recursive,repeat:t.repeat,branch:t.branch,oncreate:t.oncreate,reactive:t.reactive,DEBUGNODE:t.DEBUGNODE};if(e)return{tag:t.tag,operator:t.operator,graph:t.graph,children:t.children,parent:t.parent,forward:t.forward,backward:t.bacward,loop:t.loop,animate:t.animate,frame:t.frame,delay:t.delay,recursive:t.recursive,repeat:t.repeat,branch:t.branch,oncreate:t.oncreate,reactive:t.reactive,DEBUGNODE:t.DEBUGNODE,...this._initial};{let i={};for(let s in this._initial)i[s]=this[s];return Object.assign(r,i)}};this.setProps=(t={})=>{let e=Object.assign({},t);e.children&&(this.addChildren(t.children),delete e.children),e.operator&&(this.setOperator(t.operator),delete e.operator),Object.assign(e,t),this.runSync=this.isRunSync()};this.removeTree=t=>{if(t&&typeof t=="string"&&(t=this.nodes.get(t)),t?.nodes){let e={},r=i=>{if(typeof i.children=="object"&&!e[i.tag]){e[i.tag]=!0;for(let s in i.children)i.children[s].stopNode&&i.children[s].stopNode(),i.children[s].tag&&(this.nodes.get(i.children[s].tag)&&this.nodes.delete(i.children[s].tag),this.nodes.forEach(n=>{n.nodes.get(i.children[s].tag)&&n.nodes.delete(i.children[s].tag),n.children[s]instanceof y&&delete n.children[s]}),r(i.children[s]))}};t.stopNode&&t.stopNode(),t.tag&&(this.nodes.delete(t.tag),this.children[t.tag]&&delete this.children[t.tag],this.parent?.tag===t.tag&&delete this.parent,this[t.tag]instanceof y&&delete this[t.tag],this.nodes.forEach(i=>{i?.tag&&(i.nodes.get(i.tag)&&i.nodes.delete(i.tag),i.children[i.tag]instanceof y&&delete i.children[i.tag])}),r(t),this.graph?this.graph.removeTree(t,e):t.ondelete&&t.ondelete(t))}};this.checkNodesHaveChildMapped=(t,e,r={})=>{let i=t.tag;i||(i=t.name),r[i]||(r[i]=!0,t.children&&e.tag in t.children&&t.children[e.tag]instanceof y&&(t.nodes.get(e.tag)||t.nodes.set(e.tag,e),t.children[e.tag]=e,t.firstRun||(t.firstRun=!0)),t.parent instanceof y&&(t.nodes.get(e.tag)&&t.parent.nodes.set(e.tag,e),t.parent.children?this.checkNodesHaveChildMapped(t.parent,e,r):t.nodes&&t.nodes.forEach(s=>{r[s.tag]||this.checkNodesHaveChildMapped(s,e,r)})),t.graph&&t.parent&&t.parent.name!==t.graph.name&&t.graph.nodes.forEach(s=>{r[s.tag]||this.checkNodesHaveChildMapped(s,e,r)}))};this.convertChildrenToNodes=(t=this)=>{if(t?.children){for(let e in t.children)if(!(t.children[e]instanceof y))if(typeof t.children[e]=="object")t.children[e].tag||(t.children[e].tag=e),t.nodes.get(t.children[e].tag)||(t.children[e]=new y(t.children[e],t,t.graph),this.checkNodesHaveChildMapped(t,t.children[e]));else{if(typeof t.children[e]>"u"||t.children[e]==!0)t.children[e]=t.graph.get(e),t.children[e]||(t.children[e]=t.nodes.get(e));else if(typeof t.children[e]=="string"){let r=t.children[e];t.children[e]=t.graph.get(r),t.children[e]||(t.children[e]=t.nodes.get(e))}t.children[e]instanceof y&&(t.nodes.set(t.children[e].tag,t.children[e]),this.checkNodesHaveChildMapped(t,t.children[e]),t.children[e].tag in t||(t[t.children[e].tag]=t.children[e]))}}return t.children};this.stopLooping=(t=this)=>{t.isLooping=!1};this.stopAnimating=(t=this)=>{t.isAnimating=!1};this.stopNode=(t=this)=>{t.stopAnimating(t),t.stopLooping(t)};this.subscribeNode=t=>{if(typeof t=="string"&&(t=this.nodes.get(t)),t.tag&&this.nodes.set(t.tag,t),t)return this.state.subscribeTrigger(this.tag,e=>{Array.isArray(e)?t.run(...e):t.run(e)})};this.print=(t=this,e=!0,r=[])=>{let i=new y;if(typeof t=="string"&&(t=this.nodes.get(t)),t instanceof y){r.push(t.tag);let s={tag:t.tag,operator:t.operator.toString()};if(t.parent&&(s.parent=t.parent.tag),typeof t.children=="object")for(let n in t.children)return typeof t.children[n]=="string"?t.children[n]:r.includes(t.children[n].tag)?t.children[n].tag:e?t.children[n].print(t.children[n],e,r):t.children[n].tag;for(let n in t)n==="parent"||n==="children"||typeof i[n]>"u"&&(typeof t[n]=="function"?s[n]=t[n].toString():typeof t[n]=="object"?s[n]=JSON.stringifyWithCircularRefs(t[n]):s[n]=t[n]);return JSON.stringify(s)}};this.reconstruct=t=>{let e=j(t);if(e)return this.add(e)};this.setState=t=>{this.state.setState(t)};this.DEBUGNODES=(t=!0)=>{this.DEBUGNODE=t,this.nodes.forEach(e=>{t?e.DEBUGNODE=!0:e.DEBUGNODE=!1})};if(typeof t=="function"&&(t={operator:t}),typeof t=="object"){if(t instanceof y&&t._initial&&Object.assign(t,t._initial),t instanceof v){let s=t;t={source:s,operator:n=>{if(typeof n=="object"){let a={};for(let o in n)typeof s[o]=="function"?Array.isArray(n[o])?a[o]=s[o](...n[o]):a[o]=s[o](n[o]):(s[o]=n[o],a[o]=s[o]);return a}return s}},s.operator&&(t.operator=s.operator),s.children&&(t.children=s.children),s.forward&&(t.forward=s.forward),s.backward&&(t.backward=s.backward),s.repeat&&(t.repeat=s.repeat),s.recursive&&(t.recursive=s.recursive),s.loop&&(t.loop=s.loop),s.animate&&(t.animate=s.animate),s.looper&&(t.looper=s.looper),s.animation&&(t.animation=s.animation),s.delay&&(t.delay=s.delay),s.oncreate&&(t.oncreate=s.oncreate),s.node&&s.node._initial&&Object.assign(t,s.node._initial),s._initial&&Object.assign(t,s._initial),s.tag&&(t.tag=s.tag),this.nodes=s.nodes,s.node=this,r&&s.nodes.forEach(n=>{r.nodes.get(n.tag)||(r.nodes.set(n.tag,n),r.nNodes++)})}if(typeof e=="string"&&(r?e=r.nodes.get(e):e=void 0),t.tag&&(r||e)){let s;if(r?.nodes&&(s=r.nodes.get(t.tag)),!s&&e?.nodes&&(s=e.nodes.get(t.tag)),s){this.reactive&&this.addLocalState(s),this.source||(this.source=s);let n=s.getProps();delete n.graph,delete n.parent;for(let a in n)t[a]=n[a]}}t?.operator&&(t.operator=this.setOperator(t.operator)),!t.tag&&r?t.tag=`node${r.nNodes}`:t.tag||(t.tag=`node${Math.floor(Math.random()*1e10)}`);let i=Object.getOwnPropertyNames(this);for(let s in t)i.includes(s)||(this._initial[s]=t[s]);if(t.children&&(this._initial.children=Object.assign({},t.children)),Object.assign(this,t),this.tag||(r?this.tag=`node${r.nNodes}`:this.tag=`node${Math.floor(Math.random()*1e10)}`),r&&(this.graph=r,r.nodes.get(this.tag)&&(this.tag=`${this.tag}${r.nNodes+1}`),r.nodes.set(this.tag,this),r.nNodes++,this.state=r.state),this.reactive&&(S(t),typeof this.reactive=="function"&&this.state.subscribeTrigger(this._unique,this.reactive)),typeof e=="object"&&(this.parent=e,(e instanceof y||e instanceof v)&&e.nodes.set(this.tag,this)),typeof t.tree=="object")for(let s in t.tree){typeof t.tree[s]=="object"&&(!t.tree[s]).tag&&(t.tree[s].tag=s);let n=new y(t.tree[s],this,r);this.nodes.set(n.tag,n)}this.children&&this.convertChildrenToNodes(this),(this.parent instanceof y||this.parent instanceof v)&&this.checkNodesHaveChildMapped(this.parent,this),typeof this.oncreate=="function"&&this.oncreate(this),this.firstRun||(this.firstRun=!0),this.animation&&!this.animate&&(this.animate=!0)}else return t}},v=class{constructor(t,e,r){this.nNodes=0;this.nodes=new Map;this.state=new O;this._unique=`${Math.random()}`;this.tree={};this.addLocalState=S;this.add=(t={})=>{t?.node instanceof y&&(t=t.node);let e=t;return t instanceof y?(this.nNodes=this.nodes.size,t.tag&&(this.tree[t.tag]=e,this.nodes.set(t.tag,t))):t=new y(e?.node??e,this,this),t};this.setTree=(t=this.tree)=>{if(!!t){for(let e in t){let r=this.nodes.get(e);if(r){if(typeof t[e]=="function")r.setOperator(t[e]);else if(typeof t[e]=="object")if(t[e]instanceof y)this.add(t[e]);else if(t[e]instanceof v){let i=t[e],s={};i.operator&&(s.operator=i.operator),i.children&&(s.children=i.children),i.forward&&(s.forward=i.forward),i.backward&&(s.backward=i.backward),i.repeat&&(s.repeat=i.repeat),i.recursive&&(s.recursive=i.recursive),i.loop&&(s.loop=i.loop),i.animate&&(s.animate=i.animate),i.looper&&(s.looper=i.looper),i.animation&&(s.animation=i.animation),i.delay&&(s.delay=i.delay),i.tag&&(s.tag=i.tag),i.oncreate&&(s.oncreate=i.oncreate),i.node?._initial&&Object.assign(s,i.node._initial),s.nodes=i.nodes,s.source=i,r.setProps(s)}else r.setProps(t[e])}else if(typeof t[e]=="function")this.add({tag:e,operator:t[e]});else if(typeof t[e]=="object"&&!Array.isArray(t[e])){t[e].tag||(t[e].tag=e);let i=this.add(t[e]);t[e].aliases&&t[e].aliases.forEach(s=>{this.nodes.set(s,i)})}else this.add({tag:e,operator:(...i)=>t[e]})}this.nodes.forEach(e=>{if(typeof e.children=="object")for(let r in e.children)typeof e.children[r]=="string"?this.nodes.get(e.children[r])&&(e.children[r]=this.nodes.get(e.children[r])):(e.children[r]===!0||typeof e.children[r]>"u")&&this.nodes.get(r)&&(e.children[r]=this.nodes.get(r)),e.children[r]instanceof y&&e.checkNodesHaveChildMapped(e,e.children[r]);typeof e.parent=="string"&&this.nodes.get(e.parent)&&(e.parent=this.nodes.get(e.parent),e.nodes.set(e.parent.tag,e.parent))})}};this.get=t=>this.nodes.get(t);this.set=t=>this.nodes.set(t.tag,t);this.run=(t,...e)=>{if(typeof t=="string"&&(t=this.nodes.get(t)),t?.run)return t.run(...e)};this.runAsync=(t,...e)=>(typeof t=="string"&&(t=this.nodes.get(t)),t?.run?new Promise((r,i)=>{r(t.run(...e))}):new Promise((r,i)=>{r(void 0)}));this.removeTree=(t,e)=>{if(typeof t=="string"&&(t=this.nodes.get(t)),t?.nodes){e||(e={});let r=i=>{i.children&&!e[i.tag]&&(e[i.tag]=!0,Array.isArray(i.children)?i.children.forEach(s=>{s.stopNode&&s.stopNode(),s.tag&&this.nodes.get(s.tag)&&this.nodes.delete(s.tag),this.nodes.forEach(n=>{n.nodes.get(s.tag)&&n.nodes.delete(s.tag)}),r(s)}):typeof i.children=="object"&&(i.stopNode&&i.stopNode(),i.tag&&this.nodes.get(i.tag)&&this.nodes.delete(i.tag),this.nodes.forEach(s=>{s.nodes.get(i.tag)&&s.nodes.delete(i.tag)}),r(i)))};t.stopNode&&t.stopNode(),t.tag&&(this.nodes.delete(t.tag),this.nodes.forEach(i=>{i.nodes.get(i.tag)&&i.nodes.delete(i.tag)}),this.nNodes=this.nodes.size,r(t)),t.ondelete&&t.ondelete(t)}return t};this.remove=t=>(typeof t=="string"&&(t=this.nodes.get(t)),t?.nodes&&(t.stopNode&&t.stopNode(),t?.tag&&this.nodes.get(t.tag)&&(this.nodes.delete(t.tag),this.nodes.forEach(e=>{e.nodes.get(e.tag)&&e.nodes.delete(e.tag)})),t.ondelete&&t.ondelete(t)),t);this.append=(t,e)=>{e.addChildren(t)};this.callParent=async(t,...e)=>{if(t?.parent)return await t.callParent(...e)};this.callChildren=async(t,...e)=>{if(t?.children)return await t.callChildren(...e)};this.subscribe=(t,e)=>{if(!!e){if(t?.subscribe&&typeof e=="function")return t.subscribe(e);if(e instanceof y||typeof e=="string")return this.subscribeNode(t,e);if(typeof t=="string")return this.state.subscribeTrigger(t,e)}};this.unsubscribe=(t,e)=>this.state.unsubscribeTrigger(t,e);this.subscribeState=t=>{if(this.reactive){if(typeof t=="string"&&(this.graph?t=this.graph.get(t):t=this.nodes.get(t)),typeof t=="function")return this.state.subscribeTrigger(this._unique,t);if(t)return this.state.subscribeTrigger(this._unique,e=>{t.run(e)})}else return};this.subscribeNode=(t,e)=>{let r;if(t?.tag?r=t.tag:typeof t=="string"&&(r=t),typeof e=="string"&&(e=this.nodes.get(e)),t&&e)return this.state.subscribeTrigger(r,s=>{Array.isArray(s)?e.run(...s):e.run(s)})};this.stopNode=t=>{typeof t=="string"&&(t=this.nodes.get(t)),t?.stopNode&&t.stopNode()};this.print=(t,e=!0)=>{if(t?.print)return t.print(t,e);{let r="{";return this.nodes.forEach(i=>{r+=` +"${i.tag}:${i.print(i,e)}"`}),r}};this.reconstruct=t=>{let e=j(t);if(e)return this.add(e)};this.create=(t,e,r)=>P(t,e,r,this);this.setState=t=>{this.state.setState(t)};this.DEBUGNODES=(t=!0)=>{this.nodes.forEach(e=>{t?e.DEBUGNODE=!0:e.DEBUGNODE=!1})};this.tag=e||`graph${Math.floor(Math.random()*1e11)}`,r&&(r.reactive?this.addLocalState(r):Object.assign(this,r),this._initial=r),(t||Object.keys(this.tree).length>0)&&this.setTree(t)}};function E(c,t,e){let r=j(c);if(r)return new y(r,t,e)}function j(c="{}"){try{let t=typeof c=="string"?JSON.parse(c):c,e=r=>{for(let i in r)if(typeof r[i]=="string"){let s=C(r[i]);typeof s=="function"&&(r[i]=s)}else typeof r[i]=="object"&&e(r[i]);return r};return e(t)}catch(t){console.error(t);return}}var w=function(){let c=new Map,t=[],e=["this"];function r(){c.clear(),t.length=0,e.length=1}function i(n,a){var o=t.length-1,f=t[o];if(typeof f=="object")if(f[n]===a||o===0)e.push(n),t.push(a.pushed);else for(;o-->=0;){if(f=t[o],typeof f=="object"&&f[n]===a){o+=2,t.length=o,e.length=o,--o,t[o]=a,e[o]=n;break}o--}}function s(n,a){if(a!=null&&typeof a=="object"){n&&i(n,a);let o=c.get(a);if(o)return"[Circular Reference]"+o;c.set(a,e.join("."))}return a}return function(a,o){try{return t.push(a),JSON.stringify(a,s,o)}finally{r()}}}();JSON.stringifyWithCircularRefs===void 0&&(JSON.stringifyWithCircularRefs=w);var A=function(){let c=new Map,t=[],e=["this"];function r(){c.clear(),t.length=0,e.length=1}function i(n,a){var o=t.length-1;if(t[o]){var f=t[o];if(typeof f=="object")if(f[n]===a||o===0)e.push(n),t.push(a.pushed);else for(;o-->=0;){if(f=t[o],typeof f=="object"&&f[n]===a){o+=2,t.length=o,e.length=o,--o,t[o]=a,e[o]=n;break}o++}}}function s(n,a){let o;if(a!=null)if(typeof a=="object"){let f=a.constructor.name;n&&f==="Object"&&i(n,a);let b=c.get(a);if(b)return"[Circular Reference]"+b;if(c.set(a,e.join(".")),f==="Array")a.length>20?o=a.slice(a.length-20):o=a;else if(f.includes("Set"))o=Array.from(a);else if(f!=="Object"&&f!=="Number"&&f!=="String"&&f!=="Boolean")o="instanceof_"+f;else if(f==="Object"){let h={};for(let l in a)if(a[l]==null)h[l]=a[l];else if(Array.isArray(a[l]))a[l].length>20?h[l]=a[l].slice(a[l].length-20):h[l]=a[l];else if(a[l].constructor.name==="Object"){h[l]={};for(let g in a[l])if(Array.isArray(a[l][g]))a[l][g].length>20?h[l][g]=a[l][g].slice(a[l][g].length-20):h[l][g]=a[l][g];else if(a[l][g]!=null){let u=a[l][g].constructor.name;u.includes("Set")?h[l][g]=Array.from(a[l][g]):u!=="Number"&&u!=="String"&&u!=="Boolean"?h[l][g]="instanceof_"+u:h[l][g]=a[l][g]}else h[l][g]=a[l][g]}else{let g=a[l].constructor.name;g.includes("Set")?h[l]=Array.from(a[l]):g!=="Number"&&g!=="String"&&g!=="Boolean"?h[l]="instanceof_"+g:h[l]=a[l]}o=h}else o=a}else o=a;return o}return function(a,o){t.push(a);let f=JSON.stringify(a,s,o);return r(),f}}();JSON.stringifyFast===void 0&&(JSON.stringifyFast=A);function P(c,t,e,r){return typeof e=="object"?(e.operator=c,new y(e,t,r)):new y({operator:c},t,r)}var G=class extends v{constructor(e={}){super(void 0,e.name?e.name:`service${Math.floor(Math.random()*1e14)}`,e.props);this.routes={};this.loadDefaultRoutes=!1;this.keepState=!0;this.firstLoad=!0;this.customRoutes={};this.customChildren={};this.init=e=>{e?e=Object.assign({},e):e={},e.customRoutes?Object.assign(e.customRoutes,this.customRoutes):e.customRoutes=this.customRoutes,e.customChildren?Object.assign(e.customChildren,this.customChildren):e.customChildren=this.customChildren,Array.isArray(e.routes)?e.routes.forEach(r=>{this.load(r,e.includeClassName,e.routeFormat,e.customRoutes,e.customChildren,e.sharedState)}):(e.routes||(Object.keys(this.routes).length>0||this.loadDefaultRoutes)&&this.firstLoad)&&this.load(e.routes,e.includeClassName,e.routeFormat,e.customRoutes,e.customChildren,e.sharedState)};this.load=(e,r=!0,i=".",s,n,a=!0)=>{if(!e&&!this.loadDefaultRoutes&&(Object.keys(this.routes).length>0||this.firstLoad))return;this.firstLoad&&(this.firstLoad=!1),s?s=Object.assign(this.customRoutes,s):s=this.customRoutes;let o,f={};if(e){if(!(e instanceof v)&&e?.name&&!e.setTree)if(e.module){let h=e;e={},Object.getOwnPropertyNames(e.module).forEach(l=>{r?e[h.name+i+l]=e.module[l]:e[l]=e.module[l]})}else typeof e=="function"&&(o=new e({loadDefaultRoutes:this.loadDefaultRoutes}),o.load(),a&&(o.state=this.state),e=o.routes,o.customRoutes&&!this.customRoutes?this.customRoutes=o.customRoutes:o.customRoutes&&this.customRoutes&&Object.assign(this.customRoutes,o.customRoutes),o.customChildren&&!this.customChildren?this.customChildren=o.customChildren:o.customChildren&&this.customChildren&&Object.assign(this.customChildren,o.customChildren));else if(e instanceof v||e.source instanceof v||e.setTree){if(o=e,e={},a&&(o.state=this.state),r){let h=o.name;h||(h=o.tag,o.name=h),h||(h=`graph${Math.floor(Math.random()*1e15)}`,o.name=h,o.tag=h)}o.customRoutes&&!this.customRoutes?this.customRoutes=o.customRoutes:o.customRoutes&&this.customRoutes&&Object.assign(this.customRoutes,o.customRoutes),o.customChildren&&!this.customChildren?this.customChildren=o.customChildren:o.customChildren&&this.customChildren&&Object.assign(this.customChildren,o.customChildren),o.nodes.forEach(h=>{e[h.tag]=h;let l={},g=(u,p)=>{if((!l[u.tag]||p&&r&&!l[p?.tag+i+u.tag])&&(p?l[p.tag+i+u.tag]=!0:l[u.tag]=!0,u instanceof v||u.source instanceof v||u.setTree)){if(a&&(u.state=this.state),r){let d=u.name;d||(d=u.tag,u.name=d),d||(d=`graph${Math.floor(Math.random()*1e15)}`,u.name=d,u.tag=d)}u.nodes.forEach(d=>{r&&!e[u.tag+i+d.tag]?e[u.tag+i+d.tag]=d:e[d.tag]||(e[d.tag]=d),g(d,u)})}};g(h)})}else if(typeof e=="object"){let h=e.constructor.name;if(h==="Object"&&(h=Object.prototype.toString.call(e),h&&(h=h.split(" ")[1]),h&&(h=h.split("]")[0])),h&&h!=="Object"){let l=e;e={},Object.getOwnPropertyNames(l).forEach(g=>{r?e[h+i+g]=l[g]:e[g]=l[g]})}}if((o instanceof v||o?.setTree)&&o.name&&r){e=Object.assign({},e);for(let h in e){let l=e[h];delete e[h],e[o.name+i+h]=l}}}if(this.loadDefaultRoutes){let h=Object.assign({},this.defaultRoutes);e?(Object.assign(h,this.routes),e=Object.assign(h,e)):e=Object.assign(h,this.routes),this.loadDefaultRoutes=!1}e||(e=this.routes);let b=0;for(let h in e){b++;let l=(g,u)=>{if(typeof g=="object"&&(g.tag||(g.tag=u),typeof g?.children=="object")){e:for(let p in g.children)if(b++,typeof g.children[p]=="object"){let d=g.children[p];if(d.tag&&f[d.tag])continue;if(n){for(let N in n)if(d=n[N](d,p,g,e,f),!d)continue e}d.id&&!d.tag&&(d.tag=d.id);let m;if(d.tag)if(f[d.tag]){let N=`${d.tag}${b}`;f[N]=d,d.tag=N,l(f[N],p),m=N}else f[d.tag]=d,l(f[d.tag],p),m=d.tag;else if(f[p]){let N=`${p}${b}`;f[N]=d,d.tag=N,l(f[N],p),m=N}else f[p]=d,l(f[p],p),m=p;o?.name&&r?(f[o.name+i+m]=d,delete f[m]):f[m]=d}}};f[h]=e[h],l(e[h],h)}e:for(let h in f)if(typeof f[h]=="object"){let l=f[h];if(typeof l=="object"){if(s){for(let g in s)if(l=s[g](l,h,f),!l)continue e}l.get&&l.get,l.post,l.delete,l.put,l.head,l.patch,l.options,l.connect,l.trace,l.post&&!l.operator?f[h].operator=l.post:!l.operator&&typeof l.get=="function"&&(f[h].operator=l.get)}}for(let h in e)typeof e[h]=="object"?this.routes[h]?typeof this.routes[h]=="object"?Object.assign(this.routes[h],e[h]):this.routes[h]=e[h]:this.routes[h]=e[h]:this.routes[h]?typeof this.routes[h]=="object"?Object.assign(this.routes[h],e[h]):this.routes[h]=e[h]:this.routes[h]=e[h];if(o)for(let h in this.routes)(this.routes[h]instanceof y||this.routes[h].constructor.name.includes("GraphNode"))&&(this.nodes.set(h,this.routes[h]),this.nNodes=this.nodes.size);else this.setTree(this.routes);for(let h in this.routes)this.routes[h]?.aliases&&this.routes[h].aliases.forEach(g=>{o?.name&&r?e[o.name+i+g]=this.routes[h]:e[g]=this.routes[h]});return this.routes};this.unload=(e=this.routes)=>{if(!e)return;let r;!(e instanceof G)&&typeof e=="function"?(r=new G,e=r.routes):e instanceof G&&(e=e.routes);for(let i in e)delete this.routes[i],this.nodes.get(i)&&this.remove(i);return this.routes};this.handleMethod=(e,r,i)=>{let s=r.toLowerCase(),n=this.nodes.get(e);return n||(n=this.routes[e],n||(n=this.tree[e])),n?.[s]?n[s]instanceof Function?n[s](i):(i&&(n[s]=i),n[s]):this.handleServiceMessage({route:e,args:i,method:r})};this.transmit=(...e)=>typeof e[0]=="object"?e[0].method?this.handleMethod(e[0].route,e[0].method,e[0].args):e[0].route?this.handleServiceMessage(e[0]):e[0].node?this.handleGraphNodeCall(e[0].node,e[0].args):(this.keepState&&(e[0].route&&this.setState({[e[0].route]:e[0].args}),e[0].node&&this.setState({[e[0].node]:e[0].args})),e):e;this.receive=(...e)=>{if(e[0]&&typeof e[0]=="string"){let r=e[0].substring(0,8);(r.includes("{")||r.includes("["))&&(r.includes("\\")&&(e[0]=e[0].replace(/\\/g,"")),e[0][0]==='"'&&(e[0]=e[0].substring(1,e[0].length-1)),e[0]=JSON.parse(e[0]))}return typeof e[0]=="object"?e[0].method?this.handleMethod(e[0].route,e[0].method,e[0].args):e[0].route?this.handleServiceMessage(e[0]):e[0].node?this.handleGraphNodeCall(e[0].node,e[0].args):(this.keepState&&(e[0].route&&this.setState({[e[0].route]:e[0].args}),e[0].node&&this.setState({[e[0].node]:e[0].args})),e):e};this.pipe=(e,r,i,s,n)=>{if(e instanceof y)return n?e.subscribe(a=>{let o=n(a);o!==void 0?this.transmit({route:r,args:o,method:s}):this.transmit({route:r,args:a,method:s},i)}):this.subscribe(e,a=>{this.transmit({route:r,args:a,method:s},i)});if(typeof e=="string")return this.subscribe(e,a=>{this.transmit({route:r,args:a,method:s},i)})};this.pipeOnce=(e,r,i,s,n)=>{if(e instanceof y)return n?e.state.subscribeTriggerOnce(e.tag,a=>{let o=n(a);o!==void 0?this.transmit({route:r,args:o,method:s}):this.transmit({route:r,args:a,method:s},i)}):this.state.subscribeTriggerOnce(e.tag,a=>{this.transmit({route:r,args:a,method:s},i)});if(typeof e=="string")return this.state.subscribeTriggerOnce(e,a=>{this.transmit({route:r,args:a,method:s},i)})};this.terminate=(...e)=>{this.nodes.forEach(r=>{r.stopNode()})};this.recursivelyAssign=(e,r)=>{for(let i in r)typeof r[i]=="object"&&!Array.isArray(r[i])?typeof e[i]=="object"&&!Array.isArray(e[i])?this.recursivelyAssign(e[i],r[i]):e[i]=this.recursivelyAssign({},r[i]):e[i]=r[i];return e};this.defaultRoutes={"/":{get:()=>this.print(),aliases:[""]},ping:()=>(console.log("ping"),"pong"),echo:(...e)=>(this.transmit(...e),e),assign:e=>typeof e=="object"?(Object.assign(this,e),!0):!1,recursivelyAssign:e=>typeof e=="object"?(this.recursivelyAssign(this,e),!0):!1,log:{post:(...e)=>{console.log("Log: ",...e)},aliases:["info"]},error:e=>{let r=new Error(e);return console.error(e),r},state:e=>e?this.state.data[e]:this.state.data,printState:e=>e?w(this.state.data[e]):w(this.state.data),spliceTypedArray:this.spliceTypedArray,transmit:this.transmit,receive:this.receive,load:this.load,unload:this.unload,pipe:this.pipe,terminate:this.terminate,run:this.run,subscribe:this.subscribe,subscribeNode:this.subscribeNode,unsubscribe:this.unsubscribe,stopNode:this.stopNode,get:this.get,add:this.add,remove:this.remove,setTree:this.setTree,setState:this.setState,print:this.print,reconstruct:this.reconstruct,handleMethod:this.handleMethod,handleServiceMessage:this.handleServiceMessage,handleGraphNodeCall:this.handleGraphNodeCall};e.name?this.name=e.name:e.name=this.tag,"loadDefaultRoutes"in e&&(this.loadDefaultRoutes=e.loadDefaultRoutes,this.routes=Object.assign(this.defaultRoutes,this.routes)),(e||Object.keys(this.routes).length>0)&&this.init(e)}handleServiceMessage(e){let r;return typeof e=="object"&&(e.route?r=e.route:e.node&&(r=e.node)),r?Array.isArray(e.args)?this.run(r,...e.args):this.run(r,e.args):e}handleGraphNodeCall(e,r){if(!e)return r;if(r?.args)this.handleServiceMessage(r);else return Array.isArray(r)?this.run(e,...r):this.run(e,r)}isTypedArray(e){return ArrayBuffer.isView(e)&&Object.prototype.toString.call(e)!=="[object DataView]"}spliceTypedArray(e,r,i){let s=e.subarray(0,r),n;i&&(n=e.subarray(i+1));let a;return(s.length>0||n?.length>0)&&(a=new e.constructor(s.length+n.length)),s.length>0&&a.set(s),n&&n.length>0&&a.set(n,s.length),a}};var B={setRoute:function(c,t){if(typeof c=="string"&&(c=C(c)),typeof c=="function"){if(t||(t=c.name),this.graph.get(t))this.graph.get(t).setOperator(c.bind(this.graph.get(t)));else{let e=this.graph.add({tag:t,operator:c});this.graph instanceof G&&this.graph.load({[t]:e})}return!0}return!1},setNode:function(c,t){return typeof c=="string"&&(c=C(c)),typeof c=="function"?(t||(t=c.name),this.graph.get(t)?this.graph.get(t).setOperator(c):this.graph.add({tag:t,operator:c}),!0):!1},setMethod:function(c,t,e){return typeof t=="string"&&(t=C(t)),typeof t=="function"?(e||(e=t.name),this.graph.get(c)?this.graph.get(c)[e]=t:this.graph.add({tag:e,[e]:t}),!0):!1},assignRoute:function(c,t){this.graph.get(c)&&typeof t=="object"&&Object.assign(this.graph.get(c),t)},transferClass:(c,t)=>{if(typeof c=="object"){let e=c.toString();return{route:"receiveClass",args:[e,t]}}return!1},receiveClass:function(c,t){if(typeof c=="string"&&c.indexOf("class")===0){let e=(0,eval)("("+c+")"),r=t;return r||(r=e.name),this.graph[r]=e,!0}return!1},setGlobal:(c,t)=>(globalThis[c]=t,!0),assignGlobalObject:(c,t)=>globalThis[c]?(typeof t=="object"&&Object.assign(globalThis[c],t),!0):!1,setValue:function(c,t){return this.graph[c]=t,!0},assignObject:function(c,t){return this.graph[c]?(typeof t=="object"&&Object.assign(this.graph[c],t),!0):!1},setGlobalFunction:(c,t)=>(typeof c=="string"&&(c=C(c)),typeof c=="function"?(t||(t=c.name),globalThis[t]=c,!0):!1),assignFunctionToGlobalObject:function(c,t,e){return globalThis[c]?(typeof t=="string"&&(t=C(t)),typeof t=="function"?(e||(e=t.name),this.graph[c][e]=t,!0):!1):!1},setFunction:function(c,t){return typeof c=="string"&&(c=C(c)),typeof c=="function"?(t||(t=c.name),this.graph[t]=c,!0):!1},assignFunctionToObject:function(c,t,e){return this.graph[c]?(typeof t=="string"&&(t=C(t)),typeof t=="function"?(e||(e=t.name),this.graph[c][e]=t,!0):!1):!1}};var T=class extends G{constructor(e){super(e);this.name="router";this.connections={};this.sources={};this.services={};this.serviceConnections={};this.users={};this.addUser=async(e,r,i,s)=>{e._id||(e._id=`user${Math.floor(Math.random()*1e15)}`);let n=Object.assign({},e);if(r){for(let u in r)typeof r[u]=="object"&&(r[u].connection._id||await new Promise((p,d)=>{let m=performance.now(),N=()=>{r[u].connection._id?p(!0):performance.now()-m>3e3?(delete r[u],d(!1)):setTimeout(()=>{N()},100)};N()}).catch(p=>{console.error("Connections timed out:",p)}));for(let u in r)r[u]=this.addConnection(r[u],n._id)}if(i)for(let u in i)this.openConnection(i[u].service,i[u],n._id,i[u].args);let a=(u,...p)=>{let d=this.getConnection(n._id,"send");if(d?.send)return d.send(u,...p)},o=(u,p,...d)=>{let m=this.getConnection(n._id,"request");if(m?.request)return m.request(u,p,...d)},f=(u,p,d,...m)=>{let N=this.getConnection(n._id,"post");if(N?.post)return N.post(u,p,d,...m)},b=(u,p,d,...m)=>{let N=this.getConnection(n._id,"run");if(N?.run)return N.run(u,p,d,...m)},h=(u,p,...d)=>{let m=this.getConnection(n._id,"subscribe");if(m?.subscribe)return m.subscribe(u,p,...d)},l=(u,p,...d)=>{let m=this.getConnection(n._id,"unsubscribe");if(m?.unsubscribe)return m.unsubscribe(u,p,...d)},g=()=>this.removeUser(n);if(n.send=a,n.request=o,n.post=f,n.run=b,n.subscribe=h,n.unsubscribe=l,n.terminate=g,this.users[n._id]=n,r&&!s){let u={},p=!1;Object.keys(r).map((d,m)=>{r[d]?._id&&(u[`${m}`]=r[d]?._id,p=!0)}),p&&n.send({route:"addUser",args:[{_id:n._id},u,void 0,!0]})}return n};this.getConnection=(e,r)=>{if(this.sources[e])if(this.order)for(let i=0;i{if(this.sources[e]){if(!i&&!r)return this.sources[e];let s={};for(let n in this.sources[e])if(typeof this.sources[e][n]=="object"){if(this.sources[e][n]._id){let a=!0;r&&!this.sources[e][n][r]&&(a=!1);for(let o in i)if(typeof this.sources[e][n][o]=="object"&&typeof i[o]=="object"){for(let f in i[o])if(i[o][f]!==this.sources[e][n][o][f]){a=!1;break}}else if(this.sources[e][n][o]!==i[o])a=!1;else{a=!1;break}a&&this.getConnection(this.sources[e][n],r)&&(s[this.sources[e][n]._id]=this.sources[e][n])}else for(let a in this.sources[e][n])if(typeof this.sources[e][n][a]=="object"){let o=!0;r&&!this.sources[e][n][a][r]&&(o=!1);for(let f in i)if(typeof this.sources[e][n][a][f]=="object"&&typeof i[f]=="object"){for(let b in i[f])if(i[f][b]!==this.sources[e][n][a][f][b]){o=!1;break}}else if(this.sources[e][n][a][f]!==i[f])o=!1;else{o=!1;break}o&&(s[this.sources[e][n][a]._id]=this.sources[e][n][a])}}}};this.addConnection=(e,r)=>{let i={};if(typeof e=="string"){if(this.connections[e])e=this.connections[e];else for(let s in this.serviceConnections)for(let n in this.serviceConnections[s])if(this.serviceConnections[s][n][e]){e={connection:this.serviceConnections[s][n][e]},e.service=s,i.connectionType=s,i.connectionsKey=n;break}typeof e=="string"&&this.nodes.get(e)&&(e={connection:this.nodes.get(e)})}if(!(!e||typeof e=="string")){if(r&&(i.source=r),e.connection instanceof y){i.connection=e.connection;let s=i.connection;if(i.send=async n=>n.method?Array.isArray(n.args)?s[n.method]?.(...n.args):s[n.method]?.(n.args):Array.isArray(n.args)?s.run(...n.args):s.run(n.args),i.request=async(n,a)=>a?Array.isArray(n.args)?s[a]?.(...n.args):s[a]?.(n.args):Array.isArray(n.args)?s.run(...n.args):s.run(n.args),i.post=async(n,a,o)=>{if(n&&s.get(n)){let f=s.get(n);return o?Array.isArray(a)?f[o]?.(...a):f[o]?.(a):Array.isArray(a)?f.run(...a):f.run(a)}else return o?Array.isArray(a)?s[o]?.(...a):s[o]?.(a):Array.isArray(a)?s.run(...a):s.run(a)},i.run=i.post,i.subscribe=async(n,a)=>s.subscribe(a,n),i.unsubscribe=async(n,a)=>s.unsubscribe(a,n),i.terminate=()=>(s.graph.remove(s),!0),i.onclose=e.onclose,i.onclose){let n;s.ondelete&&(n=s.ondelete),s.ondelete=a=>{i.onclose&&i.onclose(i,a),n&&n(a)}}}else if(e.connection instanceof v){e.connection.nodes.get("open")&&(i.service=e.connection);let s=i.connection;i.send=async n=>{Array.isArray(n.args)?s.run(n.route,...n.args):s.run(n.route,n.args)},i.request=async(n,a)=>{if(!!n.route)return a?Array.isArray(n.args)?s.nodes.get(n.route)[a]?.(...n.args):s.nodes.get(n.route)[a]?.(n.args):Array.isArray(n.args)?s.run(n.route,...n.args):s.run(n.route,n.args)},i.post=async(n,a,o)=>{if(n&&s.get(n)){let f=s.get(n);return o?Array.isArray(a)?f[o]?.(...a):f[o]?.(a):Array.isArray(a)?f.run(...a):f.run(a)}},i.run=i.post,i.subscribe=async(n,a)=>s.subscribe(n,a),i.unsubscribe=async(n,a)=>s.unsubscribe(n,a),i.terminate=n=>(s.remove(n),!0)}else if(!(e._id&&this.connections[e._id])){let s=e.connection;if(typeof s=="string"){if(this.connections[s])s=this.connections[s];else if(e.service){if(typeof e.service=="string"&&(e.service=this.services[e.service]),typeof e.service=="object"&&e.service.connections){for(let n in e.service.connections)if(e.service.connections[n][s]){s=e.service.connections[n][s],i.connectionType=n,i.connectionsKey=s;break}}}else for(let n in this.serviceConnections)for(let a in this.serviceConnections[n])if(this.serviceConnections[n][a][s]){s=this.serviceConnections[n][a][s],e.service=n,i.connectionType=n,i.connectionsKey=a;break}}if(typeof s!="object")return;if(i._id=s._id,i.send=s.send,i.request=s.request,i.run=s.run,i.post=s.post,i.subscribe=s.subscribe,i.unsubscribe=s.unsubscribe,i.terminate=s.terminate,i.onclose=e.onclose,i.onclose){if(!(s.onclose&&i.onclose.toString()===s.onclose.toString())){let n=s.onclose;s.onclose=(...a)=>{i.onclose&&i.onclose(i,...a),this.users[i.source]&&Object.keys(this.sources[i.source]).length===0&&this.removeUser(i.source,!1),n&&n(...a)}}}else{let n=s.onclose;s.onclose=(...a)=>{this.removeConnection(i),this.users[i.source]&&Object.keys(this.sources[i.source]).length===0&&this.removeUser(i.source,!1),n&&n(...a)}}e.service?(typeof e.service=="string"&&(e.service=this.services[e.service]),i.service=e.service):s.graph&&(i.service=s.graph)}return!i.source&&e.source?i.source=e.source:!i.source&&e.service?i.source=typeof e.service=="object"?e.service.name:void 0:!i.source&&(i.connection instanceof y||i.connection instanceof v)&&(i.source="local",this.order.indexOf("local")||this.order.unshift("local")),i._id||(i._id=`connection${Math.floor(Math.random()*1e15)}`),i.source&&(this.sources[i.source]||(this.sources[i.source]={}),this.sources[i.source][i._id]=i),this.connections[i._id]||(this.connections[i._id]=i),i}};this.removeConnection=(e,r=!1)=>{if(typeof e=="object"&&e._id&&(e=e._id),typeof e=="string"){if(this.connections[e]){r&&this.connections[e]&&this.connections[e].terminate(),delete this.connections[e];for(let i in this.sources)if(this.sources[i][e])delete this.sources[i][e];else for(let s in this.sources[i])this.sources[i][s]?.[e]&&delete this.sources[i][e];return!0}else if(this.sources[e]){for(let i in this.sources[e])this.removeConnection(this.sources[e][i],r);return!0}}};this.addService=(e,r,i,s,n,a,o)=>{if(this.load(e,i,s,this.customRoutes,this.customChildren),this.services[e.name]=e,r)if(typeof r=="string")this.addServiceConnections(e,r,a);else for(let f in r)this.addServiceConnections(e,f,a);n&&this.syncServices(),o?this.order=o:(this.order||(this.order=[]),this.order.push(e.name))};this.addServiceConnections=(e,r,i)=>{if(typeof e=="string"&&(e=this.services[e]),r&&e[r]){let s={};this.serviceConnections[e.name]||(this.serviceConnections[e.name]={}),this.serviceConnections[e.name][r]=e[r];for(let n in e[r])this.connections[n]||(s[n]=this.addConnection({connection:e[r][n],service:e},i),s[n].connectionType=r);return s}};this.openConnection=async(e,r,i,...s)=>{if(typeof e=="string"&&(e=this.services[e]),e instanceof G){let n=e.run("open",r,...s);if(n instanceof Promise)return n.then(async a=>{a._id||await new Promise((o,f)=>{let b=performance.now(),h=()=>{a._id?o(!0):performance.now()-b>3e3?f(!1):setTimeout(()=>{h()},100)};h()}).catch(o=>{console.error("Connections timed out:",o)}),a._id&&this.addConnection({connection:a,service:e},i)});if(n&&(n._id||await new Promise((a,o)=>{let f=performance.now(),b=()=>{n._id?a(!0):performance.now()-f>3e3?o(!1):setTimeout(()=>{b()},100)};b()}).catch(a=>{console.error("Connections timed out:",a)}),n._id))return this.addConnection({connection:n,service:e},i)}};this.terminate=e=>(typeof e=="string"&&(e=this.connections[e]),e.terminate());this.subscribeThroughConnection=(e,r,i,s,...n)=>{if(typeof r=="string"&&(r=this.getConnection(r,"run")),typeof r=="object")return new Promise((a,o)=>{r.run("routeConnections",[e,i,r._id,...n]).then(f=>{this.subscribe(i,b=>{b?.callbackId===e&&(s?typeof s=="string"?this.setState({[s]:b.args}):s(b.args):this.setState({[i]:b.args}))}),a(f)}).catch(o)})};this.routeConnections=(e,r,i,...s)=>{let n;if(typeof i=="string"&&(this.sources[i]&&(n=i),i=this.getConnection(i,"send")),typeof r=="string"&&(r=this.getConnection(r,"subscribe")),r?.subscribe&&i?.send)return new Promise((o,f)=>{r.subscribe(e,r._id,b=>{!this.connections[i._id]&&n&&this.sources[n]&&(n=i,Object.keys(this.sources[n]).forEach(h=>{this.sources[i][h].send&&(i=this.sources[i][h])})),this.connections[i._id]&&i.send({callbackId:e,args:b})},...s).then(b=>{o(b)})})};this.syncServices=()=>{for(let e in this.services)"users"in this.services[e]&&(this.services[e].users=this.users),this.nodes.forEach((r,i)=>{this.services[e].nodes.get(r.tag)?!this.services[e].nodes.get(i)&&r._UNIQUE!==this.services[e].nodes.get(r.tag)._UNIQUE&&this.services[e].nodes.set(i,r):this.services[e].nodes.set(r.tag,r)})};this.setUserData=(e,r)=>{if(e&&typeof e=="string"&&(e=this.users[e],!e))return!1;if(r&&typeof r=="string"&&(r=JSON.parse(r)),typeof r=="object")return this.recursivelyAssign(e,r),!0};this.routes={addUser:this.addUser,removeUser:this.removeUser,getConnection:this.getConnection,addConnection:this.addConnection,removeConnection:this.removeConnection,addService:this.addService,addServiceConnections:this.addServiceConnections,openConnection:this.openConnection,terminate:this.terminate,routeConnections:this.routeConnections,subscribeThroughConnection:this.subscribeThroughConnection,syncServices:this.syncServices};if(this.load(this.routes),e&&(e.order&&(this.order=e.order),e.services))for(let r in e.services){let i=e.services[r];if(i instanceof G)i.service.name=r,i.service.tag=r,this.addService(i.service,i.connections,e.includeClassName,e.routeFormat,e.syncServices);else if(typeof i=="function"){let s=new i;s.name=r,s.tag=r,s&&this.addService(s,s.connections,e.includeClassName,e.routeFormat,e.syncServices)}else{if(typeof i.service=="function"){let s=new i.service({name:r});s.name=r,s.tag=r,s&&this.addService(s,void 0,e.includeClassName,e.routeFormat,e.syncServices),i.service=s}else i.service instanceof G&&(i.service.name=r,i.service.tag=r,this.addService(i.service,void 0,e.includeClassName,e.routeFormat,e.syncServices));if(typeof i.service=="object"&&(i.connections&&(Array.isArray(i.connections)?i.connections.forEach(s=>{this.addServiceConnections(i[r].service,s)}):this.addServiceConnections(i.service,i.connections)),i.config))for(let s in i.config)this.openConnection(i.service,i.config[s],i.config[s].source,i.config[s].args)}}}removeUser(e,r){return r&&this.removeConnection(e,r),typeof e=="string"&&(e=this.users[e]),typeof e=="object"&&e._id&&(delete this.users[e._id],e.onclose&&e.onclose(e)),!0}};export{O as EventHandler,v as Graph,y as GraphNode,T as Router,G as Service,P as createNode,C as parseFunctionFromText,E as reconstructNode,j as reconstructObject,R as state,A as stringifyFast,w as stringifyWithCircularRefs,B as unsafeRoutes}; diff --git a/dist/index.core.js b/dist/index.core.js index e2031152..d2f04d2e 100644 --- a/dist/index.core.js +++ b/dist/index.core.js @@ -1 +1,2 @@ -(()=>{var x=class{data={};triggers={};ctr=0;constructor(e){typeof e=="object"&&(this.data=e)}setState=e=>{Object.assign(this.data,e);let t=Object.getOwnPropertyNames(e);for(let n of t)this.triggerEvent(n,this.data[n]);if(this.triggers[G]){let n=s=>{s(e)},i=this.triggers[G].length;for(let s=i-1;s>=0;s--)n(this.triggers[G][s].onchange)}return this.data};setValue=(e,t)=>{this.data[e]=t,this.triggerEvent(e,t)};triggerEvent=(e,t)=>{if(this.triggers[e]){let n=s=>{s.onchange(t)},i=this.triggers[e].length;for(let s=i-1;s>=0;s--)n(this.triggers[e][s])}};subscribeState=e=>this.subscribeEvent(G,e);unsubscribeState=e=>this.unsubscribeEvent(G,e);subscribeEvent=(e,t,n,i)=>{if(e){n&&i&&!this.triggers[e]&&Object.defineProperty(this.data,e,{get:()=>n[i],set:r=>{n[i]=r},enumerable:!0,configurable:!0}),this.triggers[e]||(this.triggers[e]=[]);let s=this.ctr;return this.ctr++,this.triggers[e].push({sub:s,onchange:t}),s}else return};unsubscribeEvent=(e,t)=>{let n=this.triggers[e];if(n)if(t===void 0)delete this.triggers[e],delete this.data[e];else{let i,s=n.find((r,o)=>{if(r.sub===t)return i=o,!0});return s&&n.splice(i,1),Object.keys(n).length===0&&(delete this.triggers[e],delete this.data[e]),this.onRemoved&&this.onRemoved(s),!0}};subscribeEventOnce=(e,t)=>{let n,i=s=>{t(s),this.unsubscribeEvent(e,n)};return n=this.subscribeEvent(e,i),n};getEvent=(e,t)=>{if(typeof t!="number")return this.triggers[e];for(let n in this.triggers[e])if(this.triggers[e][n].sub===t)return this.triggers[e][n]};getSnapshot=()=>{let e={};for(let t in this.data)e[t]=this.data[t]};onRemoved},G="*s";var F=new x,w=class extends Function{__bound;__call;constructor(){return super("return this.__bound.__call.apply(this.__bound, arguments)"),this.__bound=this.bind(this),this.__bound}},p=class _{__node={tag:`node${Math.floor(Math.random()*1e15)}`,unique:`${Math.floor(Math.random()*1e15)}`,state:F};__children;__parent;__operator;__listeners;__props;__args;constructor(e,t,n){if(this.__setProperties(e,t,n),typeof e=="function"||e?.__callable){let i=new w;i.__call=(...r)=>this.__operator(...r);let s=new Proxy(i,{get:(r,o,l)=>Reflect.has(this,o)?Reflect.get(this,o,l):Reflect.get(r,o,l),set:(r,o,l,f)=>Reflect.has(this,o)?Reflect.set(this,o,l,f):Reflect.set(r,o,l,f)});return Object.setPrototypeOf(s,this),s}}get __graph(){return this.__node?.graph}set __graph(e){this.__node.graph=e}__setProperties=(e,t,n)=>{if((()=>{let s=e;typeof e=="function"?P(e)?e=new e:e={__operator:e,__node:{forward:!0,tag:e.name}}:typeof e=="string"&&n?.get(e)&&(e=n.get(e)),"__node"in e||(e.__node={}),e.__node.initial||(e.__node.initial=s)})(),typeof e=="object"){let s=()=>{e.__node?.state?this.__node.state=e.__node.state:n&&(e.__node.state=n.__node.state)},r=()=>{e.__props&&(typeof e.__props=="function"&&(e.__props=new e.__props),typeof e.__props=="object"&&this.__proxyObject(e.__props))},o=()=>{e.__node.tag||(e.__operator?.name?e.__node.tag=e.__operator.name:e.__node.tag=`node${Math.floor(Math.random()*1e15)}`)},l=()=>{typeof e.__node=="string"?n?.get(e.__node.tag)?e=n.get(e.__node.tag):e.__node={}:e.__node||(e.__node={}),n&&(e.__node.graph=n),e instanceof y&&(e.__node.source=e)},f=()=>{if(!e.__parent&&t&&(e.__parent=t),t?.__node&&!(t instanceof y||e instanceof y)&&(e.__node.tag=t.__node.tag+"."+e.__node.tag),t instanceof y&&e instanceof y&&(e.__node.loaders&&Object.assign(t.__node.loaders?t.__node.loaders:{},e.__node.loaders),t.__node.mapGraphs)){e.__node.nodes.forEach(h=>{t.set(e.__node.tag+"."+h.__node.tag,h)});let u=()=>{e.__node.nodes.forEach(h=>{t.__node.nodes.delete(e.__node.tag+"."+h.__node.tag)})};this.__addOndisconnected(u)}},a=()=>{if(typeof e.default=="function"&&!e.__operator&&(e.__operator=e.default),e.__operator){if(typeof e.__operator=="string"&&n){let u=n.get(e.__operator);u&&(e.__operator=u.__operator),!e.__node.tag&&e.__operator.name&&(e.__node.tag=e.__operator.name)}typeof e.__operator=="function"&&(e.__operator=this.__setOperator(e.__operator)),e.default&&(e.default=e.__operator)}},d=()=>{e.__node=Object.assign(this.__node,e.__node);let u=Object.getOwnPropertyNames(e).filter(h=>{if(!O[h])return!0});for(let h of u)h in e&&h!=="name"&&(this[h]=e[h])},c=()=>{this.__onconnected&&(typeof this.__onconnected=="function"?this.__onconnected=this.__onconnected.bind(this):Array.isArray(this.__onconnected)&&(this.__onconnected=this.__onconnected.map(u=>u.bind(this))),typeof this.__ondisconnected=="function"?this.__ondisconnected=this.__ondisconnected.bind(this):Array.isArray(this.__ondisconnected)&&(this.__ondisconnected=this.__ondisconnected.map(u=>u.bind(this))))};s(),o(),r(),l(),f(),d(),c(),a()}};__subscribe=(e,t,n,i,s,r,o)=>{let l=(a,d=(u,h)=>h||u,c=e)=>{let u;if(r){let b=A(c,r,this.__node.graph);c=b.__callback,u=b.__args}let h=this.__node.state.subscribeEvent(a,c,this,t),g=this.__node.state.getEvent(a,h);return this.__listeners||(this.__listeners={}),this.__listeners[a]=this.__node.state.triggers[a],g&&(g.source=this.__node.tag,t&&(g.key=t),g.target=d(e,i),s&&(g.tkey=s),n&&(g.subInput=n),r&&(g.arguments=u,g.__args=r),o&&(g.__callback=o),g.node=this,g.graph=this.__node.graph),h},f=a=>{let d=this.__node.graph.get(a);if(!d&&a.includes(".")){i=a.substring(0,a.lastIndexOf("."));let c=this.__node.graph.get(a.substring(0,i));s=a.lastIndexOf(".")+1,c&&typeof c[t]=="function"&&(a=(...u)=>c[s](...u))}else d.__operator&&(a=d.__operator,s="__operator");return a};if(t){if((!this.__node.localState||!this.__node.localState[t])&&this.__addLocalState(this,t),typeof e=="string"){if(o=this.__node.tag+"."+e,s=e,i){if(this.__node.graph?.get(i)){let c=this.__node.graph?.get(i);if(typeof c[e]=="function"){let u=c[e];e=(...h)=>{u(...h)}}else{let u=e;e=g=>{c[u]=g}}}}else if(typeof this[e]=="function"){let c=this[e];e=(...u)=>{c(...u)}}else this.__node.graph?.get(e)&&(e=f(e));if(typeof e!="function")return}let a,d=n?this.__node.unique+"."+t+"input":this.__node.unique+"."+t;return typeof e=="function"&&!e?.__node?a=l(d,(c,u)=>u||c,e):e?.__node&&(a=l(d,(c,u)=>u||c.__node.unique,(...c)=>{e.__operator&&e.__operator(...c)})),a}else{if(typeof e=="string"&&(o=e,i||(i=e),this.__node.graph.get(e)&&(e=this.__node.graph.get(e)),s="__operator",typeof e!="object"))return;let a,d=n?this.__node.unique+"input":this.__node.unique;return typeof e=="function"&&!e?.__node?a=l(d,(c,u)=>u||c,e):e?.__node&&(a=l(d,(c,u)=>u||c.__node.unique,(...c)=>{e.__operator&&e.__operator(...c)})),a}};__unsubscribe=(e,t,n)=>t?this.__node.state.unsubscribeEvent(n?this.__node.unique+"."+t+"input":this.__node.unique+"."+t,e):this.__node.state.unsubscribeEvent(n?this.__node.unique+"input":this.__node.unique,e);__setOperator=e=>{e=e.bind(this),this.__args&&this.__node.graph&&(e=A(e,this.__args,this.__node.graph).__callback);let t=`${this.__node.unique}input`;if(this.__operator=(...n)=>{this.__node.state.triggers[t]&&this.__node.state.setValue(t,n);let i=e(...n);return this.__node.state.triggers[this.__node.unique]&&(typeof i?.then=="function"?i.then(s=>{s!==void 0&&this.__node.state.setValue(this.__node.unique,s)}).catch(console.error):i!==void 0&&this.__node.state.setValue(this.__node.unique,i)),i},this.__parent instanceof _&&!this.__subscribedToParent&&this.__parent.__operator){let n=this.__parent.__subscribe(this),i=()=>{this.__parent?.__unsubscribe(n),delete this.__subscribedToParent};this.__addOndisconnected(i),this.__subscribedToParent=!0}return this.__operator};__addLocalState=(e,t)=>{if(!e)return;this.__node.localState||(this.__node.localState={});let n=this.__node.localState,i=(s,r)=>{let o=this.__node.unique+"."+r,l=`${o}input`,f,a,d,c;if(typeof s[r]=="function"&&r!=="__operator")this.__props?.[r]?d=this.__props:d=n,f=()=>d[r],a=u=>{this.__props?.[r]||(u=u.bind(this)),d[r]=(...h)=>{this.__node.state.triggers[l]&&this.__node.state.setValue(l,h);let g=u(...h);return this.__node.state.triggers[o]&&(typeof g?.then=="function"?g.then(b=>{this.__node.state.triggerEvent(o,b)}).catch(console.error):this.__node.state.triggerEvent(o,g)),g}},n[r]=s[r].bind(this),c={get:f,set:a,enumerable:!0,configurable:!0};else if(r!=="__graph"){let u,h,g;this.__props?.[r]?g=this.__props:g=n,u=()=>g[r],h=b=>{g[r]=b,this.__node.state.triggers[o]&&this.__node.state.triggerEvent(o,b)},n[r]=s[r],c={get:u,set:h,enumerable:!0,configurable:!0}}if(Object.defineProperty(s,r,c),typeof this.__node.initial=="object"){let u=Object.getOwnPropertyDescriptor(this.__node.initial,r);(u===void 0||u?.configurable)&&Object.defineProperty(this.__node.initial,r,c)}};if(t)i(e,t);else for(let s in e)i(e,s)};__proxyObject=e=>{let t=q(e);for(let n of t){let i={get:()=>e[n],set:s=>{e[n]=s},enumerable:!0,configurable:!0};if(Object.defineProperty(this,n,i),typeof this.__node.initial=="object"){let s=Object.getOwnPropertyDescriptor(this.__node.initial,n);(s===void 0||s?.configurable)&&Object.defineProperty(this.__node.initial,n,i)}}};__addOnconnected(e){e=e.bind(this),Array.isArray(this.__onconnected)?this.__onconnected.push(e):typeof this.__onconnected=="function"?this.__onconnected=[e,this.__onconnected]:this.__onconnected=e}__addOndisconnected(e){e=e.bind(this),Array.isArray(this.__ondisconnected)?this.__ondisconnected.push(e):typeof this.__ondisconnected=="function"?this.__ondisconnected=[e,this.__ondisconnected]:this.__ondisconnected=e}__callConnected(e=this){if(typeof this.__onconnected=="function")this.__onconnected(this);else if(Array.isArray(this.__onconnected)){let t=n=>{n(this)};this.__onconnected.forEach(t)}}__callDisconnected(e=this){if(typeof this.__ondisconnected=="function")this.__ondisconnected(this);else if(Array.isArray(this.__ondisconnected)){let t=n=>{n(this)};this.__ondisconnected.forEach(t)}}},y=class _{__node={tag:`graph${Math.floor(Math.random()*1e15)}`,unique:`${Math.random()}`,nodes:new Map,state:F,roots:{}};constructor(e){this.init(e)}init=e=>{if(e){let t=Object.assign({},e);delete t.roots,N(this.__node,t),e.roots&&this.load(e.roots)}};load=(e,t=!1)=>{function n(r,o,l=!0,f=!0){if(f){r||(r={});for(let a in o)!a.startsWith("__")&&o[a]&&typeof o[a]=="object"?(r[a]=o[a],o[a]?.__children&&n({},o[a].__children,!1,!1)):typeof o[a]=="function"&&(r[a]=o[a]);n(r,o,!0,!1)}else if(o?.__children&&!l)o.__children?.constructor.name==="Object"?r.__children?.constructor.name==="Object"?r.__children=n(r.__children,o.__children,!0,!1):r.__children=n({},o.__children,!0,!1):r.__children=o.__children;else if(l)for(let a in o)!a.startsWith("__")&&o[a]&&typeof o[a]=="object"?(r[a]=Object.assign({},o[a]),o[a]?.__children&&(r[a].__children=n({},o[a].__children,!1,!1))):typeof o[a]=="function"&&(r[a]=o[a]);return r}this.__node.roots=n(this.__node.roots?this.__node.roots:{},e);let i=Object.assign({},e);i.__node&&delete i.__node;let s=this.recursiveSet(i,this,void 0,e,t);if(e.__node){if(!e.__node.tag)e.__node._tag=`roots${Math.floor(Math.random()*1e15)}`;else if(!this.get(e.__node.tag)){let r=new p(e,this,this);this.set(r.__node.tag,r),this.runLoaders(r,this,e,e.__node.tag),r.__listeners&&(s[r.__node.tag]=r.__listeners)}}else e.__listeners&&this.setListeners(e.__listeners);return this.setListeners(s),i};setLoaders=(e,t)=>(t?this.__node.loaders=e:Object.assign(this.__node.loaders,e),this.__node.loaders);runLoaders=(e,t,n,i)=>{for(let s in this.__node.loaders)typeof this.__node.loaders[s]=="object"?(this.__node.loaders[s].init&&this.__node.loaders[s](e,t,this,this.__node.roots,n,i),this.__node.loaders[s].connected&&e.__addOnconnected(this.__node.loaders[s].connect),this.__node.loaders[s].disconnected&&e.__addOndisconnected(this.__node.loaders[s].disconnect)):typeof this.__node.loaders[s]=="function"&&this.__node.loaders[s](e,t,this,this.__node.roots,n,i)};add=(e,t,n=!0)=>{let i={};typeof t=="string"&&(t=this.get(t));let s;if(typeof e=="function"?P(e)?e.prototype instanceof p?(e=e.prototype.constructor(e,t,this),s=!0):e=new e:e={__operator:e,__callable:!0}:typeof e=="string"&&(e=this.__node.roots[e]),!e)return;if(!s){let l=Object.getOwnPropertyNames(e),f=Object.getOwnPropertyNames(Object.getPrototypeOf(e));l.push(...f),l=l.filter(d=>!O.includes(d));let a={};for(let d of l)a[d]=e[d];e=a}if(e.__node||(e.__node={}),e.__node.initial=e,typeof e=="object"&&this.get(e.__node.tag))if(n)this.remove(e.__node.tag,!0);else return;else if(e.__node.tag&&this.get(e.__node.tag))return this.get(e.__node.tag);let r,o=N({},e,2);if(s?r=e:r=new p(e,t,this),this.set(r.__node.tag,r),this.runLoaders(r,t,e,r.__node.tag),this.__node.roots[r.__node.tag]=o,r.__children&&(r.__children=Object.assign({},r.__children),this.recursiveSet(r.__children,r,i,r.__children)),r.__listeners){i[r.__node.tag]=Object.assign({},r.__listeners);for(let l in r.__listeners){let f=r.__listeners[l];r[l]&&(delete i[r.__node.tag][l],i[r.__node.tag][r.__node.tag+"."+l]=f),typeof f=="string"&&(r.__children?.[f]?i[r.__node.tag][l]=r.__node.tag+"."+f:t instanceof p&&(t.__node.tag===f||t.__node.tag.includes(".")&&t.__node.tag.split(".").pop()===f)&&(i[r.__node.tag][l]=t.__node.tag))}}return this.setListeners(i),r.__callConnected(),r};recursiveSet=(e,t,n={},i,s=!1)=>{let r=Object.getOwnPropertyNames(i).filter(l=>!O.includes(l)),o=Object.getOwnPropertyNames(Object.getPrototypeOf(i)).filter(l=>!O.includes(l));r.push(...o);for(let l of r){if(l.includes("__"))continue;let f=i[l];if(Array.isArray(f))continue;let a;if(typeof f=="function"?P(f)?(f=new f,f instanceof p&&(f=f.prototype.constructor(f,t,this),a=!0)):f={__operator:f,__callable:!0}:typeof f=="string"?this.__node.nodes.get(f)?f=this.__node.nodes.get(f):f=this.__node.roots[f]:typeof f=="boolean"&&(this.__node.nodes.get(l)?f=this.__node.nodes.get(l):f=this.__node.roots[l]),f&&typeof f=="object"){if(!a&&!(f instanceof p)){let h=Object.getOwnPropertyNames(f).filter(m=>!O.includes(m)),g=Object.getOwnPropertyNames(Object.getPrototypeOf(f)).filter(m=>!O.includes(m));g.splice(g.indexOf("constructor"),1),h.push(...g);let b={};for(let m of h)b[m]=f[m];f=b}if(f.__node||(f.__node={}),f.__node.tag||(f.__node.tag=l),f.__node.initial||(f.__node.initial=e[l]),s&&this.get(f.__node.tag))this.remove(f.__node.tag,!0);else if(this.get(f.__node.tag)&&!(!(t instanceof _)&&t?.__node)||t?.__node&&this.get(t.__node.tag+"."+f.__node.tag))continue;let d,c=!1,u=N({},f,2);if(a||f instanceof p?d=f:(d=new p(f,t,this),c=!0),!c&&f instanceof p&&!a&&t instanceof p){let h=this.subscribe(t.__node.tag,d.__node.tag),g=b=>{this.unsubscribe(t.__node.tag,h)};d.__addOndisconnected(g)}else if(d){if(this.set(d.__node.tag,d),this.runLoaders(d,t,e[l],l),e[l]=d,this.__node.roots[d.__node.tag]=u,d.__children&&(d.__children=Object.assign({},d.__children),this.recursiveSet(d.__children,d,n,d.__children)),d.__listeners){n[d.__node.tag]=Object.assign({},d.__listeners);for(let h in d.__listeners){let g=d.__listeners[h],b=h;d[h]&&(delete n[d.__node.tag][h],b=d.__node.tag+"."+h,n[d.__node.tag][b]=g),typeof g=="string"&&(d.__children?.[g]?n[d.__node.tag][b]=d.__node.tag+"."+g:t instanceof p&&(t.__node.tag===g||t.__node.tag.includes(".")&&t.__node.tag.split(".").pop()===g)&&(n[d.__node.tag][b]=t.__node.tag))}}d.__callConnected()}}}return n};remove=(e,t=!0)=>{if(this.unsubscribe(e),typeof e=="string"&&(e=this.get(e)),e instanceof p){this.delete(e.__node.tag),delete this.__node.roots[e.__node.tag],t&&this.clearListeners(e),e.__callDisconnected();let n=i=>{for(let s in i)this.unsubscribe(i[s]),this.delete(i[s].__node.tag),delete this.__node.roots[i[s].__node.tag],this.delete(s),delete this.__node.roots[s],i[s].__node.tag=i[s].__node.tag.substring(i[s].__node.tag.lastIndexOf(".")+1),t&&this.clearListeners(i[s]),i[s].__callDisconnected(),i[s].__children&&n(i[s].__children)};e.__children&&n(e.__children)}return e?.__node.tag&&e?.__parent&&(delete e?.__parent,e.__node.tag=e.__node.tag.substring(e.__node.tag.indexOf(".")+1)),e?.__node.graph&&(e.__node.graph=void 0),e};run=(e,...t)=>{if(typeof e=="string"){let n=this.get(e);if(!n&&e.includes(".")){if(n=this.get(e.substring(0,e.lastIndexOf("."))),typeof n?.[e.substring(e.lastIndexOf(".")+1)]=="function")return n[e.substring(e.lastIndexOf(".")+1)](...t)}else if(n?.__operator)return n.__operator(...t)}if(e?.__operator)return e?.__operator(...t)};setListeners=e=>{for(let t in e){let n=this.get(t);if(typeof e[t]=="object")for(let i in e[t]){let s=this.get(i),r;if(typeof e[t][i]!="object")e[t][i]={__callback:e[t][i]};else if(!e[t][i].__callback)for(let o in e[t][i]){typeof e[t][i][o]!="object"&&(e[t][i][o]={__callback:e[t][i][o]},n.__operator&&(e[t][i][o].__callback===!0||typeof e[t][i][o].__callback>"u")&&(e[t][i][o].__callback=n.__operator));let l=this.get(o);if(l)r=this.subscribe(l,e[t][i][o].__callback,e[t][i][o].__args,void 0,e[t][i][o].subInput,t);else{let f=i.substring(0,i.lastIndexOf("."));if(l=this.get(f),l){let a=i.substring(i.lastIndexOf(".")+1);r=this.subscribe(l,e[t][i][o].__callback,e[t][i][o].__args,a,e[t][i][o].subInput,t)}}}if("__callback"in e[t][i])if(n&&((e[t][i].__callback===!0||typeof e[t][i].__callback>"u")&&(e[t][i].__callback=n.__operator),typeof e[t][i].__callback=="function"&&(e[t][i].__callback=e[t][i].__callback.bind(n))),s)r=this.subscribe(s,e[t][i].__callback,e[t][i].__args,void 0,e[t][i].subInput,t);else{let o=i.substring(0,i.lastIndexOf("."));s=this.get(o),s&&(r=this.subscribe(s,e[t][i].__callback,e[t][i].__args,i.substring(i.lastIndexOf(".")+1),e[t][i].subInput,t))}}}};clearListeners=(e,t)=>{if(typeof e=="string"&&(e=this.get(e)),e?.__listeners)for(let n in e.__listeners){if(t&&n!==t||typeof e.__listeners[n]?.sub!="number")continue;let i=this.get(n);if(i)if(typeof!e.__listeners[n]?.__callback=="number")for(let s in e.__listeners[n])e.__listeners[n][s]?.sub&&(this.unsubscribe(i,e.__listeners[n][s].sub,void 0,e.__listeners[n][s].subInput),e.__listeners[n][s].sub=void 0);else typeof e.__listeners[n]?.sub=="number"&&(this.unsubscribe(i,e.__listeners[n].sub,void 0,e.__listeners[n].subInput),e.__listeners[n].sub=void 0);else if(i=this.get(n.substring(0,n.lastIndexOf("."))),i)if(typeof e.__listeners[n]=="object"&&!e.__listeners[n]?.__callback)for(let s in e.__listeners[n])typeof e.__listeners[n][s]?.sub=="number"&&(this.unsubscribe(i,e.__listeners[n][s].sub,n.substring(n.lastIndexOf(".")+1),e.__listeners[n][s].subInput),e.__listeners[n][s].sub=void 0);else typeof e.__listeners[n]?.sub=="number"&&(this.unsubscribe(i,e.__listeners[n].sub,n.substring(n.lastIndexOf(".")+1),e.__listeners[n].subInput),e.__listeners[n].sub=void 0)}};get=e=>this.__node.nodes.get(e);getByUnique=e=>Array.from(this.__node.nodes.values()).find(t=>{if(t.__node.unique===e)return!0});set=(e,t)=>this.__node.nodes.set(e,t);delete=e=>this.__node.nodes.delete(e);list=()=>Array.from(this.__node.nodes.keys());getListener=(e,t,n)=>{let i=this.get(e);if(i){let s=i.__node.unique;return t&&(s+="."+t),this.__node.state.getEvent(s,n)}};getProps=(e,t)=>{if(typeof e=="string"&&(e=this.get(e)),e instanceof p){let n;if(t)n=Object.assign({},this.__node.roots[e.__node.tag]);else{n=Object.assign({},e);for(let i in n)i.includes("__")&&delete n[i]}}};subscribe=(e,t,n,i,s,r,o)=>{let l=e;typeof e=="string"&&(l=this.get(e),!l&&e.includes(".")&&(l=this.get(e.substring(0,e.lastIndexOf("."))),i=e.substring(e.lastIndexOf(".")+1))),r instanceof p&&(r=r.__node.tag);let f;if(typeof t=="string"){f=t;let d=c=>{if(this.get(c)?.__operator){let u=this.get(c);r=c,c=function(...h){return u.__operator(...h)}}else if(c.includes(".")){r=c.substring(0,c.lastIndexOf("."));let u=this.get(r),h=c.substring(c.lastIndexOf(".")+1);o=h,typeof u[h]=="function"?u[h]instanceof p?c=u[h]:c=function(...g){return u[h](...g)}:c=function(g){return u[h]=g,u[h]}}return c};if(r){let c=this.get(r);typeof c?.[t]=="function"?(o=t,t=function(...u){return c[i](...u)}):c?.[i]?(o=i,c[i]instanceof p?t=c[i]:t=function(u){return c[i]=u,c[i]}):t=d(t)}else t=d(t)}let a;if(l instanceof p){let d=()=>{a=l.__subscribe(t,i,s,r,o,n,f);let c=()=>{a!==void 0&&l.__unsubscribe(a,i,s),a=void 0};l.__addOndisconnected(()=>{c(),l.__addOnconnected(()=>{a===void 0&&l.__node.graph.__node.tag===this.__node.tag&&d()})}),typeof t=="string"&&this.get(t)&&(t=this.get(t)),t instanceof p&&t.__addOndisconnected(()=>{c()})};d()}else if(typeof e=="string"){let d=this.get(e);if(d){if(t instanceof p&&t.__operator){let c=()=>{a=d.__subscribe(t.__operator,i,s,r,o,n,f);let u=()=>{a!==void 0&&d.__unsubscribe(a,i,s)};d.__addOndisconnected(()=>{u(),d.__addOnconnected(()=>{a===void 0&&d.__node.graph.__node.tag===this.__node.tag&&c()})}),t.__addOndisconnected(u)};c()}else if(typeof t=="function"||typeof t=="string"){let c=()=>{a=d.__subscribe(t,i,s,r,o,n,f);let u=()=>{a!==void 0&&d.__unsubscribe(a,i,s),a=void 0};d.__addOndisconnected(()=>{u(),d.__addOnconnected(()=>{a===void 0&&d.__node.graph.__node.tag===this.__node.tag&&c()})}),typeof t=="string"&&this.get(t)&&this.get(t).__addOndisconnected(u)};c()}}else typeof t=="string"&&(t=this.__node.nodes.get(t).__operator),typeof t=="function"&&!t?.__node&&(a=this.__node.state.subscribeEvent(e,t))}return a};unsubscribe=(e,t,n,i)=>e instanceof p?e.__unsubscribe(t,n,i):this.get(e)?.__unsubscribe(t,n,i);setState=e=>{this.__node.state.setState(e)}};function N(_,e,t=1/0,n=0){for(let i in e)e[i]?.constructor.name==="Object"&&n{if(e.get(_)?.__operator){let t=e.get(_);return(...n)=>{t.__operator(...n)}}else if(_.includes(".")){let t=_.split("."),n=t.pop(),i=t.join("."),s=e.get(i);return typeof e.get(i)?.[n]=="function"?(...r)=>s[n](...r):()=>s[n]}else if(e.get(_)){let t=e.get(_);return()=>t}else{let t=_;return()=>t}},A=(_,e,t)=>{let n=[],i=(r,o)=>{if(r==="__output"||r==="__input"||r==="__callback")n[o]={__callback:l=>l,__args:void 0,idx:o};else if(typeof r=="string")n[o]={__callback:j(r,t),__args:void 0,idx:o};else if(typeof r=="function"){let l=r;n[o]={__callback:(...f)=>l(...f),__args:void 0,idx:o}}else if(typeof r=="object"&&(r.__input||r.__callback)){let l=function(f){let a=f.__input?f.__input:f.__callback;if(typeof f.__input=="string"&&(a={__callback:j(f.__input,t),__args:void 0,idx:o}),f.__args){let d=A(a,f.__args,t);a={__callback:d.__callback,__args:d.__args,idx:o}}else a={__callback:a,__args:void 0,idx:o};if(f.__output){let d=f.__output;if(typeof f.__output=="string"?d={__callback:j(d,t),__args:void 0,idx:o}:typeof r.__output=="object"&&(d=l(d)),typeof d?.__callback=="function"){let c=a.__callback,u=d.__callback;a={__callback:(...h)=>u(c(...h)),__args:d.__args,idx:o}}}return a};n[o]=l(r)}else{let l=r;n[o]={__callback:()=>l,__args:void 0,idx:o}}};e.forEach(i),typeof _=="string"&&(_={__callback:j(_,t),__args:void 0});let s=typeof _=="function"?_:_.__callback;return _=function(...r){let o=f=>f.__callback(...r);return s(...n.map(o))},{__callback:_,__args:n}},O=Object.getOwnPropertyNames(Object.getPrototypeOf({}));var S=(_,e,t)=>{_.__node.backward&&e instanceof p&&t.setListeners({[e.__node.tag]:{[_.__node.tag]:e}})},I=(_,e,t)=>{if(_.__operator){let n=Math.random();if(_.__node.loops||(_.__node.loops={}),typeof _.__node.delay=="number"){let i=_.__operator;_.__setOperator((...s)=>new Promise((r,o)=>{_.__node.loops[n]=setTimeout(async()=>{r(await i(...s))},_.__node.delay)}))}else if(_.__node.frame===!0){let i=_.__operator;_.__setOperator((...s)=>new Promise((r,o)=>{_.__node.loops[n]=requestAnimationFrame(async()=>{r(await i(...s))})}))}if(typeof _.__node.repeat=="number"||typeof _.__node.recursive=="number"){let i=_.__operator;_.__setOperator(async(...s)=>{let r=_.__node.repeat?_.__node.repeat:_.__node.recursive,o,l=async(f,...a)=>{for(;f>0;){if(_.__node.delay||_.__node.frame){i(...a).then(async d=>{_.__node.recursive?await l(f,d):await l(f,...a)});break}else o=await i(...s);f--}};return await l(r,...s),o})}if(_.__node.loop&&typeof _.__node.loop=="number"){let i=_.__operator,s=_.__node.loop;_.__setOperator((...o)=>{if("looping"in _.__node||(_.__node.looping=!0),_.__node.looping){let l=performance.now();i(...o),_.__node.loops[n]=setTimeout(()=>{let a=performance.now()-l-_.__node.loop;a>0?s=_.__node.loop-a:s=_.__node.loop,s<=0&&(s=_.__node.loop),_.__operator(...o)},s)}}),_.__node.looping&&_.__operator();let r=o=>{o.__node.looping&&(o.__node.looping=!1),o.__node.loops[n]&&(clearTimeout(o.__node.loops[n]),cancelAnimationFrame(o.__node.loops[n]))};_.__addOndisconnected(r)}}},v=(_,e,t)=>{if(_.__node.animate===!0||_.__animation){let n=_.__operator;_.__setOperator((...s)=>{"animating"in _.__node||(_.__node.animating=!0),_.__node.animating&&(typeof _.__animation=="function"?_.__animation(...s):n(...s),_.__node.animationFrame=requestAnimationFrame(()=>{_.__operator(...s)}))}),(_.__node.animating||(!("animating"in _.__node)||_.__node.animating)&&_.__animation)&&setTimeout(()=>{_.__node.animationFrame=requestAnimationFrame(_.__operator)},10);let i=s=>{s.__node.animating&&(s.__node.animating=!1),s.__node.animationFrame&&cancelAnimationFrame(s.__node.animationFrame)};_.__addOndisconnected(i)}},M=(_,e,t)=>{if(typeof _.__branch=="object"&&_.__operator&&!_.__branchApplied){let n=_.__operator;_.__branchApplied=!0,_.__operator=(...i)=>{let s=n(...i);for(let r in _.__branch){let o=()=>{typeof _.__branch[r].then=="function"?_.__branch[r].then(s):_.__branch[r].then instanceof p&&_.__branch[r].then.__operator?_.__branch[r].then.__operator(s):s=_.__branch[r].then};typeof _.__branch[r].if=="function"?_.__branch[r].if(s)==!0&&o():_.__branch[r].if===s&&o()}return s}}if(_.__listeners){for(let n in _.__listeners)if(typeof _.__listeners[n]=="object"&&_.__listeners[n].branch&&!_.__listeners[n].branchApplied){let i=_.__listeners[n].callback;_.__listeners[n].branchApplied=!0,_.__listeners.callback=s=>{let r=()=>{typeof _.__listeners[n].branch.then=="function"?s=_.__listeners[n].branch.then(s):_.__listeners[n].branch.then instanceof p&&_.__listeners[n].branch.then.__operator?s=_.__listeners[n].branch.then.__operator(s):s=_.__listeners[n].branch.then};return typeof _.__listeners[n].branch.if=="function"?_.__listeners[n].branch.if(s)&&r():_.__listeners[n].branch.if===s&&r(),i(s)}}}},R=(_,e,t)=>{if(_.__listeners)for(let n in _.__listeners)typeof _.__listeners[n]=="object"&&_.__listeners[n].oncreate&&_.__listeners[n].callback(_.__listeners[n].oncreate)},T=(_,e,t)=>{if(_.__listeners)for(let n in _.__listeners)typeof _.__listeners[n]=="object"&&typeof _.__listeners[n].binding=="object"&&(_.__listeners.callback=_.__listeners.callback.bind(_.__listeners[n].binding))},$=(_,e,t)=>{if(_.__listeners){for(let n in _.__listeners)if(typeof _.__listeners[n]=="object"&&typeof _.__listeners[n].transform=="function"&&!_.__listeners[n].transformApplied){let i=_.__listeners[n].callback;_.__listeners[n].transformApplied=!0,_.__listeners.callback=s=>(s=_.__listeners[n].transform(s),i(s))}}},C=(_,e,t)=>{_.post&&!_.__operator?_.__setOperator(_.post):!_.__operator&&typeof _.get=="function"&&_.__setOperator(_.get),!_.get&&_.__operator,_.aliases&&_.aliases.forEach(n=>{t.set(n,_);let i=s=>{t.__node.nodes.delete(n)};_.__addOndisconnected(i)}),typeof t.__node.roots?.[_.__node.tag]=="object"&&_.get&&(t.__node.roots[_.__node.tag].get=_.get)},J={backprop:S,loop:I,animate:v,branching:M,triggerListenerOncreate:R,bindListener:T,transformListenerResult:$,substitute__operator:C};})(); +(()=>{function C(c=""){let t=n=>n.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i,"$2$3$4"),r=(n=>{let a=n.indexOf("=>")+1;return a<=0&&(a=n.indexOf("){")),a<=0&&(a=n.indexOf(") {")),n.slice(0,n.indexOf("{",a)+1)})(c),i=t(c),s;if(r.includes("function")){let n=r.split("(")[1].split(")")[0];s=new Function(n,i)}else if(r.substring(0,6)===i.substring(0,6)){let n=r.split("(")[1].split(")")[0];s=new Function(n,i.substring(i.indexOf("{")+1,i.length-1))}else try{s=(0,eval)(r+i+"}")}catch{}return s}var O=class{constructor(){this.pushToState={};this.data={};this.triggers={};this.setState=t=>{Object.assign(this.data,t);for(let e of Object.getOwnPropertyNames(t))this.triggers[e]&&this.triggers[e].forEach(r=>r.onchange(this.data[e]));return this.data};this.subscribeTrigger=(t,e)=>{if(t){this.triggers[t]||(this.triggers[t]=[]);let r=this.triggers[t].length;return this.triggers[t].push({idx:r,onchange:e}),this.triggers[t].length-1}else return};this.unsubscribeTrigger=(t,e)=>{let r=this.triggers[t];if(r)if(!e)delete this.triggers[t];else{let i;return r.find((n,a)=>{if(n.idx===e)return i=a,!0})&&r.splice(i,1),!0}};this.subscribeTriggerOnce=(t,e)=>{let r,i=s=>{e(s),this.unsubscribeTrigger(t,r)};r=this.subscribeTrigger(t,i)}}},R=new O;function S(c){this._state||(this._state={});for(let t in c)t==="_state"||t==="graph"||(this._state[t]=c[t],t in this?this[t]=c[t]:Object.defineProperty(this,t,{get:()=>{this._state[t]},set:e=>{this._state[t]=e,this.state.triggers[this._unique]&&this.setState({[this._unique]:this._state})},enumerable:!0,configurable:!0}))}var y=class{constructor(t={},e,r){this.nodes=new Map;this._initial={};this._unique=`${Math.random()}`;this.state=R;this.isLooping=!1;this.isAnimating=!1;this.looper=void 0;this.animation=void 0;this.forward=!0;this.backward=!1;this.reactive=!1;this.runSync=!1;this.firstRun=!0;this.DEBUGNODE=!1;this.addLocalState=S;this.operator=(...t)=>t;this.runOp=(...t)=>{this.DEBUGNODE&&console.time(this.tag);let e=this.operator(...t);return e instanceof Promise?e.then(r=>(r!==void 0&&this.setState({[this.tag]:r}),this.DEBUGNODE&&(console.timeEnd(this.tag),e!==void 0&&console.log(`${this.tag} result:`,e)),r)):(e!==void 0&&this.setState({[this.tag]:e}),this.DEBUGNODE&&(console.timeEnd(this.tag),e!==void 0&&console.log(`${this.tag} result:`,e))),e};this.setOperator=t=>(typeof t!="function"||(this.operator=t.bind(this)),t);this.runAsync=(...t)=>new Promise((e,r)=>{e(this.run(...t))});this.transformArgs=(t=[])=>t;this.isRunSync=()=>!(this.children&&this.forward||this.parent&&this.backward||this.repeat||this.delay||this.frame||this.recursive||this.branch);this.run=(...t)=>{if(typeof this.transformArgs=="function"&&(t=this.transformArgs(t,this)),!(this.firstRun&&(this.firstRun=!1,this.runSync=this.isRunSync(),this.animate&&!this.isAnimating&&this.runAnimation(this.animation,t),this.loop&&typeof this.loop=="number"&&!this.isLooping&&this.runLoop(this.looper,t),this.loop||this.animate)))return this.runSync?this.runOp(...t):new Promise(async e=>{if(this){let r=(s,n=0,...a)=>new Promise(async o=>{n++;let f=await s.runOp(...a);if(s.repeat){for(;n{o(await r(s,n,...a))},s.delay);break}else if(s.frame&&window?.requestAnimationFrame){requestAnimationFrame(async()=>{o(await r(s,n,...a))});break}else f=await s.runOp(...a);n++}if(n===s.repeat){o(f);return}}else if(s.recursive){for(;n{o(await r(s,n,...f))},s.delay);break}else if(s.frame&&window?.requestAnimationFrame){requestAnimationFrame(async()=>{o(await r(s,n,...f))});break}else f=await s.runOp(...f);n++}if(n===s.recursive){o(f);return}}else{o(f);return}}),i=async()=>{let s=await r(this,void 0,...t);return s!==void 0&&(this.backward&&this.parent instanceof y&&(Array.isArray(s)?await this.runParent(this,...s):await this.runParent(this,s)),this.children&&this.forward&&(Array.isArray(s)?await this.runChildren(this,...s):await this.runChildren(this,s)),this.branch&&this.runBranch(this,s)),s};this.delay?setTimeout(async()=>{e(await i())},this.delay):this.frame&&window?.requestAnimationFrame?requestAnimationFrame(async()=>{e(await i())}):e(await i())}else e(void 0)})};this.runParent=async(t,...e)=>{t.backward&&t.parent&&(typeof t.parent=="string"&&(t.graph&&t.graph?.get(t.parent)?(t.parent=t.graph,t.parent&&this.nodes.set(t.parent.tag,t.parent)):t.parent=this.nodes.get(t.parent)),t.parent instanceof y&&await t.parent.run(...e))};this.runChildren=async(t,...e)=>{if(typeof t.children=="object")for(let r in t.children)typeof t.children[r]=="string"?(t.graph&&t.graph?.get(t.children[r])&&(t.children[r]=t.graph.get(t.children[r]),t.nodes.get(t.children[r].tag)||t.nodes.set(t.children[r].tag,t.children[r])),!t.children[r]&&t.nodes.get(t.children[r])&&(t.children[r]=t.nodes.get(t.children[r]))):(typeof t.children[r]>"u"||t.children[r]===!0)&&(t.graph&&t.graph?.get(r)&&(t.children[r]=t.graph.get(r),t.nodes.get(t.children[r].tag)||t.nodes.set(t.children[r].tag,t.children[r])),!t.children[r]&&t.nodes.get(r)&&(t.children[r]=t.nodes.get(r))),t.children[r]?.runOp&&await t.children[r].run(...e)};this.runBranch=async(t,e)=>{if(t.branch){let r=Object.keys(t.branch);await Promise.all(r.map(async i=>{typeof t.branch[i].if=="object"&&(t.branch[i].if=A(t.branch[i].if));let s=!1;return typeof t.branch[i].if=="function"?s=t.branch[i].if(e):typeof e=="object"?A(e)===t.branch[i].if&&(s=!0):e===t.branch[i].if&&(s=!0),s&&(t.branch[i].then.run?Array.isArray(e)?await t.branch[i].then.run(...e):await t.branch[i].then.run(...e):typeof t.branch[i].then=="function"?Array.isArray(e)?await t.branch[i].then(...e):await t.branch[i].then(e):typeof t.branch[i].then=="string"&&(t.graph?t.branch[i].then=t.graph.nodes.get(t.branch[i].then):t.branch[i].then=t.nodes.get(t.branch[i].then),t.branch[i].then.run&&(Array.isArray(e)?await t.branch[i].then.run(...e):await t.branch[i].then.run(...e)))),s}))}};this.runAnimation=(t=this.animation,e=[])=>{if(this.animation=t,t||(this.animation=this.operator),this.animate&&!this.isAnimating&&"requestAnimationFrame"in window){this.isAnimating=!0;let r=async()=>{if(this.isAnimating){this.DEBUGNODE&&console.time(this.tag);let i=this.animation.call(this,...e);i instanceof Promise&&(i=await i),this.DEBUGNODE&&(console.timeEnd(this.tag),i!==void 0&&console.log(`${this.tag} result:`,i)),i!==void 0&&(this.tag&&this.setState({[this.tag]:i}),this.backward&&this.parent?.run&&(Array.isArray(i)?await this.runParent(this,...i):await this.runParent(this,i)),this.children&&this.forward&&(Array.isArray(i)?await this.runChildren(this,...i):await this.runChildren(this,i)),this.branch&&this.runBranch(this,i),this.setState({[this.tag]:i})),requestAnimationFrame(r)}};requestAnimationFrame(r)}};this.runLoop=(t=this.looper,e=[],r=this.loop)=>{if(this.looper=t,t||(this.looper=this.operator),typeof r=="number"&&!this.isLooping){this.isLooping=!0;let i=async()=>{if(this.isLooping){this.DEBUGNODE&&console.time(this.tag);let s=this.looper.call(this,...e);s instanceof Promise&&(s=await s),this.DEBUGNODE&&(console.timeEnd(this.tag),s!==void 0&&console.log(`${this.tag} result:`,s)),s!==void 0&&(this.tag&&this.setState({[this.tag]:s}),this.backward&&this.parent?.run&&(Array.isArray(s)?await this.runParent(this,...s):await this.runParent(this,s)),this.children&&this.forward&&(Array.isArray(s)?await this.runChildren(this,...s):await this.runChildren(this,s)),this.branch&&this.runBranch(this,s),this.setState({[this.tag]:s})),setTimeout(async()=>{await i()},r)}};i()}};this.setParent=t=>{this.parent=t,this.backward&&(this.runSync=!1)};this.setChildren=t=>{this.children=t,this.forward&&(this.runSync=!1)};this.add=(t={})=>(typeof t=="function"&&(t={operator:t}),t?.node instanceof y&&(t=t.node),t instanceof y||(t=new y(t.node??t,this,this.graph)),this.nodes.set(t.tag,t),this.graph&&(this.graph.nodes.set(t.tag,t),this.graph.nNodes=this.graph.nodes.size),t);this.remove=t=>{typeof t=="string"&&(t=this.nodes.get(t)),t?.tag&&(this.nodes.delete(t.tag),this.children[t.tag]&&delete this.children[t.tag],this.graph&&(this.graph.nodes.delete(t.tag),this.graph.nNodes=this.graph.nodes.size),this.nodes.forEach(e=>{e.nodes.get(e.tag)&&(e.nodes.delete(e.tag),e.children[e.tag]&&delete e.children[e.tag],e.parent?.tag===e.tag&&delete e.parent)}),t.ondelete&&t.ondelete(t)),typeof this._state=="object"&&this.state.unsubscribeTrigger(this._unique)};this.append=(t,e=this)=>{typeof t=="string"&&(t=this.nodes.get(t)),t?.nodes&&(e.addChildren(t),t.forward&&(t.runSync=!1))};this.subscribe=(t,e=this.tag)=>{if(typeof t=="string"&&(this.graph?t=this.graph.get(t):t=this.nodes.get(t)),typeof t=="function")return this.state.subscribeTrigger(e,t);if(t)return this.state.subscribeTrigger(e,r=>{t.run(r)})};this.unsubscribe=(t,e=this.tag)=>this.state.unsubscribeTrigger(e,t);this.subscribeState=t=>{if(this.reactive){if(typeof t=="string"&&(this.graph?t=this.graph.get(t):t=this.nodes.get(t)),typeof t=="function")return this.state.subscribeTrigger(this._unique,t);if(t)return this.state.subscribeTrigger(this._unique,e=>{t.run(e)})}else return};this.addChildren=t=>{this.children||(this.children={}),typeof t=="object"&&Object.assign(this.children,t),this.convertChildrenToNodes(),this.forward&&(this.runSync=!1)};this.callParent=(...t)=>{if(typeof this.parent=="string"&&(this.graph&&this.graph?.get(this.parent)?(this.parent=this.graph,this.parent&&this.nodes.set(this.parent.tag,this.parent)):this.parent=this.nodes.get(this.parent)),typeof this.parent?.operator=="function")return this.parent.runOp(...t)};this.callChildren=(...t)=>{let e;if(typeof this.children=="object")for(let r in this.children)this.children[r]?.runOp&&this.children[r].runOp(...t);return e};this.getProps=(t=this,e=!0)=>{let r={tag:t.tag,operator:t.operator,graph:t.graph,children:t.children,parent:t.parent,forward:t.forward,backward:t.bacward,loop:t.loop,animate:t.animate,frame:t.frame,delay:t.delay,recursive:t.recursive,repeat:t.repeat,branch:t.branch,oncreate:t.oncreate,reactive:t.reactive,DEBUGNODE:t.DEBUGNODE};if(e)return{tag:t.tag,operator:t.operator,graph:t.graph,children:t.children,parent:t.parent,forward:t.forward,backward:t.bacward,loop:t.loop,animate:t.animate,frame:t.frame,delay:t.delay,recursive:t.recursive,repeat:t.repeat,branch:t.branch,oncreate:t.oncreate,reactive:t.reactive,DEBUGNODE:t.DEBUGNODE,...this._initial};{let i={};for(let s in this._initial)i[s]=this[s];return Object.assign(r,i)}};this.setProps=(t={})=>{let e=Object.assign({},t);e.children&&(this.addChildren(t.children),delete e.children),e.operator&&(this.setOperator(t.operator),delete e.operator),Object.assign(e,t),this.runSync=this.isRunSync()};this.removeTree=t=>{if(t&&typeof t=="string"&&(t=this.nodes.get(t)),t?.nodes){let e={},r=i=>{if(typeof i.children=="object"&&!e[i.tag]){e[i.tag]=!0;for(let s in i.children)i.children[s].stopNode&&i.children[s].stopNode(),i.children[s].tag&&(this.nodes.get(i.children[s].tag)&&this.nodes.delete(i.children[s].tag),this.nodes.forEach(n=>{n.nodes.get(i.children[s].tag)&&n.nodes.delete(i.children[s].tag),n.children[s]instanceof y&&delete n.children[s]}),r(i.children[s]))}};t.stopNode&&t.stopNode(),t.tag&&(this.nodes.delete(t.tag),this.children[t.tag]&&delete this.children[t.tag],this.parent?.tag===t.tag&&delete this.parent,this[t.tag]instanceof y&&delete this[t.tag],this.nodes.forEach(i=>{i?.tag&&(i.nodes.get(i.tag)&&i.nodes.delete(i.tag),i.children[i.tag]instanceof y&&delete i.children[i.tag])}),r(t),this.graph?this.graph.removeTree(t,e):t.ondelete&&t.ondelete(t))}};this.checkNodesHaveChildMapped=(t,e,r={})=>{let i=t.tag;i||(i=t.name),r[i]||(r[i]=!0,t.children&&e.tag in t.children&&t.children[e.tag]instanceof y&&(t.nodes.get(e.tag)||t.nodes.set(e.tag,e),t.children[e.tag]=e,t.firstRun||(t.firstRun=!0)),t.parent instanceof y&&(t.nodes.get(e.tag)&&t.parent.nodes.set(e.tag,e),t.parent.children?this.checkNodesHaveChildMapped(t.parent,e,r):t.nodes&&t.nodes.forEach(s=>{r[s.tag]||this.checkNodesHaveChildMapped(s,e,r)})),t.graph&&t.parent&&t.parent.name!==t.graph.name&&t.graph.nodes.forEach(s=>{r[s.tag]||this.checkNodesHaveChildMapped(s,e,r)}))};this.convertChildrenToNodes=(t=this)=>{if(t?.children){for(let e in t.children)if(!(t.children[e]instanceof y))if(typeof t.children[e]=="object")t.children[e].tag||(t.children[e].tag=e),t.nodes.get(t.children[e].tag)||(t.children[e]=new y(t.children[e],t,t.graph),this.checkNodesHaveChildMapped(t,t.children[e]));else{if(typeof t.children[e]>"u"||t.children[e]==!0)t.children[e]=t.graph.get(e),t.children[e]||(t.children[e]=t.nodes.get(e));else if(typeof t.children[e]=="string"){let r=t.children[e];t.children[e]=t.graph.get(r),t.children[e]||(t.children[e]=t.nodes.get(e))}t.children[e]instanceof y&&(t.nodes.set(t.children[e].tag,t.children[e]),this.checkNodesHaveChildMapped(t,t.children[e]),t.children[e].tag in t||(t[t.children[e].tag]=t.children[e]))}}return t.children};this.stopLooping=(t=this)=>{t.isLooping=!1};this.stopAnimating=(t=this)=>{t.isAnimating=!1};this.stopNode=(t=this)=>{t.stopAnimating(t),t.stopLooping(t)};this.subscribeNode=t=>{if(typeof t=="string"&&(t=this.nodes.get(t)),t.tag&&this.nodes.set(t.tag,t),t)return this.state.subscribeTrigger(this.tag,e=>{Array.isArray(e)?t.run(...e):t.run(e)})};this.print=(t=this,e=!0,r=[])=>{let i=new y;if(typeof t=="string"&&(t=this.nodes.get(t)),t instanceof y){r.push(t.tag);let s={tag:t.tag,operator:t.operator.toString()};if(t.parent&&(s.parent=t.parent.tag),typeof t.children=="object")for(let n in t.children)return typeof t.children[n]=="string"?t.children[n]:r.includes(t.children[n].tag)?t.children[n].tag:e?t.children[n].print(t.children[n],e,r):t.children[n].tag;for(let n in t)n==="parent"||n==="children"||typeof i[n]>"u"&&(typeof t[n]=="function"?s[n]=t[n].toString():typeof t[n]=="object"?s[n]=JSON.stringifyWithCircularRefs(t[n]):s[n]=t[n]);return JSON.stringify(s)}};this.reconstruct=t=>{let e=j(t);if(e)return this.add(e)};this.setState=t=>{this.state.setState(t)};this.DEBUGNODES=(t=!0)=>{this.DEBUGNODE=t,this.nodes.forEach(e=>{t?e.DEBUGNODE=!0:e.DEBUGNODE=!1})};if(typeof t=="function"&&(t={operator:t}),typeof t=="object"){if(t instanceof y&&t._initial&&Object.assign(t,t._initial),t instanceof v){let s=t;t={source:s,operator:n=>{if(typeof n=="object"){let a={};for(let o in n)typeof s[o]=="function"?Array.isArray(n[o])?a[o]=s[o](...n[o]):a[o]=s[o](n[o]):(s[o]=n[o],a[o]=s[o]);return a}return s}},s.operator&&(t.operator=s.operator),s.children&&(t.children=s.children),s.forward&&(t.forward=s.forward),s.backward&&(t.backward=s.backward),s.repeat&&(t.repeat=s.repeat),s.recursive&&(t.recursive=s.recursive),s.loop&&(t.loop=s.loop),s.animate&&(t.animate=s.animate),s.looper&&(t.looper=s.looper),s.animation&&(t.animation=s.animation),s.delay&&(t.delay=s.delay),s.oncreate&&(t.oncreate=s.oncreate),s.node&&s.node._initial&&Object.assign(t,s.node._initial),s._initial&&Object.assign(t,s._initial),s.tag&&(t.tag=s.tag),this.nodes=s.nodes,s.node=this,r&&s.nodes.forEach(n=>{r.nodes.get(n.tag)||(r.nodes.set(n.tag,n),r.nNodes++)})}if(typeof e=="string"&&(r?e=r.nodes.get(e):e=void 0),t.tag&&(r||e)){let s;if(r?.nodes&&(s=r.nodes.get(t.tag)),!s&&e?.nodes&&(s=e.nodes.get(t.tag)),s){this.reactive&&this.addLocalState(s),this.source||(this.source=s);let n=s.getProps();delete n.graph,delete n.parent;for(let a in n)t[a]=n[a]}}t?.operator&&(t.operator=this.setOperator(t.operator)),!t.tag&&r?t.tag=`node${r.nNodes}`:t.tag||(t.tag=`node${Math.floor(Math.random()*1e10)}`);let i=Object.getOwnPropertyNames(this);for(let s in t)i.includes(s)||(this._initial[s]=t[s]);if(t.children&&(this._initial.children=Object.assign({},t.children)),Object.assign(this,t),this.tag||(r?this.tag=`node${r.nNodes}`:this.tag=`node${Math.floor(Math.random()*1e10)}`),r&&(this.graph=r,r.nodes.get(this.tag)&&(this.tag=`${this.tag}${r.nNodes+1}`),r.nodes.set(this.tag,this),r.nNodes++,this.state=r.state),this.reactive&&(S(t),typeof this.reactive=="function"&&this.state.subscribeTrigger(this._unique,this.reactive)),typeof e=="object"&&(this.parent=e,(e instanceof y||e instanceof v)&&e.nodes.set(this.tag,this)),typeof t.tree=="object")for(let s in t.tree){typeof t.tree[s]=="object"&&(!t.tree[s]).tag&&(t.tree[s].tag=s);let n=new y(t.tree[s],this,r);this.nodes.set(n.tag,n)}this.children&&this.convertChildrenToNodes(this),(this.parent instanceof y||this.parent instanceof v)&&this.checkNodesHaveChildMapped(this.parent,this),typeof this.oncreate=="function"&&this.oncreate(this),this.firstRun||(this.firstRun=!0),this.animation&&!this.animate&&(this.animate=!0)}else return t}},v=class{constructor(t,e,r){this.nNodes=0;this.nodes=new Map;this.state=new O;this._unique=`${Math.random()}`;this.tree={};this.addLocalState=S;this.add=(t={})=>{t?.node instanceof y&&(t=t.node);let e=t;return t instanceof y?(this.nNodes=this.nodes.size,t.tag&&(this.tree[t.tag]=e,this.nodes.set(t.tag,t))):t=new y(e?.node??e,this,this),t};this.setTree=(t=this.tree)=>{if(!!t){for(let e in t){let r=this.nodes.get(e);if(r){if(typeof t[e]=="function")r.setOperator(t[e]);else if(typeof t[e]=="object")if(t[e]instanceof y)this.add(t[e]);else if(t[e]instanceof v){let i=t[e],s={};i.operator&&(s.operator=i.operator),i.children&&(s.children=i.children),i.forward&&(s.forward=i.forward),i.backward&&(s.backward=i.backward),i.repeat&&(s.repeat=i.repeat),i.recursive&&(s.recursive=i.recursive),i.loop&&(s.loop=i.loop),i.animate&&(s.animate=i.animate),i.looper&&(s.looper=i.looper),i.animation&&(s.animation=i.animation),i.delay&&(s.delay=i.delay),i.tag&&(s.tag=i.tag),i.oncreate&&(s.oncreate=i.oncreate),i.node?._initial&&Object.assign(s,i.node._initial),s.nodes=i.nodes,s.source=i,r.setProps(s)}else r.setProps(t[e])}else if(typeof t[e]=="function")this.add({tag:e,operator:t[e]});else if(typeof t[e]=="object"&&!Array.isArray(t[e])){t[e].tag||(t[e].tag=e);let i=this.add(t[e]);t[e].aliases&&t[e].aliases.forEach(s=>{this.nodes.set(s,i)})}else this.add({tag:e,operator:(...i)=>t[e]})}this.nodes.forEach(e=>{if(typeof e.children=="object")for(let r in e.children)typeof e.children[r]=="string"?this.nodes.get(e.children[r])&&(e.children[r]=this.nodes.get(e.children[r])):(e.children[r]===!0||typeof e.children[r]>"u")&&this.nodes.get(r)&&(e.children[r]=this.nodes.get(r)),e.children[r]instanceof y&&e.checkNodesHaveChildMapped(e,e.children[r]);typeof e.parent=="string"&&this.nodes.get(e.parent)&&(e.parent=this.nodes.get(e.parent),e.nodes.set(e.parent.tag,e.parent))})}};this.get=t=>this.nodes.get(t);this.set=t=>this.nodes.set(t.tag,t);this.run=(t,...e)=>{if(typeof t=="string"&&(t=this.nodes.get(t)),t?.run)return t.run(...e)};this.runAsync=(t,...e)=>(typeof t=="string"&&(t=this.nodes.get(t)),t?.run?new Promise((r,i)=>{r(t.run(...e))}):new Promise((r,i)=>{r(void 0)}));this.removeTree=(t,e)=>{if(typeof t=="string"&&(t=this.nodes.get(t)),t?.nodes){e||(e={});let r=i=>{i.children&&!e[i.tag]&&(e[i.tag]=!0,Array.isArray(i.children)?i.children.forEach(s=>{s.stopNode&&s.stopNode(),s.tag&&this.nodes.get(s.tag)&&this.nodes.delete(s.tag),this.nodes.forEach(n=>{n.nodes.get(s.tag)&&n.nodes.delete(s.tag)}),r(s)}):typeof i.children=="object"&&(i.stopNode&&i.stopNode(),i.tag&&this.nodes.get(i.tag)&&this.nodes.delete(i.tag),this.nodes.forEach(s=>{s.nodes.get(i.tag)&&s.nodes.delete(i.tag)}),r(i)))};t.stopNode&&t.stopNode(),t.tag&&(this.nodes.delete(t.tag),this.nodes.forEach(i=>{i.nodes.get(i.tag)&&i.nodes.delete(i.tag)}),this.nNodes=this.nodes.size,r(t)),t.ondelete&&t.ondelete(t)}return t};this.remove=t=>(typeof t=="string"&&(t=this.nodes.get(t)),t?.nodes&&(t.stopNode&&t.stopNode(),t?.tag&&this.nodes.get(t.tag)&&(this.nodes.delete(t.tag),this.nodes.forEach(e=>{e.nodes.get(e.tag)&&e.nodes.delete(e.tag)})),t.ondelete&&t.ondelete(t)),t);this.append=(t,e)=>{e.addChildren(t)};this.callParent=async(t,...e)=>{if(t?.parent)return await t.callParent(...e)};this.callChildren=async(t,...e)=>{if(t?.children)return await t.callChildren(...e)};this.subscribe=(t,e)=>{if(!!e){if(t?.subscribe&&typeof e=="function")return t.subscribe(e);if(e instanceof y||typeof e=="string")return this.subscribeNode(t,e);if(typeof t=="string")return this.state.subscribeTrigger(t,e)}};this.unsubscribe=(t,e)=>this.state.unsubscribeTrigger(t,e);this.subscribeState=t=>{if(this.reactive){if(typeof t=="string"&&(this.graph?t=this.graph.get(t):t=this.nodes.get(t)),typeof t=="function")return this.state.subscribeTrigger(this._unique,t);if(t)return this.state.subscribeTrigger(this._unique,e=>{t.run(e)})}else return};this.subscribeNode=(t,e)=>{let r;if(t?.tag?r=t.tag:typeof t=="string"&&(r=t),typeof e=="string"&&(e=this.nodes.get(e)),t&&e)return this.state.subscribeTrigger(r,s=>{Array.isArray(s)?e.run(...s):e.run(s)})};this.stopNode=t=>{typeof t=="string"&&(t=this.nodes.get(t)),t?.stopNode&&t.stopNode()};this.print=(t,e=!0)=>{if(t?.print)return t.print(t,e);{let r="{";return this.nodes.forEach(i=>{r+=` +"${i.tag}:${i.print(i,e)}"`}),r}};this.reconstruct=t=>{let e=j(t);if(e)return this.add(e)};this.create=(t,e,r)=>P(t,e,r,this);this.setState=t=>{this.state.setState(t)};this.DEBUGNODES=(t=!0)=>{this.nodes.forEach(e=>{t?e.DEBUGNODE=!0:e.DEBUGNODE=!1})};this.tag=e||`graph${Math.floor(Math.random()*1e11)}`,r&&(r.reactive?this.addLocalState(r):Object.assign(this,r),this._initial=r),(t||Object.keys(this.tree).length>0)&&this.setTree(t)}};function E(c,t,e){let r=j(c);if(r)return new y(r,t,e)}function j(c="{}"){try{let t=typeof c=="string"?JSON.parse(c):c,e=r=>{for(let i in r)if(typeof r[i]=="string"){let s=C(r[i]);typeof s=="function"&&(r[i]=s)}else typeof r[i]=="object"&&e(r[i]);return r};return e(t)}catch(t){console.error(t);return}}var w=function(){let c=new Map,t=[],e=["this"];function r(){c.clear(),t.length=0,e.length=1}function i(n,a){var o=t.length-1,f=t[o];if(typeof f=="object")if(f[n]===a||o===0)e.push(n),t.push(a.pushed);else for(;o-->=0;){if(f=t[o],typeof f=="object"&&f[n]===a){o+=2,t.length=o,e.length=o,--o,t[o]=a,e[o]=n;break}o--}}function s(n,a){if(a!=null&&typeof a=="object"){n&&i(n,a);let o=c.get(a);if(o)return"[Circular Reference]"+o;c.set(a,e.join("."))}return a}return function(a,o){try{return t.push(a),JSON.stringify(a,s,o)}finally{r()}}}();JSON.stringifyWithCircularRefs===void 0&&(JSON.stringifyWithCircularRefs=w);var A=function(){let c=new Map,t=[],e=["this"];function r(){c.clear(),t.length=0,e.length=1}function i(n,a){var o=t.length-1;if(t[o]){var f=t[o];if(typeof f=="object")if(f[n]===a||o===0)e.push(n),t.push(a.pushed);else for(;o-->=0;){if(f=t[o],typeof f=="object"&&f[n]===a){o+=2,t.length=o,e.length=o,--o,t[o]=a,e[o]=n;break}o++}}}function s(n,a){let o;if(a!=null)if(typeof a=="object"){let f=a.constructor.name;n&&f==="Object"&&i(n,a);let b=c.get(a);if(b)return"[Circular Reference]"+b;if(c.set(a,e.join(".")),f==="Array")a.length>20?o=a.slice(a.length-20):o=a;else if(f.includes("Set"))o=Array.from(a);else if(f!=="Object"&&f!=="Number"&&f!=="String"&&f!=="Boolean")o="instanceof_"+f;else if(f==="Object"){let h={};for(let l in a)if(a[l]==null)h[l]=a[l];else if(Array.isArray(a[l]))a[l].length>20?h[l]=a[l].slice(a[l].length-20):h[l]=a[l];else if(a[l].constructor.name==="Object"){h[l]={};for(let g in a[l])if(Array.isArray(a[l][g]))a[l][g].length>20?h[l][g]=a[l][g].slice(a[l][g].length-20):h[l][g]=a[l][g];else if(a[l][g]!=null){let u=a[l][g].constructor.name;u.includes("Set")?h[l][g]=Array.from(a[l][g]):u!=="Number"&&u!=="String"&&u!=="Boolean"?h[l][g]="instanceof_"+u:h[l][g]=a[l][g]}else h[l][g]=a[l][g]}else{let g=a[l].constructor.name;g.includes("Set")?h[l]=Array.from(a[l]):g!=="Number"&&g!=="String"&&g!=="Boolean"?h[l]="instanceof_"+g:h[l]=a[l]}o=h}else o=a}else o=a;return o}return function(a,o){t.push(a);let f=JSON.stringify(a,s,o);return r(),f}}();JSON.stringifyFast===void 0&&(JSON.stringifyFast=A);function P(c,t,e,r){return typeof e=="object"?(e.operator=c,new y(e,t,r)):new y({operator:c},t,r)}var G=class extends v{constructor(e={}){super(void 0,e.name?e.name:`service${Math.floor(Math.random()*1e14)}`,e.props);this.routes={};this.loadDefaultRoutes=!1;this.keepState=!0;this.firstLoad=!0;this.customRoutes={};this.customChildren={};this.init=e=>{e?e=Object.assign({},e):e={},e.customRoutes?Object.assign(e.customRoutes,this.customRoutes):e.customRoutes=this.customRoutes,e.customChildren?Object.assign(e.customChildren,this.customChildren):e.customChildren=this.customChildren,Array.isArray(e.routes)?e.routes.forEach(r=>{this.load(r,e.includeClassName,e.routeFormat,e.customRoutes,e.customChildren,e.sharedState)}):(e.routes||(Object.keys(this.routes).length>0||this.loadDefaultRoutes)&&this.firstLoad)&&this.load(e.routes,e.includeClassName,e.routeFormat,e.customRoutes,e.customChildren,e.sharedState)};this.load=(e,r=!0,i=".",s,n,a=!0)=>{if(!e&&!this.loadDefaultRoutes&&(Object.keys(this.routes).length>0||this.firstLoad))return;this.firstLoad&&(this.firstLoad=!1),s?s=Object.assign(this.customRoutes,s):s=this.customRoutes;let o,f={};if(e){if(!(e instanceof v)&&e?.name&&!e.setTree)if(e.module){let h=e;e={},Object.getOwnPropertyNames(e.module).forEach(l=>{r?e[h.name+i+l]=e.module[l]:e[l]=e.module[l]})}else typeof e=="function"&&(o=new e({loadDefaultRoutes:this.loadDefaultRoutes}),o.load(),a&&(o.state=this.state),e=o.routes,o.customRoutes&&!this.customRoutes?this.customRoutes=o.customRoutes:o.customRoutes&&this.customRoutes&&Object.assign(this.customRoutes,o.customRoutes),o.customChildren&&!this.customChildren?this.customChildren=o.customChildren:o.customChildren&&this.customChildren&&Object.assign(this.customChildren,o.customChildren));else if(e instanceof v||e.source instanceof v||e.setTree){if(o=e,e={},a&&(o.state=this.state),r){let h=o.name;h||(h=o.tag,o.name=h),h||(h=`graph${Math.floor(Math.random()*1e15)}`,o.name=h,o.tag=h)}o.customRoutes&&!this.customRoutes?this.customRoutes=o.customRoutes:o.customRoutes&&this.customRoutes&&Object.assign(this.customRoutes,o.customRoutes),o.customChildren&&!this.customChildren?this.customChildren=o.customChildren:o.customChildren&&this.customChildren&&Object.assign(this.customChildren,o.customChildren),o.nodes.forEach(h=>{e[h.tag]=h;let l={},g=(u,p)=>{if((!l[u.tag]||p&&r&&!l[p?.tag+i+u.tag])&&(p?l[p.tag+i+u.tag]=!0:l[u.tag]=!0,u instanceof v||u.source instanceof v||u.setTree)){if(a&&(u.state=this.state),r){let d=u.name;d||(d=u.tag,u.name=d),d||(d=`graph${Math.floor(Math.random()*1e15)}`,u.name=d,u.tag=d)}u.nodes.forEach(d=>{r&&!e[u.tag+i+d.tag]?e[u.tag+i+d.tag]=d:e[d.tag]||(e[d.tag]=d),g(d,u)})}};g(h)})}else if(typeof e=="object"){let h=e.constructor.name;if(h==="Object"&&(h=Object.prototype.toString.call(e),h&&(h=h.split(" ")[1]),h&&(h=h.split("]")[0])),h&&h!=="Object"){let l=e;e={},Object.getOwnPropertyNames(l).forEach(g=>{r?e[h+i+g]=l[g]:e[g]=l[g]})}}if((o instanceof v||o?.setTree)&&o.name&&r){e=Object.assign({},e);for(let h in e){let l=e[h];delete e[h],e[o.name+i+h]=l}}}if(this.loadDefaultRoutes){let h=Object.assign({},this.defaultRoutes);e?(Object.assign(h,this.routes),e=Object.assign(h,e)):e=Object.assign(h,this.routes),this.loadDefaultRoutes=!1}e||(e=this.routes);let b=0;for(let h in e){b++;let l=(g,u)=>{if(typeof g=="object"&&(g.tag||(g.tag=u),typeof g?.children=="object")){e:for(let p in g.children)if(b++,typeof g.children[p]=="object"){let d=g.children[p];if(d.tag&&f[d.tag])continue;if(n){for(let N in n)if(d=n[N](d,p,g,e,f),!d)continue e}d.id&&!d.tag&&(d.tag=d.id);let m;if(d.tag)if(f[d.tag]){let N=`${d.tag}${b}`;f[N]=d,d.tag=N,l(f[N],p),m=N}else f[d.tag]=d,l(f[d.tag],p),m=d.tag;else if(f[p]){let N=`${p}${b}`;f[N]=d,d.tag=N,l(f[N],p),m=N}else f[p]=d,l(f[p],p),m=p;o?.name&&r?(f[o.name+i+m]=d,delete f[m]):f[m]=d}}};f[h]=e[h],l(e[h],h)}e:for(let h in f)if(typeof f[h]=="object"){let l=f[h];if(typeof l=="object"){if(s){for(let g in s)if(l=s[g](l,h,f),!l)continue e}l.get&&l.get,l.post,l.delete,l.put,l.head,l.patch,l.options,l.connect,l.trace,l.post&&!l.operator?f[h].operator=l.post:!l.operator&&typeof l.get=="function"&&(f[h].operator=l.get)}}for(let h in e)typeof e[h]=="object"?this.routes[h]?typeof this.routes[h]=="object"?Object.assign(this.routes[h],e[h]):this.routes[h]=e[h]:this.routes[h]=e[h]:this.routes[h]?typeof this.routes[h]=="object"?Object.assign(this.routes[h],e[h]):this.routes[h]=e[h]:this.routes[h]=e[h];if(o)for(let h in this.routes)(this.routes[h]instanceof y||this.routes[h].constructor.name.includes("GraphNode"))&&(this.nodes.set(h,this.routes[h]),this.nNodes=this.nodes.size);else this.setTree(this.routes);for(let h in this.routes)this.routes[h]?.aliases&&this.routes[h].aliases.forEach(g=>{o?.name&&r?e[o.name+i+g]=this.routes[h]:e[g]=this.routes[h]});return this.routes};this.unload=(e=this.routes)=>{if(!e)return;let r;!(e instanceof G)&&typeof e=="function"?(r=new G,e=r.routes):e instanceof G&&(e=e.routes);for(let i in e)delete this.routes[i],this.nodes.get(i)&&this.remove(i);return this.routes};this.handleMethod=(e,r,i)=>{let s=r.toLowerCase(),n=this.nodes.get(e);return n||(n=this.routes[e],n||(n=this.tree[e])),n?.[s]?n[s]instanceof Function?n[s](i):(i&&(n[s]=i),n[s]):this.handleServiceMessage({route:e,args:i,method:r})};this.transmit=(...e)=>typeof e[0]=="object"?e[0].method?this.handleMethod(e[0].route,e[0].method,e[0].args):e[0].route?this.handleServiceMessage(e[0]):e[0].node?this.handleGraphNodeCall(e[0].node,e[0].args):(this.keepState&&(e[0].route&&this.setState({[e[0].route]:e[0].args}),e[0].node&&this.setState({[e[0].node]:e[0].args})),e):e;this.receive=(...e)=>{if(e[0]&&typeof e[0]=="string"){let r=e[0].substring(0,8);(r.includes("{")||r.includes("["))&&(r.includes("\\")&&(e[0]=e[0].replace(/\\/g,"")),e[0][0]==='"'&&(e[0]=e[0].substring(1,e[0].length-1)),e[0]=JSON.parse(e[0]))}return typeof e[0]=="object"?e[0].method?this.handleMethod(e[0].route,e[0].method,e[0].args):e[0].route?this.handleServiceMessage(e[0]):e[0].node?this.handleGraphNodeCall(e[0].node,e[0].args):(this.keepState&&(e[0].route&&this.setState({[e[0].route]:e[0].args}),e[0].node&&this.setState({[e[0].node]:e[0].args})),e):e};this.pipe=(e,r,i,s,n)=>{if(e instanceof y)return n?e.subscribe(a=>{let o=n(a);o!==void 0?this.transmit({route:r,args:o,method:s}):this.transmit({route:r,args:a,method:s},i)}):this.subscribe(e,a=>{this.transmit({route:r,args:a,method:s},i)});if(typeof e=="string")return this.subscribe(e,a=>{this.transmit({route:r,args:a,method:s},i)})};this.pipeOnce=(e,r,i,s,n)=>{if(e instanceof y)return n?e.state.subscribeTriggerOnce(e.tag,a=>{let o=n(a);o!==void 0?this.transmit({route:r,args:o,method:s}):this.transmit({route:r,args:a,method:s},i)}):this.state.subscribeTriggerOnce(e.tag,a=>{this.transmit({route:r,args:a,method:s},i)});if(typeof e=="string")return this.state.subscribeTriggerOnce(e,a=>{this.transmit({route:r,args:a,method:s},i)})};this.terminate=(...e)=>{this.nodes.forEach(r=>{r.stopNode()})};this.recursivelyAssign=(e,r)=>{for(let i in r)typeof r[i]=="object"&&!Array.isArray(r[i])?typeof e[i]=="object"&&!Array.isArray(e[i])?this.recursivelyAssign(e[i],r[i]):e[i]=this.recursivelyAssign({},r[i]):e[i]=r[i];return e};this.defaultRoutes={"/":{get:()=>this.print(),aliases:[""]},ping:()=>(console.log("ping"),"pong"),echo:(...e)=>(this.transmit(...e),e),assign:e=>typeof e=="object"?(Object.assign(this,e),!0):!1,recursivelyAssign:e=>typeof e=="object"?(this.recursivelyAssign(this,e),!0):!1,log:{post:(...e)=>{console.log("Log: ",...e)},aliases:["info"]},error:e=>{let r=new Error(e);return console.error(e),r},state:e=>e?this.state.data[e]:this.state.data,printState:e=>e?w(this.state.data[e]):w(this.state.data),spliceTypedArray:this.spliceTypedArray,transmit:this.transmit,receive:this.receive,load:this.load,unload:this.unload,pipe:this.pipe,terminate:this.terminate,run:this.run,subscribe:this.subscribe,subscribeNode:this.subscribeNode,unsubscribe:this.unsubscribe,stopNode:this.stopNode,get:this.get,add:this.add,remove:this.remove,setTree:this.setTree,setState:this.setState,print:this.print,reconstruct:this.reconstruct,handleMethod:this.handleMethod,handleServiceMessage:this.handleServiceMessage,handleGraphNodeCall:this.handleGraphNodeCall};e.name?this.name=e.name:e.name=this.tag,"loadDefaultRoutes"in e&&(this.loadDefaultRoutes=e.loadDefaultRoutes,this.routes=Object.assign(this.defaultRoutes,this.routes)),(e||Object.keys(this.routes).length>0)&&this.init(e)}handleServiceMessage(e){let r;return typeof e=="object"&&(e.route?r=e.route:e.node&&(r=e.node)),r?Array.isArray(e.args)?this.run(r,...e.args):this.run(r,e.args):e}handleGraphNodeCall(e,r){if(!e)return r;if(r?.args)this.handleServiceMessage(r);else return Array.isArray(r)?this.run(e,...r):this.run(e,r)}isTypedArray(e){return ArrayBuffer.isView(e)&&Object.prototype.toString.call(e)!=="[object DataView]"}spliceTypedArray(e,r,i){let s=e.subarray(0,r),n;i&&(n=e.subarray(i+1));let a;return(s.length>0||n?.length>0)&&(a=new e.constructor(s.length+n.length)),s.length>0&&a.set(s),n&&n.length>0&&a.set(n,s.length),a}};var B={setRoute:function(c,t){if(typeof c=="string"&&(c=C(c)),typeof c=="function"){if(t||(t=c.name),this.graph.get(t))this.graph.get(t).setOperator(c.bind(this.graph.get(t)));else{let e=this.graph.add({tag:t,operator:c});this.graph instanceof G&&this.graph.load({[t]:e})}return!0}return!1},setNode:function(c,t){return typeof c=="string"&&(c=C(c)),typeof c=="function"?(t||(t=c.name),this.graph.get(t)?this.graph.get(t).setOperator(c):this.graph.add({tag:t,operator:c}),!0):!1},setMethod:function(c,t,e){return typeof t=="string"&&(t=C(t)),typeof t=="function"?(e||(e=t.name),this.graph.get(c)?this.graph.get(c)[e]=t:this.graph.add({tag:e,[e]:t}),!0):!1},assignRoute:function(c,t){this.graph.get(c)&&typeof t=="object"&&Object.assign(this.graph.get(c),t)},transferClass:(c,t)=>{if(typeof c=="object"){let e=c.toString();return{route:"receiveClass",args:[e,t]}}return!1},receiveClass:function(c,t){if(typeof c=="string"&&c.indexOf("class")===0){let e=(0,eval)("("+c+")"),r=t;return r||(r=e.name),this.graph[r]=e,!0}return!1},setGlobal:(c,t)=>(globalThis[c]=t,!0),assignGlobalObject:(c,t)=>globalThis[c]?(typeof t=="object"&&Object.assign(globalThis[c],t),!0):!1,setValue:function(c,t){return this.graph[c]=t,!0},assignObject:function(c,t){return this.graph[c]?(typeof t=="object"&&Object.assign(this.graph[c],t),!0):!1},setGlobalFunction:(c,t)=>(typeof c=="string"&&(c=C(c)),typeof c=="function"?(t||(t=c.name),globalThis[t]=c,!0):!1),assignFunctionToGlobalObject:function(c,t,e){return globalThis[c]?(typeof t=="string"&&(t=C(t)),typeof t=="function"?(e||(e=t.name),this.graph[c][e]=t,!0):!1):!1},setFunction:function(c,t){return typeof c=="string"&&(c=C(c)),typeof c=="function"?(t||(t=c.name),this.graph[t]=c,!0):!1},assignFunctionToObject:function(c,t,e){return this.graph[c]?(typeof t=="string"&&(t=C(t)),typeof t=="function"?(e||(e=t.name),this.graph[c][e]=t,!0):!1):!1}};var T=class extends G{constructor(e){super(e);this.name="router";this.connections={};this.sources={};this.services={};this.serviceConnections={};this.users={};this.addUser=async(e,r,i,s)=>{e._id||(e._id=`user${Math.floor(Math.random()*1e15)}`);let n=Object.assign({},e);if(r){for(let u in r)typeof r[u]=="object"&&(r[u].connection._id||await new Promise((p,d)=>{let m=performance.now(),N=()=>{r[u].connection._id?p(!0):performance.now()-m>3e3?(delete r[u],d(!1)):setTimeout(()=>{N()},100)};N()}).catch(p=>{console.error("Connections timed out:",p)}));for(let u in r)r[u]=this.addConnection(r[u],n._id)}if(i)for(let u in i)this.openConnection(i[u].service,i[u],n._id,i[u].args);let a=(u,...p)=>{let d=this.getConnection(n._id,"send");if(d?.send)return d.send(u,...p)},o=(u,p,...d)=>{let m=this.getConnection(n._id,"request");if(m?.request)return m.request(u,p,...d)},f=(u,p,d,...m)=>{let N=this.getConnection(n._id,"post");if(N?.post)return N.post(u,p,d,...m)},b=(u,p,d,...m)=>{let N=this.getConnection(n._id,"run");if(N?.run)return N.run(u,p,d,...m)},h=(u,p,...d)=>{let m=this.getConnection(n._id,"subscribe");if(m?.subscribe)return m.subscribe(u,p,...d)},l=(u,p,...d)=>{let m=this.getConnection(n._id,"unsubscribe");if(m?.unsubscribe)return m.unsubscribe(u,p,...d)},g=()=>this.removeUser(n);if(n.send=a,n.request=o,n.post=f,n.run=b,n.subscribe=h,n.unsubscribe=l,n.terminate=g,this.users[n._id]=n,r&&!s){let u={},p=!1;Object.keys(r).map((d,m)=>{r[d]?._id&&(u[`${m}`]=r[d]?._id,p=!0)}),p&&n.send({route:"addUser",args:[{_id:n._id},u,void 0,!0]})}return n};this.getConnection=(e,r)=>{if(this.sources[e])if(this.order)for(let i=0;i{if(this.sources[e]){if(!i&&!r)return this.sources[e];let s={};for(let n in this.sources[e])if(typeof this.sources[e][n]=="object"){if(this.sources[e][n]._id){let a=!0;r&&!this.sources[e][n][r]&&(a=!1);for(let o in i)if(typeof this.sources[e][n][o]=="object"&&typeof i[o]=="object"){for(let f in i[o])if(i[o][f]!==this.sources[e][n][o][f]){a=!1;break}}else if(this.sources[e][n][o]!==i[o])a=!1;else{a=!1;break}a&&this.getConnection(this.sources[e][n],r)&&(s[this.sources[e][n]._id]=this.sources[e][n])}else for(let a in this.sources[e][n])if(typeof this.sources[e][n][a]=="object"){let o=!0;r&&!this.sources[e][n][a][r]&&(o=!1);for(let f in i)if(typeof this.sources[e][n][a][f]=="object"&&typeof i[f]=="object"){for(let b in i[f])if(i[f][b]!==this.sources[e][n][a][f][b]){o=!1;break}}else if(this.sources[e][n][a][f]!==i[f])o=!1;else{o=!1;break}o&&(s[this.sources[e][n][a]._id]=this.sources[e][n][a])}}}};this.addConnection=(e,r)=>{let i={};if(typeof e=="string"){if(this.connections[e])e=this.connections[e];else for(let s in this.serviceConnections)for(let n in this.serviceConnections[s])if(this.serviceConnections[s][n][e]){e={connection:this.serviceConnections[s][n][e]},e.service=s,i.connectionType=s,i.connectionsKey=n;break}typeof e=="string"&&this.nodes.get(e)&&(e={connection:this.nodes.get(e)})}if(!(!e||typeof e=="string")){if(r&&(i.source=r),e.connection instanceof y){i.connection=e.connection;let s=i.connection;if(i.send=async n=>n.method?Array.isArray(n.args)?s[n.method]?.(...n.args):s[n.method]?.(n.args):Array.isArray(n.args)?s.run(...n.args):s.run(n.args),i.request=async(n,a)=>a?Array.isArray(n.args)?s[a]?.(...n.args):s[a]?.(n.args):Array.isArray(n.args)?s.run(...n.args):s.run(n.args),i.post=async(n,a,o)=>{if(n&&s.get(n)){let f=s.get(n);return o?Array.isArray(a)?f[o]?.(...a):f[o]?.(a):Array.isArray(a)?f.run(...a):f.run(a)}else return o?Array.isArray(a)?s[o]?.(...a):s[o]?.(a):Array.isArray(a)?s.run(...a):s.run(a)},i.run=i.post,i.subscribe=async(n,a)=>s.subscribe(a,n),i.unsubscribe=async(n,a)=>s.unsubscribe(a,n),i.terminate=()=>(s.graph.remove(s),!0),i.onclose=e.onclose,i.onclose){let n;s.ondelete&&(n=s.ondelete),s.ondelete=a=>{i.onclose&&i.onclose(i,a),n&&n(a)}}}else if(e.connection instanceof v){e.connection.nodes.get("open")&&(i.service=e.connection);let s=i.connection;i.send=async n=>{Array.isArray(n.args)?s.run(n.route,...n.args):s.run(n.route,n.args)},i.request=async(n,a)=>{if(!!n.route)return a?Array.isArray(n.args)?s.nodes.get(n.route)[a]?.(...n.args):s.nodes.get(n.route)[a]?.(n.args):Array.isArray(n.args)?s.run(n.route,...n.args):s.run(n.route,n.args)},i.post=async(n,a,o)=>{if(n&&s.get(n)){let f=s.get(n);return o?Array.isArray(a)?f[o]?.(...a):f[o]?.(a):Array.isArray(a)?f.run(...a):f.run(a)}},i.run=i.post,i.subscribe=async(n,a)=>s.subscribe(n,a),i.unsubscribe=async(n,a)=>s.unsubscribe(n,a),i.terminate=n=>(s.remove(n),!0)}else if(!(e._id&&this.connections[e._id])){let s=e.connection;if(typeof s=="string"){if(this.connections[s])s=this.connections[s];else if(e.service){if(typeof e.service=="string"&&(e.service=this.services[e.service]),typeof e.service=="object"&&e.service.connections){for(let n in e.service.connections)if(e.service.connections[n][s]){s=e.service.connections[n][s],i.connectionType=n,i.connectionsKey=s;break}}}else for(let n in this.serviceConnections)for(let a in this.serviceConnections[n])if(this.serviceConnections[n][a][s]){s=this.serviceConnections[n][a][s],e.service=n,i.connectionType=n,i.connectionsKey=a;break}}if(typeof s!="object")return;if(i._id=s._id,i.send=s.send,i.request=s.request,i.run=s.run,i.post=s.post,i.subscribe=s.subscribe,i.unsubscribe=s.unsubscribe,i.terminate=s.terminate,i.onclose=e.onclose,i.onclose){if(!(s.onclose&&i.onclose.toString()===s.onclose.toString())){let n=s.onclose;s.onclose=(...a)=>{i.onclose&&i.onclose(i,...a),this.users[i.source]&&Object.keys(this.sources[i.source]).length===0&&this.removeUser(i.source,!1),n&&n(...a)}}}else{let n=s.onclose;s.onclose=(...a)=>{this.removeConnection(i),this.users[i.source]&&Object.keys(this.sources[i.source]).length===0&&this.removeUser(i.source,!1),n&&n(...a)}}e.service?(typeof e.service=="string"&&(e.service=this.services[e.service]),i.service=e.service):s.graph&&(i.service=s.graph)}return!i.source&&e.source?i.source=e.source:!i.source&&e.service?i.source=typeof e.service=="object"?e.service.name:void 0:!i.source&&(i.connection instanceof y||i.connection instanceof v)&&(i.source="local",this.order.indexOf("local")||this.order.unshift("local")),i._id||(i._id=`connection${Math.floor(Math.random()*1e15)}`),i.source&&(this.sources[i.source]||(this.sources[i.source]={}),this.sources[i.source][i._id]=i),this.connections[i._id]||(this.connections[i._id]=i),i}};this.removeConnection=(e,r=!1)=>{if(typeof e=="object"&&e._id&&(e=e._id),typeof e=="string"){if(this.connections[e]){r&&this.connections[e]&&this.connections[e].terminate(),delete this.connections[e];for(let i in this.sources)if(this.sources[i][e])delete this.sources[i][e];else for(let s in this.sources[i])this.sources[i][s]?.[e]&&delete this.sources[i][e];return!0}else if(this.sources[e]){for(let i in this.sources[e])this.removeConnection(this.sources[e][i],r);return!0}}};this.addService=(e,r,i,s,n,a,o)=>{if(this.load(e,i,s,this.customRoutes,this.customChildren),this.services[e.name]=e,r)if(typeof r=="string")this.addServiceConnections(e,r,a);else for(let f in r)this.addServiceConnections(e,f,a);n&&this.syncServices(),o?this.order=o:(this.order||(this.order=[]),this.order.push(e.name))};this.addServiceConnections=(e,r,i)=>{if(typeof e=="string"&&(e=this.services[e]),r&&e[r]){let s={};this.serviceConnections[e.name]||(this.serviceConnections[e.name]={}),this.serviceConnections[e.name][r]=e[r];for(let n in e[r])this.connections[n]||(s[n]=this.addConnection({connection:e[r][n],service:e},i),s[n].connectionType=r);return s}};this.openConnection=async(e,r,i,...s)=>{if(typeof e=="string"&&(e=this.services[e]),e instanceof G){let n=e.run("open",r,...s);if(n instanceof Promise)return n.then(async a=>{a._id||await new Promise((o,f)=>{let b=performance.now(),h=()=>{a._id?o(!0):performance.now()-b>3e3?f(!1):setTimeout(()=>{h()},100)};h()}).catch(o=>{console.error("Connections timed out:",o)}),a._id&&this.addConnection({connection:a,service:e},i)});if(n&&(n._id||await new Promise((a,o)=>{let f=performance.now(),b=()=>{n._id?a(!0):performance.now()-f>3e3?o(!1):setTimeout(()=>{b()},100)};b()}).catch(a=>{console.error("Connections timed out:",a)}),n._id))return this.addConnection({connection:n,service:e},i)}};this.terminate=e=>(typeof e=="string"&&(e=this.connections[e]),e.terminate());this.subscribeThroughConnection=(e,r,i,s,...n)=>{if(typeof r=="string"&&(r=this.getConnection(r,"run")),typeof r=="object")return new Promise((a,o)=>{r.run("routeConnections",[e,i,r._id,...n]).then(f=>{this.subscribe(i,b=>{b?.callbackId===e&&(s?typeof s=="string"?this.setState({[s]:b.args}):s(b.args):this.setState({[i]:b.args}))}),a(f)}).catch(o)})};this.routeConnections=(e,r,i,...s)=>{let n;if(typeof i=="string"&&(this.sources[i]&&(n=i),i=this.getConnection(i,"send")),typeof r=="string"&&(r=this.getConnection(r,"subscribe")),r?.subscribe&&i?.send)return new Promise((o,f)=>{r.subscribe(e,r._id,b=>{!this.connections[i._id]&&n&&this.sources[n]&&(n=i,Object.keys(this.sources[n]).forEach(h=>{this.sources[i][h].send&&(i=this.sources[i][h])})),this.connections[i._id]&&i.send({callbackId:e,args:b})},...s).then(b=>{o(b)})})};this.syncServices=()=>{for(let e in this.services)"users"in this.services[e]&&(this.services[e].users=this.users),this.nodes.forEach((r,i)=>{this.services[e].nodes.get(r.tag)?!this.services[e].nodes.get(i)&&r._UNIQUE!==this.services[e].nodes.get(r.tag)._UNIQUE&&this.services[e].nodes.set(i,r):this.services[e].nodes.set(r.tag,r)})};this.setUserData=(e,r)=>{if(e&&typeof e=="string"&&(e=this.users[e],!e))return!1;if(r&&typeof r=="string"&&(r=JSON.parse(r)),typeof r=="object")return this.recursivelyAssign(e,r),!0};this.routes={addUser:this.addUser,removeUser:this.removeUser,getConnection:this.getConnection,addConnection:this.addConnection,removeConnection:this.removeConnection,addService:this.addService,addServiceConnections:this.addServiceConnections,openConnection:this.openConnection,terminate:this.terminate,routeConnections:this.routeConnections,subscribeThroughConnection:this.subscribeThroughConnection,syncServices:this.syncServices};if(this.load(this.routes),e&&(e.order&&(this.order=e.order),e.services))for(let r in e.services){let i=e.services[r];if(i instanceof G)i.service.name=r,i.service.tag=r,this.addService(i.service,i.connections,e.includeClassName,e.routeFormat,e.syncServices);else if(typeof i=="function"){let s=new i;s.name=r,s.tag=r,s&&this.addService(s,s.connections,e.includeClassName,e.routeFormat,e.syncServices)}else{if(typeof i.service=="function"){let s=new i.service({name:r});s.name=r,s.tag=r,s&&this.addService(s,void 0,e.includeClassName,e.routeFormat,e.syncServices),i.service=s}else i.service instanceof G&&(i.service.name=r,i.service.tag=r,this.addService(i.service,void 0,e.includeClassName,e.routeFormat,e.syncServices));if(typeof i.service=="object"&&(i.connections&&(Array.isArray(i.connections)?i.connections.forEach(s=>{this.addServiceConnections(i[r].service,s)}):this.addServiceConnections(i.service,i.connections)),i.config))for(let s in i.config)this.openConnection(i.service,i.config[s],i.config[s].source,i.config[s].args)}}}removeUser(e,r){return r&&this.removeConnection(e,r),typeof e=="string"&&(e=this.users[e]),typeof e=="object"&&e._id&&(delete this.users[e._id],e.onclose&&e.onclose(e)),!0}};})(); diff --git a/dist/index.d.ts b/dist/index.d.ts index 07ec783e..89c5b63b 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -1,22 +1,17 @@ -export * from './src/core/Graph'; -export * from './src/core/EventHandler'; -export * from './src/loaders'; -export * from './src/services/utils'; -export { methodstrings } from './src/loaders/methodstrings'; -export * from './src/services/Service'; -export * from './src/services/remote/remote.routes'; -export * from './src/services/ecs/ECS.service'; -export { html, xml } from './src/loaders/html/html'; -export * from './src/loaders/html/html.loader'; -export { DOMElement, addCustomElement } from './src/loaders/html/DOMElement'; -export * from './src/loaders/html/wc.loader'; -export * from './src/services/e2ee/E2EE.service'; -export * from './src/services/http/HTTP.browser'; -export * from './src/services/sse/SSE.browser'; -export * from './src/services/wss/WSS.browser'; -export * from './src/services/webrtc/WebRTC.browser'; -export * from './src/services/worker/Worker.service'; -export * from './src/services/worker/ProxyListener'; -export * from './src/services/worker/WorkerCanvas'; -export * from './src/services/sessions/sessions.service'; -export * from './src/services/router/Router'; +export * from './Graph'; +export * from './services/Service'; +export * from './services/unsafe/Unsafe.service'; +export * from './services/ecs/ECS.service'; +export * from './services/dom/DOM.service'; +export { DOMElement, addCustomElement } from './services/dom/DOMElement'; +export * from './services/e2ee/E2EE.service'; +export * from './services/http/HTTP.browser'; +export * from './services/sse/SSE.browser'; +export * from './services/wss/WSS.browser'; +export * from './services/webrtc/WebRTC.browser'; +export * from './services/worker/Worker.service'; +export * from './services/worker/ProxyListener'; +export * from './services/worker/WorkerCanvas'; +export * from './services/worker/Subprocess'; +export * from './services/sessions/sessions.service'; +export * from './services/router/Router'; diff --git a/dist/index.esm.js b/dist/index.esm.js index 25d48469..ec8c4b7e 100644 --- a/dist/index.esm.js +++ b/dist/index.esm.js @@ -1 +1,5 @@ -var __require=(x=>typeof require!=="undefined"?require:typeof Proxy!=="undefined"?new Proxy(x,{get:(a,b)=>(typeof require!=="undefined"?require:a)[b]}):x)(function(x){if(typeof require!=="undefined")return require.apply(this,arguments);throw Error('Dynamic require of "'+x+'" is not supported')});var EventHandler=class{data={};triggers={};ctr=0;constructor(data){if(typeof data==="object")this.data=data}setState=updateObj=>{Object.assign(this.data,updateObj);let props=Object.getOwnPropertyNames(updateObj);for(const prop of props){this.triggerEvent(prop,this.data[prop])}if(this.triggers[statesubKey]){let run=fn=>{fn(updateObj)};const l=this.triggers[statesubKey].length;for(let i2=l-1;i2>=0;i2--){run(this.triggers[statesubKey][i2].onchange)}}return this.data};setValue=(key,value)=>{this.data[key]=value;this.triggerEvent(key,value)};triggerEvent=(key,value)=>{if(this.triggers[key]){let fn=obj=>{obj.onchange(value)};const l=this.triggers[key].length;for(let i2=l-1;i2>=0;i2--){fn(this.triggers[key][i2])}}};subscribeState=onchange=>{return this.subscribeEvent(statesubKey,onchange)};unsubscribeState=sub=>{return this.unsubscribeEvent(statesubKey,sub)};subscribeEvent=(key,onchange,refObject,refKey)=>{if(key){if(refObject&&refKey&&!this.triggers[key]){Object.defineProperty(this.data,key,{get:()=>{return refObject[refKey]},set:value=>{refObject[refKey]=value},enumerable:true,configurable:true})}if(!this.triggers[key]){this.triggers[key]=[]}let l=this.ctr;this.ctr++;this.triggers[key].push({sub:l,onchange});return l}else return void 0};unsubscribeEvent=(key,sub)=>{let triggers=this.triggers[key];if(triggers){if(sub===void 0){delete this.triggers[key];delete this.data[key]}else{let idx=void 0;let obj=triggers.find((o,i2)=>{if(o.sub===sub){idx=i2;return true}});if(obj)triggers.splice(idx,1);if(Object.keys(triggers).length===0){delete this.triggers[key];delete this.data[key]}if(this.onRemoved)this.onRemoved(obj);return true}}};subscribeEventOnce=(key,onchange)=>{let sub;let changed=value=>{onchange(value);this.unsubscribeEvent(key,sub)};sub=this.subscribeEvent(key,changed);return sub};getEvent=(key,sub)=>{if(typeof sub!=="number")return this.triggers[key];for(const s in this.triggers[key]){if(this.triggers[key][s].sub===sub)return this.triggers[key][s]}};getSnapshot=()=>{const snapshot={};for(const key in this.data){snapshot[key]=this.data[key]}};onRemoved};var statesubKey="*s";var state=new EventHandler;var Callable=class extends Function{__bound;__call;constructor(){super("return this.__bound.__call.apply(this.__bound, arguments)");this.__bound=this.bind(this);return this.__bound}};var GraphNode=class _GraphNode{__node={tag:`node${Math.floor(Math.random()*1e15)}`,unique:`${Math.floor(Math.random()*1e15)}`,state};__children;__parent;__operator;__listeners;__props;__args;constructor(properties,parent,graph){this.__setProperties(properties,parent,graph);if(typeof properties==="function"||properties?.__callable){const callableInstance=new Callable;callableInstance.__call=(...args)=>this.__operator(...args);const proxy=new Proxy(callableInstance,{get:(target,prop,receiver)=>{if(Reflect.has(this,prop)){return Reflect.get(this,prop,receiver)}return Reflect.get(target,prop,receiver)},set:(target,prop,value,receiver)=>{if(Reflect.has(this,prop)){return Reflect.set(this,prop,value,receiver)}return Reflect.set(target,prop,value,receiver)}});Object.setPrototypeOf(proxy,this);return proxy}}get __graph(){return this.__node?.graph}set __graph(graph){this.__node.graph=graph}__setProperties=(properties,parent,graph)=>{let enforceProperties=()=>{let orig=properties;if(typeof properties==="function"){if(isNativeClass(properties)){properties=new properties}else properties={__operator:properties,__node:{forward:true,tag:properties.name}}}else if(typeof properties==="string"){if(graph?.get(properties)){properties=graph.get(properties)}}if(!("__node"in properties))properties.__node={};if(!properties.__node.initial)properties.__node.initial=orig};enforceProperties();if(typeof properties==="object"){let assignState=()=>{if(properties.__node?.state)this.__node.state=properties.__node.state;else if(graph){properties.__node.state=graph.__node.state}};let setProps2=()=>{if(properties.__props){if(typeof properties.__props==="function")properties.__props=new properties.__props;if(typeof properties.__props==="object"){this.__proxyObject(properties.__props)}}};let setTag=()=>{if(!properties.__node.tag){if(properties.__operator?.name)properties.__node.tag=properties.__operator.name;else properties.__node.tag=`node${Math.floor(Math.random()*1e15)}`}};let setNode=()=>{if(typeof properties.__node==="string"){if(graph?.get(properties.__node.tag)){properties=graph.get(properties.__node.tag)}else properties.__node={}}else if(!properties.__node)properties.__node={};if(graph){properties.__node.graph=graph}if(properties instanceof Graph)properties.__node.source=properties};let setParent=()=>{if(!properties.__parent&&parent)properties.__parent=parent;if(parent?.__node&&!(parent instanceof Graph||properties instanceof Graph))properties.__node.tag=parent.__node.tag+"."+properties.__node.tag;if(parent instanceof Graph&&properties instanceof Graph){if(properties.__node.loaders)Object.assign(parent.__node.loaders?parent.__node.loaders:{},properties.__node.loaders);if(parent.__node.mapGraphs){properties.__node.nodes.forEach(n=>{parent.set(properties.__node.tag+"."+n.__node.tag,n)});let ondelete=()=>{properties.__node.nodes.forEach(n=>{parent.__node.nodes.delete(properties.__node.tag+"."+n.__node.tag)})};this.__addOndisconnected(ondelete)}}};let setOp=()=>{if(typeof properties.default==="function"&&!properties.__operator){properties.__operator=properties.default}if(properties.__operator){if(typeof properties.__operator==="string"){if(graph){let n=graph.get(properties.__operator);if(n)properties.__operator=n.__operator;if(!properties.__node.tag&&properties.__operator.name)properties.__node.tag=properties.__operator.name}}if(typeof properties.__operator==="function")properties.__operator=this.__setOperator(properties.__operator);if(properties.default)properties.default=properties.__operator}};let assignProps=()=>{properties.__node=Object.assign(this.__node,properties.__node);let keys2=Object.getOwnPropertyNames(properties).filter(v=>{if(!objProps[v])return true});for(const key of keys2){if(key in properties&&key!=="name")this[key]=properties[key]}};let bindCallbacks=()=>{if(this.__onconnected){if(typeof this.__onconnected==="function"){this.__onconnected=this.__onconnected.bind(this)}else if(Array.isArray(this.__onconnected)){this.__onconnected=this.__onconnected.map(f=>{return f.bind(this)})}if(typeof this.__ondisconnected==="function"){this.__ondisconnected=this.__ondisconnected.bind(this)}else if(Array.isArray(this.__ondisconnected)){this.__ondisconnected=this.__ondisconnected.map(f=>{return f.bind(this)})}}};assignState();setTag();setProps2();setNode();setParent();assignProps();bindCallbacks();setOp()}};__subscribe=(callback,key,subInput,target,tkey,args,callbackStr)=>{const subscribeToFunction=(k,setTarget=(callback2,target2)=>target2?target2:callback2,triggerCallback=callback)=>{let wrappedArgs;if(args){let wrapped=wrapArgs(triggerCallback,args,this.__node.graph);triggerCallback=wrapped.__callback;wrappedArgs=wrapped.__args}let sub=this.__node.state.subscribeEvent(k,triggerCallback,this,key);let trigger=this.__node.state.getEvent(k,sub);if(!this.__listeners)this.__listeners={};this.__listeners[k]=this.__node.state.triggers[k];if(!trigger)return sub;trigger.source=this.__node.tag;if(key)trigger.key=key;trigger.target=setTarget(callback,target);if(tkey)trigger.tkey=tkey;if(subInput)trigger.subInput=subInput;if(args){trigger.arguments=wrappedArgs;trigger.__args=args}if(callbackStr)trigger.__callback=callbackStr;trigger.node=this;trigger.graph=this.__node.graph;return sub};const getCallbackFromGraph=callback2=>{let fn=this.__node.graph.get(callback2);if(!fn&&callback2.includes(".")){target=callback2.substring(0,callback2.lastIndexOf("."));let n=this.__node.graph.get(callback2.substring(0,target));tkey=callback2.lastIndexOf(".")+1;if(n&&typeof n[key]==="function")callback2=(...args2)=>{return n[tkey](...args2)}}else if(fn.__operator){callback2=fn.__operator;tkey="__operator"}return callback2};if(key){if(!this.__node.localState||!this.__node.localState[key]){this.__addLocalState(this,key)}if(typeof callback==="string"){callbackStr=this.__node.tag+"."+callback;tkey=callback;if(target){if(this.__node.graph?.get(target)){let n=this.__node.graph?.get(target);if(typeof n[callback]==="function"){let fn=n[callback];callback=(...inp)=>{fn(...inp)}}else{let k2=callback;let setter=inp=>{n[k2]=inp};callback=setter}}}else if(typeof this[callback]==="function"){let fn=this[callback];callback=(...inp)=>{fn(...inp)}}else if(this.__node.graph?.get(callback))callback=getCallbackFromGraph(callback);if(typeof callback!=="function")return void 0}let sub;let k=subInput?this.__node.unique+"."+key+"input":this.__node.unique+"."+key;if(typeof callback==="function"&&!callback?.__node)sub=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2,callback);else if(callback?.__node)sub=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2.__node.unique,(...inp)=>{if(callback.__operator)callback.__operator(...inp)});return sub}else{if(typeof callback==="string"){callbackStr=callback;if(!target)target=callback;if(this.__node.graph.get(callback))callback=this.__node.graph.get(callback);tkey="__operator";if(typeof callback!=="object")return void 0}let sub;let k=subInput?this.__node.unique+"input":this.__node.unique;if(typeof callback==="function"&&!callback?.__node)sub=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2,callback);else if(callback?.__node){sub=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2.__node.unique,(...inp)=>{if(callback.__operator)callback.__operator(...inp)})}return sub}};__unsubscribe=(sub,key,unsubInput)=>{if(key){return this.__node.state.unsubscribeEvent(unsubInput?this.__node.unique+"."+key+"input":this.__node.unique+"."+key,sub)}else return this.__node.state.unsubscribeEvent(unsubInput?this.__node.unique+"input":this.__node.unique,sub)};__setOperator=fn=>{fn=fn.bind(this);if(this.__args&&this.__node.graph){fn=wrapArgs(fn,this.__args,this.__node.graph).__callback}let inpstr=`${this.__node.unique}input`;this.__operator=(...args)=>{if(this.__node.state.triggers[inpstr])this.__node.state.setValue(inpstr,args);let result=fn(...args);if(this.__node.state.triggers[this.__node.unique]){if(typeof result?.then==="function"){result.then(res=>{if(res!==void 0)this.__node.state.setValue(this.__node.unique,res)}).catch(console.error)}else if(result!==void 0)this.__node.state.setValue(this.__node.unique,result)}return result};if(this.__parent instanceof _GraphNode&&!this.__subscribedToParent){if(this.__parent.__operator){let sub=this.__parent.__subscribe(this);let ondelete=()=>{this.__parent?.__unsubscribe(sub);delete this.__subscribedToParent};this.__addOndisconnected(ondelete);this.__subscribedToParent=true}}return this.__operator};__addLocalState=(props,key)=>{if(!props)return;if(!this.__node.localState){this.__node.localState={}}const localState=this.__node.localState;const initState=(props2,k)=>{let str2=this.__node.unique+"."+k;let inpstr=`${str2}input`;let get,set;let obj,descriptor;if(typeof props2[k]==="function"&&k!=="__operator"){if(this.__props?.[k]){obj=this.__props}else{obj=localState}get=()=>{return obj[k]};set=fn=>{if(!this.__props?.[k])fn=fn.bind(this);obj[k]=(...args)=>{if(this.__node.state.triggers[inpstr])this.__node.state.setValue(inpstr,args);let result=fn(...args);if(this.__node.state.triggers[str2]){if(typeof result?.then==="function"){result.then(res=>{this.__node.state.triggerEvent(str2,res)}).catch(console.error)}else this.__node.state.triggerEvent(str2,result)}return result}};localState[k]=props2[k].bind(this);descriptor={get,set,enumerable:true,configurable:true}}else if(k!=="__graph"){let get2,set2;let obj2;if(this.__props?.[k]){obj2=this.__props}else{obj2=localState}get2=()=>{return obj2[k]};set2=v=>{obj2[k]=v;if(this.__node.state.triggers[str2])this.__node.state.triggerEvent(str2,v)};localState[k]=props2[k];descriptor={get:get2,set:set2,enumerable:true,configurable:true}}Object.defineProperty(props2,k,descriptor);if(typeof this.__node.initial==="object"){let dec=Object.getOwnPropertyDescriptor(this.__node.initial,k);if(dec===void 0||dec?.configurable){Object.defineProperty(this.__node.initial,k,descriptor)}}};if(key)initState(props,key);else{for(let k in props){initState(props,k)}}};__proxyObject=obj=>{const allProps=getAllProperties(obj);for(const k of allProps){const descriptor={get:()=>{return obj[k]},set:value=>{obj[k]=value},enumerable:true,configurable:true};Object.defineProperty(this,k,descriptor);if(typeof this.__node.initial==="object"){let dec=Object.getOwnPropertyDescriptor(this.__node.initial,k);if(dec===void 0||dec?.configurable){Object.defineProperty(this.__node.initial,k,descriptor)}}}};__addOnconnected(callback){callback=callback.bind(this);if(Array.isArray(this.__onconnected)){this.__onconnected.push(callback)}else if(typeof this.__onconnected==="function"){this.__onconnected=[callback,this.__onconnected]}else this.__onconnected=callback}__addOndisconnected(callback){callback=callback.bind(this);if(Array.isArray(this.__ondisconnected)){this.__ondisconnected.push(callback)}else if(typeof this.__ondisconnected==="function"){this.__ondisconnected=[callback,this.__ondisconnected]}else this.__ondisconnected=callback}__callConnected(node=this){if(typeof this.__onconnected==="function"){this.__onconnected(this)}else if(Array.isArray(this.__onconnected)){let fn=o=>{o(this)};this.__onconnected.forEach(fn)}}__callDisconnected(node=this){if(typeof this.__ondisconnected==="function")this.__ondisconnected(this);else if(Array.isArray(this.__ondisconnected)){let fn=o=>{o(this)};this.__ondisconnected.forEach(fn)}}};var Graph=class _Graph{__node={tag:`graph${Math.floor(Math.random()*1e15)}`,unique:`${Math.random()}`,nodes:new Map,state,roots:{}};constructor(options){this.init(options)}init=options=>{if(options){let cpy=Object.assign({},options);delete cpy.roots;recursivelyAssign(this.__node,cpy);if(options.roots)this.load(options.roots)}};load=(roots,overwrite=false)=>{function recursivelyAssignChildren(target,obj,inChildren=true,top=true){if(top){if(!target)target={};for(const key in obj){if(!key.startsWith("__")&&obj[key]&&typeof obj[key]==="object"){target[key]=obj[key];if(obj[key]?.__children){recursivelyAssignChildren({},obj[key].__children,false,false)}}else if(typeof obj[key]==="function")target[key]=obj[key]}recursivelyAssignChildren(target,obj,true,false)}else{if(obj?.__children&&!inChildren){if(obj.__children?.constructor.name==="Object"){if(target.__children?.constructor.name==="Object")target.__children=recursivelyAssignChildren(target.__children,obj.__children,true,false);else target.__children=recursivelyAssignChildren({},obj.__children,true,false)}else{target.__children=obj.__children}}else if(inChildren){for(const key in obj){if(!key.startsWith("__")&&obj[key]&&typeof obj[key]==="object"){target[key]=Object.assign({},obj[key]);if(obj[key]?.__children){target[key].__children=recursivelyAssignChildren({},obj[key].__children,false,false)}}else if(typeof obj[key]==="function")target[key]=obj[key]}}}return target}this.__node.roots=recursivelyAssignChildren(this.__node.roots?this.__node.roots:{},roots);let cpy=Object.assign({},roots);if(cpy.__node)delete cpy.__node;let listeners=this.recursiveSet(cpy,this,void 0,roots,overwrite);if(roots.__node){if(!roots.__node.tag)roots.__node._tag=`roots${Math.floor(Math.random()*1e15)}`;else if(!this.get(roots.__node.tag)){let node=new GraphNode(roots,this,this);this.set(node.__node.tag,node);this.runLoaders(node,this,roots,roots.__node.tag);if(node.__listeners){listeners[node.__node.tag]=node.__listeners}}}else if(roots.__listeners){this.setListeners(roots.__listeners)}this.setListeners(listeners);return cpy};setLoaders=(loaders2,replace)=>{if(replace)this.__node.loaders=loaders2;else Object.assign(this.__node.loaders,loaders2);return this.__node.loaders};runLoaders=(node,parent,properties,key)=>{for(const l in this.__node.loaders){if(typeof this.__node.loaders[l]==="object"){if(this.__node.loaders[l].init)this.__node.loaders[l](node,parent,this,this.__node.roots,properties,key);if(this.__node.loaders[l].connected)node.__addOnconnected(this.__node.loaders[l].connect);if(this.__node.loaders[l].disconnected)node.__addOndisconnected(this.__node.loaders[l].disconnect)}else if(typeof this.__node.loaders[l]==="function")this.__node.loaders[l](node,parent,this,this.__node.roots,properties,key)}};add=(properties,parent,overwrite=true)=>{let listeners={};if(typeof parent==="string")parent=this.get(parent);let instanced;if(typeof properties==="function"){if(isNativeClass(properties)){if(properties.prototype instanceof GraphNode){properties=properties.prototype.constructor(properties,parent,this);instanced=true}else properties=new properties}else properties={__operator:properties,__callable:true}}else if(typeof properties==="string"){properties=this.__node.roots[properties]}if(!properties)return;if(!instanced){let keys2=Object.getOwnPropertyNames(properties);let nonArrowFunctions=Object.getOwnPropertyNames(Object.getPrototypeOf(properties));keys2.push(...nonArrowFunctions);keys2=keys2.filter(v=>!objProps.includes(v));let cpy={};for(const key of keys2){cpy[key]=properties[key]}properties=cpy}if(!properties.__node)properties.__node={};properties.__node.initial=properties;if(typeof properties==="object"&&this.get(properties.__node.tag)){if(overwrite)this.remove(properties.__node.tag,true);else return}else if(properties.__node.tag&&this.get(properties.__node.tag))return this.get(properties.__node.tag);let node;let root=recursivelyAssign({},properties,2);if(instanced)node=properties;else node=new GraphNode(properties,parent,this);this.set(node.__node.tag,node);this.runLoaders(node,parent,properties,node.__node.tag);this.__node.roots[node.__node.tag]=root;if(node.__children){node.__children=Object.assign({},node.__children);this.recursiveSet(node.__children,node,listeners,node.__children)}if(node.__listeners){listeners[node.__node.tag]=Object.assign({},node.__listeners);for(const key in node.__listeners){let listener=node.__listeners[key];if(node[key]){delete listeners[node.__node.tag][key];listeners[node.__node.tag][node.__node.tag+"."+key]=listener}if(typeof listener==="string"){if(node.__children?.[listener]){listeners[node.__node.tag][key]=node.__node.tag+"."+listener}else if(parent instanceof GraphNode&&(parent.__node.tag===listener||parent.__node.tag.includes(".")&&parent.__node.tag.split(".").pop()===listener)){listeners[node.__node.tag][key]=parent.__node.tag}}}}this.setListeners(listeners);node.__callConnected();return node};recursiveSet=(originCpy,parent,listeners={},origin,overwrite=false)=>{let keys2=Object.getOwnPropertyNames(origin).filter(v=>!objProps.includes(v));let nonArrowFunctions=Object.getOwnPropertyNames(Object.getPrototypeOf(origin)).filter(v=>!objProps.includes(v));keys2.push(...nonArrowFunctions);for(const key of keys2){if(key.includes("__"))continue;let p=origin[key];if(Array.isArray(p))continue;let instanced;if(typeof p==="function"){if(isNativeClass(p)){p=new p;if(p instanceof GraphNode){p=p.prototype.constructor(p,parent,this);instanced=true}}else p={__operator:p,__callable:true}}else if(typeof p==="string"){if(this.__node.nodes.get(p))p=this.__node.nodes.get(p);else p=this.__node.roots[p]}else if(typeof p==="boolean"){if(this.__node.nodes.get(key))p=this.__node.nodes.get(key);else p=this.__node.roots[key]}if(p&&typeof p==="object"){if(!instanced&&!(p instanceof GraphNode)){let ks=Object.getOwnPropertyNames(p).filter(v=>!objProps.includes(v));let nonArrowFunctions2=Object.getOwnPropertyNames(Object.getPrototypeOf(p)).filter(v=>!objProps.includes(v));nonArrowFunctions2.splice(nonArrowFunctions2.indexOf("constructor"),1);ks.push(...nonArrowFunctions2);let cpy={};for(const key2 of ks){cpy[key2]=p[key2]}p=cpy}if(!p.__node)p.__node={};if(!p.__node.tag)p.__node.tag=key;if(!p.__node.initial)p.__node.initial=originCpy[key];if(overwrite&&this.get(p.__node.tag)){this.remove(p.__node.tag,true)}else if(this.get(p.__node.tag)&&!(!(parent instanceof _Graph)&&parent?.__node)||parent?.__node&&this.get(parent.__node.tag+"."+p.__node.tag))continue;let node;let newnode=false;let root=recursivelyAssign({},p,2);if(instanced||p instanceof GraphNode){node=p}else{node=new GraphNode(p,parent,this);newnode=true}if(!newnode&&p instanceof GraphNode&&!instanced&&parent instanceof GraphNode){let sub=this.subscribe(parent.__node.tag,node.__node.tag);let ondelete=node2=>{this.unsubscribe(parent.__node.tag,sub)};node.__addOndisconnected(ondelete)}else if(node){this.set(node.__node.tag,node);this.runLoaders(node,parent,originCpy[key],key);originCpy[key]=node;this.__node.roots[node.__node.tag]=root;if(node.__children){node.__children=Object.assign({},node.__children);this.recursiveSet(node.__children,node,listeners,node.__children)}if(node.__listeners){listeners[node.__node.tag]=Object.assign({},node.__listeners);for(const key2 in node.__listeners){let listener=node.__listeners[key2];let k=key2;if(node[key2]){delete listeners[node.__node.tag][key2];k=node.__node.tag+"."+key2;listeners[node.__node.tag][k]=listener}if(typeof listener==="string"){if(node.__children?.[listener]){listeners[node.__node.tag][k]=node.__node.tag+"."+listener}else if(parent instanceof GraphNode&&(parent.__node.tag===listener||parent.__node.tag.includes(".")&&parent.__node.tag.split(".").pop()===listener)){listeners[node.__node.tag][k]=parent.__node.tag}}}}node.__callConnected()}}}return listeners};remove=(node,clearListeners=true)=>{this.unsubscribe(node);if(typeof node==="string")node=this.get(node);if(node instanceof GraphNode){this.delete(node.__node.tag);delete this.__node.roots[node.__node.tag];if(clearListeners){this.clearListeners(node)}node.__callDisconnected();const recursiveRemove=t2=>{for(const key in t2){this.unsubscribe(t2[key]);this.delete(t2[key].__node.tag);delete this.__node.roots[t2[key].__node.tag];this.delete(key);delete this.__node.roots[key];t2[key].__node.tag=t2[key].__node.tag.substring(t2[key].__node.tag.lastIndexOf(".")+1);if(clearListeners){this.clearListeners(t2[key])}t2[key].__callDisconnected();if(t2[key].__children){recursiveRemove(t2[key].__children)}}};if(node.__children){recursiveRemove(node.__children)}}if(node?.__node.tag&&node?.__parent){delete node?.__parent;node.__node.tag=node.__node.tag.substring(node.__node.tag.indexOf(".")+1)}if(node?.__node.graph)node.__node.graph=void 0;return node};run=(node,...args)=>{if(typeof node==="string"){let nd=this.get(node);if(!nd&&node.includes(".")){nd=this.get(node.substring(0,node.lastIndexOf(".")));if(typeof nd?.[node.substring(node.lastIndexOf(".")+1)]==="function")return nd[node.substring(node.lastIndexOf(".")+1)](...args)}else if(nd?.__operator)return nd.__operator(...args)}if(node?.__operator){return node?.__operator(...args)}};setListeners=listeners=>{for(const key in listeners){let node=this.get(key);if(typeof listeners[key]==="object"){for(const k in listeners[key]){let n=this.get(k);let sub;if(typeof listeners[key][k]!=="object")listeners[key][k]={__callback:listeners[key][k]};else if(!listeners[key][k].__callback){for(const kk in listeners[key][k]){if(typeof listeners[key][k][kk]!=="object"){listeners[key][k][kk]={__callback:listeners[key][k][kk]};if(node.__operator&&(listeners[key][k][kk].__callback===true||typeof listeners[key][k][kk].__callback==="undefined"))listeners[key][k][kk].__callback=node.__operator}let nn=this.get(kk);if(!nn){let tag=k.substring(0,k.lastIndexOf("."));nn=this.get(tag);if(nn){let prop=k.substring(k.lastIndexOf(".")+1);sub=this.subscribe(nn,listeners[key][k][kk].__callback,listeners[key][k][kk].__args,prop,listeners[key][k][kk].subInput,key)}}else{sub=this.subscribe(nn,listeners[key][k][kk].__callback,listeners[key][k][kk].__args,void 0,listeners[key][k][kk].subInput,key)}}}if("__callback"in listeners[key][k]){if(node){if(listeners[key][k].__callback===true||typeof listeners[key][k].__callback==="undefined")listeners[key][k].__callback=node.__operator;if(typeof listeners[key][k].__callback==="function")listeners[key][k].__callback=listeners[key][k].__callback.bind(node)}if(!n){let tag=k.substring(0,k.lastIndexOf("."));n=this.get(tag);if(n){sub=this.subscribe(n,listeners[key][k].__callback,listeners[key][k].__args,k.substring(k.lastIndexOf(".")+1),listeners[key][k].subInput,key)}}else{sub=this.subscribe(n,listeners[key][k].__callback,listeners[key][k].__args,void 0,listeners[key][k].subInput,key)}}}}}};clearListeners=(node,listener)=>{if(typeof node==="string")node=this.get(node);if(node?.__listeners){for(const key in node.__listeners){if(listener&&key!==listener)continue;if(typeof node.__listeners[key]?.sub!=="number")continue;let n=this.get(key);if(!n){n=this.get(key.substring(0,key.lastIndexOf(".")));if(n){if(typeof node.__listeners[key]==="object"&&!node.__listeners[key]?.__callback){for(const k in node.__listeners[key]){if(typeof node.__listeners[key][k]?.sub==="number"){this.unsubscribe(n,node.__listeners[key][k].sub,key.substring(key.lastIndexOf(".")+1),node.__listeners[key][k].subInput);node.__listeners[key][k].sub=void 0}}}else if(typeof node.__listeners[key]?.sub==="number"){this.unsubscribe(n,node.__listeners[key].sub,key.substring(key.lastIndexOf(".")+1),node.__listeners[key].subInput);node.__listeners[key].sub=void 0}}}else{if(typeof!node.__listeners[key]?.__callback==="number"){for(const k in node.__listeners[key]){if(node.__listeners[key][k]?.sub){this.unsubscribe(n,node.__listeners[key][k].sub,void 0,node.__listeners[key][k].subInput);node.__listeners[key][k].sub=void 0}}}else if(typeof node.__listeners[key]?.sub==="number"){this.unsubscribe(n,node.__listeners[key].sub,void 0,node.__listeners[key].subInput);node.__listeners[key].sub=void 0}}}}};get=tag=>{return this.__node.nodes.get(tag)};getByUnique=unique=>{return Array.from(this.__node.nodes.values()).find(node=>{if(node.__node.unique===unique)return true})};set=(tag,node)=>{return this.__node.nodes.set(tag,node)};delete=tag=>{return this.__node.nodes.delete(tag)};list=()=>{return Array.from(this.__node.nodes.keys())};getListener=(nodeTag,key,sub)=>{let node=this.get(nodeTag);if(node){let k=node.__node.unique;if(key){k+="."+key}return this.__node.state.getEvent(k,sub)}};getProps=(node,getInitial)=>{if(typeof node==="string")node=this.get(node);if(node instanceof GraphNode){let cpy;if(getInitial)cpy=Object.assign({},this.__node.roots[node.__node.tag]);else{cpy=Object.assign({},node);for(const key in cpy){if(key.includes("__"))delete cpy[key]}}}};subscribe=(nodeEvent,onEvent,args,key,subInput,target,tkey)=>{let nd=nodeEvent;if(typeof nodeEvent==="string"){nd=this.get(nodeEvent);if(!nd&&nodeEvent.includes(".")){nd=this.get(nodeEvent.substring(0,nodeEvent.lastIndexOf(".")));key=nodeEvent.substring(nodeEvent.lastIndexOf(".")+1)}}if(target instanceof GraphNode)target=target.__node.tag;let callbackStr;if(typeof onEvent==="string"){callbackStr=onEvent;let setOnEventFromString=onEvent2=>{if(this.get(onEvent2)?.__operator){let node=this.get(onEvent2);target=onEvent2;onEvent2=function(...inp){return node.__operator(...inp)}}else if(onEvent2.includes(".")){target=onEvent2.substring(0,onEvent2.lastIndexOf("."));let n=this.get(target);let k=onEvent2.substring(onEvent2.lastIndexOf(".")+1);tkey=k;if(typeof n[k]==="function"){if(n[k]instanceof GraphNode)onEvent2=n[k];else onEvent2=function(...inp){return n[k](...inp)}}else{onEvent2=function(inp){n[k]=inp;return n[k]}}}return onEvent2};if(target){let node=this.get(target);if(typeof node?.[onEvent]==="function"){tkey=onEvent;onEvent=function(...inp){return node[key](...inp)}}else if(node?.[key]){tkey=key;if(node[key]instanceof GraphNode)onEvent=node[key];else onEvent=function(inp){node[key]=inp;return node[key]}}else{onEvent=setOnEventFromString(onEvent)}}else{onEvent=setOnEventFromString(onEvent)}}let sub;if(nd instanceof GraphNode){const doSub=()=>{sub=nd.__subscribe(onEvent,key,subInput,target,tkey,args,callbackStr);let ondelete=()=>{if(sub!==void 0)nd.__unsubscribe(sub,key,subInput);sub=void 0};nd.__addOndisconnected(()=>{ondelete();nd.__addOnconnected(()=>{if(sub===void 0&&nd.__node.graph.__node.tag===this.__node.tag)doSub()})});if(typeof onEvent==="string"&&this.get(onEvent))onEvent=this.get(onEvent);if(onEvent instanceof GraphNode){onEvent.__addOndisconnected(()=>{ondelete()})}};doSub()}else if(typeof nodeEvent==="string"){let node=this.get(nodeEvent);if(node){if(onEvent instanceof GraphNode&&onEvent.__operator){const doSub=()=>{sub=node.__subscribe(onEvent.__operator,key,subInput,target,tkey,args,callbackStr);let ondelete=()=>{if(sub!==void 0)node.__unsubscribe(sub,key,subInput)};node.__addOndisconnected(()=>{ondelete();node.__addOnconnected(()=>{if(sub===void 0&&node.__node.graph.__node.tag===this.__node.tag)doSub()})});onEvent.__addOndisconnected(ondelete)};doSub()}else if(typeof onEvent==="function"||typeof onEvent==="string"){const doSub=()=>{sub=node.__subscribe(onEvent,key,subInput,target,tkey,args,callbackStr);let ondelete=()=>{if(sub!==void 0)node.__unsubscribe(sub,key,subInput);sub=void 0};node.__addOndisconnected(()=>{ondelete();node.__addOnconnected(()=>{if(sub===void 0&&node.__node.graph.__node.tag===this.__node.tag)doSub()})});if(typeof onEvent==="string"&&this.get(onEvent))this.get(onEvent).__addOndisconnected(ondelete)};doSub()}}else{if(typeof onEvent==="string")onEvent=this.__node.nodes.get(onEvent).__operator;if(typeof onEvent==="function"&&!onEvent?.__node)sub=this.__node.state.subscribeEvent(nodeEvent,onEvent)}}return sub};unsubscribe=(node,sub,key,subInput)=>{if(node instanceof GraphNode){return node.__unsubscribe(sub,key,subInput)}else return this.get(node)?.__unsubscribe(sub,key,subInput)};setState=update=>{this.__node.state.setState(update)}};function recursivelyAssign(target,obj,maxDepth=Infinity,curDepth=0){for(const key in obj){if(obj[key]?.constructor.name==="Object"&&curDepth{if(graph.get(a)?.__operator){let node=graph.get(a);return(...inp)=>{node.__operator(...inp)}}else if(a.includes(".")){let split=a.split(".");let popped=split.pop();let joined=split.join(".");let node=graph.get(joined);if(typeof graph.get(joined)?.[popped]==="function"){return(...inp)=>{return node[popped](...inp)}}else return()=>{return node[popped]}}else if(graph.get(a)){let node=graph.get(a);return()=>{return node}}else{let arg=a;return()=>{return arg}}};var wrapArgs=(callback,argOrder,graph)=>{let args=[];let forArg=(a,i2)=>{if(a==="__output"||a==="__input"||a==="__callback"){args[i2]={__callback:inp=>{return inp},__args:void 0,idx:i2}}else if(typeof a==="string"){args[i2]={__callback:getCallbackFromString(a,graph),__args:void 0,idx:i2}}else if(typeof a==="function"){let fn2=a;args[i2]={__callback:(...inp)=>{return fn2(...inp)},__args:void 0,idx:i2}}else if(typeof a==="object"&&(a.__input||a.__callback)){let recursivelyCreateCallback=function(c){let input=c.__input?c.__input:c.__callback;if(typeof c.__input==="string"){input={__callback:getCallbackFromString(c.__input,graph),__args:void 0,idx:i2}}if(c.__args){let wrapped=wrapArgs(input,c.__args,graph);input={__callback:wrapped.__callback,__args:wrapped.__args,idx:i2}}else{input={__callback:input,__args:void 0,idx:i2}}if(c.__output){let output=c.__output;if(typeof c.__output==="string"){output={__callback:getCallbackFromString(output,graph),__args:void 0,idx:i2}}else if(typeof a.__output==="object"){output=recursivelyCreateCallback(output)}if(typeof output?.__callback==="function"){let fn2=input.__callback;let callback2=output.__callback;input={__callback:(...inp)=>{return callback2(fn2(...inp))},__args:output.__args,idx:i2}}}return input};args[i2]=recursivelyCreateCallback(a)}else{let arg=a;args[i2]={__callback:()=>{return arg},__args:void 0,idx:i2}}};argOrder.forEach(forArg);if(typeof callback==="string")callback={__callback:getCallbackFromString(callback,graph),__args:void 0};let fn=typeof callback==="function"?callback:callback.__callback;callback=function(...inp){let mapArg=arg=>{return arg.__callback(...inp)};const result=fn(...args.map(mapArg));return result};return{__callback:callback,__args:args}};var objProps=Object.getOwnPropertyNames(Object.getPrototypeOf({}));var backprop=(node,parent,graph)=>{if(node.__node.backward&&parent instanceof GraphNode){graph.setListeners({[parent.__node.tag]:{[node.__node.tag]:parent}})}};var loop=(node,parent,graph)=>{if(node.__operator){let loopId=Math.random();if(!node.__node.loops)node.__node.loops={};if(typeof node.__node.delay==="number"){let fn=node.__operator;node.__setOperator((...args)=>{return new Promise((res,rej)=>{node.__node.loops[loopId]=setTimeout(async()=>{res(await fn(...args))},node.__node.delay)})})}else if(node.__node.frame===true){let fn=node.__operator;node.__setOperator((...args)=>{return new Promise((res,rej)=>{node.__node.loops[loopId]=requestAnimationFrame(async()=>{res(await fn(...args))})})})}if(typeof node.__node.repeat==="number"||typeof node.__node.recursive==="number"){let fn=node.__operator;node.__setOperator(async(...args)=>{let i2=node.__node.repeat?node.__node.repeat:node.__node.recursive;let result;let repeater=async(tick,...inp)=>{while(tick>0){if(node.__node.delay||node.__node.frame){fn(...inp).then(async res=>{if(node.__node.recursive){await repeater(tick,res)}else await repeater(tick,...inp)});break}else result=await fn(...args);tick--}};await repeater(i2,...args);return result})}if(node.__node.loop&&typeof node.__node.loop==="number"){let fn=node.__operator;let time=node.__node.loop;node.__setOperator((...args)=>{if(!("looping"in node.__node))node.__node.looping=true;if(node.__node.looping){let last=performance.now();fn(...args);node.__node.loops[loopId]=setTimeout(()=>{let now=performance.now();let overshoot=now-last-node.__node.loop;if(overshoot>0)time=node.__node.loop-overshoot;else time=node.__node.loop;if(time<=0)time=node.__node.loop;node.__operator(...args)},time)}});if(node.__node.looping)node.__operator();let ondelete=node2=>{if(node2.__node.looping)node2.__node.looping=false;if(node2.__node.loops[loopId]){clearTimeout(node2.__node.loops[loopId]);cancelAnimationFrame(node2.__node.loops[loopId])}};node.__addOndisconnected(ondelete)}}};var animate=(node,parent,graph)=>{if(node.__node.animate===true||node.__animation){let fn=node.__operator;node.__setOperator((...args)=>{if(!("animating"in node.__node))node.__node.animating=true;if(node.__node.animating){if(typeof node.__animation==="function")node.__animation(...args);else fn(...args);node.__node.animationFrame=requestAnimationFrame(()=>{node.__operator(...args)})}});if(node.__node.animating||(!("animating"in node.__node)||node.__node.animating)&&node.__animation)setTimeout(()=>{node.__node.animationFrame=requestAnimationFrame(node.__operator)},10);let ondelete=node2=>{if(node2.__node.animating)node2.__node.animating=false;if(node2.__node.animationFrame)cancelAnimationFrame(node2.__node.animationFrame)};node.__addOndisconnected(ondelete)}};var branching=(node,parent,graph)=>{if(typeof node.__branch==="object"&&node.__operator&&!node.__branchApplied){let fn=node.__operator;node.__branchApplied=true;node.__operator=(...args)=>{let result=fn(...args);for(const key in node.__branch){let triggered=()=>{if(typeof node.__branch[key].then==="function"){node.__branch[key].then(result)}else if(node.__branch[key].then instanceof GraphNode&&node.__branch[key].then.__operator){node.__branch[key].then.__operator(result)}else result=node.__branch[key].then};if(typeof node.__branch[key].if==="function"){if(node.__branch[key].if(result)==true){triggered()}}else if(node.__branch[key].if===result){triggered()}}return result}}if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(node.__listeners[key].branch&&!node.__listeners[key].branchApplied){let fn=node.__listeners[key].callback;node.__listeners[key].branchApplied=true;node.__listeners.callback=ret=>{let triggered=()=>{if(typeof node.__listeners[key].branch.then==="function"){ret=node.__listeners[key].branch.then(ret)}else if(node.__listeners[key].branch.then instanceof GraphNode&&node.__listeners[key].branch.then.__operator){ret=node.__listeners[key].branch.then.__operator(ret)}else ret=node.__listeners[key].branch.then};if(typeof node.__listeners[key].branch.if==="function"){if(node.__listeners[key].branch.if(ret)){triggered()}}else if(node.__listeners[key].branch.if===ret){triggered()}return fn(ret)}}}}}};var triggerListenerOncreate=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(node.__listeners[key].oncreate){node.__listeners[key].callback(node.__listeners[key].oncreate)}}}}};var bindListener=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(typeof node.__listeners[key].binding==="object"){node.__listeners.callback=node.__listeners.callback.bind(node.__listeners[key].binding)}}}}};var transformListenerResult=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(typeof node.__listeners[key].transform==="function"&&!node.__listeners[key].transformApplied){let fn=node.__listeners[key].callback;node.__listeners[key].transformApplied=true;node.__listeners.callback=ret=>{ret=node.__listeners[key].transform(ret);return fn(ret)}}}}}};var substitute__operator=(node,parent,graph)=>{if(node.post&&!node.__operator){node.__setOperator(node.post)}else if(!node.__operator&&typeof node.get=="function"){node.__setOperator(node.get)}if(!node.get&&node.__operator){}if(node.aliases){node.aliases.forEach(a=>{graph.set(a,node);let ondelete=node2=>{graph.__node.nodes.delete(a)};node.__addOndisconnected(ondelete)})}if(typeof graph.__node.roots?.[node.__node.tag]==="object"&&node.get)graph.__node.roots[node.__node.tag].get=node.get};var loaders={backprop,loop,animate,branching,triggerListenerOncreate,bindListener,transformListenerResult,substitute__operator};var recursivelyStringifyFunctions=obj=>{let cpy={};for(const key in obj){if(typeof obj[key]==="object"){cpy[key]=recursivelyStringifyFunctions(obj[key])}else if(typeof obj[key]==="function"){cpy[key]=obj[key].toString()}else cpy[key]=obj[key]}return cpy};function getFnParamNames(fn){if(typeof fn!=="string")fn=fn.toString();const arrowMatch=fn.match(/\(?[^]*?\)?\s*=>/);if(arrowMatch)return arrowMatch[0].replace(/[()\s]/gi,"").replace("=>","").split(",");const match=fn.match(/\([^]*?\)/);return match?match[0].replace(/[()\s]/gi,"").split(","):[]}var getFunctionHead=methodString=>{let startindex=methodString.indexOf("=>")+1;if(startindex<=0){startindex=methodString.indexOf("){")}if(startindex<=0){startindex=methodString.indexOf(") {")}return methodString.slice(0,methodString.indexOf("{",startindex)+1)};function parseFunctionFromText(method=""){let getFunctionBody=methodString=>{return methodString.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i,"$2$3$4")};let newFuncHead=getFunctionHead(method);let newFuncBody=getFunctionBody(method);let newFunc;if(newFuncHead.includes("function")){let varName=newFuncHead.substring(newFuncHead.indexOf("(")+1,newFuncHead.lastIndexOf(")"));newFunc=new Function(varName,newFuncBody)}else{if(newFuncHead.substring(0,6)===newFuncBody.substring(0,6)){let varName=newFuncHead.substring(newFuncHead.indexOf("(")+1,newFuncHead.lastIndexOf(")"));newFunc=new Function(varName,newFuncBody.substring(newFuncBody.indexOf("{")+1,newFuncBody.length-1))}else{try{newFunc=(0,eval)(method)}catch{}}}return newFunc}function reconstructObject(json="{}"){try{let parsed=typeof json==="string"?JSON.parse(json):json;const parseObj=obj=>{for(const prop in obj){if(typeof obj[prop]==="string"){let funcParsed=parseFunctionFromText(obj[prop]);if(typeof funcParsed==="function"){obj[prop]=funcParsed}}else if(typeof obj[prop]==="object"){parseObj(obj[prop])}}return obj};return parseObj(parsed)}catch(err){console.error(err);return void 0}}var stringifyWithCircularRefs=function(){const refs=new Map;const parents=[];const path=["this"];function clear(){refs.clear();parents.length=0;path.length=1}function updateParents(key,value){var idx=parents.length-1;var prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value||idx===0){path.push(key);parents.push(value.pushed)}else{while(idx-->=0){prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value){idx+=2;parents.length=idx;path.length=idx;--idx;parents[idx]=value;path[idx]=key;break}}idx--}}}}function checkCircular(key,value){if(value!=null){if(typeof value==="object"){if(key){updateParents(key,value)}let other=refs.get(value);if(other){return"[Circular Reference]"+other}else{refs.set(value,path.join("."))}}}return value}return function stringifyWithCircularRefs3(obj,space){try{parents.push(obj);return JSON.stringify(obj,checkCircular,space)}finally{clear()}}}();if(JSON.stringifyWithCircularRefs===void 0){JSON.stringifyWithCircularRefs=stringifyWithCircularRefs}var stringifyWithFunctionsAndCircularRefs=function(){const refs=new Map;const parents=[];const path=["this"];function clear(){refs.clear();parents.length=0;path.length=1}function updateParents(key,value){var idx=parents.length-1;var prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value||idx===0){path.push(key);parents.push(value.pushed)}else{while(idx-->=0){prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value){idx+=2;parents.length=idx;path.length=idx;--idx;parents[idx]=value;path[idx]=key;break}}idx--}}}}function checkCircular(key,value){if(value!=null){if(typeof value==="object"){if(key){updateParents(key,value)}let other=refs.get(value);if(other){return"[Circular Reference]"+other}else{refs.set(typeof value==="function"?value.toString():value,path.join("."))}}}return typeof value==="function"?value.toString():value}return function stringifyWithFunctionsAndCircularRefs2(obj,space){try{parents.push(obj);return JSON.stringify(obj,checkCircular,space)}finally{clear()}}}();if(JSON.stringifyWithFunctionsAndCircularRefs===void 0){JSON.stringifyWithFunctionsAndCircularRefs=stringifyWithFunctionsAndCircularRefs}var stringifyFast=function(){const refs=new Map;const parents=[];const path=["this"];function clear(){refs.clear();parents.length=0;path.length=1}function updateParents(key,value){var idx=parents.length-1;if(parents[idx]){var prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value||idx===0){path.push(key);parents.push(value.pushed)}else{while(idx-->=0){prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value){idx+=2;parents.length=idx;path.length=idx;--idx;parents[idx]=value;path[idx]=key;break}}idx++}}}}}function checkValues(key,value){let val;if(value!=null){if(typeof value==="object"){let c=value.constructor.name;if(key&&c==="Object"){updateParents(key,value)}let other=refs.get(value);if(other){return"[Circular Reference]"+other}else{refs.set(value,path.join("."))}if(c==="Array"){if(value.length>20){val=value.slice(value.length-20)}else val=value}else if(c.includes("Set")){val=Array.from(value)}else if(c!=="Object"&&c!=="Number"&&c!=="String"&&c!=="Boolean"){val="instanceof_"+c}else if(c==="Object"){let obj={};for(const prop in value){if(value[prop]==null){obj[prop]=value[prop]}else if(Array.isArray(value[prop])){if(value[prop].length>20)obj[prop]=value[prop].slice(value[prop].length-20);else obj[prop]=value[prop]}else if(value[prop].constructor.name==="Object"){obj[prop]={};for(const p in value[prop]){if(Array.isArray(value[prop][p])){if(value[prop][p].length>20)obj[prop][p]=value[prop][p].slice(value[prop][p].length-20);else obj[prop][p]=value[prop][p]}else{if(value[prop][p]!=null){let con=value[prop][p].constructor.name;if(con.includes("Set")){obj[prop][p]=Array.from(value[prop][p])}else if(con!=="Number"&&con!=="String"&&con!=="Boolean"){obj[prop][p]="instanceof_"+con}else{obj[prop][p]=value[prop][p]}}else{obj[prop][p]=value[prop][p]}}}}else{let con=value[prop].constructor.name;if(con.includes("Set")){obj[prop]=Array.from(value[prop])}else if(con!=="Number"&&con!=="String"&&con!=="Boolean"){obj[prop]="instanceof_"+con}else{obj[prop]=value[prop]}}}val=obj}else{val=value}}else{val=value}}return val}return function stringifyFast2(obj,space){parents.push(obj);let res=JSON.stringify(obj,checkValues,space);clear();return res}}();if(JSON.stringifyFast===void 0){JSON.stringifyFast=stringifyFast}function methodstrings(node){if(typeof node.__methods==="object"){for(const key in node.__methods){let fstr=node.__methods[key];let fn=typeof fstr==="function"?fstr:parseFunctionFromText(fstr);if(key==="__operator"){node.__setOperator(fn)}else{node[key]=fn.bind(node)}}}}var Service=class extends Graph{name=`service${Math.floor(Math.random()*1e15)}`;restrict;constructor(options){super({...options,loaders:options?.loaders?Object.assign({...loaders},options.loaders):{...loaders}});if(options?.services)this.addServices(options.services);if(options?.restrict)this.restrict=options.restrict;this.load(this)}addServices=services=>{for(const s in services){if(typeof services[s]==="function")services[s]=new services[s];if(services[s]?.__node?.loaders)Object.assign(this.__node.loaders,services[s].__node.loaders);if(services[s]?.__node?.nodes){services[s].__node.nodes.forEach((n,tag)=>{if(!this.get(tag)){this.set(tag,n)}else this.set(s+"."+tag,n)});this.__node.nodes.forEach((n,k)=>{if(!services[s].__node.nodes.get(k))services[s].__node.nodes.set(k,n)});let set=this.set;this.set=(tag,node)=>{services[s].set(tag,node);return set(tag,node)};let del=this.delete;this.delete=tag=>{services[s].delete(tag);return del(tag)}}else if(typeof services[s]==="object"){this.load(services[s])}}};handleMethod=(route,method,args)=>{let m=method.toLowerCase();let src=this.__node.nodes.get(route);if(!src){src=this.__node.roots[route]}if(src?.[m]){if(typeof src[m]!=="function"){if(args){if(Array.isArray(args)&&args.length===1)src[m]=args[0];else src[m]=args;return}return src[m]}else{if(Array.isArray(args))return src[m](...args);else return src[m](args)}}else return this.handleServiceMessage({route,args,method})};handleServiceMessage(message){let call;if(typeof message==="object"){if(message.route)call=message.route;else if(message.node)call=message.node}if(call){if(Array.isArray(message.args))return this.run(call,...message.args);else return this.run(call,message.args)}else return message}handleGraphNodeCall(route,args){if(!route)return args;if(args?.args){this.handleServiceMessage(args)}else if(Array.isArray(args))return this.run(route,...args);else return this.run(route,args)}transmit=(...args)=>{if(typeof args[0]==="object"){const message=args[0];if(message.method){return this.handleMethod(message.route,message.method,message.args)}else if(message.route){return this.handleServiceMessage(message)}else if(message.node){return this.handleGraphNodeCall(message.node,message.args)}else if(this.__node.keepState){if(message.route)this.setState({[message.route]:message.args});if(message.node)this.setState({[message.node]:message.args})}return void 0}else return void 0};receive=(...args)=>{if(args[0]){let message=args[0];if(typeof message==="string"){let substr=message.substring(0,8);if(substr.includes("{")||substr.includes("[")){if(substr.includes("\\"))message=message.replace(/\\/g,"");if(message[0]==='"'){message=message.substring(1,message.length-1)};message=JSON.parse(message)}}if(typeof message==="object"){if(message.method){if(this.restrict?.[message.route])return void 0;return this.handleMethod(message.route,message.method,message.args)}else if(message.route){if(this.restrict?.[message.route])return void 0;return this.handleServiceMessage(message)}else if(message.node){if(typeof message.node==="string"&&this.restrict?.[message.node])return void 0;return this.handleGraphNodeCall(message.node,message.args)}else if(this.__node.keepState){if(message.route)this.setState({[message.route]:message.args});if(message.node)this.setState({[message.node]:message.args})}return void 0}}return void 0};pipe=(source,destination,endpoint,method,callback)=>{if(source instanceof GraphNode){if(callback)return this.subscribe(source,res=>{let mod=callback(res);if(mod!==void 0)this.transmit({route:destination,args:mod,method});else this.transmit({route:destination,args:res,method},endpoint)});else return this.subscribe(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})}else if(typeof source==="string")return this.subscribe(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})};pipeOnce=(source,destination,endpoint,method,callback)=>{if(source instanceof GraphNode){if(callback)return source.__node.state.subscribeEventOnce(source.__node.unique,res=>{let mod=callback(res);if(mod!==void 0)this.transmit({route:destination,args:mod,method});else this.transmit({route:destination,args:res,method},endpoint)});else return this.__node.state.subscribeEventOnce(source.__node.unique,res=>{this.transmit({route:destination,args:res,method},endpoint)})}else if(typeof source==="string")return this.__node.state.subscribeEventOnce(this.__node.nodes.get(source).__node.unique,res=>{this.transmit({route:destination,args:res,method},endpoint)})};terminate=(...args)=>{};isTypedArray=isTypedArray;recursivelyAssign=recursivelyAssign2;spliceTypedArray=spliceTypedArray;ping=()=>{console.log("pinged!");return"pong"};echo=(...args)=>{this.transmit(...args);return args};log=(...args)=>{console.log(...args);return true};error=(...args)=>{console.error(...args);return true}};function isTypedArray(x){return ArrayBuffer.isView(x)&&Object.prototype.toString.call(x)!=="[object DataView]"}var recursivelyAssign2=(target,obj)=>{for(const key in obj){if(obj[key]?.constructor.name==="Object"&&!Array.isArray(obj[key])){if(target[key]?.constructor.name==="Object"&&!Array.isArray(target[key]))recursivelyAssign2(target[key],obj[key]);else target[key]=recursivelyAssign2({},obj[key])}else target[key]=obj[key]}return target};function spliceTypedArray(arr,start,end){let s=arr.subarray(0,start);let e;if(end){e=arr.subarray(end+1)}let ta;if(s.length>0||e?.length>0)ta=new arr.constructor(s.length+e.length);if(ta){if(s.length>0)ta.set(s);if(e&&e.length>0)ta.set(e,s.length)}return ta}var nodeTemplates={};var remoteGraphRoutes={transferNode:(properties,connection,name2)=>{let str2;if(typeof properties==="object"){if(!properties.__node){properties.__node={}}if(name2)properties.__node.tag=name2;for(const key in properties){if(typeof properties[key]==="function"){if(!properties.__methods)properties.__methods={};properties.__methods[key]=properties[key].toString()}}str2=recursivelyStringifyFunctions(properties)}else if(typeof properties==="function")str2=properties.toString();else if(typeof properties==="string")str2=properties;if(str2){if(connection.run)return connection.run("setNode",[str2]);else if(connection.postMessage){connection.postMessage({route:"setNode",args:str2},void 0);return new Promise(r=>r(name2))}else if(connection.send){connection.send(JSON.stringify({route:"setNode",args:str2}));return new Promise(r=>r(name2))}}},setNode:function(properties,name2){if(typeof properties==="object"){if(properties.__methods){if(!this.__node.graph.__node.loaders.methodstrings){this.__node.graph.__node.loaders.methodstrings=methodstrings}}}if(typeof properties==="string"){let f=parseFunctionFromText(properties);if(typeof f==="function")properties={__operator:f,__node:{tag:name2?name2:f.name}};else{f=JSON.parse(properties);if(typeof f==="object")properties=f}}if(typeof properties==="object"||typeof properties==="function"){let template={};if(typeof properties==="object")Object.assign(template,properties);else template.__operator=properties;let node=this.__node.graph.add(template);if(node){nodeTemplates[node.__node.tag]=template;return node.__node?.tag}else return false}else return false},makeNodeTransferrable:function(properties,name2){if(!properties.__node){properties.__node={}}if(name2)properties.__node.tag=name2;for(const key in properties){if(typeof properties[key]==="function"){if(!properties.__methods)properties.__methods={};properties.__methods[key]=properties[key].toString()}}const str2=recursivelyStringifyFunctions(properties);return str2},getListenerJSON:function(){const triggers=this.__node.state.triggers;let result={};for(const key in triggers){triggers[key].forEach(trigger=>{let t2=trigger;if(!result[t2.target])result[t2.target]={};let l=t2.source+(t2.key?"."+t2.key:"");result[t2.target][l]={__callback:t2.__callback};if(t2.__args)result[t2.target][l].__args=t2.__args;if(t2.subInput)result[t2.target][l].subInput=t2.subInput})}return result},makeRootTransferrable:function(){let roots={};for(const r in this.__node.graph.__node.roots){let properties=this.__node.graph.__node.roots[r];if(typeof properties==="function"){roots[r]=properties.toString()}else if(typeof properties!=="object"){roots[r]=properties}else{roots[r]={};let keys2=Object.getOwnPropertyNames(properties).filter(v=>!objProps2.includes(v));let nonArrowFunctions=Object.getOwnPropertyNames(Object.getPrototypeOf(properties)).filter(v=>!objProps2.includes(v));keys2.push(...nonArrowFunctions);for(const key of keys2){if(typeof properties[key]==="function"){roots[r][key]=properties[key].toString()}else if(typeof properties[key]==="object")roots[r][key]=stringifyWithFunctionsAndCircularRefs(properties[key]);else roots[r][key]=properties[key]}}}return roots},setTemplate:function(properties,name2){if(typeof properties==="object"){if(properties.__methods){if(!this.__node.graph.__node.loaders.methodstrings){this.__node.graph.__node.loaders.methodstrings=methodstrings}}}if(typeof properties==="string"){let f=parseFunctionFromText(properties);if(typeof f==="function"){if(!name2)name2=f.name;properties={__operator:f,__node:{tag:name2}}}else{f=JSON.parse(properties);if(typeof f==="object"){properties=f;if(!name2&&f.__node?.tag)name2=f.__node.tag}}}if(!name2)name2=`node${Math.floor(Math.random()*1e15)}`;if(typeof properties==="object"||typeof properties==="function"){nodeTemplates[name2]=properties;return name2}else return false},loadFromTemplate:function(templateName,name2,properties){if(nodeTemplates[templateName]){let cpy=recursivelyAssign2({},nodeTemplates[templateName]);if(name2){if(!cpy.__node)cpy.__node={};cpy.__node.tag=name2}if(properties)Object.assign(cpy,properties);let node=this.__node.graph.add(cpy);return node.__node.tag}},setMethod:function(nodeTag,fn,methodKey){if(typeof fn==="string"){let f=parseFunctionFromText(fn);if(typeof f==="function")fn=f}if(!methodKey&&typeof fn==="function")methodKey=fn.name;if(this.__node.graph.get(nodeTag)){this.__node.graph.get(nodeTag)[methodKey]=fn}else this.__node.graph.add({__node:{tag:methodKey,[methodKey]:fn}});return true},assignNode:function(nodeTag,source){if(this.__node.graph.get(nodeTag)&&typeof source==="object"){Object.assign(this.__node.graph.get(nodeTag),source)}},getNodeProperties:function(nodeTag){let node=this.__node.graph.get(nodeTag);if(node){let properties=Object.getOwnPropertyNames(node);let result={};for(const key of properties){if(typeof node[key]==="function"){let str2=node[key].toString();let isNative=str2.indexOf("[native code]")>-1;result[key]={type:"function",args:getFnParamNames(node[key]),native:isNative}}else result[key]=typeof node[key]}return result}return void 0},proxyRemoteNode:function(name2,connection){return new Promise((res,rej)=>{connection.run("getNodeProperties",name2).then(props=>{let proxy={};if(typeof props==="object"){for(const key in props){if(props[key]?.type==="function"){if(props[key].native||props[key].args){proxy[key]=(...args)=>{return new Promise(r=>{connection.run(name2,args,key).then(r)})}}else{proxy[key]=()=>{return new Promise(r=>{connection.run(name2,void 0,key).then(r)})}}}else{Object.defineProperty(proxy,key,{get:()=>{return new Promise(r=>{connection.run(name2,void 0,key).then(r)})},set:value=>{connection.post(name2,value,key)},configurable:true,enumerable:true})}}}res(proxy)})})},transferClass:(classObj,connection,className)=>{if(typeof classObj==="object"){let str2=classObj.toString();let message={route:"receiveClass",args:[str2,className]};if(connection.run)return connection.run("receiveClass",[str2,className]);else if(connection.postMessage){connection.postMessage({route:"receiveClass",args:[str2,className]},void 0);return new Promise(r=>r(name))}else if(connection.send){connection.send(JSON.stringify({route:"receiveClass",args:[str2,className]}));return new Promise(r=>r(name))}return message}return false},receiveClass:function(stringified,className){if(typeof stringified==="string"){if(stringified.indexOf("class")===0){let cls=(0,eval)("("+stringified+")");let name2=className;if(!name2)name2=cls.name;this.__node.graph[name2]=cls;return true}}return false},transferFunction:(fn,connection,fnName)=>{if(!fnName)fnName=fn.name;let str2=fn.toString();let message={route:"setNode",args:[str2,fnName]};if(connection.run)return connection.run("setNode",[str2,fnName]);else if(connection.postMessage){connection.postMessage({route:"setNode",args:[str2,fnName]},void 0);return new Promise(r=>r(fnName))}else if(connection.send){connection.send(JSON.stringify({route:"setNode",args:[str2,fnName]}));return new Promise(r=>r(fnName))}return message},setGlobal:(key,value)=>{globalThis[key]=value;return true},assignGlobalObject:(target,source)=>{if(!globalThis[target])return false;if(typeof source==="object")Object.assign(globalThis[target],source);return true},setValue:function(key,value){this.__node.graph[key]=value;return true},assignObject:function(target,source){if(!this.__node.graph[target])return false;if(typeof source==="object")Object.assign(this.__node.graph[target],source);return true},setGlobalFunction:(fn,fnName)=>{if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function"){if(!fnName)fnName=fn.name;globalThis[fnName]=fn;return true}return false},setGraphFunction:function(fn,fnName){if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function"){if(!fnName)fnName=fn.name;this.__node.graph[fnName]=fn;return true}return false}};var objProps2=Object.getOwnPropertyNames(Object.getPrototypeOf({}));var ECSService=class extends Service{entities={};systems={};entityMap=new Map;entityKeyMap=new Map;order=[];animating=false;entityCt=0;systemCt=0;constructor(options){super(options);this.load(this);if(options?.systems)for(const key in options.systems){this.addSystem(options.systems[key],void 0,void 0,void 0,void 0,options.order)}if(options?.entities){for(const key in options.entities){this.addEntity(options.entities[key],options.entities[key].components)}}}updateEntities=(order=this.order,filter,debug=false)=>{order.forEach(k=>{if(this.systems[k]){if(filter){if(debug)debug=performance.now();if(this.entityKeyMap.get(k).length>0)this.systems[k].__operator(this.entityMap.get(k));if(debug)console.log("system",k,"took",performance.now()-debug,"ms for",Object.keys(this.entityMap.get(k)).length,"entities")}else{if(debug)debug=performance.now();if(this.entityKeyMap.get(k).length>0)this.systems[k].__operator(this.entities);if(debug)console.log("system",k,"took",performance.now()-debug,"ms for",Object.keys(this.entities).length,"entities")}}})};animateEntities=(filter=true,order)=>{if(!this.animating){this.animating=true;if(typeof requestAnimationFrame!=="undefined"){let anim=()=>{requestAnimationFrame(()=>{if(this.animating){this.updateEntities(order,filter);anim()}})};anim()}else{let looper=()=>{setTimeout(async()=>{if(this.animating){this.updateEntities(order,filter);looper()}},10)};looper()}}};stop=()=>{this.animating=false};start=filter=>{this.animateEntities(filter)};addEntities=(prototype,components={},count=1)=>{let i2=0;let newEntities={};while(i2{if(!prototype)return;const entity=this.recursivelyAssign({},prototype);entity.components=components;if(Object.keys(components).length===0){Object.keys(this.systems).forEach(k=>{components[k]=true})}if(!entity.__node)entity.__node={};if(entity.__node.tag&&this.entities[entity.__node.tag]){this.entityCt++;let tag=entity.__node.tag+this.entityCt;while(this.entities[entity.__node.tag]){this.entityCt++;entity.__node.tag=`${tag}${this.entityCt}`}}else if(!entity.__node.tag)entity.__node.tag=`entity${Math.floor(Math.random()*1e15)}`;this.add(entity);this.entities[entity.__node.tag]=this.__node.nodes.get(entity.__node.tag);this.setupEntity(this.entities[entity.__node.tag]);return this.entities[entity.__node.tag]};addSystems=(systems={},order)=>{for(const key in systems){systems[key].__node.tag=key;this.addSystem(systems[key],void 0,void 0,void 0,void 0,order)}return this.systems};addSystem=(prototype,setupEntities,setupEntity,operator,remove,order)=>{if(!prototype)return;const system=this.recursivelyAssign({},prototype);if(setupEntities)system.setupEntities=setupEntities;if(setupEntity)system.setupEntity=setupEntity;if(operator)system.__operator=operator;if(remove)system.remove=remove;if(system.__node.tag&&this.systems[system.__node.tag]){this.systemCt++;let tag=system.__node.tag+this.systemCt;while(this.systems[system.__node.tag]){this.systemCt++;system.__node.tag=`${tag}${this.systemCt}`}}else if(!system.__node.tag)system.__node.tag=`system${Math.floor(Math.random()*1e15)}`;this.add(system);this.systems[system.__node.tag]=this.__node.nodes.get(system.__node.tag);if(!this.entityMap.get(system.__node.tag))this.entityMap.set(system.__node.tag,{});if(!this.entityKeyMap.get(system.__node.tag))this.entityKeyMap.set(system.__node.tag,[]);this.systems[system.__node.tag].entities=this.entityMap.get(system.__node.tag);this.systems[system.__node.tag].entityKeys=this.entityKeyMap.get(system.__node.tag);if(this.systems[system.__node.tag]?.setupEntities&&Object.keys(this.entities).length>1){let filtered=this.filterObject(this.entities,(key,v)=>{if(v.components[system.__node.tag])return true});this.systems[system.__node.tag].setupEntities(filtered);Object.assign(this.entityMap.get(system.__node.tag),filtered)}if(!order)this.order.push(system.__node.tag);else this.order=order;return this.systems[system.__node.tag]};setupEntity=entity=>{if(entity?.components){for(const key in entity.components){if(this.systems[key]){this.systems[key].setupEntity(entity);this.entityMap.get(key)[entity.__node.tag]=entity;this.entityKeyMap.get(key).push(entity.__node.tag)}}}};removeEntity=tag=>{const entity=this.entities[tag];for(const key in entity.components){if(this.entityMap.get(key)){delete this.entityMap.get(key)[entity.__node.tag];this.entityKeyMap.get(key).splice(this.entityKeyMap.get(key).indexOf(entity.__node.tag),1)}if(this.systems[key]?.remove){this.systems[key].remove(entity,this.entityMap.get(key))}}delete this.entities[tag];return this.remove(tag)};removeEntities(entities){if(!Array.isArray(entities))entities=Object.keys(entities);entities.forEach(t2=>{this.removeEntity(t2)})}removeSystem=tag=>{if(this.systems[tag]?.remove){for(const e in this.entityKeyMap.get(tag)){this.systems[tag].remove(this.entityMap.get(tag)[e],this.entityMap.get(tag))}}delete this.systems[tag];this.entityMap.delete(tag);this.entityKeyMap.delete(tag);this.order.splice(this.order.indexOf(tag),1);return this.remove(tag)};filterObject(o,filter){return Object.fromEntries(Object.entries(o).filter(([key,value])=>{filter(key,value)}))}setEntities=(entities,props)=>{if(Array.isArray(entities)){entities.forEach(k=>{if(this.entities[k])this.recursivelyAssign(this.entities[k],props)})}else{for(const key in this.entities){this.setEntity(this.entities[key],props)}}return true};setEntity=(entity,props)=>{return this.recursivelyAssign(entity,props)};bufferValues=(entities,property,keys2,buffer)=>{if(!Array.isArray(keys2)&&typeof keys2==="object")keys2=Object.keys(keys2);if(!buffer){let entkeys=Object.keys(entities);if(keys2)buffer=new Float32Array(entkeys.length*keys2.length);else{if(typeof entities[entkeys[0]][property]==="object"){keys2=Object.keys(entities[entkeys[0]][property]);buffer=new Float32Array(entkeys.length*keys2.length)}else buffer=new Float32Array(entkeys.length)}}let i2=0;for(const key in entities){if(entities[key][property]){if(keys2){for(let j=0;j{combinedHTML+=string;if(args[i2]instanceof HTMLElement){combinedHTML+=``}else if(args[i2]!==void 0){combinedHTML+=args[i2]}};strings.forEach(withStr);template.innerHTML=combinedHTML;let dummyNodes=Array.from(template.content.querySelectorAll(`#${rand}`));const withArg=(arg,i2)=>{if(arg instanceof HTMLElement){let dummyNode=dummyNodes[i2];if(dummyNode){dummyNode.parentNode.replaceChild(arg,dummyNode)}}};args.forEach(withArg);if(elm){elm.appendChild(template.content);return elm}return template.content}}function xml(strings,...args){return function append(elm,namespace="http://www.w3.org/1999/xhtml"){let parser=new DOMParser;let serializer=new XMLSerializer;let xmlDoc=parser.parseFromString('',"application/xml");let template=xmlDoc.createElement("template");xmlDoc.documentElement.appendChild(template);for(let i2=0;i2{if(node.__onresize){let onresize=node.__onresize;node.__onresize=ev=>{onresize.call(node,ev,node.__props)}}if(node.__onremove){let ondelete=node.__onremove;node.__onremove=element=>{ondelete.call(node,element)}}if(node.__onrender){let onrender=node.__onrender;node.__onrender=element=>{onrender.call(node,element)}}if(node.tagName||node.__element){if(node.tagName)node.__props=document.createElement(node.tagName);else if(node.__element){if(node.__element instanceof HTMLElement)node.__props=node.__element;else node.__props=document.createElement(node.__element)}if(!(node.__props instanceof HTMLElement))return}if(node.__props instanceof HTMLElement){let cpy=Object.assign({},node);let keys2=Object.getOwnPropertyNames(cpy);for(const k of keys2){if(k==="style"&&typeof node[k]==="object"){Object.assign(node.__props.style,cpy[k])}else if(k==="className")node.__props.setAttribute("class",cpy[k]);else if(!k.includes("outer"))node.__props[k]=cpy[k]}if(node.__attributes){for(const k in node.__attributes){if(k==="style"&&typeof node.__attributes[k]==="object"){Object.assign(node.__props.style,node.__attributes[k])}else if(k==="className")node.__props.setAttribute("class",node.__attributes[k]);else if(!k.includes("outer"))node.__props[k]=node.__attributes[k]}}node.__proxyObject(node.__props);for(const k of keys2){if(typeof cpy[k]==="function"){let fn=cpy[k];node.__props[k]=(...inp)=>{let res=fn(...inp);node.__node.state.triggerEvent(node.__node.unique+"."+k,res)};node[k]=node.__props[k]}}if(node.__attributes){for(const k in node.__attributes){if(typeof cpy[k]==="function"){let fn=node.__attributes[k];node.__props[k]=(...inp)=>{let res=fn(...inp);node.__node.state.triggerEvent(node.__node.unique+"."+k,res)};node[k]=node.__props[k]}}}if(node.__onresize)window.addEventListener("resize",node.__onresize)}if(node.__props instanceof HTMLElement){node.__props.id=key;node.__props.node=node;node.__addOnconnected(n=>{if(!(node.__props instanceof HTMLBodyElement||node.__props instanceof HTMLHeadElement)&&n.__props.parentNode)n.__props.remove();if(properties.parentNode){if(typeof properties.parentNode==="string"&&document.getElementById(properties.parentNode))document.getElementById(properties.parentNode)?.appendChild(n.__props);else if(properties.parentNode instanceof HTMLElement)properties.parentNode.appendChild(n.__props)}else if(parent?.__props instanceof HTMLElement){parent.__props.appendChild(node.__props)}else if(typeof graph.parentNode==="string"&&document.getElementById(properties.parentNode)){document.getElementById(properties.parentNode)?.appendChild(graph.__props)}else if(graph.parentNode instanceof HTMLElement){graph.parentNode.appendChild(node.__props)}else if(!(node.__props instanceof HTMLBodyElement||node.__props instanceof HTMLHeadElement))document.body.appendChild(node.__props);if(node.__onrender)setTimeout(()=>{node.__onrender(node.__props)},.01)});node.__addOndisconnected(n=>{n.__props.remove();if(typeof n.__onremove==="function"){n.__onremove(n.__props)}if(n.__onresize){window.removeEventListener("resize",n.__onresize)}})}};var dummy=html``;var DOMElement=class extends HTMLElement{useShadow=false;FRAGMENT;STYLE;attachedShadow=false;static get tag(){return this.name.toLowerCase()+"-"}obsAttributes=["props","options","onchanged","onresize","ondelete","oncreate","template"];props={};static addElement(tag=this.tag,cls=this,extend=void 0){addCustomElement(cls,tag,extend)}attributeChangedCallback=(name2,old,val)=>{if(name2==="onchanged"){let onchanged=val;if(typeof onchanged==="string")onchanged=parseFunctionFromText2(onchanged);if(typeof onchanged==="function"){this.onchanged=onchanged;this.state.data.props=this.props;this.state.unsubscribeTrigger("props");this.state.subscribeTrigger("props",this.onchanged);let changed=new CustomEvent("changed",{detail:{props:this.props,self:this}});this.state.subscribeTrigger("props",()=>{this.dispatchEvent(changed)})}}else if(name2==="onresize"){let onresize=val;if(typeof onresize==="string")onresize=parseFunctionFromText2(onresize);if(typeof onresize==="function"){if(this.ONRESIZE){try{window.removeEventListener("resize",this.ONRESIZE)}catch(err){}}this.ONRESIZE=ev=>{this.onresize(this.props,this)};this.onresize=onresize;window.addEventListener("resize",this.ONRESIZE)}}else if(name2==="ondelete"){let ondelete=val;if(typeof ondelete==="string")ondelete=parseFunctionFromText2(ondelete);if(typeof ondelete==="function"){this.ondelete=()=>{if(this.ONRESIZE)window.removeEventListener("resize",this.ONRESIZE);this.state.unsubscribeTrigger("props");if(ondelete)ondelete(this.props,this)}}}else if(name2==="oncreate"){let oncreate=val;if(typeof oncreate==="string")oncreate=parseFunctionFromText2(oncreate);if(typeof oncreate==="function"){this.oncreate=oncreate}}else if(name2==="renderonchanged"){let rpc=val;if(typeof this.renderonchanged==="number")this.unsubscribeTrigger(this.renderonchanged);if(typeof rpc==="string")rpc=parseFunctionFromText2(rpc);if(typeof rpc==="function"){this.renderonchanged=this.state.subscribeTrigger("props",p=>{this.render(p);rpc(this,p)})}else if(rpc!=false)this.renderonchanged=this.state.subscribeTrigger("props",this.render)}else if(name2==="props"){let newProps=val;if(typeof newProps==="string")newProps=JSON.parse(newProps);Object.assign(this.props,newProps);this.state.setState({props:this.props})}else if(name2==="template"){let template=val;this.template=template;this.render(this.props);let created=new CustomEvent("created",{detail:{props:this.props}});this.dispatchEvent(created)}else{let parsed=val;if(name2.includes("eval_")){name2=name2.split("_");name2.shift();name2=name2.join();parsed=parseFunctionFromText2(val)}else if(typeof val==="string"){try{parsed=JSON.parse(val)}catch(err){parsed=val}}this[name2]=parsed;if(name2!=="props"&&this.props)this.props[name2]=parsed}};connectedCallback(){if(!this.props)this.props={};let newProps=this.getAttribute("props");if(typeof newProps==="string")newProps=JSON.parse(newProps);Object.assign(this.props,newProps);this.state.setState({props:this.props});Array.from(this.attributes).forEach(att=>{let name2=att.name;let parsed=att.value;if(name2.includes("eval_")||name2.includes("()")){if(name2.includes("eval_"))name2=name2.split("_");else if(name2.includes("()"))name2=name2.substring(0,name2.indexOf("("));name2.shift();name2=name2.join();parsed=parseFunctionFromText2(att.value)}else if(typeof att.value==="string"){try{parsed=JSON.parse(att.value)}catch(err){parsed=att.value}}if(!this[name2]){Object.defineProperties(this,att,{value:parsed,writable:true,get(){return this[name2]},set(val){this.setAttribute(name2,val)}})}this[name2]=parsed;if(name2!=="props")this.props[name2]=parsed;this.obsAttributes.push(name2)});let resizeevent=new CustomEvent("resized",{detail:{props:this.props,self:this}});let changed=new CustomEvent("changed",{detail:{props:this.props,self:this}});let deleted=new CustomEvent("deleted",{detail:{props:this.props,self:this}});let created=new CustomEvent("created",{detail:{props:this.props,self:this}});this.render(this.props);this.dispatchEvent(created);this.state.subscribeTrigger("props",()=>{this.dispatchEvent(changed)});if(typeof this.onresize==="function"){if(this.ONRESIZE){try{window.removeEventListener("resize",this.ONRESIZE)}catch(err){}}this.ONRESIZE=ev=>{this.onresize(this,this.props);this.dispatchEvent(resizeevent)};window.addEventListener("resize",this.ONRESIZE)}if(typeof this.ondelete==="function"){let ondelete=this.ondelete;this.ondelete=(props=this.props)=>{if(this.ONRESIZE)window.removeEventListener("resize",this.ONRESIZE);this.state.unsubscribeTrigger("props");this.dispatchEvent(deleted);ondelete(this,props)}}if(typeof this.onchanged==="function"){this.state.data.props=this.props;this.state.subscribeTrigger("props",this.onchanged)}if(this.renderonchanged){let rpc=this.renderonchanged;if(typeof this.renderonchanged==="number")this.unsubscribeTrigger(this.renderonchanged);if(typeof rpc==="string")rpc=parseFunctionFromText2(rpc);if(typeof rpc==="function"){this.renderonchanged=this.state.subscribeTrigger("props",p=>{this.render(p);rpc(this,p)})}else if(rpc!==false)this.renderonchanged=this.state.subscribeTrigger("props",this.render)}}constructor(){super()}delete=()=>{this.remove();if(typeof this.ondelete==="function")this.ondelete(this.props)};render=(props=this.props)=>{const t2=document.createElement("template");let usingHTMLFunction=this.template.prototype?.constructor?.name==dummy.prototype.constructor.name;if(typeof this.template==="function"){if(usingHTMLFunction){this.template(t2.content)}else this.templateResult=this.template(this,props)}else this.templateResult=this.template;if(this.styles)this.templateResult=`${this.templateResult}`;if(!usingHTMLFunction){if(typeof this.templateResult==="string")t2.innerHTML=this.templateResult;else if(this.templateResult instanceof HTMLElement||this.templateResult instanceof DocumentFragment){if(this.templateResult.parentNode){this.templateResult.parentNode.removeChild(this.templateResult)}t2.content.appendChild(this.templateResult)}}const fragment=t2.content;if(this.FRAGMENT){if(this.useShadow){if(this.STYLE)this.shadowRoot.removeChild(this.STYLE);this.FRAGMENT.forEach(c=>{this.shadowRoot.removeChild(c)})}else this.FRAGMENT.forEach(c=>{this.removeChild(c)})}if(this.useShadow){if(!this.attachedShadow){this.attachShadow({mode:"open"}).innerHTML="";this.attachedShadow=true}if(this.styles){let style=document.createElement("style");style.textContent=this.styles;this.shadowRoot.prepend(style);this.STYLE=style}let len=fragment.childNodes.length;this.shadowRoot.prepend(fragment);this.FRAGMENT=Array.from(this.shadowRoot.childNodes).slice(0,len)}else{let len=fragment.childNodes.length;this.prepend(fragment);this.FRAGMENT=Array.from(this.childNodes).slice(0,len)}let rendered=new CustomEvent("rendered",{detail:{props:this.props,self:this}});this.dispatchEvent(rendered);if(this.oncreate)this.oncreate(this,props)};state={pushToState:{},data:{},triggers:{},setState(updateObj){Object.assign(this.pushToState,updateObj);if(Object.keys(this.triggers).length>0){for(const prop of Object.getOwnPropertyNames(this.triggers)){if(this.pushToState[prop]){this.data[prop]=this.pushToState[prop];delete this.pushToState[prop];this.triggers[prop].forEach(obj=>{obj.onchanged(this.data[prop])})}}}return this.pushToState},subscribeTrigger(key,onchanged=res=>{}){if(key){if(!this.triggers[key]){this.triggers[key]=[]}let l=this.triggers[key].length;this.triggers[key].push({idx:l,onchanged});return this.triggers[key].length-1}else return void 0},unsubscribeTrigger(key,sub){let triggers=this.triggers[key];if(triggers){if(!sub)delete this.triggers[key];else{let idx=void 0;let obj=triggers.find((o,i2)=>{if(o.idx===sub){idx=i2;return true}});if(obj)triggers.splice(idx,1);return true}}},subscribeTriggerOnce(key=void 0,onchanged=value=>{}){let sub;let changed=value=>{onchanged(value);this.unsubscribeTrigger(key,sub)};sub=this.subscribeTrigger(key,changed)}}};function addCustomElement(cls,tag,extend=null){try{if(extend){if(tag)window.customElements.define(tag,cls,{extends:extend});else window.customElements.define(cls.name.toLowerCase()+"-",cls,{extends:extend})}else{if(tag)window.customElements.define(tag,cls);else window.customElements.define(cls.name.toLowerCase()+"-",cls)}}catch(err){}}function parseFunctionFromText2(method){let getFunctionBody=methodString=>{return methodString.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i,"$2$3$4")};let getFunctionHead3=methodString=>{let startindex=methodString.indexOf(")");return methodString.slice(0,methodString.indexOf("{",startindex)+1)};let newFuncHead=getFunctionHead3(method);let newFuncBody=getFunctionBody(method);let newFunc;try{if(newFuncHead.includes("function")){let varName=newFuncHead.split("(")[1].split(")")[0];newFunc=new Function(varName,newFuncBody)}else{if(newFuncHead.substring(0,6)===newFuncBody.substring(0,6)){let varName=newFuncHead.split("(")[1].split(")")[0];newFunc=new Function(varName,newFuncBody.substring(newFuncBody.indexOf("{")+1,newFuncBody.length-1))}else{try{newFunc=(0,eval)(newFuncHead+newFuncBody+"}")}catch(err){newFunc=(0,eval)(method)}}}}catch(err){}return newFunc}var wchtmlloader=(node,parent,graph,roots,properties,key)=>{if(node.__onresize){let onresize=node.__onresize;node.__onresize=ev=>{onresize.call(node,ev,node.__props)}}if(node.__onremove){let ondelete=node.__onremove;node.__onremove=element=>{ondelete.call(node,element)}}if(node.__onrender){let onrender=node.__onrender;node.__onrender=element=>{onrender.call(node,element)}}if((node.tagName||node.__element)&&!node.__props&&!node.__template){if(node.tagName)node.__props=document.createElement(node.tagName);else if(node.__element){if(node.__element instanceof HTMLElement)node.__props=node.__element;else node.__props=document.createElement(node.__element)}if(!(node.__props instanceof HTMLElement))return}else if(typeof node.__css==="string"){node.__template+=``;delete node.__css}const registerElement=(node2,tagNameOverride)=>{if(isNativeClass(node2))node2=new node2;else if(typeof node2==="function"&&!node2.__node)node2=node2();class CustomElement extends DOMElement{props=node2.props;styles=node2.__css;useShadow=node2.useShadow;template=node2.__template;oncreate=node2.__onrender;onresize=node2.__onresize;ondelete=node2.__onremove;renderonchanged=node2.__renderonchanged}if(tagNameOverride?.includes("-"))node2.tagName=tagNameOverride;else if(node2.__element)node2.tagName=node2.__element;if(!node2.tagName)node2.tagName=`element${Math.floor(Math.random()*1e15)}-`;CustomElement.addElement(node2.tagName)};if("__components"in node){if(Array.isArray(node.__components))node.__components.forEach(c=>registerElement(c));else Object.entries(node.__components).forEach(([k,c])=>registerElement(c,k.includes("-")?k:void 0))}if("__template"in node){if(typeof node.__renderonchanged==="function"){let renderonchanged=node.__renderonchanged;node.__renderonchanged=element=>{renderonchanged.call(element.node,element)}}registerElement(node);node.__props=document.createElement(node.tagName);let cpy=Object.assign({},node);let keys2=Object.getOwnPropertyNames(cpy);for(const k of keys2){if(k==="style"&&typeof node[k]==="object"){Object.assign(node.__props.style,cpy[k])}else if(k==="className")node.__props.setAttribute("class",cpy[k]);else if(!k.includes("outer"))node.__props[k]=cpy[k]}if(node.__attributes){for(const k in node.__attributes){if(k==="style"&&typeof node.__attributes[k]==="object"){Object.assign(node.__props.style,node.__attributes[k])}else if(k==="className")node.__props.setAttribute("class",node.__attributes[k]);else if(!k.includes("outer"))node.__props[k]=node.__attributes[k]}}node.__proxyObject(node.__props);for(const k of keys2){if(typeof cpy[k]==="function"){let fn=cpy[k];node.__props[k]=(...inp)=>{let res=fn(...inp);node.__node.state.triggerEvent(node.__node.unique+"."+k,res)}}}if(node.__attributes){for(const k in node.__attributes){if(typeof cpy[k]==="function"){let fn=node.__attributes[k];node.__props[k]=(...inp)=>{let res=fn(...inp);node.__node.state.triggerEvent(node.__node.unique+"."+k,res)}}}}}else if(node.__props instanceof HTMLElement){let cpy=Object.assign({},node);let keys2=Object.getOwnPropertyNames(cpy);for(const k of keys2){if(k==="style"&&typeof node[k]==="object"){Object.assign(node.__props.style,cpy[k])}else if(k==="className")node.__props.setAttribute("class",cpy[k]);else if(!k.includes("outer"))node.__props[k]=cpy[k]}if(node.__attributes){for(const k in node.__attributes){if(k==="style"&&typeof node.__attributes[k]==="object"){Object.assign(node.__props.style,node.__attributes[k])}else if(k==="className")node.__props.setAttribute("class",cpy[k]);else if(!k.includes("outer"))node.__props[k]=node.__attributes[k]}}node.__proxyObject(node.__props);for(const k of keys2){if(typeof cpy[k]==="function"){let fn=cpy[k];node.__props[k]=(...inp)=>{let res=fn(...inp);node.__node.state.triggerEvent(node.__node.unique+"."+k,res)};node[k]=node.__props[k]}}if(node.__attributes){for(const k in node.__attributes){if(typeof cpy[k]==="function"){let fn=node.__attributes[k];node.__props[k]=(...inp)=>{let res=fn(...inp);node.__node.state.triggerEvent(node.__node.unique+"."+k,res)};node[k]=node.__props[k]}}}if(node.__onresize)window.addEventListener("resize",node.__onresize)}if(node.__props instanceof HTMLElement){node.__props.id=key;node.__props.node=node;node.__addOnconnected(n=>{if(!(node.__props instanceof HTMLBodyElement||node.__props instanceof HTMLHeadElement)&&n.__props.parentNode)n.__props.remove();if(properties.parentNode){if(typeof properties.parentNode==="string"&&document.getElementById(properties.parentNode))document.getElementById(properties.parentNode)?.appendChild(n.__props);else if(properties.parentNode instanceof HTMLElement)properties.parentNode.appendChild(n.__props)}else if(parent?.__props instanceof HTMLElement){parent.__props.appendChild(node.__props)}else if(typeof graph.parentNode==="string"&&document.getElementById(properties.parentNode)){document.getElementById(properties.parentNode)?.appendChild(graph.__props)}else if(graph.parentNode instanceof HTMLElement){graph.parentNode.appendChild(node.__props)}else if(!(node.__props instanceof HTMLBodyElement||node.__props instanceof HTMLHeadElement))document.body.appendChild(node.__props);if(node.__onrender&&!(node.__props instanceof DOMElement)&&!node.__template)setTimeout(()=>{node.__onrender(node.__props)},.01)});node.__addOndisconnected(n=>{n.__props.remove();if(typeof n.__onremove==="function"){n.__onremove(n.__props)}if(n.__onresize){window.removeEventListener("resize",n.__onresize)}})}};var sjcl={cipher:{},hash:{},keyexchange:{},mode:{},misc:{},codec:{},exception:{corrupt:function(a){this.toString=function(){return"CORRUPT: "+this.message};this.message=a},invalid:function(a){this.toString=function(){return"INVALID: "+this.message};this.message=a},bug:function(a){this.toString=function(){return"BUG: "+this.message};this.message=a},notReady:function(a){this.toString=function(){return"NOT READY: "+this.message};this.message=a}}};sjcl.cipher.aes=function(a){this.s[0][0][0]||this.O();var b,c,d,e,f=this.s[0][4],g=this.s[1];b=a.length;var h=1;if(4!==b&&6!==b&&8!==b)throw new sjcl.exception.invalid("invalid aes key size");this.b=[d=a.slice(0),e=[]];for(a=b;a<4*b+28;a++){c=d[a-1];if(0===a%b||8===b&&4===a%b)c=f[c>>>24]<<24^f[c>>16&255]<<16^f[c>>8&255]<<8^f[c&255],0===a%b&&(c=c<<8^c>>>24^h<<24,h=h<<1^283*(h>>7));d[a]=d[a-b]^c}for(b=0;a;b++,a--)c=d[b&3?a:a-4],e[b]=4>=a||4>b?c:g[0][f[c>>>24]]^g[1][f[c>>16&255]]^g[2][f[c>>8&255]]^g[3][f[c&255]]};sjcl.cipher.aes.prototype={encrypt:function(a){return t(this,a,0)},decrypt:function(a){return t(this,a,1)},s:[[[],[],[],[],[]],[[],[],[],[],[]]],O:function(){var a=this.s[0],b=this.s[1],c=a[4],d=b[4],e,f,g,h=[],k=[],l,n,m,p;for(e=0;256>e;e++)k[(h[e]=e<<1^283*(e>>7))^e]=e;for(f=g=0;!c[f];f^=l||1,g=k[g]||1)for(m=g^g<<1^g<<2^g<<3^g<<4,m=m>>8^m&255^99,c[f]=m,d[m]=f,n=h[e=h[l=h[f]]],p=16843009*n^65537*e^257*l^16843008*f,n=257*h[m]^16843008*m,e=0;4>e;e++)a[e][f]=n=n<<24^n>>>8,b[e][m]=p=p<<24^p>>>8;for(e=0;5>e;e++)a[e]=a[e].slice(0),b[e]=b[e].slice(0)}};function t(a,b,c){if(4!==b.length)throw new sjcl.exception.invalid("invalid aes block size");var d=a.b[c],e=b[0]^d[0],f=b[c?3:1]^d[1],g=b[2]^d[2];b=b[c?1:3]^d[3];var h,k,l,n=d.length/4-2,m,p=4,r=[0,0,0,0];h=a.s[c];a=h[0];var q=h[1],v=h[2],w=h[3],x=h[4];for(m=0;m>>24]^q[f>>16&255]^v[g>>8&255]^w[b&255]^d[p],k=a[f>>>24]^q[g>>16&255]^v[b>>8&255]^w[e&255]^d[p+1],l=a[g>>>24]^q[b>>16&255]^v[e>>8&255]^w[f&255]^d[p+2],b=a[b>>>24]^q[e>>16&255]^v[f>>8&255]^w[g&255]^d[p+3],p+=4,e=h,f=k,g=l;for(m=0;4>m;m++)r[c?3&-m:m]=x[e>>>24]<<24^x[f>>16&255]<<16^x[g>>8&255]<<8^x[b&255]^d[p++],h=e,e=f,f=g,g=b,b=h;return r}sjcl.bitArray={bitSlice:function(a,b,c){a=sjcl.bitArray.$(a.slice(b/32),32-(b&31)).slice(1);return void 0===c?a:sjcl.bitArray.clamp(a,c-b)},extract:function(a,b,c){var d=Math.floor(-b-c&31);return((b+c-1^b)&-32?a[b/32|0]<<32-d^a[b/32+1|0]>>>d:a[b/32|0]>>>d)&(1<>b-1,1));return a},partial:function(a,b,c){return 32===a?b:(c?b|0:b<<32-a)+1099511627776*a},getPartial:function(a){return Math.round(a/1099511627776)||32},equal:function(a,b){if(sjcl.bitArray.bitLength(a)!==sjcl.bitArray.bitLength(b))return false;var c=0,d;for(d=0;d>>b),c=a[e]<<32-b;e=a.length?a[a.length-1]:0;a=sjcl.bitArray.getPartial(e);d.push(sjcl.bitArray.partial(b+a&31,32>>24|c>>>8&65280|(c&65280)<<8|c<<24;return a}};sjcl.codec.utf8String={fromBits:function(a){var b="",c=sjcl.bitArray.bitLength(a),d,e;for(d=0;d>>8>>>8>>>8),e<<=8;return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,d=0;for(c=0;c>>g)>>>e),gn){if(!b)try{return sjcl.codec.base32hex.toBits(a)}catch(p){}throw new sjcl.exception.invalid("this isn't "+m+"!")}h>e?(h-=e,f.push(l^n>>>h),l=n<>>e)>>>26),6>e?(g=a[c]<<6-e,e+=26,c++):(g<<=6,e-=6);for(;d.length&3&&!b;)d+="=";return d},toBits:function(a,b){a=a.replace(/\s|=/g,"");var c=[],d,e=0,f=sjcl.codec.base64.B,g=0,h;b&&(f=f.substr(0,62)+"-_");for(d=0;dh)throw new sjcl.exception.invalid("this isn't base64!");26>>e),g=h<<32-e):(e+=6,g^=h<<32-e)}e&56&&c.push(sjcl.bitArray.partial(e&56,g,1));return c}};sjcl.codec.base64url={fromBits:function(a){return sjcl.codec.base64.fromBits(a,1,1)},toBits:function(a){return sjcl.codec.base64.toBits(a,1)}};sjcl.hash.sha256=function(a){this.b[0]||this.O();a?(this.F=a.F.slice(0),this.A=a.A.slice(0),this.l=a.l):this.reset()};sjcl.hash.sha256.hash=function(a){return new sjcl.hash.sha256().update(a).finalize()};sjcl.hash.sha256.prototype={blockSize:512,reset:function(){this.F=this.Y.slice(0);this.A=[];this.l=0;return this},update:function(a){"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));var b,c=this.A=sjcl.bitArray.concat(this.A,a);b=this.l;a=this.l=b+sjcl.bitArray.bitLength(a);if(9007199254740991b;c++){e=true;for(d=2;d*d<=c;d++)if(0===c%d){e=false;break}e&&(8>b&&(this.Y[b]=a(Math.pow(c,.5))),this.b[b]=a(Math.pow(c,1/3)),b++)}}};function u(a,b){var c,d,e,f=a.F,g=a.b,h=f[0],k=f[1],l=f[2],n=f[3],m=f[4],p=f[5],r=f[6],q=f[7];for(c=0;64>c;c++)16>c?d=b[c]:(d=b[c+1&15],e=b[c+14&15],d=b[c&15]=(d>>>7^d>>>18^d>>>3^d<<25^d<<14)+(e>>>17^e>>>19^e>>>10^e<<15^e<<13)+b[c&15]+b[c+9&15]|0),d=d+q+(m>>>6^m>>>11^m>>>25^m<<26^m<<21^m<<7)+(r^m&(p^r))+g[c],q=r,r=p,p=m,m=n+d|0,n=l,l=k,k=h,h=d+(k&l^n&(k^l))+(k>>>2^k>>>13^k>>>22^k<<30^k<<19^k<<10)|0;f[0]=f[0]+h|0;f[1]=f[1]+k|0;f[2]=f[2]+l|0;f[3]=f[3]+n|0;f[4]=f[4]+m|0;f[5]=f[5]+p|0;f[6]=f[6]+r|0;f[7]=f[7]+q|0}sjcl.mode.ccm={name:"ccm",G:[],listenProgress:function(a){sjcl.mode.ccm.G.push(a)},unListenProgress:function(a){a=sjcl.mode.ccm.G.indexOf(a);-1k)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(f=2;4>f&&l>>>8*f;f++);f<15-k&&(f=15-k);c=h.clamp(c,8*(15-f));b=sjcl.mode.ccm.V(a,b,c,d,e,f);g=sjcl.mode.ccm.C(a,g,c,b,e,f);return h.concat(g.data,g.tag)},decrypt:function(a,b,c,d,e){e=e||64;d=d||[];var f=sjcl.bitArray,g=f.bitLength(c)/8,h=f.bitLength(b),k=f.clamp(b,h-e),l=f.bitSlice(b,h-e),h=(h-e)/8;if(7>g)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(b=2;4>b&&h>>>8*b;b++);b<15-g&&(b=15-g);c=f.clamp(c,8*(15-b));k=sjcl.mode.ccm.C(a,k,c,l,e,b);a=sjcl.mode.ccm.V(a,k.data,c,d,e,b);if(!f.equal(k.tag,a))throw new sjcl.exception.corrupt("ccm: tag doesn't match");return k.data},na:function(a,b,c,d,e,f){var g=[],h=sjcl.bitArray,k=h.i;d=[h.partial(8,(b.length?64:0)|d-2<<2|f-1)];d=h.concat(d,c);d[3]|=e;d=a.encrypt(d);if(b.length)for(c=h.bitLength(b)/8,65279>=c?g=[h.partial(16,c)]:4294967295>=c&&(g=h.concat([h.partial(16,65534)],[c])),g=h.concat(g,b),b=0;be||16n&&(sjcl.mode.ccm.fa(g/k),n+=m),c[3]++,e=a.encrypt(c),b[g]^=e[0],b[g+1]^=e[1],b[g+2]^=e[2],b[g+3]^=e[3];return{tag:d,data:h.clamp(b,l)}}};sjcl.mode.ocb2={name:"ocb2",encrypt:function(a,b,c,d,e,f){if(128!==sjcl.bitArray.bitLength(c))throw new sjcl.exception.invalid("ocb iv must be 128 bits");var g,h=sjcl.mode.ocb2.S,k=sjcl.bitArray,l=k.i,n=[0,0,0,0];c=h(a.encrypt(c));var m,p=[];d=d||[];e=e||64;for(g=0;g+4e.bitLength(c)&&(h=f(h,d(h)),c=e.concat(c,[-2147483648,0,0,0]));g=f(g,c);return a.encrypt(f(d(f(h,d(h))),g))},S:function(a){return[a[0]<<1^a[1]>>>31,a[1]<<1^a[2]>>>31,a[2]<<1^a[3]>>>31,a[3]<<1^135*(a[0]>>>31)]}};sjcl.mode.gcm={name:"gcm",encrypt:function(a,b,c,d,e){var f=b.slice(0);b=sjcl.bitArray;d=d||[];a=sjcl.mode.gcm.C(true,a,f,d,c,e||128);return b.concat(a.data,a.tag)},decrypt:function(a,b,c,d,e){var f=b.slice(0),g=sjcl.bitArray,h=g.bitLength(f);e=e||128;d=d||[];e<=h?(b=g.bitSlice(f,h-e),f=g.bitSlice(f,0,h-e)):(b=f,f=[]);a=sjcl.mode.gcm.C(false,a,f,d,c,e);if(!g.equal(a.tag,b))throw new sjcl.exception.corrupt("gcm: tag doesn't match");return a.data},ka:function(a,b){var c,d,e,f,g,h=sjcl.bitArray.i;e=[0,0,0,0];f=b.slice(0);for(c=0;128>c;c++){(d=0!==(a[Math.floor(c/32)]&1<<31-c%32))&&(e=h(e,f));g=0!==(f[3]&1);for(d=3;0>>1|(f[d-1]&1)<<31;f[0]>>>=1;g&&(f[0]^=-520093696)}return e},j:function(a,b,c){var d,e=c.length;b=b.slice(0);for(d=0;de&&(a=b.hash(a));for(d=0;dd||0>c)throw new sjcl.exception.invalid("invalid params to pbkdf2");"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));"string"===typeof b&&(b=sjcl.codec.utf8String.toBits(b));e=e||sjcl.misc.hmac;a=new e(a);var f,g,h,k,l=[],n=sjcl.bitArray;for(k=1;32*l.length<(d||1);k++){e=f=a.encrypt(n.concat(b,[k]));for(g=1;gg;g++)e.push(4294967296*Math.random()|0);for(g=0;g=1<this.o&&(this.o=f);this.P++;this.b=sjcl.hash.sha256.hash(this.b.concat(e));this.L=new sjcl.cipher.aes(this.b);for(d=0;4>d&&(this.h[d]=this.h[d]+1|0,!this.h[d]);d++);}for(d=0;d>>1;this.c[g].update([d,this.N++,2,b,f,a.length].concat(a))}break;case"string":void 0===b&&(b=a.length);this.c[g].update([d,this.N++,3,b,f,a.length]);this.c[g].update(a);break;default:k=1}if(k)throw new sjcl.exception.bug("random: addEntropy only supports number, array of numbers or string");this.m[g]+=b;this.f+=b;h===this.u&&(this.isReady()!==this.u&&A("seeded",Math.max(this.o,this.f)),A("progress",this.getProgress()))},isReady:function(a){a=this.T[void 0!==a?a:this.M];return this.o&&this.o>=a?this.m[0]>this.ba&&new Date().valueOf()>this.Z?this.J|this.I:this.I:this.f>=a?this.J|this.u:this.u},getProgress:function(a){a=this.T[a?a:this.M];return this.o>=a?1:this.f>a?1:this.f/a},startCollectors:function(){if(!this.D){this.a={loadTimeCollector:B(this,this.ma),mouseCollector:B(this,this.oa),keyboardCollector:B(this,this.la),accelerometerCollector:B(this,this.ea),touchCollector:B(this,this.qa)};if(window.addEventListener)window.addEventListener("load",this.a.loadTimeCollector,false),window.addEventListener("mousemove",this.a.mouseCollector,false),window.addEventListener("keypress",this.a.keyboardCollector,false),window.addEventListener("devicemotion",this.a.accelerometerCollector,false),window.addEventListener("touchmove",this.a.touchCollector,false);else if(document.attachEvent)document.attachEvent("onload",this.a.loadTimeCollector),document.attachEvent("onmousemove",this.a.mouseCollector),document.attachEvent("keypress",this.a.keyboardCollector);else throw new sjcl.exception.bug("can't attach event");this.D=true}},stopCollectors:function(){this.D&&(window.removeEventListener?(window.removeEventListener("load",this.a.loadTimeCollector,false),window.removeEventListener("mousemove",this.a.mouseCollector,false),window.removeEventListener("keypress",this.a.keyboardCollector,false),window.removeEventListener("devicemotion",this.a.accelerometerCollector,false),window.removeEventListener("touchmove",this.a.touchCollector,false)):document.detachEvent&&(document.detachEvent("onload",this.a.loadTimeCollector),document.detachEvent("onmousemove",this.a.mouseCollector),document.detachEvent("keypress",this.a.keyboardCollector)),this.D=false)},addEventListener:function(a,b){this.K[a][this.ga++]=b},removeEventListener:function(a,b){var c,d,e=this.K[a],f=[];for(d in e)e.hasOwnProperty(d)&&e[d]===b&&f.push(d);for(c=0;cb&&(a.h[b]=a.h[b]+1|0,!a.h[b]);b++);return a.L.encrypt(a.h)}function B(a,b){return function(){b.apply(a,arguments)}}sjcl.random=new sjcl.prng(6);a:try{if(G="undefined"!==typeof module&&module.exports){try{H=__require("crypto")}catch(a){H=null}G=E=H}if(G&&E.randomBytes)D=E.randomBytes(128),D=new Uint32Array(new Uint8Array(D).buffer),sjcl.random.addEntropy(D,1024,"crypto['randomBytes']");else if("undefined"!==typeof window&&"undefined"!==typeof Uint32Array){F=new Uint32Array(32);if(window.crypto&&window.crypto.getRandomValues)window.crypto.getRandomValues(F);else if(window.msCrypto&&window.msCrypto.getRandomValues)window.msCrypto.getRandomValues(F);else break a;sjcl.random.addEntropy(F,1024,"crypto['getRandomValues']")}}catch(a){"undefined"!==typeof window&&window.console&&(console.log("There was an error collecting entropy from the browser:"),console.log(a))}var D;var E;var F;var G;var H;sjcl.json={defaults:{v:1,iter:1e4,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},ja:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json,f=e.g({iv:sjcl.random.randomWords(4,0)},e.defaults),g;e.g(f,c);c=f.adata;"string"===typeof f.salt&&(f.salt=sjcl.codec.base64.toBits(f.salt));"string"===typeof f.iv&&(f.iv=sjcl.codec.base64.toBits(f.iv));if(!sjcl.mode[f.mode]||!sjcl.cipher[f.cipher]||"string"===typeof a&&100>=f.iter||64!==f.ts&&96!==f.ts&&128!==f.ts||128!==f.ks&&192!==f.ks&&256!==f.ks||2>f.iv.length||4=b.iter||64!==b.ts&&96!==b.ts&&128!==b.ts||128!==b.ks&&192!==b.ks&&256!==b.ks||!b.iv||2>b.iv.length||4{if(!_id)_id=`key${Math.floor(Math.random()*1e15)}`;if(this.securedKeys&&this.secret&&this.encryptedkeys){let decrypted=JSON.parse(sjcl_default.decrypt(this.secret,this.encryptedkeys));decrypted[_id]={key,_id};this.encryptedkeys=sjcl_default.encrypt(this.secret,decrypted).cipher;return this.encryptedkeys}else this.keys[_id]={key,_id};return this.keys[_id]};static generateSecret(){return sjcl_default.codec.base64.fromBits(sjcl_default.random.randomWords(8,10))}encrypt(message,key){message=sjcl_default.encrypt(key,message).cipher;return message}decrypt(message,key){message=sjcl_default.decrypt(key,message);return message}encryptRoute=(message,keyId)=>{if(typeof message==="object")message=JSON.stringify(message);let key;if(this.securedKeys&&this.secret&&this.encryptedkeys){let decrypted=JSON.parse(sjcl_default.decrypt(this.secret,this.encryptedkeys));if(decrypted[keyId]?.key){message=sjcl_default.encrypt(this.secret,decrypted[keyId].key).cipher}}else{if(this.keys[keyId]){if(!key)key=keyId;message=this.encrypt(message,key)}}message={route:"decryptRoute",args:[message,keyId]};return message};decryptRoute=(message,keyId)=>{let decryptedMessage=message;if(typeof message==="object"){if(!keyId){if(typeof message.keyId==="string")keyId=message.keyId}if(keyId){let key;if(this.securedKeys&&this.secret&&this.encryptedkeys){let decrypted=JSON.parse(sjcl_default.decrypt(this.secret,this.encryptedkeys));if(decrypted[keyId]?.key){decryptedMessage=sjcl_default.decrypt(this.secret,decrypted[keyId].key);return decryptedMessage}}else{if(this.keys[keyId])key=this.keys[keyId].key;if(key)decryptedMessage=this.decrypt(message.args,key)}}}else{let key;if(this.securedKeys&&this.secret&&this.encryptedkeys){let decrypted=JSON.parse(sjcl_default.decrypt(this.secret,this.encryptedkeys));if(decrypted[keyId]?.key){decryptedMessage=sjcl_default.decrypt(this.secret,decrypted[keyId].key);return decryptedMessage}}else{if(this.keys[keyId])key=this.keys[keyId].key;if(key)decryptedMessage=this.decrypt(message,key)}}return decryptedMessage};transmit=(message,keyId)=>{if(!keyId){keyId=Object.keys(this.keys)[0]}message=this.encryptRoute(message,keyId);return this.handleServiceMessage(message)};receive=(message,keyId)=>{if(!keyId){keyId=Object.keys(this.keys)[0]}message=this.decryptRoute(message,keyId);if(typeof message==="string"){let substr=message.substring(0,8);if(substr.includes("{")||substr.includes("[")){if(substr.includes("\\"))message=message.replace(/\\/g,"");if(message[0]==='"'){message=message.substring(1,message.length-1)};message=JSON.parse(message)}}if(typeof message==="object"){if(typeof message.method==="string"){return this.handleMethod(message.route,message.method,message.args)}else if(typeof message.route==="string"){return this.handleServiceMessage(message)}else if(typeof message.node==="string"||message.node instanceof GraphNode){return this.handleGraphNodeCall(message.node,message.args)}else if(this.__node.keepState){if(message.route)this.setState({[message.route]:message.args});if(message.node)this.setState({[message.node]:message.args})}}else return message}};var HTTPfrontend=class _HTTPfrontend extends Service{name="http";fetchProxied=false;listening={};constructor(options,path,fetched){super(options);this.load(this);this.listen(path,fetched)}static request=options=>{const xhr=new XMLHttpRequest;if(options.responseType)xhr.responseType=options.responseType;else options.responseType="json";if(options.mimeType){xhr.overrideMimeType(options.mimeType)}if(options.onload)xhr.addEventListener("load",options.onload,false);if(options.onprogress)xhr.addEventListener("progress",options.onprogress,false);if(options.onabort)xhr.addEventListener("abort",options.onabort,false);if(options.onloadend)xhr.addEventListener("loadend",options.onloadend,false);if(options.onerror)xhr.addEventListener("error",options.onerror,false);xhr.open(options.method,options.url,true,options.user,options.pass);if(!options.onerror)xhr.onerror=function(){xhr.abort()};xhr.send(options.data);return xhr};GET=(url2="http://localhost:8080/ping",type="",mimeType)=>{if(type==="json")mimeType="application/json";return new Promise((resolve,reject)=>{let xhr=_HTTPfrontend.request({method:"GET",url:url2,responseType:type,mimeType,onload:ev=>{let data;if(xhr.responseType===""||xhr.responseType==="text")data=xhr.responseText;else data=xhr.response;if(url2 instanceof URL)url2=url2.toString();this.setState({[url2]:data});resolve(data)},onabort:er=>{reject(er)}})}).catch(console.error)};POST=(message,url2="http://localhost:8080/echo",type="",mimeType)=>{if(typeof message==="object"&&!message.byteLength&&(type==="json"||type==="text"||!type)){message=JSON.stringify(message)}if(type==="json")mimeType="application/json";return new Promise((resolve,reject)=>{let xhr=_HTTPfrontend.request({method:"POST",url:url2,data:message,responseType:type,mimeType,onload:ev=>{let data;if(xhr.responseType===""||xhr.responseType==="text")data=xhr.responseText;else data=xhr.response;if(url2 instanceof URL)url2=url2.toString();this.setState({[url2]:data});resolve(data)},onabort:er=>{reject(er)}})}).catch(console.error)};transmit=(message,url2)=>{let obj=message;if(typeof obj==="object"&&!obj.byteLength){message=JSON.stringify(obj)}if(obj?.method?.toLowerCase()=="get"||message?.toLowerCase()==="get")return this.GET(url2);return this.POST(message,url2)};transponder=(url2,message,type="",mimeType)=>{if(typeof message==="object")message=JSON.stringify(message);let method="GET";if(message){method="POST"}if(type==="json")mimeType="application/json";else return new Promise((resolve,reject)=>{let xhr=_HTTPfrontend.request({method,url:url2,data:message,responseType:type,onload:ev=>{let body=xhr.response;if(typeof body==="string"){let substr=body.substring(0,8);if(substr.includes("{")||substr.includes("[")){if(substr.includes("\\"))body=body.replace(/\\/g,"");if(body[0]==='"'){body=body.substring(1,body.length-1)};body=JSON.parse(body)}}if(typeof body?.method==="string"){return resolve(this.handleMethod(body.route,body.method,body.args))}else if(typeof body?.route==="string"){return resolve(this.handleServiceMessage(body))}else if(typeof body?.node==="string"||body.node instanceof GraphNode){return resolve(this.handleGraphNodeCall(body.node,body.args))}else return resolve(body)},onabort:er=>{reject(er)}})}).catch(console.error)};listen=(path="0",fetched=async(clone,args,response)=>{const result=await clone.text();const returned=this.receive(result);this.setState({[response.url]:returned})})=>{this.listening[path]={};let listenerId=`${path}${Math.floor(Math.random()*1e15)}`;this.listening[path][listenerId]=fetched;if(!this.fetchProxied){globalThis.fetch=new Proxy(globalThis.fetch,{apply(fetch,that,args){const result=fetch.apply(that,args);result.then(response=>{if(!response.ok)return;if(this.listening["0"]){for(const key in this.listeners){const clone=response.clone();this.listening["0"][key](clone,args,response)}}else{for(const key in this.listening){if(response.url.includes(key)){for(const key2 in this.listening[path]){const clone=response.clone();this.listening[path][key2](clone,args,response)}break}}}}).catch(er=>{console.error(er)});return result}});this.fetchProxied=true}return listenerId};stopListening=(path,listener)=>{if(!path&&path!==0){for(const key in this.listening)delete this.listening[key]}else{if(!listener)delete this.listening[path];else delete this.listening[listener]}}};var SSEfrontend=class extends Service{name="sse";eventsources={};connections={eventsources:this.eventsources};constructor(options){super(options);this.load(this)}openSSE=options=>{let source=new EventSource(options.url);let sse={source,type:"eventsource",...options};if(!("keepState"in options))options.keepState=true;if(!options.events)options.events={};let close;if(options.events.close){close=options.events.close}options.events.close=ev=>{if(sse.onclose)sse.onclose(ev,sse);if(close)close(ev,sse);delete this.eventsources[options.url]};let open;if(options.events.open){open=options.events.open}options.events.open=ev=>{if(sse.onopen)sse.onopen(ev,sse);if(open)open(ev,sse)};let error;if(options.events.error){error=options.events.error}options.events.error=ev=>{if(sse.onerror)sse.onerror(ev,sse);if(error)error(ev,sse)};let message;if(options.events.message){message=options.events.message}if(!sse.onmessage){sse.onmessage=(ev,sse2)=>{let data=ev.data;if(data){if(typeof data==="string"){let substr=data.substring(0,8);if(substr.includes("{")||substr.includes("[")){if(substr.includes("\\"))data=data.replace(/\\/g,"");if(data[0]==='"'){data=data.substring(1,data.length-1)};data=JSON.parse(data);if(data.route==="setId"&&sse2){sse2._id=data.args;options.events.message=(e,sse3)=>{const result2=this.receive(e.data,sse3);if(options.keepState)this.setState({[options.url]:e.data})}}}}}const result=this.receive(ev.data,sse2);if(options.keepState)this.setState({[options.url]:data})}}options.events.message=ev=>{if(sse.onmessage)sse.onmessage(ev,sse);if(message)message(ev,sse)};if(!options.events.error)options.events.error=(ev,sse2)=>{this.terminate(sse2);delete this.eventsources[options.url]};if(options.events){if(!options.evoptions)options.evoptions=false;for(const key in options.events){if(typeof options.events[key]!=="function"){options.events[key]=ev=>{const result=this.receive(ev.data,sse);if(options.keepState)this.setState({[options.url]:result})}}else{let l=options.events[key];options.events[key]=ev=>{l(ev,sse)}}source.addEventListener(key,options.events[key],options.evoptions)}}let send=message2=>{return this.transmit(message2,options.url)};let request=(message2,method,sessionId)=>{return this.request(message2,options.url,method,sessionId)};let post=(route,args,method)=>{let message2={route,args};if(method)message2.method=method;return this.transmit(message2,options.url)};let run=(route,args,method,sessionId)=>{return this.request({route,args},options.url,method,sessionId)};let subscribe=(route,callback,args,key,subInput)=>{return this.subscribeToSSE(route,options.url,callback,args,key,subInput,sse._id)};let unsubscribe=(route,sub)=>{return run("unsubscribe",[route,sub])};let terminate=()=>{return this.terminate(options.url)};sse.send=send;sse.request=request;sse.post=post;sse.run=run;sse.subscribe=subscribe;sse.unsubscribe=unsubscribe;sse.terminate=terminate;sse.graph=this;this.eventsources[options.url]=sse;return sse};open=this.openSSE;POST=(message,url2="http://localhost:8080/echo",type="",mimeType)=>{if(typeof message==="number"||typeof message==="object"&&!message.byteLength&&(type==="json"||type==="text"||!type)){message=JSON.stringify(message)}if(type==="json")mimeType="application/json";return new Promise((resolve,reject)=>{let xhr=HTTPfrontend.request({method:"POST",url:url2,data:message,responseType:type,mimeType,onload:ev=>{let data;if(xhr.responseType===""||xhr.responseType==="text")data=xhr.responseText;else data=xhr.response;if(url2 instanceof URL)url2=url2.toString();this.setState({[url2]:data});resolve(data)},onabort:er=>{reject(er)}})}).catch(console.error)};transmit=(message,url2)=>{return this.POST(message,url2,"json")};request=(message,url2,method,sessionId)=>{return new Promise((res,rej)=>{let callbackId=`${Math.random()}`;let req={route:"runRequest",args:[message,url2,callbackId,sessionId]};if(method)req.method=method;let evs=this.eventsources[url2].source;let onmessage=ev=>{let data=ev.data;if(typeof data==="string"){if(data.includes("callbackId"))data=JSON.parse(data)}if(typeof data==="object"){if(data.callbackId===callbackId){evs.removeEventListener("message",onmessage);res(data.args)}}};evs.addEventListener("message",onmessage);this.POST(message,url2,"json")})};runRequest=(message,url2,callbackId,sessionId)=>{let res=this.receive(message);if(url2){if(res instanceof Promise){res.then(r=>{let message2={args:r,callbackId,sessionId};this.POST(message2,url2,"json")})}else{let message2={args:res,callbackId,sessionId};this.POST(message2,url2,"json")}}return res};subscribeSSE=(route,url2,args,key,subInput)=>{if(this.restrict?.[route])return void 0;return this.subscribe(route,res=>{this.POST(res,url2,"json")},args,key,subInput)};subscribeToSSE=(route,url2,callback,args,key,subInput,sessionId)=>{if(url2){this.__node.state.subscribeEvent(url2,res=>{let msg=JSON.parse(res);if(msg?.callbackId===route){if(!callback)this.setState({[url2]:msg.args});else if(typeof callback==="string"){this.run(callback,msg.args)}else callback(msg.args)}});return this.eventsources[url2].run("subscribeSSE",[route,url2,args,key,subInput,sessionId])}};terminate=sse=>{if(typeof sse==="string"){let str2=sse;sse=this.eventsources[sse];delete this.eventsources[str2]}if(!sse)return;if(typeof sse==="object"){if(sse.source){sse=sse.source}if(sse instanceof EventSource){if(sse.readyState!==2)sse.close()}}}};var WSSfrontend=class extends Service{name="wss";sockets={};connections={sockets:this.sockets};constructor(options){super(options);this.load(this)}loadWebSocketRoute=node=>{let wsInfo=this.openWS(node);if(!wsInfo.__ondisconnected){wsInfo.__addOndisconnected(()=>{wsInfo.terminate()})}if(!node.__operator){node.__operator=(...args)=>{if(node.callback){if(!this.__node.nodes.get(node.__node.tag)?.__children)wsInfo.post(node.callback,args);else return wsInfo.run(node.callback,args)}else{if(!this.__node.nodes.get(node.__node.tag)?.__children)wsInfo.send(args);else return wsInfo.request(args)}}}if(!node.__ondisconnected){let ondelete=rt=>{rt?.terminate()};node.__addOndisconnected(ondelete)}return wsInfo};socketloader={"websockets":(node,parent,graph,roots)=>{node._id=node.__node.tag;let ws=this.loadWebSocketRoute(node);Object.assign(node,ws);if(parent&&parent.type==="socket"){let parentWs=this.sockets[parent._id];if(node.parentRoute){parentWs.subscribe(node.parentRoute,node.__operator)}}}};openWS=(options={host:"localhost",port:7e3,path:void 0,protocol:"ws"})=>{let protocol=options.protocol;if(!protocol)protocol="ws";let address=`${protocol}://${options.host}`;if(!("keepState"in options))options.keepState=true;if(options.port)address+=":"+options.port;if(options.path&&!options.path?.startsWith("/"))address+="/";if(options.path)address+=options.path;if(this.sockets[address]?.socket){if(this.sockets[address].socket.readyState===this.sockets[address].socket.OPEN)this.sockets[address].socket.close()}const socket=new WebSocket(address);if(!options.onmessage){if(!options._id){options.onmessage=(data,ws,wsinfo)=>{if(data){if(typeof data==="string"){if(options.debug){console.log("Message from ",address,": ",data)}let substr=data.substring(0,8);if(substr.includes("{")||substr.includes("[")){if(substr.includes("\\"))data=data.replace(/\\/g,"");if(data[0]==='"'){data=data.substring(1,data.length-1)};data=JSON.parse(data);if(data.route==="setId"){this.sockets[address]._id=data.args;options.onmessage=(data2,ws2,wsinfo2)=>{if(options.debug){console.log("Message from ",address,": ",data2)}this.receive(data2);if(options.keepState){this.setState({[address]:data2})}}}}}}let res=this.receive(data);if(options.keepState)this.setState({[address]:data})}}else{options.onmessage=(data,ws,wsinfo)=>{if(options.debug){console.log("Message from ",socket.url,": ",data)}this.receive(data,socket,this.sockets[address]);if(options.keepState){this.setState({[address]:data})}}}}if(options.onmessage){socket.addEventListener("message",ev=>{this.sockets[address].onmessage(ev.data,socket,this.sockets[address])})}socket.addEventListener("open",ev=>{if(this.sockets[address].onopen)this.sockets[address].onopen(ev,socket,this.sockets[address])});socket.addEventListener("close",ev=>{let obj=this.sockets[address];let onclose=obj.onclose;delete this.sockets[address];this.remove(address);if(onclose)onclose(ev,socket,obj)});socket.addEventListener("error",ev=>{if(this.sockets[address].onerror)this.sockets[address].onerror(ev,socket,this.sockets[address])});let send=message=>{return this.transmit(message,socket)};let post=(route,args,method)=>{let message={route,args};if(method)message.method=method;return this.transmit(message,socket)};let run=(route,args,method)=>{return new Promise((res,rej)=>{let callbackId=Math.random();let req={route:"runRequest",args:[{route,args},this.sockets[address]._id,callbackId]};if(method)req.args[0].method=method;let onmessage=ev=>{let data=ev.data;if(typeof data==="string"&&data.indexOf("{")>-1)data=JSON.parse(ev.data);if(typeof data==="object"){if(data.callbackId===callbackId){socket.removeEventListener("message",onmessage);res(data.args)}}};socket.addEventListener("message",onmessage);this.transmit(req,socket)})};let request=(message,method)=>{return new Promise((res,rej)=>{let callbackId=Math.random();let req={route:"runRequest",args:[message,this.sockets[address]._id,callbackId]};if(method)req.method=method;let onmessage=ev=>{let data=ev.data;if(typeof data==="string"&&data.indexOf("{")>-1)data=JSON.parse(ev.data);if(typeof data==="object"){if(data.callbackId===callbackId){socket.removeEventListener("message",onmessage);res(data.args)}}};socket.addEventListener("message",onmessage);this.transmit(req,socket)})};let subscribe=(route,callback,args,key,subInput)=>{return this.subscribeToSocket(route,this.sockets[address]._id,callback,args,key,subInput)};let unsubscribe=(route,sub)=>{return run("unsubscribe",[route,sub])};let terminate=()=>{return this.terminate(address)};Object.assign(options,{type:"socket",socket,address,send,post,run,request,subscribe,unsubscribe,terminate});if(!(options instanceof GraphNode)){let node=this.add(options);node.__addOndisconnected(function(){terminate()});options=node}this.sockets[address]=options;return options};open=this.openWS;transmit=(data,ws)=>{if(typeof data==="object"&&(data?.route||data?.node||typeof data.arrayBuffer!=="function"&&typeof data.byteLength!=="number")||typeof data==="number")data=JSON.stringify(data);if(!ws){let s=this.sockets[Object.keys(this.sockets)[0]];if(s)ws=s.socket}if(ws instanceof WebSocket&&ws?.readyState===1)ws.send(data);return true};terminate=ws=>{let str2;if(!ws){let keys2=Object.keys(this.sockets);for(const key in keys2){this.terminate(key)}}else if(typeof ws==="string"){str2=ws;for(const k in this.sockets){if(k.includes(ws)||this.sockets[k]._id===k){ws=this.sockets[k].socket;break}}}if(ws instanceof WebSocket){if(ws.readyState===ws.OPEN)ws.close();if(this.get(str2?str2:ws.url))this.remove(str2?str2:ws.url)}return true};request=(message,ws,_id,method)=>{let callbackId=`${Math.random()}`;let req={route:"runRequest",args:[message,_id,callbackId]};if(method)req.method=method;return new Promise((res,rej)=>{let onmessage=ev=>{let data=ev.data;if(typeof data==="string"){if(data.includes("callbackId"))data=JSON.parse(data)}if(typeof data==="object"){if(data.callbackId===callbackId){ws.removeEventListener("message",onmessage);res(data.args)}}};ws.addEventListener("message",onmessage);ws.send(JSON.stringify(req))})};runRequest=(message,ws,callbackId)=>{let res=this.receive(message);if(typeof ws==="string"){for(const s in this.sockets){if(s===ws||this.sockets[s]._id===ws){ws=this.sockets[s].socket;break}}}if(ws){if(res instanceof Promise){res.then(v=>{res={args:v,callbackId};if(ws instanceof WebSocket)ws.send(JSON.stringify(res))})}else{res={args:res,callbackId};if(ws instanceof WebSocket)ws.send(JSON.stringify(res))}}return res};subscribeSocket=(route,socket,args,key,subInput)=>{if(this.restrict?.[route])return void 0;if(typeof socket==="string"&&this.sockets[socket]){socket=this.sockets[socket].socket}if(typeof socket==="object"){return this.subscribe(route,res=>{if(socket.readyState===socket.OPEN){if(res instanceof Promise){res.then(r=>{socket.send(JSON.stringify({args:r,callbackId:route}))})}else{socket.send(JSON.stringify({args:res,callbackId:route}))}}},args,key,subInput)}};subscribeToSocket=(route,socketId,callback,args,key,subInput)=>{if(typeof socketId==="string"&&this.sockets[socketId]){this.__node.state.subscribeEvent(socketId,res=>{let msg=JSON.parse(res);if(msg?.callbackId===route){if(!callback)this.setState({[socketId]:msg.args});else if(typeof callback==="string"){this.run(callback,msg.args)}else callback(msg.args)}});return this.sockets[socketId].request({route:"subscribeSocket",args:[route,socketId,args,key,subInput]})}}};var WebRTCfrontend=class extends Service{name="webrtc";rtc={};unanswered={};iceServers=[{urls:["stun:stun.l.google.com:19302"]},{urls:["stun:stun1.l.google.com:19302"]},{urls:["stun:stun2.l.google.com:19302"]},{urls:["stun:stun3.l.google.com:19302"]},{urls:["stun:stun4.l.google.com:19302"]}];connections={rtc:this.rtc};constructor(options,iceServers){super(options);if(iceServers)this.iceServers=iceServers;this.load(this)}openRTC=async options=>{if(!options)options={};if(!options._id)options._id=`rtc${Math.floor(Math.random()*1e15)}`;if(!options.config)options.config={iceServers:this.iceServers};if(!this.rtc[options._id]){let rtc=new RTCPeerConnection(options.config);if(!options.channels)options.channels={"data":true};let firstChannel;for(const key in options.channels){firstChannel=key;break}let send=message=>{return this.transmit(message,options._id,options.channels[firstChannel])};let post=(route,args,method)=>{let message={route,args};if(method)message.method=method;return this.transmit(message,options._id,options.channels[firstChannel])};let run=(route,args,method)=>{return new Promise((res,rej)=>{let callbackId=Math.random();let req={route:"runRequest",args:[{route,args},options._id,callbackId]};if(method)req.args[0].method=method;let sub;let ondata=data=>{if(typeof data==="string"&&data.indexOf("{")>-1)data=JSON.parse(data);if(typeof data==="object"){if(data.callbackId===callbackId){this.unsubscribe(options._id,sub);res(data.args)}}};sub=this.subscribe(options._id,ondata);this.transmit(req,options._id,options.channels[firstChannel])})};let request=(message,method)=>{return new Promise((res,rej)=>{let callbackId=Math.random();let req={route:"runRequest",args:[message,options._id,callbackId]};if(method)req.method=method;let sub;let ondata=data=>{if(typeof data==="string"&&data.indexOf("{")>-1)data=JSON.parse(data);if(typeof data==="object"){if(data.callbackId===callbackId){this.unsubscribe(options._id,sub);res(data.args)}}};sub=this.subscribe(options._id,ondata);this.transmit(req,options._id,options.channels[firstChannel])})};let subscribe=(route,callback,args,key,subInput,channelId)=>{return this.subscribeToRTC(route,options._id,channelId?channelId:firstChannel,callback,args,key,subInput)};let unsubscribe=(route,sub)=>{return run("unsubscribe",[route,sub])};let terminate=()=>{return this.terminate(options._id)};this.rtc[options._id]={rtc,_id:options._id,request,run,post,send,subscribe,unsubscribe,terminate,graph:this,...options};const setMessageChannelHandle=channel=>{if(!this.rtc[options._id].ondata){this.rtc[options._id].ondata=mev=>{this.receive(mev.data,channel,this.rtc[options._id]);this.setState({[options._id]:mev.data})};channel.addEventListener("message",mev=>{if(this.rtc[options._id].ondata)this.rtc[options._id].ondata(mev,channel,this.rtc[options._id])})}else{channel.addEventListener("message",mev=>{if(this.rtc[options._id].ondata)this.rtc[options._id].ondata(mev,channel,this.rtc[options._id])})}};if(this.rtc[options._id].channels){for(const channel in this.rtc[options._id].channels){if(this.rtc[options._id].channels[channel]instanceof RTCDataChannel){}else if(typeof this.rtc[options._id].channels[channel]==="object"){this.rtc[options._id].channels[channel]=this.addDataChannel(rtc,channel,this.rtc[options._id].channels[channel])}else{this.rtc[options._id].channels[channel]=this.addDataChannel(rtc,channel)}setMessageChannelHandle(this.rtc[options._id].channels[channel])}}rtc.ontrack=ev=>{if(!this.rtc[options._id].receivers)this.rtc[options._id].receivers=[];this.rtc[options._id].receivers.push(ev.receiver);if(!this.rtc[options._id].streams)this.rtc[options._id].streams=[];this.rtc[options._id].streams.push(...ev.streams);let rlength=this.rtc[options._id].receivers.length;let slength=this.rtc[options._id].streams.length;ev.streams.forEach(s=>{s.addEventListener("removetrack",ev2=>{this.rtc[options._id].receivers[rlength]=void 0;this.rtc[options._id].streams[slength]=void 0;if(this.rtc[options._id].removetrack)this.rtc[options._id].removetrack(ev2)})});if(this.rtc[options._id].ontrack)this.rtc[options._id].ontrack(ev)};rtc.ondatachannel=ev=>{this.rtc[options._id].channels[ev.channel.label]=ev.channel;setMessageChannelHandle(ev.channel);if(this.rtc[options._id].ondatachannel)this.rtc[options._id].ondatachannel(ev)};rtc.onicecandidate=ev=>{if(this.rtc[options._id].onicecandidate)this.rtc[options._id].onicecandidate(ev)};rtc.onicecandidateerror=ev=>{if(this.rtc[options._id].onicecandidateerror)this.rtc[options._id].onicecandidateerror(ev)};let initialOffer=this.rtc[options._id].description===void 0;rtc.onnegotiationneeded=async ev=>{if(!initialOffer){const offer=await rtc.createOffer(this.rtc[options._id].offer);if(rtc.signalingState!="stable")return;await rtc.setLocalDescription(offer);if(this.rtc[options._id].onnegotiationneeded)this.rtc[options._id].onnegotiationneeded(ev,rtc.localDescription)}};rtc.oniceconnectionstatechange=ev=>{if(this.rtc[options._id].oniceconnectionstatechange)this.rtc[options._id].oniceconnectionstatechange(ev)};rtc.onconnectionstatechange=ev=>{if(this.rtc[options._id].onconnectionstatechange)this.rtc[options._id].onconnectionstatechange(ev)};rtc.addEventListener("connectionstatechange",ev=>{if(rtc.connectionState==="closed"||rtc.connectionState==="failed"){if(this.rtc[options._id].onclose){this.rtc[options._id].onclose(this.rtc[options._id])}delete this.rtc[options._id]}});if(!this.rtc[options._id].onicecandidate)this.rtc[options._id].onicecandidate=ev=>{if(ev.candidate){let icecandidate=ev.candidate;if(!this.rtc[options._id].candidates)this.rtc[options._id].candidates={};this.rtc[options._id].candidates[`candidate${Math.floor(Math.random()*1e15)}`]=icecandidate}};if(!options.description)return await new Promise((res,rej)=>{this.rtc[options._id].rtc.createOffer(options.offer).then(offer=>this.rtc[options._id].rtc.setLocalDescription(offer)).then(()=>{initialOffer=false;res(this.rtc[options._id])})})}else{Object.assign(this.rtc[options._id],options)}if(options.description){this.rtc[options._id].polite=true;await this.negotiateCall(options._id,options.description,true)}if(options.candidates){for(const prop in options.candidates){const candidate=new RTCIceCandidate(options.candidates[prop]);this.rtc[options._id].rtc.addIceCandidate(candidate).catch(console.error)}}return this.rtc[options._id]};open=this.openRTC;addIceCandidate=(rtc,candidate)=>{if(typeof rtc==="string")rtc=this.rtc[rtc]?.rtc;if(typeof candidate==="string")candidate=JSON.parse(decodeURIComponent(candidate));if(rtc&&rtc.remoteDescription)return rtc.addIceCandidate(candidate)};receiveCallInformation=async options=>{if(!options._id)options._id=`rtc${Math.floor(Math.random()*1e15)}`;if(this.rtc[options._id]){if(options.candidates){for(const key in options.candidates)this.addIceCandidate(this.rtc[options._id].rtc,options.candidates[key]);delete options.candidates}Object.assign(this.rtc[options._id],options)}else if(this.unanswered[options._id]){this.recursivelyAssign(this.unanswered[options._id],options)}else this.unanswered[options._id]=options;return options._id};answerCall=options=>{if(typeof options==="string")options=this.unanswered[options];delete this.unanswered[options._id];return this.openRTC(options)};rejectCall=options=>{if(typeof options==="string")options=this.unanswered[options];delete this.unanswered[options._id];return true};negotiateCall=async(rtc,description,polite)=>{if(typeof rtc==="string"){if(polite===void 0)polite=this.rtc[rtc].description!==void 0;rtc=this.rtc[rtc].rtc}if(typeof description==="string")description=new RTCSessionDescription(JSON.parse(decodeURIComponent(description)));if(description.type==="offer"&&rtc.signalingState!=="stable"){if(!polite)return;await Promise.all([rtc.setLocalDescription({type:"rollback"}),rtc.setRemoteDescription(description)]);return encodeURIComponent(JSON.stringify(rtc.localDescription))}else{await rtc.setRemoteDescription(description)}if(description.type=="offer"){await rtc.setLocalDescription(await rtc.createAnswer());return encodeURIComponent(JSON.stringify(rtc.localDescription))}};createOffer(rtc,options){if(typeof rtc==="string")rtc=this.rtc[rtc].rtc;if(typeof options==="string")options=this.rtc[options];return new Promise((res,rej)=>{if(!rtc)rej(void 0);rtc.createOffer(options.offer).then(offer=>rtc.setLocalDescription(offer)).then(()=>{let description=encodeURIComponent(JSON.stringify(rtc.localDescription));res(description)})})}createAnswer(rtc,options){if(typeof rtc==="string")rtc=this.rtc[rtc]?.rtc;if(typeof options==="string")options=this.rtc[options];return new Promise((res,rej)=>{if(!rtc)rej(void 0);rtc.createAnswer(options.answer).then(answer=>rtc.setLocalDescription(answer)).then(()=>{let description=encodeURIComponent(JSON.stringify(rtc.localDescription));res(description)})})}answerPeer=(rtc,options)=>{if(typeof rtc==="string"){let cpy=Object.assign(this.rtc[rtc],options);delete cpy.description;delete cpy.candidates;Object.assign(this.rtc[rtc],cpy);rtc=this.rtc[rtc]?.rtc}if(typeof options==="string")options=this.rtc[options];return new Promise((res,rej)=>{if(typeof options.description==="string"){options.description=JSON.parse(decodeURIComponent(options.description))}const description=new RTCSessionDescription(options.description);rtc.setRemoteDescription(description).then(()=>{if(options.candidates){for(const prop in options.candidates){const candidate=new RTCIceCandidate(options.candidates[prop]);if(this.rtc[options._id])this.rtc[options._id].candidates[prop]=options.candidates[prop];rtc.addIceCandidate(candidate).catch(console.error)}}if(description.type==="offer"){this.rtc[options._id].rtc.createAnswer(options.answer).then(a=>{this.rtc[options._id].rtc.setLocalDescription(a)})}res(this.rtc[options._id]?this.rtc[options._id]:rtc)}).catch(rej)})};createStream=options=>{let stream=new MediaStream;for(const key in options){let track=options[key].track;if(!(track instanceof MediaStreamTrack)&&typeof track==="object"){track=new MediaStreamTrack;track.applyConstraints(options[key].track);stream.addTrack(track)}if(track instanceof MediaStreamTrack){stream.addTrack(track);track.onmute=options[key].onmute;track.onunmute=options[key].onunmute;track.onended=options[key].onended}}return stream};addUserMedia=(rtc,options={audio:true,video:{optional:[{minWidth:320},{minWidth:640},{minWidth:1024},{minWidth:1280},{minWidth:1920},{minWidth:2560}]}},info)=>{return new Promise(async(res,rej)=>{let RTCRtpSenders=[];let stream=await navigator.mediaDevices.getUserMedia(options);if(stream){let tracks=stream.getTracks();tracks.forEach(track=>{let sender=rtc.addTrack(track,stream);if(track.kind==="video"&&info){info.videoSender=sender;info.videoStream=stream}if(track.kind==="audio"&&info){info.audioSender=sender;info.audioStream=stream}RTCRtpSenders.push(sender)});let str2=stream;if(info)info.senders=info.senders?[...info.senders,...RTCRtpSenders]:RTCRtpSenders;res(str2)}})};addTrack=(rtc,track,stream)=>{return rtc.addTrack(track,stream)};removeTrack=(rtc,sender)=>{rtc.removeTrack(sender);return true};addDataChannel=(rtc,name2,options)=>{return rtc.createDataChannel(name2,options)};enableAudio=async(call,audioOptions=true)=>{if(call.audioStream)this.disableAudio(call);let stream=await this.addUserMedia(call.rtc,{audio:audioOptions,video:false},call);if(audioOptions?.deviceId)call.audioSender.deviceId=audioOptions.deviceId;return stream};enableVideo=async(call,videoOptions={optional:[{minWidth:320},{minWidth:640},{minWidth:1024},{minWidth:1280},{minWidth:1920},{minWidth:2560},{minWidth:3840}]},includeAudio=false)=>{if(call.videoStream)this.disableVideo(call);let stream=await this.addUserMedia(call.rtc,{audio:includeAudio,video:videoOptions?videoOptions:{optional:[{minWidth:320},{minWidth:640},{minWidth:1024},{minWidth:1280},{minWidth:1920},{minWidth:2560},{minWidth:3840}]}},call);if(videoOptions?.deviceId)call.videoSender.deviceId=videoOptions.deviceId;if(includeAudio){if(includeAudio?.deviceId)call.audioSender.deviceId=includeAudio.deviceId;else if(videoOptions?.deviceId)call.audioSender.deviceId=videoOptions.deviceId}return stream};disableAudio(call){if(call.audioSender){call.senders?.find((s,i2)=>{if(call.audioStream?.getAudioTracks()[0].id===s.track.id){call.senders.splice(i2,1);return true}});call.rtc.removeTrack(call.audioSender);call.audioSender=void 0}call.audioStream?.getTracks().forEach(track=>{if(track.kind==="audio")track.stop()});call.audioStream=void 0}disableVideo(call){if(call.videoSender){call.senders?.find((s,i2)=>{if(call.videoStream?.getVideoTracks()[0].id===s.track.id){call.senders.splice(i2,1);return true}});call.rtc.removeTrack(call.videoSender);call.videoSender=void 0}call.videoStream?.getTracks().forEach(track=>{if(track.kind==="video")track.stop()});call.videoStream=void 0}transmit=(data,id,channel)=>{if(typeof data==="object"&&(data.route||data.node||!data.byteLength&&typeof data.arrayBuffer!=="function")||typeof data==="number")data=JSON.stringify(data);if(!channel&&id){let keys2=Object.keys(this.rtc[id].channels);if(keys2[0])channel=this.rtc[id].channels[keys2[0]]}if(typeof channel==="string"){if(id){channel=this.rtc[id].channels[channel]}else{for(const id2 in this.rtc){if(this.rtc[id2].channels[channel]instanceof RTCDataChannel)this.rtc[id2].channels[channel].send(data)}}}if(channel instanceof RTCDataChannel)channel.send(data);return true};terminate=rtc=>{let tx;if(typeof rtc==="string"){let room=this.rtc[rtc];delete this.rtc[rtc];if(room){tx=room.rtc}}else if(typeof rtc==="object"){tx=rtc.rtc}if(rtc instanceof RTCPeerConnection&&rtc.signalingState!=="closed"){rtc.close()}else if(tx&&tx.signalingState!=="closed"){if(tx)tx.close()}return true};request=(message,channel,_id,method)=>{let callbackId=`${Math.random()}`;let req={route:"runRequest",args:[message,_id,callbackId]};if(method)req.method=method;return new Promise((res,rej)=>{let onmessage=ev=>{let data=ev.data;if(typeof data==="string"&&data.indexOf("{")>-1)data=JSON.parse(ev.data);if(typeof data==="object"){if(data.callbackId===callbackId){channel.removeEventListener("message",onmessage);res(data.args)}}};channel.addEventListener("message",onmessage);channel.send(JSON.stringify(req))})};runRequest=(message,channelOrRtcId,callbackId)=>{let res=this.receive(message);if(channelOrRtcId){if(typeof channelOrRtcId==="string"){for(const key in this.rtc){if(key===channelOrRtcId){channelOrRtcId=this.rtc[key].channels.data?this.rtc[key].channels.data:this.rtc[key].channels[Object.keys(this.rtc[key].channels)[0]];break}}}if(res instanceof Promise)res.then(v=>{res={args:v,callbackId};if(channelOrRtcId instanceof RTCDataChannel)channelOrRtcId.send(JSON.stringify(res));return res});else{res={args:res,callbackId};if(channelOrRtcId instanceof RTCDataChannel)channelOrRtcId.send(JSON.stringify(res))}}return res};subscribeRTC=(route,rtcId,args,key,subInput,channel)=>{if(this.restrict?.[route])return void 0;if(typeof channel==="string"&&this.rtc[rtcId]){channel=this.rtc[rtcId].channels[channel]}else if(!channel){channel=this.rtc[rtcId].channels[Object.keys(this.rtc[rtcId].channels)[0]]}return this.subscribe(route,res=>{if(res instanceof Promise){res.then(r=>{channel.send(JSON.stringify({args:r,callbackId:route}))})}else{channel.send(JSON.stringify({args:res,callbackId:route}))}},args,key,subInput)};subscribeToRTC=(route,rtcId,channelId,callback,args,key,subInput)=>{if(typeof channelId==="string"&&this.rtc[rtcId]){let c=this.rtc[rtcId];let channel=c.channels[channelId];if(channel){this.__node.state.subscribeEvent(rtcId,res=>{if(res?.callbackId===route){if(!callback)this.setState({[rtcId]:res.args});else if(typeof callback==="string"){this.run(callback,res.args)}else callback(res.args)}});return c.request({route:"subscribeRTC",args:[route,rtcId,args,key,subInput,channelId]})}}}};var browser_default=Worker;var WorkerService=class extends Service{name="worker";workers={};threadRot=0;connections;constructor(options){super();this.connections={workers:this.workers};if(options?.services)this.addServices(options.services);this.load(this);this.setLoaders(this.workerloader);if(options)this.init(options);if(typeof WorkerGlobalScope!=="undefined"&&globalThis instanceof WorkerGlobalScope){this.addDefaultMessageListener()}}loadWorkerRoute=(node,routeKey)=>{if(node.workerUrl)node.url=node.workerUrl;if(node._id)node.__node.tag=node._id;if(!node.__node.tag)node.__node.tag=routeKey;node._id=node.__node.tag;let worker;if(this.workers[node._id])worker=this.workers[node._id];else if(node.worker)worker=node.worker;if(!worker){worker=this.addWorker(node)}node.worker=worker;if(!node.__ondisconnected){let ondelete=rt=>{rt.worker?.terminate()};node.__addOndisconnected(ondelete)}if(node.transferFunctions){for(const prop in node.transferFunctions){this.transferFunction(worker,node.transferFunctions[prop],prop)}}if(node.transferClasses){for(const prop in node.transferClasses){this.transferClass(worker,node.transferClasses[prop],prop)}}if(worker){if(!node.__operator){node.__operator=(...args)=>{if(node.callback){if(!this.__node.nodes.get(node.__node.tag)?.__children)worker.post(node.callback,args);else return worker.run(node.callback,args)}else{if(!this.__node.nodes.get(node.__node.tag)?.__children)worker.send(args);else return worker.request(args)}}}if(node.init){worker.run(node.init,node.initArgs,void 0,node.initTransfer)}return worker}};workerloader={"workers":(node,parent,graph,roots)=>{let rt=node;if(!node.parentRoute&&(parent?.callback&&parent?.worker))node.parentRoute=parent?.callback;if(rt?.worker||rt?._id&&this.workers[rt._id]||rt?.workerUrl){let worker=this.loadWorkerRoute(rt,rt.__node.tag);if(worker){if(!rt.parentRoute&&rt.__parent?.callback)rt.parentRoute=rt.__parent.callback;if(rt.__parent&&!rt.portId){if(typeof rt.__parent==="string"){if(rt.__node.tag!==rt.__parent&&worker._id!==rt.__parent)rt.portId=this.establishMessageChannel(worker,rt.__parent)}else if(rt.__node.tag!==rt.__parent?.__node?.tag&&worker._id!==rt.__parent?.tag){rt.portId=this.establishMessageChannel(worker,rt.__parent.worker)}};if(rt.parentRoute){if(!rt.stopped){if(typeof rt.__parent==="string"&&rt.__parent===worker._id){worker.run("subscribe",[rt.parentRoute,void 0,void 0,rt.callback])}else if(rt.__node.tag===rt.__parent?.__node?.tag||worker._id===rt.__parent?.__node?.tag){worker.run("subscribe",[rt.parentRoute,void 0,void 0,rt.callback])}else worker.run("subscribeToWorker",[rt.parentRoute,rt.portId,void 0,rt.callback,void 0,void 0,rt.blocking]).then(sub=>{worker.workerSubs[rt.parentRoute+rt.portId].sub=sub})}if(!(typeof rt.__parent==="string"&&rt.__parent===worker._id)&&!(rt.__node.tag===rt.__parent?.__node?.tag||worker._id===rt.__parent?.__node?.tag))worker.workerSubs[rt.parentRoute+rt.portId]={sub:null,route:rt.parentRoute,portId:rt.portId,callback:rt.callback,blocking:rt.blocking}}else if(rt.__parent){if(typeof rt.__parent==="string"){if(!rt.stopped){if(rt.__parent===worker._id){worker.run("subscribe",[rt.__parent,void 0,rt.callback])}else worker.run("subscribeToWorker",[rt.__parent,rt.portId,void 0,rt.callback,void 0,void 0,rt.blocking]).then(sub=>{worker.workerSubs[rt.__parent+rt.portId].sub=sub})}if(!(typeof rt.__parent==="string"&&rt.__parent===worker._id))worker.workerSubs[rt.__parent+rt.portId]={sub:null,route:worker._id,portId:rt.portId,callback:rt.callback,blocking:rt.blocking}}else if(rt.__parent?.__node?.tag&&rt.__parent?.worker){if(!rt.stopped){if(rt.__node.tag===rt.__parent.__node.tag||worker._id===rt.__parent.__node.tag){worker.run("subscribe",[rt.__parent.__node.tag,void 0,void 0,rt.callback])}else worker.run("subscribeToWorker",[rt.__parent.__node.tag,rt.portId,void 0,rt.callback,void 0,void 0,rt.blocking]).then(sub=>{worker.workerSubs[rt.__parent.__node.tag+rt.portId].sub=sub})}if(!(rt.__node.tag===rt.__parent?.__node?.tag||worker._id===rt.__parent?.__node?.tag))worker.workerSubs[rt.__parent.__node.tag+rt.portId]={sub:null,route:rt.__parent.__node.tag,portId:rt.portId,callback:rt.callback,blocking:rt.blocking}}}}}else if(rt.__parent&&rt.parentRoute){if(typeof rt.__parent==="string"&&roots[rt.__parent]?.worker){roots[rt.__parent].worker.subscribe(rt.parentRoute,rt.__operator,void 0,void 0,void 0,rt.blocking)}else if(rt.__parent?.worker){rt.__parent.worker.subscribe(rt.parentRoute,rt.__operator,void 0,void 0,void 0,rt.blocking)}}return rt}};addDefaultMessageListener=()=>{globalThis.onmessage=ev=>{let result=this.receive(ev.data);if(this.__node.keepState)this.setState({[this.name]:result})}};postMessage=(message,target,transfer)=>{if(this.workers[target]){this.workers[target].send(message,transfer)}else{globalThis.postMessage(message,target,transfer)}};addWorker=options=>{let worker;if(!options._id)options._id=`worker${Math.floor(Math.random()*1e15)}`;if(options.url)worker=new browser_default(options.url);else if(options.port){worker=options.port}else if(this.workers[options._id]){if(this.workers[options._id].port)worker=this.workers[options._id].port;else worker=this.workers[options._id].worker}if(!worker)return;let send=(message,transfer)=>{return this.transmit(message,worker,transfer)};let post=(route,args,method,transfer)=>{let message={route,args};if(method)message.method=method;return this.transmit(message,worker,transfer)};let run=(route,args,method,transfer)=>{return new Promise((res,rej)=>{let callbackId=Math.random();let req={route:"runRequest",args:[{route,args},options._id,callbackId]};if(method)req.args[0].method=method;let onmessage=ev=>{if(typeof ev.data==="object"){if(ev.data.callbackId===callbackId){worker.removeEventListener("message",onmessage);res(ev.data.args)}}};worker.addEventListener("message",onmessage);this.transmit(req,worker,transfer)})};let request=(message,method,transfer)=>{return new Promise((res,rej)=>{let callbackId=Math.random();let req={route:"runRequest",args:[message,options._id,callbackId]};if(method)req.method=method;let onmessage=ev=>{if(typeof ev.data==="object"){if(ev.data.callbackId===callbackId){worker.removeEventListener("message",onmessage);res(ev.data.args)}}};worker.addEventListener("message",onmessage);this.transmit(req,worker,transfer)})};let workerSubs={};let subscribe=(route,callback,args,key,subInput,blocking)=>{return this.subscribeToWorker(route,options._id,callback,args,key,subInput,blocking)};let unsubscribe=(route,sub)=>{return run("unsubscribe",[route,sub])};let start=async(route,portId,callback,blocking)=>{if(route)await run("subscribeToWorker",[route,portId,void 0,callback,blocking]).then(sub=>{if(sub)workerSubs[route+portId]={sub,route,portId,callback,blocking}});else for(const key in workerSubs){if(typeof workerSubs[key].sub!=="number")await run("subscribeToWorker",[workerSubs[key].route,workerSubs[key].portId,void 0,workerSubs[key].callback,void 0,workerSubs[key].blocking]).then(sub=>{workerSubs[key].sub=sub});console.log(JSON.stringify(workerSubs))}return true};let stop=async(route,portId)=>{if(route&&portId&&workerSubs[route+portId]){await run("unsubscribe",[route,workerSubs[route+portId].sub]);workerSubs[route+portId].sub=false}else{for(const key in workerSubs){if(typeof workerSubs[key].sub==="number"){await run("unpipeWorkers",[workerSubs[key].route,workerSubs[key].portId,workerSubs[key].sub]).then(console.log)}workerSubs[key].sub=false}}return true};let terminate=()=>{for(const key in workerSubs){if(typeof workerSubs[key].sub==="number"){run("unpipeWorkers",[workerSubs[key].route,workerSubs[key].portId,workerSubs[key].sub])}workerSubs[key].sub=false}return this.terminate(options._id)};if(!options.onmessage)options.onmessage=ev=>{this.receive(ev.data);this.setState({[options._id]:ev.data})};if(!options.onerror){options.onerror=ev=>{console.error(ev.data)}}worker.onmessage=options.onmessage;worker.onerror=options.onerror;let workersettings={worker,__node:{tag:options._id},send,post,run,request,subscribe,unsubscribe,terminate,start,stop,postMessage:worker.postMessage,workerSubs,graph:this,...options};let node=this.add(workersettings);this.workers[options._id]=node;node.__addOndisconnected(function(){terminate()});return this.workers[options._id]};open=this.addWorker;close=()=>{globalThis.close()};toObjectURL=scriptTemplate=>{let blob=new Blob([scriptTemplate],{type:"text/javascript"});return URL.createObjectURL(blob)};getTransferable(message){let transfer;if(typeof message==="object"){if(message.args){if(message.args?.constructor?.name==="Object"){for(const key in message.args){if(ArrayBuffer.isView(message.args[key])){if(!transfer)transfer=[message.args[key].buffer];else transfer.push(message.args[key].buffer)}else if(message.args[key]?.constructor?.name==="ArrayBuffer"){if(!transfer)transfer=[message.args[key]];else transfer.push(message.args[key])}}}else if(Array.isArray(message.args)&&message.args.length<11){message.args.forEach(arg=>{if(ArrayBuffer.isView(arg)){transfer=[arg.buffer]}else if(arg?.constructor?.name==="ArrayBuffer")transfer=[arg]})}else if(ArrayBuffer.isView(message.args)){transfer=[message.args.buffer]}else if(message.args?.constructor?.name==="ArrayBuffer"){transfer=[message]}}else if(message?.constructor?.name==="Object"){for(const key in message){if(ArrayBuffer.isView(message[key])){if(!transfer)transfer=[message[key].buffer];else transfer.push(message[key].buffer)}else if(message[key]?.constructor?.name==="ArrayBuffer"){if(!transfer)transfer=[message[key]];else transfer.push(message[key])}}}else if(Array.isArray(message)&&message.length<11){message.forEach(arg=>{if(ArrayBuffer.isView(arg)){transfer=[arg.buffer]}else if(arg.constructor?.name==="ArrayBuffer")transfer=[arg]})}else if(ArrayBuffer.isView(message)){transfer=[message.buffer]}else if(message.constructor?.name==="ArrayBuffer"){transfer=[message]}}return transfer}transmit=(message,worker,transfer)=>{if(!transfer){transfer=this.getTransferable(message)}if(worker instanceof browser_default||worker instanceof MessagePort){worker.postMessage(message,transfer)}else if(typeof worker==="string"){if(this.workers[worker]){if(this.workers[worker].port)this.workers[worker].port.postMessage(message,transfer);else if(this.workers[worker].worker)this.workers[worker].worker.postMessage(message,transfer)}}else{let keys2=Object.keys(this.workers);this.workers[keys2[this.threadRot]].worker.postMessage(message,transfer);this.threadRot++;if(this.threadRot===keys2.length)this.threadRot=0}return message};terminate=worker=>{let onclose;let str2;if(typeof worker==="string"){str2=worker;let obj=this.workers[worker];if(obj){delete this.workers[worker];worker=obj.worker;if(obj.onclose)onclose=obj.onclose}}else if(typeof worker==="object"){if(worker?._id){worker=worker.worker;delete this.workers[worker?._id]}}if(worker instanceof browser_default){worker.terminate();if(onclose)onclose(worker);if(str2&&this.get(str2))this.remove(str2);return true}if(worker instanceof MessagePort){worker.close();if(onclose)onclose(worker);if(str2&&this.get(str2))this.remove(str2);return true}return false};establishMessageChannel=(worker,worker2)=>{let workerId;if(typeof worker==="string"){workerId=worker;if(this.workers[worker]){if(this.workers[worker].port)worker=this.workers[worker].port;else worker2=this.workers[worker].worker}}else if(worker?.worker){worker=worker.worker}if(typeof worker2==="string"){if(this.workers[worker2]){if(this.workers[worker2].port)worker2=this.workers[worker2].port;else worker2=this.workers[worker2].worker}}else if(worker2?.worker){worker2=worker2.worker}if(worker instanceof browser_default||worker instanceof MessagePort){let channel=new MessageChannel;let portId=`port${Math.floor(Math.random()*1e15)}`;worker.postMessage({route:"addWorker",args:{port:channel.port1,_id:portId}},[channel.port1]);if(worker2 instanceof browser_default||worker2 instanceof MessagePort){worker2.postMessage({route:"addWorker",args:{port:channel.port2,_id:portId}},[channel.port2])}else if(workerId&&this.workers[workerId]){channel.port2.onmessage=this.workers[workerId].onmessage;this.workers[workerId].port=channel.port2}return portId}return false};request=(message,workerId,transfer,method)=>{let worker=this.workers[workerId].worker;return new Promise((res,rej)=>{let callbackId=Math.random();let req={route:"runRequest",args:[message,callbackId]};if(method)req.method=method;let onmessage=ev=>{if(typeof ev.data==="object"){if(ev.data.callbackId===callbackId){worker.removeEventListener("message",onmessage);res(ev.data.args)}}};worker.addEventListener("message",onmessage);this.transmit(req,worker,transfer)})};runRequest=(message,worker,callbackId,getTransferable=true)=>{let res=this.receive(message);if(typeof worker==="string"&&this.workers[worker]){if(this.workers[worker].port)worker=this.workers[worker].port;else worker=this.workers[worker].worker}if(res instanceof Promise){res.then(r=>{let transfer=getTransferable?this.getTransferable(r):void 0;if(worker instanceof browser_default||worker instanceof MessagePort)worker.postMessage({args:r,callbackId},transfer);else if(typeof WorkerGlobalScope!=="undefined"&&self instanceof WorkerGlobalScope)globalThis.postMessage({args:r,callbackId},transfer)})}else{let transfer=getTransferable?this.getTransferable(res):void 0;if(worker instanceof browser_default||worker instanceof MessagePort)worker.postMessage({args:res,callbackId},transfer);else if(typeof WorkerGlobalScope!=="undefined"&&self instanceof WorkerGlobalScope)globalThis.postMessage({args:res,callbackId},transfer)}return res};subscribeWorker=(route,worker,args,key,subInput,blocking,getTransferable=true)=>{if(this.restrict?.[route])return void 0;let callback;if(blocking){let blocked=false;callback=res=>{if(!blocked){blocked=true;if(res instanceof Promise){res.then(r=>{if(worker?.run)worker.run("triggerSubscription",[route,worker._id,r]).then(ret=>{blocked=false})})}else{if(worker?.run)worker.run("triggerSubscription",[route,worker._id,res]).then(ret=>{blocked=false})}}}}else{callback=res=>{if(res instanceof Promise){res.then(r=>{let transfer=getTransferable?this.getTransferable(r):void 0;if(worker?.postMessage)worker.postMessage({args:r,callbackId:route},transfer);else if(globalThis.postMessage)globalThis.postMessage({args:r,callbackId:route},transfer)})}else{let transfer=getTransferable?this.getTransferable(res):void 0;if(worker?.postMessage)worker.postMessage({args:res,callbackId:route},transfer);else if(globalThis.postMessage)globalThis.postMessage({args:res,callbackId:route},transfer)}}}if(!blocking&&worker?.port){worker=worker.port}else if(!blocking&&worker?.worker){worker=worker.worker}else if(typeof worker==="string"&&this.workers[worker]){if(blocking)worker=this.workers[worker];else if(this.workers[worker].port)worker=this.workers[worker].port;else worker=this.workers[worker].worker}return this.subscribe(route,callback,args,key,subInput)};subscribeToWorker=(route,workerId,callback,args,key,subInput,blocking,getTransferable=true)=>{if(typeof workerId==="string"&&this.workers[workerId]){this.__node.state.subscribeEvent(workerId,res=>{if(res?.callbackId===route){if(!callback)this.setState({[workerId]:res.args});else if(typeof callback==="string"){this.run(callback,res.args)}else callback(res.args)}});return this.workers[workerId].run("subscribeWorker",[route,workerId,args,key,subInput,blocking,getTransferable])}};triggerSubscription=async(route,workerId,result)=>{if(this.__node.state.triggers[workerId])for(let i2=0;i2{if(typeof sourceWorker==="string")sourceWorker=this.workers[sourceWorker];if(typeof listenerWorker==="string")listenerWorker=this.workers[listenerWorker];if(!portId){portId=this.establishMessageChannel(sourceWorker.worker,listenerWorker.worker)}return listenerWorker.run("subscribeToWorker",[sourceRoute,portId,listenerRoute,args,key,subInput,blocking,getTransferable])};unpipeWorkers=(sourceRoute,sourceWorker,sub)=>{if(typeof sourceWorker==="string")sourceWorker=this.workers[sourceWorker];if(typeof sourceWorker==="object"){return sourceWorker.run("unsubscribe",[sourceRoute,sub])}}};var mouseEventHandler=makeSendPropertiesHandler(["ctrlKey","metaKey","altKey","shiftKey","button","which","pointerType","clientX","clientY","pageX","pageY","movementX","movementY","x","y","which","timeStamp"]);var wheelEventHandlerImpl=makeSendPropertiesHandler(["deltaX","deltaY"]);var keydownEventHandler=makeSendPropertiesHandler(["ctrlKey","metaKey","shiftKey","altKey","isComposing","keyCode","key","code","repeat","timeStamp"]);function focusEventHandler(event,sendFn){const data={type:event.type};data.isTrusted=event.isTrusted;data.bubbles=event.bubbles;data.cancelBubble=event.cancelBubble;data.cancelable=event.cancelable;data.composed=event.composed;data.defaultPrevent=event.defaultPrevented;data.eventPhase=event.eventPhase;data.returnValue=event.returnValue;data.currentTarget=event.currentTarget.id?event.currentTarget.id:event.currentTarget.constructor.name;data.target=data.currentTarget;data.srcElement=data.currentTarget;sendFn(data)}function wheelEventHandler(event,sendFn,preventDefault){if(preventDefault&&event.preventDefault)event.preventDefault();wheelEventHandlerImpl(event,sendFn)}function preventDefaultHandler(event,sendFn,preventDefault){if(preventDefault&&event.preventDefault)event.preventDefault()}function copyProperties(src,properties,dst){for(const name2 of properties){dst[name2]=src[name2]}}function makeSendPropertiesHandler(properties){return function sendProperties(event,sendFn){const data={type:event.type};copyProperties(event,properties,data);sendFn(data)}}function touchEventHandler(event,sendFn,preventDefault){if(preventDefault&&event.preventDefault)event.preventDefault();const touches=[];const data={type:event.type,touches};for(let i2=0;i2123))event.preventDefault();keydownEventHandler(event,sendFn)}}var eventHandlers={contextmenu:preventDefaultHandler,mousedown:mouseEventHandler,mousemove:mouseEventHandler,mouseup:mouseEventHandler,pointerdown:mouseEventHandler,pointermove:mouseEventHandler,pointerup:mouseEventHandler,pointerlockchange:mouseEventHandler,webkitpointerlockchange:mouseEventHandler,focus:focusEventHandler,blur:focusEventHandler,pointerout:mouseEventHandler,touchstart:touchEventHandler,touchmove:touchEventHandler,touchend:touchEventHandler,wheel:wheelEventHandler,keydown:filteredKeydownEventHandler,keyup:filteredKeydownEventHandler};function initProxyElement(element,worker,id,preventDefault){if(!id)id="proxy"+Math.floor(Math.random()*1e15);const sendEvent=data=>{if(!worker){handleProxyEvent(data,id)}else worker.postMessage({route:"handleProxyEvent",args:[data,id]})};let entries=Object.entries(eventHandlers);for(const[eventName,handler]of entries){element.addEventListener(eventName,function(event){handler(event,sendEvent,preventDefault)})}if(eventHandlers.keydown){globalThis.addEventListener("keydown",function(ev){eventHandlers.keydown(ev,sendEvent,preventDefault)})}if(eventHandlers.keyup){globalThis.addEventListener("keyup",function(ev){eventHandlers.keyup(ev,sendEvent,preventDefault)})}const sendSize=()=>{const rect=element.getBoundingClientRect();sendEvent({type:"resize",left:rect.left,top:rect.top,width:element.clientWidth,height:element.clientHeight})};sendSize();globalThis.addEventListener("resize",sendSize);return id}var EventDispatcher=class{__listeners;addEventListener(type,listener){if(this.__listeners===void 0)this.__listeners={};const listeners=this.__listeners;if(listeners[type]===void 0){listeners[type]=[]}if(listeners[type].indexOf(listener)===-1){listeners[type].push(listener)}}hasEventListener(type,listener){if(this.__listeners===void 0)return false;const listeners=this.__listeners;return listeners[type]!==void 0&&listeners[type].indexOf(listener)!==-1}removeEventListener(type,listener){if(this.__listeners===void 0)return;const listeners=this.__listeners;const listenerArray=listeners[type];if(listenerArray!==void 0){const index=listenerArray.indexOf(listener);if(index!==-1){listenerArray.splice(index,1)}}}dispatchEvent(event,target){if(this.__listeners===void 0)return;const listeners=this.__listeners;const listenerArray=listeners[event.type];if(listenerArray!==void 0){if(!target)event.target=this;else event.target=target;const array=listenerArray.slice(0);for(let i2=0,l=array.length;i2{};releasePointerCapture=()=>{};getBoundingClientRect=()=>{return{left:this.left,top:this.top,width:this.width,height:this.height,right:this.left+this.width,bottom:this.top+this.height}};handleEvent=data=>{if(data.type==="resize"){this.left=data.left;this.top=data.top;this.width=data.width;this.height=data.height;if(typeof this.proxied==="object"){this.proxied.style.width=this.width+"px";this.proxied.style.height=this.height+"px";this.proxied.clientWidth=this.width;this.proxied.clientHeight=this.height}}data.preventDefault=noop;data.stopPropagation=noop;this.dispatchEvent(data,this.proxied)};focus(){}blur(){}};var ProxyManager=class{targets={};constructor(){if(!globalThis.document)globalThis.document={elementFromPoint:(...args)=>{return this.targets[Object.keys(this.targets)[0]].proxied}}}makeProxy=(id,addTo=void 0)=>{if(!id)id=`proxyReceiver${Math.floor(Math.random()*1e15)}`;let proxy;if(this.targets[id])proxy=this.targets[id];else{proxy=new ElementProxyReceiver;this.targets[id]=proxy}if(typeof addTo==="object"){addTo.proxy=proxy;proxy.proxied=addTo;if(typeof WorkerGlobalScope!=="undefined")addTo.style=proxy.style;if(proxy.width){addTo.style.width=proxy.width+"px";addTo.clientWidth=proxy.width}if(proxy.height){addTo.style.height=proxy.height+"px";addTo.clientHeight=proxy.height}addTo.setPointerCapture=proxy.setPointerCapture.bind(proxy);addTo.releasePointerCapture=proxy.releasePointerCapture.bind(proxy);addTo.getBoundingClientRect=proxy.getBoundingClientRect.bind(proxy);addTo.addEventListener=proxy.addEventListener.bind(proxy);addTo.removeEventListener=proxy.removeEventListener.bind(proxy);addTo.handleEvent=proxy.handleEvent.bind(proxy);addTo.dispatchEvent=proxy.dispatchEvent.bind(proxy);addTo.focus=proxy.focus.bind(proxy);addTo.blur=proxy.blur.bind(proxy)}};getProxy=id=>{return this.targets[id]};handleEvent=(data,id)=>{if(!this.targets[id])this.makeProxy(id);if(this.targets[id]){this.targets[id].handleEvent(data);return true}return void 0}};function makeProxy(id,elm){if(this?.__node?.graph){if(!this.__node.graph.ProxyManager)this.__node.graph.ProxyManager=new ProxyManager;this.__node.graph.ProxyManager.makeProxy(id,elm)}else{if(!globalThis.ProxyManager)globalThis.ProxyManager=new ProxyManager;globalThis.ProxyManager.makeProxy(id,elm)}return id}function handleProxyEvent(data,id){if(this?.__node?.graph){if(!this.__node.graph.ProxyManager)this.__node.graph.ProxyManager=new ProxyManager;if(this.__node.graph.ProxyManager.handleEvent(data,id))return data}else{if(!globalThis.ProxyManager)globalThis.ProxyManager=new ProxyManager;if(globalThis.ProxyManager.handleEvent(data,id))return data}}var proxyElementWorkerRoutes={initProxyElement,makeProxy,handleProxyEvent};var str=String('(()=>{var mouseEventHandler=makeSendPropertiesHandler(["ctrlKey","metaKey","altKey","shiftKey","button","which","pointerType","clientX","clientY","pageX","pageY","movementX","movementY","x","y","which","timeStamp"]);var wheelEventHandlerImpl=makeSendPropertiesHandler(["deltaX","deltaY"]);var keydownEventHandler=makeSendPropertiesHandler(["ctrlKey","metaKey","shiftKey","altKey","isComposing","keyCode","key","code","repeat","timeStamp"]);function focusEventHandler(event,sendFn){const data={type:event.type};data.isTrusted=event.isTrusted;data.bubbles=event.bubbles;data.cancelBubble=event.cancelBubble;data.cancelable=event.cancelable;data.composed=event.composed;data.defaultPrevent=event.defaultPrevented;data.eventPhase=event.eventPhase;data.returnValue=event.returnValue;data.currentTarget=event.currentTarget.id?event.currentTarget.id:event.currentTarget.constructor.name;data.target=data.currentTarget;data.srcElement=data.currentTarget;sendFn(data)}function wheelEventHandler(event,sendFn,preventDefault){if(preventDefault&&event.preventDefault)event.preventDefault();wheelEventHandlerImpl(event,sendFn)}function preventDefaultHandler(event,sendFn,preventDefault){if(preventDefault&&event.preventDefault)event.preventDefault()}function copyProperties(src,properties,dst){for(const name of properties){dst[name]=src[name]}}function makeSendPropertiesHandler(properties){return function sendProperties(event,sendFn){const data={type:event.type};copyProperties(event,properties,data);sendFn(data)}}function touchEventHandler(event,sendFn,preventDefault){if(preventDefault&&event.preventDefault)event.preventDefault();const touches=[];const data={type:event.type,touches};for(let i2=0;i2123))event.preventDefault();keydownEventHandler(event,sendFn)}}var eventHandlers={contextmenu:preventDefaultHandler,mousedown:mouseEventHandler,mousemove:mouseEventHandler,mouseup:mouseEventHandler,pointerdown:mouseEventHandler,pointermove:mouseEventHandler,pointerup:mouseEventHandler,pointerlockchange:mouseEventHandler,webkitpointerlockchange:mouseEventHandler,focus:focusEventHandler,blur:focusEventHandler,pointerout:mouseEventHandler,touchstart:touchEventHandler,touchmove:touchEventHandler,touchend:touchEventHandler,wheel:wheelEventHandler,keydown:filteredKeydownEventHandler,keyup:filteredKeydownEventHandler};function initProxyElement(element,worker,id,preventDefault){if(!id)id="proxy"+Math.floor(Math.random()*1e15);const sendEvent=data=>{if(!worker){handleProxyEvent(data,id)}else worker.postMessage({route:"handleProxyEvent",args:[data,id]})};let entries=Object.entries(eventHandlers);for(const[eventName,handler]of entries){element.addEventListener(eventName,function(event){handler(event,sendEvent,preventDefault)})}if(eventHandlers.keydown){globalThis.addEventListener("keydown",function(ev){eventHandlers.keydown(ev,sendEvent,preventDefault)})}if(eventHandlers.keyup){globalThis.addEventListener("keyup",function(ev){eventHandlers.keyup(ev,sendEvent,preventDefault)})}const sendSize=()=>{const rect=element.getBoundingClientRect();sendEvent({type:"resize",left:rect.left,top:rect.top,width:element.clientWidth,height:element.clientHeight})};sendSize();globalThis.addEventListener("resize",sendSize);return id}var EventDispatcher=class{__listeners;addEventListener(type,listener){if(this.__listeners===void 0)this.__listeners={};const listeners=this.__listeners;if(listeners[type]===void 0){listeners[type]=[]}if(listeners[type].indexOf(listener)===-1){listeners[type].push(listener)}}hasEventListener(type,listener){if(this.__listeners===void 0)return false;const listeners=this.__listeners;return listeners[type]!==void 0&&listeners[type].indexOf(listener)!==-1}removeEventListener(type,listener){if(this.__listeners===void 0)return;const listeners=this.__listeners;const listenerArray=listeners[type];if(listenerArray!==void 0){const index=listenerArray.indexOf(listener);if(index!==-1){listenerArray.splice(index,1)}}}dispatchEvent(event,target){if(this.__listeners===void 0)return;const listeners=this.__listeners;const listenerArray=listeners[event.type];if(listenerArray!==void 0){if(!target)event.target=this;else event.target=target;const array=listenerArray.slice(0);for(let i2=0,l=array.length;i2{};releasePointerCapture=()=>{};getBoundingClientRect=()=>{return{left:this.left,top:this.top,width:this.width,height:this.height,right:this.left+this.width,bottom:this.top+this.height}};handleEvent=data=>{if(data.type==="resize"){this.left=data.left;this.top=data.top;this.width=data.width;this.height=data.height;if(typeof this.proxied==="object"){this.proxied.style.width=this.width+"px";this.proxied.style.height=this.height+"px";this.proxied.clientWidth=this.width;this.proxied.clientHeight=this.height}}data.preventDefault=noop;data.stopPropagation=noop;this.dispatchEvent(data,this.proxied)};focus(){}blur(){}};var ProxyManager=class{targets={};constructor(){if(!globalThis.document)globalThis.document={elementFromPoint:(...args)=>{return this.targets[Object.keys(this.targets)[0]].proxied}}}makeProxy=(id,addTo=void 0)=>{if(!id)id=`proxyReceiver${Math.floor(Math.random()*1e15)}`;let proxy;if(this.targets[id])proxy=this.targets[id];else{proxy=new ElementProxyReceiver;this.targets[id]=proxy}if(typeof addTo==="object"){addTo.proxy=proxy;proxy.proxied=addTo;if(typeof WorkerGlobalScope!=="undefined")addTo.style=proxy.style;if(proxy.width){addTo.style.width=proxy.width+"px";addTo.clientWidth=proxy.width}if(proxy.height){addTo.style.height=proxy.height+"px";addTo.clientHeight=proxy.height}addTo.setPointerCapture=proxy.setPointerCapture.bind(proxy);addTo.releasePointerCapture=proxy.releasePointerCapture.bind(proxy);addTo.getBoundingClientRect=proxy.getBoundingClientRect.bind(proxy);addTo.addEventListener=proxy.addEventListener.bind(proxy);addTo.removeEventListener=proxy.removeEventListener.bind(proxy);addTo.handleEvent=proxy.handleEvent.bind(proxy);addTo.dispatchEvent=proxy.dispatchEvent.bind(proxy);addTo.focus=proxy.focus.bind(proxy);addTo.blur=proxy.blur.bind(proxy)}};getProxy=id=>{return this.targets[id]};handleEvent=(data,id)=>{if(!this.targets[id])this.makeProxy(id);if(this.targets[id]){this.targets[id].handleEvent(data);return true}return void 0}};function makeProxy(id,elm){if(this?.__node?.graph){if(!this.__node.graph.ProxyManager)this.__node.graph.ProxyManager=new ProxyManager;this.__node.graph.ProxyManager.makeProxy(id,elm)}else{if(!globalThis.ProxyManager)globalThis.ProxyManager=new ProxyManager;globalThis.ProxyManager.makeProxy(id,elm)}return id}function handleProxyEvent(data,id){if(this?.__node?.graph){if(!this.__node.graph.ProxyManager)this.__node.graph.ProxyManager=new ProxyManager;if(this.__node.graph.ProxyManager.handleEvent(data,id))return data}else{if(!globalThis.ProxyManager)globalThis.ProxyManager=new ProxyManager;if(globalThis.ProxyManager.handleEvent(data,id))return data}}var proxyElementWorkerRoutes={initProxyElement,makeProxy,handleProxyEvent};function Renderer(options){if(options.worker===true){options.worker=canvas_worker_default}if(options.worker){let worker=options.worker;let route=options.route;if(worker instanceof Blob||typeof worker==="string"){worker=new Worker(worker)}delete options.worker;delete options.route;return transferCanvas(worker,options,route)}else{initProxyElement(options.canvas,void 0,options._id,options.preventDefault);return setupCanvas(options)}}function transferCanvas(worker,options,route){if(!options)return void 0;if(!options._id)options._id=`canvas${Math.floor(Math.random()*1e15)}`;let offscreen=options.canvas instanceof OffscreenCanvas?options.canvas:options.canvas.transferControlToOffscreen();if(!options.width)options.width=options.canvas.clientWidth;if(!options.height)options.height=options.canvas.clientHeight;let message={route:route?route:"setupCanvas",args:{...options,canvas:offscreen}};let proxy;if(this?.__node?.graph)proxy=this.__node.graph.run("initProxyElement",options.canvas,worker,options._id,options.preventDefault);else proxy=initProxyElement(options.canvas,worker,options._id,options.preventDefault);if(options.draw){if(typeof options.draw==="function")message.args.draw=options.draw.toString();else message.args.draw=options.draw}if(options.update){if(typeof options.update==="function")message.args.update=options.update.toString();else message.args.update=options.update}if(options.init){if(typeof options.init==="function")message.args.init=options.init.toString();else message.args.init=options.init}if(options.clear){if(typeof options.clear==="function")message.args.clear=options.clear.toString();else message.args.clear=options.clear}let tr=[offscreen];if(options.transfer){tr.push(...options.transfer);delete options.transfer}worker.postMessage(message,tr);const canvascontrols={_id:options._id,width:options.width,height:options.height,worker,draw:(props,transfer)=>{worker.postMessage({route:"drawFrame",args:[props,options._id]},transfer)},update:(props,transfer)=>{worker.postMessage({route:"updateCanvas",args:[props,options._id]},transfer)},clear:()=>{worker.postMessage({route:"clearCanvas",args:options._id})},init:()=>{worker.postMessage({route:"initCanvas",args:options._id})},stop:()=>{worker.postMessage({route:"stopAnim",args:options._id})},start:()=>{worker.postMessage({route:"startAnim",args:options._id})},set:(newDrawProps,transfer)=>{worker.postMessage({route:"setDraw",args:[newDrawProps,options._id]},transfer)},terminate:()=>{if(proxy)proxy.terminate();worker.terminate()}};return canvascontrols}function setDraw(settings,_id){let canvasopts;if(this?.__node?.graph){if(_id)canvasopts=this.__node.graph.CANVASES?.[settings._id];else if(settings._id)canvasopts=this.__node.graph.CANVASES?.[settings._id];else canvasopts=this.__node.graph.CANVASES?.[Object.keys(this.__node.graph.CANVASES)[0]]}else{if(_id)canvasopts=globalThis.CANVASES?.[settings._id];else if(settings._id)canvasopts=globalThis.CANVASES?.[settings._id];else canvasopts=globalThis.CANVASES?.[Object.keys(globalThis.CANVASES)[0]]}if(canvasopts){if(settings.canvas){canvasopts.canvas=settings.canvas;if(canvasopts.proxy)canvasopts.proxy.terminate();let proxy;if(this?.__node?.graph)proxy=this.__node.graph.run("makeProxy",canvasopts._id,canvasopts.canvas);else proxy=proxyElementWorkerRoutes.makeProxy(canvasopts._id,canvasopts.canvas);canvasopts.proxy=proxy}if(typeof settings.context==="string")canvasopts.context=canvasopts.canvas.getContext(settings.context);else if(settings.context)canvasopts.context=settings.context;if(settings.width)canvasopts.canvas.width=settings.width;if(settings.height)canvasopts.canvas.height=settings.height;if(typeof settings.draw==="string")settings.draw=parseFunctionFromText(settings.draw);if(typeof settings.draw==="function"){canvasopts.draw=settings.draw.bind(settings)}if(typeof settings.update==="string")settings.update=parseFunctionFromText(settings.update);if(typeof settings.update==="function"){canvasopts.update=settings.update.bind(settings)}if(typeof settings.init==="string")settings.init=parseFunctionFromText(settings.init);if(typeof settings.init==="function"){canvasopts.init=settings.init.bind(settings)}if(typeof settings.clear==="string")settings.clear=parseFunctionFromText(settings.clear);if(typeof settings.clear==="function"){canvasopts.clear=settings.clear.bind(settings)}return settings._id}return void 0}function setupCanvas(options){if(this?.__node?.graph){if(!this.__node.graph.CANVASES)this.__node.graph.CANVASES={}}else if(!globalThis.CANVASES)globalThis.CANVASES={};let canvasOptions=options;options._id?canvasOptions._id=options._id:canvasOptions._id=`canvas${Math.floor(Math.random()*1e15)}`;typeof options.context==="string"?canvasOptions.context=options.canvas.getContext(options.context):canvasOptions.context=options.context;"animating"in options?canvasOptions.animating=options.animating:canvasOptions.animating=true;let proxy;if(this?.__node?.graph?.CANVASES[canvasOptions._id]){this.__node.graph.run("setDraw",canvasOptions)}else if(globalThis.CANVASES?.[canvasOptions._id]){setDraw(canvasOptions)}else{if(this?.__node?.graph){canvasOptions.graph=this.__node.graph;if(!canvasOptions.__node){canvasOptions.__node={}}if(!canvasOptions.__node.tag)canvasOptions.__node.tag=canvasOptions._id;canvasOptions=this.__node.graph.add(canvasOptions);canvasOptions.__addOndisconnected=()=>{canvasOptions.stop();delete this.__node.graph.CANVASES[canvasOptions._id]}}if(this?.__node?.graph)this.__node.graph.CANVASES[canvasOptions._id]=canvasOptions;else globalThis.CANVASES[canvasOptions._id]=canvasOptions;if(this?.__node?.graph)proxy=this.__node.graph.run("makeProxy",canvasOptions._id,canvasOptions.canvas);else proxy=proxyElementWorkerRoutes.makeProxy(canvasOptions._id,canvasOptions.canvas);if(options.width)canvasOptions.canvas.width=options.width;if(options.height)canvasOptions.canvas.height=options.height;if(typeof canvasOptions.draw==="string"){canvasOptions.draw=parseFunctionFromText(canvasOptions.draw)}else if(typeof canvasOptions.draw==="function"){canvasOptions.draw=canvasOptions.draw.bind(canvasOptions)}if(typeof canvasOptions.update==="string"){canvasOptions.update=parseFunctionFromText(canvasOptions.update)}else if(typeof canvasOptions.update==="function"){canvasOptions.update=canvasOptions.update.bind(canvasOptions)}if(typeof canvasOptions.init==="string"){canvasOptions.init=parseFunctionFromText(canvasOptions.init)}else if(typeof canvasOptions.init==="function"){canvasOptions.init=canvasOptions.init.bind(canvasOptions)}if(typeof canvasOptions.clear==="string"){canvasOptions.clear=parseFunctionFromText(canvasOptions.clear)}else if(typeof canvasOptions.clear==="function"){canvasOptions.clear=canvasOptions.clear.bind(canvasOptions)}const finishSetup=()=>{canvasOptions.stop=()=>{stopAnim(canvasOptions._id)};canvasOptions.start=draw=>{startAnim(canvasOptions._id,draw)};canvasOptions.set=settings=>{setDraw(settings,canvasOptions._id)};if(typeof canvasOptions.draw==="function"&&canvasOptions.animating){let draw=(s,canvas,context)=>{if(s.animating){let res=s.draw(s,canvas,context);if(res?.then){res.then(()=>{requestAnimationFrame(()=>{draw(s,canvas,context)})})}else requestAnimationFrame(()=>{draw(s,canvas,context)})}};draw(canvasOptions,canvasOptions.canvas,canvasOptions.context)}if(typeof WorkerGlobalScope!=="undefined"&&self instanceof WorkerGlobalScope)return canvasOptions._id;else{const canvascontrols={_id:options._id,width:options.width,height:options.height,proxy,draw:props=>{drawFrame(props,options._id)},update:props=>{updateCanvas(props,options._id)},clear:()=>{clearCanvas(options._id)},init:()=>{initCanvas(options._id)},stop:()=>{stopAnim(options._id)},start:()=>{startAnim(options._id)},set:newDrawProps=>{setDraw(newDrawProps,options._id)},terminate:()=>{if(canvascontrols.proxy){canvascontrols.proxy.terminate()}if(this.__node?.graph)this.__node.graph.remove(options._id);else{stopAnim(options._id);if(this?.__node?.graph)delete this.__node.graph.CANVASES[canvasOptions._id];else delete globalThis.CANVASES[canvasOptions._id]}}};return canvascontrols}};if(typeof canvasOptions.init==="function"){let res=canvasOptions.init(canvasOptions,canvasOptions.canvas,canvasOptions.context);if(res?.then){return new Promise(resolve=>{res.then(()=>{resolve(finishSetup())})})}}return finishSetup()}}function drawFrame(props,_id){let canvasopts=getCanvas.call(this,_id);if(canvasopts){if(props)Object.assign(canvasopts,props);if(canvasopts.draw){canvasopts.draw(canvasopts,canvasopts.canvas,canvasopts.context);return _id}}return void 0}function clearCanvas(_id){let canvasopts=getCanvas.call(this,_id);if(canvasopts?.clear){canvasopts.clear(canvasopts,canvasopts.canvas,canvasopts.context);return _id}return void 0}function initCanvas(_id){let canvasopts=getCanvas.call(this,_id);if(canvasopts?.init){canvasopts.init(canvasopts,canvasopts.canvas,canvasopts.context);return _id}return void 0}function updateCanvas(input,_id){let canvasopts=getCanvas.call(this,_id);if(canvasopts?.update){canvasopts.update(canvasopts,canvasopts.canvas,canvasopts.context,input);return _id}return void 0}function setProps(props,_id){let canvasopts=getCanvas.call(this,_id);if(canvasopts&&props){Object.assign(canvasopts,props);if(props.width)canvasopts.canvas.width=props.width;if(props.height)canvasopts.canvas.height=props.height;return _id}return void 0}function startAnim(_id,draw){let canvasopts=getCanvas.call(this,_id);canvasopts.animating=true;if(canvasopts&&draw){if(typeof draw==="string")draw=parseFunctionFromText(draw);if(typeof draw==="function"){canvasopts.draw=draw}return _id}if(typeof canvasopts?.draw==="function"){let draw2=(s,canvas,context)=>{if(s.animating){s.draw(s,canvas,context);requestAnimationFrame(()=>{draw2(s,canvas,context)})}};if(typeof canvasopts.clear==="function")canvasopts.clear(canvasopts,canvasopts.canvas,canvasopts.context);if(typeof canvasopts.init==="function")canvasopts.init(canvasopts,canvasopts.canvas,canvasopts.context);draw2(canvasopts,canvasopts.canvas,canvasopts.context);return _id}return void 0}function stopAnim(_id){let canvasopts=getCanvas.call(this,_id);if(canvasopts){canvasopts.animating=false;if(typeof canvasopts.clear==="function")requestAnimationFrame(canvasopts.clear(canvasopts,canvasopts.canvas,canvasopts.context));return _id}return void 0}function getCanvas(_id){let canvasopts;if(this?.__node?.graph){if(!_id)canvasopts=this.__node.graph.CANVASES?.[Object.keys(this.__node.graph.CANVASES)[0]];else canvasopts=this.__node.graph.CANVASES?.[_id]}else{if(!_id)canvasopts=globalThis.CANVASES?.[Object.keys(globalThis.CANVASES)[0]];else canvasopts=globalThis.CANVASES?.[_id]}return canvasopts}var workerCanvasRoutes={...proxyElementWorkerRoutes,Renderer,transferCanvas,setupCanvas,setDraw,drawFrame,clearCanvas,initCanvas,updateCanvas,setProps,startAnim,stopAnim,getCanvas};function parseFunctionFromText(method=""){let getFunctionBody=methodString=>{return methodString.replace(/^\\W*(function[^{]+\\{([\\s\\S]*)\\}|[^=]+=>[^{]*\\{([\\s\\S]*)\\}|[^=]+=>(.+))/i,"$2$3$4")};let getFunctionHead=methodString=>{let startindex=methodString.indexOf("=>")+1;if(startindex<=0){startindex=methodString.indexOf("){")}if(startindex<=0){startindex=methodString.indexOf(") {")}return methodString.slice(0,methodString.indexOf("{",startindex)+1)};let newFuncHead=getFunctionHead(method);let newFuncBody=getFunctionBody(method);let newFunc;if(newFuncHead.includes("function")){let varName=newFuncHead.split("(")[1].split(")")[0];newFunc=new Function(varName,newFuncBody)}else{if(newFuncHead.substring(0,6)===newFuncBody.substring(0,6)){let varName=newFuncHead.split("(")[1].split(")")[0];newFunc=new Function(varName,newFuncBody.substring(newFuncBody.indexOf("{")+1,newFuncBody.length-1))}else{try{newFunc=(0,eval)(newFuncHead+newFuncBody+"}")}catch{}}}return newFunc}if(typeof WorkerGlobalScope!=="undefined"){const routes={...workerCanvasRoutes};self.onmessage=ev=>{if(ev.data.route){if(Array.isArray(ev.data.args)){routes[ev.data.route](...ev.data.args)}else routes[ev.data.route](ev.data.args)}}}var canvas_worker_default=self;})();\n');var url=URL.createObjectURL(new globalThis.Blob([str],{type:"text/javascript"}));var canvas_worker_default=url;function Renderer(options){if(options.worker===true){options.worker=canvas_worker_default}if(options.worker){let worker=options.worker;let route=options.route;if(worker instanceof Blob||typeof worker==="string"){worker=new Worker(worker)}delete options.worker;delete options.route;return transferCanvas(worker,options,route)}else{initProxyElement(options.canvas,void 0,options._id,options.preventDefault);return setupCanvas(options)}}function transferCanvas(worker,options,route){if(!options)return void 0;if(!options._id)options._id=`canvas${Math.floor(Math.random()*1e15)}`;let offscreen=options.canvas instanceof OffscreenCanvas?options.canvas:options.canvas.transferControlToOffscreen();if(!options.width)options.width=options.canvas.clientWidth;if(!options.height)options.height=options.canvas.clientHeight;let message={route:route?route:"setupCanvas",args:{...options,canvas:offscreen}};let proxy;if(this?.__node?.graph)proxy=this.__node.graph.run("initProxyElement",options.canvas,worker,options._id,options.preventDefault);else proxy=initProxyElement(options.canvas,worker,options._id,options.preventDefault);if(options.draw){if(typeof options.draw==="function")message.args.draw=options.draw.toString();else message.args.draw=options.draw}if(options.update){if(typeof options.update==="function")message.args.update=options.update.toString();else message.args.update=options.update}if(options.init){if(typeof options.init==="function")message.args.init=options.init.toString();else message.args.init=options.init}if(options.clear){if(typeof options.clear==="function")message.args.clear=options.clear.toString();else message.args.clear=options.clear}let tr=[offscreen];if(options.transfer){tr.push(...options.transfer);delete options.transfer}worker.postMessage(message,tr);const canvascontrols={_id:options._id,width:options.width,height:options.height,worker,draw:(props,transfer)=>{worker.postMessage({route:"drawFrame",args:[props,options._id]},transfer)},update:(props,transfer)=>{worker.postMessage({route:"updateCanvas",args:[props,options._id]},transfer)},clear:()=>{worker.postMessage({route:"clearCanvas",args:options._id})},init:()=>{worker.postMessage({route:"initCanvas",args:options._id})},stop:()=>{worker.postMessage({route:"stopAnim",args:options._id})},start:()=>{worker.postMessage({route:"startAnim",args:options._id})},set:(newDrawProps,transfer)=>{worker.postMessage({route:"setDraw",args:[newDrawProps,options._id]},transfer)},terminate:()=>{if(proxy)proxy.terminate();worker.terminate()}};return canvascontrols}function setDraw(settings,_id){let canvasopts;if(this?.__node?.graph){if(_id)canvasopts=this.__node.graph.CANVASES?.[settings._id];else if(settings._id)canvasopts=this.__node.graph.CANVASES?.[settings._id];else canvasopts=this.__node.graph.CANVASES?.[Object.keys(this.__node.graph.CANVASES)[0]]}else{if(_id)canvasopts=globalThis.CANVASES?.[settings._id];else if(settings._id)canvasopts=globalThis.CANVASES?.[settings._id];else canvasopts=globalThis.CANVASES?.[Object.keys(globalThis.CANVASES)[0]]}if(canvasopts){if(settings.canvas){canvasopts.canvas=settings.canvas;if(canvasopts.proxy)canvasopts.proxy.terminate();let proxy;if(this?.__node?.graph)proxy=this.__node.graph.run("makeProxy",canvasopts._id,canvasopts.canvas);else proxy=proxyElementWorkerRoutes.makeProxy(canvasopts._id,canvasopts.canvas);canvasopts.proxy=proxy}if(typeof settings.context==="string")canvasopts.context=canvasopts.canvas.getContext(settings.context);else if(settings.context)canvasopts.context=settings.context;if(settings.width)canvasopts.canvas.width=settings.width;if(settings.height)canvasopts.canvas.height=settings.height;if(typeof settings.draw==="string")settings.draw=parseFunctionFromText3(settings.draw);if(typeof settings.draw==="function"){canvasopts.draw=settings.draw.bind(settings)}if(typeof settings.update==="string")settings.update=parseFunctionFromText3(settings.update);if(typeof settings.update==="function"){canvasopts.update=settings.update.bind(settings)}if(typeof settings.init==="string")settings.init=parseFunctionFromText3(settings.init);if(typeof settings.init==="function"){canvasopts.init=settings.init.bind(settings)}if(typeof settings.clear==="string")settings.clear=parseFunctionFromText3(settings.clear);if(typeof settings.clear==="function"){canvasopts.clear=settings.clear.bind(settings)}return settings._id}return void 0}function setupCanvas(options){if(this?.__node?.graph){if(!this.__node.graph.CANVASES)this.__node.graph.CANVASES={}}else if(!globalThis.CANVASES)globalThis.CANVASES={};let canvasOptions=options;options._id?canvasOptions._id=options._id:canvasOptions._id=`canvas${Math.floor(Math.random()*1e15)}`;typeof options.context==="string"?canvasOptions.context=options.canvas.getContext(options.context):canvasOptions.context=options.context;"animating"in options?canvasOptions.animating=options.animating:canvasOptions.animating=true;let proxy;if(this?.__node?.graph?.CANVASES[canvasOptions._id]){this.__node.graph.run("setDraw",canvasOptions)}else if(globalThis.CANVASES?.[canvasOptions._id]){setDraw(canvasOptions)}else{if(this?.__node?.graph){canvasOptions.graph=this.__node.graph;if(!canvasOptions.__node){canvasOptions.__node={}}if(!canvasOptions.__node.tag)canvasOptions.__node.tag=canvasOptions._id;canvasOptions=this.__node.graph.add(canvasOptions);canvasOptions.__addOndisconnected=()=>{canvasOptions.stop();delete this.__node.graph.CANVASES[canvasOptions._id]}}if(this?.__node?.graph)this.__node.graph.CANVASES[canvasOptions._id]=canvasOptions;else globalThis.CANVASES[canvasOptions._id]=canvasOptions;if(this?.__node?.graph)proxy=this.__node.graph.run("makeProxy",canvasOptions._id,canvasOptions.canvas);else proxy=proxyElementWorkerRoutes.makeProxy(canvasOptions._id,canvasOptions.canvas);if(options.width)canvasOptions.canvas.width=options.width;if(options.height)canvasOptions.canvas.height=options.height;if(typeof canvasOptions.draw==="string"){canvasOptions.draw=parseFunctionFromText3(canvasOptions.draw)}else if(typeof canvasOptions.draw==="function"){canvasOptions.draw=canvasOptions.draw.bind(canvasOptions)}if(typeof canvasOptions.update==="string"){canvasOptions.update=parseFunctionFromText3(canvasOptions.update)}else if(typeof canvasOptions.update==="function"){canvasOptions.update=canvasOptions.update.bind(canvasOptions)}if(typeof canvasOptions.init==="string"){canvasOptions.init=parseFunctionFromText3(canvasOptions.init)}else if(typeof canvasOptions.init==="function"){canvasOptions.init=canvasOptions.init.bind(canvasOptions)}if(typeof canvasOptions.clear==="string"){canvasOptions.clear=parseFunctionFromText3(canvasOptions.clear)}else if(typeof canvasOptions.clear==="function"){canvasOptions.clear=canvasOptions.clear.bind(canvasOptions)}const finishSetup=()=>{canvasOptions.stop=()=>{stopAnim(canvasOptions._id)};canvasOptions.start=draw=>{startAnim(canvasOptions._id,draw)};canvasOptions.set=settings=>{setDraw(settings,canvasOptions._id)};if(typeof canvasOptions.draw==="function"&&canvasOptions.animating){let draw=(s,canvas,context)=>{if(s.animating){let res=s.draw(s,canvas,context);if(res?.then){res.then(()=>{requestAnimationFrame(()=>{draw(s,canvas,context)})})}else requestAnimationFrame(()=>{draw(s,canvas,context)})}};draw(canvasOptions,canvasOptions.canvas,canvasOptions.context)}if(typeof WorkerGlobalScope!=="undefined"&&self instanceof WorkerGlobalScope)return canvasOptions._id;else{const canvascontrols={_id:options._id,width:options.width,height:options.height,proxy,draw:props=>{drawFrame(props,options._id)},update:props=>{updateCanvas(props,options._id)},clear:()=>{clearCanvas(options._id)},init:()=>{initCanvas(options._id)},stop:()=>{stopAnim(options._id)},start:()=>{startAnim(options._id)},set:newDrawProps=>{setDraw(newDrawProps,options._id)},terminate:()=>{if(canvascontrols.proxy){canvascontrols.proxy.terminate()}if(this.__node?.graph)this.__node.graph.remove(options._id);else{stopAnim(options._id);if(this?.__node?.graph)delete this.__node.graph.CANVASES[canvasOptions._id];else delete globalThis.CANVASES[canvasOptions._id]}}};return canvascontrols}};if(typeof canvasOptions.init==="function"){let res=canvasOptions.init(canvasOptions,canvasOptions.canvas,canvasOptions.context);if(res?.then){return new Promise(resolve=>{res.then(()=>{resolve(finishSetup())})})}}return finishSetup()}}function drawFrame(props,_id){let canvasopts=getCanvas.call(this,_id);if(canvasopts){if(props)Object.assign(canvasopts,props);if(canvasopts.draw){canvasopts.draw(canvasopts,canvasopts.canvas,canvasopts.context);return _id}}return void 0}function clearCanvas(_id){let canvasopts=getCanvas.call(this,_id);if(canvasopts?.clear){canvasopts.clear(canvasopts,canvasopts.canvas,canvasopts.context);return _id}return void 0}function initCanvas(_id){let canvasopts=getCanvas.call(this,_id);if(canvasopts?.init){canvasopts.init(canvasopts,canvasopts.canvas,canvasopts.context);return _id}return void 0}function updateCanvas(input,_id){let canvasopts=getCanvas.call(this,_id);if(canvasopts?.update){canvasopts.update(canvasopts,canvasopts.canvas,canvasopts.context,input);return _id}return void 0}function setProps(props,_id){let canvasopts=getCanvas.call(this,_id);if(canvasopts&&props){Object.assign(canvasopts,props);if(props.width)canvasopts.canvas.width=props.width;if(props.height)canvasopts.canvas.height=props.height;return _id}return void 0}function startAnim(_id,draw){let canvasopts=getCanvas.call(this,_id);canvasopts.animating=true;if(canvasopts&&draw){if(typeof draw==="string")draw=parseFunctionFromText3(draw);if(typeof draw==="function"){canvasopts.draw=draw}return _id}if(typeof canvasopts?.draw==="function"){let draw2=(s,canvas,context)=>{if(s.animating){s.draw(s,canvas,context);requestAnimationFrame(()=>{draw2(s,canvas,context)})}};if(typeof canvasopts.clear==="function")canvasopts.clear(canvasopts,canvasopts.canvas,canvasopts.context);if(typeof canvasopts.init==="function")canvasopts.init(canvasopts,canvasopts.canvas,canvasopts.context);draw2(canvasopts,canvasopts.canvas,canvasopts.context);return _id}return void 0}function stopAnim(_id){let canvasopts=getCanvas.call(this,_id);if(canvasopts){canvasopts.animating=false;if(typeof canvasopts.clear==="function")requestAnimationFrame(canvasopts.clear(canvasopts,canvasopts.canvas,canvasopts.context));return _id}return void 0}function getCanvas(_id){let canvasopts;if(this?.__node?.graph){if(!_id)canvasopts=this.__node.graph.CANVASES?.[Object.keys(this.__node.graph.CANVASES)[0]];else canvasopts=this.__node.graph.CANVASES?.[_id]}else{if(!_id)canvasopts=globalThis.CANVASES?.[Object.keys(globalThis.CANVASES)[0]];else canvasopts=globalThis.CANVASES?.[_id]}return canvasopts}var workerCanvasRoutes={...proxyElementWorkerRoutes,Renderer,transferCanvas,setupCanvas,setDraw,drawFrame,clearCanvas,initCanvas,updateCanvas,setProps,startAnim,stopAnim,getCanvas};function parseFunctionFromText3(method=""){let getFunctionBody=methodString=>{return methodString.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i,"$2$3$4")};let getFunctionHead3=methodString=>{let startindex=methodString.indexOf("=>")+1;if(startindex<=0){startindex=methodString.indexOf("){")}if(startindex<=0){startindex=methodString.indexOf(") {")}return methodString.slice(0,methodString.indexOf("{",startindex)+1)};let newFuncHead=getFunctionHead3(method);let newFuncBody=getFunctionBody(method);let newFunc;if(newFuncHead.includes("function")){let varName=newFuncHead.split("(")[1].split(")")[0];newFunc=new Function(varName,newFuncBody)}else{if(newFuncHead.substring(0,6)===newFuncBody.substring(0,6)){let varName=newFuncHead.split("(")[1].split(")")[0];newFunc=new Function(varName,newFuncBody.substring(newFuncBody.indexOf("{")+1,newFuncBody.length-1))}else{try{newFunc=(0,eval)(newFuncHead+newFuncBody+"}")}catch{}}}return newFunc}var SessionsService=class extends Service{name="sessions";users={};sessions={oneWay:{},shared:{}};invites={};constructor(options,users){super(options);this.setLoaders(loaders);this.load(this);if(users)this.users=users}getSessionInfo=(sessionIdOrName,userId)=>{if(!sessionIdOrName){return this.sessions.shared}else{if(this.sessions.oneWay[sessionIdOrName]){let s=this.sessions.oneWay[sessionIdOrName];if(s.settings){if(s.settings.source===userId||s.settings.listener===userId||s.settings.ownerId===userId||s.settings.admins?.[userId]||s.settings.moderators?.[userId])return{oneWay:{[sessionIdOrName]:s}}}}else if(this.sessions.shared[sessionIdOrName]){return{shared:{[sessionIdOrName]:this.sessions.shared[sessionIdOrName]}}}else{let res={};for(const id in this.sessions.shared){if(this.sessions.shared[id].settings?.name)res[id]=this.sessions.shared.settings}if(Object.keys(res).length>0)return res}}};openOneWaySession=(options={},sourceUserId,listenerUserId)=>{if(!options._id){options._id=`oneWay${Math.floor(Math.random()*1e15)}`;if(this.sessions.oneWay[options._id]){delete options._id;this.openOneWaySession(options,sourceUserId)}}if(options._id&&sourceUserId&&this.users[sourceUserId]){if(sourceUserId){if(!options.settings)options.settings={listener:sourceUserId,source:sourceUserId,propnames:{latency:true},admins:{[sourceUserId]:true},ownerId:sourceUserId};if(!options.settings.listener)options.settings.listener=listenerUserId?listenerUserId:sourceUserId;if(!options.settings.source)options.settings.source=sourceUserId;if(!this.users[sourceUserId].sessions)this.users[sourceUserId].sessions={};this.users[sourceUserId].sessions[options._id]=options}if(!options.data)options.data={};if(options.onopen)options.onopen(options);if(this.sessions.oneWay[options._id]){return this.updateSession(options,sourceUserId)}else if(options.settings?.listener&&options.settings.source)this.sessions.oneWay[options._id]=options}return options};openSharedSession=(options,userId)=>{if(!options._id){options._id=`shared${Math.floor(Math.random()*1e15)}`;if(this.sessions.shared[options._id]){delete options._id;return this.openSharedSession(options,userId)}}if(options._id&&userId&&this.users[userId]){if(typeof userId==="string"){if(!options.settings)options.settings={name:"shared",propnames:{latency:true},users:{[userId]:true},admins:{[userId]:true},ownerId:userId};if(!options.settings.users)options.settings.users={[userId]:true};if(!options.settings.admins)options.settings.admins={[userId]:true};if(!options.settings.ownerId)options.settings.ownerId=userId;if(!this.users[userId].sessions)this.users[userId].sessions={};this.users[userId].sessions[options._id]=options}else if(!options.settings)options.settings={name:"shared",propnames:{latency:true},users:{}};if(!options.data)options.data={oneWay:{},shared:{}};if(!options.settings.name)options.name=options.id;if(options.onopen)options.onopen(options);if(this.sessions.shared[options._id]){return this.updateSession(options,userId)}else this.sessions.shared[options._id]=options}return options};open=(options,userId)=>{if(options.listener)this.openOneWaySession(options,userId);else this.openSharedSession(options,userId)};updateSession=(options,userId)=>{let session;if(options._id){session=this.sessions.oneWay[options._id];if(!session)session=this.sessions.shared[options._id];if(session&&userId){if(session.settings&&(session?.settings.source===userId||session.settings.admins?.[userId]||session.settings.moderators?.[userId]||session.settings.ownerId===userId)){return this.recursivelyAssign(session,options)}}else if(options.settings?.source){return this.openOneWaySession(options,userId)}else return this.openSharedSession(options,userId)}return false};joinSession=(sessionId,userId,options,remoteUser=true)=>{if(!userId&&!this.users[userId])return false;if(!this.users[userId].sessions)this.users[userId].sessions={};let sesh=this.sessions.shared[sessionId];if(!sesh)sesh=this.sessions.oneWay[sessionId];if(sesh?.settings){if(sesh.settings?.banned){if(sesh.settings.banned[userId])return false}if(sesh.settings?.password){if(!options?.settings?.password)return false;if(options.settings.password!==sesh.settings.password)return false}sesh.settings.users[userId]=true;sesh.settings.newUser=true;this.users[userId].sessions[sessionId]=sesh;if(options){return this.updateSession(options,userId)};if(remoteUser&&this.users[userId]?.send){this.users[userId].send({route:"joinSession",args:[sessionId,userId,sesh]})}return sesh}else if(options?.source||options?.listener){sesh=this.openOneWaySession(options,userId);if(remoteUser&&this.users[userId]?.send){this.users[userId].send({route:"joinSession",args:[sessionId,userId,sesh]})}return sesh}else if(options){sesh=this.openSharedSession(options,userId);if(remoteUser&&this.users[userId]?.send){this.users[userId].send({route:"joinSession",args:[sessionId,userId,sesh]})}return sesh}return false};inviteToSession=(session,userInvited,inviteEndpoint,remoteUser=true)=>{if(remoteUser&&this.users[userInvited]?.send){this.users[userInvited]?.send({route:"receiveSessionInvite",args:[session,userInvited,inviteEndpoint]})}else{this.receiveSessionInvite(session,userInvited,inviteEndpoint)}};receiveSessionInvite=(session,userInvited,endpoint)=>{if(!this.invites[userInvited])this.invites[userInvited]={};let id=typeof session==="string"?session:session._id;this.invites[userInvited][id]={session,endpoint};return id};acceptInvite=(session,userInvited,remoteUser=true)=>{let id=typeof session==="string"?session:session._id;let invite=this.invites[userInvited]?.[id];let endpoint;if(invite){session=invite.session;endpoint=invite.endpoint;delete this.invites[userInvited]?.[id]}return new Promise((res,rej)=>{if(!id)res(false);if(remoteUser&&endpoint&&this.users[endpoint]?.send){let resolved;let timeout=setTimeout(()=>{if(!resolved){this.unsubscribe("joinSession",subbed);rej(new Error("Session join timed out"))}},1e4);let subbed=this.subscribe("joinSession",result=>{if(typeof result==="object"&&result?._id===id){if(result.setting?.users?.includes(userInvited)){this.unsubscribe("joinSession",subbed);resolved=true;if(timeout)clearTimeout(timeout);res(result)}}});this.users[endpoint]?.send({route:"joinSession",args:[id,userInvited,void 0,true]})}else res(this.joinSession(id,userInvited,typeof session==="object"?session:void 0))})};rejectInvite=(session,userInvited,remoteUser=true)=>{let id=typeof session==="string"?session:session._id;if(this.invites[userInvited]?.[id]){let endpoint=this.invites[userInvited][id].endpoint;delete this.invites[userInvited][id];if(remoteUser&&endpoint&&this.users[endpoint]?.send){this.users[endpoint].send({route:"rejectInvite",args:[id,userInvited]})}return true}};leaveSession=(session,userId,clear=true,remoteUser=true)=>{let sessionId;if(typeof session==="string"){sessionId=session;session=this.sessions.oneWay[sessionId];if(!session)session=this.sessions.shared[sessionId]}else sessionId=session._id;if(session){if(this.sessions.oneWay[sessionId]){if(userId===session.settings.source||userId===session.settings.listener||session.settings.admins?.[userId]||session.settings.moderators?.[userId]){delete this.sessions.oneWay[sessionId];delete this.users[userId]?.sessions[sessionId];delete this.users[userId]?.sessionSubs?.[sessionId];if(clear){if(session.settings.admins?.[userId])delete(this.sessions.shared[sessionId].settings?.admins)[userId];if(session.settings.moderators?.[userId])delete(this.sessions.shared[sessionId].settings?.moderators)[userId]}if(remoteUser&&this.users[userId]?.send){this.users[userId].send({route:"unsubscribeFromSession",args:[session._id,userId,clear]})}else{this.unsubsribeFromSession(session,userId,clear)}}}else if(this.sessions.shared[sessionId]){delete this.sessions.shared.settings.users[userId];delete this.users[userId]?.sessions[sessionId];delete this.users[userId]?.sessionSubs?.[sessionId];if(clear){if(session.settings.admins?.[userId])delete(this.sessions.shared[sessionId].settings?.admins)[userId];if(session.settings.moderators?.[userId])delete(this.sessions.shared[sessionId].settings?.moderators)[userId];if(session.data.shared[userId])delete this.sessions.shared[sessionId].data?.shared[userId];if(session.settings.host===userId){this.swapHost(session,void 0,true);delete session.data.shared[userId]}}if(remoteUser&&this.users[userId]?.send){this.users[userId].send({route:"unsubscribeFromSession",args:[session._id,userId,clear]})}else{this.unsubsribeFromSession(session,userId,clear)}}return true}return false};deleteSession=(session,userId,remoteUsers=true)=>{if(typeof session==="string"){let id=session;session=this.sessions.oneWay[id];if(!session)session=this.sessions.shared[id]}if(session){if(session.source===userId||session.listener===userId||session.admins?.[userId]||session.ownerId===userId){for(const user in session.settings.users){if(this.users[user]?.sessions)delete this.users[user].sessions[session._id];if(this.users[user]?.sessionSubs)delete this.users[user].sessionSubs[session._id];if(remoteUsers){if(session.users){for(const key in session.users){if(this.users[key]?.send)this.users[key].send({route:"unsubscribeFromSession",args:[session._id,key]})}}else if(session.listener){if(this.users[session.listener]?.send)this.users[session.listener].send({route:"unsubscribeFromSession",args:[session._id,session.listener]})}else if(this.users[userId]?.send){this.users[userId].send({route:"unsubscribeFromSession",args:[session._id,userId]})}}else{this.unsubsribeFromSession(session,user)}}if(this.sessions.oneWay[session._id])delete this.sessions.oneWay[session._id];else if(this.sessions.shared[session._id])delete this.sessions.oneWay[session._id];if(session.onclose)session.onclose(session)}}return true};getFirstMatch(obj1,obj2){for(const i2 in obj1){if(i2 in obj2)return i2}return false}swapHost=(session,newHostId,adoptData=true,remoteUser=true)=>{if(typeof session==="string"){if(this.sessions.oneWay[session])session=this.sessions.oneWay[session];else if(this.sessions.shared[session])session=this.sessions.shared[session]}if(typeof session==="object"&&session.settings){let oldHost=session.settings.host;delete session.settings.host;if(newHostId){if(session.settings.users[newHostId])session.settings.host=newHostId}if(session.settings.ownerId&&!session.settings.host){if(session.settings.users[session.settings.ownerId])session.settings.host=session.settings.ownerId}if(session.settings.admins&&!session.settings.host){let match=this.getFirstMatch(session.settings.users,session.settings.admins);if(match)session.settings.host=match}if(session.settings.moderators&&!session.settings.host){let match=this.getFirstMatch(session.settings.users,session.settings.moderators);if(match)session.settings.host=match}if(!session.settings.host)session.settings.host=Object.keys(session.settings.users)[0];if(adoptData&&oldHost&&session.settings.inheritHostData!==false){if(session.data?.shared[oldHost]){if(session.data?.shared[oldHost]){session.data.shared[session.settings.host]=Object.assign(session.data.shared[session.settings.host]?session.data.shared[session.settings.host]:{},session.data.shared[oldHost]);if(remoteUser){}}}}return true}return false};subscribeToSession=(session,userId,onmessage,onopen,onclose)=>{if(typeof session==="string"){let s=this.sessions.oneWay[session];if(!s)s=this.sessions.shared[session];if(!s)return void 0;session=s}let user=this.users[userId];if(!user)return void 0;if(!user.sessionSubs)user.sessionSubs={};if(!user.sessionSubs[session._id])user.sessionSubs[session._id]={};if(onmessage)user.sessionSubs[session._id].onmessage=onmessage;if(onopen)this.sessionSubs[userId][session._id].onopen=onopen;if(onclose)user.sessionSubs[session._id].onclose=onclose;if(typeof onopen==="function"){let sub=this.subscribe("joinSession",res=>{if(res._id===session._id)this.sessionSubs[userId][session._id].onopen(session,user);this.unsubscribe("joinSession",sub)});user.sessionSubs[session._id].onopenSub=sub}return session};unsubsribeFromSession=(session,userId,clear=true)=>{if(typeof session==="string"){let s=this.sessions.oneWay[session];if(!s)s=this.sessions.shared[session];if(!s)return void 0;session=s}const clearSessionSubs=(Id,s)=>{let u2=this.users[Id];if(!u2)return void 0;if(u2.sessionSubs?.[s._id]){if(u2.sessionSubs[s._id].onopenSub){this.unsubscribe("joinSession",u2.sessionSubs[s._id].onopenSub)}}if(u2.sessionSubs[s._id].onclose)u2.sessionSubs[s._id].onclose(s,u2);delete u2.sessionSubs[s._id]};if(userId){clearSessionSubs(userId,session)}else{for(const key in this.users){clearSessionSubs(key,session)}}if(clear){if(this.sessions.oneWay[session._id])delete this.sessions.oneWay[session._id];else if(this.sessions.shared[session._id])delete this.sessions.shared[session._id]}};sessionUpdateCheck=(sessionHasUpdate,transmit=true)=>{let updates={oneWay:{},shared:{}};for(const session in this.sessions.oneWay){const sesh=this.sessions.oneWay[session];const updateObj={_id:sesh._id,settings:{listener:sesh.listener,source:sesh.source},data:{}};if(!this.users[sesh.source]){delete this.sessions.oneWay[session];continue}if(sesh.settings&&sesh.data){for(const prop in sesh.settings.propnames){if(prop in this.users[sesh.source]){if(this.sessions.oneWay[session].data){if(typeof sesh.data[prop]==="object"){if(this.users[sesh.source][prop]&&(stringifyFast(sesh.data[prop])!==stringifyFast(this.users[sesh.source][prop])||!(prop in sesh.data)))updateObj.data[prop]=this.users[sesh.source][prop]}else if(prop in this.users[sesh.source]&&(sesh.data[prop]!==this.users[sesh.source][prop]||!(prop in sesh.data)))updateObj.data[prop]=this.users[sesh.source][prop]}else updateObj.data[prop]=this.users[sesh.source][prop]}else if(this.sessions.oneWay[session]?.data&&prop in this.sessions.oneWay[session]?.data)delete this.sessions.oneWay[session].data[prop]}}if(Object.keys(updateObj.data).length>0){this.recursivelyAssign(this.sessions.oneWay[session].data,updateObj.data);updates.oneWay[sesh._id]=updateObj;if(sessionHasUpdate)sessionHasUpdate(sesh,updateObj);if(sesh.settings.onhasupdate)sesh.onhasupdate(sesh,updateObj)}}for(const session in this.sessions.shared){const sesh=this.sessions.shared[session];const updateObj={_id:sesh._id,settings:{name:sesh.name},data:{}};if(sesh.settings?.host){const oneWayData={};const sharedData={};for(const user in sesh.settings.users){if(!this.users[user]){delete sesh.settings.users[user];if(sesh.settings.host===user)this.swapHost(sesh,void 0,true);if(sesh.data?.shared[user])delete sesh.data.shared[user];if(sesh.data?.oneWay?.[user])delete sesh.data.shared[user];updateObj.settings.users=sesh.settings.users;updateObj.settings.host=sesh.settings.host;continue}else if(sesh.settings.newUser){updateObj.settings.users=sesh.settings.users;updateObj.settings.host=sesh.settings.host;sesh.settings.newUser=false}if(user!==sesh.settings.host){oneWayData[user]={};for(const prop in sesh.settings.propnames){if(prop in this.users[user]){if(sesh.data?.oneWay&&!(user in sesh.data.oneWay)){if(typeof this.users[user][prop]==="object")oneWayData[user][prop]=this.recursivelyAssign({},this.users[user][prop]);else oneWayData[user][prop]=this.users[user][prop]}else if(typeof oneWayData[user][prop]==="object"&&sesh.data){if(prop in this.users[user][prop]&&(stringifyFast(sesh.data?.shared[user][prop])!==stringifyFast(this.users[user][prop])||!(prop in sesh.data)))oneWayData[user][prop]=this.users[user][prop]}else if(this.users[user][prop]&&sesh.data?.oneWay?.[prop]!==this.users[user][prop])oneWayData[user][prop]=this.users[user][prop]}else if(sesh.data?.oneWay?.[user]&&prop in sesh.data?.oneWay?.[user])delete sesh.data.oneWay[user][prop]}if(Object.keys(oneWayData[user]).length===0)delete oneWayData[user]}else{sharedData[user]={};for(const prop in sesh.settings.hostprops){if(prop in this.users[user]){if(sesh.data&&!(user in sesh.data.shared)){if(typeof this.users[user][prop]==="object")sharedData[user][prop]=this.recursivelyAssign({},this.users[user][prop]);else sharedData[user][prop]=this.users[user][prop]}else if(typeof sharedData[user][prop]==="object"&&sesh.data){if(stringifyFast(sesh.data?.shared[user][prop])!==stringifyFast(this.users[user][prop])||!(prop in sesh.data.shared[user]))sharedData[user][prop]=this.users[user][prop]}else if(sesh.data?.shared[user][prop]!==this.users[user][prop])sharedData[user][prop]=this.users[user][prop]}else if(sesh.data?.shared[user]&&prop in sesh.data?.shared[user])delete sesh.data.shared[user][prop]}}}if(Object.keys(oneWayData).length>0){updateObj.data.oneWay=oneWayData}if(Object.keys(sharedData).length>0){updateObj.data.shared=sharedData}}else{const sharedData={};if(sesh.settings?.users){for(const user in sesh.settings.users){if(!this.users[user]){delete sesh.settings.users[user];if(sesh.settings.host===user)this.swapHost(sesh,void 0,true);if(sesh.data?.shared[user])delete sesh.data.shared[user];if(sesh.data?.oneWay?.[user])delete sesh.data.shared[user];updateObj.settings.users=sesh.settings.users;updateObj.settings.host=sesh.settings.host;continue}sharedData[user]={};for(const prop in sesh.settings.propnames){if(prop in this.users[user]){if(sesh.data&&!(user in sesh.data.shared)){if(typeof this.users[user][prop]==="object")sharedData[user][prop]=this.recursivelyAssign({},this.users[user][prop]);else sharedData[user][prop]=this.users[user][prop]}else if(typeof sesh.data?.shared[user]?.[prop]==="object"){if(stringifyFast(sesh.data.shared[user][prop])!==stringifyFast(this.users[user][prop])||!(prop in sesh.data.shared[user])){sharedData[user][prop]=this.users[user][prop]}}else if(sesh.data?.shared[user]?.[prop]!==this.users[user][prop])sharedData[user][prop]=this.users[user][prop]}else if(sesh.data?.shared[user]&&prop in sesh.data?.shared[user])delete sesh.data.shared[user][prop]}if(Object.keys(sharedData[user]).length===0)delete sharedData[user]}if(Object.keys(sharedData).length>0){updateObj.data.shared=sharedData}}}if(updateObj.data.shared||updateObj.data.oneWay){updates.shared[sesh._id]=updateObj;if(updateObj.data.shared){Object.assign(this.sessions.shared[session].data?.shared,updateObj.data.shared)}if(updateObj.data.oneWay){Object.assign(this.sessions.shared[session].data?.oneWay,updateObj.data.oneWay)}if(sessionHasUpdate)sessionHasUpdate(sesh,updateObj);if(sesh.settings.onhasupdate)sesh.settings.onhasupdate(sesh,updateObj)}}if(Object.keys(updates.oneWay).length===0)delete updates.oneWay;if(Object.keys(updates.shared).length===0)delete updates.shared;if(Object.keys(updates).length===0)return void 0;if(transmit)this.transmitSessionUpdates(updates);return updates};transmitSessionUpdates=updates=>{let users={};if(updates.oneWay){for(const s in updates.oneWay){let session=this.sessions.oneWay[s];if(session?.settings){let u2=session.settings.listener;if(!users[u2])users[u2]={};users[u2].oneWay[s]=updates.oneWay[s]}}}if(updates.shared){for(const s in updates.shared){let session=this.sessions.shared[s];if(session?.settings){for(const u2 in session.settings.users){if(!users[u2])users[u2]={};users[u2].shared[s]=updates.shared[s]}}}}let message={route:"receiveSessionUpdates",args:null};for(const u2 in users){message.args=[u2,users[u2]];if(this.users[u2]?.send)this.users[u2].send(JSON.stringify(message));this.setState({[u2]:Object.create(message)})}return users};receiveSessionUpdates=(origin,update)=>{if(update){if(typeof update==="string")update=JSON.parse(update)}if(typeof update==="object"){let user=this.users[origin];if(user){if(!user.sessions)user.sessions={oneWay:{},shared:{}};if(!user.sessionSubs)user.sessionSubs={}}if(update.oneWay){for(const key in update.oneWay){this.recursivelyAssign(this.sessions.oneWay[key].data,update.oneWay[key].data);if(this.sessions.oneWay[key]?.settings.onmessage)this.sessions.oneWay[key].settings.onmessage(this.sessions.oneWay[key],update.oneWay[key]);if(user?.sessionSubs[user._id]?.[key]?.onmessage)user.sessionSubs[user._id][key].onmessage(user.sessions[key],update,user)}}if(update.shared){for(const key in update.shared){if(update.shared[key].settings.users)this.sessions.shared[key].settings.users=update.shared[key].settings.users;if(update.shared[key].settings.host)this.sessions.shared[key].settings.host=update.shared[key].settings.host;if(update.shared[key].data.oneWay)this.recursivelyAssign(this.sessions.shared[key].data.oneWay,update.shared[key].data.oneWay);if(update.shared[key].data.shared)this.recursivelyAssign(this.sessions.shared[key].data.shared,update.shared[key].data.shared);if(this.sessions.shared[key]?.settings.onmessage)this.sessions.shared[key].settings.onmessage(this.sessions.shared[key],update.shared[key]);if(user?.sessionSubs[user._id]?.[key]?.onmessage)user.sessionSubs[user._id][key].onmessage(user.sessions[key],update,user)}}return user}};getUpdatedUserData=user=>{const updateObj={};for(const key in user.sessions){let s=user.sessions[key];if(s.settings.users[user._id]||s.settings.source===user._id){if(!s.settings.spectators?.[user._id]){if(s.settings.host===user._id){for(const prop in s.settings.hostprops){if(!updateObj[prop]&&prop in user){if(s.data.shared?.[user._id]&&prop in s.data.shared?.[user._id]){if(typeof user[prop]==="object"){if(stringifyFast(s.data.shared[user._id][prop])!==stringifyFast(user[prop]))updateObj[prop]=user[prop]}else if(s.data.shared[user._id][prop]!==user[prop])updateObj[prop]=user[prop]}else updateObj[prop]=user[prop]}}}else{for(const prop in s.settings.propnames){if(!updateObj[prop]&&user[prop]!==void 0){if(s.settings.source){if(typeof user[prop]==="object"&&prop in s.data){if(stringifyFast(s.data[prop])!==stringifyFast(user[prop]))updateObj[prop]=user[prop]}else if(s.data[prop]!==user[prop])updateObj[prop]=user[prop]}else{if(s.data.shared?.[user._id]&&prop in s.data.shared?.[user._id]){if(typeof user[prop]==="object"){if(stringifyFast(s.data.shared[user._id][prop])!==stringifyFast(user[prop]))updateObj[prop]=user[prop]}else if(s.data.shared[user._id][prop]!==user[prop])updateObj[prop]=user[prop]}else updateObj[prop]=user[prop]}}}}}}}return updateObj};userUpdateCheck=(user,onupdate)=>{if(user.sessions){const updateObj=this.getUpdatedUserData(user);if(Object.keys(updateObj).length>0){let message={route:"setUserProps",args:[user._id,updateObj]};if(user.send)user.send(message);this.setState({[user._id]:message});if(onupdate){onupdate(user,updateObj)};return updateObj}}return void 0};setUserProps=(user,props)=>{if(user){if(typeof user==="string"){user=this.users[user];if(!user)return false}}if(props){if(typeof props==="string"){props=JSON.parse(props)}}this.recursivelyAssign(user,props);return true};userUpdateLoop={__operator:this.userUpdateCheck,__node:{loop:10}};sessionLoop={__operator:this.sessionUpdateCheck,__node:{loop:10}};STREAMLATEST=0;STREAMALLLATEST=1;streamSettings={};streamFunctions={allLatestValues:(prop,setting)=>{let result=void 0;if(Array.isArray(prop)){if(prop.length!==setting.lastRead){result=prop.slice(setting.lastRead);setting.lastRead=prop.length}}else if(typeof prop==="object"){result={};for(const p in prop){if(Array.isArray(prop[p])){if(typeof setting==="number")setting={[p]:{lastRead:void 0}};else if(!setting[p])setting[p]={lastRead:void 0};if(prop[p].length!==setting[p].lastRead){result[p]=prop[p].slice(setting[p].lastRead);setting[p].lastRead=prop[p].length}}else{if(typeof setting==="number")setting={[p]:{lastRead:void 0}};else if(!setting[p])setting[p]={lastRead:void 0};if(setting[p].lastRead!==prop[p]){result[p]=prop[p];setting[p].lastRead=prop[p]}}}if(Object.keys(result).length===0)result=void 0}else{if(setting.lastRead!==prop){result=prop;setting.lastRead=prop}}return result},latestValue:(prop,setting)=>{let result=void 0;if(Array.isArray(prop)){if(prop.length!==setting.lastRead){result=prop[prop.length-1];setting.lastRead=prop.length}}else if(typeof prop==="object"){result={};for(const p in prop){if(Array.isArray(prop[p])){if(typeof setting==="number")setting={[p]:{lastRead:void 0}};else if(!setting[p])setting[p]={lastRead:void 0};if(prop[p].length!==setting[p].lastRead){result[p]=prop[p][prop[p].length-1];setting[p].lastRead=prop[p].length}}else{if(typeof setting==="number")setting={[p]:{lastRead:void 0}};else if(!setting[p])setting[p]={lastRead:void 0};if(setting[p].lastRead!==prop[p]){result[p]=prop[p];setting[p].lastRead=prop[p]}}}}else{if(setting.lastRead!==prop){result=prop;setting.lastRead=prop}}return result}};setStreamFunc=(name2,key,callback=this.streamFunctions.allLatestValues)=>{if(!this.streamSettings[name2].settings[key])this.streamSettings[name2].settings[key]={lastRead:0};if(callback===this.STREAMLATEST)this.streamSettings[name2].settings[key].callback=this.streamFunctions.latestValue;else if(callback===this.STREAMALLLATEST)this.streamSettings[name2].settings[key].callback=this.streamFunctions.allLatestValues;else if(typeof callback==="string")this.streamSettings[name2].settings[key].callback=this.streamFunctions[callback];else if(typeof callback==="function")this.streamSettings[name2].settings[key].callback=callback;if(!this.streamSettings[name2].settings[key].callback)this.streamSettings[name2].settings[key].callback=this.streamFunctions.allLatestValues;return true};addStreamFunc=(name2,callback=data=>{})=>{this.streamFunctions[name2]=callback};setStream=(object={},settings={},streamName=`stream${Math.floor(Math.random()*1e10)}`,onupdate,onclose)=>{if(settings.keys){if(settings.keys.length===0){let k=Object.keys(object);if(k.length>0){settings.keys=Array.from(k)}}}else{settings.keys=Array.from(Object.keys(object))}this.streamSettings[streamName]={object,settings,onupdate,onclose};this.subscribe(streamName,res=>{if(this.streamSettings[streamName].onupdate)this.streamSettings[streamName].onupdate(res,this.streamSettings[streamName])});settings.keys.forEach(prop=>{if(settings[prop]?.callback)this.setStreamFunc(streamName,prop,settings[prop].callback);else this.setStreamFunc(streamName,prop,settings.callback)});return this.streamSettings[streamName]};removeStream=(streamName,key)=>{if(streamName&&this.streamSettings[streamName]&&!key){if(this.streamSettings[streamName].onclose)this.streamSettings[streamName].onclose(this.streamSettings[streamName]);this.unsubscribe(streamName);delete this.streamSettings[streamName]}else if(key&&this.streamSettings[streamName]?.settings?.keys){let idx=this.streamSettings[streamName].settings.keys.indexOf(key);if(idx>-1)this.streamSettings[streamName].settings.keys.splice(idx,1);if(this.streamSettings[streamName].settings[key])delete this.streamSettings[streamName].settings[key];return true}return false};updateStreamData=(streamName,data={})=>{if(this.streamSettings[streamName]){Object.assign(this.streamSettings[streamName].object,data);return this.streamSettings[streamName].object}return false};getStreamUpdate=streamName=>{if(!this.streamSettings[streamName])return;let streamUpdate={};this.streamSettings[streamName].settings.keys.forEach(key=>{if(this.streamSettings[streamName].settings[key]){let data=this.streamSettings[streamName].settings[key].callback(this.streamSettings[streamName].object[key],this.streamSettings[streamName].settings[key]);if(data!==void 0)streamUpdate[key]=data}});this.setState({[streamName]:streamUpdate});return streamUpdate};getAllStreamUpdates=()=>{let updateObj={};for(const streamName in this.streamSettings){let streamUpdate=this.getStreamUpdate(streamName);Object.assign(updateObj,streamUpdate)}return updateObj};streamLoop={__operator:this.getAllStreamUpdates,__node:{loop:10}}};var Router=class extends Service{name="router";connections={};sources={};services={};serviceConnections={};users={};userTimeout=1e4;order;constructor(options){super(options);this.load(this);if(options){if(options.order)this.order=options.order;if(options.timeout)this.userTimeout=options.timeout;if(options.graph){for(const key in options.graph){let opt=options.graph[key];if(typeof opt==="function")opt=new opt;if(opt?.__node?.nodes){opt.name=key;opt.__node.tag=key;this.addServices({[opt.name]:opt});this.routeService(opt,opt.connections)}else{if(typeof opt?.service==="function")opt.service=new opt.service;if(opt?.service?.__node?.nodes){opt.service.name=key;opt.service.__node.tag=key;this.addServices({[opt.service.name]:opt.service});this.routeService(opt.service)}if(typeof opt?.service==="object"){if(opt.connections){if(Array.isArray(opt.connections)){opt.connections.forEach(k=>{this.addServiceConnections(opt[key].service,k)})}else this.addServiceConnections(opt.service,opt.connections)}if(opt.config){for(const c in opt.config){this.openConnection(opt.service,opt.config[c],opt.config[c].source,opt.config[c].args)}}}}}}}}addUser=async(info,connections,config,receiving)=>{let user;if(!info._id){info._id=`user${Math.floor(Math.random()*1e15)}`}if(this.users[info._id]){user=this.users[info._id]}else{user=Object.assign({},info)}if(connections){for(const key in connections){if(typeof connections[key]==="object"){if(!connections[key].connection._id){await new Promise((res,rej)=>{let start=performance.now();let checker=()=>{if(!connections[key].connection._id){if(performance.now()-start>this.userTimeout){delete connections[key];rej(false)}else{setTimeout(()=>{checker()},100)}}else{res(true)}};checker()}).catch(er=>{console.error("Connections timed out:",er)})}}}for(const key in connections){connections[key]=this.addConnection(connections[key],user._id)}}if(config){for(const c in config){this.openConnection(config[c].service,config[c],user._id,config[c].args)}}if(!this.users[info._id]){let send=(message,...a)=>{let connection=this.getConnection(user._id,"send");if(connection?.send)return connection.send(message,...a)};let sendAll=(message,...a)=>{let connections2=this.getConnections(user._id,"send");for(const key in connections2)if(connections2[key]?.send)return connections2[key].send(message,...a)};let request=(message,method,...a)=>{let connection=this.getConnection(user._id,"request");if(connection?.request)return connection.request(message,method,...a)};let requestAll=(message,method,...a)=>{let connections2=this.getConnections(user._id,"request");let results=[];for(const key in connections2)if(connections2[key]?.request)results.push(connections2[key].request(message,method,...a));return Promise.all(results)};let post=(route,args,method,...a)=>{let connection=this.getConnection(user._id,"post");if(connection?.post)return connection.post(route,args,method,...a)};let postAll=(route,args,method,...a)=>{let connections2=this.getConnections(user._id,"post");for(const key in connections2)if(connections2[key]?.post)connections2[key].post(route,args,method,...a)};let run=(route,args,method,...a)=>{let connection=this.getConnection(user._id,"run");if(connection?.run)return connection.run(route,args,method,...a)};let runAll=(route,args,method,...a)=>{let connections2=this.getConnections(user._id,"run");let results=[];for(const key in connections2)if(connections2[key]?.run)results.push(connections2[key].run(route,args,method,...a));return Promise.all(results)};let subscribe=(route,callback,...a)=>{let connection=this.getConnection(user._id,"subscribe");if(connection?.subscribe)return connection.subscribe(route,callback,...a)};let subscribeAll=(route,callback,...a)=>{let connections2=this.getConnections(user._id,"subscribe");let results=[];for(const key in connections2)if(connections2[key]?.post)results.push(connections2[key].subscribe(route,callback,...a));return Promise.all(results)};let unsubscribe=(route,sub,...a)=>{let connection=this.getConnection(user._id,"unsubscribe");if(connection?.unsubscribe)return connection.unsubscribe(route,sub,...a)};let unsubscribeAll=(route,subs,...a)=>{let connections2=this.getConnections(user._id,"unsubscribe");let results=[];for(const key in connections2)if(connections2[key]?.post&&subs[key])results.push(connections2[key].unsubscribe(route,subs[key],...a));return Promise.all(results)};let terminate=()=>{return this.removeUser(user)};user.send=send;user.request=request;user.post=post;user.run=run;user.subscribe=subscribe;user.unsubscribe=unsubscribe;user.terminate=terminate;user.sendAll=sendAll;user.requestAll=requestAll;user.postAll=postAll;user.runAll=runAll;user.subscribeAll=subscribeAll;user.unsubscribeAll=unsubscribeAll;user.terminateAll=terminate;this.users[user._id]=user}if(connections&&!receiving){let connectionIds={};let pass=false;Object.keys(connections).map((k,i2)=>{if(connections[k]?._id){connectionIds[`${i2}`]=connections[k]?._id;pass=true}});if(pass){user.send({route:"addUser",args:[{_id:user._id},connectionIds,void 0,true]})}}return user};removeUser(profile,terminate){if(terminate)this.removeConnection(profile,terminate);if(typeof profile==="string")profile=this.users[profile];if(typeof profile==="object"&&profile._id){delete this.users[profile._id];if(profile.onclose)profile.onclose(profile)}return true}getConnection=(sourceId,hasMethod,connectionId)=>{if(this.connections[sourceId]){return this.connections[sourceId]}else if(this.sources[sourceId]){if(hasMethod?.includes("All"))return this.users[sourceId];if(connectionId){if(hasMethod){if(this.sources[sourceId][connectionId]?.[hasMethod])return this.sources[sourceId][connectionId]}else if(this.sources[sourceId][connectionId])return this.sources[sourceId][connectionId];else return void 0}else if(this.order){for(let i2=0;i2{if(this.sources[sourceId]){if(!props&&!hasMethod)return this.sources[sourceId];let found={};for(const key in this.sources[sourceId]){if(typeof this.sources[sourceId][key]==="object"){if(!this.sources[sourceId][key]._id){for(const k in this.sources[sourceId][key]){if(typeof this.sources[sourceId][key][k]==="object"){let pass=true;if(hasMethod&&!this.sources[sourceId][key][k][hasMethod])pass=false;if(props){for(const p in props){if(typeof this.sources[sourceId][key][k][p]==="object"&&typeof props[p]==="object"){for(const pp in props[p]){if(props[p][pp]!==this.sources[sourceId][key][k][p][pp]){pass=false;break}}}else if(this.sources[sourceId][key][k][p]!==props[p]){pass=false}else{pass=false;break}}}if(pass){found[this.sources[sourceId][key][k]._id]=this.sources[sourceId][key][k]}}}}else{let pass=true;if(hasMethod&&!this.sources[sourceId][key][hasMethod])pass=false;if(props){for(const p in props){if(typeof this.sources[sourceId][key][p]==="object"&&typeof props[p]==="object"){for(const pp in props[p]){if(props[p][pp]!==this.sources[sourceId][key][p][pp]){pass=false;break}}}else if(this.sources[sourceId][key][p]!==props[p]){pass=false}else{pass=false;break}}}if(pass){found[this.sources[sourceId][key]._id]=this.sources[sourceId][key]}}}}return found}};runConnection=async(userId,method,args,connectionId)=>{let sendTo;if(method.indexOf("All")>-1){sendTo=this.users[userId]}else{sendTo=this.getConnection(userId,method,connectionId)}if(sendTo){let res=sendTo[method](...args);res=await res;return res}};subscribeThroughConnection=(route,remoteRelay,remoteEndpoint,callback,...args)=>{if(typeof remoteRelay==="string"){remoteRelay=this.getConnection(remoteRelay,"run")}if(typeof remoteRelay==="object")return new Promise((res,rej)=>{remoteRelay.run("routeConnections",[route,remoteEndpoint,remoteRelay._id,...args]).then(sub=>{this.__node.state.subscribeEvent(remoteEndpoint,res2=>{if(res2?.callbackId===route){if(!callback)this.setState({[remoteEndpoint]:res2.args});else if(typeof callback==="string"){this.setState({[callback]:res2.args})}else callback(res2.args)}});res(sub)}).catch(rej)})};addConnection=(options,source,autoRemove=true)=>{let settings={};if(typeof options==="string"){if(this.connections[options]){options=this.connections[options]}else{for(const j in this.serviceConnections){for(const k in this.serviceConnections[j]){if(this.serviceConnections[j][k][options]){options={connection:this.serviceConnections[j][k][options]};options.service=j;settings.connectionType=j;settings.connectionsKey=k;break}}}}if(typeof options==="string"&&this.__node.nodes.get(options))options={connection:this.__node.nodes.get(options)}}if(!options||typeof options==="string")return void 0;if(source)settings.source=source;if(options.connection instanceof GraphNode){settings.connection=options.connection;let node=settings.connection;settings.send=async message=>{if(message.method){if(Array.isArray(message.args)){return node[message.method]?.(...message.args)}else return node[message.method]?.(message.args)}else{if(!node.__operator)return;if(Array.isArray(message.args)){return node.__operator(...message.args)}else return node.__operator(message.args)}};settings.request=async(message,method)=>{if(method){if(Array.isArray(message.args)){return node[method]?.(...message.args)}else return node[method]?.(message.args)}else{if(!node.__operator)return;if(Array.isArray(message.args)){return node.__operator(...message.args)}else return node.__operator(message.args)}};settings.post=async(route,args,method)=>{if(route&&node.__node.graph.get(route)){let n=node.__node.graph.get(route);if(method){if(Array.isArray(args)){return n[method]?.(...args)}else return n[method]?.(args)}else{if(Array.isArray(args)){return n.__operator(...args)}else return n.__operator(args)}}else{if(method){if(Array.isArray(args)){return node[method]?.(...args)}else return node[method]?.(args)}else{if(Array.isArray(args)){return node.__operator(...args)}else return node.__operator(args)}}};settings.run=settings.post;settings.subscribe=async callback=>{return node.__subscribe(callback)};settings.unsubscribe=async sub=>{return node.__unsubscribe(sub)};settings.terminate=()=>{node.__node.graph.remove(node);return true};settings.onclose=options.onclose;if(settings.onclose){node.__addOndisconnected(n=>{if(settings.onclose)settings.onclose(settings,n)})}}else if(options.connection instanceof Graph){if(options.connection.__node.nodes.get("open"))settings.service=options.connection;let graph=settings.connection;settings.send=async message=>{if(Array.isArray(message.args))graph.run(message.route,...message.args);else graph.run(message.route,message.args)};settings.request=async(message,method)=>{if(!message.route)return void 0;if(method){if(Array.isArray(message.args)){return graph.__node.nodes.get(message.route)[method]?.(...message.args)}else return graph.__node.nodes.get(message.route)[method]?.(message.args)}else{if(Array.isArray(message.args)){return graph.run(message.route,...message.args)}else return graph.run(message.route,message.args)}};settings.post=async(route,args,method)=>{if(route&&graph.get(route)){let n=graph.get(route);if(method){if(Array.isArray(args)){return n[method]?.(...args)}else return n[method]?.(args)}else{if(Array.isArray(args)){return n.run(...args)}else return n.run(args)}}};settings.run=settings.post;settings.subscribe=async(route,callback)=>{return graph.subscribe(route,callback)};settings.unsubscribe=async(route,sub)=>{return graph.unsubscribe(route,sub)};settings.terminate=n=>{graph.remove(n);return true}}else if(!(options._id&&this.connections[options._id])){let c=options.connection;if(typeof c==="string"){if(this.connections[c])c=this.connections[c];else if(options.service){if(typeof options.service==="string"){options.service=this.services[options.service]}if(typeof options.service==="object"){if(options.service.connections){for(const key in options.service.connections){if(options.service.connections[key][c]){c=options.service.connections[key][c];settings.connectionType=key;settings.connectionsKey=c;break}}}}}else{for(const j in this.serviceConnections){for(const k in this.serviceConnections[j]){if(this.serviceConnections[j][k][c]){c=this.serviceConnections[j][k][c];options.service=j;settings.connectionType=j;settings.connectionsKey=k;break}}}}}if(typeof c!=="object")return void 0;settings._id=c._id;settings.connection=options.connection;settings.send=c.send;settings.request=c.request;settings.run=c.run;settings.post=c.post;settings.subscribe=c.subscribe;settings.unsubscribe=c.unsubscribe;settings.terminate=c.terminate;settings.onclose=options.onclose;if(settings.onclose){if(!(c.onclose&&settings.onclose.toString()===c.onclose.toString())){let oldonclose=c.onclose;c.onclose=(...args)=>{if(settings.onclose)settings.onclose(settings,...args);if(autoRemove&&settings.source&&this.users[settings.source]&&Object.keys(this.sources[settings.source]).length===0){this.removeUser(settings.source,false)}if(oldonclose)oldonclose(...args)}}}else{let oldonclose=c.onclose;c.onclose=(...args)=>{this.removeConnection(settings);if(autoRemove&&settings.source&&this.users[settings.source]&&Object.keys(this.sources[settings.source]).length===0){this.removeUser(settings.source,false)}if(oldonclose)oldonclose(...args)}}if(options.service){if(typeof options.service==="string")options.service=this.services[options.service];settings.service=options.service}else if(c.graph)settings.service=c.graph}if(!settings.source&&options.source){settings.source=options.source}else if(!settings.source&&options.service){settings.source=typeof options.service==="object"?options.service?.name:void 0}else if(!settings.source&&(settings.connection instanceof GraphNode||settings.connection instanceof Graph)){settings.source="local";if(!this.order.indexOf("local"))this.order.unshift("local")}if(!settings._id)settings._id=`connection${Math.floor(Math.random()*1e15)}`;if(settings.source){if(!this.sources[settings.source])this.sources[settings.source]={};this.sources[settings.source][settings._id]=settings}if(!this.connections[settings._id])this.connections[settings._id]=settings;return settings};removeConnection=(connection,terminate=false)=>{if(typeof connection==="object"&&connection._id)connection=connection._id;if(typeof connection==="string"){if(this.connections[connection]){if(terminate&&this.connections[connection])this.connections[connection].terminate();delete this.connections[connection];for(const key in this.sources){if(this.sources[key][connection])delete this.sources[key][connection];else{for(const k in this.sources[key]){if(this.sources[key][k]?.[connection]){delete this.sources[key][connection]}}}}return true}else if(this.sources[connection]){for(const key in this.sources[connection]){this.removeConnection(this.sources[connection][key],terminate)}return true}}};routeService=(service,connections,source,order)=>{this.services[service.name]=service;if(service.__node?.nodes)this.__node.nodes.forEach((n,k)=>{if(!service.__node?.nodes.get(k)){service.__node?.nodes.set(k,n)}else service.__node?.nodes.set(this.name+"."+k,n)});if(service.users)service.users=this.users;if(connections){if(typeof connections==="string")this.addServiceConnections(service,connections,source);else{for(const c in connections){this.addServiceConnections(service,c,source)}}}if(order)this.order=order;else{if(!this.order)this.order=[];this.order.push(service.name)}};addServiceConnections=(service,connectionsKey,source)=>{if(typeof service==="string"){service=this.services[service]}if(connectionsKey&&service[connectionsKey]){let newConnections={};if(!this.serviceConnections[service.name])this.serviceConnections[service.name]={};this.serviceConnections[service.name][connectionsKey]=service[connectionsKey];for(const key in service[connectionsKey]){if(!this.connections[key]){newConnections[key]=this.addConnection({connection:service[connectionsKey][key],service},source);newConnections[key].connectionType=connectionsKey}}return newConnections}};openConnection=async(service,options,source,...args)=>{if(typeof service==="string"){service=this.services[service]}if(service?.__node.nodes){let connection=service.run("open",options,...args);if(connection instanceof Promise){return connection.then(async info=>{if(!info._id){await connectionHasId(info,this.userTimeout)}if(info._id)this.addConnection({connection:info,service},source)})}else if(connection){if(!connection._id){await connectionHasId(connection,this.userTimeout)}if(connection._id)return this.addConnection({connection,service},source)}}};terminate=connection=>{if(typeof connection==="string")connection=this.connections[connection];return connection.terminate()};routeConnections=(route,transmitter,receiver,...args)=>{let rxsrc;if(typeof receiver==="string"){if(this.sources[receiver]){rxsrc=receiver}receiver=this.getConnection(receiver,"send")}if(typeof transmitter==="string"){transmitter=this.getConnection(transmitter,"subscribe")}if(transmitter?.subscribe&&receiver?.send){let res=new Promise((res2,rej)=>{transmitter.subscribe(route,res3=>{if(!this.connections[receiver._id]&&rxsrc){if(this.sources[rxsrc]){rxsrc=receiver;Object.keys(this.sources[rxsrc]).forEach(k=>{if(this.sources[receiver][k].send){receiver=this.sources[receiver][k]}})}}if(this.connections[receiver._id])receiver.send({callbackId:route,args:res3})},...args).then(sub=>{res2(sub)})});return res}};setUserData=(user,data)=>{if(user){if(typeof user==="string"){user=this.users[user];if(!user)return false}}if(data){if(typeof data==="string"){data=JSON.parse(data)}}if(typeof data==="object"){this.recursivelyAssign(user,data);return true}}};function connectionHasId(connection,timeout=1e4){return new Promise((res,rej)=>{let start=performance.now();let checker=()=>{if(!connection._id){if(performance.now()-start>timeout){rej(false)}else{setTimeout(()=>{checker()},100)}}else{res(true)}};checker()}).catch(er=>{console.error("Connection timed out:",er)})}export{Callable,DOMElement,E2EEService,ECSService,ElementProxyReceiver,EventDispatcher,EventHandler,Graph,GraphNode,HTTPfrontend,ProxyManager,Renderer,Router,SSEfrontend,Service,SessionsService,WSSfrontend,WebRTCfrontend,WorkerService,addCustomElement,animate,backprop,bindListener,branching,clearCanvas,connectionHasId,drawFrame,eventHandlers,getAllProperties,getCallbackFromString,getCanvas,getFnParamNames,getFunctionHead,html,htmlloader,initCanvas,initProxyElement,instanceObject,isFunction,isNativeClass,isTypedArray,loaders,loop,methodstrings,nodeTemplates,parseFunctionFromText,proxyElementWorkerRoutes,reconstructObject,recursivelyAssign2 as recursivelyAssign,recursivelyStringifyFunctions,remoteGraphRoutes,setDraw,setProps,setupCanvas,spliceTypedArray,startAnim,state,stopAnim,stringifyFast,stringifyWithCircularRefs,stringifyWithFunctionsAndCircularRefs,substitute__operator,transferCanvas,transformListenerResult,triggerListenerOncreate,updateCanvas,wchtmlloader,workerCanvasRoutes,wrapArgs,xml}; +var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf;var __hasOwnProp=Object.prototype.hasOwnProperty;var __defNormalProp=(obj,key,value)=>key in obj?__defProp(obj,key,{enumerable:true,configurable:true,writable:true,value}):obj[key]=value;var __require=(x=>typeof require!=="undefined"?require:typeof Proxy!=="undefined"?new Proxy(x,{get:(a,b)=>(typeof require!=="undefined"?require:a)[b]}):x)(function(x){if(typeof require!=="undefined")return require.apply(this,arguments);throw new Error('Dynamic require of "'+x+'" is not supported')});var __commonJS=(cb,mod)=>function __require2(){return mod||(0,cb[__getOwnPropNames(cb)[0]])((mod={exports:{}}).exports,mod),mod.exports};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from==="object"||typeof from==="function"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:true}):target,mod));var __publicField=(obj,key,value)=>{__defNormalProp(obj,typeof key!=="symbol"?key+"":key,value);return value};var require_sjcl=__commonJS({"services/e2ee/sjcl.js"(exports,module){"use strict";var sjcl2={cipher:{},hash:{},keyexchange:{},mode:{},misc:{},codec:{},exception:{corrupt:function(a){this.toString=function(){return"CORRUPT: "+this.message};this.message=a},invalid:function(a){this.toString=function(){return"INVALID: "+this.message};this.message=a},bug:function(a){this.toString=function(){return"BUG: "+this.message};this.message=a},notReady:function(a){this.toString=function(){return"NOT READY: "+this.message};this.message=a}}};sjcl2.cipher.aes=function(a){this.s[0][0][0]||this.O();var b,c,d,e,f=this.s[0][4],g=this.s[1];b=a.length;var h=1;if(4!==b&&6!==b&&8!==b)throw new sjcl2.exception.invalid("invalid aes key size");this.b=[d=a.slice(0),e=[]];for(a=b;a<4*b+28;a++){c=d[a-1];if(0===a%b||8===b&&4===a%b)c=f[c>>>24]<<24^f[c>>16&255]<<16^f[c>>8&255]<<8^f[c&255],0===a%b&&(c=c<<8^c>>>24^h<<24,h=h<<1^283*(h>>7));d[a]=d[a-b]^c}for(b=0;a;b++,a--)c=d[b&3?a:a-4],e[b]=4>=a||4>b?c:g[0][f[c>>>24]]^g[1][f[c>>16&255]]^g[2][f[c>>8&255]]^g[3][f[c&255]]};sjcl2.cipher.aes.prototype={encrypt:function(a){return t(this,a,0)},decrypt:function(a){return t(this,a,1)},s:[[[],[],[],[],[]],[[],[],[],[],[]]],O:function(){var a=this.s[0],b=this.s[1],c=a[4],d=b[4],e,f,g,h=[],k=[],l,n,m,p;for(e=0;256>e;e++)k[(h[e]=e<<1^283*(e>>7))^e]=e;for(f=g=0;!c[f];f^=l||1,g=k[g]||1)for(m=g^g<<1^g<<2^g<<3^g<<4,m=m>>8^m&255^99,c[f]=m,d[m]=f,n=h[e=h[l=h[f]]],p=16843009*n^65537*e^257*l^16843008*f,n=257*h[m]^16843008*m,e=0;4>e;e++)a[e][f]=n=n<<24^n>>>8,b[e][m]=p=p<<24^p>>>8;for(e=0;5>e;e++)a[e]=a[e].slice(0),b[e]=b[e].slice(0)}};function t(a,b,c){if(4!==b.length)throw new sjcl2.exception.invalid("invalid aes block size");var d=a.b[c],e=b[0]^d[0],f=b[c?3:1]^d[1],g=b[2]^d[2];b=b[c?1:3]^d[3];var h,k,l,n=d.length/4-2,m,p=4,r=[0,0,0,0];h=a.s[c];a=h[0];var q=h[1],v=h[2],w=h[3],x=h[4];for(m=0;m>>24]^q[f>>16&255]^v[g>>8&255]^w[b&255]^d[p],k=a[f>>>24]^q[g>>16&255]^v[b>>8&255]^w[e&255]^d[p+1],l=a[g>>>24]^q[b>>16&255]^v[e>>8&255]^w[f&255]^d[p+2],b=a[b>>>24]^q[e>>16&255]^v[f>>8&255]^w[g&255]^d[p+3],p+=4,e=h,f=k,g=l;for(m=0;4>m;m++)r[c?3&-m:m]=x[e>>>24]<<24^x[f>>16&255]<<16^x[g>>8&255]<<8^x[b&255]^d[p++],h=e,e=f,f=g,g=b,b=h;return r}sjcl2.bitArray={bitSlice:function(a,b,c){a=sjcl2.bitArray.$(a.slice(b/32),32-(b&31)).slice(1);return void 0===c?a:sjcl2.bitArray.clamp(a,c-b)},extract:function(a,b,c){var d=Math.floor(-b-c&31);return((b+c-1^b)&-32?a[b/32|0]<<32-d^a[b/32+1|0]>>>d:a[b/32|0]>>>d)&(1<>b-1,1));return a},partial:function(a,b,c){return 32===a?b:(c?b|0:b<<32-a)+1099511627776*a},getPartial:function(a){return Math.round(a/1099511627776)||32},equal:function(a,b){if(sjcl2.bitArray.bitLength(a)!==sjcl2.bitArray.bitLength(b))return false;var c=0,d;for(d=0;d>>b),c=a[e]<<32-b;e=a.length?a[a.length-1]:0;a=sjcl2.bitArray.getPartial(e);d.push(sjcl2.bitArray.partial(b+a&31,32>>24|c>>>8&65280|(c&65280)<<8|c<<24;return a}};sjcl2.codec.utf8String={fromBits:function(a){var b="",c=sjcl2.bitArray.bitLength(a),d,e;for(d=0;d>>8>>>8>>>8),e<<=8;return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,d=0;for(c=0;c>>g)>>>e),gn){if(!b)try{return sjcl2.codec.base32hex.toBits(a)}catch(p){}throw new sjcl2.exception.invalid("this isn't "+m+"!")}h>e?(h-=e,f.push(l^n>>>h),l=n<>>e)>>>26),6>e?(g=a[c]<<6-e,e+=26,c++):(g<<=6,e-=6);for(;d.length&3&&!b;)d+="=";return d},toBits:function(a,b){a=a.replace(/\s|=/g,"");var c=[],d,e=0,f=sjcl2.codec.base64.B,g=0,h;b&&(f=f.substr(0,62)+"-_");for(d=0;dh)throw new sjcl2.exception.invalid("this isn't base64!");26>>e),g=h<<32-e):(e+=6,g^=h<<32-e)}e&56&&c.push(sjcl2.bitArray.partial(e&56,g,1));return c}};sjcl2.codec.base64url={fromBits:function(a){return sjcl2.codec.base64.fromBits(a,1,1)},toBits:function(a){return sjcl2.codec.base64.toBits(a,1)}};sjcl2.hash.sha256=function(a){this.b[0]||this.O();a?(this.F=a.F.slice(0),this.A=a.A.slice(0),this.l=a.l):this.reset()};sjcl2.hash.sha256.hash=function(a){return new sjcl2.hash.sha256().update(a).finalize()};sjcl2.hash.sha256.prototype={blockSize:512,reset:function(){this.F=this.Y.slice(0);this.A=[];this.l=0;return this},update:function(a){"string"===typeof a&&(a=sjcl2.codec.utf8String.toBits(a));var b,c=this.A=sjcl2.bitArray.concat(this.A,a);b=this.l;a=this.l=b+sjcl2.bitArray.bitLength(a);if(9007199254740991b;c++){e=true;for(d=2;d*d<=c;d++)if(0===c%d){e=false;break}e&&(8>b&&(this.Y[b]=a(Math.pow(c,.5))),this.b[b]=a(Math.pow(c,1/3)),b++)}}};function u(a,b){var c,d,e,f=a.F,g=a.b,h=f[0],k=f[1],l=f[2],n=f[3],m=f[4],p=f[5],r=f[6],q=f[7];for(c=0;64>c;c++)16>c?d=b[c]:(d=b[c+1&15],e=b[c+14&15],d=b[c&15]=(d>>>7^d>>>18^d>>>3^d<<25^d<<14)+(e>>>17^e>>>19^e>>>10^e<<15^e<<13)+b[c&15]+b[c+9&15]|0),d=d+q+(m>>>6^m>>>11^m>>>25^m<<26^m<<21^m<<7)+(r^m&(p^r))+g[c],q=r,r=p,p=m,m=n+d|0,n=l,l=k,k=h,h=d+(k&l^n&(k^l))+(k>>>2^k>>>13^k>>>22^k<<30^k<<19^k<<10)|0;f[0]=f[0]+h|0;f[1]=f[1]+k|0;f[2]=f[2]+l|0;f[3]=f[3]+n|0;f[4]=f[4]+m|0;f[5]=f[5]+p|0;f[6]=f[6]+r|0;f[7]=f[7]+q|0}sjcl2.mode.ccm={name:"ccm",G:[],listenProgress:function(a){sjcl2.mode.ccm.G.push(a)},unListenProgress:function(a){a=sjcl2.mode.ccm.G.indexOf(a);-1k)throw new sjcl2.exception.invalid("ccm: iv must be at least 7 bytes");for(f=2;4>f&&l>>>8*f;f++);f<15-k&&(f=15-k);c=h.clamp(c,8*(15-f));b=sjcl2.mode.ccm.V(a,b,c,d,e,f);g=sjcl2.mode.ccm.C(a,g,c,b,e,f);return h.concat(g.data,g.tag)},decrypt:function(a,b,c,d,e){e=e||64;d=d||[];var f=sjcl2.bitArray,g=f.bitLength(c)/8,h=f.bitLength(b),k=f.clamp(b,h-e),l=f.bitSlice(b,h-e),h=(h-e)/8;if(7>g)throw new sjcl2.exception.invalid("ccm: iv must be at least 7 bytes");for(b=2;4>b&&h>>>8*b;b++);b<15-g&&(b=15-g);c=f.clamp(c,8*(15-b));k=sjcl2.mode.ccm.C(a,k,c,l,e,b);a=sjcl2.mode.ccm.V(a,k.data,c,d,e,b);if(!f.equal(k.tag,a))throw new sjcl2.exception.corrupt("ccm: tag doesn't match");return k.data},na:function(a,b,c,d,e,f){var g=[],h=sjcl2.bitArray,k=h.i;d=[h.partial(8,(b.length?64:0)|d-2<<2|f-1)];d=h.concat(d,c);d[3]|=e;d=a.encrypt(d);if(b.length)for(c=h.bitLength(b)/8,65279>=c?g=[h.partial(16,c)]:4294967295>=c&&(g=h.concat([h.partial(16,65534)],[c])),g=h.concat(g,b),b=0;be||16n&&(sjcl2.mode.ccm.fa(g/k),n+=m),c[3]++,e=a.encrypt(c),b[g]^=e[0],b[g+1]^=e[1],b[g+2]^=e[2],b[g+3]^=e[3];return{tag:d,data:h.clamp(b,l)}}};sjcl2.mode.ocb2={name:"ocb2",encrypt:function(a,b,c,d,e,f){if(128!==sjcl2.bitArray.bitLength(c))throw new sjcl2.exception.invalid("ocb iv must be 128 bits");var g,h=sjcl2.mode.ocb2.S,k=sjcl2.bitArray,l=k.i,n=[0,0,0,0];c=h(a.encrypt(c));var m,p=[];d=d||[];e=e||64;for(g=0;g+4e.bitLength(c)&&(h=f(h,d(h)),c=e.concat(c,[-2147483648,0,0,0]));g=f(g,c);return a.encrypt(f(d(f(h,d(h))),g))},S:function(a){return[a[0]<<1^a[1]>>>31,a[1]<<1^a[2]>>>31,a[2]<<1^a[3]>>>31,a[3]<<1^135*(a[0]>>>31)]}};sjcl2.mode.gcm={name:"gcm",encrypt:function(a,b,c,d,e){var f=b.slice(0);b=sjcl2.bitArray;d=d||[];a=sjcl2.mode.gcm.C(true,a,f,d,c,e||128);return b.concat(a.data,a.tag)},decrypt:function(a,b,c,d,e){var f=b.slice(0),g=sjcl2.bitArray,h=g.bitLength(f);e=e||128;d=d||[];e<=h?(b=g.bitSlice(f,h-e),f=g.bitSlice(f,0,h-e)):(b=f,f=[]);a=sjcl2.mode.gcm.C(false,a,f,d,c,e);if(!g.equal(a.tag,b))throw new sjcl2.exception.corrupt("gcm: tag doesn't match");return a.data},ka:function(a,b){var c,d,e,f,g,h=sjcl2.bitArray.i;e=[0,0,0,0];f=b.slice(0);for(c=0;128>c;c++){(d=0!==(a[Math.floor(c/32)]&1<<31-c%32))&&(e=h(e,f));g=0!==(f[3]&1);for(d=3;0>>1|(f[d-1]&1)<<31;f[0]>>>=1;g&&(f[0]^=-520093696)}return e},j:function(a,b,c){var d,e=c.length;b=b.slice(0);for(d=0;de&&(a=b.hash(a));for(d=0;dd||0>c)throw new sjcl2.exception.invalid("invalid params to pbkdf2");"string"===typeof a&&(a=sjcl2.codec.utf8String.toBits(a));"string"===typeof b&&(b=sjcl2.codec.utf8String.toBits(b));e=e||sjcl2.misc.hmac;a=new e(a);var f,g,h,k,l=[],n=sjcl2.bitArray;for(k=1;32*l.length<(d||1);k++){e=f=a.encrypt(n.concat(b,[k]));for(g=1;gg;g++)e.push(4294967296*Math.random()|0);for(g=0;g=1<this.o&&(this.o=f);this.P++;this.b=sjcl2.hash.sha256.hash(this.b.concat(e));this.L=new sjcl2.cipher.aes(this.b);for(d=0;4>d&&(this.h[d]=this.h[d]+1|0,!this.h[d]);d++);}for(d=0;d>>1;this.c[g].update([d,this.N++,2,b,f,a.length].concat(a))}break;case"string":void 0===b&&(b=a.length);this.c[g].update([d,this.N++,3,b,f,a.length]);this.c[g].update(a);break;default:k=1}if(k)throw new sjcl2.exception.bug("random: addEntropy only supports number, array of numbers or string");this.m[g]+=b;this.f+=b;h===this.u&&(this.isReady()!==this.u&&A("seeded",Math.max(this.o,this.f)),A("progress",this.getProgress()))},isReady:function(a){a=this.T[void 0!==a?a:this.M];return this.o&&this.o>=a?this.m[0]>this.ba&&new Date().valueOf()>this.Z?this.J|this.I:this.I:this.f>=a?this.J|this.u:this.u},getProgress:function(a){a=this.T[a?a:this.M];return this.o>=a?1:this.f>a?1:this.f/a},startCollectors:function(){if(!this.D){this.a={loadTimeCollector:B(this,this.ma),mouseCollector:B(this,this.oa),keyboardCollector:B(this,this.la),accelerometerCollector:B(this,this.ea),touchCollector:B(this,this.qa)};if(window.addEventListener)window.addEventListener("load",this.a.loadTimeCollector,false),window.addEventListener("mousemove",this.a.mouseCollector,false),window.addEventListener("keypress",this.a.keyboardCollector,false),window.addEventListener("devicemotion",this.a.accelerometerCollector,false),window.addEventListener("touchmove",this.a.touchCollector,false);else if(document.attachEvent)document.attachEvent("onload",this.a.loadTimeCollector),document.attachEvent("onmousemove",this.a.mouseCollector),document.attachEvent("keypress",this.a.keyboardCollector);else throw new sjcl2.exception.bug("can't attach event");this.D=true}},stopCollectors:function(){this.D&&(window.removeEventListener?(window.removeEventListener("load",this.a.loadTimeCollector,false),window.removeEventListener("mousemove",this.a.mouseCollector,false),window.removeEventListener("keypress",this.a.keyboardCollector,false),window.removeEventListener("devicemotion",this.a.accelerometerCollector,false),window.removeEventListener("touchmove",this.a.touchCollector,false)):document.detachEvent&&(document.detachEvent("onload",this.a.loadTimeCollector),document.detachEvent("onmousemove",this.a.mouseCollector),document.detachEvent("keypress",this.a.keyboardCollector)),this.D=false)},addEventListener:function(a,b){this.K[a][this.ga++]=b},removeEventListener:function(a,b){var c,d,e=this.K[a],f=[];for(d in e)e.hasOwnProperty(d)&&e[d]===b&&f.push(d);for(c=0;cb&&(a.h[b]=a.h[b]+1|0,!a.h[b]);b++);return a.L.encrypt(a.h)}function B(a,b){return function(){b.apply(a,arguments)}}sjcl2.random=new sjcl2.prng(6);a:try{if(G="undefined"!==typeof module&&module.exports){try{H=__require("crypto")}catch(a){H=null}G=E=H}if(G&&E.randomBytes)D=E.randomBytes(128),D=new Uint32Array(new Uint8Array(D).buffer),sjcl2.random.addEntropy(D,1024,"crypto['randomBytes']");else if("undefined"!==typeof window&&"undefined"!==typeof Uint32Array){F=new Uint32Array(32);if(window.crypto&&window.crypto.getRandomValues)window.crypto.getRandomValues(F);else if(window.msCrypto&&window.msCrypto.getRandomValues)window.msCrypto.getRandomValues(F);else break a;sjcl2.random.addEntropy(F,1024,"crypto['getRandomValues']")}}catch(a){"undefined"!==typeof window&&window.console&&(console.log("There was an error collecting entropy from the browser:"),console.log(a))}var D;var E;var F;var G;var H;sjcl2.json={defaults:{v:1,iter:1e4,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},ja:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl2.json,f=e.g({iv:sjcl2.random.randomWords(4,0)},e.defaults),g;e.g(f,c);c=f.adata;"string"===typeof f.salt&&(f.salt=sjcl2.codec.base64.toBits(f.salt));"string"===typeof f.iv&&(f.iv=sjcl2.codec.base64.toBits(f.iv));if(!sjcl2.mode[f.mode]||!sjcl2.cipher[f.cipher]||"string"===typeof a&&100>=f.iter||64!==f.ts&&96!==f.ts&&128!==f.ts||128!==f.ks&&192!==f.ks&&256!==f.ks||2>f.iv.length||4=b.iter||64!==b.ts&&96!==b.ts&&128!==b.ts||128!==b.ks&&192!==b.ks&&256!==b.ks||!b.iv||2>b.iv.length||4{return methodString.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i,"$2$3$4")};let getFunctionHead=methodString=>{let startindex=methodString.indexOf("=>")+1;if(startindex<=0){startindex=methodString.indexOf("){")}if(startindex<=0){startindex=methodString.indexOf(") {")}return methodString.slice(0,methodString.indexOf("{",startindex)+1)};let newFuncHead=getFunctionHead(method);let newFuncBody=getFunctionBody(method);let newFunc;if(newFuncHead.includes("function")){let varName=newFuncHead.split("(")[1].split(")")[0];newFunc=new Function(varName,newFuncBody)}else{if(newFuncHead.substring(0,6)===newFuncBody.substring(0,6)){let varName=newFuncHead.split("(")[1].split(")")[0];newFunc=new Function(varName,newFuncBody.substring(newFuncBody.indexOf("{")+1,newFuncBody.length-1))}else{try{newFunc=(0,eval)(newFuncHead+newFuncBody+"}")}catch{}}}return newFunc}var EventHandler=class{constructor(){this.pushToState={};this.data={};this.triggers={};this.setState=updateObj=>{Object.assign(this.data,updateObj);for(const prop of Object.getOwnPropertyNames(updateObj)){if(this.triggers[prop])this.triggers[prop].forEach(obj=>obj.onchange(this.data[prop]))}return this.data};this.subscribeTrigger=(key,onchange)=>{if(key){if(!this.triggers[key]){this.triggers[key]=[]}let l=this.triggers[key].length;this.triggers[key].push({idx:l,onchange});return this.triggers[key].length-1}else return void 0};this.unsubscribeTrigger=(key,sub)=>{let triggers=this.triggers[key];if(triggers){if(!sub)delete this.triggers[key];else{let idx=void 0;let obj=triggers.find((o,i)=>{if(o.idx===sub){idx=i;return true}});if(obj)triggers.splice(idx,1);return true}}};this.subscribeTriggerOnce=(key,onchange)=>{let sub;let changed=value=>{onchange(value);this.unsubscribeTrigger(key,sub)};sub=this.subscribeTrigger(key,changed)}}};var state=new EventHandler;function addLocalState(props){if(!this._state)this._state={};for(let k in props){if(k==="_state"||k==="graph")continue;else{this._state[k]=props[k];if(k in this)this[k]=props[k];else Object.defineProperty(this,k,{get:()=>{this._state[k]},set:v=>{this._state[k]=v;if(this.state.triggers[this._unique])this.setState({[this._unique]:this._state})},enumerable:true,configurable:true})}}}var GraphNode=class{constructor(properties={},parent,graph){this.nodes=new Map;this._initial={};this._unique=`${Math.random()}`;this.state=state;this.isLooping=false;this.isAnimating=false;this.looper=void 0;this.animation=void 0;this.forward=true;this.backward=false;this.reactive=false;this.runSync=false;this.firstRun=true;this.DEBUGNODE=false;this.addLocalState=addLocalState;this.operator=(...args)=>{return args};this.runOp=(...args)=>{if(this.DEBUGNODE)console.time(this.tag);let result=this.operator(...args);if(result instanceof Promise){result.then(res=>{if(res!==void 0)this.setState({[this.tag]:res});if(this.DEBUGNODE){console.timeEnd(this.tag);if(result!==void 0)console.log(`${this.tag} result:`,result)};return res})}else{if(result!==void 0)this.setState({[this.tag]:result});if(this.DEBUGNODE){console.timeEnd(this.tag);if(result!==void 0)console.log(`${this.tag} result:`,result)};}return result};this.setOperator=operator=>{if(typeof operator!=="function")return operator;this.operator=operator.bind(this);return operator};this.runAsync=(...args)=>{return new Promise((res,rej)=>{res(this.run(...args))})};this.transformArgs=(args=[])=>args;this.isRunSync=()=>{return!(this.children&&this.forward||this.parent&&this.backward||this.repeat||this.delay||this.frame||this.recursive||this.branch)};this.run=(...args)=>{if(typeof this.transformArgs==="function")args=this.transformArgs(args,this);if(this.firstRun){this.firstRun=false;this.runSync=this.isRunSync();if(this.animate&&!this.isAnimating){this.runAnimation(this.animation,args)}if(this.loop&&typeof this.loop==="number"&&!this.isLooping){this.runLoop(this.looper,args)}if(this.loop||this.animate)return}if(this.runSync){let res=this.runOp(...args);return res}return new Promise(async resolve=>{if(this){let run=(node,tick=0,...input)=>{return new Promise(async r=>{tick++;let res=await node.runOp(...input);if(node.repeat){while(tick{r(await run(node,tick,...input))},node.delay);break}else if(node.frame&&window?.requestAnimationFrame){requestAnimationFrame(async()=>{r(await run(node,tick,...input))});break}else res=await node.runOp(...input);tick++}if(tick===node.repeat){r(res);return}}else if(node.recursive){while(tick{r(await run(node,tick,...res))},node.delay);break}else if(node.frame&&window?.requestAnimationFrame){requestAnimationFrame(async()=>{r(await run(node,tick,...res))});break}else res=await node.runOp(...res);tick++}if(tick===node.recursive){r(res);return}}else{r(res);return}})};let runnode=async()=>{let res=await run(this,void 0,...args);if(res!==void 0){if(this.backward&&this.parent instanceof GraphNode){if(Array.isArray(res))await this.runParent(this,...res);else await this.runParent(this,res)}if(this.children&&this.forward){if(Array.isArray(res))await this.runChildren(this,...res);else await this.runChildren(this,res)}if(this.branch){this.runBranch(this,res)}}return res};if(this.delay){setTimeout(async()=>{resolve(await runnode())},this.delay)}else if(this.frame&&window?.requestAnimationFrame){requestAnimationFrame(async()=>{resolve(await runnode())})}else{resolve(await runnode())}}else resolve(void 0)})};this.runParent=async(n,...args)=>{if(n.backward&&n.parent){if(typeof n.parent==="string"){if(n.graph&&n.graph?.get(n.parent)){n.parent=n.graph;if(n.parent)this.nodes.set(n.parent.tag,n.parent)}else n.parent=this.nodes.get(n.parent)}if(n.parent instanceof GraphNode)await n.parent.run(...args)}};this.runChildren=async(n,...args)=>{if(typeof n.children==="object"){for(const key in n.children){if(typeof n.children[key]==="string"){if(n.graph&&n.graph?.get(n.children[key])){n.children[key]=n.graph.get(n.children[key]);if(!n.nodes.get(n.children[key].tag))n.nodes.set(n.children[key].tag,n.children[key])}if(!n.children[key]&&n.nodes.get(n.children[key]))n.children[key]=n.nodes.get(n.children[key])}else if(typeof n.children[key]==="undefined"||n.children[key]===true){if(n.graph&&n.graph?.get(key)){n.children[key]=n.graph.get(key);if(!n.nodes.get(n.children[key].tag))n.nodes.set(n.children[key].tag,n.children[key])}if(!n.children[key]&&n.nodes.get(key))n.children[key]=n.nodes.get(key)}if(n.children[key]?.runOp)await n.children[key].run(...args)}}};this.runBranch=async(n,output)=>{if(n.branch){let keys=Object.keys(n.branch);await Promise.all(keys.map(async k=>{if(typeof n.branch[k].if==="object")n.branch[k].if=stringifyFast(n.branch[k].if);let pass=false;if(typeof n.branch[k].if==="function"){pass=n.branch[k].if(output)}else{if(typeof output==="object"){if(stringifyFast(output)===n.branch[k].if)pass=true}else if(output===n.branch[k].if)pass=true}if(pass){if(n.branch[k].then.run){if(Array.isArray(output))await n.branch[k].then.run(...output);else await n.branch[k].then.run(...output)}else if(typeof n.branch[k].then==="function"){if(Array.isArray(output))await n.branch[k].then(...output);else await n.branch[k].then(output)}else if(typeof n.branch[k].then==="string"){if(n.graph)n.branch[k].then=n.graph.nodes.get(n.branch[k].then);else n.branch[k].then=n.nodes.get(n.branch[k].then);if(n.branch[k].then.run){if(Array.isArray(output))await n.branch[k].then.run(...output);else await n.branch[k].then.run(...output)}}}return pass}))}};this.runAnimation=(animation=this.animation,args=[])=>{this.animation=animation;if(!animation)this.animation=this.operator;if(this.animate&&!this.isAnimating&&"requestAnimationFrame"in window){this.isAnimating=true;let anim=async()=>{if(this.isAnimating){if(this.DEBUGNODE)console.time(this.tag);let result=this.animation.call(this,...args);if(result instanceof Promise){result=await result}if(this.DEBUGNODE){console.timeEnd(this.tag);if(result!==void 0)console.log(`${this.tag} result:`,result)};if(result!==void 0){if(this.tag)this.setState({[this.tag]:result});if(this.backward&&this.parent?.run){if(Array.isArray(result))await this.runParent(this,...result);else await this.runParent(this,result)}if(this.children&&this.forward){if(Array.isArray(result))await this.runChildren(this,...result);else await this.runChildren(this,result)}if(this.branch){this.runBranch(this,result)}this.setState({[this.tag]:result})}requestAnimationFrame(anim)}};requestAnimationFrame(anim)}};this.runLoop=(loop=this.looper,args=[],timeout=this.loop)=>{this.looper=loop;if(!loop)this.looper=this.operator;if(typeof timeout==="number"&&!this.isLooping){this.isLooping=true;let looping=async()=>{if(this.isLooping){if(this.DEBUGNODE)console.time(this.tag);let result=this.looper.call(this,...args);if(result instanceof Promise){result=await result}if(this.DEBUGNODE){console.timeEnd(this.tag);if(result!==void 0)console.log(`${this.tag} result:`,result)};if(result!==void 0){if(this.tag)this.setState({[this.tag]:result});if(this.backward&&this.parent?.run){if(Array.isArray(result))await this.runParent(this,...result);else await this.runParent(this,result)}if(this.children&&this.forward){if(Array.isArray(result))await this.runChildren(this,...result);else await this.runChildren(this,result)}if(this.branch){this.runBranch(this,result)}this.setState({[this.tag]:result})}setTimeout(async()=>{await looping()},timeout)}};looping()}};this.setParent=parent=>{this.parent=parent;if(this.backward)this.runSync=false};this.setChildren=children=>{this.children=children;if(this.forward)this.runSync=false};this.add=(n={})=>{if(typeof n==="function")n={operator:n};if(n?.node instanceof GraphNode)n=n.node;if(!(n instanceof GraphNode))n=new GraphNode(n.node??n,this,this.graph);this.nodes.set(n.tag,n);if(this.graph){this.graph.nodes.set(n.tag,n);this.graph.nNodes=this.graph.nodes.size}return n};this.remove=n=>{if(typeof n==="string")n=this.nodes.get(n);if(n?.tag){this.nodes.delete(n.tag);if(this.children[n.tag])delete this.children[n.tag];if(this.graph){this.graph.nodes.delete(n.tag);this.graph.nNodes=this.graph.nodes.size}this.nodes.forEach(n2=>{if(n2.nodes.get(n2.tag)){n2.nodes.delete(n2.tag);if(n2.children[n2.tag])delete n2.children[n2.tag];if(n2.parent?.tag===n2.tag)delete n2.parent}});if(n.ondelete)n.ondelete(n)}if(typeof this._state==="object"){this.state.unsubscribeTrigger(this._unique)}};this.append=(n,parentNode=this)=>{if(typeof n==="string")n=this.nodes.get(n);if(n?.nodes){parentNode.addChildren(n);if(n.forward)n.runSync=false}};this.subscribe=(callback,tag=this.tag)=>{if(typeof callback==="string"){if(this.graph)callback=this.graph.get(callback);else callback=this.nodes.get(callback)}if(typeof callback==="function"){return this.state.subscribeTrigger(tag,callback)}else if(callback)return this.state.subscribeTrigger(tag,res=>{callback.run(res)})};this.unsubscribe=(sub,tag=this.tag)=>{return this.state.unsubscribeTrigger(tag,sub)};this.subscribeState=callback=>{if(!this.reactive){return void 0}else{if(typeof callback==="string"){if(this.graph)callback=this.graph.get(callback);else callback=this.nodes.get(callback)}if(typeof callback==="function"){return this.state.subscribeTrigger(this._unique,callback)}else if(callback)return this.state.subscribeTrigger(this._unique,_state=>{callback.run(_state)})}};this.addChildren=children=>{if(!this.children)this.children={};if(typeof children==="object"){Object.assign(this.children,children)}this.convertChildrenToNodes();if(this.forward)this.runSync=false};this.callParent=(...args)=>{if(typeof this.parent==="string"){if(this.graph&&this.graph?.get(this.parent)){this.parent=this.graph;if(this.parent)this.nodes.set(this.parent.tag,this.parent)}else this.parent=this.nodes.get(this.parent)}if(typeof this.parent?.operator==="function")return this.parent.runOp(...args)};this.callChildren=(...args)=>{let result;if(typeof this.children==="object"){for(const key in this.children){if(this.children[key]?.runOp)this.children[key].runOp(...args)}}return result};this.getProps=(n=this,getInitial=true)=>{let baseprops={tag:n.tag,operator:n.operator,graph:n.graph,children:n.children,parent:n.parent,forward:n.forward,backward:n.bacward,loop:n.loop,animate:n.animate,frame:n.frame,delay:n.delay,recursive:n.recursive,repeat:n.repeat,branch:n.branch,oncreate:n.oncreate,reactive:n.reactive,DEBUGNODE:n.DEBUGNODE};if(!getInitial){let uniqueprops={};for(const key in this._initial){uniqueprops[key]=this[key]}return Object.assign(baseprops,uniqueprops)}else return{tag:n.tag,operator:n.operator,graph:n.graph,children:n.children,parent:n.parent,forward:n.forward,backward:n.bacward,loop:n.loop,animate:n.animate,frame:n.frame,delay:n.delay,recursive:n.recursive,repeat:n.repeat,branch:n.branch,oncreate:n.oncreate,reactive:n.reactive,DEBUGNODE:n.DEBUGNODE,...this._initial}};this.setProps=(props={})=>{let tmp=Object.assign({},props);if(tmp.children){this.addChildren(props.children);delete tmp.children}if(tmp.operator){this.setOperator(props.operator);delete tmp.operator}Object.assign(tmp,props);this.runSync=this.isRunSync()};this.removeTree=n=>{if(n){if(typeof n==="string")n=this.nodes.get(n)}if(n?.nodes){let checked={};const recursivelyRemove=node=>{if(typeof node.children==="object"&&!checked[node.tag]){checked[node.tag]=true;for(const key in node.children){if(node.children[key].stopNode)node.children[key].stopNode();if(node.children[key].tag){if(this.nodes.get(node.children[key].tag))this.nodes.delete(node.children[key].tag);this.nodes.forEach(n2=>{if(n2.nodes.get(node.children[key].tag))n2.nodes.delete(node.children[key].tag);if(n2.children[key]instanceof GraphNode)delete n2.children[key]});recursivelyRemove(node.children[key])}}}};if(n.stopNode)n.stopNode();if(n.tag){this.nodes.delete(n.tag);if(this.children[n.tag])delete this.children[n.tag];if(this.parent?.tag===n.tag)delete this.parent;if(this[n.tag]instanceof GraphNode)delete this[n.tag];this.nodes.forEach(n2=>{if(n2?.tag){if(n2.nodes.get(n2.tag))n2.nodes.delete(n2.tag);if(n2.children[n2.tag]instanceof GraphNode)delete n2.children[n2.tag]}});recursivelyRemove(n);if(this.graph)this.graph.removeTree(n,checked);else if(n.ondelete)n.ondelete(n)}}};this.checkNodesHaveChildMapped=(n,child,checked={})=>{let tag=n.tag;if(!tag)tag=n.name;if(!checked[tag]){checked[tag]=true;if(n.children){if(child.tag in n.children){if(n.children[child.tag]instanceof GraphNode){if(!n.nodes.get(child.tag))n.nodes.set(child.tag,child);n.children[child.tag]=child;if(!n.firstRun)n.firstRun=true}}}if(n.parent instanceof GraphNode){if(n.nodes.get(child.tag))n.parent.nodes.set(child.tag,child);if(n.parent.children){this.checkNodesHaveChildMapped(n.parent,child,checked)}else if(n.nodes){n.nodes.forEach(n2=>{if(!checked[n2.tag]){this.checkNodesHaveChildMapped(n2,child,checked)}})}}if(n.graph){if(n.parent&&n.parent.name!==n.graph.name){n.graph.nodes.forEach(n2=>{if(!checked[n2.tag]){this.checkNodesHaveChildMapped(n2,child,checked)}})}}}};this.convertChildrenToNodes=(n=this)=>{if(n?.children){for(const key in n.children){if(!(n.children[key]instanceof GraphNode)){if(typeof n.children[key]==="object"){if(!n.children[key].tag)n.children[key].tag=key;if(!n.nodes.get(n.children[key].tag)){n.children[key]=new GraphNode(n.children[key],n,n.graph);this.checkNodesHaveChildMapped(n,n.children[key])}}else{if(typeof n.children[key]==="undefined"||n.children[key]==true){n.children[key]=n.graph.get(key);if(!n.children[key])n.children[key]=n.nodes.get(key)}else if(typeof n.children[key]==="string"){let k=n.children[key];n.children[key]=n.graph.get(k);if(!n.children[key])n.children[key]=n.nodes.get(key)}if(n.children[key]instanceof GraphNode){n.nodes.set(n.children[key].tag,n.children[key]);this.checkNodesHaveChildMapped(n,n.children[key]);if(!(n.children[key].tag in n))n[n.children[key].tag]=n.children[key]}}}}}return n.children};this.stopLooping=(n=this)=>{n.isLooping=false};this.stopAnimating=(n=this)=>{n.isAnimating=false};this.stopNode=(n=this)=>{n.stopAnimating(n);n.stopLooping(n)};this.subscribeNode=n=>{if(typeof n==="string")n=this.nodes.get(n);if(n.tag)this.nodes.set(n.tag,n);if(n)return this.state.subscribeTrigger(this.tag,res=>{if(Array.isArray(res))n.run(...res);else n.run(res)})};this.print=(n=this,printChildren=true,nodesPrinted=[])=>{let dummyNode=new GraphNode;if(typeof n==="string")n=this.nodes.get(n);if(n instanceof GraphNode){nodesPrinted.push(n.tag);let jsonToPrint={tag:n.tag,operator:n.operator.toString()};if(n.parent)jsonToPrint.parent=n.parent.tag;if(typeof n.children==="object"){for(const key in n.children){if(typeof n.children[key]==="string")return n.children[key];if(nodesPrinted.includes(n.children[key].tag))return n.children[key].tag;else if(!printChildren){return n.children[key].tag}else return n.children[key].print(n.children[key],printChildren,nodesPrinted)}}for(const prop in n){if(prop==="parent"||prop==="children")continue;if(typeof dummyNode[prop]==="undefined"){if(typeof n[prop]==="function"){jsonToPrint[prop]=n[prop].toString()}else if(typeof n[prop]==="object"){jsonToPrint[prop]=JSON.stringifyWithCircularRefs(n[prop])}else{jsonToPrint[prop]=n[prop]}}}return JSON.stringify(jsonToPrint)}};this.reconstruct=json=>{let parsed=reconstructObject(json);if(parsed)return this.add(parsed)};this.setState=data=>{this.state.setState(data)};this.DEBUGNODES=(debugging=true)=>{this.DEBUGNODE=debugging;this.nodes.forEach(n=>{if(debugging)n.DEBUGNODE=true;else n.DEBUGNODE=false})};if(typeof properties==="function"){properties={operator:properties}}if(typeof properties==="object"){if(properties instanceof GraphNode&&properties._initial)Object.assign(properties,properties._initial);if(properties instanceof Graph){let source=properties;properties={source,operator:input=>{if(typeof input==="object"){let result={};for(const key in input){if(typeof source[key]==="function"){if(Array.isArray(input[key]))result[key]=source[key](...input[key]);else result[key]=source[key](input[key])}else{source[key]=input[key];result[key]=source[key]}}return result}return source}};if(source.operator)properties.operator=source.operator;if(source.children)properties.children=source.children;if(source.forward)properties.forward=source.forward;if(source.backward)properties.backward=source.backward;if(source.repeat)properties.repeat=source.repeat;if(source.recursive)properties.recursive=source.recursive;if(source.loop)properties.loop=source.loop;if(source.animate)properties.animate=source.animate;if(source.looper)properties.looper=source.looper;if(source.animation)properties.animation=source.animation;if(source.delay)properties.delay=source.delay;if(source.oncreate)properties.oncreate=source.oncreate;if(source.node){if(source.node._initial)Object.assign(properties,source.node._initial)}if(source._initial)Object.assign(properties,source._initial);if(source.tag)properties.tag=source.tag;this.nodes=source.nodes;source.node=this;if(graph){source.nodes.forEach(n=>{if(!graph.nodes.get(n.tag)){graph.nodes.set(n.tag,n);graph.nNodes++}})}}if(typeof parent==="string"){if(graph)parent=graph.nodes.get(parent);else parent=void 0}if(properties.tag&&(graph||parent)){let hasnode;if(graph?.nodes){hasnode=graph.nodes.get(properties.tag)}if(!hasnode&&parent?.nodes){hasnode=parent.nodes.get(properties.tag)}if(hasnode){if(this.reactive){this.addLocalState(hasnode)}if(!this.source)this.source=hasnode;let props=hasnode.getProps();delete props.graph;delete props.parent;for(let k in props)properties[k]=props[k]}}if(properties?.operator){properties.operator=this.setOperator(properties.operator)}if(!properties.tag&&graph){properties.tag=`node${graph.nNodes}`}else if(!properties.tag){properties.tag=`node${Math.floor(Math.random()*1e10)}`}let keys=Object.getOwnPropertyNames(this);for(const key in properties){if(!keys.includes(key))this._initial[key]=properties[key]}if(properties.children)this._initial.children=Object.assign({},properties.children);Object.assign(this,properties);if(!this.tag){if(graph){this.tag=`node${graph.nNodes}`}else{this.tag=`node${Math.floor(Math.random()*1e10)}`}}if(graph){this.graph=graph;if(graph.nodes.get(this.tag)){this.tag=`${this.tag}${graph.nNodes+1}`}graph.nodes.set(this.tag,this);graph.nNodes++;this.state=graph.state}if(this.reactive){addLocalState(properties);if(typeof this.reactive==="function"){this.state.subscribeTrigger(this._unique,this.reactive)}}if(typeof parent==="object"){this.parent=parent;if(parent instanceof GraphNode||parent instanceof Graph)parent.nodes.set(this.tag,this)}if(typeof properties.tree==="object"){for(const key in properties.tree){if(typeof properties.tree[key]==="object"){if((!properties.tree[key]).tag){properties.tree[key].tag=key}}let node=new GraphNode(properties.tree[key],this,graph);this.nodes.set(node.tag,node)}}if(this.children)this.convertChildrenToNodes(this);if(this.parent instanceof GraphNode||this.parent instanceof Graph)this.checkNodesHaveChildMapped(this.parent,this);if(typeof this.oncreate==="function")this.oncreate(this);if(!this.firstRun)this.firstRun=true;if(this.animation&&!this.animate)this.animate=true}else return properties}};var Graph=class{constructor(tree,tag,props){this.nNodes=0;this.nodes=new Map;this.state=new EventHandler;this._unique=`${Math.random()}`;this.tree={};this.addLocalState=addLocalState;this.add=(n={})=>{if(n?.node instanceof GraphNode)n=n.node;let props=n;if(!(n instanceof GraphNode))n=new GraphNode(props?.node??props,this,this);else{this.nNodes=this.nodes.size;if(n.tag){this.tree[n.tag]=props;this.nodes.set(n.tag,n)}}return n};this.setTree=(tree=this.tree)=>{if(!tree)return;for(const node in tree){const n=this.nodes.get(node);if(!n){if(typeof tree[node]==="function"){this.add({tag:node,operator:tree[node]})}else if(typeof tree[node]==="object"&&!Array.isArray(tree[node])){if(!tree[node].tag)tree[node].tag=node;let newNode=this.add(tree[node]);if(tree[node].aliases){tree[node].aliases.forEach(a=>{this.nodes.set(a,newNode)})}}else{this.add({tag:node,operator:(...args)=>{return tree[node]}})}}else{if(typeof tree[node]==="function"){n.setOperator(tree[node])}else if(typeof tree[node]==="object"){if(tree[node]instanceof GraphNode){this.add(tree[node])}else if(tree[node]instanceof Graph){let source=tree[node];let properties={};if(source.operator)properties.operator=source.operator;if(source.children)properties.children=source.children;if(source.forward)properties.forward=source.forward;if(source.backward)properties.backward=source.backward;if(source.repeat)properties.repeat=source.repeat;if(source.recursive)properties.recursive=source.recursive;if(source.loop)properties.loop=source.loop;if(source.animate)properties.animate=source.animate;if(source.looper)properties.looper=source.looper;if(source.animation)properties.animation=source.animation;if(source.delay)properties.delay=source.delay;if(source.tag)properties.tag=source.tag;if(source.oncreate)properties.oncreate=source.oncreate;if(source.node?._initial)Object.assign(properties,source.node._initial);properties.nodes=source.nodes;properties.source=source;n.setProps(properties)}else{n.setProps(tree[node])}}}}this.nodes.forEach(node=>{if(typeof node.children==="object"){for(const key in node.children){if(typeof node.children[key]==="string"){if(this.nodes.get(node.children[key])){node.children[key]=this.nodes.get(node.children[key])}}else if(node.children[key]===true||typeof node.children[key]==="undefined"){if(this.nodes.get(key)){node.children[key]=this.nodes.get(key)}}if(node.children[key]instanceof GraphNode){node.checkNodesHaveChildMapped(node,node.children[key])}}}if(typeof node.parent==="string"){if(this.nodes.get(node.parent)){node.parent=this.nodes.get(node.parent);node.nodes.set(node.parent.tag,node.parent)}}})};this.get=tag=>{return this.nodes.get(tag)};this.set=n=>{return this.nodes.set(n.tag,n)};this.run=(n,...args)=>{if(typeof n==="string")n=this.nodes.get(n);if(n?.run)return n.run(...args);else return void 0};this.runAsync=(n,...args)=>{if(typeof n==="string")n=this.nodes.get(n);if(n?.run)return new Promise((res,rej)=>{res(n.run(...args))});else return new Promise((res,rej)=>{res(void 0)})};this.removeTree=(n,checked)=>{if(typeof n==="string")n=this.nodes.get(n);if(n?.nodes){if(!checked)checked={};const recursivelyRemove=node=>{if(node.children&&!checked[node.tag]){checked[node.tag]=true;if(Array.isArray(node.children)){node.children.forEach(c=>{if(c.stopNode)c.stopNode();if(c.tag){if(this.nodes.get(c.tag))this.nodes.delete(c.tag)}this.nodes.forEach(n2=>{if(n2.nodes.get(c.tag))n2.nodes.delete(c.tag)});recursivelyRemove(c)})}else if(typeof node.children==="object"){if(node.stopNode)node.stopNode();if(node.tag){if(this.nodes.get(node.tag))this.nodes.delete(node.tag)}this.nodes.forEach(n2=>{if(n2.nodes.get(node.tag))n2.nodes.delete(node.tag)});recursivelyRemove(node)}}};if(n.stopNode)n.stopNode();if(n.tag){this.nodes.delete(n.tag);this.nodes.forEach(n2=>{if(n2.nodes.get(n2.tag))n2.nodes.delete(n2.tag)});this.nNodes=this.nodes.size;recursivelyRemove(n)}if(n.ondelete)n.ondelete(n)}return n};this.remove=n=>{if(typeof n==="string")n=this.nodes.get(n);if(n?.nodes){if(n.stopNode)n.stopNode();if(n?.tag){if(this.nodes.get(n.tag)){this.nodes.delete(n.tag);this.nodes.forEach(n2=>{if(n2.nodes.get(n2.tag))n2.nodes.delete(n2.tag)})}}if(n.ondelete)n.ondelete(n)}return n};this.append=(n,parentNode)=>{parentNode.addChildren(n)};this.callParent=async(n,...args)=>{if(n?.parent){return await n.callParent(...args)}};this.callChildren=async(n,...args)=>{if(n?.children){return await n.callChildren(...args)}};this.subscribe=(n,callback)=>{if(!callback)return;if(n?.subscribe&&typeof callback==="function"){return n.subscribe(callback)}else if(callback instanceof GraphNode||typeof callback==="string")return this.subscribeNode(n,callback);else if(typeof n=="string"){return this.state.subscribeTrigger(n,callback)}};this.unsubscribe=(tag,sub)=>{return this.state.unsubscribeTrigger(tag,sub)};this.subscribeState=callback=>{if(!this.reactive){return void 0}else{if(typeof callback==="string"){if(this.graph)callback=this.graph.get(callback);else callback=this.nodes.get(callback)}if(typeof callback==="function"){return this.state.subscribeTrigger(this._unique,callback)}else if(callback)return this.state.subscribeTrigger(this._unique,_state=>{callback.run(_state)})}};this.subscribeNode=(inputNode,outputNode)=>{let tag;if(inputNode?.tag)tag=inputNode.tag;else if(typeof inputNode==="string")tag=inputNode;if(typeof outputNode==="string")outputNode=this.nodes.get(outputNode);if(inputNode&&outputNode){let sub=this.state.subscribeTrigger(tag,res=>{if(Array.isArray(res))outputNode.run(...res);else outputNode.run(res)});return sub}};this.stopNode=n=>{if(typeof n==="string"){n=this.nodes.get(n)}if(n?.stopNode){n.stopNode()}};this.print=(n,printChildren=true)=>{if(n?.print)return n.print(n,printChildren);else{let printed=`{`;this.nodes.forEach(n2=>{printed+=` +"${n2.tag}:${n2.print(n2,printChildren)}"`});return printed}};this.reconstruct=json=>{let parsed=reconstructObject(json);if(parsed)return this.add(parsed)};this.create=(operator,parentNode,props)=>{return createNode(operator,parentNode,props,this)};this.setState=data=>{this.state.setState(data)};this.DEBUGNODES=(debugging=true)=>{this.nodes.forEach(n=>{if(debugging)n.DEBUGNODE=true;else n.DEBUGNODE=false})};this.tag=tag?tag:`graph${Math.floor(Math.random()*1e11)}`;if(props){if(props.reactive){this.addLocalState(props)}else Object.assign(this,props);this._initial=props}if(tree||Object.keys(this.tree).length>0)this.setTree(tree)}};function reconstructNode(json,parentNode,graph){let reconstructed=reconstructObject(json);if(reconstructed)return new GraphNode(reconstructed,parentNode,graph);else return void 0}function reconstructObject(json="{}"){try{let parsed=typeof json==="string"?JSON.parse(json):json;const parseObj=obj=>{for(const prop in obj){if(typeof obj[prop]==="string"){let funcParsed=parseFunctionFromText(obj[prop]);if(typeof funcParsed==="function"){obj[prop]=funcParsed}}else if(typeof obj[prop]==="object"){parseObj(obj[prop])}}return obj};return parseObj(parsed)}catch(err){console.error(err);return void 0}}var stringifyWithCircularRefs=function(){const refs=new Map;const parents=[];const path=["this"];function clear(){refs.clear();parents.length=0;path.length=1}function updateParents(key,value){var idx=parents.length-1;var prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value||idx===0){path.push(key);parents.push(value.pushed)}else{while(idx-->=0){prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value){idx+=2;parents.length=idx;path.length=idx;--idx;parents[idx]=value;path[idx]=key;break}}idx--}}}}function checkCircular(key,value){if(value!=null){if(typeof value==="object"){if(key){updateParents(key,value)}let other=refs.get(value);if(other){return"[Circular Reference]"+other}else{refs.set(value,path.join("."))}}}return value}return function stringifyWithCircularRefs2(obj,space){try{parents.push(obj);return JSON.stringify(obj,checkCircular,space)}finally{clear()}}}();if(JSON.stringifyWithCircularRefs===void 0){JSON.stringifyWithCircularRefs=stringifyWithCircularRefs}var stringifyFast=function(){const refs=new Map;const parents=[];const path=["this"];function clear(){refs.clear();parents.length=0;path.length=1}function updateParents(key,value){var idx=parents.length-1;if(parents[idx]){var prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value||idx===0){path.push(key);parents.push(value.pushed)}else{while(idx-->=0){prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value){idx+=2;parents.length=idx;path.length=idx;--idx;parents[idx]=value;path[idx]=key;break}}idx++}}}}}function checkValues(key,value){let val;if(value!=null){if(typeof value==="object"){let c=value.constructor.name;if(key&&c==="Object"){updateParents(key,value)}let other=refs.get(value);if(other){return"[Circular Reference]"+other}else{refs.set(value,path.join("."))}if(c==="Array"){if(value.length>20){val=value.slice(value.length-20)}else val=value}else if(c.includes("Set")){val=Array.from(value)}else if(c!=="Object"&&c!=="Number"&&c!=="String"&&c!=="Boolean"){val="instanceof_"+c}else if(c==="Object"){let obj={};for(const prop in value){if(value[prop]==null){obj[prop]=value[prop]}else if(Array.isArray(value[prop])){if(value[prop].length>20)obj[prop]=value[prop].slice(value[prop].length-20);else obj[prop]=value[prop]}else if(value[prop].constructor.name==="Object"){obj[prop]={};for(const p in value[prop]){if(Array.isArray(value[prop][p])){if(value[prop][p].length>20)obj[prop][p]=value[prop][p].slice(value[prop][p].length-20);else obj[prop][p]=value[prop][p]}else{if(value[prop][p]!=null){let con=value[prop][p].constructor.name;if(con.includes("Set")){obj[prop][p]=Array.from(value[prop][p])}else if(con!=="Number"&&con!=="String"&&con!=="Boolean"){obj[prop][p]="instanceof_"+con}else{obj[prop][p]=value[prop][p]}}else{obj[prop][p]=value[prop][p]}}}}else{let con=value[prop].constructor.name;if(con.includes("Set")){obj[prop]=Array.from(value[prop])}else if(con!=="Number"&&con!=="String"&&con!=="Boolean"){obj[prop]="instanceof_"+con}else{obj[prop]=value[prop]}}}val=obj}else{val=value}}else{val=value}}return val}return function stringifyFast2(obj,space){parents.push(obj);let res=JSON.stringify(obj,checkValues,space);clear();return res}}();if(JSON.stringifyFast===void 0){JSON.stringifyFast=stringifyFast}function createNode(operator,parentNode,props,graph){if(typeof props==="object"){props.operator=operator;return new GraphNode(props,parentNode,graph)}return new GraphNode({operator},parentNode,graph)}var Service=class extends Graph{constructor(options={}){super(void 0,options.name?options.name:`service${Math.floor(Math.random()*1e14)}`,options.props);this.routes={};this.loadDefaultRoutes=false;this.keepState=true;this.firstLoad=true;this.customRoutes={};this.customChildren={};this.init=options=>{if(options)options=Object.assign({},options);else options={};if(options.customRoutes)Object.assign(options.customRoutes,this.customRoutes);else options.customRoutes=this.customRoutes;if(options.customChildren)Object.assign(options.customChildren,this.customChildren);else options.customChildren=this.customChildren;if(Array.isArray(options.routes)){options.routes.forEach(r=>{this.load(r,options.includeClassName,options.routeFormat,options.customRoutes,options.customChildren,options.sharedState)})}else if(options.routes||(Object.keys(this.routes).length>0||this.loadDefaultRoutes)&&this.firstLoad)this.load(options.routes,options.includeClassName,options.routeFormat,options.customRoutes,options.customChildren,options.sharedState)};this.load=(routes,includeClassName=true,routeFormat=".",customRoutes,customChildren,sharedState=true)=>{if(!routes&&!this.loadDefaultRoutes&&(Object.keys(this.routes).length>0||this.firstLoad))return;if(this.firstLoad)this.firstLoad=false;if(customRoutes)customRoutes=Object.assign(this.customRoutes,customRoutes);else customRoutes=this.customRoutes;let service;let allRoutes={};if(routes){if(!(routes instanceof Graph)&&routes?.name&&!routes.setTree){if(routes.module){let mod=routes;routes={};Object.getOwnPropertyNames(routes.module).forEach(prop=>{if(includeClassName)routes[mod.name+routeFormat+prop]=routes.module[prop];else routes[prop]=routes.module[prop]})}else if(typeof routes==="function"){service=new routes({loadDefaultRoutes:this.loadDefaultRoutes});service.load();if(sharedState)service.state=this.state;routes=service.routes;if(service.customRoutes&&!this.customRoutes)this.customRoutes=service.customRoutes;else if(service.customRoutes&&this.customRoutes)Object.assign(this.customRoutes,service.customRoutes);if(service.customChildren&&!this.customChildren)this.customChildren=service.customChildren;else if(service.customChildren&&this.customChildren)Object.assign(this.customChildren,service.customChildren)}}else if(routes instanceof Graph||routes.source instanceof Graph||routes.setTree){service=routes;routes={};if(sharedState)service.state=this.state;if(includeClassName){let name=service.name;if(!name){name=service.tag;service.name=name}if(!name){name=`graph${Math.floor(Math.random()*1e15)}`;service.name=name;service.tag=name}}if(service.customRoutes&&!this.customRoutes)this.customRoutes=service.customRoutes;else if(service.customRoutes&&this.customRoutes)Object.assign(this.customRoutes,service.customRoutes);if(service.customChildren&&!this.customChildren)this.customChildren=service.customChildren;else if(service.customChildren&&this.customChildren)Object.assign(this.customChildren,service.customChildren);service.nodes.forEach(node=>{routes[node.tag]=node;let checked={};let checkChildGraphNodes=(nd,par)=>{if(!checked[nd.tag]||par&&includeClassName&&!checked[par?.tag+routeFormat+nd.tag]){if(!par)checked[nd.tag]=true;else checked[par.tag+routeFormat+nd.tag]=true;if(nd instanceof Graph||nd.source instanceof Graph||nd.setTree){if(sharedState)nd.state=this.state;if(includeClassName){let nm=nd.name;if(!nm){nm=nd.tag;nd.name=nm}if(!nm){nm=`graph${Math.floor(Math.random()*1e15)}`;nd.name=nm;nd.tag=nm}}nd.nodes.forEach(n=>{if(includeClassName&&!routes[nd.tag+routeFormat+n.tag])routes[nd.tag+routeFormat+n.tag]=n;else if(!routes[n.tag])routes[n.tag]=n;checkChildGraphNodes(n,nd)})}}};checkChildGraphNodes(node)})}else if(typeof routes==="object"){let name=routes.constructor.name;if(name==="Object"){name=Object.prototype.toString.call(routes);if(name)name=name.split(" ")[1];if(name)name=name.split("]")[0]}if(name&&name!=="Object"){let module=routes;routes={};Object.getOwnPropertyNames(module).forEach(route=>{if(includeClassName)routes[name+routeFormat+route]=module[route];else routes[route]=module[route]})}}if((service instanceof Graph||service?.setTree)&&service.name&&includeClassName){routes=Object.assign({},routes);for(const prop in routes){let route=routes[prop];delete routes[prop];routes[service.name+routeFormat+prop]=route}}}if(this.loadDefaultRoutes){let rts=Object.assign({},this.defaultRoutes);if(routes){Object.assign(rts,this.routes);routes=Object.assign(rts,routes)}else routes=Object.assign(rts,this.routes);this.loadDefaultRoutes=false}if(!routes)routes=this.routes;let incr=0;for(const tag in routes){incr++;let childrenIter=(route,routeKey)=>{if(typeof route==="object"){if(!route.tag)route.tag=routeKey;if(typeof route?.children==="object"){nested:for(const key in route.children){incr++;if(typeof route.children[key]==="object"){let rt=route.children[key];if(rt.tag&&allRoutes[rt.tag])continue;if(customChildren){for(const k2 in customChildren){rt=customChildren[k2](rt,key,route,routes,allRoutes);if(!rt)continue nested}}if(rt.id&&!rt.tag){rt.tag=rt.id}let k;if(rt.tag){if(allRoutes[rt.tag]){let randkey=`${rt.tag}${incr}`;allRoutes[randkey]=rt;rt.tag=randkey;childrenIter(allRoutes[randkey],key);k=randkey}else{allRoutes[rt.tag]=rt;childrenIter(allRoutes[rt.tag],key);k=rt.tag}}else{if(allRoutes[key]){let randkey=`${key}${incr}`;allRoutes[randkey]=rt;rt.tag=randkey;childrenIter(allRoutes[randkey],key);k=randkey}else{allRoutes[key]=rt;childrenIter(allRoutes[key],key);k=key}}if(service?.name&&includeClassName){allRoutes[service.name+routeFormat+k]=rt;delete allRoutes[k]}else allRoutes[k]=rt}}}}};allRoutes[tag]=routes[tag];childrenIter(routes[tag],tag)}top:for(const route in allRoutes){if(typeof allRoutes[route]==="object"){let r=allRoutes[route];if(typeof r==="object"){if(customRoutes){for(const key in customRoutes){r=customRoutes[key](r,route,allRoutes);if(!r)continue top}}if(r.get){if(typeof r.get=="object"){}}if(r.post){}if(r.delete){}if(r.put){}if(r.head){}if(r.patch){}if(r.options){}if(r.connect){}if(r.trace){}if(r.post&&!r.operator){allRoutes[route].operator=r.post}else if(!r.operator&&typeof r.get=="function"){allRoutes[route].operator=r.get}}}}for(const route in routes){if(typeof routes[route]==="object"){if(this.routes[route]){if(typeof this.routes[route]==="object")Object.assign(this.routes[route],routes[route]);else this.routes[route]=routes[route]}else this.routes[route]=routes[route]}else if(this.routes[route]){if(typeof this.routes[route]==="object")Object.assign(this.routes[route],routes[route]);else this.routes[route]=routes[route]}else this.routes[route]=routes[route]}if(service){for(const key in this.routes){if(this.routes[key]instanceof GraphNode||this.routes[key].constructor.name.includes("GraphNode")){this.nodes.set(key,this.routes[key]);this.nNodes=this.nodes.size}}}else this.setTree(this.routes);for(const prop in this.routes){if(this.routes[prop]?.aliases){let aliases=this.routes[prop].aliases;aliases.forEach(a=>{if(service?.name&&includeClassName)routes[service.name+routeFormat+a]=this.routes[prop];else routes[a]=this.routes[prop]})}}return this.routes};this.unload=(routes=this.routes)=>{if(!routes)return;let service;if(!(routes instanceof Service)&&typeof routes==="function"){service=new Service;routes=service.routes}else if(routes instanceof Service){routes=routes.routes}for(const r in routes){delete this.routes[r];if(this.nodes.get(r))this.remove(r)}return this.routes};this.handleMethod=(route,method,args)=>{let m=method.toLowerCase();let src=this.nodes.get(route);if(!src){src=this.routes[route];if(!src)src=this.tree[route]}if(src?.[m]){if(!(src[m]instanceof Function)){if(args)src[m]=args;return src[m]}else return src[m](args)}else return this.handleServiceMessage({route,args,method})};this.transmit=(...args)=>{if(typeof args[0]==="object"){if(args[0].method){return this.handleMethod(args[0].route,args[0].method,args[0].args)}else if(args[0].route){return this.handleServiceMessage(args[0])}else if(args[0].node){return this.handleGraphNodeCall(args[0].node,args[0].args)}else if(this.keepState){if(args[0].route)this.setState({[args[0].route]:args[0].args});if(args[0].node)this.setState({[args[0].node]:args[0].args})}return args}else return args};this.receive=(...args)=>{if(args[0]){if(typeof args[0]==="string"){let substr=args[0].substring(0,8);if(substr.includes("{")||substr.includes("[")){if(substr.includes("\\"))args[0]=args[0].replace(/\\/g,"");if(args[0][0]==='"'){args[0]=args[0].substring(1,args[0].length-1)};args[0]=JSON.parse(args[0])}}}if(typeof args[0]==="object"){if(args[0].method){return this.handleMethod(args[0].route,args[0].method,args[0].args)}else if(args[0].route){return this.handleServiceMessage(args[0])}else if(args[0].node){return this.handleGraphNodeCall(args[0].node,args[0].args)}else if(this.keepState){if(args[0].route)this.setState({[args[0].route]:args[0].args});if(args[0].node)this.setState({[args[0].node]:args[0].args})}return args}else return args};this.pipe=(source,destination,endpoint,method,callback)=>{if(source instanceof GraphNode){if(callback)return source.subscribe(res=>{let mod=callback(res);if(mod!==void 0)this.transmit({route:destination,args:mod,method});else this.transmit({route:destination,args:res,method},endpoint)});else return this.subscribe(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})}else if(typeof source==="string")return this.subscribe(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})};this.pipeOnce=(source,destination,endpoint,method,callback)=>{if(source instanceof GraphNode){if(callback)return source.state.subscribeTriggerOnce(source.tag,res=>{let mod=callback(res);if(mod!==void 0)this.transmit({route:destination,args:mod,method});else this.transmit({route:destination,args:res,method},endpoint)});else return this.state.subscribeTriggerOnce(source.tag,res=>{this.transmit({route:destination,args:res,method},endpoint)})}else if(typeof source==="string")return this.state.subscribeTriggerOnce(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})};this.terminate=(...args)=>{this.nodes.forEach(n=>{n.stopNode()})};this.recursivelyAssign=(target,obj)=>{for(const key in obj){if(typeof obj[key]==="object"&&!Array.isArray(obj[key])){if(typeof target[key]==="object"&&!Array.isArray(target[key]))this.recursivelyAssign(target[key],obj[key]);else target[key]=this.recursivelyAssign({},obj[key])}else target[key]=obj[key]}return target};this.defaultRoutes={"/":{get:()=>{return this.print()},aliases:[""]},ping:()=>{console.log("ping");return"pong"},echo:(...args)=>{this.transmit(...args);return args},assign:source=>{if(typeof source==="object"){Object.assign(this,source);return true}return false},recursivelyAssign:source=>{if(typeof source==="object"){this.recursivelyAssign(this,source);return true}return false},log:{post:(...args)=>{console.log("Log: ",...args)},aliases:["info"]},error:message=>{let er=new Error(message);console.error(message);return er},state:key=>{if(key){return this.state.data[key]}else return this.state.data},printState:key=>{if(key){return stringifyWithCircularRefs(this.state.data[key])}else return stringifyWithCircularRefs(this.state.data)},spliceTypedArray:this.spliceTypedArray,transmit:this.transmit,receive:this.receive,load:this.load,unload:this.unload,pipe:this.pipe,terminate:this.terminate,run:this.run,subscribe:this.subscribe,subscribeNode:this.subscribeNode,unsubscribe:this.unsubscribe,stopNode:this.stopNode,get:this.get,add:this.add,remove:this.remove,setTree:this.setTree,setState:this.setState,print:this.print,reconstruct:this.reconstruct,handleMethod:this.handleMethod,handleServiceMessage:this.handleServiceMessage,handleGraphNodeCall:this.handleGraphNodeCall};if(options.name)this.name=options.name;else options.name=this.tag;if("loadDefaultRoutes"in options){this.loadDefaultRoutes=options.loadDefaultRoutes;this.routes=Object.assign(this.defaultRoutes,this.routes)}if(options||Object.keys(this.routes).length>0)this.init(options)}handleServiceMessage(message){let call;if(typeof message==="object"){if(message.route)call=message.route;else if(message.node)call=message.node}if(call){if(Array.isArray(message.args))return this.run(call,...message.args);else return this.run(call,message.args)}else return message}handleGraphNodeCall(route,args){if(!route)return args;if(args?.args){this.handleServiceMessage(args)}else if(Array.isArray(args))return this.run(route,...args);else return this.run(route,args)}isTypedArray(x){return ArrayBuffer.isView(x)&&Object.prototype.toString.call(x)!=="[object DataView]"}spliceTypedArray(arr,start,end){let s=arr.subarray(0,start);let e;if(end){e=arr.subarray(end+1)}let n;if(s.length>0||e?.length>0)n=new arr.constructor(s.length+e.length);if(s.length>0)n.set(s);if(e&&e.length>0)n.set(e,s.length);return n}};var unsafeRoutes={setRoute:function(fn,fnName){if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function"){if(!fnName)fnName=fn.name;if(this.graph.get(fnName)){this.graph.get(fnName).setOperator(fn.bind(this.graph.get(fnName)))}else{let node=this.graph.add({tag:fnName,operator:fn});if(this.graph instanceof Service)this.graph.load({[fnName]:node})}return true}return false},setNode:function(fn,fnName){if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function"){if(!fnName)fnName=fn.name;if(this.graph.get(fnName)){this.graph.get(fnName).setOperator(fn)}else this.graph.add({tag:fnName,operator:fn});return true}return false},setMethod:function(route,fn,fnName){if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function"){if(!fnName)fnName=fn.name;if(this.graph.get(route)){this.graph.get(route)[fnName]=fn}else this.graph.add({tag:fnName,[fnName]:fn});return true}return false},assignRoute:function(route,source){if(this.graph.get(route)&&typeof source==="object"){Object.assign(this.graph.get(route),source)}},transferClass:(classObj,className)=>{if(typeof classObj==="object"){let str=classObj.toString();let message={route:"receiveClass",args:[str,className]};return message}return false},receiveClass:function(stringified,className){if(typeof stringified==="string"){if(stringified.indexOf("class")===0){let cls=(0,eval)("("+stringified+")");let name=className;if(!name)name=cls.name;this.graph[name]=cls;return true}}return false},setGlobal:(key,value)=>{globalThis[key]=value;return true},assignGlobalObject:(target,source)=>{if(!globalThis[target])return false;if(typeof source==="object")Object.assign(globalThis[target],source);return true},setValue:function(key,value){this.graph[key]=value;return true},assignObject:function(target,source){if(!this.graph[target])return false;if(typeof source==="object")Object.assign(this.graph[target],source);return true},setGlobalFunction:(fn,fnName)=>{if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function"){if(!fnName)fnName=fn.name;globalThis[fnName]=fn;return true}return false},assignFunctionToGlobalObject:function(globalObjectName,fn,fnName){if(!globalThis[globalObjectName])return false;if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function"){if(!fnName)fnName=fn.name;this.graph[globalObjectName][fnName]=fn;return true}return false},setFunction:function(fn,fnName){if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function"){if(!fnName)fnName=fn.name;this.graph[fnName]=fn;return true}return false},assignFunctionToObject:function(objectName,fn,fnName){if(!this.graph[objectName])return false;if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function"){if(!fnName)fnName=fn.name;this.graph[objectName][fnName]=fn;return true}return false}};var ECSService=class extends Service{constructor(options){super(options);this.entities={};this.systems={};this.entityMap=new Map;this.entityKeyMap=new Map;this.order=[];this.animating=false;this.entityCt=0;this.systemCt=0;this.updateEntities=(order=this.order,filter,debug=false)=>{order.forEach(k=>{if(this.systems[k]){if(filter){if(debug)debug=performance.now();if(this.entityKeyMap.get(k).length>0)this.systems[k].run(this.entityMap.get(k));if(debug)console.log("system",k,"took",performance.now()-debug,"ms for",Object.keys(this.entityMap.get(k)).length,"entities")}else{if(debug)debug=performance.now();if(this.entityKeyMap.get(k).length>0)this.systems[k].run(this.entities);if(debug)console.log("system",k,"took",performance.now()-debug,"ms for",Object.keys(this.entities).length,"entities")}}})};this.animate=(filter=true,order)=>{if(this.animating===false){this.animating=true;if(typeof requestAnimationFrame!=="undefined"){let anim=()=>{requestAnimationFrame(()=>{if(this.animating){this.updateEntities(order,filter);anim()}})};anim()}else{let looper=()=>{setTimeout(async()=>{if(this.animating){this.updateEntities(order,filter);looper()}},10)};looper()}}};this.stop=()=>{this.animating=false};this.start=filter=>{this.animate(filter)};this.addEntities=(prototype,components={},count=1)=>{let i=0;let newEntities={};while(i{if(!prototype)return;const entity=this.recursivelyAssign({},prototype);entity.components=components;if(Object.keys(components).length===0){Object.keys(this.systems).forEach(k=>{components[k]=true})}if(entity.tag&&this.entities[entity.tag]){this.entityCt++;let tag=entity.tag+this.entityCt;while(this.entities[entity.tag]){this.entityCt++;entity.tag=`${tag}${this.entityCt}`}}else if(!entity.tag)entity.tag=`entity${Math.floor(Math.random()*1e15)}`;this.add(entity);this.entities[entity.tag]=this.nodes.get(entity.tag);this.setupEntity(this.entities[entity.tag]);return this.entities[entity.tag]};this.addSystems=(systems={},order)=>{for(const key in systems){systems[key].tag=key;this.addSystem(systems[key],void 0,void 0,void 0,void 0,order)}return this.systems};this.addSystem=(prototype,setupEntities,setupEntity,operator,remove,order)=>{if(!prototype)return;const system=this.recursivelyAssign({},prototype);if(setupEntities)system.setupEntities=setupEntities;if(setupEntity)system.setupEntity=setupEntity;if(operator)system.operator=operator;if(remove)system.remove=remove;if(system.tag&&this.systems[system.tag]){this.systemCt++;let tag=system.tag+this.systemCt;while(this.systems[system.tag]){this.systemCt++;system.tag=`${tag}${this.systemCt}`}}else if(!system.tag)system.tag=`system${Math.floor(Math.random()*1e15)}`;this.add(system);this.systems[system.tag]=this.nodes.get(system.tag);if(!this.entityMap.get(system.tag))this.entityMap.set(system.tag,{});if(!this.entityKeyMap.get(system.tag))this.entityKeyMap.set(system.tag,[]);this.systems[system.tag].entities=this.entityMap.get(system.tag);this.systems[system.tag].entityKeys=this.entityKeyMap.get(system.tag);if(this.systems[system.tag]?.setupEntities){let filtered=this.filterObject(this.entities,(key,v)=>{if(v.components[system.tag])return true});this.systems[system.tag].setupEntities(filtered);Object.assign(this.entityMap.get(system.tag),filtered)}if(!order)this.order.push(system.tag);else this.order=order;return this.systems[system.tag]};this.setupEntity=entity=>{if(entity?.components){for(const key in entity.components){if(this.systems[key]){this.systems[key].setupEntity(entity);this.entityMap.get(key)[entity.tag]=entity;this.entityKeyMap.get(key).push(entity.tag)}}}};this.removeEntity=tag=>{const entity=this.entities[tag];for(const key in entity.components){if(this.entityMap.get(key)){delete this.entityMap.get(key)[entity.tag];this.entityKeyMap.get(key).splice(this.entityKeyMap.get(key).indexOf(entity.tag),1)}if(this.systems[key]?.remove){this.systems[key].remove(entity,this.entityMap.get(key))}}delete this.entities[tag];return this.remove(tag)};this.removeSystem=tag=>{if(this.systems[tag]?.remove){for(const e in this.entityKeyMap.get(tag)){this.systems[tag].remove(this.entityMap.get(tag)[e],this.entityMap.get(tag))}}delete this.systems[tag];this.entityMap.delete(tag);this.entityKeyMap.delete(tag);this.order.splice(this.order.indexOf(tag),1);return this.remove(tag)};this.setEntities=(entities,props)=>{if(Array.isArray(entities)){entities.forEach(k=>{if(this.entities[k])this.recursivelyAssign(this.entities[k],props)})}else{for(const key in this.entities){this.setEntity(this.entities[key],props)}}return true};this.setEntity=(entity,props)=>{return this.recursivelyAssign(entity,props)};this.bufferValues=(entities,property,keys,buffer)=>{if(!Array.isArray(keys)&&typeof keys==="object")keys=Object.keys(keys);if(!buffer){let entkeys=Object.keys(entities);if(keys)buffer=new Float32Array(entkeys.length*keys.length);else{if(typeof entities[entkeys[0]][property]==="object"){keys=Object.keys(entities[entkeys[0]][property]);buffer=new Float32Array(entkeys.length*keys.length)}else buffer=new Float32Array(entkeys.length)}}let i=0;for(const key in entities){if(entities[key][property]){if(keys){for(let j=0;j{this.removeEntity(t)})}filterObject(o,filter){return Object.fromEntries(Object.entries(o).filter(([key,value])=>{filter(key,value)}))}};var DOMElement=class extends HTMLElement{constructor(){super();__publicField(this,"template",function(self2=this,props){return`
Custom Fragment Props: ${JSON.stringify(props)}
`});__publicField(this,"props",{});__publicField(this,"useShadow",false);__publicField(this,"styles");__publicField(this,"oncreate");__publicField(this,"onresize");__publicField(this,"ondelete");__publicField(this,"onchanged");__publicField(this,"renderonchanged",false);__publicField(this,"FRAGMENT");__publicField(this,"STYLE");__publicField(this,"attachedShadow",false);__publicField(this,"obsAttributes",["props","options","onchanged","onresize","ondelete","oncreate","template"]);__publicField(this,"attributeChangedCallback",(name,old,val)=>{if(name==="onchanged"){let onchanged=val;if(typeof onchanged==="string")onchanged=parseFunctionFromText2(onchanged);if(typeof onchanged==="function"){this.onchanged=onchanged;this.state.data.props=this.props;this.state.unsubscribeTrigger("props");this.state.subscribeTrigger("props",this.onchanged);let changed=new CustomEvent("changed",{detail:{props:this.props,self:this}});this.state.subscribeTrigger("props",()=>{this.dispatchEvent(changed)})}}else if(name==="onresize"){let onresize=val;if(typeof onresize==="string")onresize=parseFunctionFromText2(onresize);if(typeof onresize==="function"){if(this.ONRESIZE){try{window.removeEventListener("resize",this.ONRESIZE)}catch(err){}}this.ONRESIZE=ev=>{this.onresize(this.props,this)};this.onresize=onresize;window.addEventListener("resize",this.ONRESIZE)}}else if(name==="ondelete"){let ondelete=val;if(typeof ondelete==="string")ondelete=parseFunctionFromText2(ondelete);if(typeof ondelete==="function"){this.ondelete=()=>{if(this.ONRESIZE)window.removeEventListener("resize",this.ONRESIZE);this.state.unsubscribeTrigger("props");if(ondelete)ondelete(this.props,this)}}}else if(name==="oncreate"){let oncreate=val;if(typeof oncreate==="string")oncreate=parseFunctionFromText2(oncreate);if(typeof oncreate==="function"){this.oncreate=oncreate}}else if(name==="renderonchanged"){let rpc=val;if(typeof this.renderonchanged==="number")this.unsubscribeTrigger(this.renderonchanged);if(typeof rpc==="string")rpc=parseFunctionFromText2(rpc);if(typeof rpc==="function"){this.renderonchanged=this.state.subscribeTrigger("props",p=>{this.render(p);rpc(this,p)})}else if(rpc!=false)this.renderonchanged=this.state.subscribeTrigger("props",this.render)}else if(name==="props"){let newProps=val;if(typeof newProps==="string")newProps=JSON.parse(newProps);Object.assign(this.props,newProps);this.state.setState({props:this.props})}else if(name==="template"){let template=val;this.template=template;this.render(this.props);let created=new CustomEvent("created",{detail:{props:this.props}});this.dispatchEvent(created)}else{let parsed=val;if(name.includes("eval_")){name=name.split("_");name.shift();name=name.join();parsed=parseFunctionFromText2(val)}else if(typeof val==="string"){try{parsed=JSON.parse(val)}catch(err){parsed=val}}this[name]=parsed;if(name!=="props"&&this.props)this.props[name]=parsed}});__publicField(this,"delete",()=>{this.remove();if(typeof this.ondelete==="function")this.ondelete(this.props)});__publicField(this,"render",(props=this.props)=>{if(typeof this.template==="function")this.templateResult=this.template(this,props);else this.templateResult=this.template;if(this.styles)this.templateResult=`${this.templateResult}`;const t=document.createElement("template");if(typeof this.templateResult==="string")t.innerHTML=this.templateResult;else if(this.templateResult instanceof HTMLElement){if(this.templateResult.parentNode){this.templateResult.parentNode.removeChild(this.templateResult)}t.appendChild(this.templateResult)}const fragment=t.content;if(this.FRAGMENT){if(this.useShadow){if(this.STYLE)this.shadowRoot.removeChild(this.STYLE);this.shadowRoot.removeChild(this.FRAGMENT)}else this.removeChild(this.FRAGMENT)}if(this.useShadow){if(!this.attachedShadow){this.attachShadow({mode:"open"}).innerHTML="";this.attachedShadow=true}if(this.styles){let style=document.createElement("style");style.textContent=this.styles;this.shadowRoot.prepend(style);this.STYLE=style}this.shadowRoot.prepend(fragment);this.FRAGMENT=this.shadowRoot.childNodes[0]}else{this.prepend(fragment);this.FRAGMENT=this.childNodes[0]}let rendered=new CustomEvent("rendered",{detail:{props:this.props,self:this}});this.dispatchEvent(rendered);if(this.oncreate)this.oncreate(this,props)});__publicField(this,"state",{pushToState:{},data:{},triggers:{},setState(updateObj){Object.assign(this.pushToState,updateObj);if(Object.keys(this.triggers).length>0){for(const prop of Object.getOwnPropertyNames(this.triggers)){if(this.pushToState[prop]){this.data[prop]=this.pushToState[prop];delete this.pushToState[prop];this.triggers[prop].forEach(obj=>{obj.onchanged(this.data[prop])})}}}return this.pushToState},subscribeTrigger(key,onchanged=res=>{}){if(key){if(!this.triggers[key]){this.triggers[key]=[]}let l=this.triggers[key].length;this.triggers[key].push({idx:l,onchanged});return this.triggers[key].length-1}else return void 0},unsubscribeTrigger(key,sub){let triggers=this.triggers[key];if(triggers){if(!sub)delete this.triggers[key];else{let idx=void 0;let obj=triggers.find((o,i)=>{if(o.idx===sub){idx=i;return true}});if(obj)triggers.splice(idx,1);return true}}},subscribeTriggerOnce(key=void 0,onchanged=value=>{}){let sub;let changed=value=>{onchanged(value);this.unsubscribeTrigger(key,sub)};sub=this.subscribeTrigger(key,changed)}})}get observedAttributes(){return this.obsAttributes}get obsAttributes(){return this.obsAttributes}set obsAttributes(att){if(typeof att==="string"){this.obsAttributes.push(att)}else if(Array.isArray(att))this.obsAttributes=att}static get tag(){return this.name.toLowerCase()+"-"}static addElement(tag=this.tag,cls=this,extend=void 0){addCustomElement(cls,tag,extend)}connectedCallback(){if(!this.props)this.props={};let newProps=this.getAttribute("props");if(typeof newProps==="string")newProps=JSON.parse(newProps);Object.assign(this.props,newProps);this.state.setState({props:this.props});Array.from(this.attributes).forEach(att=>{let name=att.name;let parsed=att.value;if(name.includes("eval_")||name.includes("()")){if(name.includes("eval_"))name=name.split("_");else if(name.includes("()"))name=name.substring(0,name.indexOf("("));name.shift();name=name.join();parsed=parseFunctionFromText2(att.value)}else if(typeof att.value==="string"){try{parsed=JSON.parse(att.value)}catch(err){parsed=att.value}}if(!this[name]){Object.defineProperties(this,att,{value:parsed,writable:true,get(){return this[name]},set(val){this.setAttribute(name,val)}})}this[name]=parsed;if(name!=="props")this.props[name]=parsed;this.obsAttributes.push(name)});let resizeevent=new CustomEvent("resized",{detail:{props:this.props,self:this}});let changed=new CustomEvent("changed",{detail:{props:this.props,self:this}});let deleted=new CustomEvent("deleted",{detail:{props:this.props,self:this}});let created=new CustomEvent("created",{detail:{props:this.props,self:this}});this.render(this.props);this.dispatchEvent(created);this.state.subscribeTrigger("props",()=>{this.dispatchEvent(changed)});if(typeof this.onresize==="function"){if(this.ONRESIZE){try{window.removeEventListener("resize",this.ONRESIZE)}catch(err){}}this.ONRESIZE=ev=>{this.onresize(this,this.props);this.dispatchEvent(resizeevent)};window.addEventListener("resize",this.ONRESIZE)}if(typeof this.ondelete==="function"){let ondelete=this.ondelete;this.ondelete=(props=this.props)=>{if(this.ONRESIZE)window.removeEventListener("resize",this.ONRESIZE);this.state.unsubscribeTrigger("props");this.dispatchEvent(deleted);ondelete(this,props)}}if(typeof this.onchanged==="function"){this.state.data.props=this.props;this.state.subscribeTrigger("props",this.onchanged)}if(this.renderonchanged){let rpc=this.renderonchanged;if(typeof this.renderonchanged==="number")this.unsubscribeTrigger(this.renderonchanged);if(typeof rpc==="string")rpc=parseFunctionFromText2(rpc);if(typeof rpc==="function"){this.renderonchanged=this.state.subscribeTrigger("props",p=>{this.render(p);rpc(this,p)})}else if(rpc!==false)this.renderonchanged=this.state.subscribeTrigger("props",this.render)}}get props(){return this.props}set props(newProps={}){this.setAttribute("props",newProps)}get template(){return this.template}set template(template){this.setAttribute("template",template)}get render(){return this.render}get delete(){return this.delete}get state(){return this.state}get onchanged(){return this.onchanged}set onchanged(onchanged){this.setAttribute("onchanged",onchanged)}get styles(){return this.styles}set styles(templateStr){this.styles=templateStr;if(this.querySelector("style")){this.querySelector("style").innerHTML=templateStr}else{this.render()}}get renderonchanged(){return this.renderonchanged}set renderonchanged(onchanged){this.setAttribute("renderonchanged",onchanged)}get onresize(){return this.props}set onresize(onresize){this.setAttribute("onresize",onresize)}get ondelete(){return this.props}set ondelete(ondelete){this.setAttribute("ondelete",ondelete)}get oncreate(){return this.oncreate}set oncreate(oncreate){this.setAttribute("oncreated",oncreate)}};function addCustomElement(cls,tag,extend=null){try{if(extend){if(tag)window.customElements.define(tag,cls,{extends:extend});else window.customElements.define(cls.name.toLowerCase()+"-",cls,{extends:extend})}else{if(tag)window.customElements.define(tag,cls);else window.customElements.define(cls.name.toLowerCase()+"-",cls)}}catch(err){}}function parseFunctionFromText2(method){let getFunctionBody=methodString=>{return methodString.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i,"$2$3$4")};let getFunctionHead=methodString=>{let startindex=methodString.indexOf(")");return methodString.slice(0,methodString.indexOf("{",startindex)+1)};let newFuncHead=getFunctionHead(method);let newFuncBody=getFunctionBody(method);let newFunc;try{if(newFuncHead.includes("function")){let varName=newFuncHead.split("(")[1].split(")")[0];newFunc=new Function(varName,newFuncBody)}else{if(newFuncHead.substring(0,6)===newFuncBody.substring(0,6)){let varName=newFuncHead.split("(")[1].split(")")[0];newFunc=new Function(varName,newFuncBody.substring(newFuncBody.indexOf("{")+1,newFuncBody.length-1))}else{try{newFunc=(0,eval)(newFuncHead+newFuncBody+"}")}catch(err){newFunc=(0,eval)(method)}}}}catch(err){}return newFunc}var DOMService=class extends Service{constructor(options,parentNode,interpreters){super({props:options?.props,name:options?.name?options.name:`dom${Math.floor(Math.random()*1e15)}`});this.loadDefaultRoutes=false;this.keepState=true;this.parentNode=document.body;this.interpreters={md:(template,options)=>{if(typeof markdownit==="undefined"){document.head.insertAdjacentHTML("beforeend",` + `})}else{template+=``}template+=``;return template}var defaultServiceWorker=function(cacheExpirationDays=4/24){return`//https://github.com/ibrahima92/pwa-with-vanilla-js - -//https://github.com/ibrahima92/pwa-with-vanilla-js -let cacheName = 'pwa-assets'; -const assets = [ - "/", - "/index.html", - "/dist/index.css", //alt default paths - "/dist/index.js", - '/favicon.ico' -]; - -let cacheExpiration = 1000 * 60 * //seconds - 60 * //minutes - 24 * //hours - ${cacheExpirationDays}; //days - -let isValid = function (response) { - if (!response) return false; - var fetched = response.headers.get('sw-fetched-on'); - if (fetched && (!navigator.onLine || (parseFloat(fetched) + (cacheExpiration)) > new Date().getTime())) - return true; - return false; -}; - -self.addEventListener("install", installEvent => { - installEvent.waitUntil( - caches.open(cacheName).then(cache => { - cache.addAll(assets); - }) - ); -}); - -self.addEventListener("fetch", fetchEvent => { //https://gomakethings.com/how-to-set-an-expiration-date-for-items-in-a-service-worker-cache/ - fetchEvent.respondWith( - caches.match(fetchEvent.request).then(function (response) { - - // If there's a cached API and it's still valid, use it - if (isValid(response)) { - return response; - } - - // Otherwise, make a fresh API call - if(response && !assets.includes(fetchEvent.request.url)) return response; - // Otherwise, make a fresh API call - else return fetch(fetchEvent.request).then(function (response) { - - // Cache for offline access - if(assets.includes(fetchEvent.request.url)){ - var copy = response.clone(); - fetchEvent.waitUntil(caches.open(cacheName).then(function (cache) { - var headers = new Headers(copy.headers); - headers.append('sw-fetched-on', new Date().getTime()); - return copy.blob().then(function (body) { - return cache.put(fetchEvent.request, new Response(body, { - status: copy.status ? copy.status : 200, - statusText: copy.statusText, - headers: headers - })); - }); - })); - } - - // Return the requested file - return response; - - }) - // .catch(function (error) { - // return caches.match(request).then(function (response) { //fallback to offline cache - // return response || caches.match('/offline.json'); //todo: figure out what is supposed to go in offline.json (https://gomakethings.com/how-to-set-an-expiration-date-for-items-in-a-service-worker-cache/) - // }); - // }); - })); -}); - -`};var defaultManifest=(pwaName="PWA")=>{return`{ - "short_name": "${pwaName}", - "name": "${pwaName}", - "start_url": "/", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff", - "description": "${pwaName} Test", - "lang": "en-US", - "permissions": [ - "storage" - ], - "icons":[{ - "src": "./assets/logo196.png", - "sizes": "196x196" - }, - { - "src": "./assets/logo512.png", - "sizes": "512x512" - }] -}`};var HTTPbackend=class extends Service{name="http";server;debug=false;servers={};mimeTypes={".html":"text/html",".htm":"text/html",".js":"text/javascript",".css":"text/css",".json":"application/json",".txt":"text/plain",".png":"image/png",".jpg":"image/jpg",".jpeg":"image/jpg",".gif":"image/gif",".svg":"image/svg+xml",".xhtml":"application/xhtml+xml",".bmp":"image/bmp",".wav":"audio/wav",".mp3":"audio/mpeg",".mp4":"video/mp4",".xml":"application/xml",".webm":"video/webm",".webp":"image/webp",".weba":"audio/webm",".woff":"font/woff","woff2":"font/woff2",".ttf":"application/font-ttf",".eot":"application/vnd.ms-fontobject",".otf":"application/font-otf",".wasm":"application/wasm",".zip":"application/zip",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".tif":"image/tiff",".sh":"application/x-sh",".csh":"application/x-csh",".rar":"application/vnd.rar",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".odt":"application/vnd.oasis.opendocument.text",".ods":"application/vnd.oasis.opendocument.spreadsheet",".odp":"application/vnd.oasis.opendocument.presentation",".mpeg":"video/mpeg",".mjs":"text/javascript",".cjs":"text/javascript",".jsonld":"application/ld+json",".jar":"application/java-archive",".ico":"image/vnd.microsoft.icon",".gz":"application/gzip","epub":"application/epub+zip",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".csv":"text/csv",".avi":"video/x-msvideo",".aac":"audio/aac",".mpkg":"application/vnd.apple.installer+xml",".oga":"audio/ogg",".ogv":"video/ogg","ogx":"application/ogg",".php":"application/x-httpd-php",".rtf":"application/rtf",".swf":"application/x-shockwave-flash",".7z":"application/x-7z-compressed",".3gp":"video/3gpp"};constructor(options,settings){super(options);this.load(this);if(settings){this.setupServer(settings)}}onStarted=(protocol,host,port)=>{console.log(`\u{1F431} Node server running at - ${protocol}://${host}:${port}/`)};setupServer=(options={protocol:"http",host:"localhost",port:8080,startpage:"index.html"},requestListener,onStarted)=>{if(options.pages){for(const key in options.pages){if(typeof options.pages[key]==="string"){this.addPage(`${options.port}/${key}`,options.pages[key])}else if(typeof options.pages[key]==="object"||typeof options.pages[key]==="function"){if(options.pages[key].template){options.pages[key].get=options.pages[key].template}let rt=`${options.port}/${key}`;if(key!=="_all")this.load({[rt]:options.pages[key]})}}}this.setupHTTPserver(options,requestListener,onStarted)};open=this.setupServer;setupHTTPserver=(options={host:"localhost",port:8080,startpage:"index.html",errpage:void 0},requestListener,onStarted=()=>{this.onStarted("http",options.host,options.port)})=>{const host=options.host?options.host:"localhost";const port=options.port?options.port:8e3;if(!host||!port)return;const address=`${host}:${port}`;if(this.servers[address])this.terminate(this.servers[address]);if(!("keepState"in options))options.keepState=true;const served={server:void 0,type:"httpserver",address,...options};if(!requestListener)requestListener=(request,response)=>{let received={args:{request,response},method:request.method,served};let url=request.url.slice(1);if(!url)url="/";if(options.debug){let time=getHoursAndMinutes(new Date);console.log(time," | ","From: ",request.socket?.remoteAddress,"For: ",request.url," | ",request.method)}if(options.pages){getPageOptions.call(this,url,received,options.pages,request,response,options.port)}else received.route=url;this.receive(received)};let server=void 0;if(options.protocol==="http")server=http.createServer(requestListener);else{let opts;if(options.keypath&&options.certpath){opts={key:fs.readFileSync(options.keypath),cert:fs.readFileSync(options.certpath),passphrase:options.passphrase};server=https.createServer(opts,requestListener)}else console.error("Error, key and/or cert .pem SSL files not provided. See OpenSSL certbot for more info on how to create free SSL certifications, or create your own self-signed one for local development.")}if(!server){console.error("Server not successfully created.");return void 0}served.server=server;served.terminate=()=>{this.terminate(served)};served.service=this;this.servers[address]=served;served._id=options._id?options._id:address;return new Promise((resolve,reject)=>{let resolved;server.on("error",err=>{if(served.onerror)served.onerror(err,served);else console.error("Server error:",err.toString());if(!resolved)reject(err)});server.on("clientError",(err,socket)=>{if(served.onerror)served.onerror(err,served);else console.error(getHoursAndMinutes(new Date)," | Server clientError:",err.toString()," | From: ",socket.remoteAddress);if(socket)socket.destroy()});server.on("tlsClientError",(err,socket)=>{if(served.onerror)served.onerror(err,served);else console.error(getHoursAndMinutes(new Date)," | Server tlsClientError: ",err.toString()," | From: ",socket.remoteAddress);if(socket)socket.destroy()});server.on("upgrade",(request,socket,head)=>{if(served.onupgrade)served.onupgrade(request,socket,head,served)});server.listen(port,host,()=>{onStarted();if(served.onopen)served.onopen(served);resolved=true;resolve(served)})})};transmit=(message,options,ondata,onend)=>{let input=message;if(typeof input==="object"&&!input.byteLength)input=JSON.stringify(input);if(typeof options==="string"&&message)return this.POST(options,message);else if(typeof options==="string")return this.GET(options);if(!options){let server=this.servers[Object.keys(this.servers)[0]];options={protocol:server.protocol,host:server.host,port:server.port,method:"POST",path:message.route,headers:{"Content-Type":"application/json","Content-Length":input.length}}}else if(!options.headers){options.headers={"Content-Type":"application/json","Content-Length":input.length}}return this.request(options,input,ondata,onend)};withResult=(response,result,message)=>{if(result&&!response.writableEnded&&!response.destroyed){let mimeType="text/plain";let head={};if(typeof result==="string"){let extname2=path.extname(result);if(extname2&&fs.existsSync(path.join(process.cwd(),result))){mimeType=this.mimeTypes[extname2]||"application/octet-stream";result=fs.readFileSync(path.join(process.cwd(),result));if(mimeType==="text/html"&&(message.served?.pages?._all||message.served?.pages?.[message.route])){let{templateString,headers}=this.injectPageCode(result.toString(),message.route,message.served);result=templateString;Object.assign(head,headers)}}else if(typeof result==="string"&&result.includes("<")&&result.includes(">")&&result.indexOf("<")")){head["Content-Type"]="text/html";if(message?.served?.pages?._all||message?.served?.pages?.[message.route]){let{templateString,headers}=this.injectPageCode(result,message.route,message.served);result=templateString;Object.assign(head,headers)}response.writeHead(200,head);response.end(result,"utf-8");return}}else if(typeof result==="object"){result=JSON.stringify(result);mimeType="application/json"}head["Content-Type"]=mimeType;response.writeHead(200,head);response.end(result,"utf-8")}else{try{response.destroy()}catch{}}};injectPageCode=(templateString,url,served)=>{if(served?.pages?.[url]?.inject){if(typeof served.pages[url].inject==="object")templateString=this.buildPage(served.pages[url].inject,templateString);else if(typeof served.pages[url].inject==="function")templateString+=served.pages[url].inject();else if(typeof served.pages[url].inject==="string"||typeof served.pages[url].inject==="number")templateString+=served.pages[url].inject}if(served?.pages?._all?.inject){if(typeof served.pages._all.inject==="object")templateString=this.buildPage(served.pages._all.inject,templateString);else if(typeof served.pages._all.inject==="function")templateString+=served.pages._all.inject();else if(typeof served.pages._all.inject==="string"||typeof served.pages._all.inject==="number")templateString+=served.pages._all.inject}let headers={};if(served.pages._all.headers)Object.assign(headers,served.pages._all.headers);if(served.pages[url].headers)Object.assign(headers,served.pages[url].headers);return{templateString,headers}};receive=message=>{if(this.debug)console.log(message.args.request.method,message.args.request.url);let result=new Promise((resolve,reject)=>{this.responsePromiseHandler(resolve,reject,message,message.args.request,message.args.response,message.method,message.served)}).catch(er=>{console.error("Request Error:",er)});return result};responseOnErrorPromiseHandler=(response,reject,err)=>{if(!response.writableEnded||!response.destroyed){response.statusCode=400;response.end(void 0,void 0);reject(err)}else{try{response.destroy()}catch{}reject(err)}};getFailedPromiseHandler=(resolve,reject,requestURL,message,response,served)=>{if(response.writableEnded||response.destroyed)reject(requestURL);if(requestURL=="./"||requestURL==served?.startpage){let template=`

Brains@Play Server

`;if(served?.pages?._all||served?.pages?.error){let{templateString,headers}=this.injectPageCode(template,message.route,served);template=templateString}response.writeHead(200,{"Content-Type":"text/html"});response.end(template,"utf-8");resolve(template);if(served?.keepState)this.setState({[served.address]:template});return}else if(this.debug)console.log(`File ${requestURL} does not exist on path!`);response.writeHead(500);response.end(void 0,void 0);reject(requestURL)};handleBufferedPostBodyPromiseHandler=(resolve,body,message,response,served)=>{body=Buffer.concat(body).toString();if(typeof body==="string"){let substr=body.substring(0,8);if(substr.includes("{")||substr.includes("[")){if(substr.includes("\\"))body=body.replace(/\\/g,"");if(body[0]==='"'){body=body.substring(1,body.length-1)};body=JSON.parse(body)}}let route,method,args;if(body?.route){route=body.route;method=body.method;args=body.args;if(!route){if(typeof body.route==="string"){if(body.route.includes("/")&&body.route.length>1)body.route=body.route.split("/").pop()}route=body.route}}if(!route){if(message?.route){let route2=message.route;method=message.method;args=message.args;if(!route2){if(typeof message.route==="string"){if(message.route.includes("/")&&message.route.length>1)message.route=message.route.split("/").pop()}route2=message.route}}}let res=body;if(route){if(this.restrict?.[route]){try{response.destroy()}catch{}resolve(res)}else{if(body.method){res=this.handleMethod(route,method,args)}else if(body.node){res=this.handleGraphNodeCall(body.node,body.args)}else res=this.handleServiceMessage({route,args,method});if(res instanceof Promise){res.then(r=>{this.withResult(response,r,message);if(served?.keepState)this.setState({[served.address]:res});resolve(res)})}else{this.withResult(response,res,message);if(served?.keepState)this.setState({[served.address]:res});resolve(res)}}}else if(!response.writableEnded||!response.destroyed){response.statusCode=200;response.end(void 0,void 0);resolve(res)}else{try{response.destroy()}catch{}resolve(res)}};onRequestFileReadPromiseHandler=(error,content,resolve,reject,requestURL,response,message,served)=>{if(error){if(error.code=="ENOENT"){if(served?.errpage){fs.readFile(served.errpage,(er,content2)=>{response.writeHead(404,{"Content-Type":"text/html"});if(served.pages?._all||served.pages?.error){let{templateString,headers}=this.injectPageCode(content2.toString(),message.route,served);content2=templateString}response.end(content2,"utf-8");reject(content2)})}else{response.writeHead(404,{"Content-Type":"text/html"});let content2=`

Error: ${error.code}

`;if(served?.pages?._all||served?.pages?.[message.route]){let{templateString,headers}=this.injectPageCode(content2.toString(),message.route,served);content2=templateString}response.end(content2,"utf-8");reject(error.code)}}else{response.writeHead(500);response.end("Something went wrong: "+error.code+" ..\n","utf-8");reject(error.code)}}else{var extname2=String(path.extname(requestURL)).toLowerCase();var contentType=this.mimeTypes[extname2]||"application/octet-stream";let head={"Content-Type":contentType};if(contentType==="text/html"&&(served?.pages?._all||served?.pages?.[message.route])){let{templateString,headers}=this.injectPageCode(content.toString(),message.route,served);Object.assign(head,headers);content=templateString}response.writeHead(200,head);response.end(content,"utf-8");resolve(content)}};responsePromiseHandler=(resolve,reject,message,request,response,method,served)=>{response.on("error",err=>{if(served.debug){let time=getHoursAndMinutes(new Date);console.error(time,"| Response Error: ",err," From: ",request.socket?.remoteAddress," For: ",request.url," | ",request.method)}this.responseOnErrorPromiseHandler(response,reject,err);request.destroy();request.socket?.destroy()});if(method==="GET"||method==="get"){var requestURL="."+request.url;if(request.url&&this.restrict?.[request.url])reject(request.url);if(requestURL=="./"&&served?.startpage){requestURL=served.startpage}if(requestURL.includes("?"))requestURL=requestURL.substring(0,requestURL.indexOf("?"));if((request.url!=="/"||served?.startpage)&&fs.existsSync(path.join(process.cwd(),requestURL))){if(response.writableEnded||response.destroyed)reject(requestURL);else{fs.readFile(path.join(process.cwd(),requestURL),(error,content)=>{this.onRequestFileReadPromiseHandler(error,content,resolve,reject,requestURL,response,message,served)})}}else if(message.route){let route;if(served){let rt=`${served.port}/${message.route}`;if(this.__node.nodes.get(rt))route=rt}if(!route&&this.__node.nodes.get(message.route))route=message.route;if(route){let res;if(message.method){res=this.handleMethod(route,message.method,void 0)}else if(message.node){res=this.handleGraphNodeCall(message.node,void 0)}else res=this.handleServiceMessage({route,args:void 0,method:message.method});if(res instanceof Promise)res.then(r=>{if(served?.keepState)this.setState({[served.address]:res});this.withResult(response,r,message);resolve(res)});else if(res){if(served?.keepState)this.setState({[served.address]:res});this.withResult(response,res,message);resolve(res)}}else if(message.redirect){response.writeHead(301,{"Location":message.redirect});response.end();resolve(true)}else this.getFailedPromiseHandler(resolve,reject,requestURL,message,response,served)}else this.getFailedPromiseHandler(resolve,reject,requestURL,message,response,served)}else{let requestBody;let timedOut=true;let timeout;request.on("data",chunk=>{if(!requestBody)requestBody=[];requestBody.push(chunk);if(timedOut){timedOut=false;if(timeout)clearTimeout(timeout)}}).on("end",()=>{this.handleBufferedPostBodyPromiseHandler(resolve,requestBody,message,response,served)});timeout=setTimeout(()=>{if(timedOut){let errMessage=new Error(`Request timed out from | ${request.socket?.remoteAddress} | For: ${request.url} | ${request.method}`);request.destroy(errMessage);served.server.emit("clientError",errMessage,request.socket);if(served.debug){console.error(errMessage)}reject(errMessage)}},served.timeout?served.timeout:1e3)}};request=(options,send,ondata,onend)=>{let client=http;if(options.protocol?.includes("https")){client=https}delete options.protocol;const req=client.request(options,res=>{if(ondata)res.on("data",ondata);if(onend)res.on("end",onend)});if(options.headers){for(const head in options.headers){req.setHeader(head,options.headers[head])}}if(send)req.write(send);req.end();return req};POST=(url,data,headers)=>{let urlstring=url;if(urlstring instanceof URL)urlstring=url.toString();let protocol=urlstring.startsWith("https")?"https":"http";let host,port,path3;let split=urlstring.split("/");split.forEach(s=>{if(s.includes(":")){let ss=s.split(":");host=ss[0];port=ss[1]}});if(split.length>3){path3=split.slice(3).join("/")}let req=this.request({protocol,host,port,path:path3,method:"POST",headers},data);return req};GET=url=>{return new Promise((resolve,reject)=>{let client=http;let urlstring=url;if(url instanceof URL)urlstring=url.toString();if(urlstring.includes("https")){client=https}client.get(url,resp=>{let chunks=[];resp.on("data",chunk=>{chunks.push(chunk)});resp.on("end",()=>{resolve(Buffer.concat(chunks))})}).on("error",err=>{reject(err)})})};terminate=served=>{if(typeof served==="string")served=this.servers[served];if(typeof served==="object"){served.server.close();if(served.onclose)served.onclose(served)}};getRequestBody(req){let chunks=[];return new Promise((resolve,reject)=>{req.on("data",chunk=>{chunks.push(chunk)}).on("end",()=>{resolve(Buffer.concat(chunks))}).on("error",er=>{let errMessage=new Error(`Request timed out from | ${req.socket?.remoteAddress} | For: ${req.url} | ${req.method}`);req.destroy(errMessage);reject(errMessage)})})}addPage=(path3,template)=>{if(typeof template==="string"){if(!template.includes(""+template+""}if(typeof this.__node.roots?.[path3]==="object"){this.__node.roots[path3].get=template;this.__node.nodes.get(path3).get=template}else this.load({[path3]:{get:template}})};addHTML=(path3,template)=>{if(typeof template==="string"){if(!template.includes("<")||!template.includes(">"))template="
"+template+"
"}if(typeof this.__node.roots?.[path3]==="object"){this.__node.roots[path3].get=template;this.__node.nodes.get(path3).get=template}else this.load({[path3]:{get:template}})};buildPage=(pageStructure,baseTemplate)=>{let result=``;if(baseTemplate)result+=baseTemplate;let appendTemplate=(obj,r,res)=>{if(!Array.isArray(obj[r])&&typeof obj[r]==="object"){for(const key in obj){appendTemplate(obj,key,res)}}else if(this.__node.nodes.get(r)?.get){let toAdd=this.__node.nodes.get(r)?.get;if(typeof toAdd==="function"){if(Array.isArray(obj[r])){toAdd=toAdd(...obj[r])}else toAdd=toAdd(obj[r])}if(typeof toAdd==="string"){let lastDiv=res.lastIndexOf("<");if(lastDiv>0){let end=res.substring(lastDiv);res=res.substring(0,lastDiv)+toAdd+end}else res+=toAdd}}else if(this.__node.nodes.get(r)?.__operator){let routeresult;if(this.__node.nodes.get(r)?.__operator)routeresult=this.__node.nodes.get(r).__operator(obj[r]);if(typeof routeresult==="string"){let lastDiv=res.lastIndexOf("<");if(lastDiv>0){let end=res.substring(lastDiv);res=res.substring(0,lastDiv)+routeresult+end}else res+=routeresult}}else if(typeof this.__node.nodes.get(r)==="string")res+=this.__node.nodes.get(r);return res};if(Array.isArray(pageStructure)){pageStructure.forEach(r=>{result=appendTemplate(pageStructure,r,result)})}else if(typeof pageStructure==="object"){for(const r in pageStructure){result=appendTemplate(pageStructure,r,result)}}else if(typeof pageStructure==="string")result+=pageStructure;else if(typeof pageStructure==="function")result+=pageStructure();return result};hotreload=(socketURL=`http://localhost:8080/wss`,esbuild_cssFileName)=>{if(socketURL instanceof URL)socketURL=socketURL.toString();const HotReloadClient=(socketUrl,esbuild_cssFileName2)=>{let socket=new WebSocket(socketUrl);function reloadLink(file){let split=file.includes("/")?file.split("/"):file.split("\\");let fname=split[split.length-1];var links=document.getElementsByTagName("link");for(var cl in links){var link=links[cl];if(!file||link.href?.includes(fname)){let href=link.getAttribute("href").split("?")[0];let newHref=href+="";link.setAttribute("href",newHref)}}}function reloadAsset(file,reloadscripts,isJs){let split=file.includes("/")?file.split("/"):file.split("\\");let fname=split[split.length-1];let elements=document.querySelectorAll("[src]");let found=false;for(const s of elements){if(s.src.includes(fname)){if(s.tagName==="SCRIPT"&&!reloadscripts){window.location.reload();return}else{let placeholder=document.createElement("object");s.insertAdjacentElement("afterend",placeholder);s.remove();let elm=s.cloneNode(true);placeholder.insertAdjacentElement("beforebegin",elm);placeholder.remove();found=true}}}if(!found)window.location.reload()}socket.addEventListener("message",ev=>{let message=ev.data;if(typeof message==="string"&&message.startsWith("{")){message=JSON.parse(message)}if(message.file){let f=message.file;let rs=message.reloadscripts;if(f.endsWith("html")||f.endsWith("xml")||f.endsWith("wasm")){window.location.reload()}else if(f.endsWith("css")){if(!esbuild_cssFileName2.endsWith("css"))esbuild_cssFileName2+=".css";reloadLink(esbuild_cssFileName2)}else if(f.endsWith("js")||f.endsWith("ts")||f.endsWith("jsx")||f.endsWith("tsx")||f.endsWith("vue")){reloadAsset(f,rs)}else{reloadLink(f);reloadAsset(f)}}});socket.addEventListener("close",()=>{const interAttemptTimeoutMilliseconds=100;const maxDisconnectedTimeMilliseconds=3e3;const maxAttempts=Math.round(maxDisconnectedTimeMilliseconds/interAttemptTimeoutMilliseconds);let attempts=0;const reloadIfCanConnect=()=>{attempts++;if(attempts>maxAttempts){console.error("Could not reconnect to dev server.");return}socket=new WebSocket(socketUrl);socket.onerror=er=>{console.error(`Hot reload port disconnected, will reload on reconnected. Attempt ${attempts} of ${maxAttempts}`)};socket.addEventListener("error",()=>{setTimeout(reloadIfCanConnect,interAttemptTimeoutMilliseconds)});socket.addEventListener("open",()=>{location.reload()})};reloadIfCanConnect()})};return` - - `};pwa=(pwaName="PWA",cacheExpirationDays=4/24,serviceWorkerUrl="service-worker.js")=>{if(!fs.existsSync(serviceWorkerUrl)){fs.writeFileSync(path.join(process.cwd(),serviceWorkerUrl),defaultServiceWorker(cacheExpirationDays))}if(!fs.existsSync("manifest.webmanifest")){fs.writeFileSync(path.join(process.cwd(),"/manifest.webmanifest"),defaultManifest(pwaName))}function ServiceWorkerInstaller(serviceWorkerUrl2){if(!Array.from(document.head.querySelectorAll("link")).find(elm=>{if(elm.href.includes("manifest"))return true})){document.head.insertAdjacentHTML("beforeend",``)}const isLocalhost=Boolean(window.location.hostname==="localhost"||window.location.hostname==="[::1]"||window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/));function registerSW(){navigator.serviceWorker.register(serviceWorkerUrl2).then(registration=>{registration.onupdatefound=()=>{const installingWorker=registration.installing;if(installingWorker==null){return}installingWorker.onstatechange=()=>{if(installingWorker.state==="installed"){if(navigator.serviceWorker.controller){console.log("New content is available and will be used when all tabs for this page are closed.")}else{console.log("Content is cached for offline use.")}}}}}).catch(error=>{console.error("Error during service worker registration:",error)})}if("serviceWorker"in navigator)addEventListener("load",()=>{if(isLocalhost){fetch(serviceWorkerUrl2).then(response=>{const contentType=response.headers.get("content-type");if(response.status===404||contentType!=null&&contentType.indexOf("javascript")===-1){navigator.serviceWorker.ready.then(registration=>{registration.unregister().then(()=>{window.location.reload()})})}else{registerSW()}}).catch(()=>{console.log("No internet connection found. App is running in offline mode.")});navigator.serviceWorker.ready.then(()=>{console.log("This web app is being served cache-first by a service worker.")})}else{registerSW()}})}return` - - `}};function getPageOptions(url,received,pages,request,response,port){let pageOptions=pages[url];let key=url;if(!pageOptions){let url2="/"+url;pageOptions=pages[url2];key=url2;if(!pageOptions&&!path.extname(url)){let split=url.split("/");key=split[0]+"/*";if(pages[key]){pageOptions=pages[key];received.route=key;request.url=key}else{let spl=url2.split("/");spl[spl.length-1]="";key=spl.join("/")+"*";if(pages[key]){pageOptions=pages[key];received.route=key;request.url=key}}}else{received.route=url2;request.url=url2}}else{received.route=url;request.url=url}if(typeof pageOptions==="object"){if(pageOptions.redirect){url=pageOptions.redirect;received.redirect=url;received.route=url}if(pageOptions.onrequest){if(typeof pageOptions.onrequest==="string"){pageOptions.onrequest=this.__node.nodes.get(pageOptions.onrequest)}if(typeof pageOptions.onrequest==="object"){if(pageOptions.onrequest.__operator){pageOptions.onrequest.__operator(pageOptions,request,response)}}else if(typeof pageOptions.onrequest==="function"){pageOptions.onrequest(this,this.__node.nodes.get(`${port}/${key}`),request,response)}}}return pageOptions}function getHoursAndMinutes(date){let hours=date.getHours();let minutes=date.getMinutes();hours=hours<10?"0"+hours:hours;minutes=minutes<10?"0"+minutes:minutes;return`${hours}:${minutes}`}var import_better_sse=__toESM(require_build());var SSEbackend=class extends Service{name="sse";debug=false;servers={};eventsources={};connections={servers:this.servers,eventsources:this.eventsources};constructor(options){super(options);this.load(this)}openSSE=options=>{const server=options.server;let path3=options.path;if(this.servers[path3]){return false}const channel=(0,import_better_sse.createChannel)();let sse={type:"sse",channel,sessions:{},requests:{},...options};this.servers[path3]=sse;sse._id=options._id?options._id:path3;const send=(message,eventName,sessionId)=>{return this.transmit(message,path3,eventName,sessionId)};const terminate=()=>{return this.terminate(path3)};let request=(message,method,sessionId,eventName)=>{if(!sessionId){let promises=[];for(const key in sse.sessions){promises.push(this.request(message,path3,key,eventName))}return promises}return this.request(message,path3,method,sessionId,eventName)};let post=(route,args,method,sessionId,eventName)=>{let message={route,args};if(method)message.method=method;return this.transmit(message,path3,eventName,sessionId)};let run=(route,args,method,sessionId,eventName)=>{let r={route,args};if(!sessionId){let promises=[];for(const key in sse.sessions){promises.push(this.request(r,path3,key,eventName))}return promises}return this.request(r,path3,method,sessionId,eventName)};let subscribe=(route,callback,args,key,subInput,sessionId,eventName)=>{return this.subscribeToSSE(route,options.url,callback,args,key,subInput,sessionId,eventName)};let unsubscribe=(route,sub,sessionId,eventName)=>{return run("unsubscribe",[route,sub],void 0,sessionId,eventName)};sse.send=send;sse.request=request;sse.post=post;sse.run=run;sse.subscribe=subscribe;sse.unsubscribe=unsubscribe;sse.terminate=terminate;sse.graph=this;let onRequest=(req,response)=>{if(req.url?.includes(path3)){if(req.method==="GET"){if(this.debug)console.log("SSE Request",path3);(0,import_better_sse.createSession)(req,response).then(session=>{channel.register(session);let _id=`sse${Math.floor(Math.random()*1e15)}`;sse.sessions[_id]=session;this.eventsources[_id]={_id,session,served:sse,send:(message,eventName)=>{return send(message,eventName,_id)},request:(message,method,eventName)=>{return request(message,method,_id,eventName)},post:(route,args,method,eventName)=>{return post(route,args,method,_id,eventName)},run:(route,args,method,eventName)=>{return run(route,args,method,_id,eventName)},subscribe:(route,callback)=>{return subscribe(route,callback,void 0,_id)},unsubscribe:(route,sub,eventName)=>{return unsubscribe(route,sub,_id,eventName)},terminate:()=>{delete this.eventsources[_id];delete sse.sessions[_id];return true},onclose:(session2,sse2,_id2,req2,res)=>{if(sse2.onconnectionclose)sse2.onconnectionclose(session2,sse2,_id2,req2,res)},graph:this};session.push(JSON.stringify({route:"setId",args:_id}));session.on("close",()=>{let obj=this.eventsources[_id];let onclose=obj.onclose;delete this.eventsources[_id];if(onclose)obj.onclose(session,sse,_id,req,response)});if(sse.onconnection){sse.onconnection(session,sse,_id,req,response)}})}else{let body=[];req.on("data",chunk=>{body.push(chunk)}).on("end",()=>{body=Buffer.concat(body).toString();if(typeof body==="string"){let substr=body.substring(0,8);if(substr.includes("{")||substr.includes("[")){if(substr.includes("\\"))body=body.replace(/\\/g,"");if(body[0]==='"'){body=body.substring(1,body.length-1)};body=JSON.parse(body)}}let route,method,args,callbackId;if(body?.route||body?.callbackId){method=body.method;args=body.args;callbackId=body.callbackId;if(typeof body.route==="string"){if(body.route.includes("/")&&body.route.length>1)body.route=body.route.split("/").pop();route=this.__node.roots?.[body.route]}}if(route){let res=this.receive({route,args,method})}else if(callbackId&&sse.requests[callbackId]){sse.requests[callbackId](args)}if(this.__node.keepState)this.setState({[path3]:body})})}}};let requestListeners=server.listeners("request");server.removeAllListeners("request");const otherListeners=(req,res)=>{requestListeners.forEach(l=>{l(req,res)})};const sseListener=(req,res)=>{if(req.url)if(req.url.indexOf(path3)>-1){if(!this.servers[path3]){server.removeListener("request",sseListener);server.addListener("request",otherListeners)}onRequest(req,res)}else otherListeners(req,res)};server.addListener("request",sseListener);server.addListener("close",()=>{if(sse.onclose)sse.onclose(sse)});return sse};open=this.openSSE;streamIterable=(path3,iterable,sessionId,eventName="message")=>{let server=this.servers[path3];if(server){if(sessionId){if(server.sessions[sessionId]){return server.sessions[sessionId].iterate(iterable,{eventName})}}else{let promises=[];for(const key in server.sessions){promises.push(server.sessions[key].iterate(iterable))}return promises}}};streamReadable=(path3,readable,sessionId,eventName="message")=>{let server=this.servers[path3];if(server){if(sessionId){if(server.sessions[sessionId]){return server.sessions[sessionId].stream(readable,{eventName})}}else{let promises=[];for(const key in server.sessions){promises.push(server.sessions[key].stream(readable))}return promises}}};transmit=(data,path3,eventName,sessionId)=>{if(!path3&&(typeof data==="object"&&!data.byteLength||typeof data==="number")){if(data?.route){let keys=Object.keys(this.servers);if(keys.length>0){let evs=this.servers[keys[0]];if(evs.channels?.includes(data.route)){path3=evs.path;eventName=data.route}}if(!path3&&data.route){if(this.servers[data.route])path3=data.route}}data=JSON.stringify(data)}if(!path3)path3=Object.keys(this.servers)[0];if(path3&&this.servers[path3]){if(sessionId){if(this.servers[path3].sessions[sessionId]?.isConnected){this.servers[path3].sessions[sessionId].push(data,eventName)}else if(this.servers[path3].sessions[sessionId]){delete this.servers[path3].sessions[sessionId];return false}}else this.servers[path3].channel.broadcast(data,eventName);return true}return false};request=(message,path3,method,sessionId,eventName)=>{return new Promise((res,rej)=>{let callbackId=`${Math.random()}`;let req={route:"runRequest",args:[message,path3,callbackId,sessionId]};if(method)req.method=method;let sse=this.servers[path3];let callback=result=>{res(result)};sse.requests[callbackId]=callback;if(sse){if(sessionId){if(sse.sessions[sessionId])sse.sessions[sessionId].push(JSON.stringify(req),eventName)}else sse.channel.broadcast(JSON.stringify(req),eventName)}})};runRequest=(message,path3,callbackId,sessionId)=>{let res=this.receive(message);if(path3){let sse=this.servers[path3];if(sse){if(res instanceof Promise){res.then(r=>{if(sessionId){if(sse.sessions[sessionId]){sse.sessions[sessionId].push(JSON.stringify({args:r,callbackId}))}}else{sse.channel.broadcast(JSON.stringify({args:r,callbackId}))}})}else{if(sessionId){if(sse.sessions[sessionId]){sse.sessions[sessionId].push(JSON.stringify({args:res,callbackId}))}}else sse.channel.broadcast(JSON.stringify({args:res,callbackId}))}}}return res};subscribeSSE=(route,path3,args,key,subInput,sessionId,eventName)=>{if(this.restrict?.[route])return void 0;if(this.servers[path3]){return this.subscribe(route,res=>{this.servers[path3].send({args:res,callbackId:route},eventName,sessionId)},args,key,subInput)}};subscribeToSSE=(route,path3,callback,args,key,subInput,sessionId,eventName)=>{if(this.servers[path3]){this.__node.state.subscribeEvent(path3,res=>{if(res?.callbackId===route){if(!callback)this.setState({[path3]:res.args});else if(typeof callback==="string"){this.run(callback,res.args)}else callback(res.args)}});if(sessionId){if(this.servers[path3].sessions[sessionId]){return this.eventsources[sessionId].run("subscribeSSE",{route:"subscribeSSE",args:[route,path3,args,key,subInput]},void 0,eventName)}}else{let promises=[];for(const k in this.servers[path3].sessions){promises.push(this.eventsources[k].run("subscribeSSE",{route:"subscribeSSE",args:[route,path3,args,key,subInput]},void 0,eventName))}return promises}}};terminate=sse=>{if(typeof sse==="object")delete this.servers[sse.path];else if(typeof sse==="string"){delete this.servers[sse];delete this.eventsources[sse]}return true}};var import_stream=__toESM(require_stream(),1);var import_receiver=__toESM(require_receiver(),1);var import_sender=__toESM(require_sender(),1);var import_websocket=__toESM(require_websocket(),1);var import_websocket_server=__toESM(require_websocket_server(),1);var wrapper_default=import_websocket.default;var WSSbackend=class extends Service{name="wss";debug=false;servers={};sockets={};connections={servers:this.servers,sockets:this.sockets};constructor(options){super(options);this.load(this)}open=options=>{if(options?.server){return this.setupWSS(options)}else return this.openWS(options)};setupWSS=options=>{let port=options.port;let path3=options.path;const server=typeof options.server==="object"?options.server:void 0;let host=options.host;delete options.server;if(!("keepState"in options))options.keepState=true;let opts={};if(options.noServer)opts.noServer=true;else if(port){if(port)opts.port=port}else if(server)opts.server=server;if(options.perMessageDeflate)opts.perMessageDeflate=options.perMessageDeflate;if(typeof options.serverOptions)Object.assign(opts,options.serverOptions);const wss=new import_websocket_server.default(opts);let address="";if(!host&&server){let addr=server.address();if(!port)port=addr.port;address=addr.address}else if(host)address=host;if(port)address+=":"+port;if(path3){if(!path3.startsWith("/"))path3="/"+path3;address+=path3}this.servers[address]={type:"wss",wss,clients:{},address,...options};if(!options.onmessage)options.onmessage=data=>{if(data instanceof Buffer)data=data.toString();if(options.debug){console.log(data)}const result=this.receive(data,wss,this.servers[address]);if(options.keepState)this.setState({[address]:result})};wss.addListener("connection",(ws,request2)=>{if(this.debug)console.log(`New socket connection on ${address}`);let clientId=`socket${Math.floor(Math.random()*1e12)}`;this.servers[address].clients[clientId]=ws;ws.send(JSON.stringify({route:"setId",args:clientId}));this.openWS({socket:ws,address:clientId,_id:clientId,debug:options.debug,onclose:(code,reason)=>{if(this.servers[address].onconnectionclosed)this.servers[address].onconnectionclosed(code,reason,ws,this.servers[address],clientId);delete this.servers[address].clients[clientId]}});if(options.debug){let time=getHoursAndMinutes2(new Date);console.log(time," | ",clientId," | Number of live sockets: ",Object.keys(this.servers[address].clients).length)}if(this.servers[address].onconnection)this.servers[address].onconnection(ws,request2,this.servers[address],clientId)});wss.on("error",err=>{if(this.debug)console.log("Socket Error:",err);if(this.servers[address].onerror)this.servers[address].onerror(err,wss,this.servers[address]);else console.error(err)});let onUpgrade=(request2,socket,head)=>{if(request2.headers&&request2.url){if(this.debug)console.log("Upgrade request at: ",request2.url);let pass=false;if(path3&&request2.url===path3)pass=true;else{let addr=request2.headers.host.split(":")[0];if(port)addr+=":"+port;if(addr===address)pass=true;else{addr+=request2.url.split("?")[0];if(addr===address)pass=true}}if(pass&&this.servers[address]){this.servers[address].wss.handleUpgrade(request2,socket,head,ws=>{if(this.servers[address].onupgrade)this.servers[address].onupgrade(ws,this.servers[address],request2,socket,head);this.servers[address].wss.emit("connection",ws,request2)})}}};if(server)server.addListener("upgrade",onUpgrade);wss.addListener("close",()=>{if(server)server.removeListener("upgrade",onUpgrade);if(this.servers[address].onclose)this.servers[address].onclose(wss,this.servers[address]);else console.log(`wss closed: ${address}`);delete this.servers[address]});let send=(message,socketId)=>{if(typeof message==="object")message=JSON.stringify(message);if(!socketId){for(const key in this.servers[address].clients){this.sockets[key].send(message)}}else return this.sockets[socketId].send(message)};let request=(message,method,socketId)=>{if(!socketId){let promises=[];for(const key in this.servers[address].clients){promises.push(this.sockets[key].request(message,method))}return promises}else return this.sockets[socketId].request(message,method)};let post=(route,args,method,socketId)=>{if(!socketId){for(const key in this.servers[address].clients){this.sockets[key].post(route,args,method)}}else return this.sockets[socketId].post(route,args,method)};let run=(route,args,method,socketId)=>{if(!socketId){let promises=[];for(const key in this.servers[address].clients){promises.push(this.sockets[key].run(route,args,method))}return promises}else return this.sockets[socketId].run(route,args,method)};let subscribe=(route,callback,socketId,args,key,subInput)=>{if(!socketId){let promises=[];for(const k in this.servers[address].clients){promises.push(this.sockets[k].subscribe(route,callback,args,key,subInput))}return promises}else this.sockets[socketId].subscribe(route,callback,args,key,subInput)};let unsubscribe=(route,sub,socketId)=>{if(!socketId){let promises=[];for(const key in this.servers[address].clients){promises.push(this.sockets[key].unsubscribe(route,sub))}return promises}else this.sockets[socketId].unsubscribe(route,sub)};let terminate=socketId=>{if(socketId)return this.terminate(socketId);else return this.terminate(address)};this.servers[address].send=send;this.servers[address].request=request;this.servers[address].post=post;this.servers[address].run=run;this.servers[address].subscribe=subscribe;this.servers[address].unsubscribe=unsubscribe;this.servers[address].terminate=terminate;this.servers[address].graph=this;this.servers[address]._id=options._id?options._id:address;return this.servers[address]};openWS=options=>{if(!options.address){let protocol=options.protocol;if(!protocol)protocol="wss";options.address=`${protocol}://${options.host}`;if(options.port)options.address+=":"+options.port;if(!options.path||options.path?.startsWith("/"))options.address+="/";if(options.path)options.address+=options.path}const address=options.address;let socket;if(options.socket)socket=options.socket;else socket=new wrapper_default(address);if(!("keepState"in options))options.keepState=true;if(options.onmessage){socket.on("message",data=>{this.sockets[address].onmessage(data,socket,this.sockets[address])})}else if(options._id){socket.addListener("message",data=>{if(ArrayBuffer.isView(data))data=data.toString();if(options.debug){console.log("Message from ",options._id,": ",data)}this.receive(data,socket,this.sockets[address]);if(options.keepState){this.setState({[address]:data})}})}else{let socketonmessage=data=>{if(ArrayBuffer.isView(data))data=data.toString();if(data){if(options.debug){console.log("Message from ",address,": ",data)}if(typeof data==="string"){let substr=data.substring(0,8);if(substr.includes("{")||substr.includes("[")){if(substr.includes("\\"))data=data.replace(/\\/g,"");if(data[0]==='"'){data=data.substring(1,data.length-1)};data=JSON.parse(data);if(data.route==="setId"){this.sockets[address]._id=data.args;socket.removeEventListener("message",socketonmessage);socket.on("message",data2=>{if(ArrayBuffer.isView(data2))data2=data2.toString();if(options.debug){console.log("Message from ",this.sockets[address]._id,": ",data2)}this.receive(data2,socket,this.sockets[address]);if(options.keepState){this.setState({[address]:data2})}})}}}}this.receive(data,socket,this.sockets[address]);if(options.keepState)this.setState({[address]:data})};socket.addListener("message",socketonmessage);options.onmessage=socketonmessage}socket.addListener("open",()=>{if(this.sockets[address].onopen)this.sockets[address].onopen(socket,this.sockets[address])});socket.addListener("close",(code,reason)=>{let obj=this.sockets[address];let onclose=obj.onclose;delete this.sockets[address];if(onclose)onclose(code,reason,socket,obj)});socket.on("error",er=>{if(this.sockets[address].onerror)this.sockets[address].onerror(er,socket,this.sockets[address])});let send=message=>{return this.transmit(message,socket)};let post=(route,args,method)=>{let message={route,args};if(method)message.method=method;return this.transmit(message,socket)};let run=(route,args,method)=>{return new Promise((res,rej)=>{let callbackId=Math.random();let req={route:"runRequest",args:[{route,args},this.sockets[address]._id,callbackId]};if(method)req.args[0].method=method;let onmessage=ev=>{let data=ev.data;if(typeof data==="string"&&data.indexOf("{")>-1)data=JSON.parse(data);if(typeof data==="object"){if(data.callbackId===callbackId){socket.removeEventListener("message",onmessage);res(data.args)}}};socket.addEventListener("message",onmessage);this.transmit(req,socket)})};let request=(message,method)=>{return this.request(message,socket,this.sockets[address]._id,method)};let subscribe=(route,callback)=>{return this.subscribeToSocket(route,this.sockets[address]._id,callback)};let unsubscribe=(route,sub)=>{return run("unsubscribe",[route,sub])};let terminate=()=>{this.terminate(this.sockets[address]._id)};this.sockets[address]={type:"socket",socket,send,post,request,run,subscribe,unsubscribe,terminate,graph:this,__node:{tag:address},...options};return this.sockets[address]};transmit=(message,ws)=>{if(typeof message==="object"&&(message?.route||message?.node||typeof message.arrayBuffer!=="function"&&typeof message.byteLength!=="number"&&typeof message[0]?.byteLength!=="number")||typeof message==="number")message=JSON.stringify(message);if(!ws){let served=this.servers[Object.keys(this.servers)[0]];if(served)ws=served.wss;else{let s=this.sockets[Object.keys(this.sockets)[0]];if(s)ws=s.socket};}if(ws instanceof import_websocket_server.default){ws.clients.forEach(c=>{c.send(message)})}else if(ws instanceof wrapper_default)ws.send(message)};closeWS=ws=>{if(!ws){let s=this.sockets[Object.keys(this.sockets)[0]];if(s)ws=s.socket}else if(typeof ws==="string"){for(const k in this.sockets){if(k.includes(ws)){ws=this.sockets[k].socket;delete this.sockets[k];break}}}if(ws instanceof wrapper_default){if(ws.readyState===ws.OPEN)ws.close()}return true};terminate=ws=>{let str;if(!ws){let served=Object.keys(this.servers);for(const key in served){this.terminate(key)}let sockets=Object.keys(this.sockets);for(const key in sockets){this.terminate(key)}}else if(typeof ws==="string"){str=ws;for(const k in this.servers){if(k.includes(ws)||this.servers[k]._id===ws){ws=this.servers[k].wss;for(const key in this.servers[k].clients){this.closeWS(this.servers[k].clients[key])}delete this.servers[k];break}}if(!ws){for(const k in this.sockets){if(k.includes(ws)||this.sockets[k]._id===ws){ws=this.sockets[k].socket;delete this.sockets[k];break}}}}if(ws instanceof import_websocket_server.default){ws.close(er=>{if(er)console.error(er)})}else if(ws instanceof wrapper_default){if(ws.readyState===ws.OPEN)ws.close();if(this.get(str?str:ws.url))this.remove(str?str:ws.url)}return true};request=(message,ws,_id,method)=>{let callbackId=`${Math.random()}`;let req={route:"runRequest",args:[message,_id,callbackId]};if(method)req.method=method;return new Promise((res,rej)=>{let onmessage=ev=>{let data=ev.data;if(typeof data==="string"){if(data.includes("callbackId"))data=JSON.parse(data)}if(typeof data==="object"){if(data.callbackId===callbackId){ws.removeEventListener("message",onmessage);res(data.args)}}};ws.addEventListener("message",onmessage);ws.send(JSON.stringify(req))})};runRequest=(message,ws,callbackId)=>{let res=this.receive(message);if(ws){if(typeof ws==="string"){for(const key in this.servers){for(const c in this.servers[key].clients){if(c===ws){ws=this.servers[key].clients[c];break}}}if(!(ws instanceof wrapper_default)){for(const s in this.sockets){if(s===ws){ws=this.sockets[s].socket;break}}}}if(res instanceof Promise){res.then(v=>{res={args:v,callbackId};if(ws instanceof wrapper_default)ws.send(JSON.stringify(res))})}else{res={args:res,callbackId};if(ws instanceof wrapper_default)ws.send(JSON.stringify(res))}}return res};subscribeSocket=(route,socket,args,key,subInput)=>{if(this.restrict?.[route])return void 0;if(typeof socket==="string"){if(this.sockets[socket])socket=this.sockets[socket].socket;else{for(const prop in this.servers){if(this.servers[prop].clients[socket])socket=this.servers[prop].clients[socket]}}}if(typeof socket==="object"){return this.subscribe(route,res=>{if(socket.readyState===socket.OPEN){if(res instanceof Promise){res.then(r=>{socket.send(JSON.stringify({args:r,callbackId:route}))})}else{socket.send(JSON.stringify({args:res,callbackId:route}))}}},args,key,subInput)}};subscribeToSocket=(route,socketId,callback,args,key,subInput)=>{if(typeof socketId==="string"&&this.sockets[socketId]){this.__node.state.subscribeEvent(socketId,res=>{if(res?.callbackId===route){if(!callback)this.setState({[socketId]:res.args});else if(typeof callback==="string"){this.setState({[callback]:res.args})}else callback(res.args)}});return this.sockets[socketId].request({route:"subscribeSocket",args:[route,socketId,args,key,subInput]})}}};function getHoursAndMinutes2(date){let hours=date.getHours();let minutes=date.getMinutes();hours=hours<10?"0"+hours:hours;minutes=minutes<10?"0"+minutes:minutes;return`${hours}:${minutes}`}var import_child_process=require("child_process");var import_path=__toESM(require("path"));var CMDService=class extends Service{processes;connections={processes:void 0};subprocessloader={"process":(node,parent,graph,roots,properties)=>{if(node.command){this.createProcess(node)}}};constructor(options){super(options);this.load(this);this.connections.processes=this.processes;if(process?.stdin){process.stdin.on("data",data=>{let str=data.toString();this.receive(str)})}}createProcess=properties=>{let newprocess=properties;if(!newprocess.command)newprocess.command="node";if(!newprocess.args)newprocess.args=[import_path.default.join(process.cwd(),"node_modules","graphscript-node","services","cmd","childprocess.js")];if(newprocess.command){let p;if(!newprocess.options){newprocess.options={shell:true,stdio:"inherit"}}newprocess.controller=new AbortController;newprocess.options=Object.assign({signal:newprocess.controller.signal,env:process.env,cwd:process.cwd()},newprocess.options);if(newprocess.tag)newprocess._id=newprocess.tag;else{newprocess._id=`process${Math.floor(Math.random()*1e15)}`;newprocess.tag=newprocess._id}if(typeof newprocess.command==="string"){if(newprocess.command.includes(".js")){p=(0,import_child_process.fork)(newprocess.command,newprocess.args,newprocess.options)}else p=(0,import_child_process.spawn)(newprocess.command,newprocess.args?newprocess.args:[],newprocess.options);if(p instanceof import_child_process.ChildProcess){if(p.stderr){if(newprocess.onerror){p.stderr.on("data",newprocess.onerror)}else p.stderr.on("data",console.error)}if(p.stdout){if(newprocess.stdout){p.stdout.on("data",newprocess.stdout)}else p.stdout.on("data",data=>{let str=data.toString();this.receive(str);this.setState({[newprocess._id]:str})})}if(newprocess.onclose){p.on("close",newprocess.onclose)}newprocess.process=p;newprocess.controller=new AbortController;newprocess.send=data=>{return p.send(data)};newprocess.request=(message,method)=>{return this.request(message,newprocess._id,method)};newprocess.post=(route,args,method)=>{let message={route,args};if(method)message.method=method;return p.send(JSON.stringify(message))};newprocess.run=(route,args,method)=>{let message={route,args};if(method)message.method=method;return this.request(message,newprocess._id)};newprocess.subscribe=(route,callback,args,key,subInput)=>{return this.subscribeToProcess(route,newprocess._id,callback,args,key,subInput)};newprocess.unsubscribe=(route,sub)=>{return newprocess.run("unsubscribe",[route,sub])};this.processes[newprocess._id]=newprocess}}}return newprocess};open=this.createProcess;abort=childprocess=>{if(childprocess.controller)childprocess.controller.abort();else childprocess.kill();return true};send=(childprocess,data)=>{return childprocess.send(data)};request=(message,processId,method)=>{let childprocess=this.processes[processId].process;return new Promise((res,rej)=>{let callbackId=Math.random();let req={route:"runRequest",args:[message,callbackId]};if(method)req.method=method;let ondata=data=>{let str=data.toString();if(str.includes("{")){let parsed=JSON.parse(str);if(parsed.callbackId===callbackId){childprocess.removeListener("data",ondata);res(parsed.args)}}};childprocess.addListener("data",ondata);childprocess.send(req)})};runRequest=(message,callbackId,childprocess)=>{let res=this.receive(message);if(typeof childprocess==="string")childprocess=this.processes[childprocess].process;if(res instanceof Promise){res.then(v=>{res={args:v,callbackId};if(childprocess instanceof import_child_process.ChildProcess)childprocess.send(JSON.stringify(res));else process.stdout.write(JSON.stringify(res))})}else{res={args:res,callbackId};if(childprocess instanceof import_child_process.ChildProcess)childprocess.send(JSON.stringify(res));else process.stdout.write(JSON.stringify(res))}return res};subscribeProcess(route,childprocess,args,key,subInput){if(this.restrict?.[route])return void 0;if(typeof childprocess==="string"&&this.processes[childprocess]){childprocess=this.processes[childprocess].process}return this.subscribe(route,res=>{if(res instanceof Promise){res.then(r=>{childprocess.send(JSON.stringify({args:r,callbackId:route}))})}else{childprocess.send(JSON.stringify({args:res,callbackId:route}))}},args,key,subInput)}subscribeToProcess(route,processId,callback,args,key,subInput){if(typeof processId==="string"&&this.processes[processId]){this.__node.state.subscribeEvent(processId,res=>{if(res?.callbackId===route){if(!callback)this.setState({[processId]:res.args});else if(typeof callback==="string"){this.run(callback,res.args)}else callback(res.args)}});return this.processes[processId].request(JSON.stringify({route:"subscribeSocket",args:[route,processId,args,key,subInput]}))}}};var SessionsService=class extends Service{name="sessions";users={};sessions={oneWay:{},shared:{}};invites={};constructor(options,users){super(options);this.setLoaders(loaders);this.load(this);if(users)this.users=users}getSessionInfo=(sessionIdOrName,userId)=>{if(!sessionIdOrName){return this.sessions.shared}else{if(this.sessions.oneWay[sessionIdOrName]){let s=this.sessions.oneWay[sessionIdOrName];if(s.settings){if(s.settings.source===userId||s.settings.listener===userId||s.settings.ownerId===userId||s.settings.admins?.[userId]||s.settings.moderators?.[userId])return{oneWay:{[sessionIdOrName]:s}}}}else if(this.sessions.shared[sessionIdOrName]){return{shared:{[sessionIdOrName]:this.sessions.shared[sessionIdOrName]}}}else{let res={};for(const id in this.sessions.shared){if(this.sessions.shared[id].settings?.name)res[id]=this.sessions.shared.settings}if(Object.keys(res).length>0)return res}}};openOneWaySession=(options={},sourceUserId,listenerUserId)=>{if(!options._id){options._id=`oneWay${Math.floor(Math.random()*1e15)}`;if(this.sessions.oneWay[options._id]){delete options._id;this.openOneWaySession(options,sourceUserId)}}if(options._id&&sourceUserId&&this.users[sourceUserId]){if(sourceUserId){if(!options.settings)options.settings={listener:sourceUserId,source:sourceUserId,propnames:{latency:true},admins:{[sourceUserId]:true},ownerId:sourceUserId};if(!options.settings.listener)options.settings.listener=listenerUserId?listenerUserId:sourceUserId;if(!options.settings.source)options.settings.source=sourceUserId;if(!this.users[sourceUserId].sessions)this.users[sourceUserId].sessions={};this.users[sourceUserId].sessions[options._id]=options}if(!options.data)options.data={};if(options.onopen)options.onopen(options);if(this.sessions.oneWay[options._id]){return this.updateSession(options,sourceUserId)}else if(options.settings?.listener&&options.settings.source)this.sessions.oneWay[options._id]=options}return options};openSharedSession=(options,userId)=>{if(!options._id){options._id=`shared${Math.floor(Math.random()*1e15)}`;if(this.sessions.shared[options._id]){delete options._id;return this.openSharedSession(options,userId)}}if(options._id&&userId&&this.users[userId]){if(typeof userId==="string"){if(!options.settings)options.settings={name:"shared",propnames:{latency:true},users:{[userId]:true},admins:{[userId]:true},ownerId:userId};if(!options.settings.users)options.settings.users={[userId]:true};if(!options.settings.admins)options.settings.admins={[userId]:true};if(!options.settings.ownerId)options.settings.ownerId=userId;if(!this.users[userId].sessions)this.users[userId].sessions={};this.users[userId].sessions[options._id]=options}else if(!options.settings)options.settings={name:"shared",propnames:{latency:true},users:{}};if(!options.data)options.data={oneWay:{},shared:{}};if(!options.settings.name)options.name=options.id;if(options.onopen)options.onopen(options);if(this.sessions.shared[options._id]){return this.updateSession(options,userId)}else this.sessions.shared[options._id]=options}return options};open=(options,userId)=>{if(options.listener)this.openOneWaySession(options,userId);else this.openSharedSession(options,userId)};updateSession=(options,userId)=>{let session;if(options._id){session=this.sessions.oneWay[options._id];if(!session)session=this.sessions.shared[options._id];if(session&&userId){if(session.settings&&(session?.settings.source===userId||session.settings.admins?.[userId]||session.settings.moderators?.[userId]||session.settings.ownerId===userId)){return this.recursivelyAssign(session,options)}}else if(options.settings?.source){return this.openOneWaySession(options,userId)}else return this.openSharedSession(options,userId)}return false};joinSession=(sessionId,userId,options,remoteUser=true)=>{if(!userId&&!this.users[userId])return false;if(!this.users[userId].sessions)this.users[userId].sessions={};let sesh=this.sessions.shared[sessionId];if(!sesh)sesh=this.sessions.oneWay[sessionId];if(sesh?.settings){if(sesh.settings?.banned){if(sesh.settings.banned[userId])return false}if(sesh.settings?.password){if(!options?.settings?.password)return false;if(options.settings.password!==sesh.settings.password)return false}sesh.settings.users[userId]=true;sesh.settings.newUser=true;this.users[userId].sessions[sessionId]=sesh;if(options){return this.updateSession(options,userId)};if(remoteUser&&this.users[userId]?.send){this.users[userId].send({route:"joinSession",args:[sessionId,userId,sesh]})}return sesh}else if(options?.source||options?.listener){sesh=this.openOneWaySession(options,userId);if(remoteUser&&this.users[userId]?.send){this.users[userId].send({route:"joinSession",args:[sessionId,userId,sesh]})}return sesh}else if(options){sesh=this.openSharedSession(options,userId);if(remoteUser&&this.users[userId]?.send){this.users[userId].send({route:"joinSession",args:[sessionId,userId,sesh]})}return sesh}return false};inviteToSession=(session,userInvited,inviteEndpoint,remoteUser=true)=>{if(remoteUser&&this.users[userInvited]?.send){this.users[userInvited]?.send({route:"receiveSessionInvite",args:[session,userInvited,inviteEndpoint]})}else{this.receiveSessionInvite(session,userInvited,inviteEndpoint)}};receiveSessionInvite=(session,userInvited,endpoint)=>{if(!this.invites[userInvited])this.invites[userInvited]={};let id=typeof session==="string"?session:session._id;this.invites[userInvited][id]={session,endpoint};return id};acceptInvite=(session,userInvited,remoteUser=true)=>{let id=typeof session==="string"?session:session._id;let invite=this.invites[userInvited]?.[id];let endpoint;if(invite){session=invite.session;endpoint=invite.endpoint;delete this.invites[userInvited]?.[id]}return new Promise((res,rej)=>{if(!id)res(false);if(remoteUser&&endpoint&&this.users[endpoint]?.send){let resolved;let timeout=setTimeout(()=>{if(!resolved){this.unsubscribe("joinSession",subbed);rej(new Error("Session join timed out"))}},1e4);let subbed=this.subscribe("joinSession",result=>{if(typeof result==="object"&&result?._id===id){if(result.setting?.users?.includes(userInvited)){this.unsubscribe("joinSession",subbed);resolved=true;if(timeout)clearTimeout(timeout);res(result)}}});this.users[endpoint]?.send({route:"joinSession",args:[id,userInvited,void 0,true]})}else res(this.joinSession(id,userInvited,typeof session==="object"?session:void 0))})};rejectInvite=(session,userInvited,remoteUser=true)=>{let id=typeof session==="string"?session:session._id;if(this.invites[userInvited]?.[id]){let endpoint=this.invites[userInvited][id].endpoint;delete this.invites[userInvited][id];if(remoteUser&&endpoint&&this.users[endpoint]?.send){this.users[endpoint].send({route:"rejectInvite",args:[id,userInvited]})}return true}};leaveSession=(session,userId,clear=true,remoteUser=true)=>{let sessionId;if(typeof session==="string"){sessionId=session;session=this.sessions.oneWay[sessionId];if(!session)session=this.sessions.shared[sessionId]}else sessionId=session._id;if(session){if(this.sessions.oneWay[sessionId]){if(userId===session.settings.source||userId===session.settings.listener||session.settings.admins?.[userId]||session.settings.moderators?.[userId]){delete this.sessions.oneWay[sessionId];delete this.users[userId]?.sessions[sessionId];delete this.users[userId]?.sessionSubs?.[sessionId];if(clear){if(session.settings.admins?.[userId])delete(this.sessions.shared[sessionId].settings?.admins)[userId];if(session.settings.moderators?.[userId])delete(this.sessions.shared[sessionId].settings?.moderators)[userId]}if(remoteUser&&this.users[userId]?.send){this.users[userId].send({route:"unsubscribeFromSession",args:[session._id,userId,clear]})}else{this.unsubsribeFromSession(session,userId,clear)}}}else if(this.sessions.shared[sessionId]){delete this.sessions.shared.settings.users[userId];delete this.users[userId]?.sessions[sessionId];delete this.users[userId]?.sessionSubs?.[sessionId];if(clear){if(session.settings.admins?.[userId])delete(this.sessions.shared[sessionId].settings?.admins)[userId];if(session.settings.moderators?.[userId])delete(this.sessions.shared[sessionId].settings?.moderators)[userId];if(session.data.shared[userId])delete this.sessions.shared[sessionId].data?.shared[userId];if(session.settings.host===userId){this.swapHost(session,void 0,true);delete session.data.shared[userId]}}if(remoteUser&&this.users[userId]?.send){this.users[userId].send({route:"unsubscribeFromSession",args:[session._id,userId,clear]})}else{this.unsubsribeFromSession(session,userId,clear)}}return true}return false};deleteSession=(session,userId,remoteUsers=true)=>{if(typeof session==="string"){let id=session;session=this.sessions.oneWay[id];if(!session)session=this.sessions.shared[id]}if(session){if(session.source===userId||session.listener===userId||session.admins?.[userId]||session.ownerId===userId){for(const user in session.settings.users){if(this.users[user]?.sessions)delete this.users[user].sessions[session._id];if(this.users[user]?.sessionSubs)delete this.users[user].sessionSubs[session._id];if(remoteUsers){if(session.users){for(const key in session.users){if(this.users[key]?.send)this.users[key].send({route:"unsubscribeFromSession",args:[session._id,key]})}}else if(session.listener){if(this.users[session.listener]?.send)this.users[session.listener].send({route:"unsubscribeFromSession",args:[session._id,session.listener]})}else if(this.users[userId]?.send){this.users[userId].send({route:"unsubscribeFromSession",args:[session._id,userId]})}}else{this.unsubsribeFromSession(session,user)}}if(this.sessions.oneWay[session._id])delete this.sessions.oneWay[session._id];else if(this.sessions.shared[session._id])delete this.sessions.oneWay[session._id];if(session.onclose)session.onclose(session)}}return true};getFirstMatch(obj1,obj2){for(const i in obj1){if(i in obj2)return i}return false}swapHost=(session,newHostId,adoptData=true,remoteUser=true)=>{if(typeof session==="string"){if(this.sessions.oneWay[session])session=this.sessions.oneWay[session];else if(this.sessions.shared[session])session=this.sessions.shared[session]}if(typeof session==="object"&&session.settings){let oldHost=session.settings.host;delete session.settings.host;if(newHostId){if(session.settings.users[newHostId])session.settings.host=newHostId}if(session.settings.ownerId&&!session.settings.host){if(session.settings.users[session.settings.ownerId])session.settings.host=session.settings.ownerId}if(session.settings.admins&&!session.settings.host){let match=this.getFirstMatch(session.settings.users,session.settings.admins);if(match)session.settings.host=match}if(session.settings.moderators&&!session.settings.host){let match=this.getFirstMatch(session.settings.users,session.settings.moderators);if(match)session.settings.host=match}if(!session.settings.host)session.settings.host=Object.keys(session.settings.users)[0];if(adoptData&&oldHost&&session.settings.inheritHostData!==false){if(session.data?.shared[oldHost]){if(session.data?.shared[oldHost]){session.data.shared[session.settings.host]=Object.assign(session.data.shared[session.settings.host]?session.data.shared[session.settings.host]:{},session.data.shared[oldHost]);if(remoteUser){}}}}return true}return false};subscribeToSession=(session,userId,onmessage,onopen,onclose)=>{if(typeof session==="string"){let s=this.sessions.oneWay[session];if(!s)s=this.sessions.shared[session];if(!s)return void 0;session=s}let user=this.users[userId];if(!user)return void 0;if(!user.sessionSubs)user.sessionSubs={};if(!user.sessionSubs[session._id])user.sessionSubs[session._id]={};if(onmessage)user.sessionSubs[session._id].onmessage=onmessage;if(onopen)this.sessionSubs[userId][session._id].onopen=onopen;if(onclose)user.sessionSubs[session._id].onclose=onclose;if(typeof onopen==="function"){let sub=this.subscribe("joinSession",res=>{if(res._id===session._id)this.sessionSubs[userId][session._id].onopen(session,user);this.unsubscribe("joinSession",sub)});user.sessionSubs[session._id].onopenSub=sub}return session};unsubsribeFromSession=(session,userId,clear=true)=>{if(typeof session==="string"){let s=this.sessions.oneWay[session];if(!s)s=this.sessions.shared[session];if(!s)return void 0;session=s}const clearSessionSubs=(Id,s)=>{let u2=this.users[Id];if(!u2)return void 0;if(u2.sessionSubs?.[s._id]){if(u2.sessionSubs[s._id].onopenSub){this.unsubscribe("joinSession",u2.sessionSubs[s._id].onopenSub)}}if(u2.sessionSubs[s._id].onclose)u2.sessionSubs[s._id].onclose(s,u2);delete u2.sessionSubs[s._id]};if(userId){clearSessionSubs(userId,session)}else{for(const key in this.users){clearSessionSubs(key,session)}}if(clear){if(this.sessions.oneWay[session._id])delete this.sessions.oneWay[session._id];else if(this.sessions.shared[session._id])delete this.sessions.shared[session._id]}};sessionUpdateCheck=(sessionHasUpdate,transmit=true)=>{let updates={oneWay:{},shared:{}};for(const session in this.sessions.oneWay){const sesh=this.sessions.oneWay[session];const updateObj={_id:sesh._id,settings:{listener:sesh.listener,source:sesh.source},data:{}};if(!this.users[sesh.source]){delete this.sessions.oneWay[session];continue}if(sesh.settings&&sesh.data){for(const prop in sesh.settings.propnames){if(prop in this.users[sesh.source]){if(this.sessions.oneWay[session].data){if(typeof sesh.data[prop]==="object"){if(this.users[sesh.source][prop]&&(stringifyFast(sesh.data[prop])!==stringifyFast(this.users[sesh.source][prop])||!(prop in sesh.data)))updateObj.data[prop]=this.users[sesh.source][prop]}else if(prop in this.users[sesh.source]&&(sesh.data[prop]!==this.users[sesh.source][prop]||!(prop in sesh.data)))updateObj.data[prop]=this.users[sesh.source][prop]}else updateObj.data[prop]=this.users[sesh.source][prop]}else if(this.sessions.oneWay[session]?.data&&prop in this.sessions.oneWay[session]?.data)delete this.sessions.oneWay[session].data[prop]}}if(Object.keys(updateObj.data).length>0){this.recursivelyAssign(this.sessions.oneWay[session].data,updateObj.data);updates.oneWay[sesh._id]=updateObj;if(sessionHasUpdate)sessionHasUpdate(sesh,updateObj);if(sesh.settings.onhasupdate)sesh.onhasupdate(sesh,updateObj)}}for(const session in this.sessions.shared){const sesh=this.sessions.shared[session];const updateObj={_id:sesh._id,settings:{name:sesh.name},data:{}};if(sesh.settings?.host){const oneWayData={};const sharedData={};for(const user in sesh.settings.users){if(!this.users[user]){delete sesh.settings.users[user];if(sesh.settings.host===user)this.swapHost(sesh,void 0,true);if(sesh.data?.shared[user])delete sesh.data.shared[user];if(sesh.data?.oneWay?.[user])delete sesh.data.shared[user];updateObj.settings.users=sesh.settings.users;updateObj.settings.host=sesh.settings.host;continue}else if(sesh.settings.newUser){updateObj.settings.users=sesh.settings.users;updateObj.settings.host=sesh.settings.host;sesh.settings.newUser=false}if(user!==sesh.settings.host){oneWayData[user]={};for(const prop in sesh.settings.propnames){if(prop in this.users[user]){if(sesh.data?.oneWay&&!(user in sesh.data.oneWay)){if(typeof this.users[user][prop]==="object")oneWayData[user][prop]=this.recursivelyAssign({},this.users[user][prop]);else oneWayData[user][prop]=this.users[user][prop]}else if(typeof oneWayData[user][prop]==="object"&&sesh.data){if(prop in this.users[user][prop]&&(stringifyFast(sesh.data?.shared[user][prop])!==stringifyFast(this.users[user][prop])||!(prop in sesh.data)))oneWayData[user][prop]=this.users[user][prop]}else if(this.users[user][prop]&&sesh.data?.oneWay?.[prop]!==this.users[user][prop])oneWayData[user][prop]=this.users[user][prop]}else if(sesh.data?.oneWay?.[user]&&prop in sesh.data?.oneWay?.[user])delete sesh.data.oneWay[user][prop]}if(Object.keys(oneWayData[user]).length===0)delete oneWayData[user]}else{sharedData[user]={};for(const prop in sesh.settings.hostprops){if(prop in this.users[user]){if(sesh.data&&!(user in sesh.data.shared)){if(typeof this.users[user][prop]==="object")sharedData[user][prop]=this.recursivelyAssign({},this.users[user][prop]);else sharedData[user][prop]=this.users[user][prop]}else if(typeof sharedData[user][prop]==="object"&&sesh.data){if(stringifyFast(sesh.data?.shared[user][prop])!==stringifyFast(this.users[user][prop])||!(prop in sesh.data.shared[user]))sharedData[user][prop]=this.users[user][prop]}else if(sesh.data?.shared[user][prop]!==this.users[user][prop])sharedData[user][prop]=this.users[user][prop]}else if(sesh.data?.shared[user]&&prop in sesh.data?.shared[user])delete sesh.data.shared[user][prop]}}}if(Object.keys(oneWayData).length>0){updateObj.data.oneWay=oneWayData}if(Object.keys(sharedData).length>0){updateObj.data.shared=sharedData}}else{const sharedData={};if(sesh.settings?.users){for(const user in sesh.settings.users){if(!this.users[user]){delete sesh.settings.users[user];if(sesh.settings.host===user)this.swapHost(sesh,void 0,true);if(sesh.data?.shared[user])delete sesh.data.shared[user];if(sesh.data?.oneWay?.[user])delete sesh.data.shared[user];updateObj.settings.users=sesh.settings.users;updateObj.settings.host=sesh.settings.host;continue}sharedData[user]={};for(const prop in sesh.settings.propnames){if(prop in this.users[user]){if(sesh.data&&!(user in sesh.data.shared)){if(typeof this.users[user][prop]==="object")sharedData[user][prop]=this.recursivelyAssign({},this.users[user][prop]);else sharedData[user][prop]=this.users[user][prop]}else if(typeof sesh.data?.shared[user]?.[prop]==="object"){if(stringifyFast(sesh.data.shared[user][prop])!==stringifyFast(this.users[user][prop])||!(prop in sesh.data.shared[user])){sharedData[user][prop]=this.users[user][prop]}}else if(sesh.data?.shared[user]?.[prop]!==this.users[user][prop])sharedData[user][prop]=this.users[user][prop]}else if(sesh.data?.shared[user]&&prop in sesh.data?.shared[user])delete sesh.data.shared[user][prop]}if(Object.keys(sharedData[user]).length===0)delete sharedData[user]}if(Object.keys(sharedData).length>0){updateObj.data.shared=sharedData}}}if(updateObj.data.shared||updateObj.data.oneWay){updates.shared[sesh._id]=updateObj;if(updateObj.data.shared){Object.assign(this.sessions.shared[session].data?.shared,updateObj.data.shared)}if(updateObj.data.oneWay){Object.assign(this.sessions.shared[session].data?.oneWay,updateObj.data.oneWay)}if(sessionHasUpdate)sessionHasUpdate(sesh,updateObj);if(sesh.settings.onhasupdate)sesh.settings.onhasupdate(sesh,updateObj)}}if(Object.keys(updates.oneWay).length===0)delete updates.oneWay;if(Object.keys(updates.shared).length===0)delete updates.shared;if(Object.keys(updates).length===0)return void 0;if(transmit)this.transmitSessionUpdates(updates);return updates};transmitSessionUpdates=updates=>{let users={};if(updates.oneWay){for(const s in updates.oneWay){let session=this.sessions.oneWay[s];if(session?.settings){let u2=session.settings.listener;if(!users[u2])users[u2]={};users[u2].oneWay[s]=updates.oneWay[s]}}}if(updates.shared){for(const s in updates.shared){let session=this.sessions.shared[s];if(session?.settings){for(const u2 in session.settings.users){if(!users[u2])users[u2]={};users[u2].shared[s]=updates.shared[s]}}}}let message={route:"receiveSessionUpdates",args:null};for(const u2 in users){message.args=[u2,users[u2]];if(this.users[u2]?.send)this.users[u2].send(JSON.stringify(message));this.setState({[u2]:Object.create(message)})}return users};receiveSessionUpdates=(origin,update)=>{if(update){if(typeof update==="string")update=JSON.parse(update)}if(typeof update==="object"){let user=this.users[origin];if(user){if(!user.sessions)user.sessions={oneWay:{},shared:{}};if(!user.sessionSubs)user.sessionSubs={}}if(update.oneWay){for(const key in update.oneWay){this.recursivelyAssign(this.sessions.oneWay[key].data,update.oneWay[key].data);if(this.sessions.oneWay[key]?.settings.onmessage)this.sessions.oneWay[key].settings.onmessage(this.sessions.oneWay[key],update.oneWay[key]);if(user?.sessionSubs[user._id]?.[key]?.onmessage)user.sessionSubs[user._id][key].onmessage(user.sessions[key],update,user)}}if(update.shared){for(const key in update.shared){if(update.shared[key].settings.users)this.sessions.shared[key].settings.users=update.shared[key].settings.users;if(update.shared[key].settings.host)this.sessions.shared[key].settings.host=update.shared[key].settings.host;if(update.shared[key].data.oneWay)this.recursivelyAssign(this.sessions.shared[key].data.oneWay,update.shared[key].data.oneWay);if(update.shared[key].data.shared)this.recursivelyAssign(this.sessions.shared[key].data.shared,update.shared[key].data.shared);if(this.sessions.shared[key]?.settings.onmessage)this.sessions.shared[key].settings.onmessage(this.sessions.shared[key],update.shared[key]);if(user?.sessionSubs[user._id]?.[key]?.onmessage)user.sessionSubs[user._id][key].onmessage(user.sessions[key],update,user)}}return user}};getUpdatedUserData=user=>{const updateObj={};for(const key in user.sessions){let s=user.sessions[key];if(s.settings.users[user._id]||s.settings.source===user._id){if(!s.settings.spectators?.[user._id]){if(s.settings.host===user._id){for(const prop in s.settings.hostprops){if(!updateObj[prop]&&prop in user){if(s.data.shared?.[user._id]&&prop in s.data.shared?.[user._id]){if(typeof user[prop]==="object"){if(stringifyFast(s.data.shared[user._id][prop])!==stringifyFast(user[prop]))updateObj[prop]=user[prop]}else if(s.data.shared[user._id][prop]!==user[prop])updateObj[prop]=user[prop]}else updateObj[prop]=user[prop]}}}else{for(const prop in s.settings.propnames){if(!updateObj[prop]&&user[prop]!==void 0){if(s.settings.source){if(typeof user[prop]==="object"&&prop in s.data){if(stringifyFast(s.data[prop])!==stringifyFast(user[prop]))updateObj[prop]=user[prop]}else if(s.data[prop]!==user[prop])updateObj[prop]=user[prop]}else{if(s.data.shared?.[user._id]&&prop in s.data.shared?.[user._id]){if(typeof user[prop]==="object"){if(stringifyFast(s.data.shared[user._id][prop])!==stringifyFast(user[prop]))updateObj[prop]=user[prop]}else if(s.data.shared[user._id][prop]!==user[prop])updateObj[prop]=user[prop]}else updateObj[prop]=user[prop]}}}}}}}return updateObj};userUpdateCheck=(user,onupdate)=>{if(user.sessions){const updateObj=this.getUpdatedUserData(user);if(Object.keys(updateObj).length>0){let message={route:"setUserProps",args:[user._id,updateObj]};if(user.send)user.send(message);this.setState({[user._id]:message});if(onupdate){onupdate(user,updateObj)};return updateObj}}return void 0};setUserProps=(user,props)=>{if(user){if(typeof user==="string"){user=this.users[user];if(!user)return false}}if(props){if(typeof props==="string"){props=JSON.parse(props)}}this.recursivelyAssign(user,props);return true};userUpdateLoop={__operator:this.userUpdateCheck,__node:{loop:10}};sessionLoop={__operator:this.sessionUpdateCheck,__node:{loop:10}};STREAMLATEST=0;STREAMALLLATEST=1;streamSettings={};streamFunctions={allLatestValues:(prop,setting)=>{let result=void 0;if(Array.isArray(prop)){if(prop.length!==setting.lastRead){result=prop.slice(setting.lastRead);setting.lastRead=prop.length}}else if(typeof prop==="object"){result={};for(const p in prop){if(Array.isArray(prop[p])){if(typeof setting==="number")setting={[p]:{lastRead:void 0}};else if(!setting[p])setting[p]={lastRead:void 0};if(prop[p].length!==setting[p].lastRead){result[p]=prop[p].slice(setting[p].lastRead);setting[p].lastRead=prop[p].length}}else{if(typeof setting==="number")setting={[p]:{lastRead:void 0}};else if(!setting[p])setting[p]={lastRead:void 0};if(setting[p].lastRead!==prop[p]){result[p]=prop[p];setting[p].lastRead=prop[p]}}}if(Object.keys(result).length===0)result=void 0}else{if(setting.lastRead!==prop){result=prop;setting.lastRead=prop}}return result},latestValue:(prop,setting)=>{let result=void 0;if(Array.isArray(prop)){if(prop.length!==setting.lastRead){result=prop[prop.length-1];setting.lastRead=prop.length}}else if(typeof prop==="object"){result={};for(const p in prop){if(Array.isArray(prop[p])){if(typeof setting==="number")setting={[p]:{lastRead:void 0}};else if(!setting[p])setting[p]={lastRead:void 0};if(prop[p].length!==setting[p].lastRead){result[p]=prop[p][prop[p].length-1];setting[p].lastRead=prop[p].length}}else{if(typeof setting==="number")setting={[p]:{lastRead:void 0}};else if(!setting[p])setting[p]={lastRead:void 0};if(setting[p].lastRead!==prop[p]){result[p]=prop[p];setting[p].lastRead=prop[p]}}}}else{if(setting.lastRead!==prop){result=prop;setting.lastRead=prop}}return result}};setStreamFunc=(name2,key,callback=this.streamFunctions.allLatestValues)=>{if(!this.streamSettings[name2].settings[key])this.streamSettings[name2].settings[key]={lastRead:0};if(callback===this.STREAMLATEST)this.streamSettings[name2].settings[key].callback=this.streamFunctions.latestValue;else if(callback===this.STREAMALLLATEST)this.streamSettings[name2].settings[key].callback=this.streamFunctions.allLatestValues;else if(typeof callback==="string")this.streamSettings[name2].settings[key].callback=this.streamFunctions[callback];else if(typeof callback==="function")this.streamSettings[name2].settings[key].callback=callback;if(!this.streamSettings[name2].settings[key].callback)this.streamSettings[name2].settings[key].callback=this.streamFunctions.allLatestValues;return true};addStreamFunc=(name2,callback=data=>{})=>{this.streamFunctions[name2]=callback};setStream=(object={},settings={},streamName=`stream${Math.floor(Math.random()*1e10)}`,onupdate,onclose)=>{if(settings.keys){if(settings.keys.length===0){let k=Object.keys(object);if(k.length>0){settings.keys=Array.from(k)}}}else{settings.keys=Array.from(Object.keys(object))}this.streamSettings[streamName]={object,settings,onupdate,onclose};this.subscribe(streamName,res=>{if(this.streamSettings[streamName].onupdate)this.streamSettings[streamName].onupdate(res,this.streamSettings[streamName])});settings.keys.forEach(prop=>{if(settings[prop]?.callback)this.setStreamFunc(streamName,prop,settings[prop].callback);else this.setStreamFunc(streamName,prop,settings.callback)});return this.streamSettings[streamName]};removeStream=(streamName,key)=>{if(streamName&&this.streamSettings[streamName]&&!key){if(this.streamSettings[streamName].onclose)this.streamSettings[streamName].onclose(this.streamSettings[streamName]);this.unsubscribe(streamName);delete this.streamSettings[streamName]}else if(key&&this.streamSettings[streamName]?.settings?.keys){let idx=this.streamSettings[streamName].settings.keys.indexOf(key);if(idx>-1)this.streamSettings[streamName].settings.keys.splice(idx,1);if(this.streamSettings[streamName].settings[key])delete this.streamSettings[streamName].settings[key];return true}return false};updateStreamData=(streamName,data={})=>{if(this.streamSettings[streamName]){Object.assign(this.streamSettings[streamName].object,data);return this.streamSettings[streamName].object}return false};getStreamUpdate=streamName=>{if(!this.streamSettings[streamName])return;let streamUpdate={};this.streamSettings[streamName].settings.keys.forEach(key=>{if(this.streamSettings[streamName].settings[key]){let data=this.streamSettings[streamName].settings[key].callback(this.streamSettings[streamName].object[key],this.streamSettings[streamName].settings[key]);if(data!==void 0)streamUpdate[key]=data}});this.setState({[streamName]:streamUpdate});return streamUpdate};getAllStreamUpdates=()=>{let updateObj={};for(const streamName in this.streamSettings){let streamUpdate=this.getStreamUpdate(streamName);Object.assign(updateObj,streamUpdate)}return updateObj};streamLoop={__operator:this.getAllStreamUpdates,__node:{loop:10}}};var Router=class extends Service{name="router";connections={};sources={};services={};serviceConnections={};users={};userTimeout=1e4;order;constructor(options){super(options);this.load(this);if(options){if(options.order)this.order=options.order;if(options.timeout)this.userTimeout=options.timeout;if(options.graph){for(const key in options.graph){let opt=options.graph[key];if(typeof opt==="function")opt=new opt;if(opt?.__node?.nodes){opt.name=key;opt.__node.tag=key;this.addServices({[opt.name]:opt});this.routeService(opt,opt.connections)}else{if(typeof opt?.service==="function")opt.service=new opt.service;if(opt?.service?.__node?.nodes){opt.service.name=key;opt.service.__node.tag=key;this.addServices({[opt.service.name]:opt.service});this.routeService(opt.service)}if(typeof opt?.service==="object"){if(opt.connections){if(Array.isArray(opt.connections)){opt.connections.forEach(k=>{this.addServiceConnections(opt[key].service,k)})}else this.addServiceConnections(opt.service,opt.connections)}if(opt.config){for(const c in opt.config){this.openConnection(opt.service,opt.config[c],opt.config[c].source,opt.config[c].args)}}}}}}}}addUser=async(info,connections,config,receiving)=>{let user;if(!info._id){info._id=`user${Math.floor(Math.random()*1e15)}`}if(this.users[info._id]){user=this.users[info._id]}else{user=Object.assign({},info)}if(connections){for(const key in connections){if(typeof connections[key]==="object"){if(!connections[key].connection._id){await new Promise((res,rej)=>{let start=performance.now();let checker=()=>{if(!connections[key].connection._id){if(performance.now()-start>this.userTimeout){delete connections[key];rej(false)}else{setTimeout(()=>{checker()},100)}}else{res(true)}};checker()}).catch(er=>{console.error("Connections timed out:",er)})}}}for(const key in connections){connections[key]=this.addConnection(connections[key],user._id)}}if(config){for(const c in config){this.openConnection(config[c].service,config[c],user._id,config[c].args)}}if(!this.users[info._id]){let send=(message,...a)=>{let connection=this.getConnection(user._id,"send");if(connection?.send)return connection.send(message,...a)};let sendAll=(message,...a)=>{let connections2=this.getConnections(user._id,"send");for(const key in connections2)if(connections2[key]?.send)return connections2[key].send(message,...a)};let request=(message,method,...a)=>{let connection=this.getConnection(user._id,"request");if(connection?.request)return connection.request(message,method,...a)};let requestAll=(message,method,...a)=>{let connections2=this.getConnections(user._id,"request");let results=[];for(const key in connections2)if(connections2[key]?.request)results.push(connections2[key].request(message,method,...a));return Promise.all(results)};let post=(route,args,method,...a)=>{let connection=this.getConnection(user._id,"post");if(connection?.post)return connection.post(route,args,method,...a)};let postAll=(route,args,method,...a)=>{let connections2=this.getConnections(user._id,"post");for(const key in connections2)if(connections2[key]?.post)connections2[key].post(route,args,method,...a)};let run=(route,args,method,...a)=>{let connection=this.getConnection(user._id,"run");if(connection?.run)return connection.run(route,args,method,...a)};let runAll=(route,args,method,...a)=>{let connections2=this.getConnections(user._id,"run");let results=[];for(const key in connections2)if(connections2[key]?.run)results.push(connections2[key].run(route,args,method,...a));return Promise.all(results)};let subscribe=(route,callback,...a)=>{let connection=this.getConnection(user._id,"subscribe");if(connection?.subscribe)return connection.subscribe(route,callback,...a)};let subscribeAll=(route,callback,...a)=>{let connections2=this.getConnections(user._id,"subscribe");let results=[];for(const key in connections2)if(connections2[key]?.post)results.push(connections2[key].subscribe(route,callback,...a));return Promise.all(results)};let unsubscribe=(route,sub,...a)=>{let connection=this.getConnection(user._id,"unsubscribe");if(connection?.unsubscribe)return connection.unsubscribe(route,sub,...a)};let unsubscribeAll=(route,subs,...a)=>{let connections2=this.getConnections(user._id,"unsubscribe");let results=[];for(const key in connections2)if(connections2[key]?.post&&subs[key])results.push(connections2[key].unsubscribe(route,subs[key],...a));return Promise.all(results)};let terminate=()=>{return this.removeUser(user)};user.send=send;user.request=request;user.post=post;user.run=run;user.subscribe=subscribe;user.unsubscribe=unsubscribe;user.terminate=terminate;user.sendAll=sendAll;user.requestAll=requestAll;user.postAll=postAll;user.runAll=runAll;user.subscribeAll=subscribeAll;user.unsubscribeAll=unsubscribeAll;user.terminateAll=terminate;this.users[user._id]=user}if(connections&&!receiving){let connectionIds={};let pass=false;Object.keys(connections).map((k,i)=>{if(connections[k]?._id){connectionIds[`${i}`]=connections[k]?._id;pass=true}});if(pass){user.send({route:"addUser",args:[{_id:user._id},connectionIds,void 0,true]})}}return user};removeUser(profile,terminate){if(terminate)this.removeConnection(profile,terminate);if(typeof profile==="string")profile=this.users[profile];if(typeof profile==="object"&&profile._id){delete this.users[profile._id];if(profile.onclose)profile.onclose(profile)}return true}getConnection=(sourceId,hasMethod,connectionId)=>{if(this.connections[sourceId]){return this.connections[sourceId]}else if(this.sources[sourceId]){if(hasMethod?.includes("All"))return this.users[sourceId];if(connectionId){if(hasMethod){if(this.sources[sourceId][connectionId]?.[hasMethod])return this.sources[sourceId][connectionId]}else if(this.sources[sourceId][connectionId])return this.sources[sourceId][connectionId];else return void 0}else if(this.order){for(let i=0;i{if(this.sources[sourceId]){if(!props&&!hasMethod)return this.sources[sourceId];let found={};for(const key in this.sources[sourceId]){if(typeof this.sources[sourceId][key]==="object"){if(!this.sources[sourceId][key]._id){for(const k in this.sources[sourceId][key]){if(typeof this.sources[sourceId][key][k]==="object"){let pass=true;if(hasMethod&&!this.sources[sourceId][key][k][hasMethod])pass=false;if(props){for(const p in props){if(typeof this.sources[sourceId][key][k][p]==="object"&&typeof props[p]==="object"){for(const pp in props[p]){if(props[p][pp]!==this.sources[sourceId][key][k][p][pp]){pass=false;break}}}else if(this.sources[sourceId][key][k][p]!==props[p]){pass=false}else{pass=false;break}}}if(pass){found[this.sources[sourceId][key][k]._id]=this.sources[sourceId][key][k]}}}}else{let pass=true;if(hasMethod&&!this.sources[sourceId][key][hasMethod])pass=false;if(props){for(const p in props){if(typeof this.sources[sourceId][key][p]==="object"&&typeof props[p]==="object"){for(const pp in props[p]){if(props[p][pp]!==this.sources[sourceId][key][p][pp]){pass=false;break}}}else if(this.sources[sourceId][key][p]!==props[p]){pass=false}else{pass=false;break}}}if(pass){found[this.sources[sourceId][key]._id]=this.sources[sourceId][key]}}}}return found}};runConnection=async(userId,method,args,connectionId)=>{let sendTo;if(method.indexOf("All")>-1){sendTo=this.users[userId]}else{sendTo=this.getConnection(userId,method,connectionId)}if(sendTo){let res=sendTo[method](...args);res=await res;return res}};subscribeThroughConnection=(route,remoteRelay,remoteEndpoint,callback,...args)=>{if(typeof remoteRelay==="string"){remoteRelay=this.getConnection(remoteRelay,"run")}if(typeof remoteRelay==="object")return new Promise((res,rej)=>{remoteRelay.run("routeConnections",[route,remoteEndpoint,remoteRelay._id,...args]).then(sub=>{this.__node.state.subscribeEvent(remoteEndpoint,res2=>{if(res2?.callbackId===route){if(!callback)this.setState({[remoteEndpoint]:res2.args});else if(typeof callback==="string"){this.setState({[callback]:res2.args})}else callback(res2.args)}});res(sub)}).catch(rej)})};addConnection=(options,source,autoRemove=true)=>{let settings={};if(typeof options==="string"){if(this.connections[options]){options=this.connections[options]}else{for(const j in this.serviceConnections){for(const k in this.serviceConnections[j]){if(this.serviceConnections[j][k][options]){options={connection:this.serviceConnections[j][k][options]};options.service=j;settings.connectionType=j;settings.connectionsKey=k;break}}}}if(typeof options==="string"&&this.__node.nodes.get(options))options={connection:this.__node.nodes.get(options)}}if(!options||typeof options==="string")return void 0;if(source)settings.source=source;if(options.connection instanceof GraphNode){settings.connection=options.connection;let node=settings.connection;settings.send=async message=>{if(message.method){if(Array.isArray(message.args)){return node[message.method]?.(...message.args)}else return node[message.method]?.(message.args)}else{if(!node.__operator)return;if(Array.isArray(message.args)){return node.__operator(...message.args)}else return node.__operator(message.args)}};settings.request=async(message,method)=>{if(method){if(Array.isArray(message.args)){return node[method]?.(...message.args)}else return node[method]?.(message.args)}else{if(!node.__operator)return;if(Array.isArray(message.args)){return node.__operator(...message.args)}else return node.__operator(message.args)}};settings.post=async(route,args,method)=>{if(route&&node.__node.graph.get(route)){let n=node.__node.graph.get(route);if(method){if(Array.isArray(args)){return n[method]?.(...args)}else return n[method]?.(args)}else{if(Array.isArray(args)){return n.__operator(...args)}else return n.__operator(args)}}else{if(method){if(Array.isArray(args)){return node[method]?.(...args)}else return node[method]?.(args)}else{if(Array.isArray(args)){return node.__operator(...args)}else return node.__operator(args)}}};settings.run=settings.post;settings.subscribe=async callback=>{return node.__subscribe(callback)};settings.unsubscribe=async sub=>{return node.__unsubscribe(sub)};settings.terminate=()=>{node.__node.graph.remove(node);return true};settings.onclose=options.onclose;if(settings.onclose){node.__addOndisconnected(n=>{if(settings.onclose)settings.onclose(settings,n)})}}else if(options.connection instanceof Graph){if(options.connection.__node.nodes.get("open"))settings.service=options.connection;let graph=settings.connection;settings.send=async message=>{if(Array.isArray(message.args))graph.run(message.route,...message.args);else graph.run(message.route,message.args)};settings.request=async(message,method)=>{if(!message.route)return void 0;if(method){if(Array.isArray(message.args)){return graph.__node.nodes.get(message.route)[method]?.(...message.args)}else return graph.__node.nodes.get(message.route)[method]?.(message.args)}else{if(Array.isArray(message.args)){return graph.run(message.route,...message.args)}else return graph.run(message.route,message.args)}};settings.post=async(route,args,method)=>{if(route&&graph.get(route)){let n=graph.get(route);if(method){if(Array.isArray(args)){return n[method]?.(...args)}else return n[method]?.(args)}else{if(Array.isArray(args)){return n.run(...args)}else return n.run(args)}}};settings.run=settings.post;settings.subscribe=async(route,callback)=>{return graph.subscribe(route,callback)};settings.unsubscribe=async(route,sub)=>{return graph.unsubscribe(route,sub)};settings.terminate=n=>{graph.remove(n);return true}}else if(!(options._id&&this.connections[options._id])){let c=options.connection;if(typeof c==="string"){if(this.connections[c])c=this.connections[c];else if(options.service){if(typeof options.service==="string"){options.service=this.services[options.service]}if(typeof options.service==="object"){if(options.service.connections){for(const key in options.service.connections){if(options.service.connections[key][c]){c=options.service.connections[key][c];settings.connectionType=key;settings.connectionsKey=c;break}}}}}else{for(const j in this.serviceConnections){for(const k in this.serviceConnections[j]){if(this.serviceConnections[j][k][c]){c=this.serviceConnections[j][k][c];options.service=j;settings.connectionType=j;settings.connectionsKey=k;break}}}}}if(typeof c!=="object")return void 0;settings._id=c._id;settings.connection=options.connection;settings.send=c.send;settings.request=c.request;settings.run=c.run;settings.post=c.post;settings.subscribe=c.subscribe;settings.unsubscribe=c.unsubscribe;settings.terminate=c.terminate;settings.onclose=options.onclose;if(settings.onclose){if(!(c.onclose&&settings.onclose.toString()===c.onclose.toString())){let oldonclose=c.onclose;c.onclose=(...args)=>{if(settings.onclose)settings.onclose(settings,...args);if(autoRemove&&settings.source&&this.users[settings.source]&&Object.keys(this.sources[settings.source]).length===0){this.removeUser(settings.source,false)}if(oldonclose)oldonclose(...args)}}}else{let oldonclose=c.onclose;c.onclose=(...args)=>{this.removeConnection(settings);if(autoRemove&&settings.source&&this.users[settings.source]&&Object.keys(this.sources[settings.source]).length===0){this.removeUser(settings.source,false)}if(oldonclose)oldonclose(...args)}}if(options.service){if(typeof options.service==="string")options.service=this.services[options.service];settings.service=options.service}else if(c.graph)settings.service=c.graph}if(!settings.source&&options.source){settings.source=options.source}else if(!settings.source&&options.service){settings.source=typeof options.service==="object"?options.service?.name:void 0}else if(!settings.source&&(settings.connection instanceof GraphNode||settings.connection instanceof Graph)){settings.source="local";if(!this.order.indexOf("local"))this.order.unshift("local")}if(!settings._id)settings._id=`connection${Math.floor(Math.random()*1e15)}`;if(settings.source){if(!this.sources[settings.source])this.sources[settings.source]={};this.sources[settings.source][settings._id]=settings}if(!this.connections[settings._id])this.connections[settings._id]=settings;return settings};removeConnection=(connection,terminate=false)=>{if(typeof connection==="object"&&connection._id)connection=connection._id;if(typeof connection==="string"){if(this.connections[connection]){if(terminate&&this.connections[connection])this.connections[connection].terminate();delete this.connections[connection];for(const key in this.sources){if(this.sources[key][connection])delete this.sources[key][connection];else{for(const k in this.sources[key]){if(this.sources[key][k]?.[connection]){delete this.sources[key][connection]}}}}return true}else if(this.sources[connection]){for(const key in this.sources[connection]){this.removeConnection(this.sources[connection][key],terminate)}return true}}};routeService=(service,connections,source,order)=>{this.services[service.name]=service;if(service.__node?.nodes)this.__node.nodes.forEach((n,k)=>{if(!service.__node?.nodes.get(k)){service.__node?.nodes.set(k,n)}else service.__node?.nodes.set(this.name+"."+k,n)});if(service.users)service.users=this.users;if(connections){if(typeof connections==="string")this.addServiceConnections(service,connections,source);else{for(const c in connections){this.addServiceConnections(service,c,source)}}}if(order)this.order=order;else{if(!this.order)this.order=[];this.order.push(service.name)}};addServiceConnections=(service,connectionsKey,source)=>{if(typeof service==="string"){service=this.services[service]}if(connectionsKey&&service[connectionsKey]){let newConnections={};if(!this.serviceConnections[service.name])this.serviceConnections[service.name]={};this.serviceConnections[service.name][connectionsKey]=service[connectionsKey];for(const key in service[connectionsKey]){if(!this.connections[key]){newConnections[key]=this.addConnection({connection:service[connectionsKey][key],service},source);newConnections[key].connectionType=connectionsKey}}return newConnections}};openConnection=async(service,options,source,...args)=>{if(typeof service==="string"){service=this.services[service]}if(service?.__node.nodes){let connection=service.run("open",options,...args);if(connection instanceof Promise){return connection.then(async info=>{if(!info._id){await connectionHasId(info,this.userTimeout)}if(info._id)this.addConnection({connection:info,service},source)})}else if(connection){if(!connection._id){await connectionHasId(connection,this.userTimeout)}if(connection._id)return this.addConnection({connection,service},source)}}};terminate=connection=>{if(typeof connection==="string")connection=this.connections[connection];return connection.terminate()};routeConnections=(route,transmitter,receiver,...args)=>{let rxsrc;if(typeof receiver==="string"){if(this.sources[receiver]){rxsrc=receiver}receiver=this.getConnection(receiver,"send")}if(typeof transmitter==="string"){transmitter=this.getConnection(transmitter,"subscribe")}if(transmitter?.subscribe&&receiver?.send){let res=new Promise((res2,rej)=>{transmitter.subscribe(route,res3=>{if(!this.connections[receiver._id]&&rxsrc){if(this.sources[rxsrc]){rxsrc=receiver;Object.keys(this.sources[rxsrc]).forEach(k=>{if(this.sources[receiver][k].send){receiver=this.sources[receiver][k]}})}}if(this.connections[receiver._id])receiver.send({callbackId:route,args:res3})},...args).then(sub=>{res2(sub)})});return res}};setUserData=(user,data)=>{if(user){if(typeof user==="string"){user=this.users[user];if(!user)return false}}if(data){if(typeof data==="string"){data=JSON.parse(data)}}if(typeof data==="object"){this.recursivelyAssign(user,data);return true}}};function connectionHasId(connection,timeout=1e4){return new Promise((res,rej)=>{let start=performance.now();let checker=()=>{if(!connection._id){if(performance.now()-start>timeout){rej(false)}else{setTimeout(()=>{checker()},100)}}else{res(true)}};checker()}).catch(er=>{console.error("Connection timed out:",er)})}0&&(module.exports={CMDService,Callable,E2EEService,ECSService,EventHandler,Graph,GraphNode,HTTPbackend,Router,SSEbackend,Service,SessionsService,WSSbackend,animate,backprop,bindListener,branching,connectionHasId,defaultManifest,defaultServiceWorker,getAllProperties,getCallbackFromString,htmlBodyBoilerPlate,instanceObject,isFunction,isNativeClass,isTypedArray,loaders,loop,methodstrings,nodeTemplates,recursivelyAssign,remoteGraphRoutes,scriptBoilerPlate,spliceTypedArray,state,substitute__operator,transformListenerResult,triggerListenerOncreate,wrapArgs}); +var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf;var __hasOwnProp=Object.prototype.hasOwnProperty;var __commonJS=(cb,mod)=>function __require(){return mod||(0,cb[__getOwnPropNames(cb)[0]])((mod={exports:{}}).exports,mod),mod.exports};var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from==="object"||typeof from==="function"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:true}):target,mod));var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:true}),mod);var require_sjcl=__commonJS({"services/e2ee/sjcl.js"(exports,module2){"use strict";var sjcl2={cipher:{},hash:{},keyexchange:{},mode:{},misc:{},codec:{},exception:{corrupt:function(a){this.toString=function(){return"CORRUPT: "+this.message};this.message=a},invalid:function(a){this.toString=function(){return"INVALID: "+this.message};this.message=a},bug:function(a){this.toString=function(){return"BUG: "+this.message};this.message=a},notReady:function(a){this.toString=function(){return"NOT READY: "+this.message};this.message=a}}};sjcl2.cipher.aes=function(a){this.s[0][0][0]||this.O();var b,c,d,e,f=this.s[0][4],g=this.s[1];b=a.length;var h=1;if(4!==b&&6!==b&&8!==b)throw new sjcl2.exception.invalid("invalid aes key size");this.b=[d=a.slice(0),e=[]];for(a=b;a<4*b+28;a++){c=d[a-1];if(0===a%b||8===b&&4===a%b)c=f[c>>>24]<<24^f[c>>16&255]<<16^f[c>>8&255]<<8^f[c&255],0===a%b&&(c=c<<8^c>>>24^h<<24,h=h<<1^283*(h>>7));d[a]=d[a-b]^c}for(b=0;a;b++,a--)c=d[b&3?a:a-4],e[b]=4>=a||4>b?c:g[0][f[c>>>24]]^g[1][f[c>>16&255]]^g[2][f[c>>8&255]]^g[3][f[c&255]]};sjcl2.cipher.aes.prototype={encrypt:function(a){return t(this,a,0)},decrypt:function(a){return t(this,a,1)},s:[[[],[],[],[],[]],[[],[],[],[],[]]],O:function(){var a=this.s[0],b=this.s[1],c=a[4],d=b[4],e,f,g,h=[],k=[],l,n,m,p;for(e=0;256>e;e++)k[(h[e]=e<<1^283*(e>>7))^e]=e;for(f=g=0;!c[f];f^=l||1,g=k[g]||1)for(m=g^g<<1^g<<2^g<<3^g<<4,m=m>>8^m&255^99,c[f]=m,d[m]=f,n=h[e=h[l=h[f]]],p=16843009*n^65537*e^257*l^16843008*f,n=257*h[m]^16843008*m,e=0;4>e;e++)a[e][f]=n=n<<24^n>>>8,b[e][m]=p=p<<24^p>>>8;for(e=0;5>e;e++)a[e]=a[e].slice(0),b[e]=b[e].slice(0)}};function t(a,b,c){if(4!==b.length)throw new sjcl2.exception.invalid("invalid aes block size");var d=a.b[c],e=b[0]^d[0],f=b[c?3:1]^d[1],g=b[2]^d[2];b=b[c?1:3]^d[3];var h,k,l,n=d.length/4-2,m,p=4,r=[0,0,0,0];h=a.s[c];a=h[0];var q=h[1],v=h[2],w=h[3],x=h[4];for(m=0;m>>24]^q[f>>16&255]^v[g>>8&255]^w[b&255]^d[p],k=a[f>>>24]^q[g>>16&255]^v[b>>8&255]^w[e&255]^d[p+1],l=a[g>>>24]^q[b>>16&255]^v[e>>8&255]^w[f&255]^d[p+2],b=a[b>>>24]^q[e>>16&255]^v[f>>8&255]^w[g&255]^d[p+3],p+=4,e=h,f=k,g=l;for(m=0;4>m;m++)r[c?3&-m:m]=x[e>>>24]<<24^x[f>>16&255]<<16^x[g>>8&255]<<8^x[b&255]^d[p++],h=e,e=f,f=g,g=b,b=h;return r}sjcl2.bitArray={bitSlice:function(a,b,c){a=sjcl2.bitArray.$(a.slice(b/32),32-(b&31)).slice(1);return void 0===c?a:sjcl2.bitArray.clamp(a,c-b)},extract:function(a,b,c){var d=Math.floor(-b-c&31);return((b+c-1^b)&-32?a[b/32|0]<<32-d^a[b/32+1|0]>>>d:a[b/32|0]>>>d)&(1<>b-1,1));return a},partial:function(a,b,c){return 32===a?b:(c?b|0:b<<32-a)+1099511627776*a},getPartial:function(a){return Math.round(a/1099511627776)||32},equal:function(a,b){if(sjcl2.bitArray.bitLength(a)!==sjcl2.bitArray.bitLength(b))return false;var c=0,d;for(d=0;d>>b),c=a[e]<<32-b;e=a.length?a[a.length-1]:0;a=sjcl2.bitArray.getPartial(e);d.push(sjcl2.bitArray.partial(b+a&31,32>>24|c>>>8&65280|(c&65280)<<8|c<<24;return a}};sjcl2.codec.utf8String={fromBits:function(a){var b="",c=sjcl2.bitArray.bitLength(a),d,e;for(d=0;d>>8>>>8>>>8),e<<=8;return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,d=0;for(c=0;c>>g)>>>e),gn){if(!b)try{return sjcl2.codec.base32hex.toBits(a)}catch(p){}throw new sjcl2.exception.invalid("this isn't "+m+"!")}h>e?(h-=e,f.push(l^n>>>h),l=n<>>e)>>>26),6>e?(g=a[c]<<6-e,e+=26,c++):(g<<=6,e-=6);for(;d.length&3&&!b;)d+="=";return d},toBits:function(a,b){a=a.replace(/\s|=/g,"");var c=[],d,e=0,f=sjcl2.codec.base64.B,g=0,h;b&&(f=f.substr(0,62)+"-_");for(d=0;dh)throw new sjcl2.exception.invalid("this isn't base64!");26>>e),g=h<<32-e):(e+=6,g^=h<<32-e)}e&56&&c.push(sjcl2.bitArray.partial(e&56,g,1));return c}};sjcl2.codec.base64url={fromBits:function(a){return sjcl2.codec.base64.fromBits(a,1,1)},toBits:function(a){return sjcl2.codec.base64.toBits(a,1)}};sjcl2.hash.sha256=function(a){this.b[0]||this.O();a?(this.F=a.F.slice(0),this.A=a.A.slice(0),this.l=a.l):this.reset()};sjcl2.hash.sha256.hash=function(a){return new sjcl2.hash.sha256().update(a).finalize()};sjcl2.hash.sha256.prototype={blockSize:512,reset:function(){this.F=this.Y.slice(0);this.A=[];this.l=0;return this},update:function(a){"string"===typeof a&&(a=sjcl2.codec.utf8String.toBits(a));var b,c=this.A=sjcl2.bitArray.concat(this.A,a);b=this.l;a=this.l=b+sjcl2.bitArray.bitLength(a);if(9007199254740991b;c++){e=true;for(d=2;d*d<=c;d++)if(0===c%d){e=false;break}e&&(8>b&&(this.Y[b]=a(Math.pow(c,.5))),this.b[b]=a(Math.pow(c,1/3)),b++)}}};function u(a,b){var c,d,e,f=a.F,g=a.b,h=f[0],k=f[1],l=f[2],n=f[3],m=f[4],p=f[5],r=f[6],q=f[7];for(c=0;64>c;c++)16>c?d=b[c]:(d=b[c+1&15],e=b[c+14&15],d=b[c&15]=(d>>>7^d>>>18^d>>>3^d<<25^d<<14)+(e>>>17^e>>>19^e>>>10^e<<15^e<<13)+b[c&15]+b[c+9&15]|0),d=d+q+(m>>>6^m>>>11^m>>>25^m<<26^m<<21^m<<7)+(r^m&(p^r))+g[c],q=r,r=p,p=m,m=n+d|0,n=l,l=k,k=h,h=d+(k&l^n&(k^l))+(k>>>2^k>>>13^k>>>22^k<<30^k<<19^k<<10)|0;f[0]=f[0]+h|0;f[1]=f[1]+k|0;f[2]=f[2]+l|0;f[3]=f[3]+n|0;f[4]=f[4]+m|0;f[5]=f[5]+p|0;f[6]=f[6]+r|0;f[7]=f[7]+q|0}sjcl2.mode.ccm={name:"ccm",G:[],listenProgress:function(a){sjcl2.mode.ccm.G.push(a)},unListenProgress:function(a){a=sjcl2.mode.ccm.G.indexOf(a);-1k)throw new sjcl2.exception.invalid("ccm: iv must be at least 7 bytes");for(f=2;4>f&&l>>>8*f;f++);f<15-k&&(f=15-k);c=h.clamp(c,8*(15-f));b=sjcl2.mode.ccm.V(a,b,c,d,e,f);g=sjcl2.mode.ccm.C(a,g,c,b,e,f);return h.concat(g.data,g.tag)},decrypt:function(a,b,c,d,e){e=e||64;d=d||[];var f=sjcl2.bitArray,g=f.bitLength(c)/8,h=f.bitLength(b),k=f.clamp(b,h-e),l=f.bitSlice(b,h-e),h=(h-e)/8;if(7>g)throw new sjcl2.exception.invalid("ccm: iv must be at least 7 bytes");for(b=2;4>b&&h>>>8*b;b++);b<15-g&&(b=15-g);c=f.clamp(c,8*(15-b));k=sjcl2.mode.ccm.C(a,k,c,l,e,b);a=sjcl2.mode.ccm.V(a,k.data,c,d,e,b);if(!f.equal(k.tag,a))throw new sjcl2.exception.corrupt("ccm: tag doesn't match");return k.data},na:function(a,b,c,d,e,f){var g=[],h=sjcl2.bitArray,k=h.i;d=[h.partial(8,(b.length?64:0)|d-2<<2|f-1)];d=h.concat(d,c);d[3]|=e;d=a.encrypt(d);if(b.length)for(c=h.bitLength(b)/8,65279>=c?g=[h.partial(16,c)]:4294967295>=c&&(g=h.concat([h.partial(16,65534)],[c])),g=h.concat(g,b),b=0;be||16n&&(sjcl2.mode.ccm.fa(g/k),n+=m),c[3]++,e=a.encrypt(c),b[g]^=e[0],b[g+1]^=e[1],b[g+2]^=e[2],b[g+3]^=e[3];return{tag:d,data:h.clamp(b,l)}}};sjcl2.mode.ocb2={name:"ocb2",encrypt:function(a,b,c,d,e,f){if(128!==sjcl2.bitArray.bitLength(c))throw new sjcl2.exception.invalid("ocb iv must be 128 bits");var g,h=sjcl2.mode.ocb2.S,k=sjcl2.bitArray,l=k.i,n=[0,0,0,0];c=h(a.encrypt(c));var m,p=[];d=d||[];e=e||64;for(g=0;g+4e.bitLength(c)&&(h=f(h,d(h)),c=e.concat(c,[-2147483648,0,0,0]));g=f(g,c);return a.encrypt(f(d(f(h,d(h))),g))},S:function(a){return[a[0]<<1^a[1]>>>31,a[1]<<1^a[2]>>>31,a[2]<<1^a[3]>>>31,a[3]<<1^135*(a[0]>>>31)]}};sjcl2.mode.gcm={name:"gcm",encrypt:function(a,b,c,d,e){var f=b.slice(0);b=sjcl2.bitArray;d=d||[];a=sjcl2.mode.gcm.C(true,a,f,d,c,e||128);return b.concat(a.data,a.tag)},decrypt:function(a,b,c,d,e){var f=b.slice(0),g=sjcl2.bitArray,h=g.bitLength(f);e=e||128;d=d||[];e<=h?(b=g.bitSlice(f,h-e),f=g.bitSlice(f,0,h-e)):(b=f,f=[]);a=sjcl2.mode.gcm.C(false,a,f,d,c,e);if(!g.equal(a.tag,b))throw new sjcl2.exception.corrupt("gcm: tag doesn't match");return a.data},ka:function(a,b){var c,d,e,f,g,h=sjcl2.bitArray.i;e=[0,0,0,0];f=b.slice(0);for(c=0;128>c;c++){(d=0!==(a[Math.floor(c/32)]&1<<31-c%32))&&(e=h(e,f));g=0!==(f[3]&1);for(d=3;0>>1|(f[d-1]&1)<<31;f[0]>>>=1;g&&(f[0]^=-520093696)}return e},j:function(a,b,c){var d,e=c.length;b=b.slice(0);for(d=0;de&&(a=b.hash(a));for(d=0;dd||0>c)throw new sjcl2.exception.invalid("invalid params to pbkdf2");"string"===typeof a&&(a=sjcl2.codec.utf8String.toBits(a));"string"===typeof b&&(b=sjcl2.codec.utf8String.toBits(b));e=e||sjcl2.misc.hmac;a=new e(a);var f,g,h,k,l=[],n=sjcl2.bitArray;for(k=1;32*l.length<(d||1);k++){e=f=a.encrypt(n.concat(b,[k]));for(g=1;gg;g++)e.push(4294967296*Math.random()|0);for(g=0;g=1<this.o&&(this.o=f);this.P++;this.b=sjcl2.hash.sha256.hash(this.b.concat(e));this.L=new sjcl2.cipher.aes(this.b);for(d=0;4>d&&(this.h[d]=this.h[d]+1|0,!this.h[d]);d++);}for(d=0;d>>1;this.c[g].update([d,this.N++,2,b,f,a.length].concat(a))}break;case"string":void 0===b&&(b=a.length);this.c[g].update([d,this.N++,3,b,f,a.length]);this.c[g].update(a);break;default:k=1}if(k)throw new sjcl2.exception.bug("random: addEntropy only supports number, array of numbers or string");this.m[g]+=b;this.f+=b;h===this.u&&(this.isReady()!==this.u&&A("seeded",Math.max(this.o,this.f)),A("progress",this.getProgress()))},isReady:function(a){a=this.T[void 0!==a?a:this.M];return this.o&&this.o>=a?this.m[0]>this.ba&&new Date().valueOf()>this.Z?this.J|this.I:this.I:this.f>=a?this.J|this.u:this.u},getProgress:function(a){a=this.T[a?a:this.M];return this.o>=a?1:this.f>a?1:this.f/a},startCollectors:function(){if(!this.D){this.a={loadTimeCollector:B(this,this.ma),mouseCollector:B(this,this.oa),keyboardCollector:B(this,this.la),accelerometerCollector:B(this,this.ea),touchCollector:B(this,this.qa)};if(window.addEventListener)window.addEventListener("load",this.a.loadTimeCollector,false),window.addEventListener("mousemove",this.a.mouseCollector,false),window.addEventListener("keypress",this.a.keyboardCollector,false),window.addEventListener("devicemotion",this.a.accelerometerCollector,false),window.addEventListener("touchmove",this.a.touchCollector,false);else if(document.attachEvent)document.attachEvent("onload",this.a.loadTimeCollector),document.attachEvent("onmousemove",this.a.mouseCollector),document.attachEvent("keypress",this.a.keyboardCollector);else throw new sjcl2.exception.bug("can't attach event");this.D=true}},stopCollectors:function(){this.D&&(window.removeEventListener?(window.removeEventListener("load",this.a.loadTimeCollector,false),window.removeEventListener("mousemove",this.a.mouseCollector,false),window.removeEventListener("keypress",this.a.keyboardCollector,false),window.removeEventListener("devicemotion",this.a.accelerometerCollector,false),window.removeEventListener("touchmove",this.a.touchCollector,false)):document.detachEvent&&(document.detachEvent("onload",this.a.loadTimeCollector),document.detachEvent("onmousemove",this.a.mouseCollector),document.detachEvent("keypress",this.a.keyboardCollector)),this.D=false)},addEventListener:function(a,b){this.K[a][this.ga++]=b},removeEventListener:function(a,b){var c,d,e=this.K[a],f=[];for(d in e)e.hasOwnProperty(d)&&e[d]===b&&f.push(d);for(c=0;cb&&(a.h[b]=a.h[b]+1|0,!a.h[b]);b++);return a.L.encrypt(a.h)}function B(a,b){return function(){b.apply(a,arguments)}}sjcl2.random=new sjcl2.prng(6);a:try{if(G="undefined"!==typeof module2&&module2.exports){try{H=require("crypto")}catch(a){H=null}G=E=H}if(G&&E.randomBytes)D=E.randomBytes(128),D=new Uint32Array(new Uint8Array(D).buffer),sjcl2.random.addEntropy(D,1024,"crypto['randomBytes']");else if("undefined"!==typeof window&&"undefined"!==typeof Uint32Array){F=new Uint32Array(32);if(window.crypto&&window.crypto.getRandomValues)window.crypto.getRandomValues(F);else if(window.msCrypto&&window.msCrypto.getRandomValues)window.msCrypto.getRandomValues(F);else break a;sjcl2.random.addEntropy(F,1024,"crypto['getRandomValues']")}}catch(a){"undefined"!==typeof window&&window.console&&(console.log("There was an error collecting entropy from the browser:"),console.log(a))}var D;var E;var F;var G;var H;sjcl2.json={defaults:{v:1,iter:1e4,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},ja:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl2.json,f=e.g({iv:sjcl2.random.randomWords(4,0)},e.defaults),g;e.g(f,c);c=f.adata;"string"===typeof f.salt&&(f.salt=sjcl2.codec.base64.toBits(f.salt));"string"===typeof f.iv&&(f.iv=sjcl2.codec.base64.toBits(f.iv));if(!sjcl2.mode[f.mode]||!sjcl2.cipher[f.cipher]||"string"===typeof a&&100>=f.iter||64!==f.ts&&96!==f.ts&&128!==f.ts||128!==f.ks&&192!==f.ks&&256!==f.ks||2>f.iv.length||4=b.iter||64!==b.ts&&96!==b.ts&&128!==b.ts||128!==b.ks&&192!==b.ks&&256!==b.ks||!b.iv||2>b.iv.length||4(()=>{"use strict";var e={n:t2=>{var s2=t2&&t2.__esModule?()=>t2.default:()=>t2;return e.d(s2,{a:s2}),s2},d:(t2,s2)=>{for(var i2 in s2)e.o(s2,i2)&&!e.o(t2,i2)&&Object.defineProperty(t2,i2,{enumerable:true,get:s2[i2]})},o:(e2,t2)=>Object.prototype.hasOwnProperty.call(e2,t2),r:e2=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e2,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e2,"__esModule",{value:true})}},t={};e.r(t),e.d(t,{Channel:()=>f,Session:()=>u,createChannel:()=>v,createSession:()=>p});const s=require("http"),i=require("events");var r=e.n(i);class n extends r(){addListener(e2,t2){return super.addListener(e2,t2)}prependListener(e2,t2){return super.prependListener(e2,t2)}prependOnceListener(e2,t2){return super.prependOnceListener(e2,t2)}on(e2,t2){return super.on(e2,t2)}once(e2,t2){return super.once(e2,t2)}emit(e2,...t2){return super.emit(e2,...t2)}off(e2,t2){return super.off(e2,t2)}removeListener(e2,t2){return super.removeListener(e2,t2)}}const o=e2=>JSON.stringify(e2),a=/(\r\n|\r|\n)/g,h=/\n+$/g,l=e2=>{let t2=e2;return t2=t2.replace(a,"\n"),t2=t2.replace(h,""),t2},d=require("crypto");let c;c=d.randomUUID?()=>(0,d.randomUUID)():()=>(0,d.randomBytes)(4).toString("hex");class u extends n{constructor(e2,t2,i2={}){var r2,n2,a2,h2,d2,u2,p2;super(),this.lastId="",this.isConnected=false,this.state={},this.buffer="",this.initialize=()=>{var e3,t3,i3;const r3=`http://${this.req.headers.host}${this.req.url}`,n3=new URL(r3).searchParams;if(this.trustClientEventId){const s2=null!==(i3=null!==(t3=null!==(e3=this.req.headers["last-event-id"])&&void 0!==e3?e3:n3.get("lastEventId"))&&void 0!==t3?t3:n3.get("evs_last_event_id"))&&void 0!==i3?i3:"";this.lastId=s2}const o2={};this.res instanceof s.ServerResponse?(o2["Content-Type"]="text/event-stream",o2["Cache-Control"]="private, no-cache, no-store, no-transform, must-revalidate, max-age=0",o2.Connection="keep-alive",o2.Pragma="no-cache",o2["X-Accel-Buffering"]="no"):(o2["content-type"]="text/event-stream",o2["cache-control"]="private, no-cache, no-store, no-transform, must-revalidate, max-age=0",o2.pragma="no-cache",o2["x-accel-buffering"]="no");for(const[e4,t4]of Object.entries(this.headers))o2[e4]=null!=t4?t4:"";this.res.writeHead(this.statusCode,o2),n3.has("padding")&&this.comment(" ".repeat(2049)).dispatch(),n3.has("evs_preamble")&&this.comment(" ".repeat(2056)).dispatch(),null!==this.initialRetry&&this.retry(this.initialRetry).dispatch(),this.flush(),null!==this.keepAliveInterval&&(this.keepAliveTimer=setInterval(this.keepAlive,this.keepAliveInterval)),this.isConnected=true,this.emit("connected")},this.onDisconnected=()=>{this.keepAliveTimer&&clearInterval(this.keepAliveTimer),this.isConnected=false,this.emit("disconnected")},this.writeField=(e3,t3)=>{const s2=this.sanitize(t3);return this.buffer+=e3+":"+s2+"\n",this},this.keepAlive=()=>{this.comment().dispatch().flush()},this.data=e3=>{const t3=this.serialize(e3);return this.writeField("data",t3),this},this.id=(e3="")=>(this.writeField("id",e3),this.lastId=e3,this),this.retry=e3=>{const t3=e3.toString();return this.writeField("retry",t3),this},this.comment=(e3="")=>(this.writeField("",e3),this),this.dispatch=()=>(this.buffer+="\n",this),this.flush=()=>(this.res.write(this.buffer),this.buffer="",this),this.push=(e3,t3="message",s2=c())=>(this.event(t3).id(s2).data(e3).dispatch().flush(),this.emit("push",e3,t3,s2),this),this.stream=async(e3,t3={})=>{const{eventName:s2="stream"}=t3;return new Promise((t4,i3)=>{e3.on("data",e4=>{let t5;t5=Buffer.isBuffer(e4)?e4.toString():e4,this.push(t5,s2)}),e3.once("end",()=>t4(true)),e3.once("close",()=>t4(true)),e3.once("error",e4=>i3(e4))})},this.iterate=async(e3,t3={})=>{const{eventName:s2="iteration"}=t3;for await(const t4 of e3)this.push(t4,s2)},this.req=e2,this.res=t2,this.serialize=null!==(r2=i2.serializer)&&void 0!==r2?r2:o,this.sanitize=null!==(n2=i2.sanitizer)&&void 0!==n2?n2:l,this.trustClientEventId=null===(a2=i2.trustClientEventId)||void 0===a2||a2,this.initialRetry=null===i2.retry?null:null!==(h2=i2.retry)&&void 0!==h2?h2:2e3,this.keepAliveInterval=null===i2.keepAlive?null:null!==(d2=i2.keepAlive)&&void 0!==d2?d2:1e4,this.statusCode=null!==(u2=i2.statusCode)&&void 0!==u2?u2:200,this.headers=null!==(p2=i2.headers)&&void 0!==p2?p2:{},this.req.once("close",this.onDisconnected),setImmediate(this.initialize)}event(e2){return this.writeField("event",e2),this}}const p=(...e2)=>new Promise(t2=>{const s2=new u(...e2);s2.once("connected",()=>{t2(s2)})});class f extends n{constructor(){super(),this.state={},this.sessions=new Set,this.broadcast=(e2,t2="message",s2={})=>{const i2=c();let r2;r2=s2.filter?Array.from(this.sessions).filter(s2.filter):this.sessions;for(const s3 of r2)s3.push(e2,t2,i2);return this.emit("broadcast",e2,t2,i2),this}}get activeSessions(){return Array.from(this.sessions)}get sessionCount(){return this.sessions.size}register(e2){if(this.sessions.has(e2))return this;if(!e2.isConnected)throw new Error("Cannot register a non-active session.");return e2.once("disconnected",()=>{this.emit("session-disconnected",e2),this.deregister(e2)}),this.sessions.add(e2),this.emit("session-registered",e2),this}deregister(e2){return this.sessions.has(e2)?(this.sessions.delete(e2),this.emit("session-deregistered",e2),this):this}}const v=(...e2)=>new f(...e2);return t})())}});var require_stream=__commonJS({"node_modules/ws/lib/stream.js"(exports,module2){"use strict";var{Duplex}=require("stream");function emitClose(stream){stream.emit("close")}function duplexOnEnd(){if(!this.destroyed&&this._writableState.finished){this.destroy()}}function duplexOnError(err){this.removeListener("error",duplexOnError);this.destroy();if(this.listenerCount("error")===0){this.emit("error",err)}}function createWebSocketStream2(ws,options){let terminateOnDestroy=true;const duplex=new Duplex({...options,autoDestroy:false,emitClose:false,objectMode:false,writableObjectMode:false});ws.on("message",function message(msg,isBinary){const data=!isBinary&&duplex._readableState.objectMode?msg.toString():msg;if(!duplex.push(data))ws.pause()});ws.once("error",function error(err){if(duplex.destroyed)return;terminateOnDestroy=false;duplex.destroy(err)});ws.once("close",function close(){if(duplex.destroyed)return;duplex.push(null)});duplex._destroy=function(err,callback){if(ws.readyState===ws.CLOSED){callback(err);process.nextTick(emitClose,duplex);return}let called=false;ws.once("error",function error(err2){called=true;callback(err2)});ws.once("close",function close(){if(!called)callback(err);process.nextTick(emitClose,duplex)});if(terminateOnDestroy)ws.terminate()};duplex._final=function(callback){if(ws.readyState===ws.CONNECTING){ws.once("open",function open(){duplex._final(callback)});return}if(ws._socket===null)return;if(ws._socket._writableState.finished){callback();if(duplex._readableState.endEmitted)duplex.destroy()}else{ws._socket.once("finish",function finish(){callback()});ws.close()}};duplex._read=function(){if(ws.isPaused)ws.resume()};duplex._write=function(chunk,encoding,callback){if(ws.readyState===ws.CONNECTING){ws.once("open",function open(){duplex._write(chunk,encoding,callback)});return}ws.send(chunk,callback)};duplex.on("end",duplexOnEnd);duplex.on("error",duplexOnError);return duplex}module2.exports=createWebSocketStream2}});var require_constants=__commonJS({"node_modules/ws/lib/constants.js"(exports,module2){"use strict";module2.exports={BINARY_TYPES:["nodebuffer","arraybuffer","fragments"],EMPTY_BUFFER:Buffer.alloc(0),GUID:"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",kForOnEventAttribute:Symbol("kIsForOnEventAttribute"),kListener:Symbol("kListener"),kStatusCode:Symbol("status-code"),kWebSocket:Symbol("websocket"),NOOP:()=>{}}}});var require_buffer_util=__commonJS({"node_modules/ws/lib/buffer-util.js"(exports,module2){"use strict";var{EMPTY_BUFFER}=require_constants();function concat(list,totalLength){if(list.length===0)return EMPTY_BUFFER;if(list.length===1)return list[0];const target=Buffer.allocUnsafe(totalLength);let offset=0;for(let i=0;i{this.pending--;this[kRun]()};this.concurrency=concurrency||Infinity;this.jobs=[];this.pending=0}add(job){this.jobs.push(job);this[kRun]()}[kRun](){if(this.pending===this.concurrency)return;if(this.jobs.length){const job=this.jobs.shift();this.pending++;job(this[kDone])}}};module2.exports=Limiter}});var require_permessage_deflate=__commonJS({"node_modules/ws/lib/permessage-deflate.js"(exports,module2){"use strict";var zlib=require("zlib");var bufferUtil=require_buffer_util();var Limiter=require_limiter();var{kStatusCode}=require_constants();var TRAILER=Buffer.from([0,0,255,255]);var kPerMessageDeflate=Symbol("permessage-deflate");var kTotalLength=Symbol("total-length");var kCallback=Symbol("callback");var kBuffers=Symbol("buffers");var kError=Symbol("error");var zlibLimiter;var PerMessageDeflate=class{constructor(options,isServer,maxPayload){this._maxPayload=maxPayload|0;this._options=options||{};this._threshold=this._options.threshold!==void 0?this._options.threshold:1024;this._isServer=!!isServer;this._deflate=null;this._inflate=null;this.params=null;if(!zlibLimiter){const concurrency=this._options.concurrencyLimit!==void 0?this._options.concurrencyLimit:10;zlibLimiter=new Limiter(concurrency)}}static get extensionName(){return"permessage-deflate"}offer(){const params={};if(this._options.serverNoContextTakeover){params.server_no_context_takeover=true}if(this._options.clientNoContextTakeover){params.client_no_context_takeover=true}if(this._options.serverMaxWindowBits){params.server_max_window_bits=this._options.serverMaxWindowBits}if(this._options.clientMaxWindowBits){params.client_max_window_bits=this._options.clientMaxWindowBits}else if(this._options.clientMaxWindowBits==null){params.client_max_window_bits=true}return params}accept(configurations){configurations=this.normalizeParams(configurations);this.params=this._isServer?this.acceptAsServer(configurations):this.acceptAsClient(configurations);return this.params}cleanup(){if(this._inflate){this._inflate.close();this._inflate=null}if(this._deflate){const callback=this._deflate[kCallback];this._deflate.close();this._deflate=null;if(callback){callback(new Error("The deflate stream was closed while data was being processed"))}}}acceptAsServer(offers){const opts=this._options;const accepted=offers.find(params=>{if(opts.serverNoContextTakeover===false&¶ms.server_no_context_takeover||params.server_max_window_bits&&(opts.serverMaxWindowBits===false||typeof opts.serverMaxWindowBits==="number"&&opts.serverMaxWindowBits>params.server_max_window_bits)||typeof opts.clientMaxWindowBits==="number"&&!params.client_max_window_bits){return false}return true});if(!accepted){throw new Error("None of the extension offers can be accepted")}if(opts.serverNoContextTakeover){accepted.server_no_context_takeover=true}if(opts.clientNoContextTakeover){accepted.client_no_context_takeover=true}if(typeof opts.serverMaxWindowBits==="number"){accepted.server_max_window_bits=opts.serverMaxWindowBits}if(typeof opts.clientMaxWindowBits==="number"){accepted.client_max_window_bits=opts.clientMaxWindowBits}else if(accepted.client_max_window_bits===true||opts.clientMaxWindowBits===false){delete accepted.client_max_window_bits}return accepted}acceptAsClient(response){const params=response[0];if(this._options.clientNoContextTakeover===false&¶ms.client_no_context_takeover){throw new Error('Unexpected parameter "client_no_context_takeover"')}if(!params.client_max_window_bits){if(typeof this._options.clientMaxWindowBits==="number"){params.client_max_window_bits=this._options.clientMaxWindowBits}}else if(this._options.clientMaxWindowBits===false||typeof this._options.clientMaxWindowBits==="number"&¶ms.client_max_window_bits>this._options.clientMaxWindowBits){throw new Error('Unexpected or invalid parameter "client_max_window_bits"')}return params}normalizeParams(configurations){configurations.forEach(params=>{Object.keys(params).forEach(key=>{let value=params[key];if(value.length>1){throw new Error(`Parameter "${key}" must have only a single value`)}value=value[0];if(key==="client_max_window_bits"){if(value!==true){const num=+value;if(!Number.isInteger(num)||num<8||num>15){throw new TypeError(`Invalid value for parameter "${key}": ${value}`)}value=num}else if(!this._isServer){throw new TypeError(`Invalid value for parameter "${key}": ${value}`)}}else if(key==="server_max_window_bits"){const num=+value;if(!Number.isInteger(num)||num<8||num>15){throw new TypeError(`Invalid value for parameter "${key}": ${value}`)}value=num}else if(key==="client_no_context_takeover"||key==="server_no_context_takeover"){if(value!==true){throw new TypeError(`Invalid value for parameter "${key}": ${value}`)}}else{throw new Error(`Unknown parameter "${key}"`)}params[key]=value})});return configurations}decompress(data,fin,callback){zlibLimiter.add(done=>{this._decompress(data,fin,(err,result)=>{done();callback(err,result)})})}compress(data,fin,callback){zlibLimiter.add(done=>{this._compress(data,fin,(err,result)=>{done();callback(err,result)})})}_decompress(data,fin,callback){const endpoint=this._isServer?"client":"server";if(!this._inflate){const key=`${endpoint}_max_window_bits`;const windowBits=typeof this.params[key]!=="number"?zlib.Z_DEFAULT_WINDOWBITS:this.params[key];this._inflate=zlib.createInflateRaw({...this._options.zlibInflateOptions,windowBits});this._inflate[kPerMessageDeflate]=this;this._inflate[kTotalLength]=0;this._inflate[kBuffers]=[];this._inflate.on("error",inflateOnError);this._inflate.on("data",inflateOnData)}this._inflate[kCallback]=callback;this._inflate.write(data);if(fin)this._inflate.write(TRAILER);this._inflate.flush(()=>{const err=this._inflate[kError];if(err){this._inflate.close();this._inflate=null;callback(err);return}const data2=bufferUtil.concat(this._inflate[kBuffers],this._inflate[kTotalLength]);if(this._inflate._readableState.endEmitted){this._inflate.close();this._inflate=null}else{this._inflate[kTotalLength]=0;this._inflate[kBuffers]=[];if(fin&&this.params[`${endpoint}_no_context_takeover`]){this._inflate.reset()}}callback(null,data2)})}_compress(data,fin,callback){const endpoint=this._isServer?"server":"client";if(!this._deflate){const key=`${endpoint}_max_window_bits`;const windowBits=typeof this.params[key]!=="number"?zlib.Z_DEFAULT_WINDOWBITS:this.params[key];this._deflate=zlib.createDeflateRaw({...this._options.zlibDeflateOptions,windowBits});this._deflate[kTotalLength]=0;this._deflate[kBuffers]=[];this._deflate.on("data",deflateOnData)}this._deflate[kCallback]=callback;this._deflate.write(data);this._deflate.flush(zlib.Z_SYNC_FLUSH,()=>{if(!this._deflate){return}let data2=bufferUtil.concat(this._deflate[kBuffers],this._deflate[kTotalLength]);if(fin)data2=data2.slice(0,data2.length-4);this._deflate[kCallback]=null;this._deflate[kTotalLength]=0;this._deflate[kBuffers]=[];if(fin&&this.params[`${endpoint}_no_context_takeover`]){this._deflate.reset()}callback(null,data2)})}};module2.exports=PerMessageDeflate;function deflateOnData(chunk){this[kBuffers].push(chunk);this[kTotalLength]+=chunk.length}function inflateOnData(chunk){this[kTotalLength]+=chunk.length;if(this[kPerMessageDeflate]._maxPayload<1||this[kTotalLength]<=this[kPerMessageDeflate]._maxPayload){this[kBuffers].push(chunk);return}this[kError]=new RangeError("Max payload size exceeded");this[kError].code="WS_ERR_UNSUPPORTED_MESSAGE_LENGTH";this[kError][kStatusCode]=1009;this.removeListener("data",inflateOnData);this.reset()}function inflateOnError(err){this[kPerMessageDeflate]._inflate=null;err[kStatusCode]=1007;this[kCallback](err)}}});var require_validation=__commonJS({"node_modules/ws/lib/validation.js"(exports,module2){"use strict";var tokenChars=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0];function isValidStatusCode(code){return code>=1e3&&code<=1014&&code!==1004&&code!==1005&&code!==1006||code>=3e3&&code<=4999}function _isValidUTF8(buf){const len=buf.length;let i=0;while(i=len||(buf[i+1]&192)!==128||(buf[i+2]&192)!==128||buf[i]===224&&(buf[i+1]&224)===128||buf[i]===237&&(buf[i+1]&224)===160){return false}i+=3}else if((buf[i]&248)===240){if(i+3>=len||(buf[i+1]&192)!==128||(buf[i+2]&192)!==128||(buf[i+3]&192)!==128||buf[i]===240&&(buf[i+1]&240)===128||buf[i]===244&&buf[i+1]>143||buf[i]>244){return false}i+=4}else{return false}}return true}module2.exports={isValidStatusCode,isValidUTF8:_isValidUTF8,tokenChars};if(!process.env.WS_NO_UTF_8_VALIDATE){try{const isValidUTF8=require("utf-8-validate");module2.exports.isValidUTF8=function(buf){return buf.length<150?_isValidUTF8(buf):isValidUTF8(buf)}}catch(e){}}}});var require_receiver=__commonJS({"node_modules/ws/lib/receiver.js"(exports,module2){"use strict";var{Writable}=require("stream");var PerMessageDeflate=require_permessage_deflate();var{BINARY_TYPES,EMPTY_BUFFER,kStatusCode,kWebSocket}=require_constants();var{concat,toArrayBuffer,unmask}=require_buffer_util();var{isValidStatusCode,isValidUTF8}=require_validation();var GET_INFO=0;var GET_PAYLOAD_LENGTH_16=1;var GET_PAYLOAD_LENGTH_64=2;var GET_MASK=3;var GET_DATA=4;var INFLATING=5;var Receiver2=class extends Writable{constructor(options={}){super();this._binaryType=options.binaryType||BINARY_TYPES[0];this._extensions=options.extensions||{};this._isServer=!!options.isServer;this._maxPayload=options.maxPayload|0;this._skipUTF8Validation=!!options.skipUTF8Validation;this[kWebSocket]=void 0;this._bufferedBytes=0;this._buffers=[];this._compressed=false;this._payloadLength=0;this._mask=void 0;this._fragmented=0;this._masked=false;this._fin=false;this._opcode=0;this._totalPayloadLength=0;this._messageLength=0;this._fragments=[];this._state=GET_INFO;this._loop=false}_write(chunk,encoding,cb){if(this._opcode===8&&this._state==GET_INFO)return cb();this._bufferedBytes+=chunk.length;this._buffers.push(chunk);this.startLoop(cb)}consume(n){this._bufferedBytes-=n;if(n===this._buffers[0].length)return this._buffers.shift();if(n=buf.length){dst.set(this._buffers.shift(),offset)}else{dst.set(new Uint8Array(buf.buffer,buf.byteOffset,n),offset);this._buffers[0]=buf.slice(n)}n-=buf.length}while(n>0);return dst}startLoop(cb){let err;this._loop=true;do{switch(this._state){case GET_INFO:err=this.getInfo();break;case GET_PAYLOAD_LENGTH_16:err=this.getPayloadLength16();break;case GET_PAYLOAD_LENGTH_64:err=this.getPayloadLength64();break;case GET_MASK:this.getMask();break;case GET_DATA:err=this.getData(cb);break;default:this._loop=false;return}}while(this._loop);cb(err)}getInfo(){if(this._bufferedBytes<2){this._loop=false;return}const buf=this.consume(2);if((buf[0]&48)!==0){this._loop=false;return error(RangeError,"RSV2 and RSV3 must be clear",true,1002,"WS_ERR_UNEXPECTED_RSV_2_3")}const compressed=(buf[0]&64)===64;if(compressed&&!this._extensions[PerMessageDeflate.extensionName]){this._loop=false;return error(RangeError,"RSV1 must be clear",true,1002,"WS_ERR_UNEXPECTED_RSV_1")}this._fin=(buf[0]&128)===128;this._opcode=buf[0]&15;this._payloadLength=buf[1]&127;if(this._opcode===0){if(compressed){this._loop=false;return error(RangeError,"RSV1 must be clear",true,1002,"WS_ERR_UNEXPECTED_RSV_1")}if(!this._fragmented){this._loop=false;return error(RangeError,"invalid opcode 0",true,1002,"WS_ERR_INVALID_OPCODE")}this._opcode=this._fragmented}else if(this._opcode===1||this._opcode===2){if(this._fragmented){this._loop=false;return error(RangeError,`invalid opcode ${this._opcode}`,true,1002,"WS_ERR_INVALID_OPCODE")}this._compressed=compressed}else if(this._opcode>7&&this._opcode<11){if(!this._fin){this._loop=false;return error(RangeError,"FIN must be set",true,1002,"WS_ERR_EXPECTED_FIN")}if(compressed){this._loop=false;return error(RangeError,"RSV1 must be clear",true,1002,"WS_ERR_UNEXPECTED_RSV_1")}if(this._payloadLength>125){this._loop=false;return error(RangeError,`invalid payload length ${this._payloadLength}`,true,1002,"WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH")}}else{this._loop=false;return error(RangeError,`invalid opcode ${this._opcode}`,true,1002,"WS_ERR_INVALID_OPCODE")}if(!this._fin&&!this._fragmented)this._fragmented=this._opcode;this._masked=(buf[1]&128)===128;if(this._isServer){if(!this._masked){this._loop=false;return error(RangeError,"MASK must be set",true,1002,"WS_ERR_EXPECTED_MASK")}}else if(this._masked){this._loop=false;return error(RangeError,"MASK must be clear",true,1002,"WS_ERR_UNEXPECTED_MASK")}if(this._payloadLength===126)this._state=GET_PAYLOAD_LENGTH_16;else if(this._payloadLength===127)this._state=GET_PAYLOAD_LENGTH_64;else return this.haveLength()}getPayloadLength16(){if(this._bufferedBytes<2){this._loop=false;return}this._payloadLength=this.consume(2).readUInt16BE(0);return this.haveLength()}getPayloadLength64(){if(this._bufferedBytes<8){this._loop=false;return}const buf=this.consume(8);const num=buf.readUInt32BE(0);if(num>Math.pow(2,53-32)-1){this._loop=false;return error(RangeError,"Unsupported WebSocket frame: payload length > 2^53 - 1",false,1009,"WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH")}this._payloadLength=num*Math.pow(2,32)+buf.readUInt32BE(4);return this.haveLength()}haveLength(){if(this._payloadLength&&this._opcode<8){this._totalPayloadLength+=this._payloadLength;if(this._totalPayloadLength>this._maxPayload&&this._maxPayload>0){this._loop=false;return error(RangeError,"Max payload size exceeded",false,1009,"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH")}}if(this._masked)this._state=GET_MASK;else this._state=GET_DATA}getMask(){if(this._bufferedBytes<4){this._loop=false;return}this._mask=this.consume(4);this._state=GET_DATA}getData(cb){let data=EMPTY_BUFFER;if(this._payloadLength){if(this._bufferedBytes7)return this.controlMessage(data);if(this._compressed){this._state=INFLATING;this.decompress(data,cb);return}if(data.length){this._messageLength=this._totalPayloadLength;this._fragments.push(data)}return this.dataMessage()}decompress(data,cb){const perMessageDeflate=this._extensions[PerMessageDeflate.extensionName];perMessageDeflate.decompress(data,this._fin,(err,buf)=>{if(err)return cb(err);if(buf.length){this._messageLength+=buf.length;if(this._messageLength>this._maxPayload&&this._maxPayload>0){return cb(error(RangeError,"Max payload size exceeded",false,1009,"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH"))}this._fragments.push(buf)}const er=this.dataMessage();if(er)return cb(er);this.startLoop(cb)})}dataMessage(){if(this._fin){const messageLength=this._messageLength;const fragments=this._fragments;this._totalPayloadLength=0;this._messageLength=0;this._fragmented=0;this._fragments=[];if(this._opcode===2){let data;if(this._binaryType==="nodebuffer"){data=concat(fragments,messageLength)}else if(this._binaryType==="arraybuffer"){data=toArrayBuffer(concat(fragments,messageLength))}else{data=fragments}this.emit("message",data,true)}else{const buf=concat(fragments,messageLength);if(!this._skipUTF8Validation&&!isValidUTF8(buf)){this._loop=false;return error(Error,"invalid UTF-8 sequence",true,1007,"WS_ERR_INVALID_UTF8")}this.emit("message",buf,false)}}this._state=GET_INFO}controlMessage(data){if(this._opcode===8){this._loop=false;if(data.length===0){this.emit("conclude",1005,EMPTY_BUFFER);this.end()}else if(data.length===1){return error(RangeError,"invalid payload length 1",true,1002,"WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH")}else{const code=data.readUInt16BE(0);if(!isValidStatusCode(code)){return error(RangeError,`invalid status code ${code}`,true,1002,"WS_ERR_INVALID_CLOSE_CODE")}const buf=data.slice(2);if(!this._skipUTF8Validation&&!isValidUTF8(buf)){return error(Error,"invalid UTF-8 sequence",true,1007,"WS_ERR_INVALID_UTF8")}this.emit("conclude",code,buf);this.end()}}else if(this._opcode===9){this.emit("ping",data)}else{this.emit("pong",data)}this._state=GET_INFO}};module2.exports=Receiver2;function error(ErrorCtor,message,prefix,statusCode,errorCode){const err=new ErrorCtor(prefix?`Invalid WebSocket frame: ${message}`:message);Error.captureStackTrace(err,error);err.code=errorCode;err[kStatusCode]=statusCode;return err}}});var require_sender=__commonJS({"node_modules/ws/lib/sender.js"(exports,module2){"use strict";var net=require("net");var tls=require("tls");var{randomFillSync}=require("crypto");var PerMessageDeflate=require_permessage_deflate();var{EMPTY_BUFFER}=require_constants();var{isValidStatusCode}=require_validation();var{mask:applyMask,toBuffer}=require_buffer_util();var kByteLength=Symbol("kByteLength");var maskBuffer=Buffer.alloc(4);var Sender2=class{constructor(socket,extensions,generateMask){this._extensions=extensions||{};if(generateMask){this._generateMask=generateMask;this._maskBuffer=Buffer.alloc(4)}this._socket=socket;this._firstFragment=true;this._compress=false;this._bufferedBytes=0;this._deflating=false;this._queue=[]}static frame(data,options){let mask;let merge=false;let offset=2;let skipMasking=false;if(options.mask){mask=options.maskBuffer||maskBuffer;if(options.generateMask){options.generateMask(mask)}else{randomFillSync(mask,0,4)}skipMasking=(mask[0]|mask[1]|mask[2]|mask[3])===0;offset=6}let dataLength;if(typeof data==="string"){if((!options.mask||skipMasking)&&options[kByteLength]!==void 0){dataLength=options[kByteLength]}else{data=Buffer.from(data);dataLength=data.length}}else{dataLength=data.length;merge=options.mask&&options.readOnly&&!skipMasking}let payloadLength=dataLength;if(dataLength>=65536){offset+=8;payloadLength=127}else if(dataLength>125){offset+=2;payloadLength=126}const target=Buffer.allocUnsafe(merge?dataLength+offset:offset);target[0]=options.fin?options.opcode|128:options.opcode;if(options.rsv1)target[0]|=64;target[1]=payloadLength;if(payloadLength===126){target.writeUInt16BE(dataLength,2)}else if(payloadLength===127){target[2]=target[3]=0;target.writeUIntBE(dataLength,4,6)}if(!options.mask)return[target,data];target[1]|=128;target[offset-4]=mask[0];target[offset-3]=mask[1];target[offset-2]=mask[2];target[offset-1]=mask[3];if(skipMasking)return[target,data];if(merge){applyMask(data,mask,target,offset,dataLength);return[target]}applyMask(data,mask,data,0,dataLength);return[target,data]}close(code,data,mask,cb){let buf;if(code===void 0){buf=EMPTY_BUFFER}else if(typeof code!=="number"||!isValidStatusCode(code)){throw new TypeError("First argument must be a valid error code number")}else if(data===void 0||!data.length){buf=Buffer.allocUnsafe(2);buf.writeUInt16BE(code,0)}else{const length=Buffer.byteLength(data);if(length>123){throw new RangeError("The message must not be greater than 123 bytes")}buf=Buffer.allocUnsafe(2+length);buf.writeUInt16BE(code,0);if(typeof data==="string"){buf.write(data,2)}else{buf.set(data,2)}}const options={[kByteLength]:buf.length,fin:true,generateMask:this._generateMask,mask,maskBuffer:this._maskBuffer,opcode:8,readOnly:false,rsv1:false};if(this._deflating){this.enqueue([this.dispatch,buf,false,options,cb])}else{this.sendFrame(Sender2.frame(buf,options),cb)}}ping(data,mask,cb){let byteLength;let readOnly;if(typeof data==="string"){byteLength=Buffer.byteLength(data);readOnly=false}else{data=toBuffer(data);byteLength=data.length;readOnly=toBuffer.readOnly}if(byteLength>125){throw new RangeError("The data size must not be greater than 125 bytes")}const options={[kByteLength]:byteLength,fin:true,generateMask:this._generateMask,mask,maskBuffer:this._maskBuffer,opcode:9,readOnly,rsv1:false};if(this._deflating){this.enqueue([this.dispatch,data,false,options,cb])}else{this.sendFrame(Sender2.frame(data,options),cb)}}pong(data,mask,cb){let byteLength;let readOnly;if(typeof data==="string"){byteLength=Buffer.byteLength(data);readOnly=false}else{data=toBuffer(data);byteLength=data.length;readOnly=toBuffer.readOnly}if(byteLength>125){throw new RangeError("The data size must not be greater than 125 bytes")}const options={[kByteLength]:byteLength,fin:true,generateMask:this._generateMask,mask,maskBuffer:this._maskBuffer,opcode:10,readOnly,rsv1:false};if(this._deflating){this.enqueue([this.dispatch,data,false,options,cb])}else{this.sendFrame(Sender2.frame(data,options),cb)}}send(data,options,cb){const perMessageDeflate=this._extensions[PerMessageDeflate.extensionName];let opcode=options.binary?2:1;let rsv1=options.compress;let byteLength;let readOnly;if(typeof data==="string"){byteLength=Buffer.byteLength(data);readOnly=false}else{data=toBuffer(data);byteLength=data.length;readOnly=toBuffer.readOnly}if(this._firstFragment){this._firstFragment=false;if(rsv1&&perMessageDeflate&&perMessageDeflate.params[perMessageDeflate._isServer?"server_no_context_takeover":"client_no_context_takeover"]){rsv1=byteLength>=perMessageDeflate._threshold}this._compress=rsv1}else{rsv1=false;opcode=0}if(options.fin)this._firstFragment=true;if(perMessageDeflate){const opts={[kByteLength]:byteLength,fin:options.fin,generateMask:this._generateMask,mask:options.mask,maskBuffer:this._maskBuffer,opcode,readOnly,rsv1};if(this._deflating){this.enqueue([this.dispatch,data,this._compress,opts,cb])}else{this.dispatch(data,this._compress,opts,cb)}}else{this.sendFrame(Sender2.frame(data,{[kByteLength]:byteLength,fin:options.fin,generateMask:this._generateMask,mask:options.mask,maskBuffer:this._maskBuffer,opcode,readOnly,rsv1:false}),cb)}}dispatch(data,compress,options,cb){if(!compress){this.sendFrame(Sender2.frame(data,options),cb);return}const perMessageDeflate=this._extensions[PerMessageDeflate.extensionName];this._bufferedBytes+=options[kByteLength];this._deflating=true;perMessageDeflate.compress(data,options.fin,(_,buf)=>{if(this._socket.destroyed){const err=new Error("The socket was closed while data was being compressed");if(typeof cb==="function")cb(err);for(let i=0;i{let configurations=extensions[extension];if(!Array.isArray(configurations))configurations=[configurations];return configurations.map(params=>{return[extension].concat(Object.keys(params).map(k=>{let values=params[k];if(!Array.isArray(values))values=[values];return values.map(v=>v===true?k:`${k}=${v}`).join("; ")})).join("; ")}).join(", ")}).join(", ")}module2.exports={format,parse}}});var require_websocket=__commonJS({"node_modules/ws/lib/websocket.js"(exports,module2){"use strict";var EventEmitter=require("events");var https2=require("https");var http2=require("http");var net=require("net");var tls=require("tls");var{randomBytes,createHash}=require("crypto");var{Readable}=require("stream");var{URL:URL2}=require("url");var PerMessageDeflate=require_permessage_deflate();var Receiver2=require_receiver();var Sender2=require_sender();var{BINARY_TYPES,EMPTY_BUFFER,GUID,kForOnEventAttribute,kListener,kStatusCode,kWebSocket,NOOP}=require_constants();var{EventTarget:{addEventListener,removeEventListener}}=require_event_target();var{format,parse}=require_extension();var{toBuffer}=require_buffer_util();var closeTimeout=30*1e3;var kAborted=Symbol("kAborted");var protocolVersions=[8,13];var readyStates=["CONNECTING","OPEN","CLOSING","CLOSED"];var subprotocolRegex=/^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;var WebSocket3=class extends EventEmitter{constructor(address,protocols,options){super();this._binaryType=BINARY_TYPES[0];this._closeCode=1006;this._closeFrameReceived=false;this._closeFrameSent=false;this._closeMessage=EMPTY_BUFFER;this._closeTimer=null;this._extensions={};this._paused=false;this._protocol="";this._readyState=WebSocket3.CONNECTING;this._receiver=null;this._sender=null;this._socket=null;if(address!==null){this._bufferedAmount=0;this._isServer=false;this._redirects=0;if(protocols===void 0){protocols=[]}else if(!Array.isArray(protocols)){if(typeof protocols==="object"&&protocols!==null){options=protocols;protocols=[]}else{protocols=[protocols]}}initAsClient(this,address,protocols,options)}else{this._isServer=true}}get binaryType(){return this._binaryType}set binaryType(type){if(!BINARY_TYPES.includes(type))return;this._binaryType=type;if(this._receiver)this._receiver._binaryType=type}get bufferedAmount(){if(!this._socket)return this._bufferedAmount;return this._socket._writableState.length+this._sender._bufferedBytes}get extensions(){return Object.keys(this._extensions).join()}get isPaused(){return this._paused}get onclose(){return null}get onerror(){return null}get onopen(){return null}get onmessage(){return null}get protocol(){return this._protocol}get readyState(){return this._readyState}get url(){return this._url}setSocket(socket,head,options){const receiver=new Receiver2({binaryType:this.binaryType,extensions:this._extensions,isServer:this._isServer,maxPayload:options.maxPayload,skipUTF8Validation:options.skipUTF8Validation});this._sender=new Sender2(socket,this._extensions,options.generateMask);this._receiver=receiver;this._socket=socket;receiver[kWebSocket]=this;socket[kWebSocket]=this;receiver.on("conclude",receiverOnConclude);receiver.on("drain",receiverOnDrain);receiver.on("error",receiverOnError);receiver.on("message",receiverOnMessage);receiver.on("ping",receiverOnPing);receiver.on("pong",receiverOnPong);socket.setTimeout(0);socket.setNoDelay();if(head.length>0)socket.unshift(head);socket.on("close",socketOnClose);socket.on("data",socketOnData);socket.on("end",socketOnEnd);socket.on("error",socketOnError);this._readyState=WebSocket3.OPEN;this.emit("open")}emitClose(){if(!this._socket){this._readyState=WebSocket3.CLOSED;this.emit("close",this._closeCode,this._closeMessage);return}if(this._extensions[PerMessageDeflate.extensionName]){this._extensions[PerMessageDeflate.extensionName].cleanup()}this._receiver.removeAllListeners();this._readyState=WebSocket3.CLOSED;this.emit("close",this._closeCode,this._closeMessage)}close(code,data){if(this.readyState===WebSocket3.CLOSED)return;if(this.readyState===WebSocket3.CONNECTING){const msg="WebSocket was closed before the connection was established";return abortHandshake(this,this._req,msg)}if(this.readyState===WebSocket3.CLOSING){if(this._closeFrameSent&&(this._closeFrameReceived||this._receiver._writableState.errorEmitted)){this._socket.end()}return}this._readyState=WebSocket3.CLOSING;this._sender.close(code,data,!this._isServer,err=>{if(err)return;this._closeFrameSent=true;if(this._closeFrameReceived||this._receiver._writableState.errorEmitted){this._socket.end()}});this._closeTimer=setTimeout(this._socket.destroy.bind(this._socket),closeTimeout)}pause(){if(this.readyState===WebSocket3.CONNECTING||this.readyState===WebSocket3.CLOSED){return}this._paused=true;this._socket.pause()}ping(data,mask,cb){if(this.readyState===WebSocket3.CONNECTING){throw new Error("WebSocket is not open: readyState 0 (CONNECTING)")}if(typeof data==="function"){cb=data;data=mask=void 0}else if(typeof mask==="function"){cb=mask;mask=void 0}if(typeof data==="number")data=data.toString();if(this.readyState!==WebSocket3.OPEN){sendAfterClose(this,data,cb);return}if(mask===void 0)mask=!this._isServer;this._sender.ping(data||EMPTY_BUFFER,mask,cb)}pong(data,mask,cb){if(this.readyState===WebSocket3.CONNECTING){throw new Error("WebSocket is not open: readyState 0 (CONNECTING)")}if(typeof data==="function"){cb=data;data=mask=void 0}else if(typeof mask==="function"){cb=mask;mask=void 0}if(typeof data==="number")data=data.toString();if(this.readyState!==WebSocket3.OPEN){sendAfterClose(this,data,cb);return}if(mask===void 0)mask=!this._isServer;this._sender.pong(data||EMPTY_BUFFER,mask,cb)}resume(){if(this.readyState===WebSocket3.CONNECTING||this.readyState===WebSocket3.CLOSED){return}this._paused=false;if(!this._receiver._writableState.needDrain)this._socket.resume()}send(data,options,cb){if(this.readyState===WebSocket3.CONNECTING){throw new Error("WebSocket is not open: readyState 0 (CONNECTING)")}if(typeof options==="function"){cb=options;options={}}if(typeof data==="number")data=data.toString();if(this.readyState!==WebSocket3.OPEN){sendAfterClose(this,data,cb);return}const opts={binary:typeof data!=="string",mask:!this._isServer,compress:true,fin:true,...options};if(!this._extensions[PerMessageDeflate.extensionName]){opts.compress=false}this._sender.send(data||EMPTY_BUFFER,opts,cb)}terminate(){if(this.readyState===WebSocket3.CLOSED)return;if(this.readyState===WebSocket3.CONNECTING){const msg="WebSocket was closed before the connection was established";return abortHandshake(this,this._req,msg)}if(this._socket){this._readyState=WebSocket3.CLOSING;this._socket.destroy()}}};Object.defineProperty(WebSocket3,"CONNECTING",{enumerable:true,value:readyStates.indexOf("CONNECTING")});Object.defineProperty(WebSocket3.prototype,"CONNECTING",{enumerable:true,value:readyStates.indexOf("CONNECTING")});Object.defineProperty(WebSocket3,"OPEN",{enumerable:true,value:readyStates.indexOf("OPEN")});Object.defineProperty(WebSocket3.prototype,"OPEN",{enumerable:true,value:readyStates.indexOf("OPEN")});Object.defineProperty(WebSocket3,"CLOSING",{enumerable:true,value:readyStates.indexOf("CLOSING")});Object.defineProperty(WebSocket3.prototype,"CLOSING",{enumerable:true,value:readyStates.indexOf("CLOSING")});Object.defineProperty(WebSocket3,"CLOSED",{enumerable:true,value:readyStates.indexOf("CLOSED")});Object.defineProperty(WebSocket3.prototype,"CLOSED",{enumerable:true,value:readyStates.indexOf("CLOSED")});["binaryType","bufferedAmount","extensions","isPaused","protocol","readyState","url"].forEach(property=>{Object.defineProperty(WebSocket3.prototype,property,{enumerable:true})});["open","error","close","message"].forEach(method=>{Object.defineProperty(WebSocket3.prototype,`on${method}`,{enumerable:true,get(){for(const listener of this.listeners(method)){if(listener[kForOnEventAttribute])return listener[kListener]}return null},set(handler){for(const listener of this.listeners(method)){if(listener[kForOnEventAttribute]){this.removeListener(method,listener);break}}if(typeof handler!=="function")return;this.addEventListener(method,handler,{[kForOnEventAttribute]:true})}})});WebSocket3.prototype.addEventListener=addEventListener;WebSocket3.prototype.removeEventListener=removeEventListener;module2.exports=WebSocket3;function initAsClient(websocket,address,protocols,options){const opts={protocolVersion:protocolVersions[1],maxPayload:100*1024*1024,skipUTF8Validation:false,perMessageDeflate:true,followRedirects:false,maxRedirects:10,...options,createConnection:void 0,socketPath:void 0,hostname:void 0,protocol:void 0,timeout:void 0,method:"GET",host:void 0,path:void 0,port:void 0};if(!protocolVersions.includes(opts.protocolVersion)){throw new RangeError(`Unsupported protocol version: ${opts.protocolVersion} (supported versions: ${protocolVersions.join(", ")})`)}let parsedUrl;if(address instanceof URL2){parsedUrl=address;websocket._url=address.href}else{try{parsedUrl=new URL2(address)}catch(e){throw new SyntaxError(`Invalid URL: ${address}`)}websocket._url=address}const isSecure=parsedUrl.protocol==="wss:";const isUnixSocket=parsedUrl.protocol==="ws+unix:";let invalidURLMessage;if(parsedUrl.protocol!=="ws:"&&!isSecure&&!isUnixSocket){invalidURLMessage=`The URL's protocol must be one of "ws:", "wss:", or "ws+unix:"`}else if(isUnixSocket&&!parsedUrl.pathname){invalidURLMessage="The URL's pathname is empty"}else if(parsedUrl.hash){invalidURLMessage="The URL contains a fragment identifier"}if(invalidURLMessage){const err=new SyntaxError(invalidURLMessage);if(websocket._redirects===0){throw err}else{emitErrorAndClose(websocket,err);return}}const defaultPort=isSecure?443:80;const key=randomBytes(16).toString("base64");const request=isSecure?https2.request:http2.request;const protocolSet=new Set;let perMessageDeflate;opts.createConnection=isSecure?tlsConnect:netConnect;opts.defaultPort=opts.defaultPort||defaultPort;opts.port=parsedUrl.port||defaultPort;opts.host=parsedUrl.hostname.startsWith("[")?parsedUrl.hostname.slice(1,-1):parsedUrl.hostname;opts.headers={...opts.headers,"Sec-WebSocket-Version":opts.protocolVersion,"Sec-WebSocket-Key":key,Connection:"Upgrade",Upgrade:"websocket"};opts.path=parsedUrl.pathname+parsedUrl.search;opts.timeout=opts.handshakeTimeout;if(opts.perMessageDeflate){perMessageDeflate=new PerMessageDeflate(opts.perMessageDeflate!==true?opts.perMessageDeflate:{},false,opts.maxPayload);opts.headers["Sec-WebSocket-Extensions"]=format({[PerMessageDeflate.extensionName]:perMessageDeflate.offer()})}if(protocols.length){for(const protocol of protocols){if(typeof protocol!=="string"||!subprotocolRegex.test(protocol)||protocolSet.has(protocol)){throw new SyntaxError("An invalid or duplicated subprotocol was specified")}protocolSet.add(protocol)}opts.headers["Sec-WebSocket-Protocol"]=protocols.join(",")}if(opts.origin){if(opts.protocolVersion<13){opts.headers["Sec-WebSocket-Origin"]=opts.origin}else{opts.headers.Origin=opts.origin}}if(parsedUrl.username||parsedUrl.password){opts.auth=`${parsedUrl.username}:${parsedUrl.password}`}if(isUnixSocket){const parts=opts.path.split(":");opts.socketPath=parts[0];opts.path=parts[1]}let req;if(opts.followRedirects){if(websocket._redirects===0){websocket._originalUnixSocket=isUnixSocket;websocket._originalSecure=isSecure;websocket._originalHostOrSocketPath=isUnixSocket?opts.socketPath:parsedUrl.host;const headers=options&&options.headers;options={...options,headers:{}};if(headers){for(const[key2,value]of Object.entries(headers)){options.headers[key2.toLowerCase()]=value}}}else if(websocket.listenerCount("redirect")===0){const isSameHost=isUnixSocket?websocket._originalUnixSocket?opts.socketPath===websocket._originalHostOrSocketPath:false:websocket._originalUnixSocket?false:parsedUrl.host===websocket._originalHostOrSocketPath;if(!isSameHost||websocket._originalSecure&&!isSecure){delete opts.headers.authorization;delete opts.headers.cookie;if(!isSameHost)delete opts.headers.host;opts.auth=void 0}}if(opts.auth&&!options.headers.authorization){options.headers.authorization="Basic "+Buffer.from(opts.auth).toString("base64")}req=websocket._req=request(opts);if(websocket._redirects){websocket.emit("redirect",websocket.url,req)}}else{req=websocket._req=request(opts)}if(opts.timeout){req.on("timeout",()=>{abortHandshake(websocket,req,"Opening handshake has timed out")})}req.on("error",err=>{if(req===null||req[kAborted])return;req=websocket._req=null;emitErrorAndClose(websocket,err)});req.on("response",res=>{const location2=res.headers.location;const statusCode=res.statusCode;if(location2&&opts.followRedirects&&statusCode>=300&&statusCode<400){if(++websocket._redirects>opts.maxRedirects){abortHandshake(websocket,req,"Maximum redirects exceeded");return}req.abort();let addr;try{addr=new URL2(location2,address)}catch(e){const err=new SyntaxError(`Invalid URL: ${location2}`);emitErrorAndClose(websocket,err);return}initAsClient(websocket,addr,protocols,options)}else if(!websocket.emit("unexpected-response",req,res)){abortHandshake(websocket,req,`Unexpected server response: ${res.statusCode}`)}});req.on("upgrade",(res,socket,head)=>{websocket.emit("upgrade",res);if(websocket.readyState!==WebSocket3.CONNECTING)return;req=websocket._req=null;if(res.headers.upgrade.toLowerCase()!=="websocket"){abortHandshake(websocket,socket,"Invalid Upgrade header");return}const digest=createHash("sha1").update(key+GUID).digest("base64");if(res.headers["sec-websocket-accept"]!==digest){abortHandshake(websocket,socket,"Invalid Sec-WebSocket-Accept header");return}const serverProt=res.headers["sec-websocket-protocol"];let protError;if(serverProt!==void 0){if(!protocolSet.size){protError="Server sent a subprotocol but none was requested"}else if(!protocolSet.has(serverProt)){protError="Server sent an invalid subprotocol"}}else if(protocolSet.size){protError="Server sent no subprotocol"}if(protError){abortHandshake(websocket,socket,protError);return}if(serverProt)websocket._protocol=serverProt;const secWebSocketExtensions=res.headers["sec-websocket-extensions"];if(secWebSocketExtensions!==void 0){if(!perMessageDeflate){const message="Server sent a Sec-WebSocket-Extensions header but no extension was requested";abortHandshake(websocket,socket,message);return}let extensions;try{extensions=parse(secWebSocketExtensions)}catch(err){const message="Invalid Sec-WebSocket-Extensions header";abortHandshake(websocket,socket,message);return}const extensionNames=Object.keys(extensions);if(extensionNames.length!==1||extensionNames[0]!==PerMessageDeflate.extensionName){const message="Server indicated an extension that was not requested";abortHandshake(websocket,socket,message);return}try{perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName])}catch(err){const message="Invalid Sec-WebSocket-Extensions header";abortHandshake(websocket,socket,message);return}websocket._extensions[PerMessageDeflate.extensionName]=perMessageDeflate}websocket.setSocket(socket,head,{generateMask:opts.generateMask,maxPayload:opts.maxPayload,skipUTF8Validation:opts.skipUTF8Validation})});req.end()}function emitErrorAndClose(websocket,err){websocket._readyState=WebSocket3.CLOSING;websocket.emit("error",err);websocket.emitClose()}function netConnect(options){options.path=options.socketPath;return net.connect(options)}function tlsConnect(options){options.path=void 0;if(!options.servername&&options.servername!==""){options.servername=net.isIP(options.host)?"":options.host}return tls.connect(options)}function abortHandshake(websocket,stream,message){websocket._readyState=WebSocket3.CLOSING;const err=new Error(message);Error.captureStackTrace(err,abortHandshake);if(stream.setHeader){stream[kAborted]=true;stream.abort();if(stream.socket&&!stream.socket.destroyed){stream.socket.destroy()}process.nextTick(emitErrorAndClose,websocket,err)}else{stream.destroy(err);stream.once("error",websocket.emit.bind(websocket,"error"));stream.once("close",websocket.emitClose.bind(websocket))}}function sendAfterClose(websocket,data,cb){if(data){const length=toBuffer(data).length;if(websocket._socket)websocket._sender._bufferedBytes+=length;else websocket._bufferedAmount+=length}if(cb){const err=new Error(`WebSocket is not open: readyState ${websocket.readyState} (${readyStates[websocket.readyState]})`);cb(err)}}function receiverOnConclude(code,reason){const websocket=this[kWebSocket];websocket._closeFrameReceived=true;websocket._closeMessage=reason;websocket._closeCode=code;if(websocket._socket[kWebSocket]===void 0)return;websocket._socket.removeListener("data",socketOnData);process.nextTick(resume,websocket._socket);if(code===1005)websocket.close();else websocket.close(code,reason)}function receiverOnDrain(){const websocket=this[kWebSocket];if(!websocket.isPaused)websocket._socket.resume()}function receiverOnError(err){const websocket=this[kWebSocket];if(websocket._socket[kWebSocket]!==void 0){websocket._socket.removeListener("data",socketOnData);process.nextTick(resume,websocket._socket);websocket.close(err[kStatusCode])}websocket.emit("error",err)}function receiverOnFinish(){this[kWebSocket].emitClose()}function receiverOnMessage(data,isBinary){this[kWebSocket].emit("message",data,isBinary)}function receiverOnPing(data){const websocket=this[kWebSocket];websocket.pong(data,!websocket._isServer,NOOP);websocket.emit("ping",data)}function receiverOnPong(data){this[kWebSocket].emit("pong",data)}function resume(stream){stream.resume()}function socketOnClose(){const websocket=this[kWebSocket];this.removeListener("close",socketOnClose);this.removeListener("data",socketOnData);this.removeListener("end",socketOnEnd);websocket._readyState=WebSocket3.CLOSING;let chunk;if(!this._readableState.endEmitted&&!websocket._closeFrameReceived&&!websocket._receiver._writableState.errorEmitted&&(chunk=websocket._socket.read())!==null){websocket._receiver.write(chunk)}websocket._receiver.end();this[kWebSocket]=void 0;clearTimeout(websocket._closeTimer);if(websocket._receiver._writableState.finished||websocket._receiver._writableState.errorEmitted){websocket.emitClose()}else{websocket._receiver.on("error",receiverOnFinish);websocket._receiver.on("finish",receiverOnFinish)}}function socketOnData(chunk){if(!this[kWebSocket]._receiver.write(chunk)){this.pause()}}function socketOnEnd(){const websocket=this[kWebSocket];websocket._readyState=WebSocket3.CLOSING;websocket._receiver.end();this.end()}function socketOnError(){const websocket=this[kWebSocket];this.removeListener("error",socketOnError);this.on("error",NOOP);if(websocket){websocket._readyState=WebSocket3.CLOSING;this.destroy()}}}});var require_subprotocol=__commonJS({"node_modules/ws/lib/subprotocol.js"(exports,module2){"use strict";var{tokenChars}=require_validation();function parse(header){const protocols=new Set;let start=-1;let end=-1;let i=0;for(i;i{const body=http2.STATUS_CODES[426];res.writeHead(426,{"Content-Length":body.length,"Content-Type":"text/plain"});res.end(body)});this._server.listen(options.port,options.host,options.backlog,callback)}else if(options.server){this._server=options.server}if(this._server){const emitConnection=this.emit.bind(this,"connection");this._removeListeners=addListeners(this._server,{listening:this.emit.bind(this,"listening"),error:this.emit.bind(this,"error"),upgrade:(req,socket,head)=>{this.handleUpgrade(req,socket,head,emitConnection)}})}if(options.perMessageDeflate===true)options.perMessageDeflate={};if(options.clientTracking){this.clients=new Set;this._shouldEmitClose=false}this.options=options;this._state=RUNNING}address(){if(this.options.noServer){throw new Error('The server is operating in "noServer" mode')}if(!this._server)return null;return this._server.address()}close(cb){if(this._state===CLOSED){if(cb){this.once("close",()=>{cb(new Error("The server is not running"))})}process.nextTick(emitClose,this);return}if(cb)this.once("close",cb);if(this._state===CLOSING)return;this._state=CLOSING;if(this.options.noServer||this.options.server){if(this._server){this._removeListeners();this._removeListeners=this._server=null}if(this.clients){if(!this.clients.size){process.nextTick(emitClose,this)}else{this._shouldEmitClose=true}}else{process.nextTick(emitClose,this)}}else{const server=this._server;this._removeListeners();this._removeListeners=this._server=null;server.close(()=>{emitClose(this)})}}shouldHandle(req){if(this.options.path){const index=req.url.indexOf("?");const pathname=index!==-1?req.url.slice(0,index):req.url;if(pathname!==this.options.path)return false}return true}handleUpgrade(req,socket,head,cb){socket.on("error",socketOnError);const key=req.headers["sec-websocket-key"];const version=+req.headers["sec-websocket-version"];if(req.method!=="GET"){const message="Invalid HTTP method";abortHandshakeOrEmitwsClientError(this,req,socket,405,message);return}if(req.headers.upgrade.toLowerCase()!=="websocket"){const message="Invalid Upgrade header";abortHandshakeOrEmitwsClientError(this,req,socket,400,message);return}if(!key||!keyRegex.test(key)){const message="Missing or invalid Sec-WebSocket-Key header";abortHandshakeOrEmitwsClientError(this,req,socket,400,message);return}if(version!==8&&version!==13){const message="Missing or invalid Sec-WebSocket-Version header";abortHandshakeOrEmitwsClientError(this,req,socket,400,message);return}if(!this.shouldHandle(req)){abortHandshake(socket,400);return}const secWebSocketProtocol=req.headers["sec-websocket-protocol"];let protocols=new Set;if(secWebSocketProtocol!==void 0){try{protocols=subprotocol.parse(secWebSocketProtocol)}catch(err){const message="Invalid Sec-WebSocket-Protocol header";abortHandshakeOrEmitwsClientError(this,req,socket,400,message);return}}const secWebSocketExtensions=req.headers["sec-websocket-extensions"];const extensions={};if(this.options.perMessageDeflate&&secWebSocketExtensions!==void 0){const perMessageDeflate=new PerMessageDeflate(this.options.perMessageDeflate,true,this.options.maxPayload);try{const offers=extension.parse(secWebSocketExtensions);if(offers[PerMessageDeflate.extensionName]){perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]);extensions[PerMessageDeflate.extensionName]=perMessageDeflate}}catch(err){const message="Invalid or unacceptable Sec-WebSocket-Extensions header";abortHandshakeOrEmitwsClientError(this,req,socket,400,message);return}}if(this.options.verifyClient){const info={origin:req.headers[`${version===8?"sec-websocket-origin":"origin"}`],secure:!!(req.socket.authorized||req.socket.encrypted),req};if(this.options.verifyClient.length===2){this.options.verifyClient(info,(verified,code,message,headers)=>{if(!verified){return abortHandshake(socket,code||401,message,headers)}this.completeUpgrade(extensions,key,protocols,req,socket,head,cb)});return}if(!this.options.verifyClient(info))return abortHandshake(socket,401)}this.completeUpgrade(extensions,key,protocols,req,socket,head,cb)}completeUpgrade(extensions,key,protocols,req,socket,head,cb){if(!socket.readable||!socket.writable)return socket.destroy();if(socket[kWebSocket]){throw new Error("server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration")}if(this._state>RUNNING)return abortHandshake(socket,503);const digest=createHash("sha1").update(key+GUID).digest("base64");const headers=["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade",`Sec-WebSocket-Accept: ${digest}`];const ws=new this.options.WebSocket(null);if(protocols.size){const protocol=this.options.handleProtocols?this.options.handleProtocols(protocols,req):protocols.values().next().value;if(protocol){headers.push(`Sec-WebSocket-Protocol: ${protocol}`);ws._protocol=protocol}}if(extensions[PerMessageDeflate.extensionName]){const params=extensions[PerMessageDeflate.extensionName].params;const value=extension.format({[PerMessageDeflate.extensionName]:[params]});headers.push(`Sec-WebSocket-Extensions: ${value}`);ws._extensions=extensions}this.emit("headers",headers,req);socket.write(headers.concat("\r\n").join("\r\n"));socket.removeListener("error",socketOnError);ws.setSocket(socket,head,{maxPayload:this.options.maxPayload,skipUTF8Validation:this.options.skipUTF8Validation});if(this.clients){this.clients.add(ws);ws.on("close",()=>{this.clients.delete(ws);if(this._shouldEmitClose&&!this.clients.size){process.nextTick(emitClose,this)}})}cb(ws,req)}};module2.exports=WebSocketServer2;function addListeners(server,map){for(const event of Object.keys(map))server.on(event,map[event]);return function removeListeners(){for(const event of Object.keys(map)){server.removeListener(event,map[event])}}}function emitClose(server){server._state=CLOSED;server.emit("close")}function socketOnError(){this.destroy()}function abortHandshake(socket,code,message,headers){message=message||http2.STATUS_CODES[code];headers={Connection:"close","Content-Type":"text/html","Content-Length":Buffer.byteLength(message),...headers};socket.once("finish",socket.destroy);socket.end(`HTTP/1.1 ${code} ${http2.STATUS_CODES[code]}\r +`+Object.keys(headers).map(h=>`${h}: ${headers[h]}`).join("\r\n")+"\r\n\r\n"+message)}function abortHandshakeOrEmitwsClientError(server,req,socket,code,message){if(server.listenerCount("wsClientError")){const err=new Error(message);Error.captureStackTrace(err,abortHandshakeOrEmitwsClientError);server.emit("wsClientError",err,socket,req)}else{abortHandshake(socket,code,message)}}}});var require_node=__commonJS({"node_modules/web-worker/cjs/node.js"(exports,module2){var URL2=require("url");var VM=require("vm");var threads=require("worker_threads");var WORKER=Symbol.for("worker");var EVENTS=Symbol.for("events");var EventTarget=class{constructor(){Object.defineProperty(this,EVENTS,{value:new Map})}dispatchEvent(event){event.target=event.currentTarget=this;if(this["on"+event.type]){try{this["on"+event.type](event)}catch(err){console.error(err)}}const list=this[EVENTS].get(event.type);if(list==null)return;list.forEach(handler=>{try{handler.call(this,event)}catch(err){console.error(err)}})}addEventListener(type,fn){let events=this[EVENTS].get(type);if(!events)this[EVENTS].set(type,events=[]);events.push(fn)}removeEventListener(type,fn){let events=this[EVENTS].get(type);if(events){const index=events.indexOf(fn);if(index!==-1)events.splice(index,1)}}};function Event(type,target){this.type=type;this.timeStamp=Date.now();this.target=this.currentTarget=this.data=null}module2.exports=threads.isMainThread?mainThread():workerThread();var baseUrl=URL2.pathToFileURL(process.cwd()+"/");function mainThread(){class Worker2 extends EventTarget{constructor(url,options){super();const{name,type}=options||{};url+="";let mod;if(/^data:/.test(url)){mod=url}else{mod=URL2.fileURLToPath(new URL2.URL(url,baseUrl))}const worker=new threads.Worker(__filename,{workerData:{mod,name,type}});Object.defineProperty(this,WORKER,{value:worker});worker.on("message",data=>{const event=new Event("message");event.data=data;this.dispatchEvent(event)});worker.on("error",error=>{error.type="error";this.dispatchEvent(error)});worker.on("exit",()=>{this.dispatchEvent(new Event("close"))})}postMessage(data,transferList){this[WORKER].postMessage(data,transferList)}terminate(){this[WORKER].terminate()}}Worker2.prototype.onmessage=Worker2.prototype.onerror=Worker2.prototype.onclose=null;return Worker2}function workerThread(){let{mod,name,type}=threads.workerData;const self2=global.self=global;let q=[];function flush(){const buffered=q;q=null;buffered.forEach(event=>{self2.dispatchEvent(event)})}threads.parentPort.on("message",data=>{const event=new Event("message");event.data=data;if(q==null)self2.dispatchEvent(event);else q.push(event)});threads.parentPort.on("error",err=>{err.type="Error";self2.dispatchEvent(err)});class WorkerGlobalScope2 extends EventTarget{postMessage(data,transferList){threads.parentPort.postMessage(data,transferList)}close(){process.exit()}}let proto=Object.getPrototypeOf(global);delete proto.constructor;Object.defineProperties(WorkerGlobalScope2.prototype,proto);proto=Object.setPrototypeOf(global,new WorkerGlobalScope2);["postMessage","addEventListener","removeEventListener","dispatchEvent"].forEach(fn=>{proto[fn]=proto[fn].bind(global)});global.name=name;const isDataUrl=/^data:/.test(mod);if(type==="module"){import(mod).catch(err=>{if(isDataUrl&&err.message==="Not supported"){console.warn("Worker(): Importing data: URLs requires Node 12.10+. Falling back to classic worker.");return evaluateDataUrl(mod,name)}console.error(err)}).then(flush)}else{try{if(/^data:/.test(mod)){evaluateDataUrl(mod,name)}else{require(mod)}}catch(err){console.error(err)}Promise.resolve().then(flush)}}function evaluateDataUrl(url,name){const{data}=parseDataUrl(url);return VM.runInThisContext(data,{filename:"worker.<"+(name||"data:")+">"})}function parseDataUrl(url){let[m,type,encoding,data]=url.match(/^data: *([^;,]*)(?: *; *([^,]*))? *,(.*)$/)||[];if(!m)throw Error("Invalid Data URL.");if(encoding)switch(encoding.toLowerCase()){case"base64":data=Buffer.from(data,"base64").toString();break;default:throw Error('Unknown Data URL encoding "'+encoding+'"')}return{type,data}}}});var index_node_exports={};__export(index_node_exports,{CMDService:()=>CMDService,E2EEService:()=>E2EEService,ECSService:()=>ECSService,EventHandler:()=>EventHandler,Graph:()=>Graph,GraphNode:()=>GraphNode,HTTPbackend:()=>HTTPbackend,Router:()=>Router,SSEbackend:()=>SSEbackend,Service:()=>Service,SessionsService:()=>SessionsService,WSSbackend:()=>WSSbackend,WorkerService:()=>WorkerService,algorithms:()=>algorithms,createNode:()=>createNode,createSubprocess:()=>createSubprocess,loadAlgorithms:()=>loadAlgorithms,parseFunctionFromText:()=>parseFunctionFromText,reconstructNode:()=>reconstructNode,reconstructObject:()=>reconstructObject,state:()=>state,stringifyFast:()=>stringifyFast,stringifyWithCircularRefs:()=>stringifyWithCircularRefs,subprocessRoutes:()=>subprocessRoutes,unsafeRoutes:()=>unsafeRoutes});module.exports=__toCommonJS(index_node_exports);function parseFunctionFromText(method=""){let getFunctionBody=methodString=>{return methodString.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i,"$2$3$4")};let getFunctionHead=methodString=>{let startindex=methodString.indexOf("=>")+1;if(startindex<=0){startindex=methodString.indexOf("){")}if(startindex<=0){startindex=methodString.indexOf(") {")}return methodString.slice(0,methodString.indexOf("{",startindex)+1)};let newFuncHead=getFunctionHead(method);let newFuncBody=getFunctionBody(method);let newFunc;if(newFuncHead.includes("function")){let varName=newFuncHead.split("(")[1].split(")")[0];newFunc=new Function(varName,newFuncBody)}else{if(newFuncHead.substring(0,6)===newFuncBody.substring(0,6)){let varName=newFuncHead.split("(")[1].split(")")[0];newFunc=new Function(varName,newFuncBody.substring(newFuncBody.indexOf("{")+1,newFuncBody.length-1))}else{try{newFunc=(0,eval)(newFuncHead+newFuncBody+"}")}catch{}}}return newFunc}var EventHandler=class{constructor(){this.pushToState={};this.data={};this.triggers={};this.setState=updateObj=>{Object.assign(this.data,updateObj);for(const prop of Object.getOwnPropertyNames(updateObj)){if(this.triggers[prop])this.triggers[prop].forEach(obj=>obj.onchange(this.data[prop]))}return this.data};this.subscribeTrigger=(key,onchange)=>{if(key){if(!this.triggers[key]){this.triggers[key]=[]}let l=this.triggers[key].length;this.triggers[key].push({idx:l,onchange});return this.triggers[key].length-1}else return void 0};this.unsubscribeTrigger=(key,sub)=>{let triggers=this.triggers[key];if(triggers){if(!sub)delete this.triggers[key];else{let idx=void 0;let obj=triggers.find((o,i)=>{if(o.idx===sub){idx=i;return true}});if(obj)triggers.splice(idx,1);return true}}};this.subscribeTriggerOnce=(key,onchange)=>{let sub;let changed=value=>{onchange(value);this.unsubscribeTrigger(key,sub)};sub=this.subscribeTrigger(key,changed)}}};var state=new EventHandler;function addLocalState(props){if(!this._state)this._state={};for(let k in props){if(k==="_state"||k==="graph")continue;else{this._state[k]=props[k];if(k in this)this[k]=props[k];else Object.defineProperty(this,k,{get:()=>{this._state[k]},set:v=>{this._state[k]=v;if(this.state.triggers[this._unique])this.setState({[this._unique]:this._state})},enumerable:true,configurable:true})}}}var GraphNode=class{constructor(properties={},parent,graph){this.nodes=new Map;this._initial={};this._unique=`${Math.random()}`;this.state=state;this.isLooping=false;this.isAnimating=false;this.looper=void 0;this.animation=void 0;this.forward=true;this.backward=false;this.reactive=false;this.runSync=false;this.firstRun=true;this.DEBUGNODE=false;this.addLocalState=addLocalState;this.operator=(...args)=>{return args};this.runOp=(...args)=>{if(this.DEBUGNODE)console.time(this.tag);let result=this.operator(...args);if(result instanceof Promise){result.then(res=>{if(res!==void 0)this.setState({[this.tag]:res});if(this.DEBUGNODE){console.timeEnd(this.tag);if(result!==void 0)console.log(`${this.tag} result:`,result)};return res})}else{if(result!==void 0)this.setState({[this.tag]:result});if(this.DEBUGNODE){console.timeEnd(this.tag);if(result!==void 0)console.log(`${this.tag} result:`,result)};}return result};this.setOperator=operator=>{if(typeof operator!=="function")return operator;this.operator=operator.bind(this);return operator};this.runAsync=(...args)=>{return new Promise((res,rej)=>{res(this.run(...args))})};this.transformArgs=(args=[])=>args;this.isRunSync=()=>{return!(this.children&&this.forward||this.parent&&this.backward||this.repeat||this.delay||this.frame||this.recursive||this.branch)};this.run=(...args)=>{if(typeof this.transformArgs==="function")args=this.transformArgs(args,this);if(this.firstRun){this.firstRun=false;this.runSync=this.isRunSync();if(this.animate&&!this.isAnimating){this.runAnimation(this.animation,args)}if(this.loop&&typeof this.loop==="number"&&!this.isLooping){this.runLoop(this.looper,args)}if(this.loop||this.animate)return}if(this.runSync){let res=this.runOp(...args);return res}return new Promise(async resolve=>{if(this){let run=(node,tick=0,...input)=>{return new Promise(async r=>{tick++;let res=await node.runOp(...input);if(node.repeat){while(tick{r(await run(node,tick,...input))},node.delay);break}else if(node.frame&&window?.requestAnimationFrame){requestAnimationFrame(async()=>{r(await run(node,tick,...input))});break}else res=await node.runOp(...input);tick++}if(tick===node.repeat){r(res);return}}else if(node.recursive){while(tick{r(await run(node,tick,...res))},node.delay);break}else if(node.frame&&window?.requestAnimationFrame){requestAnimationFrame(async()=>{r(await run(node,tick,...res))});break}else res=await node.runOp(...res);tick++}if(tick===node.recursive){r(res);return}}else{r(res);return}})};let runnode=async()=>{let res=await run(this,void 0,...args);if(res!==void 0){if(this.backward&&this.parent instanceof GraphNode){if(Array.isArray(res))await this.runParent(this,...res);else await this.runParent(this,res)}if(this.children&&this.forward){if(Array.isArray(res))await this.runChildren(this,...res);else await this.runChildren(this,res)}if(this.branch){this.runBranch(this,res)}}return res};if(this.delay){setTimeout(async()=>{resolve(await runnode())},this.delay)}else if(this.frame&&window?.requestAnimationFrame){requestAnimationFrame(async()=>{resolve(await runnode())})}else{resolve(await runnode())}}else resolve(void 0)})};this.runParent=async(n,...args)=>{if(n.backward&&n.parent){if(typeof n.parent==="string"){if(n.graph&&n.graph?.get(n.parent)){n.parent=n.graph;if(n.parent)this.nodes.set(n.parent.tag,n.parent)}else n.parent=this.nodes.get(n.parent)}if(n.parent instanceof GraphNode)await n.parent.run(...args)}};this.runChildren=async(n,...args)=>{if(typeof n.children==="object"){for(const key in n.children){if(typeof n.children[key]==="string"){if(n.graph&&n.graph?.get(n.children[key])){n.children[key]=n.graph.get(n.children[key]);if(!n.nodes.get(n.children[key].tag))n.nodes.set(n.children[key].tag,n.children[key])}if(!n.children[key]&&n.nodes.get(n.children[key]))n.children[key]=n.nodes.get(n.children[key])}else if(typeof n.children[key]==="undefined"||n.children[key]===true){if(n.graph&&n.graph?.get(key)){n.children[key]=n.graph.get(key);if(!n.nodes.get(n.children[key].tag))n.nodes.set(n.children[key].tag,n.children[key])}if(!n.children[key]&&n.nodes.get(key))n.children[key]=n.nodes.get(key)}if(n.children[key]?.runOp)await n.children[key].run(...args)}}};this.runBranch=async(n,output)=>{if(n.branch){let keys=Object.keys(n.branch);await Promise.all(keys.map(async k=>{if(typeof n.branch[k].if==="object")n.branch[k].if=stringifyFast(n.branch[k].if);let pass=false;if(typeof n.branch[k].if==="function"){pass=n.branch[k].if(output)}else{if(typeof output==="object"){if(stringifyFast(output)===n.branch[k].if)pass=true}else if(output===n.branch[k].if)pass=true}if(pass){if(n.branch[k].then.run){if(Array.isArray(output))await n.branch[k].then.run(...output);else await n.branch[k].then.run(...output)}else if(typeof n.branch[k].then==="function"){if(Array.isArray(output))await n.branch[k].then(...output);else await n.branch[k].then(output)}else if(typeof n.branch[k].then==="string"){if(n.graph)n.branch[k].then=n.graph.nodes.get(n.branch[k].then);else n.branch[k].then=n.nodes.get(n.branch[k].then);if(n.branch[k].then.run){if(Array.isArray(output))await n.branch[k].then.run(...output);else await n.branch[k].then.run(...output)}}}return pass}))}};this.runAnimation=(animation=this.animation,args=[])=>{this.animation=animation;if(!animation)this.animation=this.operator;if(this.animate&&!this.isAnimating&&"requestAnimationFrame"in window){this.isAnimating=true;let anim=async()=>{if(this.isAnimating){if(this.DEBUGNODE)console.time(this.tag);let result=this.animation.call(this,...args);if(result instanceof Promise){result=await result}if(this.DEBUGNODE){console.timeEnd(this.tag);if(result!==void 0)console.log(`${this.tag} result:`,result)};if(result!==void 0){if(this.tag)this.setState({[this.tag]:result});if(this.backward&&this.parent?.run){if(Array.isArray(result))await this.runParent(this,...result);else await this.runParent(this,result)}if(this.children&&this.forward){if(Array.isArray(result))await this.runChildren(this,...result);else await this.runChildren(this,result)}if(this.branch){this.runBranch(this,result)}this.setState({[this.tag]:result})}requestAnimationFrame(anim)}};requestAnimationFrame(anim)}};this.runLoop=(loop=this.looper,args=[],timeout=this.loop)=>{this.looper=loop;if(!loop)this.looper=this.operator;if(typeof timeout==="number"&&!this.isLooping){this.isLooping=true;let looping=async()=>{if(this.isLooping){if(this.DEBUGNODE)console.time(this.tag);let result=this.looper.call(this,...args);if(result instanceof Promise){result=await result}if(this.DEBUGNODE){console.timeEnd(this.tag);if(result!==void 0)console.log(`${this.tag} result:`,result)};if(result!==void 0){if(this.tag)this.setState({[this.tag]:result});if(this.backward&&this.parent?.run){if(Array.isArray(result))await this.runParent(this,...result);else await this.runParent(this,result)}if(this.children&&this.forward){if(Array.isArray(result))await this.runChildren(this,...result);else await this.runChildren(this,result)}if(this.branch){this.runBranch(this,result)}this.setState({[this.tag]:result})}setTimeout(async()=>{await looping()},timeout)}};looping()}};this.setParent=parent=>{this.parent=parent;if(this.backward)this.runSync=false};this.setChildren=children=>{this.children=children;if(this.forward)this.runSync=false};this.add=(n={})=>{if(typeof n==="function")n={operator:n};if(n?.node instanceof GraphNode)n=n.node;if(!(n instanceof GraphNode))n=new GraphNode(n.node??n,this,this.graph);this.nodes.set(n.tag,n);if(this.graph){this.graph.nodes.set(n.tag,n);this.graph.nNodes=this.graph.nodes.size}return n};this.remove=n=>{if(typeof n==="string")n=this.nodes.get(n);if(n?.tag){this.nodes.delete(n.tag);if(this.children[n.tag])delete this.children[n.tag];if(this.graph){this.graph.nodes.delete(n.tag);this.graph.nNodes=this.graph.nodes.size}this.nodes.forEach(n2=>{if(n2.nodes.get(n2.tag)){n2.nodes.delete(n2.tag);if(n2.children[n2.tag])delete n2.children[n2.tag];if(n2.parent?.tag===n2.tag)delete n2.parent}});if(n.ondelete)n.ondelete(n)}if(typeof this._state==="object"){this.state.unsubscribeTrigger(this._unique)}};this.append=(n,parentNode=this)=>{if(typeof n==="string")n=this.nodes.get(n);if(n?.nodes){parentNode.addChildren(n);if(n.forward)n.runSync=false}};this.subscribe=(callback,tag=this.tag)=>{if(typeof callback==="string"){if(this.graph)callback=this.graph.get(callback);else callback=this.nodes.get(callback)}if(typeof callback==="function"){return this.state.subscribeTrigger(tag,callback)}else if(callback)return this.state.subscribeTrigger(tag,res=>{callback.run(res)})};this.unsubscribe=(sub,tag=this.tag)=>{return this.state.unsubscribeTrigger(tag,sub)};this.subscribeState=callback=>{if(!this.reactive){return void 0}else{if(typeof callback==="string"){if(this.graph)callback=this.graph.get(callback);else callback=this.nodes.get(callback)}if(typeof callback==="function"){return this.state.subscribeTrigger(this._unique,callback)}else if(callback)return this.state.subscribeTrigger(this._unique,_state=>{callback.run(_state)})}};this.addChildren=children=>{if(!this.children)this.children={};if(typeof children==="object"){Object.assign(this.children,children)}this.convertChildrenToNodes();if(this.forward)this.runSync=false};this.callParent=(...args)=>{if(typeof this.parent==="string"){if(this.graph&&this.graph?.get(this.parent)){this.parent=this.graph;if(this.parent)this.nodes.set(this.parent.tag,this.parent)}else this.parent=this.nodes.get(this.parent)}if(typeof this.parent?.operator==="function")return this.parent.runOp(...args)};this.callChildren=(...args)=>{let result;if(typeof this.children==="object"){for(const key in this.children){if(this.children[key]?.runOp)this.children[key].runOp(...args)}}return result};this.getProps=(n=this,getInitial=true)=>{let baseprops={tag:n.tag,operator:n.operator,graph:n.graph,children:n.children,parent:n.parent,forward:n.forward,backward:n.bacward,loop:n.loop,animate:n.animate,frame:n.frame,delay:n.delay,recursive:n.recursive,repeat:n.repeat,branch:n.branch,oncreate:n.oncreate,reactive:n.reactive,DEBUGNODE:n.DEBUGNODE};if(!getInitial){let uniqueprops={};for(const key in this._initial){uniqueprops[key]=this[key]}return Object.assign(baseprops,uniqueprops)}else return{tag:n.tag,operator:n.operator,graph:n.graph,children:n.children,parent:n.parent,forward:n.forward,backward:n.bacward,loop:n.loop,animate:n.animate,frame:n.frame,delay:n.delay,recursive:n.recursive,repeat:n.repeat,branch:n.branch,oncreate:n.oncreate,reactive:n.reactive,DEBUGNODE:n.DEBUGNODE,...this._initial}};this.setProps=(props={})=>{let tmp=Object.assign({},props);if(tmp.children){this.addChildren(props.children);delete tmp.children}if(tmp.operator){this.setOperator(props.operator);delete tmp.operator}Object.assign(tmp,props);this.runSync=this.isRunSync()};this.removeTree=n=>{if(n){if(typeof n==="string")n=this.nodes.get(n)}if(n?.nodes){let checked={};const recursivelyRemove=node=>{if(typeof node.children==="object"&&!checked[node.tag]){checked[node.tag]=true;for(const key in node.children){if(node.children[key].stopNode)node.children[key].stopNode();if(node.children[key].tag){if(this.nodes.get(node.children[key].tag))this.nodes.delete(node.children[key].tag);this.nodes.forEach(n2=>{if(n2.nodes.get(node.children[key].tag))n2.nodes.delete(node.children[key].tag);if(n2.children[key]instanceof GraphNode)delete n2.children[key]});recursivelyRemove(node.children[key])}}}};if(n.stopNode)n.stopNode();if(n.tag){this.nodes.delete(n.tag);if(this.children[n.tag])delete this.children[n.tag];if(this.parent?.tag===n.tag)delete this.parent;if(this[n.tag]instanceof GraphNode)delete this[n.tag];this.nodes.forEach(n2=>{if(n2?.tag){if(n2.nodes.get(n2.tag))n2.nodes.delete(n2.tag);if(n2.children[n2.tag]instanceof GraphNode)delete n2.children[n2.tag]}});recursivelyRemove(n);if(this.graph)this.graph.removeTree(n,checked);else if(n.ondelete)n.ondelete(n)}}};this.checkNodesHaveChildMapped=(n,child,checked={})=>{let tag=n.tag;if(!tag)tag=n.name;if(!checked[tag]){checked[tag]=true;if(n.children){if(child.tag in n.children){if(n.children[child.tag]instanceof GraphNode){if(!n.nodes.get(child.tag))n.nodes.set(child.tag,child);n.children[child.tag]=child;if(!n.firstRun)n.firstRun=true}}}if(n.parent instanceof GraphNode){if(n.nodes.get(child.tag))n.parent.nodes.set(child.tag,child);if(n.parent.children){this.checkNodesHaveChildMapped(n.parent,child,checked)}else if(n.nodes){n.nodes.forEach(n2=>{if(!checked[n2.tag]){this.checkNodesHaveChildMapped(n2,child,checked)}})}}if(n.graph){if(n.parent&&n.parent.name!==n.graph.name){n.graph.nodes.forEach(n2=>{if(!checked[n2.tag]){this.checkNodesHaveChildMapped(n2,child,checked)}})}}}};this.convertChildrenToNodes=(n=this)=>{if(n?.children){for(const key in n.children){if(!(n.children[key]instanceof GraphNode)){if(typeof n.children[key]==="object"){if(!n.children[key].tag)n.children[key].tag=key;if(!n.nodes.get(n.children[key].tag)){n.children[key]=new GraphNode(n.children[key],n,n.graph);this.checkNodesHaveChildMapped(n,n.children[key])}}else{if(typeof n.children[key]==="undefined"||n.children[key]==true){n.children[key]=n.graph.get(key);if(!n.children[key])n.children[key]=n.nodes.get(key)}else if(typeof n.children[key]==="string"){let k=n.children[key];n.children[key]=n.graph.get(k);if(!n.children[key])n.children[key]=n.nodes.get(key)}if(n.children[key]instanceof GraphNode){n.nodes.set(n.children[key].tag,n.children[key]);this.checkNodesHaveChildMapped(n,n.children[key]);if(!(n.children[key].tag in n))n[n.children[key].tag]=n.children[key]}}}}}return n.children};this.stopLooping=(n=this)=>{n.isLooping=false};this.stopAnimating=(n=this)=>{n.isAnimating=false};this.stopNode=(n=this)=>{n.stopAnimating(n);n.stopLooping(n)};this.subscribeNode=n=>{if(typeof n==="string")n=this.nodes.get(n);if(n.tag)this.nodes.set(n.tag,n);if(n)return this.state.subscribeTrigger(this.tag,res=>{if(Array.isArray(res))n.run(...res);else n.run(res)})};this.print=(n=this,printChildren=true,nodesPrinted=[])=>{let dummyNode=new GraphNode;if(typeof n==="string")n=this.nodes.get(n);if(n instanceof GraphNode){nodesPrinted.push(n.tag);let jsonToPrint={tag:n.tag,operator:n.operator.toString()};if(n.parent)jsonToPrint.parent=n.parent.tag;if(typeof n.children==="object"){for(const key in n.children){if(typeof n.children[key]==="string")return n.children[key];if(nodesPrinted.includes(n.children[key].tag))return n.children[key].tag;else if(!printChildren){return n.children[key].tag}else return n.children[key].print(n.children[key],printChildren,nodesPrinted)}}for(const prop in n){if(prop==="parent"||prop==="children")continue;if(typeof dummyNode[prop]==="undefined"){if(typeof n[prop]==="function"){jsonToPrint[prop]=n[prop].toString()}else if(typeof n[prop]==="object"){jsonToPrint[prop]=JSON.stringifyWithCircularRefs(n[prop])}else{jsonToPrint[prop]=n[prop]}}}return JSON.stringify(jsonToPrint)}};this.reconstruct=json=>{let parsed=reconstructObject(json);if(parsed)return this.add(parsed)};this.setState=data=>{this.state.setState(data)};this.DEBUGNODES=(debugging=true)=>{this.DEBUGNODE=debugging;this.nodes.forEach(n=>{if(debugging)n.DEBUGNODE=true;else n.DEBUGNODE=false})};if(typeof properties==="function"){properties={operator:properties}}if(typeof properties==="object"){if(properties instanceof GraphNode&&properties._initial)Object.assign(properties,properties._initial);if(properties instanceof Graph){let source=properties;properties={source,operator:input=>{if(typeof input==="object"){let result={};for(const key in input){if(typeof source[key]==="function"){if(Array.isArray(input[key]))result[key]=source[key](...input[key]);else result[key]=source[key](input[key])}else{source[key]=input[key];result[key]=source[key]}}return result}return source}};if(source.operator)properties.operator=source.operator;if(source.children)properties.children=source.children;if(source.forward)properties.forward=source.forward;if(source.backward)properties.backward=source.backward;if(source.repeat)properties.repeat=source.repeat;if(source.recursive)properties.recursive=source.recursive;if(source.loop)properties.loop=source.loop;if(source.animate)properties.animate=source.animate;if(source.looper)properties.looper=source.looper;if(source.animation)properties.animation=source.animation;if(source.delay)properties.delay=source.delay;if(source.oncreate)properties.oncreate=source.oncreate;if(source.node){if(source.node._initial)Object.assign(properties,source.node._initial)}if(source._initial)Object.assign(properties,source._initial);if(source.tag)properties.tag=source.tag;this.nodes=source.nodes;source.node=this;if(graph){source.nodes.forEach(n=>{if(!graph.nodes.get(n.tag)){graph.nodes.set(n.tag,n);graph.nNodes++}})}}if(typeof parent==="string"){if(graph)parent=graph.nodes.get(parent);else parent=void 0}if(properties.tag&&(graph||parent)){let hasnode;if(graph?.nodes){hasnode=graph.nodes.get(properties.tag)}if(!hasnode&&parent?.nodes){hasnode=parent.nodes.get(properties.tag)}if(hasnode){if(this.reactive){this.addLocalState(hasnode)}if(!this.source)this.source=hasnode;let props=hasnode.getProps();delete props.graph;delete props.parent;for(let k in props)properties[k]=props[k]}}if(properties?.operator){properties.operator=this.setOperator(properties.operator)}if(!properties.tag&&graph){properties.tag=`node${graph.nNodes}`}else if(!properties.tag){properties.tag=`node${Math.floor(Math.random()*1e10)}`}let keys=Object.getOwnPropertyNames(this);for(const key in properties){if(!keys.includes(key))this._initial[key]=properties[key]}if(properties.children)this._initial.children=Object.assign({},properties.children);Object.assign(this,properties);if(!this.tag){if(graph){this.tag=`node${graph.nNodes}`}else{this.tag=`node${Math.floor(Math.random()*1e10)}`}}if(graph){this.graph=graph;if(graph.nodes.get(this.tag)){this.tag=`${this.tag}${graph.nNodes+1}`}graph.nodes.set(this.tag,this);graph.nNodes++;this.state=graph.state}if(this.reactive){addLocalState(properties);if(typeof this.reactive==="function"){this.state.subscribeTrigger(this._unique,this.reactive)}}if(typeof parent==="object"){this.parent=parent;if(parent instanceof GraphNode||parent instanceof Graph)parent.nodes.set(this.tag,this)}if(typeof properties.tree==="object"){for(const key in properties.tree){if(typeof properties.tree[key]==="object"){if((!properties.tree[key]).tag){properties.tree[key].tag=key}}let node=new GraphNode(properties.tree[key],this,graph);this.nodes.set(node.tag,node)}}if(this.children)this.convertChildrenToNodes(this);if(this.parent instanceof GraphNode||this.parent instanceof Graph)this.checkNodesHaveChildMapped(this.parent,this);if(typeof this.oncreate==="function")this.oncreate(this);if(!this.firstRun)this.firstRun=true;if(this.animation&&!this.animate)this.animate=true}else return properties}};var Graph=class{constructor(tree,tag,props){this.nNodes=0;this.nodes=new Map;this.state=new EventHandler;this._unique=`${Math.random()}`;this.tree={};this.addLocalState=addLocalState;this.add=(n={})=>{if(n?.node instanceof GraphNode)n=n.node;let props=n;if(!(n instanceof GraphNode))n=new GraphNode(props?.node??props,this,this);else{this.nNodes=this.nodes.size;if(n.tag){this.tree[n.tag]=props;this.nodes.set(n.tag,n)}}return n};this.setTree=(tree=this.tree)=>{if(!tree)return;for(const node in tree){const n=this.nodes.get(node);if(!n){if(typeof tree[node]==="function"){this.add({tag:node,operator:tree[node]})}else if(typeof tree[node]==="object"&&!Array.isArray(tree[node])){if(!tree[node].tag)tree[node].tag=node;let newNode=this.add(tree[node]);if(tree[node].aliases){tree[node].aliases.forEach(a=>{this.nodes.set(a,newNode)})}}else{this.add({tag:node,operator:(...args)=>{return tree[node]}})}}else{if(typeof tree[node]==="function"){n.setOperator(tree[node])}else if(typeof tree[node]==="object"){if(tree[node]instanceof GraphNode){this.add(tree[node])}else if(tree[node]instanceof Graph){let source=tree[node];let properties={};if(source.operator)properties.operator=source.operator;if(source.children)properties.children=source.children;if(source.forward)properties.forward=source.forward;if(source.backward)properties.backward=source.backward;if(source.repeat)properties.repeat=source.repeat;if(source.recursive)properties.recursive=source.recursive;if(source.loop)properties.loop=source.loop;if(source.animate)properties.animate=source.animate;if(source.looper)properties.looper=source.looper;if(source.animation)properties.animation=source.animation;if(source.delay)properties.delay=source.delay;if(source.tag)properties.tag=source.tag;if(source.oncreate)properties.oncreate=source.oncreate;if(source.node?._initial)Object.assign(properties,source.node._initial);properties.nodes=source.nodes;properties.source=source;n.setProps(properties)}else{n.setProps(tree[node])}}}}this.nodes.forEach(node=>{if(typeof node.children==="object"){for(const key in node.children){if(typeof node.children[key]==="string"){if(this.nodes.get(node.children[key])){node.children[key]=this.nodes.get(node.children[key])}}else if(node.children[key]===true||typeof node.children[key]==="undefined"){if(this.nodes.get(key)){node.children[key]=this.nodes.get(key)}}if(node.children[key]instanceof GraphNode){node.checkNodesHaveChildMapped(node,node.children[key])}}}if(typeof node.parent==="string"){if(this.nodes.get(node.parent)){node.parent=this.nodes.get(node.parent);node.nodes.set(node.parent.tag,node.parent)}}})};this.get=tag=>{return this.nodes.get(tag)};this.set=n=>{return this.nodes.set(n.tag,n)};this.run=(n,...args)=>{if(typeof n==="string")n=this.nodes.get(n);if(n?.run)return n.run(...args);else return void 0};this.runAsync=(n,...args)=>{if(typeof n==="string")n=this.nodes.get(n);if(n?.run)return new Promise((res,rej)=>{res(n.run(...args))});else return new Promise((res,rej)=>{res(void 0)})};this.removeTree=(n,checked)=>{if(typeof n==="string")n=this.nodes.get(n);if(n?.nodes){if(!checked)checked={};const recursivelyRemove=node=>{if(node.children&&!checked[node.tag]){checked[node.tag]=true;if(Array.isArray(node.children)){node.children.forEach(c=>{if(c.stopNode)c.stopNode();if(c.tag){if(this.nodes.get(c.tag))this.nodes.delete(c.tag)}this.nodes.forEach(n2=>{if(n2.nodes.get(c.tag))n2.nodes.delete(c.tag)});recursivelyRemove(c)})}else if(typeof node.children==="object"){if(node.stopNode)node.stopNode();if(node.tag){if(this.nodes.get(node.tag))this.nodes.delete(node.tag)}this.nodes.forEach(n2=>{if(n2.nodes.get(node.tag))n2.nodes.delete(node.tag)});recursivelyRemove(node)}}};if(n.stopNode)n.stopNode();if(n.tag){this.nodes.delete(n.tag);this.nodes.forEach(n2=>{if(n2.nodes.get(n2.tag))n2.nodes.delete(n2.tag)});this.nNodes=this.nodes.size;recursivelyRemove(n)}if(n.ondelete)n.ondelete(n)}return n};this.remove=n=>{if(typeof n==="string")n=this.nodes.get(n);if(n?.nodes){if(n.stopNode)n.stopNode();if(n?.tag){if(this.nodes.get(n.tag)){this.nodes.delete(n.tag);this.nodes.forEach(n2=>{if(n2.nodes.get(n2.tag))n2.nodes.delete(n2.tag)})}}if(n.ondelete)n.ondelete(n)}return n};this.append=(n,parentNode)=>{parentNode.addChildren(n)};this.callParent=async(n,...args)=>{if(n?.parent){return await n.callParent(...args)}};this.callChildren=async(n,...args)=>{if(n?.children){return await n.callChildren(...args)}};this.subscribe=(n,callback)=>{if(!callback)return;if(n?.subscribe&&typeof callback==="function"){return n.subscribe(callback)}else if(callback instanceof GraphNode||typeof callback==="string")return this.subscribeNode(n,callback);else if(typeof n=="string"){return this.state.subscribeTrigger(n,callback)}};this.unsubscribe=(tag,sub)=>{return this.state.unsubscribeTrigger(tag,sub)};this.subscribeState=callback=>{if(!this.reactive){return void 0}else{if(typeof callback==="string"){if(this.graph)callback=this.graph.get(callback);else callback=this.nodes.get(callback)}if(typeof callback==="function"){return this.state.subscribeTrigger(this._unique,callback)}else if(callback)return this.state.subscribeTrigger(this._unique,_state=>{callback.run(_state)})}};this.subscribeNode=(inputNode,outputNode)=>{let tag;if(inputNode?.tag)tag=inputNode.tag;else if(typeof inputNode==="string")tag=inputNode;if(typeof outputNode==="string")outputNode=this.nodes.get(outputNode);if(inputNode&&outputNode){let sub=this.state.subscribeTrigger(tag,res=>{if(Array.isArray(res))outputNode.run(...res);else outputNode.run(res)});return sub}};this.stopNode=n=>{if(typeof n==="string"){n=this.nodes.get(n)}if(n?.stopNode){n.stopNode()}};this.print=(n,printChildren=true)=>{if(n?.print)return n.print(n,printChildren);else{let printed=`{`;this.nodes.forEach(n2=>{printed+=` +"${n2.tag}:${n2.print(n2,printChildren)}"`});return printed}};this.reconstruct=json=>{let parsed=reconstructObject(json);if(parsed)return this.add(parsed)};this.create=(operator,parentNode,props)=>{return createNode(operator,parentNode,props,this)};this.setState=data=>{this.state.setState(data)};this.DEBUGNODES=(debugging=true)=>{this.nodes.forEach(n=>{if(debugging)n.DEBUGNODE=true;else n.DEBUGNODE=false})};this.tag=tag?tag:`graph${Math.floor(Math.random()*1e11)}`;if(props){if(props.reactive){this.addLocalState(props)}else Object.assign(this,props);this._initial=props}if(tree||Object.keys(this.tree).length>0)this.setTree(tree)}};function reconstructNode(json,parentNode,graph){let reconstructed=reconstructObject(json);if(reconstructed)return new GraphNode(reconstructed,parentNode,graph);else return void 0}function reconstructObject(json="{}"){try{let parsed=typeof json==="string"?JSON.parse(json):json;const parseObj=obj=>{for(const prop in obj){if(typeof obj[prop]==="string"){let funcParsed=parseFunctionFromText(obj[prop]);if(typeof funcParsed==="function"){obj[prop]=funcParsed}}else if(typeof obj[prop]==="object"){parseObj(obj[prop])}}return obj};return parseObj(parsed)}catch(err){console.error(err);return void 0}}var stringifyWithCircularRefs=function(){const refs=new Map;const parents=[];const path3=["this"];function clear(){refs.clear();parents.length=0;path3.length=1}function updateParents(key,value){var idx=parents.length-1;var prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value||idx===0){path3.push(key);parents.push(value.pushed)}else{while(idx-->=0){prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value){idx+=2;parents.length=idx;path3.length=idx;--idx;parents[idx]=value;path3[idx]=key;break}}idx--}}}}function checkCircular(key,value){if(value!=null){if(typeof value==="object"){if(key){updateParents(key,value)}let other=refs.get(value);if(other){return"[Circular Reference]"+other}else{refs.set(value,path3.join("."))}}}return value}return function stringifyWithCircularRefs2(obj,space){try{parents.push(obj);return JSON.stringify(obj,checkCircular,space)}finally{clear()}}}();if(JSON.stringifyWithCircularRefs===void 0){JSON.stringifyWithCircularRefs=stringifyWithCircularRefs}var stringifyFast=function(){const refs=new Map;const parents=[];const path3=["this"];function clear(){refs.clear();parents.length=0;path3.length=1}function updateParents(key,value){var idx=parents.length-1;if(parents[idx]){var prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value||idx===0){path3.push(key);parents.push(value.pushed)}else{while(idx-->=0){prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value){idx+=2;parents.length=idx;path3.length=idx;--idx;parents[idx]=value;path3[idx]=key;break}}idx++}}}}}function checkValues(key,value){let val;if(value!=null){if(typeof value==="object"){let c=value.constructor.name;if(key&&c==="Object"){updateParents(key,value)}let other=refs.get(value);if(other){return"[Circular Reference]"+other}else{refs.set(value,path3.join("."))}if(c==="Array"){if(value.length>20){val=value.slice(value.length-20)}else val=value}else if(c.includes("Set")){val=Array.from(value)}else if(c!=="Object"&&c!=="Number"&&c!=="String"&&c!=="Boolean"){val="instanceof_"+c}else if(c==="Object"){let obj={};for(const prop in value){if(value[prop]==null){obj[prop]=value[prop]}else if(Array.isArray(value[prop])){if(value[prop].length>20)obj[prop]=value[prop].slice(value[prop].length-20);else obj[prop]=value[prop]}else if(value[prop].constructor.name==="Object"){obj[prop]={};for(const p in value[prop]){if(Array.isArray(value[prop][p])){if(value[prop][p].length>20)obj[prop][p]=value[prop][p].slice(value[prop][p].length-20);else obj[prop][p]=value[prop][p]}else{if(value[prop][p]!=null){let con=value[prop][p].constructor.name;if(con.includes("Set")){obj[prop][p]=Array.from(value[prop][p])}else if(con!=="Number"&&con!=="String"&&con!=="Boolean"){obj[prop][p]="instanceof_"+con}else{obj[prop][p]=value[prop][p]}}else{obj[prop][p]=value[prop][p]}}}}else{let con=value[prop].constructor.name;if(con.includes("Set")){obj[prop]=Array.from(value[prop])}else if(con!=="Number"&&con!=="String"&&con!=="Boolean"){obj[prop]="instanceof_"+con}else{obj[prop]=value[prop]}}}val=obj}else{val=value}}else{val=value}}return val}return function stringifyFast2(obj,space){parents.push(obj);let res=JSON.stringify(obj,checkValues,space);clear();return res}}();if(JSON.stringifyFast===void 0){JSON.stringifyFast=stringifyFast}function createNode(operator,parentNode,props,graph){if(typeof props==="object"){props.operator=operator;return new GraphNode(props,parentNode,graph)}return new GraphNode({operator},parentNode,graph)}var Service=class extends Graph{constructor(options={}){super(void 0,options.name?options.name:`service${Math.floor(Math.random()*1e14)}`,options.props);this.routes={};this.loadDefaultRoutes=false;this.keepState=true;this.firstLoad=true;this.customRoutes={};this.customChildren={};this.init=options=>{if(options)options=Object.assign({},options);else options={};if(options.customRoutes)Object.assign(options.customRoutes,this.customRoutes);else options.customRoutes=this.customRoutes;if(options.customChildren)Object.assign(options.customChildren,this.customChildren);else options.customChildren=this.customChildren;if(Array.isArray(options.routes)){options.routes.forEach(r=>{this.load(r,options.includeClassName,options.routeFormat,options.customRoutes,options.customChildren,options.sharedState)})}else if(options.routes||(Object.keys(this.routes).length>0||this.loadDefaultRoutes)&&this.firstLoad)this.load(options.routes,options.includeClassName,options.routeFormat,options.customRoutes,options.customChildren,options.sharedState)};this.load=(routes,includeClassName=true,routeFormat=".",customRoutes,customChildren,sharedState=true)=>{if(!routes&&!this.loadDefaultRoutes&&(Object.keys(this.routes).length>0||this.firstLoad))return;if(this.firstLoad)this.firstLoad=false;if(customRoutes)customRoutes=Object.assign(this.customRoutes,customRoutes);else customRoutes=this.customRoutes;let service;let allRoutes={};if(routes){if(!(routes instanceof Graph)&&routes?.name&&!routes.setTree){if(routes.module){let mod=routes;routes={};Object.getOwnPropertyNames(routes.module).forEach(prop=>{if(includeClassName)routes[mod.name+routeFormat+prop]=routes.module[prop];else routes[prop]=routes.module[prop]})}else if(typeof routes==="function"){service=new routes({loadDefaultRoutes:this.loadDefaultRoutes});service.load();if(sharedState)service.state=this.state;routes=service.routes;if(service.customRoutes&&!this.customRoutes)this.customRoutes=service.customRoutes;else if(service.customRoutes&&this.customRoutes)Object.assign(this.customRoutes,service.customRoutes);if(service.customChildren&&!this.customChildren)this.customChildren=service.customChildren;else if(service.customChildren&&this.customChildren)Object.assign(this.customChildren,service.customChildren)}}else if(routes instanceof Graph||routes.source instanceof Graph||routes.setTree){service=routes;routes={};if(sharedState)service.state=this.state;if(includeClassName){let name=service.name;if(!name){name=service.tag;service.name=name}if(!name){name=`graph${Math.floor(Math.random()*1e15)}`;service.name=name;service.tag=name}}if(service.customRoutes&&!this.customRoutes)this.customRoutes=service.customRoutes;else if(service.customRoutes&&this.customRoutes)Object.assign(this.customRoutes,service.customRoutes);if(service.customChildren&&!this.customChildren)this.customChildren=service.customChildren;else if(service.customChildren&&this.customChildren)Object.assign(this.customChildren,service.customChildren);service.nodes.forEach(node=>{routes[node.tag]=node;let checked={};let checkChildGraphNodes=(nd,par)=>{if(!checked[nd.tag]||par&&includeClassName&&!checked[par?.tag+routeFormat+nd.tag]){if(!par)checked[nd.tag]=true;else checked[par.tag+routeFormat+nd.tag]=true;if(nd instanceof Graph||nd.source instanceof Graph||nd.setTree){if(sharedState)nd.state=this.state;if(includeClassName){let nm=nd.name;if(!nm){nm=nd.tag;nd.name=nm}if(!nm){nm=`graph${Math.floor(Math.random()*1e15)}`;nd.name=nm;nd.tag=nm}}nd.nodes.forEach(n=>{if(includeClassName&&!routes[nd.tag+routeFormat+n.tag])routes[nd.tag+routeFormat+n.tag]=n;else if(!routes[n.tag])routes[n.tag]=n;checkChildGraphNodes(n,nd)})}}};checkChildGraphNodes(node)})}else if(typeof routes==="object"){let name=routes.constructor.name;if(name==="Object"){name=Object.prototype.toString.call(routes);if(name)name=name.split(" ")[1];if(name)name=name.split("]")[0]}if(name&&name!=="Object"){let module2=routes;routes={};Object.getOwnPropertyNames(module2).forEach(route=>{if(includeClassName)routes[name+routeFormat+route]=module2[route];else routes[route]=module2[route]})}}if((service instanceof Graph||service?.setTree)&&service.name&&includeClassName){routes=Object.assign({},routes);for(const prop in routes){let route=routes[prop];delete routes[prop];routes[service.name+routeFormat+prop]=route}}}if(this.loadDefaultRoutes){let rts=Object.assign({},this.defaultRoutes);if(routes){Object.assign(rts,this.routes);routes=Object.assign(rts,routes)}else routes=Object.assign(rts,this.routes);this.loadDefaultRoutes=false}if(!routes)routes=this.routes;let incr=0;for(const tag in routes){incr++;let childrenIter=(route,routeKey)=>{if(typeof route==="object"){if(!route.tag)route.tag=routeKey;if(typeof route?.children==="object"){nested:for(const key in route.children){incr++;if(typeof route.children[key]==="object"){let rt=route.children[key];if(rt.tag&&allRoutes[rt.tag])continue;if(customChildren){for(const k2 in customChildren){rt=customChildren[k2](rt,key,route,routes,allRoutes);if(!rt)continue nested}}if(rt.id&&!rt.tag){rt.tag=rt.id}let k;if(rt.tag){if(allRoutes[rt.tag]){let randkey=`${rt.tag}${incr}`;allRoutes[randkey]=rt;rt.tag=randkey;childrenIter(allRoutes[randkey],key);k=randkey}else{allRoutes[rt.tag]=rt;childrenIter(allRoutes[rt.tag],key);k=rt.tag}}else{if(allRoutes[key]){let randkey=`${key}${incr}`;allRoutes[randkey]=rt;rt.tag=randkey;childrenIter(allRoutes[randkey],key);k=randkey}else{allRoutes[key]=rt;childrenIter(allRoutes[key],key);k=key}}if(service?.name&&includeClassName){allRoutes[service.name+routeFormat+k]=rt;delete allRoutes[k]}else allRoutes[k]=rt}}}}};allRoutes[tag]=routes[tag];childrenIter(routes[tag],tag)}top:for(const route in allRoutes){if(typeof allRoutes[route]==="object"){let r=allRoutes[route];if(typeof r==="object"){if(customRoutes){for(const key in customRoutes){r=customRoutes[key](r,route,allRoutes);if(!r)continue top}}if(r.get){if(typeof r.get=="object"){}}if(r.post){}if(r.delete){}if(r.put){}if(r.head){}if(r.patch){}if(r.options){}if(r.connect){}if(r.trace){}if(r.post&&!r.operator){allRoutes[route].operator=r.post}else if(!r.operator&&typeof r.get=="function"){allRoutes[route].operator=r.get}}}}for(const route in routes){if(typeof routes[route]==="object"){if(this.routes[route]){if(typeof this.routes[route]==="object")Object.assign(this.routes[route],routes[route]);else this.routes[route]=routes[route]}else this.routes[route]=routes[route]}else if(this.routes[route]){if(typeof this.routes[route]==="object")Object.assign(this.routes[route],routes[route]);else this.routes[route]=routes[route]}else this.routes[route]=routes[route]}if(service){for(const key in this.routes){if(this.routes[key]instanceof GraphNode||this.routes[key].constructor.name.includes("GraphNode")){this.nodes.set(key,this.routes[key]);this.nNodes=this.nodes.size}}}else this.setTree(this.routes);for(const prop in this.routes){if(this.routes[prop]?.aliases){let aliases=this.routes[prop].aliases;aliases.forEach(a=>{if(service?.name&&includeClassName)routes[service.name+routeFormat+a]=this.routes[prop];else routes[a]=this.routes[prop]})}}return this.routes};this.unload=(routes=this.routes)=>{if(!routes)return;let service;if(!(routes instanceof Service)&&typeof routes==="function"){service=new Service;routes=service.routes}else if(routes instanceof Service){routes=routes.routes}for(const r in routes){delete this.routes[r];if(this.nodes.get(r))this.remove(r)}return this.routes};this.handleMethod=(route,method,args)=>{let m=method.toLowerCase();let src=this.nodes.get(route);if(!src){src=this.routes[route];if(!src)src=this.tree[route]}if(src?.[m]){if(!(src[m]instanceof Function)){if(args)src[m]=args;return src[m]}else return src[m](args)}else return this.handleServiceMessage({route,args,method})};this.transmit=(...args)=>{if(typeof args[0]==="object"){if(args[0].method){return this.handleMethod(args[0].route,args[0].method,args[0].args)}else if(args[0].route){return this.handleServiceMessage(args[0])}else if(args[0].node){return this.handleGraphNodeCall(args[0].node,args[0].args)}else if(this.keepState){if(args[0].route)this.setState({[args[0].route]:args[0].args});if(args[0].node)this.setState({[args[0].node]:args[0].args})}return args}else return args};this.receive=(...args)=>{if(args[0]){if(typeof args[0]==="string"){let substr=args[0].substring(0,8);if(substr.includes("{")||substr.includes("[")){if(substr.includes("\\"))args[0]=args[0].replace(/\\/g,"");if(args[0][0]==='"'){args[0]=args[0].substring(1,args[0].length-1)};args[0]=JSON.parse(args[0])}}}if(typeof args[0]==="object"){if(args[0].method){return this.handleMethod(args[0].route,args[0].method,args[0].args)}else if(args[0].route){return this.handleServiceMessage(args[0])}else if(args[0].node){return this.handleGraphNodeCall(args[0].node,args[0].args)}else if(this.keepState){if(args[0].route)this.setState({[args[0].route]:args[0].args});if(args[0].node)this.setState({[args[0].node]:args[0].args})}return args}else return args};this.pipe=(source,destination,endpoint,method,callback)=>{if(source instanceof GraphNode){if(callback)return source.subscribe(res=>{let mod=callback(res);if(mod!==void 0)this.transmit({route:destination,args:mod,method});else this.transmit({route:destination,args:res,method},endpoint)});else return this.subscribe(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})}else if(typeof source==="string")return this.subscribe(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})};this.pipeOnce=(source,destination,endpoint,method,callback)=>{if(source instanceof GraphNode){if(callback)return source.state.subscribeTriggerOnce(source.tag,res=>{let mod=callback(res);if(mod!==void 0)this.transmit({route:destination,args:mod,method});else this.transmit({route:destination,args:res,method},endpoint)});else return this.state.subscribeTriggerOnce(source.tag,res=>{this.transmit({route:destination,args:res,method},endpoint)})}else if(typeof source==="string")return this.state.subscribeTriggerOnce(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})};this.terminate=(...args)=>{this.nodes.forEach(n=>{n.stopNode()})};this.recursivelyAssign=(target,obj)=>{for(const key in obj){if(typeof obj[key]==="object"&&!Array.isArray(obj[key])){if(typeof target[key]==="object"&&!Array.isArray(target[key]))this.recursivelyAssign(target[key],obj[key]);else target[key]=this.recursivelyAssign({},obj[key])}else target[key]=obj[key]}return target};this.defaultRoutes={"/":{get:()=>{return this.print()},aliases:[""]},ping:()=>{console.log("ping");return"pong"},echo:(...args)=>{this.transmit(...args);return args},assign:source=>{if(typeof source==="object"){Object.assign(this,source);return true}return false},recursivelyAssign:source=>{if(typeof source==="object"){this.recursivelyAssign(this,source);return true}return false},log:{post:(...args)=>{console.log("Log: ",...args)},aliases:["info"]},error:message=>{let er=new Error(message);console.error(message);return er},state:key=>{if(key){return this.state.data[key]}else return this.state.data},printState:key=>{if(key){return stringifyWithCircularRefs(this.state.data[key])}else return stringifyWithCircularRefs(this.state.data)},spliceTypedArray:this.spliceTypedArray,transmit:this.transmit,receive:this.receive,load:this.load,unload:this.unload,pipe:this.pipe,terminate:this.terminate,run:this.run,subscribe:this.subscribe,subscribeNode:this.subscribeNode,unsubscribe:this.unsubscribe,stopNode:this.stopNode,get:this.get,add:this.add,remove:this.remove,setTree:this.setTree,setState:this.setState,print:this.print,reconstruct:this.reconstruct,handleMethod:this.handleMethod,handleServiceMessage:this.handleServiceMessage,handleGraphNodeCall:this.handleGraphNodeCall};if(options.name)this.name=options.name;else options.name=this.tag;if("loadDefaultRoutes"in options){this.loadDefaultRoutes=options.loadDefaultRoutes;this.routes=Object.assign(this.defaultRoutes,this.routes)}if(options||Object.keys(this.routes).length>0)this.init(options)}handleServiceMessage(message){let call;if(typeof message==="object"){if(message.route)call=message.route;else if(message.node)call=message.node}if(call){if(Array.isArray(message.args))return this.run(call,...message.args);else return this.run(call,message.args)}else return message}handleGraphNodeCall(route,args){if(!route)return args;if(args?.args){this.handleServiceMessage(args)}else if(Array.isArray(args))return this.run(route,...args);else return this.run(route,args)}isTypedArray(x){return ArrayBuffer.isView(x)&&Object.prototype.toString.call(x)!=="[object DataView]"}spliceTypedArray(arr,start,end){let s=arr.subarray(0,start);let e;if(end){e=arr.subarray(end+1)}let n;if(s.length>0||e?.length>0)n=new arr.constructor(s.length+e.length);if(s.length>0)n.set(s);if(e&&e.length>0)n.set(e,s.length);return n}};var unsafeRoutes={setRoute:function(fn,fnName){if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function"){if(!fnName)fnName=fn.name;if(this.graph.get(fnName)){this.graph.get(fnName).setOperator(fn.bind(this.graph.get(fnName)))}else{let node=this.graph.add({tag:fnName,operator:fn});if(this.graph instanceof Service)this.graph.load({[fnName]:node})}return true}return false},setNode:function(fn,fnName){if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function"){if(!fnName)fnName=fn.name;if(this.graph.get(fnName)){this.graph.get(fnName).setOperator(fn)}else this.graph.add({tag:fnName,operator:fn});return true}return false},setMethod:function(route,fn,fnName){if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function"){if(!fnName)fnName=fn.name;if(this.graph.get(route)){this.graph.get(route)[fnName]=fn}else this.graph.add({tag:fnName,[fnName]:fn});return true}return false},assignRoute:function(route,source){if(this.graph.get(route)&&typeof source==="object"){Object.assign(this.graph.get(route),source)}},transferClass:(classObj,className)=>{if(typeof classObj==="object"){let str=classObj.toString();let message={route:"receiveClass",args:[str,className]};return message}return false},receiveClass:function(stringified,className){if(typeof stringified==="string"){if(stringified.indexOf("class")===0){let cls=(0,eval)("("+stringified+")");let name=className;if(!name)name=cls.name;this.graph[name]=cls;return true}}return false},setGlobal:(key,value)=>{globalThis[key]=value;return true},assignGlobalObject:(target,source)=>{if(!globalThis[target])return false;if(typeof source==="object")Object.assign(globalThis[target],source);return true},setValue:function(key,value){this.graph[key]=value;return true},assignObject:function(target,source){if(!this.graph[target])return false;if(typeof source==="object")Object.assign(this.graph[target],source);return true},setGlobalFunction:(fn,fnName)=>{if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function"){if(!fnName)fnName=fn.name;globalThis[fnName]=fn;return true}return false},assignFunctionToGlobalObject:function(globalObjectName,fn,fnName){if(!globalThis[globalObjectName])return false;if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function"){if(!fnName)fnName=fn.name;this.graph[globalObjectName][fnName]=fn;return true}return false},setFunction:function(fn,fnName){if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function"){if(!fnName)fnName=fn.name;this.graph[fnName]=fn;return true}return false},assignFunctionToObject:function(objectName,fn,fnName){if(!this.graph[objectName])return false;if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function"){if(!fnName)fnName=fn.name;this.graph[objectName][fnName]=fn;return true}return false}};var ECSService=class extends Service{constructor(options){super(options);this.entities={};this.systems={};this.entityMap=new Map;this.entityKeyMap=new Map;this.order=[];this.animating=false;this.entityCt=0;this.systemCt=0;this.updateEntities=(order=this.order,filter,debug=false)=>{order.forEach(k=>{if(this.systems[k]){if(filter){if(debug)debug=performance.now();if(this.entityKeyMap.get(k).length>0)this.systems[k].run(this.entityMap.get(k));if(debug)console.log("system",k,"took",performance.now()-debug,"ms for",Object.keys(this.entityMap.get(k)).length,"entities")}else{if(debug)debug=performance.now();if(this.entityKeyMap.get(k).length>0)this.systems[k].run(this.entities);if(debug)console.log("system",k,"took",performance.now()-debug,"ms for",Object.keys(this.entities).length,"entities")}}})};this.animate=(filter=true,order)=>{if(this.animating===false){this.animating=true;if(typeof requestAnimationFrame!=="undefined"){let anim=()=>{requestAnimationFrame(()=>{if(this.animating){this.updateEntities(order,filter);anim()}})};anim()}else{let looper=()=>{setTimeout(async()=>{if(this.animating){this.updateEntities(order,filter);looper()}},10)};looper()}}};this.stop=()=>{this.animating=false};this.start=filter=>{this.animate(filter)};this.addEntities=(prototype,components={},count=1)=>{let i=0;let newEntities={};while(i{if(!prototype)return;const entity=this.recursivelyAssign({},prototype);entity.components=components;if(Object.keys(components).length===0){Object.keys(this.systems).forEach(k=>{components[k]=true})}if(entity.tag&&this.entities[entity.tag]){this.entityCt++;let tag=entity.tag+this.entityCt;while(this.entities[entity.tag]){this.entityCt++;entity.tag=`${tag}${this.entityCt}`}}else if(!entity.tag)entity.tag=`entity${Math.floor(Math.random()*1e15)}`;this.add(entity);this.entities[entity.tag]=this.nodes.get(entity.tag);this.setupEntity(this.entities[entity.tag]);return this.entities[entity.tag]};this.addSystems=(systems={},order)=>{for(const key in systems){systems[key].tag=key;this.addSystem(systems[key],void 0,void 0,void 0,void 0,order)}return this.systems};this.addSystem=(prototype,setupEntities,setupEntity,operator,remove,order)=>{if(!prototype)return;const system=this.recursivelyAssign({},prototype);if(setupEntities)system.setupEntities=setupEntities;if(setupEntity)system.setupEntity=setupEntity;if(operator)system.operator=operator;if(remove)system.remove=remove;if(system.tag&&this.systems[system.tag]){this.systemCt++;let tag=system.tag+this.systemCt;while(this.systems[system.tag]){this.systemCt++;system.tag=`${tag}${this.systemCt}`}}else if(!system.tag)system.tag=`system${Math.floor(Math.random()*1e15)}`;this.add(system);this.systems[system.tag]=this.nodes.get(system.tag);if(!this.entityMap.get(system.tag))this.entityMap.set(system.tag,{});if(!this.entityKeyMap.get(system.tag))this.entityKeyMap.set(system.tag,[]);this.systems[system.tag].entities=this.entityMap.get(system.tag);this.systems[system.tag].entityKeys=this.entityKeyMap.get(system.tag);if(this.systems[system.tag]?.setupEntities){let filtered=this.filterObject(this.entities,(key,v)=>{if(v.components[system.tag])return true});this.systems[system.tag].setupEntities(filtered);Object.assign(this.entityMap.get(system.tag),filtered)}if(!order)this.order.push(system.tag);else this.order=order;return this.systems[system.tag]};this.setupEntity=entity=>{if(entity?.components){for(const key in entity.components){if(this.systems[key]){this.systems[key].setupEntity(entity);this.entityMap.get(key)[entity.tag]=entity;this.entityKeyMap.get(key).push(entity.tag)}}}};this.removeEntity=tag=>{const entity=this.entities[tag];for(const key in entity.components){if(this.entityMap.get(key)){delete this.entityMap.get(key)[entity.tag];this.entityKeyMap.get(key).splice(this.entityKeyMap.get(key).indexOf(entity.tag),1)}if(this.systems[key]?.remove){this.systems[key].remove(entity,this.entityMap.get(key))}}delete this.entities[tag];return this.remove(tag)};this.removeSystem=tag=>{if(this.systems[tag]?.remove){for(const e in this.entityKeyMap.get(tag)){this.systems[tag].remove(this.entityMap.get(tag)[e],this.entityMap.get(tag))}}delete this.systems[tag];this.entityMap.delete(tag);this.entityKeyMap.delete(tag);this.order.splice(this.order.indexOf(tag),1);return this.remove(tag)};this.setEntities=(entities,props)=>{if(Array.isArray(entities)){entities.forEach(k=>{if(this.entities[k])this.recursivelyAssign(this.entities[k],props)})}else{for(const key in this.entities){this.setEntity(this.entities[key],props)}}return true};this.setEntity=(entity,props)=>{return this.recursivelyAssign(entity,props)};this.bufferValues=(entities,property,keys,buffer)=>{if(!Array.isArray(keys)&&typeof keys==="object")keys=Object.keys(keys);if(!buffer){let entkeys=Object.keys(entities);if(keys)buffer=new Float32Array(entkeys.length*keys.length);else{if(typeof entities[entkeys[0]][property]==="object"){keys=Object.keys(entities[entkeys[0]][property]);buffer=new Float32Array(entkeys.length*keys.length)}else buffer=new Float32Array(entkeys.length)}}let i=0;for(const key in entities){if(entities[key][property]){if(keys){for(let j=0;j{this.removeEntity(t)})}filterObject(o,filter){return Object.fromEntries(Object.entries(o).filter(([key,value])=>{filter(key,value)}))}};var import_sjcl=__toESM(require_sjcl());var E2EEService=class extends Service{constructor(options,keys,secureKeys,secret){super(options);this.name="e2ee";this.securedKeys=false;this.addKey=(key,_id)=>{if(!_id)_id=`key${Math.floor(Math.random()*1e15)}`;if(this.securedKeys&&this.secret&&this.encryptedkeys){let decrypted=JSON.parse(import_sjcl.default.decrypt(this.secret,this.encryptedkeys));decrypted[_id]={key,_id};this.encryptedkeys=import_sjcl.default.encrypt(this.secret,decrypted).cipher;return this.encryptedkeys}else this.keys[_id]={key,_id};return this.keys[_id]};this.encryptRoute=(message,keyId)=>{if(typeof message==="object")message=JSON.stringify(message);let key;if(this.securedKeys&&this.secret&&this.encryptedkeys){let decrypted=JSON.parse(import_sjcl.default.decrypt(this.secret,this.encryptedkeys));if(decrypted[keyId]?.key){message=import_sjcl.default.encrypt(this.secret,decrypted[keyId].key).cipher}}else{if(this.keys[keyId]){if(!key)key=keyId;message=this.encrypt(message,key)}}message={route:"decryptRoute",args:[message,keyId]};return message};this.decryptRoute=(message,keyId)=>{let decryptedMessage=message;if(typeof message==="object"){if(!keyId){if(typeof message.keyId==="string")keyId=message.keyId}if(keyId){let key;if(this.securedKeys&&this.secret&&this.encryptedkeys){let decrypted=JSON.parse(import_sjcl.default.decrypt(this.secret,this.encryptedkeys));if(decrypted[keyId]?.key){decryptedMessage=import_sjcl.default.decrypt(this.secret,decrypted[keyId].key);return decryptedMessage}}else{if(this.keys[keyId])key=this.keys[keyId].key;if(key)decryptedMessage=this.decrypt(message.args,key)}}}else{let key;if(this.securedKeys&&this.secret&&this.encryptedkeys){let decrypted=JSON.parse(import_sjcl.default.decrypt(this.secret,this.encryptedkeys));if(decrypted[keyId]?.key){decryptedMessage=import_sjcl.default.decrypt(this.secret,decrypted[keyId].key);return decryptedMessage}}else{if(this.keys[keyId])key=this.keys[keyId].key;if(key)decryptedMessage=this.decrypt(message,key)}}return decryptedMessage};this.transmit=(message,keyId)=>{if(!keyId){keyId=Object.keys(this.keys)[0]}message=this.encryptRoute(message,keyId);return this.handleServiceMessage(message)};this.receive=(message,keyId)=>{if(!keyId){keyId=Object.keys(this.keys)[0]}message=this.decryptRoute(message,keyId);if(typeof message==="string"){let substr=message.substring(0,8);if(substr.includes("{")||substr.includes("[")){if(substr.includes("\\"))message=message.replace(/\\/g,"");if(message[0]==='"'){message=message.substring(1,message.length-1)};message=JSON.parse(message)}}if(typeof message==="object"){if(typeof message.method==="string"){return this.handleMethod(message.route,message.method,message.args)}else if(typeof message.route==="string"){return this.handleServiceMessage(message)}else if(typeof message.node==="string"||message.node instanceof GraphNode){return this.handleGraphNodeCall(message.node,message.args)}else if(this.keepState){if(message.route)this.setState({[message.route]:message.args});if(message.node)this.setState({[message.node]:message.args})}}else return message};this.routes={encryptRoute:this.encryptRoute,decryptRoute:this.decryptRoute,encrypt:this.encrypt,decrypt:this.decrypt,generateSecret:E2EEService.generateSecret,addKey:this.addKey};if(keys){if(secureKeys&&secret){this.securedKeys=true;this.encryptedkeys=import_sjcl.default.encrypt(secret,JSON.stringify(keys)).cipher;this.secret=secret}else Object.assign(this.keys,keys)}}static generateSecret(){return import_sjcl.default.codec.base64.fromBits(import_sjcl.default.random.randomWords(8,10))}encrypt(message,key){message=import_sjcl.default.encrypt(key,message).cipher;return message}decrypt(message,key){message=import_sjcl.default.decrypt(key,message);return message}};var http=__toESM(require("http"));var https=__toESM(require("https"));var fs=__toESM(require("fs"));var path=__toESM(require("path"));var HTTPbackend=class extends Service{constructor(options,settings){super(options);this.name="http";this.debug=false;this.servers={};this.mimeTypes={".html":"text/html",".htm":"text/html",".js":"text/javascript",".css":"text/css",".json":"application/json",".txt":"text/plain",".png":"image/png",".jpg":"image/jpg",".jpeg":"image/jpg",".gif":"image/gif",".svg":"image/svg+xml",".xhtml":"application/xhtml+xml",".bmp":"image/bmp",".wav":"audio/wav",".mp3":"audio/mpeg",".mp4":"video/mp4",".xml":"application/xml",".webm":"video/webm",".webp":"image/webp",".weba":"audio/webm",".woff":"font/woff","woff2":"font/woff2",".ttf":"application/font-ttf",".eot":"application/vnd.ms-fontobject",".otf":"application/font-otf",".wasm":"application/wasm",".zip":"application/zip",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".tif":"image/tiff",".sh":"application/x-sh",".csh":"application/x-csh",".rar":"application/vnd.rar",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".odt":"application/vnd.oasis.opendocument.text",".ods":"application/vnd.oasis.opendocument.spreadsheet",".odp":"application/vnd.oasis.opendocument.presentation",".mpeg":"video/mpeg",".mjs":"text/javascript",".cjs":"text/javascript",".jsonld":"application/ld+json",".jar":"application/java-archive",".ico":"image/vnd.microsoft.icon",".gz":"application/gzip","epub":"application/epub+zip",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".csv":"text/csv",".avi":"video/x-msvideo",".aac":"audio/aac",".mpkg":"application/vnd.apple.installer+xml",".oga":"audio/ogg",".ogv":"video/ogg","ogx":"application/ogg",".php":"application/x-httpd-php",".rtf":"application/rtf",".swf":"application/x-shockwave-flash",".7z":"application/x-7z-compressed",".3gp":"video/3gpp"};this.onStarted=(protocol,host,port)=>{console.log(`\u{1F431} Node server running at + ${protocol}://${host}:${port}/`)};this.setupServer=(options={protocol:"http",host:"localhost",port:8080,startpage:"index.html"},requestListener,onStarted)=>{console.log(options);if(options.pages){for(const key in options.pages){if(typeof options.pages[key]==="string"){this.addPage(`${options.port}/${key}`,options.pages[key])}else if(typeof options.pages[key]==="object"){if(options.pages[key].template){options.pages[key].get=options.pages[key].template}if(key!=="_all")this.load({[`${options.port}/${key}`]:options.pages[key]})}}}if(options.protocol==="https"){return this.setupHTTPSserver(options,requestListener,onStarted)}else return this.setupHTTPserver(options,requestListener,onStarted)};this.setupHTTPserver=(options={host:"localhost",port:8080,startpage:"index.html",errpage:void 0},requestListener,onStarted=()=>{this.onStarted("http",options.host,options.port)})=>{const host=options.host;const port=options.port;options.protocol="http";if(!host||!port)return;const address=`${host}:${port}`;if(this.servers[address])this.terminate(this.servers[address]);if(!("keepState"in options))options.keepState=true;const served={server:void 0,type:"httpserver",address,...options};if(!requestListener)requestListener=(request,response)=>{let received={args:{request,response},method:request.method,served};let url=request.url.slice(1);if(!url)url="/";if(options.pages){if(typeof options.pages[url]==="object"){if(options.pages[url].onrequest){if(typeof options.pages[url].onrequest==="string"){options.pages[url].onrequest=this.nodes.get(options.pages[url].onrequest)}if(typeof options.pages[url].onrequest==="object"){if(options.pages[url].onrequest.run){options.pages[url].onrequest.run(options.pages[url],request,response)}}else if(typeof options.pages[url].onrequest==="function"){options.pages[url].onrequest(this,options.pages[url],request,response)}}if(options.pages[url].redirect){url=options.pages[url].redirect;received.redirect=url}}}received.route=url;this.receive(received)};const server=http.createServer(requestListener);served.server=server;served.terminate=()=>{this.terminate(served)};served.service=this;this.servers[address]=served;served._id=options._id?options._id:address;return new Promise((resolve,reject)=>{server.on("error",err=>{console.error("Server error:",err.toString());reject(err)});server.listen(port,host,()=>{onStarted();if(served.onopen)served.onopen(served);resolve(served)})})};this.setupHTTPSserver=(options={host:"localhost",port:8080,startpage:"index.html",certpath:"cert.pem",keypath:"key.pem",passphrase:"encryption",errpage:void 0},requestListener,onStarted=()=>{this.onStarted("https",options.host,options.port)})=>{const host=options.host;const port=options.port;options.protocol="https";if(!host||!port||!options.certpath||!options.keypath)return;if(this.servers[`${host}:${port}`])this.terminate(this.servers[`${host}:${port}`]);var opts={key:fs.readFileSync(options.keypath),cert:fs.readFileSync(options.certpath),passphrase:options.passphrase};if(!("keepState"in options))options.keepState=true;const address=`${host}:${port}`;const served={server:void 0,type:"httpserver",address,...options};if(!requestListener)requestListener=(request,response)=>{let received={args:{request,response},method:request.method,served};let url=request.url.slice(1);if(!url)url="/";if(options.pages){if(typeof options.pages[url]==="object"){if(options.pages[url].redirect){url=options.pages[url].redirect;received.redirect=url}if(options.pages[url].onrequest){if(typeof options.pages[url].onrequest==="string"){options.pages[url].onrequest=this.nodes.get(options.pages[url].onrequest)}if(typeof options.pages[url].onrequest==="object"){if(options.pages[url].onrequest.run){options.pages[url].onrequest.run(options.pages[url],request,response)}}else if(typeof options.pages[url].onrequest==="function"){options.pages[url].onrequest(this,options.pages[url],request,response)}}}}received.route=url;this.receive(received)};const server=https.createServer(opts,requestListener);served.server=server;served.terminate=()=>{this.terminate(served)};served.service=this;this.servers[address]=served;served._id=options._id?options._id:address;return new Promise((resolve,reject)=>{server.on("error",err=>{console.error("Server error:",err.toString());reject(err)});server.listen(port,host,()=>{onStarted();if(served.onopen)served.onopen(served);resolve(served)})})};this.transmit=(message,options,ondata,onend)=>{let input=message;if(typeof input==="object")input=JSON.stringify(input);if(typeof options==="string"&&message)return this.post(options,message);else if(typeof options==="string")return this.get(options);if(!options){let server=this.servers[Object.keys(this.servers)[0]];options={protocol:server.protocol,host:server.host,port:server.port,method:"POST",path:message.route,headers:{"Content-Type":"application/json","Content-Length":input.length}}}else if(!options.headers){options.headers={"Content-Type":"application/json","Content-Length":input.length}}return this.request(options,input,ondata,onend)};this.withResult=(response,result,message)=>{if(result&&!response.writableEnded&&!response.destroyed){let mimeType="text/plain";if(typeof result==="string"){let extname2=path.extname(result);if(extname2&&fs.existsSync(path.join(process.cwd(),result))){mimeType=this.mimeTypes[extname2]||"application/octet-stream";result=fs.readFileSync(path.join(process.cwd(),result));if(mimeType==="text/html"&&(message.served?.pages?._all||message.served?.pages?.[message.route])){result=this.injectPageCode(result.toString(),message.route,message.served)}}if(typeof result==="string"&&result.includes("<")&&result.includes(">")&&result.indexOf("<")")){if(message?.served?.pages?._all||message?.served?.pages?.[message.route]){result=this.injectPageCode(result,message.route,message.served)}response.writeHead(200,{"Content-Type":"text/html"});response.end(result,"utf-8");return}}else if(typeof result==="object"){result=JSON.stringify(result);mimeType="application/json"}response.writeHead(200,{"Content-Type":mimeType});response.end(result,"utf-8")}};this.injectPageCode=(templateString,url,served)=>{if(served?.pages?.[url]?.inject){if(typeof served.pages[url].inject==="object")templateString=this.buildPage(served.pages[url].inject,templateString);else if(typeof served.pages[url].inject==="function")templateString+=served.pages[url].inject();else if(typeof served.pages[url].inject==="string"||typeof served.pages[url].inject==="number")templateString+=served.pages[url].inject}if(served?.pages?._all?.inject){if(typeof served.pages._all.inject==="object")templateString=this.buildPage(served.pages._all.inject,templateString);else if(typeof served.pages._all.inject==="function")templateString+=served.pages._all.inject();else if(typeof served.pages._all.inject==="string"||typeof served.pages._all.inject==="number")templateString+=served.pages._all.inject}return templateString};this.receive=message=>{const request=message.args.request;const response=message.args.response;const method=message.method;const served=message.served;if(this.debug)console.log(request.method,request.url);let result=new Promise((resolve,reject)=>{response.on("error",err=>{if(!response.writableEnded||!response.destroyed){response.statusCode=400;response.end(void 0,void 0,()=>{reject(err)})}});let getFailed=()=>{if(response.writableEnded||response.destroyed)reject(requestURL);if(requestURL=="./"||requestURL==served?.startpage){let template=`

Brains@Play Server

`;if(served?.pages?._all||served?.pages?.error){template=this.injectPageCode(template,message.route,served)}response.writeHead(200,{"Content-Type":"text/html"});response.end(template,"utf-8",()=>{resolve(template)});if(served?.keepState)this.setState({[served.address]:template})}else if(this.debug)console.log(`File ${requestURL} does not exist on path!`);response.writeHead(500);response.end(void 0,void 0,()=>{reject(requestURL)})};if(method==="GET"||method==="get"){var requestURL="."+request.url;if(requestURL=="./"&&served?.startpage){requestURL=served.startpage}if((request.url!=="/"||served?.startpage)&&fs.existsSync(path.join(process.cwd(),requestURL))){if(response.writableEnded||response.destroyed)reject(requestURL);fs.readFile(path.join(process.cwd(),requestURL),(error,content)=>{if(error){if(error.code=="ENOENT"){if(served?.errpage){fs.readFile(served.errpage,(er,content2)=>{response.writeHead(404,{"Content-Type":"text/html"});if(served.pages?._all||served.pages?.error){content2=this.injectPageCode(content2.toString(),message.route,served)}response.end(content2,"utf-8");reject(content2)})}else{response.writeHead(404,{"Content-Type":"text/html"});let content2=`

Error: ${error.code}

`;if(served?.pages?._all||served?.pages?.[message.route]){content2=this.injectPageCode(content2.toString(),message.route,served)}response.end(content2,"utf-8",()=>{reject(error.code)})}}else{response.writeHead(500);response.end("Something went wrong: "+error.code+" ..\n","utf-8",()=>{reject(error.code)})}}else{var extname2=String(path.extname(requestURL)).toLowerCase();var contentType=this.mimeTypes[extname2]||"application/octet-stream";if(contentType==="text/html"&&(served?.pages?._all||served?.pages?.[message.route])){content=this.injectPageCode(content.toString(),message.route,served)}response.writeHead(200,{"Content-Type":contentType});response.end(content,"utf-8",()=>{resolve(content)})}})}else if(message.route){let route;if(served){let rt=`${served.port}/${message.route}`;if(this.nodes.get(rt))route=rt}if(!route&&this.nodes.get(message.route))route=message.route;if(route){let res;if(message.method){res=this.handleMethod(route,message.method,void 0)}else if(message.node){res=this.handleGraphNodeCall(message.node,void 0)}else res=this.handleServiceMessage({route,args:void 0,method:message.method});if(res instanceof Promise)res.then(r=>{if(served?.keepState)this.setState({[served.address]:res});this.withResult(response,r,message);resolve(res)});else if(res){if(served?.keepState)this.setState({[served.address]:res});this.withResult(response,res,message);resolve(res)}}else if(message.redirect){response.writeHead(301,{"Location":message.redirect});response.end();resolve(true)}else getFailed()}else getFailed()}else{let body=[];request.on("data",chunk=>{body.push(chunk)}).on("end",()=>{body=Buffer.concat(body).toString();if(typeof body==="string"){let substr=body.substring(0,8);if(substr.includes("{")||substr.includes("[")){if(substr.includes("\\"))body=body.replace(/\\/g,"");if(body[0]==='"'){body=body.substring(1,body.length-1)};body=JSON.parse(body)}}let route,method2,args;if(body?.route){route=this.routes[body.route];method2=body.method;args=body.args;if(!route){if(typeof body.route==="string"){if(body.route.includes("/")&&body.route.length>1)body.route=body.route.split("/").pop()}route=this.routes[body.route]}}if(!route){if(message?.route){let route2=this.routes[message.route];method2=message.method;args=message.args;if(!route2){if(typeof message.route==="string"){if(message.route.includes("/")&&message.route.length>1)message.route=message.route.split("/").pop()}route2=this.routes[message.route]}}}let res=body;if(route){if(body.method){res=this.handleMethod(route,method2,args)}else if(body.node){res=this.handleGraphNodeCall(body.node,body.args)}else res=this.handleServiceMessage({route,args,method:method2});if(res instanceof Promise){res.then(r=>{this.withResult(response,r,message);if(served?.keepState)this.setState({[served.address]:res});resolve(res)})}else{this.withResult(response,res,message);if(served?.keepState)this.setState({[served.address]:res});resolve(res)}}else if(!response.writableEnded||!response.destroyed){response.statusCode=200;response.end(void 0,void 0,()=>{resolve(res)})}else resolve(res)})}}).catch(er=>{console.error("Request Error:",er)});return result};this.request=(options,send,ondata,onend)=>{let client=http;if(options.protocol?.includes("https")){client=https}delete options.protocol;const req=client.request(options,res=>{if(ondata)res.on("data",ondata);if(onend)res.on("end",onend)});if(options.headers){for(const head in options.headers){req.setHeader(head,options.headers[head])}}if(send)req.write(send);req.end();return req};this.post=(url,data,headers)=>{let urlstring=url;if(urlstring instanceof URL)urlstring=url.toString();let protocol=urlstring.startsWith("https")?"https":"http";let host,port,path3;let split=urlstring.split("/");split.forEach(s=>{if(s.includes(":")){let ss=s.split(":");host=ss[0];port=ss[1]}});if(split.length>3){path3=split.slice(3).join("/")}let req=this.request({protocol,host,port,path:path3,method:"POST",headers},data);return req};this.get=url=>{return new Promise((resolve,reject)=>{let client=http;let urlstring=url;if(url instanceof URL)urlstring=url.toString();if(urlstring.includes("https")){client=https}client.get(url,resp=>{let chunks=[];resp.on("data",chunk=>{chunks.push(chunk)});resp.on("end",()=>{resolve(Buffer.concat(chunks))})}).on("error",err=>{reject(err)})})};this.terminate=served=>{if(typeof served==="string")served=this.servers[served];if(typeof served==="object"){served.server.close();if(served.onclose)served.onclose(served)}};this.addPage=(path3,template)=>{if(typeof template==="string"){if(!template.includes(""+template+""}if(typeof this.routes[path3]==="object"){this.routes[path3].get=template;this.nodes.get(path3).get=template}else this.load({[path3]:{get:template}})};this.addHTML=(path3,template)=>{if(typeof template==="string"){if(!template.includes("<")||!template.includes(">"))template="
"+template+"
"}if(typeof this.routes[path3]==="object"){this.routes[path3].get=template;this.nodes.get(path3).get=template}else this.load({[path3]:{get:template}})};this.buildPage=(pageStructure,baseTemplate)=>{let result=``;if(baseTemplate)result+=baseTemplate;let appendTemplate=(obj,r,res)=>{if(typeof obj[r]==="object"){for(const key in obj){appendTemplate(obj,key,res)}}else if(this.routes[r]?.get){let toAdd=this.routes[r].get;if(typeof toAdd==="function")toAdd=toAdd(obj[r]);if(typeof toAdd==="string"){let lastDiv=res.lastIndexOf("<");if(lastDiv>0){let end=res.substring(lastDiv);res=res.substring(0,lastDiv)+toAdd+end}res+=toAdd}}else if(typeof this.routes[r]==="function"){let routeresult=this.routes[r](obj[r]);if(typeof routeresult==="string"){let lastDiv=res.lastIndexOf("<");if(lastDiv>0){let end=res.substring(lastDiv);res=res.substring(0,lastDiv)+routeresult+end}else res+=routeresult}}else if(typeof this.routes[r]==="string")res+=this.routes[r];return res};if(Array.isArray(pageStructure)){pageStructure.forEach(r=>{result=appendTemplate(pageStructure,r,result)})}else if(typeof pageStructure==="object"){for(const r in pageStructure){result=appendTemplate(pageStructure,r,result)}}else if(typeof pageStructure==="string")result+=pageStructure;else if(typeof pageStructure==="function")result+=pageStructure();return result};this.routes={setupServer:{operator:this.setupServer,aliases:["open"]},terminate:path3=>{if(path3)for(const address in this.servers){if(address.includes(`${path3}`)){this.terminate(this.servers[address]);delete this.servers[address]}}},GET:this.get,POST:this.post,addPage:this.addPage,addHTML:this.addHTML,buildPage:this.buildPage,getRequestBody:this.getRequestBody,hotreload:(socketURL=`http://localhost:8080/wss`)=>{if(socketURL instanceof URL)socketURL=socketURL.toString();const HotReloadClient=(url=`http://localhost:8080/wss`)=>{let socket=new WebSocket(url);socket.addEventListener("close",()=>{const interAttemptTimeoutMilliseconds=100;const maxDisconnectedTimeMilliseconds=3e3;const maxAttempts=Math.round(maxDisconnectedTimeMilliseconds/interAttemptTimeoutMilliseconds);let attempts=0;const reloadIfCanConnect=()=>{attempts++;if(attempts>maxAttempts){console.error("Could not reconnect to dev server.");return}socket=new WebSocket(url);socket.onerror=er=>{console.error(`Hot reload port disconnected, will reload on reconnected. Attempt ${attempts} of ${maxAttempts}`)};socket.addEventListener("error",()=>{setTimeout(reloadIfCanConnect,interAttemptTimeoutMilliseconds)});socket.addEventListener("open",()=>{location.reload()})};reloadIfCanConnect()})};return` + - - - \ No newline at end of file diff --git a/examples/basics/proxy/index.ts b/examples/basics/proxy/index.ts deleted file mode 100644 index 6df61448..00000000 --- a/examples/basics/proxy/index.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Graph, GraphNodeProperties, Roots } from "../../../src/core/Graph"; -import { dragElement } from "./draggable"; - -//this example demonstrates using nodes as a proxy -let roots = { - - htmlNode:{ - __props:document.createElement('div'), //proxy this object - - draggable:true, - innerHTML:` -
- Drag Me! -
`, - - __onconnected:function() { - - const element = this.__props as HTMLElement; - const style = element.style as CSSStyleDeclaration; - style.position = 'absolute'; - style.height = '120px' - style.flex = 'flex'; - style.width = '120px'; - style.borderRadius = '50%'; - style.backgroundColor = 'lightblue'; - - style.cursor='move'; - - dragElement(this); //the htmlElement properties are bound to 'this' as well as 'this.__props' so you can manipulate the node directly - - document.body.appendChild(element); - }, - - __ondisconnected:function() { - const element = this.__props as HTMLElement; - document.body.removeChild(element); - } - - } as GraphNodeProperties - -} as Roots; - - -let graph = new Graph({ - roots -}); - -console.log('Graph instance:', graph); - -//now we can play with the proxy -let node = graph.get('htmlNode'); - -node.style.top = '50%'; -node.style.left = '50%'; - - - - - diff --git a/examples/basics/sync_async/index.html b/examples/basics/sync_async/index.html deleted file mode 100644 index 49564abb..00000000 --- a/examples/basics/sync_async/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/basics/sync_async/index.ts b/examples/basics/sync_async/index.ts deleted file mode 100644 index c12a4732..00000000 --- a/examples/basics/sync_async/index.ts +++ /dev/null @@ -1,49 +0,0 @@ -import {Graph, GraphNodeProperties, Roots} from '../../../src/core/Graph'; - -//graphscript lets us not need to differentiate sync and async results via listeners. -// Running operators however still does. -let roots = { - - sync:function () { - return 'sync run!'; - }, - - async:async function() { - return 'async run!' - }, - - listenerNode:{ - __listeners:{ - 'sync':function(outp) { - console.log(outp); - document.body.insertAdjacentHTML('beforeend',`
${outp}
`); - }, - 'async':function(outp) { - //the state output is automatically awaited for us so we don't - // need to think too hard - console.log(outp); - document.body.insertAdjacentHTML('beforeend',`
${outp}
`); - } - } - } - -} as Roots; - -const graph = new Graph({ - roots -}); - -function logResult (res) { console.log('subscription result:',res) } - -graph.subscribe('async', logResult); //subscription output is already evaluated for us -graph.subscribe('sync', logResult); - -console.log( - 'this is a promise:', - graph.run('async').then((res) => {console.log('this is the promise result:', res);}) -); //should show up second - -console.log( - 'this is not a promise:', - graph.run('sync') -); diff --git a/examples/editing/TODO.md b/examples/editing/TODO.md deleted file mode 100644 index b150ed97..00000000 --- a/examples/editing/TODO.md +++ /dev/null @@ -1,19 +0,0 @@ -## TODO - -PRIORITY 1. -2. Write new variables to globalThis or to specific nodes. Include parsing functions. -3. Dynamically type unknown output types? E.g. function outputs with unknown types or undefined values. -4. Instantiate/delete new nodes from prototypes or proxying classes (passing a class constructor function as a prototype or in __proxy). Incl listener cleanup. Node menu should be based on node and then available methods/values. We should include icons to indicate the type. - 4-1. Also instantiate class instances in proxy nodes or other node instances (e.g. by getting the initial values and copying it to a new name) so you can create lots of entities (e.g. html or game objects) -5. Widgets for values etc. -6. Custom widgets or UI overlay? E.g. a "+" sign underneath a pin to add and declare more pins e.g. for custom branch conditions. -7. Print out modified root. Structure strings in arrays for easy swapping then just join with newlines for writing -8. Save editor state. -9. Styling. Color code the nodes based on type (e.g. a variable or method or an operator), including the title bar and the i/o colors based on type so they're not just green and grey - -:DONE: -Cnstruct listener and __args objects from connecting nodes. -Parse input arguments names (possibly types?) for nodes representing functions - - -10. See if we can port into the babylonjs editor. \ No newline at end of file diff --git a/examples/editing/index.html b/examples/editing/index.html deleted file mode 100644 index 470cc03f..00000000 --- a/examples/editing/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/examples/editing/index.ts b/examples/editing/index.ts deleted file mode 100644 index ba88db69..00000000 --- a/examples/editing/index.ts +++ /dev/null @@ -1,250 +0,0 @@ -import {Graph, WorkerService, GraphNode, GraphNodeProperties, getAllProperties, isNativeClass, parseFunctionFromText, wchtmlloader, Router, remoteGraphRoutes} from '../../index' - -import { LiteGraph, LGraph, LGraphCanvas, LGraphNode} from './litegraph.js' -import { registerLGraphNodesFromGraph, renderLGraphFromExistingEvents } from './litegraphScripts'; -import { makeNodeEditorMenu, makeNodePropsCreator, makeProxyMenu } from './proxyMenu'; - -import './styles.css' - -import worker1 from './worker' - - -(Math as any).multiply = (a,b) => { return a*b; }; - - -let objProps = Object.getOwnPropertyNames(Object.getPrototypeOf({})); -let keys = Object.getOwnPropertyNames(globalThis); -let nonArrowFunctions = Object.getOwnPropertyNames(Object.getPrototypeOf(globalThis)).filter((v) => !objProps.includes(v)); -keys.push(...nonArrowFunctions); //this is weird but it works - -let globalThisProxy = {} as any; -let proxyable = {} as any; //class constructors we can allow for node creation - -keys.forEach((k) => { - if((typeof globalThis[k] === 'function' && !isNativeClass(globalThis[k])) || typeof globalThis[k] === 'object') - { - if(k !== 'globalThis' && k !== 'window' && k !== 'self' && k !== 'frames' && k !== 'top' && k !== 'parent') { - globalThisProxy[k] = globalThis[k]; - } - } else if(isNativeClass(globalThis[k])) { //Symbol is a no-go - let pass = false; - try{ new globalThis[k](); pass=true; } catch {} - if(pass) proxyable[k] = globalThis[k]; - } -}); - -proxyable.HTMLElement = class HTML { - constructor(tagName:string) { - return document.createElement(tagName); - } -} - -proxyable = Object.keys(proxyable).sort().reduce( - (obj, key) => { - obj[key] = proxyable[key]; - return obj; - }, - {} -); - -//this will be existing logic that we'll simply represent on the LiteGraph plugin -const roots = { - - //these will be what are made accessible on the LiteGraph - - ...globalThisProxy, - - Button:{ - __element:'button', - innerHTML: 'Click me', - onclick:function(ev){ - console.log('clicked!'); - } - }, - - NumberInput:{ - __element:'input', - value:1, - type:'number' - }, - - NumberOutput:{ - __element:'div', - innerHTML:'Press the button', - multiplier:2 - }, - - - //the __listeners are really what we're visualizing on the LiteGraph, while the node are what are available to visualize and create/set listeners for - __listeners:{ - 'NumberOutput':{ //listener block relevant to this node. If the name is a node, then arbitrary callbacks specified will be bound to that node, or use "true" for that node's operator - 'Button.onclick': { //Wire from Button.onclick method execution pin. Name is not arbitrary. - __callback:'NumberOutput.innerHTML', //Wire to NumberOutput.innerHtml setter execution - __args:[ //input to NumberOutput.innerHTML setter, default arg otherwise is the output from the thing being listened to - { //argument input - __callback:'Math.multiply', //Multiply the following argument - __args:[ //secondary inputs - { - __callback:'Math.cos', //Math.cos method - __args:['NumberInput.value'] //This value inputted - }, - { - __callback:'Math.cos', - __args:[{ - __callback:'Math.multiply', - __args:['NumberInput.value','NumberOutput.multiplier'] - }] //This value inputted - } - ] - } - ] - }, - }, - - 'console':{ - 'NumberOutput.innerHTML': { - __callback:'console.log', - } - } - } -}; - -// Instantiate GraphScript Graph -// const graph = new Graph({ -// roots, -// loaders:{ -// wchtmlloader -// } -// }); - -const graph = new Router({ - services:{ - WorkerService - }, - roots, - loaders:{ - wchtmlloader - } -}); - -const initApp = () => { - - // Create Canvas - const canvas = document.createElement('canvas'); - setTimeout(() => { - canvas.style.width = '100%'; - canvas.style.height = '100%'; - canvas.width = window.innerWidth; - canvas.height = window.innerHeight; - document.body.appendChild(canvas); - }, - 1); - - - - // Start LiteGraph - const editor = new LGraph(); - new LGraphCanvas(canvas, editor); - editor.start(); - - registerLGraphNodesFromGraph(graph, editor); - renderLGraphFromExistingEvents(graph.__node.state.triggers, editor); - - document.body.appendChild(canvas); - - let menuContainer = document.createElement('div'); - let mode = document.createElement('select'); - mode.insertAdjacentHTML('beforeend', ``); - mode.insertAdjacentHTML('beforeend', ``); - mode.insertAdjacentHTML('beforeend', ``); - let c1 = makeProxyMenu(proxyable,graph,editor); - let c2 = makeNodePropsCreator(graph,editor); - c2.style.display = 'none'; - menuContainer.appendChild(mode); - menuContainer.appendChild(c1); - menuContainer.appendChild(c2); - - let c3:HTMLElement|undefined; - - mode.onchange = () => { - if(mode.value === "0") { - if(c3) { - c3.remove(); - c3 = undefined - } - c2.style.display = "none"; - c1.style.display = ""; - } else if (mode.value === "1") { - if(c3) { - c3.remove(); - c3 = undefined - } - c1.style.display = "none"; - c2.style.display = ""; - } else if (mode.value === "2") { - c1.style.display = "none"; - c2.style.display = "none"; - if(!c3) { - c3 = makeNodeEditorMenu(graph,editor); - menuContainer.appendChild(c3); - } - } - } - - document.body.appendChild(menuContainer); - - const triggers = graph.__node.state.triggers - console.warn('Triggers', triggers) -} - -const worker = graph.run('addWorker',{url:worker1}); -console.log(worker); -worker?.run('makeRootTransferrable').then((root) => { - console.log('worker root',root); - worker.run('getListenerJSON').then(async (listeners) => { - console.log('worker listeners',listeners); - for(const key in root) { - let proxy = await remoteGraphRoutes.proxyRemoteNode(key, worker) as any; - console.log(key,proxy); - //graph.add({__props:proxy, __node:{tag:`${worker._id}.${key}`}}) - //console.log(`${worker._id}.${key}`);//graph.add({...proxy, __node:{tag:`${worker._id}.${key}`}}) - } - - initApp(); - - }); -}); - - -// const stringifyTriggers = (triggers) => { -// const entries = Object.entries(triggers).map(([key, arr]) => { -// const [unique, property] = key.split('.'); -// //@ts-ignore -// return [`${property}.${arr[0].source}`, arr.map(o => `${o.target}.${o.tkey}`)] -// }) -// return JSON.stringify(entries.reduce((acc, [key, value]) => { -// acc[key] = value -// return acc -// }, {})) -// } - -// const striggers = stringifyTriggers(triggers) -// console.warn('Stringified Triggers', striggers) - -// const stringifyRoot = (root) => { -// const entries = Object.entries(root).map(([key, node]) => { -// const [unique, property] = key.split('.') -// return [key, node] -// }) - -// return JSON.stringify(entries.reduce((acc, [key, value]) => { -// console.log(acc); -// //@ts-ignore -// acc[key] = value -// return acc -// }, {})) -// } - - -// const sroot = stringifyRoot(graph.__node.roots) -// console.warn('Stringified Roots', sroot) diff --git a/examples/editing/listenerManip.ts b/examples/editing/listenerManip.ts deleted file mode 100644 index 1bed4f5f..00000000 --- a/examples/editing/listenerManip.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { getCallbackFromString, wrapArgs } from "../../src/core/Graph"; - - -export let replaceListenerArg = ( - graph, - listener, //get this off the node - arg:string|{__input:string,__args?:any[]}, - position:{[key:number]:true|{[key:number]:true|any}} -) => { - - let foundPosition = false; - let depth = position; - let tracea = listener.arguments; // the prototype string-based structure - let traceb = listener.__args; // the wrapped functions, same structure - while(!foundPosition) { - let key = Object.keys(depth)[0]; - if(tracea[key]) { - if(typeof depth[key] === 'object' && tracea[key].__args) { - depth = depth[key] - tracea = tracea[key].__args; - traceb = traceb[key].__args; - } else if (depth[key] == true) { - tracea[key] = arg; //replace the prototype - let callback; - if(typeof arg === 'string') - callback = getCallbackFromString(arg, graph); - else if (typeof arg === 'object') { - callback = getCallbackFromString(arg.__input, graph); - if(typeof callback === 'function' && arg.__args && !arg.__args[0]?.__callback) { //unwrapped (fresh) args - let wrapped = wrapArgs(callback, arg.__args, graph); - callback = wrapped.__callback; - traceb[key].__args = wrapped.__args; - } - } - traceb[key].__callback = callback; //replace the callback - foundPosition = true; - } - } else break; - } - - return; - -} diff --git a/examples/editing/litegraph.js/LICENSE b/examples/editing/litegraph.js/LICENSE deleted file mode 100644 index 9f95642a..00000000 --- a/examples/editing/litegraph.js/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2013 by Javi Agenjo - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/examples/editing/litegraph.js/README.md b/examples/editing/litegraph.js/README.md deleted file mode 100644 index f1d21271..00000000 --- a/examples/editing/litegraph.js/README.md +++ /dev/null @@ -1,189 +0,0 @@ -# litegraph.js - -A library in Javascript to create graphs in the browser similar to Unreal Blueprints. Nodes can be programmed easily and it includes an editor to construct and tests the graphs. - -It can be integrated easily in any existing web applications and graphs can be run without the need of the editor. - -Try it in the [demo site](https://tamats.com/projects/litegraph/editor). - -![Node Graph](imgs/node_graph_example.png "WebGLStudio") - -## Features -- Renders on Canvas2D (zoom in/out and panning, easy to render complex interfaces, can be used inside a WebGLTexture) -- Easy to use editor (searchbox, keyboard shortcuts, multiple selection, context menu, ...) -- Optimized to support hundreds of nodes per graph (on editor but also on execution) -- Customizable theme (colors, shapes, background) -- Callbacks to personalize every action/drawing/event of nodes -- Subgraphs (nodes that contain graphs themselves) -- Live mode system (hides the graph but calls nodes to render whatever they want, useful to create UIs) -- Graphs can be executed in NodeJS -- Highly customizable nodes (color, shape, slots vertical or horizontal, widgets, custom rendering) -- Easy to integrate in any JS application (one single file, no dependencies) -- Typescript support - -## Nodes provided -Although it is easy to create new node types, LiteGraph comes with some default nodes that could be useful for many cases: -- Interface (Widgets) -- Math (trigonometry, math operations) -- Audio (AudioAPI and MIDI) -- 3D Graphics (Postprocessing in WebGL) -- Input (read Gamepad) - -## Installation - -You can install it using npm -``` -npm install litegraph.js -``` - -Or downloading the ```build/litegraph.js``` and ```css/litegraph.css``` version from this repository. - -## First project ## - -```html - - - - - - - - - - -``` - -## How to code a new Node type - -Here is an example of how to build a node that sums two inputs: - -```javascript -//node constructor class -function MyAddNode() -{ - this.addInput("A","number"); - this.addInput("B","number"); - this.addOutput("A+B","number"); - this.properties = { precision: 1 }; -} - -//name to show -MyAddNode.title = "Sum"; - -//function to call when the node is executed -MyAddNode.prototype.onExecute = function() -{ - var A = this.getInputData(0); - if( A === undefined ) - A = 0; - var B = this.getInputData(1); - if( B === undefined ) - B = 0; - this.setOutputData( 0, A + B ); -} - -//register in the system -LiteGraph.registerNodeType("basic/sum", MyAddNode ); - -``` - -or you can wrap an existing function: - -```js -function sum(a,b) -{ - return a+b; -} - -LiteGraph.wrapFunctionAsNode("math/sum",sum, ["Number","Number"],"Number"); -``` - -## Server side - -It also works server-side using NodeJS although some nodes do not work in server (audio, graphics, input, etc). - -```js -var LiteGraph = require("./litegraph.js").LiteGraph; - -var graph = new LiteGraph.LGraph(); - -var node_time = LiteGraph.createNode("basic/time"); -graph.add(node_time); - -var node_console = LiteGraph.createNode("basic/console"); -node_console.mode = LiteGraph.ALWAYS; -graph.add(node_console); - -node_time.connect( 0, node_console, 1 ); - -graph.start() -``` - - -## Projects using it - -### [webglstudio.org](http://webglstudio.org) - -![WebGLStudio](imgs/webglstudio.gif "WebGLStudio") - -### [MOI Elephant](http://moiscript.weebly.com/elephant-systegraveme-nodal.html) - -![MOI Elephant](imgs/elephant.gif "MOI Elephant") - -### Mynodes - -![MyNodes](imgs/mynodes.png "MyNodes") - -## Utils ------ - -It includes several commands in the utils folder to generate doc, check errors and build minifyed version. - - -## Demo ------ -The demo includes some examples of graphs. In order to try them you can visit [demo site](http://tamats.com/projects/litegraph/editor) or install it on your local computer, to do so you need `git`, `node` and `npm`. Given those dependencies are installed, run the following commands to try it out: -```sh -$ git clone https://github.com/jagenjo/litegraph.js.git -$ cd litegraph.js -$ npm install -$ node utils/server.js -Example app listening on port 80! -``` -Open your browser and point it to http://localhost:8000/. You can select a demo from the dropdown at the top of the page. - -## Feedback --------- - -You can write any feedback to javi.agenjo@gmail.com - -## Contributors - -- atlasan -- kriffe -- rappestad -- InventivetalentDev -- NateScarlet -- coderofsalvation -- ilyabesk -- gausszhou - - - diff --git a/examples/editing/litegraph.js/build/litegraph.core.js b/examples/editing/litegraph.js/build/litegraph.core.js deleted file mode 100644 index 7a63b128..00000000 --- a/examples/editing/litegraph.js/build/litegraph.core.js +++ /dev/null @@ -1,14328 +0,0 @@ -//packer version - - -(function(global) { - // ************************************************************* - // LiteGraph CLASS ******* - // ************************************************************* - - //MODDED - const execPin = '►'; - - /** - * The Global Scope. It contains all the registered node classes. - * - * @class LiteGraph - * @constructor - */ - - var LiteGraph = (global.LiteGraph = { - VERSION: 0.4, - - CANVAS_GRID_SIZE: 10, - - NODE_TITLE_HEIGHT: 30, - NODE_TITLE_TEXT_Y: 20, - NODE_SLOT_HEIGHT: 20, - NODE_WIDGET_HEIGHT: 20, - NODE_WIDTH: 140, - NODE_MIN_WIDTH: 50, - NODE_COLLAPSED_RADIUS: 10, - NODE_COLLAPSED_WIDTH: 80, - NODE_TITLE_COLOR: "#999", - NODE_SELECTED_TITLE_COLOR: "#FFF", - NODE_TEXT_SIZE: 14, - NODE_TEXT_COLOR: "#AAA", - NODE_SUBTEXT_SIZE: 12, - NODE_DEFAULT_COLOR: "#333", - NODE_DEFAULT_BGCOLOR: "#353535", - NODE_DEFAULT_BOXCOLOR: "#666", - NODE_DEFAULT_SHAPE: "box", - NODE_BOX_OUTLINE_COLOR: "#FFF", - DEFAULT_SHADOW_COLOR: "rgba(0,0,0,0.5)", - DEFAULT_GROUP_FONT: 24, - - WIDGET_BGCOLOR: "#222", - WIDGET_OUTLINE_COLOR: "#666", - WIDGET_TEXT_COLOR: "#DDD", - WIDGET_SECONDARY_TEXT_COLOR: "#999", - - LINK_COLOR: "#9A9", - EVENT_LINK_COLOR: "#A86", - CONNECTING_LINK_COLOR: "#AFA", - - MAX_NUMBER_OF_NODES: 1000, //avoid infinite loops - DEFAULT_POSITION: [100, 100], //default node position - VALID_SHAPES: ["default", "box", "round", "card"], //,"circle" - - //shapes are used for nodes but also for slots - BOX_SHAPE: 1, - ROUND_SHAPE: 2, - CIRCLE_SHAPE: 3, - CARD_SHAPE: 4, - ARROW_SHAPE: 5, - GRID_SHAPE: 6, // intended for slot arrays - - //enums - INPUT: 1, - OUTPUT: 2, - - EVENT: -1, //for outputs - ACTION: -1, //for inputs - - NODE_MODES: ["Always", "On Event", "Never", "On Trigger"], // helper, will add "On Request" and more in the future - NODE_MODES_COLORS:["#666","#422","#333","#224","#626"], // use with node_box_coloured_by_mode - ALWAYS: 0, - ON_EVENT: 1, - NEVER: 2, - ON_TRIGGER: 3, - - UP: 1, - DOWN: 2, - LEFT: 3, - RIGHT: 4, - CENTER: 5, - - LINK_RENDER_MODES: ["Straight", "Linear", "Spline"], // helper - STRAIGHT_LINK: 0, - LINEAR_LINK: 1, - SPLINE_LINK: 2, - - NORMAL_TITLE: 0, - NO_TITLE: 1, - TRANSPARENT_TITLE: 2, - AUTOHIDE_TITLE: 3, - VERTICAL_LAYOUT: "vertical", // arrange nodes vertically - - proxy: null, //used to redirect calls - node_images_path: "", - - debug: false, - catch_exceptions: true, - throw_errors: true, - allow_scripts: false, //if set to true some nodes like Formula would be allowed to evaluate code that comes from unsafe sources (like node configuration), which could lead to exploits - registered_node_types: {}, //nodetypes by string - node_types_by_file_extension: {}, //used for dropping files in the canvas - Nodes: {}, //node types by classname - Globals: {}, //used to store vars between graphs - - searchbox_extras: {}, //used to add extra features to the search box - auto_sort_node_types: false, // [true!] If set to true, will automatically sort node types / categories in the context menus - - node_box_coloured_when_on: false, // [true!] this make the nodes box (top left circle) coloured when triggered (execute/action), visual feedback - node_box_coloured_by_mode: false, // [true!] nodebox based on node mode, visual feedback - - dialog_close_on_mouse_leave: true, // [false on mobile] better true if not touch device, TODO add an helper/listener to close if false - dialog_close_on_mouse_leave_delay: 500, - - shift_click_do_break_link_from: false, // [false!] prefer false if results too easy to break links - implement with ALT or TODO custom keys - click_do_break_link_to: false, // [false!]prefer false, way too easy to break links - - search_hide_on_mouse_leave: true, // [false on mobile] better true if not touch device, TODO add an helper/listener to close if false - search_filter_enabled: false, // [true!] enable filtering slots type in the search widget, !requires auto_load_slot_types or manual set registered_slot_[in/out]_types and slot_types_[in/out] - search_show_all_on_open: true, // [true!] opens the results list when opening the search widget - - auto_load_slot_types: false, // [if want false, use true, run, get vars values to be statically set, than disable] nodes types and nodeclass association with node types need to be calculated, if dont want this, calculate once and set registered_slot_[in/out]_types and slot_types_[in/out] - - // set these values if not using auto_load_slot_types - registered_slot_in_types: {}, // slot types for nodeclass - registered_slot_out_types: {}, // slot types for nodeclass - slot_types_in: [], // slot types IN - slot_types_out: [], // slot types OUT - slot_types_default_in: [], // specify for each IN slot type a(/many) default node(s), use single string, array, or object (with node, title, parameters, ..) like for search - slot_types_default_out: [], // specify for each OUT slot type a(/many) default node(s), use single string, array, or object (with node, title, parameters, ..) like for search - - alt_drag_do_clone_nodes: false, // [true!] very handy, ALT click to clone and drag the new node - - do_add_triggers_slots: false, // [true!] will create and connect event slots when using action/events connections, !WILL CHANGE node mode when using onTrigger (enable mode colors), onExecuted does not need this - - allow_multi_output_for_events: true, // [false!] being events, it is strongly reccomended to use them sequentially, one by one - - middle_click_slot_add_default_node: false, //[true!] allows to create and connect a ndoe clicking with the third button (wheel) - - release_link_on_empty_shows_menu: false, //[true!] dragging a link to empty space will open a menu, add from list, search or defaults - - pointerevents_method: "mouse", // "mouse"|"pointer" use mouse for retrocompatibility issues? (none found @ now) - // TODO implement pointercancel, gotpointercapture, lostpointercapture, (pointerover, pointerout if necessary) - - ctrl_shift_v_paste_connect_unselected_outputs: false, //[true!] allows ctrl + shift + v to paste nodes with the outputs of the unselected nodes connected with the inputs of the newly pasted nodes - - /** - * Register a node class so it can be listed when the user wants to create a new one - * @method registerNodeType - * @param {String} type name of the node and path - * @param {Class} base_class class containing the structure of a node - */ - - registerNodeType: function(type, base_class) { - if (!base_class.prototype) { - throw "Cannot register a simple object, it must be a class with a prototype"; - } - base_class.type = type; - - if (LiteGraph.debug) { - console.log("Node registered: " + type); - } - - const classname = base_class.name; - - const pos = type.lastIndexOf("/"); - base_class.category = type.substring(0, pos); - - if (!base_class.title) { - base_class.title = classname; - } - - //extend class - for (var i in LGraphNode.prototype) { - if (!base_class.prototype[i]) { - base_class.prototype[i] = LGraphNode.prototype[i]; - } - } - - const prev = this.registered_node_types[type]; - if(prev) { - console.log("replacing node type: " + type); - } - if( !Object.prototype.hasOwnProperty.call( base_class.prototype, "shape") ) { - Object.defineProperty(base_class.prototype, "shape", { - set: function(v) { - switch (v) { - case "default": - delete this._shape; - break; - case "box": - this._shape = LiteGraph.BOX_SHAPE; - break; - case "round": - this._shape = LiteGraph.ROUND_SHAPE; - break; - case "circle": - this._shape = LiteGraph.CIRCLE_SHAPE; - break; - case "card": - this._shape = LiteGraph.CARD_SHAPE; - break; - default: - this._shape = v; - } - }, - get: function() { - return this._shape; - }, - enumerable: true, - configurable: true - }); - - - //used to know which nodes to create when dragging files to the canvas - if (base_class.supported_extensions) { - for (let i in base_class.supported_extensions) { - const ext = base_class.supported_extensions[i]; - if(ext && ext.constructor === String) { - this.node_types_by_file_extension[ ext.toLowerCase() ] = base_class; - } - } - } - } - - this.registered_node_types[type] = base_class; - if (base_class.constructor.name) { - this.Nodes[classname] = base_class; - } - if (LiteGraph.onNodeTypeRegistered) { - LiteGraph.onNodeTypeRegistered(type, base_class); - } - if (prev && LiteGraph.onNodeTypeReplaced) { - LiteGraph.onNodeTypeReplaced(type, base_class, prev); - } - - //warnings - if (base_class.prototype.onPropertyChange) { - console.warn( - "LiteGraph node class " + - type + - " has onPropertyChange method, it must be called onPropertyChanged with d at the end" - ); - } - - // TODO one would want to know input and ouput :: this would allow through registerNodeAndSlotType to get all the slots types - if (this.auto_load_slot_types) { - new base_class(base_class.title || "tmpnode"); - } - }, - - /** - * removes a node type from the system - * @method unregisterNodeType - * @param {String|Object} type name of the node or the node constructor itself - */ - unregisterNodeType: function(type) { - const base_class = - type.constructor === String - ? this.registered_node_types[type] - : type; - if (!base_class) { - throw "node type not found: " + type; - } - delete this.registered_node_types[base_class.type]; - if (base_class.constructor.name) { - delete this.Nodes[base_class.constructor.name]; - } - }, - - /** - * Save a slot type and his node - * @method registerSlotType - * @param {String|Object} type name of the node or the node constructor itself - * @param {String} slot_type name of the slot type (variable type), eg. string, number, array, boolean, .. - */ - registerNodeAndSlotType: function(type, slot_type, out){ - out = out || false; - const base_class = - type.constructor === String && - this.registered_node_types[type] !== "anonymous" - ? this.registered_node_types[type] - : type; - - const class_type = base_class.constructor.type; - - let allTypes = []; - if (typeof slot_type === "string") { - allTypes = slot_type.split(","); - } else if (slot_type == this.EVENT || slot_type == this.ACTION) { - allTypes = ["_event_"]; - } else { - allTypes = ["*"]; - } - - for (let i = 0; i < allTypes.length; ++i) { - let slotType = allTypes[i]; - if (slotType === "") { - slotType = "*"; - } - const registerTo = out - ? "registered_slot_out_types" - : "registered_slot_in_types"; - if (this[registerTo][slotType] === undefined) { - this[registerTo][slotType] = { nodes: [] }; - } - if (!this[registerTo][slotType].nodes.includes(class_type)) { - this[registerTo][slotType].nodes.push(class_type); - } - - // check if is a new type - if (!out) { - if (!this.slot_types_in.includes(slotType.toLowerCase())) { - this.slot_types_in.push(slotType.toLowerCase()); - this.slot_types_in.sort(); - } - } else { - if (!this.slot_types_out.includes(slotType.toLowerCase())) { - this.slot_types_out.push(slotType.toLowerCase()); - this.slot_types_out.sort(); - } - } - } - }, - - /** - * Create a new nodetype by passing a function, it wraps it with a proper class and generates inputs according to the parameters of the function. - * Useful to wrap simple methods that do not require properties, and that only process some input to generate an output. - * @method wrapFunctionAsNode - * @param {String} name node name with namespace (p.e.: 'math/sum') - * @param {Function} func - * @param {Array} param_types [optional] an array containing the type of every parameter, otherwise parameters will accept any type - * @param {String} return_type [optional] string with the return type, otherwise it will be generic - * @param {Object} properties [optional] properties to be configurable - */ - wrapFunctionAsNode: function( - name, - func, - param_types, - return_type, - properties - ) { - var params = Array(func.length); - var code = ""; - var names = LiteGraph.getParameterNames(func); - for (var i = 0; i < names.length; ++i) { - code += - "this.addInput('" + - names[i] + - "'," + - (param_types && param_types[i] - ? "'" + param_types[i] + "'" - : "0") + - ");\n"; - } - code += - "this.addOutput('out'," + - (return_type ? "'" + return_type + "'" : 0) + - ");\n"; - if (properties) { - code += - "this.properties = " + JSON.stringify(properties) + ";\n"; - } - var classobj = Function(code); - classobj.title = name.split("/").pop(); - classobj.desc = "Generated from " + func.name; - classobj.prototype.onExecute = function onExecute() { - for (var i = 0; i < params.length; ++i) { - params[i] = this.getInputData(i); - } - var r = func.apply(this, params); - this.setOutputData(0, r); - }; - this.registerNodeType(name, classobj); - }, - - /** - * Removes all previously registered node's types - */ - clearRegisteredTypes: function() { - this.registered_node_types = {}; - this.node_types_by_file_extension = {}; - this.Nodes = {}; - this.searchbox_extras = {}; - }, - - /** - * 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) - * @method addNodeMethod - * @param {Function} func - */ - addNodeMethod: function(name, func) { - LGraphNode.prototype[name] = func; - for (var i in this.registered_node_types) { - var type = this.registered_node_types[i]; - if (type.prototype[name]) { - type.prototype["_" + name] = type.prototype[name]; - } //keep old in case of replacing - type.prototype[name] = func; - } - }, - - /** - * Create a node of a given type with a name. The node is not attached to any graph yet. - * @method createNode - * @param {String} type full name of the node class. p.e. "math/sin" - * @param {String} name a name to distinguish from other nodes - * @param {Object} options to set options - */ - - createNode: function(type, title, options) { - var base_class = this.registered_node_types[type]; - if (!base_class) { - if (LiteGraph.debug) { - console.log( - 'GraphNode type "' + type + '" not registered.' - ); - } - return null; - } - - var prototype = base_class.prototype || base_class; - - title = title || base_class.title || type; - - var node = null; - - if (LiteGraph.catch_exceptions) { - try { - node = new base_class(title); - } catch (err) { - console.error(err); - return null; - } - } else { - node = new base_class(title); - } - - node.type = type; - - if (!node.title && title) { - node.title = title; - } - if (!node.properties) { - node.properties = {}; - } - if (!node.properties_info) { - node.properties_info = []; - } - if (!node.flags) { - node.flags = {}; - } - if (!node.size) { - node.size = node.computeSize(); - //call onresize? - } - if (!node.pos) { - node.pos = LiteGraph.DEFAULT_POSITION.concat(); - } - if (!node.mode) { - node.mode = LiteGraph.ALWAYS; - } - - //extra options - if (options) { - for (var i in options) { - node[i] = options[i]; - } - } - - // callback - if ( node.onNodeCreated ) { - node.onNodeCreated(); - } - - return node; - }, - - /** - * Returns a registered node type with a given name - * @method getNodeType - * @param {String} type full name of the node class. p.e. "math/sin" - * @return {Class} the node class - */ - getNodeType: function(type) { - return this.registered_node_types[type]; - }, - - /** - * Returns a list of node types matching one category - * @method getNodeType - * @param {String} category category name - * @return {Array} array with all the node classes - */ - - getNodeTypesInCategory: function(category, filter) { - var r = []; - for (var i in this.registered_node_types) { - var type = this.registered_node_types[i]; - if (type.filter != filter) { - continue; - } - - if (category == "") { - if (type.category == null) { - r.push(type); - } - } else if (type.category == category) { - r.push(type); - } - } - - if (this.auto_sort_node_types) { - r.sort(function(a,b){return a.title.localeCompare(b.title)}); - } - - return r; - }, - - /** - * Returns a list with all the node type categories - * @method getNodeTypesCategories - * @param {String} filter only nodes with ctor.filter equal can be shown - * @return {Array} array with all the names of the categories - */ - getNodeTypesCategories: function( filter ) { - var categories = { "": 1 }; - for (var i in this.registered_node_types) { - var type = this.registered_node_types[i]; - if ( type.category && !type.skip_list ) - { - if(type.filter != filter) - continue; - categories[type.category] = 1; - } - } - var result = []; - for (var i in categories) { - result.push(i); - } - return this.auto_sort_node_types ? result.sort() : result; - }, - - //debug purposes: reloads all the js scripts that matches a wildcard - reloadNodes: function(folder_wildcard) { - var tmp = document.getElementsByTagName("script"); - //weird, this array changes by its own, so we use a copy - var script_files = []; - for (var i=0; i < tmp.length; i++) { - script_files.push(tmp[i]); - } - - var docHeadObj = document.getElementsByTagName("head")[0]; - folder_wildcard = document.location.href + folder_wildcard; - - for (var i=0; i < script_files.length; i++) { - var src = script_files[i].src; - if ( - !src || - src.substr(0, folder_wildcard.length) != folder_wildcard - ) { - continue; - } - - try { - if (LiteGraph.debug) { - console.log("Reloading: " + src); - } - var dynamicScript = document.createElement("script"); - dynamicScript.type = "text/javascript"; - dynamicScript.src = src; - docHeadObj.appendChild(dynamicScript); - docHeadObj.removeChild(script_files[i]); - } catch (err) { - if (LiteGraph.throw_errors) { - throw err; - } - if (LiteGraph.debug) { - console.log("Error while reloading " + src); - } - } - } - - if (LiteGraph.debug) { - console.log("Nodes reloaded"); - } - }, - - //separated just to improve if it doesn't work - cloneObject: function(obj, target) { - if (obj == null) { - return null; - } - var r = JSON.parse(JSON.stringify(obj)); - if (!target) { - return r; - } - - for (var i in r) { - target[i] = r[i]; - } - return target; - }, - - /** - * Returns if the types of two slots are compatible (taking into account wildcards, etc) - * @method isValidConnection - * @param {String} type_a - * @param {String} type_b - * @return {Boolean} true if they can be connected - */ - isValidConnection: function(type_a, type_b) { - if (type_a=="" || type_a==="*") type_a = 0; - if (type_b=="" || type_b==="*") type_b = 0; - if ( - !type_a //generic output - || !type_b // generic input - || type_a == type_b //same type (is valid for triggers) - || (type_a == LiteGraph.EVENT && type_b == LiteGraph.ACTION) - ) { - return true; - } - - // Enforce string type to handle toLowerCase call (-1 number not ok) - type_a = String(type_a); - type_b = String(type_b); - type_a = type_a.toLowerCase(); - type_b = type_b.toLowerCase(); - - // For nodes supporting multiple connection types - if (type_a.indexOf(",") == -1 && type_b.indexOf(",") == -1) { - return type_a == type_b; - } - - // Check all permutations to see if one is valid - var supported_types_a = type_a.split(","); - var supported_types_b = type_b.split(","); - for (var i = 0; i < supported_types_a.length; ++i) { - for (var j = 0; j < supported_types_b.length; ++j) { - if(this.isValidConnection(supported_types_a[i],supported_types_b[j])){ - //if (supported_types_a[i] == supported_types_b[j]) { - return true; - } - } - } - - return false; - }, - - /** - * Register a string in the search box so when the user types it it will recommend this node - * @method registerSearchboxExtra - * @param {String} node_type the node recommended - * @param {String} description text to show next to it - * @param {Object} data it could contain info of how the node should be configured - * @return {Boolean} true if they can be connected - */ - registerSearchboxExtra: function(node_type, description, data) { - this.searchbox_extras[description.toLowerCase()] = { - type: node_type, - desc: description, - data: data - }; - }, - - /** - * Wrapper to load files (from url using fetch or from file using FileReader) - * @method fetchFile - * @param {String|File|Blob} url the url of the file (or the file itself) - * @param {String} type an string to know how to fetch it: "text","arraybuffer","json","blob" - * @param {Function} on_complete callback(data) - * @param {Function} on_error in case of an error - * @return {FileReader|Promise} returns the object used to - */ - fetchFile: function( url, type, on_complete, on_error ) { - var that = this; - if(!url) - return null; - - type = type || "text"; - if( url.constructor === String ) - { - if (url.substr(0, 4) == "http" && LiteGraph.proxy) { - url = LiteGraph.proxy + url.substr(url.indexOf(":") + 3); - } - return fetch(url) - .then(function(response) { - if(!response.ok) - throw new Error("File not found"); //it will be catch below - if(type == "arraybuffer") - return response.arrayBuffer(); - else if(type == "text" || type == "string") - return response.text(); - else if(type == "json") - return response.json(); - else if(type == "blob") - return response.blob(); - }) - .then(function(data) { - if(on_complete) - on_complete(data); - }) - .catch(function(error) { - console.error("error fetching file:",url); - if(on_error) - on_error(error); - }); - } - else if( url.constructor === File || url.constructor === Blob) - { - var reader = new FileReader(); - reader.onload = function(e) - { - var v = e.target.result; - if( type == "json" ) - v = JSON.parse(v); - if(on_complete) - on_complete(v); - } - if(type == "arraybuffer") - return reader.readAsArrayBuffer(url); - else if(type == "text" || type == "json") - return reader.readAsText(url); - else if(type == "blob") - return reader.readAsBinaryString(url); - } - return null; - } - }); - - //timer that works everywhere - if (typeof performance != "undefined") { - LiteGraph.getTime = performance.now.bind(performance); - } else if (typeof Date != "undefined" && Date.now) { - LiteGraph.getTime = Date.now.bind(Date); - } else if (typeof process != "undefined") { - LiteGraph.getTime = function() { - var t = process.hrtime(); - return t[0] * 0.001 + t[1] * 1e-6; - }; - } else { - LiteGraph.getTime = function getTime() { - return new Date().getTime(); - }; - } - - //********************************************************************************* - // LGraph CLASS - //********************************************************************************* - - /** - * 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. - * supported callbacks: - + onNodeAdded: when a new node is added to the graph - + onNodeRemoved: when a node inside this graph is removed - + onNodeConnectionChange: some connection has changed in the graph (connected or disconnected) - * - * @class LGraph - * @constructor - * @param {Object} o data from previous serialization [optional] - */ - - function LGraph(o) { - if (LiteGraph.debug) { - console.log("Graph created"); - } - this.list_of_graphcanvas = null; - this.clear(); - - if (o) { - this.configure(o); - } - } - - global.LGraph = LiteGraph.LGraph = LGraph; - - //default supported types - LGraph.supported_types = ["number", "string", "boolean"]; - - //used to know which types of connections support this graph (some graphs do not allow certain types) - LGraph.prototype.getSupportedTypes = function() { - return this.supported_types || LGraph.supported_types; - }; - - LGraph.STATUS_STOPPED = 1; - LGraph.STATUS_RUNNING = 2; - - /** - * Removes all nodes from this graph - * @method clear - */ - - LGraph.prototype.clear = function() { - this.stop(); - this.status = LGraph.STATUS_STOPPED; - - this.last_node_id = 0; - this.last_link_id = 0; - - this._version = -1; //used to detect changes - - //safe clear - if (this._nodes) { - for (var i = 0; i < this._nodes.length; ++i) { - var node = this._nodes[i]; - if (node.onRemoved) { - node.onRemoved(); - } - } - } - - //nodes - this._nodes = []; - this._nodes_by_id = {}; - this._nodes_in_order = []; //nodes sorted in execution order - this._nodes_executable = null; //nodes that contain onExecute sorted in execution order - - //other scene stuff - this._groups = []; - - //links - this.links = {}; //container with all the links - - //iterations - this.iteration = 0; - - //custom data - this.config = {}; - this.vars = {}; - this.extra = {}; //to store custom data - - //timing - this.globaltime = 0; - this.runningtime = 0; - this.fixedtime = 0; - this.fixedtime_lapse = 0.01; - this.elapsed_time = 0.01; - this.last_update_time = 0; - this.starttime = 0; - - this.catch_errors = true; - - this.nodes_executing = []; - this.nodes_actioning = []; - this.nodes_executedAction = []; - - //subgraph_data - this.inputs = {}; - this.outputs = {}; - - //notify canvas to redraw - this.change(); - - this.sendActionToCanvas("clear"); - }; - - /** - * Attach Canvas to this graph - * @method attachCanvas - * @param {GraphCanvas} graph_canvas - */ - - LGraph.prototype.attachCanvas = function(graphcanvas) { - if (graphcanvas.constructor != LGraphCanvas) { - throw "attachCanvas expects a LGraphCanvas instance"; - } - if (graphcanvas.graph && graphcanvas.graph != this) { - graphcanvas.graph.detachCanvas(graphcanvas); - } - - graphcanvas.graph = this; - - if (!this.list_of_graphcanvas) { - this.list_of_graphcanvas = []; - } - this.list_of_graphcanvas.push(graphcanvas); - }; - - /** - * Detach Canvas from this graph - * @method detachCanvas - * @param {GraphCanvas} graph_canvas - */ - LGraph.prototype.detachCanvas = function(graphcanvas) { - if (!this.list_of_graphcanvas) { - return; - } - - var pos = this.list_of_graphcanvas.indexOf(graphcanvas); - if (pos == -1) { - return; - } - graphcanvas.graph = null; - this.list_of_graphcanvas.splice(pos, 1); - }; - - /** - * Starts running this graph every interval milliseconds. - * @method start - * @param {number} interval amount of milliseconds between executions, if 0 then it renders to the monitor refresh rate - */ - - LGraph.prototype.start = function(interval) { - if (this.status == LGraph.STATUS_RUNNING) { - return; - } - this.status = LGraph.STATUS_RUNNING; - - if (this.onPlayEvent) { - this.onPlayEvent(); - } - - this.sendEventToAllNodes("onStart"); - - //launch - this.starttime = LiteGraph.getTime(); - this.last_update_time = this.starttime; - interval = interval || 0; - var that = this; - - //execute once per frame - if ( interval == 0 && typeof window != "undefined" && window.requestAnimationFrame ) { - function on_frame() { - if (that.execution_timer_id != -1) { - return; - } - window.requestAnimationFrame(on_frame); - if(that.onBeforeStep) - that.onBeforeStep(); - that.runStep(1, !that.catch_errors); - if(that.onAfterStep) - that.onAfterStep(); - } - this.execution_timer_id = -1; - on_frame(); - } else { //execute every 'interval' ms - this.execution_timer_id = setInterval(function() { - //execute - if(that.onBeforeStep) - that.onBeforeStep(); - that.runStep(1, !that.catch_errors); - if(that.onAfterStep) - that.onAfterStep(); - }, interval); - } - }; - - /** - * Stops the execution loop of the graph - * @method stop execution - */ - - LGraph.prototype.stop = function() { - if (this.status == LGraph.STATUS_STOPPED) { - return; - } - - this.status = LGraph.STATUS_STOPPED; - - if (this.onStopEvent) { - this.onStopEvent(); - } - - if (this.execution_timer_id != null) { - if (this.execution_timer_id != -1) { - clearInterval(this.execution_timer_id); - } - this.execution_timer_id = null; - } - - this.sendEventToAllNodes("onStop"); - }; - - /** - * Run N steps (cycles) of the graph - * @method runStep - * @param {number} num number of steps to run, default is 1 - * @param {Boolean} do_not_catch_errors [optional] if you want to try/catch errors - * @param {number} limit max number of nodes to execute (used to execute from start to a node) - */ - - LGraph.prototype.runStep = function(num, do_not_catch_errors, limit ) { - num = num || 1; - - var start = LiteGraph.getTime(); - this.globaltime = 0.001 * (start - this.starttime); - - var nodes = this._nodes_executable - ? this._nodes_executable - : this._nodes; - if (!nodes) { - return; - } - - limit = limit || nodes.length; - - if (do_not_catch_errors) { - //iterations - for (var i = 0; i < num; i++) { - for (var j = 0; j < limit; ++j) { - var node = nodes[j]; - if (node.mode == LiteGraph.ALWAYS && node.onExecute) { - //wrap node.onExecute(); - node.doExecute(); - } - } - - this.fixedtime += this.fixedtime_lapse; - if (this.onExecuteStep) { - this.onExecuteStep(); - } - } - - if (this.onAfterExecute) { - this.onAfterExecute(); - } - } else { - try { - //iterations - for (var i = 0; i < num; i++) { - for (var j = 0; j < limit; ++j) { - var node = nodes[j]; - if (node.mode == LiteGraph.ALWAYS && node.onExecute) { - node.onExecute(); - } - } - - this.fixedtime += this.fixedtime_lapse; - if (this.onExecuteStep) { - this.onExecuteStep(); - } - } - - if (this.onAfterExecute) { - this.onAfterExecute(); - } - this.errors_in_execution = false; - } catch (err) { - this.errors_in_execution = true; - if (LiteGraph.throw_errors) { - throw err; - } - if (LiteGraph.debug) { - console.log("Error during execution: " + err); - } - this.stop(); - } - } - - var now = LiteGraph.getTime(); - var elapsed = now - start; - if (elapsed == 0) { - elapsed = 1; - } - this.execution_time = 0.001 * elapsed; - this.globaltime += 0.001 * elapsed; - this.iteration += 1; - this.elapsed_time = (now - this.last_update_time) * 0.001; - this.last_update_time = now; - this.nodes_executing = []; - this.nodes_actioning = []; - this.nodes_executedAction = []; - }; - - /** - * Updates the graph execution order according to relevance of the nodes (nodes with only outputs have more relevance than - * nodes with only inputs. - * @method updateExecutionOrder - */ - LGraph.prototype.updateExecutionOrder = function() { - this._nodes_in_order = this.computeExecutionOrder(false); - this._nodes_executable = []; - for (var i = 0; i < this._nodes_in_order.length; ++i) { - if (this._nodes_in_order[i].onExecute) { - this._nodes_executable.push(this._nodes_in_order[i]); - } - } - }; - - //This is more internal, it computes the executable nodes in order and returns it - LGraph.prototype.computeExecutionOrder = function( - only_onExecute, - set_level - ) { - var L = []; - var S = []; - var M = {}; - var visited_links = {}; //to avoid repeating links - var remaining_links = {}; //to a - - //search for the nodes without inputs (starting nodes) - for (var i = 0, l = this._nodes.length; i < l; ++i) { - var node = this._nodes[i]; - if (only_onExecute && !node.onExecute) { - continue; - } - - M[node.id] = node; //add to pending nodes - - var num = 0; //num of input connections - if (node.inputs) { - for (var j = 0, l2 = node.inputs.length; j < l2; j++) { - if (node.inputs[j] && node.inputs[j].link != null) { - num += 1; - } - } - } - - if (num == 0) { - //is a starting node - S.push(node); - if (set_level) { - node._level = 1; - } - } //num of input links - else { - if (set_level) { - node._level = 0; - } - remaining_links[node.id] = num; - } - } - - while (true) { - if (S.length == 0) { - break; - } - - //get an starting node - var node = S.shift(); - L.push(node); //add to ordered list - delete M[node.id]; //remove from the pending nodes - - if (!node.outputs) { - continue; - } - - //for every output - for (var i = 0; i < node.outputs.length; i++) { - var output = node.outputs[i]; - //not connected - if ( - output == null || - output.links == null || - output.links.length == 0 - ) { - continue; - } - - //for every connection - for (var j = 0; j < output.links.length; j++) { - var link_id = output.links[j]; - var link = this.links[link_id]; - if (!link) { - continue; - } - - //already visited link (ignore it) - if (visited_links[link.id]) { - continue; - } - - var target_node = this.getNodeById(link.target_id); - if (target_node == null) { - visited_links[link.id] = true; - continue; - } - - if ( - set_level && - (!target_node._level || - target_node._level <= node._level) - ) { - target_node._level = node._level + 1; - } - - visited_links[link.id] = true; //mark as visited - remaining_links[target_node.id] -= 1; //reduce the number of links remaining - if (remaining_links[target_node.id] == 0) { - S.push(target_node); - } //if no more links, then add to starters array - } - } - } - - //the remaining ones (loops) - for (var i in M) { - L.push(M[i]); - } - - if (L.length != this._nodes.length && LiteGraph.debug) { - console.warn("something went wrong, nodes missing"); - } - - var l = L.length; - - //save order number in the node - for (var i = 0; i < l; ++i) { - L[i].order = i; - } - - //sort now by priority - L = L.sort(function(A, B) { - var Ap = A.constructor.priority || A.priority || 0; - var Bp = B.constructor.priority || B.priority || 0; - if (Ap == Bp) { - //if same priority, sort by order - return A.order - B.order; - } - return Ap - Bp; //sort by priority - }); - - //save order number in the node, again... - for (var i = 0; i < l; ++i) { - L[i].order = i; - } - - return L; - }; - - /** - * Returns all the nodes that could affect this one (ancestors) by crawling all the inputs recursively. - * It doesn't include the node itself - * @method getAncestors - * @return {Array} an array with all the LGraphNodes that affect this node, in order of execution - */ - LGraph.prototype.getAncestors = function(node) { - var ancestors = []; - var pending = [node]; - var visited = {}; - - while (pending.length) { - var current = pending.shift(); - if (!current.inputs) { - continue; - } - if (!visited[current.id] && current != node) { - visited[current.id] = true; - ancestors.push(current); - } - - for (var i = 0; i < current.inputs.length; ++i) { - var input = current.getInputNode(i); - if (input && ancestors.indexOf(input) == -1) { - pending.push(input); - } - } - } - - ancestors.sort(function(a, b) { - return a.order - b.order; - }); - return ancestors; - }; - - /** - * Positions every node in a more readable manner - * @method arrange - */ - LGraph.prototype.arrange = function (margin, layout) { - margin = margin || 100; - - const nodes = this.computeExecutionOrder(false, true); - const columns = []; - for (let i = 0; i < nodes.length; ++i) { - const node = nodes[i]; - const col = node._level || 1; - if (!columns[col]) { - columns[col] = []; - } - columns[col].push(node); - } - - let x = margin; - - for (let i = 0; i < columns.length; ++i) { - const column = columns[i]; - if (!column) { - continue; - } - let max_size = 100; - let y = margin + LiteGraph.NODE_TITLE_HEIGHT; - for (let j = 0; j < column.length; ++j) { - const node = column[j]; - node.pos[0] = (layout == LiteGraph.VERTICAL_LAYOUT) ? y : x; - node.pos[1] = (layout == LiteGraph.VERTICAL_LAYOUT) ? x : y; - const max_size_index = (layout == LiteGraph.VERTICAL_LAYOUT) ? 1 : 0; - if (node.size[max_size_index] > max_size) { - max_size = node.size[max_size_index]; - } - const node_size_index = (layout == LiteGraph.VERTICAL_LAYOUT) ? 0 : 1; - y += node.size[node_size_index] + margin + LiteGraph.NODE_TITLE_HEIGHT; - } - x += max_size + margin; - } - - this.setDirtyCanvas(true, true); - }; - - /** - * Returns the amount of time the graph has been running in milliseconds - * @method getTime - * @return {number} number of milliseconds the graph has been running - */ - LGraph.prototype.getTime = function() { - return this.globaltime; - }; - - /** - * Returns the amount of time accumulated using the fixedtime_lapse var. This is used in context where the time increments should be constant - * @method getFixedTime - * @return {number} number of milliseconds the graph has been running - */ - - LGraph.prototype.getFixedTime = function() { - return this.fixedtime; - }; - - /** - * Returns the amount of time it took to compute the latest iteration. Take into account that this number could be not correct - * if the nodes are using graphical actions - * @method getElapsedTime - * @return {number} number of milliseconds it took the last cycle - */ - - LGraph.prototype.getElapsedTime = function() { - return this.elapsed_time; - }; - - /** - * Sends an event to all the nodes, useful to trigger stuff - * @method sendEventToAllNodes - * @param {String} eventname the name of the event (function to be called) - * @param {Array} params parameters in array format - */ - LGraph.prototype.sendEventToAllNodes = function(eventname, params, mode) { - mode = mode || LiteGraph.ALWAYS; - - var nodes = this._nodes_in_order ? this._nodes_in_order : this._nodes; - if (!nodes) { - return; - } - - for (var j = 0, l = nodes.length; j < l; ++j) { - var node = nodes[j]; - - if ( - node.constructor === LiteGraph.Subgraph && - eventname != "onExecute" - ) { - if (node.mode == mode) { - node.sendEventToAllNodes(eventname, params, mode); - } - continue; - } - - if (!node[eventname] || node.mode != mode) { - continue; - } - if (params === undefined) { - node[eventname](); - } else if (params && params.constructor === Array) { - node[eventname].apply(node, params); - } else { - node[eventname](params); - } - } - }; - - LGraph.prototype.sendActionToCanvas = function(action, params) { - if (!this.list_of_graphcanvas) { - return; - } - - for (var i = 0; i < this.list_of_graphcanvas.length; ++i) { - var c = this.list_of_graphcanvas[i]; - - if (c[action]) { - c[action].apply(c, params); - } - } - }; - - /** - * Adds a new node instance to this graph - * @method add - * @param {LGraphNode} node the instance of the node - */ - - LGraph.prototype.add = function(node, skip_compute_order) { - if (!node) { - return; - } - - //groups - if (node.constructor === LGraphGroup) { - this._groups.push(node); - this.setDirtyCanvas(true); - this.change(); - node.graph = this; - this._version++; - return; - } - - //nodes - if (node.id != -1 && this._nodes_by_id[node.id] != null) { - console.warn( - "LiteGraph: there is already a node with this ID, changing it" - ); - node.id = ++this.last_node_id; - } - - if (this._nodes.length >= LiteGraph.MAX_NUMBER_OF_NODES) { - throw "LiteGraph: max number of nodes in a graph reached"; - } - - //give him an id - if (node.id == null || node.id == -1) { - node.id = ++this.last_node_id; - } else if (this.last_node_id < node.id) { - this.last_node_id = node.id; - } - - node.graph = this; - this._version++; - - this._nodes.push(node); - this._nodes_by_id[node.id] = node; - - if (node.onAdded) { - node.onAdded(this); - } - - if (this.config.align_to_grid) { - node.alignToGrid(); - } - - if (!skip_compute_order) { - this.updateExecutionOrder(); - } - - if (this.onNodeAdded) { - this.onNodeAdded(node); - } - - this.setDirtyCanvas(true); - this.change(); - - return node; //to chain actions - }; - - /** - * Removes a node from the graph - * @method remove - * @param {LGraphNode} node the instance of the node - */ - - LGraph.prototype.remove = function(node) { - if (node.constructor === LiteGraph.LGraphGroup) { - var index = this._groups.indexOf(node); - if (index != -1) { - this._groups.splice(index, 1); - } - node.graph = null; - this._version++; - this.setDirtyCanvas(true, true); - this.change(); - return; - } - - if (this._nodes_by_id[node.id] == null) { - return; - } //not found - - if (node.ignore_remove) { - return; - } //cannot be removed - - this.beforeChange(); //sure? - almost sure is wrong - - //disconnect inputs - if (node.inputs) { - for (var i = 0; i < node.inputs.length; i++) { - var slot = node.inputs[i]; - if(node.inputs[i].extraLinks) { //MODDED - for(const key in node.inputs[i].extraLinks) { - node.removeLink(node.inputs[i].extraLinks[key]); - delete node.inputs[i].extraLinks[key]; - } - - } - if (slot.link != null) { - node.disconnectInput(i); - } - } - } - - - //disconnect outputs - if (node.outputs) { - for (var i = 0; i < node.outputs.length; i++) { - var slot = node.outputs[i]; - if (slot.links != null && slot.links.length) { - node.disconnectOutput(i); - } - } - } - - //node.id = -1; //why? - - //callback - if (node.onRemoved) { - node.onRemoved(); - } - - node.graph = null; - this._version++; - - //remove from canvas render - if (this.list_of_graphcanvas) { - for (var i = 0; i < this.list_of_graphcanvas.length; ++i) { - var canvas = this.list_of_graphcanvas[i]; - if (canvas.selected_nodes[node.id]) { - delete canvas.selected_nodes[node.id]; - } - if (canvas.node_dragged == node) { - canvas.node_dragged = null; - } - } - } - - //remove from containers - var pos = this._nodes.indexOf(node); - if (pos != -1) { - this._nodes.splice(pos, 1); - } - delete this._nodes_by_id[node.id]; - - if (this.onNodeRemoved) { - this.onNodeRemoved(node); - } - - //close panels - this.sendActionToCanvas("checkPanels"); - - this.setDirtyCanvas(true, true); - this.afterChange(); //sure? - almost sure is wrong - this.change(); - - this.updateExecutionOrder(); - }; - - /** - * Returns a node by its id. - * @method getNodeById - * @param {Number} id - */ - - LGraph.prototype.getNodeById = function(id) { - if (id == null) { - return null; - } - return this._nodes_by_id[id]; - }; - - /** - * Returns a list of nodes that matches a class - * @method findNodesByClass - * @param {Class} classObject the class itself (not an string) - * @return {Array} a list with all the nodes of this type - */ - LGraph.prototype.findNodesByClass = function(classObject, result) { - result = result || []; - result.length = 0; - for (var i = 0, l = this._nodes.length; i < l; ++i) { - if (this._nodes[i].constructor === classObject) { - result.push(this._nodes[i]); - } - } - return result; - }; - - /** - * Returns a list of nodes that matches a type - * @method findNodesByType - * @param {String} type the name of the node type - * @return {Array} a list with all the nodes of this type - */ - LGraph.prototype.findNodesByType = function(type, result) { - var type = type.toLowerCase(); - result = result || []; - result.length = 0; - for (var i = 0, l = this._nodes.length; i < l; ++i) { - if (this._nodes[i].type.toLowerCase() == type) { - result.push(this._nodes[i]); - } - } - return result; - }; - - /** - * Returns the first node that matches a name in its title - * @method findNodeByTitle - * @param {String} name the name of the node to search - * @return {Node} the node or null - */ - LGraph.prototype.findNodeByTitle = function(title) { - for (var i = 0, l = this._nodes.length; i < l; ++i) { - if (this._nodes[i].title == title) { - return this._nodes[i]; - } - } - return null; - }; - - /** - * Returns a list of nodes that matches a name - * @method findNodesByTitle - * @param {String} name the name of the node to search - * @return {Array} a list with all the nodes with this name - */ - LGraph.prototype.findNodesByTitle = function(title) { - var result = []; - for (var i = 0, l = this._nodes.length; i < l; ++i) { - if (this._nodes[i].title == title) { - result.push(this._nodes[i]); - } - } - return result; - }; - - /** - * Returns the top-most node in this position of the canvas - * @method getNodeOnPos - * @param {number} x the x coordinate in canvas space - * @param {number} y the y coordinate in canvas space - * @param {Array} nodes_list a list with all the nodes to search from, by default is all the nodes in the graph - * @return {LGraphNode} the node at this position or null - */ - LGraph.prototype.getNodeOnPos = function(x, y, nodes_list, margin) { - nodes_list = nodes_list || this._nodes; - var nRet = null; - for (var i = nodes_list.length - 1; i >= 0; i--) { - var n = nodes_list[i]; - if (n.isPointInside(x, y, margin)) { - // check for lesser interest nodes (TODO check for overlapping, use the top) - /*if (typeof n == "LGraphGroup"){ - nRet = n; - }else{*/ - return n; - /*}*/ - } - } - return nRet; - }; - - /** - * Returns the top-most group in that position - * @method getGroupOnPos - * @param {number} x the x coordinate in canvas space - * @param {number} y the y coordinate in canvas space - * @return {LGraphGroup} the group or null - */ - LGraph.prototype.getGroupOnPos = function(x, y) { - for (var i = this._groups.length - 1; i >= 0; i--) { - var g = this._groups[i]; - if (g.isPointInside(x, y, 2, true)) { - return g; - } - } - return null; - }; - - /** - * Checks that the node type matches the node type registered, used when replacing a nodetype by a newer version during execution - * this replaces the ones using the old version with the new version - * @method checkNodeTypes - */ - LGraph.prototype.checkNodeTypes = function() { - var changes = false; - for (var i = 0; i < this._nodes.length; i++) { - var node = this._nodes[i]; - var ctor = LiteGraph.registered_node_types[node.type]; - if (node.constructor == ctor) { - continue; - } - console.log("node being replaced by newer version: " + node.type); - var newnode = LiteGraph.createNode(node.type); - changes = true; - this._nodes[i] = newnode; - newnode.configure(node.serialize()); - newnode.graph = this; - this._nodes_by_id[newnode.id] = newnode; - if (node.inputs) { - newnode.inputs = node.inputs.concat(); - } - if (node.outputs) { - newnode.outputs = node.outputs.concat(); - } - } - this.updateExecutionOrder(); - }; - - // ********** GLOBALS ***************** - - LGraph.prototype.onAction = function(action, param, options) { - this._input_nodes = this.findNodesByClass( - LiteGraph.GraphInput, - this._input_nodes - ); - for (var i = 0; i < this._input_nodes.length; ++i) { - var node = this._input_nodes[i]; - if (node.properties.name != action) { - continue; - } - //wrap node.onAction(action, param); - node.actionDo(action, param, options); - break; - } - }; - - LGraph.prototype.trigger = function(action, param) { - if (this.onTrigger) { - this.onTrigger(action, param); - } - }; - - /** - * Tell this graph it has a global graph input of this type - * @method addGlobalInput - * @param {String} name - * @param {String} type - * @param {*} value [optional] - */ - LGraph.prototype.addInput = function(name, type, value) { - var input = this.inputs[name]; - if (input) { - //already exist - return; - } - - this.beforeChange(); - this.inputs[name] = { name: name, type: type, value: value }; - this._version++; - this.afterChange(); - - if (this.onInputAdded) { - this.onInputAdded(name, type); - } - - if (this.onInputsOutputsChange) { - this.onInputsOutputsChange(); - } - }; - - /** - * Assign a data to the global graph input - * @method setGlobalInputData - * @param {String} name - * @param {*} data - */ - LGraph.prototype.setInputData = function(name, data) { - var input = this.inputs[name]; - if (!input) { - return; - } - input.value = data; - }; - - /** - * Returns the current value of a global graph input - * @method getInputData - * @param {String} name - * @return {*} the data - */ - LGraph.prototype.getInputData = function(name) { - var input = this.inputs[name]; - if (!input) { - return null; - } - return input.value; - }; - - /** - * Changes the name of a global graph input - * @method renameInput - * @param {String} old_name - * @param {String} new_name - */ - LGraph.prototype.renameInput = function(old_name, name) { - if (name == old_name) { - return; - } - - if (!this.inputs[old_name]) { - return false; - } - - if (this.inputs[name]) { - console.error("there is already one input with that name"); - return false; - } - - this.inputs[name] = this.inputs[old_name]; - delete this.inputs[old_name]; - this._version++; - - if (this.onInputRenamed) { - this.onInputRenamed(old_name, name); - } - - if (this.onInputsOutputsChange) { - this.onInputsOutputsChange(); - } - }; - - /** - * Changes the type of a global graph input - * @method changeInputType - * @param {String} name - * @param {String} type - */ - LGraph.prototype.changeInputType = function(name, type) { - if (!this.inputs[name]) { - return false; - } - - if ( - this.inputs[name].type && - String(this.inputs[name].type).toLowerCase() == - String(type).toLowerCase() - ) { - return; - } - - this.inputs[name].type = type; - this._version++; - if (this.onInputTypeChanged) { - this.onInputTypeChanged(name, type); - } - }; - - /** - * Removes a global graph input - * @method removeInput - * @param {String} name - * @param {String} type - */ - LGraph.prototype.removeInput = function(name) { - if (!this.inputs[name]) { - return false; - } - - delete this.inputs[name]; - this._version++; - - if (this.onInputRemoved) { - this.onInputRemoved(name); - } - - if (this.onInputsOutputsChange) { - this.onInputsOutputsChange(); - } - return true; - }; - - /** - * Creates a global graph output - * @method addOutput - * @param {String} name - * @param {String} type - * @param {*} value - */ - LGraph.prototype.addOutput = function(name, type, value) { - this.outputs[name] = { name: name, type: type, value: value }; - this._version++; - - if (this.onOutputAdded) { - this.onOutputAdded(name, type); - } - - if (this.onInputsOutputsChange) { - this.onInputsOutputsChange(); - } - }; - - /** - * Assign a data to the global output - * @method setOutputData - * @param {String} name - * @param {String} value - */ - LGraph.prototype.setOutputData = function(name, value) { - var output = this.outputs[name]; - if (!output) { - return; - } - output.value = value; - }; - - /** - * Returns the current value of a global graph output - * @method getOutputData - * @param {String} name - * @return {*} the data - */ - LGraph.prototype.getOutputData = function(name) { - var output = this.outputs[name]; - if (!output) { - return null; - } - return output.value; - }; - - /** - * Renames a global graph output - * @method renameOutput - * @param {String} old_name - * @param {String} new_name - */ - LGraph.prototype.renameOutput = function(old_name, name) { - if (!this.outputs[old_name]) { - return false; - } - - if (this.outputs[name]) { - console.error("there is already one output with that name"); - return false; - } - - this.outputs[name] = this.outputs[old_name]; - delete this.outputs[old_name]; - this._version++; - - if (this.onOutputRenamed) { - this.onOutputRenamed(old_name, name); - } - - if (this.onInputsOutputsChange) { - this.onInputsOutputsChange(); - } - }; - - /** - * Changes the type of a global graph output - * @method changeOutputType - * @param {String} name - * @param {String} type - */ - LGraph.prototype.changeOutputType = function(name, type) { - if (!this.outputs[name]) { - return false; - } - - if ( - this.outputs[name].type && - String(this.outputs[name].type).toLowerCase() == - String(type).toLowerCase() - ) { - return; - } - - this.outputs[name].type = type; - this._version++; - if (this.onOutputTypeChanged) { - this.onOutputTypeChanged(name, type); - } - }; - - /** - * Removes a global graph output - * @method removeOutput - * @param {String} name - */ - LGraph.prototype.removeOutput = function(name) { - if (!this.outputs[name]) { - return false; - } - delete this.outputs[name]; - this._version++; - - if (this.onOutputRemoved) { - this.onOutputRemoved(name); - } - - if (this.onInputsOutputsChange) { - this.onInputsOutputsChange(); - } - return true; - }; - - LGraph.prototype.triggerInput = function(name, value) { - var nodes = this.findNodesByTitle(name); - for (var i = 0; i < nodes.length; ++i) { - nodes[i].onTrigger(value); - } - }; - - LGraph.prototype.setCallback = function(name, func) { - var nodes = this.findNodesByTitle(name); - for (var i = 0; i < nodes.length; ++i) { - nodes[i].setTrigger(func); - } - }; - - //used for undo, called before any change is made to the graph - LGraph.prototype.beforeChange = function(info) { - if (this.onBeforeChange) { - this.onBeforeChange(this,info); - } - this.sendActionToCanvas("onBeforeChange", this); - }; - - //used to resend actions, called after any change is made to the graph - LGraph.prototype.afterChange = function(info) { - if (this.onAfterChange) { - this.onAfterChange(this,info); - } - this.sendActionToCanvas("onAfterChange", this); - }; - - LGraph.prototype.connectionChange = function(node, link_info) { - this.updateExecutionOrder(); - if (this.onConnectionChange) { - this.onConnectionChange(node); - } - this._version++; - this.sendActionToCanvas("onConnectionChange"); - }; - - /** - * returns if the graph is in live mode - * @method isLive - */ - - LGraph.prototype.isLive = function() { - if (!this.list_of_graphcanvas) { - return false; - } - - for (var i = 0; i < this.list_of_graphcanvas.length; ++i) { - var c = this.list_of_graphcanvas[i]; - if (c.live_mode) { - return true; - } - } - return false; - }; - - /** - * clears the triggered slot animation in all links (stop visual animation) - * @method clearTriggeredSlots - */ - LGraph.prototype.clearTriggeredSlots = function() { - for (var i in this.links) { - var link_info = this.links[i]; - if (!link_info) { - continue; - } - if (link_info._last_time) { - link_info._last_time = 0; - } - } - }; - - /* Called when something visually changed (not the graph!) */ - LGraph.prototype.change = function() { - if (LiteGraph.debug) { - console.log("Graph changed"); - } - this.sendActionToCanvas("setDirty", [true, true]); - if (this.on_change) { - this.on_change(this); - } - }; - - LGraph.prototype.setDirtyCanvas = function(fg, bg) { - this.sendActionToCanvas("setDirty", [fg, bg]); - }; - - /** - * Destroys a link - * @method removeLink - * @param {Number} link_id - */ - LGraph.prototype.removeLink = function(link_id) { - var link = this.links[link_id]; - if (!link) { - return; - } - var node = this.getNodeById(link.target_id); - if (node) { - node.disconnectInput(link.target_slot); - } - }; - - //save and recover app state *************************************** - /** - * Creates a Object containing all the info about this graph, it can be serialized - * @method serialize - * @return {Object} value of the node - */ - LGraph.prototype.serialize = function() { - var nodes_info = []; - for (var i = 0, l = this._nodes.length; i < l; ++i) { - nodes_info.push(this._nodes[i].serialize()); - } - - //pack link info into a non-verbose format - var links = []; - for (var i in this.links) { - //links is an OBJECT - var link = this.links[i]; - if (!link.serialize) { - //weird bug I havent solved yet - console.warn( - "weird LLink bug, link info is not a LLink but a regular object" - ); - var link2 = new LLink(); - for (var j in link) { - link2[j] = link[j]; - } - this.links[i] = link2; - link = link2; - } - - links.push(link.serialize()); - } - - var groups_info = []; - for (var i = 0; i < this._groups.length; ++i) { - groups_info.push(this._groups[i].serialize()); - } - - var data = { - last_node_id: this.last_node_id, - last_link_id: this.last_link_id, - nodes: nodes_info, - links: links, - groups: groups_info, - config: this.config, - extra: this.extra, - version: LiteGraph.VERSION - }; - - if(this.onSerialize) - this.onSerialize(data); - - return data; - }; - - /** - * Configure a graph from a JSON string - * @method configure - * @param {String} str configure a graph from a JSON string - * @param {Boolean} returns if there was any error parsing - */ - LGraph.prototype.configure = function(data, keep_old) { - if (!data) { - return; - } - - if (!keep_old) { - this.clear(); - } - - var nodes = data.nodes; - - //decode links info (they are very verbose) - if (data.links && data.links.constructor === Array) { - var links = []; - for (var i = 0; i < data.links.length; ++i) { - var link_data = data.links[i]; - if(!link_data) //weird bug - { - console.warn("serialized graph link data contains errors, skipping."); - continue; - } - var link = new LLink(); - link.configure(link_data); - links[link.id] = link; - } - data.links = links; - } - - //copy all stored fields - for (var i in data) { - if(i == "nodes" || i == "groups" ) //links must be accepted - continue; - this[i] = data[i]; - } - - var error = false; - - //create nodes - this._nodes = []; - if (nodes) { - for (var i = 0, l = nodes.length; i < l; ++i) { - var n_info = nodes[i]; //stored info - var node = LiteGraph.createNode(n_info.type, n_info.title); - if (!node) { - if (LiteGraph.debug) { - console.log( - "Node not found or has errors: " + n_info.type - ); - } - - //in case of error we create a replacement node to avoid losing info - node = new LGraphNode(); - node.last_serialization = n_info; - node.has_errors = true; - error = true; - //continue; - } - - node.id = n_info.id; //id it or it will create a new id - this.add(node, true); //add before configure, otherwise configure cannot create links - } - - //configure nodes afterwards so they can reach each other - for (var i = 0, l = nodes.length; i < l; ++i) { - var n_info = nodes[i]; - var node = this.getNodeById(n_info.id); - if (node) { - node.configure(n_info); - } - } - } - - //groups - this._groups.length = 0; - if (data.groups) { - for (var i = 0; i < data.groups.length; ++i) { - var group = new LiteGraph.LGraphGroup(); - group.configure(data.groups[i]); - this.add(group); - } - } - - this.updateExecutionOrder(); - - this.extra = data.extra || {}; - - if(this.onConfigure) - this.onConfigure(data); - - this._version++; - this.setDirtyCanvas(true, true); - return error; - }; - - LGraph.prototype.load = function(url, callback) { - var that = this; - - //from file - if(url.constructor === File || url.constructor === Blob) - { - var reader = new FileReader(); - reader.addEventListener('load', function(event) { - var data = JSON.parse(event.target.result); - that.configure(data); - if(callback) - callback(); - }); - - reader.readAsText(url); - return; - } - - //is a string, then an URL - var req = new XMLHttpRequest(); - req.open("GET", url, true); - req.send(null); - req.onload = function(oEvent) { - if (req.status !== 200) { - console.error("Error loading graph:", req.status, req.response); - return; - } - var data = JSON.parse( req.response ); - that.configure(data); - if(callback) - callback(); - }; - req.onerror = function(err) { - console.error("Error loading graph:", err); - }; - }; - - LGraph.prototype.onNodeTrace = function(node, msg, color) { - //TODO - }; - - //this is the class in charge of storing link information - function LLink(id, type, origin_id, origin_slot, target_id, target_slot) { - this.id = id; - this.type = type; - this.origin_id = origin_id; - this.origin_slot = origin_slot; - this.target_id = target_id; - this.target_slot = target_slot; - - this._data = null; - this._pos = new Float32Array(2); //center - } - - LLink.prototype.configure = function(o) { - if (o.constructor === Array) { - this.id = o[0]; - this.origin_id = o[1]; - this.origin_slot = o[2]; - this.target_id = o[3]; - this.target_slot = o[4]; - this.type = o[5]; - } else { - this.id = o.id; - this.type = o.type; - this.origin_id = o.origin_id; - this.origin_slot = o.origin_slot; - this.target_id = o.target_id; - this.target_slot = o.target_slot; - } - }; - - LLink.prototype.serialize = function() { - return [ - this.id, - this.origin_id, - this.origin_slot, - this.target_id, - this.target_slot, - this.type - ]; - }; - - LiteGraph.LLink = LLink; - - // ************************************************************* - // Node CLASS ******* - // ************************************************************* - - /* - title: string - pos: [x,y] - size: [x,y] - - input|output: every connection - + { name:string, type:string, pos: [x,y]=Optional, direction: "input"|"output", links: Array }); - - general properties: - + clip_area: if you render outside the node, it will be clipped - + unsafe_execution: not allowed for safe execution - + skip_repeated_outputs: when adding new outputs, it wont show if there is one already connected - + resizable: if set to false it wont be resizable with the mouse - + horizontal: slots are distributed horizontally - + widgets_start_y: widgets start at y distance from the top of the node - - flags object: - + collapsed: if it is collapsed - - supported callbacks: - + onAdded: when added to graph (warning: this is called BEFORE the node is configured when loading) - + onRemoved: when removed from graph - + 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 - + onMouseMove - + onMouseUp - + onMouseEnter - + onMouseLeave - + onExecute: execute the node - + onPropertyChanged: when a property is changed in the panel (return true to skip default behaviour) - + onGetInputs: returns an array of possible inputs - + onGetOutputs: returns an array of possible outputs - + onBounding: in case this node has a bigger bounding than the node itself (the callback receives the bounding as [x,y,w,h]) - + onDblClick: double clicked in the node - + onInputDblClick: input slot double clicked (can be used to automatically create a node connected) - + onOutputDblClick: output slot double clicked (can be used to automatically create a node connected) - + onConfigure: called after the node has been configured - + onSerialize: to add extra info when serializing (the callback receives the object that should be filled with the data) - + onSelected - + onDeselected - + onDropItem : DOM item dropped over the node - + onDropFile : file dropped over the node - + onConnectInput : if returns false the incoming connection will be canceled - + onConnectionsChange : a connection changed (new one or removed) (LiteGraph.INPUT or LiteGraph.OUTPUT, slot, true if connected, link_info, input_info ) - + onAction: action slot triggered - + getExtraMenuOptions: to add option to context menu -*/ - - /** - * Base Class for all the node type classes - * @class LGraphNode - * @param {String} name a name for the node - */ - - function LGraphNode(title) { - this._ctor(title); - } - - global.LGraphNode = LiteGraph.LGraphNode = LGraphNode; - - LGraphNode.prototype._ctor = function(title) { - this.title = title || "Unnamed"; - this.size = [LiteGraph.NODE_WIDTH, 60]; - this.graph = null; - - this._pos = new Float32Array(10, 10); - - Object.defineProperty(this, "pos", { - set: function(v) { - if (!v || v.length < 2) { - return; - } - this._pos[0] = v[0]; - this._pos[1] = v[1]; - }, - get: function() { - return this._pos; - }, - enumerable: true - }); - - this.id = -1; //not know till not added - this.type = null; - - //inputs available: array of inputs - this.inputs = []; - this.outputs = []; - this.connections = []; - - //local data - this.properties = {}; //for the values - this.properties_info = []; //for the info - - this.flags = {}; - }; - - /** - * configure a node from an object containing the serialized info - * @method configure - */ - LGraphNode.prototype.configure = function(info) { - if (this.graph) { - this.graph._version++; - } - for (var j in info) { - if (j == "properties") { - //i don't want to clone properties, I want to reuse the old container - for (var k in info.properties) { - this.properties[k] = info.properties[k]; - if (this.onPropertyChanged) { - this.onPropertyChanged( k, info.properties[k] ); - } - } - continue; - } - - if (info[j] == null) { - continue; - } else if (typeof info[j] == "object") { - //object - if (this[j] && this[j].configure) { - this[j].configure(info[j]); - } else { - this[j] = LiteGraph.cloneObject(info[j], this[j]); - } - } //value - else { - this[j] = info[j]; - } - } - - if (!info.title) { - this.title = this.constructor.title; - } - - if (this.inputs) { - for (var i = 0; i < this.inputs.length; ++i) { - var input = this.inputs[i]; - var link_info = this.graph ? this.graph.links[input.link] : null; - if (this.onConnectionsChange) - this.onConnectionsChange( LiteGraph.INPUT, i, true, link_info, input ); //link_info has been created now, so its updated - - if( this.onInputAdded ) - this.onInputAdded(input); - - } - } - - if (this.outputs) { - for (var i = 0; i < this.outputs.length; ++i) { - var output = this.outputs[i]; - if (!output.links) { - continue; - } - for (var j = 0; j < output.links.length; ++j) { - var link_info = this.graph ? this.graph.links[output.links[j]] : null; - if (this.onConnectionsChange) - this.onConnectionsChange( LiteGraph.OUTPUT, i, true, link_info, output ); //link_info has been created now, so its updated - } - - if( this.onOutputAdded ) - this.onOutputAdded(output); - } - } - - if( this.widgets ) - { - for (var i = 0; i < this.widgets.length; ++i) - { - var w = this.widgets[i]; - if(!w) - continue; - if(w.options && w.options.property && this.properties[ w.options.property ]) - w.value = JSON.parse( JSON.stringify( this.properties[ w.options.property ] ) ); - } - if (info.widgets_values) { - for (var i = 0; i < info.widgets_values.length; ++i) { - if (this.widgets[i]) { - this.widgets[i].value = info.widgets_values[i]; - } - } - } - } - - if (this.onConfigure) { - this.onConfigure(info); - } - }; - - /** - * serialize the content - * @method serialize - */ - - LGraphNode.prototype.serialize = function() { - //create serialization object - var o = { - id: this.id, - type: this.type, - pos: this.pos, - size: this.size, - flags: LiteGraph.cloneObject(this.flags), - order: this.order, - mode: this.mode - }; - - //special case for when there were errors - if (this.constructor === LGraphNode && this.last_serialization) { - return this.last_serialization; - } - - if (this.inputs) { - o.inputs = this.inputs; - } - - if (this.outputs) { - //clear outputs last data (because data in connections is never serialized but stored inside the outputs info) - for (var i = 0; i < this.outputs.length; i++) { - delete this.outputs[i]._data; - } - o.outputs = this.outputs; - } - - if (this.title && this.title != this.constructor.title) { - o.title = this.title; - } - - if (this.properties) { - o.properties = LiteGraph.cloneObject(this.properties); - } - - if (this.widgets && this.serialize_widgets) { - o.widgets_values = []; - for (var i = 0; i < this.widgets.length; ++i) { - if(this.widgets[i]) - o.widgets_values[i] = this.widgets[i].value; - else - o.widgets_values[i] = null; - } - } - - if (!o.type) { - o.type = this.constructor.type; - } - - if (this.color) { - o.color = this.color; - } - if (this.bgcolor) { - o.bgcolor = this.bgcolor; - } - if (this.boxcolor) { - o.boxcolor = this.boxcolor; - } - if (this.shape) { - o.shape = this.shape; - } - - if (this.onSerialize) { - if (this.onSerialize(o)) { - console.warn( - "node onSerialize shouldnt return anything, data should be stored in the object pass in the first parameter" - ); - } - } - - return o; - }; - - /* Creates a clone of this node */ - LGraphNode.prototype.clone = function() { - var node = LiteGraph.createNode(this.type); - if (!node) { - return null; - } - - //we clone it because serialize returns shared containers - var data = LiteGraph.cloneObject(this.serialize()); - - //remove links - if (data.inputs) { - for (var i = 0; i < data.inputs.length; ++i) { - data.inputs[i].link = null; - } - } - - if (data.outputs) { - for (var i = 0; i < data.outputs.length; ++i) { - if (data.outputs[i].links) { - data.outputs[i].links.length = 0; - } - } - } - - delete data["id"]; - //remove links - node.configure(data); - - return node; - }; - - /** - * serialize and stringify - * @method toString - */ - - LGraphNode.prototype.toString = function() { - return JSON.stringify(this.serialize()); - }; - //LGraphNode.prototype.deserialize = function(info) {} //this cannot be done from within, must be done in LiteGraph - - /** - * get the title string - * @method getTitle - */ - - LGraphNode.prototype.getTitle = function() { - return this.title || this.constructor.title; - }; - - /** - * sets the value of a property - * @method setProperty - * @param {String} name - * @param {*} value - */ - LGraphNode.prototype.setProperty = function(name, value) { - if (!this.properties) { - this.properties = {}; - } - if( value === this.properties[name] ) - return; - var prev_value = this.properties[name]; - this.properties[name] = value; - if (this.onPropertyChanged) { - if( this.onPropertyChanged(name, value, prev_value) === false ) //abort change - this.properties[name] = prev_value; - } - if(this.widgets) //widgets could be linked to properties - for(var i = 0; i < this.widgets.length; ++i) - { - var w = this.widgets[i]; - if(!w) - continue; - if(w.options.property == name) - { - w.value = value; - break; - } - } - }; - - // Execution ************************* - /** - * sets the output data - * @method setOutputData - * @param {number} slot - * @param {*} data - */ - LGraphNode.prototype.setOutputData = function(slot, data) { - if (!this.outputs) { - return; - } - - //this maybe slow and a niche case - //if(slot && slot.constructor === String) - // slot = this.findOutputSlot(slot); - - if (slot == -1 || slot >= this.outputs.length) { - return; - } - - var output_info = this.outputs[slot]; - if (!output_info) { - return; - } - - //store data in the output itself in case we want to debug - output_info._data = data; - - //if there are connections, pass the data to the connections - if (this.outputs[slot].links) { - for (var i = 0; i < this.outputs[slot].links.length; i++) { - var link_id = this.outputs[slot].links[i]; - var link = this.graph.links[link_id]; - if(link) - link.data = data; - } - } - }; - - /** - * sets the output data type, useful when you want to be able to overwrite the data type - * @method setOutputDataType - * @param {number} slot - * @param {String} datatype - */ - LGraphNode.prototype.setOutputDataType = function(slot, type) { - if (!this.outputs) { - return; - } - if (slot == -1 || slot >= this.outputs.length) { - return; - } - var output_info = this.outputs[slot]; - if (!output_info) { - return; - } - //store data in the output itself in case we want to debug - output_info.type = type; - - //if there are connections, pass the data to the connections - if (this.outputs[slot].links) { - for (var i = 0; i < this.outputs[slot].links.length; i++) { - var link_id = this.outputs[slot].links[i]; - this.graph.links[link_id].type = type; - } - } - }; - - /** - * Retrieves the input data (data traveling through the connection) from one slot - * @method getInputData - * @param {number} slot - * @param {boolean} force_update if set to true it will force the connected node of this slot to output data into this link - * @return {*} data or if it is not connected returns undefined - */ - LGraphNode.prototype.getInputData = function(slot, force_update) { - if (!this.inputs) { - return; - } //undefined; - - if (slot >= this.inputs.length || this.inputs[slot].link == null) { - return; - } - - var link_id = this.inputs[slot].link; - var link = this.graph.links[link_id]; - if (!link) { - //bug: weird case but it happens sometimes - return null; - } - - if (!force_update) { - return link.data; - } - - //special case: used to extract data from the incoming connection before the graph has been executed - var node = this.graph.getNodeById(link.origin_id); - if (!node) { - return link.data; - } - - if (node.updateOutputData) { - node.updateOutputData(link.origin_slot); - } else if (node.onExecute) { - node.onExecute(); - } - - return link.data; - }; - - /** - * Retrieves the input data type (in case this supports multiple input types) - * @method getInputDataType - * @param {number} slot - * @return {String} datatype in string format - */ - LGraphNode.prototype.getInputDataType = function(slot) { - if (!this.inputs) { - return null; - } //undefined; - - if (slot >= this.inputs.length || this.inputs[slot].link == null) { - return null; - } - var link_id = this.inputs[slot].link; - var link = this.graph.links[link_id]; - if (!link) { - //bug: weird case but it happens sometimes - return null; - } - var node = this.graph.getNodeById(link.origin_id); - if (!node) { - return link.type; - } - var output_info = node.outputs[link.origin_slot]; - if (output_info) { - return output_info.type; - } - return null; - }; - - /** - * Retrieves the input data from one slot using its name instead of slot number - * @method getInputDataByName - * @param {String} slot_name - * @param {boolean} force_update if set to true it will force the connected node of this slot to output data into this link - * @return {*} data or if it is not connected returns null - */ - LGraphNode.prototype.getInputDataByName = function( - slot_name, - force_update - ) { - var slot = this.findInputSlot(slot_name); - if (slot == -1) { - return null; - } - return this.getInputData(slot, force_update); - }; - - /** - * tells you if there is a connection in one input slot - * @method isInputConnected - * @param {number} slot - * @return {boolean} - */ - LGraphNode.prototype.isInputConnected = function(slot) { - if (!this.inputs) { - return false; - } - return slot < this.inputs.length && this.inputs[slot].link != null; - }; - - /** - * tells you info about an input connection (which node, type, etc) - * @method getInputInfo - * @param {number} slot - * @return {Object} object or null { link: id, name: string, type: string or 0 } - */ - LGraphNode.prototype.getInputInfo = function(slot) { - if (!this.inputs) { - return null; - } - if (slot < this.inputs.length) { - return this.inputs[slot]; - } - return null; - }; - - /** - * Returns the link info in the connection of an input slot - * @method getInputLink - * @param {number} slot - * @return {LLink} object or null - */ - LGraphNode.prototype.getInputLink = function(slot) { - if (!this.inputs) { - return null; - } - if (slot < this.inputs.length) { - var slot_info = this.inputs[slot]; - return this.graph.links[ slot_info.link ]; - } - 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 === null) { - return null; - } - var link_info = this.graph.links[input.link]; - if (!link_info) { - return null; - } - return this.graph.getNodeById(link_info.origin_id); - }; - - /** - * returns the value of an input with this name, otherwise checks if there is a property with that name - * @method getInputOrProperty - * @param {string} name - * @return {*} value - */ - LGraphNode.prototype.getInputOrProperty = function(name) { - if (!this.inputs || !this.inputs.length) { - return this.properties ? this.properties[name] : null; - } - - for (var i = 0, l = this.inputs.length; i < l; ++i) { - var input_info = this.inputs[i]; - if (name == input_info.name && input_info.link != null) { - var link = this.graph.links[input_info.link]; - if (link) { - return link.data; - } - } - } - return this.properties[name]; - }; - - /** - * tells you the last output data that went in that slot - * @method getOutputData - * @param {number} slot - * @return {Object} object or null - */ - LGraphNode.prototype.getOutputData = function(slot) { - if (!this.outputs) { - return null; - } - if (slot >= this.outputs.length) { - return null; - } - - var info = this.outputs[slot]; - return info._data; - }; - - /** - * tells you info about an output connection (which node, type, etc) - * @method getOutputInfo - * @param {number} slot - * @return {Object} object or null { name: string, type: string, links: [ ids of links in number ] } - */ - LGraphNode.prototype.getOutputInfo = function(slot) { - if (!this.outputs) { - return null; - } - if (slot < this.outputs.length) { - return this.outputs[slot]; - } - return null; - }; - - /** - * tells you if there is a connection in one output slot - * @method isOutputConnected - * @param {number} slot - * @return {boolean} - */ - LGraphNode.prototype.isOutputConnected = function(slot) { - if (!this.outputs) { - return false; - } - return ( - slot < this.outputs.length && - this.outputs[slot].links && - this.outputs[slot].links.length - ); - }; - - /** - * tells you if there is any connection in the output slots - * @method isAnyOutputConnected - * @return {boolean} - */ - LGraphNode.prototype.isAnyOutputConnected = function() { - if (!this.outputs) { - return false; - } - for (var i = 0; i < this.outputs.length; ++i) { - if (this.outputs[i].links && this.outputs[i].links.length) { - return true; - } - } - return false; - }; - - /** - * retrieves all the nodes connected to this output slot - * @method getOutputNodes - * @param {number} slot - * @return {array} - */ - LGraphNode.prototype.getOutputNodes = function(slot) { - if (!this.outputs || this.outputs.length == 0) { - return null; - } - - if (slot >= this.outputs.length) { - return null; - } - - var output = this.outputs[slot]; - if (!output.links || output.links.length == 0) { - return null; - } - - var r = []; - for (var i = 0; i < output.links.length; i++) { - var link_id = output.links[i]; - var link = this.graph.links[link_id]; - if (link) { - var target_node = this.graph.getNodeById(link.target_id); - if (target_node) { - r.push(target_node); - } - } - } - return r; - }; - - LGraphNode.prototype.addOnTriggerInput = function(){ - var trigS = this.findInputSlot("onTrigger"); - if (trigS == -1){ //!trigS || - var input = this.addInput("onTrigger", LiteGraph.EVENT, {optional: true, nameLocked: true}); - return this.findInputSlot("onTrigger"); - } - return trigS; - } - - LGraphNode.prototype.addOnExecutedOutput = function(){ - var trigS = this.findOutputSlot("onExecuted"); - if (trigS == -1){ //!trigS || - var output = this.addOutput("onExecuted", LiteGraph.ACTION, {optional: true, nameLocked: true}); - return this.findOutputSlot("onExecuted"); - } - return trigS; - } - - LGraphNode.prototype.onAfterExecuteNode = function(param, options){ - var trigS = this.findOutputSlot("onExecuted"); - if (trigS != -1){ - - //console.debug(this.id+":"+this.order+" triggering slot onAfterExecute"); - //console.debug(param); - //console.debug(options); - this.triggerSlot(trigS, param, null, options); - - } - } - - LGraphNode.prototype.changeMode = function(modeTo){ - switch(modeTo){ - case LiteGraph.ON_EVENT: - // this.addOnExecutedOutput(); - break; - - case LiteGraph.ON_TRIGGER: - this.addOnTriggerInput(); - this.addOnExecutedOutput(); - break; - - case LiteGraph.NEVER: - break; - - case LiteGraph.ALWAYS: - break; - - case LiteGraph.ON_REQUEST: - break; - - default: - return false; - break; - } - this.mode = modeTo; - return true; - }; - - /** - * Triggers the node code execution, place a boolean/counter to mark the node as being executed - * @method execute - * @param {*} param - * @param {*} options - */ - LGraphNode.prototype.doExecute = function(param, options) { - options = options || {}; - if (this.onExecute){ - - // enable this to give the event an ID - if (!options.action_call) options.action_call = this.id+"_exec_"+Math.floor(Math.random()*9999); - - this.graph.nodes_executing[this.id] = true; //.push(this.id); - - this.onExecute(param, options); - - this.graph.nodes_executing[this.id] = false; //.pop(); - - // save execution/action ref - this.exec_version = this.graph.iteration; - if(options && options.action_call){ - this.action_call = options.action_call; // if (param) - this.graph.nodes_executedAction[this.id] = options.action_call; - } - } - this.execute_triggered = 2; // the nFrames it will be used (-- each step), means "how old" is the event - if(this.onAfterExecuteNode) this.onAfterExecuteNode(param, options); // callback - }; - - /** - * Triggers an action, wrapped by logics to control execution flow - * @method actionDo - * @param {String} action name - * @param {*} param - */ - LGraphNode.prototype.actionDo = function(action, param, options) { - options = options || {}; - if (this.onAction){ - - // enable this to give the event an ID - if (!options.action_call) options.action_call = this.id+"_"+(action?action:"action")+"_"+Math.floor(Math.random()*9999); - - this.graph.nodes_actioning[this.id] = (action?action:"actioning"); //.push(this.id); - - this.onAction(action, param, options); - - this.graph.nodes_actioning[this.id] = false; //.pop(); - - // save execution/action ref - if(options && options.action_call){ - this.action_call = options.action_call; // if (param) - this.graph.nodes_executedAction[this.id] = options.action_call; - } - } - this.action_triggered = 2; // the nFrames it will be used (-- each step), means "how old" is the event - if(this.onAfterExecuteNode) this.onAfterExecuteNode(param, options); - }; - - /** - * Triggers an event in this node, this will trigger any output with the same name - * @method trigger - * @param {String} event name ( "on_play", ... ) if action is equivalent to false then the event is send to all - * @param {*} param - */ - LGraphNode.prototype.trigger = function(action, param, options) { - if (!this.outputs || !this.outputs.length) { - return; - } - - if (this.graph) - this.graph._last_trigger_time = LiteGraph.getTime(); - - for (var i = 0; i < this.outputs.length; ++i) { - var output = this.outputs[i]; - if ( !output || output.type !== LiteGraph.EVENT || (action && output.name != action) ) - continue; - this.triggerSlot(i, param, null, options); - } - }; - - /** - * Triggers a slot event in this node: cycle output slots and launch execute/action on connected nodes - * @method triggerSlot - * @param {Number} slot the index of the output slot - * @param {*} param - * @param {Number} link_id [optional] in case you want to trigger and specific output link in a slot - */ - LGraphNode.prototype.triggerSlot = function(slot, param, link_id, options) { - options = options || {}; - if (!this.outputs) { - return; - } - - if(slot == null) - { - console.error("slot must be a number"); - return; - } - - if(slot.constructor !== Number) - console.warn("slot must be a number, use node.trigger('name') if you want to use a string"); - - var output = this.outputs[slot]; - if (!output) { - return; - } - - var links = output.links; - if (!links || !links.length) { - return; - } - - if (this.graph) { - this.graph._last_trigger_time = LiteGraph.getTime(); - } - - //for every link attached here - for (var k = 0; k < links.length; ++k) { - var id = links[k]; - if (link_id != null && link_id != id) { - //to skip links - continue; - } - var link_info = this.graph.links[links[k]]; - if (!link_info) { - //not connected - continue; - } - link_info._last_time = LiteGraph.getTime(); - var node = this.graph.getNodeById(link_info.target_id); - if (!node) { - //node not found? - continue; - } - - //used to mark events in graph - var target_connection = node.inputs[link_info.target_slot]; - - if (node.mode === LiteGraph.ON_TRIGGER) - { - // generate unique trigger ID if not present - if (!options.action_call) options.action_call = this.id+"_trigg_"+Math.floor(Math.random()*9999); - if (node.onExecute) { - // -- wrapping node.onExecute(param); -- - node.doExecute(param, options); - } - } - else if (node.onAction) { - // generate unique action ID if not present - if (!options.action_call) options.action_call = this.id+"_act_"+Math.floor(Math.random()*9999); - //pass the action name - var target_connection = node.inputs[link_info.target_slot]; - // wrap node.onAction(target_connection.name, param); - node.actionDo(target_connection.name, param, options); - } - } - }; - - /** - * clears the trigger slot animation - * @method clearTriggeredSlot - * @param {Number} slot the index of the output slot - * @param {Number} link_id [optional] in case you want to trigger and specific output link in a slot - */ - LGraphNode.prototype.clearTriggeredSlot = function(slot, link_id) { - if (!this.outputs) { - return; - } - - var output = this.outputs[slot]; - if (!output) { - return; - } - - var links = output.links; - if (!links || !links.length) { - return; - } - - //for every link attached here - for (var k = 0; k < links.length; ++k) { - var id = links[k]; - if (link_id != null && link_id != id) { - //to skip links - continue; - } - var link_info = this.graph.links[links[k]]; - if (!link_info) { - //not connected - continue; - } - link_info._last_time = 0; - } - }; - - /** - * changes node size and triggers callback - * @method setSize - * @param {vec2} size - */ - LGraphNode.prototype.setSize = function(size) - { - this.size = size; - if(this.onResize) - this.onResize(this.size); - } - - /** - * add a new property to this node - * @method addProperty - * @param {string} name - * @param {*} default_value - * @param {string} type string defining the output type ("vec3","number",...) - * @param {Object} extra_info this can be used to have special properties of the property (like values, etc) - */ - LGraphNode.prototype.addProperty = function( - name, - default_value, - type, - extra_info - ) { - var o = { name: name, type: type, default_value: default_value }; - if (extra_info) { - for (var i in extra_info) { - o[i] = extra_info[i]; - } - } - if (!this.properties_info) { - this.properties_info = []; - } - this.properties_info.push(o); - if (!this.properties) { - this.properties = {}; - } - this.properties[name] = default_value; - return o; - }; - - //connections - - /** - * add a new output slot to use in this node - * @method addOutput - * @param {string} name - * @param {string} type string defining the output type ("vec3","number",...) - * @param {Object} extra_info this can be used to have special properties of an output (label, special color, position, etc) - */ - LGraphNode.prototype.addOutput = function(name, type, extra_info) { - var output = { name: name, type: type, links: null }; - if (extra_info) { - for (var i in extra_info) { - output[i] = extra_info[i]; - } - } - - if (!this.outputs) { - this.outputs = []; - } - this.outputs.push(output); - if (this.onOutputAdded) { - this.onOutputAdded(output); - } - - if (LiteGraph.auto_load_slot_types) LiteGraph.registerNodeAndSlotType(this,type,true); - - this.setSize( this.computeSize() ); - this.setDirtyCanvas(true, true); - return output; - }; - - /** - * add a new output slot to use in this node - * @method addOutputs - * @param {Array} array of triplets like [[name,type,extra_info],[...]] - */ - LGraphNode.prototype.addOutputs = function(array) { - for (var i = 0; i < array.length; ++i) { - var info = array[i]; - var o = { name: info[0], type: info[1], link: null }; - if (array[2]) { - for (var j in info[2]) { - o[j] = info[2][j]; - } - } - - if (!this.outputs) { - this.outputs = []; - } - this.outputs.push(o); - if (this.onOutputAdded) { - this.onOutputAdded(o); - } - - if (LiteGraph.auto_load_slot_types) LiteGraph.registerNodeAndSlotType(this,info[1],true); - - } - - this.setSize( this.computeSize() ); - this.setDirtyCanvas(true, true); - }; - - /** - * remove an existing output slot - * @method removeOutput - * @param {number} slot - */ - LGraphNode.prototype.removeOutput = function(slot) { - this.disconnectOutput(slot); - this.outputs.splice(slot, 1); - for (var i = slot; i < this.outputs.length; ++i) { - if (!this.outputs[i] || !this.outputs[i].links) { - continue; - } - var links = this.outputs[i].links; - for (var j = 0; j < links.length; ++j) { - var link = this.graph.links[links[j]]; - if (!link) { - continue; - } - link.origin_slot -= 1; - } - } - - this.setSize( this.computeSize() ); - if (this.onOutputRemoved) { - this.onOutputRemoved(slot); - } - this.setDirtyCanvas(true, true); - }; - - /** - * add a new input slot to use in this node - * @method addInput - * @param {string} name - * @param {string} type string defining the input type ("vec3","number",...), it its a generic one use 0 - * @param {Object} extra_info this can be used to have special properties of an input (label, color, position, etc) - */ - LGraphNode.prototype.addInput = function(name, type, extra_info) { - type = type || 0; - var input = { name: name, type: type, link: null }; - if (extra_info) { - for (var i in extra_info) { - input[i] = extra_info[i]; - } - } - - if (!this.inputs) { - this.inputs = []; - } - - this.inputs.push(input); - this.setSize( this.computeSize() ); - - if (this.onInputAdded) { - this.onInputAdded(input); - } - - LiteGraph.registerNodeAndSlotType(this,type); - - this.setDirtyCanvas(true, true); - return input; - }; - - /** - * add several new input slots in this node - * @method addInputs - * @param {Array} array of triplets like [[name,type,extra_info],[...]] - */ - LGraphNode.prototype.addInputs = function(array) { - for (var i = 0; i < array.length; ++i) { - var info = array[i]; - var o = { name: info[0], type: info[1], link: null }; - if (array[2]) { - for (var j in info[2]) { - o[j] = info[2][j]; - } - } - - if (!this.inputs) { - this.inputs = []; - } - this.inputs.push(o); - if (this.onInputAdded) { - this.onInputAdded(o); - } - - LiteGraph.registerNodeAndSlotType(this,info[1]); - } - - this.setSize( this.computeSize() ); - this.setDirtyCanvas(true, true); - }; - - /** - * remove an existing input slot - * @method removeInput - * @param {number} slot - */ - LGraphNode.prototype.removeInput = function(slot) { - this.disconnectInput(slot); - var slot_info = this.inputs.splice(slot, 1); - for (var i = slot; i < this.inputs.length; ++i) { - if (!this.inputs[i]) { - continue; - } - var link = this.graph.links[this.inputs[i].link]; - if (!link) { - continue; - } - link.target_slot -= 1; - } - this.setSize( this.computeSize() ); - if (this.onInputRemoved) { - this.onInputRemoved(slot, slot_info[0] ); - } - this.setDirtyCanvas(true, true); - }; - - /** - * add an special connection to this node (used for special kinds of graphs) - * @method addConnection - * @param {string} name - * @param {string} type string defining the input type ("vec3","number",...) - * @param {[x,y]} pos position of the connection inside the node - * @param {string} direction if is input or output - */ - LGraphNode.prototype.addConnection = function(name, type, pos, direction) { - var o = { - name: name, - type: type, - pos: pos, - direction: direction, - links: null - }; - this.connections.push(o); - return o; - }; - - /** - * computes the minimum size of a node according to its inputs and output slots - * @method computeSize - * @param {number} minHeight - * @return {number} the total size - */ - LGraphNode.prototype.computeSize = function(out) { - if (this.constructor.size) { - return this.constructor.size.concat(); - } - - var rows = Math.max( - this.inputs ? this.inputs.length : 1, - this.outputs ? this.outputs.length : 1 - ); - var size = out || new Float32Array([0, 0]); - rows = Math.max(rows, 1); - var font_size = LiteGraph.NODE_TEXT_SIZE; //although it should be graphcanvas.inner_text_font size - - var title_width = compute_text_size(this.title); - var input_width = 0; - var output_width = 0; - - if (this.inputs) { - for (var i = 0, l = this.inputs.length; i < l; ++i) { - var input = this.inputs[i]; - var text = input.label || input.name || ""; - var text_width = compute_text_size(text); - if (input_width < text_width) { - input_width = text_width; - } - } - } - - if (this.outputs) { - for (var i = 0, l = this.outputs.length; i < l; ++i) { - var output = this.outputs[i]; - var text = output.label || output.name || ""; - var text_width = compute_text_size(text); - if (output_width < text_width) { - output_width = text_width; - } - } - } - - size[0] = Math.max(input_width + output_width + 10, title_width); - size[0] = Math.max(size[0], LiteGraph.NODE_WIDTH); - if (this.widgets && this.widgets.length) { - size[0] = Math.max(size[0], LiteGraph.NODE_WIDTH * 1.5); - } - - size[1] = (this.constructor.slot_start_y || 0) + rows * LiteGraph.NODE_SLOT_HEIGHT; - - var widgets_height = 0; - if (this.widgets && this.widgets.length) { - for (var i = 0, l = this.widgets.length; i < l; ++i) { - if (this.widgets[i].computeSize) - widgets_height += this.widgets[i].computeSize(size[0])[1] + 4; - else - widgets_height += LiteGraph.NODE_WIDGET_HEIGHT + 4; - } - widgets_height += 8; - } - - //compute height using widgets height - if( this.widgets_up ) - size[1] = Math.max( size[1], widgets_height ); - else if( this.widgets_start_y != null ) - size[1] = Math.max( size[1], widgets_height + this.widgets_start_y ); - else - size[1] += widgets_height; - - function compute_text_size(text) { - if (!text) { - return 0; - } - return font_size * text.length * 0.6; - } - - if ( - this.constructor.min_height && - size[1] < this.constructor.min_height - ) { - size[1] = this.constructor.min_height; - } - - size[1] += 6; //margin - - return size; - }; - - /** - * returns all the info available about a property of this node. - * - * @method getPropertyInfo - * @param {String} property name of the property - * @return {Object} the object with all the available info - */ - LGraphNode.prototype.getPropertyInfo = function( property ) - { - var info = null; - - //there are several ways to define info about a property - //legacy mode - if (this.properties_info) { - for (var i = 0; i < this.properties_info.length; ++i) { - if (this.properties_info[i].name == property) { - info = this.properties_info[i]; - break; - } - } - } - //litescene mode using the constructor - if(this.constructor["@" + property]) - info = this.constructor["@" + property]; - - if(this.constructor.widgets_info && this.constructor.widgets_info[property]) - info = this.constructor.widgets_info[property]; - - //litescene mode using the constructor - if (!info && this.onGetPropertyInfo) { - info = this.onGetPropertyInfo(property); - } - - if (!info) - info = {}; - if(!info.type) - info.type = typeof this.properties[property]; - if(info.widget == "combo") - info.type = "enum"; - - return info; - } - - /** - * Defines a widget inside the node, it will be rendered on top of the node, you can control lots of properties - * - * @method addWidget - * @param {String} type the widget type (could be "number","string","combo" - * @param {String} name the text to show on the widget - * @param {String} value the default value - * @param {Function|String} callback function to call when it changes (optionally, it can be the name of the property to modify) - * @param {Object} options the object that contains special properties of this widget - * @return {Object} the created widget object - */ - LGraphNode.prototype.addWidget = function( type, name, value, callback, options ) - { - if (!this.widgets) { - this.widgets = []; - } - - if(!options && callback && callback.constructor === Object) - { - options = callback; - callback = null; - } - - if(options && options.constructor === String) //options can be the property name - options = { property: options }; - - if(callback && callback.constructor === String) //callback can be the property name - { - if(!options) - options = {}; - options.property = callback; - callback = null; - } - - if(callback && callback.constructor !== Function) - { - console.warn("addWidget: callback must be a function"); - callback = null; - } - - var w = { - type: type.toLowerCase(), - name: name, - value: value, - callback: callback, - options: options || {} - }; - - if (w.options.y !== undefined) { - w.y = w.options.y; - } - - if (!callback && !w.options.callback && !w.options.property) { - console.warn("LiteGraph addWidget(...) without a callback or property assigned"); - } - if (type == "combo" && !w.options.values) { - throw "LiteGraph addWidget('combo',...) requires to pass values in options: { values:['red','blue'] }"; - } - this.widgets.push(w); - this.setSize( this.computeSize() ); - return w; - }; - - LGraphNode.prototype.addCustomWidget = function(custom_widget) { - if (!this.widgets) { - this.widgets = []; - } - this.widgets.push(custom_widget); - return custom_widget; - }; - - /** - * returns the bounding of the object, used for rendering purposes - * bounding is: [topleft_cornerx, topleft_cornery, width, height] - * @method getBounding - * @return {Float32Array[4]} the total size - */ - LGraphNode.prototype.getBounding = function(out) { - out = out || new Float32Array(4); - out[0] = this.pos[0] - 4; - out[1] = this.pos[1] - LiteGraph.NODE_TITLE_HEIGHT; - out[2] = this.size[0] + 4; - out[3] = this.flags.collapsed ? LiteGraph.NODE_TITLE_HEIGHT : this.size[1] + LiteGraph.NODE_TITLE_HEIGHT; - - if (this.onBounding) { - this.onBounding(out); - } - return out; - }; - - /** - * checks if a point is inside the shape of a node - * @method isPointInside - * @param {number} x - * @param {number} y - * @return {boolean} - */ - LGraphNode.prototype.isPointInside = function(x, y, margin, skip_title) { - margin = margin || 0; - - var margin_top = this.graph && this.graph.isLive() ? 0 : LiteGraph.NODE_TITLE_HEIGHT; - if (skip_title) { - margin_top = 0; - } - if (this.flags && this.flags.collapsed) { - //if ( distance([x,y], [this.pos[0] + this.size[0]*0.5, this.pos[1] + this.size[1]*0.5]) < LiteGraph.NODE_COLLAPSED_RADIUS) - if ( - isInsideRectangle( - x, - y, - this.pos[0] - margin, - this.pos[1] - LiteGraph.NODE_TITLE_HEIGHT - margin, - (this._collapsed_width || LiteGraph.NODE_COLLAPSED_WIDTH) + - 2 * margin, - LiteGraph.NODE_TITLE_HEIGHT + 2 * margin - ) - ) { - return true; - } - } else if ( - this.pos[0] - 4 - margin < x && - this.pos[0] + this.size[0] + 4 + margin > x && - this.pos[1] - margin_top - margin < y && - this.pos[1] + this.size[1] + margin > y - ) { - return true; - } - return false; - }; - - /** - * checks if a point is inside a node slot, and returns info about which slot - * @method getSlotInPosition - * @param {number} x - * @param {number} y - * @return {Object} if found the object contains { input|output: slot object, slot: number, link_pos: [x,y] } - */ - LGraphNode.prototype.getSlotInPosition = function(x, y) { - //search for inputs - var link_pos = new Float32Array(2); - if (this.inputs) { - for (var i = 0, l = this.inputs.length; i < l; ++i) { - var input = this.inputs[i]; - this.getConnectionPos(true, i, link_pos); - if ( - isInsideRectangle( - x, - y, - link_pos[0] - 10, - link_pos[1] - 5, - 20, - 10 - ) - ) { - return { input: input, slot: i, link_pos: link_pos }; - } - } - } - - if (this.outputs) { - for (var i = 0, l = this.outputs.length; i < l; ++i) { - var output = this.outputs[i]; - this.getConnectionPos(false, i, link_pos); - if ( - isInsideRectangle( - x, - y, - link_pos[0] - 10, - link_pos[1] - 5, - 20, - 10 - ) - ) { - return { output: output, slot: i, link_pos: link_pos }; - } - } - } - - return null; - }; - - /** - * returns the input slot with a given name (used for dynamic slots), -1 if not found - * @method findInputSlot - * @param {string} name the name of the slot - * @param {boolean} returnObj if the obj itself wanted - * @return {number_or_object} the slot (-1 if not found) - */ - LGraphNode.prototype.findInputSlot = function(name, returnObj) { - if (!this.inputs) { - return -1; - } - for (var i = 0, l = this.inputs.length; i < l; ++i) { - if (name == this.inputs[i].name) { - return !returnObj ? i : this.inputs[i]; - } - } - return -1; - }; - - /** - * returns the output slot with a given name (used for dynamic slots), -1 if not found - * @method findOutputSlot - * @param {string} name the name of the slot - * @param {boolean} returnObj if the obj itself wanted - * @return {number_or_object} the slot (-1 if not found) - */ - LGraphNode.prototype.findOutputSlot = function(name, returnObj) { - returnObj = returnObj || false; - if (!this.outputs) { - return -1; - } - for (var i = 0, l = this.outputs.length; i < l; ++i) { - if (name == this.outputs[i].name) { - return !returnObj ? i : this.outputs[i]; - } - } - return -1; - }; - - // TODO refactor: USE SINGLE findInput/findOutput functions! :: merge options - - /** - * returns the first free input slot - * @method findInputSlotFree - * @param {object} options - * @return {number_or_object} the slot (-1 if not found) - */ - LGraphNode.prototype.findInputSlotFree = function(optsIn) { - var optsIn = optsIn || {}; - var optsDef = {returnObj: false - ,typesNotAccepted: [] - }; - var opts = Object.assign(optsDef,optsIn); - if (!this.inputs) { - return -1; - } - for (var i = 0, l = this.inputs.length; i < l; ++i) { - if (this.inputs[i].link && this.inputs[i].link != null) { - continue; - } - if (opts.typesNotAccepted && opts.typesNotAccepted.includes && opts.typesNotAccepted.includes(this.inputs[i].type)){ - continue; - } - return !opts.returnObj ? i : this.inputs[i]; - } - return -1; - }; - - /** - * returns the first output slot free - * @method findOutputSlotFree - * @param {object} options - * @return {number_or_object} the slot (-1 if not found) - */ - LGraphNode.prototype.findOutputSlotFree = function(optsIn) { - var optsIn = optsIn || {}; - var optsDef = { returnObj: false - ,typesNotAccepted: [] - }; - var opts = Object.assign(optsDef,optsIn); - if (!this.outputs) { - return -1; - } - for (var i = 0, l = this.outputs.length; i < l; ++i) { - if (this.outputs[i].links && this.outputs[i].links != null) { - continue; - } - if (opts.typesNotAccepted && opts.typesNotAccepted.includes && opts.typesNotAccepted.includes(this.outputs[i].type)){ - continue; - } - return !opts.returnObj ? i : this.outputs[i]; - } - return -1; - }; - - /** - * findSlotByType for INPUTS - */ - LGraphNode.prototype.findInputSlotByType = function(type, returnObj, preferFreeSlot, doNotUseOccupied) { - return this.findSlotByType(true, type, returnObj, preferFreeSlot, doNotUseOccupied); - }; - - /** - * findSlotByType for OUTPUTS - */ - LGraphNode.prototype.findOutputSlotByType = function(type, returnObj, preferFreeSlot, doNotUseOccupied) { - return this.findSlotByType(false, type, returnObj, preferFreeSlot, doNotUseOccupied); - }; - - /** - * returns the output (or input) slot with a given type, -1 if not found - * @method findSlotByType - * @param {boolean} input uise inputs instead of outputs - * @param {string} type the type of the slot - * @param {boolean} returnObj if the obj itself wanted - * @param {boolean} preferFreeSlot if we want a free slot (if not found, will return the first of the type anyway) - * @return {number_or_object} the slot (-1 if not found) - */ - LGraphNode.prototype.findSlotByType = function(input, type, returnObj, preferFreeSlot, doNotUseOccupied) { - input = input || false; - returnObj = returnObj || false; - preferFreeSlot = preferFreeSlot || false; - doNotUseOccupied = doNotUseOccupied || false; - var aSlots = input ? this.inputs : this.outputs; - if (!aSlots) { - return -1; - } - // !! empty string type is considered 0, * !! - if (type == "" || type == "*") type = 0; - for (var i = 0, l = aSlots.length; i < l; ++i) { - var tFound = false; - var aSource = (type+"").toLowerCase().split(","); - var aDest = aSlots[i].type=="0"||aSlots[i].type=="*"?"0":aSlots[i].type; - aDest = (aDest+"").toLowerCase().split(","); - for(var sI=0;sI= 0 && target_slot !== null){ - //console.debug("CONNbyTYPE type "+target_slotType+" for "+target_slot) - return this.connect(slot, target_node, target_slot); - }else{ - //console.log("type "+target_slotType+" not found or not free?") - if (opts.createEventInCase && target_slotType == LiteGraph.EVENT){ - // WILL CREATE THE onTrigger IN SLOT - //console.debug("connect WILL CREATE THE onTrigger "+target_slotType+" to "+target_node); - return this.connect(slot, target_node, -1); - } - // connect to the first general output slot if not found a specific type and - if (opts.generalTypeInCase){ - var target_slot = target_node.findInputSlotByType(0, false, true, true); - //console.debug("connect TO a general type (*, 0), if not found the specific type ",target_slotType," to ",target_node,"RES_SLOT:",target_slot); - if (target_slot >= 0){ - return this.connect(slot, target_node, target_slot); - } - } - // connect to the first free input slot if not found a specific type and this output is general - if (opts.firstFreeIfOutputGeneralInCase && (target_slotType == 0 || target_slotType == "*" || target_slotType == "")){ - var target_slot = target_node.findInputSlotFree({typesNotAccepted: [LiteGraph.EVENT] }); - //console.debug("connect TO TheFirstFREE ",target_slotType," to ",target_node,"RES_SLOT:",target_slot); - if (target_slot >= 0){ - return this.connect(slot, target_node, target_slot); - } - } - - console.debug("no way to connect type: ",target_slotType," to targetNODE ",target_node); - //TODO filter - - return null; - } - } - - /** - * connect this node input to the output of another node BY TYPE - * @method connectByType - * @param {number_or_string} slot (could be the number of the slot or the string with the name of the slot) - * @param {LGraphNode} node the target node - * @param {string} target_type the output slot type of the target node - * @return {Object} the link_info is created, otherwise null - */ - LGraphNode.prototype.connectByTypeOutput = function(slot, source_node, source_slotType, optsIn) { - var optsIn = optsIn || {}; - var optsDef = { createEventInCase: true - ,firstFreeIfInputGeneralInCase: true - ,generalTypeInCase: true - }; - var opts = Object.assign(optsDef,optsIn); - if (source_node && source_node.constructor === Number) { - source_node = this.graph.getNodeById(source_node); - } - var source_slot = source_node.findOutputSlotByType(source_slotType, false, true); - if (source_slot >= 0 && source_slot !== null){ - //console.debug("CONNbyTYPE OUT! type "+source_slotType+" for "+source_slot) - return source_node.connect(source_slot, this, slot); - }else{ - - // connect to the first general output slot if not found a specific type and - if (opts.generalTypeInCase){ - var source_slot = source_node.findOutputSlotByType(0, false, true, true); - if (source_slot >= 0){ - return source_node.connect(source_slot, this, slot); - } - } - - if (opts.createEventInCase && source_slotType == LiteGraph.EVENT){ - // WILL CREATE THE onExecuted OUT SLOT - if (LiteGraph.do_add_triggers_slots){ - var source_slot = source_node.addOnExecutedOutput(); - return source_node.connect(source_slot, this, slot); - } - } - // connect to the first free output slot if not found a specific type and this input is general - if (opts.firstFreeIfInputGeneralInCase && (source_slotType == 0 || source_slotType == "*" || source_slotType == "")){ - var source_slot = source_node.findOutputSlotFree({typesNotAccepted: [LiteGraph.EVENT] }); - if (source_slot >= 0){ - return source_node.connect(source_slot, this, slot); - } - } - - console.debug("no way to connect byOUT type: ",source_slotType," to sourceNODE ",source_node); - //TODO filter - - //console.log("type OUT! "+source_slotType+" not found or not free?") - return null; - } - } - - /** - * connect this node output to the input of another node - * @method connect - * @param {number_or_string} slot (could be the number of the slot or the string with the name of the slot) - * @param {LGraphNode} node the target node - * @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 {Object} the link_info is created, otherwise null - */ - LGraphNode.prototype.connect = function(slot, target_node, target_slot) { - target_slot = target_slot || 0; - - if (!this.graph) { - //could be connected before adding it to a graph - console.log( - "Connect: Error, node doesn't belong to any graph. Nodes must be added first to a graph before connecting them." - ); //due to link ids being associated with graphs - return null; - } - - //seek for the output slot - if (slot.constructor === String) { - slot = this.findOutputSlot(slot); - if (slot == -1) { - if (LiteGraph.debug) { - console.log("Connect: Error, no slot of name " + slot); - } - return null; - } - } else if (!this.outputs || slot >= this.outputs.length) { - if (LiteGraph.debug) { - console.log("Connect: Error, slot number not found"); - } - return null; - } - - if (target_node && target_node.constructor === Number) { - target_node = this.graph.getNodeById(target_node); - } - if (!target_node) { - throw "target node is null"; - } - - //avoid loopback - if (target_node == this) { - return null; - } - - //you can specify the slot by name - if (target_slot.constructor === String) { - target_slot = target_node.findInputSlot(target_slot); - if (target_slot == -1) { - if (LiteGraph.debug) { - console.log( - "Connect: Error, no slot of name " + target_slot - ); - } - return null; - } - } else if (target_slot === LiteGraph.EVENT) { - - if (LiteGraph.do_add_triggers_slots){ - //search for first slot with event? :: NO this is done outside - //console.log("Connect: Creating triggerEvent"); - // force mode - target_node.changeMode(LiteGraph.ON_TRIGGER); - target_slot = target_node.findInputSlot("onTrigger"); - }else{ - return null; // -- break -- - } - } else if ( - !target_node.inputs || - target_slot >= target_node.inputs.length - ) { - if (LiteGraph.debug) { - console.log("Connect: Error, slot number not found"); - } - return null; - } - - var changed = false; - - var input = target_node.inputs[target_slot]; - var link_info = null; - var output = this.outputs[slot]; - - if (!this.outputs[slot]){ - /*console.debug("Invalid slot passed: "+slot); - console.debug(this.outputs);*/ - return null; - } - - // allow target node to change slot - if (target_node.onBeforeConnectInput) { - // This way node can choose another slot (or make a new one?) - target_slot = target_node.onBeforeConnectInput(target_slot); //callback - } - - //check target_slot and check connection types - if (target_slot===false || target_slot===null || !LiteGraph.isValidConnection(output.type, input.type)) - { - this.setDirtyCanvas(false, true); - if(changed) - this.graph.connectionChange(this, link_info); - return null; - }else{ - //console.debug("valid connection",output.type, input.type); - } - - //allows nodes to block connection, callback - if (target_node.onConnectInput) { - if ( target_node.onConnectInput(target_slot, output.type, output, this, slot) === false ) { - return null; - } - } - if (this.onConnectOutput) { // callback - if ( this.onConnectOutput(slot, input.type, input, target_node, target_slot) === false ) { - return null; - } - } - - //if there is something already plugged there, disconnect - if (target_slot !== 0 && target_node.inputs[target_slot] && target_node.inputs[target_slot].link != null) { //MODDED target_slot !== 0 - this.graph.beforeChange(); - target_node.disconnectInput(target_slot, {doProcessChange: false}); - changed = true; - } - if (output.links !== null && output.links.length){ - switch(output.type){ - case LiteGraph.EVENT: - if (!LiteGraph.allow_multi_output_for_events){ - this.graph.beforeChange(); - this.disconnectOutput(slot, false, {doProcessChange: false}); // Input(target_slot, {doProcessChange: false}); - changed = true; - } - break; - default: - break; - } - } - - //create link class - link_info = new LLink( - ++this.graph.last_link_id, - input.type || output.type, - this.id, - slot, - target_node.id, - target_slot - ); - - //add to graph links list - this.graph.links[link_info.id] = link_info; - - //connect in output - if (output.links == null) { - output.links = []; - } - - output.links.push(link_info.id); - - //MODDED - //connect in input - if(target_node.inputs[target_slot].name === execPin && target_node.inputs[target_slot].link) { - let i = 0; - //custom code to handle extra input links on slot zero, treated as an execution slot - if(!target_node.inputs[target_slot].extraLinks) - target_node.inputs[target_slot].extraLinks = {}; - - target_node.inputs[target_slot].extraLinks[link_info.id] = link_info.id; - } - else target_node.inputs[target_slot].link = link_info.id; - - if (this.graph) { - this.graph._version++; - } - if (this.onConnectionsChange) { - this.onConnectionsChange( - LiteGraph.OUTPUT, - slot, - true, - link_info, - output - ); - } //link_info has been created now, so its updated - if (target_node.onConnectionsChange) { - target_node.onConnectionsChange( - LiteGraph.INPUT, - target_slot, - true, - link_info, - input - ); - } - if (this.graph && this.graph.onNodeConnectionChange) { - this.graph.onNodeConnectionChange( - LiteGraph.INPUT, - target_node, - target_slot, - this, - slot - ); - this.graph.onNodeConnectionChange( - LiteGraph.OUTPUT, - this, - slot, - target_node, - target_slot - ); - } - - this.setDirtyCanvas(false, true); - this.graph.afterChange(); - this.graph.connectionChange(this, link_info); - - return link_info; - }; - - /** - * disconnect one output to an specific node - * @method disconnectOutput - * @param {number_or_string} slot (could be the number of the slot or the string with the name of the 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 successfully - */ - LGraphNode.prototype.disconnectOutput = function(slot, target_node) { - this.console.log('disconnect', slot, target_node); - if (slot.constructor === String) { - slot = this.findOutputSlot(slot); - if (slot == -1) { - if (LiteGraph.debug) { - console.log("Connect: Error, no slot of name " + slot); - } - return false; - } - } else if (!this.outputs || slot >= this.outputs.length) { - if (LiteGraph.debug) { - console.log("Connect: Error, slot number not found"); - } - return false; - } - - //get output slot - var output = this.outputs[slot]; - if (!output || !output.links || output.links.length == 0) { - return false; - } - - //one of the output links in this slot - if (target_node) { - if (target_node.constructor === Number) { - target_node = this.graph.getNodeById(target_node); - } - if (!target_node) { - throw "Target Node not found"; - } - - for (var i = 0, l = output.links.length; i < l; i++) { - var link_id = output.links[i]; - var link_info = this.graph.links[link_id]; - - //is the link we are searching for... - if (link_info.target_id == target_node.id) { - output.links.splice(i, 1); //remove here - var input = target_node.inputs[link_info.target_slot]; - input.link = null; //remove there - delete this.graph.links[link_id]; //remove the link from the links pool - if (this.graph) { - this.graph._version++; - } - if (target_node.onConnectionsChange) { - target_node.onConnectionsChange( - LiteGraph.INPUT, - link_info.target_slot, - false, - link_info, - input - ); - } //link_info hasn't been modified so its ok - if (this.onConnectionsChange) { - this.onConnectionsChange( - LiteGraph.OUTPUT, - slot, - false, - link_info, - output - ); - } - if (this.graph && this.graph.onNodeConnectionChange) { - this.graph.onNodeConnectionChange( - LiteGraph.OUTPUT, - this, - slot - ); - } - if (this.graph && this.graph.onNodeConnectionChange) { - this.graph.onNodeConnectionChange( - LiteGraph.OUTPUT, - this, - slot - ); - this.graph.onNodeConnectionChange( - LiteGraph.INPUT, - target_node, - link_info.target_slot - ); - } - break; - } - } - } //all the links in this output slot - else { - for (var i = 0, l = output.links.length; i < l; i++) { - var link_id = output.links[i]; - var link_info = this.graph.links[link_id]; - if (!link_info) { - //bug: it happens sometimes - continue; - } - - var target_node = this.graph.getNodeById(link_info.target_id); - var input = null; - if (this.graph) { - this.graph._version++; - } - if (target_node) { - input = target_node.inputs[link_info.target_slot]; - input.link = null; //remove other side link - if (target_node.onConnectionsChange) { - target_node.onConnectionsChange( - LiteGraph.INPUT, - link_info.target_slot, - false, - link_info, - input - ); - } //link_info hasn't been modified so its ok - if (this.graph && this.graph.onNodeConnectionChange) { - this.graph.onNodeConnectionChange( - LiteGraph.INPUT, - target_node, - link_info.target_slot - ); - } - } - delete this.graph.links[link_id]; //remove the link from the links pool - if (this.onConnectionsChange) { - this.onConnectionsChange( - LiteGraph.OUTPUT, - slot, - false, - link_info, - output - ); - } - if (this.graph && this.graph.onNodeConnectionChange) { - this.graph.onNodeConnectionChange( - LiteGraph.OUTPUT, - this, - slot - ); - this.graph.onNodeConnectionChange( - LiteGraph.INPUT, - target_node, - link_info.target_slot - ); - } - } - output.links = null; - } - - this.setDirtyCanvas(false, true); - this.graph.connectionChange(this); - return true; - }; - - /** - * disconnect one input - * @method disconnectInput - * @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 successfully - */ - LGraphNode.prototype.disconnectInput = function(slot) { - //seek for the output slot - if (slot.constructor === String) { - slot = this.findInputSlot(slot); - if (slot == -1) { - if (LiteGraph.debug) { - console.log("Connect: Error, no slot of name " + slot); - } - return false; - } - } else if (!this.inputs || slot >= this.inputs.length) { - if (LiteGraph.debug) { - console.log("Connect: Error, slot number not found"); - } - return false; - } - - var input = this.inputs[slot]; - if (!input) { - return false; - } - - const removeLinkId = (link_id) => { - - //remove other side - var link_info = this.graph.links[link_id]; - if (link_info) { - var target_node = this.graph.getNodeById(link_info.origin_id); - if (!target_node) { - return false; - } - - var output = target_node.outputs[link_info.origin_slot]; - if (!output || !output.links || output.links.length == 0) { - return false; - } - - //search in the inputs list for this link - for (var i = 0, l = output.links.length; i < l; i++) { - if (output.links[i] == link_id) { - output.links.splice(i, 1); - break; - } - } - - delete this.graph.links[link_id]; //remove from the pool - if (this.graph) { - this.graph._version++; - } - if (this.onConnectionsChange) { - this.onConnectionsChange( - LiteGraph.INPUT, - slot, - false, - link_info, - input - ); - } - if (target_node.onConnectionsChange) { - target_node.onConnectionsChange( - LiteGraph.OUTPUT, - i, - false, - link_info, - output - ); - } - if (this.graph && this.graph.onNodeConnectionChange) { - this.graph.onNodeConnectionChange( - LiteGraph.OUTPUT, - target_node, - i - ); - this.graph.onNodeConnectionChange(LiteGraph.INPUT, this, slot); - } - } - } - - var link_id = this.inputs[slot].link; - if(link_id != null) - { - this.inputs[slot].link = null; - removeLinkId(link_id); - if(this.inputs[slot].extraLinks) { - for(const key in this.inputs[slot].extraLinks) { - removeLinkId(key); - } - delete this.inputs[slot].extraLinks; - } - } //link != null - - this.setDirtyCanvas(false, true); - if(this.graph) - this.graph.connectionChange(this); - return true; - }; - - /** - * returns the center of a connection point in canvas coords - * @method getConnectionPos - * @param {boolean} is_input true if if a input slot, false if it is an output - * @param {number_or_string} slot (could be the number of the slot or the string with the name of the slot) - * @param {vec2} out [optional] a place to store the output, to free garbage - * @return {[x,y]} the position - **/ - LGraphNode.prototype.getConnectionPos = function( - is_input, - slot_number, - out - ) { - out = out || new Float32Array(2); - var num_slots = 0; - if (is_input && this.inputs) { - num_slots = this.inputs.length; - } - if (!is_input && this.outputs) { - num_slots = this.outputs.length; - } - - var offset = LiteGraph.NODE_SLOT_HEIGHT * 0.5; - - if (this.flags.collapsed) { - var w = this._collapsed_width || LiteGraph.NODE_COLLAPSED_WIDTH; - if (this.horizontal) { - out[0] = this.pos[0] + w * 0.5; - if (is_input) { - out[1] = this.pos[1] - LiteGraph.NODE_TITLE_HEIGHT; - } else { - out[1] = this.pos[1]; - } - } else { - if (is_input) { - out[0] = this.pos[0]; - } else { - out[0] = this.pos[0] + w; - } - out[1] = this.pos[1] - LiteGraph.NODE_TITLE_HEIGHT * 0.5; - } - return out; - } - - //weird feature that never got finished - if (is_input && slot_number == -1) { - out[0] = this.pos[0] + LiteGraph.NODE_TITLE_HEIGHT * 0.5; - out[1] = this.pos[1] + LiteGraph.NODE_TITLE_HEIGHT * 0.5; - return out; - } - - //hard-coded pos - if ( - is_input && - num_slots > slot_number && - this.inputs[slot_number].pos - ) { - out[0] = this.pos[0] + this.inputs[slot_number].pos[0]; - out[1] = this.pos[1] + this.inputs[slot_number].pos[1]; - return out; - } else if ( - !is_input && - num_slots > slot_number && - this.outputs[slot_number].pos - ) { - out[0] = this.pos[0] + this.outputs[slot_number].pos[0]; - out[1] = this.pos[1] + this.outputs[slot_number].pos[1]; - return out; - } - - //horizontal distributed slots - if (this.horizontal) { - out[0] = - this.pos[0] + (slot_number + 0.5) * (this.size[0] / num_slots); - if (is_input) { - out[1] = this.pos[1] - LiteGraph.NODE_TITLE_HEIGHT; - } else { - out[1] = this.pos[1] + this.size[1]; - } - return out; - } - - //default vertical slots - if (is_input) { - out[0] = this.pos[0] + offset; - } else { - out[0] = this.pos[0] + this.size[0] + 1 - offset; - } - out[1] = - this.pos[1] + - (slot_number + 0.7) * LiteGraph.NODE_SLOT_HEIGHT + - (this.constructor.slot_start_y || 0); - return out; - }; - - /* Force align to grid */ - 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); - }; - - /* Console output */ - LGraphNode.prototype.trace = function(msg) { - if (!this.console) { - this.console = []; - } - - this.console.push(msg); - if (this.console.length > LGraphNode.MAX_CONSOLE) { - this.console.shift(); - } - - if(this.graph.onNodeTrace) - this.graph.onNodeTrace(this, msg); - }; - - /* Forces to redraw or the main canvas (LGraphNode) or the bg canvas (links) */ - LGraphNode.prototype.setDirtyCanvas = function( - dirty_foreground, - dirty_background - ) { - if (!this.graph) { - return; - } - this.graph.sendActionToCanvas("setDirty", [ - dirty_foreground, - dirty_background - ]); - }; - - LGraphNode.prototype.loadImage = function(url) { - var img = new Image(); - img.src = LiteGraph.node_images_path + url; - img.ready = false; - - var that = this; - img.onload = function() { - this.ready = true; - that.setDirtyCanvas(true); - }; - return img; - }; - - //safe LGraphNode action execution (not sure if safe) - /* -LGraphNode.prototype.executeAction = function(action) -{ - if(action == "") return false; - - if( action.indexOf(";") != -1 || action.indexOf("}") != -1) - { - this.trace("Error: Action contains unsafe characters"); - return false; - } - - var tokens = action.split("("); - var func_name = tokens[0]; - if( typeof(this[func_name]) != "function") - { - this.trace("Error: Action not found on node: " + func_name); - return false; - } - - var code = action; - - try - { - var _foo = eval; - eval = null; - (new Function("with(this) { " + code + "}")).call(this); - eval = _foo; - } - catch (err) - { - this.trace("Error executing action {" + action + "} :" + err); - return false; - } - - return true; -} -*/ - - /* Allows to get onMouseMove and onMouseUp events even if the mouse is out of focus */ - LGraphNode.prototype.captureInput = function(v) { - if (!this.graph || !this.graph.list_of_graphcanvas) { - return; - } - - var list = this.graph.list_of_graphcanvas; - - for (var i = 0; i < list.length; ++i) { - var c = list[i]; - //releasing somebody elses capture?! - if (!v && c.node_capturing_input != this) { - continue; - } - - //change - c.node_capturing_input = v ? this : null; - } - }; - - /** - * Collapse the node to make it smaller on the canvas - * @method collapse - **/ - LGraphNode.prototype.collapse = function(force) { - this.graph._version++; - if (this.constructor.collapsable === false && !force) { - return; - } - if (!this.flags.collapsed) { - this.flags.collapsed = true; - } else { - this.flags.collapsed = false; - } - this.setDirtyCanvas(true, true); - }; - - /** - * Forces the node to do not move or realign on Z - * @method pin - **/ - - LGraphNode.prototype.pin = function(v) { - this.graph._version++; - if (v === undefined) { - this.flags.pinned = !this.flags.pinned; - } else { - this.flags.pinned = v; - } - }; - - LGraphNode.prototype.localToScreen = function(x, y, graphcanvas) { - return [ - (x + this.pos[0]) * graphcanvas.scale + graphcanvas.offset[0], - (y + this.pos[1]) * graphcanvas.scale + graphcanvas.offset[1] - ]; - }; - - function LGraphGroup(title) { - this._ctor(title); - } - - global.LGraphGroup = LiteGraph.LGraphGroup = LGraphGroup; - - LGraphGroup.prototype._ctor = function(title) { - this.title = title || "Group"; - this.font_size = 24; - this.color = LGraphCanvas.node_colors.pale_blue - ? LGraphCanvas.node_colors.pale_blue.groupcolor - : "#AAA"; - this._bounding = new Float32Array([10, 10, 140, 80]); - this._pos = this._bounding.subarray(0, 2); - this._size = this._bounding.subarray(2, 4); - this._nodes = []; - this.graph = null; - - Object.defineProperty(this, "pos", { - set: function(v) { - if (!v || v.length < 2) { - return; - } - this._pos[0] = v[0]; - this._pos[1] = v[1]; - }, - get: function() { - return this._pos; - }, - enumerable: true - }); - - Object.defineProperty(this, "size", { - set: function(v) { - if (!v || v.length < 2) { - return; - } - this._size[0] = Math.max(140, v[0]); - this._size[1] = Math.max(80, v[1]); - }, - get: function() { - return this._size; - }, - enumerable: true - }); - }; - - LGraphGroup.prototype.configure = function(o) { - this.title = o.title; - this._bounding.set(o.bounding); - this.color = o.color; - this.font = o.font; - }; - - LGraphGroup.prototype.serialize = function() { - var b = this._bounding; - return { - title: this.title, - bounding: [ - Math.round(b[0]), - Math.round(b[1]), - Math.round(b[2]), - Math.round(b[3]) - ], - color: this.color, - font: this.font - }; - }; - - LGraphGroup.prototype.move = function(deltax, deltay, ignore_nodes) { - this._pos[0] += deltax; - this._pos[1] += deltay; - if (ignore_nodes) { - return; - } - for (var i = 0; i < this._nodes.length; ++i) { - var node = this._nodes[i]; - node.pos[0] += deltax; - node.pos[1] += deltay; - } - }; - - LGraphGroup.prototype.recomputeInsideNodes = function() { - this._nodes.length = 0; - var nodes = this.graph._nodes; - var node_bounding = new Float32Array(4); - - for (var i = 0; i < nodes.length; ++i) { - var node = nodes[i]; - node.getBounding(node_bounding); - if (!overlapBounding(this._bounding, node_bounding)) { - continue; - } //out of the visible area - this._nodes.push(node); - } - }; - - LGraphGroup.prototype.isPointInside = LGraphNode.prototype.isPointInside; - LGraphGroup.prototype.setDirtyCanvas = LGraphNode.prototype.setDirtyCanvas; - - //**************************************** - - //Scale and Offset - function DragAndScale(element, skip_events) { - this.offset = new Float32Array([0, 0]); - this.scale = 1; - this.max_scale = 10; - this.min_scale = 0.1; - this.onredraw = null; - this.enabled = true; - this.last_mouse = [0, 0]; - this.element = null; - this.visible_area = new Float32Array(4); - - if (element) { - this.element = element; - if (!skip_events) { - this.bindEvents(element); - } - } - } - - LiteGraph.DragAndScale = DragAndScale; - - DragAndScale.prototype.bindEvents = function(element) { - this.last_mouse = new Float32Array(2); - - this._binded_mouse_callback = this.onMouse.bind(this); - - LiteGraph.pointerListenerAdd(element,"down", this._binded_mouse_callback); - LiteGraph.pointerListenerAdd(element,"move", this._binded_mouse_callback); - LiteGraph.pointerListenerAdd(element,"up", this._binded_mouse_callback); - - element.addEventListener( - "mousewheel", - this._binded_mouse_callback, - false - ); - element.addEventListener("wheel", this._binded_mouse_callback, false); - }; - - DragAndScale.prototype.computeVisibleArea = function( viewport ) { - if (!this.element) { - this.visible_area[0] = this.visible_area[1] = this.visible_area[2] = this.visible_area[3] = 0; - return; - } - var width = this.element.width; - var height = this.element.height; - var startx = -this.offset[0]; - var starty = -this.offset[1]; - if( viewport ) - { - startx += viewport[0] / this.scale; - starty += viewport[1] / this.scale; - width = viewport[2]; - height = viewport[3]; - } - var endx = startx + width / this.scale; - var endy = starty + height / this.scale; - this.visible_area[0] = startx; - this.visible_area[1] = starty; - this.visible_area[2] = endx - startx; - this.visible_area[3] = endy - starty; - }; - - DragAndScale.prototype.onMouse = function(e) { - if (!this.enabled) { - return; - } - - var canvas = this.element; - var rect = canvas.getBoundingClientRect(); - var x = e.clientX - rect.left; - var y = e.clientY - rect.top; - e.canvasx = x; - e.canvasy = y; - e.dragging = this.dragging; - - var is_inside = !this.viewport || ( this.viewport && x >= this.viewport[0] && x < (this.viewport[0] + this.viewport[2]) && y >= this.viewport[1] && y < (this.viewport[1] + this.viewport[3]) ); - - //console.log("pointerevents: DragAndScale onMouse "+e.type+" "+is_inside); - - var ignore = false; - if (this.onmouse) { - ignore = this.onmouse(e); - } - - if (e.type == LiteGraph.pointerevents_method+"down" && is_inside) { - this.dragging = true; - LiteGraph.pointerListenerRemove(canvas,"move",this._binded_mouse_callback); - LiteGraph.pointerListenerAdd(document,"move",this._binded_mouse_callback); - LiteGraph.pointerListenerAdd(document,"up",this._binded_mouse_callback); - } else if (e.type == LiteGraph.pointerevents_method+"move") { - if (!ignore) { - var deltax = x - this.last_mouse[0]; - var deltay = y - this.last_mouse[1]; - if (this.dragging) { - this.mouseDrag(deltax, deltay); - } - } - } else if (e.type == LiteGraph.pointerevents_method+"up") { - this.dragging = false; - LiteGraph.pointerListenerRemove(document,"move",this._binded_mouse_callback); - LiteGraph.pointerListenerRemove(document,"up",this._binded_mouse_callback); - LiteGraph.pointerListenerAdd(canvas,"move",this._binded_mouse_callback); - } else if ( is_inside && - (e.type == "mousewheel" || - e.type == "wheel" || - e.type == "DOMMouseScroll") - ) { - e.eventType = "mousewheel"; - if (e.type == "wheel") { - e.wheel = -e.deltaY; - } else { - e.wheel = - e.wheelDeltaY != null ? e.wheelDeltaY : e.detail * -60; - } - - //from stack overflow - e.delta = e.wheelDelta - ? e.wheelDelta / 40 - : e.deltaY - ? -e.deltaY / 3 - : 0; - this.changeDeltaScale(1.0 + e.delta * 0.05); - } - - this.last_mouse[0] = x; - this.last_mouse[1] = y; - - if(is_inside) - { - e.preventDefault(); - e.stopPropagation(); - return false; - } - }; - - DragAndScale.prototype.toCanvasContext = function(ctx) { - ctx.scale(this.scale, this.scale); - ctx.translate(this.offset[0], this.offset[1]); - }; - - DragAndScale.prototype.convertOffsetToCanvas = function(pos) { - //return [pos[0] / this.scale - this.offset[0], pos[1] / this.scale - this.offset[1]]; - return [ - (pos[0] + this.offset[0]) * this.scale, - (pos[1] + this.offset[1]) * this.scale - ]; - }; - - DragAndScale.prototype.convertCanvasToOffset = function(pos, out) { - out = out || [0, 0]; - out[0] = pos[0] / this.scale - this.offset[0]; - out[1] = pos[1] / this.scale - this.offset[1]; - return out; - }; - - DragAndScale.prototype.mouseDrag = function(x, y) { - this.offset[0] += x / this.scale; - this.offset[1] += y / this.scale; - - if (this.onredraw) { - this.onredraw(this); - } - }; - - DragAndScale.prototype.changeScale = function(value, zooming_center) { - if (value < this.min_scale) { - value = this.min_scale; - } else if (value > this.max_scale) { - value = this.max_scale; - } - - if (value == this.scale) { - return; - } - - if (!this.element) { - return; - } - - var rect = this.element.getBoundingClientRect(); - if (!rect) { - return; - } - - zooming_center = zooming_center || [ - rect.width * 0.5, - rect.height * 0.5 - ]; - var center = this.convertCanvasToOffset(zooming_center); - this.scale = value; - if (Math.abs(this.scale - 1) < 0.01) { - this.scale = 1; - } - - var new_center = this.convertCanvasToOffset(zooming_center); - var delta_offset = [ - new_center[0] - center[0], - new_center[1] - center[1] - ]; - - this.offset[0] += delta_offset[0]; - this.offset[1] += delta_offset[1]; - - if (this.onredraw) { - this.onredraw(this); - } - }; - - DragAndScale.prototype.changeDeltaScale = function(value, zooming_center) { - this.changeScale(this.scale * value, zooming_center); - }; - - DragAndScale.prototype.reset = function() { - this.scale = 1; - this.offset[0] = 0; - this.offset[1] = 0; - }; - - //********************************************************************************* - // LGraphCanvas: LGraph renderer CLASS - //********************************************************************************* - - /** - * This class is in charge of rendering one graph inside a canvas. And provides all the interaction required. - * Valid callbacks are: onNodeSelected, onNodeDeselected, onShowNodePanel, onNodeDblClicked - * - * @class LGraphCanvas - * @constructor - * @param {HTMLCanvas} canvas the canvas where you want to render (it accepts a selector in string format or the canvas element itself) - * @param {LGraph} graph [optional] - * @param {Object} options [optional] { skip_rendering, autoresize, viewport } - */ - function LGraphCanvas(canvas, graph, options) { - this.options = options = options || {}; - - //if(graph === undefined) - // throw ("No graph assigned"); - this.background_image = LGraphCanvas.DEFAULT_BACKGROUND_IMAGE; - - if (canvas && canvas.constructor === String) { - canvas = document.querySelector(canvas); - } - - this.ds = new DragAndScale(); - this.zoom_modify_alpha = true; //otherwise it generates ugly patterns when scaling down too much - - this.title_text_font = "" + LiteGraph.NODE_TEXT_SIZE + "px Arial"; - this.inner_text_font = - "normal " + LiteGraph.NODE_SUBTEXT_SIZE + "px Arial"; - this.node_title_color = LiteGraph.NODE_TITLE_COLOR; - this.default_link_color = LiteGraph.LINK_COLOR; - this.default_connection_color = { - input_off: "#778", - input_on: "#7F7", //"#BBD" - output_off: "#778", - output_on: "#7F7" //"#BBD" - }; - this.default_connection_color_byType = { - /*number: "#7F7", - string: "#77F", - boolean: "#F77",*/ - } - this.default_connection_color_byTypeOff = { - /*number: "#474", - string: "#447", - boolean: "#744",*/ - }; - - this.highquality_render = true; - this.use_gradients = false; //set to true to render titlebar with gradients - this.editor_alpha = 1; //used for transition - this.pause_rendering = false; - this.clear_background = true; - this.clear_background_color = "#222"; - - this.read_only = false; //if set to true users cannot modify the graph - this.render_only_selected = true; - this.live_mode = false; - this.show_info = true; - this.allow_dragcanvas = true; - this.allow_dragnodes = true; - this.allow_interaction = true; //allow to control widgets, buttons, collapse, etc - this.multi_select = false; //allow selecting multi nodes without pressing extra keys - this.allow_searchbox = true; - this.allow_reconnect_links = true; //allows to change a connection with having to redo it again - this.align_to_grid = false; //snap to grid - - this.drag_mode = false; - this.dragging_rectangle = null; - - this.filter = null; //allows to filter to only accept some type of nodes in a graph - - this.set_canvas_dirty_on_mouse_event = true; //forces to redraw the canvas if the mouse does anything - this.always_render_background = false; - this.render_shadows = true; - this.render_canvas_border = true; - this.render_connections_shadows = false; //too much cpu - this.render_connections_border = true; - this.render_curved_connections = false; - this.render_connection_arrows = false; - this.render_collapsed_slots = true; - this.render_execution_order = false; - this.render_title_colored = true; - this.render_link_tooltip = true; - - this.links_render_mode = LiteGraph.SPLINE_LINK; - - this.mouse = [0, 0]; //mouse in canvas coordinates, where 0,0 is the top-left corner of the blue rectangle - this.graph_mouse = [0, 0]; //mouse in graph coordinates, where 0,0 is the top-left corner of the blue rectangle - this.canvas_mouse = this.graph_mouse; //LEGACY: REMOVE THIS, USE GRAPH_MOUSE INSTEAD - - //to personalize the search box - this.onSearchBox = null; - this.onSearchBoxSelection = null; - - //callbacks - this.onMouse = null; - this.onDrawBackground = null; //to render background objects (behind nodes and connections) in the canvas affected by transform - this.onDrawForeground = null; //to render foreground objects (above nodes and connections) in the canvas affected by transform - this.onDrawOverlay = null; //to render foreground objects not affected by transform (for GUIs) - this.onDrawLinkTooltip = null; //called when rendering a tooltip - this.onNodeMoved = null; //called after moving a node - this.onSelectionChange = null; //called if the selection changes - this.onConnectingChange = null; //called before any link changes - this.onBeforeChange = null; //called before modifying the graph - this.onAfterChange = null; //called after modifying the graph - - this.connections_width = 3; - this.round_radius = 8; - - this.current_node = null; - this.node_widget = null; //used for widgets - this.over_link_center = null; - this.last_mouse_position = [0, 0]; - this.visible_area = this.ds.visible_area; - this.visible_links = []; - - this.viewport = options.viewport || null; //to constraint render area to a portion of the canvas - - //link canvas and graph - if (graph) { - graph.attachCanvas(this); - } - - this.setCanvas(canvas,options.skip_events); - this.clear(); - - if (!options.skip_render) { - this.startRendering(); - } - - this.autoresize = options.autoresize; - } - - global.LGraphCanvas = LiteGraph.LGraphCanvas = LGraphCanvas; - - LGraphCanvas.DEFAULT_BACKGROUND_IMAGE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQBJREFUeNrs1rEKwjAUhlETUkj3vP9rdmr1Ysammk2w5wdxuLgcMHyptfawuZX4pJSWZTnfnu/lnIe/jNNxHHGNn//HNbbv+4dr6V+11uF527arU7+u63qfa/bnmh8sWLBgwYJlqRf8MEptXPBXJXa37BSl3ixYsGDBMliwFLyCV/DeLIMFCxYsWLBMwSt4Be/NggXLYMGCBUvBK3iNruC9WbBgwYJlsGApeAWv4L1ZBgsWLFiwYJmCV/AK3psFC5bBggULloJX8BpdwXuzYMGCBctgwVLwCl7Be7MMFixYsGDBsu8FH1FaSmExVfAxBa/gvVmwYMGCZbBg/W4vAQYA5tRF9QYlv/QAAAAASUVORK5CYII="; - - LGraphCanvas.link_type_colors = { - "-1": LiteGraph.EVENT_LINK_COLOR, - number: "#AAA", - node: "#DCA" - }; - LGraphCanvas.gradients = {}; //cache of gradients - - /** - * clears all the data inside - * - * @method clear - */ - LGraphCanvas.prototype.clear = function() { - this.frame = 0; - this.last_draw_time = 0; - this.render_time = 0; - this.fps = 0; - - //this.scale = 1; - //this.offset = [0,0]; - - this.dragging_rectangle = null; - - this.selected_nodes = {}; - this.selected_group = null; - - this.visible_nodes = []; - this.node_dragged = null; - this.node_over = null; - this.node_capturing_input = null; - this.connecting_node = null; - this.highlighted_links = {}; - - this.dragging_canvas = false; - - this.dirty_canvas = true; - this.dirty_bgcanvas = true; - this.dirty_area = null; - - this.node_in_panel = null; - this.node_widget = null; - - this.last_mouse = [0, 0]; - this.last_mouseclick = 0; - this.pointer_is_down = false; - this.pointer_is_double = false; - this.visible_area.set([0, 0, 0, 0]); - - if (this.onClear) { - this.onClear(); - } - }; - - /** - * assigns a graph, you can reassign graphs to the same canvas - * - * @method setGraph - * @param {LGraph} graph - */ - LGraphCanvas.prototype.setGraph = function(graph, skip_clear) { - if (this.graph == graph) { - return; - } - - if (!skip_clear) { - this.clear(); - } - - if (!graph && this.graph) { - this.graph.detachCanvas(this); - return; - } - - graph.attachCanvas(this); - - //remove the graph stack in case a subgraph was open - if (this._graph_stack) - this._graph_stack = null; - - this.setDirty(true, true); - }; - - /** - * returns the top level graph (in case there are subgraphs open on the canvas) - * - * @method getTopGraph - * @return {LGraph} graph - */ - LGraphCanvas.prototype.getTopGraph = function() - { - if(this._graph_stack.length) - return this._graph_stack[0]; - return this.graph; - } - - /** - * opens a graph contained inside a node in the current graph - * - * @method openSubgraph - * @param {LGraph} graph - */ - LGraphCanvas.prototype.openSubgraph = function(graph) { - if (!graph) { - throw "graph cannot be null"; - } - - if (this.graph == graph) { - throw "graph cannot be the same"; - } - - this.clear(); - - if (this.graph) { - if (!this._graph_stack) { - this._graph_stack = []; - } - this._graph_stack.push(this.graph); - } - - graph.attachCanvas(this); - this.checkPanels(); - this.setDirty(true, true); - }; - - /** - * closes a subgraph contained inside a node - * - * @method closeSubgraph - * @param {LGraph} assigns a graph - */ - LGraphCanvas.prototype.closeSubgraph = function() { - if (!this._graph_stack || this._graph_stack.length == 0) { - return; - } - var subgraph_node = this.graph._subgraph_node; - var graph = this._graph_stack.pop(); - this.selected_nodes = {}; - this.highlighted_links = {}; - graph.attachCanvas(this); - this.setDirty(true, true); - if (subgraph_node) { - this.centerOnNode(subgraph_node); - this.selectNodes([subgraph_node]); - } - // when close sub graph back to offset [0, 0] scale 1 - this.ds.offset = [0, 0] - this.ds.scale = 1 - }; - - /** - * returns the visually active graph (in case there are more in the stack) - * @method getCurrentGraph - * @return {LGraph} the active graph - */ - LGraphCanvas.prototype.getCurrentGraph = function() { - return this.graph; - }; - - /** - * assigns a canvas - * - * @method setCanvas - * @param {Canvas} assigns a canvas (also accepts the ID of the element (not a selector) - */ - LGraphCanvas.prototype.setCanvas = function(canvas, skip_events) { - var that = this; - - if (canvas) { - if (canvas.constructor === String) { - canvas = document.getElementById(canvas); - if (!canvas) { - throw "Error creating LiteGraph canvas: Canvas not found"; - } - } - } - - if (canvas === this.canvas) { - return; - } - - if (!canvas && this.canvas) { - //maybe detach events from old_canvas - if (!skip_events) { - this.unbindEvents(); - } - } - - this.canvas = canvas; - this.ds.element = canvas; - - if (!canvas) { - return; - } - - //this.canvas.tabindex = "1000"; - canvas.className += " lgraphcanvas"; - canvas.data = this; - canvas.tabindex = "1"; //to allow key events - - //bg canvas: used for non changing stuff - this.bgcanvas = null; - if (!this.bgcanvas) { - this.bgcanvas = document.createElement("canvas"); - this.bgcanvas.width = this.canvas.width; - this.bgcanvas.height = this.canvas.height; - } - - if (canvas.getContext == null) { - if (canvas.localName != "canvas") { - throw "Element supplied for LGraphCanvas must be a element, you passed a " + - canvas.localName; - } - throw "This browser doesn't support Canvas"; - } - - var ctx = (this.ctx = canvas.getContext("2d")); - if (ctx == null) { - if (!canvas.webgl_enabled) { - console.warn( - "This canvas seems to be WebGL, enabling WebGL renderer" - ); - } - this.enableWebGL(); - } - - //input: (move and up could be unbinded) - // why here? this._mousemove_callback = this.processMouseMove.bind(this); - // why here? this._mouseup_callback = this.processMouseUp.bind(this); - - if (!skip_events) { - this.bindEvents(); - } - }; - - //used in some events to capture them - LGraphCanvas.prototype._doNothing = function doNothing(e) { - //console.log("pointerevents: _doNothing "+e.type); - e.preventDefault(); - return false; - }; - LGraphCanvas.prototype._doReturnTrue = function doNothing(e) { - e.preventDefault(); - return true; - }; - - /** - * binds mouse, keyboard, touch and drag events to the canvas - * @method bindEvents - **/ - LGraphCanvas.prototype.bindEvents = function() { - if (this._events_binded) { - console.warn("LGraphCanvas: events already binded"); - return; - } - - //console.log("pointerevents: bindEvents"); - - var canvas = this.canvas; - - var ref_window = this.getCanvasWindow(); - var document = ref_window.document; //hack used when moving canvas between windows - - this._mousedown_callback = this.processMouseDown.bind(this); - this._mousewheel_callback = this.processMouseWheel.bind(this); - // why mousemove and mouseup were not binded here? - this._mousemove_callback = this.processMouseMove.bind(this); - this._mouseup_callback = this.processMouseUp.bind(this); - - //touch events -- TODO IMPLEMENT - //this._touch_callback = this.touchHandler.bind(this); - - LiteGraph.pointerListenerAdd(canvas,"down", this._mousedown_callback, true); //down do not need to store the binded - canvas.addEventListener("mousewheel", this._mousewheel_callback, false); - - LiteGraph.pointerListenerAdd(canvas,"up", this._mouseup_callback, true); // CHECK: ??? binded or not - LiteGraph.pointerListenerAdd(canvas,"move", this._mousemove_callback); - - canvas.addEventListener("contextmenu", this._doNothing); - canvas.addEventListener( - "DOMMouseScroll", - this._mousewheel_callback, - false - ); - - //touch events -- THIS WAY DOES NOT WORK, finish implementing pointerevents, than clean the touchevents - /*if( 'touchstart' in document.documentElement ) - { - canvas.addEventListener("touchstart", this._touch_callback, true); - canvas.addEventListener("touchmove", this._touch_callback, true); - canvas.addEventListener("touchend", this._touch_callback, true); - canvas.addEventListener("touchcancel", this._touch_callback, true); - }*/ - - //Keyboard ****************** - this._key_callback = this.processKey.bind(this); - - canvas.addEventListener("keydown", this._key_callback, true); - document.addEventListener("keyup", this._key_callback, true); //in document, otherwise it doesn't fire keyup - - //Dropping Stuff over nodes ************************************ - this._ondrop_callback = this.processDrop.bind(this); - - canvas.addEventListener("dragover", this._doNothing, false); - canvas.addEventListener("dragend", this._doNothing, false); - canvas.addEventListener("drop", this._ondrop_callback, false); - canvas.addEventListener("dragenter", this._doReturnTrue, false); - - this._events_binded = true; - }; - - /** - * unbinds mouse events from the canvas - * @method unbindEvents - **/ - LGraphCanvas.prototype.unbindEvents = function() { - if (!this._events_binded) { - console.warn("LGraphCanvas: no events binded"); - return; - } - - //console.log("pointerevents: unbindEvents"); - - var ref_window = this.getCanvasWindow(); - var document = ref_window.document; - - LiteGraph.pointerListenerRemove(this.canvas,"move", this._mousedown_callback); - LiteGraph.pointerListenerRemove(this.canvas,"up", this._mousedown_callback); - LiteGraph.pointerListenerRemove(this.canvas,"down", this._mousedown_callback); - this.canvas.removeEventListener( - "mousewheel", - this._mousewheel_callback - ); - this.canvas.removeEventListener( - "DOMMouseScroll", - this._mousewheel_callback - ); - this.canvas.removeEventListener("keydown", this._key_callback); - document.removeEventListener("keyup", this._key_callback); - this.canvas.removeEventListener("contextmenu", this._doNothing); - this.canvas.removeEventListener("drop", this._ondrop_callback); - this.canvas.removeEventListener("dragenter", this._doReturnTrue); - - //touch events -- THIS WAY DOES NOT WORK, finish implementing pointerevents, than clean the touchevents - /*this.canvas.removeEventListener("touchstart", this._touch_callback ); - this.canvas.removeEventListener("touchmove", this._touch_callback ); - this.canvas.removeEventListener("touchend", this._touch_callback ); - this.canvas.removeEventListener("touchcancel", this._touch_callback );*/ - - this._mousedown_callback = null; - this._mousewheel_callback = null; - this._key_callback = null; - this._ondrop_callback = null; - - this._events_binded = false; - }; - - LGraphCanvas.getFileExtension = function(url) { - var question = url.indexOf("?"); - if (question != -1) { - url = url.substr(0, question); - } - var point = url.lastIndexOf("."); - if (point == -1) { - return ""; - } - return url.substr(point + 1).toLowerCase(); - }; - - /** - * this function allows to render the canvas using WebGL instead of Canvas2D - * this is useful if you plant to render 3D objects inside your nodes, it uses litegl.js for webgl and canvas2DtoWebGL to emulate the Canvas2D calls in webGL - * @method enableWebGL - **/ - LGraphCanvas.prototype.enableWebGL = function() { - if (typeof GL === undefined) { - throw "litegl.js must be included to use a WebGL canvas"; - } - if (typeof enableWebGLCanvas === undefined) { - throw "webglCanvas.js must be included to use this feature"; - } - - this.gl = this.ctx = enableWebGLCanvas(this.canvas); - this.ctx.webgl = true; - this.bgcanvas = this.canvas; - this.bgctx = this.gl; - this.canvas.webgl_enabled = true; - - /* - GL.create({ canvas: this.bgcanvas }); - this.bgctx = enableWebGLCanvas( this.bgcanvas ); - window.gl = this.gl; - */ - }; - - /** - * marks as dirty the canvas, this way it will be rendered again - * - * @class LGraphCanvas - * @method setDirty - * @param {bool} fgcanvas if the foreground canvas is dirty (the one containing the nodes) - * @param {bool} bgcanvas if the background canvas is dirty (the one containing the wires) - */ - LGraphCanvas.prototype.setDirty = function(fgcanvas, bgcanvas) { - if (fgcanvas) { - this.dirty_canvas = true; - } - if (bgcanvas) { - this.dirty_bgcanvas = true; - } - }; - - /** - * Used to attach the canvas in a popup - * - * @method getCanvasWindow - * @return {window} returns the window where the canvas is attached (the DOM root node) - */ - LGraphCanvas.prototype.getCanvasWindow = function() { - if (!this.canvas) { - return window; - } - var doc = this.canvas.ownerDocument; - return doc.defaultView || doc.parentWindow; - }; - - /** - * starts rendering the content of the canvas when needed - * - * @method startRendering - */ - LGraphCanvas.prototype.startRendering = function() { - if (this.is_rendering) { - return; - } //already rendering - - this.is_rendering = true; - renderFrame.call(this); - - function renderFrame() { - if (!this.pause_rendering) { - this.draw(); - } - - var window = this.getCanvasWindow(); - if (this.is_rendering) { - window.requestAnimationFrame(renderFrame.bind(this)); - } - } - }; - - /** - * stops rendering the content of the canvas (to save resources) - * - * @method stopRendering - */ - LGraphCanvas.prototype.stopRendering = function() { - this.is_rendering = false; - /* - if(this.rendering_timer_id) - { - clearInterval(this.rendering_timer_id); - this.rendering_timer_id = null; - } - */ - }; - - /* LiteGraphCanvas input */ - - //used to block future mouse events (because of im gui) - LGraphCanvas.prototype.blockClick = function() - { - this.block_click = true; - this.last_mouseclick = 0; - } - - LGraphCanvas.prototype.processMouseDown = function(e) { - - if( this.set_canvas_dirty_on_mouse_event ) - this.dirty_canvas = true; - - if (!this.graph) { - return; - } - - this.adjustMouseEvent(e); - - var ref_window = this.getCanvasWindow(); - var document = ref_window.document; - LGraphCanvas.active_canvas = this; - var that = this; - - var x = e.clientX; - var y = e.clientY; - //console.log(y,this.viewport); - //console.log("pointerevents: processMouseDown pointerId:"+e.pointerId+" which:"+e.which+" isPrimary:"+e.isPrimary+" :: x y "+x+" "+y); - - this.ds.viewport = this.viewport; - var is_inside = !this.viewport || ( this.viewport && x >= this.viewport[0] && x < (this.viewport[0] + this.viewport[2]) && y >= this.viewport[1] && y < (this.viewport[1] + this.viewport[3]) ); - - //move mouse move event to the window in case it drags outside of the canvas - if(!this.options.skip_events) - { - LiteGraph.pointerListenerRemove(this.canvas,"move", this._mousemove_callback); - LiteGraph.pointerListenerAdd(ref_window.document,"move", this._mousemove_callback,true); //catch for the entire window - LiteGraph.pointerListenerAdd(ref_window.document,"up", this._mouseup_callback,true); - } - - if(!is_inside){ - return; - } - - var node = this.graph.getNodeOnPos( e.canvasX, e.canvasY, this.visible_nodes, 5 ); - var skip_dragging = false; - var skip_action = false; - var now = LiteGraph.getTime(); - var is_primary = (e.isPrimary === undefined || !e.isPrimary); - var is_double_click = (now - this.last_mouseclick < 300) && is_primary; - this.mouse[0] = e.clientX; - this.mouse[1] = e.clientY; - this.graph_mouse[0] = e.canvasX; - this.graph_mouse[1] = e.canvasY; - this.last_click_position = [this.mouse[0],this.mouse[1]]; - - if (this.pointer_is_down && is_primary ){ - this.pointer_is_double = true; - //console.log("pointerevents: pointer_is_double start"); - }else{ - this.pointer_is_double = false; - } - this.pointer_is_down = true; - - - this.canvas.focus(); - - LiteGraph.closeAllContextMenus(ref_window); - - if (this.onMouse) - { - if (this.onMouse(e) == true) - return; - } - - //left button mouse / single finger - if (e.which == 1 && !this.pointer_is_double) - { - if (e.ctrlKey) - { - this.dragging_rectangle = new Float32Array(4); - this.dragging_rectangle[0] = e.canvasX; - this.dragging_rectangle[1] = e.canvasY; - this.dragging_rectangle[2] = 1; - this.dragging_rectangle[3] = 1; - skip_action = true; - } - - // clone node ALT dragging - if (LiteGraph.alt_drag_do_clone_nodes && e.altKey && node && this.allow_interaction && !skip_action && !this.read_only) - { - if (cloned = node.clone()){ - cloned.pos[0] += 5; - cloned.pos[1] += 5; - this.graph.add(cloned,false,{doCalcSize: false}); - node = cloned; - skip_action = true; - if (!block_drag_node) { - if (this.allow_dragnodes) { - this.graph.beforeChange(); - this.node_dragged = node; - } - if (!this.selected_nodes[node.id]) { - this.processNodeSelected(node, e); - } - } - } - } - - var clicking_canvas_bg = false; - - //when clicked on top of a node - //and it is not interactive - if (node && this.allow_interaction && !skip_action && !this.read_only) { - if (!this.live_mode && !node.flags.pinned) { - this.bringToFront(node); - } //if it wasn't selected? - - //not dragging mouse to connect two slots - if ( !this.connecting_node && !node.flags.collapsed && !this.live_mode ) { - //Search for corner for resize - if ( !skip_action && - node.resizable !== false && - isInsideRectangle( e.canvasX, - e.canvasY, - node.pos[0] + node.size[0] - 5, - node.pos[1] + node.size[1] - 5, - 10, - 10 - ) - ) { - this.graph.beforeChange(); - this.resizing_node = node; - this.canvas.style.cursor = "se-resize"; - skip_action = true; - } else { - //search for outputs - if (node.outputs) { - for ( var i = 0, l = node.outputs.length; i < l; ++i ) { - var output = node.outputs[i]; - var link_pos = node.getConnectionPos(false, i); - if ( - isInsideRectangle( - e.canvasX, - e.canvasY, - link_pos[0] - 15, - link_pos[1] - 10, - 30, - 20 - ) - ) { - this.connecting_node = node; - this.connecting_output = output; - this.connecting_output.slot_index = i; - this.connecting_pos = node.getConnectionPos( false, i ); - this.connecting_slot = i; - - if (LiteGraph.shift_click_do_break_link_from){ - if (e.shiftKey) { - node.disconnectOutput(i); - } - } - - if (is_double_click) { - if (node.onOutputDblClick) { - node.onOutputDblClick(i, e); - } - } else { - if (node.onOutputClick) { - node.onOutputClick(i, e); - } - } - - skip_action = true; - break; - } - } - } - - //search for inputs - if (node.inputs) { - for ( var i = 0, l = node.inputs.length; i < l; ++i ) { - var input = node.inputs[i]; - var link_pos = node.getConnectionPos(true, i); - if ( - isInsideRectangle( - e.canvasX, - e.canvasY, - link_pos[0] - 15, - link_pos[1] - 10, - 30, - 20 - ) - ) { - if (is_double_click) { - if (node.onInputDblClick) { - node.onInputDblClick(i, e); - } - } else { - if (node.onInputClick) { - node.onInputClick(i, e); - } - } - - if (input.link !== null) { - var link_info = this.graph.links[ - input.link - ]; //before disconnecting - if (LiteGraph.click_do_break_link_to){ - node.disconnectInput(i); - this.dirty_bgcanvas = true; - skip_action = true; - }else{ - // do same action as has not node ? - } - - if ( - this.allow_reconnect_links || - //this.move_destination_link_without_shift || - e.shiftKey - ) { - if (!LiteGraph.click_do_break_link_to){ - node.disconnectInput(i); - } - this.connecting_node = this.graph._nodes_by_id[ - link_info.origin_id - ]; - this.connecting_slot = - link_info.origin_slot; - this.connecting_output = this.connecting_node.outputs[ - this.connecting_slot - ]; - this.connecting_pos = this.connecting_node.getConnectionPos( false, this.connecting_slot ); - - this.dirty_bgcanvas = true; - skip_action = true; - } - - - }else{ - // has not node - } - - if (!skip_action){ - // connect from in to out, from to to from - this.connecting_node = node; - this.connecting_input = input; - this.connecting_input.slot_index = i; - this.connecting_pos = node.getConnectionPos( true, i ); - this.connecting_slot = i; - - this.dirty_bgcanvas = true; - skip_action = true; - } - } - } - } - } //not resizing - } - - //it wasn't clicked on the links boxes - if (!skip_action) { - var block_drag_node = false; - var pos = [e.canvasX - node.pos[0], e.canvasY - node.pos[1]]; - - //widgets - var widget = this.processNodeWidgets( node, this.graph_mouse, e ); - if (widget) { - block_drag_node = true; - this.node_widget = [node, widget]; - } - - //double clicking - if (is_double_click && this.selected_nodes[node.id]) { - //double click node - if (node.onDblClick) { - node.onDblClick( e, pos, this ); - } - this.processNodeDblClicked(node); - block_drag_node = true; - } - - //if do not capture mouse - if ( node.onMouseDown && node.onMouseDown( e, pos, this ) ) { - block_drag_node = true; - } else { - //open subgraph button - if(node.subgraph && !node.skip_subgraph_button) - { - if ( !node.flags.collapsed && pos[0] > node.size[0] - LiteGraph.NODE_TITLE_HEIGHT && pos[1] < 0 ) { - var that = this; - setTimeout(function() { - that.openSubgraph(node.subgraph); - }, 10); - } - } - - if (this.live_mode) { - clicking_canvas_bg = true; - block_drag_node = true; - } - } - - if (!block_drag_node) { - if (this.allow_dragnodes) { - this.graph.beforeChange(); - this.node_dragged = node; - } - this.processNodeSelected(node, e); - } else { // double-click - /** - * Don't call the function if the block is already selected. - * Otherwise, it could cause the block to be unselected while its panel is open. - */ - if (!node.is_selected) this.processNodeSelected(node, e); - } - - this.dirty_canvas = true; - } - } //clicked outside of nodes - else { - if (!skip_action){ - //search for link connector - if(!this.read_only) { - for (var i = 0; i < this.visible_links.length; ++i) { - var link = this.visible_links[i]; - var center = link._pos; - if ( - !center || - e.canvasX < center[0] - 4 || - e.canvasX > center[0] + 4 || - e.canvasY < center[1] - 4 || - e.canvasY > center[1] + 4 - ) { - continue; - } - //link clicked - this.showLinkMenu(link, e); - this.over_link_center = null; //clear tooltip - break; - } - } - - this.selected_group = this.graph.getGroupOnPos( e.canvasX, e.canvasY ); - this.selected_group_resizing = false; - if (this.selected_group && !this.read_only ) { - if (e.ctrlKey) { - this.dragging_rectangle = null; - } - - var dist = distance( [e.canvasX, e.canvasY], [ this.selected_group.pos[0] + this.selected_group.size[0], this.selected_group.pos[1] + this.selected_group.size[1] ] ); - if (dist * this.ds.scale < 10) { - this.selected_group_resizing = true; - } else { - this.selected_group.recomputeInsideNodes(); - } - } - - if (is_double_click && !this.read_only && this.allow_searchbox) { - this.showSearchBox(e); - e.preventDefault(); - e.stopPropagation(); - } - - clicking_canvas_bg = true; - } - } - - if (!skip_action && clicking_canvas_bg && this.allow_dragcanvas) { - //console.log("pointerevents: dragging_canvas start"); - this.dragging_canvas = true; - } - - } else if (e.which == 2) { - //middle button - - if (LiteGraph.middle_click_slot_add_default_node){ - if (node && this.allow_interaction && !skip_action && !this.read_only){ - //not dragging mouse to connect two slots - if ( - !this.connecting_node && - !node.flags.collapsed && - !this.live_mode - ) { - var mClikSlot = false; - var mClikSlot_index = false; - var mClikSlot_isOut = false; - //search for outputs - if (node.outputs) { - for ( var i = 0, l = node.outputs.length; i < l; ++i ) { - var output = node.outputs[i]; - var link_pos = node.getConnectionPos(false, i); - if (isInsideRectangle(e.canvasX,e.canvasY,link_pos[0] - 15,link_pos[1] - 10,30,20)) { - mClikSlot = output; - mClikSlot_index = i; - mClikSlot_isOut = true; - break; - } - } - } - - //search for inputs - if (node.inputs) { - for ( var i = 0, l = node.inputs.length; i < l; ++i ) { - var input = node.inputs[i]; - var link_pos = node.getConnectionPos(true, i); - if (isInsideRectangle(e.canvasX,e.canvasY,link_pos[0] - 15,link_pos[1] - 10,30,20)) { - mClikSlot = input; - mClikSlot_index = i; - mClikSlot_isOut = false; - break; - } - } - } - //console.log("middleClickSlots? "+mClikSlot+" & "+(mClikSlot_index!==false)); - if (mClikSlot && mClikSlot_index!==false){ - - var alphaPosY = 0.5-((mClikSlot_index+1)/((mClikSlot_isOut?node.outputs.length:node.inputs.length))); - var node_bounding = node.getBounding(); - // estimate a position: this is a bad semi-bad-working mess .. REFACTOR with a correct autoplacement that knows about the others slots and nodes - var posRef = [ (!mClikSlot_isOut?node_bounding[0]:node_bounding[0]+node_bounding[2])// + node_bounding[0]/this.canvas.width*150 - ,e.canvasY-80// + node_bounding[0]/this.canvas.width*66 // vertical "derive" - ]; - var nodeCreated = this.createDefaultNodeForSlot({ nodeFrom: !mClikSlot_isOut?null:node - ,slotFrom: !mClikSlot_isOut?null:mClikSlot_index - ,nodeTo: !mClikSlot_isOut?node:null - ,slotTo: !mClikSlot_isOut?mClikSlot_index:null - ,position: posRef //,e: e - ,nodeType: "AUTO" //nodeNewType - ,posAdd:[!mClikSlot_isOut?-30:30, -alphaPosY*130] //-alphaPosY*30] - ,posSizeFix:[!mClikSlot_isOut?-1:0, 0] //-alphaPosY*2*/ - }); - - } - } - } - } - - } else if (e.which == 3 || this.pointer_is_double) { - - //right button - if (this.allow_interaction && !skip_action && !this.read_only){ - - // is it hover a node ? - if (node){ - if(Object.keys(this.selected_nodes).length - && (this.selected_nodes[node.id] || e.shiftKey || e.ctrlKey || e.metaKey) - ){ - // is multiselected or using shift to include the now node - if (!this.selected_nodes[node.id]) this.selectNodes([node],true); // add this if not present - }else{ - // update selection - this.selectNodes([node]); - } - } - - // show menu on this node - this.processContextMenu(node, e); - } - - } - - //TODO - //if(this.node_selected != prev_selected) - // this.onNodeSelectionChange(this.node_selected); - - this.last_mouse[0] = e.clientX; - this.last_mouse[1] = e.clientY; - this.last_mouseclick = LiteGraph.getTime(); - this.last_mouse_dragging = true; - - /* - if( (this.dirty_canvas || this.dirty_bgcanvas) && this.rendering_timer_id == null) - this.draw(); - */ - - this.graph.change(); - - //this is to ensure to defocus(blur) if a text input element is on focus - if ( - !ref_window.document.activeElement || - (ref_window.document.activeElement.nodeName.toLowerCase() != - "input" && - ref_window.document.activeElement.nodeName.toLowerCase() != - "textarea") - ) { - e.preventDefault(); - } - e.stopPropagation(); - - if (this.onMouseDown) { - this.onMouseDown(e); - } - - return false; - }; - - /** - * Called when a mouse move event has to be processed - * @method processMouseMove - **/ - LGraphCanvas.prototype.processMouseMove = function(e) { - if (this.autoresize) { - this.resize(); - } - - if( this.set_canvas_dirty_on_mouse_event ) - this.dirty_canvas = true; - - if (!this.graph) { - return; - } - - LGraphCanvas.active_canvas = this; - this.adjustMouseEvent(e); - var mouse = [e.clientX, e.clientY]; - this.mouse[0] = mouse[0]; - this.mouse[1] = mouse[1]; - var delta = [ - mouse[0] - this.last_mouse[0], - mouse[1] - this.last_mouse[1] - ]; - this.last_mouse = mouse; - this.graph_mouse[0] = e.canvasX; - this.graph_mouse[1] = e.canvasY; - - //console.log("pointerevents: processMouseMove "+e.pointerId+" "+e.isPrimary); - - if(this.block_click) - { - //console.log("pointerevents: processMouseMove block_click"); - e.preventDefault(); - return false; - } - - e.dragging = this.last_mouse_dragging; - - if (this.node_widget) { - this.processNodeWidgets( - this.node_widget[0], - this.graph_mouse, - e, - this.node_widget[1] - ); - this.dirty_canvas = true; - } - - if (this.dragging_rectangle) - { - this.dragging_rectangle[2] = e.canvasX - this.dragging_rectangle[0]; - this.dragging_rectangle[3] = e.canvasY - this.dragging_rectangle[1]; - this.dirty_canvas = true; - } - else if (this.selected_group && !this.read_only) - { - //moving/resizing a group - if (this.selected_group_resizing) { - this.selected_group.size = [ - e.canvasX - this.selected_group.pos[0], - e.canvasY - this.selected_group.pos[1] - ]; - } else { - var deltax = delta[0] / this.ds.scale; - var deltay = delta[1] / this.ds.scale; - this.selected_group.move(deltax, deltay, e.ctrlKey); - if (this.selected_group._nodes.length) { - this.dirty_canvas = true; - } - } - this.dirty_bgcanvas = true; - } else if (this.dragging_canvas) { - ////console.log("pointerevents: processMouseMove is dragging_canvas"); - this.ds.offset[0] += delta[0] / this.ds.scale; - this.ds.offset[1] += delta[1] / this.ds.scale; - this.dirty_canvas = true; - this.dirty_bgcanvas = true; - } else if (this.allow_interaction && !this.read_only) { - if (this.connecting_node) { - this.dirty_canvas = true; - } - - //get node over - var node = this.graph.getNodeOnPos(e.canvasX,e.canvasY,this.visible_nodes); - - //remove mouseover flag - for (var i = 0, l = this.graph._nodes.length; i < l; ++i) { - if (this.graph._nodes[i].mouseOver && node != this.graph._nodes[i] ) { - //mouse leave - this.graph._nodes[i].mouseOver = false; - if (this.node_over && this.node_over.onMouseLeave) { - this.node_over.onMouseLeave(e); - } - this.node_over = null; - this.dirty_canvas = true; - } - } - - //mouse over a node - if (node) { - - if(node.redraw_on_mouse) - this.dirty_canvas = true; - - //this.canvas.style.cursor = "move"; - if (!node.mouseOver) { - //mouse enter - node.mouseOver = true; - this.node_over = node; - this.dirty_canvas = true; - - if (node.onMouseEnter) { - node.onMouseEnter(e); - } - } - - //in case the node wants to do something - if (node.onMouseMove) { - node.onMouseMove( e, [e.canvasX - node.pos[0], e.canvasY - node.pos[1]], this ); - } - - //if dragging a link - if (this.connecting_node) { - - if (this.connecting_output){ - - var pos = this._highlight_input || [0, 0]; //to store the output of isOverNodeInput - - //on top of input - if (this.isOverNodeBox(node, e.canvasX, e.canvasY)) { - //mouse on top of the corner box, don't know what to do - } else { - //check if I have a slot below de mouse - var slot = this.isOverNodeInput( node, e.canvasX, e.canvasY, pos ); - if (slot != -1 && node.inputs[slot]) { - var slot_type = node.inputs[slot].type; - if ( LiteGraph.isValidConnection( this.connecting_output.type, slot_type ) ) { - this._highlight_input = pos; - this._highlight_input_slot = node.inputs[slot]; // XXX CHECK THIS - } - } else { - this._highlight_input = null; - this._highlight_input_slot = null; // XXX CHECK THIS - } - } - - }else if(this.connecting_input){ - - var pos = this._highlight_output || [0, 0]; //to store the output of isOverNodeOutput - - //on top of output - if (this.isOverNodeBox(node, e.canvasX, e.canvasY)) { - //mouse on top of the corner box, don't know what to do - } else { - //check if I have a slot below de mouse - var slot = this.isOverNodeOutput( node, e.canvasX, e.canvasY, pos ); - if (slot != -1 && node.outputs[slot]) { - var slot_type = node.outputs[slot].type; - if ( LiteGraph.isValidConnection( this.connecting_input.type, slot_type ) ) { - this._highlight_output = pos; - } - } else { - this._highlight_output = null; - } - } - } - } - - //Search for corner - if (this.canvas) { - if ( - isInsideRectangle( - e.canvasX, - e.canvasY, - node.pos[0] + node.size[0] - 5, - node.pos[1] + node.size[1] - 5, - 5, - 5 - ) - ) { - this.canvas.style.cursor = "se-resize"; - } else { - this.canvas.style.cursor = "crosshair"; - } - } - } else { //not over a node - - //search for link connector - var over_link = null; - for (var i = 0; i < this.visible_links.length; ++i) { - var link = this.visible_links[i]; - var center = link._pos; - if ( - !center || - e.canvasX < center[0] - 4 || - e.canvasX > center[0] + 4 || - e.canvasY < center[1] - 4 || - e.canvasY > center[1] + 4 - ) { - continue; - } - over_link = link; - break; - } - if( over_link != this.over_link_center ) - { - this.over_link_center = over_link; - this.dirty_canvas = true; - } - - if (this.canvas) { - this.canvas.style.cursor = ""; - } - } //end - - //send event to node if capturing input (used with widgets that allow drag outside of the area of the node) - if ( this.node_capturing_input && this.node_capturing_input != node && this.node_capturing_input.onMouseMove ) { - this.node_capturing_input.onMouseMove(e,[e.canvasX - this.node_capturing_input.pos[0],e.canvasY - this.node_capturing_input.pos[1]], this); - } - - //node being dragged - if (this.node_dragged && !this.live_mode) { - //console.log("draggin!",this.selected_nodes); - for (var i in this.selected_nodes) { - var n = this.selected_nodes[i]; - n.pos[0] += delta[0] / this.ds.scale; - n.pos[1] += delta[1] / this.ds.scale; - if (!n.is_selected) this.processNodeSelected(n, e); /* - * Don't call the function if the block is already selected. - * Otherwise, it could cause the block to be unselected while dragging. - */ - } - - this.dirty_canvas = true; - this.dirty_bgcanvas = true; - } - - if (this.resizing_node && !this.live_mode) { - //convert mouse to node space - var desired_size = [ e.canvasX - this.resizing_node.pos[0], e.canvasY - this.resizing_node.pos[1] ]; - var min_size = this.resizing_node.computeSize(); - desired_size[0] = Math.max( min_size[0], desired_size[0] ); - desired_size[1] = Math.max( min_size[1], desired_size[1] ); - this.resizing_node.setSize( desired_size ); - - this.canvas.style.cursor = "se-resize"; - this.dirty_canvas = true; - this.dirty_bgcanvas = true; - } - } - - e.preventDefault(); - return false; - }; - - /** - * Called when a mouse up event has to be processed - * @method processMouseUp - **/ - LGraphCanvas.prototype.processMouseUp = function(e) { - - var is_primary = ( e.isPrimary === undefined || e.isPrimary ); - - //early exit for extra pointer - if(!is_primary){ - /*e.stopPropagation(); - e.preventDefault();*/ - //console.log("pointerevents: processMouseUp pointerN_stop "+e.pointerId+" "+e.isPrimary); - return false; - } - - //console.log("pointerevents: processMouseUp "+e.pointerId+" "+e.isPrimary+" :: "+e.clientX+" "+e.clientY); - - if( this.set_canvas_dirty_on_mouse_event ) - this.dirty_canvas = true; - - if (!this.graph) - return; - - var window = this.getCanvasWindow(); - var document = window.document; - LGraphCanvas.active_canvas = this; - - //restore the mousemove event back to the canvas - if(!this.options.skip_events) - { - //console.log("pointerevents: processMouseUp adjustEventListener"); - LiteGraph.pointerListenerRemove(document,"move", this._mousemove_callback,true); - LiteGraph.pointerListenerAdd(this.canvas,"move", this._mousemove_callback,true); - LiteGraph.pointerListenerRemove(document,"up", this._mouseup_callback,true); - } - - this.adjustMouseEvent(e); - var now = LiteGraph.getTime(); - e.click_time = now - this.last_mouseclick; - this.last_mouse_dragging = false; - this.last_click_position = null; - - if(this.block_click) - { - //console.log("pointerevents: processMouseUp block_clicks"); - this.block_click = false; //used to avoid sending twice a click in a immediate button - } - - //console.log("pointerevents: processMouseUp which: "+e.which); - - if (e.which == 1) { - - if( this.node_widget ) - { - this.processNodeWidgets( this.node_widget[0], this.graph_mouse, e ); - } - - //left button - this.node_widget = null; - - if (this.selected_group) { - var diffx = - this.selected_group.pos[0] - - Math.round(this.selected_group.pos[0]); - var diffy = - this.selected_group.pos[1] - - Math.round(this.selected_group.pos[1]); - this.selected_group.move(diffx, diffy, e.ctrlKey); - this.selected_group.pos[0] = Math.round( - this.selected_group.pos[0] - ); - this.selected_group.pos[1] = Math.round( - this.selected_group.pos[1] - ); - if (this.selected_group._nodes.length) { - this.dirty_canvas = true; - } - this.selected_group = null; - } - this.selected_group_resizing = false; - - var node = this.graph.getNodeOnPos( - e.canvasX, - e.canvasY, - this.visible_nodes - ); - - if (this.dragging_rectangle) { - if (this.graph) { - var nodes = this.graph._nodes; - var node_bounding = new Float32Array(4); - - //compute bounding and flip if left to right - var w = Math.abs(this.dragging_rectangle[2]); - var h = Math.abs(this.dragging_rectangle[3]); - var startx = - this.dragging_rectangle[2] < 0 - ? this.dragging_rectangle[0] - w - : this.dragging_rectangle[0]; - var starty = - this.dragging_rectangle[3] < 0 - ? this.dragging_rectangle[1] - h - : this.dragging_rectangle[1]; - this.dragging_rectangle[0] = startx; - this.dragging_rectangle[1] = starty; - this.dragging_rectangle[2] = w; - this.dragging_rectangle[3] = h; - - // test dragging rect size, if minimun simulate a click - if (!node || (w > 10 && h > 10 )){ - //test against all nodes (not visible because the rectangle maybe start outside - var to_select = []; - for (var i = 0; i < nodes.length; ++i) { - var nodeX = nodes[i]; - nodeX.getBounding(node_bounding); - if ( - !overlapBounding( - this.dragging_rectangle, - node_bounding - ) - ) { - continue; - } //out of the visible area - to_select.push(nodeX); - } - if (to_select.length) { - this.selectNodes(to_select,e.shiftKey); // add to selection with shift - } - }else{ - // will select of update selection - this.selectNodes([node],e.shiftKey||e.ctrlKey); // add to selection add to selection with ctrlKey or shiftKey - } - - } - this.dragging_rectangle = null; - } else if (this.connecting_node) { - //dragging a connection - this.dirty_canvas = true; - this.dirty_bgcanvas = true; - - var connInOrOut = this.connecting_output || this.connecting_input; - var connType = connInOrOut.type; - - //node below mouse - if (node) { - - /* no need to condition on event type.. just another type - if ( - connType == LiteGraph.EVENT && - this.isOverNodeBox(node, e.canvasX, e.canvasY) - ) { - - this.connecting_node.connect( - this.connecting_slot, - node, - LiteGraph.EVENT - ); - - } else {*/ - - //slot below mouse? connect - - if (this.connecting_output){ - - var slot = this.isOverNodeInput( - node, - e.canvasX, - e.canvasY - ); - if (slot != -1) { - this.connecting_node.connect(this.connecting_slot, node, slot); - } else { - //not on top of an input - // look for a good slot - this.connecting_node.connectByType(this.connecting_slot,node,connType); - } - - }else if (this.connecting_input){ - var slot = this.isOverNodeOutput( - node, - e.canvasX, - e.canvasY - ); - - if (slot != -1) { - node.connect(slot, this.connecting_node, this.connecting_slot); // this is inverted has output-input nature like - } else { - //not on top of an input - // look for a good slot - this.connecting_node.connectByTypeOutput(this.connecting_slot,node,connType); - } - - } - - - //} - - }else{ - - // add menu when releasing link in empty space - if (LiteGraph.release_link_on_empty_shows_menu){ - if (e.shiftKey && this.allow_searchbox){ - if(this.connecting_output){ - this.showSearchBox(e,{node_from: this.connecting_node, slot_from: this.connecting_output, type_filter_in: this.connecting_output.type}); - }else if(this.connecting_input){ - this.showSearchBox(e,{node_to: this.connecting_node, slot_from: this.connecting_input, type_filter_out: this.connecting_input.type}); - } - }else{ - if(this.connecting_output){ - this.showConnectionMenu({nodeFrom: this.connecting_node, slotFrom: this.connecting_output, e: e}); - }else if(this.connecting_input){ - this.showConnectionMenu({nodeTo: this.connecting_node, slotTo: this.connecting_input, e: e}); - } - } - } - } - - this.connecting_output = null; - this.connecting_input = null; - this.connecting_pos = null; - this.connecting_node = null; - this.connecting_slot = -1; - } //not dragging connection - else if (this.resizing_node) { - this.dirty_canvas = true; - this.dirty_bgcanvas = true; - this.graph.afterChange(this.resizing_node); - this.resizing_node = null; - } else if (this.node_dragged) { - //node being dragged? - var node = this.node_dragged; - if ( - node && - e.click_time < 300 && - isInsideRectangle( e.canvasX, e.canvasY, node.pos[0], node.pos[1] - LiteGraph.NODE_TITLE_HEIGHT, LiteGraph.NODE_TITLE_HEIGHT, LiteGraph.NODE_TITLE_HEIGHT ) - ) { - node.collapse(); - } - - this.dirty_canvas = true; - this.dirty_bgcanvas = true; - this.node_dragged.pos[0] = Math.round(this.node_dragged.pos[0]); - this.node_dragged.pos[1] = Math.round(this.node_dragged.pos[1]); - if (this.graph.config.align_to_grid || this.align_to_grid ) { - this.node_dragged.alignToGrid(); - } - if( this.onNodeMoved ) - this.onNodeMoved( this.node_dragged ); - this.graph.afterChange(this.node_dragged); - this.node_dragged = null; - } //no node being dragged - else { - //get node over - var node = this.graph.getNodeOnPos( - e.canvasX, - e.canvasY, - this.visible_nodes - ); - - if (!node && e.click_time < 300) { - this.deselectAllNodes(); - } - - this.dirty_canvas = true; - this.dragging_canvas = false; - - if (this.node_over && this.node_over.onMouseUp) { - this.node_over.onMouseUp( e, [ e.canvasX - this.node_over.pos[0], e.canvasY - this.node_over.pos[1] ], this ); - } - if ( - this.node_capturing_input && - this.node_capturing_input.onMouseUp - ) { - this.node_capturing_input.onMouseUp(e, [ - e.canvasX - this.node_capturing_input.pos[0], - e.canvasY - this.node_capturing_input.pos[1] - ]); - } - } - } else if (e.which == 2) { - //middle button - //trace("middle"); - this.dirty_canvas = true; - this.dragging_canvas = false; - } else if (e.which == 3) { - //right button - //trace("right"); - this.dirty_canvas = true; - this.dragging_canvas = false; - } - - /* - if((this.dirty_canvas || this.dirty_bgcanvas) && this.rendering_timer_id == null) - this.draw(); - */ - - if (is_primary) - { - this.pointer_is_down = false; - this.pointer_is_double = false; - } - - this.graph.change(); - - //console.log("pointerevents: processMouseUp stopPropagation"); - e.stopPropagation(); - e.preventDefault(); - return false; - }; - - /** - * Called when a mouse wheel event has to be processed - * @method processMouseWheel - **/ - LGraphCanvas.prototype.processMouseWheel = function(e) { - if (!this.graph || !this.allow_dragcanvas) { - return; - } - - var delta = e.wheelDeltaY != null ? e.wheelDeltaY : e.detail * -60; - - this.adjustMouseEvent(e); - - var x = e.clientX; - var y = e.clientY; - var is_inside = !this.viewport || ( this.viewport && x >= this.viewport[0] && x < (this.viewport[0] + this.viewport[2]) && y >= this.viewport[1] && y < (this.viewport[1] + this.viewport[3]) ); - if(!is_inside) - return; - - var scale = this.ds.scale; - - if (delta > 0) { - scale *= 1.1; - } else if (delta < 0) { - scale *= 1 / 1.1; - } - - //this.setZoom( scale, [ e.clientX, e.clientY ] ); - this.ds.changeScale(scale, [e.clientX, e.clientY]); - - this.graph.change(); - - e.preventDefault(); - return false; // prevent default - }; - - /** - * returns true if a position (in graph space) is on top of a node little corner box - * @method isOverNodeBox - **/ - LGraphCanvas.prototype.isOverNodeBox = function(node, canvasx, canvasy) { - var title_height = LiteGraph.NODE_TITLE_HEIGHT; - if ( - isInsideRectangle( - canvasx, - canvasy, - node.pos[0] + 2, - node.pos[1] + 2 - title_height, - title_height - 4, - title_height - 4 - ) - ) { - return true; - } - return false; - }; - - /** - * returns the INDEX if a position (in graph space) is on top of a node input slot - * @method isOverNodeInput - **/ - LGraphCanvas.prototype.isOverNodeInput = function( - node, - canvasx, - canvasy, - slot_pos - ) { - if (node.inputs) { - for (var i = 0, l = node.inputs.length; i < l; ++i) { - var input = node.inputs[i]; - var link_pos = node.getConnectionPos(true, i); - var is_inside = false; - if (node.horizontal) { - is_inside = isInsideRectangle( - canvasx, - canvasy, - link_pos[0] - 5, - link_pos[1] - 10, - 10, - 20 - ); - } else { - is_inside = isInsideRectangle( - canvasx, - canvasy, - link_pos[0] - 10, - link_pos[1] - 5, - 40, - 10 - ); - } - if (is_inside) { - if (slot_pos) { - slot_pos[0] = link_pos[0]; - slot_pos[1] = link_pos[1]; - } - return i; - } - } - } - return -1; - }; - - /** - * returns the INDEX if a position (in graph space) is on top of a node output slot - * @method isOverNodeOuput - **/ - LGraphCanvas.prototype.isOverNodeOutput = function( - node, - canvasx, - canvasy, - slot_pos - ) { - if (node.outputs) { - for (var i = 0, l = node.outputs.length; i < l; ++i) { - var output = node.outputs[i]; - var link_pos = node.getConnectionPos(false, i); - var is_inside = false; - if (node.horizontal) { - is_inside = isInsideRectangle( - canvasx, - canvasy, - link_pos[0] - 5, - link_pos[1] - 10, - 10, - 20 - ); - } else { - is_inside = isInsideRectangle( - canvasx, - canvasy, - link_pos[0] - 10, - link_pos[1] - 5, - 40, - 10 - ); - } - if (is_inside) { - if (slot_pos) { - slot_pos[0] = link_pos[0]; - slot_pos[1] = link_pos[1]; - } - return i; - } - } - } - return -1; - }; - - /** - * process a key event - * @method processKey - **/ - LGraphCanvas.prototype.processKey = function(e) { - if (!this.graph) { - return; - } - - var block_default = false; - //console.log(e); //debug - - if (e.target.localName == "input") { - return; - } - - if (e.type == "keydown") { - if (e.keyCode == 32) { - //space - this.dragging_canvas = true; - block_default = true; - } - - if (e.keyCode == 27) { - //esc - if(this.node_panel) this.node_panel.close(); - if(this.options_panel) this.options_panel.close(); - block_default = true; - } - - //select all Control A - if (e.keyCode == 65 && e.ctrlKey) { - this.selectNodes(); - block_default = true; - } - - if (e.code == "KeyC" && (e.metaKey || e.ctrlKey) && !e.shiftKey) { - //copy - if (this.selected_nodes) { - this.copyToClipboard(); - block_default = true; - } - } - - if (e.code == "KeyV" && (e.metaKey || e.ctrlKey)) { - //paste - this.pasteFromClipboard(e.shiftKey); - } - - //delete or backspace - if (e.keyCode == 46 || e.keyCode == 8) { - if ( - e.target.localName != "input" && - e.target.localName != "textarea" - ) { - this.deleteSelectedNodes(); - block_default = true; - } - } - - //collapse - //... - - //TODO - if (this.selected_nodes) { - for (var i in this.selected_nodes) { - if (this.selected_nodes[i].onKeyDown) { - this.selected_nodes[i].onKeyDown(e); - } - } - } - } else if (e.type == "keyup") { - if (e.keyCode == 32) { - // space - this.dragging_canvas = false; - } - - if (this.selected_nodes) { - for (var i in this.selected_nodes) { - if (this.selected_nodes[i].onKeyUp) { - this.selected_nodes[i].onKeyUp(e); - } - } - } - } - - this.graph.change(); - - if (block_default) { - e.preventDefault(); - e.stopImmediatePropagation(); - return false; - } - }; - - LGraphCanvas.prototype.copyToClipboard = function() { - var clipboard_info = { - nodes: [], - links: [] - }; - var index = 0; - var selected_nodes_array = []; - for (var i in this.selected_nodes) { - var node = this.selected_nodes[i]; - node._relative_id = index; - selected_nodes_array.push(node); - index += 1; - } - - for (var i = 0; i < selected_nodes_array.length; ++i) { - var node = selected_nodes_array[i]; - var cloned = node.clone(); - if(!cloned) - { - console.warn("node type not found: " + node.type ); - continue; - } - clipboard_info.nodes.push(cloned.serialize()); - if (node.inputs && node.inputs.length) { - for (var j = 0; j < node.inputs.length; ++j) { - var input = node.inputs[j]; - if (!input || input.link == null) { - continue; - } - var link_info = this.graph.links[input.link]; - if (!link_info) { - continue; - } - var target_node = this.graph.getNodeById( - link_info.origin_id - ); - if (!target_node) { - continue; - } - clipboard_info.links.push([ - target_node._relative_id, - link_info.origin_slot, //j, - node._relative_id, - link_info.target_slot, - target_node.id - ]); - } - } - } - localStorage.setItem( - "litegrapheditor_clipboard", - JSON.stringify(clipboard_info) - ); - }; - - LGraphCanvas.prototype.pasteFromClipboard = function(isConnectUnselected = false) { - // if ctrl + shift + v is off, return when isConnectUnselected is true (shift is pressed) to maintain old behavior - if (!LiteGraph.ctrl_shift_v_paste_connect_unselected_outputs && isConnectUnselected) { - return; - } - var data = localStorage.getItem("litegrapheditor_clipboard"); - if (!data) { - return; - } - - this.graph.beforeChange(); - - //create nodes - var clipboard_info = JSON.parse(data); - // calculate top-left node, could work without this processing but using diff with last node pos :: clipboard_info.nodes[clipboard_info.nodes.length-1].pos - var posMin = false; - var posMinIndexes = false; - for (var i = 0; i < clipboard_info.nodes.length; ++i) { - if (posMin){ - if(posMin[0]>clipboard_info.nodes[i].pos[0]){ - posMin[0] = clipboard_info.nodes[i].pos[0]; - posMinIndexes[0] = i; - } - if(posMin[1]>clipboard_info.nodes[i].pos[1]){ - posMin[1] = clipboard_info.nodes[i].pos[1]; - posMinIndexes[1] = i; - } - } - else{ - posMin = [clipboard_info.nodes[i].pos[0], clipboard_info.nodes[i].pos[1]]; - posMinIndexes = [i, i]; - } - } - var nodes = []; - for (var i = 0; i < clipboard_info.nodes.length; ++i) { - var node_data = clipboard_info.nodes[i]; - var node = LiteGraph.createNode(node_data.type); - if (node) { - node.configure(node_data); - - //paste in last known mouse position - node.pos[0] += this.graph_mouse[0] - posMin[0]; //+= 5; - node.pos[1] += this.graph_mouse[1] - posMin[1]; //+= 5; - - this.graph.add(node,{doProcessChange:false}); - - nodes.push(node); - } - } - - //create links - for (var i = 0; i < clipboard_info.links.length; ++i) { - var link_info = clipboard_info.links[i]; - var origin_node; - var origin_node_relative_id = link_info[0]; - if (origin_node_relative_id != null) { - origin_node = nodes[origin_node_relative_id]; - } else if (LiteGraph.ctrl_shift_v_paste_connect_unselected_outputs && isConnectUnselected) { - var origin_node_id = link_info[4]; - if (origin_node_id) { - origin_node = this.graph.getNodeById(origin_node_id); - } - } - var target_node = nodes[link_info[2]]; - if( origin_node && target_node ) - origin_node.connect(link_info[1], target_node, link_info[3]); - else - console.warn("Warning, nodes missing on pasting"); - } - - this.selectNodes(nodes); - - this.graph.afterChange(); - }; - - /** - * process a item drop event on top the canvas - * @method processDrop - **/ - LGraphCanvas.prototype.processDrop = function(e) { - e.preventDefault(); - this.adjustMouseEvent(e); - var x = e.clientX; - var y = e.clientY; - var is_inside = !this.viewport || ( this.viewport && x >= this.viewport[0] && x < (this.viewport[0] + this.viewport[2]) && y >= this.viewport[1] && y < (this.viewport[1] + this.viewport[3]) ); - if(!is_inside){ - return; - // --- BREAK --- - } - - var pos = [e.canvasX, e.canvasY]; - - - var node = this.graph ? this.graph.getNodeOnPos(pos[0], pos[1]) : null; - - if (!node) { - var r = null; - if (this.onDropItem) { - r = this.onDropItem(event); - } - if (!r) { - this.checkDropItem(e); - } - return; - } - - if (node.onDropFile || node.onDropData) { - var files = e.dataTransfer.files; - if (files && files.length) { - for (var i = 0; i < files.length; i++) { - var file = e.dataTransfer.files[0]; - var filename = file.name; - var ext = LGraphCanvas.getFileExtension(filename); - //console.log(file); - - if (node.onDropFile) { - node.onDropFile(file); - } - - if (node.onDropData) { - //prepare reader - var reader = new FileReader(); - reader.onload = function(event) { - //console.log(event.target); - var data = event.target.result; - node.onDropData(data, filename, file); - }; - - //read data - var type = file.type.split("/")[0]; - if (type == "text" || type == "") { - reader.readAsText(file); - } else if (type == "image") { - reader.readAsDataURL(file); - } else { - reader.readAsArrayBuffer(file); - } - } - } - } - } - - if (node.onDropItem) { - if (node.onDropItem(event)) { - return true; - } - } - - if (this.onDropItem) { - return this.onDropItem(event); - } - - return false; - }; - - //called if the graph doesn't have a default drop item behaviour - LGraphCanvas.prototype.checkDropItem = function(e) { - if (e.dataTransfer.files.length) { - var file = e.dataTransfer.files[0]; - var ext = LGraphCanvas.getFileExtension(file.name).toLowerCase(); - var nodetype = LiteGraph.node_types_by_file_extension[ext]; - if (nodetype) { - this.graph.beforeChange(); - var node = LiteGraph.createNode(nodetype.type); - node.pos = [e.canvasX, e.canvasY]; - this.graph.add(node); - if (node.onDropFile) { - node.onDropFile(file); - } - this.graph.afterChange(); - } - } - }; - - LGraphCanvas.prototype.processNodeDblClicked = function(n) { - if (this.onShowNodePanel) { - this.onShowNodePanel(n); - } - else - { - this.showShowNodePanel(n); - } - - if (this.onNodeDblClicked) { - this.onNodeDblClicked(n); - } - - this.setDirty(true); - }; - - LGraphCanvas.prototype.processNodeSelected = function(node, e) { - this.selectNode(node, e && (e.shiftKey || e.ctrlKey || this.multi_select)); - if (this.onNodeSelected) { - this.onNodeSelected(node); - } - }; - - /** - * selects a given node (or adds it to the current selection) - * @method selectNode - **/ - LGraphCanvas.prototype.selectNode = function( - node, - add_to_current_selection - ) { - if (node == null) { - this.deselectAllNodes(); - } else { - this.selectNodes([node], add_to_current_selection); - } - }; - - /** - * selects several nodes (or adds them to the current selection) - * @method selectNodes - **/ - LGraphCanvas.prototype.selectNodes = function( nodes, add_to_current_selection ) - { - if (!add_to_current_selection) { - this.deselectAllNodes(); - } - - nodes = nodes || this.graph._nodes; - if (typeof nodes == "string") nodes = [nodes]; - for (var i in nodes) { - var node = nodes[i]; - if (node.is_selected) { - this.deselectNode(node); - continue; - } - - if (!node.is_selected && node.onSelected) { - node.onSelected(); - } - node.is_selected = true; - this.selected_nodes[node.id] = node; - - if (node.inputs) { - for (var j = 0; j < node.inputs.length; ++j) { - this.highlighted_links[node.inputs[j].link] = true; - } - } - if (node.outputs) { - for (var j = 0; j < node.outputs.length; ++j) { - var out = node.outputs[j]; - if (out.links) { - for (var k = 0; k < out.links.length; ++k) { - this.highlighted_links[out.links[k]] = true; - } - } - } - } - } - - if( this.onSelectionChange ) - this.onSelectionChange( this.selected_nodes ); - - this.setDirty(true); - }; - - /** - * removes a node from the current selection - * @method deselectNode - **/ - LGraphCanvas.prototype.deselectNode = function(node) { - if (!node.is_selected) { - return; - } - if (node.onDeselected) { - node.onDeselected(); - } - node.is_selected = false; - - if (this.onNodeDeselected) { - this.onNodeDeselected(node); - } - - //remove highlighted - if (node.inputs) { - for (var i = 0; i < node.inputs.length; ++i) { - delete this.highlighted_links[node.inputs[i].link]; - } - } - if (node.outputs) { - for (var i = 0; i < node.outputs.length; ++i) { - var out = node.outputs[i]; - if (out.links) { - for (var j = 0; j < out.links.length; ++j) { - delete this.highlighted_links[out.links[j]]; - } - } - } - } - }; - - /** - * removes all nodes from the current selection - * @method deselectAllNodes - **/ - LGraphCanvas.prototype.deselectAllNodes = function() { - if (!this.graph) { - return; - } - var nodes = this.graph._nodes; - for (var i = 0, l = nodes.length; i < l; ++i) { - var node = nodes[i]; - if (!node.is_selected) { - continue; - } - if (node.onDeselected) { - node.onDeselected(); - } - node.is_selected = false; - if (this.onNodeDeselected) { - this.onNodeDeselected(node); - } - } - this.selected_nodes = {}; - this.current_node = null; - this.highlighted_links = {}; - if( this.onSelectionChange ) - this.onSelectionChange( this.selected_nodes ); - this.setDirty(true); - }; - - /** - * deletes all nodes in the current selection from the graph - * @method deleteSelectedNodes - **/ - LGraphCanvas.prototype.deleteSelectedNodes = function() { - - this.graph.beforeChange(); - - for (var i in this.selected_nodes) { - var node = this.selected_nodes[i]; - - if(node.block_delete) - continue; - - //autoconnect when possible (very basic, only takes into account first input-output) - if(node.inputs && node.inputs.length && node.outputs && node.outputs.length && LiteGraph.isValidConnection( node.inputs[0].type, node.outputs[0].type ) && node.inputs[0].link && node.outputs[0].links && node.outputs[0].links.length ) - { - var input_link = node.graph.links[ node.inputs[0].link ]; - var output_link = node.graph.links[ node.outputs[0].links[0] ]; - var input_node = node.getInputNode(0); - var output_node = node.getOutputNodes(0)[0]; - if(input_node && output_node) - input_node.connect( input_link.origin_slot, output_node, output_link.target_slot ); - } - this.graph.remove(node); - if (this.onNodeDeselected) { - this.onNodeDeselected(node); - } - } - this.selected_nodes = {}; - this.current_node = null; - this.highlighted_links = {}; - this.setDirty(true); - this.graph.afterChange(); - }; - - /** - * centers the camera on a given node - * @method centerOnNode - **/ - LGraphCanvas.prototype.centerOnNode = function(node) { - this.ds.offset[0] = - -node.pos[0] - - node.size[0] * 0.5 + - (this.canvas.width * 0.5) / this.ds.scale; - this.ds.offset[1] = - -node.pos[1] - - node.size[1] * 0.5 + - (this.canvas.height * 0.5) / this.ds.scale; - this.setDirty(true, true); - }; - - /** - * adds some useful properties to a mouse event, like the position in graph coordinates - * @method adjustMouseEvent - **/ - LGraphCanvas.prototype.adjustMouseEvent = function(e) { - var clientX_rel = 0; - var clientY_rel = 0; - - if (this.canvas) { - var b = this.canvas.getBoundingClientRect(); - clientX_rel = e.clientX - b.left; - clientY_rel = e.clientY - b.top; - } else { - clientX_rel = e.clientX; - clientY_rel = e.clientY; - } - - // e.deltaX = clientX_rel - this.last_mouse_position[0]; - // e.deltaY = clientY_rel- this.last_mouse_position[1]; - - this.last_mouse_position[0] = clientX_rel; - this.last_mouse_position[1] = clientY_rel; - - e.canvasX = clientX_rel / this.ds.scale - this.ds.offset[0]; - e.canvasY = clientY_rel / this.ds.scale - this.ds.offset[1]; - - //console.log("pointerevents: adjustMouseEvent "+e.clientX+":"+e.clientY+" "+clientX_rel+":"+clientY_rel+" "+e.canvasX+":"+e.canvasY); - }; - - /** - * changes the zoom level of the graph (default is 1), you can pass also a place used to pivot the zoom - * @method setZoom - **/ - LGraphCanvas.prototype.setZoom = function(value, zooming_center) { - this.ds.changeScale(value, zooming_center); - /* - if(!zooming_center && this.canvas) - zooming_center = [this.canvas.width * 0.5,this.canvas.height * 0.5]; - - var center = this.convertOffsetToCanvas( zooming_center ); - - this.ds.scale = value; - - if(this.scale > this.max_zoom) - this.scale = this.max_zoom; - else if(this.scale < this.min_zoom) - this.scale = this.min_zoom; - - var new_center = this.convertOffsetToCanvas( zooming_center ); - var delta_offset = [new_center[0] - center[0], new_center[1] - center[1]]; - - this.offset[0] += delta_offset[0]; - this.offset[1] += delta_offset[1]; - */ - - this.dirty_canvas = true; - this.dirty_bgcanvas = true; - }; - - /** - * converts a coordinate from graph coordinates to canvas2D coordinates - * @method convertOffsetToCanvas - **/ - LGraphCanvas.prototype.convertOffsetToCanvas = function(pos, out) { - return this.ds.convertOffsetToCanvas(pos, out); - }; - - /** - * converts a coordinate from Canvas2D coordinates to graph space - * @method convertCanvasToOffset - **/ - LGraphCanvas.prototype.convertCanvasToOffset = function(pos, out) { - return this.ds.convertCanvasToOffset(pos, out); - }; - - //converts event coordinates from canvas2D to graph coordinates - LGraphCanvas.prototype.convertEventToCanvasOffset = function(e) { - var rect = this.canvas.getBoundingClientRect(); - return this.convertCanvasToOffset([ - e.clientX - rect.left, - e.clientY - rect.top - ]); - }; - - /** - * brings a node to front (above all other nodes) - * @method bringToFront - **/ - LGraphCanvas.prototype.bringToFront = function(node) { - var i = this.graph._nodes.indexOf(node); - if (i == -1) { - return; - } - - this.graph._nodes.splice(i, 1); - this.graph._nodes.push(node); - }; - - /** - * sends a node to the back (below all other nodes) - * @method sendToBack - **/ - LGraphCanvas.prototype.sendToBack = function(node) { - var i = this.graph._nodes.indexOf(node); - if (i == -1) { - return; - } - - this.graph._nodes.splice(i, 1); - this.graph._nodes.unshift(node); - }; - - /* Interaction */ - - /* LGraphCanvas render */ - var temp = new Float32Array(4); - - /** - * checks which nodes are visible (inside the camera area) - * @method computeVisibleNodes - **/ - LGraphCanvas.prototype.computeVisibleNodes = function(nodes, out) { - var visible_nodes = out || []; - visible_nodes.length = 0; - nodes = nodes || this.graph._nodes; - for (var i = 0, l = nodes.length; i < l; ++i) { - var n = nodes[i]; - - //skip rendering nodes in live mode - if (this.live_mode && !n.onDrawBackground && !n.onDrawForeground) { - continue; - } - - if (!overlapBounding(this.visible_area, n.getBounding(temp))) { - continue; - } //out of the visible area - - visible_nodes.push(n); - } - return visible_nodes; - }; - - /** - * renders the whole canvas content, by rendering in two separated canvas, one containing the background grid and the connections, and one containing the nodes) - * @method draw - **/ - LGraphCanvas.prototype.draw = function(force_canvas, force_bgcanvas) { - if (!this.canvas || this.canvas.width == 0 || this.canvas.height == 0) { - return; - } - - //fps counting - var now = LiteGraph.getTime(); - this.render_time = (now - this.last_draw_time) * 0.001; - this.last_draw_time = now; - - if (this.graph) { - this.ds.computeVisibleArea(this.viewport); - } - - if ( - this.dirty_bgcanvas || - force_bgcanvas || - this.always_render_background || - (this.graph && - this.graph._last_trigger_time && - now - this.graph._last_trigger_time < 1000) - ) { - this.drawBackCanvas(); - } - - if (this.dirty_canvas || force_canvas) { - this.drawFrontCanvas(); - } - - this.fps = this.render_time ? 1.0 / this.render_time : 0; - this.frame += 1; - }; - - /** - * draws the front canvas (the one containing all the nodes) - * @method drawFrontCanvas - **/ - LGraphCanvas.prototype.drawFrontCanvas = function() { - this.dirty_canvas = false; - - if (!this.ctx) { - this.ctx = this.bgcanvas.getContext("2d"); - } - var ctx = this.ctx; - if (!ctx) { - //maybe is using webgl... - return; - } - - var canvas = this.canvas; - if ( ctx.start2D && !this.viewport ) { - ctx.start2D(); - ctx.restore(); - ctx.setTransform(1, 0, 0, 1, 0, 0); - } - - //clip dirty area if there is one, otherwise work in full canvas - var area = this.viewport || this.dirty_area; - if (area) { - ctx.save(); - ctx.beginPath(); - ctx.rect( area[0],area[1],area[2],area[3] ); - ctx.clip(); - } - - //clear - //canvas.width = canvas.width; - if (this.clear_background) { - if(area) - ctx.clearRect( area[0],area[1],area[2],area[3] ); - else - ctx.clearRect(0, 0, canvas.width, canvas.height); - } - - //draw bg canvas - if (this.bgcanvas == this.canvas) { - this.drawBackCanvas(); - } else { - ctx.drawImage( this.bgcanvas, 0, 0 ); - } - - //rendering - if (this.onRender) { - this.onRender(canvas, ctx); - } - - //info widget - if (this.show_info) { - this.renderInfo(ctx, area ? area[0] : 0, area ? area[1] : 0 ); - } - - if (this.graph) { - //apply transformations - ctx.save(); - this.ds.toCanvasContext(ctx); - - //draw nodes - var drawn_nodes = 0; - var visible_nodes = this.computeVisibleNodes( - null, - this.visible_nodes - ); - - for (var i = 0; i < visible_nodes.length; ++i) { - var node = visible_nodes[i]; - - //transform coords system - ctx.save(); - ctx.translate(node.pos[0], node.pos[1]); - - //Draw - this.drawNode(node, ctx); - drawn_nodes += 1; - - //Restore - ctx.restore(); - } - - //on top (debug) - if (this.render_execution_order) { - this.drawExecutionOrder(ctx); - } - - //connections ontop? - if (this.graph.config.links_ontop) { - if (!this.live_mode) { - this.drawConnections(ctx); - } - } - - //current connection (the one being dragged by the mouse) - if (this.connecting_pos != null) { - ctx.lineWidth = this.connections_width; - var link_color = null; - - var connInOrOut = this.connecting_output || this.connecting_input; - - var connType = connInOrOut.type; - var connDir = connInOrOut.dir; - if(connDir == null) - { - if (this.connecting_output) - connDir = this.connecting_node.horizontal ? LiteGraph.DOWN : LiteGraph.RIGHT; - else - connDir = this.connecting_node.horizontal ? LiteGraph.UP : LiteGraph.LEFT; - } - var connShape = connInOrOut.shape; - - switch (connType) { - case LiteGraph.EVENT: - link_color = LiteGraph.EVENT_LINK_COLOR; - break; - default: - link_color = LiteGraph.CONNECTING_LINK_COLOR; - } - - //the connection being dragged by the mouse - this.renderLink( - ctx, - this.connecting_pos, - [this.graph_mouse[0], this.graph_mouse[1]], - null, - false, - null, - link_color, - connDir, - LiteGraph.CENTER - ); - - ctx.beginPath(); - if ( - connType === LiteGraph.EVENT || - connShape === LiteGraph.BOX_SHAPE - ) { - //MODDED - - ctx.beginPath(); - ctx.moveTo(this.connecting_pos[0] - 5 + 0.5, this.connecting_pos[1] - 6 + 0.5); // top-left point - ctx.lineTo(this.connecting_pos[0] + 5.5, this.connecting_pos[1] + 0.5); // middle-right point - ctx.lineTo(this.connecting_pos[0] - 5 + 0.5, this.connecting_pos[1] + 6 + 0.5); // bottom-left point - ctx.closePath(); - ctx.stroke(); - - // ctx.rect( - // this.connecting_pos[0] - 6 + 0.5, - // this.connecting_pos[1] - 5 + 0.5, - // 14, - // 10 - // ); - ctx.fill(); - ctx.beginPath(); - - ctx.beginPath(); - ctx.moveTo(this.graph_mouse[0] - 5 + 0.5, this.graph_mouse[1] - 6 + 0.5); // top-left point - ctx.lineTo(this.graph_mouse[0] + 5.5, this.graph_mouse[1] + 0.5); // middle-right point - ctx.lineTo(this.graph_mouse[0] - 5 + 0.5, this.graph_mouse[1] + 6 + 0.5); // bottom-left point - ctx.closePath(); - ctx.stroke(); - // ctx.rect( - // this.graph_mouse[0] - 6 + 0.5, - // this.graph_mouse[1] - 5 + 0.5, - // 14, - // 10 - // ); - } else if (connShape === LiteGraph.ARROW_SHAPE) { - ctx.moveTo(this.connecting_pos[0] + 8, this.connecting_pos[1] + 0.5); - ctx.lineTo(this.connecting_pos[0] - 4, this.connecting_pos[1] + 6 + 0.5); - ctx.lineTo(this.connecting_pos[0] - 4, this.connecting_pos[1] - 6 + 0.5); - ctx.closePath(); - } - else { - ctx.arc( - this.connecting_pos[0], - this.connecting_pos[1], - 4, - 0, - Math.PI * 2 - ); - ctx.fill(); - ctx.beginPath(); - ctx.arc( - this.graph_mouse[0], - this.graph_mouse[1], - 4, - 0, - Math.PI * 2 - ); - } - ctx.fill(); - - ctx.fillStyle = "#ffcc00"; - if (this._highlight_input) { - ctx.beginPath(); - var shape = this._highlight_input_slot.shape; - if (shape === LiteGraph.ARROW_SHAPE) { - ctx.moveTo(this._highlight_input[0] + 8, this._highlight_input[1] + 0.5); - ctx.lineTo(this._highlight_input[0] - 4, this._highlight_input[1] + 6 + 0.5); - ctx.lineTo(this._highlight_input[0] - 4, this._highlight_input[1] - 6 + 0.5); - ctx.closePath(); - } else { - ctx.arc( - this._highlight_input[0], - this._highlight_input[1], - 6, - 0, - Math.PI * 2 - ); - } - ctx.fill(); - } - if (this._highlight_output) { - ctx.beginPath(); - if (shape === LiteGraph.ARROW_SHAPE) { - ctx.moveTo(this._highlight_output[0] + 8, this._highlight_output[1] + 0.5); - ctx.lineTo(this._highlight_output[0] - 4, this._highlight_output[1] + 6 + 0.5); - ctx.lineTo(this._highlight_output[0] - 4, this._highlight_output[1] - 6 + 0.5); - ctx.closePath(); - } else { - ctx.arc( - this._highlight_output[0], - this._highlight_output[1], - 6, - 0, - Math.PI * 2 - ); - } - ctx.fill(); - } - } - - //the selection rectangle - if (this.dragging_rectangle) { - ctx.strokeStyle = "#FFF"; - ctx.strokeRect( - this.dragging_rectangle[0], - this.dragging_rectangle[1], - this.dragging_rectangle[2], - this.dragging_rectangle[3] - ); - } - - //on top of link center - if(this.over_link_center && this.render_link_tooltip) - this.drawLinkTooltip( ctx, this.over_link_center ); - else - if(this.onDrawLinkTooltip) //to remove - this.onDrawLinkTooltip(ctx,null); - - //custom info - if (this.onDrawForeground) { - this.onDrawForeground(ctx, this.visible_rect); - } - - ctx.restore(); - } - - //draws panel in the corner - if (this._graph_stack && this._graph_stack.length) { - this.drawSubgraphPanel( ctx ); - } - - - if (this.onDrawOverlay) { - this.onDrawOverlay(ctx); - } - - if (area){ - ctx.restore(); - } - - if (ctx.finish2D) { - //this is a function I use in webgl renderer - ctx.finish2D(); - } - }; - - /** - * draws the panel in the corner that shows subgraph properties - * @method drawSubgraphPanel - **/ - LGraphCanvas.prototype.drawSubgraphPanel = function (ctx) { - var subgraph = this.graph; - var subnode = subgraph._subgraph_node; - if (!subnode) { - console.warn("subgraph without subnode"); - return; - } - this.drawSubgraphPanelLeft(subgraph, subnode, ctx) - this.drawSubgraphPanelRight(subgraph, subnode, ctx) - } - - LGraphCanvas.prototype.drawSubgraphPanelLeft = function (subgraph, subnode, ctx) { - var num = subnode.inputs ? subnode.inputs.length : 0; - var w = 200; - var h = Math.floor(LiteGraph.NODE_SLOT_HEIGHT * 1.6); - - ctx.fillStyle = "#111"; - ctx.globalAlpha = 0.8; - ctx.beginPath(); - ctx.roundRect(10, 10, w, (num + 1) * h + 50, [8]); - ctx.fill(); - ctx.globalAlpha = 1; - - ctx.fillStyle = "#888"; - ctx.font = "14px Arial"; - ctx.textAlign = "left"; - ctx.fillText("Graph Inputs", 20, 34); - // var pos = this.mouse; - - if (this.drawButton(w - 20, 20, 20, 20, "X", "#151515")) { - this.closeSubgraph(); - return; - } - - var y = 50; - ctx.font = "14px Arial"; - if (subnode.inputs) - for (var i = 0; i < subnode.inputs.length; ++i) { - var input = subnode.inputs[i]; - if (input.not_subgraph_input) - continue; - - //input button clicked - if (this.drawButton(20, y + 2, w - 20, h - 2)) { - var type = subnode.constructor.input_node_type || "graph/input"; - this.graph.beforeChange(); - var newnode = LiteGraph.createNode(type); - if (newnode) { - subgraph.add(newnode); - this.block_click = false; - this.last_click_position = null; - this.selectNodes([newnode]); - this.node_dragged = newnode; - this.dragging_canvas = false; - newnode.setProperty("name", input.name); - newnode.setProperty("type", input.type); - this.node_dragged.pos[0] = this.graph_mouse[0] - 5; - this.node_dragged.pos[1] = this.graph_mouse[1] - 5; - this.graph.afterChange(); - } - else - console.error("graph input node not found:", type); - } - ctx.fillStyle = "#9C9"; - ctx.beginPath(); - ctx.arc(w - 16, y + h * 0.5, 5, 0, 2 * Math.PI); - ctx.fill(); - ctx.fillStyle = "#AAA"; - ctx.fillText(input.name, 30, y + h * 0.75); - // var tw = ctx.measureText(input.name); - ctx.fillStyle = "#777"; - ctx.fillText(input.type, 130, y + h * 0.75); - y += h; - } - //add + button - if (this.drawButton(20, y + 2, w - 20, h - 2, "+", "#151515", "#222")) { - this.showSubgraphPropertiesDialog(subnode); - } - } - LGraphCanvas.prototype.drawSubgraphPanelRight = function (subgraph, subnode, ctx) { - var num = subnode.outputs ? subnode.outputs.length : 0; - var canvas_w = this.bgcanvas.width - var w = 200; - var h = Math.floor(LiteGraph.NODE_SLOT_HEIGHT * 1.6); - - ctx.fillStyle = "#111"; - ctx.globalAlpha = 0.8; - ctx.beginPath(); - ctx.roundRect(canvas_w - w - 10, 10, w, (num + 1) * h + 50, [8]); - ctx.fill(); - ctx.globalAlpha = 1; - - ctx.fillStyle = "#888"; - ctx.font = "14px Arial"; - ctx.textAlign = "left"; - var title_text = "Graph Outputs" - var tw = ctx.measureText(title_text).width - ctx.fillText(title_text, (canvas_w - tw) - 20, 34); - // var pos = this.mouse; - if (this.drawButton(canvas_w - w, 20, 20, 20, "X", "#151515")) { - this.closeSubgraph(); - return; - } - - var y = 50; - ctx.font = "14px Arial"; - if (subnode.outputs) - for (var i = 0; i < subnode.outputs.length; ++i) { - var output = subnode.outputs[i]; - if (output.not_subgraph_input) - continue; - - //output button clicked - if (this.drawButton(canvas_w - w, y + 2, w - 20, h - 2)) { - var type = subnode.constructor.output_node_type || "graph/output"; - this.graph.beforeChange(); - var newnode = LiteGraph.createNode(type); - if (newnode) { - subgraph.add(newnode); - this.block_click = false; - this.last_click_position = null; - this.selectNodes([newnode]); - this.node_dragged = newnode; - this.dragging_canvas = false; - newnode.setProperty("name", output.name); - newnode.setProperty("type", output.type); - this.node_dragged.pos[0] = this.graph_mouse[0] - 5; - this.node_dragged.pos[1] = this.graph_mouse[1] - 5; - this.graph.afterChange(); - } - else - console.error("graph input node not found:", type); - } - ctx.fillStyle = "#9C9"; - ctx.beginPath(); - ctx.arc(canvas_w - w + 16, y + h * 0.5, 5, 0, 2 * Math.PI); - ctx.fill(); - ctx.fillStyle = "#AAA"; - ctx.fillText(output.name, canvas_w - w + 30, y + h * 0.75); - // var tw = ctx.measureText(input.name); - ctx.fillStyle = "#777"; - ctx.fillText(output.type, canvas_w - w + 130, y + h * 0.75); - y += h; - } - //add + button - if (this.drawButton(canvas_w - w, y + 2, w - 20, h - 2, "+", "#151515", "#222")) { - this.showSubgraphPropertiesDialogRight(subnode); - } - } - //Draws a button into the canvas overlay and computes if it was clicked using the immediate gui paradigm - LGraphCanvas.prototype.drawButton = function( x,y,w,h, text, bgcolor, hovercolor, textcolor ) - { - var ctx = this.ctx; - bgcolor = bgcolor || LiteGraph.NODE_DEFAULT_COLOR; - hovercolor = hovercolor || "#555"; - textcolor = textcolor || LiteGraph.NODE_TEXT_COLOR; - var yFix = y + LiteGraph.NODE_TITLE_HEIGHT + 2; // fix the height with the title - var pos = this.mouse; - var hover = LiteGraph.isInsideRectangle( pos[0], pos[1], x,yFix,w,h ); - pos = this.last_click_position; - var clicked = pos && LiteGraph.isInsideRectangle( pos[0], pos[1], x,yFix,w,h ); - - ctx.fillStyle = hover ? hovercolor : bgcolor; - if(clicked) - ctx.fillStyle = "#AAA"; - ctx.beginPath(); - ctx.roundRect(x,y,w,h,[4] ); - ctx.fill(); - - if(text != null) - { - if(text.constructor == String) - { - ctx.fillStyle = textcolor; - ctx.textAlign = "center"; - ctx.font = ((h * 0.65)|0) + "px Arial"; - ctx.fillText( text, x + w * 0.5,y + h * 0.75 ); - ctx.textAlign = "left"; - } - } - - var was_clicked = clicked && !this.block_click; - if(clicked) - this.blockClick(); - return was_clicked; - } - - LGraphCanvas.prototype.isAreaClicked = function( x,y,w,h, hold_click ) - { - var pos = this.mouse; - var hover = LiteGraph.isInsideRectangle( pos[0], pos[1], x,y,w,h ); - pos = this.last_click_position; - var clicked = pos && LiteGraph.isInsideRectangle( pos[0], pos[1], x,y,w,h ); - var was_clicked = clicked && !this.block_click; - if(clicked && hold_click) - this.blockClick(); - return was_clicked; - } - - /** - * draws some useful stats in the corner of the canvas - * @method renderInfo - **/ - LGraphCanvas.prototype.renderInfo = function(ctx, x, y) { - x = x || 10; - y = y || this.canvas.height - 80; - - ctx.save(); - ctx.translate(x, y); - - ctx.font = "10px Arial"; - ctx.fillStyle = "#888"; - ctx.textAlign = "left"; - if (this.graph) { - ctx.fillText( "T: " + this.graph.globaltime.toFixed(2) + "s", 5, 13 * 1 ); - ctx.fillText("I: " + this.graph.iteration, 5, 13 * 2 ); - ctx.fillText("N: " + this.graph._nodes.length + " [" + this.visible_nodes.length + "]", 5, 13 * 3 ); - ctx.fillText("V: " + this.graph._version, 5, 13 * 4); - ctx.fillText("FPS:" + this.fps.toFixed(2), 5, 13 * 5); - } else { - ctx.fillText("No graph selected", 5, 13 * 1); - } - ctx.restore(); - }; - - /** - * draws the back canvas (the one containing the background and the connections) - * @method drawBackCanvas - **/ - LGraphCanvas.prototype.drawBackCanvas = function() { - var canvas = this.bgcanvas; - if ( - canvas.width != this.canvas.width || - canvas.height != this.canvas.height - ) { - canvas.width = this.canvas.width; - canvas.height = this.canvas.height; - } - - if (!this.bgctx) { - this.bgctx = this.bgcanvas.getContext("2d"); - } - var ctx = this.bgctx; - if (ctx.start) { - ctx.start(); - } - - var viewport = this.viewport || [0,0,ctx.canvas.width,ctx.canvas.height]; - - //clear - if (this.clear_background) { - ctx.clearRect( viewport[0], viewport[1], viewport[2], viewport[3] ); - } - - //show subgraph stack header - if (this._graph_stack && this._graph_stack.length) { - ctx.save(); - var parent_graph = this._graph_stack[this._graph_stack.length - 1]; - var subgraph_node = this.graph._subgraph_node; - ctx.strokeStyle = subgraph_node.bgcolor; - ctx.lineWidth = 10; - ctx.strokeRect(1, 1, canvas.width - 2, canvas.height - 2); - ctx.lineWidth = 1; - ctx.font = "40px Arial"; - ctx.textAlign = "center"; - ctx.fillStyle = subgraph_node.bgcolor || "#AAA"; - var title = ""; - for (var i = 1; i < this._graph_stack.length; ++i) { - title += - this._graph_stack[i]._subgraph_node.getTitle() + " >> "; - } - ctx.fillText( - title + subgraph_node.getTitle(), - canvas.width * 0.5, - 40 - ); - ctx.restore(); - } - - var bg_already_painted = false; - if (this.onRenderBackground) { - bg_already_painted = this.onRenderBackground(canvas, ctx); - } - - //reset in case of error - if ( !this.viewport ) - { - ctx.restore(); - ctx.setTransform(1, 0, 0, 1, 0, 0); - } - this.visible_links.length = 0; - - if (this.graph) { - //apply transformations - ctx.save(); - this.ds.toCanvasContext(ctx); - - //render BG - if ( this.ds.scale < 1.5 && !bg_already_painted && this.clear_background_color ) - { - ctx.fillStyle = this.clear_background_color; - ctx.fillRect( - this.visible_area[0], - this.visible_area[1], - this.visible_area[2], - this.visible_area[3] - ); - } - - if ( - this.background_image && - this.ds.scale > 0.5 && - !bg_already_painted - ) { - if (this.zoom_modify_alpha) { - ctx.globalAlpha = - (1.0 - 0.5 / this.ds.scale) * this.editor_alpha; - } else { - ctx.globalAlpha = this.editor_alpha; - } - ctx.imageSmoothingEnabled = ctx.imageSmoothingEnabled = false; // ctx.mozImageSmoothingEnabled = - if ( - !this._bg_img || - this._bg_img.name != this.background_image - ) { - this._bg_img = new Image(); - this._bg_img.name = this.background_image; - this._bg_img.src = this.background_image; - var that = this; - this._bg_img.onload = function() { - that.draw(true, true); - }; - } - - var pattern = null; - if (this._pattern == null && this._bg_img.width > 0) { - pattern = ctx.createPattern(this._bg_img, "repeat"); - this._pattern_img = this._bg_img; - this._pattern = pattern; - } else { - pattern = this._pattern; - } - if (pattern) { - ctx.fillStyle = pattern; - ctx.fillRect( - this.visible_area[0], - this.visible_area[1], - this.visible_area[2], - this.visible_area[3] - ); - ctx.fillStyle = "transparent"; - } - - ctx.globalAlpha = 1.0; - ctx.imageSmoothingEnabled = ctx.imageSmoothingEnabled = true; //= ctx.mozImageSmoothingEnabled - } - - //groups - if (this.graph._groups.length && !this.live_mode) { - this.drawGroups(canvas, ctx); - } - - if (this.onDrawBackground) { - this.onDrawBackground(ctx, this.visible_area); - } - if (this.onBackgroundRender) { - //LEGACY - console.error( - "WARNING! onBackgroundRender deprecated, now is named onDrawBackground " - ); - this.onBackgroundRender = null; - } - - //DEBUG: show clipping area - //ctx.fillStyle = "red"; - //ctx.fillRect( this.visible_area[0] + 10, this.visible_area[1] + 10, this.visible_area[2] - 20, this.visible_area[3] - 20); - - //bg - if (this.render_canvas_border) { - ctx.strokeStyle = "#235"; - ctx.strokeRect(0, 0, canvas.width, canvas.height); - } - - if (this.render_connections_shadows) { - ctx.shadowColor = "#000"; - ctx.shadowOffsetX = 0; - ctx.shadowOffsetY = 0; - ctx.shadowBlur = 6; - } else { - ctx.shadowColor = "rgba(0,0,0,0)"; - } - - //draw connections - if (!this.live_mode) { - this.drawConnections(ctx); - } - - ctx.shadowColor = "rgba(0,0,0,0)"; - - //restore state - ctx.restore(); - } - - if (ctx.finish) { - ctx.finish(); - } - - this.dirty_bgcanvas = false; - this.dirty_canvas = true; //to force to repaint the front canvas with the bgcanvas - }; - - var temp_vec2 = new Float32Array(2); - - /** - * draws the given node inside the canvas - * @method drawNode - **/ - LGraphCanvas.prototype.drawNode = function(node, ctx) { - var glow = false; - this.current_node = node; - - var color = node.color || node.constructor.color || LiteGraph.NODE_DEFAULT_COLOR; - var bgcolor = node.bgcolor || node.constructor.bgcolor || LiteGraph.NODE_DEFAULT_BGCOLOR; - - //shadow and glow - if (node.mouseOver) { - glow = true; - } - - var low_quality = this.ds.scale < 0.6; //zoomed out - - //only render if it forces it to do it - if (this.live_mode) { - if (!node.flags.collapsed) { - ctx.shadowColor = "transparent"; - if (node.onDrawForeground) { - node.onDrawForeground(ctx, this, this.canvas); - } - } - return; - } - - var editor_alpha = this.editor_alpha; - ctx.globalAlpha = editor_alpha; - - if (this.render_shadows && !low_quality) { - ctx.shadowColor = LiteGraph.DEFAULT_SHADOW_COLOR; - ctx.shadowOffsetX = 2 * this.ds.scale; - ctx.shadowOffsetY = 2 * this.ds.scale; - ctx.shadowBlur = 3 * this.ds.scale; - } else { - ctx.shadowColor = "transparent"; - } - - //custom draw collapsed method (draw after shadows because they are affected) - if ( - node.flags.collapsed && - node.onDrawCollapsed && - node.onDrawCollapsed(ctx, this) == true - ) { - return; - } - - //clip if required (mask) - var shape = node._shape || LiteGraph.BOX_SHAPE; - var size = temp_vec2; - temp_vec2.set(node.size); - var horizontal = node.horizontal; // || node.flags.horizontal; - - if (node.flags.collapsed) { - ctx.font = this.inner_text_font; - var title = node.getTitle ? node.getTitle() : node.title; - if (title != null) { - node._collapsed_width = Math.min( - node.size[0], - ctx.measureText(title).width + - LiteGraph.NODE_TITLE_HEIGHT * 2 - ); //LiteGraph.NODE_COLLAPSED_WIDTH; - size[0] = node._collapsed_width; - size[1] = 0; - } - } - - if (node.clip_area) { - //Start clipping - ctx.save(); - ctx.beginPath(); - if (shape == LiteGraph.BOX_SHAPE) { - ctx.rect(0, 0, size[0], size[1]); - } else if (shape == LiteGraph.ROUND_SHAPE) { - ctx.roundRect(0, 0, size[0], size[1], [10]); - } else if (shape == LiteGraph.CIRCLE_SHAPE) { - ctx.arc( - size[0] * 0.5, - size[1] * 0.5, - size[0] * 0.5, - 0, - Math.PI * 2 - ); - } - ctx.clip(); - } - - //draw shape - if (node.has_errors) { - bgcolor = "red"; - } - this.drawNodeShape( - node, - ctx, - size, - color, - bgcolor, - node.is_selected, - node.mouseOver - ); - ctx.shadowColor = "transparent"; - - //draw foreground - if (node.onDrawForeground) { - node.onDrawForeground(ctx, this, this.canvas); - } - - //connection slots - ctx.textAlign = horizontal ? "center" : "left"; - ctx.font = this.inner_text_font; - - var render_text = !low_quality; - - var out_slot = this.connecting_output; - var in_slot = this.connecting_input; - ctx.lineWidth = 1; - - var max_y = 0; - var slot_pos = new Float32Array(2); //to reuse - - //render inputs and outputs - if (!node.flags.collapsed) { - //input connection slots - if (node.inputs) { - for (var i = 0; i < node.inputs.length; i++) { - var slot = node.inputs[i]; - - var slot_type = slot.type; - var slot_shape = slot.shape; - - ctx.globalAlpha = editor_alpha; - //change opacity of incompatible slots when dragging a connection - if ( this.connecting_output && !LiteGraph.isValidConnection( slot.type , out_slot.type) ) { - ctx.globalAlpha = 0.4 * editor_alpha; - } - - ctx.fillStyle = - slot.link != null - ? slot.color_on || - this.default_connection_color_byType[slot_type] || - this.default_connection_color.input_on - : slot.color_off || - this.default_connection_color_byTypeOff[slot_type] || - this.default_connection_color_byType[slot_type] || - this.default_connection_color.input_off; - - var pos = node.getConnectionPos(true, i, slot_pos); - pos[0] -= node.pos[0]; - pos[1] -= node.pos[1]; - if (max_y < pos[1] + LiteGraph.NODE_SLOT_HEIGHT * 0.5) { - max_y = pos[1] + LiteGraph.NODE_SLOT_HEIGHT * 0.5; - } - - ctx.beginPath(); - - if (slot_type == "array"){ - slot_shape = LiteGraph.GRID_SHAPE; // place in addInput? addOutput instead? - } - - var doStroke = true; - - if ( - slot.type === LiteGraph.EVENT || - slot.shape === LiteGraph.BOX_SHAPE - ) { - //MODDED - if(slot.link == null) { - if (horizontal) { - ctx.beginPath(); - ctx.moveTo(pos[0] - 5 + 0.5, pos[1] - 2 + 0.5); // top-left point - ctx.lineTo(pos[0] + 5.5, pos[1] + 0.5); // middle point - ctx.lineTo(pos[0] - 5 + 0.5, pos[1] + 2 + 0.5); // bottom-left point - ctx.closePath(); - ctx.stroke(); - } else { - ctx.beginPath(); - ctx.moveTo(pos[0] - 5 + 0.5, pos[1] - 2 + 0.5); // top-left point - ctx.lineTo(pos[0] + 5.5, pos[1] + 0.5); // middle-right point - ctx.lineTo(pos[0] - 5 + 0.5, pos[1] + 2 + 0.5); // bottom-left point - ctx.closePath(); - ctx.stroke(); - } - } else { - if (horizontal) { - ctx.beginPath(); - ctx.moveTo(pos[0] - 5 + 0.5, pos[1] - 6 + 0.5); // top-left point - ctx.lineTo(pos[0] + 5.5, pos[1] + 0.5); // middle point - ctx.lineTo(pos[0] - 5 + 0.5, pos[1] + 6 + 0.5); // bottom-left point - ctx.closePath(); - ctx.stroke(); - } else { - ctx.beginPath(); - ctx.moveTo(pos[0] - 5 + 0.5, pos[1] - 6 + 0.5); // top-left point - ctx.lineTo(pos[0] + 5.5, pos[1] + 0.5); // middle-right point - ctx.lineTo(pos[0] - 5 + 0.5, pos[1] + 6 + 0.5); // bottom-left point - ctx.closePath(); - ctx.stroke(); - } - } - } else if (slot_shape === LiteGraph.ARROW_SHAPE) { - ctx.moveTo(pos[0] + 8, pos[1] + 0.5); - ctx.lineTo(pos[0] - 4, pos[1] + 6 + 0.5); - ctx.lineTo(pos[0] - 4, pos[1] - 6 + 0.5); - ctx.closePath(); - } else if (slot_shape === LiteGraph.GRID_SHAPE) { - ctx.rect(pos[0] - 4, pos[1] - 4, 2, 2); - ctx.rect(pos[0] - 1, pos[1] - 4, 2, 2); - ctx.rect(pos[0] + 2, pos[1] - 4, 2, 2); - ctx.rect(pos[0] - 4, pos[1] - 1, 2, 2); - ctx.rect(pos[0] - 1, pos[1] - 1, 2, 2); - ctx.rect(pos[0] + 2, pos[1] - 1, 2, 2); - ctx.rect(pos[0] - 4, pos[1] + 2, 2, 2); - ctx.rect(pos[0] - 1, pos[1] + 2, 2, 2); - ctx.rect(pos[0] + 2, pos[1] + 2, 2, 2); - doStroke = false; - } else { - if(low_quality) - ctx.rect(pos[0] - 4, pos[1] - 4, 8, 8 ); //faster - else - ctx.arc(pos[0], pos[1], 4, 0, Math.PI * 2); - } - ctx.fill(); - - //render name - if (render_text && !( - slot_type === LiteGraph.EVENT || //MODDED - slot_shape === LiteGraph.BOX_SHAPE - )) { - var text = slot.label != null ? slot.label : slot.name; - if (text) { - ctx.fillStyle = LiteGraph.NODE_TEXT_COLOR; - if (horizontal || slot.dir == LiteGraph.UP) { - ctx.fillText(text, pos[0], pos[1] - 10); - } else { - ctx.fillText(text, pos[0] + 10, pos[1] + 5); - } - } - } - } - } - - //output connection slots - - ctx.textAlign = horizontal ? "center" : "right"; - ctx.strokeStyle = "black"; - if (node.outputs) { - for (var i = 0; i < node.outputs.length; i++) { - var slot = node.outputs[i]; - - var slot_type = slot.type; - var slot_shape = slot.shape; - - //change opacity of incompatible slots when dragging a connection - if (this.connecting_input && !LiteGraph.isValidConnection( slot_type , in_slot.type) ) { - ctx.globalAlpha = 0.4 * editor_alpha; - } - - var pos = node.getConnectionPos(false, i, slot_pos); - pos[0] -= node.pos[0]; - pos[1] -= node.pos[1]; - if (max_y < pos[1] + LiteGraph.NODE_SLOT_HEIGHT * 0.5) { - max_y = pos[1] + LiteGraph.NODE_SLOT_HEIGHT * 0.5; - } - - ctx.fillStyle = - slot.links && slot.links.length - ? slot.color_on || - this.default_connection_color_byType[slot_type] || - this.default_connection_color.output_on - : slot.color_off || - this.default_connection_color_byTypeOff[slot_type] || - this.default_connection_color_byType[slot_type] || - this.default_connection_color.output_off; - ctx.beginPath(); - //ctx.rect( node.size[0] - 14,i*14,10,10); - - if (slot_type == "array"){ - slot_shape = LiteGraph.GRID_SHAPE; - } - - var doStroke = true; - - if ( - slot_type === LiteGraph.EVENT || - slot_shape === LiteGraph.BOX_SHAPE - ) { - //MODDED - if(!(slot.links && slot.links.length)) { - if (horizontal) { - ctx.beginPath(); - ctx.moveTo(pos[0] - 5 + 0.5, pos[1] - 2 + 0.5); // top-left point - ctx.lineTo(pos[0] + 5.5, pos[1] + 0.5); // middle point - ctx.lineTo(pos[0] - 5 + 0.5, pos[1] + 2 + 0.5); // bottom-left point - ctx.closePath(); - ctx.stroke(); - } else { - ctx.beginPath(); - ctx.moveTo(pos[0] - 5 + 0.5, pos[1] - 2 + 0.5); // top-left point - ctx.lineTo(pos[0] + 5.5, pos[1] + 0.5); // middle-right point - ctx.lineTo(pos[0] - 5 + 0.5, pos[1] + 2 + 0.5); // bottom-left point - ctx.closePath(); - ctx.stroke(); - } - } else { - if (horizontal) { - ctx.beginPath(); - ctx.moveTo(pos[0] - 5 + 0.5, pos[1] - 6 + 0.5); // top-left point - ctx.lineTo(pos[0] + 5.5, pos[1] + 0.5); // middle point - ctx.lineTo(pos[0] - 5 + 0.5, pos[1] + 6 + 0.5); // bottom-left point - ctx.closePath(); - ctx.stroke(); - } else { - ctx.beginPath(); - ctx.moveTo(pos[0] - 5 + 0.5, pos[1] - 6 + 0.5); // top-left point - ctx.lineTo(pos[0] + 5.5, pos[1] + 0.5); // middle-right point - ctx.lineTo(pos[0] - 5 + 0.5, pos[1] + 6 + 0.5); // bottom-left point - ctx.closePath(); - ctx.stroke(); - } - } - } else if (slot_shape === LiteGraph.ARROW_SHAPE) { - ctx.moveTo(pos[0] + 8, pos[1] + 0.5); - ctx.lineTo(pos[0] - 4, pos[1] + 6 + 0.5); - ctx.lineTo(pos[0] - 4, pos[1] - 6 + 0.5); - ctx.closePath(); - } else if (slot_shape === LiteGraph.GRID_SHAPE) { - ctx.rect(pos[0] - 4, pos[1] - 4, 2, 2); - ctx.rect(pos[0] - 1, pos[1] - 4, 2, 2); - ctx.rect(pos[0] + 2, pos[1] - 4, 2, 2); - ctx.rect(pos[0] - 4, pos[1] - 1, 2, 2); - ctx.rect(pos[0] - 1, pos[1] - 1, 2, 2); - ctx.rect(pos[0] + 2, pos[1] - 1, 2, 2); - ctx.rect(pos[0] - 4, pos[1] + 2, 2, 2); - ctx.rect(pos[0] - 1, pos[1] + 2, 2, 2); - ctx.rect(pos[0] + 2, pos[1] + 2, 2, 2); - doStroke = false; - } else { - if(low_quality) - ctx.rect(pos[0] - 4, pos[1] - 4, 8, 8 ); - else - ctx.arc(pos[0], pos[1], 4, 0, Math.PI * 2); - } - - //trigger - //if(slot.node_id != null && slot.slot == -1) - // ctx.fillStyle = "#F85"; - - //if(slot.links != null && slot.links.length) - ctx.fill(); - if(!low_quality && doStroke) - ctx.stroke(); - - //render output name - if (render_text && !( - slot_type === LiteGraph.EVENT || //MODDED - slot_shape === LiteGraph.BOX_SHAPE - )) { - var text = slot.label != null ? slot.label : slot.name; - if (text) { - ctx.fillStyle = LiteGraph.NODE_TEXT_COLOR; - if (horizontal || slot.dir == LiteGraph.DOWN) { - ctx.fillText(text, pos[0], pos[1] - 8); - } else { - ctx.fillText(text, pos[0] - 10, pos[1] + 5); - } - } - } - } - } - - ctx.textAlign = "left"; - ctx.globalAlpha = 1; - - if (node.widgets) { - var widgets_y = max_y; - if (horizontal || node.widgets_up) { - widgets_y = 2; - } - if( node.widgets_start_y != null ) - widgets_y = node.widgets_start_y; - this.drawNodeWidgets( - node, - widgets_y, - ctx, - this.node_widget && this.node_widget[0] == node - ? this.node_widget[1] - : null - ); - } - } else if (this.render_collapsed_slots) { - //if collapsed - var input_slot = null; - var output_slot = null; - - //get first connected slot to render - if (node.inputs) { - for (var i = 0; i < node.inputs.length; i++) { - var slot = node.inputs[i]; - if (slot.link == null) { - continue; - } - input_slot = slot; - break; - } - } - if (node.outputs) { - for (var i = 0; i < node.outputs.length; i++) { - var slot = node.outputs[i]; - if (!slot.links || !slot.links.length) { - continue; - } - output_slot = slot; - } - } - - if (input_slot) { - var x = 0; - var y = LiteGraph.NODE_TITLE_HEIGHT * -0.5; //center - if (horizontal) { - x = node._collapsed_width * 0.5; - y = -LiteGraph.NODE_TITLE_HEIGHT; - } - ctx.fillStyle = "#686"; - ctx.beginPath(); - if ( - slot.type === LiteGraph.EVENT || - slot.shape === LiteGraph.BOX_SHAPE - ) { - ctx.rect(x - 7 + 0.5, y - 4, 14, 8); - } else if (slot.shape === LiteGraph.ARROW_SHAPE) { - ctx.moveTo(x + 8, y); - ctx.lineTo(x + -4, y - 4); - ctx.lineTo(x + -4, y + 4); - ctx.closePath(); - } else { - ctx.arc(x, y, 4, 0, Math.PI * 2); - } - ctx.fill(); - } - - if (output_slot) { - var x = node._collapsed_width; - var y = LiteGraph.NODE_TITLE_HEIGHT * -0.5; //center - if (horizontal) { - x = node._collapsed_width * 0.5; - y = 0; - } - ctx.fillStyle = "#686"; - ctx.strokeStyle = "black"; - ctx.beginPath(); - if ( - slot.type === LiteGraph.EVENT || //MODDED - slot.shape === LiteGraph.BOX_SHAPE - ) { - ctx.rect(x - 7 + 0.5, y - 4, 14, 8); - } else if (slot.shape === LiteGraph.ARROW_SHAPE) { - ctx.moveTo(x + 6, y); - ctx.lineTo(x - 6, y - 4); - ctx.lineTo(x - 6, y + 4); - ctx.closePath(); - } else { - ctx.arc(x, y, 4, 0, Math.PI * 2); - } - ctx.fill(); - //ctx.stroke(); - } - } - - if (node.clip_area) { - ctx.restore(); - } - - ctx.globalAlpha = 1.0; - }; - - //used by this.over_link_center - LGraphCanvas.prototype.drawLinkTooltip = function( ctx, link ) - { - var pos = link._pos; - ctx.fillStyle = "black"; - ctx.beginPath(); - ctx.arc( pos[0], pos[1], 3, 0, Math.PI * 2 ); - ctx.fill(); - - if(link.data == null) - return; - - if(this.onDrawLinkTooltip) - if( this.onDrawLinkTooltip(ctx,link,this) == true ) - return; - - var data = link.data; - var text = null; - - if( data.constructor === Number ) - text = data.toFixed(2); - else if( data.constructor === String ) - text = "\"" + data + "\""; - else if( data.constructor === Boolean ) - text = String(data); - else if (data.toToolTip) - text = data.toToolTip(); - else - text = "[" + data.constructor.name + "]"; - - if(text == null) - return; - text = text.substr(0,30); //avoid weird - - ctx.font = "14px Courier New"; - var info = ctx.measureText(text); - var w = info.width + 20; - var h = 24; - ctx.shadowColor = "black"; - ctx.shadowOffsetX = 2; - ctx.shadowOffsetY = 2; - ctx.shadowBlur = 3; - ctx.fillStyle = "#454"; - ctx.beginPath(); - ctx.roundRect( pos[0] - w*0.5, pos[1] - 15 - h, w, h, [3]); - ctx.moveTo( pos[0] - 10, pos[1] - 15 ); - ctx.lineTo( pos[0] + 10, pos[1] - 15 ); - ctx.lineTo( pos[0], pos[1] - 5 ); - ctx.fill(); - ctx.shadowColor = "transparent"; - ctx.textAlign = "center"; - ctx.fillStyle = "#CEC"; - ctx.fillText(text, pos[0], pos[1] - 15 - h * 0.3); - } - - /** - * draws the shape of the given node in the canvas - * @method drawNodeShape - **/ - var tmp_area = new Float32Array(4); - - LGraphCanvas.prototype.drawNodeShape = function( - node, - ctx, - size, - fgcolor, - bgcolor, - selected, - mouse_over - ) { - //bg rect - ctx.strokeStyle = fgcolor; - ctx.fillStyle = bgcolor; - - var title_height = LiteGraph.NODE_TITLE_HEIGHT; - var low_quality = this.ds.scale < 0.5; - - //render node area depending on shape - var shape = - node._shape || node.constructor.shape || LiteGraph.ROUND_SHAPE; - - var title_mode = node.constructor.title_mode; - - var render_title = true; - if (title_mode == LiteGraph.TRANSPARENT_TITLE || title_mode == LiteGraph.NO_TITLE) { - render_title = false; - } else if (title_mode == LiteGraph.AUTOHIDE_TITLE && mouse_over) { - render_title = true; - } - - var area = tmp_area; - area[0] = 0; //x - area[1] = render_title ? -title_height : 0; //y - area[2] = size[0] + 1; //w - area[3] = render_title ? size[1] + title_height : size[1]; //h - - var old_alpha = ctx.globalAlpha; - - //full node shape - //if(node.flags.collapsed) - { - ctx.beginPath(); - if (shape == LiteGraph.BOX_SHAPE || low_quality) { - ctx.fillRect(area[0], area[1], area[2], area[3]); - } else if ( - shape == LiteGraph.ROUND_SHAPE || - shape == LiteGraph.CARD_SHAPE - ) { - ctx.roundRect( - area[0], - area[1], - area[2], - area[3], - shape == LiteGraph.CARD_SHAPE ? [this.round_radius,this.round_radius,0,0] : [this.round_radius] - ); - } else if (shape == LiteGraph.CIRCLE_SHAPE) { - ctx.arc( - size[0] * 0.5, - size[1] * 0.5, - size[0] * 0.5, - 0, - Math.PI * 2 - ); - } - ctx.fill(); - - //separator - if(!node.flags.collapsed && render_title) - { - ctx.shadowColor = "transparent"; - ctx.fillStyle = "rgba(0,0,0,0.2)"; - ctx.fillRect(0, -1, area[2], 2); - } - } - ctx.shadowColor = "transparent"; - - if (node.onDrawBackground) { - node.onDrawBackground(ctx, this, this.canvas, this.graph_mouse ); - } - - //title bg (remember, it is rendered ABOVE the node) - if (render_title || title_mode == LiteGraph.TRANSPARENT_TITLE) { - //title bar - if (node.onDrawTitleBar) { - node.onDrawTitleBar( ctx, title_height, size, this.ds.scale, fgcolor ); - } else if ( - title_mode != LiteGraph.TRANSPARENT_TITLE && - (node.constructor.title_color || this.render_title_colored) - ) { - var title_color = node.constructor.title_color || fgcolor; - - if (node.flags.collapsed) { - ctx.shadowColor = LiteGraph.DEFAULT_SHADOW_COLOR; - } - - //* gradient test - if (this.use_gradients) { - var grad = LGraphCanvas.gradients[title_color]; - if (!grad) { - grad = LGraphCanvas.gradients[ title_color ] = ctx.createLinearGradient(0, 0, 400, 0); - grad.addColorStop(0, title_color); // TODO refactor: validate color !! prevent DOMException - grad.addColorStop(1, "#000"); - } - ctx.fillStyle = grad; - } else { - ctx.fillStyle = title_color; - } - - //ctx.globalAlpha = 0.5 * old_alpha; - ctx.beginPath(); - if (shape == LiteGraph.BOX_SHAPE || low_quality) { - ctx.rect(0, -title_height, size[0] + 1, title_height); - } else if ( shape == LiteGraph.ROUND_SHAPE || shape == LiteGraph.CARD_SHAPE ) { - ctx.roundRect( - 0, - -title_height, - size[0] + 1, - title_height, - node.flags.collapsed ? [this.round_radius] : [this.round_radius,this.round_radius,0,0] - ); - } - ctx.fill(); - ctx.shadowColor = "transparent"; - } - - var colState = false; - if (LiteGraph.node_box_coloured_by_mode){ - if(LiteGraph.NODE_MODES_COLORS[node.mode]){ - colState = LiteGraph.NODE_MODES_COLORS[node.mode]; - } - } - if (LiteGraph.node_box_coloured_when_on){ - colState = node.action_triggered ? "#FFF" : (node.execute_triggered ? "#AAA" : colState); - } - - //title box - var box_size = 10; - if (node.onDrawTitleBox) { - node.onDrawTitleBox(ctx, title_height, size, this.ds.scale); - } else if ( - shape == LiteGraph.ROUND_SHAPE || - shape == LiteGraph.CIRCLE_SHAPE || - shape == LiteGraph.CARD_SHAPE - ) { - if (low_quality) { - ctx.fillStyle = "black"; - ctx.beginPath(); - ctx.arc( - title_height * 0.5, - title_height * -0.5, - box_size * 0.5 + 1, - 0, - Math.PI * 2 - ); - ctx.fill(); - } - - ctx.fillStyle = node.boxcolor || colState || LiteGraph.NODE_DEFAULT_BOXCOLOR; - if(low_quality) - ctx.fillRect( title_height * 0.5 - box_size *0.5, title_height * -0.5 - box_size *0.5, box_size , box_size ); - else - { - ctx.beginPath(); - ctx.arc( - title_height * 0.5, - title_height * -0.5, - box_size * 0.5, - 0, - Math.PI * 2 - ); - ctx.fill(); - } - } else { - if (low_quality) { - ctx.fillStyle = "black"; - ctx.fillRect( - (title_height - box_size) * 0.5 - 1, - (title_height + box_size) * -0.5 - 1, - box_size + 2, - box_size + 2 - ); - } - ctx.fillStyle = node.boxcolor || colState || LiteGraph.NODE_DEFAULT_BOXCOLOR; - ctx.fillRect( - (title_height - box_size) * 0.5, - (title_height + box_size) * -0.5, - box_size, - box_size - ); - } - ctx.globalAlpha = old_alpha; - - //title text - if (node.onDrawTitleText) { - node.onDrawTitleText( - ctx, - title_height, - size, - this.ds.scale, - this.title_text_font, - selected - ); - } - if (!low_quality) { - ctx.font = this.title_text_font; - var title = String(node.getTitle()); - if (title) { - if (selected) { - ctx.fillStyle = LiteGraph.NODE_SELECTED_TITLE_COLOR; - } else { - ctx.fillStyle = - node.constructor.title_text_color || - this.node_title_color; - } - if (node.flags.collapsed) { - ctx.textAlign = "left"; - var measure = ctx.measureText(title); - ctx.fillText( - title.substr(0,20), //avoid urls too long - title_height,// + measure.width * 0.5, - LiteGraph.NODE_TITLE_TEXT_Y - title_height - ); - ctx.textAlign = "left"; - } else { - ctx.textAlign = "left"; - ctx.fillText( - title, - title_height, - LiteGraph.NODE_TITLE_TEXT_Y - title_height - ); - } - } - } - - //subgraph box - if (!node.flags.collapsed && node.subgraph && !node.skip_subgraph_button) { - var w = LiteGraph.NODE_TITLE_HEIGHT; - var x = node.size[0] - w; - var over = LiteGraph.isInsideRectangle( this.graph_mouse[0] - node.pos[0], this.graph_mouse[1] - node.pos[1], x+2, -w+2, w-4, w-4 ); - ctx.fillStyle = over ? "#888" : "#555"; - if( shape == LiteGraph.BOX_SHAPE || low_quality) - ctx.fillRect(x+2, -w+2, w-4, w-4); - else - { - ctx.beginPath(); - ctx.roundRect(x+2, -w+2, w-4, w-4,[4]); - ctx.fill(); - } - ctx.fillStyle = "#333"; - ctx.beginPath(); - ctx.moveTo(x + w * 0.2, -w * 0.6); - ctx.lineTo(x + w * 0.8, -w * 0.6); - ctx.lineTo(x + w * 0.5, -w * 0.3); - ctx.fill(); - } - - //custom title render - if (node.onDrawTitle) { - node.onDrawTitle(ctx); - } - } - - //render selection marker - if (selected) { - if (node.onBounding) { - node.onBounding(area); - } - - if (title_mode == LiteGraph.TRANSPARENT_TITLE) { - area[1] -= title_height; - area[3] += title_height; - } - ctx.lineWidth = 1; - ctx.globalAlpha = 0.8; - ctx.beginPath(); - if (shape == LiteGraph.BOX_SHAPE) { - ctx.rect( - -6 + area[0], - -6 + area[1], - 12 + area[2], - 12 + area[3] - ); - } else if ( - shape == LiteGraph.ROUND_SHAPE || - (shape == LiteGraph.CARD_SHAPE && node.flags.collapsed) - ) { - ctx.roundRect( - -6 + area[0], - -6 + area[1], - 12 + area[2], - 12 + area[3], - [this.round_radius * 2] - ); - } else if (shape == LiteGraph.CARD_SHAPE) { - ctx.roundRect( - -6 + area[0], - -6 + area[1], - 12 + area[2], - 12 + area[3], - [this.round_radius * 2,2,this.round_radius * 2,2] - ); - } else if (shape == LiteGraph.CIRCLE_SHAPE) { - ctx.arc( - size[0] * 0.5, - size[1] * 0.5, - size[0] * 0.5 + 6, - 0, - Math.PI * 2 - ); - } - ctx.strokeStyle = LiteGraph.NODE_BOX_OUTLINE_COLOR; - ctx.stroke(); - ctx.strokeStyle = fgcolor; - ctx.globalAlpha = 1; - } - - // these counter helps in conditioning drawing based on if the node has been executed or an action occurred - if (node.execute_triggered>0) node.execute_triggered--; - if (node.action_triggered>0) node.action_triggered--; - }; - - var margin_area = new Float32Array(4); - var link_bounding = new Float32Array(4); - var tempA = new Float32Array(2); - var tempB = new Float32Array(2); - - /** - * draws every connection visible in the canvas - * OPTIMIZE THIS: pre-catch connections position instead of recomputing them every time - * @method drawConnections - **/ - LGraphCanvas.prototype.drawConnections = function(ctx) { - var now = LiteGraph.getTime(); - var visible_area = this.visible_area; - margin_area[0] = visible_area[0] - 20; - margin_area[1] = visible_area[1] - 20; - margin_area[2] = visible_area[2] + 40; - margin_area[3] = visible_area[3] + 40; - - //draw connections - ctx.lineWidth = this.connections_width; - - ctx.fillStyle = "#AAA"; - ctx.strokeStyle = "#AAA"; - ctx.globalAlpha = this.editor_alpha; - //for every node - var nodes = this.graph._nodes; - for (var n = 0, l = nodes.length; n < l; ++n) { - var node = nodes[n]; - //for every input (we render just inputs because it is easier as every slot can only have one input) - if (!node.inputs || !node.inputs.length) { - continue; - } - - for (var i = 0; i < node.inputs.length; ++i) { - var input = node.inputs[i]; - if (!input || input.link == null) { - continue; - } - var link_id = input.link; - var link = this.graph.links[link_id]; - if (!link) { - continue; - } - - let drawLink = (link) => { - - //find link info - var start_node = this.graph.getNodeById(link.origin_id); - if (start_node == null) { - return; - } - - var start_node_slot = link.origin_slot; - var start_node_slotpos = null; - if (start_node_slot == -1) { - start_node_slotpos = [ - start_node.pos[0] + 10, - start_node.pos[1] + 10 - ]; - } else { - start_node_slotpos = start_node.getConnectionPos( - false, - start_node_slot, - tempA - ); - } - var end_node_slotpos = node.getConnectionPos(true, i, tempB); - - //compute link bounding - link_bounding[0] = start_node_slotpos[0]; - link_bounding[1] = start_node_slotpos[1]; - link_bounding[2] = end_node_slotpos[0] - start_node_slotpos[0]; - link_bounding[3] = end_node_slotpos[1] - start_node_slotpos[1]; - if (link_bounding[2] < 0) { - link_bounding[0] += link_bounding[2]; - link_bounding[2] = Math.abs(link_bounding[2]); - } - if (link_bounding[3] < 0) { - link_bounding[1] += link_bounding[3]; - link_bounding[3] = Math.abs(link_bounding[3]); - } - - //skip links outside of the visible area of the canvas - if (!overlapBounding(link_bounding, margin_area)) { - return; - } - - var start_slot = start_node.outputs[start_node_slot]; - var end_slot = node.inputs[i]; - if (!start_slot || !end_slot) { - return; - } - - var start_dir = - start_slot.dir || - (start_node.horizontal ? LiteGraph.DOWN : LiteGraph.RIGHT); - var end_dir = - end_slot.dir || - (node.horizontal ? LiteGraph.UP : LiteGraph.LEFT); - - this.renderLink( - ctx, - start_node_slotpos, - end_node_slotpos, - link, - false, - 0, - null, - start_dir, - end_dir, - undefined, - node.inputs[i] - ); - - //event triggered rendered on top - if (link && link._last_time && now - link._last_time < 1000) { - var f = 2.0 - (now - link._last_time) * 0.002; - var tmp = ctx.globalAlpha; - ctx.globalAlpha = tmp * f; - this.renderLink( - ctx, - start_node_slotpos, - end_node_slotpos, - link, - true, - f, - "white", - start_dir, - end_dir, - undefined, - node.inputs[i] - ); - ctx.globalAlpha = tmp; - } - } - - drawLink(link); - - if(input?.extraLinks) { - for(const key in input.extraLinks) { - let l = this.graph.links[input.extraLinks[key]]; - drawLink(l); - } - } - - } - } - ctx.globalAlpha = 1; - }; - - /** - * draws a link between two points - * @method renderLink - * @param {vec2} a start pos - * @param {vec2} b end pos - * @param {Object} link the link object with all the link info - * @param {boolean} skip_border ignore the shadow of the link - * @param {boolean} flow show flow animation (for events) - * @param {string} color the color for the link - * @param {number} start_dir the direction enum - * @param {number} end_dir the direction enum - * @param {number} num_sublines number of sublines (useful to represent vec3 or rgb) - **/ - LGraphCanvas.prototype.renderLink = function( - ctx, - a, - b, - link, - skip_border, - flow, - color, - start_dir, - end_dir, - num_sublines, - inputSlot - ) { - if (link) { - this.visible_links.push(link); - } - - //choose color - if(inputSlot?.name === execPin) { //MODDED - color = '#FFF'; - } else if(!link || link.type === "any") color = '#EAD6FF' - if (!color && link) { - color = link.color || LGraphCanvas.link_type_colors[link.type]; - } - if (!color) { - color = this.default_link_color; - } - if (link != null && this.highlighted_links[link.id]) { - color = "#FFB"; - } - - start_dir = start_dir || LiteGraph.RIGHT; - end_dir = end_dir || LiteGraph.LEFT; - - var dist = distance(a, b); - - if (this.render_connections_border && this.ds.scale > 0.6) { - ctx.lineWidth = this.connections_width + 4; - } - ctx.lineJoin = "round"; - num_sublines = num_sublines || 1; - if (num_sublines > 1) { - ctx.lineWidth = 0.5; - } - - //begin line shape - ctx.beginPath(); - for (var i = 0; i < num_sublines; i += 1) { - var offsety = (i - (num_sublines - 1) * 0.5) * 5; - - if (this.links_render_mode == LiteGraph.SPLINE_LINK) { - ctx.moveTo(a[0], a[1] + offsety); - var start_offset_x = 0; - var start_offset_y = 0; - var end_offset_x = 0; - var end_offset_y = 0; - switch (start_dir) { - case LiteGraph.LEFT: - start_offset_x = dist * -0.25; - break; - case LiteGraph.RIGHT: - start_offset_x = dist * 0.25; - break; - case LiteGraph.UP: - start_offset_y = dist * -0.25; - break; - case LiteGraph.DOWN: - start_offset_y = dist * 0.25; - break; - } - switch (end_dir) { - case LiteGraph.LEFT: - end_offset_x = dist * -0.25; - break; - case LiteGraph.RIGHT: - end_offset_x = dist * 0.25; - break; - case LiteGraph.UP: - end_offset_y = dist * -0.25; - break; - case LiteGraph.DOWN: - end_offset_y = dist * 0.25; - break; - } - ctx.bezierCurveTo( - a[0] + start_offset_x, - a[1] + start_offset_y + offsety, - b[0] + end_offset_x, - b[1] + end_offset_y + offsety, - b[0], - b[1] + offsety - ); - } else if (this.links_render_mode == LiteGraph.LINEAR_LINK) { - ctx.moveTo(a[0], a[1] + offsety); - var start_offset_x = 0; - var start_offset_y = 0; - var end_offset_x = 0; - var end_offset_y = 0; - switch (start_dir) { - case LiteGraph.LEFT: - start_offset_x = -1; - break; - case LiteGraph.RIGHT: - start_offset_x = 1; - break; - case LiteGraph.UP: - start_offset_y = -1; - break; - case LiteGraph.DOWN: - start_offset_y = 1; - break; - } - switch (end_dir) { - case LiteGraph.LEFT: - end_offset_x = -1; - break; - case LiteGraph.RIGHT: - end_offset_x = 1; - break; - case LiteGraph.UP: - end_offset_y = -1; - break; - case LiteGraph.DOWN: - end_offset_y = 1; - break; - } - var l = 15; - ctx.lineTo( - a[0] + start_offset_x * l, - a[1] + start_offset_y * l + offsety - ); - ctx.lineTo( - b[0] + end_offset_x * l, - b[1] + end_offset_y * l + offsety - ); - ctx.lineTo(b[0], b[1] + offsety); - } else if (this.links_render_mode == LiteGraph.STRAIGHT_LINK) { - ctx.moveTo(a[0], a[1]); - var start_x = a[0]; - var start_y = a[1]; - var end_x = b[0]; - var end_y = b[1]; - if (start_dir == LiteGraph.RIGHT) { - start_x += 10; - } else { - start_y += 10; - } - if (end_dir == LiteGraph.LEFT) { - end_x -= 10; - } else { - end_y -= 10; - } - ctx.lineTo(start_x, start_y); - ctx.lineTo((start_x + end_x) * 0.5, start_y); - ctx.lineTo((start_x + end_x) * 0.5, end_y); - ctx.lineTo(end_x, end_y); - ctx.lineTo(b[0], b[1]); - } else { - return; - } //unknown - } - - //rendering the outline of the connection can be a little bit slow - if ( - this.render_connections_border && - this.ds.scale > 0.6 && - !skip_border - ) { - ctx.strokeStyle = "rgba(0,0,0,0.5)"; - ctx.stroke(); - } - - ctx.lineWidth = this.connections_width; - ctx.fillStyle = ctx.strokeStyle = color; - ctx.stroke(); - //end line shape - - var pos = this.computeConnectionPoint(a, b, 0.5, start_dir, end_dir); - if (link && link._pos) { - link._pos[0] = pos[0]; - link._pos[1] = pos[1]; - } - - //render arrow in the middle - if ( - this.ds.scale >= 0.6 && - this.highquality_render && - end_dir != LiteGraph.CENTER - ) { - //render arrow - if (this.render_connection_arrows || inputSlot?.name === execPin) { //MODDED - //compute two points in the connection - var posA = this.computeConnectionPoint( - a, - b, - 0.25, - start_dir, - end_dir - ); - var posB = this.computeConnectionPoint( - a, - b, - 0.26, - start_dir, - end_dir - ); - var posC = this.computeConnectionPoint( - a, - b, - 0.75, - start_dir, - end_dir - ); - var posD = this.computeConnectionPoint( - a, - b, - 0.76, - start_dir, - end_dir - ); - - //compute the angle between them so the arrow points in the right direction - var angleA = 0; - var angleB = 0; - if (this.render_curved_connections === false) { //MODDED - angleA = -Math.atan2(posB[0] - posA[0], posB[1] - posA[1]); - angleB = -Math.atan2(posD[0] - posC[0], posD[1] - posC[1]); - } else { - angleB = angleA = b[1] > a[1] ? 0 : Math.PI; - } - - //render arrow - ctx.save(); - ctx.translate(posA[0], posA[1]); - ctx.rotate(angleA); - ctx.beginPath(); - ctx.moveTo(-5, -3); - ctx.lineTo(0, +7); - ctx.lineTo(+5, -3); - ctx.fill(); - ctx.restore(); - ctx.save(); - ctx.translate(posC[0], posC[1]); - ctx.rotate(angleB); - ctx.beginPath(); - ctx.moveTo(-5, -3); - ctx.lineTo(0, +7); - ctx.lineTo(+5, -3); - ctx.fill(); - ctx.restore(); - } - - //circle at midpoint - - if(inputSlot?.name === execPin) {//MODDED - - var posE = this.computeConnectionPoint( - a, - b, - 0.75, - start_dir, - end_dir - ); - var posF = this.computeConnectionPoint( - a, - b, - 0.76, - start_dir, - end_dir - ); - let angleC = -Math.atan2(posF[0] - posE[0], posF[1] - posE[1]); - ctx.save(); - ctx.translate(pos[0], pos[1]); - ctx.rotate(angleC); - ctx.beginPath(); - ctx.moveTo(-5, -3); - ctx.lineTo(0, +7); - ctx.lineTo(+5, -3); - ctx.fill(); - ctx.restore(); - } else { - // ctx.beginPath(); - // ctx.arc(pos[0], pos[1], 5, 0, Math.PI * 2); - // ctx.fill(); - } - } - - //render flowing points - if (flow) { - ctx.fillStyle = color; - for (var i = 0; i < 5; ++i) { - var f = (LiteGraph.getTime() * 0.001 + i * 0.2) % 1; - var pos = this.computeConnectionPoint( - a, - b, - f, - start_dir, - end_dir - ); - ctx.beginPath(); - ctx.arc(pos[0], pos[1], 5, 0, 2 * Math.PI); - ctx.fill(); - } - } - }; - - //returns the link center point based on curvature - LGraphCanvas.prototype.computeConnectionPoint = function( - a, - b, - t, - start_dir, - end_dir - ) { - start_dir = start_dir || LiteGraph.RIGHT; - end_dir = end_dir || LiteGraph.LEFT; - - var dist = distance(a, b); - var p0 = a; - var p1 = [a[0], a[1]]; - var p2 = [b[0], b[1]]; - var p3 = b; - - switch (start_dir) { - case LiteGraph.LEFT: - p1[0] += dist * -0.25; - break; - case LiteGraph.RIGHT: - p1[0] += dist * 0.25; - break; - case LiteGraph.UP: - p1[1] += dist * -0.25; - break; - case LiteGraph.DOWN: - p1[1] += dist * 0.25; - break; - } - switch (end_dir) { - case LiteGraph.LEFT: - p2[0] += dist * -0.25; - break; - case LiteGraph.RIGHT: - p2[0] += dist * 0.25; - break; - case LiteGraph.UP: - p2[1] += dist * -0.25; - break; - case LiteGraph.DOWN: - p2[1] += dist * 0.25; - break; - } - - var c1 = (1 - t) * (1 - t) * (1 - t); - var c2 = 3 * ((1 - t) * (1 - t)) * t; - var c3 = 3 * (1 - t) * (t * t); - var c4 = t * t * t; - - var x = c1 * p0[0] + c2 * p1[0] + c3 * p2[0] + c4 * p3[0]; - var y = c1 * p0[1] + c2 * p1[1] + c3 * p2[1] + c4 * p3[1]; - return [x, y]; - }; - - LGraphCanvas.prototype.drawExecutionOrder = function(ctx) { - ctx.shadowColor = "transparent"; - ctx.globalAlpha = 0.25; - - ctx.textAlign = "center"; - ctx.strokeStyle = "white"; - ctx.globalAlpha = 0.75; - - var visible_nodes = this.visible_nodes; - for (var i = 0; i < visible_nodes.length; ++i) { - var node = visible_nodes[i]; - ctx.fillStyle = "black"; - ctx.fillRect( - node.pos[0] - LiteGraph.NODE_TITLE_HEIGHT, - node.pos[1] - LiteGraph.NODE_TITLE_HEIGHT, - LiteGraph.NODE_TITLE_HEIGHT, - LiteGraph.NODE_TITLE_HEIGHT - ); - if (node.order == 0) { - ctx.strokeRect( - node.pos[0] - LiteGraph.NODE_TITLE_HEIGHT + 0.5, - node.pos[1] - LiteGraph.NODE_TITLE_HEIGHT + 0.5, - LiteGraph.NODE_TITLE_HEIGHT, - LiteGraph.NODE_TITLE_HEIGHT - ); - } - ctx.fillStyle = "#FFF"; - ctx.fillText( - node.order, - node.pos[0] + LiteGraph.NODE_TITLE_HEIGHT * -0.5, - node.pos[1] - 6 - ); - } - ctx.globalAlpha = 1; - }; - - /** - * draws the widgets stored inside a node - * @method drawNodeWidgets - **/ - LGraphCanvas.prototype.drawNodeWidgets = function( - node, - posY, - ctx, - active_widget - ) { - if (!node.widgets || !node.widgets.length) { - return 0; - } - var width = node.size[0]; - var widgets = node.widgets; - posY += 2; - var H = LiteGraph.NODE_WIDGET_HEIGHT; - var show_text = this.ds.scale > 0.5; - ctx.save(); - ctx.globalAlpha = this.editor_alpha; - var outline_color = LiteGraph.WIDGET_OUTLINE_COLOR; - var background_color = LiteGraph.WIDGET_BGCOLOR; - var text_color = LiteGraph.WIDGET_TEXT_COLOR; - var secondary_text_color = LiteGraph.WIDGET_SECONDARY_TEXT_COLOR; - var margin = 15; - - for (var i = 0; i < widgets.length; ++i) { - var w = widgets[i]; - var y = posY; - if (w.y) { - y = w.y; - } - w.last_y = y; - ctx.strokeStyle = outline_color; - ctx.fillStyle = "#222"; - ctx.textAlign = "left"; - //ctx.lineWidth = 2; - if(w.disabled) - ctx.globalAlpha *= 0.5; - var widget_width = w.width || width; - - switch (w.type) { - case "button": - if (w.clicked) { - ctx.fillStyle = "#AAA"; - w.clicked = false; - this.dirty_canvas = true; - } - ctx.fillRect(margin, y, widget_width - margin * 2, H); - if(show_text && !w.disabled) - ctx.strokeRect( margin, y, widget_width - margin * 2, H ); - if (show_text) { - ctx.textAlign = "center"; - ctx.fillStyle = text_color; - ctx.fillText(w.name, widget_width * 0.5, y + H * 0.7); - } - break; - case "toggle": - ctx.textAlign = "left"; - ctx.strokeStyle = outline_color; - ctx.fillStyle = background_color; - ctx.beginPath(); - if (show_text) - ctx.roundRect(margin, y, widget_width - margin * 2, H, [H * 0.5]); - else - ctx.rect(margin, y, widget_width - margin * 2, H ); - ctx.fill(); - if(show_text && !w.disabled) - ctx.stroke(); - ctx.fillStyle = w.value ? "#89A" : "#333"; - ctx.beginPath(); - ctx.arc( widget_width - margin * 2, y + H * 0.5, H * 0.36, 0, Math.PI * 2 ); - ctx.fill(); - if (show_text) { - ctx.fillStyle = secondary_text_color; - if (w.name != null) { - ctx.fillText(w.name, margin * 2, y + H * 0.7); - } - ctx.fillStyle = w.value ? text_color : secondary_text_color; - ctx.textAlign = "right"; - ctx.fillText( - w.value - ? w.options.on || "true" - : w.options.off || "false", - widget_width - 40, - y + H * 0.7 - ); - } - break; - case "slider": - ctx.fillStyle = background_color; - ctx.fillRect(margin, y, widget_width - margin * 2, H); - var range = w.options.max - w.options.min; - var nvalue = (w.value - w.options.min) / range; - if(nvalue < 0.0) nvalue = 0.0; - if(nvalue > 1.0) nvalue = 1.0; - ctx.fillStyle = w.options.hasOwnProperty("slider_color") ? w.options.slider_color : (active_widget == w ? "#89A" : "#678"); - ctx.fillRect(margin, y, nvalue * (widget_width - margin * 2), H); - if(show_text && !w.disabled) - ctx.strokeRect(margin, y, widget_width - margin * 2, H); - if (w.marker) { - var marker_nvalue = (w.marker - w.options.min) / range; - if(marker_nvalue < 0.0) marker_nvalue = 0.0; - if(marker_nvalue > 1.0) marker_nvalue = 1.0; - ctx.fillStyle = w.options.hasOwnProperty("marker_color") ? w.options.marker_color : "#AA9"; - ctx.fillRect( margin + marker_nvalue * (widget_width - margin * 2), y, 2, H ); - } - if (show_text) { - ctx.textAlign = "center"; - ctx.fillStyle = text_color; - ctx.fillText( - w.name + " " + Number(w.value).toFixed(3), - widget_width * 0.5, - y + H * 0.7 - ); - } - break; - case "number": - case "combo": - ctx.textAlign = "left"; - ctx.strokeStyle = outline_color; - ctx.fillStyle = background_color; - ctx.beginPath(); - if(show_text) - ctx.roundRect(margin, y, widget_width - margin * 2, H, [H * 0.5] ); - else - ctx.rect(margin, y, widget_width - margin * 2, H ); - ctx.fill(); - if (show_text) { - if(!w.disabled) - ctx.stroke(); - ctx.fillStyle = text_color; - if(!w.disabled) - { - ctx.beginPath(); - ctx.moveTo(margin + 16, y + 5); - ctx.lineTo(margin + 6, y + H * 0.5); - ctx.lineTo(margin + 16, y + H - 5); - ctx.fill(); - ctx.beginPath(); - ctx.moveTo(widget_width - margin - 16, y + 5); - ctx.lineTo(widget_width - margin - 6, y + H * 0.5); - ctx.lineTo(widget_width - margin - 16, y + H - 5); - ctx.fill(); - } - ctx.fillStyle = secondary_text_color; - ctx.fillText(w.name, margin * 2 + 5, y + H * 0.7); - ctx.fillStyle = text_color; - ctx.textAlign = "right"; - if (w.type == "number") { - ctx.fillText( - Number(w.value).toFixed( - w.options.precision !== undefined - ? w.options.precision - : 3 - ), - widget_width - margin * 2 - 20, - y + H * 0.7 - ); - } else { - var v = w.value; - if( w.options.values ) - { - var values = w.options.values; - if( values.constructor === Function ) - values = values(); - if(values && values.constructor !== Array) - v = values[ w.value ]; - } - ctx.fillText( - v, - widget_width - margin * 2 - 20, - y + H * 0.7 - ); - } - } - break; - case "string": - case "text": - ctx.textAlign = "left"; - ctx.strokeStyle = outline_color; - ctx.fillStyle = background_color; - ctx.beginPath(); - if (show_text) - ctx.roundRect(margin, y, widget_width - margin * 2, H, [H * 0.5]); - else - ctx.rect( margin, y, widget_width - margin * 2, H ); - ctx.fill(); - if (show_text) { - if(!w.disabled) - ctx.stroke(); - ctx.save(); - ctx.beginPath(); - ctx.rect(margin, y, widget_width - margin * 2, H); - ctx.clip(); - - //ctx.stroke(); - ctx.fillStyle = secondary_text_color; - if (w.name != null) { - ctx.fillText(w.name, margin * 2, y + H * 0.7); - } - ctx.fillStyle = text_color; - ctx.textAlign = "right"; - ctx.fillText(String(w.value).substr(0,30), widget_width - margin * 2, y + H * 0.7); //30 chars max - ctx.restore(); - } - break; - default: - if (w.draw) { - w.draw(ctx, node, widget_width, y, H); - } - break; - } - posY += (w.computeSize ? w.computeSize(widget_width)[1] : H) + 4; - ctx.globalAlpha = this.editor_alpha; - - } - ctx.restore(); - ctx.textAlign = "left"; - }; - - /** - * process an event on widgets - * @method processNodeWidgets - **/ - LGraphCanvas.prototype.processNodeWidgets = function( - node, - pos, - event, - active_widget - ) { - if (!node.widgets || !node.widgets.length) { - return null; - } - - var x = pos[0] - node.pos[0]; - var y = pos[1] - node.pos[1]; - var width = node.size[0]; - var that = this; - var ref_window = this.getCanvasWindow(); - - for (var i = 0; i < node.widgets.length; ++i) { - var w = node.widgets[i]; - if(!w || w.disabled) - continue; - var widget_height = w.computeSize ? w.computeSize(width)[1] : LiteGraph.NODE_WIDGET_HEIGHT; - var widget_width = w.width || width; - //outside - if ( w != active_widget && - (x < 6 || x > widget_width - 12 || y < w.last_y || y > w.last_y + widget_height || w.last_y === undefined) ) - continue; - - var old_value = w.value; - - //if ( w == active_widget || (x > 6 && x < widget_width - 12 && y > w.last_y && y < w.last_y + widget_height) ) { - //inside widget - switch (w.type) { - case "button": - if (event.type === LiteGraph.pointerevents_method+"down") { - if (w.callback) { - setTimeout(function() { - w.callback(w, that, node, pos, event); - }, 20); - } - w.clicked = true; - this.dirty_canvas = true; - } - break; - case "slider": - var range = w.options.max - w.options.min; - var nvalue = Math.clamp((x - 15) / (widget_width - 30), 0, 1); - if(w.options.read_only) break; - w.value = w.options.min + (w.options.max - w.options.min) * nvalue; - if (w.callback) { - setTimeout(function() { - inner_value_change(w, w.value); - }, 20); - } - this.dirty_canvas = true; - break; - case "number": - case "combo": - var old_value = w.value; - if (event.type == LiteGraph.pointerevents_method+"move" && w.type == "number") { - if(event.deltaX) - w.value += event.deltaX * 0.1 * (w.options.step || 1); - if ( w.options.min != null && w.value < w.options.min ) { - w.value = w.options.min; - } - if ( w.options.max != null && w.value > w.options.max ) { - w.value = w.options.max; - } - } else if (event.type == LiteGraph.pointerevents_method+"down") { - var values = w.options.values; - if (values && values.constructor === Function) { - values = w.options.values(w, node); - } - var values_list = null; - - if( w.type != "number") - values_list = values.constructor === Array ? values : Object.keys(values); - - var delta = x < 40 ? -1 : x > widget_width - 40 ? 1 : 0; - if (w.type == "number") { - w.value += delta * 0.1 * (w.options.step || 1); - if ( w.options.min != null && w.value < w.options.min ) { - w.value = w.options.min; - } - if ( w.options.max != null && w.value > w.options.max ) { - w.value = w.options.max; - } - } else if (delta) { //clicked in arrow, used for combos - var index = -1; - this.last_mouseclick = 0; //avoids dobl click event - if(values.constructor === Object) - index = values_list.indexOf( String( w.value ) ) + delta; - else - index = values_list.indexOf( w.value ) + delta; - if (index >= values_list.length) { - index = values_list.length - 1; - } - if (index < 0) { - index = 0; - } - if( values.constructor === Array ) - w.value = values[index]; - else - w.value = index; - } else { //combo clicked - var text_values = values != values_list ? Object.values(values) : values; - var menu = new LiteGraph.ContextMenu(text_values, { - scale: Math.max(1, this.ds.scale), - event: event, - className: "dark", - callback: inner_clicked.bind(w) - }, - ref_window); - function inner_clicked(v, option, event) { - if(values != values_list) - v = text_values.indexOf(v); - this.value = v; - inner_value_change(this, v); - that.dirty_canvas = true; - return false; - } - } - } //end mousedown - else if(event.type == LiteGraph.pointerevents_method+"up" && w.type == "number") - { - var delta = x < 40 ? -1 : x > widget_width - 40 ? 1 : 0; - if (event.click_time < 200 && delta == 0) { - this.prompt("Value",w.value,function(v) { - // check if v is a valid equation or a number - if (/^[0-9+\-*/()\s]+$/.test(v)) { - try {//solve the equation if possible - v = eval(v); - } catch (e) { } - } - this.value = Number(v); - inner_value_change(this, this.value); - }.bind(w), - event); - } - } - - if( old_value != w.value ) - setTimeout( - function() { - inner_value_change(this, this.value); - }.bind(w), - 20 - ); - this.dirty_canvas = true; - break; - case "toggle": - if (event.type == LiteGraph.pointerevents_method+"down") { - w.value = !w.value; - setTimeout(function() { - inner_value_change(w, w.value); - }, 20); - } - break; - case "string": - case "text": - if (event.type == LiteGraph.pointerevents_method+"down") { - this.prompt("Value",w.value,function(v) { - inner_value_change(this, v); - }.bind(w), - event,w.options ? w.options.multiline : false ); - } - break; - default: - if (w.mouse) { - this.dirty_canvas = w.mouse(event, [x, y], node); - } - break; - } //end switch - - //value changed - if( old_value != w.value ) - { - if(node.onWidgetChanged) - node.onWidgetChanged( w.name,w.value,old_value,w ); - node.graph._version++; - } - - return w; - }//end for - - function inner_value_change(widget, value) { - if(widget.type == "number"){ - value = Number(value); - } - widget.value = value; - if ( widget.options && widget.options.property && node.properties[widget.options.property] !== undefined ) { - node.setProperty( widget.options.property, value ); - } - if (widget.callback) { - widget.callback(widget.value, that, node, pos, event); - } - } - - return null; - }; - - /** - * draws every group area in the background - * @method drawGroups - **/ - LGraphCanvas.prototype.drawGroups = function(canvas, ctx) { - if (!this.graph) { - return; - } - - var groups = this.graph._groups; - - ctx.save(); - ctx.globalAlpha = 0.5 * this.editor_alpha; - - for (var i = 0; i < groups.length; ++i) { - var group = groups[i]; - - if (!overlapBounding(this.visible_area, group._bounding)) { - continue; - } //out of the visible area - - ctx.fillStyle = group.color || "#335"; - ctx.strokeStyle = group.color || "#335"; - var pos = group._pos; - var size = group._size; - ctx.globalAlpha = 0.25 * this.editor_alpha; - ctx.beginPath(); - ctx.rect(pos[0] + 0.5, pos[1] + 0.5, size[0], size[1]); - ctx.fill(); - ctx.globalAlpha = this.editor_alpha; - ctx.stroke(); - - ctx.beginPath(); - ctx.moveTo(pos[0] + size[0], pos[1] + size[1]); - ctx.lineTo(pos[0] + size[0] - 10, pos[1] + size[1]); - ctx.lineTo(pos[0] + size[0], pos[1] + size[1] - 10); - ctx.fill(); - - var font_size = - group.font_size || LiteGraph.DEFAULT_GROUP_FONT_SIZE; - ctx.font = font_size + "px Arial"; - ctx.textAlign = "left"; - ctx.fillText(group.title, pos[0] + 4, pos[1] + font_size); - } - - ctx.restore(); - }; - - LGraphCanvas.prototype.adjustNodesSize = function() { - var nodes = this.graph._nodes; - for (var i = 0; i < nodes.length; ++i) { - nodes[i].size = nodes[i].computeSize(); - } - this.setDirty(true, true); - }; - - /** - * resizes the canvas to a given size, if no size is passed, then it tries to fill the parentNode - * @method resize - **/ - LGraphCanvas.prototype.resize = function(width, height) { - if (!width && !height) { - var parent = this.canvas.parentNode; - width = parent.offsetWidth; - height = parent.offsetHeight; - } - - if (this.canvas.width == width && this.canvas.height == height) { - return; - } - - this.canvas.width = width; - this.canvas.height = height; - this.bgcanvas.width = this.canvas.width; - this.bgcanvas.height = this.canvas.height; - this.setDirty(true, true); - }; - - /** - * switches to live mode (node shapes are not rendered, only the content) - * this feature was designed when graphs where meant to create user interfaces - * @method switchLiveMode - **/ - LGraphCanvas.prototype.switchLiveMode = function(transition) { - if (!transition) { - this.live_mode = !this.live_mode; - this.dirty_canvas = true; - this.dirty_bgcanvas = true; - return; - } - - var self = this; - var delta = this.live_mode ? 1.1 : 0.9; - if (this.live_mode) { - this.live_mode = false; - this.editor_alpha = 0.1; - } - - var t = setInterval(function() { - self.editor_alpha *= delta; - self.dirty_canvas = true; - self.dirty_bgcanvas = true; - - if (delta < 1 && self.editor_alpha < 0.01) { - clearInterval(t); - if (delta < 1) { - self.live_mode = true; - } - } - if (delta > 1 && self.editor_alpha > 0.99) { - clearInterval(t); - self.editor_alpha = 1; - } - }, 1); - }; - - LGraphCanvas.prototype.onNodeSelectionChange = function(node) { - return; //disabled - }; - - /* this is an implementation for touch not in production and not ready - */ - /*LGraphCanvas.prototype.touchHandler = function(event) { - //alert("foo"); - var touches = event.changedTouches, - first = touches[0], - type = ""; - - switch (event.type) { - case "touchstart": - type = "mousedown"; - break; - case "touchmove": - type = "mousemove"; - break; - case "touchend": - type = "mouseup"; - break; - default: - return; - } - - //initMouseEvent(type, canBubble, cancelable, view, clickCount, - // screenX, screenY, clientX, clientY, ctrlKey, - // altKey, shiftKey, metaKey, button, relatedTarget); - - // this is eventually a Dom object, get the LGraphCanvas back - if(typeof this.getCanvasWindow == "undefined"){ - var window = this.lgraphcanvas.getCanvasWindow(); - }else{ - var window = this.getCanvasWindow(); - } - - var document = window.document; - - var simulatedEvent = document.createEvent("MouseEvent"); - simulatedEvent.initMouseEvent( - type, - true, - true, - window, - 1, - first.screenX, - first.screenY, - first.clientX, - first.clientY, - false, - false, - false, - false, - 0, //left - null - ); - first.target.dispatchEvent(simulatedEvent); - event.preventDefault(); - };*/ - - /* CONTEXT MENU ********************/ - - LGraphCanvas.onGroupAdd = function(info, entry, mouse_event) { - var canvas = LGraphCanvas.active_canvas; - var ref_window = canvas.getCanvasWindow(); - - var group = new LiteGraph.LGraphGroup(); - group.pos = canvas.convertEventToCanvasOffset(mouse_event); - canvas.graph.add(group); - }; - - LGraphCanvas.onMenuAdd = function (node, options, e, prev_menu, callback) { - - var canvas = LGraphCanvas.active_canvas; - var ref_window = canvas.getCanvasWindow(); - var graph = canvas.graph; - if (!graph) - return; - - function inner_onMenuAdded(base_category ,prev_menu){ - - var categories = LiteGraph.getNodeTypesCategories(canvas.filter || graph.filter).filter(function(category){return category.startsWith(base_category)}); - var entries = []; - - categories.map(function(category){ - - if (!category) - return; - - var base_category_regex = new RegExp('^(' + base_category + ')'); - var category_name = category.replace(base_category_regex,"").split('/')[0]; - var category_path = base_category === '' ? category_name + '/' : base_category + category_name + '/'; - - var name = category_name; - if(name.indexOf("::") != -1) //in case it has a namespace like "shader::math/rand" it hides the namespace - name = name.split("::")[1]; - - var index = entries.findIndex(function(entry){return entry.value === category_path}); - if (index === -1) { - entries.push({ value: category_path, content: name, has_submenu: true, callback : function(value, event, mouseEvent, contextMenu){ - inner_onMenuAdded(value.value, contextMenu) - }}); - } - - }); - - var nodes = LiteGraph.getNodeTypesInCategory(base_category.slice(0, -1), canvas.filter || graph.filter ); - nodes.map(function(node){ - - if (node.skip_list) - return; - - var entry = { value: node.type, content: node.title, has_submenu: false , callback : function(value, event, mouseEvent, contextMenu){ - - var first_event = contextMenu.getFirstEvent(); - canvas.graph.beforeChange(); - var node = LiteGraph.createNode(value.value); - if (node) { - node.pos = canvas.convertEventToCanvasOffset(first_event); - canvas.graph.add(node); - } - if(callback) - callback(node); - canvas.graph.afterChange(); - - } - } - - entries.push(entry); - - }); - - new LiteGraph.ContextMenu( entries, { event: e, parentMenu: prev_menu }, ref_window ); - - } - - inner_onMenuAdded('',prev_menu); - return false; - - }; - - LGraphCanvas.onMenuCollapseAll = function() {}; - - LGraphCanvas.onMenuNodeEdit = function() {}; - - LGraphCanvas.showMenuNodeOptionalInputs = function( - v, - options, - e, - prev_menu, - node - ) { - if (!node) { - return; - } - - var that = this; - var canvas = LGraphCanvas.active_canvas; - var ref_window = canvas.getCanvasWindow(); - - var options = node.optional_inputs; - if (node.onGetInputs) { - options = node.onGetInputs(); - } - - var entries = []; - if (options) { - for (var i=0; i < options.length; i++) { - var entry = options[i]; - if (!entry) { - entries.push(null); - continue; - } - var label = entry[0]; - if(!entry[2]) - entry[2] = {}; - - if (entry[2].label) { - label = entry[2].label; - } - - entry[2].removable = true; - var data = { content: label, value: entry }; - if (entry[1] == LiteGraph.ACTION) { - data.className = "event"; - } - entries.push(data); - } - } - - if (node.onMenuNodeInputs) { - var retEntries = node.onMenuNodeInputs(entries); - if(retEntries) entries = retEntries; - } - - if (!entries.length) { - console.log("no input entries"); - return; - } - - var menu = new LiteGraph.ContextMenu( - entries, - { - event: e, - callback: inner_clicked, - parentMenu: prev_menu, - node: node - }, - ref_window - ); - - function inner_clicked(v, e, prev) { - if (!node) { - return; - } - - if (v.callback) { - v.callback.call(that, node, v, e, prev); - } - - if (v.value) { - node.graph.beforeChange(); - node.addInput(v.value[0], v.value[1], v.value[2]); - - if (node.onNodeInputAdd) { // callback to the node when adding a slot - node.onNodeInputAdd(v.value); - } - node.setDirtyCanvas(true, true); - node.graph.afterChange(); - } - } - - return false; - }; - - LGraphCanvas.showMenuNodeOptionalOutputs = function( - v, - options, - e, - prev_menu, - node - ) { - if (!node) { - return; - } - - var that = this; - var canvas = LGraphCanvas.active_canvas; - var ref_window = canvas.getCanvasWindow(); - - var options = node.optional_outputs; - if (node.onGetOutputs) { - options = node.onGetOutputs(); - } - - var entries = []; - if (options) { - for (var i=0; i < options.length; i++) { - var entry = options[i]; - if (!entry) { - //separator? - entries.push(null); - continue; - } - - if ( - node.flags && - node.flags.skip_repeated_outputs && - node.findOutputSlot(entry[0]) != -1 - ) { - continue; - } //skip the ones already on - var label = entry[0]; - if(!entry[2]) - entry[2] = {}; - if (entry[2].label) { - label = entry[2].label; - } - entry[2].removable = true; - var data = { content: label, value: entry }; - if (entry[1] == LiteGraph.EVENT) { - data.className = "event"; - } - entries.push(data); - } - } - - if (this.onMenuNodeOutputs) { - entries = this.onMenuNodeOutputs(entries); - } - if (LiteGraph.do_add_triggers_slots){ //canvas.allow_addOutSlot_onExecuted - if (node.findOutputSlot("onExecuted") == -1){ - entries.push({content: "On Executed", value: ["onExecuted", LiteGraph.EVENT, {nameLocked: true}], className: "event"}); //, opts: {} - } - } - // add callback for modifing the menu elements onMenuNodeOutputs - if (node.onMenuNodeOutputs) { - var retEntries = node.onMenuNodeOutputs(entries); - if(retEntries) entries = retEntries; - } - - if (!entries.length) { - return; - } - - var menu = new LiteGraph.ContextMenu( - entries, - { - event: e, - callback: inner_clicked, - parentMenu: prev_menu, - node: node - }, - ref_window - ); - - function inner_clicked(v, e, prev) { - if (!node) { - return; - } - - if (v.callback) { - v.callback.call(that, node, v, e, prev); - } - - if (!v.value) { - return; - } - - var value = v.value[1]; - - if ( - value && - (value.constructor === Object || value.constructor === Array) - ) { - //submenu why? - var entries = []; - for (var i in value) { - entries.push({ content: i, value: value[i] }); - } - new LiteGraph.ContextMenu(entries, { - event: e, - callback: inner_clicked, - parentMenu: prev_menu, - node: node - }); - return false; - } else { - node.graph.beforeChange(); - node.addOutput(v.value[0], v.value[1], v.value[2]); - - if (node.onNodeOutputAdd) { // a callback to the node when adding a slot - node.onNodeOutputAdd(v.value); - } - node.setDirtyCanvas(true, true); - node.graph.afterChange(); - } - } - - return false; - }; - - LGraphCanvas.onShowMenuNodeProperties = function( - value, - options, - e, - prev_menu, - node - ) { - if (!node || !node.properties) { - return; - } - - var that = this; - var canvas = LGraphCanvas.active_canvas; - var ref_window = canvas.getCanvasWindow(); - - var entries = []; - for (var i in node.properties) { - var value = node.properties[i] !== undefined ? node.properties[i] : " "; - if( typeof value == "object" ) - value = JSON.stringify(value); - var info = node.getPropertyInfo(i); - if(info.type == "enum" || info.type == "combo") - value = LGraphCanvas.getPropertyPrintableValue( value, info.values ); - - //value could contain invalid html characters, clean that - value = LGraphCanvas.decodeHTML(value); - entries.push({ - content: - "" + - (info.label ? info.label : i) + - "" + - "" + - value + - "", - value: i - }); - } - if (!entries.length) { - return; - } - - var menu = new LiteGraph.ContextMenu( - entries, - { - event: e, - callback: inner_clicked, - parentMenu: prev_menu, - allow_html: true, - node: node - }, - ref_window - ); - - function inner_clicked(v, options, e, prev) { - if (!node) { - return; - } - var rect = this.getBoundingClientRect(); - canvas.showEditPropertyValue(node, v.value, { - position: [rect.left, rect.top] - }); - } - - return false; - }; - - LGraphCanvas.decodeHTML = function(str) { - var e = document.createElement("div"); - e.innerText = str; - return e.innerHTML; - }; - - LGraphCanvas.onMenuResizeNode = function(value, options, e, menu, node) { - if (!node) { - return; - } - - var fApplyMultiNode = function(node){ - node.size = node.computeSize(); - if (node.onResize) - node.onResize(node.size); - } - - var graphcanvas = LGraphCanvas.active_canvas; - if (!graphcanvas.selected_nodes || Object.keys(graphcanvas.selected_nodes).length <= 1){ - fApplyMultiNode(node); - }else{ - for (var i in graphcanvas.selected_nodes) { - fApplyMultiNode(graphcanvas.selected_nodes[i]); - } - } - - node.setDirtyCanvas(true, true); - }; - - LGraphCanvas.prototype.showLinkMenu = function(link, e) { - var that = this; - // console.log(link); - var node_left = that.graph.getNodeById( link.origin_id ); - var node_right = that.graph.getNodeById( link.target_id ); - var fromType = false; - if (node_left && node_left.outputs && node_left.outputs[link.origin_slot]) fromType = node_left.outputs[link.origin_slot].type; - var destType = false; - if (node_right && node_right.outputs && node_right.outputs[link.target_slot]) destType = node_right.inputs[link.target_slot].type; - - var options = ["Add Node",null,"Delete",null]; - - - var menu = new LiteGraph.ContextMenu(options, { - event: e, - title: link.data != null ? link.data.constructor.name : null, - callback: inner_clicked - }); - - function inner_clicked(v,options,e) { - switch (v) { - case "Add Node": - LGraphCanvas.onMenuAdd(null, null, e, menu, function(node){ - // console.debug("node autoconnect"); - if(!node.inputs || !node.inputs.length || !node.outputs || !node.outputs.length){ - return; - } - // leave the connection type checking inside connectByType - if (node_left.connectByType( link.origin_slot, node, fromType )){ - node.connectByType( link.target_slot, node_right, destType ); - node.pos[0] -= node.size[0] * 0.5; - } - }); - break; - - case "Delete": - that.graph.removeLink(link.id); - break; - default: - /*var nodeCreated = createDefaultNodeForSlot({ nodeFrom: node_left - ,slotFrom: link.origin_slot - ,nodeTo: node - ,slotTo: link.target_slot - ,e: e - ,nodeType: "AUTO" - }); - if(nodeCreated) console.log("new node in beetween "+v+" created");*/ - } - } - - return false; - }; - - LGraphCanvas.prototype.createDefaultNodeForSlot = function(optPass) { // addNodeMenu for connection - var optPass = optPass || {}; - var opts = Object.assign({ nodeFrom: null // input - ,slotFrom: null // input - ,nodeTo: null // output - ,slotTo: null // output - ,position: [] // pass the event coords - ,nodeType: null // choose a nodetype to add, AUTO to set at first good - ,posAdd:[0,0] // adjust x,y - ,posSizeFix:[0,0] // alpha, adjust the position x,y based on the new node size w,h - } - ,optPass - ); - var that = this; - - var isFrom = opts.nodeFrom && opts.slotFrom!==null; - var isTo = !isFrom && opts.nodeTo && opts.slotTo!==null; - - if (!isFrom && !isTo){ - console.warn("No data passed to createDefaultNodeForSlot "+opts.nodeFrom+" "+opts.slotFrom+" "+opts.nodeTo+" "+opts.slotTo); - return false; - } - if (!opts.nodeType){ - console.warn("No type to createDefaultNodeForSlot"); - return false; - } - - var nodeX = isFrom ? opts.nodeFrom : opts.nodeTo; - var slotX = isFrom ? opts.slotFrom : opts.slotTo; - - var iSlotConn = false; - switch (typeof slotX){ - case "string": - iSlotConn = isFrom ? nodeX.findOutputSlot(slotX,false) : nodeX.findInputSlot(slotX,false); - slotX = isFrom ? nodeX.outputs[slotX] : nodeX.inputs[slotX]; - break; - case "object": - // ok slotX - iSlotConn = isFrom ? nodeX.findOutputSlot(slotX.name) : nodeX.findInputSlot(slotX.name); - break; - case "number": - iSlotConn = slotX; - slotX = isFrom ? nodeX.outputs[slotX] : nodeX.inputs[slotX]; - break; - case "undefined": - default: - // bad ? - //iSlotConn = 0; - console.warn("Cant get slot information "+slotX); - return false; - } - - if (slotX===false || iSlotConn===false){ - console.warn("createDefaultNodeForSlot bad slotX "+slotX+" "+iSlotConn); - } - - // check for defaults nodes for this slottype - var fromSlotType = slotX.type==LiteGraph.EVENT?"_event_":slotX.type; - var slotTypesDefault = isFrom ? LiteGraph.slot_types_default_out : LiteGraph.slot_types_default_in; - if(slotTypesDefault && slotTypesDefault[fromSlotType]){ - if (slotX.link !== null) { - // is connected - }else{ - // is not not connected - } - nodeNewType = false; - if(slotTypesDefault[fromSlotType] == "object" || slotTypesDefault[fromSlotType] == "array"){ - for(var typeX in slotTypesDefault[fromSlotType]){ - if (opts.nodeType == slotTypesDefault[fromSlotType][typeX] || opts.nodeType == "AUTO"){ - nodeNewType = slotTypesDefault[fromSlotType][typeX]; - // console.log("opts.nodeType == slotTypesDefault[fromSlotType][typeX] :: "+opts.nodeType); - break; // -------- - } - } - }else{ - if (opts.nodeType == slotTypesDefault[fromSlotType] || opts.nodeType == "AUTO") nodeNewType = slotTypesDefault[fromSlotType]; - } - if (nodeNewType) { - var nodeNewOpts = false; - if (typeof nodeNewType == "object" && nodeNewType.node){ - nodeNewOpts = nodeNewType; - nodeNewType = nodeNewType.node; - } - - //that.graph.beforeChange(); - - var newNode = LiteGraph.createNode(nodeNewType); - if(newNode){ - // if is object pass options - if (nodeNewOpts){ - if (nodeNewOpts.properties) { - for (var i in nodeNewOpts.properties) { - newNode.addProperty( i, nodeNewOpts.properties[i] ); - } - } - if (nodeNewOpts.inputs) { - newNode.inputs = []; - for (var i in nodeNewOpts.inputs) { - newNode.addOutput( - nodeNewOpts.inputs[i][0], - nodeNewOpts.inputs[i][1] - ); - } - } - if (nodeNewOpts.outputs) { - newNode.outputs = []; - for (var i in nodeNewOpts.outputs) { - newNode.addOutput( - nodeNewOpts.outputs[i][0], - nodeNewOpts.outputs[i][1] - ); - } - } - if (nodeNewOpts.title) { - newNode.title = nodeNewOpts.title; - } - if (nodeNewOpts.json) { - newNode.configure(nodeNewOpts.json); - } - - } - - // add the node - that.graph.add(newNode); - newNode.pos = [ opts.position[0]+opts.posAdd[0]+(opts.posSizeFix[0]?opts.posSizeFix[0]*newNode.size[0]:0) - ,opts.position[1]+opts.posAdd[1]+(opts.posSizeFix[1]?opts.posSizeFix[1]*newNode.size[1]:0)]; //that.last_click_position; //[e.canvasX+30, e.canvasX+5];*/ - - //that.graph.afterChange(); - - // connect the two! - if (isFrom){ - opts.nodeFrom.connectByType( iSlotConn, newNode, fromSlotType ); - }else{ - opts.nodeTo.connectByTypeOutput( iSlotConn, newNode, fromSlotType ); - } - - // if connecting in between - if (isFrom && isTo){ - // TODO - } - - return true; - - }else{ - console.log("failed creating "+nodeNewType); - } - } - } - return false; - } - - LGraphCanvas.prototype.showConnectionMenu = function(optPass) { // addNodeMenu for connection - var optPass = optPass || {}; - var opts = Object.assign({ nodeFrom: null // input - ,slotFrom: null // input - ,nodeTo: null // output - ,slotTo: null // output - ,e: null - } - ,optPass - ); - var that = this; - - var isFrom = opts.nodeFrom && opts.slotFrom; - var isTo = !isFrom && opts.nodeTo && opts.slotTo; - - if (!isFrom && !isTo){ - console.warn("No data passed to showConnectionMenu"); - return false; - } - - var nodeX = isFrom ? opts.nodeFrom : opts.nodeTo; - var slotX = isFrom ? opts.slotFrom : opts.slotTo; - - var iSlotConn = false; - switch (typeof slotX){ - case "string": - iSlotConn = isFrom ? nodeX.findOutputSlot(slotX,false) : nodeX.findInputSlot(slotX,false); - slotX = isFrom ? nodeX.outputs[slotX] : nodeX.inputs[slotX]; - break; - case "object": - // ok slotX - iSlotConn = isFrom ? nodeX.findOutputSlot(slotX.name) : nodeX.findInputSlot(slotX.name); - break; - case "number": - iSlotConn = slotX; - slotX = isFrom ? nodeX.outputs[slotX] : nodeX.inputs[slotX]; - break; - default: - // bad ? - //iSlotConn = 0; - console.warn("Cant get slot information "+slotX); - return false; - } - - var options = ["Add Node",null]; - - if (that.allow_searchbox){ - options.push("Search"); - options.push(null); - } - - // get defaults nodes for this slottype - var fromSlotType = slotX.type==LiteGraph.EVENT?"_event_":slotX.type; - var slotTypesDefault = isFrom ? LiteGraph.slot_types_default_out : LiteGraph.slot_types_default_in; - if(slotTypesDefault && slotTypesDefault[fromSlotType]){ - if(slotTypesDefault[fromSlotType] == "object" || slotTypesDefault[fromSlotType] == "array"){ - for(var typeX in slotTypesDefault[fromSlotType]){ - options.push(slotTypesDefault[fromSlotType][typeX]); - } - }else{ - options.push(slotTypesDefault[fromSlotType]); - } - } - - // build menu - var menu = new LiteGraph.ContextMenu(options, { - event: opts.e, - title: (slotX && slotX.name!="" ? (slotX.name + (fromSlotType?" | ":"")) : "")+(slotX && fromSlotType ? fromSlotType : ""), - callback: inner_clicked - }); - - // callback - function inner_clicked(v,options,e) { - //console.log("Process showConnectionMenu selection"); - switch (v) { - case "Add Node": - LGraphCanvas.onMenuAdd(null, null, e, menu, function(node){ - if (isFrom){ - opts.nodeFrom.connectByType( iSlotConn, node, fromSlotType ); - }else{ - opts.nodeTo.connectByTypeOutput( iSlotConn, node, fromSlotType ); - } - }); - break; - case "Search": - if(isFrom){ - that.showSearchBox(e,{node_from: opts.nodeFrom, slot_from: slotX, type_filter_in: fromSlotType}); - }else{ - that.showSearchBox(e,{node_to: opts.nodeTo, slot_from: slotX, type_filter_out: fromSlotType}); - } - break; - default: - // check for defaults nodes for this slottype - var nodeCreated = that.createDefaultNodeForSlot(Object.assign(opts,{ position: [opts.e.canvasX, opts.e.canvasY] - ,nodeType: v - })); - if (nodeCreated){ - // new node created - //console.log("node "+v+" created") - }else{ - // failed or v is not in defaults - } - break; - } - } - - return false; - }; - - // TODO refactor :: this is used fot title but not for properties! - LGraphCanvas.onShowPropertyEditor = function(item, options, e, menu, node) { - var input_html = ""; - var property = item.property || "title"; - var value = node[property]; - - // TODO refactor :: use createDialog ? - - var dialog = document.createElement("div"); - dialog.is_modified = false; - dialog.className = "graphdialog"; - dialog.innerHTML = - ""; - dialog.close = function() { - if (dialog.parentNode) { - dialog.parentNode.removeChild(dialog); - } - }; - var title = dialog.querySelector(".name"); - title.innerText = property; - var input = dialog.querySelector(".value"); - if (input) { - input.value = value; - input.addEventListener("blur", function(e) { - this.focus(); - }); - input.addEventListener("keydown", function(e) { - dialog.is_modified = true; - if (e.keyCode == 27) { - //ESC - dialog.close(); - } else if (e.keyCode == 13) { - inner(); // save - } else if (e.keyCode != 13 && e.target.localName != "textarea") { - return; - } - e.preventDefault(); - e.stopPropagation(); - }); - } - - var graphcanvas = LGraphCanvas.active_canvas; - var canvas = graphcanvas.canvas; - - var rect = canvas.getBoundingClientRect(); - var offsetx = -20; - var offsety = -20; - if (rect) { - offsetx -= rect.left; - offsety -= rect.top; - } - - if (event) { - dialog.style.left = event.clientX + offsetx + "px"; - dialog.style.top = event.clientY + offsety + "px"; - } else { - dialog.style.left = canvas.width * 0.5 + offsetx + "px"; - dialog.style.top = canvas.height * 0.5 + offsety + "px"; - } - - var button = dialog.querySelector("button"); - button.addEventListener("click", inner); - canvas.parentNode.appendChild(dialog); - - if(input) input.focus(); - - var dialogCloseTimer = null; - dialog.addEventListener("mouseleave", function(e) { - if(LiteGraph.dialog_close_on_mouse_leave) - if (!dialog.is_modified && LiteGraph.dialog_close_on_mouse_leave) - dialogCloseTimer = setTimeout(dialog.close, LiteGraph.dialog_close_on_mouse_leave_delay); //dialog.close(); - }); - dialog.addEventListener("mouseenter", function(e) { - if(LiteGraph.dialog_close_on_mouse_leave) - if(dialogCloseTimer) clearTimeout(dialogCloseTimer); - }); - - function inner() { - if(input) setValue(input.value); - } - - function setValue(value) { - if (item.type == "Number") { - value = Number(value); - } else if (item.type == "Boolean") { - value = Boolean(value); - } - node[property] = value; - if (dialog.parentNode) { - dialog.parentNode.removeChild(dialog); - } - node.setDirtyCanvas(true, true); - } - }; - - // refactor: there are different dialogs, some uses createDialog some dont - LGraphCanvas.prototype.prompt = function(title, value, callback, event, multiline) { - var that = this; - var input_html = ""; - title = title || ""; - - var dialog = document.createElement("div"); - dialog.is_modified = false; - dialog.className = "graphdialog rounded"; - if(multiline) - dialog.innerHTML = " "; - else - dialog.innerHTML = " "; - dialog.close = function() { - that.prompt_box = null; - if (dialog.parentNode) { - dialog.parentNode.removeChild(dialog); - } - }; - - var graphcanvas = LGraphCanvas.active_canvas; - var canvas = graphcanvas.canvas; - canvas.parentNode.appendChild(dialog); - - if (this.ds.scale > 1) { - dialog.style.transform = "scale(" + this.ds.scale + ")"; - } - - var dialogCloseTimer = null; - var prevent_timeout = false; - LiteGraph.pointerListenerAdd(dialog,"leave", function(e) { - if (prevent_timeout) - return; - if(LiteGraph.dialog_close_on_mouse_leave) - if (!dialog.is_modified && LiteGraph.dialog_close_on_mouse_leave) - dialogCloseTimer = setTimeout(dialog.close, LiteGraph.dialog_close_on_mouse_leave_delay); //dialog.close(); - }); - LiteGraph.pointerListenerAdd(dialog,"enter", function(e) { - if(LiteGraph.dialog_close_on_mouse_leave) - if(dialogCloseTimer) clearTimeout(dialogCloseTimer); - }); - var selInDia = dialog.querySelectorAll("select"); - if (selInDia){ - // if filtering, check focus changed to comboboxes and prevent closing - selInDia.forEach(function(selIn) { - selIn.addEventListener("click", function(e) { - prevent_timeout++; - }); - selIn.addEventListener("blur", function(e) { - prevent_timeout = 0; - }); - selIn.addEventListener("change", function(e) { - prevent_timeout = -1; - }); - }); - } - - if (that.prompt_box) { - that.prompt_box.close(); - } - that.prompt_box = dialog; - - var first = null; - var timeout = null; - var selected = null; - - var name_element = dialog.querySelector(".name"); - name_element.innerText = title; - var value_element = dialog.querySelector(".value"); - value_element.value = value; - - var input = value_element; - input.addEventListener("keydown", function(e) { - dialog.is_modified = true; - if (e.keyCode == 27) { - //ESC - dialog.close(); - } else if (e.keyCode == 13 && e.target.localName != "textarea") { - if (callback) { - callback(this.value); - } - dialog.close(); - } else { - return; - } - e.preventDefault(); - e.stopPropagation(); - }); - - var button = dialog.querySelector("button"); - button.addEventListener("click", function(e) { - if (callback) { - callback(input.value); - } - that.setDirty(true); - dialog.close(); - }); - - var rect = canvas.getBoundingClientRect(); - var offsetx = -20; - var offsety = -20; - if (rect) { - offsetx -= rect.left; - offsety -= rect.top; - } - - if (event) { - dialog.style.left = event.clientX + offsetx + "px"; - dialog.style.top = event.clientY + offsety + "px"; - } else { - dialog.style.left = canvas.width * 0.5 + offsetx + "px"; - dialog.style.top = canvas.height * 0.5 + offsety + "px"; - } - - setTimeout(function() { - input.focus(); - }, 10); - - return dialog; - }; - - LGraphCanvas.search_limit = -1; - LGraphCanvas.prototype.showSearchBox = function(event, options) { - // proposed defaults - var def_options = { slot_from: null - ,node_from: null - ,node_to: null - ,do_type_filter: LiteGraph.search_filter_enabled // TODO check for registered_slot_[in/out]_types not empty // this will be checked for functionality enabled : filter on slot type, in and out - ,type_filter_in: false // these are default: pass to set initially set values - ,type_filter_out: false - ,show_general_if_none_on_typefilter: true - ,show_general_after_typefiltered: true - ,hide_on_mouse_leave: LiteGraph.search_hide_on_mouse_leave - ,show_all_if_empty: true - ,show_all_on_open: LiteGraph.search_show_all_on_open - }; - options = Object.assign(def_options, options || {}); - - //console.log(options); - - var that = this; - var input_html = ""; - var graphcanvas = LGraphCanvas.active_canvas; - var canvas = graphcanvas.canvas; - var root_document = canvas.ownerDocument || document; - - var dialog = document.createElement("div"); - dialog.className = "litegraph litesearchbox graphdialog rounded"; - dialog.innerHTML = "Search "; - if (options.do_type_filter){ - dialog.innerHTML += ""; - dialog.innerHTML += ""; - } - dialog.innerHTML += "
"; - - if( root_document.fullscreenElement ) - root_document.fullscreenElement.appendChild(dialog); - else - { - root_document.body.appendChild(dialog); - root_document.body.style.overflow = "hidden"; - } - // dialog element has been appended - - if (options.do_type_filter){ - var selIn = dialog.querySelector(".slot_in_type_filter"); - var selOut = dialog.querySelector(".slot_out_type_filter"); - } - - dialog.close = function() { - that.search_box = null; - this.blur(); - canvas.focus(); - root_document.body.style.overflow = ""; - - setTimeout(function() { - that.canvas.focus(); - }, 20); //important, if canvas loses focus keys wont be captured - if (dialog.parentNode) { - dialog.parentNode.removeChild(dialog); - } - }; - - if (this.ds.scale > 1) { - dialog.style.transform = "scale(" + this.ds.scale + ")"; - } - - // hide on mouse leave - if(options.hide_on_mouse_leave){ - var prevent_timeout = false; - var timeout_close = null; - LiteGraph.pointerListenerAdd(dialog,"enter", function(e) { - if (timeout_close) { - clearTimeout(timeout_close); - timeout_close = null; - } - }); - LiteGraph.pointerListenerAdd(dialog,"leave", function(e) { - if (prevent_timeout){ - return; - } - timeout_close = setTimeout(function() { - dialog.close(); - }, 500); - }); - // if filtering, check focus changed to comboboxes and prevent closing - if (options.do_type_filter){ - selIn.addEventListener("click", function(e) { - prevent_timeout++; - }); - selIn.addEventListener("blur", function(e) { - prevent_timeout = 0; - }); - selIn.addEventListener("change", function(e) { - prevent_timeout = -1; - }); - selOut.addEventListener("click", function(e) { - prevent_timeout++; - }); - selOut.addEventListener("blur", function(e) { - prevent_timeout = 0; - }); - selOut.addEventListener("change", function(e) { - prevent_timeout = -1; - }); - } - } - - if (that.search_box) { - that.search_box.close(); - } - that.search_box = dialog; - - var helper = dialog.querySelector(".helper"); - - var first = null; - var timeout = null; - var selected = null; - - var input = dialog.querySelector("input"); - if (input) { - input.addEventListener("blur", function(e) { - this.focus(); - }); - input.addEventListener("keydown", function(e) { - if (e.keyCode == 38) { - //UP - changeSelection(false); - } else if (e.keyCode == 40) { - //DOWN - changeSelection(true); - } else if (e.keyCode == 27) { - //ESC - dialog.close(); - } else if (e.keyCode == 13) { - if (selected) { - select(selected.innerHTML); - } else if (first) { - select(first); - } else { - dialog.close(); - } - } else { - if (timeout) { - clearInterval(timeout); - } - timeout = setTimeout(refreshHelper, 250); - return; - } - e.preventDefault(); - e.stopPropagation(); - e.stopImmediatePropagation(); - return true; - }); - } - - // if should filter on type, load and fill selected and choose elements if passed - if (options.do_type_filter){ - if (selIn){ - var aSlots = LiteGraph.slot_types_in; - var nSlots = aSlots.length; // this for object :: Object.keys(aSlots).length; - - if (options.type_filter_in == LiteGraph.EVENT || options.type_filter_in == LiteGraph.ACTION) - options.type_filter_in = "_event_"; - /* this will filter on * .. but better do it manually in case - else if(options.type_filter_in === "" || options.type_filter_in === 0) - options.type_filter_in = "*";*/ - - for (var iK=0; iK (rect.height - 200)) - helper.style.maxHeight = (rect.height - event.layerY - 20) + "px"; - - /* - var offsetx = -20; - var offsety = -20; - if (rect) { - offsetx -= rect.left; - offsety -= rect.top; - } - - if (event) { - dialog.style.left = event.clientX + offsetx + "px"; - dialog.style.top = event.clientY + offsety + "px"; - } else { - dialog.style.left = canvas.width * 0.5 + offsetx + "px"; - dialog.style.top = canvas.height * 0.5 + offsety + "px"; - } - canvas.parentNode.appendChild(dialog); - */ - - input.focus(); - if (options.show_all_on_open) refreshHelper(); - - function select(name) { - if (name) { - if (that.onSearchBoxSelection) { - that.onSearchBoxSelection(name, event, graphcanvas); - } else { - var extra = LiteGraph.searchbox_extras[name.toLowerCase()]; - if (extra) { - name = extra.type; - } - - graphcanvas.graph.beforeChange(); - var node = LiteGraph.createNode(name); - if (node) { - node.pos = graphcanvas.convertEventToCanvasOffset( - event - ); - graphcanvas.graph.add(node, false); - } - - if (extra && extra.data) { - if (extra.data.properties) { - for (var i in extra.data.properties) { - node.addProperty( i, extra.data.properties[i] ); - } - } - if (extra.data.inputs) { - node.inputs = []; - for (var i in extra.data.inputs) { - node.addOutput( - extra.data.inputs[i][0], - extra.data.inputs[i][1] - ); - } - } - if (extra.data.outputs) { - node.outputs = []; - for (var i in extra.data.outputs) { - node.addOutput( - extra.data.outputs[i][0], - extra.data.outputs[i][1] - ); - } - } - if (extra.data.title) { - node.title = extra.data.title; - } - if (extra.data.json) { - node.configure(extra.data.json); - } - - } - - // join node after inserting - if (options.node_from){ - var iS = false; - switch (typeof options.slot_from){ - case "string": - iS = options.node_from.findOutputSlot(options.slot_from); - break; - case "object": - if (options.slot_from.name){ - iS = options.node_from.findOutputSlot(options.slot_from.name); - }else{ - iS = -1; - } - if (iS==-1 && typeof options.slot_from.slot_index !== "undefined") iS = options.slot_from.slot_index; - break; - case "number": - iS = options.slot_from; - break; - default: - iS = 0; // try with first if no name set - } - if (typeof options.node_from.outputs[iS] !== undefined){ - if (iS!==false && iS>-1){ - options.node_from.connectByType( iS, node, options.node_from.outputs[iS].type ); - } - }else{ - // console.warn("cant find slot " + options.slot_from); - } - } - if (options.node_to){ - var iS = false; - switch (typeof options.slot_from){ - case "string": - iS = options.node_to.findInputSlot(options.slot_from); - break; - case "object": - if (options.slot_from.name){ - iS = options.node_to.findInputSlot(options.slot_from.name); - }else{ - iS = -1; - } - if (iS==-1 && typeof options.slot_from.slot_index !== "undefined") iS = options.slot_from.slot_index; - break; - case "number": - iS = options.slot_from; - break; - default: - iS = 0; // try with first if no name set - } - if (typeof options.node_to.inputs[iS] !== undefined){ - if (iS!==false && iS>-1){ - // try connection - options.node_to.connectByTypeOutput(iS,node,options.node_to.inputs[iS].type); - } - }else{ - // console.warn("cant find slot_nodeTO " + options.slot_from); - } - } - - graphcanvas.graph.afterChange(); - } - } - - dialog.close(); - } - - function changeSelection(forward) { - var prev = selected; - if (selected) { - selected.classList.remove("selected"); - } - if (!selected) { - selected = forward - ? helper.childNodes[0] - : helper.childNodes[helper.childNodes.length]; - } else { - selected = forward - ? selected.nextSibling - : selected.previousSibling; - if (!selected) { - selected = prev; - } - } - if (!selected) { - return; - } - selected.classList.add("selected"); - selected.scrollIntoView({block: "end", behavior: "smooth"}); - } - - function refreshHelper() { - timeout = null; - var str = input.value; - first = null; - helper.innerHTML = ""; - if (!str && !options.show_all_if_empty) { - return; - } - - if (that.onSearchBox) { - var list = that.onSearchBox(helper, str, graphcanvas); - if (list) { - for (var i = 0; i < list.length; ++i) { - addResult(list[i]); - } - } - } else { - var c = 0; - str = str.toLowerCase(); - var filter = graphcanvas.filter || graphcanvas.graph.filter; - - // filter by type preprocess - if(options.do_type_filter && that.search_box){ - var sIn = that.search_box.querySelector(".slot_in_type_filter"); - var sOut = that.search_box.querySelector(".slot_out_type_filter"); - }else{ - var sIn = false; - var sOut = false; - } - - //extras - for (var i in LiteGraph.searchbox_extras) { - var extra = LiteGraph.searchbox_extras[i]; - if ((!options.show_all_if_empty || str) && extra.desc.toLowerCase().indexOf(str) === -1) { - continue; - } - var ctor = LiteGraph.registered_node_types[ extra.type ]; - if( ctor && ctor.filter != filter ) - continue; - if( ! inner_test_filter(extra.type) ) - continue; - addResult( extra.desc, "searchbox_extra" ); - if ( LGraphCanvas.search_limit !== -1 && c++ > LGraphCanvas.search_limit ) { - break; - } - } - - var filtered = null; - if (Array.prototype.filter) { //filter supported - var keys = Object.keys( LiteGraph.registered_node_types ); //types - var filtered = keys.filter( inner_test_filter ); - } else { - filtered = []; - for (var i in LiteGraph.registered_node_types) { - if( inner_test_filter(i) ) - filtered.push(i); - } - } - - for (var i = 0; i < filtered.length; i++) { - addResult(filtered[i]); - if ( LGraphCanvas.search_limit !== -1 && c++ > LGraphCanvas.search_limit ) { - break; - } - } - - // add general type if filtering - if (options.show_general_after_typefiltered - && (sIn.value || sOut.value) - ){ - filtered_extra = []; - for (var i in LiteGraph.registered_node_types) { - if( inner_test_filter(i, {inTypeOverride: sIn&&sIn.value?"*":false, outTypeOverride: sOut&&sOut.value?"*":false}) ) - filtered_extra.push(i); - } - for (var i = 0; i < filtered_extra.length; i++) { - addResult(filtered_extra[i], "generic_type"); - if ( LGraphCanvas.search_limit !== -1 && c++ > LGraphCanvas.search_limit ) { - break; - } - } - } - - // check il filtering gave no results - if ((sIn.value || sOut.value) && - ( (helper.childNodes.length == 0 && options.show_general_if_none_on_typefilter) ) - ){ - filtered_extra = []; - for (var i in LiteGraph.registered_node_types) { - if( inner_test_filter(i, {skipFilter: true}) ) - filtered_extra.push(i); - } - for (var i = 0; i < filtered_extra.length; i++) { - addResult(filtered_extra[i], "not_in_filter"); - if ( LGraphCanvas.search_limit !== -1 && c++ > LGraphCanvas.search_limit ) { - break; - } - } - } - - function inner_test_filter( type, optsIn ) - { - var optsIn = optsIn || {}; - var optsDef = { skipFilter: false - ,inTypeOverride: false - ,outTypeOverride: false - }; - var opts = Object.assign(optsDef,optsIn); - var ctor = LiteGraph.registered_node_types[ type ]; - if(filter && ctor.filter != filter ) - return false; - if ((!options.show_all_if_empty || str) && type.toLowerCase().indexOf(str) === -1) - return false; - - // filter by slot IN, OUT types - if(options.do_type_filter && !opts.skipFilter){ - var sType = type; - - var sV = sIn.value; - if (opts.inTypeOverride!==false) sV = opts.inTypeOverride; - //if (sV.toLowerCase() == "_event_") sV = LiteGraph.EVENT; // -1 - - if(sIn && sV){ - //console.log("will check filter against "+sV); - if (LiteGraph.registered_slot_in_types[sV] && LiteGraph.registered_slot_in_types[sV].nodes){ // type is stored - //console.debug("check "+sType+" in "+LiteGraph.registered_slot_in_types[sV].nodes); - var doesInc = LiteGraph.registered_slot_in_types[sV].nodes.includes(sType); - if (doesInc!==false){ - //console.log(sType+" HAS "+sV); - }else{ - /*console.debug(LiteGraph.registered_slot_in_types[sV]); - console.log(+" DONT includes "+type);*/ - return false; - } - } - } - - var sV = sOut.value; - if (opts.outTypeOverride!==false) sV = opts.outTypeOverride; - //if (sV.toLowerCase() == "_event_") sV = LiteGraph.EVENT; // -1 - - if(sOut && sV){ - //console.log("search will check filter against "+sV); - if (LiteGraph.registered_slot_out_types[sV] && LiteGraph.registered_slot_out_types[sV].nodes){ // type is stored - //console.debug("check "+sType+" in "+LiteGraph.registered_slot_out_types[sV].nodes); - var doesInc = LiteGraph.registered_slot_out_types[sV].nodes.includes(sType); - if (doesInc!==false){ - //console.log(sType+" HAS "+sV); - }else{ - /*console.debug(LiteGraph.registered_slot_out_types[sV]); - console.log(+" DONT includes "+type);*/ - return false; - } - } - } - } - return true; - } - } - - function addResult(type, className) { - var help = document.createElement("div"); - if (!first) { - first = type; - } - help.innerText = type; - help.dataset["type"] = escape(type); - help.className = "litegraph lite-search-item"; - if (className) { - help.className += " " + className; - } - help.addEventListener("click", function(e) { - select(unescape(this.dataset["type"])); - }); - helper.appendChild(help); - } - } - - return dialog; - }; - - LGraphCanvas.prototype.showEditPropertyValue = function( node, property, options ) { - if (!node || node.properties[property] === undefined) { - return; - } - - options = options || {}; - var that = this; - - var info = node.getPropertyInfo(property); - var type = info.type; - - var input_html = ""; - - if (type == "string" || type == "number" || type == "array" || type == "object") { - input_html = ""; - } else if ( (type == "enum" || type == "combo") && info.values) { - input_html = ""; - } else if (type == "boolean" || type == "toggle") { - input_html = - ""; - } else { - console.warn("unknown type: " + type); - return; - } - - var dialog = this.createDialog( - "" + - (info.label ? info.label : property) + - "" + - input_html + - "", - options - ); - - var input = false; - if ((type == "enum" || type == "combo") && info.values) { - input = dialog.querySelector("select"); - input.addEventListener("change", function(e) { - dialog.modified(); - setValue(e.target.value); - //var index = e.target.value; - //setValue( e.options[e.selectedIndex].value ); - }); - } else if (type == "boolean" || type == "toggle") { - input = dialog.querySelector("input"); - if (input) { - input.addEventListener("click", function(e) { - dialog.modified(); - setValue(!!input.checked); - }); - } - } else { - input = dialog.querySelector("input"); - if (input) { - input.addEventListener("blur", function(e) { - this.focus(); - }); - - var v = node.properties[property] !== undefined ? node.properties[property] : ""; - if (type !== 'string') { - v = JSON.stringify(v); - } - - input.value = v; - input.addEventListener("keydown", function(e) { - if (e.keyCode == 27) { - //ESC - dialog.close(); - } else if (e.keyCode == 13) { - // ENTER - inner(); // save - } else if (e.keyCode != 13) { - dialog.modified(); - return; - } - e.preventDefault(); - e.stopPropagation(); - }); - } - } - if (input) input.focus(); - - var button = dialog.querySelector("button"); - button.addEventListener("click", inner); - - function inner() { - setValue(input.value); - } - - function setValue(value) { - - if(info && info.values && info.values.constructor === Object && info.values[value] != undefined ) - value = info.values[value]; - - if (typeof node.properties[property] == "number") { - value = Number(value); - } - if (type == "array" || type == "object") { - value = JSON.parse(value); - } - node.properties[property] = value; - if (node.graph) { - node.graph._version++; - } - if (node.onPropertyChanged) { - node.onPropertyChanged(property, value); - } - if(options.onclose) - options.onclose(); - dialog.close(); - node.setDirtyCanvas(true, true); - } - - return dialog; - }; - - // TODO refactor, theer are different dialog, some uses createDialog, some dont - LGraphCanvas.prototype.createDialog = function(html, options) { - var def_options = { checkForInput: false, closeOnLeave: true, closeOnLeave_checkModified: true }; - options = Object.assign(def_options, options || {}); - - var dialog = document.createElement("div"); - dialog.className = "graphdialog"; - dialog.innerHTML = html; - dialog.is_modified = false; - - var rect = this.canvas.getBoundingClientRect(); - var offsetx = -20; - var offsety = -20; - if (rect) { - offsetx -= rect.left; - offsety -= rect.top; - } - - if (options.position) { - offsetx += options.position[0]; - offsety += options.position[1]; - } else if (options.event) { - offsetx += options.event.clientX; - offsety += options.event.clientY; - } //centered - else { - offsetx += this.canvas.width * 0.5; - offsety += this.canvas.height * 0.5; - } - - dialog.style.left = offsetx + "px"; - dialog.style.top = offsety + "px"; - - this.canvas.parentNode.appendChild(dialog); - - // acheck for input and use default behaviour: save on enter, close on esc - if (options.checkForInput){ - var aI = []; - var focused = false; - if (aI = dialog.querySelectorAll("input")){ - aI.forEach(function(iX) { - iX.addEventListener("keydown",function(e){ - dialog.modified(); - if (e.keyCode == 27) { - dialog.close(); - } else if (e.keyCode != 13) { - return; - } - // set value ? - e.preventDefault(); - e.stopPropagation(); - }); - if (!focused) iX.focus(); - }); - } - } - - dialog.modified = function(){ - dialog.is_modified = true; - } - dialog.close = function() { - if (dialog.parentNode) { - dialog.parentNode.removeChild(dialog); - } - }; - - var dialogCloseTimer = null; - var prevent_timeout = false; - dialog.addEventListener("mouseleave", function(e) { - if (prevent_timeout) - return; - if(options.closeOnLeave || LiteGraph.dialog_close_on_mouse_leave) - if (!dialog.is_modified && LiteGraph.dialog_close_on_mouse_leave) - dialogCloseTimer = setTimeout(dialog.close, LiteGraph.dialog_close_on_mouse_leave_delay); //dialog.close(); - }); - dialog.addEventListener("mouseenter", function(e) { - if(options.closeOnLeave || LiteGraph.dialog_close_on_mouse_leave) - if(dialogCloseTimer) clearTimeout(dialogCloseTimer); - }); - var selInDia = dialog.querySelectorAll("select"); - if (selInDia){ - // if filtering, check focus changed to comboboxes and prevent closing - selInDia.forEach(function(selIn) { - selIn.addEventListener("click", function(e) { - prevent_timeout++; - }); - selIn.addEventListener("blur", function(e) { - prevent_timeout = 0; - }); - selIn.addEventListener("change", function(e) { - prevent_timeout = -1; - }); - }); - } - - return dialog; - }; - - LGraphCanvas.prototype.createPanel = function(title, options) { - options = options || {}; - - var ref_window = options.window || window; - var root = document.createElement("div"); - root.className = "litegraph dialog"; - root.innerHTML = "
"; - root.header = root.querySelector(".dialog-header"); - - if(options.width) - root.style.width = options.width + (options.width.constructor === Number ? "px" : ""); - if(options.height) - root.style.height = options.height + (options.height.constructor === Number ? "px" : ""); - if(options.closable) - { - var close = document.createElement("span"); - close.innerHTML = "✕"; - close.classList.add("close"); - close.addEventListener("click",function(){ - root.close(); - }); - root.header.appendChild(close); - } - root.title_element = root.querySelector(".dialog-title"); - root.title_element.innerText = title; - root.content = root.querySelector(".dialog-content"); - root.alt_content = root.querySelector(".dialog-alt-content"); - root.footer = root.querySelector(".dialog-footer"); - - root.close = function() - { - if (root.onClose && typeof root.onClose == "function"){ - root.onClose(); - } - if(root.parentNode) - root.parentNode.removeChild(root); - /* XXX CHECK THIS */ - if(this.parentNode){ - this.parentNode.removeChild(this); - } - /* XXX this was not working, was fixed with an IF, check this */ - } - - // function to swap panel content - root.toggleAltContent = function(force){ - if (typeof force != "undefined"){ - var vTo = force ? "block" : "none"; - var vAlt = force ? "none" : "block"; - }else{ - var vTo = root.alt_content.style.display != "block" ? "block" : "none"; - var vAlt = root.alt_content.style.display != "block" ? "none" : "block"; - } - root.alt_content.style.display = vTo; - root.content.style.display = vAlt; - } - - root.toggleFooterVisibility = function(force){ - if (typeof force != "undefined"){ - var vTo = force ? "block" : "none"; - }else{ - var vTo = root.footer.style.display != "block" ? "block" : "none"; - } - root.footer.style.display = vTo; - } - - root.clear = function() - { - this.content.innerHTML = ""; - } - - root.addHTML = function(code, classname, on_footer) - { - var elem = document.createElement("div"); - if(classname) - elem.className = classname; - elem.innerHTML = code; - if(on_footer) - root.footer.appendChild(elem); - else - root.content.appendChild(elem); - return elem; - } - - root.addButton = function( name, callback, options ) - { - var elem = document.createElement("button"); - elem.innerText = name; - elem.options = options; - elem.classList.add("btn"); - elem.addEventListener("click",callback); - root.footer.appendChild(elem); - return elem; - } - - root.addSeparator = function() - { - var elem = document.createElement("div"); - elem.className = "separator"; - root.content.appendChild(elem); - } - - root.addWidget = function( type, name, value, options, callback ) - { - options = options || {}; - var str_value = String(value); - type = type.toLowerCase(); - if(type == "number") - str_value = value.toFixed(3); - - var elem = document.createElement("div"); - elem.className = "property"; - elem.innerHTML = ""; - elem.querySelector(".property_name").innerText = options.label || name; - var value_element = elem.querySelector(".property_value"); - value_element.innerText = str_value; - elem.dataset["property"] = name; - elem.dataset["type"] = options.type || type; - elem.options = options; - elem.value = value; - - if( type == "code" ) - elem.addEventListener("click", function(e){ root.inner_showCodePad( this.dataset["property"] ); }); - else if (type == "boolean") - { - elem.classList.add("boolean"); - if(value) - elem.classList.add("bool-on"); - elem.addEventListener("click", function(){ - //var v = node.properties[this.dataset["property"]]; - //node.setProperty(this.dataset["property"],!v); this.innerText = v ? "true" : "false"; - var propname = this.dataset["property"]; - this.value = !this.value; - this.classList.toggle("bool-on"); - this.querySelector(".property_value").innerText = this.value ? "true" : "false"; - innerChange(propname, this.value ); - }); - } - else if (type == "string" || type == "number") - { - value_element.setAttribute("contenteditable",true); - value_element.addEventListener("keydown", function(e){ - if(e.code == "Enter" && (type != "string" || !e.shiftKey)) // allow for multiline - { - e.preventDefault(); - this.blur(); - } - }); - value_element.addEventListener("blur", function(){ - var v = this.innerText; - var propname = this.parentNode.dataset["property"]; - var proptype = this.parentNode.dataset["type"]; - if( proptype == "number") - v = Number(v); - innerChange(propname, v); - }); - } - else if (type == "enum" || type == "combo") { - var str_value = LGraphCanvas.getPropertyPrintableValue( value, options.values ); - value_element.innerText = str_value; - - value_element.addEventListener("click", function(event){ - var values = options.values || []; - var propname = this.parentNode.dataset["property"]; - var elem_that = this; - var menu = new LiteGraph.ContextMenu(values,{ - event: event, - className: "dark", - callback: inner_clicked - }, - ref_window); - function inner_clicked(v, option, event) { - //node.setProperty(propname,v); - //graphcanvas.dirty_canvas = true; - elem_that.innerText = v; - innerChange(propname,v); - return false; - } - }); - } - - root.content.appendChild(elem); - - function innerChange(name, value) - { - //console.log("change",name,value); - //that.dirty_canvas = true; - if(options.callback) - options.callback(name,value,options); - if(callback) - callback(name,value,options); - } - - return elem; - } - - if (root.onOpen && typeof root.onOpen == "function") root.onOpen(); - - return root; - }; - - LGraphCanvas.getPropertyPrintableValue = function(value, values) - { - if(!values) - return String(value); - - if(values.constructor === Array) - { - return String(value); - } - - if(values.constructor === Object) - { - var desc_value = ""; - for(var k in values) - { - if(values[k] != value) - continue; - desc_value = k; - break; - } - return String(value) + " ("+desc_value+")"; - } - } - - LGraphCanvas.prototype.closePanels = function(){ - var panel = document.querySelector("#node-panel"); - if(panel) - panel.close(); - var panel = document.querySelector("#option-panel"); - if(panel) - panel.close(); - } - - LGraphCanvas.prototype.showShowGraphOptionsPanel = function(refOpts, obEv, refMenu, refMenu2){ - if(this.constructor && this.constructor.name == "HTMLDivElement"){ - // assume coming from the menu event click - if (!obEv || !obEv.event || !obEv.event.target || !obEv.event.target.lgraphcanvas){ - console.warn("Canvas not found"); // need a ref to canvas obj - /*console.debug(event); - console.debug(event.target);*/ - return; - } - var graphcanvas = obEv.event.target.lgraphcanvas; - }else{ - // assume called internally - var graphcanvas = this; - } - graphcanvas.closePanels(); - var ref_window = graphcanvas.getCanvasWindow(); - panel = graphcanvas.createPanel("Options",{ - closable: true - ,window: ref_window - ,onOpen: function(){ - graphcanvas.OPTIONPANEL_IS_OPEN = true; - } - ,onClose: function(){ - graphcanvas.OPTIONPANEL_IS_OPEN = false; - graphcanvas.options_panel = null; - } - }); - graphcanvas.options_panel = panel; - panel.id = "option-panel"; - panel.classList.add("settings"); - - function inner_refresh(){ - - panel.content.innerHTML = ""; //clear - - var fUpdate = function(name, value, options){ - switch(name){ - /*case "Render mode": - // Case "".. - if (options.values && options.key){ - var kV = Object.values(options.values).indexOf(value); - if (kV>=0 && options.values[kV]){ - console.debug("update graph options: "+options.key+": "+kV); - graphcanvas[options.key] = kV; - //console.debug(graphcanvas); - break; - } - } - console.warn("unexpected options"); - console.debug(options); - break;*/ - default: - //console.debug("want to update graph options: "+name+": "+value); - if (options && options.key){ - name = options.key; - } - if (options.values){ - value = Object.values(options.values).indexOf(value); - } - //console.debug("update graph option: "+name+": "+value); - graphcanvas[name] = value; - break; - } - }; - - // panel.addWidget( "string", "Graph name", "", {}, fUpdate); // implement - - var aProps = LiteGraph.availableCanvasOptions; - aProps.sort(); - for(var pI in aProps){ - var pX = aProps[pI]; - panel.addWidget( "boolean", pX, graphcanvas[pX], {key: pX, on: "True", off: "False"}, fUpdate); - } - - var aLinks = [ graphcanvas.links_render_mode ]; - panel.addWidget( "combo", "Render mode", LiteGraph.LINK_RENDER_MODES[graphcanvas.links_render_mode], {key: "links_render_mode", values: LiteGraph.LINK_RENDER_MODES}, fUpdate); - - panel.addSeparator(); - - panel.footer.innerHTML = ""; // clear - - } - inner_refresh(); - - graphcanvas.canvas.parentNode.appendChild( panel ); - } - - LGraphCanvas.prototype.showShowNodePanel = function( node ) - { - this.SELECTED_NODE = node; - this.closePanels(); - var ref_window = this.getCanvasWindow(); - var that = this; - var graphcanvas = this; - var panel = this.createPanel(node.title || "",{ - closable: true - ,window: ref_window - ,onOpen: function(){ - graphcanvas.NODEPANEL_IS_OPEN = true; - } - ,onClose: function(){ - graphcanvas.NODEPANEL_IS_OPEN = false; - graphcanvas.node_panel = null; - } - }); - graphcanvas.node_panel = panel; - panel.id = "node-panel"; - panel.node = node; - panel.classList.add("settings"); - - function inner_refresh() - { - panel.content.innerHTML = ""; //clear - panel.addHTML(""+node.type+""+(node.constructor.desc || "")+""); - - panel.addHTML("

Properties

"); - - var fUpdate = function(name,value){ - graphcanvas.graph.beforeChange(node); - switch(name){ - case "Title": - node.title = value; - break; - case "Mode": - var kV = Object.values(LiteGraph.NODE_MODES).indexOf(value); - if (kV>=0 && LiteGraph.NODE_MODES[kV]){ - node.changeMode(kV); - }else{ - console.warn("unexpected mode: "+value); - } - break; - case "Color": - if (LGraphCanvas.node_colors[value]){ - node.color = LGraphCanvas.node_colors[value].color; - node.bgcolor = LGraphCanvas.node_colors[value].bgcolor; - }else{ - console.warn("unexpected color: "+value); - } - break; - default: - node.setProperty(name,value); - break; - } - graphcanvas.graph.afterChange(); - graphcanvas.dirty_canvas = true; - }; - - panel.addWidget( "string", "Title", node.title, {}, fUpdate); - - panel.addWidget( "combo", "Mode", LiteGraph.NODE_MODES[node.mode], {values: LiteGraph.NODE_MODES}, fUpdate); - - var nodeCol = ""; - if (node.color !== undefined){ - nodeCol = Object.keys(LGraphCanvas.node_colors).filter(function(nK){ return LGraphCanvas.node_colors[nK].color == node.color; }); - } - - panel.addWidget( "combo", "Color", nodeCol, {values: Object.keys(LGraphCanvas.node_colors)}, fUpdate); - - for(var pName in node.properties) - { - var value = node.properties[pName]; - var info = node.getPropertyInfo(pName); - var type = info.type || "string"; - - //in case the user wants control over the side panel widget - if( node.onAddPropertyToPanel && node.onAddPropertyToPanel(pName,panel) ) - continue; - - panel.addWidget( info.widget || info.type, pName, value, info, fUpdate); - } - - panel.addSeparator(); - - if(node.onShowCustomPanelInfo) - node.onShowCustomPanelInfo(panel); - - panel.footer.innerHTML = ""; // clear - panel.addButton("Delete",function(){ - if(node.block_delete) - return; - node.graph.remove(node); - panel.close(); - }).classList.add("delete"); - } - - panel.inner_showCodePad = function( propname ) - { - panel.classList.remove("settings"); - panel.classList.add("centered"); - - - /*if(window.CodeFlask) //disabled for now - { - panel.content.innerHTML = "
"; - var flask = new CodeFlask( "div.code", { language: 'js' }); - flask.updateCode(node.properties[propname]); - flask.onUpdate( function(code) { - node.setProperty(propname, code); - }); - } - else - {*/ - panel.alt_content.innerHTML = ""; - var textarea = panel.alt_content.querySelector("textarea"); - var fDoneWith = function(){ - panel.toggleAltContent(false); //if(node_prop_div) node_prop_div.style.display = "block"; // panel.close(); - panel.toggleFooterVisibility(true); - textarea.parentNode.removeChild(textarea); - panel.classList.add("settings"); - panel.classList.remove("centered"); - inner_refresh(); - } - textarea.value = node.properties[propname]; - textarea.addEventListener("keydown", function(e){ - if(e.code == "Enter" && e.ctrlKey ) - { - node.setProperty(propname, textarea.value); - fDoneWith(); - } - }); - panel.toggleAltContent(true); - panel.toggleFooterVisibility(false); - textarea.style.height = "calc(100% - 40px)"; - /*}*/ - var assign = panel.addButton( "Assign", function(){ - node.setProperty(propname, textarea.value); - fDoneWith(); - }); - panel.alt_content.appendChild(assign); //panel.content.appendChild(assign); - var button = panel.addButton( "Close", fDoneWith); - button.style.float = "right"; - panel.alt_content.appendChild(button); // panel.content.appendChild(button); - } - - inner_refresh(); - - this.canvas.parentNode.appendChild( panel ); - } - - LGraphCanvas.prototype.showSubgraphPropertiesDialog = function(node) - { - console.log("showing subgraph properties dialog"); - - var old_panel = this.canvas.parentNode.querySelector(".subgraph_dialog"); - if(old_panel) - old_panel.close(); - - var panel = this.createPanel("Subgraph Inputs",{closable:true, width: 500}); - panel.node = node; - panel.classList.add("subgraph_dialog"); - - function inner_refresh() - { - panel.clear(); - - //show currents - if(node.inputs) - for(var i = 0; i < node.inputs.length; ++i) - { - var input = node.inputs[i]; - if(input.not_subgraph_input) - continue; - var html = " "; - var elem = panel.addHTML(html,"subgraph_property"); - elem.dataset["name"] = input.name; - elem.dataset["slot"] = i; - elem.querySelector(".name").innerText = input.name; - elem.querySelector(".type").innerText = input.type; - elem.querySelector("button").addEventListener("click",function(e){ - node.removeInput( Number( this.parentNode.dataset["slot"] ) ); - inner_refresh(); - }); - } - } - - //add extra - var html = " + NameType"; - var elem = panel.addHTML(html,"subgraph_property extra", true); - elem.querySelector("button").addEventListener("click", function(e){ - var elem = this.parentNode; - var name = elem.querySelector(".name").value; - var type = elem.querySelector(".type").value; - if(!name || node.findInputSlot(name) != -1) - return; - node.addInput(name,type); - elem.querySelector(".name").value = ""; - elem.querySelector(".type").value = ""; - inner_refresh(); - }); - - inner_refresh(); - this.canvas.parentNode.appendChild(panel); - return panel; - } - LGraphCanvas.prototype.showSubgraphPropertiesDialogRight = function (node) { - - // console.log("showing subgraph properties dialog"); - var that = this; - // old_panel if old_panel is exist close it - var old_panel = this.canvas.parentNode.querySelector(".subgraph_dialog"); - if (old_panel) - old_panel.close(); - // new panel - var panel = this.createPanel("Subgraph Outputs", { closable: true, width: 500 }); - panel.node = node; - panel.classList.add("subgraph_dialog"); - - function inner_refresh() { - panel.clear(); - //show currents - if (node.outputs) - for (var i = 0; i < node.outputs.length; ++i) { - var input = node.outputs[i]; - if (input.not_subgraph_output) - continue; - var html = " "; - var elem = panel.addHTML(html, "subgraph_property"); - elem.dataset["name"] = input.name; - elem.dataset["slot"] = i; - elem.querySelector(".name").innerText = input.name; - elem.querySelector(".type").innerText = input.type; - elem.querySelector("button").addEventListener("click", function (e) { - node.removeOutput(Number(this.parentNode.dataset["slot"])); - inner_refresh(); - }); - } - } - - //add extra - var html = " + NameType"; - var elem = panel.addHTML(html, "subgraph_property extra", true); - elem.querySelector(".name").addEventListener("keydown", function (e) { - if (e.keyCode == 13) { - addOutput.apply(this) - } - }) - elem.querySelector("button").addEventListener("click", function (e) { - addOutput.apply(this) - }); - function addOutput() { - var elem = this.parentNode; - var name = elem.querySelector(".name").value; - var type = elem.querySelector(".type").value; - if (!name || node.findOutputSlot(name) != -1) - return; - node.addOutput(name, type); - elem.querySelector(".name").value = ""; - elem.querySelector(".type").value = ""; - inner_refresh(); - } - - inner_refresh(); - this.canvas.parentNode.appendChild(panel); - return panel; - } - LGraphCanvas.prototype.checkPanels = function() - { - if(!this.canvas) - return; - var panels = this.canvas.parentNode.querySelectorAll(".litegraph.dialog"); - for(var i = 0; i < panels.length; ++i) - { - var panel = panels[i]; - if( !panel.node ) - continue; - if( !panel.node.graph || panel.graph != this.graph ) - panel.close(); - } - } - - LGraphCanvas.onMenuNodeCollapse = function(value, options, e, menu, node) { - node.graph.beforeChange(/*?*/); - - var fApplyMultiNode = function(node){ - node.collapse(); - } - - var graphcanvas = LGraphCanvas.active_canvas; - if (!graphcanvas.selected_nodes || Object.keys(graphcanvas.selected_nodes).length <= 1){ - fApplyMultiNode(node); - }else{ - for (var i in graphcanvas.selected_nodes) { - fApplyMultiNode(graphcanvas.selected_nodes[i]); - } - } - - node.graph.afterChange(/*?*/); - }; - - LGraphCanvas.onMenuNodePin = function(value, options, e, menu, node) { - node.pin(); - }; - - LGraphCanvas.onMenuNodeMode = function(value, options, e, menu, node) { - new LiteGraph.ContextMenu( - LiteGraph.NODE_MODES, - { event: e, callback: inner_clicked, parentMenu: menu, node: node } - ); - - function inner_clicked(v) { - if (!node) { - return; - } - var kV = Object.values(LiteGraph.NODE_MODES).indexOf(v); - var fApplyMultiNode = function(node){ - if (kV>=0 && LiteGraph.NODE_MODES[kV]) - node.changeMode(kV); - else{ - console.warn("unexpected mode: "+v); - node.changeMode(LiteGraph.ALWAYS); - } - } - - var graphcanvas = LGraphCanvas.active_canvas; - if (!graphcanvas.selected_nodes || Object.keys(graphcanvas.selected_nodes).length <= 1){ - fApplyMultiNode(node); - }else{ - for (var i in graphcanvas.selected_nodes) { - fApplyMultiNode(graphcanvas.selected_nodes[i]); - } - } - } - - return false; - }; - - LGraphCanvas.onMenuNodeColors = function(value, options, e, menu, node) { - if (!node) { - throw "no node for color"; - } - - var values = []; - values.push({ - value: null, - content: - "No color" - }); - - for (var i in LGraphCanvas.node_colors) { - var color = LGraphCanvas.node_colors[i]; - var value = { - value: i, - content: - "" + - i + - "" - }; - values.push(value); - } - new LiteGraph.ContextMenu(values, { - event: e, - callback: inner_clicked, - parentMenu: menu, - node: node - }); - - function inner_clicked(v) { - if (!node) { - return; - } - - var color = v.value ? LGraphCanvas.node_colors[v.value] : null; - - var fApplyColor = function(node){ - if (color) { - if (node.constructor === LiteGraph.LGraphGroup) { - node.color = color.groupcolor; - } else { - node.color = color.color; - node.bgcolor = color.bgcolor; - } - } else { - delete node.color; - delete node.bgcolor; - } - } - - var graphcanvas = LGraphCanvas.active_canvas; - if (!graphcanvas.selected_nodes || Object.keys(graphcanvas.selected_nodes).length <= 1){ - fApplyColor(node); - }else{ - for (var i in graphcanvas.selected_nodes) { - fApplyColor(graphcanvas.selected_nodes[i]); - } - } - node.setDirtyCanvas(true, true); - } - - return false; - }; - - LGraphCanvas.onMenuNodeShapes = function(value, options, e, menu, node) { - if (!node) { - throw "no node passed"; - } - - new LiteGraph.ContextMenu(LiteGraph.VALID_SHAPES, { - event: e, - callback: inner_clicked, - parentMenu: menu, - node: node - }); - - function inner_clicked(v) { - if (!node) { - return; - } - node.graph.beforeChange(/*?*/); //node - - var fApplyMultiNode = function(node){ - node.shape = v; - } - - var graphcanvas = LGraphCanvas.active_canvas; - if (!graphcanvas.selected_nodes || Object.keys(graphcanvas.selected_nodes).length <= 1){ - fApplyMultiNode(node); - }else{ - for (var i in graphcanvas.selected_nodes) { - fApplyMultiNode(graphcanvas.selected_nodes[i]); - } - } - - node.graph.afterChange(/*?*/); //node - node.setDirtyCanvas(true); - } - - return false; - }; - - LGraphCanvas.onMenuNodeRemove = function(value, options, e, menu, node) { - if (!node) { - throw "no node passed"; - } - - var graph = node.graph; - graph.beforeChange(); - - - var fApplyMultiNode = function(node){ - if (node.removable === false) { - return; - } - graph.remove(node); - } - - var graphcanvas = LGraphCanvas.active_canvas; - if (!graphcanvas.selected_nodes || Object.keys(graphcanvas.selected_nodes).length <= 1){ - fApplyMultiNode(node); - }else{ - for (var i in graphcanvas.selected_nodes) { - fApplyMultiNode(graphcanvas.selected_nodes[i]); - } - } - - graph.afterChange(); - node.setDirtyCanvas(true, true); - }; - - LGraphCanvas.onMenuNodeToSubgraph = function(value, options, e, menu, node) { - var graph = node.graph; - var graphcanvas = LGraphCanvas.active_canvas; - if(!graphcanvas) //?? - return; - - var nodes_list = Object.values( graphcanvas.selected_nodes || {} ); - if( !nodes_list.length ) - nodes_list = [ node ]; - - var subgraph_node = LiteGraph.createNode("graph/subgraph"); - subgraph_node.pos = node.pos.concat(); - graph.add(subgraph_node); - - subgraph_node.buildFromNodes( nodes_list ); - - graphcanvas.deselectAllNodes(); - node.setDirtyCanvas(true, true); - }; - - LGraphCanvas.onMenuNodeClone = function(value, options, e, menu, node) { - - node.graph.beforeChange(); - - var newSelected = {}; - - var fApplyMultiNode = function(node){ - if (node.clonable == false) { - return; - } - var newnode = node.clone(); - if (!newnode) { - return; - } - newnode.pos = [node.pos[0] + 5, node.pos[1] + 5]; - node.graph.add(newnode); - newSelected[newnode.id] = newnode; - } - - var graphcanvas = LGraphCanvas.active_canvas; - if (!graphcanvas.selected_nodes || Object.keys(graphcanvas.selected_nodes).length <= 1){ - fApplyMultiNode(node); - }else{ - for (var i in graphcanvas.selected_nodes) { - fApplyMultiNode(graphcanvas.selected_nodes[i]); - } - } - - if(Object.keys(newSelected).length){ - graphcanvas.selectNodes(newSelected); - } - - node.graph.afterChange(); - - node.setDirtyCanvas(true, true); - }; - - LGraphCanvas.node_colors = { - red: { color: "#322", bgcolor: "#533", groupcolor: "#A88" }, - brown: { color: "#332922", bgcolor: "#593930", groupcolor: "#b06634" }, - green: { color: "#232", bgcolor: "#353", groupcolor: "#8A8" }, - blue: { color: "#223", bgcolor: "#335", groupcolor: "#88A" }, - pale_blue: { - color: "#2a363b", - bgcolor: "#3f5159", - groupcolor: "#3f789e" - }, - cyan: { color: "#233", bgcolor: "#355", groupcolor: "#8AA" }, - purple: { color: "#323", bgcolor: "#535", groupcolor: "#a1309b" }, - yellow: { color: "#432", bgcolor: "#653", groupcolor: "#b58b2a" }, - black: { color: "#222", bgcolor: "#000", groupcolor: "#444" } - }; - - LGraphCanvas.prototype.getCanvasMenuOptions = function() { - var options = null; - var that = this; - if (this.getMenuOptions) { - options = this.getMenuOptions(); - } else { - options = [ - { - content: "Add Node", - has_submenu: true, - callback: LGraphCanvas.onMenuAdd - }, - { content: "Add Group", callback: LGraphCanvas.onGroupAdd }, - //{ content: "Arrange", callback: that.graph.arrange }, - //{content:"Collapse All", callback: LGraphCanvas.onMenuCollapseAll } - ]; - /*if (LiteGraph.showCanvasOptions){ - options.push({ content: "Options", callback: that.showShowGraphOptionsPanel }); - }*/ - - if (this._graph_stack && this._graph_stack.length > 0) { - options.push(null, { - content: "Close subgraph", - callback: this.closeSubgraph.bind(this) - }); - } - } - - if (this.getExtraMenuOptions) { - var extra = this.getExtraMenuOptions(this, options); - if (extra) { - options = options.concat(extra); - } - } - - return options; - }; - - //called by processContextMenu to extract the menu list - LGraphCanvas.prototype.getNodeMenuOptions = function(node) { - var options = null; - - if (node.getMenuOptions) { - options = node.getMenuOptions(this); - } else { - options = [ - { - content: "Inputs", - has_submenu: true, - disabled: true, - callback: LGraphCanvas.showMenuNodeOptionalInputs - }, - { - content: "Outputs", - has_submenu: true, - disabled: true, - callback: LGraphCanvas.showMenuNodeOptionalOutputs - }, - null, - { - content: "Properties", - has_submenu: true, - callback: LGraphCanvas.onShowMenuNodeProperties - }, - null, - { - content: "Title", - callback: LGraphCanvas.onShowPropertyEditor - }, - { - content: "Mode", - has_submenu: true, - callback: LGraphCanvas.onMenuNodeMode - }]; - if(node.resizable !== false){ - options.push({ - content: "Resize", callback: LGraphCanvas.onMenuResizeNode - }); - } - options.push( - { - content: "Collapse", - callback: LGraphCanvas.onMenuNodeCollapse - }, - { content: "Pin", callback: LGraphCanvas.onMenuNodePin }, - { - content: "Colors", - has_submenu: true, - callback: LGraphCanvas.onMenuNodeColors - }, - { - content: "Shapes", - has_submenu: true, - callback: LGraphCanvas.onMenuNodeShapes - }, - null - ); - } - - if (node.onGetInputs) { - var inputs = node.onGetInputs(); - if (inputs && inputs.length) { - options[0].disabled = false; - } - } - - if (node.onGetOutputs) { - var outputs = node.onGetOutputs(); - if (outputs && outputs.length) { - options[1].disabled = false; - } - } - - if (node.getExtraMenuOptions) { - var extra = node.getExtraMenuOptions(this, options); - if (extra) { - extra.push(null); - options = extra.concat(options); - } - } - - if (node.clonable !== false) { - options.push({ - content: "Clone", - callback: LGraphCanvas.onMenuNodeClone - }); - } - - if(0) //TODO - options.push({ - content: "To Subgraph", - callback: LGraphCanvas.onMenuNodeToSubgraph - }); - - options.push(null, { - content: "Remove", - disabled: !(node.removable !== false && !node.block_delete ), - callback: LGraphCanvas.onMenuNodeRemove - }); - - if (node.graph && node.graph.onGetNodeMenuOptions) { - node.graph.onGetNodeMenuOptions(options, node); - } - - return options; - }; - - LGraphCanvas.prototype.getGroupMenuOptions = function(node) { - var o = [ - { content: "Title", callback: LGraphCanvas.onShowPropertyEditor }, - { - content: "Color", - has_submenu: true, - callback: LGraphCanvas.onMenuNodeColors - }, - { - content: "Font size", - property: "font_size", - type: "Number", - callback: LGraphCanvas.onShowPropertyEditor - }, - null, - { content: "Remove", callback: LGraphCanvas.onMenuNodeRemove } - ]; - - return o; - }; - - LGraphCanvas.prototype.processContextMenu = function(node, event) { - var that = this; - var canvas = LGraphCanvas.active_canvas; - var ref_window = canvas.getCanvasWindow(); - - var menu_info = null; - var options = { - event: event, - callback: inner_option_clicked, - extra: node - }; - - if(node) - options.title = node.type; - - //check if mouse is in input - var slot = null; - if (node) { - slot = node.getSlotInPosition(event.canvasX, event.canvasY); - LGraphCanvas.active_node = node; - } - - if (slot) { - //on slot - menu_info = []; - if (node.getSlotMenuOptions) { - menu_info = node.getSlotMenuOptions(slot); - } else { - if ( - slot && - slot.output && - slot.output.links && - slot.output.links.length - ) { - menu_info.push({ content: "Disconnect Links", slot: slot }); - } - var _slot = slot.input || slot.output; - if (_slot.removable){ - menu_info.push( - _slot.locked - ? "Cannot remove" - : { content: "Remove Slot", slot: slot } - ); - } - if (!_slot.nameLocked){ - menu_info.push({ content: "Rename Slot", slot: slot }); - } - - } - options.title = - (slot.input ? slot.input.type : slot.output.type) || "*"; - if (slot.input && slot.input.type == LiteGraph.ACTION) { - options.title = "Action"; - } - if (slot.output && slot.output.type == LiteGraph.EVENT) { - options.title = "Event"; - } - } else { - if (node) { - //on node - menu_info = this.getNodeMenuOptions(node); - } else { - menu_info = this.getCanvasMenuOptions(); - var group = this.graph.getGroupOnPos( - event.canvasX, - event.canvasY - ); - if (group) { - //on group - menu_info.push(null, { - content: "Edit Group", - has_submenu: true, - submenu: { - title: "Group", - extra: group, - options: this.getGroupMenuOptions(group) - } - }); - } - } - } - - //show menu - if (!menu_info) { - return; - } - - var menu = new LiteGraph.ContextMenu(menu_info, options, ref_window); - - function inner_option_clicked(v, options, e) { - if (!v) { - return; - } - - if (v.content == "Remove Slot") { - var info = v.slot; - node.graph.beforeChange(); - if (info.input) { - node.removeInput(info.slot); - } else if (info.output) { - node.removeOutput(info.slot); - } - node.graph.afterChange(); - return; - } else if (v.content == "Disconnect Links") { - var info = v.slot; - node.graph.beforeChange(); - if (info.output) { - node.disconnectOutput(info.slot); - } else if (info.input) { - node.disconnectInput(info.slot); - } - node.graph.afterChange(); - return; - } else if (v.content == "Rename Slot") { - var info = v.slot; - var slot_info = info.input - ? node.getInputInfo(info.slot) - : node.getOutputInfo(info.slot); - var dialog = that.createDialog( - "Name", - options - ); - var input = dialog.querySelector("input"); - if (input && slot_info) { - input.value = slot_info.label || ""; - } - var inner = function(){ - node.graph.beforeChange(); - if (input.value) { - if (slot_info) { - slot_info.label = input.value; - } - that.setDirty(true); - } - dialog.close(); - node.graph.afterChange(); - } - dialog.querySelector("button").addEventListener("click", inner); - input.addEventListener("keydown", function(e) { - dialog.is_modified = true; - if (e.keyCode == 27) { - //ESC - dialog.close(); - } else if (e.keyCode == 13) { - inner(); // save - } else if (e.keyCode != 13 && e.target.localName != "textarea") { - return; - } - e.preventDefault(); - e.stopPropagation(); - }); - input.focus(); - } - - //if(v.callback) - // return v.callback.call(that, node, options, e, menu, that, event ); - } - }; - - //API ************************************************* - //like rect but rounded corners - if (typeof(window) != "undefined" && window.CanvasRenderingContext2D && !window.CanvasRenderingContext2D.prototype.roundRect) { - window.CanvasRenderingContext2D.prototype.roundRect = function( - x, - y, - w, - h, - radius, - radius_low - ) { - var top_left_radius = 0; - var top_right_radius = 0; - var bottom_left_radius = 0; - var bottom_right_radius = 0; - - if ( radius === 0 ) - { - this.rect(x,y,w,h); - return; - } - - if(radius_low === undefined) - radius_low = radius; - - //make it compatible with official one - if(radius != null && radius.constructor === Array) - { - if(radius.length == 1) - top_left_radius = top_right_radius = bottom_left_radius = bottom_right_radius = radius[0]; - else if(radius.length == 2) - { - top_left_radius = bottom_right_radius = radius[0]; - top_right_radius = bottom_left_radius = radius[1]; - } - else if(radius.length == 4) - { - top_left_radius = radius[0]; - top_right_radius = radius[1]; - bottom_left_radius = radius[2]; - bottom_right_radius = radius[3]; - } - else - return; - } - else //old using numbers - { - top_left_radius = radius || 0; - top_right_radius = radius || 0; - bottom_left_radius = radius_low || 0; - bottom_right_radius = radius_low || 0; - } - - //top right - this.moveTo(x + top_left_radius, y); - this.lineTo(x + w - top_right_radius, y); - this.quadraticCurveTo(x + w, y, x + w, y + top_right_radius); - - //bottom right - this.lineTo(x + w, y + h - bottom_right_radius); - this.quadraticCurveTo( - x + w, - y + h, - x + w - bottom_right_radius, - y + h - ); - - //bottom left - this.lineTo(x + bottom_right_radius, y + h); - this.quadraticCurveTo(x, y + h, x, y + h - bottom_left_radius); - - //top left - this.lineTo(x, y + bottom_left_radius); - this.quadraticCurveTo(x, y, x + top_left_radius, y); - }; - }//if - - function compareObjects(a, b) { - for (var i in a) { - if (a[i] != b[i]) { - return false; - } - } - return true; - } - LiteGraph.compareObjects = compareObjects; - - function distance(a, b) { - return Math.sqrt( - (b[0] - a[0]) * (b[0] - a[0]) + (b[1] - a[1]) * (b[1] - a[1]) - ); - } - LiteGraph.distance = distance; - - function colorToString(c) { - return ( - "rgba(" + - Math.round(c[0] * 255).toFixed() + - "," + - Math.round(c[1] * 255).toFixed() + - "," + - Math.round(c[2] * 255).toFixed() + - "," + - (c.length == 4 ? c[3].toFixed(2) : "1.0") + - ")" - ); - } - LiteGraph.colorToString = colorToString; - - function isInsideRectangle(x, y, left, top, width, height) { - if (left < x && left + width > x && top < y && top + height > y) { - return true; - } - return false; - } - LiteGraph.isInsideRectangle = isInsideRectangle; - - //[minx,miny,maxx,maxy] - function growBounding(bounding, x, y) { - if (x < bounding[0]) { - bounding[0] = x; - } else if (x > bounding[2]) { - bounding[2] = x; - } - - if (y < bounding[1]) { - bounding[1] = y; - } else if (y > bounding[3]) { - bounding[3] = y; - } - } - LiteGraph.growBounding = growBounding; - - //point inside bounding box - function isInsideBounding(p, bb) { - if ( - p[0] < bb[0][0] || - p[1] < bb[0][1] || - p[0] > bb[1][0] || - p[1] > bb[1][1] - ) { - return false; - } - return true; - } - LiteGraph.isInsideBounding = isInsideBounding; - - //bounding overlap, format: [ startx, starty, width, height ] - function overlapBounding(a, b) { - var A_end_x = a[0] + a[2]; - var A_end_y = a[1] + a[3]; - var B_end_x = b[0] + b[2]; - var B_end_y = b[1] + b[3]; - - if ( - a[0] > B_end_x || - a[1] > B_end_y || - A_end_x < b[0] || - A_end_y < b[1] - ) { - return false; - } - return true; - } - LiteGraph.overlapBounding = overlapBounding; - - //Convert a hex value to its decimal value - the inputted hex must be in the - // format of a hex triplet - the kind we use for HTML colours. The function - // will return an array with three values. - function hex2num(hex) { - if (hex.charAt(0) == "#") { - hex = hex.slice(1); - } //Remove the '#' char - if there is one. - hex = hex.toUpperCase(); - var hex_alphabets = "0123456789ABCDEF"; - var value = new Array(3); - var k = 0; - var int1, int2; - for (var i = 0; i < 6; i += 2) { - int1 = hex_alphabets.indexOf(hex.charAt(i)); - int2 = hex_alphabets.indexOf(hex.charAt(i + 1)); - value[k] = int1 * 16 + int2; - k++; - } - return value; - } - - LiteGraph.hex2num = hex2num; - - //Give a array with three values as the argument and the function will return - // the corresponding hex triplet. - function num2hex(triplet) { - var hex_alphabets = "0123456789ABCDEF"; - var hex = "#"; - var int1, int2; - for (var i = 0; i < 3; i++) { - int1 = triplet[i] / 16; - int2 = triplet[i] % 16; - - hex += hex_alphabets.charAt(int1) + hex_alphabets.charAt(int2); - } - return hex; - } - - LiteGraph.num2hex = num2hex; - - /* LiteGraph GUI elements used for canvas editing *************************************/ - - /** - * ContextMenu from LiteGUI - * - * @class ContextMenu - * @constructor - * @param {Array} values (allows object { title: "Nice text", callback: function ... }) - * @param {Object} options [optional] Some options:\ - * - title: title to show on top of the menu - * - callback: function to call when an option is clicked, it receives the item information - * - ignore_item_callbacks: ignores the callback inside the item, it just calls the options.callback - * - event: you can pass a MouseEvent, this way the ContextMenu appears in that position - */ - function ContextMenu(values, options) { - options = options || {}; - this.options = options; - var that = this; - - //to link a menu with its parent - if (options.parentMenu) { - if (options.parentMenu.constructor !== this.constructor) { - console.error( - "parentMenu must be of class ContextMenu, ignoring it" - ); - options.parentMenu = null; - } else { - this.parentMenu = options.parentMenu; - this.parentMenu.lock = true; - this.parentMenu.current_submenu = this; - } - } - - var eventClass = null; - if(options.event) //use strings because comparing classes between windows doesnt work - eventClass = options.event.constructor.name; - if ( eventClass !== "MouseEvent" && - eventClass !== "CustomEvent" && - eventClass !== "PointerEvent" - ) { - console.error( - "Event passed to ContextMenu is not of type MouseEvent or CustomEvent. Ignoring it. ("+eventClass+")" - ); - options.event = null; - } - - var root = document.createElement("div"); - root.className = "litegraph litecontextmenu litemenubar-panel"; - if (options.className) { - root.className += " " + options.className; - } - root.style.minWidth = 100; - root.style.minHeight = 100; - root.style.pointerEvents = "none"; - setTimeout(function() { - root.style.pointerEvents = "auto"; - }, 100); //delay so the mouse up event is not caught by this element - - //this prevents the default context browser menu to open in case this menu was created when pressing right button - LiteGraph.pointerListenerAdd(root,"up", - function(e) { - //console.log("pointerevents: ContextMenu up root prevent"); - e.preventDefault(); - return true; - }, - true - ); - root.addEventListener( - "contextmenu", - function(e) { - if (e.button != 2) { - //right button - return false; - } - e.preventDefault(); - return false; - }, - true - ); - - LiteGraph.pointerListenerAdd(root,"down", - function(e) { - //console.log("pointerevents: ContextMenu down"); - if (e.button == 2) { - that.close(); - e.preventDefault(); - return true; - } - }, - true - ); - - function on_mouse_wheel(e) { - var pos = parseInt(root.style.top); - root.style.top = - (pos + e.deltaY * options.scroll_speed).toFixed() + "px"; - e.preventDefault(); - return true; - } - - if (!options.scroll_speed) { - options.scroll_speed = 0.1; - } - - root.addEventListener("wheel", on_mouse_wheel, true); - root.addEventListener("mousewheel", on_mouse_wheel, true); - - this.root = root; - - //title - if (options.title) { - var element = document.createElement("div"); - element.className = "litemenu-title"; - element.innerHTML = options.title; - root.appendChild(element); - } - - //entries - var num = 0; - for (var i=0; i < values.length; i++) { - var name = values.constructor == Array ? values[i] : i; - if (name != null && name.constructor !== String) { - name = name.content === undefined ? String(name) : name.content; - } - var value = values[i]; - this.addItem(name, value, options); - num++; - } - - //close on leave? touch enabled devices won't work TODO use a global device detector and condition on that - /*LiteGraph.pointerListenerAdd(root,"leave", function(e) { - console.log("pointerevents: ContextMenu leave"); - if (that.lock) { - return; - } - if (root.closing_timer) { - clearTimeout(root.closing_timer); - } - root.closing_timer = setTimeout(that.close.bind(that, e), 500); - //that.close(e); - });*/ - - LiteGraph.pointerListenerAdd(root,"enter", function(e) { - //console.log("pointerevents: ContextMenu enter"); - if (root.closing_timer) { - clearTimeout(root.closing_timer); - } - }); - - //insert before checking position - var root_document = document; - if (options.event) { - root_document = options.event.target.ownerDocument; - } - - if (!root_document) { - root_document = document; - } - - if( root_document.fullscreenElement ) - root_document.fullscreenElement.appendChild(root); - else - root_document.body.appendChild(root); - - //compute best position - var left = options.left || 0; - var top = options.top || 0; - if (options.event) { - left = options.event.clientX - 10; - top = options.event.clientY - 10; - if (options.title) { - top -= 20; - } - - if (options.parentMenu) { - var rect = options.parentMenu.root.getBoundingClientRect(); - left = rect.left + rect.width; - } - - var body_rect = document.body.getBoundingClientRect(); - var root_rect = root.getBoundingClientRect(); - if(body_rect.height == 0) - console.error("document.body height is 0. That is dangerous, set html,body { height: 100%; }"); - - if (body_rect.width && left > body_rect.width - root_rect.width - 10) { - left = body_rect.width - root_rect.width - 10; - } - if (body_rect.height && top > body_rect.height - root_rect.height - 10) { - top = body_rect.height - root_rect.height - 10; - } - } - - root.style.left = left + "px"; - root.style.top = top + "px"; - - if (options.scale) { - root.style.transform = "scale(" + options.scale + ")"; - } - } - - ContextMenu.prototype.addItem = function(name, value, options) { - var that = this; - options = options || {}; - - var element = document.createElement("div"); - element.className = "litemenu-entry submenu"; - - var disabled = false; - - if (value === null) { - element.classList.add("separator"); - //element.innerHTML = "
" - //continue; - } else { - element.innerHTML = value && value.title ? value.title : name; - element.value = value; - - if (value) { - if (value.disabled) { - disabled = true; - element.classList.add("disabled"); - } - if (value.submenu || value.has_submenu) { - element.classList.add("has_submenu"); - } - } - - if (typeof value == "function") { - element.dataset["value"] = name; - element.onclick_callback = value; - } else { - element.dataset["value"] = value; - } - - if (value.className) { - element.className += " " + value.className; - } - } - - this.root.appendChild(element); - if (!disabled) { - element.addEventListener("click", inner_onclick); - } - if (options.autoopen) { - LiteGraph.pointerListenerAdd(element,"enter",inner_over); - } - - function inner_over(e) { - var value = this.value; - if (!value || !value.has_submenu) { - return; - } - //if it is a submenu, autoopen like the item was clicked - inner_onclick.call(this, e); - } - - //menu option clicked - function inner_onclick(e) { - var value = this.value; - var close_parent = true; - - if (that.current_submenu) { - that.current_submenu.close(e); - } - - //global callback - if (options.callback) { - var r = options.callback.call( - this, - value, - options, - e, - that, - options.node - ); - if (r === true) { - close_parent = false; - } - } - - //special cases - if (value) { - if ( - value.callback && - !options.ignore_item_callbacks && - value.disabled !== true - ) { - //item callback - var r = value.callback.call( - this, - value, - options, - e, - that, - options.extra - ); - if (r === true) { - close_parent = false; - } - } - if (value.submenu) { - if (!value.submenu.options) { - throw "ContextMenu submenu needs options"; - } - var submenu = new that.constructor(value.submenu.options, { - callback: value.submenu.callback, - event: e, - parentMenu: that, - ignore_item_callbacks: - value.submenu.ignore_item_callbacks, - title: value.submenu.title, - extra: value.submenu.extra, - autoopen: options.autoopen - }); - close_parent = false; - } - } - - if (close_parent && !that.lock) { - that.close(); - } - } - - return element; - }; - - ContextMenu.prototype.close = function(e, ignore_parent_menu) { - if (this.root.parentNode) { - this.root.parentNode.removeChild(this.root); - } - if (this.parentMenu && !ignore_parent_menu) { - this.parentMenu.lock = false; - this.parentMenu.current_submenu = null; - if (e === undefined) { - this.parentMenu.close(); - } else if ( - e && - !ContextMenu.isCursorOverElement(e, this.parentMenu.root) - ) { - ContextMenu.trigger(this.parentMenu.root, LiteGraph.pointerevents_method+"leave", e); - } - } - if (this.current_submenu) { - this.current_submenu.close(e, true); - } - - if (this.root.closing_timer) { - clearTimeout(this.root.closing_timer); - } - - // TODO implement : LiteGraph.contextMenuClosed(); :: keep track of opened / closed / current ContextMenu - // on key press, allow filtering/selecting the context menu elements - }; - - //this code is used to trigger events easily (used in the context menu mouseleave - ContextMenu.trigger = function(element, event_name, params, origin) { - var evt = document.createEvent("CustomEvent"); - evt.initCustomEvent(event_name, true, true, params); //canBubble, cancelable, detail - evt.srcElement = origin; - if (element.dispatchEvent) { - element.dispatchEvent(evt); - } else if (element.__events) { - element.__events.dispatchEvent(evt); - } - //else nothing seems binded here so nothing to do - return evt; - }; - - //returns the top most menu - ContextMenu.prototype.getTopMenu = function() { - if (this.options.parentMenu) { - return this.options.parentMenu.getTopMenu(); - } - return this; - }; - - ContextMenu.prototype.getFirstEvent = function() { - if (this.options.parentMenu) { - return this.options.parentMenu.getFirstEvent(); - } - return this.options.event; - }; - - ContextMenu.isCursorOverElement = function(event, element) { - var left = event.clientX; - var top = event.clientY; - var rect = element.getBoundingClientRect(); - if (!rect) { - return false; - } - if ( - top > rect.top && - top < rect.top + rect.height && - left > rect.left && - left < rect.left + rect.width - ) { - return true; - } - return false; - }; - - LiteGraph.ContextMenu = ContextMenu; - - LiteGraph.closeAllContextMenus = function(ref_window) { - ref_window = ref_window || window; - - var elements = ref_window.document.querySelectorAll(".litecontextmenu"); - if (!elements.length) { - return; - } - - var result = []; - for (var i = 0; i < elements.length; i++) { - result.push(elements[i]); - } - - for (var i=0; i < result.length; i++) { - if (result[i].close) { - result[i].close(); - } else if (result[i].parentNode) { - result[i].parentNode.removeChild(result[i]); - } - } - }; - - LiteGraph.extendClass = function(target, origin) { - for (var i in origin) { - //copy class properties - if (target.hasOwnProperty(i)) { - continue; - } - target[i] = origin[i]; - } - - if (origin.prototype) { - //copy prototype properties - for (var i in origin.prototype) { - //only enumerable - if (!origin.prototype.hasOwnProperty(i)) { - continue; - } - - if (target.prototype.hasOwnProperty(i)) { - //avoid overwriting existing ones - continue; - } - - //copy getters - if (origin.prototype.__lookupGetter__(i)) { - target.prototype.__defineGetter__( - i, - origin.prototype.__lookupGetter__(i) - ); - } else { - target.prototype[i] = origin.prototype[i]; - } - - //and setters - if (origin.prototype.__lookupSetter__(i)) { - target.prototype.__defineSetter__( - i, - origin.prototype.__lookupSetter__(i) - ); - } - } - } - }; - - //used by some widgets to render a curve editor - function CurveEditor( points ) - { - this.points = points; - this.selected = -1; - this.nearest = -1; - this.size = null; //stores last size used - this.must_update = true; - this.margin = 5; - } - - CurveEditor.sampleCurve = function(f,points) - { - if(!points) - return; - for(var i = 0; i < points.length - 1; ++i) - { - var p = points[i]; - var pn = points[i+1]; - if(pn[0] < f) - continue; - var r = (pn[0] - p[0]); - if( Math.abs(r) < 0.00001 ) - return p[1]; - var local_f = (f - p[0]) / r; - return p[1] * (1.0 - local_f) + pn[1] * local_f; - } - return 0; - } - - CurveEditor.prototype.draw = function( ctx, size, graphcanvas, background_color, line_color, inactive ) - { - var points = this.points; - if(!points) - return; - this.size = size; - var w = size[0] - this.margin * 2; - var h = size[1] - this.margin * 2; - - line_color = line_color || "#666"; - - ctx.save(); - ctx.translate(this.margin,this.margin); - - if(background_color) - { - ctx.fillStyle = "#111"; - ctx.fillRect(0,0,w,h); - ctx.fillStyle = "#222"; - ctx.fillRect(w*0.5,0,1,h); - ctx.strokeStyle = "#333"; - ctx.strokeRect(0,0,w,h); - } - ctx.strokeStyle = line_color; - if(inactive) - ctx.globalAlpha = 0.5; - ctx.beginPath(); - for(var i = 0; i < points.length; ++i) - { - var p = points[i]; - ctx.lineTo( p[0] * w, (1.0 - p[1]) * h ); - } - ctx.stroke(); - ctx.globalAlpha = 1; - if(!inactive) - for(var i = 0; i < points.length; ++i) - { - var p = points[i]; - ctx.fillStyle = this.selected == i ? "#FFF" : (this.nearest == i ? "#DDD" : "#AAA"); - ctx.beginPath(); - ctx.arc( p[0] * w, (1.0 - p[1]) * h, 2, 0, Math.PI * 2 ); - ctx.fill(); - } - ctx.restore(); - } - - //localpos is mouse in curve editor space - CurveEditor.prototype.onMouseDown = function( localpos, graphcanvas ) - { - var points = this.points; - if(!points) - return; - if( localpos[1] < 0 ) - return; - - //this.captureInput(true); - var w = this.size[0] - this.margin * 2; - var h = this.size[1] - this.margin * 2; - var x = localpos[0] - this.margin; - var y = localpos[1] - this.margin; - var pos = [x,y]; - var max_dist = 30 / graphcanvas.ds.scale; - //search closer one - this.selected = this.getCloserPoint(pos, max_dist); - //create one - if(this.selected == -1) - { - var point = [x / w, 1 - y / h]; - points.push(point); - points.sort(function(a,b){ return a[0] - b[0]; }); - this.selected = points.indexOf(point); - this.must_update = true; - } - if(this.selected != -1) - return true; - } - - CurveEditor.prototype.onMouseMove = function( localpos, graphcanvas ) - { - var points = this.points; - if(!points) - return; - var s = this.selected; - if(s < 0) - return; - var x = (localpos[0] - this.margin) / (this.size[0] - this.margin * 2 ); - var y = (localpos[1] - this.margin) / (this.size[1] - this.margin * 2 ); - var curvepos = [(localpos[0] - this.margin),(localpos[1] - this.margin)]; - var max_dist = 30 / graphcanvas.ds.scale; - this._nearest = this.getCloserPoint(curvepos, max_dist); - var point = points[s]; - if(point) - { - var is_edge_point = s == 0 || s == points.length - 1; - if( !is_edge_point && (localpos[0] < -10 || localpos[0] > this.size[0] + 10 || localpos[1] < -10 || localpos[1] > this.size[1] + 10) ) - { - points.splice(s,1); - this.selected = -1; - return; - } - if( !is_edge_point ) //not edges - point[0] = Math.clamp(x,0,1); - else - point[0] = s == 0 ? 0 : 1; - point[1] = 1.0 - Math.clamp(y,0,1); - points.sort(function(a,b){ return a[0] - b[0]; }); - this.selected = points.indexOf(point); - this.must_update = true; - } - } - - CurveEditor.prototype.onMouseUp = function( localpos, graphcanvas ) - { - this.selected = -1; - return false; - } - - CurveEditor.prototype.getCloserPoint = function(pos, max_dist) - { - var points = this.points; - if(!points) - return -1; - max_dist = max_dist || 30; - var w = (this.size[0] - this.margin * 2); - var h = (this.size[1] - this.margin * 2); - var num = points.length; - var p2 = [0,0]; - var min_dist = 1000000; - var closest = -1; - var last_valid = -1; - for(var i = 0; i < num; ++i) - { - var p = points[i]; - p2[0] = p[0] * w; - p2[1] = (1.0 - p[1]) * h; - if(p2[0] < pos[0]) - last_valid = i; - var dist = vec2.distance(pos,p2); - if(dist > min_dist || dist > max_dist) - continue; - closest = i; - min_dist = dist; - } - return closest; - } - - LiteGraph.CurveEditor = CurveEditor; - - //used to create nodes from wrapping functions - LiteGraph.getParameterNames = function(func) { - return (func + "") - .replace(/[/][/].*$/gm, "") // strip single-line comments - .replace(/\s+/g, "") // strip white space - .replace(/[/][*][^/*]*[*][/]/g, "") // strip multi-line comments /**/ - .split("){", 1)[0] - .replace(/^[^(]*[(]/, "") // extract the parameters - .replace(/=[^,]+/g, "") // strip any ES6 defaults - .split(",") - .filter(Boolean); // split & filter [""] - }; - - /* helper for interaction: pointer, touch, mouse Listeners - used by LGraphCanvas DragAndScale ContextMenu*/ - LiteGraph.pointerListenerAdd = function(oDOM, sEvIn, fCall, capture=false) { - if (!oDOM || !oDOM.addEventListener || !sEvIn || typeof fCall!=="function"){ - //console.log("cant pointerListenerAdd "+oDOM+", "+sEvent+", "+fCall); - return; // -- break -- - } - - var sMethod = LiteGraph.pointerevents_method; - var sEvent = sEvIn; - - // UNDER CONSTRUCTION - // convert pointerevents to touch event when not available - if (sMethod=="pointer" && !window.PointerEvent){ - console.warn("sMethod=='pointer' && !window.PointerEvent"); - console.log("Converting pointer["+sEvent+"] : down move up cancel enter TO touchstart touchmove touchend, etc .."); - switch(sEvent){ - case "down":{ - sMethod = "touch"; - sEvent = "start"; - break; - } - case "move":{ - sMethod = "touch"; - //sEvent = "move"; - break; - } - case "up":{ - sMethod = "touch"; - sEvent = "end"; - break; - } - case "cancel":{ - sMethod = "touch"; - //sEvent = "cancel"; - break; - } - case "enter":{ - console.log("debug: Should I send a move event?"); // ??? - break; - } - // case "over": case "out": not used at now - default:{ - console.warn("PointerEvent not available in this browser ? The event "+sEvent+" would not be called"); - } - } - } - - switch(sEvent){ - //both pointer and move events - case "down": case "up": case "move": case "over": case "out": case "enter": - { - oDOM.addEventListener(sMethod+sEvent, fCall, capture); - } - // only pointerevents - case "leave": case "cancel": case "gotpointercapture": case "lostpointercapture": - { - if (sMethod!="mouse"){ - return oDOM.addEventListener(sMethod+sEvent, fCall, capture); - } - } - // not "pointer" || "mouse" - default: - return oDOM.addEventListener(sEvent, fCall, capture); - } - } - LiteGraph.pointerListenerRemove = function(oDOM, sEvent, fCall, capture=false) { - if (!oDOM || !oDOM.removeEventListener || !sEvent || typeof fCall!=="function"){ - //console.log("cant pointerListenerRemove "+oDOM+", "+sEvent+", "+fCall); - return; // -- break -- - } - switch(sEvent){ - //both pointer and move events - case "down": case "up": case "move": case "over": case "out": case "enter": - { - if (LiteGraph.pointerevents_method=="pointer" || LiteGraph.pointerevents_method=="mouse"){ - oDOM.removeEventListener(LiteGraph.pointerevents_method+sEvent, fCall, capture); - } - } - // only pointerevents - case "leave": case "cancel": case "gotpointercapture": case "lostpointercapture": - { - if (LiteGraph.pointerevents_method=="pointer"){ - return oDOM.removeEventListener(LiteGraph.pointerevents_method+sEvent, fCall, capture); - } - } - // not "pointer" || "mouse" - default: - return oDOM.removeEventListener(sEvent, fCall, capture); - } - } - - Math.clamp = function(v, a, b) { - return a > v ? a : b < v ? b : v; - }; - - if (typeof window != "undefined" && !window["requestAnimationFrame"]) { - window.requestAnimationFrame = - window.webkitRequestAnimationFrame || - window.mozRequestAnimationFrame || - function(callback) { - window.setTimeout(callback, 1000 / 60); - }; - } -})(this); - -if (typeof exports != "undefined") { - exports.LiteGraph = this.LiteGraph; -} - - diff --git a/examples/editing/litegraph.js/css/litegraph.css b/examples/editing/litegraph.js/css/litegraph.css deleted file mode 100644 index 918858f4..00000000 --- a/examples/editing/litegraph.js/css/litegraph.css +++ /dev/null @@ -1,680 +0,0 @@ -/* this CSS contains only the basic CSS needed to run the app and use it */ - -.lgraphcanvas { - /*cursor: crosshair;*/ - user-select: none; - -moz-user-select: none; - -webkit-user-select: none; - outline: none; - font-family: Tahoma, sans-serif; -} - -.lgraphcanvas * { - box-sizing: border-box; -} - -.litegraph.litecontextmenu { - font-family: Tahoma, sans-serif; - position: fixed; - top: 100px; - left: 100px; - min-width: 100px; - color: #aaf; - padding: 0; - box-shadow: 0 0 10px black !important; - background-color: #2e2e2e !important; - z-index: 10; -} - -.litegraph.litecontextmenu.dark { - background-color: #000 !important; -} - -.litegraph.litecontextmenu .litemenu-title img { - margin-top: 2px; - margin-left: 2px; - margin-right: 4px; -} - -.litegraph.litecontextmenu .litemenu-entry { - margin: 2px; - padding: 2px; -} - -.litegraph.litecontextmenu .litemenu-entry.submenu { - background-color: #2e2e2e !important; -} - -.litegraph.litecontextmenu.dark .litemenu-entry.submenu { - background-color: #000 !important; -} - -.litegraph .litemenubar ul { - font-family: Tahoma, sans-serif; - margin: 0; - padding: 0; -} - -.litegraph .litemenubar li { - font-size: 14px; - color: #999; - display: inline-block; - min-width: 50px; - padding-left: 10px; - padding-right: 10px; - user-select: none; - -moz-user-select: none; - -webkit-user-select: none; - cursor: pointer; -} - -.litegraph .litemenubar li:hover { - background-color: #777; - color: #eee; -} - -.litegraph .litegraph .litemenubar-panel { - position: absolute; - top: 5px; - left: 5px; - min-width: 100px; - background-color: #444; - box-shadow: 0 0 3px black; - padding: 4px; - border-bottom: 2px solid #aaf; - z-index: 10; -} - -.litegraph .litemenu-entry, -.litemenu-title { - font-size: 12px; - color: #aaa; - padding: 0 0 0 4px; - margin: 2px; - padding-left: 2px; - -moz-user-select: none; - -webkit-user-select: none; - user-select: none; - cursor: pointer; -} - -.litegraph .litemenu-entry .icon { - display: inline-block; - width: 12px; - height: 12px; - margin: 2px; - vertical-align: top; -} - -.litegraph .litemenu-entry.checked .icon { - background-color: #aaf; -} - -.litegraph .litemenu-entry .more { - float: right; - padding-right: 5px; -} - -.litegraph .litemenu-entry.disabled { - opacity: 0.5; - cursor: default; -} - -.litegraph .litemenu-entry.separator { - display: block; - border-top: 1px solid #333; - border-bottom: 1px solid #666; - width: 100%; - height: 0px; - margin: 3px 0 2px 0; - background-color: transparent; - padding: 0 !important; - cursor: default !important; -} - -.litegraph .litemenu-entry.has_submenu { - border-right: 2px solid cyan; -} - -.litegraph .litemenu-title { - color: #dde; - background-color: #111; - margin: 0; - padding: 2px; - cursor: default; -} - -.litegraph .litemenu-entry:hover:not(.disabled):not(.separator) { - background-color: #444 !important; - color: #eee; - transition: all 0.2s; -} - -.litegraph .litemenu-entry .property_name { - display: inline-block; - text-align: left; - min-width: 80px; - min-height: 1.2em; -} - -.litegraph .litemenu-entry .property_value { - display: inline-block; - background-color: rgba(0, 0, 0, 0.5); - text-align: right; - min-width: 80px; - min-height: 1.2em; - vertical-align: middle; - padding-right: 10px; -} - -.litegraph.litesearchbox { - font-family: Tahoma, sans-serif; - position: absolute; - background-color: rgba(0, 0, 0, 0.5); - padding-top: 4px; -} - -.litegraph.litesearchbox input, -.litegraph.litesearchbox select { - margin-top: 3px; - min-width: 60px; - min-height: 1.5em; - background-color: black; - border: 0; - color: white; - padding-left: 10px; - margin-right: 5px; -} - -.litegraph.litesearchbox .name { - display: inline-block; - min-width: 60px; - min-height: 1.5em; - padding-left: 10px; -} - -.litegraph.litesearchbox .helper { - overflow: auto; - max-height: 200px; - margin-top: 2px; -} - -.litegraph.lite-search-item { - font-family: Tahoma, sans-serif; - background-color: rgba(0, 0, 0, 0.5); - color: white; - padding-top: 2px; -} - -.litegraph.lite-search-item.not_in_filter{ - /*background-color: rgba(50, 50, 50, 0.5);*/ - /*color: #999;*/ - color: #B99; - font-style: italic; -} - -.litegraph.lite-search-item.generic_type{ - /*background-color: rgba(50, 50, 50, 0.5);*/ - /*color: #DD9;*/ - color: #999; - font-style: italic; -} - -.litegraph.lite-search-item:hover, -.litegraph.lite-search-item.selected { - cursor: pointer; - background-color: white; - color: black; -} - -/* DIALOGs ******/ - -.litegraph .dialog { - position: absolute; - top: 50%; - left: 50%; - margin-top: -150px; - margin-left: -200px; - - background-color: #2A2A2A; - - min-width: 400px; - min-height: 200px; - box-shadow: 0 0 4px #111; - border-radius: 6px; -} - -.litegraph .dialog.settings { - left: 10px; - top: 10px; - height: calc( 100% - 20px ); - margin: auto; - max-width: 50%; -} - -.litegraph .dialog.centered { - top: 50px; - left: 50%; - position: absolute; - transform: translateX(-50%); - min-width: 600px; - min-height: 300px; - height: calc( 100% - 100px ); - margin: auto; -} - -.litegraph .dialog .close { - float: right; - margin: 4px; - margin-right: 10px; - cursor: pointer; - font-size: 1.4em; -} - -.litegraph .dialog .close:hover { - color: white; -} - -.litegraph .dialog .dialog-header { - color: #AAA; - border-bottom: 1px solid #161616; -} - -.litegraph .dialog .dialog-header { height: 40px; } -.litegraph .dialog .dialog-footer { height: 50px; padding: 10px; border-top: 1px solid #1a1a1a;} - -.litegraph .dialog .dialog-header .dialog-title { - font: 20px "Arial"; - margin: 4px; - padding: 4px 10px; - display: inline-block; -} - -.litegraph .dialog .dialog-content, .litegraph .dialog .dialog-alt-content { - height: calc(100% - 90px); - width: 100%; - min-height: 100px; - display: inline-block; - color: #AAA; - /*background-color: black;*/ - overflow: auto; -} - -.litegraph .dialog .dialog-content h3 { - margin: 10px; -} - -.litegraph .dialog .dialog-content .connections { - flex-direction: row; -} - -.litegraph .dialog .dialog-content .connections .connections_side { - width: calc(50% - 5px); - min-height: 100px; - background-color: black; - display: flex; -} - -.litegraph .dialog .node_type { - font-size: 1.2em; - display: block; - margin: 10px; -} - -.litegraph .dialog .node_desc { - opacity: 0.5; - display: block; - margin: 10px; -} - -.litegraph .dialog .separator { - display: block; - width: calc( 100% - 4px ); - height: 1px; - border-top: 1px solid #000; - border-bottom: 1px solid #333; - margin: 10px 2px; - padding: 0; -} - -.litegraph .dialog .property { - margin-bottom: 2px; - padding: 4px; -} - -.litegraph .dialog .property:hover { - background: #545454; -} - -.litegraph .dialog .property_name { - color: #737373; - display: inline-block; - text-align: left; - vertical-align: top; - width: 160px; - padding-left: 4px; - overflow: hidden; - margin-right: 6px; -} - -.litegraph .dialog .property:hover .property_name { - color: white; -} - -.litegraph .dialog .property_value { - display: inline-block; - text-align: right; - color: #AAA; - background-color: #1A1A1A; - /*width: calc( 100% - 122px );*/ - max-width: calc( 100% - 162px ); - min-width: 200px; - max-height: 300px; - min-height: 20px; - padding: 4px; - padding-right: 12px; - overflow: hidden; - cursor: pointer; - border-radius: 3px; -} - -.litegraph .dialog .property_value:hover { - color: white; -} - -.litegraph .dialog .property.boolean .property_value { - padding-right: 30px; - color: #A88; - /*width: auto; - float: right;*/ -} - -.litegraph .dialog .property.boolean.bool-on .property_name{ - color: #8A8; -} -.litegraph .dialog .property.boolean.bool-on .property_value{ - color: #8A8; -} - -.litegraph .dialog .btn { - border: 0; - border-radius: 4px; - padding: 4px 20px; - margin-left: 0px; - background-color: #060606; - color: #8e8e8e; -} - -.litegraph .dialog .btn:hover { - background-color: #111; - color: #FFF; -} - -.litegraph .dialog .btn.delete:hover { - background-color: #F33; - color: black; -} - -.litegraph .subgraph_property { - padding: 4px; -} - -.litegraph .subgraph_property:hover { - background-color: #333; -} - -.litegraph .subgraph_property.extra { - margin-top: 8px; -} - -.litegraph .subgraph_property span.name { - font-size: 1.3em; - padding-left: 4px; -} - -.litegraph .subgraph_property span.type { - opacity: 0.5; - margin-right: 20px; - padding-left: 4px; -} - -.litegraph .subgraph_property span.label { - display: inline-block; - width: 60px; - padding: 0px 10px; -} - -.litegraph .subgraph_property input { - width: 140px; - color: #999; - background-color: #1A1A1A; - border-radius: 4px; - border: 0; - margin-right: 10px; - padding: 4px; - padding-left: 10px; -} - -.litegraph .subgraph_property button { - background-color: #1c1c1c; - color: #aaa; - border: 0; - border-radius: 2px; - padding: 4px 10px; - cursor: pointer; -} - -.litegraph .subgraph_property.extra { - color: #ccc; -} - -.litegraph .subgraph_property.extra input { - background-color: #111; -} - -.litegraph .bullet_icon { - margin-left: 10px; - border-radius: 10px; - width: 12px; - height: 12px; - background-color: #666; - display: inline-block; - margin-top: 2px; - margin-right: 4px; - transition: background-color 0.1s ease 0s; - -moz-transition: background-color 0.1s ease 0s; -} - -.litegraph .bullet_icon:hover { - background-color: #698; - cursor: pointer; -} - -/* OLD */ - -.graphcontextmenu { - padding: 4px; - min-width: 100px; -} - -.graphcontextmenu-title { - color: #dde; - background-color: #222; - margin: 0; - padding: 2px; - cursor: default; -} - -.graphmenu-entry { - box-sizing: border-box; - margin: 2px; - padding-left: 20px; - user-select: none; - -moz-user-select: none; - -webkit-user-select: none; - transition: all linear 0.3s; -} - -.graphmenu-entry.event, -.litemenu-entry.event { - border-left: 8px solid orange; - padding-left: 12px; -} - -.graphmenu-entry.disabled { - opacity: 0.3; -} - -.graphmenu-entry.submenu { - border-right: 2px solid #eee; -} - -.graphmenu-entry:hover { - background-color: #555; -} - -.graphmenu-entry.separator { - background-color: #111; - border-bottom: 1px solid #666; - height: 1px; - width: calc(100% - 20px); - -moz-width: calc(100% - 20px); - -webkit-width: calc(100% - 20px); -} - -.graphmenu-entry .property_name { - display: inline-block; - text-align: left; - min-width: 80px; - min-height: 1.2em; -} - -.graphmenu-entry .property_value, -.litemenu-entry .property_value { - display: inline-block; - background-color: rgba(0, 0, 0, 0.5); - text-align: right; - min-width: 80px; - min-height: 1.2em; - vertical-align: middle; - padding-right: 10px; -} - -.graphdialog { - position: absolute; - top: 10px; - left: 10px; - min-height: 2em; - background-color: #333; - font-size: 1.2em; - box-shadow: 0 0 10px black !important; - z-index: 10; -} - -.graphdialog.rounded { - border-radius: 12px; - padding-right: 2px; -} - -.graphdialog .name { - display: inline-block; - min-width: 60px; - min-height: 1.5em; - padding-left: 10px; -} - -.graphdialog input, -.graphdialog textarea, -.graphdialog select { - margin: 3px; - min-width: 60px; - min-height: 1.5em; - background-color: black; - border: 0; - color: white; - padding-left: 10px; - outline: none; -} - -.graphdialog textarea { - min-height: 150px; -} - -.graphdialog button { - margin-top: 3px; - vertical-align: top; - background-color: #999; - border: 0; -} - -.graphdialog button.rounded, -.graphdialog input.rounded { - border-radius: 0 12px 12px 0; -} - -.graphdialog .helper { - overflow: auto; - max-height: 200px; -} - -.graphdialog .help-item { - padding-left: 10px; -} - -.graphdialog .help-item:hover, -.graphdialog .help-item.selected { - cursor: pointer; - background-color: white; - color: black; -} - -.litegraph .dialog { - min-height: 0; -} -.litegraph .dialog .dialog-content { -display: block; -} -.litegraph .dialog .dialog-content .subgraph_property { -padding: 5px; -} -.litegraph .dialog .dialog-footer { -margin: 0; -} -.litegraph .dialog .dialog-footer .subgraph_property { -margin-top: 0; -display: flex; -align-items: center; -padding: 5px; -} -.litegraph .dialog .dialog-footer .subgraph_property .name { -flex: 1; -} -.litegraph .graphdialog { -display: flex; -align-items: center; -border-radius: 20px; -padding: 4px 10px; -position: fixed; -} -.litegraph .graphdialog .name { -padding: 0; -min-height: 0; -font-size: 16px; -vertical-align: middle; -} -.litegraph .graphdialog .value { -font-size: 16px; -min-height: 0; -margin: 0 10px; -padding: 2px 5px; -} -.litegraph .graphdialog input[type="checkbox"] { -width: 16px; -height: 16px; -} -.litegraph .graphdialog button { -padding: 4px 18px; -border-radius: 20px; -cursor: pointer; -} - diff --git a/examples/editing/litegraph.js/package.json b/examples/editing/litegraph.js/package.json deleted file mode 100644 index 6a298d6a..00000000 --- a/examples/editing/litegraph.js/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "litegraph.js", - "version": "0.7.14", - "description": "A graph node editor similar to PD or UDK Blueprints. It works in an HTML5 Canvas and allows to export graphs to be included in applications.", - "main": "build/litegraph.core.js", - "types": "src/litegraph.d.ts", - "directories": { - "doc": "doc" - }, - "private": false, - "scripts": { - "prebuild": "rimraf build", - "build": "grunt build", - "start": "nodemon utils/server.js", - "test": "jest", - "test:allVersions": "./utils/test.sh", - "prettier": "npx prettier --write src/**/*.* css/**/*.*", - "lint": "npx eslint src", - "lint:fix": "npx eslint --fix src" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/jagenjo/litegraph.js.git" - }, - "author": "jagenjo", - "license": "MIT", - "files": [ - "build", - "css/litegraph.css", - "src/litegraph.d.ts" - ], - "bugs": { - "url": "https://github.com/jagenjo/litegraph.js/issues" - }, - "homepage": "https://github.com/jagenjo/litegraph.js#readme", - "devDependencies": { - "@types/jest": "^28.1.3", - "eslint": "^8.37.0 ", - "eslint-plugin-jest": "^27.2.1", - "express": "^4.17.1", - "google-closure-compiler": "^20171112.0.0", - "grunt": "^1.1.0", - "grunt-cli": "^1.2.0", - "grunt-closure-tools": "^1.0.0", - "grunt-contrib-concat": "^1.0.1", - "jest": "^28.1.3", - "nodemon": "^1.19.4", - "rimraf": "^2.7.1" - } -} diff --git a/examples/editing/litegraph.js/src/litegraph.d.ts b/examples/editing/litegraph.js/src/litegraph.d.ts deleted file mode 100644 index 6629e779..00000000 --- a/examples/editing/litegraph.js/src/litegraph.d.ts +++ /dev/null @@ -1,1506 +0,0 @@ -// Type definitions for litegraph.js 0.7.0 -// Project: litegraph.js -// Definitions by: NateScarlet - -export type Vector2 = [number, number]; -export type Vector4 = [number, number, number, number]; -export type widgetTypes = - | "number" - | "slider" - | "combo" - | "text" - | "toggle" - | "button"; -export type SlotShape = - | typeof LiteGraph.BOX_SHAPE - | typeof LiteGraph.CIRCLE_SHAPE - | typeof LiteGraph.ARROW_SHAPE - | typeof LiteGraph.SQUARE_SHAPE - | number; // For custom shapes - -/** https://github.com/jagenjo/litegraph.js/tree/master/guides#node-slots */ -export interface INodeSlot { - name: string; - type: string | -1; - label?: string; - dir?: - | typeof LiteGraph.UP - | typeof LiteGraph.RIGHT - | typeof LiteGraph.DOWN - | typeof LiteGraph.LEFT; - color_on?: string; - color_off?: string; - shape?: SlotShape; - locked?: boolean; - nameLocked?: boolean; -} - -export interface INodeInputSlot extends INodeSlot { - link: LLink["id"] | null; -} -export interface INodeOutputSlot extends INodeSlot { - links: LLink["id"][] | null; -} - -export type WidgetCallback = ( - this: T, - value: T["value"], - graphCanvas: LGraphCanvas, - node: LGraphNode, - pos: Vector2, - event?: MouseEvent -) => void; - -export interface IWidget { - name: string | null; - value: TValue; - options?: TOptions; - type?: widgetTypes; - y?: number; - property?: string; - last_y?: number; - clicked?: boolean; - marker?: boolean; - callback?: WidgetCallback; - /** Called by `LGraphCanvas.drawNodeWidgets` */ - draw?( - ctx: CanvasRenderingContext2D, - node: LGraphNode, - width: number, - posY: number, - height: number - ): void; - /** - * Called by `LGraphCanvas.processNodeWidgets` - * https://github.com/jagenjo/litegraph.js/issues/76 - */ - mouse?( - event: MouseEvent, - pos: Vector2, - node: LGraphNode - ): boolean; - /** Called by `LGraphNode.computeSize` */ - computeSize?(width: number): [number, number]; -} -export interface IButtonWidget extends IWidget { - type: "button"; -} -export interface IToggleWidget - extends IWidget { - type: "toggle"; -} -export interface ISliderWidget - extends IWidget { - type: "slider"; -} -export interface INumberWidget extends IWidget { - type: "number"; -} -export interface IComboWidget - extends IWidget< - string[], - { - values: - | string[] - | ((widget: IComboWidget, node: LGraphNode) => string[]); - } - > { - type: "combo"; -} - -export interface ITextWidget extends IWidget { - type: "text"; -} - -export interface IContextMenuItem { - content: string; - callback?: ContextMenuEventListener; - /** Used as innerHTML for extra child element */ - title?: string; - disabled?: boolean; - has_submenu?: boolean; - submenu?: { - options: ContextMenuItem[]; - } & IContextMenuOptions; - className?: string; -} -export interface IContextMenuOptions { - callback?: ContextMenuEventListener; - ignore_item_callbacks?: Boolean; - event?: MouseEvent | CustomEvent; - parentMenu?: ContextMenu; - autoopen?: boolean; - title?: string; - extra?: any; -} - -export type ContextMenuItem = IContextMenuItem | null; -export type ContextMenuEventListener = ( - value: ContextMenuItem, - options: IContextMenuOptions, - event: MouseEvent, - parentMenu: ContextMenu | undefined, - node: LGraphNode -) => boolean | void; - -export const LiteGraph: { - VERSION: number; - - CANVAS_GRID_SIZE: number; - - NODE_TITLE_HEIGHT: number; - NODE_TITLE_TEXT_Y: number; - NODE_SLOT_HEIGHT: number; - NODE_WIDGET_HEIGHT: number; - NODE_WIDTH: number; - NODE_MIN_WIDTH: number; - NODE_COLLAPSED_RADIUS: number; - NODE_COLLAPSED_WIDTH: number; - NODE_TITLE_COLOR: string; - NODE_TEXT_SIZE: number; - NODE_TEXT_COLOR: string; - NODE_SUBTEXT_SIZE: number; - NODE_DEFAULT_COLOR: string; - NODE_DEFAULT_BGCOLOR: string; - NODE_DEFAULT_BOXCOLOR: string; - NODE_DEFAULT_SHAPE: string; - DEFAULT_SHADOW_COLOR: string; - DEFAULT_GROUP_FONT: number; - - LINK_COLOR: string; - EVENT_LINK_COLOR: string; - CONNECTING_LINK_COLOR: string; - - MAX_NUMBER_OF_NODES: number; //avoid infinite loops - DEFAULT_POSITION: Vector2; //default node position - VALID_SHAPES: ["default", "box", "round", "card"]; //,"circle" - - //shapes are used for nodes but also for slots - BOX_SHAPE: 1; - ROUND_SHAPE: 2; - CIRCLE_SHAPE: 3; - CARD_SHAPE: 4; - ARROW_SHAPE: 5; - SQUARE_SHAPE: 6; - - //enums - INPUT: 1; - OUTPUT: 2; - - EVENT: -1; //for outputs - ACTION: -1; //for inputs - - ALWAYS: 0; - ON_EVENT: 1; - NEVER: 2; - ON_TRIGGER: 3; - - UP: 1; - DOWN: 2; - LEFT: 3; - RIGHT: 4; - CENTER: 5; - - STRAIGHT_LINK: 0; - LINEAR_LINK: 1; - SPLINE_LINK: 2; - - NORMAL_TITLE: 0; - NO_TITLE: 1; - TRANSPARENT_TITLE: 2; - AUTOHIDE_TITLE: 3; - - node_images_path: string; - - debug: boolean; - catch_exceptions: boolean; - throw_errors: boolean; - /** if set to true some nodes like Formula would be allowed to evaluate code that comes from unsafe sources (like node configuration), which could lead to exploits */ - allow_scripts: boolean; - /** node types by string */ - registered_node_types: Record; - /** used for dropping files in the canvas */ - node_types_by_file_extension: Record; - /** node types by class name */ - Nodes: Record; - - /** used to add extra features to the search box */ - searchbox_extras: Record< - string, - { - data: { outputs: string[][]; title: string }; - desc: string; - type: string; - } - >; - - createNode(type: string): T; - /** Register a node class so it can be listed when the user wants to create a new one */ - registerNodeType(type: string, base: { new (): LGraphNode }): void; - /** removes a node type from the system */ - unregisterNodeType(type: string): void; - /** Removes all previously registered node's types. */ - clearRegisteredTypes(): void; - /** - * Create a new node type by passing a function, it wraps it with a proper class and generates inputs according to the parameters of the function. - * Useful to wrap simple methods that do not require properties, and that only process some input to generate an output. - * @param name node name with namespace (p.e.: 'math/sum') - * @param func - * @param param_types an array containing the type of every parameter, otherwise parameters will accept any type - * @param return_type string with the return type, otherwise it will be generic - * @param properties properties to be configurable - */ - wrapFunctionAsNode( - name: string, - func: (...args: any[]) => any, - param_types?: string[], - return_type?: string, - properties?: object - ): void; - - /** - * Adds this method to all node types, existing and to be created - * (You can add it to LGraphNode.prototype but then existing node types wont have it) - */ - addNodeMethod(name: string, func: (...args: any[]) => any): void; - - /** - * Create a node of a given type with a name. The node is not attached to any graph yet. - * @param type full name of the node class. p.e. "math/sin" - * @param name a name to distinguish from other nodes - * @param options to set options - */ - createNode( - type: string, - title: string, - options: object - ): T; - - /** - * Returns a registered node type with a given name - * @param type full name of the node class. p.e. "math/sin" - */ - getNodeType(type: string): LGraphNodeConstructor; - - /** - * Returns a list of node types matching one category - * @method getNodeTypesInCategory - * @param {String} category category name - * @param {String} filter only nodes with ctor.filter equal can be shown - * @return {Array} array with all the node classes - */ - getNodeTypesInCategory( - category: string, - filter: string - ): LGraphNodeConstructor[]; - - /** - * Returns a list with all the node type categories - * @method getNodeTypesCategories - * @param {String} filter only nodes with ctor.filter equal can be shown - * @return {Array} array with all the names of the categories - */ - getNodeTypesCategories(filter: string): string[]; - - /** debug purposes: reloads all the js scripts that matches a wildcard */ - reloadNodes(folder_wildcard: string): void; - - getTime(): number; - LLink: typeof LLink; - LGraph: typeof LGraph; - DragAndScale: typeof DragAndScale; - compareObjects(a: object, b: object): boolean; - distance(a: Vector2, b: Vector2): number; - colorToString(c: string): string; - isInsideRectangle( - x: number, - y: number, - left: number, - top: number, - width: number, - height: number - ): boolean; - growBounding(bounding: Vector4, x: number, y: number): Vector4; - isInsideBounding(p: Vector2, bb: Vector4): boolean; - hex2num(hex: string): [number, number, number]; - num2hex(triplet: [number, number, number]): string; - ContextMenu: typeof ContextMenu; - extendClass(target: A, origin: B): A & B; - getParameterNames(func: string): string[]; -}; - -export type serializedLGraph< - TNode = ReturnType, - // https://github.com/jagenjo/litegraph.js/issues/74 - TLink = [number, number, number, number, number, string], - TGroup = ReturnType -> = { - last_node_id: LGraph["last_node_id"]; - last_link_id: LGraph["last_link_id"]; - nodes: TNode[]; - links: TLink[]; - groups: TGroup[]; - config: LGraph["config"]; - version: typeof LiteGraph.VERSION; -}; - -export declare class LGraph { - static supported_types: string[]; - static STATUS_STOPPED: 1; - static STATUS_RUNNING: 2; - - constructor(o?: object); - - filter: string; - catch_errors: boolean; - /** custom data */ - config: object; - elapsed_time: number; - fixedtime: number; - fixedtime_lapse: number; - globaltime: number; - inputs: any; - iteration: number; - last_link_id: number; - last_node_id: number; - last_update_time: number; - links: Record; - list_of_graphcanvas: LGraphCanvas[]; - outputs: any; - runningtime: number; - starttime: number; - status: typeof LGraph.STATUS_RUNNING | typeof LGraph.STATUS_STOPPED; - - private _nodes: LGraphNode[]; - private _groups: LGraphGroup[]; - private _nodes_by_id: Record; - /** nodes that are executable sorted in execution order */ - private _nodes_executable: - | (LGraphNode & { onExecute: NonNullable }[]) - | null; - /** nodes that contain onExecute */ - private _nodes_in_order: LGraphNode[]; - private _version: number; - - getSupportedTypes(): string[]; - /** Removes all nodes from this graph */ - clear(): void; - /** Attach Canvas to this graph */ - attachCanvas(graphCanvas: LGraphCanvas): void; - /** Detach Canvas to this graph */ - detachCanvas(graphCanvas: LGraphCanvas): void; - /** - * Starts running this graph every interval milliseconds. - * @param interval amount of milliseconds between executions, if 0 then it renders to the monitor refresh rate - */ - start(interval?: number): void; - /** Stops the execution loop of the graph */ - stop(): void; - /** - * Run N steps (cycles) of the graph - * @param num number of steps to run, default is 1 - */ - runStep(num?: number, do_not_catch_errors?: boolean): void; - /** - * Updates the graph execution order according to relevance of the nodes (nodes with only outputs have more relevance than - * nodes with only inputs. - */ - updateExecutionOrder(): void; - /** This is more internal, it computes the executable nodes in order and returns it */ - computeExecutionOrder(only_onExecute: boolean, set_level: any): T; - /** - * Returns all the nodes that could affect this one (ancestors) by crawling all the inputs recursively. - * It doesn't include the node itself - * @return an array with all the LGraphNodes that affect this node, in order of execution - */ - getAncestors(node: LGraphNode): LGraphNode[]; - /** - * Positions every node in a more readable manner - */ - arrange(margin?: number,layout?: string): void; - /** - * Returns the amount of time the graph has been running in milliseconds - * @return number of milliseconds the graph has been running - */ - getTime(): number; - - /** - * Returns the amount of time accumulated using the fixedtime_lapse var. This is used in context where the time increments should be constant - * @return number of milliseconds the graph has been running - */ - getFixedTime(): number; - - /** - * Returns the amount of time it took to compute the latest iteration. Take into account that this number could be not correct - * if the nodes are using graphical actions - * @return number of milliseconds it took the last cycle - */ - getElapsedTime(): number; - /** - * Sends an event to all the nodes, useful to trigger stuff - * @param eventName the name of the event (function to be called) - * @param params parameters in array format - */ - sendEventToAllNodes(eventName: string, params: any[], mode?: any): void; - - sendActionToCanvas(action: any, params: any[]): void; - /** - * Adds a new node instance to this graph - * @param node the instance of the node - */ - add(node: LGraphNode, skip_compute_order?: boolean): void; - /** - * Called when a new node is added - * @param node the instance of the node - */ - onNodeAdded(node: LGraphNode): void; - /** Removes a node from the graph */ - remove(node: LGraphNode): void; - /** Returns a node by its id. */ - getNodeById(id: number): LGraphNode | undefined; - /** - * Returns a list of nodes that matches a class - * @param classObject the class itself (not an string) - * @return a list with all the nodes of this type - */ - findNodesByClass( - classObject: LGraphNodeConstructor - ): T[]; - /** - * Returns a list of nodes that matches a type - * @param type the name of the node type - * @return a list with all the nodes of this type - */ - findNodesByType(type: string): T[]; - /** - * Returns the first node that matches a name in its title - * @param title the name of the node to search - * @return the node or null - */ - findNodeByTitle(title: string): T | null; - /** - * Returns a list of nodes that matches a name - * @param title the name of the node to search - * @return a list with all the nodes with this name - */ - findNodesByTitle(title: string): T[]; - /** - * Returns the top-most node in this position of the canvas - * @param x the x coordinate in canvas space - * @param y the y coordinate in canvas space - * @param nodes_list a list with all the nodes to search from, by default is all the nodes in the graph - * @return the node at this position or null - */ - getNodeOnPos( - x: number, - y: number, - node_list?: LGraphNode[], - margin?: number - ): T | null; - /** - * Returns the top-most group in that position - * @param x the x coordinate in canvas space - * @param y the y coordinate in canvas space - * @return the group or null - */ - getGroupOnPos(x: number, y: number): LGraphGroup | null; - - onAction(action: any, param: any): void; - trigger(action: any, param: any): void; - /** Tell this graph it has a global graph input of this type */ - addInput(name: string, type: string, value?: any): void; - /** Assign a data to the global graph input */ - setInputData(name: string, data: any): void; - /** Returns the current value of a global graph input */ - getInputData(name: string): T; - /** Changes the name of a global graph input */ - renameInput(old_name: string, name: string): false | undefined; - /** Changes the type of a global graph input */ - changeInputType(name: string, type: string): false | undefined; - /** Removes a global graph input */ - removeInput(name: string): boolean; - /** Creates a global graph output */ - addOutput(name: string, type: string, value: any): void; - /** Assign a data to the global output */ - setOutputData(name: string, value: string): void; - /** Returns the current value of a global graph output */ - getOutputData(name: string): T; - - /** Renames a global graph output */ - renameOutput(old_name: string, name: string): false | undefined; - /** Changes the type of a global graph output */ - changeOutputType(name: string, type: string): false | undefined; - /** Removes a global graph output */ - removeOutput(name: string): boolean; - triggerInput(name: string, value: any): void; - setCallback(name: string, func: (...args: any[]) => any): void; - beforeChange(info?: LGraphNode): void; - afterChange(info?: LGraphNode): void; - connectionChange(node: LGraphNode): void; - /** returns if the graph is in live mode */ - isLive(): boolean; - /** clears the triggered slot animation in all links (stop visual animation) */ - clearTriggeredSlots(): void; - /* Called when something visually changed (not the graph!) */ - change(): void; - setDirtyCanvas(fg: boolean, bg: boolean): void; - /** Destroys a link */ - removeLink(link_id: number): void; - /** Creates a Object containing all the info about this graph, it can be serialized */ - serialize(): T; - /** - * Configure a graph from a JSON string - * @param data configure a graph from a JSON string - * @returns if there was any error parsing - */ - configure(data: object, keep_old?: boolean): boolean | undefined; - load(url: string): void; -} - -export type SerializedLLink = [number, string, number, number, number, number]; -export declare class LLink { - id: number; - type: string; - origin_id: number; - origin_slot: number; - target_id: number; - target_slot: number; - constructor( - id: number, - type: string, - origin_id: number, - origin_slot: number, - target_id: number, - target_slot: number - ); - configure(o: LLink | SerializedLLink): void; - serialize(): SerializedLLink; -} - -export type SerializedLGraphNode = { - id: T["id"]; - type: T["type"]; - pos: T["pos"]; - size: T["size"]; - flags: T["flags"]; - mode: T["mode"]; - inputs: T["inputs"]; - outputs: T["outputs"]; - title: T["title"]; - properties: T["properties"]; - widgets_values?: IWidget["value"][]; -}; - -/** https://github.com/jagenjo/litegraph.js/blob/master/guides/README.md#lgraphnode */ -export declare class LGraphNode { - static title_color: string; - static title: string; - static type: null | string; - static widgets_up: boolean; - constructor(title?: string); - - title: string; - type: null | string; - size: Vector2; - graph: null | LGraph; - graph_version: number; - pos: Vector2; - is_selected: boolean; - mouseOver: boolean; - - id: number; - - //inputs available: array of inputs - inputs: INodeInputSlot[]; - outputs: INodeOutputSlot[]; - connections: any[]; - - //local data - properties: Record; - properties_info: any[]; - - flags: Partial<{ - collapsed: boolean - }>; - - color: string; - bgcolor: string; - boxcolor: string; - shape: - | typeof LiteGraph.BOX_SHAPE - | typeof LiteGraph.ROUND_SHAPE - | typeof LiteGraph.CIRCLE_SHAPE - | typeof LiteGraph.CARD_SHAPE - | typeof LiteGraph.ARROW_SHAPE; - - serialize_widgets: boolean; - skip_list: boolean; - - /** Used in `LGraphCanvas.onMenuNodeMode` */ - mode?: - | typeof LiteGraph.ON_EVENT - | typeof LiteGraph.ON_TRIGGER - | typeof LiteGraph.NEVER - | typeof LiteGraph.ALWAYS; - - /** If set to true widgets do not start after the slots */ - widgets_up: boolean; - /** widgets start at y distance from the top of the node */ - widgets_start_y: number; - /** if you render outside the node, it will be clipped */ - clip_area: boolean; - /** if set to false it wont be resizable with the mouse */ - resizable: boolean; - /** slots are distributed horizontally */ - horizontal: boolean; - /** if true, the node will show the bgcolor as 'red' */ - has_errors?: boolean; - - /** configure a node from an object containing the serialized info */ - configure(info: SerializedLGraphNode): void; - /** serialize the content */ - serialize(): SerializedLGraphNode; - /** Creates a clone of this node */ - clone(): this; - /** serialize and stringify */ - toString(): string; - /** get the title string */ - getTitle(): string; - /** sets the value of a property */ - setProperty(name: string, value: any): void; - /** sets the output data */ - setOutputData(slot: number, data: any): void; - /** sets the output data */ - setOutputDataType(slot: number, type: string): void; - /** - * Retrieves the input data (data traveling through the connection) from one slot - * @param slot - * @param force_update if set to true it will force the connected node of this slot to output data into this link - * @return data or if it is not connected returns undefined - */ - getInputData(slot: number, force_update?: boolean): T; - /** - * Retrieves the input data type (in case this supports multiple input types) - * @param slot - * @return datatype in string format - */ - getInputDataType(slot: number): string; - /** - * Retrieves the input data from one slot using its name instead of slot number - * @param slot_name - * @param force_update if set to true it will force the connected node of this slot to output data into this link - * @return data or if it is not connected returns null - */ - getInputDataByName(slot_name: string, force_update?: boolean): T; - /** tells you if there is a connection in one input slot */ - isInputConnected(slot: number): boolean; - /** tells you info about an input connection (which node, type, etc) */ - getInputInfo( - slot: number - ): { link: number; name: string; type: string | 0 } | null; - /** returns the node connected in the input slot */ - getInputNode(slot: number): LGraphNode | null; - /** returns the value of an input with this name, otherwise checks if there is a property with that name */ - getInputOrProperty(name: string): T; - /** tells you the last output data that went in that slot */ - getOutputData(slot: number): T | null; - /** tells you info about an output connection (which node, type, etc) */ - getOutputInfo( - slot: number - ): { name: string; type: string; links: number[] } | null; - /** tells you if there is a connection in one output slot */ - isOutputConnected(slot: number): boolean; - /** tells you if there is any connection in the output slots */ - isAnyOutputConnected(): boolean; - /** retrieves all the nodes connected to this output slot */ - getOutputNodes(slot: number): LGraphNode[]; - /** Triggers an event in this node, this will trigger any output with the same name */ - trigger(action: string, param: any): void; - /** - * Triggers an slot event in this node - * @param slot the index of the output slot - * @param param - * @param link_id in case you want to trigger and specific output link in a slot - */ - triggerSlot(slot: number, param: any, link_id?: number): void; - /** - * clears the trigger slot animation - * @param slot the index of the output slot - * @param link_id in case you want to trigger and specific output link in a slot - */ - clearTriggeredSlot(slot: number, link_id?: number): void; - /** - * add a new property to this node - * @param name - * @param default_value - * @param type string defining the output type ("vec3","number",...) - * @param extra_info this can be used to have special properties of the property (like values, etc) - */ - addProperty( - name: string, - default_value: any, - type: string, - extra_info?: object - ): T; - /** - * add a new output slot to use in this node - * @param name - * @param type string defining the output type ("vec3","number",...) - * @param extra_info this can be used to have special properties of an output (label, special color, position, etc) - */ - addOutput( - name: string, - type: string | -1, - extra_info?: Partial - ): INodeOutputSlot; - /** - * add a new output slot to use in this node - * @param array of triplets like [[name,type,extra_info],[...]] - */ - addOutputs( - array: [string, string | -1, Partial | undefined][] - ): void; - /** remove an existing output slot */ - removeOutput(slot: number): void; - /** - * add a new input slot to use in this node - * @param name - * @param type string defining the input type ("vec3","number",...), it its a generic one use 0 - * @param extra_info this can be used to have special properties of an input (label, color, position, etc) - */ - addInput( - name: string, - type: string | -1, - extra_info?: Partial - ): INodeInputSlot; - /** - * add several new input slots in this node - * @param array of triplets like [[name,type,extra_info],[...]] - */ - addInputs( - array: [string, string | -1, Partial | undefined][] - ): void; - /** remove an existing input slot */ - removeInput(slot: number): void; - /** - * add an special connection to this node (used for special kinds of graphs) - * @param name - * @param type string defining the input type ("vec3","number",...) - * @param pos position of the connection inside the node - * @param direction if is input or output - */ - addConnection( - name: string, - type: string, - pos: Vector2, - direction: string - ): { - name: string; - type: string; - pos: Vector2; - direction: string; - links: null; - }; - setValue(v: any): void; - /** computes the size of a node according to its inputs and output slots */ - computeSize(): [number, number]; - /** - * https://github.com/jagenjo/litegraph.js/blob/master/guides/README.md#node-widgets - * @return created widget - */ - addWidget( - type: T["type"], - name: string, - value: T["value"], - callback?: WidgetCallback | string, - options?: T["options"] - ): T; - - addCustomWidget(customWidget: T): T; - - /** - * returns the bounding of the object, used for rendering purposes - * @return [x, y, width, height] - */ - getBounding(): Vector4; - /** checks if a point is inside the shape of a node */ - isPointInside( - x: number, - y: number, - margin?: number, - skipTitle?: boolean - ): boolean; - /** checks if a point is inside a node slot, and returns info about which slot */ - getSlotInPosition( - x: number, - y: number - ): { - input?: INodeInputSlot; - output?: INodeOutputSlot; - slot: number; - link_pos: Vector2; - }; - /** - * returns the input slot with a given name (used for dynamic slots), -1 if not found - * @param name the name of the slot - * @return the slot (-1 if not found) - */ - findInputSlot(name: string): number; - /** - * returns the output slot with a given name (used for dynamic slots), -1 if not found - * @param name the name of the slot - * @return the slot (-1 if not found) - */ - findOutputSlot(name: string): number; - /** - * connect this node output to the input of another node - * @param slot (could be the number of the slot or the string with the name of the slot) - * @param targetNode the target node - * @param targetSlot 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 {Object} the link_info is created, otherwise null - */ - connect( - slot: number | string, - targetNode: LGraphNode, - targetSlot: number | string - ): T | null; - /** - * disconnect one output to an specific node - * @param slot (could be the number of the slot or the string with the name of the slot) - * @param target_node the target node to which this slot is connected [Optional, if not target_node is specified all nodes will be disconnected] - * @return if it was disconnected successfully - */ - disconnectOutput(slot: number | string, targetNode?: LGraphNode): boolean; - /** - * disconnect one input - * @param slot (could be the number of the slot or the string with the name of the slot) - * @return if it was disconnected successfully - */ - disconnectInput(slot: number | string): boolean; - /** - * returns the center of a connection point in canvas coords - * @param is_input true if if a input slot, false if it is an output - * @param slot (could be the number of the slot or the string with the name of the slot) - * @param out a place to store the output, to free garbage - * @return the position - **/ - getConnectionPos( - is_input: boolean, - slot: number | string, - out?: Vector2 - ): Vector2; - /** Force align to grid */ - alignToGrid(): void; - /** Console output */ - trace(msg: string): void; - /** Forces to redraw or the main canvas (LGraphNode) or the bg canvas (links) */ - setDirtyCanvas(fg: boolean, bg: boolean): void; - loadImage(url: string): void; - /** Allows to get onMouseMove and onMouseUp events even if the mouse is out of focus */ - captureInput(v: any): void; - /** Collapse the node to make it smaller on the canvas */ - collapse(force: boolean): void; - /** Forces the node to do not move or realign on Z */ - pin(v?: boolean): void; - localToScreen(x: number, y: number, graphCanvas: LGraphCanvas): Vector2; - - // https://github.com/jagenjo/litegraph.js/blob/master/guides/README.md#custom-node-appearance - onDrawBackground?( - ctx: CanvasRenderingContext2D, - canvas: HTMLCanvasElement - ): void; - onDrawForeground?( - ctx: CanvasRenderingContext2D, - canvas: HTMLCanvasElement - ): void; - - // https://github.com/jagenjo/litegraph.js/blob/master/guides/README.md#custom-node-behaviour - onMouseDown?( - event: MouseEvent, - pos: Vector2, - graphCanvas: LGraphCanvas - ): void; - onMouseMove?( - event: MouseEvent, - pos: Vector2, - graphCanvas: LGraphCanvas - ): void; - onMouseUp?( - event: MouseEvent, - pos: Vector2, - graphCanvas: LGraphCanvas - ): void; - onMouseEnter?( - event: MouseEvent, - pos: Vector2, - graphCanvas: LGraphCanvas - ): void; - onMouseLeave?( - event: MouseEvent, - pos: Vector2, - graphCanvas: LGraphCanvas - ): void; - onKey?(event: KeyboardEvent, pos: Vector2, graphCanvas: LGraphCanvas): void; - - /** Called by `LGraphCanvas.selectNodes` */ - onSelected?(): void; - /** Called by `LGraphCanvas.deselectNode` */ - onDeselected?(): void; - /** Called by `LGraph.runStep` `LGraphNode.getInputData` */ - onExecute?(): void; - /** Called by `LGraph.serialize` */ - onSerialize?(o: SerializedLGraphNode): void; - /** Called by `LGraph.configure` */ - onConfigure?(o: SerializedLGraphNode): void; - /** - * when added to graph (warning: this is called BEFORE the node is configured when loading) - * Called by `LGraph.add` - */ - onAdded?(graph: LGraph): void; - /** - * when removed from graph - * Called by `LGraph.remove` `LGraph.clear` - */ - onRemoved?(): void; - /** - * if returns false the incoming connection will be canceled - * Called by `LGraph.connect` - * @param inputIndex target input slot number - * @param outputType type of output slot - * @param outputSlot output slot object - * @param outputNode node containing the output - * @param outputIndex index of output slot - */ - onConnectInput?( - inputIndex: number, - outputType: INodeOutputSlot["type"], - outputSlot: INodeOutputSlot, - outputNode: LGraphNode, - outputIndex: number - ): boolean; - /** - * if returns false the incoming connection will be canceled - * Called by `LGraph.connect` - * @param outputIndex target output slot number - * @param inputType type of input slot - * @param inputSlot input slot object - * @param inputNode node containing the input - * @param inputIndex index of input slot - */ - onConnectOutput?( - outputIndex: number, - inputType: INodeInputSlot["type"], - inputSlot: INodeInputSlot, - inputNode: LGraphNode, - inputIndex: number - ): boolean; - - /** - * Called just before connection (or disconnect - if input is linked). - * A convenient place to switch to another input, or create new one. - * This allow for ability to automatically add slots if needed - * @param inputIndex - * @return selected input slot index, can differ from parameter value - */ - onBeforeConnectInput?( - inputIndex: number - ): number; - - /** a connection changed (new one or removed) (LiteGraph.INPUT or LiteGraph.OUTPUT, slot, true if connected, link_info, input_info or output_info ) */ - onConnectionsChange( - type: number, - slotIndex: number, - isConnected: boolean, - link: LLink, - ioSlot: (INodeOutputSlot | INodeInputSlot) - ): void; - - /** - * if returns false, will abort the `LGraphNode.setProperty` - * Called when a property is changed - * @param property - * @param value - * @param prevValue - */ - onPropertyChanged?(property: string, value: any, prevValue: any): void | boolean; - - /** Called by `LGraphCanvas.processContextMenu` */ - getMenuOptions?(graphCanvas: LGraphCanvas): ContextMenuItem[]; - getSlotMenuOptions?(slot: INodeSlot): ContextMenuItem[]; -} - -export type LGraphNodeConstructor = { - new (): T; -}; - -export type SerializedLGraphGroup = { - title: LGraphGroup["title"]; - bounding: LGraphGroup["_bounding"]; - color: LGraphGroup["color"]; - font: LGraphGroup["font"]; -}; -export declare class LGraphGroup { - title: string; - private _bounding: Vector4; - color: string; - font: string; - - configure(o: SerializedLGraphGroup): void; - serialize(): SerializedLGraphGroup; - move(deltaX: number, deltaY: number, ignoreNodes?: boolean): void; - recomputeInsideNodes(): void; - isPointInside: LGraphNode["isPointInside"]; - setDirtyCanvas: LGraphNode["setDirtyCanvas"]; -} - -export declare class DragAndScale { - constructor(element?: HTMLElement, skipEvents?: boolean); - offset: [number, number]; - scale: number; - max_scale: number; - min_scale: number; - onredraw: Function | null; - enabled: boolean; - last_mouse: Vector2; - element: HTMLElement | null; - visible_area: Vector4; - bindEvents(element: HTMLElement): void; - computeVisibleArea(): void; - onMouse(e: MouseEvent): void; - toCanvasContext(ctx: CanvasRenderingContext2D): void; - convertOffsetToCanvas(pos: Vector2): Vector2; - convertCanvasToOffset(pos: Vector2): Vector2; - mouseDrag(x: number, y: number): void; - changeScale(value: number, zooming_center?: Vector2): void; - changeDeltaScale(value: number, zooming_center?: Vector2): void; - reset(): void; -} - -/** - * This class is in charge of rendering one graph inside a canvas. And provides all the interaction required. - * Valid callbacks are: onNodeSelected, onNodeDeselected, onShowNodePanel, onNodeDblClicked - * - * @param canvas the canvas where you want to render (it accepts a selector in string format or the canvas element itself) - * @param graph - * @param options { skip_rendering, autoresize } - */ -export declare class LGraphCanvas { - static node_colors: Record< - string, - { - color: string; - bgcolor: string; - groupcolor: string; - } - >; - static link_type_colors: Record; - static gradients: object; - static search_limit: number; - - static getFileExtension(url: string): string; - static decodeHTML(str: string): string; - - static onMenuCollapseAll(): void; - static onMenuNodeEdit(): void; - static onShowPropertyEditor( - item: any, - options: any, - e: any, - menu: any, - node: any - ): void; - /** Create menu for `Add Group` */ - static onGroupAdd: ContextMenuEventListener; - /** Create menu for `Add Node` */ - static onMenuAdd: ContextMenuEventListener; - static showMenuNodeOptionalInputs: ContextMenuEventListener; - static showMenuNodeOptionalOutputs: ContextMenuEventListener; - static onShowMenuNodeProperties: ContextMenuEventListener; - static onResizeNode: ContextMenuEventListener; - static onMenuNodeCollapse: ContextMenuEventListener; - static onMenuNodePin: ContextMenuEventListener; - static onMenuNodeMode: ContextMenuEventListener; - static onMenuNodeColors: ContextMenuEventListener; - static onMenuNodeShapes: ContextMenuEventListener; - static onMenuNodeRemove: ContextMenuEventListener; - static onMenuNodeClone: ContextMenuEventListener; - - constructor( - canvas: HTMLCanvasElement | string, - graph?: LGraph, - options?: { - skip_render?: boolean; - autoresize?: boolean; - } - ); - - static active_canvas: HTMLCanvasElement; - - allow_dragcanvas: boolean; - allow_dragnodes: boolean; - /** allow to control widgets, buttons, collapse, etc */ - allow_interaction: boolean; - /** allows to change a connection with having to redo it again */ - allow_reconnect_links: boolean; - /** allow selecting multi nodes without pressing extra keys */ - multi_select: boolean; - /** No effect */ - allow_searchbox: boolean; - always_render_background: boolean; - autoresize?: boolean; - background_image: string; - bgcanvas: HTMLCanvasElement; - bgctx: CanvasRenderingContext2D; - canvas: HTMLCanvasElement; - canvas_mouse: Vector2; - clear_background: boolean; - connecting_node: LGraphNode | null; - connections_width: number; - ctx: CanvasRenderingContext2D; - current_node: LGraphNode | null; - default_connection_color: { - input_off: string; - input_on: string; - output_off: string; - output_on: string; - }; - default_link_color: string; - dirty_area: Vector4 | null; - dirty_bgcanvas?: boolean; - dirty_canvas?: boolean; - drag_mode: boolean; - dragging_canvas: boolean; - dragging_rectangle: Vector4 | null; - ds: DragAndScale; - /** used for transition */ - editor_alpha: number; - filter: any; - fps: number; - frame: number; - graph: LGraph; - highlighted_links: Record; - highquality_render: boolean; - inner_text_font: string; - is_rendering: boolean; - last_draw_time: number; - last_mouse: Vector2; - /** - * Possible duplicated with `last_mouse` - * https://github.com/jagenjo/litegraph.js/issues/70 - */ - last_mouse_position: Vector2; - /** Timestamp of last mouse click, defaults to 0 */ - last_mouseclick: number; - links_render_mode: - | typeof LiteGraph.STRAIGHT_LINK - | typeof LiteGraph.LINEAR_LINK - | typeof LiteGraph.SPLINE_LINK; - live_mode: boolean; - node_capturing_input: LGraphNode | null; - node_dragged: LGraphNode | null; - node_in_panel: LGraphNode | null; - node_over: LGraphNode | null; - node_title_color: string; - node_widget: [LGraphNode, IWidget] | null; - /** Called by `LGraphCanvas.drawBackCanvas` */ - onDrawBackground: - | ((ctx: CanvasRenderingContext2D, visibleArea: Vector4) => void) - | null; - /** Called by `LGraphCanvas.drawFrontCanvas` */ - onDrawForeground: - | ((ctx: CanvasRenderingContext2D, visibleArea: Vector4) => void) - | null; - onDrawOverlay: ((ctx: CanvasRenderingContext2D) => void) | null; - /** Called by `LGraphCanvas.processMouseDown` */ - onMouse: ((event: MouseEvent) => boolean) | null; - /** Called by `LGraphCanvas.drawFrontCanvas` and `LGraphCanvas.drawLinkTooltip` */ - onDrawLinkTooltip: ((ctx: CanvasRenderingContext2D, link: LLink, _this: this) => void) | null; - /** Called by `LGraphCanvas.selectNodes` */ - onNodeMoved: ((node: LGraphNode) => void) | null; - /** Called by `LGraphCanvas.processNodeSelected` */ - onNodeSelected: ((node: LGraphNode) => void) | null; - /** Called by `LGraphCanvas.deselectNode` */ - onNodeDeselected: ((node: LGraphNode) => void) | null; - /** Called by `LGraphCanvas.processNodeDblClicked` */ - onShowNodePanel: ((node: LGraphNode) => void) | null; - /** Called by `LGraphCanvas.processNodeDblClicked` */ - onNodeDblClicked: ((node: LGraphNode) => void) | null; - /** Called by `LGraphCanvas.selectNodes` */ - onSelectionChange: ((nodes: Record) => void) | null; - /** Called by `LGraphCanvas.showSearchBox` */ - onSearchBox: - | (( - helper: Element, - value: string, - graphCanvas: LGraphCanvas - ) => string[]) - | null; - onSearchBoxSelection: - | ((name: string, event: MouseEvent, graphCanvas: LGraphCanvas) => void) - | null; - pause_rendering: boolean; - render_canvas_border: boolean; - render_collapsed_slots: boolean; - render_connection_arrows: boolean; - render_connections_border: boolean; - render_connections_shadows: boolean; - render_curved_connections: boolean; - render_execution_order: boolean; - render_only_selected: boolean; - render_shadows: boolean; - render_title_colored: boolean; - round_radius: number; - selected_group: null | LGraphGroup; - selected_group_resizing: boolean; - selected_nodes: Record; - show_info: boolean; - title_text_font: string; - /** set to true to render title bar with gradients */ - use_gradients: boolean; - visible_area: DragAndScale["visible_area"]; - visible_links: LLink[]; - visible_nodes: LGraphNode[]; - zoom_modify_alpha: boolean; - - /** clears all the data inside */ - clear(): void; - /** assigns a graph, you can reassign graphs to the same canvas */ - setGraph(graph: LGraph, skipClear?: boolean): void; - /** opens a graph contained inside a node in the current graph */ - openSubgraph(graph: LGraph): void; - /** closes a subgraph contained inside a node */ - closeSubgraph(): void; - /** assigns a canvas */ - setCanvas(canvas: HTMLCanvasElement, skipEvents?: boolean): void; - /** binds mouse, keyboard, touch and drag events to the canvas */ - bindEvents(): void; - /** unbinds mouse events from the canvas */ - unbindEvents(): void; - - /** - * this function allows to render the canvas using WebGL instead of Canvas2D - * this is useful if you plant to render 3D objects inside your nodes, it uses litegl.js for webgl and canvas2DtoWebGL to emulate the Canvas2D calls in webGL - **/ - enableWebGL(): void; - - /** - * marks as dirty the canvas, this way it will be rendered again - * @param fg if the foreground canvas is dirty (the one containing the nodes) - * @param bg if the background canvas is dirty (the one containing the wires) - */ - setDirty(fg: boolean, bg: boolean): void; - - /** - * Used to attach the canvas in a popup - * @return the window where the canvas is attached (the DOM root node) - */ - getCanvasWindow(): Window; - /** starts rendering the content of the canvas when needed */ - startRendering(): void; - /** stops rendering the content of the canvas (to save resources) */ - stopRendering(): void; - - processMouseDown(e: MouseEvent): boolean | undefined; - processMouseMove(e: MouseEvent): boolean | undefined; - processMouseUp(e: MouseEvent): boolean | undefined; - processMouseWheel(e: MouseEvent): boolean | undefined; - - /** returns true if a position (in graph space) is on top of a node little corner box */ - isOverNodeBox(node: LGraphNode, canvasX: number, canvasY: number): boolean; - /** returns true if a position (in graph space) is on top of a node input slot */ - isOverNodeInput( - node: LGraphNode, - canvasX: number, - canvasY: number, - slotPos: Vector2 - ): boolean; - - /** process a key event */ - processKey(e: KeyboardEvent): boolean | undefined; - - copyToClipboard(): void; - pasteFromClipboard(): void; - processDrop(e: DragEvent): void; - checkDropItem(e: DragEvent): void; - processNodeDblClicked(n: LGraphNode): void; - processNodeSelected(n: LGraphNode, e: MouseEvent): void; - processNodeDeselected(node: LGraphNode): void; - - /** selects a given node (or adds it to the current selection) */ - selectNode(node: LGraphNode, add?: boolean): void; - /** selects several nodes (or adds them to the current selection) */ - selectNodes(nodes?: LGraphNode[], add?: boolean): void; - /** removes a node from the current selection */ - deselectNode(node: LGraphNode): void; - /** removes all nodes from the current selection */ - deselectAllNodes(): void; - /** deletes all nodes in the current selection from the graph */ - deleteSelectedNodes(): void; - - /** centers the camera on a given node */ - centerOnNode(node: LGraphNode): void; - /** changes the zoom level of the graph (default is 1), you can pass also a place used to pivot the zoom */ - setZoom(value: number, center: Vector2): void; - /** brings a node to front (above all other nodes) */ - bringToFront(node: LGraphNode): void; - /** sends a node to the back (below all other nodes) */ - sendToBack(node: LGraphNode): void; - /** checks which nodes are visible (inside the camera area) */ - computeVisibleNodes(nodes: LGraphNode[]): LGraphNode[]; - /** renders the whole canvas content, by rendering in two separated canvas, one containing the background grid and the connections, and one containing the nodes) */ - draw(forceFG?: boolean, forceBG?: boolean): void; - /** draws the front canvas (the one containing all the nodes) */ - drawFrontCanvas(): void; - /** draws some useful stats in the corner of the canvas */ - renderInfo(ctx: CanvasRenderingContext2D, x: number, y: number): void; - /** draws the back canvas (the one containing the background and the connections) */ - drawBackCanvas(): void; - /** draws the given node inside the canvas */ - drawNode(node: LGraphNode, ctx: CanvasRenderingContext2D): void; - /** draws graphic for node's slot */ - drawSlotGraphic(ctx: CanvasRenderingContext2D, pos: number[], shape: SlotShape, horizontal: boolean): void; - /** draws the shape of the given node in the canvas */ - drawNodeShape( - node: LGraphNode, - ctx: CanvasRenderingContext2D, - size: [number, number], - fgColor: string, - bgColor: string, - selected: boolean, - mouseOver: boolean - ): void; - /** draws every connection visible in the canvas */ - drawConnections(ctx: CanvasRenderingContext2D): void; - /** - * draws a link between two points - * @param a start pos - * @param b end pos - * @param link the link object with all the link info - * @param skipBorder ignore the shadow of the link - * @param flow show flow animation (for events) - * @param color the color for the link - * @param startDir the direction enum - * @param endDir the direction enum - * @param numSublines number of sublines (useful to represent vec3 or rgb) - **/ - renderLink( - a: Vector2, - b: Vector2, - link: object, - skipBorder: boolean, - flow: boolean, - color?: string, - startDir?: number, - endDir?: number, - numSublines?: number - ): void; - - computeConnectionPoint( - a: Vector2, - b: Vector2, - t: number, - startDir?: number, - endDir?: number - ): void; - - drawExecutionOrder(ctx: CanvasRenderingContext2D): void; - /** draws the widgets stored inside a node */ - drawNodeWidgets( - node: LGraphNode, - posY: number, - ctx: CanvasRenderingContext2D, - activeWidget: object - ): void; - /** process an event on widgets */ - processNodeWidgets( - node: LGraphNode, - pos: Vector2, - event: Event, - activeWidget: object - ): void; - /** draws every group area in the background */ - drawGroups(canvas: any, ctx: CanvasRenderingContext2D): void; - adjustNodesSize(): void; - /** resizes the canvas to a given size, if no size is passed, then it tries to fill the parentNode */ - resize(width?: number, height?: number): void; - /** - * switches to live mode (node shapes are not rendered, only the content) - * this feature was designed when graphs where meant to create user interfaces - **/ - switchLiveMode(transition?: boolean): void; - onNodeSelectionChange(): void; - touchHandler(event: TouchEvent): void; - - showLinkMenu(link: LLink, e: any): false; - prompt( - title: string, - value: any, - callback: Function, - event: any - ): HTMLDivElement; - showSearchBox(event?: MouseEvent): void; - showEditPropertyValue(node: LGraphNode, property: any, options: any): void; - createDialog( - html: string, - options?: { position?: Vector2; event?: MouseEvent } - ): void; - - convertOffsetToCanvas: DragAndScale["convertOffsetToCanvas"]; - convertCanvasToOffset: DragAndScale["convertCanvasToOffset"]; - /** converts event coordinates from canvas2D to graph coordinates */ - convertEventToCanvasOffset(e: MouseEvent): Vector2; - /** adds some useful properties to a mouse event, like the position in graph coordinates */ - adjustMouseEvent(e: MouseEvent): void; - - getCanvasMenuOptions(): ContextMenuItem[]; - getNodeMenuOptions(node: LGraphNode): ContextMenuItem[]; - getGroupMenuOptions(): ContextMenuItem[]; - /** Called by `getCanvasMenuOptions`, replace default options */ - getMenuOptions?(): ContextMenuItem[]; - /** Called by `getCanvasMenuOptions`, append to default options */ - getExtraMenuOptions?(): ContextMenuItem[]; - /** Called when mouse right click */ - processContextMenu(node: LGraphNode, event: Event): void; -} - -declare class ContextMenu { - static trigger( - element: HTMLElement, - event_name: string, - params: any, - origin: any - ): void; - static isCursorOverElement(event: MouseEvent, element: HTMLElement): void; - static closeAllContextMenus(window: Window): void; - constructor(values: ContextMenuItem[], options?: IContextMenuOptions, window?: Window); - options: IContextMenuOptions; - parentMenu?: ContextMenu; - lock: boolean; - current_submenu?: ContextMenu; - addItem( - name: string, - value: ContextMenuItem, - options?: IContextMenuOptions - ): void; - close(e?: MouseEvent, ignore_parent_menu?: boolean): void; - getTopMenu(): void; - getFirstEvent(): void; -} - -declare global { - interface CanvasRenderingContext2D { - /** like rect but rounded corners */ - roundRect( - x: number, - y: number, - width: number, - height: number, - radius: number, - radiusLow: number - ): void; - } - - interface Math { - clamp(v: number, min: number, max: number): number; - } -} diff --git a/examples/editing/litegraphScripts.ts b/examples/editing/litegraphScripts.ts deleted file mode 100644 index e30e3dea..00000000 --- a/examples/editing/litegraphScripts.ts +++ /dev/null @@ -1,670 +0,0 @@ -import {ConnectionInfo, EventHandler, Graph, GraphNode, - GraphNodeProperties, Listener, WorkerInfo, getCallbackFromString, - wchtmlloader -} from '../../index' -import { replaceListenerArg } from './listenerManip'; - -import { LiteGraph, LGraph, LGraphCanvas, LGraphNode} from './litegraph.js' - -export type LGraphNodeProps = { - __renderHTML?:boolean, //do we want to visualize elements inside the node or on a blank page area (like a typical document vs in-editor) Make this toggle between where it renders in the page/editor - __widget?:{ - //we can use the built-in widgets and/or we can renderHtml, just figure out how to access the html to set them next to each other somehow - } - __position?:{ - //will be set by default otherwise based on proximity to connections - } -} & GraphNodeProperties; - -export type LGraphNodeM = LGraphNode & { - triggers:any, - __node:GraphNode, - __graph:Graph, - __unique:string,//GraphNode unique Id for event lookup - editor:LGraph, tag:string, key?:string, - subs:{[key:string]:{ sub:number, listener:Listener }} - __settings?:{ - mode?:'nodeMethod' //default, a node just runs a function method or a getter for a variable - | 'nodeInstance' //alternatively, we can break out several variables on node - | 'subGraph', //or this is a node on a subgraph for a node, so implicitly all variable are "this", i.e. for internal listeners to states for containing logic (ala blueprints) - - nodeOutputs?:string[], - [key:string]:any - }, - - firstConnect:boolean //internal -} - - -const execPin = '►'; //for modded litegraph - -//https://stackoverflow.com/questions/9091838/get-function-parameter-names-for-interface-purposes -export function getFnParamNames(fn){ - if(typeof fn !== 'string') fn = fn.toString(); - const arrowMatch = fn.match(/\(?[^]*?\)?\s*=>/) - if (arrowMatch) return arrowMatch[0].replace(/[()\s]/gi,'').replace('=>','').split(',') - const match = fn.match(/\([^]*?\)/) - return match ? match[0].replace(/[()\s]/gi,'').split(',') : [] -} - - -export let registered = new Map(); -export let created = new Map(); - -export function addNodeToLGraph(node, graph, editor:LGraph) { - let roots = graph.__node.roots; - let hasNode = registered.get(node.__node.tag) as LGraphNodeM; - if (!hasNode) { - registerNode(node, roots[node.__node.tag],undefined,editor); - for(const key in node) { - if(key !== 'get' && !key.startsWith('__')) - registerNode(node, roots[node.__node.tag], key, editor); - } - - } -} - -export function registerLGraphNodesFromGraph(graph:Graph, editor:LGraph) { - graph.__node.nodes.forEach((node) => { - addNodeToLGraph(node,graph, editor); - }); -} - -//the positioning stuff is incorrect (I broke it then forgot what it did) -export const updateNodePosition = (current, sourceNode, lastNode) => { - const previous = lastNode ? lastNode : sourceNode; - const [ x, y ] = previous.pos; - const [ width, height ] = previous.size; - - current.pos = [x + width + 50, y + height + 50]; // Update position at the end -} - -//fix!!! -export function updateArgNodePosition (target, nodes, lastNode) { - - const [ targetX ] = lastNode ? lastNode.pos : target.pos - const [ targetWidth ] = lastNode ? lastNode.size : target.size - - nodes.forEach((n:LGraphNodeM) => { - const [ _, y ] = n.pos - const [ __, height ] = n.size - - //let bb = n.getBounding(); //include bounding box? - - n.pos = [targetX - targetWidth - 50, y + height + 50]; - }); -} - -export function createNode(name:string, LGraph:LGraph, duplicate = false) { - const got = created.get(name); - if (!duplicate && got) return got as LGraphNodeM; - const node = LiteGraph.createNode(name); - created.set(name, node as LGraphNodeM) - LGraph.add(node); - return node as LGraphNodeM; -} - - - - -export function renderLGraphFromExistingEvents( - listeners:EventHandler['triggers'], - LGraph:LGraph -) { - - let minY = 0; - let lastNode; - for(const key in listeners) { - let tarr = listeners[key] as any as Listener[]; - let nodes = [] as any[]; - for(const trigger of tarr) { - //console.log(trigger); - if(!trigger.tkey) continue; - //create each node in the arg stack if exists, connect by arg position, exec pins only at listener level - - const name = trigger.tkey ? trigger.target+'.'+trigger.tkey : trigger.target as string; - let node = createNode(name,LGraph,true); - let srcname = trigger.key ? trigger.source+'.'+trigger.key : trigger.source as string; - - let hasNode = created.get(srcname); - let srcnode = createNode(srcname, LGraph, false); - - - //console.log(name,node,srcname,srcnode); - - updateNodePosition(node, srcnode, lastNode); - lastNode = hasNode; - - if(!hasNode) { - srcnode.pos[1] = minY + 25; - } - - node.pos[0] = srcnode.pos[0] + 50; - if(minY > node.pos[1]) node.pos[1] = minY + 50; - else node.pos[1] = srcnode.pos[1] + 50; - minY = node.pos[1]; - - //set x and y offset - - if(trigger.__args) { - let lastargnode; - const iterateArg = (arg, node, i) => { - if(typeof arg === 'object') { - let cb = arg.__callback ? arg.__callback : arg.__input; - if(cb) { - let argnode = createNode(cb as string,LGraph, true); - argnode.connect(1, node, i); //todo: several argument slots? - if(arg.__args) { - let argnodes = [] as any[]; - arg.__args.forEach((a,j) => { - argnodes.push(iterateArg(a,argnode,j+1)); - }); - if(argnodes.length > 0) { - updateArgNodePosition(argnode, argnodes, lastargnode); - argnodes.forEach((n) => { - if(minY > n.pos[1]) minY = n.pos[1]; - }); - } - } - lastargnode = argnode; - return argnode; - } - } else if (typeof arg === 'string') { - let argnode = createNode(arg, LGraph, true); - argnode.connect(1, node, i); //todo: several argument slots? - lastargnode = argnode; - return argnode; - } - } - - let argnodes = [] as any[]; - trigger.__args.forEach((arg,i) => { - argnodes.push(iterateArg(arg,node,i+1)); - }); - - if(argnodes.length > 0) { - updateArgNodePosition(node, argnodes, lastargnode); - argnodes.forEach((n) => { - if(minY > n.pos[1]) minY = n.pos[1]; - }); - } - } - - srcnode.connect(0,node,0); - node.subs[Object.keys(node.subs).length] = { sub:trigger.sub, listener:trigger }; - nodes.push(node); - } - for(const node of nodes) { - node.firstConnect = false; //future connections will trigger the subscription swapping - } - } -} - - //creates a new nested arg array from visual connections -const getArgsFromNode = (editor:LGraph, - currentOutputNode:LGraphNodeM, args=[] as any[], previousNode?:LGraphNodeM, curDepth = 0, wasAdded = {} //prevent circular infinite looping -) => { - currentOutputNode.inputs.forEach((inp,i) => { - if(i>0) { //don't use first slot, which we labeled as an exec pin - if(inp.link) { //all arg inputs only have one link (not the case for exec links which may have .extraLinks) - if(editor) { - let link = editor.links[inp.link]; - let inputNodei = editor.getNodeById(link.origin_id); - let origin = link.origin_slot; - if(inputNodei) { - if(inputNodei.outputs[origin].name === 'Get') { - args[i - 1] = inputNodei.title; //the title is the node or method key - //stop it here - } else { - args[i - 1] = { __callback:inputNodei.title }; - curDepth++; - if(wasAdded[link.origin_id]) { //prevent infinite recursion - args[i - 1].__args[i-1] = wasAdded[link.origin_id]; - } else { //go get em otherwise - inputNodei.inputs.forEach((inpj, j) => { - if(j > 0) { - if(inpj.link) { - if(!args[i-1].__args) { - args[i-1].__args = []; - wasAdded[link.origin_id] = args[i - 1].__args; - } - let linkj = editor.links[inpj.link]; - let inputNodej = editor.getNodeById(linkj.origin_id); - let originj = linkj.origin_slot; - if(inputNodej) { - args[i - 1].__args = getArgsFromNode( - editor, - inputNodej as LGraphNodeM, - args[i - 1].__args, - inputNodei as LGraphNodeM, - curDepth, - wasAdded - ); - } - } - } - }); - } - } - } - } - } else args[i-1] = undefined; - } - }); - - return args; -} - - -const checkNodeForSubscriptionUpdate = ( - self:LGraphNodeM, editor:LGraph, inputIndex, outputType, outputSlot, outputNode, outputIndex -) => { - - let execChanged = false; //do we need to update subscriptions? - - if( - (self.inputs[inputIndex].name === execPin && outputSlot.name !== execPin) - || - (self.inputs[inputIndex].name !== execPin && outputSlot.name === execPin) - ) { - return false; //reject a non-event connection - } else { - //these are both exec inputs - execChanged = true; - } - - //a link is updated so check if we have an exec on this node - if(!execChanged && !(Object.keys(self.inputs).find((v) => { if(self.inputs[v].name === execPin && self.inputs[v].link) return true; }) || (self.inputs[0] as any).extraLinks)) - execChanged = true; - - if(execChanged) { - //these are subscriptions - //graph.subscribe() - //and/oor modify the listener - } else { - - /* - * - * - * On connecting to an arg input, - * - * - */ - - let args = getArgsFromNode(editor, self as LGraphNodeM); - - const subNode = (i, sourceNode) => { - if(self.subs[i]) { - let listener = self.subs[i].listener; - let sub = self.subs[i].sub; - self.__graph.unsubscribe(listener.target as string, sub, listener.tkey, listener.subInput); - } else { - - } - let sub = self.__graph.subscribe( - sourceNode.tag, self.tag, args - ); - self.subs[i] = { - sub, - listener:self.__graph.__node.state.getEvent( - sourceNode.__unique + sourceNode.key ? '.'+sourceNode.key : '', - sub - ) as any as Listener - }; - } - - if((self.inputs[0] as any).link) { - let sourceNode = editor.getNodeById((self.inputs[0] as any).link.origin_id) as LGraphNodeM; - if(sourceNode) subNode(0,sourceNode); - } - if((self.inputs[0] as any).extraLinks) { - let i = 0; - for(const key in (self.inputs[0] as any).extraLinks) { - i++; - let sourceNode = editor.getNodeById(editor.links[key].origin_id) as LGraphNodeM; - if(sourceNode) subNode(i,sourceNode); - } - } - - //now propagate upstream if any outputs on the outputNode continue on - if(self.outputs) { - let checked = {} as any; - self.outputs.forEach((output) => { - //rebuild/swap args in active listeners - if(editor && output.links) { - output.links.forEach((link) => { - let outputNode = editor.getNodeById(editor.links[link].target_id); - if(!checked[editor.links[link].target_id]) { - checked[editor.links[link].target_id] = true; - //update subs - if(outputNode) - checkNodeForSubscriptionUpdate(outputNode as LGraphNodeM,editor,editor.links[link].target_slot,undefined,self.outputs[editor.links[link].origin_slot],undefined,undefined); - } - }); - - } - }); - } - - } -} - - - - -export function registerNode( - node: GraphNode, - root?:Function|GraphNodeProperties, - key?: string, - editor?:LGraph -) { - - - const tag = node.__node.tag; - const name = key ? `${tag}.${key}` : tag; - - let hasNode = registered.get(name) as LGraphNodeM; - if (hasNode) return name; - - - const NewNode = function() { - let self = this as LGraphNodeM; - self.title = name; - - self.triggers = node.__listeners ? node.__listeners : {}; - self.__node = node; - self.tag = tag; - self.key = key; - self.__unique = node.__node.unique; - self.__graph = node.__node.graph; - self.editor = editor as LGraph; - self.subs = {}; - self.firstConnect = true; - - let params; - - let setOutputNameFromFunction = (fn) => { - let str = typeof fn === 'string' ? fn : fn.toString() as string; - let isNative = str.indexOf('[native code]') > -1; - if(isNative) { - self.addInput('', 0 as any); - self.addOutput('', 0 as any); - return; - } - let idx = str.lastIndexOf('return'); - if(idx !== str.indexOf('return')) { //multiple return statements so we can't determine which one, just use a blank output - self.addOutput('', 0 as any); - return; - } - if(idx > -1) {//if exits - idx+=5; - //get output name - let lastIndex = str.lastIndexOf(';'); - if(lastIndex === -1 && lastIndex > idx) { - lastIndex = str.lastIndexOf('}'); - } - let substr; - if(lastIndex > -1 && lastIndex > idx) substr = str.substring(idx+1,lastIndex); - if(substr) self.addOutput(substr, 0 as any); //todo: can we type this at all? else do it dynamically - else self.addOutput('', 0 as any); - } - } - - self.addInput(execPin,-1); //fix to be able to add/remove contextually - self.addOutput(execPin,-1); //fix to be able to add/remove contextually - - if(key && root?.[key]) { - if(typeof root[key] === 'function') { - setOutputNameFromFunction(root[key]) - params = getFnParamNames(root[key]); - } else { - let typ = typeof root[key] as string; - if(typ === 'undefined') typ = 0 as any; - self.addInput('Set', typ); - self.addOutput('Get', typ); - } - } - if(typeof root === 'function') { - setOutputNameFromFunction(root); - params = getFnParamNames(root); - } else if(root?.__operator || root?.default) { - setOutputNameFromFunction(root.__operator ? root.__operator : root.default); - params = getFnParamNames(root.__operator ? root.__operator : root.default); - } - if(params) { - params.forEach((p,i) => { - if(p || params.length > 1) self.addInput(p,0 as any); - }); - } - - // for (let key in self) this.addInput(key) - - self.onExecute = function() { - //this can trigger the node operator here or the method of a node to cause downstream effects - } - - self.onAdded = function(graph:LGraph) { - // - } - - self.onRemoved = function() { - //graph.unsubscribe - } - - //when an input (left side) is connected on this node from an output (right side) on another node - self.onConnectInput = function(inputIndex, outputType, outputSlot, outputNode, outputIndex) { - - if(!self.firstConnect) - checkNodeForSubscriptionUpdate(self, editor as LGraph, inputIndex, outputType, outputSlot, outputNode, outputIndex); - - console.log('onConnectInput',{inputIndex, outputType, outputSlot, outputNode, outputIndex}); - - return true; - } - - //when an output is connected on this node, can just use onConnectInput - self.onConnectOutput = function(outputIndex, inputType, inputSlot, inputNode, inputIndex) { - //graph.subscribe(); - //console.log('onConnectOutput',{outputIndex, inputType, inputSlot, inputNode, inputIndex}); - - return true; - } - - self.onConnectionsChange = function(type, slotIndex, isConnected, link, ioSlot) { - //console.log('onConnectionsChange',{type, slotIndex, isConnected, link, ioSlot}); - if(!isConnected) { - //graph.unsubscribe(); - } - } - - // if(node?.__listeners) for(const key in node.__listeners) { - // //add outputs - // } - - // if(node?.__args) for(const key in node.__args) { - // //adds inputs - // } - - //self.addWidget('slider',...); //todo - - if(node?.__element && node?.__renderHTML) { - //we should be able to render the element over the node. The editor is in a canvas so we need to use the - // position X and Y of the canvas element (relative to the pageX and pageY), - // then set the HTML over the top of it and account for the size in the canvas elmeent using the html bounding box - } - - } as any as (new () => LGraphNodeM); - - LiteGraph.registerNodeType(name, NewNode); //now registered in system - - registered.set(name, NewNode); - - return name; - -} - - - - - -export function getListenersFromWorker(worker:WorkerInfo) { - return worker.run('getListenerJSON'); -} //build the graph from this result - -export function setSubscriptionOnWorker(worker:WorkerInfo, nodeEvent:string, onEvent:any, args?:any[], key?:string, subInput?:boolean, blocking?:boolean) { - return worker.subscribe(nodeEvent, onEvent, args, key, subInput, blocking); -} - -export function subscribeNodeToWorker(worker:WorkerInfo, node:LGraphNodeM) { - -} - -//todo: create a worker node - - - -export function registerRemoteNode( - root:Function|GraphNodeProperties|string, - tag:string, - endpoint:ConnectionInfo, - key?: string, - editor?:LGraph -) { - - const name = key ? `${tag}.${key}` : tag; - - let hasNode = registered.get(name) as LGraphNodeM; - if (hasNode) return name; - - - const NewNode = function() { - let self = this as LGraphNodeM; - self.title = name; - - self.tag = tag; - self.key = key; - self.editor = editor as LGraph; - self.subs = {}; - self.firstConnect = true; - - let params; - - let setOutputNameFromFunction = (fn) => { - let str = typeof fn === 'string' ? fn : fn.toString() as string; - let isNative = str.indexOf('[native code]') > -1; - if(isNative) { - self.addInput('', 0 as any); - self.addOutput('', 0 as any); - return; - } - let idx = str.lastIndexOf('return'); - if(idx !== str.indexOf('return')) { //multiple return statements so we can't determine which one, just use a blank output - self.addOutput('', 0 as any); - return; - } - if(idx > -1) {//if exits - idx+=5; - //get output name - let lastIndex = str.lastIndexOf(';'); - if(lastIndex === -1 && lastIndex > idx) { - lastIndex = str.lastIndexOf('}'); - } - let substr; - if(lastIndex > -1 && lastIndex > idx) substr = str.substring(idx+1,lastIndex); - if(substr) self.addOutput(substr, 0 as any); //todo: can we type this at all? else do it dynamically - else self.addOutput('', 0 as any); - } - } - - self.addInput(execPin,-1); //fix to be able to add/remove contextually - self.addOutput(execPin,-1); //fix to be able to add/remove contextually - - if(key && root?.[key]) { - if(typeof root[key] === 'function') { - setOutputNameFromFunction(root[key]) - params = getFnParamNames(root[key]); - } else { - let typ = typeof root[key] as string; - if(typ === 'undefined') typ = 0 as any; - self.addInput('Set', typ); - self.addOutput('Get', typ); - } - } - if(typeof root === 'function') { - setOutputNameFromFunction(root); - params = getFnParamNames(root); - } else if(typeof root === 'object' && (root?.__operator || root?.default)) { - setOutputNameFromFunction(root.__operator ? root.__operator : root.default); - params = getFnParamNames(root.__operator ? root.__operator : root.default); - } - if(params) { - params.forEach((p,i) => { - if(p || params.length > 1) self.addInput(p,0 as any); - }); - } - - // for (let key in self) this.addInput(key) - - self.onExecute = function() { - //this can trigger the node operator here or the method of a node to cause downstream effects - } - - self.onAdded = function(graph:LGraph) { - // - } - - self.onRemoved = function() { - //graph.unsubscribe - } - - //when an input (left side) is connected on this node from an output (right side) on another node - self.onConnectInput = function(inputIndex, outputType, outputSlot, outputNode, outputIndex) { - - if(!self.firstConnect) - checkNodeForSubscriptionUpdate(self, editor as LGraph, inputIndex, outputType, outputSlot, outputNode, outputIndex); - - console.log('onConnectInput',{inputIndex, outputType, outputSlot, outputNode, outputIndex}); - - return true; - } - - //when an output is connected on this node, can just use onConnectInput - self.onConnectOutput = function(outputIndex, inputType, inputSlot, inputNode, inputIndex) { - //graph.subscribe(); - //console.log('onConnectOutput',{outputIndex, inputType, inputSlot, inputNode, inputIndex}); - - return true; - } - - self.onConnectionsChange = function(type, slotIndex, isConnected, link, ioSlot) { - //console.log('onConnectionsChange',{type, slotIndex, isConnected, link, ioSlot}); - if(!isConnected) { - //graph.unsubscribe(); - } - } - - // if(node?.__listeners) for(const key in node.__listeners) { - // //add outputs - // } - - // if(node?.__args) for(const key in node.__args) { - // //adds inputs - // } - - //self.addWidget('slider',...); //todo - - // if(node?.__element && node?.__renderHTML) { - // //we should be able to render the element over the node. The editor is in a canvas so we need to use the - // // position X and Y of the canvas element (relative to the pageX and pageY), - // // then set the HTML over the top of it and account for the size in the canvas elmeent using the html bounding box - // } - - } as any as (new () => LGraphNodeM); - - LiteGraph.registerNodeType(name, NewNode); //now registered in system - - registered.set(name, NewNode); - - return name; - -} \ No newline at end of file diff --git a/examples/editing/old/WebComponent.ts b/examples/editing/old/WebComponent.ts deleted file mode 100644 index 293f739d..00000000 --- a/examples/editing/old/WebComponent.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Graph, GraphNode, GraphNodeProperties } from "../../src/core/Graph"; -import { wchtmlloader } from '../../src/loaders/html/wc.loader'; - -export class WebComponent { - - [x: keyof GraphNodeProperties]: GraphNodeProperties[keyof GraphNodeProperties] - - node: GraphNode - useShadow = true - - - constructor(properties: GraphNodeProperties) { - - // ----------------- Handle Web Component Properties ----------------- - Object.assign(this, properties); - } - - connect (properties: GraphNodeProperties, graph?: Graph, parent?: GraphNode) { - - if (graph) { - const node = graph.add(properties, parent) - if (node) { - this.node = node - this.__props = this.node.__props - } else console.error('Could not add node to graph', properties) - } else { - this.graph = new Graph({ - properties, - loaders: { wchtmlloader } - }) - - this.node = this.graph.get(this.graph.__node.tag) - } - - this.__props = this.node.__props - - return this.node - } - -} - -export default WebComponent \ No newline at end of file diff --git a/examples/editing/old/context/ContextMenu.ts b/examples/editing/old/context/ContextMenu.ts deleted file mode 100644 index c2b95b99..00000000 --- a/examples/editing/old/context/ContextMenu.ts +++ /dev/null @@ -1,99 +0,0 @@ -import WebComponent from "../WebComponent"; - -import style from './styles.css' -import html from './index.html' - -type MenuItem = { - text: string; - onclick: (e:any, returned: any) => any - } - - - type Response = { - condition: (target: HTMLElement[]) => boolean | any - contents: (ev: MouseEvent) => MenuItem[]; - } - - -export class ContextMenu extends WebComponent { - - responses: Map = new Map() - - constructor() { - super({ - __element: 'escode-context-menu', - __template: html, - __css: style - }) - - this.connect(this) - } - - __onrender () { - this.list = (this.shadowRoot ?? this).querySelector('ul') - - /** close the right click context menu on click */ - window.addEventListener('click', this.onClick) - - /** - present the right click context menu ONLY for the elements having the right class - */ - window.addEventListener('contextmenu', this.onContextMenu) - - } - - - onClick() { - this.style.display = 'none'; - if (this.style.display === 'block') document.body.style.overflow = '' - } - - setResponse = (id, info: Response) => this.responses.set(id, info) - - delete = (id) => this.responses.delete(id) - - onContextMenu = (e) => { - - document.body.style.overflow = 'hidden' - - - this.list.innerHTML = '' // Clear - - - let count = 0; - this.responses.forEach((o) => { - // console.log(o, o.condition(selected)) - - const isMatch = o.condition(e.path ?? [e.target]) - if (isMatch) { - e.preventDefault(); - - // Correct for Parent Window Offset - let parent = (this.parentNode as any) - if (parent.host) parent = parent.host // LitElement correction - var rect = parent.getBoundingClientRect() - this.style.left = e.clientX - rect.left + 'px' - this.style.top = e.clientY - rect.top + 'px' - this.style.display = 'block' - const list = o.contents(e) ?? [] - - if (list.length > 0) { - - if (count > 0) this.list.appendChild(document.createElement('hr')) // Split - - list.forEach(item => { - const li = document.createElement('li') - li.innerHTML = item.text - li.onclick = (ev) => { - item.onclick(ev, isMatch) - } - this.list.appendChild(li) - }) - - count++ - } - } - }) - } - -} \ No newline at end of file diff --git a/examples/editing/old/context/index.html b/examples/editing/old/context/index.html deleted file mode 100644 index e2d1b049..00000000 --- a/examples/editing/old/context/index.html +++ /dev/null @@ -1 +0,0 @@ -
    \ No newline at end of file diff --git a/examples/editing/old/context/styles.css b/examples/editing/old/context/styles.css deleted file mode 100644 index 3b54c68a..00000000 --- a/examples/editing/old/context/styles.css +++ /dev/null @@ -1,52 +0,0 @@ -:host { - border-radius: 10px; - box-shadow: 0 1px 5px 0 rgb(0 0 0 / 20%); - position: absolute; - display: none; - z-index: 10000; - padding: 5px; - color: black; - font-size: 80%; - min-width: 200px; - background: rgba(255, 255, 255, 0.8); - backdrop-filter: blur(6px); -} - -ul, -li { - list-style: none; - margin: 0; - padding: 0; - border-radius: 3px; - user-select: none; -} - -li { - /* border-bottom:solid 1px #CCC; */ - padding: 5px 10px; -} - -li:last-child { - border: none; -} - -li:hover { - background: #EEE; -} - -hr { - margin: 5px; -} - -@media (prefers-color-scheme: dark) { - - :host { - background: rgba(100, 100, 100, 0.8); - color: white; - } - - li:hover { - background: #AAA; - } - -} \ No newline at end of file diff --git a/examples/editing/old/editor/Editor.ts b/examples/editing/old/editor/Editor.ts deleted file mode 100644 index 343b0fd7..00000000 --- a/examples/editing/old/editor/Editor.ts +++ /dev/null @@ -1,934 +0,0 @@ -import { Graph, GraphNode, GraphNodeProperties } from "../../../src/core/Graph" -import { WebComponent } from "../WebComponent"; -import style from './styles.css' -import html from './index.html' -import context from "./context"; -import { Node, NodeProps } from "./node/Node"; -import { Listener } from "./listener/Listener"; -import drag from './utils/drag' - -export default class Editor extends WebComponent { - - - - // GraphScript Behaviors - __onrender = (el) => { - - // ------------------------- Track Elements from the Template ------------------------- - const grid = (el.shadowRoot ?? el).querySelector('#grid') - - this.elements = { grid } - - // ------------------------- Handle Events ------------------------- - el.addEventListener('mousedown', e => { - this.context.start = { x: e.clientX - this.context.point.x, y: e.clientY - this.context.point.y }; - this.mouseDown = true - }) - - window.addEventListener('mouseup', e => { this.mouseDown = false} ) - el.addEventListener('wheel', this.scale) - el.addEventListener('mousemove', this.pan) - - const rect = grid.getBoundingClientRect() - - this.middle = { - x: rect.width / 2, - y: rect.height / 2 - } - - } - - // UI Editing - context: { - zoom: number, - - minZoom: number, - maxZoom: number, - - start: { - x: number, - y: number - }, - point: { - x: number, - y: number - } - } = { - zoom: 1, - minZoom: 0.6 / window.devicePixelRatio, - maxZoom: 3.0, - start: {x: 0, y: 0}, - point: {x: 0, y: 0} - - } - editing: HTMLElement | null = null - mouseDown:boolean = false - #loaded: boolean = false - - nodes: Map = new Map() - listeners: Map = new Map() - toResolve: Function[] = [] - - // GraphScript Management - graphs: { - context: Graph - active: Graph | GraphNode - } - - // listeners: any = {} - ui?: Element - - #selectElements: any = [] - - propertiesToSubscribe: Set = new Set() - nodePaths: Set = new Set() - - #fIter = 0 - - elements: { - context?: Element, - create?: Element, - grid: HTMLElement - } - - constructor (graph, parentNode?: GraphNodeProperties['parentNode']) { - - // -------------- Create a Hidden Internal Graph -------------- - super({ - __element: 'escode-editor', - __template: html, - __css: style, - useShadow: true, - parentNode - }) - - // this.graph = new Graph({ root: this }) - - this.connect(this) - - // -------------- Setup Keyboard Shortcuts -------------- - document.onkeydown = (e) => { - if (e.ctrlKey && e.code == 'KeyS') { - e.preventDefault() - console.error('Save not defined...') - // app.save() // Global save. - } - }; - - // Set graphs blank if not defined - const contextGraph = new Graph() - this.graphs = { context: contextGraph, active: contextGraph } - // -------------- Set Context Graph -------------- - this.setGraph(graph ?? contextGraph) - - this.createContextMenu() - } - - createContextMenu = () => { - // --------------------------------------------------------------------------------------------------------- - // ------------------------------------- Setting Context Menu Response ------------------------------------- - // --------------------------------------------------------------------------------------------------------- - - if (!context.parentNode) document.body.appendChild(context.__props) - - // Setting Context Menu Responses - context.setResponse(`escode-graph-editor_nodes_${Math.random()}`, { - condition: (path) => { - let returned: any = false - this.nodes.forEach(n => { - if (path.includes(n.__props)) returned = n - }) - return returned - }, - contents: () => { - return [ - { - text: 'Delete', - onclick: (_, node) => { - this.removeNode(node) - } - } - ] - - } - }) - - - context.setResponse(`escode-graph-editor_${Math.random()}`, { - condition: (path) => path.includes(this.__props), - contents: (ev) => { - return [ - { - text: 'Add Component', - onclick: async () => { - - const grid = this.elements.grid - if (grid) { - var rect = grid.getBoundingClientRect(); - var x = ev.clientX - rect.left; //x position within the element. - var y = ev.clientY - rect.top; //y position within the element. - - - console.error('Cannot add a component!') - // // Blur the Background - // const overlay = new Overlay() - - // // Create a Modal - // const modal = new Modal({open: true, header: 'Components', footer: 'All ES Components can be found on the ESCode repository.'}) - // overlay.appendChild(modal) - - // modal.onClose = () => { - // overlay.open = false - // } - - // // Show Node Options in a List - // const result = await new Promise((resolve) => { - - // const list = new Tree({ - // target: this.plugins, - // conditions: { - // value: (o) => !!o.__ // Check if a component - // }, - // onClick: (tag, thing:any) => { - // resolve({tag, info: Object.assign({}, thing)}) // Copying thing so that it doesn't get modified globally - // } // pass a shallow copy onwards - // }) - // modal.appendChild(list) - // document.body.appendChild(overlay) - // // this.workspace.parentNode.appendChild(overlay) - // overlay.open = true - - // }) as any // TODO: Add ES Component types... - - // // Add essential info - // const info = result.info - - // const tag = `${result.tag}_${Math.floor(1000*Math.random())}` // generate tag from plugin - - // // extend info for escode - // delete info?.__escode // delete existing instance-specific info - - // this.workspace.addNode({ tag, info, x, y }) - // modal.open = false - // overlay.open = false - } - }, - }, - // { - // text: 'Do another thing', - // onclick: () => { - // console.warn('MUST DO SOMETHING') - // } - // } - ] - } - }) - } - - - // Set Graph on the Editor and React to Listeners - setGraph = (graph: Editor['graphs']['context']) => { - if (graph) { - - this.graphs.context = graph - this.setActive(graph) - - const nodes = Array.from(graph.__node.nodes.values()) - - this.nodePaths = new Set(nodes.map(o => o.__node.tag)) - this.propertiesToSubscribe = new Set(this.nodePaths) - - nodes.forEach(o => { - const listeners = o.__listeners - if (listeners) { - for (let key in listeners) this.#onListenerAdded(key, listeners[key], o) - } - }) - } else { - this.listeners = new Map() - } - } - - setActive = (node: Editor['graphs']['active']) => { - this.#loaded = false - const active = this.graphs.active = node - const nodes = active.__node.nodes as Editor['graphs']['active']['__node']['nodes'] - - nodes.forEach((n,key) => { - let gN = this.nodes.get(n.__node.tag); - - if (!gN){ - gN = this.addNode({ - tag: key, - info: n, - editor: this - }) - } - }) - - // for (let key in this.graph.edges) { - - // let nodeEdges = this.graph.edges[key] - - // // String shortcut - // if (typeof nodeEdges === 'string') nodeEdges = {[nodeEdges]: true} - - // for (let targetKey in nodeEdges) { - // const info = nodeEdges[targetKey] - // const output = (this.edgeMode === 'from') ? this.match(key) : this.match(targetKey, info) - // const input = (this.edgeMode === 'from') ? this.match(targetKey, info) : this.match(key) - - // const edges = {} - - // // Don't duplicate on construction - // const outTag = output.port.tag - // if (!edges[outTag]) edges[outTag] = [] - // if (!edges[outTag].includes(input.port.tag)){ - - // await this.resolveEdge({ - // info, - // input: input.port, - // output: output.port - // }); - - // edges[outTag].push(input.port.tag) - // } - - // } - // } - // } - - - - - // ---------------------- Auto Layout New Nodes ---------------------- // - let notMoved: any[] = [] - this.nodes.forEach((node) => { - if (node.info.__escode) { - const info = node.info.__escode; - if (info.x === 0 && info.y === 0) notMoved.push(node); - else notMoved.push(node); - } - }); - - this.autolayout(notMoved) - this.#transform() // Move to center - this.#loaded = true - } - - // Exposed method for removing a listener - removeListener = (key, value, bound) => { - console.error('Remove Listener to the graph here...') - this.#onListenerRemoved(key, value, bound) - } - - // Exposed method for adding a listener - addListener = (from, to, bound) => { - console.error('Add Listener to the graph here...') - this.#onListenerAdded(from, to, bound) - } - - // InitializE the editor UI when the UI is ready - setUI = (ui: Element=document.body) => { - if (this.ui) Array.from(this.ui.children).forEach(c => c.remove()) - this.ui = ui - - if (this.ui) { - - const createListenerInfo = this.#createListenerUI() - // Create Listener UI - const create = document.createElement('div') - create.appendChild(createListenerInfo.element) - this.ui.appendChild(create) - this.elements.create = create - - // Show context Listeners - const context = document.createElement('div') - context.id = 'context' - const contextHeader = document.createElement('h3') - contextHeader.innerText = 'context Listeners' - context.appendChild(contextHeader) - this.ui.appendChild(context) - this.elements.context = context - - // Add all listeners to the UI - for (let bound in this.listeners) { - for (let key in this.listeners[bound]) this.listeners[bound][key].forEach(value => this.#addListenerToUI(key, value, bound)) - } - } - } - - // -------------- Internal Event Managers -------------- - #onListenerAdded = (key, value, bound) => { - - bound = (typeof bound !== 'string') ? bound.__node.tag : bound - if (!this.listeners[bound]) this.listeners[bound] = {} - if (!this.listeners[bound][key]) this.listeners[bound][key] = [] - this.listeners[bound][key].push(value) - - if (this.ui) this.#addListenerToUI(key, value, bound) - } - - #onListenerRemoved = (key, value, bound) => { - console.error('Remove Listener from UI' , key, value, bound) - } - - - - // ----------------------------------------------------------- // - // ----------------- Ugly UI Management Code ----------------- // - // ----------------------------------------------------------- // - - #createListenerUI = (from?, value: any = {}, bound?) => { - const noArgs = !from && Object.keys(value).length === 0 && !bound - - const options = this.propertiesToSubscribe - let to = typeof value === 'string' ? value : undefined //value.__output - - const ogOptionsSize = options.size - - // Resolve Callback - const resolvePath = (path) => { - if (!this.nodePaths.has(path)) { - if (typeof path === 'string' && path.includes('FUNCTION_')) path = `${bound}.${path}` - } - return path - } - - const isValid = (path) => typeof path !== 'function' && typeof path !== 'boolean' && typeof path !== 'object' - - const addPathToOptions = (path) => { - if (path && !options.has(path) && isValid(path)) { - path = resolvePath(path) - options.add(path) // Ignore Function or Boolean Callbacks - } - } - - let callback = value.__callback - - if (callback && typeof callback === 'function') { - callback.gsEditorId = this.#fIter - callback = `FUNCTION_${this.#fIter}` // NOTE: These functions are all the same! - this.#fIter++ - } - else if (typeof callback === 'boolean') callback = bound - - // Assign To and Callback - if (callback && to) console.error('Has Both', callback && to) - if (!to) to = callback - addPathToOptions(to) - - const states = {from, to, bound, value} - - const div = document.createElement('div') - div.style.border = '1px solid black' - div.style.padding = '10px' - div.style.position = 'relative' - - let button = document.createElement('button') - if (noArgs) { - button.innerText = 'Create' - button.onclick = () => { - const {from, to, bound, value} = states - if (bound && from) { - console.error('Actually subscribe to the listener here', states) - this.#onListenerAdded(from, value, bound) - } - } - - } else { - button.innerText = 'Remove' - button.onclick = () => { - div.remove() - this.removeListener(from, to, bound) - } - } - - button.style.position = 'absolute' - button.style.top = '0' - button.style.right = '0' - - div.appendChild(button) - - - const fromContainer = document.createElement('div') - const fromLabel = document.createElement('label') - fromLabel.innerText = 'From' - const fromSelect = document.createElement('select') - fromSelect.id = 'from' - fromContainer.appendChild(fromLabel) - fromContainer.appendChild(fromSelect) - - const boundContainer = document.createElement('div') - const boundLabel = document.createElement('label') - boundLabel.innerText = 'Bound To' - const boundSelect = document.createElement('select') - boundSelect.id = 'bound' - boundContainer.appendChild(boundLabel) - boundContainer.appendChild(boundSelect) - - const toContainer = document.createElement('div') - const toLabel = document.createElement('label') - toLabel.innerText = 'To' - const toSelect = document.createElement('select') - toSelect.id = 'to' - toContainer.appendChild(toLabel) - toContainer.appendChild(toSelect) - - const createIO = (value) => { - - const ioStates = {} - const inputContainer = document.createElement('div') - const inputHeader = document.createElement('h4') - inputHeader.innerText = 'Input' - inputContainer.appendChild(inputHeader) - const inputSelect = document.createElement('select') - inputSelect.id = 'input' - inputContainer.appendChild(inputSelect) - - this.#addSelectElement(inputSelect, { - value: value.__input, - onchange: (ev) => { - const value = ev.target.value - this.#onSelectChange(ev, states) - states.value.__input = value - } - }, this.propertiesToSubscribe, true) - - - // array[ind] = output(input(args)) - const argsContainer = document.createElement('div') - const argsHeader = document.createElement('h4') - argsHeader.innerText = 'Arguments' - argsContainer.appendChild(argsHeader) - const argsContained = document.createElement('div') - argsContainer.appendChild(argsContained) - argsContained.style.display = 'flex' - - const createArgs = (args) => { - args.forEach((arg, i) => { - if (typeof arg === 'object') { - const io = createIO(arg) - states.value.__args[i] = io.states - argsContained.appendChild(io.element) - } else { - const argContainer = document.createElement('div') - const argSelect = document.createElement('select') - argContainer.appendChild(argSelect) - argsContained.appendChild(argContainer) - addPathToOptions(arg) - this.#addSelectElement(argSelect, { - value: arg, - onchange: (ev) => { - const value = ev.target.value - this.#onSelectChange(ev, states) - if (!states.value.__args) states.value.__args = [] - states.value.__args[i] = value - } - }, this.propertiesToSubscribe, true) - } - }) - } - - if (value.__args) createArgs(value.__args) - else createArgs([undefined]) - - const output = value.__output - const isSimple = !(output && typeof output === 'object') - - const outputContainer = document.createElement('div') - const outputHeader = document.createElement('h4') - outputHeader.innerText = 'Output' - outputContainer.appendChild(outputHeader) - - let outputValue; - if (isSimple) outputValue = document.createElement('div') - else { - const ioInfo = createIO(output) - outputValue = ioInfo.element - states.value.__output = ioInfo.states - } - - outputContainer.appendChild(outputValue) - if (isSimple) { - - const select = document.createElement('select') - select.id = 'output' - outputContainer.appendChild(select) - - this.#addSelectElement(select, { - value: output, - onchange: (ev) => { - const value = ev.target.value - this.#onSelectChange(ev, states) - states.value.__output = value - } - }, this.propertiesToSubscribe, true) - - // if (hasOutput) outputValue.innerText = output - // else outputValue.innerText = 'N/A' - } else { - states.value.__output - } - - - const ioContainer = document.createElement('div') - ioContainer.appendChild(inputContainer) - ioContainer.appendChild(argsContainer) - ioContainer.appendChild(outputContainer) - return { - element: ioContainer, - states: ioStates - } - } - - const io = createIO(value) - - - div.appendChild(fromContainer) - div.appendChild(boundContainer) - div.appendChild(toContainer) - div.appendChild(io.element) - - if (ogOptionsSize !== options.size) this.#updateSelectElements() - - this.#addSelectElement(fromSelect, { - value: from, - onchange: (ev) => this.#onSelectChange(ev, states, 'from') - }) - - this.#addSelectElement(toSelect, { - value: to, - onchange: (ev) => this.#onSelectChange(ev, states, 'to') - }) - - this.#addSelectElement(boundSelect,{ - value: bound, - onchange: (ev) => this.#onSelectChange(ev, states, 'bound') - }, this.nodePaths) - - return { - element: div, - states - } - } - - #addListenerToUI = (from, value, bound) => { - - const info = this.#createListenerUI(from, value, bound) - - this.elements.context?.appendChild(info.element) - } - - #addSelectElement = (el, configuration, options=this.propertiesToSubscribe, includeOutput = false) => { - - if (typeof configuration !== 'object') configuration = {value: configuration} - - const info = { - el, - configuration, - options, - includeOutput - } - this.#selectElements.push(info) - this.#updateSelectElement(info) - } - - #updateSelectElements = () => this.#selectElements.forEach(o => this.#updateSelectElement(o)) - - #onSelectChange = (ev, states, key?) => { - const value = ev.target.value - const node = this.graphs.active.__node.nodes.get(states.from) - if (node) { - const unique =node.__node.unique - const triggers = this.graphs.active.__node.state.triggers[unique] - if (states.value.sub !== undefined) { - const trigger = triggers[states.value.sub] - console.error('To Update Trigger', value, trigger) - } - } else { - console.error('No Node Found', states) - } - - if (key) states[key] = value - - } - - #updateSelectElement = (info) => { - - const configuration = info.configuration - const value = configuration.value - const el = info.el as HTMLSelectElement - if (el.children.length) Array.from(el.children).forEach(c => c.remove()) - - // Create grayed out selection - const option = document.createElement('option') - option.value = '' - option.innerText = 'N/A' - option.selected = true - option.disabled = true - el.appendChild(option) - - const opts = [...info.options] - if (info.includeOutput) opts.unshift('__output') - - - - opts.forEach(key => { - const option = document.createElement('option') - if (key === value) option.selected = true - option.value = key - option.innerText = key - el.appendChild(option) - }) - - if (configuration.onchange) el.onchange = configuration.onchange - - } - - - // // Events - // onedgeadded?: (edge:GraphEdge) => void = () => {} - // onedgeremoved?: (edge:GraphEdge) => void = () => {} - // onnodeadded?: (node:GraphNode) => void = () => {} - // onnoderemoved?: (node:GraphNode) => void = () => {} - - drag = (item: GraphNode | any) => { - // add drag handler - drag(this, item, () => { - this.resize([item]) - }, () => { - if (!this.editing) this.editing = item - }, () => { - if (this.editing instanceof Node) this.editing = null - }) - } - - resize = (nodes = Array.from(this.nodes.values())) => { - nodes.forEach(node => node.edges.forEach(e => e.resize())) - } - -// Currently laying out nodes in a rough square with more nodes in the columns -autolayout = (nodes: Map | Node[] = this.nodes) => { - let offset = 50 - - nodes = (nodes instanceof Map ? Array.from(nodes.values()) : nodes) as Node[] - - let nPerRow = Math.floor(Math.sqrt(nodes.length)) - - let rowSizes: any[] = [] - let colSizes: any[] = [] - let info: any[] = [] - - nodes.forEach((n, i) => { - - const col = i % nPerRow - const row = Math.floor(i/nPerRow) - - const dimensions = [ - { - value: col, - sizes: colSizes, - dimension: 'height' - }, - { - value: row, - sizes: rowSizes, - dimension: 'width' - } - ] - - const rect = n.node.__props.getBoundingClientRect() - info.push({ - rect, - col, - row - }) - - dimensions.forEach(o => { - let isNew = false - if (o.sizes[o.value] === undefined) { - isNew = true - o.sizes[o.value] = 0 - } - - o.sizes[o.value] += rect[o.dimension] - if (!isNew) o.sizes[o.value] += offset - }) - - }) - - // Set top-left viewport location - const width = this.context.point.x = rowSizes.length ? Math.max(...rowSizes) : 0 - const height = this.context.point.y = colSizes.length ? Math.max(...colSizes) : 0 - - // Actually move nodes - let rowAcc: any[] = [] - let colAcc: any[] = [] - nodes.forEach((n, i) => { - const nInfo = info[i] - - if (colAcc[nInfo.col] === undefined) colAcc[nInfo.col] = 0 - else colAcc[nInfo.col] += offset - - if (rowAcc[nInfo.row] === undefined) rowAcc[nInfo.row] = 0 - else rowAcc[nInfo.row] += offset - - const x = this.middle.x + colAcc[nInfo.col] - width // Set Column - const y = this.middle.y + rowAcc[nInfo.row] - height // Set Row - n.updatePosition(x, y) - - // Update with Shift - rowAcc[nInfo.row] += nInfo.rect.height - colAcc[nInfo.col] += nInfo.rect.width - }) - - - } - - // Behavior - scale = (e) => { - e.preventDefault() - let xs = (e.clientX - this.context.point.x) / this.context.zoom; - let ys = (e.clientY - this.context.point.y) / this.context.zoom; - let delta = (e.wheelDelta ? e.wheelDelta : -e.deltaY); - this.context.zoom = (delta > 0) ? (this.context.zoom * 1.2) : (this.context.zoom / 1.2); - if (this.context.zoom < this.context.minZoom) this.context.zoom = this.context.minZoom // clamp - if (this.context.zoom > this.context.maxZoom) this.context.zoom = this.context.maxZoom // clamp - - - this.context.point.x = e.clientX - xs * this.context.zoom; - this.context.point.y = e.clientY - ys * this.context.zoom; - - this.#transform() - } - - #transform = () => { - const grid = this.elements.grid - if (grid) grid.style['transform'] = `translate(calc(-50% + ${this.context.point.x}px), calc(-50% + ${this.context.point.y}px)) scale(${this.context.zoom*100}%)` - } - - - - pan = (e) => { - - // e.preventDefault(); - - if (!this.editing){ - - if (e.target.parentNode){ - - // Transform relative to Parent - let rectParent = e.target.parentNode.getBoundingClientRect(); - let curXParent = (e.clientX - rectParent.left)/rectParent.width; //x position within the element. - let curYParent = (e.clientY - rectParent.top)/rectParent.height; //y position within the element. - - if (this.mouseDown){ - - this.context.point.x = (e.clientX - this.context.start.x); - this.context.point.y = (e.clientY - this.context.start.y); - this.#transform() - } - this.relXParent = curXParent - this.relYParent = curYParent - } - } - } - - - // ---------------------- Add Nodes and Listeners ---------------------- // - removeNode = (node: string | Node) => { - node = ((typeof node === 'string') ? this.nodes.get(node) : node) as Node - - if ( - this.onnoderemoved instanceof Function // callback is a function - ) this.onnoderemoved(node) - - - // update ui - node.deinit(false) - this.nodes.delete(node.tag) - - } - - addNode = (props: NodeProps) => { - - if (!props.editor) props.editor = this - - // shift position to the middle - if (props.info?.__escode?.x) props.x = props.info.__escode.x - if (props.info?.__escode?.y) props.y = props.info.__escode.y - - // Only run autolayout after UI has rendered - const gN = new Node(props, this.elements.grid) - - this.nodes.set(gN.tag, gN) - - if (this.onnodeadded instanceof Function) this.onnodeadded(gN) - - return gN - } - - resolveEdge = async (info, willAwait=true) => { - - if (this.editing?.tagName === 'escode-listener') { - const component = this.editing as any as Listener // TODO: Fix this - await component.link(info) - return component - } else { - - const tempId = `${Math.round( 10000 * Math.random())}` - const edge = new Listener({editor: this, ...info}, this.elements.grid) - this.editing = edge.graph.__props - - this.edges.setNode(tempId, edge) // Place temp into DOM to trigger edge.rendered - - edge.ready.then(res => { - if (res){ - this.edges.delete(tempId) - this.edges.setNode(edge.id, edge) - edge.resize() - } - }).catch(() => {}) - - if (willAwait) await edge.ready // Wait until the edge is complete - - this.editing = null - return edge - } - } - - - match = (route:string, edgeInfo: any = {}) => { - - let tags = route.split('.') - let match = this.nodes.get(tags[0]); - - if (!match) throw new Error('Node not found: ' + route) - - // If no port name, choose between operator and default - const portName = (tags.length === 1) ? (match.info.__operator ? '__operator' : 'default') : tags.slice(1).join('.'); // fallback to default port - - tags.forEach(t => { - const temp = this.nodes.get(t) - if (temp) match = temp - }) - - let port; - try { - port = match.ports.get(portName); - if (!port) { - // alert('Port not found: ' + route) - port = match.addPort({tag: portName, node: match, value: edgeInfo.target}) - } - } catch (e) { - console.error('failed to get port', e, route, this.nodes) - } - - return { - port, - match - } -} - -} \ No newline at end of file diff --git a/examples/editing/old/editor/context.ts b/examples/editing/old/editor/context.ts deleted file mode 100644 index 6b3b4861..00000000 --- a/examples/editing/old/editor/context.ts +++ /dev/null @@ -1,4 +0,0 @@ -import '../context/ContextMenu' -import { ContextMenu } from '../context/ContextMenu' -export const context = new ContextMenu() -export default context \ No newline at end of file diff --git a/examples/editing/old/editor/index.html b/examples/editing/old/editor/index.html deleted file mode 100644 index 4cb72bce..00000000 --- a/examples/editing/old/editor/index.html +++ /dev/null @@ -1,5 +0,0 @@ -
    -
    - -
    -
    \ No newline at end of file diff --git a/examples/editing/old/editor/listener/Listener.ts b/examples/editing/old/editor/listener/Listener.ts deleted file mode 100644 index 0a559ae8..00000000 --- a/examples/editing/old/editor/listener/Listener.ts +++ /dev/null @@ -1,26 +0,0 @@ -import WebComponent from "../../WebComponent"; - -import style from './styles.css' - -export class Listener extends WebComponent { - - - constructor(props: any, parentNode?: HTMLElement) { - - const html = `` - - super({ - __element: 'escode-listener', - __template: html, - __css: style, - parentNode - }) - - this.connect( - this, - // props.editor.graph - ) - - } - -} \ No newline at end of file diff --git a/examples/editing/old/editor/listener/styles.css b/examples/editing/old/editor/listener/styles.css deleted file mode 100644 index ff40988b..00000000 --- a/examples/editing/old/editor/listener/styles.css +++ /dev/null @@ -1,50 +0,0 @@ -:host * { - box-sizing: border-box; - } - - :host { - display: block; - pointer-events: none; - --grid-color: rgb(210, 210, 210); - } - - :host > div { - width: 100%; - display: flex; - align-items: center; - justify-content: space-between; - font-size:7px; - } - - .input { - transform: translateX(-50%); - left: 0; - } - - .output { - transform: translateX(50%); - right: 0; - } - - .output.hidden { - pointer-events: none; - background: transparent; - } - - .port { - pointer-events: all; - width: 10px; - height: 10px; - background: gray; - cursor: pointer; - border-radius: 10px; - z-index: -1; - } - - @media (prefers-color-scheme: dark) { - - :host { - --grid-color: rgb(45, 45, 45); - } - - } \ No newline at end of file diff --git a/examples/editing/old/editor/node/Node.ts b/examples/editing/old/editor/node/Node.ts deleted file mode 100644 index ddd9016a..00000000 --- a/examples/editing/old/editor/node/Node.ts +++ /dev/null @@ -1,227 +0,0 @@ -import { GraphNode, GraphNodeProperties } from "../../../../../src/core/Graph"; -import WebComponent from "../../../WebComponent"; -import Editor from "../Editor"; -import { Listener } from "../listener/Listener"; -import { PortProps, Port } from "./port/Port"; - -import style from './styles.css' - -export const isPrivate = (key) => key[0] === '_' // NOTE: Is redeclared from common/standards.js - - export type NodeProps = { - editor: Editor - x?: number; - y?: number; - tag?: string, - info: GraphNode; // Add ES Component types... - - __onrender?: GraphNodeProperties['__onrender'] - } - - - -export class Node extends WebComponent { - - // workspace: GraphNodeProps['workspace']; - tag: string; - x: number = 0; - y: number = 0; - info: NodeProps['info']; - edges: Map = new Map() - ports: Map = new Map() - portCategories: { - properties: Map, - components: Map, - default: Map, - } = { - properties: new Map(), - components: new Map(), - default: new Map(), - } - - editor: Editor - portOrder = ['default', 'components', 'properties'] - - elements: { - main: HTMLDivElement - } = { - main: document.createElement('div') - } - - - __onrender(el) { - if (this.info) this.updatePorts() - - // if (!this.editor) this.editor = (this.parentNode.parentNode as any).host - - // add drag handler - this.editor.drag(this) - - this.edges.forEach(e => e.resize()) // resize all edges after - } - - constructor(node: NodeProps, parentNode?: HTMLElement) { - - const html = ` -
    - -
    - ` - - super({ - __element: 'escode-node', - __template: html, - __css: style, - // useShadow: true, - parentNode - }) - - this.elements.main.id = 'ports' - this.elements.main.innerHTML = `
    ` - - // if (node.__onrender) { - // const onrender = this.__onrender - // this.__onrender = (el) => { - // onrender(el) // Old onrender - // node.__onrender(el) - // } - // } - - - this.editor = node.editor - - this.connect( - this, - this.editor.graph - ) - - const container = (this.node.shadowRoot).querySelector('div') - container.appendChild(this.elements.main) - this.setNode(node.info) - } - - updatePosition (x, y) { - if (x !== undefined) this.x = x - if (y !== undefined) this.y = y - this.__props.style.transform = `translate(${this.x}px, ${this.y}px)` - } - - setNode (info) { - this.info = info - if (!this.info.__escode) this.info.__escode = { x: 0, y:0 } // Save ESCode Properties - - this.tag = this.info.__node.tag - this.id = this.info.__node.unique - - this.info.__escode.x = this.x = this.info.__escode.x ?? 0 - this.info.__escode.y = this.y = this.info.__escode.y ?? 0 - this.updatePorts(info) - } - - async updatePorts(info=this.info) { - const notify = (tag, value, type) => { - const got = this.portCategories[type].get(tag) - - if (got === value) console.warn('Redeclared port: ', `${this.tag}.${tag}`) - else { - console.error('Port conflict: ', `${this.tag}.${tag}`) - } - } - - const type = 'properties' - - let n = 0 - Object.keys(info).forEach((tag, i) => { - if (tag.slice(0,2) === '__') return // no __ special properties - if (isPrivate(tag)) return // no underscore (pseudo-private) properties - - let thisType = type - if (tag === 'default' || tag === '__operator') thisType = 'default' - if (this.portCategories?.[thisType]?.has(tag)) { - notify(tag, this.ports.get(tag), thisType) - return - } - console.log('Trying to add', tag, i) - if (n < 20) { - this.addPort({ tag, node: this, type: thisType as 'properties' || 'default'}) - n++ - } - }) - - // Add Port for Each Active ES Component instance (i.e. the internal graph) - const components = info.__children as {[x:string]: GraphNode} - if (components) { - const type = 'children' - Object.keys(components).forEach((tag) => { - if (this.portCategories?.[type]?.has(tag)) { - notify(tag, this.ports.get(tag), type) - return - } - console.log('Adding Port: ', tag, type, this) - this.addPort({ tag, type, node: this }) - }) - } - - } - - willUpdate (updatedProps) { - - if ((updatedProps.has('x') || updatedProps.has('y')) && this.info.__escode){ - this.info.__escode.x = this.x // brainsatplay extension - this.info._escode.y = this.y // brainsatplay extension - } - - if (updatedProps.has('info')) this.updatePorts() - } - - - setEdge (edge) { this.edges.set(edge.id, edge) } - - deleteEdge(id) { - this.edges.delete(id) - } - - #addPortCategory (type: string) { - - let ports = this.elements[type] - - if (!ports) { - this.elements[type] = ports = document.createElement('div') - ports.id = `${type}Ports` - - const idx = this.portOrder.findIndex(str => str === type) - const beforeChild = this.elements.main.children[idx] - if (beforeChild) this.elements.main.insertBefore(ports, beforeChild); - else this.elements.main.appendChild(ports) - } - - return ports - } - - addPort (info: PortProps) { - - const type = info.type ?? 'default' - - const categoryDiv = this.#addPortCategory(type) - const category = this.portCategories[type] ?? this.portCategories.default // Set in type-specific registry - - const port = new Port({ ...info, node: this}) - this.ports.set(port.tag, port) - category.set(port.tag, port) - - console.log('Appending', port) - categoryDiv.appendChild(port.__props) // Append to port category - - - return port - } - - deinit (triggerInWorkspace = true) { - if (triggerInWorkspace) this.editor.removeNode(this) - this.edges.forEach(e => e.deinit()) // Remove edges - this.remove() - } - -} \ No newline at end of file diff --git a/examples/editing/old/editor/node/port/Port.ts b/examples/editing/old/editor/node/port/Port.ts deleted file mode 100644 index d1030ff0..00000000 --- a/examples/editing/old/editor/node/port/Port.ts +++ /dev/null @@ -1,103 +0,0 @@ -import WebComponent from "../../../../WebComponent"; -import { Node } from "../Node"; -export const isListenerPort = (key) => !!key.match(/\[Function_[[0-9]+]/) // TODO: Register in standards somewhere... - -import style from './styles.css' - -export const isPrivate = (key) => key[0] === '_' // NOTE: Is redeclared from common/standards.js - -export type PortProps = { - // tree: {[x:string]: any} - // plot?: Function[], - // onPlot?: Function - // preprocess?: Function, - tag: string - node: Node, - value?: any, - type?: 'properties' | 'children' | 'default' -} - - -export class Port extends WebComponent { - - - node: PortProps['node'] - tag: PortProps['tag'] - type: PortProps['type'] - value: PortProps['value'] - - element: HTMLDivElement - output: HTMLDivElement - input: HTMLDivElement - - - resolving: boolean = false - edges: Map = new Map() - - constructor(port: PortProps, parentNode?: HTMLElement) { - - const tag = port.tag - - const html = ` -
    - ${tag} -
    - ` - - super({ - __element: 'escode-port', - __template: html, - __css: style, - // useShadow: false, - parentNode - }) - - this.node = port.node - this.tag = tag - this.value = port.value - this.type = port.type ?? 'properties' - - this.connect( - this, - this.node.editor.graph, - this.node.node - ) - } - - // updated(changedProperties) { - // this.element = this.shadowRoot.querySelector("div") - // if (!this.node) this.node = (this.parentNode.parentNode.parentNode as any).host - // } - - setEdge = (edge) => { - this.edges.set(edge.id, edge) - this.node.setEdge(edge) // Nodify node - } - - deleteEdge = (id) => { - this.edges.delete(id) - this.node.deleteEdge(id) // Nodify node - } - - resolveEdge = async (ev) => { - if (!this.resolving){ - this.resolving = true - const type = (ev.path[0].classList.contains('input')) ? 'input' : 'output' - if (this.node.workspace) await this.node.workspace.resolveEdge({[type]: this}).catch(e => console.warn(`[escode]: ${e}`)) - this.resolving = false - } - } - - onmousedown = this.resolveEdge - - onmouseup = (ev) => { - const maybeEdge = this.node.workspace.editing - if ( - 'node' in maybeEdge - && 'box' in maybeEdge - && 'svgInfo' in maybeEdge - ) this.resolveEdge(ev) - } - - -} \ No newline at end of file diff --git a/examples/editing/old/editor/node/port/styles.css b/examples/editing/old/editor/node/port/styles.css deleted file mode 100644 index 1f87a85a..00000000 --- a/examples/editing/old/editor/node/port/styles.css +++ /dev/null @@ -1,37 +0,0 @@ -:host * { - box-sizing: border-box; - } - - :host { - pointer-events: none; - width: 100%; - display: flex; - align-items: center; - justify-content: space-between; - font-size:7px; - } - - .input { - transform: translateX(-50%); - left: 0; - } - - .output { - transform: translateX(50%); - right: 0; - } - - .output.hidden { - pointer-events: none; - background: transparent; - } - - .port { - pointer-events: all; - width: 10px; - height: 10px; - background: gray; - cursor: pointer; - border-radius: 10px; - z-index: -1; - } diff --git a/examples/editing/old/editor/node/styles.css b/examples/editing/old/editor/node/styles.css deleted file mode 100644 index bd2cebd2..00000000 --- a/examples/editing/old/editor/node/styles.css +++ /dev/null @@ -1,45 +0,0 @@ -:host { - font-family: var(--escode-font-family, sans-serif); - position: absolute; - box-sizing: border-box; - top: 10px; - left: 10px; - user-select: none; - z-index: 1; -} - -:host>div { - min-width: 50px; - background: rgb(60, 60, 60); -} - -#header { - color: var(--escode-primary-font-color, white); - font-size: 8px; - background: var(--escode-primary-color, black); - padding: 5px; - padding-right: 25px; - font-weight: 800; -} - - -#ports { - min-height: 10px; - color: var(--escode-secondary-font-color, white); - background: var(--escode-secondary-color); -} - -#ports>div:not(:last-child) { - border-bottom: 1px solid var(--escode-secondary-font-color, gray); -} - -#ports escode-graph-port { - padding: 2px 0px; -} - -@media (prefers-color-scheme: dark) { - #header { - color: var(--escode-primary-font-color-dark, var(--escode-primary-font-color, black)); - background: var(--escode-primary-color-dark, var(--escode-primary-color, white)); - } -} \ No newline at end of file diff --git a/examples/editing/old/editor/styles.css b/examples/editing/old/editor/styles.css deleted file mode 100644 index 0419c52b..00000000 --- a/examples/editing/old/editor/styles.css +++ /dev/null @@ -1,54 +0,0 @@ - -:host * { - box-sizing: border-box; - } - - :host { - --escode-dark-background-color: rgb(30, 30, 30); - } - - #container { - width: 100%; - align-items: center; - justify-content: center; - position: relative; - height: 100%; - overflow: hidden; - background: rgb(245, 245, 245); - } - - #grid { - overflow: hidden; - height: 100%; - display: block; - --grid-size: 5000px; - --grid-color: rgb(210, 210, 210); - background: white; - - position: relative; - background-image: - repeating-linear-gradient(var(--grid-color) 0 1px, transparent 1px 100%), - repeating-linear-gradient(90deg, var(--grid-color) 0 1px, transparent 1px 100%); - background-size: 20px 20px; - width: var(--grid-size); - height: var(--grid-size); - } - - #grid:active:hover { - cursor: move; - } - - escode-node { - cursor: move; - } - - @media (prefers-color-scheme: dark) { - :host > * { - background-color: rgb(40, 40, 40); - } - - #grid { - --grid-color: rgb(80, 80, 80); - background: var(--escode-dark-background-color); - } - } \ No newline at end of file diff --git a/examples/editing/old/editor/utils/drag.ts b/examples/editing/old/editor/utils/drag.ts deleted file mode 100644 index c7e2208e..00000000 --- a/examples/editing/old/editor/utils/drag.ts +++ /dev/null @@ -1,91 +0,0 @@ -import Editor from "../Editor"; -import { Node } from "../node/Node"; -import { Port } from "../node/port/Port"; - -const dragElement = (workspace:Editor, dragItem: Node, onMove, onDown,onUp) => { - var active = false; - var currentX; - var currentY; - var initialX; - var initialY; - var xOffset = 0; - var yOffset = 0; - var defaultScale = 1.0 - - // container.addEventListener("touchstart", dragStart, false); - // container.addEventListener("touchend", dragEnd, false); - // container.addEventListener("touchmove", drag, false); - - (dragItem.shadowRoot ?? dragItem).addEventListener("mousedown", dragStart, false); - window.addEventListener("mouseup", dragEnd, false); - window.addEventListener("mousemove", drag, false); - - // let transform = dragItem.style.cssText.match(/transform: ([^;].+);\s?/) // TODO: Check persistence - // let transformString: string - // if (transform) transformString = transform[1] - - // if (transformString) { - // // let scale = transformString.match(/scale\(([^\)].+)\)\s?/) - // // if (scale) scale = scale[1] - // // else scale = 1 - - // let translateString = transformString.match(/translate\(([^\)].+)\)\s?/) - // if (translateString){ - // let arr = translateString[1].split(',') - // xOffset = parseFloat(arr[0].split('px')[0]) - // yOffset = parseFloat(arr[1].split('px')[0]) - // } - // } else { - // dragItem.style.transform = `scale(${defaultScale})`; - // } - - function dragStart(e) { - - const x = dragItem.x - const y = dragItem.y - - if (e.type === "touchstart") { - initialX = (e.touches[0].clientX - (workspace.context.zoom*defaultScale)*x); - initialY = (e.touches[0].clientY - (workspace.context.zoom*defaultScale)*y); - } else { - initialX = (e.clientX - (workspace.context.zoom*defaultScale)*x); - initialY = (e.clientY - (workspace.context.zoom*defaultScale)*y); - } - - // Account For Nested Control Objects - if (dragItem.shadowRoot.contains(e.target)){ - if (!(e.target instanceof Port)) active = true; - onDown() - } - } - - function dragEnd() { - initialX = currentX; - initialY = currentY; - - active = false; - onUp() - } - - function drag(e) { - if (active) { - - e.preventDefault(); - - if (e.type === "touchmove") { - currentX = (e.touches[0].clientX - initialX)/(workspace.context.zoom*defaultScale); - currentY = (e.touches[0].clientY - initialY)/(workspace.context.zoom*defaultScale); - } else { - currentX = (e.clientX - initialX)/(workspace.context.zoom*defaultScale); - currentY = (e.clientY - initialY)/(workspace.context.zoom*defaultScale); - } - - - dragItem.updatePosition(currentX, currentY) - - onMove() - } - } -} - -export default dragElement \ No newline at end of file diff --git a/examples/editing/old/index.html b/examples/editing/old/index.html deleted file mode 100644 index 43496878..00000000 --- a/examples/editing/old/index.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - -
    - -
    - -
    -
    - - - - - \ No newline at end of file diff --git a/examples/editing/old/index.ts b/examples/editing/old/index.ts deleted file mode 100644 index be7d4055..00000000 --- a/examples/editing/old/index.ts +++ /dev/null @@ -1,134 +0,0 @@ -import {Graph} from '../../../src/core/Graph' -import { htmlloader } from '../../../src/loaders/html/html.loader'; -import Editor from './editor/Editor'; -const ui = document.getElementById('ui') // NOTE: This is not becoming the parent node... - -let graph = new Graph({ - loaders:{ - htmlloader - }, - roots:{ - - nodeA:{ - __operator:function add(a,b) { - console.log('run nodeA', a, b); - return a+b; - }, - toAdd:2, - __listeners:{ - 'nodeA':'toAdd' - } - }, - - nodeB:{ - __operator:function multiply(a,b) { - console.log('run nodeB', a, b); - return a*b; - }, - __listeners:{ - 'nodeA':{ __callback:true, __args:['__output', 'nodeA.toAdd'] } - } - }, - - nodeC:{ - __operator:function exponent(a,b) { - console.log('run nodeC', a, b); - return Math.pow(a,b); - }, - __listeners:{ - 'nodeB':{ __callback:true, __args: ['__output',{ - __input:'Math.cos', - __output:{ - __input:'Math.pow', //this returns the final output for the argument list - //__output:(inp)=>{ return inp; } //function or object, etc - __args:['__output', 4] - } - }] } - } - }, - - nodeD:{ - parentNode: ui, // NOTE: This is not rendering... - __element:'div', - innerHTML:'operator output (from child): ', - __operator:function divide(a,b) { - console.log('run nodeD', a, b); - console.log('output:',a/b); - return a/b; - }, - log10:function (a) { - console.log('run nodeD.log10', a); - return Math.log10(a); - }, - __children:{ - output: { - __element:'span', - __operator:function(outp) { - console.log('child node received: ', outp); - this.innerHTML = outp; - }, - } - }, - __listeners:{ - 'nodeC':'log10', - 'nodeD.log10':{ __callback:true, __args:['__output', 3] } - } - }, - - Math - - } -}); - -const list = document.querySelector('#list'); -const editDiv = document.querySelector('#editor'); -const editor = new Editor(graph, editDiv); -if (list) editor.setUI(list) - -// let nodeAInternalSub = graph.subscribe( -// 'nodeA', -// 'nodeA.toAdd' -// ); - -// let nodeBSub = graph.subscribe( -// 'nodeA', -// 'nodeB', -// ['__output','nodeA.toAdd'], -// ); - -// let nodeCSub = graph.subscribe( -// 'nodeB', -// 'nodeC', -// ['__output', { -// __input:'Math.cos', -// __output:{ -// __input:'Math.pow', //this returns the final output for the argument list -// __args:['__output', 4] -// } -// }] -// ); - -// let nodeDSub = graph.subscribe( -// 'nodeC', -// 'nodeD.log10' -// ); - -// let nodeDInternalSub = graph.subscribe( -// 'nodeD.log10', -// 'nodeD', -// ['__output', 3] -// ); - -graph.run('nodeA', 3,4); - -graph.clearListeners('nodeC','nodeB'); - -graph.run('nodeA', 4,5) //should only call nodeB now - - -// const animate = () => { -// graph.run('nodeA', 3,4) //should only call nodeB now -// setTimeout(animate, 100); -// } - -// animate() \ No newline at end of file diff --git a/examples/editing/old/package-lock.json b/examples/editing/old/package-lock.json deleted file mode 100644 index fd55bd66..00000000 --- a/examples/editing/old/package-lock.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "escode", - "version": "0.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "escode", - "version": "0.0.0", - "license": "LGPL-3.0-or-later", - "devDependencies": {} - } - } -} diff --git a/examples/editing/old/package.json b/examples/editing/old/package.json deleted file mode 100644 index 118c5bc1..00000000 --- a/examples/editing/old/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "escode", - "version": "0.0.0", - "description": "An IDE built in GraphScript", - "main": "index.js", - "type": "module", - "scripts": { - "start": "tinybuild", - "build": "tinybuild build", - "serve": "tinybuild serve", - "init": "node tinybuild/init.js", - "concurrent": "concurrently \\'npm run python\\' \\'npm start\\'", - "dev": "npm run pip && npm i --save-dev concurrently && npm i --save-dev nodemon && npm run concurrent", - "startdev": "nodemon --exec \\'node tinybuild.js\\' -e ejs,js,ts,jsx,tsx,css,html,jpg,png,scss,txt,csv", - "python": "python python/server.py", - "pip": "pip install quart && pip install websockets", - "pwa": "npm i workbox-cli && workbox generateSW node_server/pwa/workbox-config.js && npm run build && npm start" - }, - "keywords": [ - "esbuild" - ], - "author": "Garrett Flynn", - "license": "LGPL-3.0-or-later", - "dependencies": {}, - "devDependencies": {}, - "nodemonConfig": { - "env": { - "NODEMON": true - }, - "ignore": [ - "dist/", - ".temp/" - ] - } -} \ No newline at end of file diff --git a/examples/editing/package-lock.json b/examples/editing/package-lock.json deleted file mode 100644 index 59fcbc34..00000000 --- a/examples/editing/package-lock.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "tinybuildapp5363", - "version": "0.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "tinybuildapp5363", - "version": "0.0.0", - "license": "LGPL-3.0-or-later", - "dependencies": { - "litegraph.js": "^0.7.14", - "web-worker": "^1.2.0" - } - }, - "../../../AppData/Roaming/npm/node_modules/tinybuild": { - "version": "0.3.202", - "extraneous": true, - "license": "LGPL-3.0-or-later", - "dependencies": { - "chokidar": "~3.5.3", - "esbuild": "~0.17.10", - "ws": "^8.5.0" - }, - "bin": { - "tinybuild": "tinybuild/bin/global.js" - }, - "peerDependencies": { - "typescript": "~4.9.5" - } - }, - "node_modules/litegraph.js": { - "version": "0.7.14", - "resolved": "https://registry.npmjs.org/litegraph.js/-/litegraph.js-0.7.14.tgz", - "integrity": "sha512-xVC0a/D3uLZkpdV/HxyrruDIWM0vMOoIhgaUQXYymQ8pKgbeQZKR0OfuI0c7IpQxC+M/uoc9BRDl2Fm0Q3bW0w==" - }, - "node_modules/web-worker": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", - "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" - } - }, - "dependencies": { - "litegraph.js": { - "version": "0.7.14", - "resolved": "https://registry.npmjs.org/litegraph.js/-/litegraph.js-0.7.14.tgz", - "integrity": "sha512-xVC0a/D3uLZkpdV/HxyrruDIWM0vMOoIhgaUQXYymQ8pKgbeQZKR0OfuI0c7IpQxC+M/uoc9BRDl2Fm0Q3bW0w==" - }, - "web-worker": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", - "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" - } - } -} diff --git a/examples/editing/package.json b/examples/editing/package.json deleted file mode 100644 index fc7fc57e..00000000 --- a/examples/editing/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "tinybuildapp5363", - "version": "0.0.0", - "description": "Barebones esbuild and test node server implementation. For building", - "main": "index.js", - "type": "module", - "scripts": { - "start": "tinybuild", - "build": "tinybuild build", - "serve": "tinybuild serve", - "init": "node tinybuild/init.js", - "concurrent": "concurrently \\'npm run python\\' \\'npm start\\'", - "dev": "npm run pip && npm i --save-dev concurrently && npm i --save-dev nodemon && npm run concurrent", - "startdev": "nodemon --exec \\'node tinybuild.js\\' -e ejs,js,ts,jsx,tsx,css,html,jpg,png,scss,txt,csv", - "python": "python python/server.py", - "pip": "pip install quart && pip install websockets", - "pwa": "npm i workbox-cli && workbox generateSW node_server/pwa/workbox-config.js && npm run build && npm start" - }, - "keywords": [ - "esbuild" - ], - "author": "", - "license": "LGPL-3.0-or-later", - "dependencies": { - "litegraph.js": "^0.7.14", - "web-worker": "^1.2.0" - }, - "nodemonConfig": { - "env": { - "NODEMON": true - }, - "ignore": [ - "dist/", - ".temp/" - ] - } -} diff --git a/examples/editing/proxyMenu.ts b/examples/editing/proxyMenu.ts deleted file mode 100644 index 906646e4..00000000 --- a/examples/editing/proxyMenu.ts +++ /dev/null @@ -1,340 +0,0 @@ -//add proxy menu - -import { Graph, getAllProperties } from "../../src/core/Graph"; -import { parseFunctionFromText } from "../../src/services/utils"; -import { LGraph } from "./litegraph.js/src/litegraph"; -import { addNodeToLGraph } from "./litegraphScripts"; - -let inpTypes = { - "string":(p,k,v)=>{ - p[k] = v - return p[k]; - }, - "boolean":(p,k,v)=>{if(v.toLowerCase() === "false" || v === "0" || v === "null") p[k] = false; else p[k] = true; return p[k];}, - "number":(p,k,v)=>{p[k] = parseFloat(v); return p[k];}, - "function":(p,k,v)=>{p[k] = parseFunctionFromText(v); return p[k];}, //evals - "object":(p,k,v)=>{ v.replace("'",'"'); p[k] = JSON.parse(v);}, - "array":(p,k,v)=>{ if(!v.startsWith('[')) v = `[${v}]`; v.replace("'",'"'); p[k]=JSON.parse(v); return p[k]; }, //encapsulate strings in an array - "functionSpreadArgs":(p,k,v)=>{ - if(typeof p[k] === 'function') { - let split = v.split(','); - split.forEach((s,i) => { - if(s.startsWith('function') || s.startsWith('(')) { - parsed[i] = parseFunctionFromText(s); - } - }); - let joined = `[${split.join(',')}]`; - joined.replace("'",'"'); - let parsed = JSON.parse(joined) as any[]; - return p[k](...parsed); - } - } -}; - -export let makeProxyMenu = (proxyable:{[key:string]:any}, graph:Graph, editor:LGraph) => { - let instantiateProxy = (key, args:any[]=[]) => { - let proxy = new proxyable[key](...args); - let keys = getAllProperties(proxy); - return {proxy, keys}; - } - - let container = document.createElement('div'); - let nameInput = document.createElement('input'); - let keydropdown = document.createElement('select'); - let constructorInput = document.createElement('input'); - let constructButton = document.createElement('button'); - constructButton.innerHTML = "Construct"; - - let proxySetupContainer = document.createElement('div'); - let propertydropdown = document.createElement('select'); - let propertyInput = document.createElement('input'); - let setProp = document.createElement('button'); - setProp.innerHTML = "Eval" - let propertyInputType = document.createElement('select'); - let createProxy = document.createElement('button'); - createProxy.innerHTML = "Create Node"; - - - Object.keys(inpTypes).forEach((t,i) => { - propertyInputType.insertAdjacentHTML('beforeend',``) - }); - - container.insertAdjacentHTML('beforeend',`
    Class to instantiate: `); - container.appendChild(keydropdown); - container.insertAdjacentHTML('beforeend',`
    Class constructor args (evals as a spread array): `); - container.appendChild(constructorInput); - container.appendChild(constructButton); - proxySetupContainer.insertAdjacentHTML('beforeend',`
    Name Node: `); - proxySetupContainer.appendChild(nameInput); - proxySetupContainer.insertAdjacentHTML('beforeend',`
    Class Property: `); - proxySetupContainer.appendChild(propertydropdown); - proxySetupContainer.insertAdjacentHTML('beforeend',`
    Property Type: `); - proxySetupContainer.appendChild(propertyInputType); - proxySetupContainer.insertAdjacentHTML('beforeend',`
    Input: `); - proxySetupContainer.appendChild(propertyInput); - proxySetupContainer.insertAdjacentHTML('beforeend',`
    Set: `); - proxySetupContainer.appendChild(setProp); - proxySetupContainer.insertAdjacentHTML('beforeend',`
    Add to Graph: `); - proxySetupContainer.appendChild(createProxy); - proxySetupContainer.style.display = "none"; - container.appendChild(proxySetupContainer); - - for(const key in proxyable) { - keydropdown.insertAdjacentHTML('beforeend',``); - } - keydropdown.value = ""; - - keydropdown.onchange = (ev) => { - let value = keydropdown.value; - proxySetupContainer.style.display = "none"; - constructButton.onclick = () => { - let args = constructorInput.value as any; - let split = args.split(','); - split.forEach((s,i) => { - if(s.startsWith('function') || s.startsWith('(')) { - parsed[i] = parseFunctionFromText(s); - } - }); - let joined = `[${split.join(',')}]`; - joined = joined.replace(/'/g,'"'); - let parsed = JSON.parse(joined) as any[]; - - let {proxy, keys} = instantiateProxy(value, parsed); - - nameInput.value = `${value}${Math.floor(Math.random()*1000000000000000)}`; - - propertydropdown.innerHTML = ""; - keys.forEach((k) => { - propertydropdown.insertAdjacentHTML('beforeend',``); - }); - propertydropdown.onchange = (ev) => { - let t = typeof proxy[propertydropdown.value]; - propertyInputType.value = t === "undefined" ? "string" : t; - if(t !== 'function') { - propertyInput.value = proxy[propertydropdown.value]; - } else propertyInput.value = ""; - } - setProp.onclick = (ev) => { - if(inpTypes[propertyInputType.value]) - inpTypes[propertyInputType.value](proxy, propertydropdown.value, propertyInput.value) - } - createProxy.onclick = (ev) => { - let props = { - __node:nameInput.value ? { - tag:nameInput.value - } : undefined, - __props:proxy - //todo: could instead list all the non-functional values from proxy here so they get set on the proxy when the node is created - }; - let node = graph.add(props); - addNodeToLGraph(node, graph, editor); - nameInput.value = `${value}${Math.floor(Math.random()*1000000000000000)}`; - } - - proxySetupContainer.style.display = ""; - } - - } - - return container; - -} - - -export let makeNodePropsCreator = (graph:Graph, editor:LGraph) => { - - let container = document.createElement('div'); - let nameInput = document.createElement('input'); - let propsContainer = document.createElement('div'); - let addButton = document.createElement('button'); - addButton.innerHTML = "Add Prop"; - let createButton = document.createElement('button'); - createButton.innerHTML = "Create Node"; - let clearButton = document.createElement('button'); - clearButton.innerHTML = "Clear Props"; - - container.insertAdjacentHTML('beforeend',`
    Name Node: `); - container.appendChild(nameInput); - container.insertAdjacentHTML('beforeend',` -
    Node Properties: {
    key : value
    - `); - container.appendChild(propsContainer); - container.appendChild(addButton); - container.insertAdjacentHTML('beforeend',` -
    }
    - `); - container.appendChild(clearButton); - container.appendChild(createButton); - - clearButton.onclick = () => { - propsContainer.innerHTML = ""; //clear options - } - - let addProp = () => { - let prop = document.createElement('div'); - let keyInput = document.createElement('input'); - keyInput.id = 'key'; - let propInput = document.createElement('input'); - let propInputType = document.createElement('select'); - let delProp = document.createElement('button'); - delProp.innerHTML = 'X'; - delProp.onclick = () => { - prop.remove(); - } - propInputType.id = 'ptype'; - Object.keys(inpTypes).forEach((t,i) => { - if(t !== 'functionSpreadArgs') - propInputType.insertAdjacentHTML('beforeend',``) - }); - propInput.id = 'value'; - prop.appendChild(keyInput); - prop.insertAdjacentHTML('beforeend',':'); - prop.appendChild(propInput); - prop.appendChild(propInputType); - prop.appendChild(delProp); - prop.insertAdjacentHTML('beforeend','
    '); - propsContainer.appendChild(prop); - } - - nameInput.value = `node${Math.floor(Math.random()*1000000000000000)}`; - - addButton.onclick = () => { - addProp(); - } - - createButton.onclick = () => { - let keys = Array.from(propsContainer.querySelectorAll('#key')) as any; - let values = Array.from(propsContainer.querySelectorAll('#value')) as any; - let types = Array.from(propsContainer.querySelectorAll('#ptype')) as any; - - let obj = {} as any; - - keys.forEach((k:any,i) => { - if(k.value) { - if((values[i]).value) { - inpTypes[types[i].value](obj, k.value, values[i].value); - } - } - }); - - let node = graph.add(obj); - addNodeToLGraph(node, graph, editor); - - nameInput.value = `node${Math.floor(Math.random()*1000000000000000)}`; - } - - addProp(); - - return container; - -} - - -export let makeNodeEditorMenu = (graph:Graph, editor?:LGraph) => { - - let container = document.createElement('div'); - let nameInput = document.createElement('input'); - let keydropdown = document.createElement('select'); - let constructorInput = document.createElement('input'); - let constructButton = document.createElement('button'); - constructButton.innerHTML = "Set"; - - let nodeEditorContainer = document.createElement('div'); - let propertydropdown = document.createElement('select'); - let propertyInput = document.createElement('input'); - let setProp = document.createElement('button'); - setProp.innerHTML = "Eval" - let propertyInputType = document.createElement('select'); - //let createProxy = document.createElement('button'); - //createProxy.innerHTML = "Create Node"; - - - Object.keys(inpTypes).forEach((t,i) => { - propertyInputType.insertAdjacentHTML('beforeend',``) - }); - - container.insertAdjacentHTML('beforeend',`
    Select existing node: `); - container.appendChild(keydropdown); - //nodeEditorContainer.insertAdjacentHTML('beforeend',`
    Name Node: `); - //nodeEditorContainer.appendChild(nameInput); - nodeEditorContainer.insertAdjacentHTML('beforeend',`
    Class Property: `); - nodeEditorContainer.appendChild(propertydropdown); - nodeEditorContainer.insertAdjacentHTML('beforeend',`
    Property Type: `); - nodeEditorContainer.appendChild(propertyInputType); - nodeEditorContainer.insertAdjacentHTML('beforeend',`
    Input: `); - nodeEditorContainer.appendChild(propertyInput); - nodeEditorContainer.insertAdjacentHTML('beforeend',`
    Set: `); - nodeEditorContainer.appendChild(setProp); - // nodeEditorContainer.insertAdjacentHTML('beforeend',`
    Add to Graph: `); - // nodeEditorContainer.appendChild(createProxy); - nodeEditorContainer.style.display = "none"; - container.appendChild(nodeEditorContainer); - - - let keys = Array.from(graph.__node.nodes.keys()); - for(const key of keys) { - keydropdown.insertAdjacentHTML('beforeend',``); - } - keydropdown.value = ""; - - keydropdown.onchange = (ev) => { - let value = keydropdown.value; - //nodeEditorContainer.style.display = "none"; - //constructButton.onclick = () => { - let args = constructorInput.value as any; - let split = args.split(','); - split.forEach((s,i) => { - if(s.startsWith('function') || s.startsWith('(')) { - parsed[i] = parseFunctionFromText(s); - } - }); - let joined = `[${split.join(',')}]`; - joined = joined.replace(/'/g,'"'); - let parsed = JSON.parse(joined) as any[]; - - //let {proxy, keys} = instantiateProxy(value, parsed); - - let proxy = graph.get(value); - let pkeys = Object.keys(proxy); - - - - propertydropdown.innerHTML = ""; - pkeys.forEach((k) => { - propertydropdown.insertAdjacentHTML('beforeend',``); - }); - - - propertydropdown.onchange = (ev) => { - let t = typeof proxy[propertydropdown.value]; - propertyInputType.value = t === "undefined" ? "string" : t; - if(t !== 'function') { - propertyInput.value = proxy[propertydropdown.value]; - } else propertyInput.value = ""; - } - setProp.onclick = (ev) => { - if(inpTypes[propertyInputType.value]) - inpTypes[propertyInputType.value](proxy, propertydropdown.value, propertyInput.value) - } - // createProxy.onclick = (ev) => { - // let props = { - // __node:nameInput.value ? { - // tag:nameInput.value - // } : undefined, - // __props:proxy - // //todo: could instead list all the non-functional values from proxy here so they get set on the proxy when the node is created - // }; - // let node = graph.add(props); - // addNodeToLGraph(node, graph, editor); - // nameInput.value = `${value}${Math.floor(Math.random()*1000000000000000)}`; - // } - //} - - nodeEditorContainer.style.display = ""; - - } - - return container; - - -} \ No newline at end of file diff --git a/examples/editing/styles.css b/examples/editing/styles.css deleted file mode 100644 index fd5f015b..00000000 --- a/examples/editing/styles.css +++ /dev/null @@ -1,31 +0,0 @@ -body { - margin: 0; - font-family: Arial, sans-serif; - } - - #editor { - position: relative; - width: 100%; - height: 100vh; - background-color: #eee; - } - - .node { - position: absolute; - padding: 10px; - border: 1px solid #444; - background-color: #fff; - cursor: move; - } - - .connection { - position: absolute; - width: 100%; - height: 100%; - } - - .connection-path { - stroke: #555; - stroke-width: 2px; - fill: none; - } \ No newline at end of file diff --git a/examples/editing/worker.ts b/examples/editing/worker.ts deleted file mode 100644 index 2d624555..00000000 --- a/examples/editing/worker.ts +++ /dev/null @@ -1,29 +0,0 @@ - -//functionality -import { WorkerService, workerCanvasRoutes, remoteGraphRoutes } from '../../index'; - -//wonder if we can have a scheme to dynamic import within the services? e.g. to bring in node-only or browser-only services without additional workers - -declare var WorkerGlobalScope; - -if(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) { - (self as any).SERVICE = new WorkerService({ - roots:{ - ...workerCanvasRoutes, - ...remoteGraphRoutes, //allows dynamic route loading - console, - mul:function(a,b) { return a * b; }, - - __listeners:{ - console:{ - mul:{ - __callback:'console.log' - } - } - } - } - }); -} - -export default self as any; - diff --git a/examples/services/http/backend.ts b/examples/httpserver/backend.ts similarity index 89% rename from examples/services/http/backend.ts rename to examples/httpserver/backend.ts index 77dbf649..4b1b251d 100644 --- a/examples/services/http/backend.ts +++ b/examples/httpserver/backend.ts @@ -1,5 +1,5 @@ -import { HTTPbackend, ServerProps, ServerInfo, SSEbackend, SSEProps, WSSbackend, SocketServerProps } from "../../../index.node"//"graphscript-node"; -import { Router } from '../../../src/services/router/Router'; +import { HTTPbackend, ServerProps, ServerInfo, SSEbackend, SSEProps, WSSbackend, SocketServerProps } from "graphscript-node";//"../../index.node"//"graphscript-node"; +import { Router } from '../../services/router/Router'; function exitHandler(options, exitCode) { @@ -19,18 +19,19 @@ const router = new Router({ 'http':HTTPbackend, 'wss':WSSbackend, 'sse':SSEbackend - } + }, + syncServices:true, + loadDefaultRoutes:true }); - let server = router.run( - 'setupServer', + 'http.setupServer', { protocol:'http', host:'localhost', port:8080, pages:{ - '/*':{ + '/':{ template:`
    Nice...
    `, onrequest:(self,node,req,res)=>{ node.get = `

    Hello World!! The Time: ${new Date(Date.now()).toISOString()}

    ` @@ -62,10 +63,10 @@ let server = router.run( if(server instanceof Promise) server.then((served:ServerInfo) => { //this function returns a promise so we can use .then, only explicitly async or promise-returning functions can be awaited or .then'd for good performance! - //console.log(router.__node.nodes.keys()); + console.log(router.nodes.keys()); const socketserver = router.run( - 'setupWSS', + 'wss.setupWSS', { server:served.server, host:served.host, @@ -78,7 +79,7 @@ if(server instanceof Promise) server.then((served:ServerInfo) => { //this functi ); const hotreload = router.run( - 'setupWSS', + 'wss.setupWSS', { server:served.server, host:served.host, @@ -91,7 +92,7 @@ if(server instanceof Promise) server.then((served:ServerInfo) => { //this functi ); const sseinfo = router.run( - 'setupSSE', + 'sse.setupSSE', { server:served.server, path:'sse', diff --git a/examples/httpserver/dist/backend.node.js b/examples/httpserver/dist/backend.node.js new file mode 100644 index 00000000..bb45cebc --- /dev/null +++ b/examples/httpserver/dist/backend.node.js @@ -0,0 +1,24260 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); + +// node_modules/node-gyp-build/index.js +var require_node_gyp_build = __commonJS({ + "node_modules/node-gyp-build/index.js"(exports, module2) { + var fs = require("fs"); + var path = require("path"); + var os = require("os"); + var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require; + var vars = process.config && process.config.variables || {}; + var prebuildsOnly = !!process.env.PREBUILDS_ONLY; + var abi = process.versions.modules; + var runtime = isElectron() ? "electron" : isNwjs() ? "node-webkit" : "node"; + var arch = process.env.npm_config_arch || os.arch(); + var platform = process.env.npm_config_platform || os.platform(); + var libc = process.env.LIBC || (isAlpine(platform) ? "musl" : "glibc"); + var armv = process.env.ARM_VERSION || (arch === "arm64" ? "8" : vars.arm_version) || ""; + var uv = (process.versions.uv || "").split(".")[0]; + module2.exports = load; + function load(dir) { + return runtimeRequire(load.path(dir)); + } + load.path = function(dir) { + dir = path.resolve(dir || "."); + try { + var name2 = runtimeRequire(path.join(dir, "package.json")).name.toUpperCase().replace(/-/g, "_"); + if (process.env[name2 + "_PREBUILD"]) + dir = process.env[name2 + "_PREBUILD"]; + } catch (err) { + } + if (!prebuildsOnly) { + var release = getFirst(path.join(dir, "build/Release"), matchBuild); + if (release) + return release; + var debug = getFirst(path.join(dir, "build/Debug"), matchBuild); + if (debug) + return debug; + } + var prebuild = resolve(dir); + if (prebuild) + return prebuild; + var nearby = resolve(path.dirname(process.execPath)); + if (nearby) + return nearby; + var target = [ + "platform=" + platform, + "arch=" + arch, + "runtime=" + runtime, + "abi=" + abi, + "uv=" + uv, + armv ? "armv=" + armv : "", + "libc=" + libc, + "node=" + process.versions.node, + process.versions.electron ? "electron=" + process.versions.electron : "", + typeof __webpack_require__ === "function" ? "webpack=true" : "" + ].filter(Boolean).join(" "); + throw new Error("No native build was found for " + target + "\n loaded from: " + dir + "\n"); + function resolve(dir2) { + var tuples = readdirSync(path.join(dir2, "prebuilds")).map(parseTuple); + var tuple = tuples.filter(matchTuple(platform, arch)).sort(compareTuples)[0]; + if (!tuple) + return; + var prebuilds = path.join(dir2, "prebuilds", tuple.name); + var parsed = readdirSync(prebuilds).map(parseTags); + var candidates = parsed.filter(matchTags(runtime, abi)); + var winner = candidates.sort(compareTags(runtime))[0]; + if (winner) + return path.join(prebuilds, winner.file); + } + }; + function readdirSync(dir) { + try { + return fs.readdirSync(dir); + } catch (err) { + return []; + } + } + function getFirst(dir, filter) { + var files = readdirSync(dir).filter(filter); + return files[0] && path.join(dir, files[0]); + } + function matchBuild(name2) { + return /\.node$/.test(name2); + } + function parseTuple(name2) { + var arr = name2.split("-"); + if (arr.length !== 2) + return; + var platform2 = arr[0]; + var architectures = arr[1].split("+"); + if (!platform2) + return; + if (!architectures.length) + return; + if (!architectures.every(Boolean)) + return; + return { name: name2, platform: platform2, architectures }; + } + function matchTuple(platform2, arch2) { + return function(tuple) { + if (tuple == null) + return false; + if (tuple.platform !== platform2) + return false; + return tuple.architectures.includes(arch2); + }; + } + function compareTuples(a, b) { + return a.architectures.length - b.architectures.length; + } + function parseTags(file) { + var arr = file.split("."); + var extension = arr.pop(); + var tags = { file, specificity: 0 }; + if (extension !== "node") + return; + for (var i = 0; i < arr.length; i++) { + var tag = arr[i]; + if (tag === "node" || tag === "electron" || tag === "node-webkit") { + tags.runtime = tag; + } else if (tag === "napi") { + tags.napi = true; + } else if (tag.slice(0, 3) === "abi") { + tags.abi = tag.slice(3); + } else if (tag.slice(0, 2) === "uv") { + tags.uv = tag.slice(2); + } else if (tag.slice(0, 4) === "armv") { + tags.armv = tag.slice(4); + } else if (tag === "glibc" || tag === "musl") { + tags.libc = tag; + } else { + continue; + } + tags.specificity++; + } + return tags; + } + function matchTags(runtime2, abi2) { + return function(tags) { + if (tags == null) + return false; + if (tags.runtime !== runtime2 && !runtimeAgnostic(tags)) + return false; + if (tags.abi !== abi2 && !tags.napi) + return false; + if (tags.uv && tags.uv !== uv) + return false; + if (tags.armv && tags.armv !== armv) + return false; + if (tags.libc && tags.libc !== libc) + return false; + return true; + }; + } + function runtimeAgnostic(tags) { + return tags.runtime === "node" && tags.napi; + } + function compareTags(runtime2) { + return function(a, b) { + if (a.runtime !== b.runtime) { + return a.runtime === runtime2 ? -1 : 1; + } else if (a.abi !== b.abi) { + return a.abi ? -1 : 1; + } else if (a.specificity !== b.specificity) { + return a.specificity > b.specificity ? -1 : 1; + } else { + return 0; + } + }; + } + function isNwjs() { + return !!(process.versions && process.versions.nw); + } + function isElectron() { + if (process.versions && process.versions.electron) + return true; + if (process.env.ELECTRON_RUN_AS_NODE) + return true; + return typeof window !== "undefined" && window.process && window.process.type === "renderer"; + } + function isAlpine(platform2) { + return platform2 === "linux" && fs.existsSync("/etc/alpine-release"); + } + load.parseTags = parseTags; + load.matchTags = matchTags; + load.compareTags = compareTags; + load.parseTuple = parseTuple; + load.matchTuple = matchTuple; + load.compareTuples = compareTuples; + } +}); + +// node_modules/bufferutil/fallback.js +var require_fallback = __commonJS({ + "node_modules/bufferutil/fallback.js"(exports, module2) { + "use strict"; + var mask = (source, mask2, output, offset, length) => { + for (var i = 0; i < length; i++) { + output[offset + i] = source[i] ^ mask2[i & 3]; + } + }; + var unmask = (buffer, mask2) => { + const length = buffer.length; + for (var i = 0; i < length; i++) { + buffer[i] ^= mask2[i & 3]; + } + }; + module2.exports = { mask, unmask }; + } +}); + +// node_modules/bufferutil/index.js +var require_bufferutil = __commonJS({ + "node_modules/bufferutil/index.js"(exports, module2) { + "use strict"; + try { + module2.exports = require_node_gyp_build()(__dirname); + } catch (e) { + module2.exports = require_fallback(); + } + } +}); + +// node_modules/utf-8-validate/fallback.js +var require_fallback2 = __commonJS({ + "node_modules/utf-8-validate/fallback.js"(exports, module2) { + "use strict"; + function isValidUTF8(buf) { + const len = buf.length; + let i = 0; + while (i < len) { + if ((buf[i] & 128) === 0) { + i++; + } else if ((buf[i] & 224) === 192) { + if (i + 1 === len || (buf[i + 1] & 192) !== 128 || (buf[i] & 254) === 192) { + return false; + } + i += 2; + } else if ((buf[i] & 240) === 224) { + if (i + 2 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || buf[i] === 224 && (buf[i + 1] & 224) === 128 || buf[i] === 237 && (buf[i + 1] & 224) === 160) { + return false; + } + i += 3; + } else if ((buf[i] & 248) === 240) { + if (i + 3 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || (buf[i + 3] & 192) !== 128 || buf[i] === 240 && (buf[i + 1] & 240) === 128 || buf[i] === 244 && buf[i + 1] > 143 || buf[i] > 244) { + return false; + } + i += 4; + } else { + return false; + } + } + return true; + } + module2.exports = isValidUTF8; + } +}); + +// node_modules/utf-8-validate/index.js +var require_utf_8_validate = __commonJS({ + "node_modules/utf-8-validate/index.js"(exports, module2) { + "use strict"; + try { + module2.exports = require_node_gyp_build()(__dirname); + } catch (e) { + module2.exports = require_fallback2(); + } + } +}); + +// node_modules/graphscript-node/dist/index.node.js +var require_index_node = __commonJS({ + "node_modules/graphscript-node/dist/index.node.js"(exports, module2) { + var __create2 = Object.create; + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __getProtoOf2 = Object.getPrototypeOf; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __defNormalProp = (obj, key, value2) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value: value2 }) : obj[key] = value2; + var __commonJS2 = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames2(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + }; + var __export = (target, all) => { + for (var name2 in all) + __defProp2(target, name2, { get: all[name2], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2(isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, mod)); + var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var __publicField = (obj, key, value2) => { + __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value2); + return value2; + }; + var require_sjcl = __commonJS2({ "services/e2ee/sjcl.js"(exports2, module22) { + "use strict"; + var sjcl2 = { cipher: {}, hash: {}, keyexchange: {}, mode: {}, misc: {}, codec: {}, exception: { corrupt: function(a) { + this.toString = function() { + return "CORRUPT: " + this.message; + }; + this.message = a; + }, invalid: function(a) { + this.toString = function() { + return "INVALID: " + this.message; + }; + this.message = a; + }, bug: function(a) { + this.toString = function() { + return "BUG: " + this.message; + }; + this.message = a; + }, notReady: function(a) { + this.toString = function() { + return "NOT READY: " + this.message; + }; + this.message = a; + } } }; + sjcl2.cipher.aes = function(a) { + this.s[0][0][0] || this.O(); + var b, c, d, e, f = this.s[0][4], g = this.s[1]; + b = a.length; + var h = 1; + if (4 !== b && 6 !== b && 8 !== b) + throw new sjcl2.exception.invalid("invalid aes key size"); + this.b = [d = a.slice(0), e = []]; + for (a = b; a < 4 * b + 28; a++) { + c = d[a - 1]; + if (0 === a % b || 8 === b && 4 === a % b) + c = f[c >>> 24] << 24 ^ f[c >> 16 & 255] << 16 ^ f[c >> 8 & 255] << 8 ^ f[c & 255], 0 === a % b && (c = c << 8 ^ c >>> 24 ^ h << 24, h = h << 1 ^ 283 * (h >> 7)); + d[a] = d[a - b] ^ c; + } + for (b = 0; a; b++, a--) + c = d[b & 3 ? a : a - 4], e[b] = 4 >= a || 4 > b ? c : g[0][f[c >>> 24]] ^ g[1][f[c >> 16 & 255]] ^ g[2][f[c >> 8 & 255]] ^ g[3][f[c & 255]]; + }; + sjcl2.cipher.aes.prototype = { encrypt: function(a) { + return t(this, a, 0); + }, decrypt: function(a) { + return t(this, a, 1); + }, s: [[[], [], [], [], []], [[], [], [], [], []]], O: function() { + var a = this.s[0], b = this.s[1], c = a[4], d = b[4], e, f, g, h = [], k = [], l, n, m, p; + for (e = 0; 256 > e; e++) + k[(h[e] = e << 1 ^ 283 * (e >> 7)) ^ e] = e; + for (f = g = 0; !c[f]; f ^= l || 1, g = k[g] || 1) + for (m = g ^ g << 1 ^ g << 2 ^ g << 3 ^ g << 4, m = m >> 8 ^ m & 255 ^ 99, c[f] = m, d[m] = f, n = h[e = h[l = h[f]]], p = 16843009 * n ^ 65537 * e ^ 257 * l ^ 16843008 * f, n = 257 * h[m] ^ 16843008 * m, e = 0; 4 > e; e++) + a[e][f] = n = n << 24 ^ n >>> 8, b[e][m] = p = p << 24 ^ p >>> 8; + for (e = 0; 5 > e; e++) + a[e] = a[e].slice(0), b[e] = b[e].slice(0); + } }; + function t(a, b, c) { + if (4 !== b.length) + throw new sjcl2.exception.invalid("invalid aes block size"); + var d = a.b[c], e = b[0] ^ d[0], f = b[c ? 3 : 1] ^ d[1], g = b[2] ^ d[2]; + b = b[c ? 1 : 3] ^ d[3]; + var h, k, l, n = d.length / 4 - 2, m, p = 4, r = [0, 0, 0, 0]; + h = a.s[c]; + a = h[0]; + var q = h[1], v = h[2], w = h[3], x2 = h[4]; + for (m = 0; m < n; m++) + h = a[e >>> 24] ^ q[f >> 16 & 255] ^ v[g >> 8 & 255] ^ w[b & 255] ^ d[p], k = a[f >>> 24] ^ q[g >> 16 & 255] ^ v[b >> 8 & 255] ^ w[e & 255] ^ d[p + 1], l = a[g >>> 24] ^ q[b >> 16 & 255] ^ v[e >> 8 & 255] ^ w[f & 255] ^ d[p + 2], b = a[b >>> 24] ^ q[e >> 16 & 255] ^ v[f >> 8 & 255] ^ w[g & 255] ^ d[p + 3], p += 4, e = h, f = k, g = l; + for (m = 0; 4 > m; m++) + r[c ? 3 & -m : m] = x2[e >>> 24] << 24 ^ x2[f >> 16 & 255] << 16 ^ x2[g >> 8 & 255] << 8 ^ x2[b & 255] ^ d[p++], h = e, e = f, f = g, g = b, b = h; + return r; + } + sjcl2.bitArray = { bitSlice: function(a, b, c) { + a = sjcl2.bitArray.$(a.slice(b / 32), 32 - (b & 31)).slice(1); + return void 0 === c ? a : sjcl2.bitArray.clamp(a, c - b); + }, extract: function(a, b, c) { + var d = Math.floor(-b - c & 31); + return ((b + c - 1 ^ b) & -32 ? a[b / 32 | 0] << 32 - d ^ a[b / 32 + 1 | 0] >>> d : a[b / 32 | 0] >>> d) & (1 << c) - 1; + }, concat: function(a, b) { + if (0 === a.length || 0 === b.length) + return a.concat(b); + var c = a[a.length - 1], d = sjcl2.bitArray.getPartial(c); + return 32 === d ? a.concat(b) : sjcl2.bitArray.$(b, d, c | 0, a.slice(0, a.length - 1)); + }, bitLength: function(a) { + var b = a.length; + return 0 === b ? 0 : 32 * (b - 1) + sjcl2.bitArray.getPartial(a[b - 1]); + }, clamp: function(a, b) { + if (32 * a.length < b) + return a; + a = a.slice(0, Math.ceil(b / 32)); + var c = a.length; + b = b & 31; + 0 < c && b && (a[c - 1] = sjcl2.bitArray.partial(b, a[c - 1] & 2147483648 >> b - 1, 1)); + return a; + }, partial: function(a, b, c) { + return 32 === a ? b : (c ? b | 0 : b << 32 - a) + 1099511627776 * a; + }, getPartial: function(a) { + return Math.round(a / 1099511627776) || 32; + }, equal: function(a, b) { + if (sjcl2.bitArray.bitLength(a) !== sjcl2.bitArray.bitLength(b)) + return false; + var c = 0, d; + for (d = 0; d < a.length; d++) + c |= a[d] ^ b[d]; + return 0 === c; + }, $: function(a, b, c, d) { + var e; + e = 0; + for (void 0 === d && (d = []); 32 <= b; b -= 32) + d.push(c), c = 0; + if (0 === b) + return d.concat(a); + for (e = 0; e < a.length; e++) + d.push(c | a[e] >>> b), c = a[e] << 32 - b; + e = a.length ? a[a.length - 1] : 0; + a = sjcl2.bitArray.getPartial(e); + d.push(sjcl2.bitArray.partial(b + a & 31, 32 < b + a ? c : d.pop(), 1)); + return d; + }, i: function(a, b) { + return [a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3]]; + }, byteswapM: function(a) { + var b, c; + for (b = 0; b < a.length; ++b) + c = a[b], a[b] = c >>> 24 | c >>> 8 & 65280 | (c & 65280) << 8 | c << 24; + return a; + } }; + sjcl2.codec.utf8String = { fromBits: function(a) { + var b = "", c = sjcl2.bitArray.bitLength(a), d, e; + for (d = 0; d < c / 8; d++) + 0 === (d & 3) && (e = a[d / 4]), b += String.fromCharCode(e >>> 8 >>> 8 >>> 8), e <<= 8; + return decodeURIComponent(escape(b)); + }, toBits: function(a) { + a = unescape(encodeURIComponent(a)); + var b = [], c, d = 0; + for (c = 0; c < a.length; c++) + d = d << 8 | a.charCodeAt(c), 3 === (c & 3) && (b.push(d), d = 0); + c & 3 && b.push(sjcl2.bitArray.partial(8 * (c & 3), d)); + return b; + } }; + sjcl2.codec.hex = { fromBits: function(a) { + var b = "", c; + for (c = 0; c < a.length; c++) + b += ((a[c] | 0) + 263882790666240).toString(16).substr(4); + return b.substr(0, sjcl2.bitArray.bitLength(a) / 4); + }, toBits: function(a) { + var b, c = [], d; + a = a.replace(/\s|0x/g, ""); + d = a.length; + a = a + "00000000"; + for (b = 0; b < a.length; b += 8) + c.push(parseInt(a.substr(b, 8), 16) ^ 0); + return sjcl2.bitArray.clamp(c, 4 * d); + } }; + sjcl2.codec.base32 = { B: "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", X: "0123456789ABCDEFGHIJKLMNOPQRSTUV", BITS: 32, BASE: 5, REMAINING: 27, fromBits: function(a, b, c) { + var d = sjcl2.codec.base32.BASE, e = sjcl2.codec.base32.REMAINING, f = "", g = 0, h = sjcl2.codec.base32.B, k = 0, l = sjcl2.bitArray.bitLength(a); + c && (h = sjcl2.codec.base32.X); + for (c = 0; f.length * d < l; ) + f += h.charAt((k ^ a[c] >>> g) >>> e), g < d ? (k = a[c] << d - g, g += e, c++) : (k <<= d, g -= d); + for (; f.length & 7 && !b; ) + f += "="; + return f; + }, toBits: function(a, b) { + a = a.replace(/\s|=/g, "").toUpperCase(); + var c = sjcl2.codec.base32.BITS, d = sjcl2.codec.base32.BASE, e = sjcl2.codec.base32.REMAINING, f = [], g, h = 0, k = sjcl2.codec.base32.B, l = 0, n, m = "base32"; + b && (k = sjcl2.codec.base32.X, m = "base32hex"); + for (g = 0; g < a.length; g++) { + n = k.indexOf(a.charAt(g)); + if (0 > n) { + if (!b) + try { + return sjcl2.codec.base32hex.toBits(a); + } catch (p) { + } + throw new sjcl2.exception.invalid("this isn't " + m + "!"); + } + h > e ? (h -= e, f.push(l ^ n >>> h), l = n << c - h) : (h += d, l ^= n << c - h); + } + h & 56 && f.push(sjcl2.bitArray.partial(h & 56, l, 1)); + return f; + } }; + sjcl2.codec.base32hex = { fromBits: function(a, b) { + return sjcl2.codec.base32.fromBits(a, b, 1); + }, toBits: function(a) { + return sjcl2.codec.base32.toBits(a, 1); + } }; + sjcl2.codec.base64 = { B: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", fromBits: function(a, b, c) { + var d = "", e = 0, f = sjcl2.codec.base64.B, g = 0, h = sjcl2.bitArray.bitLength(a); + c && (f = f.substr(0, 62) + "-_"); + for (c = 0; 6 * d.length < h; ) + d += f.charAt((g ^ a[c] >>> e) >>> 26), 6 > e ? (g = a[c] << 6 - e, e += 26, c++) : (g <<= 6, e -= 6); + for (; d.length & 3 && !b; ) + d += "="; + return d; + }, toBits: function(a, b) { + a = a.replace(/\s|=/g, ""); + var c = [], d, e = 0, f = sjcl2.codec.base64.B, g = 0, h; + b && (f = f.substr(0, 62) + "-_"); + for (d = 0; d < a.length; d++) { + h = f.indexOf(a.charAt(d)); + if (0 > h) + throw new sjcl2.exception.invalid("this isn't base64!"); + 26 < e ? (e -= 26, c.push(g ^ h >>> e), g = h << 32 - e) : (e += 6, g ^= h << 32 - e); + } + e & 56 && c.push(sjcl2.bitArray.partial(e & 56, g, 1)); + return c; + } }; + sjcl2.codec.base64url = { fromBits: function(a) { + return sjcl2.codec.base64.fromBits(a, 1, 1); + }, toBits: function(a) { + return sjcl2.codec.base64.toBits(a, 1); + } }; + sjcl2.hash.sha256 = function(a) { + this.b[0] || this.O(); + a ? (this.F = a.F.slice(0), this.A = a.A.slice(0), this.l = a.l) : this.reset(); + }; + sjcl2.hash.sha256.hash = function(a) { + return new sjcl2.hash.sha256().update(a).finalize(); + }; + sjcl2.hash.sha256.prototype = { blockSize: 512, reset: function() { + this.F = this.Y.slice(0); + this.A = []; + this.l = 0; + return this; + }, update: function(a) { + "string" === typeof a && (a = sjcl2.codec.utf8String.toBits(a)); + var b, c = this.A = sjcl2.bitArray.concat(this.A, a); + b = this.l; + a = this.l = b + sjcl2.bitArray.bitLength(a); + if (9007199254740991 < a) + throw new sjcl2.exception.invalid("Cannot hash more than 2^53 - 1 bits"); + if ("undefined" !== typeof Uint32Array) { + var d = new Uint32Array(c), e = 0; + for (b = 512 + b - (512 + b & 511); b <= a; b += 512) + u(this, d.subarray(16 * e, 16 * (e + 1))), e += 1; + c.splice(0, 16 * e); + } else + for (b = 512 + b - (512 + b & 511); b <= a; b += 512) + u(this, c.splice(0, 16)); + return this; + }, finalize: function() { + var a, b = this.A, c = this.F, b = sjcl2.bitArray.concat(b, [sjcl2.bitArray.partial(1, 1)]); + for (a = b.length + 2; a & 15; a++) + b.push(0); + b.push(Math.floor(this.l / 4294967296)); + for (b.push(this.l | 0); b.length; ) + u(this, b.splice(0, 16)); + this.reset(); + return c; + }, Y: [], b: [], O: function() { + function a(a2) { + return 4294967296 * (a2 - Math.floor(a2)) | 0; + } + for (var b = 0, c = 2, d, e; 64 > b; c++) { + e = true; + for (d = 2; d * d <= c; d++) + if (0 === c % d) { + e = false; + break; + } + e && (8 > b && (this.Y[b] = a(Math.pow(c, 0.5))), this.b[b] = a(Math.pow(c, 1 / 3)), b++); + } + } }; + function u(a, b) { + var c, d, e, f = a.F, g = a.b, h = f[0], k = f[1], l = f[2], n = f[3], m = f[4], p = f[5], r = f[6], q = f[7]; + for (c = 0; 64 > c; c++) + 16 > c ? d = b[c] : (d = b[c + 1 & 15], e = b[c + 14 & 15], d = b[c & 15] = (d >>> 7 ^ d >>> 18 ^ d >>> 3 ^ d << 25 ^ d << 14) + (e >>> 17 ^ e >>> 19 ^ e >>> 10 ^ e << 15 ^ e << 13) + b[c & 15] + b[c + 9 & 15] | 0), d = d + q + (m >>> 6 ^ m >>> 11 ^ m >>> 25 ^ m << 26 ^ m << 21 ^ m << 7) + (r ^ m & (p ^ r)) + g[c], q = r, r = p, p = m, m = n + d | 0, n = l, l = k, k = h, h = d + (k & l ^ n & (k ^ l)) + (k >>> 2 ^ k >>> 13 ^ k >>> 22 ^ k << 30 ^ k << 19 ^ k << 10) | 0; + f[0] = f[0] + h | 0; + f[1] = f[1] + k | 0; + f[2] = f[2] + l | 0; + f[3] = f[3] + n | 0; + f[4] = f[4] + m | 0; + f[5] = f[5] + p | 0; + f[6] = f[6] + r | 0; + f[7] = f[7] + q | 0; + } + sjcl2.mode.ccm = { name: "ccm", G: [], listenProgress: function(a) { + sjcl2.mode.ccm.G.push(a); + }, unListenProgress: function(a) { + a = sjcl2.mode.ccm.G.indexOf(a); + -1 < a && sjcl2.mode.ccm.G.splice(a, 1); + }, fa: function(a) { + var b = sjcl2.mode.ccm.G.slice(), c; + for (c = 0; c < b.length; c += 1) + b[c](a); + }, encrypt: function(a, b, c, d, e) { + var f, g = b.slice(0), h = sjcl2.bitArray, k = h.bitLength(c) / 8, l = h.bitLength(g) / 8; + e = e || 64; + d = d || []; + if (7 > k) + throw new sjcl2.exception.invalid("ccm: iv must be at least 7 bytes"); + for (f = 2; 4 > f && l >>> 8 * f; f++) + ; + f < 15 - k && (f = 15 - k); + c = h.clamp(c, 8 * (15 - f)); + b = sjcl2.mode.ccm.V(a, b, c, d, e, f); + g = sjcl2.mode.ccm.C(a, g, c, b, e, f); + return h.concat(g.data, g.tag); + }, decrypt: function(a, b, c, d, e) { + e = e || 64; + d = d || []; + var f = sjcl2.bitArray, g = f.bitLength(c) / 8, h = f.bitLength(b), k = f.clamp(b, h - e), l = f.bitSlice(b, h - e), h = (h - e) / 8; + if (7 > g) + throw new sjcl2.exception.invalid("ccm: iv must be at least 7 bytes"); + for (b = 2; 4 > b && h >>> 8 * b; b++) + ; + b < 15 - g && (b = 15 - g); + c = f.clamp(c, 8 * (15 - b)); + k = sjcl2.mode.ccm.C(a, k, c, l, e, b); + a = sjcl2.mode.ccm.V(a, k.data, c, d, e, b); + if (!f.equal(k.tag, a)) + throw new sjcl2.exception.corrupt("ccm: tag doesn't match"); + return k.data; + }, na: function(a, b, c, d, e, f) { + var g = [], h = sjcl2.bitArray, k = h.i; + d = [h.partial(8, (b.length ? 64 : 0) | d - 2 << 2 | f - 1)]; + d = h.concat(d, c); + d[3] |= e; + d = a.encrypt(d); + if (b.length) + for (c = h.bitLength(b) / 8, 65279 >= c ? g = [h.partial(16, c)] : 4294967295 >= c && (g = h.concat([h.partial(16, 65534)], [c])), g = h.concat(g, b), b = 0; b < g.length; b += 4) + d = a.encrypt(k(d, g.slice(b, b + 4).concat([0, 0, 0]))); + return d; + }, V: function(a, b, c, d, e, f) { + var g = sjcl2.bitArray, h = g.i; + e /= 8; + if (e % 2 || 4 > e || 16 < e) + throw new sjcl2.exception.invalid("ccm: invalid tag length"); + if (4294967295 < d.length || 4294967295 < b.length) + throw new sjcl2.exception.bug("ccm: can't deal with 4GiB or more data"); + c = sjcl2.mode.ccm.na(a, d, c, e, g.bitLength(b) / 8, f); + for (d = 0; d < b.length; d += 4) + c = a.encrypt(h(c, b.slice(d, d + 4).concat([0, 0, 0]))); + return g.clamp(c, 8 * e); + }, C: function(a, b, c, d, e, f) { + var g, h = sjcl2.bitArray; + g = h.i; + var k = b.length, l = h.bitLength(b), n = k / 50, m = n; + c = h.concat([h.partial(8, f - 1)], c).concat([0, 0, 0]).slice(0, 4); + d = h.bitSlice(g(d, a.encrypt(c)), 0, e); + if (!k) + return { tag: d, data: [] }; + for (g = 0; g < k; g += 4) + g > n && (sjcl2.mode.ccm.fa(g / k), n += m), c[3]++, e = a.encrypt(c), b[g] ^= e[0], b[g + 1] ^= e[1], b[g + 2] ^= e[2], b[g + 3] ^= e[3]; + return { tag: d, data: h.clamp(b, l) }; + } }; + sjcl2.mode.ocb2 = { name: "ocb2", encrypt: function(a, b, c, d, e, f) { + if (128 !== sjcl2.bitArray.bitLength(c)) + throw new sjcl2.exception.invalid("ocb iv must be 128 bits"); + var g, h = sjcl2.mode.ocb2.S, k = sjcl2.bitArray, l = k.i, n = [0, 0, 0, 0]; + c = h(a.encrypt(c)); + var m, p = []; + d = d || []; + e = e || 64; + for (g = 0; g + 4 < b.length; g += 4) + m = b.slice(g, g + 4), n = l(n, m), p = p.concat(l(c, a.encrypt(l(c, m)))), c = h(c); + m = b.slice(g); + b = k.bitLength(m); + g = a.encrypt(l(c, [0, 0, 0, b])); + m = k.clamp(l(m.concat([0, 0, 0]), g), b); + n = l(n, l(m.concat([0, 0, 0]), g)); + n = a.encrypt(l(n, l(c, h(c)))); + d.length && (n = l(n, f ? d : sjcl2.mode.ocb2.pmac(a, d))); + return p.concat(k.concat(m, k.clamp(n, e))); + }, decrypt: function(a, b, c, d, e, f) { + if (128 !== sjcl2.bitArray.bitLength(c)) + throw new sjcl2.exception.invalid("ocb iv must be 128 bits"); + e = e || 64; + var g = sjcl2.mode.ocb2.S, h = sjcl2.bitArray, k = h.i, l = [0, 0, 0, 0], n = g(a.encrypt(c)), m, p, r = sjcl2.bitArray.bitLength(b) - e, q = []; + d = d || []; + for (c = 0; c + 4 < r / 32; c += 4) + m = k(n, a.decrypt(k(n, b.slice(c, c + 4)))), l = k(l, m), q = q.concat(m), n = g(n); + p = r - 32 * c; + m = a.encrypt(k(n, [0, 0, 0, p])); + m = k(m, h.clamp(b.slice(c), p).concat([0, 0, 0])); + l = k(l, m); + l = a.encrypt(k(l, k(n, g(n)))); + d.length && (l = k(l, f ? d : sjcl2.mode.ocb2.pmac(a, d))); + if (!h.equal(h.clamp(l, e), h.bitSlice(b, r))) + throw new sjcl2.exception.corrupt("ocb: tag doesn't match"); + return q.concat(h.clamp(m, p)); + }, pmac: function(a, b) { + var c, d = sjcl2.mode.ocb2.S, e = sjcl2.bitArray, f = e.i, g = [0, 0, 0, 0], h = a.encrypt([0, 0, 0, 0]), h = f(h, d(d(h))); + for (c = 0; c + 4 < b.length; c += 4) + h = d(h), g = f(g, a.encrypt(f(h, b.slice(c, c + 4)))); + c = b.slice(c); + 128 > e.bitLength(c) && (h = f(h, d(h)), c = e.concat(c, [-2147483648, 0, 0, 0])); + g = f(g, c); + return a.encrypt(f(d(f(h, d(h))), g)); + }, S: function(a) { + return [a[0] << 1 ^ a[1] >>> 31, a[1] << 1 ^ a[2] >>> 31, a[2] << 1 ^ a[3] >>> 31, a[3] << 1 ^ 135 * (a[0] >>> 31)]; + } }; + sjcl2.mode.gcm = { name: "gcm", encrypt: function(a, b, c, d, e) { + var f = b.slice(0); + b = sjcl2.bitArray; + d = d || []; + a = sjcl2.mode.gcm.C(true, a, f, d, c, e || 128); + return b.concat(a.data, a.tag); + }, decrypt: function(a, b, c, d, e) { + var f = b.slice(0), g = sjcl2.bitArray, h = g.bitLength(f); + e = e || 128; + d = d || []; + e <= h ? (b = g.bitSlice(f, h - e), f = g.bitSlice(f, 0, h - e)) : (b = f, f = []); + a = sjcl2.mode.gcm.C(false, a, f, d, c, e); + if (!g.equal(a.tag, b)) + throw new sjcl2.exception.corrupt("gcm: tag doesn't match"); + return a.data; + }, ka: function(a, b) { + var c, d, e, f, g, h = sjcl2.bitArray.i; + e = [0, 0, 0, 0]; + f = b.slice(0); + for (c = 0; 128 > c; c++) { + (d = 0 !== (a[Math.floor(c / 32)] & 1 << 31 - c % 32)) && (e = h(e, f)); + g = 0 !== (f[3] & 1); + for (d = 3; 0 < d; d--) + f[d] = f[d] >>> 1 | (f[d - 1] & 1) << 31; + f[0] >>>= 1; + g && (f[0] ^= -520093696); + } + return e; + }, j: function(a, b, c) { + var d, e = c.length; + b = b.slice(0); + for (d = 0; d < e; d += 4) + b[0] ^= 4294967295 & c[d], b[1] ^= 4294967295 & c[d + 1], b[2] ^= 4294967295 & c[d + 2], b[3] ^= 4294967295 & c[d + 3], b = sjcl2.mode.gcm.ka(b, a); + return b; + }, C: function(a, b, c, d, e, f) { + var g, h, k, l, n, m, p, r, q = sjcl2.bitArray; + m = c.length; + p = q.bitLength(c); + r = q.bitLength(d); + h = q.bitLength(e); + g = b.encrypt([0, 0, 0, 0]); + 96 === h ? (e = e.slice(0), e = q.concat(e, [1])) : (e = sjcl2.mode.gcm.j(g, [0, 0, 0, 0], e), e = sjcl2.mode.gcm.j(g, e, [0, 0, Math.floor(h / 4294967296), h & 4294967295])); + h = sjcl2.mode.gcm.j(g, [0, 0, 0, 0], d); + n = e.slice(0); + d = h.slice(0); + a || (d = sjcl2.mode.gcm.j(g, h, c)); + for (l = 0; l < m; l += 4) + n[3]++, k = b.encrypt(n), c[l] ^= k[0], c[l + 1] ^= k[1], c[l + 2] ^= k[2], c[l + 3] ^= k[3]; + c = q.clamp(c, p); + a && (d = sjcl2.mode.gcm.j(g, h, c)); + a = [Math.floor(r / 4294967296), r & 4294967295, Math.floor(p / 4294967296), p & 4294967295]; + d = sjcl2.mode.gcm.j(g, d, a); + k = b.encrypt(e); + d[0] ^= k[0]; + d[1] ^= k[1]; + d[2] ^= k[2]; + d[3] ^= k[3]; + return { tag: q.bitSlice(d, 0, f), data: c }; + } }; + sjcl2.misc.hmac = function(a, b) { + this.W = b = b || sjcl2.hash.sha256; + var c = [[], []], d, e = b.prototype.blockSize / 32; + this.w = [new b(), new b()]; + a.length > e && (a = b.hash(a)); + for (d = 0; d < e; d++) + c[0][d] = a[d] ^ 909522486, c[1][d] = a[d] ^ 1549556828; + this.w[0].update(c[0]); + this.w[1].update(c[1]); + this.R = new b(this.w[0]); + }; + sjcl2.misc.hmac.prototype.encrypt = sjcl2.misc.hmac.prototype.mac = function(a) { + if (this.aa) + throw new sjcl2.exception.invalid("encrypt on already updated hmac called!"); + this.update(a); + return this.digest(a); + }; + sjcl2.misc.hmac.prototype.reset = function() { + this.R = new this.W(this.w[0]); + this.aa = false; + }; + sjcl2.misc.hmac.prototype.update = function(a) { + this.aa = true; + this.R.update(a); + }; + sjcl2.misc.hmac.prototype.digest = function() { + var a = this.R.finalize(), a = new this.W(this.w[1]).update(a).finalize(); + this.reset(); + return a; + }; + sjcl2.misc.pbkdf2 = function(a, b, c, d, e) { + c = c || 1e4; + if (0 > d || 0 > c) + throw new sjcl2.exception.invalid("invalid params to pbkdf2"); + "string" === typeof a && (a = sjcl2.codec.utf8String.toBits(a)); + "string" === typeof b && (b = sjcl2.codec.utf8String.toBits(b)); + e = e || sjcl2.misc.hmac; + a = new e(a); + var f, g, h, k, l = [], n = sjcl2.bitArray; + for (k = 1; 32 * l.length < (d || 1); k++) { + e = f = a.encrypt(n.concat(b, [k])); + for (g = 1; g < c; g++) + for (f = a.encrypt(f), h = 0; h < f.length; h++) + e[h] ^= f[h]; + l = l.concat(e); + } + d && (l = n.clamp(l, d)); + return l; + }; + sjcl2.prng = function(a) { + this.c = [new sjcl2.hash.sha256()]; + this.m = [0]; + this.P = 0; + this.H = {}; + this.N = 0; + this.U = {}; + this.Z = this.f = this.o = this.ha = 0; + this.b = [0, 0, 0, 0, 0, 0, 0, 0]; + this.h = [0, 0, 0, 0]; + this.L = void 0; + this.M = a; + this.D = false; + this.K = { progress: {}, seeded: {} }; + this.u = this.ga = 0; + this.I = 1; + this.J = 2; + this.ca = 65536; + this.T = [0, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024]; + this.da = 3e4; + this.ba = 80; + }; + sjcl2.prng.prototype = { randomWords: function(a, b) { + var c = [], d; + d = this.isReady(b); + var e; + if (d === this.u) + throw new sjcl2.exception.notReady("generator isn't seeded"); + if (d & this.J) { + d = !(d & this.I); + e = []; + var f = 0, g; + this.Z = e[0] = new Date().valueOf() + this.da; + for (g = 0; 16 > g; g++) + e.push(4294967296 * Math.random() | 0); + for (g = 0; g < this.c.length && (e = e.concat(this.c[g].finalize()), f += this.m[g], this.m[g] = 0, d || !(this.P & 1 << g)); g++) + ; + this.P >= 1 << this.c.length && (this.c.push(new sjcl2.hash.sha256()), this.m.push(0)); + this.f -= f; + f > this.o && (this.o = f); + this.P++; + this.b = sjcl2.hash.sha256.hash(this.b.concat(e)); + this.L = new sjcl2.cipher.aes(this.b); + for (d = 0; 4 > d && (this.h[d] = this.h[d] + 1 | 0, !this.h[d]); d++) + ; + } + for (d = 0; d < a; d += 4) + 0 === (d + 1) % this.ca && y(this), e = z(this), c.push(e[0], e[1], e[2], e[3]); + y(this); + return c.slice(0, a); + }, setDefaultParanoia: function(a, b) { + if (0 === a && "Setting paranoia=0 will ruin your security; use it only for testing" !== b) + throw new sjcl2.exception.invalid("Setting paranoia=0 will ruin your security; use it only for testing"); + this.M = a; + }, addEntropy: function(a, b, c) { + c = c || "user"; + var d, e, f = new Date().valueOf(), g = this.H[c], h = this.isReady(), k = 0; + d = this.U[c]; + void 0 === d && (d = this.U[c] = this.ha++); + void 0 === g && (g = this.H[c] = 0); + this.H[c] = (this.H[c] + 1) % this.c.length; + switch (typeof a) { + case "number": + void 0 === b && (b = 1); + this.c[g].update([d, this.N++, 1, b, f, 1, a | 0]); + break; + case "object": + c = Object.prototype.toString.call(a); + if ("[object Uint32Array]" === c) { + e = []; + for (c = 0; c < a.length; c++) + e.push(a[c]); + a = e; + } else + for ("[object Array]" !== c && (k = 1), c = 0; c < a.length && !k; c++) + "number" !== typeof a[c] && (k = 1); + if (!k) { + if (void 0 === b) + for (c = b = 0; c < a.length; c++) + for (e = a[c]; 0 < e; ) + b++, e = e >>> 1; + this.c[g].update([d, this.N++, 2, b, f, a.length].concat(a)); + } + break; + case "string": + void 0 === b && (b = a.length); + this.c[g].update([d, this.N++, 3, b, f, a.length]); + this.c[g].update(a); + break; + default: + k = 1; + } + if (k) + throw new sjcl2.exception.bug("random: addEntropy only supports number, array of numbers or string"); + this.m[g] += b; + this.f += b; + h === this.u && (this.isReady() !== this.u && A("seeded", Math.max(this.o, this.f)), A("progress", this.getProgress())); + }, isReady: function(a) { + a = this.T[void 0 !== a ? a : this.M]; + return this.o && this.o >= a ? this.m[0] > this.ba && new Date().valueOf() > this.Z ? this.J | this.I : this.I : this.f >= a ? this.J | this.u : this.u; + }, getProgress: function(a) { + a = this.T[a ? a : this.M]; + return this.o >= a ? 1 : this.f > a ? 1 : this.f / a; + }, startCollectors: function() { + if (!this.D) { + this.a = { loadTimeCollector: B(this, this.ma), mouseCollector: B(this, this.oa), keyboardCollector: B(this, this.la), accelerometerCollector: B(this, this.ea), touchCollector: B(this, this.qa) }; + if (window.addEventListener) + window.addEventListener("load", this.a.loadTimeCollector, false), window.addEventListener("mousemove", this.a.mouseCollector, false), window.addEventListener("keypress", this.a.keyboardCollector, false), window.addEventListener("devicemotion", this.a.accelerometerCollector, false), window.addEventListener("touchmove", this.a.touchCollector, false); + else if (document.attachEvent) + document.attachEvent("onload", this.a.loadTimeCollector), document.attachEvent("onmousemove", this.a.mouseCollector), document.attachEvent("keypress", this.a.keyboardCollector); + else + throw new sjcl2.exception.bug("can't attach event"); + this.D = true; + } + }, stopCollectors: function() { + this.D && (window.removeEventListener ? (window.removeEventListener("load", this.a.loadTimeCollector, false), window.removeEventListener("mousemove", this.a.mouseCollector, false), window.removeEventListener("keypress", this.a.keyboardCollector, false), window.removeEventListener("devicemotion", this.a.accelerometerCollector, false), window.removeEventListener("touchmove", this.a.touchCollector, false)) : document.detachEvent && (document.detachEvent("onload", this.a.loadTimeCollector), document.detachEvent("onmousemove", this.a.mouseCollector), document.detachEvent("keypress", this.a.keyboardCollector)), this.D = false); + }, addEventListener: function(a, b) { + this.K[a][this.ga++] = b; + }, removeEventListener: function(a, b) { + var c, d, e = this.K[a], f = []; + for (d in e) + e.hasOwnProperty(d) && e[d] === b && f.push(d); + for (c = 0; c < f.length; c++) + d = f[c], delete e[d]; + }, la: function() { + C(this, 1); + }, oa: function(a) { + var b, c; + try { + b = a.x || a.clientX || a.offsetX || 0, c = a.y || a.clientY || a.offsetY || 0; + } catch (d) { + c = b = 0; + } + 0 != b && 0 != c && this.addEntropy([b, c], 2, "mouse"); + C(this, 0); + }, qa: function(a) { + a = a.touches[0] || a.changedTouches[0]; + this.addEntropy([a.pageX || a.clientX, a.pageY || a.clientY], 1, "touch"); + C(this, 0); + }, ma: function() { + C(this, 2); + }, ea: function(a) { + a = a.accelerationIncludingGravity.x || a.accelerationIncludingGravity.y || a.accelerationIncludingGravity.z; + if (window.orientation) { + var b = window.orientation; + "number" === typeof b && this.addEntropy(b, 1, "accelerometer"); + } + a && this.addEntropy(a, 2, "accelerometer"); + C(this, 0); + } }; + function A(a, b) { + var c, d = sjcl2.random.K[a], e = []; + for (c in d) + d.hasOwnProperty(c) && e.push(d[c]); + for (c = 0; c < e.length; c++) + e[c](b); + } + function C(a, b) { + "undefined" !== typeof window && window.performance && "function" === typeof window.performance.now ? a.addEntropy(window.performance.now(), b, "loadtime") : a.addEntropy(new Date().valueOf(), b, "loadtime"); + } + function y(a) { + a.b = z(a).concat(z(a)); + a.L = new sjcl2.cipher.aes(a.b); + } + function z(a) { + for (var b = 0; 4 > b && (a.h[b] = a.h[b] + 1 | 0, !a.h[b]); b++) + ; + return a.L.encrypt(a.h); + } + function B(a, b) { + return function() { + b.apply(a, arguments); + }; + } + sjcl2.random = new sjcl2.prng(6); + a: + try { + if (G = "undefined" !== typeof module22 && module22.exports) { + try { + H = require("crypto"); + } catch (a) { + H = null; + } + G = E = H; + } + if (G && E.randomBytes) + D = E.randomBytes(128), D = new Uint32Array(new Uint8Array(D).buffer), sjcl2.random.addEntropy(D, 1024, "crypto['randomBytes']"); + else if ("undefined" !== typeof window && "undefined" !== typeof Uint32Array) { + F = new Uint32Array(32); + if (window.crypto && window.crypto.getRandomValues) + window.crypto.getRandomValues(F); + else if (window.msCrypto && window.msCrypto.getRandomValues) + window.msCrypto.getRandomValues(F); + else + break a; + sjcl2.random.addEntropy(F, 1024, "crypto['getRandomValues']"); + } + } catch (a) { + "undefined" !== typeof window && window.console && (console.log("There was an error collecting entropy from the browser:"), console.log(a)); + } + var D; + var E; + var F; + var G; + var H; + sjcl2.json = { defaults: { v: 1, iter: 1e4, ks: 128, ts: 64, mode: "ccm", adata: "", cipher: "aes" }, ja: function(a, b, c, d) { + c = c || {}; + d = d || {}; + var e = sjcl2.json, f = e.g({ iv: sjcl2.random.randomWords(4, 0) }, e.defaults), g; + e.g(f, c); + c = f.adata; + "string" === typeof f.salt && (f.salt = sjcl2.codec.base64.toBits(f.salt)); + "string" === typeof f.iv && (f.iv = sjcl2.codec.base64.toBits(f.iv)); + if (!sjcl2.mode[f.mode] || !sjcl2.cipher[f.cipher] || "string" === typeof a && 100 >= f.iter || 64 !== f.ts && 96 !== f.ts && 128 !== f.ts || 128 !== f.ks && 192 !== f.ks && 256 !== f.ks || 2 > f.iv.length || 4 < f.iv.length) + throw new sjcl2.exception.invalid("json encrypt: invalid parameters"); + "string" === typeof a ? (g = sjcl2.misc.cachedPbkdf2(a, f), a = g.key.slice(0, f.ks / 32), f.salt = g.salt) : sjcl2.ecc && a instanceof sjcl2.ecc.elGamal.publicKey && (g = a.kem(), f.kemtag = g.tag, a = g.key.slice(0, f.ks / 32)); + "string" === typeof b && (b = sjcl2.codec.utf8String.toBits(b)); + "string" === typeof c && (f.adata = c = sjcl2.codec.utf8String.toBits(c)); + g = new sjcl2.cipher[f.cipher](a); + e.g(d, f); + d.key = a; + f.ct = "ccm" === f.mode && sjcl2.arrayBuffer && sjcl2.arrayBuffer.ccm && b instanceof ArrayBuffer ? sjcl2.arrayBuffer.ccm.encrypt(g, b, f.iv, c, f.ts) : sjcl2.mode[f.mode].encrypt(g, b, f.iv, c, f.ts); + return f; + }, encrypt: function(a, b, c, d) { + var e = sjcl2.json, f = e.ja.apply(e, arguments); + return e.encode(f); + }, ia: function(a, b, c, d) { + c = c || {}; + d = d || {}; + var e = sjcl2.json; + b = e.g(e.g(e.g({}, e.defaults), b), c, true); + var f, g; + f = b.adata; + "string" === typeof b.salt && (b.salt = sjcl2.codec.base64.toBits(b.salt)); + "string" === typeof b.iv && (b.iv = sjcl2.codec.base64.toBits(b.iv)); + if (!sjcl2.mode[b.mode] || !sjcl2.cipher[b.cipher] || "string" === typeof a && 100 >= b.iter || 64 !== b.ts && 96 !== b.ts && 128 !== b.ts || 128 !== b.ks && 192 !== b.ks && 256 !== b.ks || !b.iv || 2 > b.iv.length || 4 < b.iv.length) + throw new sjcl2.exception.invalid("json decrypt: invalid parameters"); + "string" === typeof a ? (g = sjcl2.misc.cachedPbkdf2(a, b), a = g.key.slice(0, b.ks / 32), b.salt = g.salt) : sjcl2.ecc && a instanceof sjcl2.ecc.elGamal.secretKey && (a = a.unkem(sjcl2.codec.base64.toBits(b.kemtag)).slice(0, b.ks / 32)); + "string" === typeof f && (f = sjcl2.codec.utf8String.toBits(f)); + g = new sjcl2.cipher[b.cipher](a); + f = "ccm" === b.mode && sjcl2.arrayBuffer && sjcl2.arrayBuffer.ccm && b.ct instanceof ArrayBuffer ? sjcl2.arrayBuffer.ccm.decrypt(g, b.ct, b.iv, b.tag, f, b.ts) : sjcl2.mode[b.mode].decrypt(g, b.ct, b.iv, f, b.ts); + e.g(d, b); + d.key = a; + return 1 === c.raw ? f : sjcl2.codec.utf8String.fromBits(f); + }, decrypt: function(a, b, c, d) { + var e = sjcl2.json; + return e.ia(a, e.decode(b), c, d); + }, encode: function(a) { + var b, c = "{", d = ""; + for (b in a) + if (a.hasOwnProperty(b)) { + if (!b.match(/^[a-z0-9]+$/i)) + throw new sjcl2.exception.invalid("json encode: invalid property name"); + c += d + '"' + b + '":'; + d = ","; + switch (typeof a[b]) { + case "number": + case "boolean": + c += a[b]; + break; + case "string": + c += '"' + escape(a[b]) + '"'; + break; + case "object": + c += '"' + sjcl2.codec.base64.fromBits(a[b], 0) + '"'; + break; + default: + throw new sjcl2.exception.bug("json encode: unsupported type"); + } + } + return c + "}"; + }, decode: function(a) { + a = a.replace(/\s/g, ""); + if (!a.match(/^\{.*\}$/)) + throw new sjcl2.exception.invalid("json decode: this isn't json!"); + a = a.replace(/^\{|\}$/g, "").split(/,/); + var b = {}, c, d; + for (c = 0; c < a.length; c++) { + if (!(d = a[c].match(/^\s*(?:(["']?)([a-z][a-z0-9]*)\1)\s*:\s*(?:(-?\d+)|"([a-z0-9+\/%*_.@=\-]*)"|(true|false))$/i))) + throw new sjcl2.exception.invalid("json decode: this isn't json!"); + null != d[3] ? b[d[2]] = parseInt(d[3], 10) : null != d[4] ? b[d[2]] = d[2].match(/^(ct|adata|salt|iv)$/) ? sjcl2.codec.base64.toBits(d[4]) : unescape(d[4]) : null != d[5] && (b[d[2]] = "true" === d[5]); + } + return b; + }, g: function(a, b, c) { + void 0 === a && (a = {}); + if (void 0 === b) + return a; + for (var d in b) + if (b.hasOwnProperty(d)) { + if (c && void 0 !== a[d] && a[d] !== b[d]) + throw new sjcl2.exception.invalid("required parameter overridden"); + a[d] = b[d]; + } + return a; + }, sa: function(a, b) { + var c = {}, d; + for (d in a) + a.hasOwnProperty(d) && a[d] !== b[d] && (c[d] = a[d]); + return c; + }, ra: function(a, b) { + var c = {}, d; + for (d = 0; d < b.length; d++) + void 0 !== a[b[d]] && (c[b[d]] = a[b[d]]); + return c; + } }; + sjcl2.encrypt = sjcl2.json.encrypt; + sjcl2.decrypt = sjcl2.json.decrypt; + sjcl2.misc.pa = {}; + sjcl2.misc.cachedPbkdf2 = function(a, b) { + var c = sjcl2.misc.pa, d; + b = b || {}; + d = b.iter || 1e3; + c = c[a] = c[a] || {}; + d = c[d] = c[d] || { firstSalt: b.salt && b.salt.length ? b.salt.slice(0) : sjcl2.random.randomWords(2, 0) }; + c = void 0 === b.salt ? d.firstSalt : b.salt; + d[c] = d[c] || sjcl2.misc.pbkdf2(a, c, b.iter); + return { key: d[c].slice(0), salt: c.slice(0) }; + }; + "undefined" !== typeof module22 && module22.exports && (module22.exports = sjcl2); + "function" === typeof define && define([], function() { + return sjcl2; + }); + } }); + var require_build = __commonJS2({ "node_modules/better-sse/build/index.js"(exports2, module22) { + !function(e, t) { + if ("object" == typeof exports2 && "object" == typeof module22) + module22.exports = t(); + else if ("function" == typeof define && define.amd) + define([], t); + else { + var s = t(); + for (var i in s) + ("object" == typeof exports2 ? exports2 : e)[i] = s[i]; + } + }(global, function() { + return (() => { + "use strict"; + var e = { n: (t2) => { + var s2 = t2 && t2.__esModule ? () => t2.default : () => t2; + return e.d(s2, { a: s2 }), s2; + }, d: (t2, s2) => { + for (var i2 in s2) + e.o(s2, i2) && !e.o(t2, i2) && Object.defineProperty(t2, i2, { enumerable: true, get: s2[i2] }); + }, o: (e2, t2) => Object.prototype.hasOwnProperty.call(e2, t2), r: (e2) => { + "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e2, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(e2, "__esModule", { value: true }); + } }, t = {}; + e.r(t), e.d(t, { Channel: () => d, Session: () => a, createChannel: () => c, createSession: () => l }); + const s = require("crypto"), i = require("events"); + var n = e.n(i); + class r extends n() { + addListener(e2, t2) { + return super.addListener(e2, t2); + } + prependListener(e2, t2) { + return super.prependListener(e2, t2); + } + prependOnceListener(e2, t2) { + return super.prependOnceListener(e2, t2); + } + on(e2, t2) { + return super.on(e2, t2); + } + once(e2, t2) { + return super.once(e2, t2); + } + emit(e2, ...t2) { + return super.emit(e2, ...t2); + } + off(e2, t2) { + return super.off(e2, t2); + } + removeListener(e2, t2) { + return super.removeListener(e2, t2); + } + } + const o = (e2) => JSON.stringify(e2), h = (e2) => { + let t2 = e2; + return t2 = t2.replace(/(\r\n|\r|\n)/g, "\n"), t2 = t2.replace(/\n+$/g, ""), t2; + }; + class a extends r { + constructor(e2, t2, i2 = {}) { + var n2, r2, a2, l2, d2, c2, u; + super(), this.lastId = "", this.isConnected = false, this.state = {}, this.onConnected = () => { + var e3, t3, s2; + const i3 = `http://${this.req.headers.host}${this.req.url}`, n3 = new URL(i3).searchParams; + if (this.trustClientEventId) { + const i4 = null !== (s2 = null !== (t3 = null !== (e3 = this.req.headers["last-event-id"]) && void 0 !== e3 ? e3 : n3.get("lastEventId")) && void 0 !== t3 ? t3 : n3.get("evs_last_event_id")) && void 0 !== s2 ? s2 : ""; + this.lastId = i4; + } + Object.entries(this.headers).forEach(([e4, t4]) => { + this.res.setHeader(e4, null != t4 ? t4 : ""); + }), this.res.statusCode = this.statusCode, this.res.setHeader("Content-Type", "text/event-stream"), this.res.setHeader("Cache-Control", "no-cache, no-transform"), this.res.setHeader("Connection", "keep-alive"), this.res.flushHeaders(), n3.has("padding") && this.comment(" ".repeat(2049)).dispatch(), n3.has("evs_preamble") && this.comment(" ".repeat(2056)).dispatch(), null !== this.initialRetry && this.retry(this.initialRetry).dispatch(), null !== this.keepAliveInterval && (this.keepAliveTimer = setInterval(this.keepAlive, this.keepAliveInterval)), this.isConnected = true, this.emit("connected"); + }, this.onDisconnected = () => { + this.keepAliveTimer && clearInterval(this.keepAliveTimer), this.isConnected = false, this.emit("disconnected"); + }, this.writeField = (e3, t3) => { + const s2 = `${e3}:${this.sanitize(t3)} +`; + return this.res.write(s2), this; + }, this.keepAlive = () => { + this.comment().dispatch(); + }, this.dispatch = () => (this.res.write("\n"), this), this.data = (e3) => { + const t3 = this.serialize(e3); + return this.writeField("data", t3), this; + }, this.id = (e3) => { + const t3 = e3 || ""; + return this.writeField("id", t3), this.lastId = t3, this; + }, this.retry = (e3) => { + const t3 = e3.toString(); + return this.writeField("retry", t3), this; + }, this.comment = (e3) => (this.writeField("", null != e3 ? e3 : ""), this), this.push = (e3, t3, i3) => (t3 || (t3 = "message"), i3 || (i3 = (0, s.randomBytes)(4).toString("hex")), this.event(t3).id(i3).data(e3).dispatch(), this.emit("push", e3, t3, i3), this), this.stream = async (e3, t3 = {}) => { + const { eventName: s2 = "stream" } = t3; + return new Promise((t4, i3) => { + e3.on("data", (e4) => { + let t5; + t5 = Buffer.isBuffer(e4) ? e4.toString() : e4, this.push(t5, s2); + }), e3.once("end", () => t4(true)), e3.once("close", () => t4(true)), e3.once("error", (e4) => i3(e4)); + }); + }, this.iterate = async (e3, t3 = {}) => { + const { eventName: s2 = "iteration" } = t3; + for await (const t4 of e3) + this.push(t4, s2); + }, this.req = e2, this.res = t2, this.serialize = null !== (n2 = i2.serializer) && void 0 !== n2 ? n2 : o, this.sanitize = null !== (r2 = i2.sanitizer) && void 0 !== r2 ? r2 : h, this.trustClientEventId = null === (a2 = i2.trustClientEventId) || void 0 === a2 || a2, this.initialRetry = null === i2.retry ? null : null !== (l2 = i2.retry) && void 0 !== l2 ? l2 : 2e3, this.keepAliveInterval = null === i2.keepAlive ? null : null !== (d2 = i2.keepAlive) && void 0 !== d2 ? d2 : 1e4, this.statusCode = null !== (c2 = i2.statusCode) && void 0 !== c2 ? c2 : 200, this.headers = null !== (u = i2.headers) && void 0 !== u ? u : {}, this.req.on("close", this.onDisconnected), setImmediate(this.onConnected); + } + event(e2) { + return this.writeField("event", e2), this; + } + } + const l = (...e2) => new Promise((t2) => { + const s2 = new a(...e2); + s2.once("connected", () => { + t2(s2); + }); + }); + class d extends r { + constructor() { + super(), this.state = {}, this.sessions = [], this.broadcast = (e2, t2, s2 = {}) => { + t2 || (t2 = "message"); + const i2 = s2.filter ? this.sessions.filter(s2.filter) : this.sessions; + for (const s3 of i2) + s3.push(e2, t2); + return this.emit("broadcast", e2, t2), this; + }; + } + get activeSessions() { + return this.sessions; + } + get sessionCount() { + return this.sessions.length; + } + register(e2) { + if (!e2.isConnected) + throw new Error("Cannot register a non-active session."); + return e2.once("disconnected", () => { + this.deregister(e2), this.emit("session-disconnected", e2); + }), this.sessions.push(e2), this.emit("session-registered", e2), this; + } + deregister(e2) { + return this.sessions = this.sessions.filter((t2) => t2 !== e2), this.emit("session-deregistered", e2), this; + } + } + const c = (...e2) => new d(...e2); + return t; + })(); + }); + } }); + var require_stream = __commonJS2({ "node_modules/ws/lib/stream.js"(exports2, module22) { + "use strict"; + var { Duplex } = require("stream"); + function emitClose(stream) { + stream.emit("close"); + } + function duplexOnEnd() { + if (!this.destroyed && this._writableState.finished) { + this.destroy(); + } + } + function duplexOnError(err) { + this.removeListener("error", duplexOnError); + this.destroy(); + if (this.listenerCount("error") === 0) { + this.emit("error", err); + } + } + function createWebSocketStream2(ws, options) { + let terminateOnDestroy = true; + const duplex = new Duplex({ ...options, autoDestroy: false, emitClose: false, objectMode: false, writableObjectMode: false }); + ws.on("message", function message(msg, isBinary) { + const data = !isBinary && duplex._readableState.objectMode ? msg.toString() : msg; + if (!duplex.push(data)) + ws.pause(); + }); + ws.once("error", function error(err) { + if (duplex.destroyed) + return; + terminateOnDestroy = false; + duplex.destroy(err); + }); + ws.once("close", function close() { + if (duplex.destroyed) + return; + duplex.push(null); + }); + duplex._destroy = function(err, callback) { + if (ws.readyState === ws.CLOSED) { + callback(err); + process.nextTick(emitClose, duplex); + return; + } + let called = false; + ws.once("error", function error(err2) { + called = true; + callback(err2); + }); + ws.once("close", function close() { + if (!called) + callback(err); + process.nextTick(emitClose, duplex); + }); + if (terminateOnDestroy) + ws.terminate(); + }; + duplex._final = function(callback) { + if (ws.readyState === ws.CONNECTING) { + ws.once("open", function open() { + duplex._final(callback); + }); + return; + } + if (ws._socket === null) + return; + if (ws._socket._writableState.finished) { + callback(); + if (duplex._readableState.endEmitted) + duplex.destroy(); + } else { + ws._socket.once("finish", function finish() { + callback(); + }); + ws.close(); + } + }; + duplex._read = function() { + if (ws.isPaused) + ws.resume(); + }; + duplex._write = function(chunk, encoding, callback) { + if (ws.readyState === ws.CONNECTING) { + ws.once("open", function open() { + duplex._write(chunk, encoding, callback); + }); + return; + } + ws.send(chunk, callback); + }; + duplex.on("end", duplexOnEnd); + duplex.on("error", duplexOnError); + return duplex; + } + module22.exports = createWebSocketStream2; + } }); + var require_constants = __commonJS2({ "node_modules/ws/lib/constants.js"(exports2, module22) { + "use strict"; + module22.exports = { BINARY_TYPES: ["nodebuffer", "arraybuffer", "fragments"], EMPTY_BUFFER: Buffer.alloc(0), GUID: "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", kForOnEventAttribute: Symbol("kIsForOnEventAttribute"), kListener: Symbol("kListener"), kStatusCode: Symbol("status-code"), kWebSocket: Symbol("websocket"), NOOP: () => { + } }; + } }); + var require_buffer_util = __commonJS2({ "node_modules/ws/lib/buffer-util.js"(exports2, module22) { + "use strict"; + var { EMPTY_BUFFER } = require_constants(); + function concat(list, totalLength) { + if (list.length === 0) + return EMPTY_BUFFER; + if (list.length === 1) + return list[0]; + const target = Buffer.allocUnsafe(totalLength); + let offset = 0; + for (let i = 0; i < list.length; i++) { + const buf = list[i]; + target.set(buf, offset); + offset += buf.length; + } + if (offset < totalLength) + return target.slice(0, offset); + return target; + } + function _mask(source, mask, output, offset, length) { + for (let i = 0; i < length; i++) { + output[offset + i] = source[i] ^ mask[i & 3]; + } + } + function _unmask(buffer, mask) { + for (let i = 0; i < buffer.length; i++) { + buffer[i] ^= mask[i & 3]; + } + } + function toArrayBuffer(buf) { + if (buf.byteLength === buf.buffer.byteLength) { + return buf.buffer; + } + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + } + function toBuffer(data) { + toBuffer.readOnly = true; + if (Buffer.isBuffer(data)) + return data; + let buf; + if (data instanceof ArrayBuffer) { + buf = Buffer.from(data); + } else if (ArrayBuffer.isView(data)) { + buf = Buffer.from(data.buffer, data.byteOffset, data.byteLength); + } else { + buf = Buffer.from(data); + toBuffer.readOnly = false; + } + return buf; + } + try { + const bufferUtil = require_bufferutil(); + module22.exports = { concat, mask(source, mask, output, offset, length) { + if (length < 48) + _mask(source, mask, output, offset, length); + else + bufferUtil.mask(source, mask, output, offset, length); + }, toArrayBuffer, toBuffer, unmask(buffer, mask) { + if (buffer.length < 32) + _unmask(buffer, mask); + else + bufferUtil.unmask(buffer, mask); + } }; + } catch (e) { + module22.exports = { concat, mask: _mask, toArrayBuffer, toBuffer, unmask: _unmask }; + } + } }); + var require_limiter = __commonJS2({ "node_modules/ws/lib/limiter.js"(exports2, module22) { + "use strict"; + var kDone = Symbol("kDone"); + var kRun = Symbol("kRun"); + var Limiter = class { + constructor(concurrency) { + this[kDone] = () => { + this.pending--; + this[kRun](); + }; + this.concurrency = concurrency || Infinity; + this.jobs = []; + this.pending = 0; + } + add(job) { + this.jobs.push(job); + this[kRun](); + } + [kRun]() { + if (this.pending === this.concurrency) + return; + if (this.jobs.length) { + const job = this.jobs.shift(); + this.pending++; + job(this[kDone]); + } + } + }; + module22.exports = Limiter; + } }); + var require_permessage_deflate = __commonJS2({ "node_modules/ws/lib/permessage-deflate.js"(exports2, module22) { + "use strict"; + var zlib = require("zlib"); + var bufferUtil = require_buffer_util(); + var Limiter = require_limiter(); + var { kStatusCode } = require_constants(); + var TRAILER = Buffer.from([0, 0, 255, 255]); + var kPerMessageDeflate = Symbol("permessage-deflate"); + var kTotalLength = Symbol("total-length"); + var kCallback = Symbol("callback"); + var kBuffers = Symbol("buffers"); + var kError = Symbol("error"); + var zlibLimiter; + var PerMessageDeflate = class { + constructor(options, isServer, maxPayload) { + this._maxPayload = maxPayload | 0; + this._options = options || {}; + this._threshold = this._options.threshold !== void 0 ? this._options.threshold : 1024; + this._isServer = !!isServer; + this._deflate = null; + this._inflate = null; + this.params = null; + if (!zlibLimiter) { + const concurrency = this._options.concurrencyLimit !== void 0 ? this._options.concurrencyLimit : 10; + zlibLimiter = new Limiter(concurrency); + } + } + static get extensionName() { + return "permessage-deflate"; + } + offer() { + const params = {}; + if (this._options.serverNoContextTakeover) { + params.server_no_context_takeover = true; + } + if (this._options.clientNoContextTakeover) { + params.client_no_context_takeover = true; + } + if (this._options.serverMaxWindowBits) { + params.server_max_window_bits = this._options.serverMaxWindowBits; + } + if (this._options.clientMaxWindowBits) { + params.client_max_window_bits = this._options.clientMaxWindowBits; + } else if (this._options.clientMaxWindowBits == null) { + params.client_max_window_bits = true; + } + return params; + } + accept(configurations) { + configurations = this.normalizeParams(configurations); + this.params = this._isServer ? this.acceptAsServer(configurations) : this.acceptAsClient(configurations); + return this.params; + } + cleanup() { + if (this._inflate) { + this._inflate.close(); + this._inflate = null; + } + if (this._deflate) { + const callback = this._deflate[kCallback]; + this._deflate.close(); + this._deflate = null; + if (callback) { + callback(new Error("The deflate stream was closed while data was being processed")); + } + } + } + acceptAsServer(offers) { + const opts = this._options; + const accepted = offers.find((params) => { + if (opts.serverNoContextTakeover === false && params.server_no_context_takeover || params.server_max_window_bits && (opts.serverMaxWindowBits === false || typeof opts.serverMaxWindowBits === "number" && opts.serverMaxWindowBits > params.server_max_window_bits) || typeof opts.clientMaxWindowBits === "number" && !params.client_max_window_bits) { + return false; + } + return true; + }); + if (!accepted) { + throw new Error("None of the extension offers can be accepted"); + } + if (opts.serverNoContextTakeover) { + accepted.server_no_context_takeover = true; + } + if (opts.clientNoContextTakeover) { + accepted.client_no_context_takeover = true; + } + if (typeof opts.serverMaxWindowBits === "number") { + accepted.server_max_window_bits = opts.serverMaxWindowBits; + } + if (typeof opts.clientMaxWindowBits === "number") { + accepted.client_max_window_bits = opts.clientMaxWindowBits; + } else if (accepted.client_max_window_bits === true || opts.clientMaxWindowBits === false) { + delete accepted.client_max_window_bits; + } + return accepted; + } + acceptAsClient(response) { + const params = response[0]; + if (this._options.clientNoContextTakeover === false && params.client_no_context_takeover) { + throw new Error('Unexpected parameter "client_no_context_takeover"'); + } + if (!params.client_max_window_bits) { + if (typeof this._options.clientMaxWindowBits === "number") { + params.client_max_window_bits = this._options.clientMaxWindowBits; + } + } else if (this._options.clientMaxWindowBits === false || typeof this._options.clientMaxWindowBits === "number" && params.client_max_window_bits > this._options.clientMaxWindowBits) { + throw new Error('Unexpected or invalid parameter "client_max_window_bits"'); + } + return params; + } + normalizeParams(configurations) { + configurations.forEach((params) => { + Object.keys(params).forEach((key) => { + let value2 = params[key]; + if (value2.length > 1) { + throw new Error(`Parameter "${key}" must have only a single value`); + } + value2 = value2[0]; + if (key === "client_max_window_bits") { + if (value2 !== true) { + const num = +value2; + if (!Number.isInteger(num) || num < 8 || num > 15) { + throw new TypeError(`Invalid value for parameter "${key}": ${value2}`); + } + value2 = num; + } else if (!this._isServer) { + throw new TypeError(`Invalid value for parameter "${key}": ${value2}`); + } + } else if (key === "server_max_window_bits") { + const num = +value2; + if (!Number.isInteger(num) || num < 8 || num > 15) { + throw new TypeError(`Invalid value for parameter "${key}": ${value2}`); + } + value2 = num; + } else if (key === "client_no_context_takeover" || key === "server_no_context_takeover") { + if (value2 !== true) { + throw new TypeError(`Invalid value for parameter "${key}": ${value2}`); + } + } else { + throw new Error(`Unknown parameter "${key}"`); + } + params[key] = value2; + }); + }); + return configurations; + } + decompress(data, fin, callback) { + zlibLimiter.add((done) => { + this._decompress(data, fin, (err, result) => { + done(); + callback(err, result); + }); + }); + } + compress(data, fin, callback) { + zlibLimiter.add((done) => { + this._compress(data, fin, (err, result) => { + done(); + callback(err, result); + }); + }); + } + _decompress(data, fin, callback) { + const endpoint = this._isServer ? "client" : "server"; + if (!this._inflate) { + const key = `${endpoint}_max_window_bits`; + const windowBits = typeof this.params[key] !== "number" ? zlib.Z_DEFAULT_WINDOWBITS : this.params[key]; + this._inflate = zlib.createInflateRaw({ ...this._options.zlibInflateOptions, windowBits }); + this._inflate[kPerMessageDeflate] = this; + this._inflate[kTotalLength] = 0; + this._inflate[kBuffers] = []; + this._inflate.on("error", inflateOnError); + this._inflate.on("data", inflateOnData); + } + this._inflate[kCallback] = callback; + this._inflate.write(data); + if (fin) + this._inflate.write(TRAILER); + this._inflate.flush(() => { + const err = this._inflate[kError]; + if (err) { + this._inflate.close(); + this._inflate = null; + callback(err); + return; + } + const data2 = bufferUtil.concat(this._inflate[kBuffers], this._inflate[kTotalLength]); + if (this._inflate._readableState.endEmitted) { + this._inflate.close(); + this._inflate = null; + } else { + this._inflate[kTotalLength] = 0; + this._inflate[kBuffers] = []; + if (fin && this.params[`${endpoint}_no_context_takeover`]) { + this._inflate.reset(); + } + } + callback(null, data2); + }); + } + _compress(data, fin, callback) { + const endpoint = this._isServer ? "server" : "client"; + if (!this._deflate) { + const key = `${endpoint}_max_window_bits`; + const windowBits = typeof this.params[key] !== "number" ? zlib.Z_DEFAULT_WINDOWBITS : this.params[key]; + this._deflate = zlib.createDeflateRaw({ ...this._options.zlibDeflateOptions, windowBits }); + this._deflate[kTotalLength] = 0; + this._deflate[kBuffers] = []; + this._deflate.on("data", deflateOnData); + } + this._deflate[kCallback] = callback; + this._deflate.write(data); + this._deflate.flush(zlib.Z_SYNC_FLUSH, () => { + if (!this._deflate) { + return; + } + let data2 = bufferUtil.concat(this._deflate[kBuffers], this._deflate[kTotalLength]); + if (fin) + data2 = data2.slice(0, data2.length - 4); + this._deflate[kCallback] = null; + this._deflate[kTotalLength] = 0; + this._deflate[kBuffers] = []; + if (fin && this.params[`${endpoint}_no_context_takeover`]) { + this._deflate.reset(); + } + callback(null, data2); + }); + } + }; + module22.exports = PerMessageDeflate; + function deflateOnData(chunk) { + this[kBuffers].push(chunk); + this[kTotalLength] += chunk.length; + } + function inflateOnData(chunk) { + this[kTotalLength] += chunk.length; + if (this[kPerMessageDeflate]._maxPayload < 1 || this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload) { + this[kBuffers].push(chunk); + return; + } + this[kError] = new RangeError("Max payload size exceeded"); + this[kError].code = "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH"; + this[kError][kStatusCode] = 1009; + this.removeListener("data", inflateOnData); + this.reset(); + } + function inflateOnError(err) { + this[kPerMessageDeflate]._inflate = null; + err[kStatusCode] = 1007; + this[kCallback](err); + } + } }); + var require_validation = __commonJS2({ "node_modules/ws/lib/validation.js"(exports2, module22) { + "use strict"; + var tokenChars = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0]; + function isValidStatusCode(code) { + return code >= 1e3 && code <= 1014 && code !== 1004 && code !== 1005 && code !== 1006 || code >= 3e3 && code <= 4999; + } + function _isValidUTF8(buf) { + const len = buf.length; + let i = 0; + while (i < len) { + if ((buf[i] & 128) === 0) { + i++; + } else if ((buf[i] & 224) === 192) { + if (i + 1 === len || (buf[i + 1] & 192) !== 128 || (buf[i] & 254) === 192) { + return false; + } + i += 2; + } else if ((buf[i] & 240) === 224) { + if (i + 2 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || buf[i] === 224 && (buf[i + 1] & 224) === 128 || buf[i] === 237 && (buf[i + 1] & 224) === 160) { + return false; + } + i += 3; + } else if ((buf[i] & 248) === 240) { + if (i + 3 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || (buf[i + 3] & 192) !== 128 || buf[i] === 240 && (buf[i + 1] & 240) === 128 || buf[i] === 244 && buf[i + 1] > 143 || buf[i] > 244) { + return false; + } + i += 4; + } else { + return false; + } + } + return true; + } + try { + const isValidUTF8 = require_utf_8_validate(); + module22.exports = { isValidStatusCode, isValidUTF8(buf) { + return buf.length < 150 ? _isValidUTF8(buf) : isValidUTF8(buf); + }, tokenChars }; + } catch (e) { + module22.exports = { isValidStatusCode, isValidUTF8: _isValidUTF8, tokenChars }; + } + } }); + var require_receiver = __commonJS2({ "node_modules/ws/lib/receiver.js"(exports2, module22) { + "use strict"; + var { Writable } = require("stream"); + var PerMessageDeflate = require_permessage_deflate(); + var { BINARY_TYPES, EMPTY_BUFFER, kStatusCode, kWebSocket } = require_constants(); + var { concat, toArrayBuffer, unmask } = require_buffer_util(); + var { isValidStatusCode, isValidUTF8 } = require_validation(); + var GET_INFO = 0; + var GET_PAYLOAD_LENGTH_16 = 1; + var GET_PAYLOAD_LENGTH_64 = 2; + var GET_MASK = 3; + var GET_DATA = 4; + var INFLATING = 5; + var Receiver2 = class extends Writable { + constructor(options = {}) { + super(); + this._binaryType = options.binaryType || BINARY_TYPES[0]; + this._extensions = options.extensions || {}; + this._isServer = !!options.isServer; + this._maxPayload = options.maxPayload | 0; + this._skipUTF8Validation = !!options.skipUTF8Validation; + this[kWebSocket] = void 0; + this._bufferedBytes = 0; + this._buffers = []; + this._compressed = false; + this._payloadLength = 0; + this._mask = void 0; + this._fragmented = 0; + this._masked = false; + this._fin = false; + this._opcode = 0; + this._totalPayloadLength = 0; + this._messageLength = 0; + this._fragments = []; + this._state = GET_INFO; + this._loop = false; + } + _write(chunk, encoding, cb) { + if (this._opcode === 8 && this._state == GET_INFO) + return cb(); + this._bufferedBytes += chunk.length; + this._buffers.push(chunk); + this.startLoop(cb); + } + consume(n) { + this._bufferedBytes -= n; + if (n === this._buffers[0].length) + return this._buffers.shift(); + if (n < this._buffers[0].length) { + const buf = this._buffers[0]; + this._buffers[0] = buf.slice(n); + return buf.slice(0, n); + } + const dst = Buffer.allocUnsafe(n); + do { + const buf = this._buffers[0]; + const offset = dst.length - n; + if (n >= buf.length) { + dst.set(this._buffers.shift(), offset); + } else { + dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset); + this._buffers[0] = buf.slice(n); + } + n -= buf.length; + } while (n > 0); + return dst; + } + startLoop(cb) { + let err; + this._loop = true; + do { + switch (this._state) { + case GET_INFO: + err = this.getInfo(); + break; + case GET_PAYLOAD_LENGTH_16: + err = this.getPayloadLength16(); + break; + case GET_PAYLOAD_LENGTH_64: + err = this.getPayloadLength64(); + break; + case GET_MASK: + this.getMask(); + break; + case GET_DATA: + err = this.getData(cb); + break; + default: + this._loop = false; + return; + } + } while (this._loop); + cb(err); + } + getInfo() { + if (this._bufferedBytes < 2) { + this._loop = false; + return; + } + const buf = this.consume(2); + if ((buf[0] & 48) !== 0) { + this._loop = false; + return error(RangeError, "RSV2 and RSV3 must be clear", true, 1002, "WS_ERR_UNEXPECTED_RSV_2_3"); + } + const compressed = (buf[0] & 64) === 64; + if (compressed && !this._extensions[PerMessageDeflate.extensionName]) { + this._loop = false; + return error(RangeError, "RSV1 must be clear", true, 1002, "WS_ERR_UNEXPECTED_RSV_1"); + } + this._fin = (buf[0] & 128) === 128; + this._opcode = buf[0] & 15; + this._payloadLength = buf[1] & 127; + if (this._opcode === 0) { + if (compressed) { + this._loop = false; + return error(RangeError, "RSV1 must be clear", true, 1002, "WS_ERR_UNEXPECTED_RSV_1"); + } + if (!this._fragmented) { + this._loop = false; + return error(RangeError, "invalid opcode 0", true, 1002, "WS_ERR_INVALID_OPCODE"); + } + this._opcode = this._fragmented; + } else if (this._opcode === 1 || this._opcode === 2) { + if (this._fragmented) { + this._loop = false; + return error(RangeError, `invalid opcode ${this._opcode}`, true, 1002, "WS_ERR_INVALID_OPCODE"); + } + this._compressed = compressed; + } else if (this._opcode > 7 && this._opcode < 11) { + if (!this._fin) { + this._loop = false; + return error(RangeError, "FIN must be set", true, 1002, "WS_ERR_EXPECTED_FIN"); + } + if (compressed) { + this._loop = false; + return error(RangeError, "RSV1 must be clear", true, 1002, "WS_ERR_UNEXPECTED_RSV_1"); + } + if (this._payloadLength > 125) { + this._loop = false; + return error(RangeError, `invalid payload length ${this._payloadLength}`, true, 1002, "WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH"); + } + } else { + this._loop = false; + return error(RangeError, `invalid opcode ${this._opcode}`, true, 1002, "WS_ERR_INVALID_OPCODE"); + } + if (!this._fin && !this._fragmented) + this._fragmented = this._opcode; + this._masked = (buf[1] & 128) === 128; + if (this._isServer) { + if (!this._masked) { + this._loop = false; + return error(RangeError, "MASK must be set", true, 1002, "WS_ERR_EXPECTED_MASK"); + } + } else if (this._masked) { + this._loop = false; + return error(RangeError, "MASK must be clear", true, 1002, "WS_ERR_UNEXPECTED_MASK"); + } + if (this._payloadLength === 126) + this._state = GET_PAYLOAD_LENGTH_16; + else if (this._payloadLength === 127) + this._state = GET_PAYLOAD_LENGTH_64; + else + return this.haveLength(); + } + getPayloadLength16() { + if (this._bufferedBytes < 2) { + this._loop = false; + return; + } + this._payloadLength = this.consume(2).readUInt16BE(0); + return this.haveLength(); + } + getPayloadLength64() { + if (this._bufferedBytes < 8) { + this._loop = false; + return; + } + const buf = this.consume(8); + const num = buf.readUInt32BE(0); + if (num > Math.pow(2, 53 - 32) - 1) { + this._loop = false; + return error(RangeError, "Unsupported WebSocket frame: payload length > 2^53 - 1", false, 1009, "WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH"); + } + this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4); + return this.haveLength(); + } + haveLength() { + if (this._payloadLength && this._opcode < 8) { + this._totalPayloadLength += this._payloadLength; + if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) { + this._loop = false; + return error(RangeError, "Max payload size exceeded", false, 1009, "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH"); + } + } + if (this._masked) + this._state = GET_MASK; + else + this._state = GET_DATA; + } + getMask() { + if (this._bufferedBytes < 4) { + this._loop = false; + return; + } + this._mask = this.consume(4); + this._state = GET_DATA; + } + getData(cb) { + let data = EMPTY_BUFFER; + if (this._payloadLength) { + if (this._bufferedBytes < this._payloadLength) { + this._loop = false; + return; + } + data = this.consume(this._payloadLength); + if (this._masked && (this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0) { + unmask(data, this._mask); + } + } + if (this._opcode > 7) + return this.controlMessage(data); + if (this._compressed) { + this._state = INFLATING; + this.decompress(data, cb); + return; + } + if (data.length) { + this._messageLength = this._totalPayloadLength; + this._fragments.push(data); + } + return this.dataMessage(); + } + decompress(data, cb) { + const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName]; + perMessageDeflate.decompress(data, this._fin, (err, buf) => { + if (err) + return cb(err); + if (buf.length) { + this._messageLength += buf.length; + if (this._messageLength > this._maxPayload && this._maxPayload > 0) { + return cb(error(RangeError, "Max payload size exceeded", false, 1009, "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH")); + } + this._fragments.push(buf); + } + const er = this.dataMessage(); + if (er) + return cb(er); + this.startLoop(cb); + }); + } + dataMessage() { + if (this._fin) { + const messageLength = this._messageLength; + const fragments = this._fragments; + this._totalPayloadLength = 0; + this._messageLength = 0; + this._fragmented = 0; + this._fragments = []; + if (this._opcode === 2) { + let data; + if (this._binaryType === "nodebuffer") { + data = concat(fragments, messageLength); + } else if (this._binaryType === "arraybuffer") { + data = toArrayBuffer(concat(fragments, messageLength)); + } else { + data = fragments; + } + this.emit("message", data, true); + } else { + const buf = concat(fragments, messageLength); + if (!this._skipUTF8Validation && !isValidUTF8(buf)) { + this._loop = false; + return error(Error, "invalid UTF-8 sequence", true, 1007, "WS_ERR_INVALID_UTF8"); + } + this.emit("message", buf, false); + } + } + this._state = GET_INFO; + } + controlMessage(data) { + if (this._opcode === 8) { + this._loop = false; + if (data.length === 0) { + this.emit("conclude", 1005, EMPTY_BUFFER); + this.end(); + } else if (data.length === 1) { + return error(RangeError, "invalid payload length 1", true, 1002, "WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH"); + } else { + const code = data.readUInt16BE(0); + if (!isValidStatusCode(code)) { + return error(RangeError, `invalid status code ${code}`, true, 1002, "WS_ERR_INVALID_CLOSE_CODE"); + } + const buf = data.slice(2); + if (!this._skipUTF8Validation && !isValidUTF8(buf)) { + return error(Error, "invalid UTF-8 sequence", true, 1007, "WS_ERR_INVALID_UTF8"); + } + this.emit("conclude", code, buf); + this.end(); + } + } else if (this._opcode === 9) { + this.emit("ping", data); + } else { + this.emit("pong", data); + } + this._state = GET_INFO; + } + }; + module22.exports = Receiver2; + function error(ErrorCtor, message, prefix, statusCode, errorCode) { + const err = new ErrorCtor(prefix ? `Invalid WebSocket frame: ${message}` : message); + Error.captureStackTrace(err, error); + err.code = errorCode; + err[kStatusCode] = statusCode; + return err; + } + } }); + var require_sender = __commonJS2({ "node_modules/ws/lib/sender.js"(exports2, module22) { + "use strict"; + var net = require("net"); + var tls = require("tls"); + var { randomFillSync } = require("crypto"); + var PerMessageDeflate = require_permessage_deflate(); + var { EMPTY_BUFFER } = require_constants(); + var { isValidStatusCode } = require_validation(); + var { mask: applyMask, toBuffer } = require_buffer_util(); + var kByteLength = Symbol("kByteLength"); + var maskBuffer = Buffer.alloc(4); + var Sender2 = class { + constructor(socket, extensions, generateMask) { + this._extensions = extensions || {}; + if (generateMask) { + this._generateMask = generateMask; + this._maskBuffer = Buffer.alloc(4); + } + this._socket = socket; + this._firstFragment = true; + this._compress = false; + this._bufferedBytes = 0; + this._deflating = false; + this._queue = []; + } + static frame(data, options) { + let mask; + let merge = false; + let offset = 2; + let skipMasking = false; + if (options.mask) { + mask = options.maskBuffer || maskBuffer; + if (options.generateMask) { + options.generateMask(mask); + } else { + randomFillSync(mask, 0, 4); + } + skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0; + offset = 6; + } + let dataLength; + if (typeof data === "string") { + if ((!options.mask || skipMasking) && options[kByteLength] !== void 0) { + dataLength = options[kByteLength]; + } else { + data = Buffer.from(data); + dataLength = data.length; + } + } else { + dataLength = data.length; + merge = options.mask && options.readOnly && !skipMasking; + } + let payloadLength = dataLength; + if (dataLength >= 65536) { + offset += 8; + payloadLength = 127; + } else if (dataLength > 125) { + offset += 2; + payloadLength = 126; + } + const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset); + target[0] = options.fin ? options.opcode | 128 : options.opcode; + if (options.rsv1) + target[0] |= 64; + target[1] = payloadLength; + if (payloadLength === 126) { + target.writeUInt16BE(dataLength, 2); + } else if (payloadLength === 127) { + target[2] = target[3] = 0; + target.writeUIntBE(dataLength, 4, 6); + } + if (!options.mask) + return [target, data]; + target[1] |= 128; + target[offset - 4] = mask[0]; + target[offset - 3] = mask[1]; + target[offset - 2] = mask[2]; + target[offset - 1] = mask[3]; + if (skipMasking) + return [target, data]; + if (merge) { + applyMask(data, mask, target, offset, dataLength); + return [target]; + } + applyMask(data, mask, data, 0, dataLength); + return [target, data]; + } + close(code, data, mask, cb) { + let buf; + if (code === void 0) { + buf = EMPTY_BUFFER; + } else if (typeof code !== "number" || !isValidStatusCode(code)) { + throw new TypeError("First argument must be a valid error code number"); + } else if (data === void 0 || !data.length) { + buf = Buffer.allocUnsafe(2); + buf.writeUInt16BE(code, 0); + } else { + const length = Buffer.byteLength(data); + if (length > 123) { + throw new RangeError("The message must not be greater than 123 bytes"); + } + buf = Buffer.allocUnsafe(2 + length); + buf.writeUInt16BE(code, 0); + if (typeof data === "string") { + buf.write(data, 2); + } else { + buf.set(data, 2); + } + } + const options = { [kByteLength]: buf.length, fin: true, generateMask: this._generateMask, mask, maskBuffer: this._maskBuffer, opcode: 8, readOnly: false, rsv1: false }; + if (this._deflating) { + this.enqueue([this.dispatch, buf, false, options, cb]); + } else { + this.sendFrame(Sender2.frame(buf, options), cb); + } + } + ping(data, mask, cb) { + let byteLength; + let readOnly; + if (typeof data === "string") { + byteLength = Buffer.byteLength(data); + readOnly = false; + } else { + data = toBuffer(data); + byteLength = data.length; + readOnly = toBuffer.readOnly; + } + if (byteLength > 125) { + throw new RangeError("The data size must not be greater than 125 bytes"); + } + const options = { [kByteLength]: byteLength, fin: true, generateMask: this._generateMask, mask, maskBuffer: this._maskBuffer, opcode: 9, readOnly, rsv1: false }; + if (this._deflating) { + this.enqueue([this.dispatch, data, false, options, cb]); + } else { + this.sendFrame(Sender2.frame(data, options), cb); + } + } + pong(data, mask, cb) { + let byteLength; + let readOnly; + if (typeof data === "string") { + byteLength = Buffer.byteLength(data); + readOnly = false; + } else { + data = toBuffer(data); + byteLength = data.length; + readOnly = toBuffer.readOnly; + } + if (byteLength > 125) { + throw new RangeError("The data size must not be greater than 125 bytes"); + } + const options = { [kByteLength]: byteLength, fin: true, generateMask: this._generateMask, mask, maskBuffer: this._maskBuffer, opcode: 10, readOnly, rsv1: false }; + if (this._deflating) { + this.enqueue([this.dispatch, data, false, options, cb]); + } else { + this.sendFrame(Sender2.frame(data, options), cb); + } + } + send(data, options, cb) { + const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName]; + let opcode = options.binary ? 2 : 1; + let rsv1 = options.compress; + let byteLength; + let readOnly; + if (typeof data === "string") { + byteLength = Buffer.byteLength(data); + readOnly = false; + } else { + data = toBuffer(data); + byteLength = data.length; + readOnly = toBuffer.readOnly; + } + if (this._firstFragment) { + this._firstFragment = false; + if (rsv1 && perMessageDeflate && perMessageDeflate.params[perMessageDeflate._isServer ? "server_no_context_takeover" : "client_no_context_takeover"]) { + rsv1 = byteLength >= perMessageDeflate._threshold; + } + this._compress = rsv1; + } else { + rsv1 = false; + opcode = 0; + } + if (options.fin) + this._firstFragment = true; + if (perMessageDeflate) { + const opts = { [kByteLength]: byteLength, fin: options.fin, generateMask: this._generateMask, mask: options.mask, maskBuffer: this._maskBuffer, opcode, readOnly, rsv1 }; + if (this._deflating) { + this.enqueue([this.dispatch, data, this._compress, opts, cb]); + } else { + this.dispatch(data, this._compress, opts, cb); + } + } else { + this.sendFrame(Sender2.frame(data, { [kByteLength]: byteLength, fin: options.fin, generateMask: this._generateMask, mask: options.mask, maskBuffer: this._maskBuffer, opcode, readOnly, rsv1: false }), cb); + } + } + dispatch(data, compress, options, cb) { + if (!compress) { + this.sendFrame(Sender2.frame(data, options), cb); + return; + } + const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName]; + this._bufferedBytes += options[kByteLength]; + this._deflating = true; + perMessageDeflate.compress(data, options.fin, (_, buf) => { + if (this._socket.destroyed) { + const err = new Error("The socket was closed while data was being compressed"); + if (typeof cb === "function") + cb(err); + for (let i = 0; i < this._queue.length; i++) { + const params = this._queue[i]; + const callback = params[params.length - 1]; + if (typeof callback === "function") + callback(err); + } + return; + } + this._bufferedBytes -= options[kByteLength]; + this._deflating = false; + options.readOnly = false; + this.sendFrame(Sender2.frame(buf, options), cb); + this.dequeue(); + }); + } + dequeue() { + while (!this._deflating && this._queue.length) { + const params = this._queue.shift(); + this._bufferedBytes -= params[3][kByteLength]; + Reflect.apply(params[0], this, params.slice(1)); + } + } + enqueue(params) { + this._bufferedBytes += params[3][kByteLength]; + this._queue.push(params); + } + sendFrame(list, cb) { + if (list.length === 2) { + this._socket.cork(); + this._socket.write(list[0]); + this._socket.write(list[1], cb); + this._socket.uncork(); + } else { + this._socket.write(list[0], cb); + } + } + }; + module22.exports = Sender2; + } }); + var require_event_target = __commonJS2({ "node_modules/ws/lib/event-target.js"(exports2, module22) { + "use strict"; + var { kForOnEventAttribute, kListener } = require_constants(); + var kCode = Symbol("kCode"); + var kData = Symbol("kData"); + var kError = Symbol("kError"); + var kMessage = Symbol("kMessage"); + var kReason = Symbol("kReason"); + var kTarget = Symbol("kTarget"); + var kType = Symbol("kType"); + var kWasClean = Symbol("kWasClean"); + var Event = class { + constructor(type) { + this[kTarget] = null; + this[kType] = type; + } + get target() { + return this[kTarget]; + } + get type() { + return this[kType]; + } + }; + Object.defineProperty(Event.prototype, "target", { enumerable: true }); + Object.defineProperty(Event.prototype, "type", { enumerable: true }); + var CloseEvent = class extends Event { + constructor(type, options = {}) { + super(type); + this[kCode] = options.code === void 0 ? 0 : options.code; + this[kReason] = options.reason === void 0 ? "" : options.reason; + this[kWasClean] = options.wasClean === void 0 ? false : options.wasClean; + } + get code() { + return this[kCode]; + } + get reason() { + return this[kReason]; + } + get wasClean() { + return this[kWasClean]; + } + }; + Object.defineProperty(CloseEvent.prototype, "code", { enumerable: true }); + Object.defineProperty(CloseEvent.prototype, "reason", { enumerable: true }); + Object.defineProperty(CloseEvent.prototype, "wasClean", { enumerable: true }); + var ErrorEvent = class extends Event { + constructor(type, options = {}) { + super(type); + this[kError] = options.error === void 0 ? null : options.error; + this[kMessage] = options.message === void 0 ? "" : options.message; + } + get error() { + return this[kError]; + } + get message() { + return this[kMessage]; + } + }; + Object.defineProperty(ErrorEvent.prototype, "error", { enumerable: true }); + Object.defineProperty(ErrorEvent.prototype, "message", { enumerable: true }); + var MessageEvent = class extends Event { + constructor(type, options = {}) { + super(type); + this[kData] = options.data === void 0 ? null : options.data; + } + get data() { + return this[kData]; + } + }; + Object.defineProperty(MessageEvent.prototype, "data", { enumerable: true }); + var EventTarget = { addEventListener(type, listener, options = {}) { + let wrapper; + if (type === "message") { + wrapper = function onMessage(data, isBinary) { + const event = new MessageEvent("message", { data: isBinary ? data : data.toString() }); + event[kTarget] = this; + listener.call(this, event); + }; + } else if (type === "close") { + wrapper = function onClose(code, message) { + const event = new CloseEvent("close", { code, reason: message.toString(), wasClean: this._closeFrameReceived && this._closeFrameSent }); + event[kTarget] = this; + listener.call(this, event); + }; + } else if (type === "error") { + wrapper = function onError(error) { + const event = new ErrorEvent("error", { error, message: error.message }); + event[kTarget] = this; + listener.call(this, event); + }; + } else if (type === "open") { + wrapper = function onOpen() { + const event = new Event("open"); + event[kTarget] = this; + listener.call(this, event); + }; + } else { + return; + } + wrapper[kForOnEventAttribute] = !!options[kForOnEventAttribute]; + wrapper[kListener] = listener; + if (options.once) { + this.once(type, wrapper); + } else { + this.on(type, wrapper); + } + }, removeEventListener(type, handler) { + for (const listener of this.listeners(type)) { + if (listener[kListener] === handler && !listener[kForOnEventAttribute]) { + this.removeListener(type, listener); + break; + } + } + } }; + module22.exports = { CloseEvent, ErrorEvent, Event, EventTarget, MessageEvent }; + } }); + var require_extension = __commonJS2({ "node_modules/ws/lib/extension.js"(exports2, module22) { + "use strict"; + var { tokenChars } = require_validation(); + function push(dest, name2, elem) { + if (dest[name2] === void 0) + dest[name2] = [elem]; + else + dest[name2].push(elem); + } + function parse(header) { + const offers = /* @__PURE__ */ Object.create(null); + let params = /* @__PURE__ */ Object.create(null); + let mustUnescape = false; + let isEscaping = false; + let inQuotes = false; + let extensionName; + let paramName; + let start = -1; + let code = -1; + let end = -1; + let i = 0; + for (; i < header.length; i++) { + code = header.charCodeAt(i); + if (extensionName === void 0) { + if (end === -1 && tokenChars[code] === 1) { + if (start === -1) + start = i; + } else if (i !== 0 && (code === 32 || code === 9)) { + if (end === -1 && start !== -1) + end = i; + } else if (code === 59 || code === 44) { + if (start === -1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + if (end === -1) + end = i; + const name2 = header.slice(start, end); + if (code === 44) { + push(offers, name2, params); + params = /* @__PURE__ */ Object.create(null); + } else { + extensionName = name2; + } + start = end = -1; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } else if (paramName === void 0) { + if (end === -1 && tokenChars[code] === 1) { + if (start === -1) + start = i; + } else if (code === 32 || code === 9) { + if (end === -1 && start !== -1) + end = i; + } else if (code === 59 || code === 44) { + if (start === -1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + if (end === -1) + end = i; + push(params, header.slice(start, end), true); + if (code === 44) { + push(offers, extensionName, params); + params = /* @__PURE__ */ Object.create(null); + extensionName = void 0; + } + start = end = -1; + } else if (code === 61 && start !== -1 && end === -1) { + paramName = header.slice(start, i); + start = end = -1; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } else { + if (isEscaping) { + if (tokenChars[code] !== 1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + if (start === -1) + start = i; + else if (!mustUnescape) + mustUnescape = true; + isEscaping = false; + } else if (inQuotes) { + if (tokenChars[code] === 1) { + if (start === -1) + start = i; + } else if (code === 34 && start !== -1) { + inQuotes = false; + end = i; + } else if (code === 92) { + isEscaping = true; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } else if (code === 34 && header.charCodeAt(i - 1) === 61) { + inQuotes = true; + } else if (end === -1 && tokenChars[code] === 1) { + if (start === -1) + start = i; + } else if (start !== -1 && (code === 32 || code === 9)) { + if (end === -1) + end = i; + } else if (code === 59 || code === 44) { + if (start === -1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + if (end === -1) + end = i; + let value2 = header.slice(start, end); + if (mustUnescape) { + value2 = value2.replace(/\\/g, ""); + mustUnescape = false; + } + push(params, paramName, value2); + if (code === 44) { + push(offers, extensionName, params); + params = /* @__PURE__ */ Object.create(null); + extensionName = void 0; + } + paramName = void 0; + start = end = -1; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } + } + if (start === -1 || inQuotes || code === 32 || code === 9) { + throw new SyntaxError("Unexpected end of input"); + } + if (end === -1) + end = i; + const token = header.slice(start, end); + if (extensionName === void 0) { + push(offers, token, params); + } else { + if (paramName === void 0) { + push(params, token, true); + } else if (mustUnescape) { + push(params, paramName, token.replace(/\\/g, "")); + } else { + push(params, paramName, token); + } + push(offers, extensionName, params); + } + return offers; + } + function format(extensions) { + return Object.keys(extensions).map((extension) => { + let configurations = extensions[extension]; + if (!Array.isArray(configurations)) + configurations = [configurations]; + return configurations.map((params) => { + return [extension].concat(Object.keys(params).map((k) => { + let values = params[k]; + if (!Array.isArray(values)) + values = [values]; + return values.map((v) => v === true ? k : `${k}=${v}`).join("; "); + })).join("; "); + }).join(", "); + }).join(", "); + } + module22.exports = { format, parse }; + } }); + var require_websocket = __commonJS2({ "node_modules/ws/lib/websocket.js"(exports2, module22) { + "use strict"; + var EventEmitter = require("events"); + var https2 = require("https"); + var http2 = require("http"); + var net = require("net"); + var tls = require("tls"); + var { randomBytes, createHash } = require("crypto"); + var { Readable } = require("stream"); + var { URL: URL2 } = require("url"); + var PerMessageDeflate = require_permessage_deflate(); + var Receiver2 = require_receiver(); + var Sender2 = require_sender(); + var { BINARY_TYPES, EMPTY_BUFFER, GUID, kForOnEventAttribute, kListener, kStatusCode, kWebSocket, NOOP } = require_constants(); + var { EventTarget: { addEventListener, removeEventListener } } = require_event_target(); + var { format, parse } = require_extension(); + var { toBuffer } = require_buffer_util(); + var closeTimeout = 30 * 1e3; + var kAborted = Symbol("kAborted"); + var protocolVersions = [8, 13]; + var readyStates = ["CONNECTING", "OPEN", "CLOSING", "CLOSED"]; + var subprotocolRegex = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/; + var WebSocket3 = class extends EventEmitter { + constructor(address, protocols, options) { + super(); + this._binaryType = BINARY_TYPES[0]; + this._closeCode = 1006; + this._closeFrameReceived = false; + this._closeFrameSent = false; + this._closeMessage = EMPTY_BUFFER; + this._closeTimer = null; + this._extensions = {}; + this._paused = false; + this._protocol = ""; + this._readyState = WebSocket3.CONNECTING; + this._receiver = null; + this._sender = null; + this._socket = null; + if (address !== null) { + this._bufferedAmount = 0; + this._isServer = false; + this._redirects = 0; + if (protocols === void 0) { + protocols = []; + } else if (!Array.isArray(protocols)) { + if (typeof protocols === "object" && protocols !== null) { + options = protocols; + protocols = []; + } else { + protocols = [protocols]; + } + } + initAsClient(this, address, protocols, options); + } else { + this._isServer = true; + } + } + get binaryType() { + return this._binaryType; + } + set binaryType(type) { + if (!BINARY_TYPES.includes(type)) + return; + this._binaryType = type; + if (this._receiver) + this._receiver._binaryType = type; + } + get bufferedAmount() { + if (!this._socket) + return this._bufferedAmount; + return this._socket._writableState.length + this._sender._bufferedBytes; + } + get extensions() { + return Object.keys(this._extensions).join(); + } + get isPaused() { + return this._paused; + } + get onclose() { + return null; + } + get onerror() { + return null; + } + get onopen() { + return null; + } + get onmessage() { + return null; + } + get protocol() { + return this._protocol; + } + get readyState() { + return this._readyState; + } + get url() { + return this._url; + } + setSocket(socket, head, options) { + const receiver = new Receiver2({ binaryType: this.binaryType, extensions: this._extensions, isServer: this._isServer, maxPayload: options.maxPayload, skipUTF8Validation: options.skipUTF8Validation }); + this._sender = new Sender2(socket, this._extensions, options.generateMask); + this._receiver = receiver; + this._socket = socket; + receiver[kWebSocket] = this; + socket[kWebSocket] = this; + receiver.on("conclude", receiverOnConclude); + receiver.on("drain", receiverOnDrain); + receiver.on("error", receiverOnError); + receiver.on("message", receiverOnMessage); + receiver.on("ping", receiverOnPing); + receiver.on("pong", receiverOnPong); + socket.setTimeout(0); + socket.setNoDelay(); + if (head.length > 0) + socket.unshift(head); + socket.on("close", socketOnClose); + socket.on("data", socketOnData); + socket.on("end", socketOnEnd); + socket.on("error", socketOnError); + this._readyState = WebSocket3.OPEN; + this.emit("open"); + } + emitClose() { + if (!this._socket) { + this._readyState = WebSocket3.CLOSED; + this.emit("close", this._closeCode, this._closeMessage); + return; + } + if (this._extensions[PerMessageDeflate.extensionName]) { + this._extensions[PerMessageDeflate.extensionName].cleanup(); + } + this._receiver.removeAllListeners(); + this._readyState = WebSocket3.CLOSED; + this.emit("close", this._closeCode, this._closeMessage); + } + close(code, data) { + if (this.readyState === WebSocket3.CLOSED) + return; + if (this.readyState === WebSocket3.CONNECTING) { + const msg = "WebSocket was closed before the connection was established"; + return abortHandshake(this, this._req, msg); + } + if (this.readyState === WebSocket3.CLOSING) { + if (this._closeFrameSent && (this._closeFrameReceived || this._receiver._writableState.errorEmitted)) { + this._socket.end(); + } + return; + } + this._readyState = WebSocket3.CLOSING; + this._sender.close(code, data, !this._isServer, (err) => { + if (err) + return; + this._closeFrameSent = true; + if (this._closeFrameReceived || this._receiver._writableState.errorEmitted) { + this._socket.end(); + } + }); + this._closeTimer = setTimeout(this._socket.destroy.bind(this._socket), closeTimeout); + } + pause() { + if (this.readyState === WebSocket3.CONNECTING || this.readyState === WebSocket3.CLOSED) { + return; + } + this._paused = true; + this._socket.pause(); + } + ping(data, mask, cb) { + if (this.readyState === WebSocket3.CONNECTING) { + throw new Error("WebSocket is not open: readyState 0 (CONNECTING)"); + } + if (typeof data === "function") { + cb = data; + data = mask = void 0; + } else if (typeof mask === "function") { + cb = mask; + mask = void 0; + } + if (typeof data === "number") + data = data.toString(); + if (this.readyState !== WebSocket3.OPEN) { + sendAfterClose(this, data, cb); + return; + } + if (mask === void 0) + mask = !this._isServer; + this._sender.ping(data || EMPTY_BUFFER, mask, cb); + } + pong(data, mask, cb) { + if (this.readyState === WebSocket3.CONNECTING) { + throw new Error("WebSocket is not open: readyState 0 (CONNECTING)"); + } + if (typeof data === "function") { + cb = data; + data = mask = void 0; + } else if (typeof mask === "function") { + cb = mask; + mask = void 0; + } + if (typeof data === "number") + data = data.toString(); + if (this.readyState !== WebSocket3.OPEN) { + sendAfterClose(this, data, cb); + return; + } + if (mask === void 0) + mask = !this._isServer; + this._sender.pong(data || EMPTY_BUFFER, mask, cb); + } + resume() { + if (this.readyState === WebSocket3.CONNECTING || this.readyState === WebSocket3.CLOSED) { + return; + } + this._paused = false; + if (!this._receiver._writableState.needDrain) + this._socket.resume(); + } + send(data, options, cb) { + if (this.readyState === WebSocket3.CONNECTING) { + throw new Error("WebSocket is not open: readyState 0 (CONNECTING)"); + } + if (typeof options === "function") { + cb = options; + options = {}; + } + if (typeof data === "number") + data = data.toString(); + if (this.readyState !== WebSocket3.OPEN) { + sendAfterClose(this, data, cb); + return; + } + const opts = { binary: typeof data !== "string", mask: !this._isServer, compress: true, fin: true, ...options }; + if (!this._extensions[PerMessageDeflate.extensionName]) { + opts.compress = false; + } + this._sender.send(data || EMPTY_BUFFER, opts, cb); + } + terminate() { + if (this.readyState === WebSocket3.CLOSED) + return; + if (this.readyState === WebSocket3.CONNECTING) { + const msg = "WebSocket was closed before the connection was established"; + return abortHandshake(this, this._req, msg); + } + if (this._socket) { + this._readyState = WebSocket3.CLOSING; + this._socket.destroy(); + } + } + }; + Object.defineProperty(WebSocket3, "CONNECTING", { enumerable: true, value: readyStates.indexOf("CONNECTING") }); + Object.defineProperty(WebSocket3.prototype, "CONNECTING", { enumerable: true, value: readyStates.indexOf("CONNECTING") }); + Object.defineProperty(WebSocket3, "OPEN", { enumerable: true, value: readyStates.indexOf("OPEN") }); + Object.defineProperty(WebSocket3.prototype, "OPEN", { enumerable: true, value: readyStates.indexOf("OPEN") }); + Object.defineProperty(WebSocket3, "CLOSING", { enumerable: true, value: readyStates.indexOf("CLOSING") }); + Object.defineProperty(WebSocket3.prototype, "CLOSING", { enumerable: true, value: readyStates.indexOf("CLOSING") }); + Object.defineProperty(WebSocket3, "CLOSED", { enumerable: true, value: readyStates.indexOf("CLOSED") }); + Object.defineProperty(WebSocket3.prototype, "CLOSED", { enumerable: true, value: readyStates.indexOf("CLOSED") }); + ["binaryType", "bufferedAmount", "extensions", "isPaused", "protocol", "readyState", "url"].forEach((property) => { + Object.defineProperty(WebSocket3.prototype, property, { enumerable: true }); + }); + ["open", "error", "close", "message"].forEach((method) => { + Object.defineProperty(WebSocket3.prototype, `on${method}`, { enumerable: true, get() { + for (const listener of this.listeners(method)) { + if (listener[kForOnEventAttribute]) + return listener[kListener]; + } + return null; + }, set(handler) { + for (const listener of this.listeners(method)) { + if (listener[kForOnEventAttribute]) { + this.removeListener(method, listener); + break; + } + } + if (typeof handler !== "function") + return; + this.addEventListener(method, handler, { [kForOnEventAttribute]: true }); + } }); + }); + WebSocket3.prototype.addEventListener = addEventListener; + WebSocket3.prototype.removeEventListener = removeEventListener; + module22.exports = WebSocket3; + function initAsClient(websocket, address, protocols, options) { + const opts = { protocolVersion: protocolVersions[1], maxPayload: 100 * 1024 * 1024, skipUTF8Validation: false, perMessageDeflate: true, followRedirects: false, maxRedirects: 10, ...options, createConnection: void 0, socketPath: void 0, hostname: void 0, protocol: void 0, timeout: void 0, method: "GET", host: void 0, path: void 0, port: void 0 }; + if (!protocolVersions.includes(opts.protocolVersion)) { + throw new RangeError(`Unsupported protocol version: ${opts.protocolVersion} (supported versions: ${protocolVersions.join(", ")})`); + } + let parsedUrl; + if (address instanceof URL2) { + parsedUrl = address; + websocket._url = address.href; + } else { + try { + parsedUrl = new URL2(address); + } catch (e) { + throw new SyntaxError(`Invalid URL: ${address}`); + } + websocket._url = address; + } + const isSecure = parsedUrl.protocol === "wss:"; + const isUnixSocket = parsedUrl.protocol === "ws+unix:"; + let invalidURLMessage; + if (parsedUrl.protocol !== "ws:" && !isSecure && !isUnixSocket) { + invalidURLMessage = `The URL's protocol must be one of "ws:", "wss:", or "ws+unix:"`; + } else if (isUnixSocket && !parsedUrl.pathname) { + invalidURLMessage = "The URL's pathname is empty"; + } else if (parsedUrl.hash) { + invalidURLMessage = "The URL contains a fragment identifier"; + } + if (invalidURLMessage) { + const err = new SyntaxError(invalidURLMessage); + if (websocket._redirects === 0) { + throw err; + } else { + emitErrorAndClose(websocket, err); + return; + } + } + const defaultPort = isSecure ? 443 : 80; + const key = randomBytes(16).toString("base64"); + const request = isSecure ? https2.request : http2.request; + const protocolSet = /* @__PURE__ */ new Set(); + let perMessageDeflate; + opts.createConnection = isSecure ? tlsConnect : netConnect; + opts.defaultPort = opts.defaultPort || defaultPort; + opts.port = parsedUrl.port || defaultPort; + opts.host = parsedUrl.hostname.startsWith("[") ? parsedUrl.hostname.slice(1, -1) : parsedUrl.hostname; + opts.headers = { "Sec-WebSocket-Version": opts.protocolVersion, "Sec-WebSocket-Key": key, Connection: "Upgrade", Upgrade: "websocket", ...opts.headers }; + opts.path = parsedUrl.pathname + parsedUrl.search; + opts.timeout = opts.handshakeTimeout; + if (opts.perMessageDeflate) { + perMessageDeflate = new PerMessageDeflate(opts.perMessageDeflate !== true ? opts.perMessageDeflate : {}, false, opts.maxPayload); + opts.headers["Sec-WebSocket-Extensions"] = format({ [PerMessageDeflate.extensionName]: perMessageDeflate.offer() }); + } + if (protocols.length) { + for (const protocol of protocols) { + if (typeof protocol !== "string" || !subprotocolRegex.test(protocol) || protocolSet.has(protocol)) { + throw new SyntaxError("An invalid or duplicated subprotocol was specified"); + } + protocolSet.add(protocol); + } + opts.headers["Sec-WebSocket-Protocol"] = protocols.join(","); + } + if (opts.origin) { + if (opts.protocolVersion < 13) { + opts.headers["Sec-WebSocket-Origin"] = opts.origin; + } else { + opts.headers.Origin = opts.origin; + } + } + if (parsedUrl.username || parsedUrl.password) { + opts.auth = `${parsedUrl.username}:${parsedUrl.password}`; + } + if (isUnixSocket) { + const parts = opts.path.split(":"); + opts.socketPath = parts[0]; + opts.path = parts[1]; + } + let req; + if (opts.followRedirects) { + if (websocket._redirects === 0) { + websocket._originalSecure = isSecure; + websocket._originalHost = parsedUrl.host; + const headers = options && options.headers; + options = { ...options, headers: {} }; + if (headers) { + for (const [key2, value2] of Object.entries(headers)) { + options.headers[key2.toLowerCase()] = value2; + } + } + } else if (websocket.listenerCount("redirect") === 0) { + const isSameHost = parsedUrl.host === websocket._originalHost; + if (!isSameHost || websocket._originalSecure && !isSecure) { + delete opts.headers.authorization; + delete opts.headers.cookie; + if (!isSameHost) + delete opts.headers.host; + opts.auth = void 0; + } + } + if (opts.auth && !options.headers.authorization) { + options.headers.authorization = "Basic " + Buffer.from(opts.auth).toString("base64"); + } + req = websocket._req = request(opts); + if (websocket._redirects) { + websocket.emit("redirect", websocket.url, req); + } + } else { + req = websocket._req = request(opts); + } + if (opts.timeout) { + req.on("timeout", () => { + abortHandshake(websocket, req, "Opening handshake has timed out"); + }); + } + req.on("error", (err) => { + if (req === null || req[kAborted]) + return; + req = websocket._req = null; + emitErrorAndClose(websocket, err); + }); + req.on("response", (res) => { + const location2 = res.headers.location; + const statusCode = res.statusCode; + if (location2 && opts.followRedirects && statusCode >= 300 && statusCode < 400) { + if (++websocket._redirects > opts.maxRedirects) { + abortHandshake(websocket, req, "Maximum redirects exceeded"); + return; + } + req.abort(); + let addr; + try { + addr = new URL2(location2, address); + } catch (e) { + const err = new SyntaxError(`Invalid URL: ${location2}`); + emitErrorAndClose(websocket, err); + return; + } + initAsClient(websocket, addr, protocols, options); + } else if (!websocket.emit("unexpected-response", req, res)) { + abortHandshake(websocket, req, `Unexpected server response: ${res.statusCode}`); + } + }); + req.on("upgrade", (res, socket, head) => { + websocket.emit("upgrade", res); + if (websocket.readyState !== WebSocket3.CONNECTING) + return; + req = websocket._req = null; + if (res.headers.upgrade.toLowerCase() !== "websocket") { + abortHandshake(websocket, socket, "Invalid Upgrade header"); + return; + } + const digest = createHash("sha1").update(key + GUID).digest("base64"); + if (res.headers["sec-websocket-accept"] !== digest) { + abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header"); + return; + } + const serverProt = res.headers["sec-websocket-protocol"]; + let protError; + if (serverProt !== void 0) { + if (!protocolSet.size) { + protError = "Server sent a subprotocol but none was requested"; + } else if (!protocolSet.has(serverProt)) { + protError = "Server sent an invalid subprotocol"; + } + } else if (protocolSet.size) { + protError = "Server sent no subprotocol"; + } + if (protError) { + abortHandshake(websocket, socket, protError); + return; + } + if (serverProt) + websocket._protocol = serverProt; + const secWebSocketExtensions = res.headers["sec-websocket-extensions"]; + if (secWebSocketExtensions !== void 0) { + if (!perMessageDeflate) { + const message = "Server sent a Sec-WebSocket-Extensions header but no extension was requested"; + abortHandshake(websocket, socket, message); + return; + } + let extensions; + try { + extensions = parse(secWebSocketExtensions); + } catch (err) { + const message = "Invalid Sec-WebSocket-Extensions header"; + abortHandshake(websocket, socket, message); + return; + } + const extensionNames = Object.keys(extensions); + if (extensionNames.length !== 1 || extensionNames[0] !== PerMessageDeflate.extensionName) { + const message = "Server indicated an extension that was not requested"; + abortHandshake(websocket, socket, message); + return; + } + try { + perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]); + } catch (err) { + const message = "Invalid Sec-WebSocket-Extensions header"; + abortHandshake(websocket, socket, message); + return; + } + websocket._extensions[PerMessageDeflate.extensionName] = perMessageDeflate; + } + websocket.setSocket(socket, head, { generateMask: opts.generateMask, maxPayload: opts.maxPayload, skipUTF8Validation: opts.skipUTF8Validation }); + }); + req.end(); + } + function emitErrorAndClose(websocket, err) { + websocket._readyState = WebSocket3.CLOSING; + websocket.emit("error", err); + websocket.emitClose(); + } + function netConnect(options) { + options.path = options.socketPath; + return net.connect(options); + } + function tlsConnect(options) { + options.path = void 0; + if (!options.servername && options.servername !== "") { + options.servername = net.isIP(options.host) ? "" : options.host; + } + return tls.connect(options); + } + function abortHandshake(websocket, stream, message) { + websocket._readyState = WebSocket3.CLOSING; + const err = new Error(message); + Error.captureStackTrace(err, abortHandshake); + if (stream.setHeader) { + stream[kAborted] = true; + stream.abort(); + if (stream.socket && !stream.socket.destroyed) { + stream.socket.destroy(); + } + process.nextTick(emitErrorAndClose, websocket, err); + } else { + stream.destroy(err); + stream.once("error", websocket.emit.bind(websocket, "error")); + stream.once("close", websocket.emitClose.bind(websocket)); + } + } + function sendAfterClose(websocket, data, cb) { + if (data) { + const length = toBuffer(data).length; + if (websocket._socket) + websocket._sender._bufferedBytes += length; + else + websocket._bufferedAmount += length; + } + if (cb) { + const err = new Error(`WebSocket is not open: readyState ${websocket.readyState} (${readyStates[websocket.readyState]})`); + cb(err); + } + } + function receiverOnConclude(code, reason) { + const websocket = this[kWebSocket]; + websocket._closeFrameReceived = true; + websocket._closeMessage = reason; + websocket._closeCode = code; + if (websocket._socket[kWebSocket] === void 0) + return; + websocket._socket.removeListener("data", socketOnData); + process.nextTick(resume, websocket._socket); + if (code === 1005) + websocket.close(); + else + websocket.close(code, reason); + } + function receiverOnDrain() { + const websocket = this[kWebSocket]; + if (!websocket.isPaused) + websocket._socket.resume(); + } + function receiverOnError(err) { + const websocket = this[kWebSocket]; + if (websocket._socket[kWebSocket] !== void 0) { + websocket._socket.removeListener("data", socketOnData); + process.nextTick(resume, websocket._socket); + websocket.close(err[kStatusCode]); + } + websocket.emit("error", err); + } + function receiverOnFinish() { + this[kWebSocket].emitClose(); + } + function receiverOnMessage(data, isBinary) { + this[kWebSocket].emit("message", data, isBinary); + } + function receiverOnPing(data) { + const websocket = this[kWebSocket]; + websocket.pong(data, !websocket._isServer, NOOP); + websocket.emit("ping", data); + } + function receiverOnPong(data) { + this[kWebSocket].emit("pong", data); + } + function resume(stream) { + stream.resume(); + } + function socketOnClose() { + const websocket = this[kWebSocket]; + this.removeListener("close", socketOnClose); + this.removeListener("data", socketOnData); + this.removeListener("end", socketOnEnd); + websocket._readyState = WebSocket3.CLOSING; + let chunk; + if (!this._readableState.endEmitted && !websocket._closeFrameReceived && !websocket._receiver._writableState.errorEmitted && (chunk = websocket._socket.read()) !== null) { + websocket._receiver.write(chunk); + } + websocket._receiver.end(); + this[kWebSocket] = void 0; + clearTimeout(websocket._closeTimer); + if (websocket._receiver._writableState.finished || websocket._receiver._writableState.errorEmitted) { + websocket.emitClose(); + } else { + websocket._receiver.on("error", receiverOnFinish); + websocket._receiver.on("finish", receiverOnFinish); + } + } + function socketOnData(chunk) { + if (!this[kWebSocket]._receiver.write(chunk)) { + this.pause(); + } + } + function socketOnEnd() { + const websocket = this[kWebSocket]; + websocket._readyState = WebSocket3.CLOSING; + websocket._receiver.end(); + this.end(); + } + function socketOnError() { + const websocket = this[kWebSocket]; + this.removeListener("error", socketOnError); + this.on("error", NOOP); + if (websocket) { + websocket._readyState = WebSocket3.CLOSING; + this.destroy(); + } + } + } }); + var require_subprotocol = __commonJS2({ "node_modules/ws/lib/subprotocol.js"(exports2, module22) { + "use strict"; + var { tokenChars } = require_validation(); + function parse(header) { + const protocols = /* @__PURE__ */ new Set(); + let start = -1; + let end = -1; + let i = 0; + for (i; i < header.length; i++) { + const code = header.charCodeAt(i); + if (end === -1 && tokenChars[code] === 1) { + if (start === -1) + start = i; + } else if (i !== 0 && (code === 32 || code === 9)) { + if (end === -1 && start !== -1) + end = i; + } else if (code === 44) { + if (start === -1) { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + if (end === -1) + end = i; + const protocol2 = header.slice(start, end); + if (protocols.has(protocol2)) { + throw new SyntaxError(`The "${protocol2}" subprotocol is duplicated`); + } + protocols.add(protocol2); + start = end = -1; + } else { + throw new SyntaxError(`Unexpected character at index ${i}`); + } + } + if (start === -1 || end !== -1) { + throw new SyntaxError("Unexpected end of input"); + } + const protocol = header.slice(start, i); + if (protocols.has(protocol)) { + throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`); + } + protocols.add(protocol); + return protocols; + } + module22.exports = { parse }; + } }); + var require_websocket_server = __commonJS2({ "node_modules/ws/lib/websocket-server.js"(exports2, module22) { + "use strict"; + var EventEmitter = require("events"); + var http2 = require("http"); + var https2 = require("https"); + var net = require("net"); + var tls = require("tls"); + var { createHash } = require("crypto"); + var extension = require_extension(); + var PerMessageDeflate = require_permessage_deflate(); + var subprotocol = require_subprotocol(); + var WebSocket3 = require_websocket(); + var { GUID, kWebSocket } = require_constants(); + var keyRegex = /^[+/0-9A-Za-z]{22}==$/; + var RUNNING = 0; + var CLOSING = 1; + var CLOSED = 2; + var WebSocketServer2 = class extends EventEmitter { + constructor(options, callback) { + super(); + options = { maxPayload: 100 * 1024 * 1024, skipUTF8Validation: false, perMessageDeflate: false, handleProtocols: null, clientTracking: true, verifyClient: null, noServer: false, backlog: null, server: null, host: null, path: null, port: null, WebSocket: WebSocket3, ...options }; + if (options.port == null && !options.server && !options.noServer || options.port != null && (options.server || options.noServer) || options.server && options.noServer) { + throw new TypeError('One and only one of the "port", "server", or "noServer" options must be specified'); + } + if (options.port != null) { + this._server = http2.createServer((req, res) => { + const body = http2.STATUS_CODES[426]; + res.writeHead(426, { "Content-Length": body.length, "Content-Type": "text/plain" }); + res.end(body); + }); + this._server.listen(options.port, options.host, options.backlog, callback); + } else if (options.server) { + this._server = options.server; + } + if (this._server) { + const emitConnection = this.emit.bind(this, "connection"); + this._removeListeners = addListeners(this._server, { listening: this.emit.bind(this, "listening"), error: this.emit.bind(this, "error"), upgrade: (req, socket, head) => { + this.handleUpgrade(req, socket, head, emitConnection); + } }); + } + if (options.perMessageDeflate === true) + options.perMessageDeflate = {}; + if (options.clientTracking) { + this.clients = /* @__PURE__ */ new Set(); + this._shouldEmitClose = false; + } + this.options = options; + this._state = RUNNING; + } + address() { + if (this.options.noServer) { + throw new Error('The server is operating in "noServer" mode'); + } + if (!this._server) + return null; + return this._server.address(); + } + close(cb) { + if (this._state === CLOSED) { + if (cb) { + this.once("close", () => { + cb(new Error("The server is not running")); + }); + } + process.nextTick(emitClose, this); + return; + } + if (cb) + this.once("close", cb); + if (this._state === CLOSING) + return; + this._state = CLOSING; + if (this.options.noServer || this.options.server) { + if (this._server) { + this._removeListeners(); + this._removeListeners = this._server = null; + } + if (this.clients) { + if (!this.clients.size) { + process.nextTick(emitClose, this); + } else { + this._shouldEmitClose = true; + } + } else { + process.nextTick(emitClose, this); + } + } else { + const server2 = this._server; + this._removeListeners(); + this._removeListeners = this._server = null; + server2.close(() => { + emitClose(this); + }); + } + } + shouldHandle(req) { + if (this.options.path) { + const index = req.url.indexOf("?"); + const pathname = index !== -1 ? req.url.slice(0, index) : req.url; + if (pathname !== this.options.path) + return false; + } + return true; + } + handleUpgrade(req, socket, head, cb) { + socket.on("error", socketOnError); + const key = req.headers["sec-websocket-key"]; + const version = +req.headers["sec-websocket-version"]; + if (req.method !== "GET") { + const message = "Invalid HTTP method"; + abortHandshakeOrEmitwsClientError(this, req, socket, 405, message); + return; + } + if (req.headers.upgrade.toLowerCase() !== "websocket") { + const message = "Invalid Upgrade header"; + abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); + return; + } + if (!key || !keyRegex.test(key)) { + const message = "Missing or invalid Sec-WebSocket-Key header"; + abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); + return; + } + if (version !== 8 && version !== 13) { + const message = "Missing or invalid Sec-WebSocket-Version header"; + abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); + return; + } + if (!this.shouldHandle(req)) { + abortHandshake(socket, 400); + return; + } + const secWebSocketProtocol = req.headers["sec-websocket-protocol"]; + let protocols = /* @__PURE__ */ new Set(); + if (secWebSocketProtocol !== void 0) { + try { + protocols = subprotocol.parse(secWebSocketProtocol); + } catch (err) { + const message = "Invalid Sec-WebSocket-Protocol header"; + abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); + return; + } + } + const secWebSocketExtensions = req.headers["sec-websocket-extensions"]; + const extensions = {}; + if (this.options.perMessageDeflate && secWebSocketExtensions !== void 0) { + const perMessageDeflate = new PerMessageDeflate(this.options.perMessageDeflate, true, this.options.maxPayload); + try { + const offers = extension.parse(secWebSocketExtensions); + if (offers[PerMessageDeflate.extensionName]) { + perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]); + extensions[PerMessageDeflate.extensionName] = perMessageDeflate; + } + } catch (err) { + const message = "Invalid or unacceptable Sec-WebSocket-Extensions header"; + abortHandshakeOrEmitwsClientError(this, req, socket, 400, message); + return; + } + } + if (this.options.verifyClient) { + const info = { origin: req.headers[`${version === 8 ? "sec-websocket-origin" : "origin"}`], secure: !!(req.socket.authorized || req.socket.encrypted), req }; + if (this.options.verifyClient.length === 2) { + this.options.verifyClient(info, (verified, code, message, headers) => { + if (!verified) { + return abortHandshake(socket, code || 401, message, headers); + } + this.completeUpgrade(extensions, key, protocols, req, socket, head, cb); + }); + return; + } + if (!this.options.verifyClient(info)) + return abortHandshake(socket, 401); + } + this.completeUpgrade(extensions, key, protocols, req, socket, head, cb); + } + completeUpgrade(extensions, key, protocols, req, socket, head, cb) { + if (!socket.readable || !socket.writable) + return socket.destroy(); + if (socket[kWebSocket]) { + throw new Error("server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration"); + } + if (this._state > RUNNING) + return abortHandshake(socket, 503); + const digest = createHash("sha1").update(key + GUID).digest("base64"); + const headers = ["HTTP/1.1 101 Switching Protocols", "Upgrade: websocket", "Connection: Upgrade", `Sec-WebSocket-Accept: ${digest}`]; + const ws = new this.options.WebSocket(null); + if (protocols.size) { + const protocol = this.options.handleProtocols ? this.options.handleProtocols(protocols, req) : protocols.values().next().value; + if (protocol) { + headers.push(`Sec-WebSocket-Protocol: ${protocol}`); + ws._protocol = protocol; + } + } + if (extensions[PerMessageDeflate.extensionName]) { + const params = extensions[PerMessageDeflate.extensionName].params; + const value2 = extension.format({ [PerMessageDeflate.extensionName]: [params] }); + headers.push(`Sec-WebSocket-Extensions: ${value2}`); + ws._extensions = extensions; + } + this.emit("headers", headers, req); + socket.write(headers.concat("\r\n").join("\r\n")); + socket.removeListener("error", socketOnError); + ws.setSocket(socket, head, { maxPayload: this.options.maxPayload, skipUTF8Validation: this.options.skipUTF8Validation }); + if (this.clients) { + this.clients.add(ws); + ws.on("close", () => { + this.clients.delete(ws); + if (this._shouldEmitClose && !this.clients.size) { + process.nextTick(emitClose, this); + } + }); + } + cb(ws, req); + } + }; + module22.exports = WebSocketServer2; + function addListeners(server2, map) { + for (const event of Object.keys(map)) + server2.on(event, map[event]); + return function removeListeners() { + for (const event of Object.keys(map)) { + server2.removeListener(event, map[event]); + } + }; + } + function emitClose(server2) { + server2._state = CLOSED; + server2.emit("close"); + } + function socketOnError() { + this.destroy(); + } + function abortHandshake(socket, code, message, headers) { + message = message || http2.STATUS_CODES[code]; + headers = { Connection: "close", "Content-Type": "text/html", "Content-Length": Buffer.byteLength(message), ...headers }; + socket.once("finish", socket.destroy); + socket.end(`HTTP/1.1 ${code} ${http2.STATUS_CODES[code]}\r +` + Object.keys(headers).map((h) => `${h}: ${headers[h]}`).join("\r\n") + "\r\n\r\n" + message); + } + function abortHandshakeOrEmitwsClientError(server2, req, socket, code, message) { + if (server2.listenerCount("wsClientError")) { + const err = new Error(message); + Error.captureStackTrace(err, abortHandshakeOrEmitwsClientError); + server2.emit("wsClientError", err, socket, req); + } else { + abortHandshake(socket, code, message); + } + } + } }); + var require_node = __commonJS2({ "node_modules/web-worker/cjs/node.js"(exports2, module22) { + var URL2 = require("url"); + var VM = require("vm"); + var threads = require("worker_threads"); + var WORKER = Symbol.for("worker"); + var EVENTS = Symbol.for("events"); + var EventTarget = class { + constructor() { + Object.defineProperty(this, EVENTS, { value: /* @__PURE__ */ new Map() }); + } + dispatchEvent(event) { + event.target = event.currentTarget = this; + if (this["on" + event.type]) { + try { + this["on" + event.type](event); + } catch (err) { + console.error(err); + } + } + const list = this[EVENTS].get(event.type); + if (list == null) + return; + list.forEach((handler) => { + try { + handler.call(this, event); + } catch (err) { + console.error(err); + } + }); + } + addEventListener(type, fn) { + let events = this[EVENTS].get(type); + if (!events) + this[EVENTS].set(type, events = []); + events.push(fn); + } + removeEventListener(type, fn) { + let events = this[EVENTS].get(type); + if (events) { + const index = events.indexOf(fn); + if (index !== -1) + events.splice(index, 1); + } + } + }; + function Event(type, target) { + this.type = type; + this.timeStamp = Date.now(); + this.target = this.currentTarget = this.data = null; + } + module22.exports = threads.isMainThread ? mainThread() : workerThread(); + var baseUrl = URL2.pathToFileURL(process.cwd() + "/"); + function mainThread() { + class Worker3 extends EventTarget { + constructor(url, options) { + super(); + const { name: name2, type } = options || {}; + url += ""; + let mod; + if (/^data:/.test(url)) { + mod = url; + } else { + mod = URL2.fileURLToPath(new URL2.URL(url, baseUrl)); + } + const worker = new threads.Worker(__filename, { workerData: { mod, name: name2, type } }); + Object.defineProperty(this, WORKER, { value: worker }); + worker.on("message", (data) => { + const event = new Event("message"); + event.data = data; + this.dispatchEvent(event); + }); + worker.on("error", (error) => { + error.type = "error"; + this.dispatchEvent(error); + }); + worker.on("exit", () => { + this.dispatchEvent(new Event("close")); + }); + } + postMessage(data, transferList) { + this[WORKER].postMessage(data, transferList); + } + terminate() { + this[WORKER].terminate(); + } + } + Worker3.prototype.onmessage = Worker3.prototype.onerror = Worker3.prototype.onclose = null; + return Worker3; + } + function workerThread() { + let { mod, name: name2, type } = threads.workerData; + const self2 = global.self = global; + let q = []; + function flush() { + const buffered = q; + q = null; + buffered.forEach((event) => { + self2.dispatchEvent(event); + }); + } + threads.parentPort.on("message", (data) => { + const event = new Event("message"); + event.data = data; + if (q == null) + self2.dispatchEvent(event); + else + q.push(event); + }); + threads.parentPort.on("error", (err) => { + err.type = "Error"; + self2.dispatchEvent(err); + }); + class WorkerGlobalScope2 extends EventTarget { + postMessage(data, transferList) { + threads.parentPort.postMessage(data, transferList); + } + close() { + process.exit(); + } + } + let proto = Object.getPrototypeOf(global); + delete proto.constructor; + Object.defineProperties(WorkerGlobalScope2.prototype, proto); + proto = Object.setPrototypeOf(global, new WorkerGlobalScope2()); + ["postMessage", "addEventListener", "removeEventListener", "dispatchEvent"].forEach((fn) => { + proto[fn] = proto[fn].bind(global); + }); + global.name = name2; + const isDataUrl = /^data:/.test(mod); + if (type === "module") { + import(mod).catch((err) => { + if (isDataUrl && err.message === "Not supported") { + console.warn("Worker(): Importing data: URLs requires Node 12.10+. Falling back to classic worker."); + return evaluateDataUrl(mod, name2); + } + console.error(err); + }).then(flush); + } else { + try { + if (/^data:/.test(mod)) { + evaluateDataUrl(mod, name2); + } else { + require(mod); + } + } catch (err) { + console.error(err); + } + Promise.resolve().then(flush); + } + } + function evaluateDataUrl(url, name2) { + const { data } = parseDataUrl(url); + return VM.runInThisContext(data, { filename: "worker.<" + (name2 || "data:") + ">" }); + } + function parseDataUrl(url) { + let [m, type, encoding, data] = url.match(/^data: *([^;,]*)(?: *; *([^,]*))? *,(.*)$/) || []; + if (!m) + throw Error("Invalid Data URL."); + if (encoding) + switch (encoding.toLowerCase()) { + case "base64": + data = Buffer.from(data, "base64").toString(); + break; + default: + throw Error('Unknown Data URL encoding "' + encoding + '"'); + } + return { type, data }; + } + } }); + var index_node_exports = {}; + __export(index_node_exports, { CMDService: () => CMDService, E2EEService: () => E2EEService, GPUService: () => GPUService, Graph: () => Graph2, GraphNode: () => GraphNode2, HTTPbackend: () => HTTPbackend2, Router: () => Router2, SSEbackend: () => SSEbackend2, Service: () => Service2, UserRouter: () => UserRouter, WSSbackend: () => WSSbackend2, WorkerService: () => WorkerService, createNode: () => createNode2, getFnParamInfo: () => getFnParamInfo, getFnParamNames: () => getFnParamNames, parseFunctionFromText: () => parseFunctionFromText2, reconstructNode: () => reconstructNode, reconstructObject: () => reconstructObject2, state: () => state2, stringifyFast: () => stringifyFast2, stringifyWithCircularRefs: () => stringifyWithCircularRefs2, unsafeRoutes: () => unsafeRoutes }); + module2.exports = __toCommonJS(index_node_exports); + var ARGUMENT_NAMES = /([^,]*)/g; + function getFnParamInfo(fn) { + var fstr = fn.toString(); + const openPar = fstr.indexOf("("); + const closePar = fstr.indexOf(")"); + const getFirstBracket = (str, offset = 0) => { + const fb = offset + str.indexOf("{"); + if (fb < closePar && fb > openPar) { + return getFirstBracket(str.slice(fb), offset + fb); + } else + return fb; + }; + const firstBracket = getFirstBracket(fstr); + let innerMatch; + if (firstBracket === -1 || closePar < firstBracket) + innerMatch = fstr.slice(fstr.indexOf("(") + 1, fstr.indexOf(")")); + else + innerMatch = fstr.match(/([a-zA-Z]\w*|\([a-zA-Z]\w*(,\s*[a-zA-Z]\w*)*\)) =>/)?.[1]; + if (!innerMatch) + return void 0; + const matches = innerMatch.match(ARGUMENT_NAMES).filter((e) => !!e); + const info = /* @__PURE__ */ new Map(); + matches.forEach((v) => { + let [name2, value2] = v.split("="); + name2 = name2.trim(); + name2 = name2.replace(/\d+$/, ""); + const spread = name2.includes("..."); + name2 = name2.replace("...", ""); + try { + if (name2) + info.set(name2, { state: (0, eval)(`(${value2})`), spread }); + } catch (e) { + info.set(name2, {}); + } + }); + return info; + } + function getFnParamNames(fn) { + var fstr = fn.toString(); + return fstr.match(/\(.*?\)/)[0].replace(/[()]/gi, "").replace(/\s/gi, "").split(","); + } + function parseFunctionFromText2(method = "") { + let getFunctionBody = (methodString) => { + return methodString.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i, "$2$3$4"); + }; + let getFunctionHead = (methodString) => { + let startindex = methodString.indexOf("=>") + 1; + if (startindex <= 0) { + startindex = methodString.indexOf("){"); + } + if (startindex <= 0) { + startindex = methodString.indexOf(") {"); + } + return methodString.slice(0, methodString.indexOf("{", startindex) + 1); + }; + let newFuncHead = getFunctionHead(method); + let newFuncBody = getFunctionBody(method); + let newFunc; + if (newFuncHead.includes("function")) { + let varName = newFuncHead.split("(")[1].split(")")[0]; + newFunc = new Function(varName, newFuncBody); + } else { + if (newFuncHead.substring(0, 6) === newFuncBody.substring(0, 6)) { + let varName = newFuncHead.split("(")[1].split(")")[0]; + newFunc = new Function(varName, newFuncBody.substring(newFuncBody.indexOf("{") + 1, newFuncBody.length - 1)); + } else { + try { + newFunc = (0, eval)(newFuncHead + newFuncBody + "}"); + } catch { + } + } + } + return newFunc; + } + var state2 = { pushToState: {}, data: {}, triggers: {}, setState(updateObj) { + Object.assign(state2.data, updateObj); + for (const prop of Object.getOwnPropertyNames(updateObj)) { + if (state2.triggers[prop]) + state2.triggers[prop].forEach((obj) => obj.onchange(state2.data[prop])); + } + return state2.data; + }, subscribeTrigger(key, onchange) { + if (key) { + if (!state2.triggers[key]) { + state2.triggers[key] = []; + } + let l = state2.triggers[key].length; + state2.triggers[key].push({ idx: l, onchange }); + return state2.triggers[key].length - 1; + } else + return void 0; + }, unsubscribeTrigger(key, sub) { + let idx = void 0; + let triggers = state2.triggers[key]; + if (triggers) { + if (!sub) + delete state2.triggers[key]; + else { + let obj = triggers.find((o) => { + if (o.idx === sub) { + return true; + } + }); + if (obj) + triggers.splice(idx, 1); + return true; + } + } + }, subscribeTriggerOnce(key, onchange) { + let sub; + let changed = (value2) => { + onchange(value2); + state2.unsubscribeTrigger(key, sub); + }; + sub = state2.subscribeTrigger(key, changed); + } }; + var GraphNode2 = class { + constructor(properties = {}, parentNode, graph) { + this.nodes = /* @__PURE__ */ new Map(); + this.arguments = /* @__PURE__ */ new Map(); + this._initial = {}; + this.state = state2; + this.isLooping = false; + this.isAnimating = false; + this.looper = void 0; + this.animation = void 0; + this.forward = true; + this.backward = false; + this.runSync = false; + this.firstRun = true; + this.DEBUGNODE = false; + this.operator = (self2 = this, origin, ...args) => { + return args; + }; + this.runOp = (node = this, origin = this, ...args) => { + if (node.DEBUGNODE) + console.time(node.tag); + let result = node.operator(node, origin, ...args); + if (result instanceof Promise) { + result.then((res) => { + if (res !== void 0) + this.setState({ [node.tag]: res }); + if (node.DEBUGNODE) { + console.timeEnd(node.tag); + if (result !== void 0) + console.log(`${node.tag} result:`, result); + } + ; + return res; + }); + } else { + if (result !== void 0) + this.setState({ [node.tag]: result }); + if (node.DEBUGNODE) { + console.timeEnd(node.tag); + if (result !== void 0) + console.log(`${node.tag} result:`, result); + } + ; + } + return result; + }; + this.setOperator = (operator) => { + if (typeof operator !== "function") + return operator; + let params = getFnParamInfo(operator); + let pass = false; + if (params) { + const keys = params.keys(); + const paramOne = keys.next().value; + const paramTwo = keys.next().value; + const restrictedOne = ["self", "node"]; + const restrictedTwo = ["origin", "parent", "graph", "router"]; + if (paramOne) + restrictedOne.forEach((a) => { + if (paramOne.includes(a)) + pass = true; + }); + if (paramTwo) + restrictedTwo.forEach((a) => { + if (paramTwo.includes(a)) + pass = true; + }); + if (this.arguments) { + params.forEach((o, k) => { + if (!this.arguments.has(k)) + this.arguments.set(k, o.state); + }); + } + } + if (!pass) { + let fn = operator; + operator = (self2, origin, ...args) => { + return fn(...args); + }; + } + this.operator = operator; + return operator; + }; + this.run = (...args) => { + return this._run(this, void 0, ...args); + }; + this.runAsync = (...args) => { + return new Promise((res, rej) => { + res(this._run(this, void 0, ...args)); + }); + }; + this.transformArgs = (args = []) => args; + this._run = (node = this, origin, ...args) => { + if (typeof this.transformArgs === "function") + args = this.transformArgs(args, node); + if (!(typeof node === "object")) { + if (typeof node === "string") { + let fnd = void 0; + if (this.graph) + fnd = this.graph.nodes.get(node); + if (!fnd) + fnd = this.nodes.get(node); + node = fnd; + } + if (!node) + return void 0; + } + if (node.firstRun) { + node.firstRun = false; + if (!(node.children && node.forward || node.parent && node.backward || node.repeat || node.delay || node.frame || node.recursive || node.branch)) + node.runSync = true; + if (node.animate && !node.isAnimating) { + node.runAnimation(node.animation, args, node, origin); + } + if (node.loop && typeof node.loop === "number" && !node.isLooping) { + node.runLoop(node.looper, args, node, origin); + } + if (node.loop || node.animate) + return; + } + if (node.runSync) { + let res = node.runOp(node, origin, ...args); + return res; + } + return new Promise(async (resolve) => { + if (node) { + let run = (node2, tick = 0, ...input) => { + return new Promise(async (r) => { + tick++; + let res = await node2.runOp(node2, origin, ...input); + if (node2.repeat) { + while (tick < node2.repeat) { + if (node2.delay) { + setTimeout(async () => { + r(await run(node2, tick, ...input)); + }, node2.delay); + break; + } else if (node2.frame && window?.requestAnimationFrame) { + requestAnimationFrame(async () => { + r(await run(node2, tick, ...input)); + }); + break; + } else + res = await node2.runOp(node2, origin, ...input); + tick++; + } + if (tick === node2.repeat) { + r(res); + return; + } + } else if (node2.recursive) { + while (tick < node2.recursive) { + if (node2.delay) { + setTimeout(async () => { + r(await run(node2, tick, ...res)); + }, node2.delay); + break; + } else if (node2.frame && window?.requestAnimationFrame) { + requestAnimationFrame(async () => { + r(await run(node2, tick, ...res)); + }); + break; + } else + res = await node2.runOp(node2, origin, ...res); + tick++; + } + if (tick === node2.recursive) { + r(res); + return; + } + } else { + r(res); + return; + } + }); + }; + let runnode = async () => { + let res = await run(node, void 0, ...args); + if (res !== void 0) { + if (node.backward && node.parent instanceof GraphNode2) { + if (Array.isArray(res)) + await this.runParent(node, ...res); + else + await this.runParent(node, res); + } + if (node.children && node.forward) { + if (Array.isArray(res)) + await this.runChildren(node, ...res); + else + await this.runChildren(node, res); + } + if (node.branch) { + this.runBranch(node, res); + } + } + return res; + }; + if (node.delay) { + setTimeout(async () => { + resolve(await runnode()); + }, node.delay); + } else if (node.frame && window?.requestAnimationFrame) { + requestAnimationFrame(async () => { + resolve(await runnode()); + }); + } else { + resolve(await runnode()); + } + } else + resolve(void 0); + }); + }; + this.runParent = async (node, ...args) => { + if (node.backward && node.parent) { + if (typeof node.parent === "string") { + if (node.graph && node.graph?.get(node.parent)) { + node.parent = node.graph; + if (node.parent) + this.nodes.set(node.parent.tag, node.parent); + } else + node.parent = this.nodes.get(node.parent); + } + if (node.parent instanceof GraphNode2) + await node.parent._run(node.parent, this, ...args); + } + }; + this.runChildren = async (node, ...args) => { + if (typeof node.children === "object") { + for (const key in node.children) { + if (typeof node.children[key] === "string") { + if (node.graph && node.graph?.get(node.children[key])) { + node.children[key] = node.graph.get(node.children[key]); + if (!node.nodes.get(node.children[key].tag)) + node.nodes.set(node.children[key].tag, node.children[key]); + } + if (!node.children[key] && node.nodes.get(node.children[key])) + node.children[key] = node.nodes.get(node.children[key]); + } else if (typeof node.children[key] === "undefined" || node.children[key] === true) { + if (node.graph && node.graph?.get(key)) { + node.children[key] = node.graph.get(key); + if (!node.nodes.get(node.children[key].tag)) + node.nodes.set(node.children[key].tag, node.children[key]); + } + if (!node.children[key] && node.nodes.get(key)) + node.children[key] = node.nodes.get(key); + } + if (node.children[key]?.runOp) + await node.children[key]._run(node.children[key], node, ...args); + } + } + }; + this.runBranch = async (node, output) => { + if (node.branch) { + let keys = Object.keys(node.branch); + await Promise.all(keys.map(async (k) => { + if (typeof node.branch[k].if === "object") + node.branch[k].if = stringifyFast2(node.branch[k].if); + let pass = false; + if (typeof node.branch[k].if === "function") { + pass = node.branch[k].if(output); + } else { + if (typeof output === "object") { + if (stringifyFast2(output) === node.branch[k].if) + pass = true; + } else if (output === node.branch[k].if) + pass = true; + } + if (pass) { + if (node.branch[k].then instanceof GraphNode2) { + if (Array.isArray(output)) + await node.branch[k].then._run(node.branch[k].then, node, ...output); + else + await node.branch[k].then._run(node.branch[k].then, node, ...output); + } else if (typeof node.branch[k].then === "function") { + if (Array.isArray(output)) + await node.branch[k].then(...output); + else + await node.branch[k].then(output); + } else if (typeof node.branch[k].then === "string") { + if (node.graph) + node.branch[k].then = node.graph.nodes.get(node.branch[k].then); + else + node.branch[k].then = node.nodes.get(node.branch[k].then); + if (node.branch[k].then instanceof GraphNode2) { + if (Array.isArray(output)) + await node.branch[k].then._run(node.branch[k].then, node, ...output); + else + await node.branch[k].then._run(node.branch[k].then, node, ...output); + } + } + } + return pass; + })); + } + }; + this.runAnimation = (animation = this.animation, args = [], node = this, origin) => { + this.animation = animation; + if (!animation) + this.animation = this.operator; + if (node.animate && !node.isAnimating && "requestAnimationFrame" in window) { + node.isAnimating = true; + let anim = async () => { + if (node.isAnimating) { + if (node.DEBUGNODE) + console.time(node.tag); + let result = this.animation(node, origin, ...args); + if (result instanceof Promise) { + result = await result; + } + if (node.DEBUGNODE) { + console.timeEnd(node.tag); + if (result !== void 0) + console.log(`${node.tag} result:`, result); + } + ; + if (result !== void 0) { + if (this.tag) + this.setState({ [this.tag]: result }); + if (node.backward && node.parent?._run) { + if (Array.isArray(result)) + await this.runParent(node, ...result); + else + await this.runParent(node, result); + } + if (node.children && node.forward) { + if (Array.isArray(result)) + await this.runChildren(node, ...result); + else + await this.runChildren(node, result); + } + if (node.branch) { + this.runBranch(node, result); + } + this.setState({ [node.tag]: result }); + } + requestAnimationFrame(anim); + } + }; + requestAnimationFrame(anim); + } + }; + this.runLoop = (loop = this.looper, args = [], node = this, origin, timeout = node.loop) => { + node.looper = loop; + if (!loop) + node.looper = node.operator; + if (typeof timeout === "number" && !node.isLooping) { + node.isLooping = true; + let looping = async () => { + if (node.isLooping) { + if (node.DEBUGNODE) + console.time(node.tag); + let result = node.looper(node, origin, ...args); + if (result instanceof Promise) { + result = await result; + } + if (node.DEBUGNODE) { + console.timeEnd(node.tag); + if (result !== void 0) + console.log(`${node.tag} result:`, result); + } + ; + if (result !== void 0) { + if (node.tag) + node.setState({ [node.tag]: result }); + if (node.backward && node.parent?._run) { + if (Array.isArray(result)) + await this.runParent(node, ...result); + else + await this.runParent(node, result); + } + if (node.children && node.forward) { + if (Array.isArray(result)) + await this.runChildren(node, ...result); + else + await this.runChildren(node, result); + } + if (node.branch) { + this.runBranch(node, result); + } + node.setState({ [node.tag]: result }); + } + setTimeout(async () => { + await looping(); + }, timeout); + } + }; + looping(); + } + }; + this.setParent = (parent) => { + this.parent = parent; + if (this.backward) + this.runSync = false; + }; + this.setChildren = (children) => { + this.children = children; + if (this.forward) + this.runSync = false; + }; + this.add = (node = {}) => { + if (typeof node === "function") + node = { operator: node }; + if (!(node instanceof GraphNode2)) + node = new GraphNode2(node, this, this.graph); + this.nodes.set(node.tag, node); + if (this.graph) { + this.graph.nodes.set(node.tag, node); + this.graph.nNodes = this.graph.nodes.size; + } + return node; + }; + this.remove = (node) => { + if (typeof node === "string") + node = this.nodes.get(node); + if (node instanceof GraphNode2) { + this.nodes.delete(node.tag); + if (this.children[node.tag]) + delete this.children[node.tag]; + if (this.graph) { + this.graph.nodes.delete(node.tag); + this.graph.nNodes = this.graph.nodes.size; + } + this.nodes.forEach((n) => { + if (n.nodes.get(node.tag)) { + n.nodes.delete(node.tag); + if (n.children[node.tag]) + delete n.children[node.tag]; + if (n.parent?.tag === node.tag) + delete n.parent; + } + }); + if (node.ondelete) + node.ondelete(node); + } + }; + this.append = (node, parentNode2 = this) => { + if (typeof node === "string") + node = this.nodes.get(node); + if (node instanceof GraphNode2) { + parentNode2.addChildren(node); + if (node.forward) + node.runSync = false; + } + }; + this.subscribe = (callback, tag = this.tag) => { + if (callback instanceof GraphNode2) { + return this.subscribeNode(callback); + } else + return this.state.subscribeTrigger(tag, callback); + }; + this.unsubscribe = (sub, tag = this.tag) => { + this.state.unsubscribeTrigger(tag, sub); + }; + this.addChildren = (children) => { + if (!this.children) + this.children = {}; + if (typeof children === "object") { + Object.assign(this.children, children); + } + this.convertChildrenToNodes(); + if (this.forward) + this.runSync = false; + }; + this.callParent = (...args) => { + const origin = this; + if (typeof this.parent === "string") { + if (this.graph && this.graph?.get(this.parent)) { + this.parent = this.graph; + if (this.parent) + this.nodes.set(this.parent.tag, this.parent); + } else + this.parent = this.nodes.get(this.parent); + } + if (typeof this.parent?.operator === "function") + return this.parent.runOp(this.parent, origin, ...args); + }; + this.callChildren = (idx, ...args) => { + const origin = this; + let result; + if (typeof this.children === "object") { + for (const key in this.children) { + if (this.children[key]?.runOp) + this.children[key].runOp(this.children[key], origin, ...args); + } + } + return result; + }; + this.getProps = (node = this) => { + return { tag: node.tag, operator: node.operator, graph: node.graph, children: node.children, parent: node.parent, forward: node.forward, backward: node.bacward, loop: node.loop, animate: node.animate, frame: node.frame, delay: node.delay, recursive: node.recursive, repeat: node.repeat, branch: node.branch, oncreate: node.oncreate, DEBUGNODE: node.DEBUGNODE, ...this._initial }; + }; + this.setProps = (props = {}) => { + let tmp = Object.assign({}, props); + if (tmp.children) { + this.addChildren(props.children); + delete tmp.children; + } + if (tmp.operator) { + this.setOperator(props.operator); + delete tmp.operator; + } + Object.assign(tmp, props); + if (!(this.children && this.forward || this.parent && this.backward || this.repeat || this.delay || this.frame || this.recursive)) + this.runSync = true; + }; + this.removeTree = (node) => { + if (node) { + if (typeof node === "string") + node = this.nodes.get(node); + } + if (node instanceof GraphNode2) { + let checked = {}; + const recursivelyRemove = (node2) => { + if (typeof node2.children === "object" && !checked[node2.tag]) { + checked[node2.tag] = true; + for (const key in node2.children) { + if (node2.children[key].stopNode) + node2.children[key].stopNode(); + if (node2.children[key].tag) { + if (this.nodes.get(node2.children[key].tag)) + this.nodes.delete(node2.children[key].tag); + this.nodes.forEach((n) => { + if (n.nodes.get(node2.children[key].tag)) + n.nodes.delete(node2.children[key].tag); + if (n.children[key] instanceof GraphNode2) + delete n.children[key]; + }); + recursivelyRemove(node2.children[key]); + } + } + } + }; + if (node.stopNode) + node.stopNode(); + if (node.tag) { + this.nodes.delete(node.tag); + if (this.children[node.tag]) + delete this.children[node.tag]; + if (this.parent?.tag === node.tag) + delete this.parent; + if (this[node.tag] instanceof GraphNode2) + delete this[node.tag]; + this.nodes.forEach((n) => { + if (node?.tag) { + if (n.nodes.get(node.tag)) + n.nodes.delete(node.tag); + if (n.children[node.tag] instanceof GraphNode2) + delete n.children[node.tag]; + } + }); + recursivelyRemove(node); + if (this.graph) + this.graph.removeTree(node, checked); + else if (node.ondelete) + node.ondelete(node); + } + } + }; + this.checkNodesHaveChildMapped = (node, child, checked = {}) => { + let tag = node.tag; + if (!tag) + tag = node.name; + if (!checked[tag]) { + checked[tag] = true; + if (node.children) { + if (child.tag in node.children) { + if (node.children[child.tag] instanceof GraphNode2) { + if (!node.nodes.get(child.tag)) + node.nodes.set(child.tag, child); + node.children[child.tag] = child; + if (!node.firstRun) + node.firstRun = true; + } + } + } + if (node.parent instanceof GraphNode2) { + if (node.nodes.get(child.tag) && !node.parent.nodes.get(child.tag)) + node.parent.nodes.set(child.tag, child); + if (node.parent.children) { + this.checkNodesHaveChildMapped(node.parent, child, checked); + } else if (node.nodes) { + node.nodes.forEach((n) => { + if (!checked[n.tag]) { + this.checkNodesHaveChildMapped(n, child, checked); + } + }); + } + } + if (node.graph) { + if (node.parent && node.parent.name !== node.graph.name) { + node.graph.nodes.forEach((n) => { + if (!checked[n.tag]) { + this.checkNodesHaveChildMapped(n, child, checked); + } + }); + } + } + } + }; + this.convertChildrenToNodes = (n = this) => { + if (n?.children) { + for (const key in n.children) { + if (!(n.children[key] instanceof GraphNode2)) { + if (typeof n.children[key] === "object") { + if (!n.children[key].tag) + n.children[key].tag = key; + if (!n.nodes.get(n.children[key].tag)) { + n.children[key] = new GraphNode2(n.children[key], n, n.graph); + this.checkNodesHaveChildMapped(n, n.children[key]); + } + } else { + if (typeof n.children[key] === "undefined" || n.children[key] == true) { + n.children[key] = n.graph.get(key); + if (!n.children[key]) + n.children[key] = n.nodes.get(key); + } else if (typeof n.children[key] === "string") { + let k = n.children[key]; + n.children[key] = n.graph.get(k); + if (!n.children[key]) + n.children[key] = n.nodes.get(key); + } + if (n.children[key] instanceof GraphNode2) { + if (n.graph) { + let props = n.children[key].getProps(); + delete props.parent; + delete props.graph; + if (n.source instanceof Graph2) { + n.children[key] = new GraphNode2(props, n, n.source); + } else { + n.children[key] = new GraphNode2(props, n, n.graph); + } + } + n.nodes.set(n.children[key].tag, n.children[key]); + this.checkNodesHaveChildMapped(n, n.children[key]); + if (!(n.children[key].tag in n)) + n[n.children[key].tag] = n.children[key]; + } + } + } + } + } + return n.children; + }; + this.stopLooping = (node = this) => { + node.isLooping = false; + }; + this.stopAnimating = (node = this) => { + node.isAnimating = false; + }; + this.stopNode = (node = this) => { + node.stopAnimating(node); + node.stopLooping(node); + }; + this.subscribeNode = (node) => { + if (node.tag) + this.nodes.set(node.tag, node); + return this.state.subscribeTrigger(this.tag, (res) => { + node._run(node, this, res); + }); + }; + this.print = (node = this, printChildren = true, nodesPrinted = []) => { + let dummyNode = new GraphNode2(); + if (typeof node === "string") + node = this.nodes.get(node); + if (node instanceof GraphNode2) { + nodesPrinted.push(node.tag); + let jsonToPrint = { tag: node.tag, operator: node.operator.toString() }; + if (node.parent) + jsonToPrint.parent = node.parent.tag; + if (typeof node.children === "object") { + for (const key in node.children) { + if (typeof node.children[key] === "string") + return node.children[key]; + if (nodesPrinted.includes(node.children[key].tag)) + return node.children[key].tag; + else if (!printChildren) { + return node.children[key].tag; + } else + return node.children[key].print(node.children[key], printChildren, nodesPrinted); + } + } + for (const prop in node) { + if (prop === "parent" || prop === "children") + continue; + if (typeof dummyNode[prop] === "undefined") { + if (typeof node[prop] === "function") { + jsonToPrint[prop] = node[prop].toString(); + } else if (typeof node[prop] === "object") { + jsonToPrint[prop] = JSON.stringifyWithCircularRefs(node[prop]); + } else { + jsonToPrint[prop] = node[prop]; + } + } + } + return JSON.stringify(jsonToPrint); + } + }; + this.reconstruct = (json) => { + let parsed = reconstructObject2(json); + if (parsed) + return this.add(parsed); + }; + this.setState = this.state.setState; + this.DEBUGNODES = (debugging = true) => { + this.DEBUGNODE = debugging; + this.nodes.forEach((n) => { + if (debugging) + n.DEBUGNODE = true; + else + n.DEBUGNODE = false; + }); + }; + if (typeof properties === "function") { + properties = { operator: properties }; + } + if (typeof properties === "object") { + if (properties instanceof GraphNode2 && properties._initial) + Object.assign(properties, properties._initial); + if (properties instanceof Graph2) { + let source = properties; + properties = { source, operator: (input) => { + if (typeof input === "object") { + let result = {}; + for (const key in input) { + if (typeof source[key] === "function") { + if (Array.isArray(input[key])) + result[key] = source[key](...input[key]); + else + result[key] = source[key](input[key]); + } else { + source[key] = input[key]; + result[key] = source[key]; + } + } + return result; + } + return source; + } }; + if (source.operator) + properties.operator = source.operator; + if (source.children) + properties.children = source.children; + if (source.forward) + properties.forward = source.forward; + if (source.backward) + properties.backward = source.backward; + if (source.repeat) + properties.repeat = source.repeat; + if (source.recursive) + properties.recursive = source.recursive; + if (source.loop) + properties.loop = source.loop; + if (source.animate) + properties.animate = source.animate; + if (source.looper) + properties.looper = source.looper; + if (source.animation) + properties.animation = source.animation; + if (source.delay) + properties.delay = source.delay; + if (source.tag) + properties.tag = source.tag; + if (source.oncreate) + properties.oncreate = source.oncreate; + if (source.node) { + if (source.node._initial) + Object.assign(properties, source.node._initial); + } + if (source._initial) + Object.assign(properties, source._initial); + this.nodes = source.nodes; + source.node = this; + if (graph) { + source.nodes.forEach((n) => { + if (!graph.nodes.get(n.tag)) { + graph.nodes.set(n.tag, n); + graph.nNodes++; + } + }); + } + } + if (properties.tag && (graph || parentNode)) { + let hasnode; + if (graph?.nodes) { + hasnode = graph.nodes.get(properties.tag); + } + if (!hasnode && parentNode?.nodes) { + hasnode = parentNode.nodes.get(properties.tag); + } + if (hasnode) { + Object.assign(this, hasnode); + if (!this.source) + this.source = hasnode; + let props = hasnode.getProps(); + delete props.graph; + delete props.parent; + Object.assign(properties, props); + } + } + if (properties?.operator) { + properties.operator = this.setOperator(properties.operator); + } + if (!properties.tag && graph) { + properties.tag = `node${graph.nNodes}`; + } else if (!properties.tag) { + properties.tag = `node${Math.floor(Math.random() * 1e10)}`; + } + if ("arguments" in properties) { + if (properties.arguments) { + for (let key in properties.arguments) { + this.arguments.set(key, properties.arguments[key]); + } + } + properties.arguments = this.arguments; + } + let keys = Object.getOwnPropertyNames(this); + for (const key in properties) { + if (!keys.includes(key)) + this._initial[key] = properties[key]; + } + if (properties.children) + this._initial.children = Object.assign({}, properties.children); + Object.assign(this, properties); + if (!this.tag) { + if (graph) { + this.tag = `node${graph.nNodes}`; + } else { + this.tag = `node${Math.floor(Math.random() * 1e10)}`; + } + } + if (graph) { + this.graph = graph; + if (graph.nodes.get(this.tag)) { + this.tag = `${this.tag}${graph.nNodes + 1}`; + } + graph.nodes.set(this.tag, this); + graph.nNodes++; + } + if (parentNode) { + this.parent = parentNode; + if (parentNode instanceof GraphNode2 || parentNode instanceof Graph2) + parentNode.nodes.set(this.tag, this); + } + if (typeof properties.tree === "object") { + for (const key in properties.tree) { + if (typeof properties.tree[key] === "object") { + if ((!properties.tree[key]).tag) { + properties.tree[key].tag = key; + } + } + let node = new GraphNode2(properties.tree[key], this, graph); + this.nodes.set(node.tag, node); + } + } + if (this.children) + this.convertChildrenToNodes(this); + if (this.parent instanceof GraphNode2 || this.parent instanceof Graph2) + this.checkNodesHaveChildMapped(this.parent, this); + if (typeof this.oncreate === "function") + this.oncreate(this); + if (!this.firstRun) + this.firstRun = true; + } else + return properties; + } + }; + var Graph2 = class { + constructor(tree, tag, props) { + this.nNodes = 0; + this.nodes = /* @__PURE__ */ new Map(); + this.state = state2; + this.tree = {}; + this.add = (node = {}) => { + let props2 = node; + if (!(node instanceof GraphNode2)) + node = new GraphNode2(props2, this, this); + else { + this.nNodes = this.nodes.size; + if (node.tag) { + this.tree[node.tag] = props2; + this.nodes.set(node.tag, node); + } + } + return node; + }; + this.setTree = (tree2 = this.tree) => { + if (!tree2) + return; + for (const node in tree2) { + if (!this.nodes.get(node)) { + if (typeof tree2[node] === "function") { + this.add({ tag: node, operator: tree2[node] }); + } else if (typeof tree2[node] === "object" && !Array.isArray(tree2[node])) { + if (!tree2[node].tag) + tree2[node].tag = node; + let newNode = this.add(tree2[node]); + if (tree2[node].aliases) { + tree2[node].aliases.forEach((a) => { + this.nodes.set(a, newNode); + }); + } + } else { + this.add({ tag: node, operator: (self2, origin, ...args) => { + return tree2[node]; + } }); + } + } else { + let n = this.nodes.get(node); + if (typeof tree2[node] === "function") { + n.setOperator(tree2[node]); + } else if (typeof tree2[node] === "object") { + if (tree2[node] instanceof GraphNode2) { + this.add(tree2[node]); + } else if (tree2[node] instanceof Graph2) { + let source = tree2[node]; + let properties = {}; + if (source.operator) + properties.operator = source.operator; + if (source.children) + properties.children = source.children; + if (source.forward) + properties.forward = source.forward; + if (source.backward) + properties.backward = source.backward; + if (source.repeat) + properties.repeat = source.repeat; + if (source.recursive) + properties.recursive = source.recursive; + if (source.loop) + properties.loop = source.loop; + if (source.animate) + properties.animate = source.animate; + if (source.looper) + properties.looper = source.looper; + if (source.animation) + properties.animation = source.animation; + if (source.delay) + properties.delay = source.delay; + if (source.tag) + properties.tag = source.tag; + if (source.oncreate) + properties.oncreate = source.oncreate; + if (source.node?._initial) + Object.assign(properties, source.node._initial); + properties.nodes = source.nodes; + properties.source = source; + n.setProps(properties); + } else { + n.setProps(tree2[node]); + } + } + } + } + this.nodes.forEach((node) => { + if (typeof node.children === "object") { + for (const key in node.children) { + if (typeof node.children[key] === "string") { + if (this.nodes.get(node.children[key])) { + node.children[key] = this.nodes.get(node.children[key]); + } + } else if (node.children[key] === true || typeof node.children[key] === "undefined") { + if (this.nodes.get(key)) { + node.children[key] = this.nodes.get(key); + } + } + if (node.children[key] instanceof GraphNode2) { + node.checkNodesHaveChildMapped(node, node.children[key]); + } + } + } + if (typeof node.parent === "string") { + if (this.nodes.get(node.parent)) { + node.parent = this.nodes.get(node.parent); + node.nodes.set(node.parent.tag, node.parent); + } + } + }); + }; + this.get = (tag2) => { + return this.nodes.get(tag2); + }; + this.set = (node) => { + return this.nodes.set(node.tag, node); + }; + this.run = (node, ...args) => { + if (typeof node === "string") + node = this.nodes.get(node); + if (node instanceof GraphNode2) + return node._run(node, this, ...args); + else + return void 0; + }; + this.runAsync = (node, ...args) => { + if (typeof node === "string") + node = this.nodes.get(node); + if (node instanceof GraphNode2) + return new Promise((res, rej) => { + res(node._run(node, this, ...args)); + }); + else + return new Promise((res, rej) => { + res(void 0); + }); + }; + this._run = (node, origin = this, ...args) => { + if (typeof node === "string") + node = this.nodes.get(node); + if (node instanceof GraphNode2) + return node._run(node, origin, ...args); + else + return void 0; + }; + this.removeTree = (node, checked) => { + if (typeof node === "string") + node = this.nodes.get(node); + if (node instanceof GraphNode2) { + if (!checked) + checked = {}; + const recursivelyRemove = (node2) => { + if (node2.children && !checked[node2.tag]) { + checked[node2.tag] = true; + if (Array.isArray(node2.children)) { + node2.children.forEach((c) => { + if (c.stopNode) + c.stopNode(); + if (c.tag) { + if (this.nodes.get(c.tag)) + this.nodes.delete(c.tag); + } + this.nodes.forEach((n) => { + if (n.nodes.get(c.tag)) + n.nodes.delete(c.tag); + }); + recursivelyRemove(c); + }); + } else if (typeof node2.children === "object") { + if (node2.stopNode) + node2.stopNode(); + if (node2.tag) { + if (this.nodes.get(node2.tag)) + this.nodes.delete(node2.tag); + } + this.nodes.forEach((n) => { + if (n.nodes.get(node2.tag)) + n.nodes.delete(node2.tag); + }); + recursivelyRemove(node2); + } + } + }; + if (node.stopNode) + node.stopNode(); + if (node.tag) { + this.nodes.delete(node.tag); + this.nodes.forEach((n) => { + if (n.nodes.get(node.tag)) + n.nodes.delete(node.tag); + }); + this.nNodes = this.nodes.size; + recursivelyRemove(node); + } + if (node.ondelete) + node.ondelete(node); + } + return node; + }; + this.remove = (node) => { + if (typeof node === "string") + node = this.nodes.get(node); + if (node instanceof GraphNode2) { + node.stopNode(); + if (node?.tag) { + if (this.nodes.get(node.tag)) { + this.nodes.delete(node.tag); + this.nodes.forEach((n) => { + if (n.nodes.get(node.tag)) + n.nodes.delete(node.tag); + }); + } + } + if (node.ondelete) + node.ondelete(node); + } + return node; + }; + this.append = (node, parentNode) => { + parentNode.addChildren(node); + }; + this.callParent = async (node, origin = node, ...args) => { + if (node?.parent) { + return await node.callParent(node, origin, ...args); + } + }; + this.callChildren = async (node, idx, ...args) => { + if (node?.children) { + return await node.callChildren(idx, ...args); + } + }; + this.subscribe = (node, callback) => { + if (!callback) + return; + if (node instanceof GraphNode2) { + return node.subscribe(callback); + } else if (typeof node == "string") + return this.state.subscribeTrigger(node, callback); + }; + this.unsubscribe = (tag2, sub) => { + this.state.unsubscribeTrigger(tag2, sub); + }; + this.subscribeNode = (inputNode, outputNode) => { + let tag2; + if (inputNode?.tag) + tag2 = inputNode.tag; + else if (typeof inputNode === "string") + tag2 = inputNode; + return this.state.subscribeTrigger(tag2, (res) => { + this.run(outputNode, inputNode, ...res); + }); + }; + this.stopNode = (node) => { + if (typeof node === "string") { + node = this.nodes.get(node); + } + if (node instanceof GraphNode2) { + node.stopNode(); + } + }; + this.print = (node = void 0, printChildren = true) => { + if (node instanceof GraphNode2) + return node.print(node, printChildren); + else { + let printed = `{`; + this.nodes.forEach((n) => { + printed += ` +"${n.tag}:${n.print(n, printChildren)}"`; + }); + return printed; + } + }; + this.reconstruct = (json) => { + let parsed = reconstructObject2(json); + if (parsed) + return this.add(parsed); + }; + this.create = (operator, parentNode, props2) => { + return createNode2(operator, parentNode, props2, this); + }; + this.setState = this.state.setState; + this.DEBUGNODES = (debugging = true) => { + this.nodes.forEach((n) => { + if (debugging) + n.DEBUGNODE = true; + else + n.DEBUGNODE = false; + }); + }; + this.tag = tag ? tag : `graph${Math.floor(Math.random() * 1e11)}`; + if (props) { + Object.assign(this, props); + this._initial = props; + } + if (tree || Object.keys(this.tree).length > 0) + this.setTree(tree); + } + }; + function reconstructNode(json, parentNode, graph) { + let reconstructed = reconstructObject2(json); + if (reconstructed) + return new GraphNode2(reconstructed, parentNode, graph); + else + return void 0; + } + function reconstructObject2(json = "{}") { + try { + let parsed = typeof json === "string" ? JSON.parse(json) : json; + const parseObj = (obj) => { + for (const prop in obj) { + if (typeof obj[prop] === "string") { + let funcParsed = parseFunctionFromText2(obj[prop]); + if (typeof funcParsed === "function") { + obj[prop] = funcParsed; + } + } else if (typeof obj[prop] === "object") { + parseObj(obj[prop]); + } + } + return obj; + }; + return parseObj(parsed); + } catch (err) { + console.error(err); + return void 0; + } + } + var stringifyWithCircularRefs2 = function() { + const refs = /* @__PURE__ */ new Map(); + const parents = []; + const path3 = ["this"]; + function clear() { + refs.clear(); + parents.length = 0; + path3.length = 1; + } + function updateParents(key, value2) { + var idx = parents.length - 1; + var prev = parents[idx]; + if (typeof prev === "object") { + if (prev[key] === value2 || idx === 0) { + path3.push(key); + parents.push(value2.pushed); + } else { + while (idx-- >= 0) { + prev = parents[idx]; + if (typeof prev === "object") { + if (prev[key] === value2) { + idx += 2; + parents.length = idx; + path3.length = idx; + --idx; + parents[idx] = value2; + path3[idx] = key; + break; + } + } + idx--; + } + } + } + } + function checkCircular(key, value2) { + if (value2 != null) { + if (typeof value2 === "object") { + if (key) { + updateParents(key, value2); + } + let other = refs.get(value2); + if (other) { + return "[Circular Reference]" + other; + } else { + refs.set(value2, path3.join(".")); + } + } + } + return value2; + } + return function stringifyWithCircularRefs22(obj, space) { + try { + parents.push(obj); + return JSON.stringify(obj, checkCircular, space); + } finally { + clear(); + } + }; + }(); + if (JSON.stringifyWithCircularRefs === void 0) { + JSON.stringifyWithCircularRefs = stringifyWithCircularRefs2; + } + var stringifyFast2 = function() { + const refs = /* @__PURE__ */ new Map(); + const parents = []; + const path3 = ["this"]; + function clear() { + refs.clear(); + parents.length = 0; + path3.length = 1; + } + function updateParents(key, value2) { + var idx = parents.length - 1; + if (parents[idx]) { + var prev = parents[idx]; + if (typeof prev === "object") { + if (prev[key] === value2 || idx === 0) { + path3.push(key); + parents.push(value2.pushed); + } else { + while (idx-- >= 0) { + prev = parents[idx]; + if (typeof prev === "object") { + if (prev[key] === value2) { + idx += 2; + parents.length = idx; + path3.length = idx; + --idx; + parents[idx] = value2; + path3[idx] = key; + break; + } + } + idx++; + } + } + } + } + } + function checkValues(key, value2) { + let val; + if (value2 != null) { + if (typeof value2 === "object") { + let c = value2.constructor.name; + if (key && c === "Object") { + updateParents(key, value2); + } + let other = refs.get(value2); + if (other) { + return "[Circular Reference]" + other; + } else { + refs.set(value2, path3.join(".")); + } + if (c === "Array") { + if (value2.length > 20) { + val = value2.slice(value2.length - 20); + } else + val = value2; + } else if (c.includes("Set")) { + val = Array.from(value2); + } else if (c !== "Object" && c !== "Number" && c !== "String" && c !== "Boolean") { + val = "instanceof_" + c; + } else if (c === "Object") { + let obj = {}; + for (const prop in value2) { + if (value2[prop] == null) { + obj[prop] = value2[prop]; + } else if (Array.isArray(value2[prop])) { + if (value2[prop].length > 20) + obj[prop] = value2[prop].slice(value2[prop].length - 20); + else + obj[prop] = value2[prop]; + } else if (value2[prop].constructor.name === "Object") { + obj[prop] = {}; + for (const p in value2[prop]) { + if (Array.isArray(value2[prop][p])) { + if (value2[prop][p].length > 20) + obj[prop][p] = value2[prop][p].slice(value2[prop][p].length - 20); + else + obj[prop][p] = value2[prop][p]; + } else { + if (value2[prop][p] != null) { + let con = value2[prop][p].constructor.name; + if (con.includes("Set")) { + obj[prop][p] = Array.from(value2[prop][p]); + } else if (con !== "Number" && con !== "String" && con !== "Boolean") { + obj[prop][p] = "instanceof_" + con; + } else { + obj[prop][p] = value2[prop][p]; + } + } else { + obj[prop][p] = value2[prop][p]; + } + } + } + } else { + let con = value2[prop].constructor.name; + if (con.includes("Set")) { + obj[prop] = Array.from(value2[prop]); + } else if (con !== "Number" && con !== "String" && con !== "Boolean") { + obj[prop] = "instanceof_" + con; + } else { + obj[prop] = value2[prop]; + } + } + } + val = obj; + } else { + val = value2; + } + } else { + val = value2; + } + } + return val; + } + return function stringifyFast22(obj, space) { + parents.push(obj); + let res = JSON.stringify(obj, checkValues, space); + clear(); + return res; + }; + }(); + if (JSON.stringifyFast === void 0) { + JSON.stringifyFast = stringifyFast2; + } + function createNode2(operator, parentNode, props, graph) { + if (typeof props === "object") { + props.operator = operator; + return new GraphNode2(props, parentNode, graph); + } + return new GraphNode2({ operator }, parentNode, graph); + } + var Service2 = class extends Graph2 { + constructor(options = {}) { + super(void 0, options.name ? options.name : `service${Math.floor(Math.random() * 1e14)}`, options.props); + this.routes = {}; + this.loadDefaultRoutes = false; + this.keepState = true; + this.firstLoad = true; + this.init = (options2) => { + if (options2) + options2 = Object.assign({}, options2); + else + options2 = {}; + if (options2.customRoutes) + Object.assign(options2.customRoutes, this.customRoutes); + else + options2.customRoutes = this.customRoutes; + if (options2.customChildren) + Object.assign(options2.customChildren, this.customChildren); + else + options2.customChildren = this.customChildren; + if (Array.isArray(options2.routes)) { + options2.routes.forEach((r) => { + this.load(r, options2.includeClassName, options2.routeFormat, options2.customRoutes, options2.customChildren); + }); + } else if (options2.routes || (Object.keys(this.routes).length > 0 || this.loadDefaultRoutes) && this.firstLoad) + this.load(options2.routes, options2.includeClassName, options2.routeFormat, options2.customRoutes, options2.customChildren); + }; + this.load = (routes, includeClassName = true, routeFormat = ".", customRoutes, customChildren) => { + if (!routes && !this.loadDefaultRoutes && (Object.keys(this.routes).length > 0 || this.firstLoad)) + return; + if (this.firstLoad) + this.firstLoad = false; + let service; + let allRoutes = {}; + if (routes) { + if (!(routes instanceof Graph2) && routes?.name) { + if (routes.module) { + let mod = routes; + routes = {}; + Object.getOwnPropertyNames(routes.module).forEach((prop) => { + if (includeClassName) + routes[mod.name + routeFormat + prop] = routes.module[prop]; + else + routes[prop] = routes.module[prop]; + }); + } else if (typeof routes === "function") { + service = new routes({ loadDefaultRoutes: this.loadDefaultRoutes }); + service.load(); + routes = service.routes; + } + } else if (routes instanceof Graph2 || routes.source instanceof Graph2) { + service = routes; + routes = {}; + let name2; + if (includeClassName) { + name2 = service.name; + if (!name2) { + name2 = service.tag; + service.name = name2; + } + if (!name2) { + name2 = `graph${Math.floor(Math.random() * 1e15)}`; + service.name = name2; + service.tag = name2; + } + } + if (service.customRoutes && !this.customRoutes) + this.customRoutes = service.customRoutes; + else if (service.customRoutes && this.customRoutes) + Object.assign(this.customRoutes, service.customRoutes); + if (service.customChildren && !this.customChildren) + this.customChildren = service.customChildren; + else if (service.customChildren && this.customChildren) + Object.assign(this.customChildren, service.customChildren); + service.nodes.forEach((node) => { + routes[node.tag] = node; + let checked = {}; + let checkChildGraphNodes = (nd, par) => { + if (!checked[nd.tag] || par && includeClassName && !checked[par?.tag + routeFormat + nd.tag]) { + if (!par) + checked[nd.tag] = true; + else + checked[par.tag + routeFormat + nd.tag] = true; + if (nd instanceof Graph2 || nd.source instanceof Graph2) { + if (includeClassName) { + let nm = nd.name; + if (!nm) { + nm = nd.tag; + nd.name = nm; + } + if (!nm) { + nm = `graph${Math.floor(Math.random() * 1e15)}`; + nd.name = nm; + nd.tag = nm; + } + } + nd.nodes.forEach((n) => { + if (includeClassName && !routes[nd.tag + routeFormat + n.tag]) + routes[nd.tag + routeFormat + n.tag] = n; + else if (!routes[n.tag]) + routes[n.tag] = n; + checkChildGraphNodes(n, nd); + }); + } + } + }; + checkChildGraphNodes(node); + }); + } else if (typeof routes === "object") { + let name2 = routes.constructor.name; + if (name2 === "Object") { + name2 = Object.prototype.toString.call(routes); + if (name2) + name2 = name2.split(" ")[1]; + if (name2) + name2 = name2.split("]")[0]; + } + if (name2 && name2 !== "Object") { + let module22 = routes; + routes = {}; + Object.getOwnPropertyNames(module22).forEach((route) => { + if (includeClassName) + routes[name2 + routeFormat + route] = module22[route]; + else + routes[route] = module22[route]; + }); + } + } + if (service instanceof Graph2 && service.name && includeClassName) { + routes = Object.assign({}, routes); + for (const prop in routes) { + let route = routes[prop]; + delete routes[prop]; + routes[service.name + routeFormat + prop] = route; + } + } + } + if (this.loadDefaultRoutes) { + let rts = Object.assign({}, this.defaultRoutes); + if (routes) { + Object.assign(rts, this.routes); + routes = Object.assign(rts, routes); + } else + routes = Object.assign(rts, this.routes); + this.loadDefaultRoutes = false; + } + if (!routes) + routes = this.routes; + let incr = 0; + for (const tag in routes) { + incr++; + let childrenIter = (route, routeKey) => { + if (typeof route === "object") { + if (!route.tag) + route.tag = routeKey; + if (typeof route?.children === "object") { + nested: + for (const key in route.children) { + incr++; + if (typeof route.children[key] === "object") { + let rt = route.children[key]; + if (rt.tag && allRoutes[rt.tag]) + continue; + if (customChildren) { + for (const k2 in customChildren) { + rt = customChildren[k2](rt, key, route, routes, allRoutes); + if (!rt) + continue nested; + } + } + if (rt.id && !rt.tag) { + rt.tag = rt.id; + } + let k; + if (rt.tag) { + if (allRoutes[rt.tag]) { + let randkey = `${rt.tag}${incr}`; + allRoutes[randkey] = rt; + rt.tag = randkey; + childrenIter(allRoutes[randkey], key); + k = randkey; + } else { + allRoutes[rt.tag] = rt; + childrenIter(allRoutes[rt.tag], key); + k = rt.tag; + } + } else { + if (allRoutes[key]) { + let randkey = `${key}${incr}`; + allRoutes[randkey] = rt; + rt.tag = randkey; + childrenIter(allRoutes[randkey], key); + k = randkey; + } else { + allRoutes[key] = rt; + childrenIter(allRoutes[key], key); + k = key; + } + } + if (service?.name && includeClassName) { + allRoutes[service.name + routeFormat + k] = rt; + delete allRoutes[k]; + } else + allRoutes[k] = rt; + } + } + } + } + }; + allRoutes[tag] = routes[tag]; + childrenIter(routes[tag], tag); + } + top: + for (const route in allRoutes) { + if (typeof allRoutes[route] === "object") { + let r = allRoutes[route]; + if (typeof r === "object") { + if (customRoutes) { + for (const key in customRoutes) { + r = customRoutes[key](r, route, allRoutes); + if (!r) + continue top; + } + } + if (r.get) { + if (typeof r.get == "object") { + } + } + if (r.post) { + } + if (r.delete) { + } + if (r.put) { + } + if (r.head) { + } + if (r.patch) { + } + if (r.options) { + } + if (r.connect) { + } + if (r.trace) { + } + if (r.post && !r.operator) { + allRoutes[route].operator = r.post; + } else if (!r.operator && typeof r.get == "function") { + allRoutes[route].operator = r.get; + } + } + } + } + for (const route in routes) { + if (typeof routes[route] === "object") { + if (this.routes[route]) { + if (typeof this.routes[route] === "object") + Object.assign(this.routes[route], routes[route]); + else + this.routes[route] = routes[route]; + } else + this.routes[route] = routes[route]; + } else if (this.routes[route]) { + if (typeof this.routes[route] === "object") + Object.assign(this.routes[route], routes[route]); + else + this.routes[route] = routes[route]; + } else + this.routes[route] = routes[route]; + } + if (service) { + for (const key in this.routes) { + if (this.routes[key] instanceof GraphNode2) { + this.nodes.set(key, this.routes[key]); + this.nNodes = this.nodes.size; + } + } + } else + this.setTree(this.routes); + for (const prop in this.routes) { + if (this.routes[prop]?.aliases) { + let aliases = this.routes[prop].aliases; + aliases.forEach((a) => { + if (service?.name && includeClassName) + routes[service.name + routeFormat + a] = this.routes[prop]; + else + routes[a] = this.routes[prop]; + }); + } + } + return this.routes; + }; + this.unload = (routes = this.routes) => { + if (!routes) + return; + let service; + if (!(routes instanceof Service2) && typeof routes === "function") { + service = new Service2(); + routes = service.routes; + } else if (routes instanceof Service2) { + routes = routes.routes; + } + for (const r in routes) { + delete this.routes[r]; + if (this.nodes.get(r)) + this.remove(r); + } + return this.routes; + }; + this.handleMethod = (route, method, args, origin) => { + let m = method.toLowerCase(); + if (m === "get" && this.routes[route]?.get?.transform instanceof Function) { + if (Array.isArray(args)) + return this.routes[route].get.transform(...args); + else + return this.routes[route].get.transform(args); + } + if (this.routes[route]?.[m]) { + if (!(this.routes[route][m] instanceof Function)) { + if (args) + this.routes[route][m] = args; + return this.routes[route][m]; + } else + return this.routes[route][m](args); + } else + return this.handleServiceMessage({ route, args, method, origin }); + }; + this.transmit = (...args) => { + if (typeof args[0] === "object") { + if (args[0].method) { + return this.handleMethod(args[0].route, args[0].method, args[0].args); + } else if (args[0].route) { + return this.handleServiceMessage(args[0]); + } else if (args[0].node) { + return this.handleGraphNodeCall(args[0].node, args[0].args, args[0].origin); + } else if (this.keepState) { + if (args[0].route) + this.setState({ [args[0].route]: args[0].args }); + if (args[0].node) + this.setState({ [args[0].node]: args[0].args }); + } + return args; + } else + return args; + }; + this.receive = (...args) => { + if (args[0]) { + if (typeof args[0] === "string") { + let substr = args[0].substring(0, 8); + if (substr.includes("{") || substr.includes("[")) { + if (substr.includes("\\")) + args[0] = args[0].replace(/\\/g, ""); + if (args[0][0] === '"') { + args[0] = args[0].substring(1, args[0].length - 1); + } + ; + args[0] = JSON.parse(args[0]); + } + } + } + if (typeof args[0] === "object") { + if (args[0].method) { + return this.handleMethod(args[0].route, args[0].method, args[0].args); + } else if (args[0].route) { + return this.handleServiceMessage(args[0]); + } else if (args[0].node) { + return this.handleGraphNodeCall(args[0].node, args[0].args, args[0].origin); + } else if (this.keepState) { + if (args[0].route) + this.setState({ [args[0].route]: args[0].args }); + if (args[0].node) + this.setState({ [args[0].node]: args[0].args }); + } + return args; + } else + return args; + }; + this.pipe = (source, destination, endpoint, origin, method, callback) => { + if (source instanceof GraphNode2) { + if (callback) + return source.subscribe((res) => { + let mod = callback(res); + if (mod !== void 0) + this.transmit({ route: destination, args: mod, origin, method }); + else + this.transmit({ route: destination, args: res, origin, method }, endpoint); + }); + else + return this.subscribe(source, (res) => { + this.transmit({ route: destination, args: res, origin, method }, endpoint); + }); + } else if (typeof source === "string") + return this.subscribe(source, (res) => { + this.transmit({ route: destination, args: res, origin, method }, endpoint); + }); + }; + this.pipeOnce = (source, destination, endpoint, origin, method, callback) => { + if (source instanceof GraphNode2) { + if (callback) + return source.state.subscribeTriggerOnce(source.tag, (res) => { + let mod = callback(res); + if (mod !== void 0) + this.transmit({ route: destination, args: mod, origin, method }); + else + this.transmit({ route: destination, args: res, origin, method }, endpoint); + }); + else + return this.state.subscribeTriggerOnce(source.tag, (res) => { + this.transmit({ route: destination, args: res, origin, method }, endpoint); + }); + } else if (typeof source === "string") + return this.state.subscribeTriggerOnce(source, (res) => { + this.transmit({ route: destination, args: res, origin, method }, endpoint); + }); + }; + this.terminate = (...args) => { + this.nodes.forEach((n) => { + n.stopNode(); + }); + }; + this.recursivelyAssign = (target, obj) => { + for (const key in obj) { + if (typeof obj[key] === "object") { + if (typeof target[key] === "object") + this.recursivelyAssign(target[key], obj[key]); + else + target[key] = this.recursivelyAssign({}, obj[key]); + } else + target[key] = obj[key]; + } + return target; + }; + this.defaultRoutes = { "/": { get: () => { + return this.print(); + }, aliases: [""] }, ping: () => { + console.log("ping"); + return "pong"; + }, echo: (...args) => { + this.transmit(...args); + return args; + }, assign: (source) => { + if (typeof source === "object") { + Object.assign(this, source); + return true; + } + return false; + }, recursivelyAssign: (source) => { + if (typeof source === "object") { + this.recursivelyAssign(this, source); + return true; + } + return false; + }, log: { post: (...args) => { + console.log("Log: ", ...args); + }, aliases: ["info"] }, error: (message) => { + let er = new Error(message); + console.error(message); + return er; + }, state: (key) => { + if (key) { + return this.state.data[key]; + } else + return this.state.data; + }, printState: (key) => { + if (key) { + return stringifyWithCircularRefs2(this.state.data[key]); + } else + return stringifyWithCircularRefs2(this.state.data); + }, transmit: this.transmit, receive: this.receive, load: this.load, unload: this.unload, pipe: this.pipe, terminate: this.terminate, run: this.run, _run: this._run, subscribe: this.subscribe, unsubscribe: this.unsubscribe, stopNode: this.stopNode, get: this.get, add: this.add, remove: this.remove, setTree: this.setTree, setState: this.setState, print: this.print, reconstruct: this.reconstruct, handleMethod: this.handleMethod, handleServiceMessage: this.handleServiceMessage, handleGraphNodeCall: this.handleGraphNodeCall }; + if (options.name) + this.name = options.name; + else + options.name = this.tag; + if ("loadDefaultRoutes" in options) { + this.loadDefaultRoutes = options.loadDefaultRoutes; + this.routes = Object.assign(this.defaultRoutes, this.routes); + } + if (options || Object.keys(this.routes).length > 0) + this.init(options); + } + handleServiceMessage(message) { + let call; + if (typeof message === "object") { + if (message.route) + call = message.route; + else if (message.node) + call = message.node; + } + if (call) { + if (message.origin) { + if (Array.isArray(message.args)) + return this._run(call, message.origin, ...message.args); + else + return this._run(call, message.origin, message.args); + } else { + if (Array.isArray(message.args)) + return this.run(call, ...message.args); + else + return this.run(call, message.args); + } + } else + return message; + } + handleGraphNodeCall(route, args, origin) { + if (!route) + return args; + if (args?.args) { + this.handleServiceMessage(args); + } else if (origin) { + if (Array.isArray(args)) + return this._run(route, origin, ...args); + else + return this._run(route, origin, args); + } else if (Array.isArray(args)) + return this.run(route, ...args); + else + return this.run(route, args); + } + isTypedArray(x2) { + return ArrayBuffer.isView(x2) && Object.prototype.toString.call(x2) !== "[object DataView]"; + } + }; + var unsafeRoutes = { setRoute: (self2, origin, fn, fnName) => { + if (typeof fn === "string") + fn = parseFunctionFromText2(fn); + if (typeof fn === "function") { + if (!fnName) + fnName = fn.name; + if (self2.graph.get(fnName)) { + self2.graph.get(fnName).setOperator(fn); + } else + self2.graph.load({ [fnName]: { operator: fn } }); + return true; + } + return false; + }, setNode: (self2, origin, fn, fnName) => { + if (typeof fn === "string") + fn = parseFunctionFromText2(fn); + if (typeof fn === "function") { + if (!fnName) + fnName = fn.name; + if (self2.graph.get(fnName)) { + self2.graph.get(fnName).setOperator(fn); + } else + self2.graph.add({ tag: fnName, operator: fn }); + return true; + } + return false; + }, setMethod: (self2, origin, route, fn, fnName) => { + if (typeof fn === "string") + fn = parseFunctionFromText2(fn); + if (typeof fn === "function") { + if (!fnName) + fnName = fn.name; + if (self2.graph.get(route)) { + self2.graph.get(route)[fnName] = fn; + } else + self2.graph.add({ tag: fnName, [fnName]: fn }); + return true; + } + return false; + }, assignRoute: (self2, origin, route, source) => { + if (self2.graph.get(route) && typeof source === "object") { + Object.assign(self2.graph.get(route), source); + } + }, transferClass: (classObj, className) => { + if (typeof classObj === "object") { + let str = classObj.toString(); + let message = { route: "receiveClass", args: [str, className] }; + return message; + } + return false; + }, receiveClass: (self2, origin, stringified, className) => { + if (typeof stringified === "string") { + if (stringified.indexOf("class") === 0) { + let cls = (0, eval)("(" + stringified + ")"); + let name2 = className; + if (!name2) + name2 = cls.name; + self2.graph[name2] = cls; + return true; + } + } + return false; + }, setValue: (self2, origin, key, value2) => { + globalThis[key] = value2; + return true; + }, assignObject: (self2, origin, target, source) => { + if (!globalThis[target]) + return false; + if (typeof source === "object") + Object.assign(globalThis[target], source); + return true; + }, setFunction: (self2, origin, fn, fnName) => { + if (typeof fn === "string") + fn = parseFunctionFromText2(fn); + if (typeof fn === "function") { + if (!fnName) + fnName = fn.name; + globalThis[fnName] = fn; + return true; + } + return false; + }, assignFunctionToObject: (self2, origin, globalObjectName, fn, fnName) => { + if (!globalThis[globalObjectName]) + return false; + if (typeof fn === "string") + fn = parseFunctionFromText2(fn); + if (typeof fn === "function") { + if (!fnName) + fnName = fn.name; + globalThis[globalObjectName][fnName] = fn; + return true; + } + return false; + } }; + var import_sjcl = __toESM2(require_sjcl()); + var E2EEService = class extends Service2 { + constructor(options, keys, secureKeys, secret) { + super(options); + this.name = "e2ee"; + this.securedKeys = false; + this.addKey = (key, _id) => { + if (!_id) + _id = `key${Math.floor(Math.random() * 1e15)}`; + if (this.securedKeys && this.secret && this.encryptedkeys) { + let decrypted = JSON.parse(import_sjcl.default.decrypt(this.secret, this.encryptedkeys)); + decrypted[_id] = { key, _id }; + this.encryptedkeys = import_sjcl.default.encrypt(this.secret, decrypted).cipher; + return this.encryptedkeys; + } else + this.keys[_id] = { key, _id }; + return this.keys[_id]; + }; + this.encryptRoute = (message, keyId) => { + if (typeof message === "object") + message = JSON.stringify(message); + let key; + if (this.securedKeys && this.secret && this.encryptedkeys) { + let decrypted = JSON.parse(import_sjcl.default.decrypt(this.secret, this.encryptedkeys)); + if (decrypted[keyId]?.key) { + message = import_sjcl.default.encrypt(this.secret, decrypted[keyId].key).cipher; + } + } else { + if (this.keys[keyId]) { + if (!key) + key = keyId; + message = this.encrypt(message, key); + } + } + message = { route: "decryptRoute", args: [message, keyId] }; + return message; + }; + this.decryptRoute = (message, keyId) => { + let decryptedMessage = message; + if (typeof message === "object") { + if (!keyId) { + if (typeof message.origin === "string") + keyId = message.origin; + else if (typeof message.keyId === "string") + keyId = message.keyId; + } + if (keyId) { + let key; + if (this.securedKeys && this.secret && this.encryptedkeys) { + let decrypted = JSON.parse(import_sjcl.default.decrypt(this.secret, this.encryptedkeys)); + if (decrypted[keyId]?.key) { + decryptedMessage = import_sjcl.default.decrypt(this.secret, decrypted[keyId].key); + return decryptedMessage; + } + } else { + if (this.keys[keyId]) + key = this.keys[keyId].key; + if (key) + decryptedMessage = this.decrypt(message.args, key); + } + } + } else { + let key; + if (this.securedKeys && this.secret && this.encryptedkeys) { + let decrypted = JSON.parse(import_sjcl.default.decrypt(this.secret, this.encryptedkeys)); + if (decrypted[keyId]?.key) { + decryptedMessage = import_sjcl.default.decrypt(this.secret, decrypted[keyId].key); + return decryptedMessage; + } + } else { + if (this.keys[keyId]) + key = this.keys[keyId].key; + if (key) + decryptedMessage = this.decrypt(message, key); + } + } + return decryptedMessage; + }; + this.transmit = (message, keyId) => { + if (!keyId) { + keyId = Object.keys(this.keys)[0]; + } + message = this.encryptRoute(message, keyId); + return this.handleServiceMessage(message); + }; + this.receive = (message, keyId) => { + if (!keyId) { + keyId = Object.keys(this.keys)[0]; + } + message = this.decryptRoute(message, keyId); + if (typeof message === "string") { + let substr = message.substring(0, 8); + if (substr.includes("{") || substr.includes("[")) { + if (substr.includes("\\")) + message = message.replace(/\\/g, ""); + if (message[0] === '"') { + message = message.substring(1, message.length - 1); + } + ; + message = JSON.parse(message); + } + } + if (typeof message === "object") { + if (typeof message.method === "string") { + return this.handleMethod(message.route, message.method, message.args); + } else if (typeof message.route === "string") { + return this.handleServiceMessage(message); + } else if (typeof message.node === "string" || message.node instanceof GraphNode2) { + return this.handleGraphNodeCall(message.node, message.args, message.origin); + } else if (this.keepState) { + if (message.route) + this.setState({ [message.route]: message.args }); + if (message.node) + this.setState({ [message.node]: message.args }); + } + } else + return message; + }; + this.routes = { encryptRoute: this.encryptRoute, decryptRoute: this.decryptRoute, encrypt: this.encrypt, decrypt: this.decrypt, generateSecret: E2EEService.generateSecret, addKey: this.addKey }; + if (keys) { + if (secureKeys && secret) { + this.securedKeys = true; + this.encryptedkeys = import_sjcl.default.encrypt(secret, JSON.stringify(keys)).cipher; + this.secret = secret; + } else + Object.assign(this.keys, keys); + } + } + static generateSecret() { + return import_sjcl.default.codec.base64.fromBits(import_sjcl.default.random.randomWords(8, 10)); + } + encrypt(message, key) { + message = import_sjcl.default.encrypt(key, message).cipher; + return message; + } + decrypt(message, key) { + message = import_sjcl.default.decrypt(key, message); + return message; + } + }; + (() => { + var Zt = Object.create; + var Je = Object.defineProperty; + var Jt = Object.getOwnPropertyDescriptor; + var Qt = Object.getOwnPropertyNames; + var qt = Object.getPrototypeOf, ei = Object.prototype.hasOwnProperty; + var Re = ((L) => typeof require != "undefined" ? require : typeof Proxy != "undefined" ? new Proxy(L, { get: (I, $) => (typeof require != "undefined" ? require : I)[$] }) : L)(function(L) { + if (typeof require != "undefined") + return require.apply(this, arguments); + throw new Error('Dynamic require of "' + L + '" is not supported'); + }); + var ti = (L, I) => () => (I || L((I = { exports: {} }).exports, I), I.exports), ii = (L, I) => { + for (var $ in I) + Je(L, $, { get: I[$], enumerable: true }); + }, ni = (L, I, $, o) => { + if (I && typeof I == "object" || typeof I == "function") + for (let y of Qt(I)) + !ei.call(L, y) && y !== $ && Je(L, y, { get: () => I[y], enumerable: !(o = Jt(I, y)) || o.enumerable }); + return L; + }; + var si = (L, I, $) => ($ = L != null ? Zt(qt(L)) : {}, ni(I || !L || !L.__esModule ? Je($, "default", { value: L, enumerable: true }) : $, L)); + var Et = ti((wt, Qe) => { + (function(L) { + if (typeof wt == "object" && typeof Qe < "u") + Qe.exports = L(); + else if (typeof define == "function" && define.amd) + define([], L); + else { + var I; + typeof window < "u" ? I = window : typeof global < "u" ? I = global : typeof self < "u" ? I = self : I = this, L(); + } + })(function() { + var L, I, $; + return function() { + function o(y, E, p) { + function g(n, s) { + if (!E[n]) { + if (!y[n]) { + var t = typeof Re == "function" && Re; + if (!s && t) + return t(n, true); + if (f) + return f(n, true); + var i = new Error("Cannot find module '" + n + "'"); + throw i.code = "MODULE_NOT_FOUND", i; + } + var u = E[n] = { exports: {} }; + y[n][0].call(u.exports, function(x2) { + var w = y[n][1][x2]; + return g(w || x2); + }, u, u.exports, o, y, E, p); + } + return E[n].exports; + } + for (var f = typeof Re == "function" && Re, l = 0; l < p.length; l++) + g(p[l]); + return g; + } + return o; + }()({ 1: [function(o, y, E) { + (function(p, g) { + typeof E == "object" && typeof y < "u" ? g(E) : typeof L == "function" && L.amd ? L(["exports"], g) : (p = p || self, g(p.acorn = {})); + })(this, function(p) { + "use strict"; + var g = { 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", 5: "class enum extends super const export import", 6: "enum", strict: "implements interface let package private protected public static yield", strictBind: "eval arguments" }, f = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this", l = { 5: f, "5module": f + " export import", 6: f + " const class extends export import super" }, n = /^in(stanceof)?$/, s = "\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1878\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEF\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7BF\uA7C2-\uA7C6\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB67\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC", t = "\u200C\u200D\xB7\u0300-\u036F\u0387\u0483-\u0487\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u0669\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u06F0-\u06F9\u0711\u0730-\u074A\u07A6-\u07B0\u07C0-\u07C9\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0966-\u096F\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09E6-\u09EF\u09FE\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A66-\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AE6-\u0AEF\u0AFA-\u0AFF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B66-\u0B6F\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0BE6-\u0BEF\u0C00-\u0C04\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0CE6-\u0CEF\u0D00-\u0D03\u0D3B\u0D3C\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D66-\u0D6F\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0E50-\u0E59\u0EB1\u0EB4-\u0EBC\u0EC8-\u0ECD\u0ED0-\u0ED9\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1040-\u1049\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F-\u109D\u135D-\u135F\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u18A9\u1920-\u192B\u1930-\u193B\u1946-\u194F\u19D0-\u19DA\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AB0-\u1ABD\u1B00-\u1B04\u1B34-\u1B44\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BB0-\u1BB9\u1BE6-\u1BF3\u1C24-\u1C37\u1C40-\u1C49\u1C50-\u1C59\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF4\u1CF7-\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u203F\u2040\u2054\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA620-\uA629\uA66F\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F1\uA8FF-\uA909\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9D0-\uA9D9\uA9E5\uA9F0-\uA9F9\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA50-\uAA59\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uABF0-\uABF9\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFF10-\uFF19\uFF3F", i = new RegExp("[" + s + "]"), u = new RegExp("[" + s + t + "]"); + s = t = null; + var x2 = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 157, 310, 10, 21, 11, 7, 153, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 477, 28, 11, 0, 9, 21, 155, 22, 13, 52, 76, 44, 33, 24, 27, 35, 30, 0, 12, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 85, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 21, 0, 33, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 230, 43, 117, 63, 32, 0, 161, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 35, 56, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 270, 921, 103, 110, 18, 195, 2749, 1070, 4050, 582, 8634, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 754, 9486, 286, 50, 2, 18, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 2357, 44, 11, 6, 17, 0, 370, 43, 1301, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42710, 42, 4148, 12, 221, 3, 5761, 15, 7472, 3104, 541], w = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 525, 10, 176, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 4, 9, 83, 11, 7, 0, 161, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 232, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 19306, 9, 135, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 19723, 1, 5319, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 262, 6, 10, 9, 419, 13, 1495, 6, 110, 6, 6, 9, 792487, 239]; + function m(e, r) { + for (var d = 65536, _ = 0; _ < r.length; _ += 2) { + if (d += r[_], d > e) + return false; + if (d += r[_ + 1], d >= e) + return true; + } + } + function S(e, r) { + return e < 65 ? e === 36 : e < 91 ? true : e < 97 ? e === 95 : e < 123 ? true : e <= 65535 ? e >= 170 && i.test(String.fromCharCode(e)) : r === false ? false : m(e, x2); + } + function v(e, r) { + return e < 48 ? e === 36 : e < 58 ? true : e < 65 ? false : e < 91 ? true : e < 97 ? e === 95 : e < 123 ? true : e <= 65535 ? e >= 170 && u.test(String.fromCharCode(e)) : r === false ? false : m(e, x2) || m(e, w); + } + var h = function(r, d) { + d === void 0 && (d = {}), this.label = r, this.keyword = d.keyword, this.beforeExpr = !!d.beforeExpr, this.startsExpr = !!d.startsExpr, this.isLoop = !!d.isLoop, this.isAssign = !!d.isAssign, this.prefix = !!d.prefix, this.postfix = !!d.postfix, this.binop = d.binop || null, this.updateContext = null; + }; + function b(e, r) { + return new h(e, { beforeExpr: true, binop: r }); + } + var T = { beforeExpr: true }, C = { startsExpr: true }, V = {}; + function c(e, r) { + return r === void 0 && (r = {}), r.keyword = e, V[e] = new h(e, r); + } + var a = { num: new h("num", C), regexp: new h("regexp", C), string: new h("string", C), name: new h("name", C), eof: new h("eof"), bracketL: new h("[", { beforeExpr: true, startsExpr: true }), bracketR: new h("]"), braceL: new h("{", { beforeExpr: true, startsExpr: true }), braceR: new h("}"), parenL: new h("(", { beforeExpr: true, startsExpr: true }), parenR: new h(")"), comma: new h(",", T), semi: new h(";", T), colon: new h(":", T), dot: new h("."), question: new h("?", T), arrow: new h("=>", T), template: new h("template"), invalidTemplate: new h("invalidTemplate"), ellipsis: new h("...", T), backQuote: new h("`", C), dollarBraceL: new h("${", { beforeExpr: true, startsExpr: true }), eq: new h("=", { beforeExpr: true, isAssign: true }), assign: new h("_=", { beforeExpr: true, isAssign: true }), incDec: new h("++/--", { prefix: true, postfix: true, startsExpr: true }), prefix: new h("!/~", { beforeExpr: true, prefix: true, startsExpr: true }), logicalOR: b("||", 1), logicalAND: b("&&", 2), bitwiseOR: b("|", 3), bitwiseXOR: b("^", 4), bitwiseAND: b("&", 5), equality: b("==/!=/===/!==", 6), relational: b("/<=/>=", 7), bitShift: b("<>/>>>", 8), plusMin: new h("+/-", { beforeExpr: true, binop: 9, prefix: true, startsExpr: true }), modulo: b("%", 10), star: b("*", 10), slash: b("/", 10), starstar: new h("**", { beforeExpr: true }), _break: c("break"), _case: c("case", T), _catch: c("catch"), _continue: c("continue"), _debugger: c("debugger"), _default: c("default", T), _do: c("do", { isLoop: true, beforeExpr: true }), _else: c("else", T), _finally: c("finally"), _for: c("for", { isLoop: true }), _function: c("function", C), _if: c("if"), _return: c("return", T), _switch: c("switch"), _throw: c("throw", T), _try: c("try"), _var: c("var"), _const: c("const"), _while: c("while", { isLoop: true }), _with: c("with"), _new: c("new", { beforeExpr: true, startsExpr: true }), _this: c("this", C), _super: c("super", C), _class: c("class", C), _extends: c("extends", T), _export: c("export"), _import: c("import", C), _null: c("null", C), _true: c("true", C), _false: c("false", C), _in: c("in", { beforeExpr: true, binop: 7 }), _instanceof: c("instanceof", { beforeExpr: true, binop: 7 }), _typeof: c("typeof", { beforeExpr: true, prefix: true, startsExpr: true }), _void: c("void", { beforeExpr: true, prefix: true, startsExpr: true }), _delete: c("delete", { beforeExpr: true, prefix: true, startsExpr: true }) }, k = /\r\n?|\n|\u2028|\u2029/, A = new RegExp(k.source, "g"); + function N(e, r) { + return e === 10 || e === 13 || !r && (e === 8232 || e === 8233); + } + var F = /[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/, R = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g, K = Object.prototype, O = K.hasOwnProperty, X = K.toString; + function B(e, r) { + return O.call(e, r); + } + var P = Array.isArray || function(e) { + return X.call(e) === "[object Array]"; + }; + function Y(e) { + return new RegExp("^(?:" + e.replace(/ /g, "|") + ")$"); + } + var J = function(r, d) { + this.line = r, this.column = d; + }; + J.prototype.offset = function(r) { + return new J(this.line, this.column + r); + }; + var q = function(r, d, _) { + this.start = d, this.end = _, r.sourceFile !== null && (this.source = r.sourceFile); + }; + function j(e, r) { + for (var d = 1, _ = 0; ; ) { + A.lastIndex = _; + var D = A.exec(e); + if (D && D.index < r) + ++d, _ = D.index + D[0].length; + else + return new J(d, r - _); + } + } + var U = { ecmaVersion: 10, sourceType: "script", onInsertedSemicolon: null, onTrailingComma: null, allowReserved: null, allowReturnOutsideFunction: false, allowImportExportEverywhere: false, allowAwaitOutsideFunction: false, allowHashBang: false, locations: false, onToken: null, onComment: null, ranges: false, program: null, sourceFile: null, directSourceFile: null, preserveParens: false }; + function oe(e) { + var r = {}; + for (var d in U) + r[d] = e && B(e, d) ? e[d] : U[d]; + if (r.ecmaVersion >= 2015 && (r.ecmaVersion -= 2009), r.allowReserved == null && (r.allowReserved = r.ecmaVersion < 5), P(r.onToken)) { + var _ = r.onToken; + r.onToken = function(D) { + return _.push(D); + }; + } + return P(r.onComment) && (r.onComment = Z(r, r.onComment)), r; + } + function Z(e, r) { + return function(d, _, D, M, z, G) { + var H = { type: d ? "Block" : "Line", value: _, start: D, end: M }; + e.locations && (H.loc = new q(this, z, G)), e.ranges && (H.range = [D, M]), r.push(H); + }; + } + var ee = 1, be = 2, Q = ee | be, ue = 4, he = 8, pe = 16, te = 32, re = 64, de = 128; + function Te(e, r) { + return be | (e ? ue : 0) | (r ? he : 0); + } + var Se = 0, Ce = 1, _e = 2, st = 3, rt = 4, at = 5, le = function(r, d, _) { + this.options = r = oe(r), this.sourceFile = r.sourceFile, this.keywords = Y(l[r.ecmaVersion >= 6 ? 6 : r.sourceType === "module" ? "5module" : 5]); + var D = ""; + if (r.allowReserved !== true) { + for (var M = r.ecmaVersion; !(D = g[M]); M--) + ; + r.sourceType === "module" && (D += " await"); + } + this.reservedWords = Y(D); + var z = (D ? D + " " : "") + g.strict; + this.reservedWordsStrict = Y(z), this.reservedWordsStrictBind = Y(z + " " + g.strictBind), this.input = String(d), this.containsEsc = false, _ ? (this.pos = _, this.lineStart = this.input.lastIndexOf(` +`, _ - 1) + 1, this.curLine = this.input.slice(0, this.lineStart).split(k).length) : (this.pos = this.lineStart = 0, this.curLine = 1), this.type = a.eof, this.value = null, this.start = this.end = this.pos, this.startLoc = this.endLoc = this.curPosition(), this.lastTokEndLoc = this.lastTokStartLoc = null, this.lastTokStart = this.lastTokEnd = this.pos, this.context = this.initialContext(), this.exprAllowed = true, this.inModule = r.sourceType === "module", this.strict = this.inModule || this.strictDirective(this.pos), this.potentialArrowAt = -1, this.yieldPos = this.awaitPos = this.awaitIdentPos = 0, this.labels = [], this.undefinedExports = {}, this.pos === 0 && r.allowHashBang && this.input.slice(0, 2) === "#!" && this.skipLineComment(2), this.scopeStack = [], this.enterScope(ee), this.regexpState = null; + }, Ae = { inFunction: { configurable: true }, inGenerator: { configurable: true }, inAsync: { configurable: true }, allowSuper: { configurable: true }, allowDirectSuper: { configurable: true }, treatFunctionsAsVar: { configurable: true } }; + le.prototype.parse = function() { + var r = this.options.program || this.startNode(); + return this.nextToken(), this.parseTopLevel(r); + }, Ae.inFunction.get = function() { + return (this.currentVarScope().flags & be) > 0; + }, Ae.inGenerator.get = function() { + return (this.currentVarScope().flags & he) > 0; + }, Ae.inAsync.get = function() { + return (this.currentVarScope().flags & ue) > 0; + }, Ae.allowSuper.get = function() { + return (this.currentThisScope().flags & re) > 0; + }, Ae.allowDirectSuper.get = function() { + return (this.currentThisScope().flags & de) > 0; + }, Ae.treatFunctionsAsVar.get = function() { + return this.treatFunctionsAsVarInScope(this.currentScope()); + }, le.prototype.inNonArrowFunction = function() { + return (this.currentThisScope().flags & be) > 0; + }, le.extend = function() { + for (var r = [], d = arguments.length; d--; ) + r[d] = arguments[d]; + for (var _ = this, D = 0; D < r.length; D++) + _ = r[D](_); + return _; + }, le.parse = function(r, d) { + return new this(d, r).parse(); + }, le.parseExpressionAt = function(r, d, _) { + var D = new this(_, r, d); + return D.nextToken(), D.parseExpression(); + }, le.tokenizer = function(r, d) { + return new this(d, r); + }, Object.defineProperties(le.prototype, Ae); + var ge = le.prototype, Ft = /^(?:'((?:\\.|[^'])*?)'|"((?:\\.|[^"])*?)")/; + ge.strictDirective = function(e) { + for (; ; ) { + R.lastIndex = e, e += R.exec(this.input)[0].length; + var r = Ft.exec(this.input.slice(e)); + if (!r) + return false; + if ((r[1] || r[2]) === "use strict") + return true; + e += r[0].length, R.lastIndex = e, e += R.exec(this.input)[0].length, this.input[e] === ";" && e++; + } + }, ge.eat = function(e) { + return this.type === e ? (this.next(), true) : false; + }, ge.isContextual = function(e) { + return this.type === a.name && this.value === e && !this.containsEsc; + }, ge.eatContextual = function(e) { + return this.isContextual(e) ? (this.next(), true) : false; + }, ge.expectContextual = function(e) { + this.eatContextual(e) || this.unexpected(); + }, ge.canInsertSemicolon = function() { + return this.type === a.eof || this.type === a.braceR || k.test(this.input.slice(this.lastTokEnd, this.start)); + }, ge.insertSemicolon = function() { + if (this.canInsertSemicolon()) + return this.options.onInsertedSemicolon && this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc), true; + }, ge.semicolon = function() { + !this.eat(a.semi) && !this.insertSemicolon() && this.unexpected(); + }, ge.afterTrailingComma = function(e, r) { + if (this.type === e) + return this.options.onTrailingComma && this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc), r || this.next(), true; + }, ge.expect = function(e) { + this.eat(e) || this.unexpected(); + }, ge.unexpected = function(e) { + this.raise(e ?? this.start, "Unexpected token"); + }; + function Ve() { + this.shorthandAssign = this.trailingComma = this.parenthesizedAssign = this.parenthesizedBind = this.doubleProto = -1; + } + ge.checkPatternErrors = function(e, r) { + if (!!e) { + e.trailingComma > -1 && this.raiseRecoverable(e.trailingComma, "Comma is not permitted after the rest element"); + var d = r ? e.parenthesizedAssign : e.parenthesizedBind; + d > -1 && this.raiseRecoverable(d, "Parenthesized pattern"); + } + }, ge.checkExpressionErrors = function(e, r) { + if (!e) + return false; + var d = e.shorthandAssign, _ = e.doubleProto; + if (!r) + return d >= 0 || _ >= 0; + d >= 0 && this.raise(d, "Shorthand property assignments are valid only in destructuring patterns"), _ >= 0 && this.raiseRecoverable(_, "Redefinition of __proto__ property"); + }, ge.checkYieldAwaitInDefaultParams = function() { + this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos) && this.raise(this.yieldPos, "Yield expression cannot be a default value"), this.awaitPos && this.raise(this.awaitPos, "Await expression cannot be a default value"); + }, ge.isSimpleAssignTarget = function(e) { + return e.type === "ParenthesizedExpression" ? this.isSimpleAssignTarget(e.expression) : e.type === "Identifier" || e.type === "MemberExpression"; + }; + var ie = le.prototype; + ie.parseTopLevel = function(e) { + var r = {}; + for (e.body || (e.body = []); this.type !== a.eof; ) { + var d = this.parseStatement(null, true, r); + e.body.push(d); + } + if (this.inModule) + for (var _ = 0, D = Object.keys(this.undefinedExports); _ < D.length; _ += 1) { + var M = D[_]; + this.raiseRecoverable(this.undefinedExports[M].start, "Export '" + M + "' is not defined"); + } + return this.adaptDirectivePrologue(e.body), this.next(), e.sourceType = this.options.sourceType, this.finishNode(e, "Program"); + }; + var He = { kind: "loop" }, $t = { kind: "switch" }; + ie.isLet = function(e) { + if (this.options.ecmaVersion < 6 || !this.isContextual("let")) + return false; + R.lastIndex = this.pos; + var r = R.exec(this.input), d = this.pos + r[0].length, _ = this.input.charCodeAt(d); + if (_ === 91) + return true; + if (e) + return false; + if (_ === 123) + return true; + if (S(_, true)) { + for (var D = d + 1; v(this.input.charCodeAt(D), true); ) + ++D; + var M = this.input.slice(d, D); + if (!n.test(M)) + return true; + } + return false; + }, ie.isAsyncFunction = function() { + if (this.options.ecmaVersion < 8 || !this.isContextual("async")) + return false; + R.lastIndex = this.pos; + var e = R.exec(this.input), r = this.pos + e[0].length; + return !k.test(this.input.slice(this.pos, r)) && this.input.slice(r, r + 8) === "function" && (r + 8 === this.input.length || !v(this.input.charAt(r + 8))); + }, ie.parseStatement = function(e, r, d) { + var _ = this.type, D = this.startNode(), M; + switch (this.isLet(e) && (_ = a._var, M = "let"), _) { + case a._break: + case a._continue: + return this.parseBreakContinueStatement(D, _.keyword); + case a._debugger: + return this.parseDebuggerStatement(D); + case a._do: + return this.parseDoStatement(D); + case a._for: + return this.parseForStatement(D); + case a._function: + return e && (this.strict || e !== "if" && e !== "label") && this.options.ecmaVersion >= 6 && this.unexpected(), this.parseFunctionStatement(D, false, !e); + case a._class: + return e && this.unexpected(), this.parseClass(D, true); + case a._if: + return this.parseIfStatement(D); + case a._return: + return this.parseReturnStatement(D); + case a._switch: + return this.parseSwitchStatement(D); + case a._throw: + return this.parseThrowStatement(D); + case a._try: + return this.parseTryStatement(D); + case a._const: + case a._var: + return M = M || this.value, e && M !== "var" && this.unexpected(), this.parseVarStatement(D, M); + case a._while: + return this.parseWhileStatement(D); + case a._with: + return this.parseWithStatement(D); + case a.braceL: + return this.parseBlock(true, D); + case a.semi: + return this.parseEmptyStatement(D); + case a._export: + case a._import: + if (this.options.ecmaVersion > 10 && _ === a._import) { + R.lastIndex = this.pos; + var z = R.exec(this.input), G = this.pos + z[0].length, H = this.input.charCodeAt(G); + if (H === 40) + return this.parseExpressionStatement(D, this.parseExpression()); + } + return this.options.allowImportExportEverywhere || (r || this.raise(this.start, "'import' and 'export' may only appear at the top level"), this.inModule || this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'")), _ === a._import ? this.parseImport(D) : this.parseExport(D, d); + default: + if (this.isAsyncFunction()) + return e && this.unexpected(), this.next(), this.parseFunctionStatement(D, true, !e); + var ae = this.value, ye = this.parseExpression(); + return _ === a.name && ye.type === "Identifier" && this.eat(a.colon) ? this.parseLabeledStatement(D, ae, ye, e) : this.parseExpressionStatement(D, ye); + } + }, ie.parseBreakContinueStatement = function(e, r) { + var d = r === "break"; + this.next(), this.eat(a.semi) || this.insertSemicolon() ? e.label = null : this.type !== a.name ? this.unexpected() : (e.label = this.parseIdent(), this.semicolon()); + for (var _ = 0; _ < this.labels.length; ++_) { + var D = this.labels[_]; + if ((e.label == null || D.name === e.label.name) && (D.kind != null && (d || D.kind === "loop") || e.label && d)) + break; + } + return _ === this.labels.length && this.raise(e.start, "Unsyntactic " + r), this.finishNode(e, d ? "BreakStatement" : "ContinueStatement"); + }, ie.parseDebuggerStatement = function(e) { + return this.next(), this.semicolon(), this.finishNode(e, "DebuggerStatement"); + }, ie.parseDoStatement = function(e) { + return this.next(), this.labels.push(He), e.body = this.parseStatement("do"), this.labels.pop(), this.expect(a._while), e.test = this.parseParenExpression(), this.options.ecmaVersion >= 6 ? this.eat(a.semi) : this.semicolon(), this.finishNode(e, "DoWhileStatement"); + }, ie.parseForStatement = function(e) { + this.next(); + var r = this.options.ecmaVersion >= 9 && (this.inAsync || !this.inFunction && this.options.allowAwaitOutsideFunction) && this.eatContextual("await") ? this.lastTokStart : -1; + if (this.labels.push(He), this.enterScope(0), this.expect(a.parenL), this.type === a.semi) + return r > -1 && this.unexpected(r), this.parseFor(e, null); + var d = this.isLet(); + if (this.type === a._var || this.type === a._const || d) { + var _ = this.startNode(), D = d ? "let" : this.value; + return this.next(), this.parseVar(_, true, D), this.finishNode(_, "VariableDeclaration"), (this.type === a._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) && _.declarations.length === 1 ? (this.options.ecmaVersion >= 9 && (this.type === a._in ? r > -1 && this.unexpected(r) : e.await = r > -1), this.parseForIn(e, _)) : (r > -1 && this.unexpected(r), this.parseFor(e, _)); + } + var M = new Ve(), z = this.parseExpression(true, M); + return this.type === a._in || this.options.ecmaVersion >= 6 && this.isContextual("of") ? (this.options.ecmaVersion >= 9 && (this.type === a._in ? r > -1 && this.unexpected(r) : e.await = r > -1), this.toAssignable(z, false, M), this.checkLVal(z), this.parseForIn(e, z)) : (this.checkExpressionErrors(M, true), r > -1 && this.unexpected(r), this.parseFor(e, z)); + }, ie.parseFunctionStatement = function(e, r, d) { + return this.next(), this.parseFunction(e, Le | (d ? 0 : Xe), false, r); + }, ie.parseIfStatement = function(e) { + return this.next(), e.test = this.parseParenExpression(), e.consequent = this.parseStatement("if"), e.alternate = this.eat(a._else) ? this.parseStatement("if") : null, this.finishNode(e, "IfStatement"); + }, ie.parseReturnStatement = function(e) { + return !this.inFunction && !this.options.allowReturnOutsideFunction && this.raise(this.start, "'return' outside of function"), this.next(), this.eat(a.semi) || this.insertSemicolon() ? e.argument = null : (e.argument = this.parseExpression(), this.semicolon()), this.finishNode(e, "ReturnStatement"); + }, ie.parseSwitchStatement = function(e) { + this.next(), e.discriminant = this.parseParenExpression(), e.cases = [], this.expect(a.braceL), this.labels.push($t), this.enterScope(0); + for (var r, d = false; this.type !== a.braceR; ) + if (this.type === a._case || this.type === a._default) { + var _ = this.type === a._case; + r && this.finishNode(r, "SwitchCase"), e.cases.push(r = this.startNode()), r.consequent = [], this.next(), _ ? r.test = this.parseExpression() : (d && this.raiseRecoverable(this.lastTokStart, "Multiple default clauses"), d = true, r.test = null), this.expect(a.colon); + } else + r || this.unexpected(), r.consequent.push(this.parseStatement(null)); + return this.exitScope(), r && this.finishNode(r, "SwitchCase"), this.next(), this.labels.pop(), this.finishNode(e, "SwitchStatement"); + }, ie.parseThrowStatement = function(e) { + return this.next(), k.test(this.input.slice(this.lastTokEnd, this.start)) && this.raise(this.lastTokEnd, "Illegal newline after throw"), e.argument = this.parseExpression(), this.semicolon(), this.finishNode(e, "ThrowStatement"); + }; + var Lt = []; + ie.parseTryStatement = function(e) { + if (this.next(), e.block = this.parseBlock(), e.handler = null, this.type === a._catch) { + var r = this.startNode(); + if (this.next(), this.eat(a.parenL)) { + r.param = this.parseBindingAtom(); + var d = r.param.type === "Identifier"; + this.enterScope(d ? te : 0), this.checkLVal(r.param, d ? rt : _e), this.expect(a.parenR); + } else + this.options.ecmaVersion < 10 && this.unexpected(), r.param = null, this.enterScope(0); + r.body = this.parseBlock(false), this.exitScope(), e.handler = this.finishNode(r, "CatchClause"); + } + return e.finalizer = this.eat(a._finally) ? this.parseBlock() : null, !e.handler && !e.finalizer && this.raise(e.start, "Missing catch or finally clause"), this.finishNode(e, "TryStatement"); + }, ie.parseVarStatement = function(e, r) { + return this.next(), this.parseVar(e, false, r), this.semicolon(), this.finishNode(e, "VariableDeclaration"); + }, ie.parseWhileStatement = function(e) { + return this.next(), e.test = this.parseParenExpression(), this.labels.push(He), e.body = this.parseStatement("while"), this.labels.pop(), this.finishNode(e, "WhileStatement"); + }, ie.parseWithStatement = function(e) { + return this.strict && this.raise(this.start, "'with' in strict mode"), this.next(), e.object = this.parseParenExpression(), e.body = this.parseStatement("with"), this.finishNode(e, "WithStatement"); + }, ie.parseEmptyStatement = function(e) { + return this.next(), this.finishNode(e, "EmptyStatement"); + }, ie.parseLabeledStatement = function(e, r, d, _) { + for (var D = 0, M = this.labels; D < M.length; D += 1) { + var z = M[D]; + z.name === r && this.raise(d.start, "Label '" + r + "' is already declared"); + } + for (var G = this.type.isLoop ? "loop" : this.type === a._switch ? "switch" : null, H = this.labels.length - 1; H >= 0; H--) { + var ae = this.labels[H]; + if (ae.statementStart === e.start) + ae.statementStart = this.start, ae.kind = G; + else + break; + } + return this.labels.push({ name: r, kind: G, statementStart: this.start }), e.body = this.parseStatement(_ ? _.indexOf("label") === -1 ? _ + "label" : _ : "label"), this.labels.pop(), e.label = d, this.finishNode(e, "LabeledStatement"); + }, ie.parseExpressionStatement = function(e, r) { + return e.expression = r, this.semicolon(), this.finishNode(e, "ExpressionStatement"); + }, ie.parseBlock = function(e, r) { + for (e === void 0 && (e = true), r === void 0 && (r = this.startNode()), r.body = [], this.expect(a.braceL), e && this.enterScope(0); !this.eat(a.braceR); ) { + var d = this.parseStatement(null); + r.body.push(d); + } + return e && this.exitScope(), this.finishNode(r, "BlockStatement"); + }, ie.parseFor = function(e, r) { + return e.init = r, this.expect(a.semi), e.test = this.type === a.semi ? null : this.parseExpression(), this.expect(a.semi), e.update = this.type === a.parenR ? null : this.parseExpression(), this.expect(a.parenR), e.body = this.parseStatement("for"), this.exitScope(), this.labels.pop(), this.finishNode(e, "ForStatement"); + }, ie.parseForIn = function(e, r) { + var d = this.type === a._in; + return this.next(), r.type === "VariableDeclaration" && r.declarations[0].init != null && (!d || this.options.ecmaVersion < 8 || this.strict || r.kind !== "var" || r.declarations[0].id.type !== "Identifier") ? this.raise(r.start, (d ? "for-in" : "for-of") + " loop variable declaration may not have an initializer") : r.type === "AssignmentPattern" && this.raise(r.start, "Invalid left-hand side in for-loop"), e.left = r, e.right = d ? this.parseExpression() : this.parseMaybeAssign(), this.expect(a.parenR), e.body = this.parseStatement("for"), this.exitScope(), this.labels.pop(), this.finishNode(e, d ? "ForInStatement" : "ForOfStatement"); + }, ie.parseVar = function(e, r, d) { + for (e.declarations = [], e.kind = d; ; ) { + var _ = this.startNode(); + if (this.parseVarId(_, d), this.eat(a.eq) ? _.init = this.parseMaybeAssign(r) : d === "const" && !(this.type === a._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) ? this.unexpected() : _.id.type !== "Identifier" && !(r && (this.type === a._in || this.isContextual("of"))) ? this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value") : _.init = null, e.declarations.push(this.finishNode(_, "VariableDeclarator")), !this.eat(a.comma)) + break; + } + return e; + }, ie.parseVarId = function(e, r) { + e.id = this.parseBindingAtom(), this.checkLVal(e.id, r === "var" ? Ce : _e, false); + }; + var Le = 1, Xe = 2, ot = 4; + ie.parseFunction = function(e, r, d, _) { + this.initFunction(e), (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !_) && (this.type === a.star && r & Xe && this.unexpected(), e.generator = this.eat(a.star)), this.options.ecmaVersion >= 8 && (e.async = !!_), r & Le && (e.id = r & ot && this.type !== a.name ? null : this.parseIdent(), e.id && !(r & Xe) && this.checkLVal(e.id, this.strict || e.generator || e.async ? this.treatFunctionsAsVar ? Ce : _e : st)); + var D = this.yieldPos, M = this.awaitPos, z = this.awaitIdentPos; + return this.yieldPos = 0, this.awaitPos = 0, this.awaitIdentPos = 0, this.enterScope(Te(e.async, e.generator)), r & Le || (e.id = this.type === a.name ? this.parseIdent() : null), this.parseFunctionParams(e), this.parseFunctionBody(e, d, false), this.yieldPos = D, this.awaitPos = M, this.awaitIdentPos = z, this.finishNode(e, r & Le ? "FunctionDeclaration" : "FunctionExpression"); + }, ie.parseFunctionParams = function(e) { + this.expect(a.parenL), e.params = this.parseBindingList(a.parenR, false, this.options.ecmaVersion >= 8), this.checkYieldAwaitInDefaultParams(); + }, ie.parseClass = function(e, r) { + this.next(); + var d = this.strict; + this.strict = true, this.parseClassId(e, r), this.parseClassSuper(e); + var _ = this.startNode(), D = false; + for (_.body = [], this.expect(a.braceL); !this.eat(a.braceR); ) { + var M = this.parseClassElement(e.superClass !== null); + M && (_.body.push(M), M.type === "MethodDefinition" && M.kind === "constructor" && (D && this.raise(M.start, "Duplicate constructor in the same class"), D = true)); + } + return e.body = this.finishNode(_, "ClassBody"), this.strict = d, this.finishNode(e, r ? "ClassDeclaration" : "ClassExpression"); + }, ie.parseClassElement = function(e) { + var r = this; + if (this.eat(a.semi)) + return null; + var d = this.startNode(), _ = function(H, ae) { + ae === void 0 && (ae = false); + var ye = r.start, Ie = r.startLoc; + return r.eatContextual(H) ? r.type !== a.parenL && (!ae || !r.canInsertSemicolon()) ? true : (d.key && r.unexpected(), d.computed = false, d.key = r.startNodeAt(ye, Ie), d.key.name = H, r.finishNode(d.key, "Identifier"), false) : false; + }; + d.kind = "method", d.static = _("static"); + var D = this.eat(a.star), M = false; + D || (this.options.ecmaVersion >= 8 && _("async", true) ? (M = true, D = this.options.ecmaVersion >= 9 && this.eat(a.star)) : _("get") ? d.kind = "get" : _("set") && (d.kind = "set")), d.key || this.parsePropertyName(d); + var z = d.key, G = false; + return !d.computed && !d.static && (z.type === "Identifier" && z.name === "constructor" || z.type === "Literal" && z.value === "constructor") ? (d.kind !== "method" && this.raise(z.start, "Constructor can't have get/set modifier"), D && this.raise(z.start, "Constructor can't be a generator"), M && this.raise(z.start, "Constructor can't be an async method"), d.kind = "constructor", G = e) : d.static && z.type === "Identifier" && z.name === "prototype" && this.raise(z.start, "Classes may not have a static property named prototype"), this.parseClassMethod(d, D, M, G), d.kind === "get" && d.value.params.length !== 0 && this.raiseRecoverable(d.value.start, "getter should have no params"), d.kind === "set" && d.value.params.length !== 1 && this.raiseRecoverable(d.value.start, "setter should have exactly one param"), d.kind === "set" && d.value.params[0].type === "RestElement" && this.raiseRecoverable(d.value.params[0].start, "Setter cannot use rest params"), d; + }, ie.parseClassMethod = function(e, r, d, _) { + return e.value = this.parseMethod(r, d, _), this.finishNode(e, "MethodDefinition"); + }, ie.parseClassId = function(e, r) { + this.type === a.name ? (e.id = this.parseIdent(), r && this.checkLVal(e.id, _e, false)) : (r === true && this.unexpected(), e.id = null); + }, ie.parseClassSuper = function(e) { + e.superClass = this.eat(a._extends) ? this.parseExprSubscripts() : null; + }, ie.parseExport = function(e, r) { + if (this.next(), this.eat(a.star)) + return this.expectContextual("from"), this.type !== a.string && this.unexpected(), e.source = this.parseExprAtom(), this.semicolon(), this.finishNode(e, "ExportAllDeclaration"); + if (this.eat(a._default)) { + this.checkExport(r, "default", this.lastTokStart); + var d; + if (this.type === a._function || (d = this.isAsyncFunction())) { + var _ = this.startNode(); + this.next(), d && this.next(), e.declaration = this.parseFunction(_, Le | ot, false, d); + } else if (this.type === a._class) { + var D = this.startNode(); + e.declaration = this.parseClass(D, "nullableID"); + } else + e.declaration = this.parseMaybeAssign(), this.semicolon(); + return this.finishNode(e, "ExportDefaultDeclaration"); + } + if (this.shouldParseExportStatement()) + e.declaration = this.parseStatement(null), e.declaration.type === "VariableDeclaration" ? this.checkVariableExport(r, e.declaration.declarations) : this.checkExport(r, e.declaration.id.name, e.declaration.id.start), e.specifiers = [], e.source = null; + else { + if (e.declaration = null, e.specifiers = this.parseExportSpecifiers(r), this.eatContextual("from")) + this.type !== a.string && this.unexpected(), e.source = this.parseExprAtom(); + else { + for (var M = 0, z = e.specifiers; M < z.length; M += 1) { + var G = z[M]; + this.checkUnreserved(G.local), this.checkLocalExport(G.local); + } + e.source = null; + } + this.semicolon(); + } + return this.finishNode(e, "ExportNamedDeclaration"); + }, ie.checkExport = function(e, r, d) { + !e || (B(e, r) && this.raiseRecoverable(d, "Duplicate export '" + r + "'"), e[r] = true); + }, ie.checkPatternExport = function(e, r) { + var d = r.type; + if (d === "Identifier") + this.checkExport(e, r.name, r.start); + else if (d === "ObjectPattern") + for (var _ = 0, D = r.properties; _ < D.length; _ += 1) { + var M = D[_]; + this.checkPatternExport(e, M); + } + else if (d === "ArrayPattern") + for (var z = 0, G = r.elements; z < G.length; z += 1) { + var H = G[z]; + H && this.checkPatternExport(e, H); + } + else + d === "Property" ? this.checkPatternExport(e, r.value) : d === "AssignmentPattern" ? this.checkPatternExport(e, r.left) : d === "RestElement" ? this.checkPatternExport(e, r.argument) : d === "ParenthesizedExpression" && this.checkPatternExport(e, r.expression); + }, ie.checkVariableExport = function(e, r) { + if (!!e) + for (var d = 0, _ = r; d < _.length; d += 1) { + var D = _[d]; + this.checkPatternExport(e, D.id); + } + }, ie.shouldParseExportStatement = function() { + return this.type.keyword === "var" || this.type.keyword === "const" || this.type.keyword === "class" || this.type.keyword === "function" || this.isLet() || this.isAsyncFunction(); + }, ie.parseExportSpecifiers = function(e) { + var r = [], d = true; + for (this.expect(a.braceL); !this.eat(a.braceR); ) { + if (d) + d = false; + else if (this.expect(a.comma), this.afterTrailingComma(a.braceR)) + break; + var _ = this.startNode(); + _.local = this.parseIdent(true), _.exported = this.eatContextual("as") ? this.parseIdent(true) : _.local, this.checkExport(e, _.exported.name, _.exported.start), r.push(this.finishNode(_, "ExportSpecifier")); + } + return r; + }, ie.parseImport = function(e) { + return this.next(), this.type === a.string ? (e.specifiers = Lt, e.source = this.parseExprAtom()) : (e.specifiers = this.parseImportSpecifiers(), this.expectContextual("from"), e.source = this.type === a.string ? this.parseExprAtom() : this.unexpected()), this.semicolon(), this.finishNode(e, "ImportDeclaration"); + }, ie.parseImportSpecifiers = function() { + var e = [], r = true; + if (this.type === a.name) { + var d = this.startNode(); + if (d.local = this.parseIdent(), this.checkLVal(d.local, _e), e.push(this.finishNode(d, "ImportDefaultSpecifier")), !this.eat(a.comma)) + return e; + } + if (this.type === a.star) { + var _ = this.startNode(); + return this.next(), this.expectContextual("as"), _.local = this.parseIdent(), this.checkLVal(_.local, _e), e.push(this.finishNode(_, "ImportNamespaceSpecifier")), e; + } + for (this.expect(a.braceL); !this.eat(a.braceR); ) { + if (r) + r = false; + else if (this.expect(a.comma), this.afterTrailingComma(a.braceR)) + break; + var D = this.startNode(); + D.imported = this.parseIdent(true), this.eatContextual("as") ? D.local = this.parseIdent() : (this.checkUnreserved(D.imported), D.local = D.imported), this.checkLVal(D.local, _e), e.push(this.finishNode(D, "ImportSpecifier")); + } + return e; + }, ie.adaptDirectivePrologue = function(e) { + for (var r = 0; r < e.length && this.isDirectiveCandidate(e[r]); ++r) + e[r].directive = e[r].expression.raw.slice(1, -1); + }, ie.isDirectiveCandidate = function(e) { + return e.type === "ExpressionStatement" && e.expression.type === "Literal" && typeof e.expression.value == "string" && (this.input[e.start] === '"' || this.input[e.start] === "'"); + }; + var we = le.prototype; + we.toAssignable = function(e, r, d) { + if (this.options.ecmaVersion >= 6 && e) + switch (e.type) { + case "Identifier": + this.inAsync && e.name === "await" && this.raise(e.start, "Cannot use 'await' as identifier inside an async function"); + break; + case "ObjectPattern": + case "ArrayPattern": + case "RestElement": + break; + case "ObjectExpression": + e.type = "ObjectPattern", d && this.checkPatternErrors(d, true); + for (var _ = 0, D = e.properties; _ < D.length; _ += 1) { + var M = D[_]; + this.toAssignable(M, r), M.type === "RestElement" && (M.argument.type === "ArrayPattern" || M.argument.type === "ObjectPattern") && this.raise(M.argument.start, "Unexpected token"); + } + break; + case "Property": + e.kind !== "init" && this.raise(e.key.start, "Object pattern can't contain getter or setter"), this.toAssignable(e.value, r); + break; + case "ArrayExpression": + e.type = "ArrayPattern", d && this.checkPatternErrors(d, true), this.toAssignableList(e.elements, r); + break; + case "SpreadElement": + e.type = "RestElement", this.toAssignable(e.argument, r), e.argument.type === "AssignmentPattern" && this.raise(e.argument.start, "Rest elements cannot have a default value"); + break; + case "AssignmentExpression": + e.operator !== "=" && this.raise(e.left.end, "Only '=' operator can be used for specifying default value."), e.type = "AssignmentPattern", delete e.operator, this.toAssignable(e.left, r); + case "AssignmentPattern": + break; + case "ParenthesizedExpression": + this.toAssignable(e.expression, r, d); + break; + case "MemberExpression": + if (!r) + break; + default: + this.raise(e.start, "Assigning to rvalue"); + } + else + d && this.checkPatternErrors(d, true); + return e; + }, we.toAssignableList = function(e, r) { + for (var d = e.length, _ = 0; _ < d; _++) { + var D = e[_]; + D && this.toAssignable(D, r); + } + if (d) { + var M = e[d - 1]; + this.options.ecmaVersion === 6 && r && M && M.type === "RestElement" && M.argument.type !== "Identifier" && this.unexpected(M.argument.start); + } + return e; + }, we.parseSpread = function(e) { + var r = this.startNode(); + return this.next(), r.argument = this.parseMaybeAssign(false, e), this.finishNode(r, "SpreadElement"); + }, we.parseRestBinding = function() { + var e = this.startNode(); + return this.next(), this.options.ecmaVersion === 6 && this.type !== a.name && this.unexpected(), e.argument = this.parseBindingAtom(), this.finishNode(e, "RestElement"); + }, we.parseBindingAtom = function() { + if (this.options.ecmaVersion >= 6) + switch (this.type) { + case a.bracketL: + var e = this.startNode(); + return this.next(), e.elements = this.parseBindingList(a.bracketR, true, true), this.finishNode(e, "ArrayPattern"); + case a.braceL: + return this.parseObj(true); + } + return this.parseIdent(); + }, we.parseBindingList = function(e, r, d) { + for (var _ = [], D = true; !this.eat(e); ) + if (D ? D = false : this.expect(a.comma), r && this.type === a.comma) + _.push(null); + else { + if (d && this.afterTrailingComma(e)) + break; + if (this.type === a.ellipsis) { + var M = this.parseRestBinding(); + this.parseBindingListItem(M), _.push(M), this.type === a.comma && this.raise(this.start, "Comma is not permitted after the rest element"), this.expect(e); + break; + } else { + var z = this.parseMaybeDefault(this.start, this.startLoc); + this.parseBindingListItem(z), _.push(z); + } + } + return _; + }, we.parseBindingListItem = function(e) { + return e; + }, we.parseMaybeDefault = function(e, r, d) { + if (d = d || this.parseBindingAtom(), this.options.ecmaVersion < 6 || !this.eat(a.eq)) + return d; + var _ = this.startNodeAt(e, r); + return _.left = d, _.right = this.parseMaybeAssign(), this.finishNode(_, "AssignmentPattern"); + }, we.checkLVal = function(e, r, d) { + switch (r === void 0 && (r = Se), e.type) { + case "Identifier": + r === _e && e.name === "let" && this.raiseRecoverable(e.start, "let is disallowed as a lexically bound name"), this.strict && this.reservedWordsStrictBind.test(e.name) && this.raiseRecoverable(e.start, (r ? "Binding " : "Assigning to ") + e.name + " in strict mode"), d && (B(d, e.name) && this.raiseRecoverable(e.start, "Argument name clash"), d[e.name] = true), r !== Se && r !== at && this.declareName(e.name, r, e.start); + break; + case "MemberExpression": + r && this.raiseRecoverable(e.start, "Binding member expression"); + break; + case "ObjectPattern": + for (var _ = 0, D = e.properties; _ < D.length; _ += 1) { + var M = D[_]; + this.checkLVal(M, r, d); + } + break; + case "Property": + this.checkLVal(e.value, r, d); + break; + case "ArrayPattern": + for (var z = 0, G = e.elements; z < G.length; z += 1) { + var H = G[z]; + H && this.checkLVal(H, r, d); + } + break; + case "AssignmentPattern": + this.checkLVal(e.left, r, d); + break; + case "RestElement": + this.checkLVal(e.argument, r, d); + break; + case "ParenthesizedExpression": + this.checkLVal(e.expression, r, d); + break; + default: + this.raise(e.start, (r ? "Binding" : "Assigning to") + " rvalue"); + } + }; + var ne = le.prototype; + ne.checkPropClash = function(e, r, d) { + if (!(this.options.ecmaVersion >= 9 && e.type === "SpreadElement") && !(this.options.ecmaVersion >= 6 && (e.computed || e.method || e.shorthand))) { + var _ = e.key, D; + switch (_.type) { + case "Identifier": + D = _.name; + break; + case "Literal": + D = String(_.value); + break; + default: + return; + } + var M = e.kind; + if (this.options.ecmaVersion >= 6) { + D === "__proto__" && M === "init" && (r.proto && (d ? d.doubleProto < 0 && (d.doubleProto = _.start) : this.raiseRecoverable(_.start, "Redefinition of __proto__ property")), r.proto = true); + return; + } + D = "$" + D; + var z = r[D]; + if (z) { + var G; + M === "init" ? G = this.strict && z.init || z.get || z.set : G = z.init || z[M], G && this.raiseRecoverable(_.start, "Redefinition of property"); + } else + z = r[D] = { init: false, get: false, set: false }; + z[M] = true; + } + }, ne.parseExpression = function(e, r) { + var d = this.start, _ = this.startLoc, D = this.parseMaybeAssign(e, r); + if (this.type === a.comma) { + var M = this.startNodeAt(d, _); + for (M.expressions = [D]; this.eat(a.comma); ) + M.expressions.push(this.parseMaybeAssign(e, r)); + return this.finishNode(M, "SequenceExpression"); + } + return D; + }, ne.parseMaybeAssign = function(e, r, d) { + if (this.isContextual("yield")) { + if (this.inGenerator) + return this.parseYield(e); + this.exprAllowed = false; + } + var _ = false, D = -1, M = -1; + r ? (D = r.parenthesizedAssign, M = r.trailingComma, r.parenthesizedAssign = r.trailingComma = -1) : (r = new Ve(), _ = true); + var z = this.start, G = this.startLoc; + (this.type === a.parenL || this.type === a.name) && (this.potentialArrowAt = this.start); + var H = this.parseMaybeConditional(e, r); + if (d && (H = d.call(this, H, z, G)), this.type.isAssign) { + var ae = this.startNodeAt(z, G); + return ae.operator = this.value, ae.left = this.type === a.eq ? this.toAssignable(H, false, r) : H, _ || (r.parenthesizedAssign = r.trailingComma = r.doubleProto = -1), r.shorthandAssign >= ae.left.start && (r.shorthandAssign = -1), this.checkLVal(H), this.next(), ae.right = this.parseMaybeAssign(e), this.finishNode(ae, "AssignmentExpression"); + } else + _ && this.checkExpressionErrors(r, true); + return D > -1 && (r.parenthesizedAssign = D), M > -1 && (r.trailingComma = M), H; + }, ne.parseMaybeConditional = function(e, r) { + var d = this.start, _ = this.startLoc, D = this.parseExprOps(e, r); + if (this.checkExpressionErrors(r)) + return D; + if (this.eat(a.question)) { + var M = this.startNodeAt(d, _); + return M.test = D, M.consequent = this.parseMaybeAssign(), this.expect(a.colon), M.alternate = this.parseMaybeAssign(e), this.finishNode(M, "ConditionalExpression"); + } + return D; + }, ne.parseExprOps = function(e, r) { + var d = this.start, _ = this.startLoc, D = this.parseMaybeUnary(r, false); + return this.checkExpressionErrors(r) || D.start === d && D.type === "ArrowFunctionExpression" ? D : this.parseExprOp(D, d, _, -1, e); + }, ne.parseExprOp = function(e, r, d, _, D) { + var M = this.type.binop; + if (M != null && (!D || this.type !== a._in) && M > _) { + var z = this.type === a.logicalOR || this.type === a.logicalAND, G = this.value; + this.next(); + var H = this.start, ae = this.startLoc, ye = this.parseExprOp(this.parseMaybeUnary(null, false), H, ae, M, D), Ie = this.buildBinary(r, d, e, ye, G, z); + return this.parseExprOp(Ie, r, d, _, D); + } + return e; + }, ne.buildBinary = function(e, r, d, _, D, M) { + var z = this.startNodeAt(e, r); + return z.left = d, z.operator = D, z.right = _, this.finishNode(z, M ? "LogicalExpression" : "BinaryExpression"); + }, ne.parseMaybeUnary = function(e, r) { + var d = this.start, _ = this.startLoc, D; + if (this.isContextual("await") && (this.inAsync || !this.inFunction && this.options.allowAwaitOutsideFunction)) + D = this.parseAwait(), r = true; + else if (this.type.prefix) { + var M = this.startNode(), z = this.type === a.incDec; + M.operator = this.value, M.prefix = true, this.next(), M.argument = this.parseMaybeUnary(null, true), this.checkExpressionErrors(e, true), z ? this.checkLVal(M.argument) : this.strict && M.operator === "delete" && M.argument.type === "Identifier" ? this.raiseRecoverable(M.start, "Deleting local variable in strict mode") : r = true, D = this.finishNode(M, z ? "UpdateExpression" : "UnaryExpression"); + } else { + if (D = this.parseExprSubscripts(e), this.checkExpressionErrors(e)) + return D; + for (; this.type.postfix && !this.canInsertSemicolon(); ) { + var G = this.startNodeAt(d, _); + G.operator = this.value, G.prefix = false, G.argument = D, this.checkLVal(D), this.next(), D = this.finishNode(G, "UpdateExpression"); + } + } + return !r && this.eat(a.starstar) ? this.buildBinary(d, _, D, this.parseMaybeUnary(null, false), "**", false) : D; + }, ne.parseExprSubscripts = function(e) { + var r = this.start, d = this.startLoc, _ = this.parseExprAtom(e); + if (_.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")") + return _; + var D = this.parseSubscripts(_, r, d); + return e && D.type === "MemberExpression" && (e.parenthesizedAssign >= D.start && (e.parenthesizedAssign = -1), e.parenthesizedBind >= D.start && (e.parenthesizedBind = -1)), D; + }, ne.parseSubscripts = function(e, r, d, _) { + for (var D = this.options.ecmaVersion >= 8 && e.type === "Identifier" && e.name === "async" && this.lastTokEnd === e.end && !this.canInsertSemicolon() && this.input.slice(e.start, e.end) === "async"; ; ) { + var M = this.parseSubscript(e, r, d, _, D); + if (M === e || M.type === "ArrowFunctionExpression") + return M; + e = M; + } + }, ne.parseSubscript = function(e, r, d, _, D) { + var M = this.eat(a.bracketL); + if (M || this.eat(a.dot)) { + var z = this.startNodeAt(r, d); + z.object = e, z.property = M ? this.parseExpression() : this.parseIdent(this.options.allowReserved !== "never"), z.computed = !!M, M && this.expect(a.bracketR), e = this.finishNode(z, "MemberExpression"); + } else if (!_ && this.eat(a.parenL)) { + var G = new Ve(), H = this.yieldPos, ae = this.awaitPos, ye = this.awaitIdentPos; + this.yieldPos = 0, this.awaitPos = 0, this.awaitIdentPos = 0; + var Ie = this.parseExprList(a.parenR, this.options.ecmaVersion >= 8, false, G); + if (D && !this.canInsertSemicolon() && this.eat(a.arrow)) + return this.checkPatternErrors(G, false), this.checkYieldAwaitInDefaultParams(), this.awaitIdentPos > 0 && this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"), this.yieldPos = H, this.awaitPos = ae, this.awaitIdentPos = ye, this.parseArrowExpression(this.startNodeAt(r, d), Ie, true); + this.checkExpressionErrors(G, true), this.yieldPos = H || this.yieldPos, this.awaitPos = ae || this.awaitPos, this.awaitIdentPos = ye || this.awaitIdentPos; + var Fe = this.startNodeAt(r, d); + Fe.callee = e, Fe.arguments = Ie, e = this.finishNode(Fe, "CallExpression"); + } else if (this.type === a.backQuote) { + var De = this.startNodeAt(r, d); + De.tag = e, De.quasi = this.parseTemplate({ isTagged: true }), e = this.finishNode(De, "TaggedTemplateExpression"); + } + return e; + }, ne.parseExprAtom = function(e) { + this.type === a.slash && this.readRegexp(); + var r, d = this.potentialArrowAt === this.start; + switch (this.type) { + case a._super: + return this.allowSuper || this.raise(this.start, "'super' keyword outside a method"), r = this.startNode(), this.next(), this.type === a.parenL && !this.allowDirectSuper && this.raise(r.start, "super() call outside constructor of a subclass"), this.type !== a.dot && this.type !== a.bracketL && this.type !== a.parenL && this.unexpected(), this.finishNode(r, "Super"); + case a._this: + return r = this.startNode(), this.next(), this.finishNode(r, "ThisExpression"); + case a.name: + var _ = this.start, D = this.startLoc, M = this.containsEsc, z = this.parseIdent(false); + if (this.options.ecmaVersion >= 8 && !M && z.name === "async" && !this.canInsertSemicolon() && this.eat(a._function)) + return this.parseFunction(this.startNodeAt(_, D), 0, false, true); + if (d && !this.canInsertSemicolon()) { + if (this.eat(a.arrow)) + return this.parseArrowExpression(this.startNodeAt(_, D), [z], false); + if (this.options.ecmaVersion >= 8 && z.name === "async" && this.type === a.name && !M) + return z = this.parseIdent(false), (this.canInsertSemicolon() || !this.eat(a.arrow)) && this.unexpected(), this.parseArrowExpression(this.startNodeAt(_, D), [z], true); + } + return z; + case a.regexp: + var G = this.value; + return r = this.parseLiteral(G.value), r.regex = { pattern: G.pattern, flags: G.flags }, r; + case a.num: + case a.string: + return this.parseLiteral(this.value); + case a._null: + case a._true: + case a._false: + return r = this.startNode(), r.value = this.type === a._null ? null : this.type === a._true, r.raw = this.type.keyword, this.next(), this.finishNode(r, "Literal"); + case a.parenL: + var H = this.start, ae = this.parseParenAndDistinguishExpression(d); + return e && (e.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(ae) && (e.parenthesizedAssign = H), e.parenthesizedBind < 0 && (e.parenthesizedBind = H)), ae; + case a.bracketL: + return r = this.startNode(), this.next(), r.elements = this.parseExprList(a.bracketR, true, true, e), this.finishNode(r, "ArrayExpression"); + case a.braceL: + return this.parseObj(false, e); + case a._function: + return r = this.startNode(), this.next(), this.parseFunction(r, 0); + case a._class: + return this.parseClass(this.startNode(), false); + case a._new: + return this.parseNew(); + case a.backQuote: + return this.parseTemplate(); + case a._import: + return this.options.ecmaVersion >= 11 ? this.parseExprImport() : this.unexpected(); + default: + this.unexpected(); + } + }, ne.parseExprImport = function() { + var e = this.startNode(); + switch (this.next(), this.type) { + case a.parenL: + return this.parseDynamicImport(e); + default: + this.unexpected(); + } + }, ne.parseDynamicImport = function(e) { + if (this.next(), e.source = this.parseMaybeAssign(), !this.eat(a.parenR)) { + var r = this.start; + this.eat(a.comma) && this.eat(a.parenR) ? this.raiseRecoverable(r, "Trailing comma is not allowed in import()") : this.unexpected(r); + } + return this.finishNode(e, "ImportExpression"); + }, ne.parseLiteral = function(e) { + var r = this.startNode(); + return r.value = e, r.raw = this.input.slice(this.start, this.end), r.raw.charCodeAt(r.raw.length - 1) === 110 && (r.bigint = r.raw.slice(0, -1)), this.next(), this.finishNode(r, "Literal"); + }, ne.parseParenExpression = function() { + this.expect(a.parenL); + var e = this.parseExpression(); + return this.expect(a.parenR), e; + }, ne.parseParenAndDistinguishExpression = function(e) { + var r = this.start, d = this.startLoc, _, D = this.options.ecmaVersion >= 8; + if (this.options.ecmaVersion >= 6) { + this.next(); + var M = this.start, z = this.startLoc, G = [], H = true, ae = false, ye = new Ve(), Ie = this.yieldPos, Fe = this.awaitPos, De; + for (this.yieldPos = 0, this.awaitPos = 0; this.type !== a.parenR; ) + if (H ? H = false : this.expect(a.comma), D && this.afterTrailingComma(a.parenR, true)) { + ae = true; + break; + } else if (this.type === a.ellipsis) { + De = this.start, G.push(this.parseParenItem(this.parseRestBinding())), this.type === a.comma && this.raise(this.start, "Comma is not permitted after the rest element"); + break; + } else + G.push(this.parseMaybeAssign(false, ye, this.parseParenItem)); + var Xt = this.start, Yt = this.startLoc; + if (this.expect(a.parenR), e && !this.canInsertSemicolon() && this.eat(a.arrow)) + return this.checkPatternErrors(ye, false), this.checkYieldAwaitInDefaultParams(), this.yieldPos = Ie, this.awaitPos = Fe, this.parseParenArrowList(r, d, G); + (!G.length || ae) && this.unexpected(this.lastTokStart), De && this.unexpected(De), this.checkExpressionErrors(ye, true), this.yieldPos = Ie || this.yieldPos, this.awaitPos = Fe || this.awaitPos, G.length > 1 ? (_ = this.startNodeAt(M, z), _.expressions = G, this.finishNodeAt(_, "SequenceExpression", Xt, Yt)) : _ = G[0]; + } else + _ = this.parseParenExpression(); + if (this.options.preserveParens) { + var _t = this.startNodeAt(r, d); + return _t.expression = _, this.finishNode(_t, "ParenthesizedExpression"); + } else + return _; + }, ne.parseParenItem = function(e) { + return e; + }, ne.parseParenArrowList = function(e, r, d) { + return this.parseArrowExpression(this.startNodeAt(e, r), d); + }; + var Rt = []; + ne.parseNew = function() { + this.containsEsc && this.raiseRecoverable(this.start, "Escape sequence in keyword new"); + var e = this.startNode(), r = this.parseIdent(true); + if (this.options.ecmaVersion >= 6 && this.eat(a.dot)) { + e.meta = r; + var d = this.containsEsc; + return e.property = this.parseIdent(true), (e.property.name !== "target" || d) && this.raiseRecoverable(e.property.start, "The only valid meta property for new is new.target"), this.inNonArrowFunction() || this.raiseRecoverable(e.start, "new.target can only be used in functions"), this.finishNode(e, "MetaProperty"); + } + var _ = this.start, D = this.startLoc, M = this.type === a._import; + return e.callee = this.parseSubscripts(this.parseExprAtom(), _, D, true), M && e.callee.type === "ImportExpression" && this.raise(_, "Cannot use new with import()"), this.eat(a.parenL) ? e.arguments = this.parseExprList(a.parenR, this.options.ecmaVersion >= 8, false) : e.arguments = Rt, this.finishNode(e, "NewExpression"); + }, ne.parseTemplateElement = function(e) { + var r = e.isTagged, d = this.startNode(); + return this.type === a.invalidTemplate ? (r || this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal"), d.value = { raw: this.value, cooked: null }) : d.value = { raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, ` +`), cooked: this.value }, this.next(), d.tail = this.type === a.backQuote, this.finishNode(d, "TemplateElement"); + }, ne.parseTemplate = function(e) { + e === void 0 && (e = {}); + var r = e.isTagged; + r === void 0 && (r = false); + var d = this.startNode(); + this.next(), d.expressions = []; + var _ = this.parseTemplateElement({ isTagged: r }); + for (d.quasis = [_]; !_.tail; ) + this.type === a.eof && this.raise(this.pos, "Unterminated template literal"), this.expect(a.dollarBraceL), d.expressions.push(this.parseExpression()), this.expect(a.braceR), d.quasis.push(_ = this.parseTemplateElement({ isTagged: r })); + return this.next(), this.finishNode(d, "TemplateLiteral"); + }, ne.isAsyncProp = function(e) { + return !e.computed && e.key.type === "Identifier" && e.key.name === "async" && (this.type === a.name || this.type === a.num || this.type === a.string || this.type === a.bracketL || this.type.keyword || this.options.ecmaVersion >= 9 && this.type === a.star) && !k.test(this.input.slice(this.lastTokEnd, this.start)); + }, ne.parseObj = function(e, r) { + var d = this.startNode(), _ = true, D = {}; + for (d.properties = [], this.next(); !this.eat(a.braceR); ) { + if (_) + _ = false; + else if (this.expect(a.comma), this.options.ecmaVersion >= 5 && this.afterTrailingComma(a.braceR)) + break; + var M = this.parseProperty(e, r); + e || this.checkPropClash(M, D, r), d.properties.push(M); + } + return this.finishNode(d, e ? "ObjectPattern" : "ObjectExpression"); + }, ne.parseProperty = function(e, r) { + var d = this.startNode(), _, D, M, z; + if (this.options.ecmaVersion >= 9 && this.eat(a.ellipsis)) + return e ? (d.argument = this.parseIdent(false), this.type === a.comma && this.raise(this.start, "Comma is not permitted after the rest element"), this.finishNode(d, "RestElement")) : (this.type === a.parenL && r && (r.parenthesizedAssign < 0 && (r.parenthesizedAssign = this.start), r.parenthesizedBind < 0 && (r.parenthesizedBind = this.start)), d.argument = this.parseMaybeAssign(false, r), this.type === a.comma && r && r.trailingComma < 0 && (r.trailingComma = this.start), this.finishNode(d, "SpreadElement")); + this.options.ecmaVersion >= 6 && (d.method = false, d.shorthand = false, (e || r) && (M = this.start, z = this.startLoc), e || (_ = this.eat(a.star))); + var G = this.containsEsc; + return this.parsePropertyName(d), !e && !G && this.options.ecmaVersion >= 8 && !_ && this.isAsyncProp(d) ? (D = true, _ = this.options.ecmaVersion >= 9 && this.eat(a.star), this.parsePropertyName(d, r)) : D = false, this.parsePropertyValue(d, e, _, D, M, z, r, G), this.finishNode(d, "Property"); + }, ne.parsePropertyValue = function(e, r, d, _, D, M, z, G) { + if ((d || _) && this.type === a.colon && this.unexpected(), this.eat(a.colon)) + e.value = r ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, z), e.kind = "init"; + else if (this.options.ecmaVersion >= 6 && this.type === a.parenL) + r && this.unexpected(), e.kind = "init", e.method = true, e.value = this.parseMethod(d, _); + else if (!r && !G && this.options.ecmaVersion >= 5 && !e.computed && e.key.type === "Identifier" && (e.key.name === "get" || e.key.name === "set") && this.type !== a.comma && this.type !== a.braceR) { + (d || _) && this.unexpected(), e.kind = e.key.name, this.parsePropertyName(e), e.value = this.parseMethod(false); + var H = e.kind === "get" ? 0 : 1; + if (e.value.params.length !== H) { + var ae = e.value.start; + e.kind === "get" ? this.raiseRecoverable(ae, "getter should have no params") : this.raiseRecoverable(ae, "setter should have exactly one param"); + } else + e.kind === "set" && e.value.params[0].type === "RestElement" && this.raiseRecoverable(e.value.params[0].start, "Setter cannot use rest params"); + } else + this.options.ecmaVersion >= 6 && !e.computed && e.key.type === "Identifier" ? ((d || _) && this.unexpected(), this.checkUnreserved(e.key), e.key.name === "await" && !this.awaitIdentPos && (this.awaitIdentPos = D), e.kind = "init", r ? e.value = this.parseMaybeDefault(D, M, e.key) : this.type === a.eq && z ? (z.shorthandAssign < 0 && (z.shorthandAssign = this.start), e.value = this.parseMaybeDefault(D, M, e.key)) : e.value = e.key, e.shorthand = true) : this.unexpected(); + }, ne.parsePropertyName = function(e) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(a.bracketL)) + return e.computed = true, e.key = this.parseMaybeAssign(), this.expect(a.bracketR), e.key; + e.computed = false; + } + return e.key = this.type === a.num || this.type === a.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never"); + }, ne.initFunction = function(e) { + e.id = null, this.options.ecmaVersion >= 6 && (e.generator = e.expression = false), this.options.ecmaVersion >= 8 && (e.async = false); + }, ne.parseMethod = function(e, r, d) { + var _ = this.startNode(), D = this.yieldPos, M = this.awaitPos, z = this.awaitIdentPos; + return this.initFunction(_), this.options.ecmaVersion >= 6 && (_.generator = e), this.options.ecmaVersion >= 8 && (_.async = !!r), this.yieldPos = 0, this.awaitPos = 0, this.awaitIdentPos = 0, this.enterScope(Te(r, _.generator) | re | (d ? de : 0)), this.expect(a.parenL), _.params = this.parseBindingList(a.parenR, false, this.options.ecmaVersion >= 8), this.checkYieldAwaitInDefaultParams(), this.parseFunctionBody(_, false, true), this.yieldPos = D, this.awaitPos = M, this.awaitIdentPos = z, this.finishNode(_, "FunctionExpression"); + }, ne.parseArrowExpression = function(e, r, d) { + var _ = this.yieldPos, D = this.awaitPos, M = this.awaitIdentPos; + return this.enterScope(Te(d, false) | pe), this.initFunction(e), this.options.ecmaVersion >= 8 && (e.async = !!d), this.yieldPos = 0, this.awaitPos = 0, this.awaitIdentPos = 0, e.params = this.toAssignableList(r, true), this.parseFunctionBody(e, true, false), this.yieldPos = _, this.awaitPos = D, this.awaitIdentPos = M, this.finishNode(e, "ArrowFunctionExpression"); + }, ne.parseFunctionBody = function(e, r, d) { + var _ = r && this.type !== a.braceL, D = this.strict, M = false; + if (_) + e.body = this.parseMaybeAssign(), e.expression = true, this.checkParams(e, false); + else { + var z = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(e.params); + (!D || z) && (M = this.strictDirective(this.end), M && z && this.raiseRecoverable(e.start, "Illegal 'use strict' directive in function with non-simple parameter list")); + var G = this.labels; + this.labels = [], M && (this.strict = true), this.checkParams(e, !D && !M && !r && !d && this.isSimpleParamList(e.params)), e.body = this.parseBlock(false), e.expression = false, this.adaptDirectivePrologue(e.body.body), this.labels = G; + } + this.exitScope(), this.strict && e.id && this.checkLVal(e.id, at), this.strict = D; + }, ne.isSimpleParamList = function(e) { + for (var r = 0, d = e; r < d.length; r += 1) { + var _ = d[r]; + if (_.type !== "Identifier") + return false; + } + return true; + }, ne.checkParams = function(e, r) { + for (var d = {}, _ = 0, D = e.params; _ < D.length; _ += 1) { + var M = D[_]; + this.checkLVal(M, Ce, r ? null : d); + } + }, ne.parseExprList = function(e, r, d, _) { + for (var D = [], M = true; !this.eat(e); ) { + if (M) + M = false; + else if (this.expect(a.comma), r && this.afterTrailingComma(e)) + break; + var z = void 0; + d && this.type === a.comma ? z = null : this.type === a.ellipsis ? (z = this.parseSpread(_), _ && this.type === a.comma && _.trailingComma < 0 && (_.trailingComma = this.start)) : z = this.parseMaybeAssign(false, _), D.push(z); + } + return D; + }, ne.checkUnreserved = function(e) { + var r = e.start, d = e.end, _ = e.name; + if (this.inGenerator && _ === "yield" && this.raiseRecoverable(r, "Cannot use 'yield' as identifier inside a generator"), this.inAsync && _ === "await" && this.raiseRecoverable(r, "Cannot use 'await' as identifier inside an async function"), this.keywords.test(_) && this.raise(r, "Unexpected keyword '" + _ + "'"), !(this.options.ecmaVersion < 6 && this.input.slice(r, d).indexOf("\\") !== -1)) { + var D = this.strict ? this.reservedWordsStrict : this.reservedWords; + D.test(_) && (!this.inAsync && _ === "await" && this.raiseRecoverable(r, "Cannot use keyword 'await' outside an async function"), this.raiseRecoverable(r, "The keyword '" + _ + "' is reserved")); + } + }, ne.parseIdent = function(e, r) { + var d = this.startNode(); + return this.type === a.name ? d.name = this.value : this.type.keyword ? (d.name = this.type.keyword, (d.name === "class" || d.name === "function") && (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46) && this.context.pop()) : this.unexpected(), this.next(!!e), this.finishNode(d, "Identifier"), e || (this.checkUnreserved(d), d.name === "await" && !this.awaitIdentPos && (this.awaitIdentPos = d.start)), d; + }, ne.parseYield = function(e) { + this.yieldPos || (this.yieldPos = this.start); + var r = this.startNode(); + return this.next(), this.type === a.semi || this.canInsertSemicolon() || this.type !== a.star && !this.type.startsExpr ? (r.delegate = false, r.argument = null) : (r.delegate = this.eat(a.star), r.argument = this.parseMaybeAssign(e)), this.finishNode(r, "YieldExpression"); + }, ne.parseAwait = function() { + this.awaitPos || (this.awaitPos = this.start); + var e = this.startNode(); + return this.next(), e.argument = this.parseMaybeUnary(null, false), this.finishNode(e, "AwaitExpression"); + }; + var Oe = le.prototype; + Oe.raise = function(e, r) { + var d = j(this.input, e); + r += " (" + d.line + ":" + d.column + ")"; + var _ = new SyntaxError(r); + throw _.pos = e, _.loc = d, _.raisedAt = this.pos, _; + }, Oe.raiseRecoverable = Oe.raise, Oe.curPosition = function() { + if (this.options.locations) + return new J(this.curLine, this.pos - this.lineStart); + }; + var ke = le.prototype, Mt = function(r) { + this.flags = r, this.var = [], this.lexical = [], this.functions = []; + }; + ke.enterScope = function(e) { + this.scopeStack.push(new Mt(e)); + }, ke.exitScope = function() { + this.scopeStack.pop(); + }, ke.treatFunctionsAsVarInScope = function(e) { + return e.flags & be || !this.inModule && e.flags & ee; + }, ke.declareName = function(e, r, d) { + var _ = false; + if (r === _e) { + var D = this.currentScope(); + _ = D.lexical.indexOf(e) > -1 || D.functions.indexOf(e) > -1 || D.var.indexOf(e) > -1, D.lexical.push(e), this.inModule && D.flags & ee && delete this.undefinedExports[e]; + } else if (r === rt) { + var M = this.currentScope(); + M.lexical.push(e); + } else if (r === st) { + var z = this.currentScope(); + this.treatFunctionsAsVar ? _ = z.lexical.indexOf(e) > -1 : _ = z.lexical.indexOf(e) > -1 || z.var.indexOf(e) > -1, z.functions.push(e); + } else + for (var G = this.scopeStack.length - 1; G >= 0; --G) { + var H = this.scopeStack[G]; + if (H.lexical.indexOf(e) > -1 && !(H.flags & te && H.lexical[0] === e) || !this.treatFunctionsAsVarInScope(H) && H.functions.indexOf(e) > -1) { + _ = true; + break; + } + if (H.var.push(e), this.inModule && H.flags & ee && delete this.undefinedExports[e], H.flags & Q) + break; + } + _ && this.raiseRecoverable(d, "Identifier '" + e + "' has already been declared"); + }, ke.checkLocalExport = function(e) { + this.scopeStack[0].lexical.indexOf(e.name) === -1 && this.scopeStack[0].var.indexOf(e.name) === -1 && (this.undefinedExports[e.name] = e); + }, ke.currentScope = function() { + return this.scopeStack[this.scopeStack.length - 1]; + }, ke.currentVarScope = function() { + for (var e = this.scopeStack.length - 1; ; e--) { + var r = this.scopeStack[e]; + if (r.flags & Q) + return r; + } + }, ke.currentThisScope = function() { + for (var e = this.scopeStack.length - 1; ; e--) { + var r = this.scopeStack[e]; + if (r.flags & Q && !(r.flags & pe)) + return r; + } + }; + var ze = function(r, d, _) { + this.type = "", this.start = d, this.end = 0, r.options.locations && (this.loc = new q(r, _)), r.options.directSourceFile && (this.sourceFile = r.options.directSourceFile), r.options.ranges && (this.range = [d, 0]); + }, Ne = le.prototype; + Ne.startNode = function() { + return new ze(this, this.start, this.startLoc); + }, Ne.startNodeAt = function(e, r) { + return new ze(this, e, r); + }; + function ut(e, r, d, _) { + return e.type = r, e.end = d, this.options.locations && (e.loc.end = _), this.options.ranges && (e.range[1] = d), e; + } + Ne.finishNode = function(e, r) { + return ut.call(this, e, r, this.lastTokEnd, this.lastTokEndLoc); + }, Ne.finishNodeAt = function(e, r, d, _) { + return ut.call(this, e, r, d, _); + }; + var ve = function(r, d, _, D, M) { + this.token = r, this.isExpr = !!d, this.preserveSpace = !!_, this.override = D, this.generator = !!M; + }, ce = { b_stat: new ve("{", false), b_expr: new ve("{", true), b_tmpl: new ve("${", false), p_stat: new ve("(", false), p_expr: new ve("(", true), q_tmpl: new ve("`", true, true, function(e) { + return e.tryReadTemplateToken(); + }), f_stat: new ve("function", false), f_expr: new ve("function", true), f_expr_gen: new ve("function", true, false, null, true), f_gen: new ve("function", false, false, null, true) }, Pe = le.prototype; + Pe.initialContext = function() { + return [ce.b_stat]; + }, Pe.braceIsBlock = function(e) { + var r = this.curContext(); + return r === ce.f_expr || r === ce.f_stat ? true : e === a.colon && (r === ce.b_stat || r === ce.b_expr) ? !r.isExpr : e === a._return || e === a.name && this.exprAllowed ? k.test(this.input.slice(this.lastTokEnd, this.start)) : e === a._else || e === a.semi || e === a.eof || e === a.parenR || e === a.arrow ? true : e === a.braceL ? r === ce.b_stat : e === a._var || e === a._const || e === a.name ? false : !this.exprAllowed; + }, Pe.inGeneratorContext = function() { + for (var e = this.context.length - 1; e >= 1; e--) { + var r = this.context[e]; + if (r.token === "function") + return r.generator; + } + return false; + }, Pe.updateContext = function(e) { + var r, d = this.type; + d.keyword && e === a.dot ? this.exprAllowed = false : (r = d.updateContext) ? r.call(this, e) : this.exprAllowed = d.beforeExpr; + }, a.parenR.updateContext = a.braceR.updateContext = function() { + if (this.context.length === 1) { + this.exprAllowed = true; + return; + } + var e = this.context.pop(); + e === ce.b_stat && this.curContext().token === "function" && (e = this.context.pop()), this.exprAllowed = !e.isExpr; + }, a.braceL.updateContext = function(e) { + this.context.push(this.braceIsBlock(e) ? ce.b_stat : ce.b_expr), this.exprAllowed = true; + }, a.dollarBraceL.updateContext = function() { + this.context.push(ce.b_tmpl), this.exprAllowed = true; + }, a.parenL.updateContext = function(e) { + var r = e === a._if || e === a._for || e === a._with || e === a._while; + this.context.push(r ? ce.p_stat : ce.p_expr), this.exprAllowed = true; + }, a.incDec.updateContext = function() { + }, a._function.updateContext = a._class.updateContext = function(e) { + e.beforeExpr && e !== a.semi && e !== a._else && !(e === a._return && k.test(this.input.slice(this.lastTokEnd, this.start))) && !((e === a.colon || e === a.braceL) && this.curContext() === ce.b_stat) ? this.context.push(ce.f_expr) : this.context.push(ce.f_stat), this.exprAllowed = false; + }, a.backQuote.updateContext = function() { + this.curContext() === ce.q_tmpl ? this.context.pop() : this.context.push(ce.q_tmpl), this.exprAllowed = false; + }, a.star.updateContext = function(e) { + if (e === a._function) { + var r = this.context.length - 1; + this.context[r] === ce.f_expr ? this.context[r] = ce.f_expr_gen : this.context[r] = ce.f_gen; + } + this.exprAllowed = true; + }, a.name.updateContext = function(e) { + var r = false; + this.options.ecmaVersion >= 6 && e !== a.dot && (this.value === "of" && !this.exprAllowed || this.value === "yield" && this.inGeneratorContext()) && (r = true), this.exprAllowed = r; + }; + var lt = "ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS", ht = lt + " Extended_Pictographic", Vt = ht, Ot = { 9: lt, 10: ht, 11: Vt }, ct = "Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu", pt = "Adlam Adlm Ahom Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb", ft = pt + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd", zt = ft + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho", Nt = { 9: pt, 10: ft, 11: zt }, dt = {}; + function Ye(e) { + var r = dt[e] = { binary: Y(Ot[e] + " " + ct), nonBinary: { General_Category: Y(ct), Script: Y(Nt[e]) } }; + r.nonBinary.Script_Extensions = r.nonBinary.Script, r.nonBinary.gc = r.nonBinary.General_Category, r.nonBinary.sc = r.nonBinary.Script, r.nonBinary.scx = r.nonBinary.Script_Extensions; + } + Ye(9), Ye(10), Ye(11); + var W = le.prototype, Ee = function(r) { + this.parser = r, this.validFlags = "gim" + (r.options.ecmaVersion >= 6 ? "uy" : "") + (r.options.ecmaVersion >= 9 ? "s" : ""), this.unicodeProperties = dt[r.options.ecmaVersion >= 11 ? 11 : r.options.ecmaVersion], this.source = "", this.flags = "", this.start = 0, this.switchU = false, this.switchN = false, this.pos = 0, this.lastIntValue = 0, this.lastStringValue = "", this.lastAssertionIsQuantifiable = false, this.numCapturingParens = 0, this.maxBackReference = 0, this.groupNames = [], this.backReferenceNames = []; + }; + Ee.prototype.reset = function(r, d, _) { + var D = _.indexOf("u") !== -1; + this.start = r | 0, this.source = d + "", this.flags = _, this.switchU = D && this.parser.options.ecmaVersion >= 6, this.switchN = D && this.parser.options.ecmaVersion >= 9; + }, Ee.prototype.raise = function(r) { + this.parser.raiseRecoverable(this.start, "Invalid regular expression: /" + this.source + "/: " + r); + }, Ee.prototype.at = function(r) { + var d = this.source, _ = d.length; + if (r >= _) + return -1; + var D = d.charCodeAt(r); + if (!this.switchU || D <= 55295 || D >= 57344 || r + 1 >= _) + return D; + var M = d.charCodeAt(r + 1); + return M >= 56320 && M <= 57343 ? (D << 10) + M - 56613888 : D; + }, Ee.prototype.nextIndex = function(r) { + var d = this.source, _ = d.length; + if (r >= _) + return _; + var D = d.charCodeAt(r), M; + return !this.switchU || D <= 55295 || D >= 57344 || r + 1 >= _ || (M = d.charCodeAt(r + 1)) < 56320 || M > 57343 ? r + 1 : r + 2; + }, Ee.prototype.current = function() { + return this.at(this.pos); + }, Ee.prototype.lookahead = function() { + return this.at(this.nextIndex(this.pos)); + }, Ee.prototype.advance = function() { + this.pos = this.nextIndex(this.pos); + }, Ee.prototype.eat = function(r) { + return this.current() === r ? (this.advance(), true) : false; + }; + function Ke(e) { + return e <= 65535 ? String.fromCharCode(e) : (e -= 65536, String.fromCharCode((e >> 10) + 55296, (e & 1023) + 56320)); + } + W.validateRegExpFlags = function(e) { + for (var r = e.validFlags, d = e.flags, _ = 0; _ < d.length; _++) { + var D = d.charAt(_); + r.indexOf(D) === -1 && this.raise(e.start, "Invalid regular expression flag"), d.indexOf(D, _ + 1) > -1 && this.raise(e.start, "Duplicate regular expression flag"); + } + }, W.validateRegExpPattern = function(e) { + this.regexp_pattern(e), !e.switchN && this.options.ecmaVersion >= 9 && e.groupNames.length > 0 && (e.switchN = true, this.regexp_pattern(e)); + }, W.regexp_pattern = function(e) { + e.pos = 0, e.lastIntValue = 0, e.lastStringValue = "", e.lastAssertionIsQuantifiable = false, e.numCapturingParens = 0, e.maxBackReference = 0, e.groupNames.length = 0, e.backReferenceNames.length = 0, this.regexp_disjunction(e), e.pos !== e.source.length && (e.eat(41) && e.raise("Unmatched ')'"), (e.eat(93) || e.eat(125)) && e.raise("Lone quantifier brackets")), e.maxBackReference > e.numCapturingParens && e.raise("Invalid escape"); + for (var r = 0, d = e.backReferenceNames; r < d.length; r += 1) { + var _ = d[r]; + e.groupNames.indexOf(_) === -1 && e.raise("Invalid named capture referenced"); + } + }, W.regexp_disjunction = function(e) { + for (this.regexp_alternative(e); e.eat(124); ) + this.regexp_alternative(e); + this.regexp_eatQuantifier(e, true) && e.raise("Nothing to repeat"), e.eat(123) && e.raise("Lone quantifier brackets"); + }, W.regexp_alternative = function(e) { + for (; e.pos < e.source.length && this.regexp_eatTerm(e); ) + ; + }, W.regexp_eatTerm = function(e) { + return this.regexp_eatAssertion(e) ? (e.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(e) && e.switchU && e.raise("Invalid quantifier"), true) : (e.switchU ? this.regexp_eatAtom(e) : this.regexp_eatExtendedAtom(e)) ? (this.regexp_eatQuantifier(e), true) : false; + }, W.regexp_eatAssertion = function(e) { + var r = e.pos; + if (e.lastAssertionIsQuantifiable = false, e.eat(94) || e.eat(36)) + return true; + if (e.eat(92)) { + if (e.eat(66) || e.eat(98)) + return true; + e.pos = r; + } + if (e.eat(40) && e.eat(63)) { + var d = false; + if (this.options.ecmaVersion >= 9 && (d = e.eat(60)), e.eat(61) || e.eat(33)) + return this.regexp_disjunction(e), e.eat(41) || e.raise("Unterminated group"), e.lastAssertionIsQuantifiable = !d, true; + } + return e.pos = r, false; + }, W.regexp_eatQuantifier = function(e, r) { + return r === void 0 && (r = false), this.regexp_eatQuantifierPrefix(e, r) ? (e.eat(63), true) : false; + }, W.regexp_eatQuantifierPrefix = function(e, r) { + return e.eat(42) || e.eat(43) || e.eat(63) || this.regexp_eatBracedQuantifier(e, r); + }, W.regexp_eatBracedQuantifier = function(e, r) { + var d = e.pos; + if (e.eat(123)) { + var _ = 0, D = -1; + if (this.regexp_eatDecimalDigits(e) && (_ = e.lastIntValue, e.eat(44) && this.regexp_eatDecimalDigits(e) && (D = e.lastIntValue), e.eat(125))) + return D !== -1 && D < _ && !r && e.raise("numbers out of order in {} quantifier"), true; + e.switchU && !r && e.raise("Incomplete quantifier"), e.pos = d; + } + return false; + }, W.regexp_eatAtom = function(e) { + return this.regexp_eatPatternCharacters(e) || e.eat(46) || this.regexp_eatReverseSolidusAtomEscape(e) || this.regexp_eatCharacterClass(e) || this.regexp_eatUncapturingGroup(e) || this.regexp_eatCapturingGroup(e); + }, W.regexp_eatReverseSolidusAtomEscape = function(e) { + var r = e.pos; + if (e.eat(92)) { + if (this.regexp_eatAtomEscape(e)) + return true; + e.pos = r; + } + return false; + }, W.regexp_eatUncapturingGroup = function(e) { + var r = e.pos; + if (e.eat(40)) { + if (e.eat(63) && e.eat(58)) { + if (this.regexp_disjunction(e), e.eat(41)) + return true; + e.raise("Unterminated group"); + } + e.pos = r; + } + return false; + }, W.regexp_eatCapturingGroup = function(e) { + if (e.eat(40)) { + if (this.options.ecmaVersion >= 9 ? this.regexp_groupSpecifier(e) : e.current() === 63 && e.raise("Invalid group"), this.regexp_disjunction(e), e.eat(41)) + return e.numCapturingParens += 1, true; + e.raise("Unterminated group"); + } + return false; + }, W.regexp_eatExtendedAtom = function(e) { + return e.eat(46) || this.regexp_eatReverseSolidusAtomEscape(e) || this.regexp_eatCharacterClass(e) || this.regexp_eatUncapturingGroup(e) || this.regexp_eatCapturingGroup(e) || this.regexp_eatInvalidBracedQuantifier(e) || this.regexp_eatExtendedPatternCharacter(e); + }, W.regexp_eatInvalidBracedQuantifier = function(e) { + return this.regexp_eatBracedQuantifier(e, true) && e.raise("Nothing to repeat"), false; + }, W.regexp_eatSyntaxCharacter = function(e) { + var r = e.current(); + return mt(r) ? (e.lastIntValue = r, e.advance(), true) : false; + }; + function mt(e) { + return e === 36 || e >= 40 && e <= 43 || e === 46 || e === 63 || e >= 91 && e <= 94 || e >= 123 && e <= 125; + } + W.regexp_eatPatternCharacters = function(e) { + for (var r = e.pos, d = 0; (d = e.current()) !== -1 && !mt(d); ) + e.advance(); + return e.pos !== r; + }, W.regexp_eatExtendedPatternCharacter = function(e) { + var r = e.current(); + return r !== -1 && r !== 36 && !(r >= 40 && r <= 43) && r !== 46 && r !== 63 && r !== 91 && r !== 94 && r !== 124 ? (e.advance(), true) : false; + }, W.regexp_groupSpecifier = function(e) { + if (e.eat(63)) { + if (this.regexp_eatGroupName(e)) { + e.groupNames.indexOf(e.lastStringValue) !== -1 && e.raise("Duplicate capture group name"), e.groupNames.push(e.lastStringValue); + return; + } + e.raise("Invalid group"); + } + }, W.regexp_eatGroupName = function(e) { + if (e.lastStringValue = "", e.eat(60)) { + if (this.regexp_eatRegExpIdentifierName(e) && e.eat(62)) + return true; + e.raise("Invalid capture group name"); + } + return false; + }, W.regexp_eatRegExpIdentifierName = function(e) { + if (e.lastStringValue = "", this.regexp_eatRegExpIdentifierStart(e)) { + for (e.lastStringValue += Ke(e.lastIntValue); this.regexp_eatRegExpIdentifierPart(e); ) + e.lastStringValue += Ke(e.lastIntValue); + return true; + } + return false; + }, W.regexp_eatRegExpIdentifierStart = function(e) { + var r = e.pos, d = e.current(); + return e.advance(), d === 92 && this.regexp_eatRegExpUnicodeEscapeSequence(e) && (d = e.lastIntValue), Pt(d) ? (e.lastIntValue = d, true) : (e.pos = r, false); + }; + function Pt(e) { + return S(e, true) || e === 36 || e === 95; + } + W.regexp_eatRegExpIdentifierPart = function(e) { + var r = e.pos, d = e.current(); + return e.advance(), d === 92 && this.regexp_eatRegExpUnicodeEscapeSequence(e) && (d = e.lastIntValue), Kt(d) ? (e.lastIntValue = d, true) : (e.pos = r, false); + }; + function Kt(e) { + return v(e, true) || e === 36 || e === 95 || e === 8204 || e === 8205; + } + W.regexp_eatAtomEscape = function(e) { + return this.regexp_eatBackReference(e) || this.regexp_eatCharacterClassEscape(e) || this.regexp_eatCharacterEscape(e) || e.switchN && this.regexp_eatKGroupName(e) ? true : (e.switchU && (e.current() === 99 && e.raise("Invalid unicode escape"), e.raise("Invalid escape")), false); + }, W.regexp_eatBackReference = function(e) { + var r = e.pos; + if (this.regexp_eatDecimalEscape(e)) { + var d = e.lastIntValue; + if (e.switchU) + return d > e.maxBackReference && (e.maxBackReference = d), true; + if (d <= e.numCapturingParens) + return true; + e.pos = r; + } + return false; + }, W.regexp_eatKGroupName = function(e) { + if (e.eat(107)) { + if (this.regexp_eatGroupName(e)) + return e.backReferenceNames.push(e.lastStringValue), true; + e.raise("Invalid named reference"); + } + return false; + }, W.regexp_eatCharacterEscape = function(e) { + return this.regexp_eatControlEscape(e) || this.regexp_eatCControlLetter(e) || this.regexp_eatZero(e) || this.regexp_eatHexEscapeSequence(e) || this.regexp_eatRegExpUnicodeEscapeSequence(e) || !e.switchU && this.regexp_eatLegacyOctalEscapeSequence(e) || this.regexp_eatIdentityEscape(e); + }, W.regexp_eatCControlLetter = function(e) { + var r = e.pos; + if (e.eat(99)) { + if (this.regexp_eatControlLetter(e)) + return true; + e.pos = r; + } + return false; + }, W.regexp_eatZero = function(e) { + return e.current() === 48 && !Ge(e.lookahead()) ? (e.lastIntValue = 0, e.advance(), true) : false; + }, W.regexp_eatControlEscape = function(e) { + var r = e.current(); + return r === 116 ? (e.lastIntValue = 9, e.advance(), true) : r === 110 ? (e.lastIntValue = 10, e.advance(), true) : r === 118 ? (e.lastIntValue = 11, e.advance(), true) : r === 102 ? (e.lastIntValue = 12, e.advance(), true) : r === 114 ? (e.lastIntValue = 13, e.advance(), true) : false; + }, W.regexp_eatControlLetter = function(e) { + var r = e.current(); + return xt(r) ? (e.lastIntValue = r % 32, e.advance(), true) : false; + }; + function xt(e) { + return e >= 65 && e <= 90 || e >= 97 && e <= 122; + } + W.regexp_eatRegExpUnicodeEscapeSequence = function(e) { + var r = e.pos; + if (e.eat(117)) { + if (this.regexp_eatFixedHexDigits(e, 4)) { + var d = e.lastIntValue; + if (e.switchU && d >= 55296 && d <= 56319) { + var _ = e.pos; + if (e.eat(92) && e.eat(117) && this.regexp_eatFixedHexDigits(e, 4)) { + var D = e.lastIntValue; + if (D >= 56320 && D <= 57343) + return e.lastIntValue = (d - 55296) * 1024 + (D - 56320) + 65536, true; + } + e.pos = _, e.lastIntValue = d; + } + return true; + } + if (e.switchU && e.eat(123) && this.regexp_eatHexDigits(e) && e.eat(125) && Gt(e.lastIntValue)) + return true; + e.switchU && e.raise("Invalid unicode escape"), e.pos = r; + } + return false; + }; + function Gt(e) { + return e >= 0 && e <= 1114111; + } + W.regexp_eatIdentityEscape = function(e) { + if (e.switchU) + return this.regexp_eatSyntaxCharacter(e) ? true : e.eat(47) ? (e.lastIntValue = 47, true) : false; + var r = e.current(); + return r !== 99 && (!e.switchN || r !== 107) ? (e.lastIntValue = r, e.advance(), true) : false; + }, W.regexp_eatDecimalEscape = function(e) { + e.lastIntValue = 0; + var r = e.current(); + if (r >= 49 && r <= 57) { + do + e.lastIntValue = 10 * e.lastIntValue + (r - 48), e.advance(); + while ((r = e.current()) >= 48 && r <= 57); + return true; + } + return false; + }, W.regexp_eatCharacterClassEscape = function(e) { + var r = e.current(); + if (Ut(r)) + return e.lastIntValue = -1, e.advance(), true; + if (e.switchU && this.options.ecmaVersion >= 9 && (r === 80 || r === 112)) { + if (e.lastIntValue = -1, e.advance(), e.eat(123) && this.regexp_eatUnicodePropertyValueExpression(e) && e.eat(125)) + return true; + e.raise("Invalid property name"); + } + return false; + }; + function Ut(e) { + return e === 100 || e === 68 || e === 115 || e === 83 || e === 119 || e === 87; + } + W.regexp_eatUnicodePropertyValueExpression = function(e) { + var r = e.pos; + if (this.regexp_eatUnicodePropertyName(e) && e.eat(61)) { + var d = e.lastStringValue; + if (this.regexp_eatUnicodePropertyValue(e)) { + var _ = e.lastStringValue; + return this.regexp_validateUnicodePropertyNameAndValue(e, d, _), true; + } + } + if (e.pos = r, this.regexp_eatLoneUnicodePropertyNameOrValue(e)) { + var D = e.lastStringValue; + return this.regexp_validateUnicodePropertyNameOrValue(e, D), true; + } + return false; + }, W.regexp_validateUnicodePropertyNameAndValue = function(e, r, d) { + B(e.unicodeProperties.nonBinary, r) || e.raise("Invalid property name"), e.unicodeProperties.nonBinary[r].test(d) || e.raise("Invalid property value"); + }, W.regexp_validateUnicodePropertyNameOrValue = function(e, r) { + e.unicodeProperties.binary.test(r) || e.raise("Invalid property name"); + }, W.regexp_eatUnicodePropertyName = function(e) { + var r = 0; + for (e.lastStringValue = ""; gt(r = e.current()); ) + e.lastStringValue += Ke(r), e.advance(); + return e.lastStringValue !== ""; + }; + function gt(e) { + return xt(e) || e === 95; + } + W.regexp_eatUnicodePropertyValue = function(e) { + var r = 0; + for (e.lastStringValue = ""; Bt(r = e.current()); ) + e.lastStringValue += Ke(r), e.advance(); + return e.lastStringValue !== ""; + }; + function Bt(e) { + return gt(e) || Ge(e); + } + W.regexp_eatLoneUnicodePropertyNameOrValue = function(e) { + return this.regexp_eatUnicodePropertyValue(e); + }, W.regexp_eatCharacterClass = function(e) { + if (e.eat(91)) { + if (e.eat(94), this.regexp_classRanges(e), e.eat(93)) + return true; + e.raise("Unterminated character class"); + } + return false; + }, W.regexp_classRanges = function(e) { + for (; this.regexp_eatClassAtom(e); ) { + var r = e.lastIntValue; + if (e.eat(45) && this.regexp_eatClassAtom(e)) { + var d = e.lastIntValue; + e.switchU && (r === -1 || d === -1) && e.raise("Invalid character class"), r !== -1 && d !== -1 && r > d && e.raise("Range out of order in character class"); + } + } + }, W.regexp_eatClassAtom = function(e) { + var r = e.pos; + if (e.eat(92)) { + if (this.regexp_eatClassEscape(e)) + return true; + if (e.switchU) { + var d = e.current(); + (d === 99 || Tt(d)) && e.raise("Invalid class escape"), e.raise("Invalid escape"); + } + e.pos = r; + } + var _ = e.current(); + return _ !== 93 ? (e.lastIntValue = _, e.advance(), true) : false; + }, W.regexp_eatClassEscape = function(e) { + var r = e.pos; + if (e.eat(98)) + return e.lastIntValue = 8, true; + if (e.switchU && e.eat(45)) + return e.lastIntValue = 45, true; + if (!e.switchU && e.eat(99)) { + if (this.regexp_eatClassControlLetter(e)) + return true; + e.pos = r; + } + return this.regexp_eatCharacterClassEscape(e) || this.regexp_eatCharacterEscape(e); + }, W.regexp_eatClassControlLetter = function(e) { + var r = e.current(); + return Ge(r) || r === 95 ? (e.lastIntValue = r % 32, e.advance(), true) : false; + }, W.regexp_eatHexEscapeSequence = function(e) { + var r = e.pos; + if (e.eat(120)) { + if (this.regexp_eatFixedHexDigits(e, 2)) + return true; + e.switchU && e.raise("Invalid escape"), e.pos = r; + } + return false; + }, W.regexp_eatDecimalDigits = function(e) { + var r = e.pos, d = 0; + for (e.lastIntValue = 0; Ge(d = e.current()); ) + e.lastIntValue = 10 * e.lastIntValue + (d - 48), e.advance(); + return e.pos !== r; + }; + function Ge(e) { + return e >= 48 && e <= 57; + } + W.regexp_eatHexDigits = function(e) { + var r = e.pos, d = 0; + for (e.lastIntValue = 0; yt(d = e.current()); ) + e.lastIntValue = 16 * e.lastIntValue + bt(d), e.advance(); + return e.pos !== r; + }; + function yt(e) { + return e >= 48 && e <= 57 || e >= 65 && e <= 70 || e >= 97 && e <= 102; + } + function bt(e) { + return e >= 65 && e <= 70 ? 10 + (e - 65) : e >= 97 && e <= 102 ? 10 + (e - 97) : e - 48; + } + W.regexp_eatLegacyOctalEscapeSequence = function(e) { + if (this.regexp_eatOctalDigit(e)) { + var r = e.lastIntValue; + if (this.regexp_eatOctalDigit(e)) { + var d = e.lastIntValue; + r <= 3 && this.regexp_eatOctalDigit(e) ? e.lastIntValue = r * 64 + d * 8 + e.lastIntValue : e.lastIntValue = r * 8 + d; + } else + e.lastIntValue = r; + return true; + } + return false; + }, W.regexp_eatOctalDigit = function(e) { + var r = e.current(); + return Tt(r) ? (e.lastIntValue = r - 48, e.advance(), true) : (e.lastIntValue = 0, false); + }; + function Tt(e) { + return e >= 48 && e <= 55; + } + W.regexp_eatFixedHexDigits = function(e, r) { + var d = e.pos; + e.lastIntValue = 0; + for (var _ = 0; _ < r; ++_) { + var D = e.current(); + if (!yt(D)) + return e.pos = d, false; + e.lastIntValue = 16 * e.lastIntValue + bt(D), e.advance(); + } + return true; + }; + var Ue = function(r) { + this.type = r.type, this.value = r.value, this.start = r.start, this.end = r.end, r.options.locations && (this.loc = new q(r, r.startLoc, r.endLoc)), r.options.ranges && (this.range = [r.start, r.end]); + }, se = le.prototype; + se.next = function(e) { + !e && this.type.keyword && this.containsEsc && this.raiseRecoverable(this.start, "Escape sequence in keyword " + this.type.keyword), this.options.onToken && this.options.onToken(new Ue(this)), this.lastTokEnd = this.end, this.lastTokStart = this.start, this.lastTokEndLoc = this.endLoc, this.lastTokStartLoc = this.startLoc, this.nextToken(); + }, se.getToken = function() { + return this.next(), new Ue(this); + }, typeof Symbol < "u" && (se[Symbol.iterator] = function() { + var e = this; + return { next: function() { + var r = e.getToken(); + return { done: r.type === a.eof, value: r }; + } }; + }), se.curContext = function() { + return this.context[this.context.length - 1]; + }, se.nextToken = function() { + var e = this.curContext(); + if ((!e || !e.preserveSpace) && this.skipSpace(), this.start = this.pos, this.options.locations && (this.startLoc = this.curPosition()), this.pos >= this.input.length) + return this.finishToken(a.eof); + if (e.override) + return e.override(this); + this.readToken(this.fullCharCodeAtPos()); + }, se.readToken = function(e) { + return S(e, this.options.ecmaVersion >= 6) || e === 92 ? this.readWord() : this.getTokenFromCode(e); + }, se.fullCharCodeAtPos = function() { + var e = this.input.charCodeAt(this.pos); + if (e <= 55295 || e >= 57344) + return e; + var r = this.input.charCodeAt(this.pos + 1); + return (e << 10) + r - 56613888; + }, se.skipBlockComment = function() { + var e = this.options.onComment && this.curPosition(), r = this.pos, d = this.input.indexOf("*/", this.pos += 2); + if (d === -1 && this.raise(this.pos - 2, "Unterminated comment"), this.pos = d + 2, this.options.locations) { + A.lastIndex = r; + for (var _; (_ = A.exec(this.input)) && _.index < this.pos; ) + ++this.curLine, this.lineStart = _.index + _[0].length; + } + this.options.onComment && this.options.onComment(true, this.input.slice(r + 2, d), r, this.pos, e, this.curPosition()); + }, se.skipLineComment = function(e) { + for (var r = this.pos, d = this.options.onComment && this.curPosition(), _ = this.input.charCodeAt(this.pos += e); this.pos < this.input.length && !N(_); ) + _ = this.input.charCodeAt(++this.pos); + this.options.onComment && this.options.onComment(false, this.input.slice(r + e, this.pos), r, this.pos, d, this.curPosition()); + }, se.skipSpace = function() { + e: + for (; this.pos < this.input.length; ) { + var e = this.input.charCodeAt(this.pos); + switch (e) { + case 32: + case 160: + ++this.pos; + break; + case 13: + this.input.charCodeAt(this.pos + 1) === 10 && ++this.pos; + case 10: + case 8232: + case 8233: + ++this.pos, this.options.locations && (++this.curLine, this.lineStart = this.pos); + break; + case 47: + switch (this.input.charCodeAt(this.pos + 1)) { + case 42: + this.skipBlockComment(); + break; + case 47: + this.skipLineComment(2); + break; + default: + break e; + } + break; + default: + if (e > 8 && e < 14 || e >= 5760 && F.test(String.fromCharCode(e))) + ++this.pos; + else + break e; + } + } + }, se.finishToken = function(e, r) { + this.end = this.pos, this.options.locations && (this.endLoc = this.curPosition()); + var d = this.type; + this.type = e, this.value = r, this.updateContext(d); + }, se.readToken_dot = function() { + var e = this.input.charCodeAt(this.pos + 1); + if (e >= 48 && e <= 57) + return this.readNumber(true); + var r = this.input.charCodeAt(this.pos + 2); + return this.options.ecmaVersion >= 6 && e === 46 && r === 46 ? (this.pos += 3, this.finishToken(a.ellipsis)) : (++this.pos, this.finishToken(a.dot)); + }, se.readToken_slash = function() { + var e = this.input.charCodeAt(this.pos + 1); + return this.exprAllowed ? (++this.pos, this.readRegexp()) : e === 61 ? this.finishOp(a.assign, 2) : this.finishOp(a.slash, 1); + }, se.readToken_mult_modulo_exp = function(e) { + var r = this.input.charCodeAt(this.pos + 1), d = 1, _ = e === 42 ? a.star : a.modulo; + return this.options.ecmaVersion >= 7 && e === 42 && r === 42 && (++d, _ = a.starstar, r = this.input.charCodeAt(this.pos + 2)), r === 61 ? this.finishOp(a.assign, d + 1) : this.finishOp(_, d); + }, se.readToken_pipe_amp = function(e) { + var r = this.input.charCodeAt(this.pos + 1); + return r === e ? this.finishOp(e === 124 ? a.logicalOR : a.logicalAND, 2) : r === 61 ? this.finishOp(a.assign, 2) : this.finishOp(e === 124 ? a.bitwiseOR : a.bitwiseAND, 1); + }, se.readToken_caret = function() { + var e = this.input.charCodeAt(this.pos + 1); + return e === 61 ? this.finishOp(a.assign, 2) : this.finishOp(a.bitwiseXOR, 1); + }, se.readToken_plus_min = function(e) { + var r = this.input.charCodeAt(this.pos + 1); + return r === e ? r === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 && (this.lastTokEnd === 0 || k.test(this.input.slice(this.lastTokEnd, this.pos))) ? (this.skipLineComment(3), this.skipSpace(), this.nextToken()) : this.finishOp(a.incDec, 2) : r === 61 ? this.finishOp(a.assign, 2) : this.finishOp(a.plusMin, 1); + }, se.readToken_lt_gt = function(e) { + var r = this.input.charCodeAt(this.pos + 1), d = 1; + return r === e ? (d = e === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2, this.input.charCodeAt(this.pos + d) === 61 ? this.finishOp(a.assign, d + 1) : this.finishOp(a.bitShift, d)) : r === 33 && e === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 && this.input.charCodeAt(this.pos + 3) === 45 ? (this.skipLineComment(4), this.skipSpace(), this.nextToken()) : (r === 61 && (d = 2), this.finishOp(a.relational, d)); + }, se.readToken_eq_excl = function(e) { + var r = this.input.charCodeAt(this.pos + 1); + return r === 61 ? this.finishOp(a.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2) : e === 61 && r === 62 && this.options.ecmaVersion >= 6 ? (this.pos += 2, this.finishToken(a.arrow)) : this.finishOp(e === 61 ? a.eq : a.prefix, 1); + }, se.getTokenFromCode = function(e) { + switch (e) { + case 46: + return this.readToken_dot(); + case 40: + return ++this.pos, this.finishToken(a.parenL); + case 41: + return ++this.pos, this.finishToken(a.parenR); + case 59: + return ++this.pos, this.finishToken(a.semi); + case 44: + return ++this.pos, this.finishToken(a.comma); + case 91: + return ++this.pos, this.finishToken(a.bracketL); + case 93: + return ++this.pos, this.finishToken(a.bracketR); + case 123: + return ++this.pos, this.finishToken(a.braceL); + case 125: + return ++this.pos, this.finishToken(a.braceR); + case 58: + return ++this.pos, this.finishToken(a.colon); + case 63: + return ++this.pos, this.finishToken(a.question); + case 96: + if (this.options.ecmaVersion < 6) + break; + return ++this.pos, this.finishToken(a.backQuote); + case 48: + var r = this.input.charCodeAt(this.pos + 1); + if (r === 120 || r === 88) + return this.readRadixNumber(16); + if (this.options.ecmaVersion >= 6) { + if (r === 111 || r === 79) + return this.readRadixNumber(8); + if (r === 98 || r === 66) + return this.readRadixNumber(2); + } + case 49: + case 50: + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + return this.readNumber(false); + case 34: + case 39: + return this.readString(e); + case 47: + return this.readToken_slash(); + case 37: + case 42: + return this.readToken_mult_modulo_exp(e); + case 124: + case 38: + return this.readToken_pipe_amp(e); + case 94: + return this.readToken_caret(); + case 43: + case 45: + return this.readToken_plus_min(e); + case 60: + case 62: + return this.readToken_lt_gt(e); + case 61: + case 33: + return this.readToken_eq_excl(e); + case 126: + return this.finishOp(a.prefix, 1); + } + this.raise(this.pos, "Unexpected character '" + Ze(e) + "'"); + }, se.finishOp = function(e, r) { + var d = this.input.slice(this.pos, this.pos + r); + return this.pos += r, this.finishToken(e, d); + }, se.readRegexp = function() { + for (var e, r, d = this.pos; ; ) { + this.pos >= this.input.length && this.raise(d, "Unterminated regular expression"); + var _ = this.input.charAt(this.pos); + if (k.test(_) && this.raise(d, "Unterminated regular expression"), e) + e = false; + else { + if (_ === "[") + r = true; + else if (_ === "]" && r) + r = false; + else if (_ === "/" && !r) + break; + e = _ === "\\"; + } + ++this.pos; + } + var D = this.input.slice(d, this.pos); + ++this.pos; + var M = this.pos, z = this.readWord1(); + this.containsEsc && this.unexpected(M); + var G = this.regexpState || (this.regexpState = new Ee(this)); + G.reset(d, D, z), this.validateRegExpFlags(G), this.validateRegExpPattern(G); + var H = null; + try { + H = new RegExp(D, z); + } catch { + } + return this.finishToken(a.regexp, { pattern: D, flags: z, value: H }); + }, se.readInt = function(e, r) { + for (var d = this.pos, _ = 0, D = 0, M = r ?? 1 / 0; D < M; ++D) { + var z = this.input.charCodeAt(this.pos), G = void 0; + if (z >= 97 ? G = z - 97 + 10 : z >= 65 ? G = z - 65 + 10 : z >= 48 && z <= 57 ? G = z - 48 : G = 1 / 0, G >= e) + break; + ++this.pos, _ = _ * e + G; + } + return this.pos === d || r != null && this.pos - d !== r ? null : _; + }, se.readRadixNumber = function(e) { + var r = this.pos; + this.pos += 2; + var d = this.readInt(e); + return d == null && this.raise(this.start + 2, "Expected number in radix " + e), this.options.ecmaVersion >= 11 && this.input.charCodeAt(this.pos) === 110 ? (d = typeof BigInt < "u" ? BigInt(this.input.slice(r, this.pos)) : null, ++this.pos) : S(this.fullCharCodeAtPos()) && this.raise(this.pos, "Identifier directly after number"), this.finishToken(a.num, d); + }, se.readNumber = function(e) { + var r = this.pos; + !e && this.readInt(10) === null && this.raise(r, "Invalid number"); + var d = this.pos - r >= 2 && this.input.charCodeAt(r) === 48; + d && this.strict && this.raise(r, "Invalid number"); + var _ = this.input.charCodeAt(this.pos); + if (!d && !e && this.options.ecmaVersion >= 11 && _ === 110) { + var D = this.input.slice(r, this.pos), M = typeof BigInt < "u" ? BigInt(D) : null; + return ++this.pos, S(this.fullCharCodeAtPos()) && this.raise(this.pos, "Identifier directly after number"), this.finishToken(a.num, M); + } + d && /[89]/.test(this.input.slice(r, this.pos)) && (d = false), _ === 46 && !d && (++this.pos, this.readInt(10), _ = this.input.charCodeAt(this.pos)), (_ === 69 || _ === 101) && !d && (_ = this.input.charCodeAt(++this.pos), (_ === 43 || _ === 45) && ++this.pos, this.readInt(10) === null && this.raise(r, "Invalid number")), S(this.fullCharCodeAtPos()) && this.raise(this.pos, "Identifier directly after number"); + var z = this.input.slice(r, this.pos), G = d ? parseInt(z, 8) : parseFloat(z); + return this.finishToken(a.num, G); + }, se.readCodePoint = function() { + var e = this.input.charCodeAt(this.pos), r; + if (e === 123) { + this.options.ecmaVersion < 6 && this.unexpected(); + var d = ++this.pos; + r = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos), ++this.pos, r > 1114111 && this.invalidStringToken(d, "Code point out of bounds"); + } else + r = this.readHexChar(4); + return r; + }; + function Ze(e) { + return e <= 65535 ? String.fromCharCode(e) : (e -= 65536, String.fromCharCode((e >> 10) + 55296, (e & 1023) + 56320)); + } + se.readString = function(e) { + for (var r = "", d = ++this.pos; ; ) { + this.pos >= this.input.length && this.raise(this.start, "Unterminated string constant"); + var _ = this.input.charCodeAt(this.pos); + if (_ === e) + break; + _ === 92 ? (r += this.input.slice(d, this.pos), r += this.readEscapedChar(false), d = this.pos) : (N(_, this.options.ecmaVersion >= 10) && this.raise(this.start, "Unterminated string constant"), ++this.pos); + } + return r += this.input.slice(d, this.pos++), this.finishToken(a.string, r); + }; + var vt = {}; + se.tryReadTemplateToken = function() { + this.inTemplateElement = true; + try { + this.readTmplToken(); + } catch (e) { + if (e === vt) + this.readInvalidTemplateToken(); + else + throw e; + } + this.inTemplateElement = false; + }, se.invalidStringToken = function(e, r) { + if (this.inTemplateElement && this.options.ecmaVersion >= 9) + throw vt; + this.raise(e, r); + }, se.readTmplToken = function() { + for (var e = "", r = this.pos; ; ) { + this.pos >= this.input.length && this.raise(this.start, "Unterminated template"); + var d = this.input.charCodeAt(this.pos); + if (d === 96 || d === 36 && this.input.charCodeAt(this.pos + 1) === 123) + return this.pos === this.start && (this.type === a.template || this.type === a.invalidTemplate) ? d === 36 ? (this.pos += 2, this.finishToken(a.dollarBraceL)) : (++this.pos, this.finishToken(a.backQuote)) : (e += this.input.slice(r, this.pos), this.finishToken(a.template, e)); + if (d === 92) + e += this.input.slice(r, this.pos), e += this.readEscapedChar(true), r = this.pos; + else if (N(d)) { + switch (e += this.input.slice(r, this.pos), ++this.pos, d) { + case 13: + this.input.charCodeAt(this.pos) === 10 && ++this.pos; + case 10: + e += ` +`; + break; + default: + e += String.fromCharCode(d); + break; + } + this.options.locations && (++this.curLine, this.lineStart = this.pos), r = this.pos; + } else + ++this.pos; + } + }, se.readInvalidTemplateToken = function() { + for (; this.pos < this.input.length; this.pos++) + switch (this.input[this.pos]) { + case "\\": + ++this.pos; + break; + case "$": + if (this.input[this.pos + 1] !== "{") + break; + case "`": + return this.finishToken(a.invalidTemplate, this.input.slice(this.start, this.pos)); + } + this.raise(this.start, "Unterminated template"); + }, se.readEscapedChar = function(e) { + var r = this.input.charCodeAt(++this.pos); + switch (++this.pos, r) { + case 110: + return ` +`; + case 114: + return "\r"; + case 120: + return String.fromCharCode(this.readHexChar(2)); + case 117: + return Ze(this.readCodePoint()); + case 116: + return " "; + case 98: + return "\b"; + case 118: + return "\v"; + case 102: + return "\f"; + case 13: + this.input.charCodeAt(this.pos) === 10 && ++this.pos; + case 10: + return this.options.locations && (this.lineStart = this.pos, ++this.curLine), ""; + case 56: + case 57: + if (e) { + var d = this.pos - 1; + return this.invalidStringToken(d, "Invalid escape sequence in template string"), null; + } + default: + if (r >= 48 && r <= 55) { + var _ = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0], D = parseInt(_, 8); + return D > 255 && (_ = _.slice(0, -1), D = parseInt(_, 8)), this.pos += _.length - 1, r = this.input.charCodeAt(this.pos), (_ !== "0" || r === 56 || r === 57) && (this.strict || e) && this.invalidStringToken(this.pos - 1 - _.length, e ? "Octal literal in template string" : "Octal literal in strict mode"), String.fromCharCode(D); + } + return N(r) ? "" : String.fromCharCode(r); + } + }, se.readHexChar = function(e) { + var r = this.pos, d = this.readInt(16, e); + return d === null && this.invalidStringToken(r, "Bad character escape sequence"), d; + }, se.readWord1 = function() { + this.containsEsc = false; + for (var e = "", r = true, d = this.pos, _ = this.options.ecmaVersion >= 6; this.pos < this.input.length; ) { + var D = this.fullCharCodeAtPos(); + if (v(D, _)) + this.pos += D <= 65535 ? 1 : 2; + else if (D === 92) { + this.containsEsc = true, e += this.input.slice(d, this.pos); + var M = this.pos; + this.input.charCodeAt(++this.pos) !== 117 && this.invalidStringToken(this.pos, "Expecting Unicode escape sequence \\uXXXX"), ++this.pos; + var z = this.readCodePoint(); + (r ? S : v)(z, _) || this.invalidStringToken(M, "Invalid Unicode escape"), e += Ze(z), d = this.pos; + } else + break; + r = false; + } + return e + this.input.slice(d, this.pos); + }, se.readWord = function() { + var e = this.readWord1(), r = a.name; + return this.keywords.test(e) && (r = V[e]), this.finishToken(r, e); + }; + var St = "7.1.0"; + le.acorn = { Parser: le, version: St, defaultOptions: U, Position: J, SourceLocation: q, getLineInfo: j, Node: ze, TokenType: h, tokTypes: a, keywordTypes: V, TokContext: ve, tokContexts: ce, isIdentifierChar: v, isIdentifierStart: S, Token: Ue, isNewLine: N, lineBreak: k, lineBreakG: A, nonASCIIwhitespace: F }; + function Wt(e, r) { + return le.parse(e, r); + } + function jt(e, r, d) { + return le.parseExpressionAt(e, r, d); + } + function Ht(e, r) { + return le.tokenizer(e, r); + } + p.Node = ze, p.Parser = le, p.Position = J, p.SourceLocation = q, p.TokContext = ve, p.Token = Ue, p.TokenType = h, p.defaultOptions = U, p.getLineInfo = j, p.isIdentifierChar = v, p.isIdentifierStart = S, p.isNewLine = N, p.keywordTypes = V, p.lineBreak = k, p.lineBreakG = A, p.nonASCIIwhitespace = F, p.parse = Wt, p.parseExpressionAt = jt, p.tokContexts = ce, p.tokTypes = a, p.tokenizer = Ht, p.version = St, Object.defineProperty(p, "__esModule", { value: true }); + }); + }, {}], 2: [function(o, y, E) { + }, {}], 3: [function(o, y, E) { + function p(s, t = {}) { + let { contextName: i = "gl", throwGetError: u, useTrackablePrimitives: x2, readPixelsFile: w, recording: m = [], variables: S = {}, onReadPixels: v, onUnrecognizedArgumentLookup: h } = t, b = new Proxy(s, { get: k }), T = [], C = {}, V = 0, c = "", a; + return b; + function k(j, U) { + switch (U) { + case "addComment": + return B; + case "checkThrowError": + return P; + case "getReadPixelsVariableName": + return a; + case "insertVariable": + return F; + case "reset": + return N; + case "setIndent": + return K; + case "toString": + return A; + case "getContextVariableName": + return q; + } + return typeof s[U] == "function" ? function() { + switch (U) { + case "getError": + return u ? m.push(`${c}if (${i}.getError() !== ${i}.NONE) throw new Error('error');`) : m.push(`${c}${i}.getError();`), s.getError(); + case "getExtension": { + let Q = `${i}Variables${T.length}`; + m.push(`${c}const ${Q} = ${i}.getExtension('${arguments[0]}');`); + let ue = s.getExtension(arguments[0]); + if (ue && typeof ue == "object") { + let he = g(ue, { getEntity: R, useTrackablePrimitives: x2, recording: m, contextName: Q, contextVariables: T, variables: S, indent: c, onUnrecognizedArgumentLookup: h }); + return T.push(he), he; + } else + T.push(null); + return ue; + } + case "readPixels": + let Z = T.indexOf(arguments[6]), ee; + if (Z === -1) { + let Q = J(arguments[6]); + Q ? (ee = Q, m.push(`${c}${Q}`)) : (ee = `${i}Variable${T.length}`, T.push(arguments[6]), m.push(`${c}const ${ee} = new ${arguments[6].constructor.name}(${arguments[6].length});`)); + } else + ee = `${i}Variable${Z}`; + a = ee; + let be = [arguments[0], arguments[1], arguments[2], arguments[3], R(arguments[4]), R(arguments[5]), ee]; + return m.push(`${c}${i}.readPixels(${be.join(", ")});`), w && X(arguments[2], arguments[3]), v && v(ee, be), s.readPixels.apply(s, arguments); + case "drawBuffers": + return m.push(`${c}${i}.drawBuffers([${f(arguments[0], { contextName: i, contextVariables: T, getEntity: R, addVariable: O, variables: S, onUnrecognizedArgumentLookup: h })}]);`), s.drawBuffers(arguments[0]); + } + let oe = s[U].apply(s, arguments); + switch (typeof oe) { + case "undefined": + m.push(`${c}${Y(U, arguments)};`); + return; + case "number": + case "boolean": + if (x2 && T.indexOf(n(oe)) === -1) { + m.push(`${c}const ${i}Variable${T.length} = ${Y(U, arguments)};`), T.push(oe = n(oe)); + break; + } + default: + oe === null ? m.push(`${Y(U, arguments)};`) : m.push(`${c}const ${i}Variable${T.length} = ${Y(U, arguments)};`), T.push(oe); + } + return oe; + } : (C[s[U]] = U, s[U]); + } + function A() { + return m.join(` +`); + } + function N() { + for (; m.length > 0; ) + m.pop(); + } + function F(j, U) { + S[j] = U; + } + function R(j) { + let U = C[j]; + return U ? i + "." + U : j; + } + function K(j) { + c = " ".repeat(j); + } + function O(j, U) { + let oe = `${i}Variable${T.length}`; + return m.push(`${c}const ${oe} = ${U};`), T.push(j), oe; + } + function X(j, U) { + let oe = `${i}Variable${T.length}`, Z = `imageDatum${V}`; + m.push(`${c}let ${Z} = ["P3\\n# ${w}.ppm\\n", ${j}, ' ', ${U}, "\\n255\\n"].join("");`), m.push(`${c}for (let i = 0; i < ${Z}.length; i += 4) {`), m.push(`${c} ${Z} += ${oe}[i] + ' ' + ${oe}[i + 1] + ' ' + ${oe}[i + 2] + ' ';`), m.push(`${c}}`), m.push(`${c}if (typeof require !== "undefined") {`), m.push(`${c} require('fs').writeFileSync('./${w}.ppm', ${Z});`), m.push(`${c}}`), V++; + } + function B(j) { + m.push(`${c}// ${j}`); + } + function P() { + m.push(`${c}(() => { + ${c}const error = ${i}.getError(); + ${c}if (error !== ${i}.NONE) { + ${c} const names = Object.getOwnPropertyNames(gl); + ${c} for (let i = 0; i < names.length; i++) { + ${c} const name = names[i]; + ${c} if (${i}[name] === error) { + ${c} throw new Error('${i} threw ' + name); + ${c} } + ${c} } + ${c}} + ${c}})();`); + } + function Y(j, U) { + return `${i}.${j}(${f(U, { contextName: i, contextVariables: T, getEntity: R, addVariable: O, variables: S, onUnrecognizedArgumentLookup: h })})`; + } + function J(j) { + if (S) { + for (let U in S) + if (S[U] === j) + return U; + } + return null; + } + function q(j) { + let U = T.indexOf(j); + return U !== -1 ? `${i}Variable${U}` : null; + } + } + function g(s, t) { + let i = new Proxy(s, { get: C }), u = {}, { contextName: x2, contextVariables: w, getEntity: m, useTrackablePrimitives: S, recording: v, variables: h, indent: b, onUnrecognizedArgumentLookup: T } = t; + return i; + function C(k, A) { + return typeof k[A] == "function" ? function() { + switch (A) { + case "drawBuffersWEBGL": + return v.push(`${b}${x2}.drawBuffersWEBGL([${f(arguments[0], { contextName: x2, contextVariables: w, getEntity: V, addVariable: a, variables: h, onUnrecognizedArgumentLookup: T })}]);`), s.drawBuffersWEBGL(arguments[0]); + } + let N = s[A].apply(s, arguments); + switch (typeof N) { + case "undefined": + v.push(`${b}${c(A, arguments)};`); + return; + case "number": + case "boolean": + S && w.indexOf(n(N)) === -1 ? (v.push(`${b}const ${x2}Variable${w.length} = ${c(A, arguments)};`), w.push(N = n(N))) : (v.push(`${b}const ${x2}Variable${w.length} = ${c(A, arguments)};`), w.push(N)); + break; + default: + N === null ? v.push(`${c(A, arguments)};`) : v.push(`${b}const ${x2}Variable${w.length} = ${c(A, arguments)};`), w.push(N); + } + return N; + } : (u[s[A]] = A, s[A]); + } + function V(k) { + return u.hasOwnProperty(k) ? `${x2}.${u[k]}` : m(k); + } + function c(k, A) { + return `${x2}.${k}(${f(A, { contextName: x2, contextVariables: w, getEntity: V, addVariable: a, variables: h, onUnrecognizedArgumentLookup: T })})`; + } + function a(k, A) { + let N = `${x2}Variable${w.length}`; + return w.push(k), v.push(`${b}const ${N} = ${A};`), N; + } + } + function f(s, t) { + let { variables: i, onUnrecognizedArgumentLookup: u } = t; + return Array.from(s).map((w) => { + let m = x2(w); + return m || l(w, t); + }).join(", "); + function x2(w) { + if (i) { + for (let m in i) + if (!!i.hasOwnProperty(m) && i[m] === w) + return m; + } + return u ? u(w) : null; + } + } + function l(s, t) { + let { contextName: i, contextVariables: u, getEntity: x2, addVariable: w, onUnrecognizedArgumentLookup: m } = t; + if (typeof s > "u") + return "undefined"; + if (s === null) + return "null"; + let S = u.indexOf(s); + if (S > -1) + return `${i}Variable${S}`; + switch (s.constructor.name) { + case "String": + let v = /\n/.test(s), h = /'/.test(s), b = /"/.test(s); + return v ? "`" + s + "`" : h && !b ? '"' + s + '"' : "'" + s + "'"; + case "Number": + return x2(s); + case "Boolean": + return x2(s); + case "Array": + return w(s, `new ${s.constructor.name}([${Array.from(s).join(",")}])`); + case "Float32Array": + case "Uint8Array": + case "Uint16Array": + case "Int32Array": + return w(s, `new ${s.constructor.name}(${JSON.stringify(Array.from(s))})`); + default: + if (m) { + let T = m(s); + if (T) + return T; + } + throw new Error(`unrecognized argument type ${s.constructor.name}`); + } + } + function n(s) { + return new s.constructor(s); + } + typeof y < "u" && (y.exports = { glWiretap: p, glExtensionWiretap: g }), typeof window < "u" && (p.glExtensionWiretap = g, window.glWiretap = p); + }, {}], 4: [function(o, y, E) { + function p(w) { + let m = new Array(w.length); + for (let S = 0; S < w.length; S++) { + let v = w[S]; + v.toArray ? m[S] = v.toArray() : m[S] = v; + } + return m; + } + function g() { + let w = p(arguments), m = new Float32Array(this.output.x); + for (let S = 0; S < this.output.x; S++) + this.thread.x = S, this.thread.y = 0, this.thread.z = 0, m[S] = this._fn.apply(this, w); + return m; + } + function f() { + let w = p(arguments), m = new Array(this.output.y); + for (let S = 0; S < this.output.y; S++) { + let v = new Float32Array(this.output.x); + for (let h = 0; h < this.output.x; h++) + this.thread.x = h, this.thread.y = S, this.thread.z = 0, v[h] = this._fn.apply(this, w); + m[S] = v; + } + return m; + } + function l() { + let w = p(arguments); + for (let m = 0; m < this.output.y; m++) + for (let S = 0; S < this.output.x; S++) + this.thread.x = S, this.thread.y = m, this.thread.z = 0, this._fn.apply(this, w); + } + function n() { + let w = p(arguments), m = new Array(this.output.z); + for (let S = 0; S < this.output.z; S++) { + let v = new Array(this.output.y); + for (let h = 0; h < this.output.y; h++) { + let b = new Float32Array(this.output.x); + for (let T = 0; T < this.output.x; T++) + this.thread.x = T, this.thread.y = h, this.thread.z = S, b[T] = this._fn.apply(this, w); + v[h] = b; + } + m[S] = v; + } + return m; + } + function s(w) { + w.setOutput = (v) => { + w.output = i(v), w.graphical && t(w); + }, w.toJSON = () => { + throw new Error("Not usable with gpuMock"); + }, w.setConstants = (v) => (w.constants = v, w), w.setGraphical = (v) => (w.graphical = v, w), w.setCanvas = (v) => (w.canvas = v, w), w.setContext = (v) => (w.context = v, w), w.destroy = () => { + }, w.validateSettings = () => { + }, w.graphical && w.output && t(w), w.exec = function() { + return new Promise((v, h) => { + try { + v(w.apply(w, arguments)); + } catch (b) { + h(b); + } + }); + }, w.getPixels = (v) => { + let { x: h, y: b } = w.output; + return v ? x2(w._imageData.data, h, b) : w._imageData.data.slice(0); + }, w.color = function(v, h, b, T) { + typeof T > "u" && (T = 1), v = Math.floor(v * 255), h = Math.floor(h * 255), b = Math.floor(b * 255), T = Math.floor(T * 255); + let C = w.output.x, V = w.output.y, c = w.thread.x, a = V - w.thread.y - 1, k = c + a * C; + w._colorData[k * 4 + 0] = v, w._colorData[k * 4 + 1] = h, w._colorData[k * 4 + 2] = b, w._colorData[k * 4 + 3] = T; + }; + let m = () => w, S = ["setWarnVarUsage", "setArgumentTypes", "setTactic", "setOptimizeFloatMemory", "setDebug", "setLoopMaxIterations", "setConstantTypes", "setFunctions", "setNativeFunctions", "setInjectedNative", "setPipeline", "setPrecision", "setOutputToTexture", "setImmutable", "setStrictIntegers", "setDynamicOutput", "setHardcodeConstants", "setDynamicArguments", "setUseLegacyEncoder", "setWarnVarUsage", "addSubKernel"]; + for (let v = 0; v < S.length; v++) + w[S[v]] = m; + return w; + } + function t(w) { + let { x: m, y: S } = w.output; + if (w.context && w.context.createImageData) { + let v = new Uint8ClampedArray(m * S * 4); + w._imageData = w.context.createImageData(m, S), w._colorData = v; + } else { + let v = new Uint8ClampedArray(m * S * 4); + w._imageData = { data: v }, w._colorData = v; + } + } + function i(w) { + let m = null; + if (w.length) + if (w.length === 3) { + let [S, v, h] = w; + m = { x: S, y: v, z: h }; + } else if (w.length === 2) { + let [S, v] = w; + m = { x: S, y: v }; + } else { + let [S] = w; + m = { x: S }; + } + else + m = w; + return m; + } + function u(w, m = {}) { + let S = m.output ? i(m.output) : null; + function v() { + return v.output.z ? n.apply(v, arguments) : v.output.y ? v.graphical ? l.apply(v, arguments) : f.apply(v, arguments) : g.apply(v, arguments); + } + return v._fn = w, v.constants = m.constants || null, v.context = m.context || null, v.canvas = m.canvas || null, v.graphical = m.graphical || false, v._imageData = null, v._colorData = null, v.output = S, v.thread = { x: 0, y: 0, z: 0 }, s(v); + } + function x2(w, m, S) { + let v = S / 2 | 0, h = m * 4, b = new Uint8ClampedArray(m * 4), T = w.slice(0); + for (let C = 0; C < v; ++C) { + let V = C * h, c = (S - C - 1) * h; + b.set(T.subarray(V, V + h)), T.copyWithin(V, c, c + h), T.set(b, c); + } + return T; + } + y.exports = { gpuMock: u }; + }, {}], 5: [function(o, y, E) { + let { utils: p } = o("./utils"); + function g(f, l) { + let n = l.toString(); + return new Function(`return function ${f} (${p.getArgumentNamesFromString(n).join(", ")}) { + ${p.getFunctionBodyFromString(n)} + }`)(); + } + y.exports = { alias: g }; + }, { "./utils": 114 }], 6: [function(o, y, E) { + let { FunctionNode: p } = o("../function-node"); + class g extends p { + astFunction(l, n) { + if (!this.isRootKernel) { + n.push("function"), n.push(" "), n.push(this.name), n.push("("); + for (let s = 0; s < this.argumentNames.length; ++s) { + let t = this.argumentNames[s]; + s > 0 && n.push(", "), n.push("user_"), n.push(t); + } + n.push(`) { +`); + } + for (let s = 0; s < l.body.body.length; ++s) + this.astGeneric(l.body.body[s], n), n.push(` +`); + return this.isRootKernel || n.push(`} +`), n; + } + astReturnStatement(l, n) { + let s = this.returnType || this.getType(l.argument); + return this.returnType || (this.returnType = s), this.isRootKernel ? (n.push(this.leadingReturnStatement), this.astGeneric(l.argument, n), n.push(`; +`), n.push(this.followingReturnStatement), n.push(`continue; +`)) : this.isSubKernel ? (n.push(`subKernelResult_${this.name} = `), this.astGeneric(l.argument, n), n.push(";"), n.push(`return subKernelResult_${this.name};`)) : (n.push("return "), this.astGeneric(l.argument, n), n.push(";")), n; + } + astLiteral(l, n) { + if (isNaN(l.value)) + throw this.astErrorOutput("Non-numeric literal not supported : " + l.value, l); + return n.push(l.value), n; + } + astBinaryExpression(l, n) { + return n.push("("), this.astGeneric(l.left, n), n.push(l.operator), this.astGeneric(l.right, n), n.push(")"), n; + } + astIdentifierExpression(l, n) { + if (l.type !== "Identifier") + throw this.astErrorOutput("IdentifierExpression - not an Identifier", l); + switch (l.name) { + case "Infinity": + n.push("Infinity"); + break; + default: + this.constants && this.constants.hasOwnProperty(l.name) ? n.push("constants_" + l.name) : n.push("user_" + l.name); + } + return n; + } + astForStatement(l, n) { + if (l.type !== "ForStatement") + throw this.astErrorOutput("Invalid for statement", l); + let s = [], t = [], i = [], u = [], x2 = null; + if (l.init) { + this.pushState("in-for-loop-init"), this.astGeneric(l.init, s); + for (let w = 0; w < s.length; w++) + s[w].includes && s[w].includes(",") && (x2 = false); + this.popState("in-for-loop-init"); + } else + x2 = false; + if (l.test ? this.astGeneric(l.test, t) : x2 = false, l.update ? this.astGeneric(l.update, i) : x2 = false, l.body && (this.pushState("loop-body"), this.astGeneric(l.body, u), this.popState("loop-body")), x2 === null && (x2 = this.isSafe(l.init) && this.isSafe(l.test)), x2) + n.push(`for (${s.join("")};${t.join("")};${i.join("")}){ +`), n.push(u.join("")), n.push(`} +`); + else { + let w = this.getInternalVariableName("safeI"); + s.length > 0 && n.push(s.join(""), `; +`), n.push(`for (let ${w}=0;${w} 0 && n.push(`if (!${t.join("")}) break; +`), n.push(u.join("")), n.push(` +${i.join("")};`), n.push(`} +`); + } + return n; + } + astWhileStatement(l, n) { + if (l.type !== "WhileStatement") + throw this.astErrorOutput("Invalid while statement", l); + return n.push("for (let i = 0; i < LOOP_MAX; i++) {"), n.push("if ("), this.astGeneric(l.test, n), n.push(`) { +`), this.astGeneric(l.body, n), n.push(`} else { +`), n.push(`break; +`), n.push(`} +`), n.push(`} +`), n; + } + astDoWhileStatement(l, n) { + if (l.type !== "DoWhileStatement") + throw this.astErrorOutput("Invalid while statement", l); + return n.push("for (let i = 0; i < LOOP_MAX; i++) {"), this.astGeneric(l.body, n), n.push("if (!"), this.astGeneric(l.test, n), n.push(`) { +`), n.push(`break; +`), n.push(`} +`), n.push(`} +`), n; + } + astAssignmentExpression(l, n) { + let s = this.getDeclaration(l.left); + if (s && !s.assignable) + throw this.astErrorOutput(`Variable ${l.left.name} is not assignable here`, l); + return this.astGeneric(l.left, n), n.push(l.operator), this.astGeneric(l.right, n), n; + } + astBlockStatement(l, n) { + if (this.isState("loop-body")) { + this.pushState("block-body"); + for (let s = 0; s < l.body.length; s++) + this.astGeneric(l.body[s], n); + this.popState("block-body"); + } else { + n.push(`{ +`); + for (let s = 0; s < l.body.length; s++) + this.astGeneric(l.body[s], n); + n.push(`} +`); + } + return n; + } + astVariableDeclaration(l, n) { + n.push(`${l.kind} `); + let { declarations: s } = l; + for (let t = 0; t < s.length; t++) { + t > 0 && n.push(","); + let i = s[t], u = this.getDeclaration(i.id); + u.valueType || (u.valueType = this.getType(i.init)), this.astGeneric(i, n); + } + return this.isState("in-for-loop-init") || n.push(";"), n; + } + astIfStatement(l, n) { + return n.push("if ("), this.astGeneric(l.test, n), n.push(")"), l.consequent.type === "BlockStatement" ? this.astGeneric(l.consequent, n) : (n.push(` { +`), this.astGeneric(l.consequent, n), n.push(` +} +`)), l.alternate && (n.push("else "), l.alternate.type === "BlockStatement" || l.alternate.type === "IfStatement" ? this.astGeneric(l.alternate, n) : (n.push(` { +`), this.astGeneric(l.alternate, n), n.push(` +} +`))), n; + } + astSwitchStatement(l, n) { + let { discriminant: s, cases: t } = l; + n.push("switch ("), this.astGeneric(s, n), n.push(`) { +`); + for (let i = 0; i < t.length; i++) { + if (t[i].test === null) { + n.push(`default: +`), this.astGeneric(t[i].consequent, n), t[i].consequent && t[i].consequent.length > 0 && n.push(`break; +`); + continue; + } + n.push("case "), this.astGeneric(t[i].test, n), n.push(`: +`), t[i].consequent && t[i].consequent.length > 0 && (this.astGeneric(t[i].consequent, n), n.push(`break; +`)); + } + n.push(` +}`); + } + astThisExpression(l, n) { + return n.push("_this"), n; + } + astMemberExpression(l, n) { + let { signature: s, type: t, property: i, xProperty: u, yProperty: x2, zProperty: w, name: m, origin: S } = this.getMemberExpressionDetails(l); + switch (s) { + case "this.thread.value": + return n.push(`_this.thread.${m}`), n; + case "this.output.value": + switch (m) { + case "x": + n.push("outputX"); + break; + case "y": + n.push("outputY"); + break; + case "z": + n.push("outputZ"); + break; + default: + throw this.astErrorOutput("Unexpected expression", l); + } + return n; + case "value": + throw this.astErrorOutput("Unexpected expression", l); + case "value[]": + case "value[][]": + case "value[][][]": + case "value.value": + if (S === "Math") + return n.push(Math[m]), n; + switch (i) { + case "r": + return n.push(`user_${m}[0]`), n; + case "g": + return n.push(`user_${m}[1]`), n; + case "b": + return n.push(`user_${m}[2]`), n; + case "a": + return n.push(`user_${m}[3]`), n; + } + break; + case "this.constants.value": + case "this.constants.value[]": + case "this.constants.value[][]": + case "this.constants.value[][][]": + break; + case "fn()[]": + return this.astGeneric(l.object, n), n.push("["), this.astGeneric(l.property, n), n.push("]"), n; + case "fn()[][]": + return this.astGeneric(l.object.object, n), n.push("["), this.astGeneric(l.object.property, n), n.push("]"), n.push("["), this.astGeneric(l.property, n), n.push("]"), n; + default: + throw this.astErrorOutput("Unexpected expression", l); + } + if (!l.computed) + switch (t) { + case "Number": + case "Integer": + case "Float": + case "Boolean": + return n.push(`${S}_${m}`), n; + } + let v = `${S}_${m}`; + switch (t) { + case "Array(2)": + case "Array(3)": + case "Array(4)": + case "Matrix(2)": + case "Matrix(3)": + case "Matrix(4)": + case "HTMLImageArray": + case "ArrayTexture(1)": + case "ArrayTexture(2)": + case "ArrayTexture(3)": + case "ArrayTexture(4)": + case "HTMLImage": + default: + let h, b; + if (S === "constants") { + let T = this.constants[m]; + b = this.constantTypes[m] === "Input", h = b ? T.size : null; + } else + b = this.isInput(m), h = b ? this.argumentSizes[this.argumentNames.indexOf(m)] : null; + n.push(`${v}`), w && x2 ? b ? (n.push("[("), this.astGeneric(w, n), n.push(`*${this.dynamicArguments ? "(outputY * outputX)" : h[1] * h[0]})+(`), this.astGeneric(x2, n), n.push(`*${this.dynamicArguments ? "outputX" : h[0]})+`), this.astGeneric(u, n), n.push("]")) : (n.push("["), this.astGeneric(w, n), n.push("]"), n.push("["), this.astGeneric(x2, n), n.push("]"), n.push("["), this.astGeneric(u, n), n.push("]")) : x2 ? b ? (n.push("[("), this.astGeneric(x2, n), n.push(`*${this.dynamicArguments ? "outputX" : h[0]})+`), this.astGeneric(u, n), n.push("]")) : (n.push("["), this.astGeneric(x2, n), n.push("]"), n.push("["), this.astGeneric(u, n), n.push("]")) : typeof u < "u" && (n.push("["), this.astGeneric(u, n), n.push("]")); + } + return n; + } + astCallExpression(l, n) { + if (l.type !== "CallExpression") + throw this.astErrorOutput("Unknown CallExpression", l); + let s = this.astMemberExpressionUnroll(l.callee); + this.calledFunctions.indexOf(s) < 0 && this.calledFunctions.push(s); + let t = this.isAstMathFunction(l); + this.onFunctionCall && this.onFunctionCall(this.name, s, l.arguments), n.push(s), n.push("("); + let i = this.lookupFunctionArgumentTypes(s) || []; + for (let u = 0; u < l.arguments.length; ++u) { + let x2 = l.arguments[u], w = this.getType(x2); + i[u] || this.triggerImplyArgumentType(s, u, w, this), u > 0 && n.push(", "), this.astGeneric(x2, n); + } + return n.push(")"), n; + } + astArrayExpression(l, n) { + let s = this.getType(l), t = l.elements.length, i = []; + for (let u = 0; u < t; ++u) { + let x2 = []; + this.astGeneric(l.elements[u], x2), i.push(x2.join("")); + } + switch (s) { + case "Matrix(2)": + case "Matrix(3)": + case "Matrix(4)": + n.push(`[${i.join(", ")}]`); + break; + default: + n.push(`new Float32Array([${i.join(", ")}])`); + } + return n; + } + astDebuggerStatement(l, n) { + return n.push("debugger;"), n; + } + } + y.exports = { CPUFunctionNode: g }; + }, { "../function-node": 10 }], 7: [function(o, y, E) { + let { utils: p } = o("../../utils"); + function g(l, n) { + let s = []; + for (let t in n) { + if (!n.hasOwnProperty(t)) + continue; + let i = n[t], u = l[t]; + switch (i) { + case "Number": + case "Integer": + case "Float": + case "Boolean": + s.push(`${t}:${u}`); + break; + case "Array(2)": + case "Array(3)": + case "Array(4)": + case "Matrix(2)": + case "Matrix(3)": + case "Matrix(4)": + s.push(`${t}:new ${u.constructor.name}(${JSON.stringify(Array.from(u))})`); + break; + } + } + return `{ ${s.join()} }`; + } + function f(l, n) { + let s = [], t = [], i = [], u = !/^function/.test(l.color.toString()); + if (s.push(" const { context, canvas, constants: incomingConstants } = settings;", ` const output = new Int32Array(${JSON.stringify(Array.from(l.output))});`, ` const _constantTypes = ${JSON.stringify(l.constantTypes)};`, ` const _constants = ${g(l.constants, l.constantTypes)};`), t.push(" constants: _constants,", " context,", " output,", " thread: {x: 0, y: 0, z: 0},"), l.graphical) { + s.push(` const _imageData = context.createImageData(${l.output[0]}, ${l.output[1]});`), s.push(` const _colorData = new Uint8ClampedArray(${l.output[0]} * ${l.output[1]} * 4);`); + let m = p.flattenFunctionToString((u ? "function " : "") + l.color.toString(), { thisLookup: (v) => { + switch (v) { + case "_colorData": + return "_colorData"; + case "_imageData": + return "_imageData"; + case "output": + return "output"; + case "thread": + return "this.thread"; + } + return JSON.stringify(l[v]); + }, findDependency: (v, h) => null }), S = p.flattenFunctionToString((u ? "function " : "") + l.getPixels.toString(), { thisLookup: (v) => { + switch (v) { + case "_colorData": + return "_colorData"; + case "_imageData": + return "_imageData"; + case "output": + return "output"; + case "thread": + return "this.thread"; + } + return JSON.stringify(l[v]); + }, findDependency: () => null }); + t.push(" _imageData,", " _colorData,", ` color: ${m},`), i.push(` kernel.getPixels = ${S};`); + } + let x2 = [], w = Object.keys(l.constantTypes); + for (let m = 0; m < w.length; m++) + x2.push(l.constantTypes[w]); + if (l.argumentTypes.indexOf("HTMLImageArray") !== -1 || x2.indexOf("HTMLImageArray") !== -1) { + let m = p.flattenFunctionToString((u ? "function " : "") + l._imageTo3DArray.toString(), { doNotDefine: ["canvas"], findDependency: (S, v) => S === "this" ? (u ? "function " : "") + l[v].toString() : null, thisLookup: (S) => { + switch (S) { + case "canvas": + return; + case "context": + return "context"; + } + } }); + i.push(m), t.push(" _mediaTo2DArray,"), t.push(" _imageTo3DArray,"); + } else if (l.argumentTypes.indexOf("HTMLImage") !== -1 || x2.indexOf("HTMLImage") !== -1) { + let m = p.flattenFunctionToString((u ? "function " : "") + l._mediaTo2DArray.toString(), { findDependency: (S, v) => null, thisLookup: (S) => { + switch (S) { + case "canvas": + return "settings.canvas"; + case "context": + return "settings.context"; + } + throw new Error("unhandled thisLookup"); + } }); + i.push(m), t.push(" _mediaTo2DArray,"); + } + return `function(settings) { + ${s.join(` +`)} + for (const p in _constantTypes) { + if (!_constantTypes.hasOwnProperty(p)) continue; + const type = _constantTypes[p]; + switch (type) { + case 'Number': + case 'Integer': + case 'Float': + case 'Boolean': + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + case 'Matrix(2)': + case 'Matrix(3)': + case 'Matrix(4)': + if (incomingConstants.hasOwnProperty(p)) { + console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned'); + } + continue; + } + if (!incomingConstants.hasOwnProperty(p)) { + throw new Error('constant ' + p + ' not found'); + } + _constants[p] = incomingConstants[p]; + } + const kernel = (function() { + ${l._kernelString} + }) + .apply({ ${t.join(` +`)} }); + ${i.join(` +`)} + return kernel; + }`; + } + y.exports = { cpuKernelString: f }; + }, { "../../utils": 114 }], 8: [function(o, y, E) { + let { Kernel: p } = o("../kernel"), { FunctionBuilder: g } = o("../function-builder"), { CPUFunctionNode: f } = o("./function-node"), { utils: l } = o("../../utils"), { cpuKernelString: n } = o("./kernel-string"); + class s extends p { + static getFeatures() { + return this.features; + } + static get features() { + return Object.freeze({ kernelMap: true, isIntegerDivisionAccurate: true }); + } + static get isSupported() { + return true; + } + static isContextMatch(i) { + return false; + } + static get mode() { + return "cpu"; + } + static nativeFunctionArguments() { + return null; + } + static nativeFunctionReturnType() { + throw new Error(`Looking up native function return type not supported on ${this.name}`); + } + static combineKernels(i) { + return i; + } + static getSignature(i, u) { + return "cpu" + (u.length > 0 ? ":" + u.join(",") : ""); + } + constructor(i, u) { + super(i, u), this.mergeSettings(i.settings || u), this._imageData = null, this._colorData = null, this._kernelString = null, this._prependedString = [], this.thread = { x: 0, y: 0, z: 0 }, this.translatedSources = null; + } + initCanvas() { + if (typeof document < "u") + return document.createElement("canvas"); + if (typeof OffscreenCanvas < "u") + return new OffscreenCanvas(0, 0); + } + initContext() { + return this.canvas ? this.canvas.getContext("2d") : null; + } + initPlugins(i) { + return []; + } + validateSettings(i) { + if (!this.output || this.output.length === 0) { + if (i.length !== 1) + throw new Error("Auto output only supported for kernels with only one input"); + let u = l.getVariableType(i[0], this.strictIntegers); + if (u === "Array") + this.output = l.getDimensions(u); + else if (u === "NumberTexture" || u === "ArrayTexture(4)") + this.output = i[0].output; + else + throw new Error("Auto output not supported for input type: " + u); + } + if (this.graphical && this.output.length !== 2) + throw new Error("Output must have 2 dimensions on graphical mode"); + this.checkOutput(); + } + translateSource() { + if (this.leadingReturnStatement = this.output.length > 1 ? "resultX[x] = " : "result[x] = ", this.subKernels) { + let u = []; + for (let x2 = 0; x2 < this.subKernels.length; x2++) { + let { name: w } = this.subKernels[x2]; + u.push(this.output.length > 1 ? `resultX_${w}[x] = subKernelResult_${w}; +` : `result_${w}[x] = subKernelResult_${w}; +`); + } + this.followingReturnStatement = u.join(""); + } + let i = g.fromKernel(this, f); + this.translatedSources = i.getPrototypes("kernel"), !this.graphical && !this.returnType && (this.returnType = i.getKernelResultType()); + } + build() { + if (this.built) + return; + if (this.setupConstants(), this.setupArguments(arguments), this.validateSettings(arguments), this.translateSource(), this.graphical) { + let { canvas: u, output: x2 } = this; + if (!u) + throw new Error("no canvas available for using graphical output"); + let w = x2[0], m = x2[1] || 1; + u.width = w, u.height = m, this._imageData = this.context.createImageData(w, m), this._colorData = new Uint8ClampedArray(w * m * 4); + } + let i = this.getKernelString(); + this.kernelString = i, this.debug && (console.log("Function output:"), console.log(i)); + try { + this.run = new Function([], i).bind(this)(); + } catch (u) { + console.error("An error occurred compiling the javascript: ", u); + } + this.buildSignature(arguments), this.built = true; + } + color(i, u, x2, w) { + typeof w > "u" && (w = 1), i = Math.floor(i * 255), u = Math.floor(u * 255), x2 = Math.floor(x2 * 255), w = Math.floor(w * 255); + let m = this.output[0], S = this.output[1], v = this.thread.x, h = S - this.thread.y - 1, b = v + h * m; + this._colorData[b * 4 + 0] = i, this._colorData[b * 4 + 1] = u, this._colorData[b * 4 + 2] = x2, this._colorData[b * 4 + 3] = w; + } + getKernelString() { + if (this._kernelString !== null) + return this._kernelString; + let i = null, { translatedSources: u } = this; + return u.length > 1 ? u = u.filter((x2) => /^function/.test(x2) ? x2 : (i = x2, false)) : i = u.shift(), this._kernelString = ` const LOOP_MAX = ${this._getLoopMaxString()}; + ${this.injectedNative || ""} + const _this = this; + ${this._resultKernelHeader()} + ${this._processConstants()} + return (${this.argumentNames.map((x2) => "user_" + x2).join(", ")}) => { + ${this._prependedString.join("")} + ${this._earlyThrows()} + ${this._processArguments()} + ${this.graphical ? this._graphicalKernelBody(i) : this._resultKernelBody(i)} + ${u.length > 0 ? u.join(` +`) : ""} + };`; + } + toString() { + return n(this); + } + _getLoopMaxString() { + return this.loopMaxIterations ? ` ${parseInt(this.loopMaxIterations)};` : " 1000;"; + } + _processConstants() { + if (!this.constants) + return ""; + let i = []; + for (let u in this.constants) + switch (this.constantTypes[u]) { + case "HTMLCanvas": + case "HTMLImage": + case "HTMLVideo": + i.push(` const constants_${u} = this._mediaTo2DArray(this.constants.${u}); +`); + break; + case "HTMLImageArray": + i.push(` const constants_${u} = this._imageTo3DArray(this.constants.${u}); +`); + break; + case "Input": + i.push(` const constants_${u} = this.constants.${u}.value; +`); + break; + default: + i.push(` const constants_${u} = this.constants.${u}; +`); + } + return i.join(""); + } + _earlyThrows() { + if (this.graphical || this.immutable || !this.pipeline) + return ""; + let i = []; + for (let x2 = 0; x2 < this.argumentTypes.length; x2++) + this.argumentTypes[x2] === "Array" && i.push(this.argumentNames[x2]); + if (i.length === 0) + return ""; + let u = []; + for (let x2 = 0; x2 < i.length; x2++) { + let w = i[x2], m = this._mapSubKernels((S) => `user_${w} === result_${S.name}`).join(" || "); + u.push(`user_${w} === result${m ? ` || ${m}` : ""}`); + } + return `if (${u.join(" || ")}) throw new Error('Source and destination arrays are the same. Use immutable = true');`; + } + _processArguments() { + let i = []; + for (let u = 0; u < this.argumentTypes.length; u++) { + let x2 = `user_${this.argumentNames[u]}`; + switch (this.argumentTypes[u]) { + case "HTMLCanvas": + case "HTMLImage": + case "HTMLVideo": + i.push(` ${x2} = this._mediaTo2DArray(${x2}); +`); + break; + case "HTMLImageArray": + i.push(` ${x2} = this._imageTo3DArray(${x2}); +`); + break; + case "Input": + i.push(` ${x2} = ${x2}.value; +`); + break; + case "ArrayTexture(1)": + case "ArrayTexture(2)": + case "ArrayTexture(3)": + case "ArrayTexture(4)": + case "NumberTexture": + case "MemoryOptimizedNumberTexture": + i.push(` + if (${x2}.toArray) { + if (!_this.textureCache) { + _this.textureCache = []; + _this.arrayCache = []; + } + const textureIndex = _this.textureCache.indexOf(${x2}); + if (textureIndex !== -1) { + ${x2} = _this.arrayCache[textureIndex]; + } else { + _this.textureCache.push(${x2}); + ${x2} = ${x2}.toArray(); + _this.arrayCache.push(${x2}); + } + }`); + break; + } + } + return i.join(""); + } + _mediaTo2DArray(i) { + let u = this.canvas, x2 = i.width > 0 ? i.width : i.videoWidth, w = i.height > 0 ? i.height : i.videoHeight; + u.width < x2 && (u.width = x2), u.height < w && (u.height = w); + let m = this.context; + m.drawImage(i, 0, 0, x2, w); + let S = m.getImageData(0, 0, x2, w).data, v = new Array(w), h = 0; + for (let b = w - 1; b >= 0; b--) { + let T = v[b] = new Array(x2); + for (let C = 0; C < x2; C++) { + let V = new Float32Array(4); + V[0] = S[h++] / 255, V[1] = S[h++] / 255, V[2] = S[h++] / 255, V[3] = S[h++] / 255, T[C] = V; + } + } + return v; + } + getPixels(i) { + let [u, x2] = this.output; + return i ? l.flipPixels(this._imageData.data, u, x2) : this._imageData.data.slice(0); + } + _imageTo3DArray(i) { + let u = new Array(i.length); + for (let x2 = 0; x2 < i.length; x2++) + u[x2] = this._mediaTo2DArray(i[x2]); + return u; + } + _resultKernelHeader() { + if (this.graphical || this.immutable || !this.pipeline) + return ""; + switch (this.output.length) { + case 1: + return this._mutableKernel1DResults(); + case 2: + return this._mutableKernel2DResults(); + case 3: + return this._mutableKernel3DResults(); + } + } + _resultKernelBody(i) { + switch (this.output.length) { + case 1: + return (!this.immutable && this.pipeline ? this._resultMutableKernel1DLoop(i) : this._resultImmutableKernel1DLoop(i)) + this._kernelOutput(); + case 2: + return (!this.immutable && this.pipeline ? this._resultMutableKernel2DLoop(i) : this._resultImmutableKernel2DLoop(i)) + this._kernelOutput(); + case 3: + return (!this.immutable && this.pipeline ? this._resultMutableKernel3DLoop(i) : this._resultImmutableKernel3DLoop(i)) + this._kernelOutput(); + default: + throw new Error("unsupported size kernel"); + } + } + _graphicalKernelBody(i) { + switch (this.output.length) { + case 2: + return this._graphicalKernel2DLoop(i) + this._graphicalOutput(); + default: + throw new Error("unsupported size kernel"); + } + } + _graphicalOutput() { + return ` + this._imageData.data.set(this._colorData); + this.context.putImageData(this._imageData, 0, 0); + return;`; + } + _getKernelResultTypeConstructorString() { + switch (this.returnType) { + case "LiteralInteger": + case "Number": + case "Integer": + case "Float": + return "Float32Array"; + case "Array(2)": + case "Array(3)": + case "Array(4)": + return "Array"; + default: + if (this.graphical) + return "Float32Array"; + throw new Error(`unhandled returnType ${this.returnType}`); + } + } + _resultImmutableKernel1DLoop(i) { + let u = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const result = new ${u}(outputX); + ${this._mapSubKernels((x2) => `const result_${x2.name} = new ${u}(outputX); +`).join(" ")} + ${this._mapSubKernels((x2) => `let subKernelResult_${x2.name}; +`).join(" ")} + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + this.thread.y = 0; + this.thread.z = 0; + ${i} + }`; + } + _mutableKernel1DResults() { + let i = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const result = new ${i}(outputX); + ${this._mapSubKernels((u) => `const result_${u.name} = new ${i}(outputX); +`).join(" ")} + ${this._mapSubKernels((u) => `let subKernelResult_${u.name}; +`).join(" ")}`; + } + _resultMutableKernel1DLoop(i) { + return ` const outputX = _this.output[0]; + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + this.thread.y = 0; + this.thread.z = 0; + ${i} + }`; + } + _resultImmutableKernel2DLoop(i) { + let u = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + const result = new Array(outputY); + ${this._mapSubKernels((x2) => `const result_${x2.name} = new Array(outputY); +`).join(" ")} + ${this._mapSubKernels((x2) => `let subKernelResult_${x2.name}; +`).join(" ")} + for (let y = 0; y < outputY; y++) { + this.thread.z = 0; + this.thread.y = y; + const resultX = result[y] = new ${u}(outputX); + ${this._mapSubKernels((x2) => `const resultX_${x2.name} = result_${x2.name}[y] = new ${u}(outputX); +`).join("")} + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + ${i} + } + }`; + } + _mutableKernel2DResults() { + let i = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + const result = new Array(outputY); + ${this._mapSubKernels((u) => `const result_${u.name} = new Array(outputY); +`).join(" ")} + ${this._mapSubKernels((u) => `let subKernelResult_${u.name}; +`).join(" ")} + for (let y = 0; y < outputY; y++) { + const resultX = result[y] = new ${i}(outputX); + ${this._mapSubKernels((u) => `const resultX_${u.name} = result_${u.name}[y] = new ${i}(outputX); +`).join("")} + }`; + } + _resultMutableKernel2DLoop(i) { + let u = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + for (let y = 0; y < outputY; y++) { + this.thread.z = 0; + this.thread.y = y; + const resultX = result[y]; + ${this._mapSubKernels((x2) => `const resultX_${x2.name} = result_${x2.name}[y] = new ${u}(outputX); +`).join("")} + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + ${i} + } + }`; + } + _graphicalKernel2DLoop(i) { + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + for (let y = 0; y < outputY; y++) { + this.thread.z = 0; + this.thread.y = y; + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + ${i} + } + }`; + } + _resultImmutableKernel3DLoop(i) { + let u = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + const outputZ = _this.output[2]; + const result = new Array(outputZ); + ${this._mapSubKernels((x2) => `const result_${x2.name} = new Array(outputZ); +`).join(" ")} + ${this._mapSubKernels((x2) => `let subKernelResult_${x2.name}; +`).join(" ")} + for (let z = 0; z < outputZ; z++) { + this.thread.z = z; + const resultY = result[z] = new Array(outputY); + ${this._mapSubKernels((x2) => `const resultY_${x2.name} = result_${x2.name}[z] = new Array(outputY); +`).join(" ")} + for (let y = 0; y < outputY; y++) { + this.thread.y = y; + const resultX = resultY[y] = new ${u}(outputX); + ${this._mapSubKernels((x2) => `const resultX_${x2.name} = resultY_${x2.name}[y] = new ${u}(outputX); +`).join(" ")} + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + ${i} + } + } + }`; + } + _mutableKernel3DResults() { + let i = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + const outputZ = _this.output[2]; + const result = new Array(outputZ); + ${this._mapSubKernels((u) => `const result_${u.name} = new Array(outputZ); +`).join(" ")} + ${this._mapSubKernels((u) => `let subKernelResult_${u.name}; +`).join(" ")} + for (let z = 0; z < outputZ; z++) { + const resultY = result[z] = new Array(outputY); + ${this._mapSubKernels((u) => `const resultY_${u.name} = result_${u.name}[z] = new Array(outputY); +`).join(" ")} + for (let y = 0; y < outputY; y++) { + const resultX = resultY[y] = new ${i}(outputX); + ${this._mapSubKernels((u) => `const resultX_${u.name} = resultY_${u.name}[y] = new ${i}(outputX); +`).join(" ")} + } + }`; + } + _resultMutableKernel3DLoop(i) { + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + const outputZ = _this.output[2]; + for (let z = 0; z < outputZ; z++) { + this.thread.z = z; + const resultY = result[z]; + for (let y = 0; y < outputY; y++) { + this.thread.y = y; + const resultX = resultY[y]; + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + ${i} + } + } + }`; + } + _kernelOutput() { + return this.subKernels ? ` + return { + result: result, + ${this.subKernels.map((i) => `${i.property}: result_${i.name}`).join(`, + `)} + };` : ` + return result;`; + } + _mapSubKernels(i) { + return this.subKernels === null ? [""] : this.subKernels.map(i); + } + destroy(i) { + i && delete this.canvas; + } + static destroyContext(i) { + } + toJSON() { + let i = super.toJSON(); + return i.functionNodes = g.fromKernel(this, f).toJSON(), i; + } + setOutput(i) { + super.setOutput(i); + let [u, x2] = this.output; + this.graphical && (this._imageData = this.context.createImageData(u, x2), this._colorData = new Uint8ClampedArray(u * x2 * 4)); + } + prependString(i) { + if (this._kernelString) + throw new Error("Kernel already built"); + this._prependedString.push(i); + } + hasPrependString(i) { + return this._prependedString.indexOf(i) > -1; + } + } + y.exports = { CPUKernel: s }; + }, { "../../utils": 114, "../function-builder": 9, "../kernel": 36, "./function-node": 6, "./kernel-string": 7 }], 9: [function(o, y, E) { + class p { + static fromKernel(f, l, n) { + let { kernelArguments: s, kernelConstants: t, argumentNames: i, argumentSizes: u, argumentBitRatios: x2, constants: w, constantBitRatios: m, debug: S, loopMaxIterations: v, nativeFunctions: h, output: b, optimizeFloatMemory: T, precision: C, plugins: V, source: c, subKernels: a, functions: k, leadingReturnStatement: A, followingReturnStatement: N, dynamicArguments: F, dynamicOutput: R } = f, K = new Array(s.length), O = {}; + for (let te = 0; te < s.length; te++) + K[te] = s[te].type; + for (let te = 0; te < t.length; te++) { + let re = t[te]; + O[re.name] = re.type; + } + let X = (te, re) => pe.needsArgumentType(te, re), B = (te, re, de) => { + pe.assignArgumentType(te, re, de); + }, P = (te, re, de) => pe.lookupReturnType(te, re, de), Y = (te) => pe.lookupFunctionArgumentTypes(te), J = (te, re) => pe.lookupFunctionArgumentName(te, re), q = (te, re) => pe.lookupFunctionArgumentBitRatio(te, re), j = (te, re, de, Te) => { + pe.assignArgumentType(te, re, de, Te); + }, U = (te, re, de, Te) => { + pe.assignArgumentBitRatio(te, re, de, Te); + }, oe = (te, re, de) => { + pe.trackFunctionCall(te, re, de); + }, Z = (te, re) => { + let de = []; + for (let Se = 0; Se < te.params.length; Se++) + de.push(te.params[Se].name); + let Te = new l(re, Object.assign({}, ee, { returnType: null, ast: te, name: te.id.name, argumentNames: de, lookupReturnType: P, lookupFunctionArgumentTypes: Y, lookupFunctionArgumentName: J, lookupFunctionArgumentBitRatio: q, needsArgumentType: X, assignArgumentType: B, triggerImplyArgumentType: j, triggerImplyArgumentBitRatio: U, onFunctionCall: oe })); + Te.traceFunctionAST(te), pe.addFunctionNode(Te); + }, ee = Object.assign({ isRootKernel: false, onNestedFunction: Z, lookupReturnType: P, lookupFunctionArgumentTypes: Y, lookupFunctionArgumentName: J, lookupFunctionArgumentBitRatio: q, needsArgumentType: X, assignArgumentType: B, triggerImplyArgumentType: j, triggerImplyArgumentBitRatio: U, onFunctionCall: oe, optimizeFloatMemory: T, precision: C, constants: w, constantTypes: O, constantBitRatios: m, debug: S, loopMaxIterations: v, output: b, plugins: V, dynamicArguments: F, dynamicOutput: R }, n || {}), be = Object.assign({}, ee, { isRootKernel: true, name: "kernel", argumentNames: i, argumentTypes: K, argumentSizes: u, argumentBitRatios: x2, leadingReturnStatement: A, followingReturnStatement: N }); + if (typeof c == "object" && c.functionNodes) + return new p().fromJSON(c.functionNodes, l); + let Q = new l(c, be), ue = null; + k && (ue = k.map((te) => new l(te.source, { returnType: te.returnType, argumentTypes: te.argumentTypes, output: b, plugins: V, constants: w, constantTypes: O, constantBitRatios: m, optimizeFloatMemory: T, precision: C, lookupReturnType: P, lookupFunctionArgumentTypes: Y, lookupFunctionArgumentName: J, lookupFunctionArgumentBitRatio: q, needsArgumentType: X, assignArgumentType: B, triggerImplyArgumentType: j, triggerImplyArgumentBitRatio: U, onFunctionCall: oe, onNestedFunction: Z }))); + let he = null; + a && (he = a.map((te) => { + let { name: re, source: de } = te; + return new l(de, Object.assign({}, ee, { name: re, isSubKernel: true, isRootKernel: false })); + })); + let pe = new p({ kernel: f, rootNode: Q, functionNodes: ue, nativeFunctions: h, subKernelNodes: he }); + return pe; + } + constructor(f) { + if (f = f || {}, this.kernel = f.kernel, this.rootNode = f.rootNode, this.functionNodes = f.functionNodes || [], this.subKernelNodes = f.subKernelNodes || [], this.nativeFunctions = f.nativeFunctions || [], this.functionMap = {}, this.nativeFunctionNames = [], this.lookupChain = [], this.functionNodeDependencies = {}, this.functionCalls = {}, this.rootNode && (this.functionMap.kernel = this.rootNode), this.functionNodes) + for (let l = 0; l < this.functionNodes.length; l++) + this.functionMap[this.functionNodes[l].name] = this.functionNodes[l]; + if (this.subKernelNodes) + for (let l = 0; l < this.subKernelNodes.length; l++) + this.functionMap[this.subKernelNodes[l].name] = this.subKernelNodes[l]; + if (this.nativeFunctions) + for (let l = 0; l < this.nativeFunctions.length; l++) { + let n = this.nativeFunctions[l]; + this.nativeFunctionNames.push(n.name); + } + } + addFunctionNode(f) { + if (!f.name) + throw new Error("functionNode.name needs set"); + this.functionMap[f.name] = f, f.isRootKernel && (this.rootNode = f); + } + traceFunctionCalls(f, l) { + if (f = f || "kernel", l = l || [], this.nativeFunctionNames.indexOf(f) > -1) { + let s = l.indexOf(f); + if (s === -1) + l.push(f); + else { + let t = l.splice(s, 1)[0]; + l.push(t); + } + return l; + } + let n = this.functionMap[f]; + if (n) { + let s = l.indexOf(f); + if (s === -1) { + l.push(f), n.toString(); + for (let t = 0; t < n.calledFunctions.length; ++t) + this.traceFunctionCalls(n.calledFunctions[t], l); + } else { + let t = l.splice(s, 1)[0]; + l.push(t); + } + } + return l; + } + getPrototypeString(f) { + return this.getPrototypes(f).join(` +`); + } + getPrototypes(f) { + return this.rootNode && this.rootNode.toString(), f ? this.getPrototypesFromFunctionNames(this.traceFunctionCalls(f, []).reverse()) : this.getPrototypesFromFunctionNames(Object.keys(this.functionMap)); + } + getStringFromFunctionNames(f) { + let l = []; + for (let n = 0; n < f.length; ++n) + this.functionMap[f[n]] && l.push(this.functionMap[f[n]].toString()); + return l.join(` +`); + } + getPrototypesFromFunctionNames(f) { + let l = []; + for (let n = 0; n < f.length; ++n) { + let s = f[n], t = this.nativeFunctionNames.indexOf(s); + if (t > -1) { + l.push(this.nativeFunctions[t].source); + continue; + } + let i = this.functionMap[s]; + i && l.push(i.toString()); + } + return l; + } + toJSON() { + return this.traceFunctionCalls(this.rootNode.name).reverse().map((f) => { + let l = this.nativeFunctions.indexOf(f); + if (l > -1) + return { name: f, source: this.nativeFunctions[l].source }; + if (this.functionMap[f]) + return this.functionMap[f].toJSON(); + throw new Error(`function ${f} not found`); + }); + } + fromJSON(f, l) { + this.functionMap = {}; + for (let n = 0; n < f.length; n++) { + let s = f[n]; + this.functionMap[s.settings.name] = new l(s.ast, s.settings); + } + return this; + } + getString(f) { + return f ? this.getStringFromFunctionNames(this.traceFunctionCalls(f).reverse()) : this.getStringFromFunctionNames(Object.keys(this.functionMap)); + } + lookupReturnType(f, l, n) { + if (l.type !== "CallExpression") + throw new Error(`expected ast type of "CallExpression", but is ${l.type}`); + if (this._isNativeFunction(f)) + return this._lookupNativeFunctionReturnType(f); + if (this._isFunction(f)) { + let s = this._getFunction(f); + if (s.returnType) + return s.returnType; + { + for (let i = 0; i < this.lookupChain.length; i++) + if (this.lookupChain[i].ast === l) { + if (s.argumentTypes.length === 0 && l.arguments.length > 0) { + let u = l.arguments; + for (let x2 = 0; x2 < u.length; x2++) + this.lookupChain.push({ name: n.name, ast: u[i], requestingNode: n }), s.argumentTypes[x2] = n.getType(u[x2]), this.lookupChain.pop(); + return s.returnType = s.getType(s.getJsAST()); + } + throw new Error("circlical logic detected!"); + } + this.lookupChain.push({ name: n.name, ast: l, requestingNode: n }); + let t = s.getType(s.getJsAST()); + return this.lookupChain.pop(), s.returnType = t; + } + } + return null; + } + _getFunction(f) { + return this._isFunction(f) || new Error(`Function ${f} not found`), this.functionMap[f]; + } + _isFunction(f) { + return Boolean(this.functionMap[f]); + } + _getNativeFunction(f) { + for (let l = 0; l < this.nativeFunctions.length; l++) + if (this.nativeFunctions[l].name === f) + return this.nativeFunctions[l]; + return null; + } + _isNativeFunction(f) { + return Boolean(this._getNativeFunction(f)); + } + _lookupNativeFunctionReturnType(f) { + let l = this._getNativeFunction(f); + if (l) + return l.returnType; + throw new Error(`Native function ${f} not found`); + } + lookupFunctionArgumentTypes(f) { + return this._isNativeFunction(f) ? this._getNativeFunction(f).argumentTypes : this._isFunction(f) ? this._getFunction(f).argumentTypes : null; + } + lookupFunctionArgumentName(f, l) { + return this._getFunction(f).argumentNames[l]; + } + lookupFunctionArgumentBitRatio(f, l) { + if (!this._isFunction(f)) + throw new Error("function not found"); + if (this.rootNode.name === f) { + let i = this.rootNode.argumentNames.indexOf(l); + if (i !== -1) + return this.rootNode.argumentBitRatios[i]; + } + let n = this._getFunction(f), s = n.argumentNames.indexOf(l); + if (s === -1) + throw new Error("argument not found"); + let t = n.argumentBitRatios[s]; + if (typeof t != "number") + throw new Error("argument bit ratio not found"); + return t; + } + needsArgumentType(f, l) { + return this._isFunction(f) ? !this._getFunction(f).argumentTypes[l] : false; + } + assignArgumentType(f, l, n, s) { + if (!this._isFunction(f)) + return; + let t = this._getFunction(f); + t.argumentTypes[l] || (t.argumentTypes[l] = n); + } + assignArgumentBitRatio(f, l, n, s) { + let t = this._getFunction(f); + if (this._isNativeFunction(n)) + return null; + let i = this._getFunction(n), u = t.argumentNames.indexOf(l); + if (u === -1) + throw new Error(`Argument ${l} not found in arguments from function ${f}`); + let x2 = t.argumentBitRatios[u]; + if (typeof x2 != "number") + throw new Error(`Bit ratio for argument ${l} not found in function ${f}`); + i.argumentBitRatios || (i.argumentBitRatios = new Array(i.argumentNames.length)); + let w = i.argumentBitRatios[u]; + if (typeof w == "number") { + if (w !== x2) + throw new Error(`Incompatible bit ratio found at function ${f} at argument ${l}`); + return w; + } + return i.argumentBitRatios[u] = x2, x2; + } + trackFunctionCall(f, l, n) { + this.functionNodeDependencies[f] || (this.functionNodeDependencies[f] = /* @__PURE__ */ new Set(), this.functionCalls[f] = []), this.functionNodeDependencies[f].add(l), this.functionCalls[f].push(n); + } + getKernelResultType() { + return this.rootNode.returnType || this.rootNode.getType(this.rootNode.ast); + } + getSubKernelResultType(f) { + let l = this.subKernelNodes[f], n = false; + for (let s = 0; s < this.rootNode.functionCalls.length; s++) + this.rootNode.functionCalls[s].ast.callee.name === l.name && (n = true); + if (!n) + throw new Error(`SubKernel ${l.name} never called by kernel`); + return l.returnType || l.getType(l.getJsAST()); + } + getReturnTypes() { + let f = { [this.rootNode.name]: this.rootNode.getType(this.rootNode.ast) }, l = this.traceFunctionCalls(this.rootNode.name); + for (let n = 0; n < l.length; n++) { + let s = l[n], t = this.functionMap[s]; + f[s] = t.getType(t.ast); + } + return f; + } + } + y.exports = { FunctionBuilder: p }; + }, {}], 10: [function(o, y, E) { + let p = o("acorn"), { utils: g } = o("../utils"), { FunctionTracer: f } = o("./function-tracer"); + class l { + constructor(t, i) { + if (!t && !i.ast) + throw new Error("source parameter is missing"); + if (i = i || {}, this.source = t, this.ast = null, this.name = typeof t == "string" ? i.isRootKernel ? "kernel" : i.name || g.getFunctionNameFromString(t) : null, this.calledFunctions = [], this.constants = {}, this.constantTypes = {}, this.constantBitRatios = {}, this.isRootKernel = false, this.isSubKernel = false, this.debug = null, this.functions = null, this.identifiers = null, this.contexts = null, this.functionCalls = null, this.states = [], this.needsArgumentType = null, this.assignArgumentType = null, this.lookupReturnType = null, this.lookupFunctionArgumentTypes = null, this.lookupFunctionArgumentBitRatio = null, this.triggerImplyArgumentType = null, this.triggerImplyArgumentBitRatio = null, this.onNestedFunction = null, this.onFunctionCall = null, this.optimizeFloatMemory = null, this.precision = null, this.loopMaxIterations = null, this.argumentNames = typeof this.source == "string" ? g.getArgumentNamesFromString(this.source) : null, this.argumentTypes = [], this.argumentSizes = [], this.argumentBitRatios = null, this.returnType = null, this.output = [], this.plugins = null, this.leadingReturnStatement = null, this.followingReturnStatement = null, this.dynamicOutput = null, this.dynamicArguments = null, this.strictTypingChecking = false, this.fixIntegerDivisionAccuracy = null, i) + for (let u in i) + !i.hasOwnProperty(u) || !this.hasOwnProperty(u) || (this[u] = i[u]); + this.literalTypes = {}, this.validate(), this._string = null, this._internalVariableNames = {}; + } + validate() { + if (typeof this.source != "string" && !this.ast) + throw new Error("this.source not a string"); + if (!this.ast && !g.isFunctionString(this.source)) + throw new Error("this.source not a function string"); + if (!this.name) + throw new Error("this.name could not be set"); + if (this.argumentTypes.length > 0 && this.argumentTypes.length !== this.argumentNames.length) + throw new Error(`argumentTypes count of ${this.argumentTypes.length} exceeds ${this.argumentNames.length}`); + if (this.output.length < 1) + throw new Error("this.output is not big enough"); + } + isIdentifierConstant(t) { + return this.constants ? this.constants.hasOwnProperty(t) : false; + } + isInput(t) { + return this.argumentTypes[this.argumentNames.indexOf(t)] === "Input"; + } + pushState(t) { + this.states.push(t); + } + popState(t) { + if (this.state !== t) + throw new Error(`Cannot popState ${t} when in ${this.state}`); + this.states.pop(); + } + isState(t) { + return this.state === t; + } + get state() { + return this.states[this.states.length - 1]; + } + astMemberExpressionUnroll(t) { + if (t.type === "Identifier") + return t.name; + if (t.type === "ThisExpression") + return "this"; + if (t.type === "MemberExpression" && t.object && t.property) + return t.object.hasOwnProperty("name") && t.object.name !== "Math" ? this.astMemberExpressionUnroll(t.property) : this.astMemberExpressionUnroll(t.object) + "." + this.astMemberExpressionUnroll(t.property); + if (t.hasOwnProperty("expressions")) { + let i = t.expressions[0]; + if (i.type === "Literal" && i.value === 0 && t.expressions.length === 2) + return this.astMemberExpressionUnroll(t.expressions[1]); + } + throw this.astErrorOutput("Unknown astMemberExpressionUnroll", t); + } + getJsAST(t) { + if (this.ast) + return this.ast; + if (typeof this.source == "object") + return this.traceFunctionAST(this.source), this.ast = this.source; + if (t = t || p, t === null) + throw new Error("Missing JS to AST parser"); + let i = Object.freeze(t.parse(`const parser_${this.name} = ${this.source};`, { locations: true })), u = i.body[0].declarations[0].init; + if (this.traceFunctionAST(u), !i) + throw new Error("Failed to parse JS code"); + return this.ast = u; + } + traceFunctionAST(t) { + let { contexts: i, declarations: u, functions: x2, identifiers: w, functionCalls: m } = new f(t); + this.contexts = i, this.identifiers = w, this.functionCalls = m, this.functions = x2; + for (let S = 0; S < u.length; S++) { + let v = u[S], { ast: h, inForLoopInit: b, inForLoopTest: T } = v, { init: C } = h, V = this.getDependencies(C), c = null; + if (b && T) + c = "Integer"; + else if (C) { + let a = this.getType(C); + switch (a) { + case "Integer": + case "Float": + case "Number": + C.type === "MemberExpression" ? c = a : c = "Number"; + break; + case "LiteralInteger": + c = "Number"; + break; + default: + c = a; + } + } + v.valueType = c, v.dependencies = V, v.isSafe = this.isSafeDependencies(V); + } + for (let S = 0; S < x2.length; S++) + this.onNestedFunction(x2[S], this.source); + } + getDeclaration(t) { + for (let i = 0; i < this.identifiers.length; i++) { + let u = this.identifiers[i]; + if (t === u.ast) + return u.declaration; + } + return null; + } + getVariableType(t) { + if (t.type !== "Identifier") + throw new Error(`ast of ${t.type} not "Identifier"`); + let i = null, u = this.argumentNames.indexOf(t.name); + if (u === -1) { + let x2 = this.getDeclaration(t); + if (x2) + return x2.valueType; + } else { + let x2 = this.argumentTypes[u]; + x2 && (i = x2); + } + if (!i && this.strictTypingChecking) + throw new Error(`Declaration of ${name} not found`); + return i; + } + getLookupType(t) { + if (!n.hasOwnProperty(t)) + throw new Error(`unknown typeLookupMap ${t}`); + return n[t]; + } + getConstantType(t) { + if (this.constantTypes[t]) { + let i = this.constantTypes[t]; + return i === "Float" ? "Number" : i; + } + throw new Error(`Type for constant "${t}" not declared`); + } + toString() { + return this._string ? this._string : this._string = this.astGeneric(this.getJsAST(), []).join("").trim(); + } + toJSON() { + let t = { source: this.source, name: this.name, constants: this.constants, constantTypes: this.constantTypes, isRootKernel: this.isRootKernel, isSubKernel: this.isSubKernel, debug: this.debug, output: this.output, loopMaxIterations: this.loopMaxIterations, argumentNames: this.argumentNames, argumentTypes: this.argumentTypes, argumentSizes: this.argumentSizes, returnType: this.returnType, leadingReturnStatement: this.leadingReturnStatement, followingReturnStatement: this.followingReturnStatement }; + return { ast: this.ast, settings: t }; + } + getType(t) { + if (Array.isArray(t)) + return this.getType(t[t.length - 1]); + switch (t.type) { + case "BlockStatement": + return this.getType(t.body); + case "ArrayExpression": + switch (this.getType(t.elements[0])) { + case "Array(2)": + case "Array(3)": + case "Array(4)": + return `Matrix(${t.elements.length})`; + } + return `Array(${t.elements.length})`; + case "Literal": + let u = this.astKey(t); + return this.literalTypes[u] ? this.literalTypes[u] : Number.isInteger(t.value) ? "LiteralInteger" : t.value === true || t.value === false ? "Boolean" : "Number"; + case "AssignmentExpression": + return this.getType(t.left); + case "CallExpression": + if (this.isAstMathFunction(t)) + return "Number"; + if (!t.callee || !t.callee.name) { + if (t.callee.type === "SequenceExpression" && t.callee.expressions[t.callee.expressions.length - 1].property.name) { + let v = t.callee.expressions[t.callee.expressions.length - 1].property.name; + return this.inferArgumentTypesIfNeeded(v, t.arguments), this.lookupReturnType(v, t, this); + } + if (this.getVariableSignature(t.callee, true) === "this.color") + return null; + if (t.callee.type === "MemberExpression" && t.callee.object && t.callee.property && t.callee.property.name && t.arguments) { + let v = t.callee.property.name; + return this.inferArgumentTypesIfNeeded(v, t.arguments), this.lookupReturnType(v, t, this); + } + throw this.astErrorOutput("Unknown call expression", t); + } + if (t.callee && t.callee.name) { + let v = t.callee.name; + return this.inferArgumentTypesIfNeeded(v, t.arguments), this.lookupReturnType(v, t, this); + } + throw this.astErrorOutput(`Unhandled getType Type "${t.type}"`, t); + case "LogicalExpression": + return "Boolean"; + case "BinaryExpression": + switch (t.operator) { + case "%": + case "/": + if (this.fixIntegerDivisionAccuracy) + return "Number"; + break; + case ">": + case "<": + return "Boolean"; + case "&": + case "|": + case "^": + case "<<": + case ">>": + case ">>>": + return "Integer"; + } + let x2 = this.getType(t.left); + if (this.isState("skip-literal-correction")) + return x2; + if (x2 === "LiteralInteger") { + let v = this.getType(t.right); + return v === "LiteralInteger" ? t.left.value % 1 === 0 ? "Integer" : "Float" : v; + } + return n[x2] || x2; + case "UpdateExpression": + return this.getType(t.argument); + case "UnaryExpression": + return t.operator === "~" ? "Integer" : this.getType(t.argument); + case "VariableDeclaration": { + let v = t.declarations, h; + for (let b = 0; b < v.length; b++) { + let T = v[b]; + h = this.getType(T); + } + if (!h) + throw this.astErrorOutput("Unable to find type for declaration", t); + return h; + } + case "VariableDeclarator": + let w = this.getDeclaration(t.id); + if (!w) + throw this.astErrorOutput("Unable to find declarator", t); + if (!w.valueType) + throw this.astErrorOutput("Unable to find declarator valueType", t); + return w.valueType; + case "Identifier": + if (t.name === "Infinity") + return "Number"; + if (this.isAstVariable(t) && this.getVariableSignature(t) === "value") + return this.getCheckVariableType(t); + let m = this.findIdentifierOrigin(t); + return m && m.init ? this.getType(m.init) : null; + case "ReturnStatement": + return this.getType(t.argument); + case "MemberExpression": + if (this.isAstMathFunction(t)) { + switch (t.property.name) { + case "ceil": + return "Integer"; + case "floor": + return "Integer"; + case "round": + return "Integer"; + } + return "Number"; + } + if (this.isAstVariable(t)) { + switch (this.getVariableSignature(t)) { + case "value[]": + return this.getLookupType(this.getCheckVariableType(t.object)); + case "value[][]": + return this.getLookupType(this.getCheckVariableType(t.object.object)); + case "value[][][]": + return this.getLookupType(this.getCheckVariableType(t.object.object.object)); + case "value[][][][]": + return this.getLookupType(this.getCheckVariableType(t.object.object.object.object)); + case "value.thread.value": + case "this.thread.value": + return "Integer"; + case "this.output.value": + return this.dynamicOutput ? "Integer" : "LiteralInteger"; + case "this.constants.value": + return this.getConstantType(t.property.name); + case "this.constants.value[]": + return this.getLookupType(this.getConstantType(t.object.property.name)); + case "this.constants.value[][]": + return this.getLookupType(this.getConstantType(t.object.object.property.name)); + case "this.constants.value[][][]": + return this.getLookupType(this.getConstantType(t.object.object.object.property.name)); + case "this.constants.value[][][][]": + return this.getLookupType(this.getConstantType(t.object.object.object.object.property.name)); + case "fn()[]": + case "fn()[][]": + case "fn()[][][]": + return this.getLookupType(this.getType(t.object)); + case "value.value": + if (this.isAstMathVariable(t)) + return "Number"; + switch (t.property.name) { + case "r": + case "g": + case "b": + case "a": + return this.getLookupType(this.getCheckVariableType(t.object)); + } + case "[][]": + return "Number"; + } + throw this.astErrorOutput("Unhandled getType MemberExpression", t); + } + throw this.astErrorOutput("Unhandled getType MemberExpression", t); + case "ConditionalExpression": + return this.getType(t.consequent); + case "FunctionDeclaration": + case "FunctionExpression": + let S = this.findLastReturn(t.body); + return S ? this.getType(S) : null; + case "IfStatement": + return this.getType(t.consequent); + case "SequenceExpression": + return this.getType(t.expressions[t.expressions.length - 1]); + default: + throw this.astErrorOutput(`Unhandled getType Type "${t.type}"`, t); + } + } + getCheckVariableType(t) { + let i = this.getVariableType(t); + if (!i) + throw this.astErrorOutput(`${t.type} is not defined`, t); + return i; + } + inferArgumentTypesIfNeeded(t, i) { + for (let u = 0; u < i.length; u++) { + if (!this.needsArgumentType(t, u)) + continue; + let x2 = this.getType(i[u]); + if (!x2) + throw this.astErrorOutput(`Unable to infer argument ${u}`, i[u]); + this.assignArgumentType(t, u, x2); + } + } + isAstMathVariable(t) { + let i = ["E", "PI", "SQRT2", "SQRT1_2", "LN2", "LN10", "LOG2E", "LOG10E"]; + return t.type === "MemberExpression" && t.object && t.object.type === "Identifier" && t.object.name === "Math" && t.property && t.property.type === "Identifier" && i.indexOf(t.property.name) > -1; + } + isAstMathFunction(t) { + let i = ["abs", "acos", "acosh", "asin", "asinh", "atan", "atan2", "atanh", "cbrt", "ceil", "clz32", "cos", "cosh", "expm1", "exp", "floor", "fround", "imul", "log", "log2", "log10", "log1p", "max", "min", "pow", "random", "round", "sign", "sin", "sinh", "sqrt", "tan", "tanh", "trunc"]; + return t.type === "CallExpression" && t.callee && t.callee.type === "MemberExpression" && t.callee.object && t.callee.object.type === "Identifier" && t.callee.object.name === "Math" && t.callee.property && t.callee.property.type === "Identifier" && i.indexOf(t.callee.property.name) > -1; + } + isAstVariable(t) { + return t.type === "Identifier" || t.type === "MemberExpression"; + } + isSafe(t) { + return this.isSafeDependencies(this.getDependencies(t)); + } + isSafeDependencies(t) { + return t && t.every ? t.every((i) => i.isSafe) : true; + } + getDependencies(t, i, u) { + if (i || (i = []), !t) + return null; + if (Array.isArray(t)) { + for (let x2 = 0; x2 < t.length; x2++) + this.getDependencies(t[x2], i, u); + return i; + } + switch (t.type) { + case "AssignmentExpression": + return this.getDependencies(t.left, i, u), this.getDependencies(t.right, i, u), i; + case "ConditionalExpression": + return this.getDependencies(t.test, i, u), this.getDependencies(t.alternate, i, u), this.getDependencies(t.consequent, i, u), i; + case "Literal": + i.push({ origin: "literal", value: t.value, isSafe: u === true ? false : t.value > -1 / 0 && t.value < 1 / 0 && !isNaN(t.value) }); + break; + case "VariableDeclarator": + return this.getDependencies(t.init, i, u); + case "Identifier": + let x2 = this.getDeclaration(t); + if (x2) + i.push({ name: t.name, origin: "declaration", isSafe: u ? false : this.isSafeDependencies(x2.dependencies) }); + else if (this.argumentNames.indexOf(t.name) > -1) + i.push({ name: t.name, origin: "argument", isSafe: false }); + else if (this.strictTypingChecking) + throw new Error(`Cannot find identifier origin "${t.name}"`); + break; + case "FunctionDeclaration": + return this.getDependencies(t.body.body[t.body.body.length - 1], i, u); + case "ReturnStatement": + return this.getDependencies(t.argument, i); + case "BinaryExpression": + case "LogicalExpression": + return u = t.operator === "/" || t.operator === "*", this.getDependencies(t.left, i, u), this.getDependencies(t.right, i, u), i; + case "UnaryExpression": + case "UpdateExpression": + return this.getDependencies(t.argument, i, u); + case "VariableDeclaration": + return this.getDependencies(t.declarations, i, u); + case "ArrayExpression": + return i.push({ origin: "declaration", isSafe: true }), i; + case "CallExpression": + return i.push({ origin: "function", isSafe: true }), i; + case "MemberExpression": + let w = this.getMemberExpressionDetails(t); + switch (w.signature) { + case "value[]": + this.getDependencies(t.object, i, u); + break; + case "value[][]": + this.getDependencies(t.object.object, i, u); + break; + case "value[][][]": + this.getDependencies(t.object.object.object, i, u); + break; + case "this.output.value": + this.dynamicOutput && i.push({ name: w.name, origin: "output", isSafe: false }); + break; + } + if (w) + return w.property && this.getDependencies(w.property, i, u), w.xProperty && this.getDependencies(w.xProperty, i, u), w.yProperty && this.getDependencies(w.yProperty, i, u), w.zProperty && this.getDependencies(w.zProperty, i, u), i; + case "SequenceExpression": + return this.getDependencies(t.expressions, i, u); + default: + throw this.astErrorOutput(`Unhandled type ${t.type} in getDependencies`, t); + } + return i; + } + getVariableSignature(t, i) { + if (!this.isAstVariable(t)) + throw new Error(`ast of type "${t.type}" is not a variable signature`); + if (t.type === "Identifier") + return "value"; + let u = []; + for (; t; ) + t.computed ? u.push("[]") : t.type === "ThisExpression" ? u.unshift("this") : t.property && t.property.name ? t.property.name === "x" || t.property.name === "y" || t.property.name === "z" ? u.unshift(i ? "." + t.property.name : ".value") : t.property.name === "constants" || t.property.name === "thread" || t.property.name === "output" ? u.unshift("." + t.property.name) : u.unshift(i ? "." + t.property.name : ".value") : t.name ? u.unshift(i ? t.name : "value") : t.callee && t.callee.name ? u.unshift(i ? t.callee.name + "()" : "fn()") : t.elements ? u.unshift("[]") : u.unshift("unknown"), t = t.object; + let x2 = u.join(""); + return i || ["value", "value[]", "value[][]", "value[][][]", "value[][][][]", "value.value", "value.thread.value", "this.thread.value", "this.output.value", "this.constants.value", "this.constants.value[]", "this.constants.value[][]", "this.constants.value[][][]", "this.constants.value[][][][]", "fn()[]", "fn()[][]", "fn()[][][]", "[][]"].indexOf(x2) > -1 ? x2 : null; + } + build() { + return this.toString().length > 0; + } + astGeneric(t, i) { + if (t === null) + throw this.astErrorOutput("NULL ast", t); + if (Array.isArray(t)) { + for (let u = 0; u < t.length; u++) + this.astGeneric(t[u], i); + return i; + } + switch (t.type) { + case "FunctionDeclaration": + return this.astFunctionDeclaration(t, i); + case "FunctionExpression": + return this.astFunctionExpression(t, i); + case "ReturnStatement": + return this.astReturnStatement(t, i); + case "Literal": + return this.astLiteral(t, i); + case "BinaryExpression": + return this.astBinaryExpression(t, i); + case "Identifier": + return this.astIdentifierExpression(t, i); + case "AssignmentExpression": + return this.astAssignmentExpression(t, i); + case "ExpressionStatement": + return this.astExpressionStatement(t, i); + case "EmptyStatement": + return this.astEmptyStatement(t, i); + case "BlockStatement": + return this.astBlockStatement(t, i); + case "IfStatement": + return this.astIfStatement(t, i); + case "SwitchStatement": + return this.astSwitchStatement(t, i); + case "BreakStatement": + return this.astBreakStatement(t, i); + case "ContinueStatement": + return this.astContinueStatement(t, i); + case "ForStatement": + return this.astForStatement(t, i); + case "WhileStatement": + return this.astWhileStatement(t, i); + case "DoWhileStatement": + return this.astDoWhileStatement(t, i); + case "VariableDeclaration": + return this.astVariableDeclaration(t, i); + case "VariableDeclarator": + return this.astVariableDeclarator(t, i); + case "ThisExpression": + return this.astThisExpression(t, i); + case "SequenceExpression": + return this.astSequenceExpression(t, i); + case "UnaryExpression": + return this.astUnaryExpression(t, i); + case "UpdateExpression": + return this.astUpdateExpression(t, i); + case "LogicalExpression": + return this.astLogicalExpression(t, i); + case "MemberExpression": + return this.astMemberExpression(t, i); + case "CallExpression": + return this.astCallExpression(t, i); + case "ArrayExpression": + return this.astArrayExpression(t, i); + case "DebuggerStatement": + return this.astDebuggerStatement(t, i); + case "ConditionalExpression": + return this.astConditionalExpression(t, i); + } + throw this.astErrorOutput("Unknown ast type : " + t.type, t); + } + astErrorOutput(t, i) { + if (typeof this.source != "string") + return new Error(t); + let u = g.getAstString(this.source, i), w = this.source.substr(i.start).split(/\n/), m = w.length > 0 ? w[w.length - 1] : 0; + return new Error(`${t} on line ${w.length}, position ${m.length}: + ${u}`); + } + astDebuggerStatement(t, i) { + return i; + } + astConditionalExpression(t, i) { + if (t.type !== "ConditionalExpression") + throw this.astErrorOutput("Not a conditional expression", t); + return i.push("("), this.astGeneric(t.test, i), i.push("?"), this.astGeneric(t.consequent, i), i.push(":"), this.astGeneric(t.alternate, i), i.push(")"), i; + } + astFunction(t, i) { + throw new Error(`"astFunction" not defined on ${this.constructor.name}`); + } + astFunctionDeclaration(t, i) { + return this.isChildFunction(t) ? i : this.astFunction(t, i); + } + astFunctionExpression(t, i) { + return this.isChildFunction(t) ? i : this.astFunction(t, i); + } + isChildFunction(t) { + for (let i = 0; i < this.functions.length; i++) + if (this.functions[i] === t) + return true; + return false; + } + astReturnStatement(t, i) { + return i; + } + astLiteral(t, i) { + return this.literalTypes[this.astKey(t)] = "Number", i; + } + astBinaryExpression(t, i) { + return i; + } + astIdentifierExpression(t, i) { + return i; + } + astAssignmentExpression(t, i) { + return i; + } + astExpressionStatement(t, i) { + return this.astGeneric(t.expression, i), i.push(";"), i; + } + astEmptyStatement(t, i) { + return i; + } + astBlockStatement(t, i) { + return i; + } + astIfStatement(t, i) { + return i; + } + astSwitchStatement(t, i) { + return i; + } + astBreakStatement(t, i) { + return i.push("break;"), i; + } + astContinueStatement(t, i) { + return i.push(`continue; +`), i; + } + astForStatement(t, i) { + return i; + } + astWhileStatement(t, i) { + return i; + } + astDoWhileStatement(t, i) { + return i; + } + astVariableDeclarator(t, i) { + return this.astGeneric(t.id, i), t.init !== null && (i.push("="), this.astGeneric(t.init, i)), i; + } + astThisExpression(t, i) { + return i; + } + astSequenceExpression(t, i) { + let { expressions: u } = t, x2 = []; + for (let w = 0; w < u.length; w++) { + let m = u[w], S = []; + this.astGeneric(m, S), x2.push(S.join("")); + } + return x2.length > 1 ? i.push("(", x2.join(","), ")") : i.push(x2[0]), i; + } + astUnaryExpression(t, i) { + return this.checkAndUpconvertBitwiseUnary(t, i) || (t.prefix ? (i.push(t.operator), this.astGeneric(t.argument, i)) : (this.astGeneric(t.argument, i), i.push(t.operator))), i; + } + checkAndUpconvertBitwiseUnary(t, i) { + } + astUpdateExpression(t, i) { + return t.prefix ? (i.push(t.operator), this.astGeneric(t.argument, i)) : (this.astGeneric(t.argument, i), i.push(t.operator)), i; + } + astLogicalExpression(t, i) { + return i.push("("), this.astGeneric(t.left, i), i.push(t.operator), this.astGeneric(t.right, i), i.push(")"), i; + } + astMemberExpression(t, i) { + return i; + } + astCallExpression(t, i) { + return i; + } + astArrayExpression(t, i) { + return i; + } + getMemberExpressionDetails(t) { + if (t.type !== "MemberExpression") + throw this.astErrorOutput(`Expression ${t.type} not a MemberExpression`, t); + let i = null, u = null, x2 = this.getVariableSignature(t); + switch (x2) { + case "value": + return null; + case "value.thread.value": + case "this.thread.value": + case "this.output.value": + return { signature: x2, type: "Integer", name: t.property.name }; + case "value[]": + if (typeof t.object.name != "string") + throw this.astErrorOutput("Unexpected expression", t); + return i = t.object.name, { name: i, origin: "user", signature: x2, type: this.getVariableType(t.object), xProperty: t.property }; + case "value[][]": + if (typeof t.object.object.name != "string") + throw this.astErrorOutput("Unexpected expression", t); + return i = t.object.object.name, { name: i, origin: "user", signature: x2, type: this.getVariableType(t.object.object), yProperty: t.object.property, xProperty: t.property }; + case "value[][][]": + if (typeof t.object.object.object.name != "string") + throw this.astErrorOutput("Unexpected expression", t); + return i = t.object.object.object.name, { name: i, origin: "user", signature: x2, type: this.getVariableType(t.object.object.object), zProperty: t.object.object.property, yProperty: t.object.property, xProperty: t.property }; + case "value[][][][]": + if (typeof t.object.object.object.object.name != "string") + throw this.astErrorOutput("Unexpected expression", t); + return i = t.object.object.object.object.name, { name: i, origin: "user", signature: x2, type: this.getVariableType(t.object.object.object.object), zProperty: t.object.object.property, yProperty: t.object.property, xProperty: t.property }; + case "value.value": + if (typeof t.property.name != "string") + throw this.astErrorOutput("Unexpected expression", t); + if (this.isAstMathVariable(t)) + return i = t.property.name, { name: i, origin: "Math", type: "Number", signature: x2 }; + switch (t.property.name) { + case "r": + case "g": + case "b": + case "a": + return i = t.object.name, { name: i, property: t.property.name, origin: "user", signature: x2, type: "Number" }; + default: + throw this.astErrorOutput("Unexpected expression", t); + } + case "this.constants.value": + if (typeof t.property.name != "string") + throw this.astErrorOutput("Unexpected expression", t); + if (i = t.property.name, u = this.getConstantType(i), !u) + throw this.astErrorOutput("Constant has no type", t); + return { name: i, type: u, origin: "constants", signature: x2 }; + case "this.constants.value[]": + if (typeof t.object.property.name != "string") + throw this.astErrorOutput("Unexpected expression", t); + if (i = t.object.property.name, u = this.getConstantType(i), !u) + throw this.astErrorOutput("Constant has no type", t); + return { name: i, type: u, origin: "constants", signature: x2, xProperty: t.property }; + case "this.constants.value[][]": { + if (typeof t.object.object.property.name != "string") + throw this.astErrorOutput("Unexpected expression", t); + if (i = t.object.object.property.name, u = this.getConstantType(i), !u) + throw this.astErrorOutput("Constant has no type", t); + return { name: i, type: u, origin: "constants", signature: x2, yProperty: t.object.property, xProperty: t.property }; + } + case "this.constants.value[][][]": { + if (typeof t.object.object.object.property.name != "string") + throw this.astErrorOutput("Unexpected expression", t); + if (i = t.object.object.object.property.name, u = this.getConstantType(i), !u) + throw this.astErrorOutput("Constant has no type", t); + return { name: i, type: u, origin: "constants", signature: x2, zProperty: t.object.object.property, yProperty: t.object.property, xProperty: t.property }; + } + case "fn()[]": + case "fn()[][]": + case "[][]": + return { signature: x2, property: t.property }; + default: + throw this.astErrorOutput("Unexpected expression", t); + } + } + findIdentifierOrigin(t) { + let i = [this.ast]; + for (; i.length > 0; ) { + let u = i[0]; + if (u.type === "VariableDeclarator" && u.id && u.id.name && u.id.name === t.name) + return u; + if (i.shift(), u.argument) + i.push(u.argument); + else if (u.body) + i.push(u.body); + else if (u.declarations) + i.push(u.declarations); + else if (Array.isArray(u)) + for (let x2 = 0; x2 < u.length; x2++) + i.push(u[x2]); + } + return null; + } + findLastReturn(t) { + let i = [t || this.ast]; + for (; i.length > 0; ) { + let u = i.pop(); + if (u.type === "ReturnStatement") + return u; + if (u.type !== "FunctionDeclaration") + if (u.argument) + i.push(u.argument); + else if (u.body) + i.push(u.body); + else if (u.declarations) + i.push(u.declarations); + else if (Array.isArray(u)) + for (let x2 = 0; x2 < u.length; x2++) + i.push(u[x2]); + else + u.consequent ? i.push(u.consequent) : u.cases && i.push(u.cases); + } + return null; + } + getInternalVariableName(t) { + return this._internalVariableNames.hasOwnProperty(t) || (this._internalVariableNames[t] = 0), this._internalVariableNames[t]++, this._internalVariableNames[t] === 1 ? t : t + this._internalVariableNames[t]; + } + astKey(t, i = ",") { + if (!t.start || !t.end) + throw new Error("AST start and end needed"); + return `${t.start}${i}${t.end}`; + } + } + let n = { Number: "Number", Float: "Float", Integer: "Integer", Array: "Number", "Array(2)": "Number", "Array(3)": "Number", "Array(4)": "Number", "Matrix(2)": "Number", "Matrix(3)": "Number", "Matrix(4)": "Number", Array2D: "Number", Array3D: "Number", Input: "Number", HTMLCanvas: "Array(4)", HTMLImage: "Array(4)", HTMLVideo: "Array(4)", HTMLImageArray: "Array(4)", NumberTexture: "Number", MemoryOptimizedNumberTexture: "Number", "Array1D(2)": "Array(2)", "Array1D(3)": "Array(3)", "Array1D(4)": "Array(4)", "Array2D(2)": "Array(2)", "Array2D(3)": "Array(3)", "Array2D(4)": "Array(4)", "Array3D(2)": "Array(2)", "Array3D(3)": "Array(3)", "Array3D(4)": "Array(4)", "ArrayTexture(1)": "Number", "ArrayTexture(2)": "Array(2)", "ArrayTexture(3)": "Array(3)", "ArrayTexture(4)": "Array(4)" }; + y.exports = { FunctionNode: l }; + }, { "../utils": 114, "./function-tracer": 11, acorn: 1 }], 11: [function(o, y, E) { + let { utils: p } = o("../utils"); + function g(n) { + return n.length > 0 ? n[n.length - 1] : null; + } + let f = { trackIdentifiers: "trackIdentifiers", memberExpression: "memberExpression", inForLoopInit: "inForLoopInit" }; + class l { + constructor(s) { + this.runningContexts = [], this.functionContexts = [], this.contexts = [], this.functionCalls = [], this.declarations = [], this.identifiers = [], this.functions = [], this.returnStatements = [], this.trackedIdentifiers = null, this.states = [], this.newFunctionContext(), this.scan(s); + } + isState(s) { + return this.states[this.states.length - 1] === s; + } + hasState(s) { + return this.states.indexOf(s) > -1; + } + pushState(s) { + this.states.push(s); + } + popState(s) { + if (this.isState(s)) + this.states.pop(); + else + throw new Error(`Cannot pop the non-active state "${s}"`); + } + get currentFunctionContext() { + return g(this.functionContexts); + } + get currentContext() { + return g(this.runningContexts); + } + newFunctionContext() { + let s = { "@contextType": "function" }; + this.contexts.push(s), this.functionContexts.push(s); + } + newContext(s) { + let t = Object.assign({ "@contextType": "const/let" }, this.currentContext); + this.contexts.push(t), this.runningContexts.push(t), s(); + let { currentFunctionContext: i } = this; + for (let u in i) + !i.hasOwnProperty(u) || t.hasOwnProperty(u) || (t[u] = i[u]); + return this.runningContexts.pop(), t; + } + useFunctionContext(s) { + let t = g(this.functionContexts); + this.runningContexts.push(t), s(), this.runningContexts.pop(); + } + getIdentifiers(s) { + let t = this.trackedIdentifiers = []; + return this.pushState(f.trackIdentifiers), s(), this.trackedIdentifiers = null, this.popState(f.trackIdentifiers), t; + } + getDeclaration(s) { + let { currentContext: t, currentFunctionContext: i, runningContexts: u } = this, x2 = t[s] || i[s] || null; + if (!x2 && t === i && u.length > 0) { + let w = u[u.length - 2]; + if (w[s]) + return w[s]; + } + return x2; + } + scan(s) { + if (!!s) { + if (Array.isArray(s)) { + for (let t = 0; t < s.length; t++) + this.scan(s[t]); + return; + } + switch (s.type) { + case "Program": + this.useFunctionContext(() => { + this.scan(s.body); + }); + break; + case "BlockStatement": + this.newContext(() => { + this.scan(s.body); + }); + break; + case "AssignmentExpression": + case "LogicalExpression": + this.scan(s.left), this.scan(s.right); + break; + case "BinaryExpression": + this.scan(s.left), this.scan(s.right); + break; + case "UpdateExpression": + if (s.operator === "++") { + let t = this.getDeclaration(s.argument.name); + t && (t.suggestedType = "Integer"); + } + this.scan(s.argument); + break; + case "UnaryExpression": + this.scan(s.argument); + break; + case "VariableDeclaration": + s.kind === "var" ? this.useFunctionContext(() => { + s.declarations = p.normalizeDeclarations(s), this.scan(s.declarations); + }) : (s.declarations = p.normalizeDeclarations(s), this.scan(s.declarations)); + break; + case "VariableDeclarator": { + let { currentContext: t } = this, i = this.hasState(f.inForLoopInit), u = { ast: s, context: t, name: s.id.name, origin: "declaration", inForLoopInit: i, inForLoopTest: null, assignable: t === this.currentFunctionContext || !i && !t.hasOwnProperty(s.id.name), suggestedType: null, valueType: null, dependencies: null, isSafe: null }; + t[s.id.name] || (t[s.id.name] = u), this.declarations.push(u), this.scan(s.id), this.scan(s.init); + break; + } + case "FunctionExpression": + case "FunctionDeclaration": + this.runningContexts.length === 0 ? this.scan(s.body) : this.functions.push(s); + break; + case "IfStatement": + this.scan(s.test), this.scan(s.consequent), s.alternate && this.scan(s.alternate); + break; + case "ForStatement": { + let t, i = this.newContext(() => { + this.pushState(f.inForLoopInit), this.scan(s.init), this.popState(f.inForLoopInit), t = this.getIdentifiers(() => { + this.scan(s.test); + }), this.scan(s.update), this.newContext(() => { + this.scan(s.body); + }); + }); + if (t) + for (let u in i) + u !== "@contextType" && t.indexOf(u) > -1 && (i[u].inForLoopTest = true); + break; + } + case "DoWhileStatement": + case "WhileStatement": + this.newContext(() => { + this.scan(s.body), this.scan(s.test); + }); + break; + case "Identifier": { + this.isState(f.trackIdentifiers) && this.trackedIdentifiers.push(s.name), this.identifiers.push({ context: this.currentContext, declaration: this.getDeclaration(s.name), ast: s }); + break; + } + case "ReturnStatement": + this.returnStatements.push(s), this.scan(s.argument); + break; + case "MemberExpression": + this.pushState(f.memberExpression), this.scan(s.object), this.scan(s.property), this.popState(f.memberExpression); + break; + case "ExpressionStatement": + this.scan(s.expression); + break; + case "SequenceExpression": + this.scan(s.expressions); + break; + case "CallExpression": + this.functionCalls.push({ context: this.currentContext, ast: s }), this.scan(s.arguments); + break; + case "ArrayExpression": + this.scan(s.elements); + break; + case "ConditionalExpression": + this.scan(s.test), this.scan(s.alternate), this.scan(s.consequent); + break; + case "SwitchStatement": + this.scan(s.discriminant), this.scan(s.cases); + break; + case "SwitchCase": + this.scan(s.test), this.scan(s.consequent); + break; + case "ThisExpression": + case "Literal": + case "DebuggerStatement": + case "EmptyStatement": + case "BreakStatement": + case "ContinueStatement": + break; + default: + throw new Error(`unhandled type "${s.type}"`); + } + } + } + } + y.exports = { FunctionTracer: l }; + }, { "../utils": 114 }], 12: [function(o, y, E) { + let { glWiretap: p } = o("gl-wiretap"), { utils: g } = o("../../utils"); + function f(u) { + return u.toString().replace("=>", "").replace(/^function /, "").replace(/utils[.]/g, "/*utils.*/"); + } + function l(u, x2, w, m, S) { + w.built || w.build.apply(w, x2), x2 = x2 ? Array.from(x2).map((Q) => { + switch (typeof Q) { + case "boolean": + return new Boolean(Q); + case "number": + return new Number(Q); + default: + return Q; + } + }) : null; + let v = [], h = [], b = p(w.context, { useTrackablePrimitives: true, onReadPixels: (Q) => { + if (Z.subKernels) { + if (!T) + h.push(` const result = { result: ${n(Q, Z)} };`), T = true; + else { + let ue = Z.subKernels[C++].property; + h.push(` result${isNaN(ue) ? "." + ue : `[${ue}]`} = ${n(Q, Z)};`); + } + C === Z.subKernels.length && h.push(" return result;"); + return; + } + Q ? h.push(` return ${n(Q, Z)};`) : h.push(" return null;"); + }, onUnrecognizedArgumentLookup: (Q) => { + let ue = i(Q, Z.kernelArguments, [], b, v); + if (ue) + return ue; + let he = i(Q, Z.kernelConstants, F ? Object.keys(F).map((pe) => F[pe]) : [], b, v); + return he || null; + } }), T = false, C = 0, { source: V, canvas: c, output: a, pipeline: k, graphical: A, loopMaxIterations: N, constants: F, optimizeFloatMemory: R, precision: K, fixIntegerDivisionAccuracy: O, functions: X, nativeFunctions: B, subKernels: P, immutable: Y, argumentTypes: J, constantTypes: q, kernelArguments: j, kernelConstants: U, tactic: oe } = w, Z = new u(V, { canvas: c, context: b, checkContext: false, output: a, pipeline: k, graphical: A, loopMaxIterations: N, constants: F, optimizeFloatMemory: R, precision: K, fixIntegerDivisionAccuracy: O, functions: X, nativeFunctions: B, subKernels: P, immutable: Y, argumentTypes: J, constantTypes: q, tactic: oe }), ee = []; + if (b.setIndent(2), Z.build.apply(Z, x2), ee.push(b.toString()), b.reset(), Z.kernelArguments.forEach((Q, ue) => { + switch (Q.type) { + case "Integer": + case "Boolean": + case "Number": + case "Float": + case "Array": + case "Array(2)": + case "Array(3)": + case "Array(4)": + case "HTMLCanvas": + case "HTMLImage": + case "HTMLVideo": + b.insertVariable(`uploadValue_${Q.name}`, Q.uploadValue); + break; + case "HTMLImageArray": + for (let he = 0; he < x2[ue].length; he++) { + let pe = x2[ue]; + b.insertVariable(`uploadValue_${Q.name}[${he}]`, pe[he]); + } + break; + case "Input": + b.insertVariable(`uploadValue_${Q.name}`, Q.uploadValue); + break; + case "MemoryOptimizedNumberTexture": + case "NumberTexture": + case "Array1D(2)": + case "Array1D(3)": + case "Array1D(4)": + case "Array2D(2)": + case "Array2D(3)": + case "Array2D(4)": + case "Array3D(2)": + case "Array3D(3)": + case "Array3D(4)": + case "ArrayTexture(1)": + case "ArrayTexture(2)": + case "ArrayTexture(3)": + case "ArrayTexture(4)": + b.insertVariable(`uploadValue_${Q.name}`, x2[ue].texture); + break; + default: + throw new Error(`unhandled kernelArgumentType insertion for glWiretap of type ${Q.type}`); + } + }), ee.push("/** start of injected functions **/"), ee.push(`function ${f(g.flattenTo)}`), ee.push(`function ${f(g.flatten2dArrayTo)}`), ee.push(`function ${f(g.flatten3dArrayTo)}`), ee.push(`function ${f(g.flatten4dArrayTo)}`), ee.push(`function ${f(g.isArray)}`), Z.renderOutput !== Z.renderTexture && Z.formatValues && ee.push(` const renderOutput = function ${f(Z.formatValues)};`), ee.push("/** end of injected functions **/"), ee.push(` const innerKernel = function (${Z.kernelArguments.map((Q) => Q.varName).join(", ")}) {`), b.setIndent(4), Z.run.apply(Z, x2), Z.renderKernels ? Z.renderKernels() : Z.renderOutput && Z.renderOutput(), ee.push(" /** start setup uploads for kernel values **/"), Z.kernelArguments.forEach((Q) => { + ee.push(" " + Q.getStringValueHandler().split(` +`).join(` + `)); + }), ee.push(" /** end setup uploads for kernel values **/"), ee.push(b.toString()), Z.renderOutput === Z.renderTexture) { + b.reset(); + let Q = b.getContextVariableName(Z.framebuffer); + if (Z.renderKernels) { + let ue = Z.renderKernels(), he = b.getContextVariableName(Z.texture.texture); + ee.push(` return { + result: { + texture: ${he}, + type: '${ue.result.type}', + toArray: ${t(ue.result, he, Q)} + },`); + let { subKernels: pe, mappedTextures: te } = Z; + for (let re = 0; re < pe.length; re++) { + let de = te[re], Te = pe[re], Se = ue[Te.property], Ce = b.getContextVariableName(de.texture); + ee.push(` + ${Te.property}: { + texture: ${Ce}, + type: '${Se.type}', + toArray: ${t(Se, Ce, Q)} + },`); + } + ee.push(" };"); + } else { + let ue = Z.renderOutput(), he = b.getContextVariableName(Z.texture.texture); + ee.push(` return { + texture: ${he}, + type: '${ue.type}', + toArray: ${t(ue, he, Q)} + };`); + } + } + ee.push(` ${S ? ` +` + S + " " : ""}`), ee.push(h.join(` +`)), ee.push(" };"), Z.graphical && (ee.push(s(Z)), ee.push(" innerKernel.getPixels = getPixels;")), ee.push(" return innerKernel;"); + let be = []; + return U.forEach((Q) => { + be.push(`${Q.getStringValueHandler()}`); + }), `function kernel(settings) { + const { context, constants } = settings; + ${be.join("")} + ${m || ""} + ${ee.join(` +`)} + }`; + } + function n(u, x2) { + let w = x2.precision === "single" ? u : `new Float32Array(${u}.buffer)`; + return x2.output[2] ? `renderOutput(${w}, ${x2.output[0]}, ${x2.output[1]}, ${x2.output[2]})` : x2.output[1] ? `renderOutput(${w}, ${x2.output[0]}, ${x2.output[1]})` : `renderOutput(${w}, ${x2.output[0]})`; + } + function s(u) { + let x2 = u.getPixels.toString(), w = !/^function/.test(x2); + return g.flattenFunctionToString(`${w ? "function " : ""}${x2}`, { findDependency: (m, S) => m === "utils" ? `const ${S} = ${g[S].toString()};` : null, thisLookup: (m) => { + if (m === "context") + return null; + if (u.hasOwnProperty(m)) + return JSON.stringify(u[m]); + throw new Error(`unhandled thisLookup ${m}`); + } }); + } + function t(u, x2, w) { + let m = u.toArray.toString(), S = !/^function/.test(m), v = g.flattenFunctionToString(`${S ? "function " : ""}${m}`, { findDependency: (h, b) => { + if (h === "utils") + return `const ${b} = ${g[b].toString()};`; + if (h === "this") + return b === "framebuffer" ? "" : `${S ? "function " : ""}${u[b].toString()}`; + throw new Error("unhandled fromObject"); + }, thisLookup: (h, b) => { + if (h === "texture") + return x2; + if (h === "context") + return b ? null : "gl"; + if (u.hasOwnProperty(h)) + return JSON.stringify(u[h]); + throw new Error(`unhandled thisLookup ${h}`); + } }); + return `() => { + function framebuffer() { return ${w}; }; + ${v} + return toArray(); + }`; + } + function i(u, x2, w, m, S) { + if (u === null || x2 === null) + return null; + switch (typeof u) { + case "boolean": + case "number": + return null; + } + if (typeof HTMLImageElement < "u" && u instanceof HTMLImageElement) + for (let v = 0; v < x2.length; v++) { + let h = x2[v]; + if (h.type !== "HTMLImageArray" && h || h.uploadValue !== u) + continue; + let b = w[v].indexOf(u); + if (b === -1) + continue; + let T = `uploadValue_${h.name}[${b}]`; + return m.insertVariable(T, u), T; + } + for (let v = 0; v < x2.length; v++) { + let h = x2[v]; + if (u !== h.uploadValue) + continue; + let b = `uploadValue_${h.name}`; + return m.insertVariable(b, h), b; + } + return null; + } + y.exports = { glKernelString: l }; + }, { "../../utils": 114, "gl-wiretap": 3 }], 13: [function(o, y, E) { + let { Kernel: p } = o("../kernel"), { utils: g } = o("../../utils"), { GLTextureArray2Float: f } = o("./texture/array-2-float"), { GLTextureArray2Float2D: l } = o("./texture/array-2-float-2d"), { GLTextureArray2Float3D: n } = o("./texture/array-2-float-3d"), { GLTextureArray3Float: s } = o("./texture/array-3-float"), { GLTextureArray3Float2D: t } = o("./texture/array-3-float-2d"), { GLTextureArray3Float3D: i } = o("./texture/array-3-float-3d"), { GLTextureArray4Float: u } = o("./texture/array-4-float"), { GLTextureArray4Float2D: x2 } = o("./texture/array-4-float-2d"), { GLTextureArray4Float3D: w } = o("./texture/array-4-float-3d"), { GLTextureFloat: m } = o("./texture/float"), { GLTextureFloat2D: S } = o("./texture/float-2d"), { GLTextureFloat3D: v } = o("./texture/float-3d"), { GLTextureMemoryOptimized: h } = o("./texture/memory-optimized"), { GLTextureMemoryOptimized2D: b } = o("./texture/memory-optimized-2d"), { GLTextureMemoryOptimized3D: T } = o("./texture/memory-optimized-3d"), { GLTextureUnsigned: C } = o("./texture/unsigned"), { GLTextureUnsigned2D: V } = o("./texture/unsigned-2d"), { GLTextureUnsigned3D: c } = o("./texture/unsigned-3d"), { GLTextureGraphical: a } = o("./texture/graphical"); + class k extends p { + static get mode() { + return "gpu"; + } + static getIsFloatRead() { + let F = `function kernelFunction() { + return 1; + }`, R = new this(F, { context: this.testContext, canvas: this.testCanvas, validate: false, output: [1], precision: "single", returnType: "Number", tactic: "speed" }); + R.build(), R.run(); + let K = R.renderOutput(); + return R.destroy(true), K[0] === 1; + } + static getIsIntegerDivisionAccurate() { + function F(X, B) { + return X[this.thread.x] / B[this.thread.x]; + } + let R = new this(F.toString(), { context: this.testContext, canvas: this.testCanvas, validate: false, output: [2], returnType: "Number", precision: "unsigned", tactic: "speed" }), K = [[6, 6030401], [3, 3991]]; + R.build.apply(R, K), R.run.apply(R, K); + let O = R.renderOutput(); + return R.destroy(true), O[0] === 2 && O[1] === 1511; + } + static getIsSpeedTacticSupported() { + function F(X) { + return X[this.thread.x]; + } + let R = new this(F.toString(), { context: this.testContext, canvas: this.testCanvas, validate: false, output: [4], returnType: "Number", precision: "unsigned", tactic: "speed" }), K = [[0, 1, 2, 3]]; + R.build.apply(R, K), R.run.apply(R, K); + let O = R.renderOutput(); + return R.destroy(true), Math.round(O[0]) === 0 && Math.round(O[1]) === 1 && Math.round(O[2]) === 2 && Math.round(O[3]) === 3; + } + static get testCanvas() { + throw new Error(`"testCanvas" not defined on ${this.name}`); + } + static get testContext() { + throw new Error(`"testContext" not defined on ${this.name}`); + } + static getFeatures() { + let F = this.testContext, R = this.getIsDrawBuffers(); + return Object.freeze({ isFloatRead: this.getIsFloatRead(), isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), isSpeedTacticSupported: this.getIsSpeedTacticSupported(), isTextureFloat: this.getIsTextureFloat(), isDrawBuffers: R, kernelMap: R, channelCount: this.getChannelCount(), maxTextureSize: this.getMaxTextureSize(), lowIntPrecision: F.getShaderPrecisionFormat(F.FRAGMENT_SHADER, F.LOW_INT), lowFloatPrecision: F.getShaderPrecisionFormat(F.FRAGMENT_SHADER, F.LOW_FLOAT), mediumIntPrecision: F.getShaderPrecisionFormat(F.FRAGMENT_SHADER, F.MEDIUM_INT), mediumFloatPrecision: F.getShaderPrecisionFormat(F.FRAGMENT_SHADER, F.MEDIUM_FLOAT), highIntPrecision: F.getShaderPrecisionFormat(F.FRAGMENT_SHADER, F.HIGH_INT), highFloatPrecision: F.getShaderPrecisionFormat(F.FRAGMENT_SHADER, F.HIGH_FLOAT) }); + } + static setupFeatureChecks() { + throw new Error(`"setupFeatureChecks" not defined on ${this.name}`); + } + static getSignature(F, R) { + return F.getVariablePrecisionString() + (R.length > 0 ? ":" + R.join(",") : ""); + } + setFixIntegerDivisionAccuracy(F) { + return this.fixIntegerDivisionAccuracy = F, this; + } + setPrecision(F) { + return this.precision = F, this; + } + setFloatTextures(F) { + return g.warnDeprecated("method", "setFloatTextures", "setOptimizeFloatMemory"), this.floatTextures = F, this; + } + static nativeFunctionArguments(F) { + let R = [], K = [], O = [], X = /^[a-zA-Z_]/, B = /[a-zA-Z_0-9]/, P = 0, Y = null, J = null; + for (; P < F.length; ) { + let q = F[P], j = F[P + 1], U = O.length > 0 ? O[O.length - 1] : null; + if (U === "FUNCTION_ARGUMENTS" && q === "/" && j === "*") { + O.push("MULTI_LINE_COMMENT"), P += 2; + continue; + } else if (U === "MULTI_LINE_COMMENT" && q === "*" && j === "/") { + O.pop(), P += 2; + continue; + } else if (U === "FUNCTION_ARGUMENTS" && q === "/" && j === "/") { + O.push("COMMENT"), P += 2; + continue; + } else if (U === "COMMENT" && q === ` +`) { + O.pop(), P++; + continue; + } else if (U === null && q === "(") { + O.push("FUNCTION_ARGUMENTS"), P++; + continue; + } else if (U === "FUNCTION_ARGUMENTS") { + if (q === ")") { + O.pop(); + break; + } + if (q === "f" && j === "l" && F[P + 2] === "o" && F[P + 3] === "a" && F[P + 4] === "t" && F[P + 5] === " ") { + O.push("DECLARE_VARIABLE"), J = "float", Y = "", P += 6; + continue; + } else if (q === "i" && j === "n" && F[P + 2] === "t" && F[P + 3] === " ") { + O.push("DECLARE_VARIABLE"), J = "int", Y = "", P += 4; + continue; + } else if (q === "v" && j === "e" && F[P + 2] === "c" && F[P + 3] === "2" && F[P + 4] === " ") { + O.push("DECLARE_VARIABLE"), J = "vec2", Y = "", P += 5; + continue; + } else if (q === "v" && j === "e" && F[P + 2] === "c" && F[P + 3] === "3" && F[P + 4] === " ") { + O.push("DECLARE_VARIABLE"), J = "vec3", Y = "", P += 5; + continue; + } else if (q === "v" && j === "e" && F[P + 2] === "c" && F[P + 3] === "4" && F[P + 4] === " ") { + O.push("DECLARE_VARIABLE"), J = "vec4", Y = "", P += 5; + continue; + } + } else if (U === "DECLARE_VARIABLE") { + if (Y === "") { + if (q === " ") { + P++; + continue; + } + if (!X.test(q)) + throw new Error("variable name is not expected string"); + } + Y += q, B.test(j) || (O.pop(), K.push(Y), R.push(A[J])); + } + P++; + } + if (O.length > 0) + throw new Error("GLSL function was not parsable"); + return { argumentNames: K, argumentTypes: R }; + } + static nativeFunctionReturnType(F) { + return A[F.match(/int|float|vec[2-4]/)[0]]; + } + static combineKernels(F, R) { + F.apply(null, arguments); + let { texSize: K, context: O, threadDim: X } = R.texSize, B; + if (R.precision === "single") { + let P = K[0], Y = Math.ceil(K[1] / 4); + B = new Float32Array(P * Y * 4 * 4), O.readPixels(0, 0, P, Y * 4, O.RGBA, O.FLOAT, B); + } else { + let P = new Uint8Array(K[0] * K[1] * 4); + O.readPixels(0, 0, K[0], K[1], O.RGBA, O.UNSIGNED_BYTE, P), B = new Float32Array(P.buffer); + } + if (B = B.subarray(0, X[0] * X[1] * X[2]), R.output.length === 1) + return B; + if (R.output.length === 2) + return g.splitArray(B, R.output[0]); + if (R.output.length === 3) + return g.splitArray(B, R.output[0] * R.output[1]).map(function(Y) { + return g.splitArray(Y, R.output[0]); + }); + } + constructor(F, R) { + super(F, R), this.transferValues = null, this.formatValues = null, this.TextureConstructor = null, this.renderOutput = null, this.renderRawOutput = null, this.texSize = null, this.translatedSource = null, this.compiledFragmentShader = null, this.compiledVertexShader = null, this.switchingKernels = null, this._textureSwitched = null, this._mappedTextureSwitched = null; + } + checkTextureSize() { + let { features: F } = this.constructor; + if (this.texSize[0] > F.maxTextureSize || this.texSize[1] > F.maxTextureSize) + throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${F.maxTextureSize},${F.maxTextureSize}]`); + } + translateSource() { + throw new Error(`"translateSource" not defined on ${this.constructor.name}`); + } + pickRenderStrategy(F) { + if (this.graphical) + return this.renderRawOutput = this.readPackedPixelsToUint8Array, this.transferValues = (R) => R, this.TextureConstructor = a, null; + if (this.precision === "unsigned") + if (this.renderRawOutput = this.readPackedPixelsToUint8Array, this.transferValues = this.readPackedPixelsToFloat32Array, this.pipeline) + switch (this.renderOutput = this.renderTexture, this.subKernels !== null && (this.renderKernels = this.renderKernelsToTextures), this.returnType) { + case "LiteralInteger": + case "Float": + case "Number": + case "Integer": + return this.output[2] > 0 ? (this.TextureConstructor = c, null) : this.output[1] > 0 ? (this.TextureConstructor = V, null) : (this.TextureConstructor = C, null); + case "Array(2)": + case "Array(3)": + case "Array(4)": + return this.requestFallback(F); + } + else + switch (this.subKernels !== null && (this.renderKernels = this.renderKernelsToArrays), this.returnType) { + case "LiteralInteger": + case "Float": + case "Number": + case "Integer": + return this.renderOutput = this.renderValues, this.output[2] > 0 ? (this.TextureConstructor = c, this.formatValues = g.erect3DPackedFloat, null) : this.output[1] > 0 ? (this.TextureConstructor = V, this.formatValues = g.erect2DPackedFloat, null) : (this.TextureConstructor = C, this.formatValues = g.erectPackedFloat, null); + case "Array(2)": + case "Array(3)": + case "Array(4)": + return this.requestFallback(F); + } + else if (this.precision === "single") { + if (this.renderRawOutput = this.readFloatPixelsToFloat32Array, this.transferValues = this.readFloatPixelsToFloat32Array, this.pipeline) + switch (this.renderOutput = this.renderTexture, this.subKernels !== null && (this.renderKernels = this.renderKernelsToTextures), this.returnType) { + case "LiteralInteger": + case "Float": + case "Number": + case "Integer": + return this.optimizeFloatMemory ? this.output[2] > 0 ? (this.TextureConstructor = T, null) : this.output[1] > 0 ? (this.TextureConstructor = b, null) : (this.TextureConstructor = h, null) : this.output[2] > 0 ? (this.TextureConstructor = v, null) : this.output[1] > 0 ? (this.TextureConstructor = S, null) : (this.TextureConstructor = m, null); + case "Array(2)": + return this.output[2] > 0 ? (this.TextureConstructor = n, null) : this.output[1] > 0 ? (this.TextureConstructor = l, null) : (this.TextureConstructor = f, null); + case "Array(3)": + return this.output[2] > 0 ? (this.TextureConstructor = i, null) : this.output[1] > 0 ? (this.TextureConstructor = t, null) : (this.TextureConstructor = s, null); + case "Array(4)": + return this.output[2] > 0 ? (this.TextureConstructor = w, null) : this.output[1] > 0 ? (this.TextureConstructor = x2, null) : (this.TextureConstructor = u, null); + } + if (this.renderOutput = this.renderValues, this.subKernels !== null && (this.renderKernels = this.renderKernelsToArrays), this.optimizeFloatMemory) + switch (this.returnType) { + case "LiteralInteger": + case "Float": + case "Number": + case "Integer": + return this.output[2] > 0 ? (this.TextureConstructor = T, this.formatValues = g.erectMemoryOptimized3DFloat, null) : this.output[1] > 0 ? (this.TextureConstructor = b, this.formatValues = g.erectMemoryOptimized2DFloat, null) : (this.TextureConstructor = h, this.formatValues = g.erectMemoryOptimizedFloat, null); + case "Array(2)": + return this.output[2] > 0 ? (this.TextureConstructor = n, this.formatValues = g.erect3DArray2, null) : this.output[1] > 0 ? (this.TextureConstructor = l, this.formatValues = g.erect2DArray2, null) : (this.TextureConstructor = f, this.formatValues = g.erectArray2, null); + case "Array(3)": + return this.output[2] > 0 ? (this.TextureConstructor = i, this.formatValues = g.erect3DArray3, null) : this.output[1] > 0 ? (this.TextureConstructor = t, this.formatValues = g.erect2DArray3, null) : (this.TextureConstructor = s, this.formatValues = g.erectArray3, null); + case "Array(4)": + return this.output[2] > 0 ? (this.TextureConstructor = w, this.formatValues = g.erect3DArray4, null) : this.output[1] > 0 ? (this.TextureConstructor = x2, this.formatValues = g.erect2DArray4, null) : (this.TextureConstructor = u, this.formatValues = g.erectArray4, null); + } + else + switch (this.returnType) { + case "LiteralInteger": + case "Float": + case "Number": + case "Integer": + return this.output[2] > 0 ? (this.TextureConstructor = v, this.formatValues = g.erect3DFloat, null) : this.output[1] > 0 ? (this.TextureConstructor = S, this.formatValues = g.erect2DFloat, null) : (this.TextureConstructor = m, this.formatValues = g.erectFloat, null); + case "Array(2)": + return this.output[2] > 0 ? (this.TextureConstructor = n, this.formatValues = g.erect3DArray2, null) : this.output[1] > 0 ? (this.TextureConstructor = l, this.formatValues = g.erect2DArray2, null) : (this.TextureConstructor = f, this.formatValues = g.erectArray2, null); + case "Array(3)": + return this.output[2] > 0 ? (this.TextureConstructor = i, this.formatValues = g.erect3DArray3, null) : this.output[1] > 0 ? (this.TextureConstructor = t, this.formatValues = g.erect2DArray3, null) : (this.TextureConstructor = s, this.formatValues = g.erectArray3, null); + case "Array(4)": + return this.output[2] > 0 ? (this.TextureConstructor = w, this.formatValues = g.erect3DArray4, null) : this.output[1] > 0 ? (this.TextureConstructor = x2, this.formatValues = g.erect2DArray4, null) : (this.TextureConstructor = u, this.formatValues = g.erectArray4, null); + } + } else + throw new Error(`unhandled precision of "${this.precision}"`); + throw new Error(`unhandled return type "${this.returnType}"`); + } + getKernelString() { + throw new Error("abstract method call"); + } + getMainResultTexture() { + switch (this.returnType) { + case "LiteralInteger": + case "Float": + case "Integer": + case "Number": + return this.getMainResultNumberTexture(); + case "Array(2)": + return this.getMainResultArray2Texture(); + case "Array(3)": + return this.getMainResultArray3Texture(); + case "Array(4)": + return this.getMainResultArray4Texture(); + default: + throw new Error(`unhandled returnType type ${this.returnType}`); + } + } + getMainResultKernelNumberTexture() { + throw new Error("abstract method call"); + } + getMainResultSubKernelNumberTexture() { + throw new Error("abstract method call"); + } + getMainResultKernelArray2Texture() { + throw new Error("abstract method call"); + } + getMainResultSubKernelArray2Texture() { + throw new Error("abstract method call"); + } + getMainResultKernelArray3Texture() { + throw new Error("abstract method call"); + } + getMainResultSubKernelArray3Texture() { + throw new Error("abstract method call"); + } + getMainResultKernelArray4Texture() { + throw new Error("abstract method call"); + } + getMainResultSubKernelArray4Texture() { + throw new Error("abstract method call"); + } + getMainResultGraphical() { + throw new Error("abstract method call"); + } + getMainResultMemoryOptimizedFloats() { + throw new Error("abstract method call"); + } + getMainResultPackedPixels() { + throw new Error("abstract method call"); + } + getMainResultString() { + return this.graphical ? this.getMainResultGraphical() : this.precision === "single" ? this.optimizeFloatMemory ? this.getMainResultMemoryOptimizedFloats() : this.getMainResultTexture() : this.getMainResultPackedPixels(); + } + getMainResultNumberTexture() { + return g.linesToString(this.getMainResultKernelNumberTexture()) + g.linesToString(this.getMainResultSubKernelNumberTexture()); + } + getMainResultArray2Texture() { + return g.linesToString(this.getMainResultKernelArray2Texture()) + g.linesToString(this.getMainResultSubKernelArray2Texture()); + } + getMainResultArray3Texture() { + return g.linesToString(this.getMainResultKernelArray3Texture()) + g.linesToString(this.getMainResultSubKernelArray3Texture()); + } + getMainResultArray4Texture() { + return g.linesToString(this.getMainResultKernelArray4Texture()) + g.linesToString(this.getMainResultSubKernelArray4Texture()); + } + getFloatTacticDeclaration() { + return `precision ${this.getVariablePrecisionString(this.texSize, this.tactic)} float; +`; + } + getIntTacticDeclaration() { + return `precision ${this.getVariablePrecisionString(this.texSize, this.tactic, true)} int; +`; + } + getSampler2DTacticDeclaration() { + return `precision ${this.getVariablePrecisionString(this.texSize, this.tactic)} sampler2D; +`; + } + getSampler2DArrayTacticDeclaration() { + return `precision ${this.getVariablePrecisionString(this.texSize, this.tactic)} sampler2DArray; +`; + } + renderTexture() { + return this.immutable ? this.texture.clone() : this.texture; + } + readPackedPixelsToUint8Array() { + if (this.precision !== "unsigned") + throw new Error('Requires this.precision to be "unsigned"'); + let { texSize: F, context: R } = this, K = new Uint8Array(F[0] * F[1] * 4); + return R.readPixels(0, 0, F[0], F[1], R.RGBA, R.UNSIGNED_BYTE, K), K; + } + readPackedPixelsToFloat32Array() { + return new Float32Array(this.readPackedPixelsToUint8Array().buffer); + } + readFloatPixelsToFloat32Array() { + if (this.precision !== "single") + throw new Error('Requires this.precision to be "single"'); + let { texSize: F, context: R } = this, K = F[0], O = F[1], X = new Float32Array(K * O * 4); + return R.readPixels(0, 0, K, O, R.RGBA, R.FLOAT, X), X; + } + getPixels(F) { + let { context: R, output: K } = this, [O, X] = K, B = new Uint8Array(O * X * 4); + return R.readPixels(0, 0, O, X, R.RGBA, R.UNSIGNED_BYTE, B), new Uint8ClampedArray((F ? B : g.flipPixels(B, O, X)).buffer); + } + renderKernelsToArrays() { + let F = { result: this.renderOutput() }; + for (let R = 0; R < this.subKernels.length; R++) + F[this.subKernels[R].property] = this.mappedTextures[R].toArray(); + return F; + } + renderKernelsToTextures() { + let F = { result: this.renderOutput() }; + if (this.immutable) + for (let R = 0; R < this.subKernels.length; R++) + F[this.subKernels[R].property] = this.mappedTextures[R].clone(); + else + for (let R = 0; R < this.subKernels.length; R++) + F[this.subKernels[R].property] = this.mappedTextures[R]; + return F; + } + resetSwitchingKernels() { + let F = this.switchingKernels; + return this.switchingKernels = null, F; + } + setOutput(F) { + let R = this.toKernelOutput(F); + if (this.program) { + if (!this.dynamicOutput) + throw new Error("Resizing a kernel with dynamicOutput: false is not possible"); + let K = [R[0], R[1] || 1, R[2] || 1], O = g.getKernelTextureSize({ optimizeFloatMemory: this.optimizeFloatMemory, precision: this.precision }, K), X = this.texSize; + if (X) { + let P = this.getVariablePrecisionString(X, this.tactic), Y = this.getVariablePrecisionString(O, this.tactic); + if (P !== Y) { + this.debug && console.warn("Precision requirement changed, asking GPU instance to recompile"), this.switchKernels({ type: "outputPrecisionMismatch", precision: Y, needed: F }); + return; + } + } + this.output = R, this.threadDim = K, this.texSize = O; + let { context: B } = this; + if (B.bindFramebuffer(B.FRAMEBUFFER, this.framebuffer), this.updateMaxTexSize(), this.framebuffer.width = this.texSize[0], this.framebuffer.height = this.texSize[1], B.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]), this.canvas.width = this.maxTexSize[0], this.canvas.height = this.maxTexSize[1], this.texture && this.texture.delete(), this.texture = null, this._setupOutputTexture(), this.mappedTextures && this.mappedTextures.length > 0) { + for (let P = 0; P < this.mappedTextures.length; P++) + this.mappedTextures[P].delete(); + this.mappedTextures = null, this._setupSubOutputTextures(); + } + } else + this.output = R; + return this; + } + renderValues() { + return this.formatValues(this.transferValues(), this.output[0], this.output[1], this.output[2]); + } + switchKernels(F) { + this.switchingKernels ? this.switchingKernels.push(F) : this.switchingKernels = [F]; + } + getVariablePrecisionString(F = this.texSize, R = this.tactic, K = false) { + if (!R) { + if (!this.constructor.features.isSpeedTacticSupported) + return "highp"; + let O = this.constructor.features[K ? "lowIntPrecision" : "lowFloatPrecision"], X = this.constructor.features[K ? "mediumIntPrecision" : "mediumFloatPrecision"], B = this.constructor.features[K ? "highIntPrecision" : "highFloatPrecision"], P = Math.log2(F[0] * F[1]); + if (P <= O.rangeMax) + return "lowp"; + if (P <= X.rangeMax) + return "mediump"; + if (P <= B.rangeMax) + return "highp"; + throw new Error("The required size exceeds that of the ability of your system"); + } + switch (R) { + case "speed": + return "lowp"; + case "balanced": + return "mediump"; + case "precision": + return "highp"; + default: + throw new Error(`Unknown tactic "${R}" use "speed", "balanced", "precision", or empty for auto`); + } + } + updateTextureArgumentRefs(F, R) { + if (!!this.immutable) { + if (this.texture.texture === R.texture) { + let { prevArg: K } = F; + K && (K.texture._refs === 1 && (this.texture.delete(), this.texture = K.clone(), this._textureSwitched = true), K.delete()), F.prevArg = R.clone(); + } else if (this.mappedTextures && this.mappedTextures.length > 0) { + let { mappedTextures: K } = this; + for (let O = 0; O < K.length; O++) { + let X = K[O]; + if (X.texture === R.texture) { + let { prevArg: B } = F; + B && (B.texture._refs === 1 && (X.delete(), K[O] = B.clone(), this._mappedTextureSwitched[O] = true), B.delete()), F.prevArg = R.clone(); + return; + } + } + } + } + } + onActivate(F) { + if (this._textureSwitched = true, this.texture = F.texture, this.mappedTextures) { + for (let R = 0; R < this.mappedTextures.length; R++) + this._mappedTextureSwitched[R] = true; + this.mappedTextures = F.mappedTextures; + } + } + initCanvas() { + } + } + let A = { int: "Integer", float: "Number", vec2: "Array(2)", vec3: "Array(3)", vec4: "Array(4)" }; + y.exports = { GLKernel: k }; + }, { "../../utils": 114, "../kernel": 36, "./texture/array-2-float": 16, "./texture/array-2-float-2d": 14, "./texture/array-2-float-3d": 15, "./texture/array-3-float": 19, "./texture/array-3-float-2d": 17, "./texture/array-3-float-3d": 18, "./texture/array-4-float": 22, "./texture/array-4-float-2d": 20, "./texture/array-4-float-3d": 21, "./texture/float": 25, "./texture/float-2d": 23, "./texture/float-3d": 24, "./texture/graphical": 26, "./texture/memory-optimized": 30, "./texture/memory-optimized-2d": 28, "./texture/memory-optimized-3d": 29, "./texture/unsigned": 33, "./texture/unsigned-2d": 31, "./texture/unsigned-3d": 32 }], 14: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { GLTextureFloat: g } = o("./float"); + class f extends g { + constructor(n) { + super(n), this.type = "ArrayTexture(2)"; + } + toArray() { + return p.erect2DArray2(this.renderValues(), this.output[0], this.output[1]); + } + } + y.exports = { GLTextureArray2Float2D: f }; + }, { "../../../utils": 114, "./float": 25 }], 15: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { GLTextureFloat: g } = o("./float"); + class f extends g { + constructor(n) { + super(n), this.type = "ArrayTexture(2)"; + } + toArray() { + return p.erect3DArray2(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } + } + y.exports = { GLTextureArray2Float3D: f }; + }, { "../../../utils": 114, "./float": 25 }], 16: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { GLTextureFloat: g } = o("./float"); + class f extends g { + constructor(n) { + super(n), this.type = "ArrayTexture(2)"; + } + toArray() { + return p.erectArray2(this.renderValues(), this.output[0], this.output[1]); + } + } + y.exports = { GLTextureArray2Float: f }; + }, { "../../../utils": 114, "./float": 25 }], 17: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { GLTextureFloat: g } = o("./float"); + class f extends g { + constructor(n) { + super(n), this.type = "ArrayTexture(3)"; + } + toArray() { + return p.erect2DArray3(this.renderValues(), this.output[0], this.output[1]); + } + } + y.exports = { GLTextureArray3Float2D: f }; + }, { "../../../utils": 114, "./float": 25 }], 18: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { GLTextureFloat: g } = o("./float"); + class f extends g { + constructor(n) { + super(n), this.type = "ArrayTexture(3)"; + } + toArray() { + return p.erect3DArray3(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } + } + y.exports = { GLTextureArray3Float3D: f }; + }, { "../../../utils": 114, "./float": 25 }], 19: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { GLTextureFloat: g } = o("./float"); + class f extends g { + constructor(n) { + super(n), this.type = "ArrayTexture(3)"; + } + toArray() { + return p.erectArray3(this.renderValues(), this.output[0]); + } + } + y.exports = { GLTextureArray3Float: f }; + }, { "../../../utils": 114, "./float": 25 }], 20: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { GLTextureFloat: g } = o("./float"); + class f extends g { + constructor(n) { + super(n), this.type = "ArrayTexture(4)"; + } + toArray() { + return p.erect2DArray4(this.renderValues(), this.output[0], this.output[1]); + } + } + y.exports = { GLTextureArray4Float2D: f }; + }, { "../../../utils": 114, "./float": 25 }], 21: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { GLTextureFloat: g } = o("./float"); + class f extends g { + constructor(n) { + super(n), this.type = "ArrayTexture(4)"; + } + toArray() { + return p.erect3DArray4(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } + } + y.exports = { GLTextureArray4Float3D: f }; + }, { "../../../utils": 114, "./float": 25 }], 22: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { GLTextureFloat: g } = o("./float"); + class f extends g { + constructor(n) { + super(n), this.type = "ArrayTexture(4)"; + } + toArray() { + return p.erectArray4(this.renderValues(), this.output[0]); + } + } + y.exports = { GLTextureArray4Float: f }; + }, { "../../../utils": 114, "./float": 25 }], 23: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { GLTextureFloat: g } = o("./float"); + class f extends g { + constructor(n) { + super(n), this.type = "ArrayTexture(1)"; + } + toArray() { + return p.erect2DFloat(this.renderValues(), this.output[0], this.output[1]); + } + } + y.exports = { GLTextureFloat2D: f }; + }, { "../../../utils": 114, "./float": 25 }], 24: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { GLTextureFloat: g } = o("./float"); + class f extends g { + constructor(n) { + super(n), this.type = "ArrayTexture(1)"; + } + toArray() { + return p.erect3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } + } + y.exports = { GLTextureFloat3D: f }; + }, { "../../../utils": 114, "./float": 25 }], 25: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { GLTexture: g } = o("./index"); + class f extends g { + get textureType() { + return this.context.FLOAT; + } + constructor(n) { + super(n), this.type = "ArrayTexture(1)"; + } + renderRawOutput() { + let n = this.context, s = this.size; + n.bindFramebuffer(n.FRAMEBUFFER, this.framebuffer()), n.framebufferTexture2D(n.FRAMEBUFFER, n.COLOR_ATTACHMENT0, n.TEXTURE_2D, this.texture, 0); + let t = new Float32Array(s[0] * s[1] * 4); + return n.readPixels(0, 0, s[0], s[1], n.RGBA, n.FLOAT, t), t; + } + renderValues() { + return this._deleted ? null : this.renderRawOutput(); + } + toArray() { + return p.erectFloat(this.renderValues(), this.output[0]); + } + } + y.exports = { GLTextureFloat: f }; + }, { "../../../utils": 114, "./index": 27 }], 26: [function(o, y, E) { + let { GLTextureUnsigned: p } = o("./unsigned"); + class g extends p { + constructor(l) { + super(l), this.type = "ArrayTexture(4)"; + } + toArray() { + return this.renderValues(); + } + } + y.exports = { GLTextureGraphical: g }; + }, { "./unsigned": 33 }], 27: [function(o, y, E) { + let { Texture: p } = o("../../../texture"); + class g extends p { + get textureType() { + throw new Error(`"textureType" not implemented on ${this.name}`); + } + clone() { + return new this.constructor(this); + } + beforeMutate() { + return this.texture._refs > 1 ? (this.newTexture(), true) : false; + } + cloneTexture() { + this.texture._refs--; + let { context: n, size: s, texture: t, kernel: i } = this; + i.debug && console.warn("cloning internal texture"), n.bindFramebuffer(n.FRAMEBUFFER, this.framebuffer()), f(n, t), n.framebufferTexture2D(n.FRAMEBUFFER, n.COLOR_ATTACHMENT0, n.TEXTURE_2D, t, 0); + let u = n.createTexture(); + f(n, u), n.texImage2D(n.TEXTURE_2D, 0, this.internalFormat, s[0], s[1], 0, this.textureFormat, this.textureType, null), n.copyTexSubImage2D(n.TEXTURE_2D, 0, 0, 0, 0, 0, s[0], s[1]), u._refs = 1, this.texture = u; + } + newTexture() { + this.texture._refs--; + let n = this.context, s = this.size; + this.kernel.debug && console.warn("new internal texture"); + let i = n.createTexture(); + f(n, i), n.texImage2D(n.TEXTURE_2D, 0, this.internalFormat, s[0], s[1], 0, this.textureFormat, this.textureType, null), i._refs = 1, this.texture = i; + } + clear() { + if (this.texture._refs) { + this.texture._refs--; + let t = this.context, i = this.texture = t.createTexture(); + f(t, i); + let u = this.size; + i._refs = 1, t.texImage2D(t.TEXTURE_2D, 0, this.internalFormat, u[0], u[1], 0, this.textureFormat, this.textureType, null); + } + let { context: n, texture: s } = this; + n.bindFramebuffer(n.FRAMEBUFFER, this.framebuffer()), n.bindTexture(n.TEXTURE_2D, s), f(n, s), n.framebufferTexture2D(n.FRAMEBUFFER, n.COLOR_ATTACHMENT0, n.TEXTURE_2D, s, 0), n.clearColor(0, 0, 0, 0), n.clear(n.COLOR_BUFFER_BIT | n.DEPTH_BUFFER_BIT); + } + delete() { + this._deleted || (this._deleted = true, !(this.texture._refs && (this.texture._refs--, this.texture._refs)) && this.context.deleteTexture(this.texture)); + } + framebuffer() { + return this._framebuffer || (this._framebuffer = this.kernel.getRawValueFramebuffer(this.size[0], this.size[1])), this._framebuffer; + } + } + function f(l, n) { + l.activeTexture(l.TEXTURE15), l.bindTexture(l.TEXTURE_2D, n), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_WRAP_S, l.CLAMP_TO_EDGE), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_WRAP_T, l.CLAMP_TO_EDGE), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_MIN_FILTER, l.NEAREST), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_MAG_FILTER, l.NEAREST); + } + y.exports = { GLTexture: g }; + }, { "../../../texture": 113 }], 28: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { GLTextureFloat: g } = o("./float"); + class f extends g { + constructor(n) { + super(n), this.type = "MemoryOptimizedNumberTexture"; + } + toArray() { + return p.erectMemoryOptimized2DFloat(this.renderValues(), this.output[0], this.output[1]); + } + } + y.exports = { GLTextureMemoryOptimized2D: f }; + }, { "../../../utils": 114, "./float": 25 }], 29: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { GLTextureFloat: g } = o("./float"); + class f extends g { + constructor(n) { + super(n), this.type = "MemoryOptimizedNumberTexture"; + } + toArray() { + return p.erectMemoryOptimized3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } + } + y.exports = { GLTextureMemoryOptimized3D: f }; + }, { "../../../utils": 114, "./float": 25 }], 30: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { GLTextureFloat: g } = o("./float"); + class f extends g { + constructor(n) { + super(n), this.type = "MemoryOptimizedNumberTexture"; + } + toArray() { + return p.erectMemoryOptimizedFloat(this.renderValues(), this.output[0]); + } + } + y.exports = { GLTextureMemoryOptimized: f }; + }, { "../../../utils": 114, "./float": 25 }], 31: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { GLTextureUnsigned: g } = o("./unsigned"); + class f extends g { + constructor(n) { + super(n), this.type = "NumberTexture"; + } + toArray() { + return p.erect2DPackedFloat(this.renderValues(), this.output[0], this.output[1]); + } + } + y.exports = { GLTextureUnsigned2D: f }; + }, { "../../../utils": 114, "./unsigned": 33 }], 32: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { GLTextureUnsigned: g } = o("./unsigned"); + class f extends g { + constructor(n) { + super(n), this.type = "NumberTexture"; + } + toArray() { + return p.erect3DPackedFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } + } + y.exports = { GLTextureUnsigned3D: f }; + }, { "../../../utils": 114, "./unsigned": 33 }], 33: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { GLTexture: g } = o("./index"); + class f extends g { + get textureType() { + return this.context.UNSIGNED_BYTE; + } + constructor(n) { + super(n), this.type = "NumberTexture"; + } + renderRawOutput() { + let { context: n } = this; + n.bindFramebuffer(n.FRAMEBUFFER, this.framebuffer()), n.framebufferTexture2D(n.FRAMEBUFFER, n.COLOR_ATTACHMENT0, n.TEXTURE_2D, this.texture, 0); + let s = new Uint8Array(this.size[0] * this.size[1] * 4); + return n.readPixels(0, 0, this.size[0], this.size[1], n.RGBA, n.UNSIGNED_BYTE, s), s; + } + renderValues() { + return this._deleted ? null : new Float32Array(this.renderRawOutput().buffer); + } + toArray() { + return p.erectPackedFloat(this.renderValues(), this.output[0]); + } + } + y.exports = { GLTextureUnsigned: f }; + }, { "../../../utils": 114, "./index": 27 }], 34: [function(o, y, E) { + let p = o("gl"), { WebGLKernel: g } = o("../web-gl/kernel"), { glKernelString: f } = o("../gl/kernel-string"), l = null, n = null, s = null, t = null, i = null; + class u extends g { + static get isSupported() { + return l !== null || (this.setupFeatureChecks(), l = s !== null), l; + } + static setupFeatureChecks() { + if (n = null, t = null, typeof p == "function") + try { + if (s = p(2, 2, { preserveDrawingBuffer: true }), !s || !s.getExtension) + return; + t = { STACKGL_resize_drawingbuffer: s.getExtension("STACKGL_resize_drawingbuffer"), STACKGL_destroy_context: s.getExtension("STACKGL_destroy_context"), OES_texture_float: s.getExtension("OES_texture_float"), OES_texture_float_linear: s.getExtension("OES_texture_float_linear"), OES_element_index_uint: s.getExtension("OES_element_index_uint"), WEBGL_draw_buffers: s.getExtension("WEBGL_draw_buffers"), WEBGL_color_buffer_float: s.getExtension("WEBGL_color_buffer_float") }, i = this.getFeatures(); + } catch (w) { + console.warn(w); + } + } + static isContextMatch(w) { + try { + return w.getParameter(w.RENDERER) === "ANGLE"; + } catch { + return false; + } + } + static getIsTextureFloat() { + return Boolean(t.OES_texture_float); + } + static getIsDrawBuffers() { + return Boolean(t.WEBGL_draw_buffers); + } + static getChannelCount() { + return t.WEBGL_draw_buffers ? s.getParameter(t.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) : 1; + } + static getMaxTextureSize() { + return s.getParameter(s.MAX_TEXTURE_SIZE); + } + static get testCanvas() { + return n; + } + static get testContext() { + return s; + } + static get features() { + return i; + } + initCanvas() { + return {}; + } + initContext() { + return p(2, 2, { preserveDrawingBuffer: true }); + } + initExtensions() { + this.extensions = { STACKGL_resize_drawingbuffer: this.context.getExtension("STACKGL_resize_drawingbuffer"), STACKGL_destroy_context: this.context.getExtension("STACKGL_destroy_context"), OES_texture_float: this.context.getExtension("OES_texture_float"), OES_texture_float_linear: this.context.getExtension("OES_texture_float_linear"), OES_element_index_uint: this.context.getExtension("OES_element_index_uint"), WEBGL_draw_buffers: this.context.getExtension("WEBGL_draw_buffers") }; + } + build() { + super.build.apply(this, arguments), this.fallbackRequested || this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0], this.maxTexSize[1]); + } + destroyExtensions() { + this.extensions.STACKGL_resize_drawingbuffer = null, this.extensions.STACKGL_destroy_context = null, this.extensions.OES_texture_float = null, this.extensions.OES_texture_float_linear = null, this.extensions.OES_element_index_uint = null, this.extensions.WEBGL_draw_buffers = null; + } + static destroyContext(w) { + let m = w.getExtension("STACKGL_destroy_context"); + m && m.destroy && m.destroy(); + } + toString() { + let w = `const gl = context || require('gl')(1, 1); +`, m = ` if (!context) { gl.getExtension('STACKGL_destroy_context').destroy(); } +`; + return f(this.constructor, arguments, this, w, m); + } + setOutput(w) { + return super.setOutput(w), this.graphical && this.extensions.STACKGL_resize_drawingbuffer && this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0], this.maxTexSize[1]), this; + } + } + y.exports = { HeadlessGLKernel: u }; + }, { "../gl/kernel-string": 12, "../web-gl/kernel": 70, gl: 2 }], 35: [function(o, y, E) { + class p { + constructor(f, l) { + let { name: n, kernel: s, context: t, checkContext: i, onRequestContextHandle: u, onUpdateValueMismatch: x2, origin: w, strictIntegers: m, type: S, tactic: v } = l; + if (!n) + throw new Error("name not set"); + if (!S) + throw new Error("type not set"); + if (!w) + throw new Error("origin not set"); + if (w !== "user" && w !== "constants") + throw new Error(`origin must be "user" or "constants" value is "${w}"`); + if (!u) + throw new Error("onRequestContextHandle is not set"); + this.name = n, this.origin = w, this.tactic = v, this.varName = w === "constants" ? `constants.${n}` : n, this.kernel = s, this.strictIntegers = m, this.type = f.type || S, this.size = f.size || null, this.index = null, this.context = t, this.checkContext = i ?? true, this.contextHandle = null, this.onRequestContextHandle = u, this.onUpdateValueMismatch = x2, this.forceUploadEachRun = null; + } + get id() { + return `${this.origin}_${name}`; + } + getSource() { + throw new Error(`"getSource" not defined on ${this.constructor.name}`); + } + updateValue(f) { + throw new Error(`"updateValue" not defined on ${this.constructor.name}`); + } + } + y.exports = { KernelValue: p }; + }, {}], 36: [function(o, y, E) { + let { utils: p } = o("../utils"), { Input: g } = o("../input"); + class f { + static get isSupported() { + throw new Error(`"isSupported" not implemented on ${this.name}`); + } + static isContextMatch(s) { + throw new Error(`"isContextMatch" not implemented on ${this.name}`); + } + static getFeatures() { + throw new Error(`"getFeatures" not implemented on ${this.name}`); + } + static destroyContext(s) { + throw new Error(`"destroyContext" called on ${this.name}`); + } + static nativeFunctionArguments() { + throw new Error(`"nativeFunctionArguments" called on ${this.name}`); + } + static nativeFunctionReturnType() { + throw new Error(`"nativeFunctionReturnType" called on ${this.name}`); + } + static combineKernels() { + throw new Error(`"combineKernels" called on ${this.name}`); + } + constructor(s, t) { + if (typeof s != "object") { + if (typeof s != "string") + throw new Error("source not a string"); + if (!p.isFunctionString(s)) + throw new Error("source not a function string"); + } + this.useLegacyEncoder = false, this.fallbackRequested = false, this.onRequestFallback = null, this.argumentNames = typeof s == "string" ? p.getArgumentNamesFromString(s) : null, this.argumentTypes = null, this.argumentSizes = null, this.argumentBitRatios = null, this.kernelArguments = null, this.kernelConstants = null, this.forceUploadKernelConstants = null, this.source = s, this.output = null, this.debug = false, this.graphical = false, this.loopMaxIterations = 0, this.constants = null, this.constantTypes = null, this.constantBitRatios = null, this.dynamicArguments = false, this.dynamicOutput = false, this.canvas = null, this.context = null, this.checkContext = null, this.gpu = null, this.functions = null, this.nativeFunctions = null, this.injectedNative = null, this.subKernels = null, this.validate = true, this.immutable = false, this.pipeline = false, this.precision = null, this.tactic = null, this.plugins = null, this.returnType = null, this.leadingReturnStatement = null, this.followingReturnStatement = null, this.optimizeFloatMemory = null, this.strictIntegers = false, this.fixIntegerDivisionAccuracy = null, this.built = false, this.signature = null; + } + mergeSettings(s) { + for (let t in s) + if (!(!s.hasOwnProperty(t) || !this.hasOwnProperty(t))) { + switch (t) { + case "output": + if (!Array.isArray(s.output)) { + this.setOutput(s.output); + continue; + } + break; + case "functions": + this.functions = []; + for (let i = 0; i < s.functions.length; i++) + this.addFunction(s.functions[i]); + continue; + case "graphical": + s[t] && !s.hasOwnProperty("precision") && (this.precision = "unsigned"), this[t] = s[t]; + continue; + case "nativeFunctions": + if (!s.nativeFunctions) + continue; + this.nativeFunctions = []; + for (let i = 0; i < s.nativeFunctions.length; i++) { + let u = s.nativeFunctions[i], { name: x2, source: w } = u; + this.addNativeFunction(x2, w, u); + } + continue; + } + this[t] = s[t]; + } + this.canvas || (this.canvas = this.initCanvas()), this.context || (this.context = this.initContext()), this.plugins || (this.plugins = this.initPlugins(s)); + } + build() { + throw new Error(`"build" not defined on ${this.constructor.name}`); + } + run() { + throw new Error(`"run" not defined on ${this.constructor.name}`); + } + initCanvas() { + throw new Error(`"initCanvas" not defined on ${this.constructor.name}`); + } + initContext() { + throw new Error(`"initContext" not defined on ${this.constructor.name}`); + } + initPlugins(s) { + throw new Error(`"initPlugins" not defined on ${this.constructor.name}`); + } + addFunction(s, t = {}) { + if (s.name && s.source && s.argumentTypes && "returnType" in s) + this.functions.push(s); + else if ("settings" in s && "source" in s) + this.functions.push(this.functionToIGPUFunction(s.source, s.settings)); + else if (typeof s == "string" || typeof s == "function") + this.functions.push(this.functionToIGPUFunction(s, t)); + else + throw new Error("function not properly defined"); + return this; + } + addNativeFunction(s, t, i = {}) { + let { argumentTypes: u, argumentNames: x2 } = i.argumentTypes ? l(i.argumentTypes) : this.constructor.nativeFunctionArguments(t) || {}; + return this.nativeFunctions.push({ name: s, source: t, settings: i, argumentTypes: u, argumentNames: x2, returnType: i.returnType || this.constructor.nativeFunctionReturnType(t) }), this; + } + setupArguments(s) { + if (this.kernelArguments = [], this.argumentTypes) + for (let t = 0; t < this.argumentTypes.length; t++) + this.kernelArguments.push({ type: this.argumentTypes[t] }); + else if (!this.argumentTypes) { + this.argumentTypes = []; + for (let t = 0; t < s.length; t++) { + let i = p.getVariableType(s[t], this.strictIntegers), u = i === "Integer" ? "Number" : i; + this.argumentTypes.push(u), this.kernelArguments.push({ type: u }); + } + } + this.argumentSizes = new Array(s.length), this.argumentBitRatios = new Int32Array(s.length); + for (let t = 0; t < s.length; t++) { + let i = s[t]; + this.argumentSizes[t] = i.constructor === g ? i.size : null, this.argumentBitRatios[t] = this.getBitRatio(i); + } + if (this.argumentNames.length !== s.length) + throw new Error("arguments are miss-aligned"); + } + setupConstants() { + this.kernelConstants = []; + let s = this.constantTypes === null; + if (s && (this.constantTypes = {}), this.constantBitRatios = {}, this.constants) + for (let t in this.constants) { + if (s) { + let i = p.getVariableType(this.constants[t], this.strictIntegers); + this.constantTypes[t] = i, this.kernelConstants.push({ name: t, type: i }); + } else + this.kernelConstants.push({ name: t, type: this.constantTypes[t] }); + this.constantBitRatios[t] = this.getBitRatio(this.constants[t]); + } + } + setOptimizeFloatMemory(s) { + return this.optimizeFloatMemory = s, this; + } + toKernelOutput(s) { + return s.hasOwnProperty("x") ? s.hasOwnProperty("y") ? s.hasOwnProperty("z") ? [s.x, s.y, s.z] : [s.x, s.y] : [s.x] : s; + } + setOutput(s) { + return this.output = this.toKernelOutput(s), this; + } + setDebug(s) { + return this.debug = s, this; + } + setGraphical(s) { + return this.graphical = s, this.precision = "unsigned", this; + } + setLoopMaxIterations(s) { + return this.loopMaxIterations = s, this; + } + setConstants(s) { + return this.constants = s, this; + } + setConstantTypes(s) { + return this.constantTypes = s, this; + } + setFunctions(s) { + for (let t = 0; t < s.length; t++) + this.addFunction(s[t]); + return this; + } + setNativeFunctions(s) { + for (let t = 0; t < s.length; t++) { + let i = s[t], { name: u, source: x2 } = i; + this.addNativeFunction(u, x2, i); + } + return this; + } + setInjectedNative(s) { + return this.injectedNative = s, this; + } + setPipeline(s) { + return this.pipeline = s, this; + } + setPrecision(s) { + return this.precision = s, this; + } + setDimensions(s) { + return p.warnDeprecated("method", "setDimensions", "setOutput"), this.output = s, this; + } + setOutputToTexture(s) { + return p.warnDeprecated("method", "setOutputToTexture", "setPipeline"), this.pipeline = s, this; + } + setImmutable(s) { + return this.immutable = s, this; + } + setCanvas(s) { + return this.canvas = s, this; + } + setStrictIntegers(s) { + return this.strictIntegers = s, this; + } + setDynamicOutput(s) { + return this.dynamicOutput = s, this; + } + setHardcodeConstants(s) { + return p.warnDeprecated("method", "setHardcodeConstants"), this.setDynamicOutput(s), this.setDynamicArguments(s), this; + } + setDynamicArguments(s) { + return this.dynamicArguments = s, this; + } + setUseLegacyEncoder(s) { + return this.useLegacyEncoder = s, this; + } + setWarnVarUsage(s) { + return p.warnDeprecated("method", "setWarnVarUsage"), this; + } + getCanvas() { + return p.warnDeprecated("method", "getCanvas"), this.canvas; + } + getWebGl() { + return p.warnDeprecated("method", "getWebGl"), this.context; + } + setContext(s) { + return this.context = s, this; + } + setArgumentTypes(s) { + if (Array.isArray(s)) + this.argumentTypes = s; + else { + this.argumentTypes = []; + for (let t in s) { + if (!s.hasOwnProperty(t)) + continue; + let i = this.argumentNames.indexOf(t); + if (i === -1) + throw new Error(`unable to find argument ${t}`); + this.argumentTypes[i] = s[t]; + } + } + return this; + } + setTactic(s) { + return this.tactic = s, this; + } + requestFallback(s) { + if (!this.onRequestFallback) + throw new Error(`"onRequestFallback" not defined on ${this.constructor.name}`); + return this.fallbackRequested = true, this.onRequestFallback(s); + } + validateSettings() { + throw new Error(`"validateSettings" not defined on ${this.constructor.name}`); + } + addSubKernel(s) { + if (this.subKernels === null && (this.subKernels = []), !s.source) + throw new Error('subKernel missing "source" property'); + if (!s.property && isNaN(s.property)) + throw new Error('subKernel missing "property" property'); + if (!s.name) + throw new Error('subKernel missing "name" property'); + return this.subKernels.push(s), this; + } + destroy(s) { + throw new Error(`"destroy" called on ${this.constructor.name}`); + } + getBitRatio(s) { + if (this.precision === "single") + return 4; + if (Array.isArray(s[0])) + return this.getBitRatio(s[0]); + if (s.constructor === g) + return this.getBitRatio(s.value); + switch (s.constructor) { + case Uint8ClampedArray: + case Uint8Array: + case Int8Array: + return 1; + case Uint16Array: + case Int16Array: + return 2; + case Float32Array: + case Int32Array: + default: + return 4; + } + } + getPixels(s) { + throw new Error(`"getPixels" called on ${this.constructor.name}`); + } + checkOutput() { + if (!this.output || !p.isArray(this.output)) + throw new Error("kernel.output not an array"); + if (this.output.length < 1) + throw new Error("kernel.output is empty, needs at least 1 value"); + for (let s = 0; s < this.output.length; s++) + if (isNaN(this.output[s]) || this.output[s] < 1) + throw new Error(`${this.constructor.name}.output[${s}] incorrectly defined as \`${this.output[s]}\`, needs to be numeric, and greater than 0`); + } + prependString(s) { + throw new Error(`"prependString" called on ${this.constructor.name}`); + } + hasPrependString(s) { + throw new Error(`"hasPrependString" called on ${this.constructor.name}`); + } + toJSON() { + return { settings: { output: this.output, pipeline: this.pipeline, argumentNames: this.argumentNames, argumentsTypes: this.argumentTypes, constants: this.constants, pluginNames: this.plugins ? this.plugins.map((s) => s.name) : null, returnType: this.returnType } }; + } + buildSignature(s) { + let t = this.constructor; + this.signature = t.getSignature(this, t.getArgumentTypes(this, s)); + } + static getArgumentTypes(s, t) { + let i = new Array(t.length); + for (let u = 0; u < t.length; u++) { + let x2 = t[u], w = s.argumentTypes[u]; + if (x2.type) + i[u] = x2.type; + else + switch (w) { + case "Number": + case "Integer": + case "Float": + case "ArrayTexture(1)": + i[u] = p.getVariableType(x2); + break; + default: + i[u] = w; + } + } + return i; + } + static getSignature(s, t) { + throw new Error(`"getSignature" not implemented on ${this.name}`); + } + functionToIGPUFunction(s, t = {}) { + if (typeof s != "string" && typeof s != "function") + throw new Error("source not a string or function"); + let i = typeof s == "string" ? s : s.toString(), u = []; + return Array.isArray(t.argumentTypes) ? u = t.argumentTypes : typeof t.argumentTypes == "object" ? u = p.getArgumentNamesFromString(i).map((x2) => t.argumentTypes[x2]) || [] : u = t.argumentTypes || [], { name: p.getFunctionNameFromString(i) || null, source: i, argumentTypes: u, returnType: t.returnType || null }; + } + onActivate(s) { + } + } + function l(n) { + let s = Object.keys(n), t = []; + for (let i = 0; i < s.length; i++) { + let u = s[i]; + t.push(n[u]); + } + return { argumentTypes: t, argumentNames: s }; + } + y.exports = { Kernel: f }; + }, { "../input": 110, "../utils": 114 }], 37: [function(o, y, E) { + let p = `__HEADER__; + __FLOAT_TACTIC_DECLARATION__; + __INT_TACTIC_DECLARATION__; + __SAMPLER_2D_TACTIC_DECLARATION__; + + const int LOOP_MAX = __LOOP_MAX__; + + __PLUGINS__; + __CONSTANTS__; + + varying vec2 vTexCoord; + + float acosh(float x) { + return log(x + sqrt(x * x - 1.0)); + } + + float sinh(float x) { + return (pow(${Math.E}, x) - pow(${Math.E}, -x)) / 2.0; + } + + float asinh(float x) { + return log(x + sqrt(x * x + 1.0)); + } + + float atan2(float v1, float v2) { + if (v1 == 0.0 || v2 == 0.0) return 0.0; + return atan(v1 / v2); + } + + float atanh(float x) { + x = (x + 1.0) / (x - 1.0); + if (x < 0.0) { + return 0.5 * log(-x); + } + return 0.5 * log(x); + } + + float cbrt(float x) { + if (x >= 0.0) { + return pow(x, 1.0 / 3.0); + } else { + return -pow(x, 1.0 / 3.0); + } + } + + float cosh(float x) { + return (pow(${Math.E}, x) + pow(${Math.E}, -x)) / 2.0; + } + + float expm1(float x) { + return pow(${Math.E}, x) - 1.0; + } + + float fround(highp float x) { + return x; + } + + float imul(float v1, float v2) { + return float(int(v1) * int(v2)); + } + + float log10(float x) { + return log2(x) * (1.0 / log2(10.0)); + } + + float log1p(float x) { + return log(1.0 + x); + } + + float _pow(float v1, float v2) { + if (v2 == 0.0) return 1.0; + return pow(v1, v2); + } + + float tanh(float x) { + float e = exp(2.0 * x); + return (e - 1.0) / (e + 1.0); + } + + float trunc(float x) { + if (x >= 0.0) { + return floor(x); + } else { + return ceil(x); + } + } + + vec4 _round(vec4 x) { + return floor(x + 0.5); + } + + float _round(float x) { + return floor(x + 0.5); + } + + const int BIT_COUNT = 32; + int modi(int x, int y) { + return x - y * (x / y); + } + + int bitwiseOr(int a, int b) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 || b > 0)) { + break; + } + } + return result; + } + int bitwiseXOR(int a, int b) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 || b > 0)) { + break; + } + } + return result; + } + int bitwiseAnd(int a, int b) { + int result = 0; + int n = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 && b > 0)) { + break; + } + } + return result; + } + int bitwiseNot(int a) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if (modi(a, 2) == 0) { + result += n; + } + a = a / 2; + n = n * 2; + } + return result; + } + int bitwiseZeroFillLeftShift(int n, int shift) { + int maxBytes = BIT_COUNT; + for (int i = 0; i < BIT_COUNT; i++) { + if (maxBytes >= n) { + break; + } + maxBytes *= 2; + } + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= shift) { + break; + } + n *= 2; + } + + int result = 0; + int byteVal = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= maxBytes) break; + if (modi(n, 2) > 0) { result += byteVal; } + n = int(n / 2); + byteVal *= 2; + } + return result; + } + + int bitwiseSignedRightShift(int num, int shifts) { + return int(floor(float(num) / pow(2.0, float(shifts)))); + } + + int bitwiseZeroFillRightShift(int n, int shift) { + int maxBytes = BIT_COUNT; + for (int i = 0; i < BIT_COUNT; i++) { + if (maxBytes >= n) { + break; + } + maxBytes *= 2; + } + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= shift) { + break; + } + n /= 2; + } + int result = 0; + int byteVal = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= maxBytes) break; + if (modi(n, 2) > 0) { result += byteVal; } + n = int(n / 2); + byteVal *= 2; + } + return result; + } + + vec2 integerMod(vec2 x, float y) { + vec2 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); + } + + vec3 integerMod(vec3 x, float y) { + vec3 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); + } + + vec4 integerMod(vec4 x, vec4 y) { + vec4 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); + } + + float integerMod(float x, float y) { + float res = floor(mod(x, y)); + return res * (res > floor(y) - 1.0 ? 0.0 : 1.0); + } + + int integerMod(int x, int y) { + return x - (y * int(x / y)); + } + + __DIVIDE_WITH_INTEGER_CHECK__; + + // Here be dragons! + // DO NOT OPTIMIZE THIS CODE + // YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE + // LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME + const vec2 MAGIC_VEC = vec2(1.0, -256.0); + const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0); + const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536 + float decode32(vec4 texel) { + __DECODE32_ENDIANNESS__; + texel *= 255.0; + vec2 gte128; + gte128.x = texel.b >= 128.0 ? 1.0 : 0.0; + gte128.y = texel.a >= 128.0 ? 1.0 : 0.0; + float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC); + float res = exp2(_round(exponent)); + texel.b = texel.b - 128.0 * gte128.x; + res = dot(texel, SCALE_FACTOR) * exp2(_round(exponent-23.0)) + res; + res *= gte128.y * -2.0 + 1.0; + return res; + } + + float decode16(vec4 texel, int index) { + int channel = integerMod(index, 2); + if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0; + if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0; + return 0.0; + } + + float decode8(vec4 texel, int index) { + int channel = integerMod(index, 4); + if (channel == 0) return texel.r * 255.0; + if (channel == 1) return texel.g * 255.0; + if (channel == 2) return texel.b * 255.0; + if (channel == 3) return texel.a * 255.0; + return 0.0; + } + + vec4 legacyEncode32(float f) { + float F = abs(f); + float sign = f < 0.0 ? 1.0 : 0.0; + float exponent = floor(log2(F)); + float mantissa = (exp2(-exponent) * F); + // exponent += floor(log2(mantissa)); + vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV; + texel.rg = integerMod(texel.rg, 256.0); + texel.b = integerMod(texel.b, 128.0); + texel.a = exponent*0.5 + 63.5; + texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0; + texel = floor(texel); + texel *= 0.003921569; // 1/255 + __ENCODE32_ENDIANNESS__; + return texel; + } + + // https://github.com/gpujs/gpu.js/wiki/Encoder-details + vec4 encode32(float value) { + if (value == 0.0) return vec4(0, 0, 0, 0); + + float exponent; + float mantissa; + vec4 result; + float sgn; + + sgn = step(0.0, -value); + value = abs(value); + + exponent = floor(log2(value)); + + mantissa = value*pow(2.0, -exponent)-1.0; + exponent = exponent+127.0; + result = vec4(0,0,0,0); + + result.a = floor(exponent/2.0); + exponent = exponent - result.a*2.0; + result.a = result.a + 128.0*sgn; + + result.b = floor(mantissa * 128.0); + mantissa = mantissa - result.b / 128.0; + result.b = result.b + exponent*128.0; + + result.g = floor(mantissa*32768.0); + mantissa = mantissa - result.g/32768.0; + + result.r = floor(mantissa*8388608.0); + return result/255.0; + } + // Dragons end here + + int index; + ivec3 threadId; + + ivec3 indexTo3D(int idx, ivec3 texDim) { + int z = int(idx / (texDim.x * texDim.y)); + idx -= z * int(texDim.x * texDim.y); + int y = int(idx / texDim.x); + int x = int(integerMod(idx, texDim.x)); + return ivec3(x, y, z); + } + + float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize)); + return decode32(texel); + } + + float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x * 2; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y)); + return decode16(texel, index); + } + + float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x * 4; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y)); + return decode8(texel, index); + } + + float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int channel = integerMod(index, 4); + index = index / 4; + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize)); + if (channel == 0) return texel.r; + if (channel == 1) return texel.g; + if (channel == 2) return texel.b; + if (channel == 3) return texel.a; + return 0.0; + } + + vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + return texture2D(tex, st / vec2(texSize)); + } + + float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return result[0]; + } + + vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return vec2(result[0], result[1]); + } + + vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + (texDim.x * (y + (texDim.y * z))); + int channel = integerMod(index, 2); + index = index / 2; + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize)); + if (channel == 0) return vec2(texel.r, texel.g); + if (channel == 1) return vec2(texel.b, texel.a); + return vec2(0.0, 0.0); + } + + vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return vec3(result[0], result[1], result[2]); + } + + vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z)); + int vectorIndex = fieldIndex / 4; + int vectorOffset = fieldIndex - vectorIndex * 4; + int readY = vectorIndex / texSize.x; + int readX = vectorIndex - readY * texSize.x; + vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize)); + + if (vectorOffset == 0) { + return tex1.xyz; + } else if (vectorOffset == 1) { + return tex1.yzw; + } else { + readX++; + if (readX >= texSize.x) { + readX = 0; + readY++; + } + vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize)); + if (vectorOffset == 2) { + return vec3(tex1.z, tex1.w, tex2.x); + } else { + return vec3(tex1.w, tex2.x, tex2.y); + } + } + } + + vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + return getImage2D(tex, texSize, texDim, z, y, x); + } + + vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int channel = integerMod(index, 2); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize)); + return vec4(texel.r, texel.g, texel.b, texel.a); + } + + vec4 actualColor; + void color(float r, float g, float b, float a) { + actualColor = vec4(r,g,b,a); + } + + void color(float r, float g, float b) { + color(r,g,b,1.0); + } + + void color(sampler2D image) { + actualColor = texture2D(image, vTexCoord); + } + + float modulo(float number, float divisor) { + if (number < 0.0) { + number = abs(number); + if (divisor < 0.0) { + divisor = abs(divisor); + } + return -mod(number, divisor); + } + if (divisor < 0.0) { + divisor = abs(divisor); + } + return mod(number, divisor); + } + + __INJECTED_NATIVE__; + __MAIN_CONSTANTS__; + __MAIN_ARGUMENTS__; + __KERNEL__; + + void main(void) { + index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x; + __MAIN_RESULT__; + }`; + y.exports = { fragmentShader: p }; + }, {}], 38: [function(o, y, E) { + let { utils: p } = o("../../utils"), { FunctionNode: g } = o("../function-node"); + class f extends g { + constructor(t, i) { + super(t, i), i && i.hasOwnProperty("fixIntegerDivisionAccuracy") && (this.fixIntegerDivisionAccuracy = i.fixIntegerDivisionAccuracy); + } + astConditionalExpression(t, i) { + if (t.type !== "ConditionalExpression") + throw this.astErrorOutput("Not a conditional expression", t); + let u = this.getType(t.consequent), x2 = this.getType(t.alternate); + return u === null && x2 === null ? (i.push("if ("), this.astGeneric(t.test, i), i.push(") {"), this.astGeneric(t.consequent, i), i.push(";"), i.push("} else {"), this.astGeneric(t.alternate, i), i.push(";"), i.push("}"), i) : (i.push("("), this.astGeneric(t.test, i), i.push("?"), this.astGeneric(t.consequent, i), i.push(":"), this.astGeneric(t.alternate, i), i.push(")"), i); + } + astFunction(t, i) { + if (this.isRootKernel) + i.push("void"); + else { + this.returnType || this.findLastReturn() && (this.returnType = this.getType(t.body), this.returnType === "LiteralInteger" && (this.returnType = "Number")); + let { returnType: u } = this; + if (!u) + i.push("void"); + else { + let x2 = l[u]; + if (!x2) + throw new Error(`unknown type ${u}`); + i.push(x2); + } + } + if (i.push(" "), i.push(this.name), i.push("("), !this.isRootKernel) + for (let u = 0; u < this.argumentNames.length; ++u) { + let x2 = this.argumentNames[u]; + u > 0 && i.push(", "); + let w = this.argumentTypes[this.argumentNames.indexOf(x2)]; + if (!w) + throw this.astErrorOutput(`Unknown argument ${x2} type`, t); + w === "LiteralInteger" && (this.argumentTypes[u] = w = "Number"); + let m = l[w]; + if (!m) + throw this.astErrorOutput("Unexpected expression", t); + let S = p.sanitizeName(x2); + m === "sampler2D" || m === "sampler2DArray" ? i.push(`${m} user_${S},ivec2 user_${S}Size,ivec3 user_${S}Dim`) : i.push(`${m} user_${S}`); + } + i.push(`) { +`); + for (let u = 0; u < t.body.body.length; ++u) + this.astGeneric(t.body.body[u], i), i.push(` +`); + return i.push(`} +`), i; + } + astReturnStatement(t, i) { + if (!t.argument) + throw this.astErrorOutput("Unexpected return statement", t); + this.pushState("skip-literal-correction"); + let u = this.getType(t.argument); + this.popState("skip-literal-correction"); + let x2 = []; + switch (this.returnType || (u === "LiteralInteger" || u === "Integer" ? this.returnType = "Number" : this.returnType = u), this.returnType) { + case "LiteralInteger": + case "Number": + case "Float": + switch (u) { + case "Integer": + x2.push("float("), this.astGeneric(t.argument, x2), x2.push(")"); + break; + case "LiteralInteger": + this.castLiteralToFloat(t.argument, x2), this.getType(t) === "Integer" && (x2.unshift("float("), x2.push(")")); + break; + default: + this.astGeneric(t.argument, x2); + } + break; + case "Integer": + switch (u) { + case "Float": + case "Number": + this.castValueToInteger(t.argument, x2); + break; + case "LiteralInteger": + this.castLiteralToInteger(t.argument, x2); + break; + default: + this.astGeneric(t.argument, x2); + } + break; + case "Array(4)": + case "Array(3)": + case "Array(2)": + case "Matrix(2)": + case "Matrix(3)": + case "Matrix(4)": + case "Input": + this.astGeneric(t.argument, x2); + break; + default: + throw this.astErrorOutput(`unhandled return type ${this.returnType}`, t); + } + return this.isRootKernel ? (i.push(`kernelResult = ${x2.join("")};`), i.push("return;")) : this.isSubKernel ? (i.push(`subKernelResult_${this.name} = ${x2.join("")};`), i.push(`return subKernelResult_${this.name};`)) : i.push(`return ${x2.join("")};`), i; + } + astLiteral(t, i) { + if (isNaN(t.value)) + throw this.astErrorOutput("Non-numeric literal not supported : " + t.value, t); + let u = this.astKey(t); + return Number.isInteger(t.value) ? this.isState("casting-to-integer") || this.isState("building-integer") ? (this.literalTypes[u] = "Integer", i.push(`${t.value}`)) : this.isState("casting-to-float") || this.isState("building-float") ? (this.literalTypes[u] = "Number", i.push(`${t.value}.0`)) : (this.literalTypes[u] = "Number", i.push(`${t.value}.0`)) : this.isState("casting-to-integer") || this.isState("building-integer") ? (this.literalTypes[u] = "Integer", i.push(Math.round(t.value))) : (this.literalTypes[u] = "Number", i.push(`${t.value}`)), i; + } + astBinaryExpression(t, i) { + if (this.checkAndUpconvertOperator(t, i)) + return i; + if (this.fixIntegerDivisionAccuracy && t.operator === "/") { + switch (i.push("divWithIntCheck("), this.pushState("building-float"), this.getType(t.left)) { + case "Integer": + this.castValueToFloat(t.left, i); + break; + case "LiteralInteger": + this.castLiteralToFloat(t.left, i); + break; + default: + this.astGeneric(t.left, i); + } + switch (i.push(", "), this.getType(t.right)) { + case "Integer": + this.castValueToFloat(t.right, i); + break; + case "LiteralInteger": + this.castLiteralToFloat(t.right, i); + break; + default: + this.astGeneric(t.right, i); + } + return this.popState("building-float"), i.push(")"), i; + } + i.push("("); + let u = this.getType(t.left) || "Number", x2 = this.getType(t.right) || "Number"; + if (!u || !x2) + throw this.astErrorOutput("Unhandled binary expression", t); + let w = u + " & " + x2; + switch (w) { + case "Integer & Integer": + this.pushState("building-integer"), this.astGeneric(t.left, i), i.push(n[t.operator] || t.operator), this.astGeneric(t.right, i), this.popState("building-integer"); + break; + case "Number & Float": + case "Float & Number": + case "Float & Float": + case "Number & Number": + this.pushState("building-float"), this.astGeneric(t.left, i), i.push(n[t.operator] || t.operator), this.astGeneric(t.right, i), this.popState("building-float"); + break; + case "LiteralInteger & LiteralInteger": + this.isState("casting-to-integer") || this.isState("building-integer") ? (this.pushState("building-integer"), this.astGeneric(t.left, i), i.push(n[t.operator] || t.operator), this.astGeneric(t.right, i), this.popState("building-integer")) : (this.pushState("building-float"), this.castLiteralToFloat(t.left, i), i.push(n[t.operator] || t.operator), this.castLiteralToFloat(t.right, i), this.popState("building-float")); + break; + case "Integer & Float": + case "Integer & Number": + if ((t.operator === ">" || t.operator === "<" && t.right.type === "Literal") && !Number.isInteger(t.right.value)) { + this.pushState("building-float"), this.castValueToFloat(t.left, i), i.push(n[t.operator] || t.operator), this.astGeneric(t.right, i), this.popState("building-float"); + break; + } + if (this.pushState("building-integer"), this.astGeneric(t.left, i), i.push(n[t.operator] || t.operator), this.pushState("casting-to-integer"), t.right.type === "Literal") { + let m = []; + if (this.astGeneric(t.right, m), this.getType(t.right) === "Integer") + i.push(m.join("")); + else + throw this.astErrorOutput("Unhandled binary expression with literal", t); + } else + i.push("int("), this.astGeneric(t.right, i), i.push(")"); + this.popState("casting-to-integer"), this.popState("building-integer"); + break; + case "Integer & LiteralInteger": + this.pushState("building-integer"), this.astGeneric(t.left, i), i.push(n[t.operator] || t.operator), this.castLiteralToInteger(t.right, i), this.popState("building-integer"); + break; + case "Number & Integer": + this.pushState("building-float"), this.astGeneric(t.left, i), i.push(n[t.operator] || t.operator), this.castValueToFloat(t.right, i), this.popState("building-float"); + break; + case "Float & LiteralInteger": + case "Number & LiteralInteger": + this.pushState("building-float"), this.astGeneric(t.left, i), i.push(n[t.operator] || t.operator), this.castLiteralToFloat(t.right, i), this.popState("building-float"); + break; + case "LiteralInteger & Float": + case "LiteralInteger & Number": + this.isState("casting-to-integer") ? (this.pushState("building-integer"), this.castLiteralToInteger(t.left, i), i.push(n[t.operator] || t.operator), this.castValueToInteger(t.right, i), this.popState("building-integer")) : (this.pushState("building-float"), this.astGeneric(t.left, i), i.push(n[t.operator] || t.operator), this.pushState("casting-to-float"), this.astGeneric(t.right, i), this.popState("casting-to-float"), this.popState("building-float")); + break; + case "LiteralInteger & Integer": + this.pushState("building-integer"), this.castLiteralToInteger(t.left, i), i.push(n[t.operator] || t.operator), this.astGeneric(t.right, i), this.popState("building-integer"); + break; + case "Boolean & Boolean": + this.pushState("building-boolean"), this.astGeneric(t.left, i), i.push(n[t.operator] || t.operator), this.astGeneric(t.right, i), this.popState("building-boolean"); + break; + case "Float & Integer": + this.pushState("building-float"), this.astGeneric(t.left, i), i.push(n[t.operator] || t.operator), this.castValueToFloat(t.right, i), this.popState("building-float"); + break; + default: + throw this.astErrorOutput(`Unhandled binary expression between ${w}`, t); + } + return i.push(")"), i; + } + checkAndUpconvertOperator(t, i) { + let u = this.checkAndUpconvertBitwiseOperators(t, i); + if (u) + return u; + let w = { "%": this.fixIntegerDivisionAccuracy ? "integerCorrectionModulo" : "modulo", "**": "pow" }[t.operator]; + if (!w) + return null; + switch (i.push(w), i.push("("), this.getType(t.left)) { + case "Integer": + this.castValueToFloat(t.left, i); + break; + case "LiteralInteger": + this.castLiteralToFloat(t.left, i); + break; + default: + this.astGeneric(t.left, i); + } + switch (i.push(","), this.getType(t.right)) { + case "Integer": + this.castValueToFloat(t.right, i); + break; + case "LiteralInteger": + this.castLiteralToFloat(t.right, i); + break; + default: + this.astGeneric(t.right, i); + } + return i.push(")"), i; + } + checkAndUpconvertBitwiseOperators(t, i) { + let x2 = { "&": "bitwiseAnd", "|": "bitwiseOr", "^": "bitwiseXOR", "<<": "bitwiseZeroFillLeftShift", ">>": "bitwiseSignedRightShift", ">>>": "bitwiseZeroFillRightShift" }[t.operator]; + if (!x2) + return null; + switch (i.push(x2), i.push("("), this.getType(t.left)) { + case "Number": + case "Float": + this.castValueToInteger(t.left, i); + break; + case "LiteralInteger": + this.castLiteralToInteger(t.left, i); + break; + default: + this.astGeneric(t.left, i); + } + switch (i.push(","), this.getType(t.right)) { + case "Number": + case "Float": + this.castValueToInteger(t.right, i); + break; + case "LiteralInteger": + this.castLiteralToInteger(t.right, i); + break; + default: + this.astGeneric(t.right, i); + } + return i.push(")"), i; + } + checkAndUpconvertBitwiseUnary(t, i) { + let x2 = { "~": "bitwiseNot" }[t.operator]; + if (!x2) + return null; + switch (i.push(x2), i.push("("), this.getType(t.argument)) { + case "Number": + case "Float": + this.castValueToInteger(t.argument, i); + break; + case "LiteralInteger": + this.castLiteralToInteger(t.argument, i); + break; + default: + this.astGeneric(t.argument, i); + } + return i.push(")"), i; + } + castLiteralToInteger(t, i) { + return this.pushState("casting-to-integer"), this.astGeneric(t, i), this.popState("casting-to-integer"), i; + } + castLiteralToFloat(t, i) { + return this.pushState("casting-to-float"), this.astGeneric(t, i), this.popState("casting-to-float"), i; + } + castValueToInteger(t, i) { + return this.pushState("casting-to-integer"), i.push("int("), this.astGeneric(t, i), i.push(")"), this.popState("casting-to-integer"), i; + } + castValueToFloat(t, i) { + return this.pushState("casting-to-float"), i.push("float("), this.astGeneric(t, i), i.push(")"), this.popState("casting-to-float"), i; + } + astIdentifierExpression(t, i) { + if (t.type !== "Identifier") + throw this.astErrorOutput("IdentifierExpression - not an Identifier", t); + let u = this.getType(t), x2 = p.sanitizeName(t.name); + return t.name === "Infinity" ? i.push("3.402823466e+38") : u === "Boolean" ? this.argumentNames.indexOf(x2) > -1 ? i.push(`bool(user_${x2})`) : i.push(`user_${x2}`) : i.push(`user_${x2}`), i; + } + astForStatement(t, i) { + if (t.type !== "ForStatement") + throw this.astErrorOutput("Invalid for statement", t); + let u = [], x2 = [], w = [], m = [], S = null; + if (t.init) { + let { declarations: v } = t.init; + v.length > 1 && (S = false), this.astGeneric(t.init, u); + for (let h = 0; h < v.length; h++) + v[h].init && v[h].init.type !== "Literal" && (S = false); + } else + S = false; + if (t.test ? this.astGeneric(t.test, x2) : S = false, t.update ? this.astGeneric(t.update, w) : S = false, t.body && (this.pushState("loop-body"), this.astGeneric(t.body, m), this.popState("loop-body")), S === null && (S = this.isSafe(t.init) && this.isSafe(t.test)), S) { + let v = u.join(""), h = v[v.length - 1] !== ";"; + i.push(`for (${v}${h ? ";" : ""}${x2.join("")};${w.join("")}){ +`), i.push(m.join("")), i.push(`} +`); + } else { + let v = this.getInternalVariableName("safeI"); + u.length > 0 && i.push(u.join(""), ` +`), i.push(`for (int ${v}=0;${v} 0 && i.push(`if (!${x2.join("")}) break; +`), i.push(m.join("")), i.push(` +${w.join("")};`), i.push(`} +`); + } + return i; + } + astWhileStatement(t, i) { + if (t.type !== "WhileStatement") + throw this.astErrorOutput("Invalid while statement", t); + let u = this.getInternalVariableName("safeI"); + return i.push(`for (int ${u}=0;${u} 0 && m.push(S.join(",")), x2.push(m.join(";")), i.push(x2.join("")), i.push(";"), i; + } + astIfStatement(t, i) { + return i.push("if ("), this.astGeneric(t.test, i), i.push(")"), t.consequent.type === "BlockStatement" ? this.astGeneric(t.consequent, i) : (i.push(` { +`), this.astGeneric(t.consequent, i), i.push(` +} +`)), t.alternate && (i.push("else "), t.alternate.type === "BlockStatement" || t.alternate.type === "IfStatement" ? this.astGeneric(t.alternate, i) : (i.push(` { +`), this.astGeneric(t.alternate, i), i.push(` +} +`))), i; + } + astSwitchStatement(t, i) { + if (t.type !== "SwitchStatement") + throw this.astErrorOutput("Invalid switch statement", t); + let { discriminant: u, cases: x2 } = t, w = this.getType(u), m = `switchDiscriminant${this.astKey(t, "_")}`; + switch (w) { + case "Float": + case "Number": + i.push(`float ${m} = `), this.astGeneric(u, i), i.push(`; +`); + break; + case "Integer": + i.push(`int ${m} = `), this.astGeneric(u, i), i.push(`; +`); + break; + } + if (x2.length === 1 && !x2[0].test) + return this.astGeneric(x2[0].consequent, i), i; + let S = false, v = [], h = false, b = false; + for (let T = 0; T < x2.length; T++) { + if (x2[T].test) { + if (T === 0 || !b ? (b = true, i.push(`if (${m} == `)) : S ? (i.push(`${m} == `), S = false) : i.push(` else if (${m} == `), w === "Integer") + switch (this.getType(x2[T].test)) { + case "Number": + case "Float": + this.castValueToInteger(x2[T].test, i); + break; + case "LiteralInteger": + this.castLiteralToInteger(x2[T].test, i); + break; + } + else if (w === "Float") + switch (this.getType(x2[T].test)) { + case "LiteralInteger": + this.castLiteralToFloat(x2[T].test, i); + break; + case "Integer": + this.castValueToFloat(x2[T].test, i); + break; + } + else + throw new Error("unhanlded"); + if (!x2[T].consequent || x2[T].consequent.length === 0) { + S = true, i.push(" || "); + continue; + } + i.push(`) { +`); + } else if (x2.length > T + 1) { + h = true, this.astGeneric(x2[T].consequent, v); + continue; + } else + i.push(` else { +`); + this.astGeneric(x2[T].consequent, i), i.push(` +}`); + } + return h && (i.push(" else {"), i.push(v.join("")), i.push("}")), i; + } + astThisExpression(t, i) { + return i.push("this"), i; + } + astMemberExpression(t, i) { + let { property: u, name: x2, signature: w, origin: m, type: S, xProperty: v, yProperty: h, zProperty: b } = this.getMemberExpressionDetails(t); + switch (w) { + case "value.thread.value": + case "this.thread.value": + if (x2 !== "x" && x2 !== "y" && x2 !== "z") + throw this.astErrorOutput("Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`", t); + return i.push(`threadId.${x2}`), i; + case "this.output.value": + if (this.dynamicOutput) + switch (x2) { + case "x": + this.isState("casting-to-float") ? i.push("float(uOutputDim.x)") : i.push("uOutputDim.x"); + break; + case "y": + this.isState("casting-to-float") ? i.push("float(uOutputDim.y)") : i.push("uOutputDim.y"); + break; + case "z": + this.isState("casting-to-float") ? i.push("float(uOutputDim.z)") : i.push("uOutputDim.z"); + break; + default: + throw this.astErrorOutput("Unexpected expression", t); + } + else + switch (x2) { + case "x": + this.isState("casting-to-integer") ? i.push(this.output[0]) : i.push(this.output[0], ".0"); + break; + case "y": + this.isState("casting-to-integer") ? i.push(this.output[1]) : i.push(this.output[1], ".0"); + break; + case "z": + this.isState("casting-to-integer") ? i.push(this.output[2]) : i.push(this.output[2], ".0"); + break; + default: + throw this.astErrorOutput("Unexpected expression", t); + } + return i; + case "value": + throw this.astErrorOutput("Unexpected expression", t); + case "value[]": + case "value[][]": + case "value[][][]": + case "value[][][][]": + case "value.value": + if (m === "Math") + return i.push(Math[x2]), i; + let C = p.sanitizeName(x2); + switch (u) { + case "r": + return i.push(`user_${C}.r`), i; + case "g": + return i.push(`user_${C}.g`), i; + case "b": + return i.push(`user_${C}.b`), i; + case "a": + return i.push(`user_${C}.a`), i; + } + break; + case "this.constants.value": + if (typeof v > "u") + switch (S) { + case "Array(2)": + case "Array(3)": + case "Array(4)": + return i.push(`constants_${p.sanitizeName(x2)}`), i; + } + case "this.constants.value[]": + case "this.constants.value[][]": + case "this.constants.value[][][]": + case "this.constants.value[][][][]": + break; + case "fn()[]": + return this.astCallExpression(t.object, i), i.push("["), i.push(this.memberExpressionPropertyMarkup(u)), i.push("]"), i; + case "fn()[][]": + return this.astCallExpression(t.object.object, i), i.push("["), i.push(this.memberExpressionPropertyMarkup(t.object.property)), i.push("]"), i.push("["), i.push(this.memberExpressionPropertyMarkup(t.property)), i.push("]"), i; + case "[][]": + return this.astArrayExpression(t.object, i), i.push("["), i.push(this.memberExpressionPropertyMarkup(u)), i.push("]"), i; + default: + throw this.astErrorOutput("Unexpected expression", t); + } + if (t.computed === false) + switch (S) { + case "Number": + case "Integer": + case "Float": + case "Boolean": + return i.push(`${m}_${p.sanitizeName(x2)}`), i; + } + let T = `${m}_${p.sanitizeName(x2)}`; + switch (S) { + case "Array(2)": + case "Array(3)": + case "Array(4)": + this.astGeneric(t.object, i), i.push("["), i.push(this.memberExpressionPropertyMarkup(v)), i.push("]"); + break; + case "HTMLImageArray": + i.push(`getImage3D(${T}, ${T}Size, ${T}Dim, `), this.memberExpressionXYZ(v, h, b, i), i.push(")"); + break; + case "ArrayTexture(1)": + i.push(`getFloatFromSampler2D(${T}, ${T}Size, ${T}Dim, `), this.memberExpressionXYZ(v, h, b, i), i.push(")"); + break; + case "Array1D(2)": + case "Array2D(2)": + case "Array3D(2)": + i.push(`getMemoryOptimizedVec2(${T}, ${T}Size, ${T}Dim, `), this.memberExpressionXYZ(v, h, b, i), i.push(")"); + break; + case "ArrayTexture(2)": + i.push(`getVec2FromSampler2D(${T}, ${T}Size, ${T}Dim, `), this.memberExpressionXYZ(v, h, b, i), i.push(")"); + break; + case "Array1D(3)": + case "Array2D(3)": + case "Array3D(3)": + i.push(`getMemoryOptimizedVec3(${T}, ${T}Size, ${T}Dim, `), this.memberExpressionXYZ(v, h, b, i), i.push(")"); + break; + case "ArrayTexture(3)": + i.push(`getVec3FromSampler2D(${T}, ${T}Size, ${T}Dim, `), this.memberExpressionXYZ(v, h, b, i), i.push(")"); + break; + case "Array1D(4)": + case "Array2D(4)": + case "Array3D(4)": + i.push(`getMemoryOptimizedVec4(${T}, ${T}Size, ${T}Dim, `), this.memberExpressionXYZ(v, h, b, i), i.push(")"); + break; + case "ArrayTexture(4)": + case "HTMLCanvas": + case "HTMLImage": + case "HTMLVideo": + i.push(`getVec4FromSampler2D(${T}, ${T}Size, ${T}Dim, `), this.memberExpressionXYZ(v, h, b, i), i.push(")"); + break; + case "NumberTexture": + case "Array": + case "Array2D": + case "Array3D": + case "Array4D": + case "Input": + case "Number": + case "Float": + case "Integer": + if (this.precision === "single") + i.push(`getMemoryOptimized32(${T}, ${T}Size, ${T}Dim, `), this.memberExpressionXYZ(v, h, b, i), i.push(")"); + else { + let C = m === "user" ? this.lookupFunctionArgumentBitRatio(this.name, x2) : this.constantBitRatios[x2]; + switch (C) { + case 1: + i.push(`get8(${T}, ${T}Size, ${T}Dim, `); + break; + case 2: + i.push(`get16(${T}, ${T}Size, ${T}Dim, `); + break; + case 4: + case 0: + i.push(`get32(${T}, ${T}Size, ${T}Dim, `); + break; + default: + throw new Error(`unhandled bit ratio of ${C}`); + } + this.memberExpressionXYZ(v, h, b, i), i.push(")"); + } + break; + case "MemoryOptimizedNumberTexture": + i.push(`getMemoryOptimized32(${T}, ${T}Size, ${T}Dim, `), this.memberExpressionXYZ(v, h, b, i), i.push(")"); + break; + case "Matrix(2)": + case "Matrix(3)": + case "Matrix(4)": + i.push(`${T}[${this.memberExpressionPropertyMarkup(h)}]`), h && i.push(`[${this.memberExpressionPropertyMarkup(v)}]`); + break; + default: + throw new Error(`unhandled member expression "${S}"`); + } + return i; + } + astCallExpression(t, i) { + if (!t.callee) + throw this.astErrorOutput("Unknown CallExpression", t); + let u = null, x2 = this.isAstMathFunction(t); + if (x2 || t.callee.object && t.callee.object.type === "ThisExpression" ? u = t.callee.property.name : t.callee.type === "SequenceExpression" && t.callee.expressions[0].type === "Literal" && !isNaN(t.callee.expressions[0].raw) ? u = t.callee.expressions[1].property.name : u = t.callee.name, !u) + throw this.astErrorOutput("Unhandled function, couldn't find name", t); + switch (u) { + case "pow": + u = "_pow"; + break; + case "round": + u = "_round"; + break; + } + if (this.calledFunctions.indexOf(u) < 0 && this.calledFunctions.push(u), u === "random" && this.plugins && this.plugins.length > 0) + for (let w = 0; w < this.plugins.length; w++) { + let m = this.plugins[w]; + if (m.functionMatch === "Math.random()" && m.functionReplace) + return i.push(m.functionReplace), i; + } + if (this.onFunctionCall && this.onFunctionCall(this.name, u, t.arguments), i.push(u), i.push("("), x2) + for (let w = 0; w < t.arguments.length; ++w) { + let m = t.arguments[w], S = this.getType(m); + switch (w > 0 && i.push(", "), S) { + case "Integer": + this.castValueToFloat(m, i); + break; + default: + this.astGeneric(m, i); + break; + } + } + else { + let w = this.lookupFunctionArgumentTypes(u) || []; + for (let m = 0; m < t.arguments.length; ++m) { + let S = t.arguments[m], v = w[m]; + m > 0 && i.push(", "); + let h = this.getType(S); + switch (v || (this.triggerImplyArgumentType(u, m, h, this), v = h), h) { + case "Boolean": + this.astGeneric(S, i); + continue; + case "Number": + case "Float": + if (v === "Integer") { + i.push("int("), this.astGeneric(S, i), i.push(")"); + continue; + } else if (v === "Number" || v === "Float") { + this.astGeneric(S, i); + continue; + } else if (v === "LiteralInteger") { + this.castLiteralToFloat(S, i); + continue; + } + break; + case "Integer": + if (v === "Number" || v === "Float") { + i.push("float("), this.astGeneric(S, i), i.push(")"); + continue; + } else if (v === "Integer") { + this.astGeneric(S, i); + continue; + } + break; + case "LiteralInteger": + if (v === "Integer") { + this.castLiteralToInteger(S, i); + continue; + } else if (v === "Number" || v === "Float") { + this.castLiteralToFloat(S, i); + continue; + } else if (v === "LiteralInteger") { + this.astGeneric(S, i); + continue; + } + break; + case "Array(2)": + case "Array(3)": + case "Array(4)": + if (v === h) { + if (S.type === "Identifier") + i.push(`user_${p.sanitizeName(S.name)}`); + else if (S.type === "ArrayExpression" || S.type === "MemberExpression" || S.type === "CallExpression") + this.astGeneric(S, i); + else + throw this.astErrorOutput(`Unhandled argument type ${S.type}`, t); + continue; + } + break; + case "HTMLCanvas": + case "HTMLImage": + case "HTMLImageArray": + case "HTMLVideo": + case "ArrayTexture(1)": + case "ArrayTexture(2)": + case "ArrayTexture(3)": + case "ArrayTexture(4)": + case "Array": + case "Input": + if (v === h) { + if (S.type !== "Identifier") + throw this.astErrorOutput(`Unhandled argument type ${S.type}`, t); + this.triggerImplyArgumentBitRatio(this.name, S.name, u, m); + let b = p.sanitizeName(S.name); + i.push(`user_${b},user_${b}Size,user_${b}Dim`); + continue; + } + break; + } + throw this.astErrorOutput(`Unhandled argument combination of ${h} and ${v} for argument named "${S.name}"`, t); + } + } + return i.push(")"), i; + } + astArrayExpression(t, i) { + let u = this.getType(t), x2 = t.elements.length; + switch (u) { + case "Matrix(2)": + case "Matrix(3)": + case "Matrix(4)": + i.push(`mat${x2}(`); + break; + default: + i.push(`vec${x2}(`); + } + for (let w = 0; w < x2; ++w) { + w > 0 && i.push(", "); + let m = t.elements[w]; + this.astGeneric(m, i); + } + return i.push(")"), i; + } + memberExpressionXYZ(t, i, u, x2) { + return u ? x2.push(this.memberExpressionPropertyMarkup(u), ", ") : x2.push("0, "), i ? x2.push(this.memberExpressionPropertyMarkup(i), ", ") : x2.push("0, "), x2.push(this.memberExpressionPropertyMarkup(t)), x2; + } + memberExpressionPropertyMarkup(t) { + if (!t) + throw new Error("Property not set"); + let i = this.getType(t), u = []; + switch (i) { + case "Number": + case "Float": + this.castValueToInteger(t, u); + break; + case "LiteralInteger": + this.castLiteralToInteger(t, u); + break; + default: + this.astGeneric(t, u); + } + return u.join(""); + } + } + let l = { Array: "sampler2D", "Array(2)": "vec2", "Array(3)": "vec3", "Array(4)": "vec4", "Matrix(2)": "mat2", "Matrix(3)": "mat3", "Matrix(4)": "mat4", Array2D: "sampler2D", Array3D: "sampler2D", Boolean: "bool", Float: "float", Input: "sampler2D", Integer: "int", Number: "float", LiteralInteger: "float", NumberTexture: "sampler2D", MemoryOptimizedNumberTexture: "sampler2D", "ArrayTexture(1)": "sampler2D", "ArrayTexture(2)": "sampler2D", "ArrayTexture(3)": "sampler2D", "ArrayTexture(4)": "sampler2D", HTMLVideo: "sampler2D", HTMLCanvas: "sampler2D", HTMLImage: "sampler2D", HTMLImageArray: "sampler2DArray" }, n = { "===": "==", "!==": "!=" }; + y.exports = { WebGLFunctionNode: f }; + }, { "../../utils": 114, "../function-node": 10 }], 39: [function(o, y, E) { + let { WebGLKernelValueBoolean: p } = o("./kernel-value/boolean"), { WebGLKernelValueFloat: g } = o("./kernel-value/float"), { WebGLKernelValueInteger: f } = o("./kernel-value/integer"), { WebGLKernelValueHTMLImage: l } = o("./kernel-value/html-image"), { WebGLKernelValueDynamicHTMLImage: n } = o("./kernel-value/dynamic-html-image"), { WebGLKernelValueHTMLVideo: s } = o("./kernel-value/html-video"), { WebGLKernelValueDynamicHTMLVideo: t } = o("./kernel-value/dynamic-html-video"), { WebGLKernelValueSingleInput: i } = o("./kernel-value/single-input"), { WebGLKernelValueDynamicSingleInput: u } = o("./kernel-value/dynamic-single-input"), { WebGLKernelValueUnsignedInput: x2 } = o("./kernel-value/unsigned-input"), { WebGLKernelValueDynamicUnsignedInput: w } = o("./kernel-value/dynamic-unsigned-input"), { WebGLKernelValueMemoryOptimizedNumberTexture: m } = o("./kernel-value/memory-optimized-number-texture"), { WebGLKernelValueDynamicMemoryOptimizedNumberTexture: S } = o("./kernel-value/dynamic-memory-optimized-number-texture"), { WebGLKernelValueNumberTexture: v } = o("./kernel-value/number-texture"), { WebGLKernelValueDynamicNumberTexture: h } = o("./kernel-value/dynamic-number-texture"), { WebGLKernelValueSingleArray: b } = o("./kernel-value/single-array"), { WebGLKernelValueDynamicSingleArray: T } = o("./kernel-value/dynamic-single-array"), { WebGLKernelValueSingleArray1DI: C } = o("./kernel-value/single-array1d-i"), { WebGLKernelValueDynamicSingleArray1DI: V } = o("./kernel-value/dynamic-single-array1d-i"), { WebGLKernelValueSingleArray2DI: c } = o("./kernel-value/single-array2d-i"), { WebGLKernelValueDynamicSingleArray2DI: a } = o("./kernel-value/dynamic-single-array2d-i"), { WebGLKernelValueSingleArray3DI: k } = o("./kernel-value/single-array3d-i"), { WebGLKernelValueDynamicSingleArray3DI: A } = o("./kernel-value/dynamic-single-array3d-i"), { WebGLKernelValueSingleArray2: N } = o("./kernel-value/single-array2"), { WebGLKernelValueSingleArray3: F } = o("./kernel-value/single-array3"), { WebGLKernelValueSingleArray4: R } = o("./kernel-value/single-array4"), { WebGLKernelValueUnsignedArray: K } = o("./kernel-value/unsigned-array"), { WebGLKernelValueDynamicUnsignedArray: O } = o("./kernel-value/dynamic-unsigned-array"), X = { unsigned: { dynamic: { Boolean: p, Integer: f, Float: g, Array: O, "Array(2)": false, "Array(3)": false, "Array(4)": false, "Array1D(2)": false, "Array1D(3)": false, "Array1D(4)": false, "Array2D(2)": false, "Array2D(3)": false, "Array2D(4)": false, "Array3D(2)": false, "Array3D(3)": false, "Array3D(4)": false, Input: w, NumberTexture: h, "ArrayTexture(1)": h, "ArrayTexture(2)": h, "ArrayTexture(3)": h, "ArrayTexture(4)": h, MemoryOptimizedNumberTexture: S, HTMLCanvas: n, HTMLImage: n, HTMLImageArray: false, HTMLVideo: t }, static: { Boolean: p, Float: g, Integer: f, Array: K, "Array(2)": false, "Array(3)": false, "Array(4)": false, "Array1D(2)": false, "Array1D(3)": false, "Array1D(4)": false, "Array2D(2)": false, "Array2D(3)": false, "Array2D(4)": false, "Array3D(2)": false, "Array3D(3)": false, "Array3D(4)": false, Input: x2, NumberTexture: v, "ArrayTexture(1)": v, "ArrayTexture(2)": v, "ArrayTexture(3)": v, "ArrayTexture(4)": v, MemoryOptimizedNumberTexture: m, HTMLCanvas: l, HTMLImage: l, HTMLImageArray: false, HTMLVideo: s } }, single: { dynamic: { Boolean: p, Integer: f, Float: g, Array: T, "Array(2)": N, "Array(3)": F, "Array(4)": R, "Array1D(2)": V, "Array1D(3)": V, "Array1D(4)": V, "Array2D(2)": a, "Array2D(3)": a, "Array2D(4)": a, "Array3D(2)": A, "Array3D(3)": A, "Array3D(4)": A, Input: u, NumberTexture: h, "ArrayTexture(1)": h, "ArrayTexture(2)": h, "ArrayTexture(3)": h, "ArrayTexture(4)": h, MemoryOptimizedNumberTexture: S, HTMLCanvas: n, HTMLImage: n, HTMLImageArray: false, HTMLVideo: t }, static: { Boolean: p, Float: g, Integer: f, Array: b, "Array(2)": N, "Array(3)": F, "Array(4)": R, "Array1D(2)": C, "Array1D(3)": C, "Array1D(4)": C, "Array2D(2)": c, "Array2D(3)": c, "Array2D(4)": c, "Array3D(2)": k, "Array3D(3)": k, "Array3D(4)": k, Input: i, NumberTexture: v, "ArrayTexture(1)": v, "ArrayTexture(2)": v, "ArrayTexture(3)": v, "ArrayTexture(4)": v, MemoryOptimizedNumberTexture: m, HTMLCanvas: l, HTMLImage: l, HTMLImageArray: false, HTMLVideo: s } } }; + function B(P, Y, J, q) { + if (!P) + throw new Error("type missing"); + if (!Y) + throw new Error("dynamic missing"); + if (!J) + throw new Error("precision missing"); + q.type && (P = q.type); + let j = X[J][Y]; + if (j[P] === false) + return null; + if (j[P] === void 0) + throw new Error(`Could not find a KernelValue for ${P}`); + return j[P]; + } + y.exports = { lookupKernelValueType: B, kernelValueMaps: X }; + }, { "./kernel-value/boolean": 41, "./kernel-value/dynamic-html-image": 42, "./kernel-value/dynamic-html-video": 43, "./kernel-value/dynamic-memory-optimized-number-texture": 44, "./kernel-value/dynamic-number-texture": 45, "./kernel-value/dynamic-single-array": 46, "./kernel-value/dynamic-single-array1d-i": 47, "./kernel-value/dynamic-single-array2d-i": 48, "./kernel-value/dynamic-single-array3d-i": 49, "./kernel-value/dynamic-single-input": 50, "./kernel-value/dynamic-unsigned-array": 51, "./kernel-value/dynamic-unsigned-input": 52, "./kernel-value/float": 53, "./kernel-value/html-image": 54, "./kernel-value/html-video": 55, "./kernel-value/integer": 57, "./kernel-value/memory-optimized-number-texture": 58, "./kernel-value/number-texture": 59, "./kernel-value/single-array": 60, "./kernel-value/single-array1d-i": 61, "./kernel-value/single-array2": 62, "./kernel-value/single-array2d-i": 63, "./kernel-value/single-array3": 64, "./kernel-value/single-array3d-i": 65, "./kernel-value/single-array4": 66, "./kernel-value/single-input": 67, "./kernel-value/unsigned-array": 68, "./kernel-value/unsigned-input": 69 }], 40: [function(o, y, E) { + let { WebGLKernelValue: p } = o("./index"), { Input: g } = o("../../../input"); + class f extends p { + checkSize(n, s) { + if (!this.kernel.validate) + return; + let { maxTextureSize: t } = this.kernel.constructor.features; + if (n > t || s > t) + throw n > s ? new Error(`Argument texture width of ${n} larger than maximum size of ${t} for your GPU`) : n < s ? new Error(`Argument texture height of ${s} larger than maximum size of ${t} for your GPU`) : new Error(`Argument texture height and width of ${s} larger than maximum size of ${t} for your GPU`); + } + setup() { + this.requestTexture(), this.setupTexture(), this.defineTexture(); + } + requestTexture() { + this.texture = this.onRequestTexture(); + } + defineTexture() { + let { context: n } = this; + n.activeTexture(this.contextHandle), n.bindTexture(n.TEXTURE_2D, this.texture), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_WRAP_S, n.CLAMP_TO_EDGE), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_WRAP_T, n.CLAMP_TO_EDGE), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_MIN_FILTER, n.NEAREST), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_MAG_FILTER, n.NEAREST); + } + setupTexture() { + this.contextHandle = this.onRequestContextHandle(), this.index = this.onRequestIndex(), this.dimensionsId = this.id + "Dim", this.sizeId = this.id + "Size"; + } + getBitRatio(n) { + if (Array.isArray(n[0])) + return this.getBitRatio(n[0]); + if (n.constructor === g) + return this.getBitRatio(n.value); + switch (n.constructor) { + case Uint8ClampedArray: + case Uint8Array: + case Int8Array: + return 1; + case Uint16Array: + case Int16Array: + return 2; + case Float32Array: + case Int32Array: + default: + return 4; + } + } + destroy() { + this.prevArg && this.prevArg.delete(), this.context.deleteTexture(this.texture); + } + } + y.exports = { WebGLKernelArray: f }; + }, { "../../../input": 110, "./index": 56 }], 41: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValue: g } = o("./index"); + class f extends g { + constructor(n, s) { + super(n, s), this.uploadValue = n; + } + getSource(n) { + return this.origin === "constants" ? `const bool ${this.id} = ${n}; +` : `uniform bool ${this.id}; +`; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName}; +`; + } + updateValue(n) { + this.origin !== "constants" && this.kernel.setUniform1i(this.id, this.uploadValue = n); + } + } + y.exports = { WebGLKernelValueBoolean: f }; + }, { "../../../utils": 114, "./index": 56 }], 42: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueHTMLImage: g } = o("./html-image"); + class f extends g { + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `uniform ivec2 ${this.sizeId}`, `uniform ivec3 ${this.dimensionsId}`]); + } + updateValue(n) { + let { width: s, height: t } = n; + this.checkSize(s, t), this.dimensions = [s, t, 1], this.textureSize = [s, t], this.kernel.setUniform3iv(this.dimensionsId, this.dimensions), this.kernel.setUniform2iv(this.sizeId, this.textureSize), super.updateValue(n); + } + } + y.exports = { WebGLKernelValueDynamicHTMLImage: f }; + }, { "../../../utils": 114, "./html-image": 54 }], 43: [function(o, y, E) { + let { WebGLKernelValueDynamicHTMLImage: p } = o("./dynamic-html-image"); + class g extends p { + } + y.exports = { WebGLKernelValueDynamicHTMLVideo: g }; + }, { "./dynamic-html-image": 42 }], 44: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueMemoryOptimizedNumberTexture: g } = o("./memory-optimized-number-texture"); + class f extends g { + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `uniform ivec2 ${this.sizeId}`, `uniform ivec3 ${this.dimensionsId}`]); + } + updateValue(n) { + this.dimensions = n.dimensions, this.checkSize(n.size[0], n.size[1]), this.textureSize = n.size, this.kernel.setUniform3iv(this.dimensionsId, this.dimensions), this.kernel.setUniform2iv(this.sizeId, this.textureSize), super.updateValue(n); + } + } + y.exports = { WebGLKernelValueDynamicMemoryOptimizedNumberTexture: f }; + }, { "../../../utils": 114, "./memory-optimized-number-texture": 58 }], 45: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueNumberTexture: g } = o("./number-texture"); + class f extends g { + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `uniform ivec2 ${this.sizeId}`, `uniform ivec3 ${this.dimensionsId}`]); + } + updateValue(n) { + this.dimensions = n.dimensions, this.checkSize(n.size[0], n.size[1]), this.textureSize = n.size, this.kernel.setUniform3iv(this.dimensionsId, this.dimensions), this.kernel.setUniform2iv(this.sizeId, this.textureSize), super.updateValue(n); + } + } + y.exports = { WebGLKernelValueDynamicNumberTexture: f }; + }, { "../../../utils": 114, "./number-texture": 59 }], 46: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueSingleArray: g } = o("./single-array"); + class f extends g { + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `uniform ivec2 ${this.sizeId}`, `uniform ivec3 ${this.dimensionsId}`]); + } + updateValue(n) { + this.dimensions = p.getDimensions(n, true), this.textureSize = p.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio), this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio, this.checkSize(this.textureSize[0], this.textureSize[1]), this.uploadValue = new Float32Array(this.uploadArrayLength), this.kernel.setUniform3iv(this.dimensionsId, this.dimensions), this.kernel.setUniform2iv(this.sizeId, this.textureSize), super.updateValue(n); + } + } + y.exports = { WebGLKernelValueDynamicSingleArray: f }; + }, { "../../../utils": 114, "./single-array": 60 }], 47: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueSingleArray1DI: g } = o("./single-array1d-i"); + class f extends g { + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `uniform ivec2 ${this.sizeId}`, `uniform ivec3 ${this.dimensionsId}`]); + } + updateValue(n) { + this.setShape(n), this.kernel.setUniform3iv(this.dimensionsId, this.dimensions), this.kernel.setUniform2iv(this.sizeId, this.textureSize), super.updateValue(n); + } + } + y.exports = { WebGLKernelValueDynamicSingleArray1DI: f }; + }, { "../../../utils": 114, "./single-array1d-i": 61 }], 48: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueSingleArray2DI: g } = o("./single-array2d-i"); + class f extends g { + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `uniform ivec2 ${this.sizeId}`, `uniform ivec3 ${this.dimensionsId}`]); + } + updateValue(n) { + this.setShape(n), this.kernel.setUniform3iv(this.dimensionsId, this.dimensions), this.kernel.setUniform2iv(this.sizeId, this.textureSize), super.updateValue(n); + } + } + y.exports = { WebGLKernelValueDynamicSingleArray2DI: f }; + }, { "../../../utils": 114, "./single-array2d-i": 63 }], 49: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueSingleArray3DI: g } = o("./single-array3d-i"); + class f extends g { + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `uniform ivec2 ${this.sizeId}`, `uniform ivec3 ${this.dimensionsId}`]); + } + updateValue(n) { + this.setShape(n), this.kernel.setUniform3iv(this.dimensionsId, this.dimensions), this.kernel.setUniform2iv(this.sizeId, this.textureSize), super.updateValue(n); + } + } + y.exports = { WebGLKernelValueDynamicSingleArray3DI: f }; + }, { "../../../utils": 114, "./single-array3d-i": 65 }], 50: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueSingleInput: g } = o("./single-input"); + class f extends g { + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `uniform ivec2 ${this.sizeId}`, `uniform ivec3 ${this.dimensionsId}`]); + } + updateValue(n) { + let [s, t, i] = n.size; + this.dimensions = new Int32Array([s || 1, t || 1, i || 1]), this.textureSize = p.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio), this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio, this.checkSize(this.textureSize[0], this.textureSize[1]), this.uploadValue = new Float32Array(this.uploadArrayLength), this.kernel.setUniform3iv(this.dimensionsId, this.dimensions), this.kernel.setUniform2iv(this.sizeId, this.textureSize), super.updateValue(n); + } + } + y.exports = { WebGLKernelValueDynamicSingleInput: f }; + }, { "../../../utils": 114, "./single-input": 67 }], 51: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueUnsignedArray: g } = o("./unsigned-array"); + class f extends g { + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `uniform ivec2 ${this.sizeId}`, `uniform ivec3 ${this.dimensionsId}`]); + } + updateValue(n) { + this.dimensions = p.getDimensions(n, true), this.textureSize = p.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio), this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio), this.checkSize(this.textureSize[0], this.textureSize[1]); + let s = this.getTransferArrayType(n); + this.preUploadValue = new s(this.uploadArrayLength), this.uploadValue = new Uint8Array(this.preUploadValue.buffer), this.kernel.setUniform3iv(this.dimensionsId, this.dimensions), this.kernel.setUniform2iv(this.sizeId, this.textureSize), super.updateValue(n); + } + } + y.exports = { WebGLKernelValueDynamicUnsignedArray: f }; + }, { "../../../utils": 114, "./unsigned-array": 68 }], 52: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueUnsignedInput: g } = o("./unsigned-input"); + class f extends g { + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `uniform ivec2 ${this.sizeId}`, `uniform ivec3 ${this.dimensionsId}`]); + } + updateValue(n) { + let [s, t, i] = n.size; + this.dimensions = new Int32Array([s || 1, t || 1, i || 1]), this.textureSize = p.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio), this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio), this.checkSize(this.textureSize[0], this.textureSize[1]); + let u = this.getTransferArrayType(n.value); + this.preUploadValue = new u(this.uploadArrayLength), this.uploadValue = new Uint8Array(this.preUploadValue.buffer), this.kernel.setUniform3iv(this.dimensionsId, this.dimensions), this.kernel.setUniform2iv(this.sizeId, this.textureSize), super.updateValue(n); + } + } + y.exports = { WebGLKernelValueDynamicUnsignedInput: f }; + }, { "../../../utils": 114, "./unsigned-input": 69 }], 53: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValue: g } = o("./index"); + class f extends g { + constructor(n, s) { + super(n, s), this.uploadValue = n; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName}; +`; + } + getSource(n) { + return this.origin === "constants" ? Number.isInteger(n) ? `const float ${this.id} = ${n}.0; +` : `const float ${this.id} = ${n}; +` : `uniform float ${this.id}; +`; + } + updateValue(n) { + this.origin !== "constants" && this.kernel.setUniform1f(this.id, this.uploadValue = n); + } + } + y.exports = { WebGLKernelValueFloat: f }; + }, { "../../../utils": 114, "./index": 56 }], 54: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelArray: g } = o("./array"); + class f extends g { + constructor(n, s) { + super(n, s); + let { width: t, height: i } = n; + this.checkSize(t, i), this.dimensions = [t, i, 1], this.textureSize = [t, i], this.uploadValue = n; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName}; +`; + } + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`]); + } + updateValue(n) { + if (n.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(n.constructor); + return; + } + let { context: s } = this; + s.activeTexture(this.contextHandle), s.bindTexture(s.TEXTURE_2D, this.texture), s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL, true), s.texImage2D(s.TEXTURE_2D, 0, s.RGBA, s.RGBA, s.UNSIGNED_BYTE, this.uploadValue = n), this.kernel.setUniform1i(this.id, this.index); + } + } + y.exports = { WebGLKernelValueHTMLImage: f }; + }, { "../../../utils": 114, "./array": 40 }], 55: [function(o, y, E) { + let { WebGLKernelValueHTMLImage: p } = o("./html-image"); + class g extends p { + } + y.exports = { WebGLKernelValueHTMLVideo: g }; + }, { "./html-image": 54 }], 56: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { KernelValue: g } = o("../../kernel-value"); + class f extends g { + constructor(n, s) { + super(n, s), this.dimensionsId = null, this.sizeId = null, this.initialValueConstructor = n.constructor, this.onRequestTexture = s.onRequestTexture, this.onRequestIndex = s.onRequestIndex, this.uploadValue = null, this.textureSize = null, this.bitRatio = null, this.prevArg = null; + } + get id() { + return `${this.origin}_${p.sanitizeName(this.name)}`; + } + setup() { + } + getTransferArrayType(n) { + if (Array.isArray(n[0])) + return this.getTransferArrayType(n[0]); + switch (n.constructor) { + case Array: + case Int32Array: + case Int16Array: + case Int8Array: + return Float32Array; + case Uint8ClampedArray: + case Uint8Array: + case Uint16Array: + case Uint32Array: + case Float32Array: + case Float64Array: + return n.constructor; + } + return console.warn("Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros"), n.constructor; + } + getStringValueHandler() { + throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`); + } + getVariablePrecisionString() { + return this.kernel.getVariablePrecisionString(this.textureSize || void 0, this.tactic || void 0); + } + destroy() { + } + } + y.exports = { WebGLKernelValue: f }; + }, { "../../../utils": 114, "../../kernel-value": 35 }], 57: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValue: g } = o("./index"); + class f extends g { + constructor(n, s) { + super(n, s), this.uploadValue = n; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName}; +`; + } + getSource(n) { + return this.origin === "constants" ? `const int ${this.id} = ${parseInt(n)}; +` : `uniform int ${this.id}; +`; + } + updateValue(n) { + this.origin !== "constants" && this.kernel.setUniform1i(this.id, this.uploadValue = n); + } + } + y.exports = { WebGLKernelValueInteger: f }; + }, { "../../../utils": 114, "./index": 56 }], 58: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelArray: g } = o("./array"), f = "Source and destination textures are the same. Use immutable = true and manually cleanup kernel output texture memory with texture.delete()"; + class l extends g { + constructor(s, t) { + super(s, t); + let [i, u] = s.size; + this.checkSize(i, u), this.dimensions = s.dimensions, this.textureSize = s.size, this.uploadValue = s.texture, this.forceUploadEachRun = true; + } + setup() { + this.setupTexture(); + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName}.texture; +`; + } + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`]); + } + updateValue(s) { + if (s.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(s.constructor); + return; + } + if (this.checkContext && s.context !== this.context) + throw new Error(`Value ${this.name} (${this.type}) must be from same context`); + let { kernel: t, context: i } = this; + if (t.pipeline) + if (t.immutable) + t.updateTextureArgumentRefs(this, s); + else { + if (t.texture.texture === s.texture) + throw new Error(f); + if (t.mappedTextures) { + let { mappedTextures: u } = t; + for (let x2 = 0; x2 < u.length; x2++) + if (u[x2].texture === s.texture) + throw new Error(f); + } + } + i.activeTexture(this.contextHandle), i.bindTexture(i.TEXTURE_2D, this.uploadValue = s.texture), this.kernel.setUniform1i(this.id, this.index); + } + } + y.exports = { WebGLKernelValueMemoryOptimizedNumberTexture: l, sameError: f }; + }, { "../../../utils": 114, "./array": 40 }], 59: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelArray: g } = o("./array"), { sameError: f } = o("./memory-optimized-number-texture"); + class l extends g { + constructor(s, t) { + super(s, t); + let [i, u] = s.size; + this.checkSize(i, u); + let { size: x2, dimensions: w } = s; + this.bitRatio = this.getBitRatio(s), this.dimensions = w, this.textureSize = x2, this.uploadValue = s.texture, this.forceUploadEachRun = true; + } + setup() { + this.setupTexture(); + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName}.texture; +`; + } + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`]); + } + updateValue(s) { + if (s.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(s.constructor); + return; + } + if (this.checkContext && s.context !== this.context) + throw new Error(`Value ${this.name} (${this.type}) must be from same context`); + let { kernel: t, context: i } = this; + if (t.pipeline) + if (t.immutable) + t.updateTextureArgumentRefs(this, s); + else { + if (t.texture.texture === s.texture) + throw new Error(f); + if (t.mappedTextures) { + let { mappedTextures: u } = t; + for (let x2 = 0; x2 < u.length; x2++) + if (u[x2].texture === s.texture) + throw new Error(f); + } + } + i.activeTexture(this.contextHandle), i.bindTexture(i.TEXTURE_2D, this.uploadValue = s.texture), this.kernel.setUniform1i(this.id, this.index); + } + } + y.exports = { WebGLKernelValueNumberTexture: l }; + }, { "../../../utils": 114, "./array": 40, "./memory-optimized-number-texture": 58 }], 60: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelArray: g } = o("./array"); + class f extends g { + constructor(n, s) { + super(n, s), this.bitRatio = 4, this.dimensions = p.getDimensions(n, true), this.textureSize = p.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio), this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio, this.checkSize(this.textureSize[0], this.textureSize[1]), this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return p.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, `flattenTo(${this.varName}, uploadValue_${this.name})`]); + } + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`]); + } + updateValue(n) { + if (n.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(n.constructor); + return; + } + let { context: s } = this; + p.flattenTo(n, this.uploadValue), s.activeTexture(this.contextHandle), s.bindTexture(s.TEXTURE_2D, this.texture), s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL, false), s.texImage2D(s.TEXTURE_2D, 0, s.RGBA, this.textureSize[0], this.textureSize[1], 0, s.RGBA, s.FLOAT, this.uploadValue), this.kernel.setUniform1i(this.id, this.index); + } + } + y.exports = { WebGLKernelValueSingleArray: f }; + }, { "../../../utils": 114, "./array": 40 }], 61: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelArray: g } = o("./array"); + class f extends g { + constructor(n, s) { + super(n, s), this.bitRatio = 4, this.setShape(n); + } + setShape(n) { + let s = p.getDimensions(n, true); + this.textureSize = p.getMemoryOptimizedFloatTextureSize(s, this.bitRatio), this.dimensions = new Int32Array([s[1], 1, 1]), this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio, this.checkSize(this.textureSize[0], this.textureSize[1]), this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return p.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, `flattenTo(${this.varName}, uploadValue_${this.name})`]); + } + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`]); + } + updateValue(n) { + if (n.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(n.constructor); + return; + } + let { context: s } = this; + p.flatten2dArrayTo(n, this.uploadValue), s.activeTexture(this.contextHandle), s.bindTexture(s.TEXTURE_2D, this.texture), s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL, false), s.texImage2D(s.TEXTURE_2D, 0, s.RGBA, this.textureSize[0], this.textureSize[1], 0, s.RGBA, s.FLOAT, this.uploadValue), this.kernel.setUniform1i(this.id, this.index); + } + } + y.exports = { WebGLKernelValueSingleArray1DI: f }; + }, { "../../../utils": 114, "./array": 40 }], 62: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValue: g } = o("./index"); + class f extends g { + constructor(n, s) { + super(n, s), this.uploadValue = n; + } + getSource(n) { + return this.origin === "constants" ? `const vec2 ${this.id} = vec2(${n[0]},${n[1]}); +` : `uniform vec2 ${this.id}; +`; + } + getStringValueHandler() { + return this.origin === "constants" ? "" : `const uploadValue_${this.name} = ${this.varName}; +`; + } + updateValue(n) { + this.origin !== "constants" && this.kernel.setUniform2fv(this.id, this.uploadValue = n); + } + } + y.exports = { WebGLKernelValueSingleArray2: f }; + }, { "../../../utils": 114, "./index": 56 }], 63: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelArray: g } = o("./array"); + class f extends g { + constructor(n, s) { + super(n, s), this.bitRatio = 4, this.setShape(n); + } + setShape(n) { + let s = p.getDimensions(n, true); + this.textureSize = p.getMemoryOptimizedFloatTextureSize(s, this.bitRatio), this.dimensions = new Int32Array([s[1], s[2], 1]), this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio, this.checkSize(this.textureSize[0], this.textureSize[1]), this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return p.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, `flattenTo(${this.varName}, uploadValue_${this.name})`]); + } + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`]); + } + updateValue(n) { + if (n.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(n.constructor); + return; + } + let { context: s } = this; + p.flatten3dArrayTo(n, this.uploadValue), s.activeTexture(this.contextHandle), s.bindTexture(s.TEXTURE_2D, this.texture), s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL, false), s.texImage2D(s.TEXTURE_2D, 0, s.RGBA, this.textureSize[0], this.textureSize[1], 0, s.RGBA, s.FLOAT, this.uploadValue), this.kernel.setUniform1i(this.id, this.index); + } + } + y.exports = { WebGLKernelValueSingleArray2DI: f }; + }, { "../../../utils": 114, "./array": 40 }], 64: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValue: g } = o("./index"); + class f extends g { + constructor(n, s) { + super(n, s), this.uploadValue = n; + } + getSource(n) { + return this.origin === "constants" ? `const vec3 ${this.id} = vec3(${n[0]},${n[1]},${n[2]}); +` : `uniform vec3 ${this.id}; +`; + } + getStringValueHandler() { + return this.origin === "constants" ? "" : `const uploadValue_${this.name} = ${this.varName}; +`; + } + updateValue(n) { + this.origin !== "constants" && this.kernel.setUniform3fv(this.id, this.uploadValue = n); + } + } + y.exports = { WebGLKernelValueSingleArray3: f }; + }, { "../../../utils": 114, "./index": 56 }], 65: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelArray: g } = o("./array"); + class f extends g { + constructor(n, s) { + super(n, s), this.bitRatio = 4, this.setShape(n); + } + setShape(n) { + let s = p.getDimensions(n, true); + this.textureSize = p.getMemoryOptimizedFloatTextureSize(s, this.bitRatio), this.dimensions = new Int32Array([s[1], s[2], s[3]]), this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio, this.checkSize(this.textureSize[0], this.textureSize[1]), this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return p.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, `flattenTo(${this.varName}, uploadValue_${this.name})`]); + } + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`]); + } + updateValue(n) { + if (n.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(n.constructor); + return; + } + let { context: s } = this; + p.flatten4dArrayTo(n, this.uploadValue), s.activeTexture(this.contextHandle), s.bindTexture(s.TEXTURE_2D, this.texture), s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL, false), s.texImage2D(s.TEXTURE_2D, 0, s.RGBA, this.textureSize[0], this.textureSize[1], 0, s.RGBA, s.FLOAT, this.uploadValue), this.kernel.setUniform1i(this.id, this.index); + } + } + y.exports = { WebGLKernelValueSingleArray3DI: f }; + }, { "../../../utils": 114, "./array": 40 }], 66: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValue: g } = o("./index"); + class f extends g { + constructor(n, s) { + super(n, s), this.uploadValue = n; + } + getSource(n) { + return this.origin === "constants" ? `const vec4 ${this.id} = vec4(${n[0]},${n[1]},${n[2]},${n[3]}); +` : `uniform vec4 ${this.id}; +`; + } + getStringValueHandler() { + return this.origin === "constants" ? "" : `const uploadValue_${this.name} = ${this.varName}; +`; + } + updateValue(n) { + this.origin !== "constants" && this.kernel.setUniform4fv(this.id, this.uploadValue = n); + } + } + y.exports = { WebGLKernelValueSingleArray4: f }; + }, { "../../../utils": 114, "./index": 56 }], 67: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelArray: g } = o("./array"); + class f extends g { + constructor(n, s) { + super(n, s), this.bitRatio = 4; + let [t, i, u] = n.size; + this.dimensions = new Int32Array([t || 1, i || 1, u || 1]), this.textureSize = p.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio), this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio, this.checkSize(this.textureSize[0], this.textureSize[1]), this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return p.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, `flattenTo(${this.varName}.value, uploadValue_${this.name})`]); + } + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`]); + } + updateValue(n) { + if (n.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(n.constructor); + return; + } + let { context: s } = this; + p.flattenTo(n.value, this.uploadValue), s.activeTexture(this.contextHandle), s.bindTexture(s.TEXTURE_2D, this.texture), s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL, false), s.texImage2D(s.TEXTURE_2D, 0, s.RGBA, this.textureSize[0], this.textureSize[1], 0, s.RGBA, s.FLOAT, this.uploadValue), this.kernel.setUniform1i(this.id, this.index); + } + } + y.exports = { WebGLKernelValueSingleInput: f }; + }, { "../../../utils": 114, "./array": 40 }], 68: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelArray: g } = o("./array"); + class f extends g { + constructor(n, s) { + super(n, s), this.bitRatio = this.getBitRatio(n), this.dimensions = p.getDimensions(n, true), this.textureSize = p.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio), this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio), this.checkSize(this.textureSize[0], this.textureSize[1]), this.TranserArrayType = this.getTransferArrayType(n), this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength), this.uploadValue = new Uint8Array(this.preUploadValue.buffer); + } + getStringValueHandler() { + return p.linesToString([`const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`, `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`, `flattenTo(${this.varName}, preUploadValue_${this.name})`]); + } + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`]); + } + updateValue(n) { + if (n.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(n.constructor); + return; + } + let { context: s } = this; + p.flattenTo(n, this.preUploadValue), s.activeTexture(this.contextHandle), s.bindTexture(s.TEXTURE_2D, this.texture), s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL, false), s.texImage2D(s.TEXTURE_2D, 0, s.RGBA, this.textureSize[0], this.textureSize[1], 0, s.RGBA, s.UNSIGNED_BYTE, this.uploadValue), this.kernel.setUniform1i(this.id, this.index); + } + } + y.exports = { WebGLKernelValueUnsignedArray: f }; + }, { "../../../utils": 114, "./array": 40 }], 69: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelArray: g } = o("./array"); + class f extends g { + constructor(n, s) { + super(n, s), this.bitRatio = this.getBitRatio(n); + let [t, i, u] = n.size; + this.dimensions = new Int32Array([t || 1, i || 1, u || 1]), this.textureSize = p.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio), this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio), this.checkSize(this.textureSize[0], this.textureSize[1]), this.TranserArrayType = this.getTransferArrayType(n.value), this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength), this.uploadValue = new Uint8Array(this.preUploadValue.buffer); + } + getStringValueHandler() { + return p.linesToString([`const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`, `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`, `flattenTo(${this.varName}.value, preUploadValue_${this.name})`]); + } + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`]); + } + updateValue(n) { + if (n.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(value.constructor); + return; + } + let { context: s } = this; + p.flattenTo(n.value, this.preUploadValue), s.activeTexture(this.contextHandle), s.bindTexture(s.TEXTURE_2D, this.texture), s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL, false), s.texImage2D(s.TEXTURE_2D, 0, s.RGBA, this.textureSize[0], this.textureSize[1], 0, s.RGBA, s.UNSIGNED_BYTE, this.uploadValue), this.kernel.setUniform1i(this.id, this.index); + } + } + y.exports = { WebGLKernelValueUnsignedInput: f }; + }, { "../../../utils": 114, "./array": 40 }], 70: [function(o, y, E) { + let { GLKernel: p } = o("../gl/kernel"), { FunctionBuilder: g } = o("../function-builder"), { WebGLFunctionNode: f } = o("./function-node"), { utils: l } = o("../../utils"), n = o("../../plugins/math-random-uniformly-distributed"), { fragmentShader: s } = o("./fragment-shader"), { vertexShader: t } = o("./vertex-shader"), { glKernelString: i } = o("../gl/kernel-string"), { lookupKernelValueType: u } = o("./kernel-value-maps"), x2 = null, w = null, m = null, S = null, v = null, h = [n], b = [], T = {}; + class C extends p { + static get isSupported() { + return x2 !== null || (this.setupFeatureChecks(), x2 = this.isContextMatch(m)), x2; + } + static setupFeatureChecks() { + typeof document < "u" ? w = document.createElement("canvas") : typeof OffscreenCanvas < "u" && (w = new OffscreenCanvas(0, 0)), w && (m = w.getContext("webgl") || w.getContext("experimental-webgl"), !(!m || !m.getExtension) && (S = { OES_texture_float: m.getExtension("OES_texture_float"), OES_texture_float_linear: m.getExtension("OES_texture_float_linear"), OES_element_index_uint: m.getExtension("OES_element_index_uint"), WEBGL_draw_buffers: m.getExtension("WEBGL_draw_buffers") }, v = this.getFeatures())); + } + static isContextMatch(c) { + return typeof WebGLRenderingContext < "u" ? c instanceof WebGLRenderingContext : false; + } + static getIsTextureFloat() { + return Boolean(S.OES_texture_float); + } + static getIsDrawBuffers() { + return Boolean(S.WEBGL_draw_buffers); + } + static getChannelCount() { + return S.WEBGL_draw_buffers ? m.getParameter(S.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) : 1; + } + static getMaxTextureSize() { + return m.getParameter(m.MAX_TEXTURE_SIZE); + } + static lookupKernelValueType(c, a, k, A) { + return u(c, a, k, A); + } + static get testCanvas() { + return w; + } + static get testContext() { + return m; + } + static get features() { + return v; + } + static get fragmentShader() { + return s; + } + static get vertexShader() { + return t; + } + constructor(c, a) { + super(c, a), this.program = null, this.pipeline = a.pipeline, this.endianness = l.systemEndianness(), this.extensions = {}, this.argumentTextureCount = 0, this.constantTextureCount = 0, this.fragShader = null, this.vertShader = null, this.drawBuffersMap = null, this.maxTexSize = null, this.onRequestSwitchKernel = null, this.texture = null, this.mappedTextures = null, this.mergeSettings(c.settings || a), this.threadDim = null, this.framebuffer = null, this.buffer = null, this.textureCache = [], this.programUniformLocationCache = {}, this.uniform1fCache = {}, this.uniform1iCache = {}, this.uniform2fCache = {}, this.uniform2fvCache = {}, this.uniform2ivCache = {}, this.uniform3fvCache = {}, this.uniform3ivCache = {}, this.uniform4fvCache = {}, this.uniform4ivCache = {}; + } + initCanvas() { + if (typeof document < "u") { + let c = document.createElement("canvas"); + return c.width = 2, c.height = 2, c; + } else if (typeof OffscreenCanvas < "u") + return new OffscreenCanvas(0, 0); + } + initContext() { + let c = { alpha: false, depth: false, antialias: false }; + return this.canvas.getContext("webgl", c) || this.canvas.getContext("experimental-webgl", c); + } + initPlugins(c) { + let a = [], { source: k } = this; + if (typeof k == "string") + for (let A = 0; A < h.length; A++) { + let N = h[A]; + k.match(N.functionMatch) && a.push(N); + } + else if (typeof k == "object" && c.pluginNames) + for (let A = 0; A < h.length; A++) { + let N = h[A]; + c.pluginNames.some((R) => R === N.name) && a.push(N); + } + return a; + } + initExtensions() { + this.extensions = { OES_texture_float: this.context.getExtension("OES_texture_float"), OES_texture_float_linear: this.context.getExtension("OES_texture_float_linear"), OES_element_index_uint: this.context.getExtension("OES_element_index_uint"), WEBGL_draw_buffers: this.context.getExtension("WEBGL_draw_buffers"), WEBGL_color_buffer_float: this.context.getExtension("WEBGL_color_buffer_float") }; + } + validateSettings(c) { + if (!this.validate) { + this.texSize = l.getKernelTextureSize({ optimizeFloatMemory: this.optimizeFloatMemory, precision: this.precision }, this.output); + return; + } + let { features: a } = this.constructor; + if (this.optimizeFloatMemory === true && !a.isTextureFloat) + throw new Error("Float textures are not supported"); + if (this.precision === "single" && !a.isFloatRead) + throw new Error("Single precision not supported"); + if (!this.graphical && this.precision === null && a.isTextureFloat && (this.precision = a.isFloatRead ? "single" : "unsigned"), this.subKernels && this.subKernels.length > 0 && !this.extensions.WEBGL_draw_buffers) + throw new Error("could not instantiate draw buffers extension"); + if (this.fixIntegerDivisionAccuracy === null ? this.fixIntegerDivisionAccuracy = !a.isIntegerDivisionAccurate : this.fixIntegerDivisionAccuracy && a.isIntegerDivisionAccurate && (this.fixIntegerDivisionAccuracy = false), this.checkOutput(), !this.output || this.output.length === 0) { + if (c.length !== 1) + throw new Error("Auto output only supported for kernels with only one input"); + let k = l.getVariableType(c[0], this.strictIntegers); + switch (k) { + case "Array": + this.output = l.getDimensions(k); + break; + case "NumberTexture": + case "MemoryOptimizedNumberTexture": + case "ArrayTexture(1)": + case "ArrayTexture(2)": + case "ArrayTexture(3)": + case "ArrayTexture(4)": + this.output = c[0].output; + break; + default: + throw new Error("Auto output not supported for input type: " + k); + } + } + if (this.graphical) { + if (this.output.length !== 2) + throw new Error("Output must have 2 dimensions on graphical mode"); + this.precision === "precision" && (this.precision = "unsigned", console.warn("Cannot use graphical mode and single precision at the same time")), this.texSize = l.clone(this.output); + return; + } else + this.precision === null && a.isTextureFloat && (this.precision = "single"); + this.texSize = l.getKernelTextureSize({ optimizeFloatMemory: this.optimizeFloatMemory, precision: this.precision }, this.output), this.checkTextureSize(); + } + updateMaxTexSize() { + let { texSize: c, canvas: a } = this; + if (this.maxTexSize === null) { + let k = b.indexOf(a); + k === -1 && (k = b.length, b.push(a), T[k] = [c[0], c[1]]), this.maxTexSize = T[k]; + } + this.maxTexSize[0] < c[0] && (this.maxTexSize[0] = c[0]), this.maxTexSize[1] < c[1] && (this.maxTexSize[1] = c[1]); + } + setupArguments(c) { + this.kernelArguments = [], this.argumentTextureCount = 0; + let a = this.argumentTypes === null; + if (a && (this.argumentTypes = []), this.argumentSizes = [], this.argumentBitRatios = [], c.length < this.argumentNames.length) + throw new Error("not enough arguments for kernel"); + if (c.length > this.argumentNames.length) + throw new Error("too many arguments for kernel"); + let { context: k } = this, A = 0, N = () => this.createTexture(), F = () => this.constantTextureCount + A++, R = (O) => { + this.switchKernels({ type: "argumentMismatch", needed: O }); + }, K = () => k.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++; + for (let O = 0; O < c.length; O++) { + let X = c[O], B = this.argumentNames[O], P; + a ? (P = l.getVariableType(X, this.strictIntegers), this.argumentTypes.push(P)) : P = this.argumentTypes[O]; + let Y = this.constructor.lookupKernelValueType(P, this.dynamicArguments ? "dynamic" : "static", this.precision, c[O]); + if (Y === null) + return this.requestFallback(c); + let J = new Y(X, { name: B, type: P, tactic: this.tactic, origin: "user", context: k, checkContext: this.checkContext, kernel: this, strictIntegers: this.strictIntegers, onRequestTexture: N, onRequestIndex: F, onUpdateValueMismatch: R, onRequestContextHandle: K }); + this.kernelArguments.push(J), J.setup(), this.argumentSizes.push(J.textureSize), this.argumentBitRatios[O] = J.bitRatio; + } + } + createTexture() { + let c = this.context.createTexture(); + return this.textureCache.push(c), c; + } + setupConstants(c) { + let { context: a } = this; + this.kernelConstants = [], this.forceUploadKernelConstants = []; + let k = this.constantTypes === null; + k && (this.constantTypes = {}), this.constantBitRatios = {}; + let A = 0; + for (let N in this.constants) { + let F = this.constants[N], R; + k ? (R = l.getVariableType(F, this.strictIntegers), this.constantTypes[N] = R) : R = this.constantTypes[N]; + let K = this.constructor.lookupKernelValueType(R, "static", this.precision, F); + if (K === null) + return this.requestFallback(c); + let O = new K(F, { name: N, type: R, tactic: this.tactic, origin: "constants", context: this.context, checkContext: this.checkContext, kernel: this, strictIntegers: this.strictIntegers, onRequestTexture: () => this.createTexture(), onRequestIndex: () => A++, onRequestContextHandle: () => a.TEXTURE0 + this.constantTextureCount++ }); + this.constantBitRatios[N] = O.bitRatio, this.kernelConstants.push(O), O.setup(), O.forceUploadEachRun && this.forceUploadKernelConstants.push(O); + } + } + build() { + if (this.built || (this.initExtensions(), this.validateSettings(arguments), this.setupConstants(arguments), this.fallbackRequested) || (this.setupArguments(arguments), this.fallbackRequested)) + return; + this.updateMaxTexSize(), this.translateSource(); + let c = this.pickRenderStrategy(arguments); + if (c) + return c; + let { texSize: a, context: k, canvas: A } = this; + k.enable(k.SCISSOR_TEST), this.pipeline && this.precision === "single" ? (k.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]), A.width = this.maxTexSize[0], A.height = this.maxTexSize[1]) : (k.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]), A.width = this.maxTexSize[0], A.height = this.maxTexSize[1]); + let N = this.threadDim = Array.from(this.output); + for (; N.length < 3; ) + N.push(1); + let F = this.getVertexShader(arguments), R = k.createShader(k.VERTEX_SHADER); + k.shaderSource(R, F), k.compileShader(R), this.vertShader = R; + let K = this.getFragmentShader(arguments), O = k.createShader(k.FRAGMENT_SHADER); + if (k.shaderSource(O, K), k.compileShader(O), this.fragShader = O, this.debug && (console.log("GLSL Shader Output:"), console.log(K)), !k.getShaderParameter(R, k.COMPILE_STATUS)) + throw new Error("Error compiling vertex shader: " + k.getShaderInfoLog(R)); + if (!k.getShaderParameter(O, k.COMPILE_STATUS)) + throw new Error("Error compiling fragment shader: " + k.getShaderInfoLog(O)); + let X = this.program = k.createProgram(); + k.attachShader(X, R), k.attachShader(X, O), k.linkProgram(X), this.framebuffer = k.createFramebuffer(), this.framebuffer.width = a[0], this.framebuffer.height = a[1], this.rawValueFramebuffers = {}; + let B = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), P = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]), Y = B.byteLength, J = this.buffer; + J ? k.bindBuffer(k.ARRAY_BUFFER, J) : (J = this.buffer = k.createBuffer(), k.bindBuffer(k.ARRAY_BUFFER, J), k.bufferData(k.ARRAY_BUFFER, B.byteLength + P.byteLength, k.STATIC_DRAW)), k.bufferSubData(k.ARRAY_BUFFER, 0, B), k.bufferSubData(k.ARRAY_BUFFER, Y, P); + let q = k.getAttribLocation(this.program, "aPos"); + k.enableVertexAttribArray(q), k.vertexAttribPointer(q, 2, k.FLOAT, false, 0, 0); + let j = k.getAttribLocation(this.program, "aTexCoord"); + k.enableVertexAttribArray(j), k.vertexAttribPointer(j, 2, k.FLOAT, false, 0, Y), k.bindFramebuffer(k.FRAMEBUFFER, this.framebuffer); + let U = 0; + k.useProgram(this.program); + for (let oe in this.constants) + this.kernelConstants[U++].updateValue(this.constants[oe]); + this._setupOutputTexture(), this.subKernels !== null && this.subKernels.length > 0 && (this._mappedTextureSwitched = {}, this._setupSubOutputTextures()), this.buildSignature(arguments), this.built = true; + } + translateSource() { + let c = g.fromKernel(this, f, { fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy }); + this.translatedSource = c.getPrototypeString("kernel"), this.setupReturnTypes(c); + } + setupReturnTypes(c) { + if (!this.graphical && !this.returnType && (this.returnType = c.getKernelResultType()), this.subKernels && this.subKernels.length > 0) + for (let a = 0; a < this.subKernels.length; a++) { + let k = this.subKernels[a]; + k.returnType || (k.returnType = c.getSubKernelResultType(a)); + } + } + run() { + let { kernelArguments: c, texSize: a, forceUploadKernelConstants: k, context: A } = this; + A.useProgram(this.program), A.scissor(0, 0, a[0], a[1]), this.dynamicOutput && (this.setUniform3iv("uOutputDim", new Int32Array(this.threadDim)), this.setUniform2iv("uTexSize", a)), this.setUniform2f("ratio", a[0] / this.maxTexSize[0], a[1] / this.maxTexSize[1]); + for (let N = 0; N < k.length; N++) { + let F = k[N]; + if (F.updateValue(this.constants[F.name]), this.switchingKernels) + return; + } + for (let N = 0; N < c.length; N++) + if (c[N].updateValue(arguments[N]), this.switchingKernels) + return; + if (this.plugins) + for (let N = 0; N < this.plugins.length; N++) { + let F = this.plugins[N]; + F.onBeforeRun && F.onBeforeRun(this); + } + if (this.graphical) { + if (this.pipeline) + return A.bindRenderbuffer(A.RENDERBUFFER, null), A.bindFramebuffer(A.FRAMEBUFFER, this.framebuffer), this.immutable && this._replaceOutputTexture(), A.drawArrays(A.TRIANGLE_STRIP, 0, 4), this.immutable ? this.texture.clone() : this.texture; + A.bindRenderbuffer(A.RENDERBUFFER, null), A.bindFramebuffer(A.FRAMEBUFFER, null), A.drawArrays(A.TRIANGLE_STRIP, 0, 4); + return; + } + A.bindFramebuffer(A.FRAMEBUFFER, this.framebuffer), this.immutable && this._replaceOutputTexture(), this.subKernels !== null && (this.immutable && this._replaceSubOutputTextures(), this.drawBuffers()), A.drawArrays(A.TRIANGLE_STRIP, 0, 4); + } + drawBuffers() { + this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap); + } + getInternalFormat() { + return this.context.RGBA; + } + getTextureFormat() { + let { context: c } = this; + switch (this.getInternalFormat()) { + case c.RGBA: + return c.RGBA; + default: + throw new Error("Unknown internal format"); + } + } + _replaceOutputTexture() { + if (this.texture.beforeMutate() || this._textureSwitched) { + let c = this.context; + c.framebufferTexture2D(c.FRAMEBUFFER, c.COLOR_ATTACHMENT0, c.TEXTURE_2D, this.texture.texture, 0), this._textureSwitched = false; + } + } + _setupOutputTexture() { + let c = this.context, a = this.texSize; + if (this.texture) { + c.framebufferTexture2D(c.FRAMEBUFFER, c.COLOR_ATTACHMENT0, c.TEXTURE_2D, this.texture.texture, 0); + return; + } + let k = this.createTexture(); + c.activeTexture(c.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount), c.bindTexture(c.TEXTURE_2D, k), c.texParameteri(c.TEXTURE_2D, c.TEXTURE_WRAP_S, c.CLAMP_TO_EDGE), c.texParameteri(c.TEXTURE_2D, c.TEXTURE_WRAP_T, c.CLAMP_TO_EDGE), c.texParameteri(c.TEXTURE_2D, c.TEXTURE_MIN_FILTER, c.NEAREST), c.texParameteri(c.TEXTURE_2D, c.TEXTURE_MAG_FILTER, c.NEAREST); + let A = this.getInternalFormat(); + this.precision === "single" ? c.texImage2D(c.TEXTURE_2D, 0, A, a[0], a[1], 0, c.RGBA, c.FLOAT, null) : c.texImage2D(c.TEXTURE_2D, 0, A, a[0], a[1], 0, A, c.UNSIGNED_BYTE, null), c.framebufferTexture2D(c.FRAMEBUFFER, c.COLOR_ATTACHMENT0, c.TEXTURE_2D, k, 0), this.texture = new this.TextureConstructor({ texture: k, size: a, dimensions: this.threadDim, output: this.output, context: this.context, internalFormat: this.getInternalFormat(), textureFormat: this.getTextureFormat(), kernel: this }); + } + _replaceSubOutputTextures() { + let c = this.context; + for (let a = 0; a < this.mappedTextures.length; a++) { + let k = this.mappedTextures[a]; + (k.beforeMutate() || this._mappedTextureSwitched[a]) && (c.framebufferTexture2D(c.FRAMEBUFFER, c.COLOR_ATTACHMENT0 + a + 1, c.TEXTURE_2D, k.texture, 0), this._mappedTextureSwitched[a] = false); + } + } + _setupSubOutputTextures() { + let c = this.context; + if (this.mappedTextures) { + for (let k = 0; k < this.subKernels.length; k++) + c.framebufferTexture2D(c.FRAMEBUFFER, c.COLOR_ATTACHMENT0 + k + 1, c.TEXTURE_2D, this.mappedTextures[k].texture, 0); + return; + } + let a = this.texSize; + this.drawBuffersMap = [c.COLOR_ATTACHMENT0], this.mappedTextures = []; + for (let k = 0; k < this.subKernels.length; k++) { + let A = this.createTexture(); + this.drawBuffersMap.push(c.COLOR_ATTACHMENT0 + k + 1), c.activeTexture(c.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + k), c.bindTexture(c.TEXTURE_2D, A), c.texParameteri(c.TEXTURE_2D, c.TEXTURE_WRAP_S, c.CLAMP_TO_EDGE), c.texParameteri(c.TEXTURE_2D, c.TEXTURE_WRAP_T, c.CLAMP_TO_EDGE), c.texParameteri(c.TEXTURE_2D, c.TEXTURE_MIN_FILTER, c.NEAREST), c.texParameteri(c.TEXTURE_2D, c.TEXTURE_MAG_FILTER, c.NEAREST), this.precision === "single" ? c.texImage2D(c.TEXTURE_2D, 0, c.RGBA, a[0], a[1], 0, c.RGBA, c.FLOAT, null) : c.texImage2D(c.TEXTURE_2D, 0, c.RGBA, a[0], a[1], 0, c.RGBA, c.UNSIGNED_BYTE, null), c.framebufferTexture2D(c.FRAMEBUFFER, c.COLOR_ATTACHMENT0 + k + 1, c.TEXTURE_2D, A, 0), this.mappedTextures.push(new this.TextureConstructor({ texture: A, size: a, dimensions: this.threadDim, output: this.output, context: this.context, internalFormat: this.getInternalFormat(), textureFormat: this.getTextureFormat(), kernel: this })); + } + } + setUniform1f(c, a) { + if (this.uniform1fCache.hasOwnProperty(c)) { + let A = this.uniform1fCache[c]; + if (a === A) + return; + } + this.uniform1fCache[c] = a; + let k = this.getUniformLocation(c); + this.context.uniform1f(k, a); + } + setUniform1i(c, a) { + if (this.uniform1iCache.hasOwnProperty(c)) { + let A = this.uniform1iCache[c]; + if (a === A) + return; + } + this.uniform1iCache[c] = a; + let k = this.getUniformLocation(c); + this.context.uniform1i(k, a); + } + setUniform2f(c, a, k) { + if (this.uniform2fCache.hasOwnProperty(c)) { + let N = this.uniform2fCache[c]; + if (a === N[0] && k === N[1]) + return; + } + this.uniform2fCache[c] = [a, k]; + let A = this.getUniformLocation(c); + this.context.uniform2f(A, a, k); + } + setUniform2fv(c, a) { + if (this.uniform2fvCache.hasOwnProperty(c)) { + let A = this.uniform2fvCache[c]; + if (a[0] === A[0] && a[1] === A[1]) + return; + } + this.uniform2fvCache[c] = a; + let k = this.getUniformLocation(c); + this.context.uniform2fv(k, a); + } + setUniform2iv(c, a) { + if (this.uniform2ivCache.hasOwnProperty(c)) { + let A = this.uniform2ivCache[c]; + if (a[0] === A[0] && a[1] === A[1]) + return; + } + this.uniform2ivCache[c] = a; + let k = this.getUniformLocation(c); + this.context.uniform2iv(k, a); + } + setUniform3fv(c, a) { + if (this.uniform3fvCache.hasOwnProperty(c)) { + let A = this.uniform3fvCache[c]; + if (a[0] === A[0] && a[1] === A[1] && a[2] === A[2]) + return; + } + this.uniform3fvCache[c] = a; + let k = this.getUniformLocation(c); + this.context.uniform3fv(k, a); + } + setUniform3iv(c, a) { + if (this.uniform3ivCache.hasOwnProperty(c)) { + let A = this.uniform3ivCache[c]; + if (a[0] === A[0] && a[1] === A[1] && a[2] === A[2]) + return; + } + this.uniform3ivCache[c] = a; + let k = this.getUniformLocation(c); + this.context.uniform3iv(k, a); + } + setUniform4fv(c, a) { + if (this.uniform4fvCache.hasOwnProperty(c)) { + let A = this.uniform4fvCache[c]; + if (a[0] === A[0] && a[1] === A[1] && a[2] === A[2] && a[3] === A[3]) + return; + } + this.uniform4fvCache[c] = a; + let k = this.getUniformLocation(c); + this.context.uniform4fv(k, a); + } + setUniform4iv(c, a) { + if (this.uniform4ivCache.hasOwnProperty(c)) { + let A = this.uniform4ivCache[c]; + if (a[0] === A[0] && a[1] === A[1] && a[2] === A[2] && a[3] === A[3]) + return; + } + this.uniform4ivCache[c] = a; + let k = this.getUniformLocation(c); + this.context.uniform4iv(k, a); + } + getUniformLocation(c) { + return this.programUniformLocationCache.hasOwnProperty(c) ? this.programUniformLocationCache[c] : this.programUniformLocationCache[c] = this.context.getUniformLocation(this.program, c); + } + _getFragShaderArtifactMap(c) { + return { HEADER: this._getHeaderString(), LOOP_MAX: this._getLoopMaxString(), PLUGINS: this._getPluginsString(), CONSTANTS: this._getConstantsString(), DECODE32_ENDIANNESS: this._getDecode32EndiannessString(), ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(), DIVIDE_WITH_INTEGER_CHECK: this._getDivideWithIntegerCheckString(), INJECTED_NATIVE: this._getInjectedNative(), MAIN_CONSTANTS: this._getMainConstantsString(), MAIN_ARGUMENTS: this._getMainArgumentsString(c), KERNEL: this.getKernelString(), MAIN_RESULT: this.getMainResultString(), FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(), INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(), SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(), SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration() }; + } + _getVertShaderArtifactMap(c) { + return { FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(), INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(), SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(), SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration() }; + } + _getHeaderString() { + return this.subKernels !== null ? `#extension GL_EXT_draw_buffers : require +` : ""; + } + _getLoopMaxString() { + return this.loopMaxIterations ? ` ${parseInt(this.loopMaxIterations)}; +` : ` 1000; +`; + } + _getPluginsString() { + return this.plugins ? this.plugins.map((c) => c.source && this.source.match(c.functionMatch) ? c.source : "").join(` +`) : ` +`; + } + _getConstantsString() { + let c = [], { threadDim: a, texSize: k } = this; + return this.dynamicOutput ? c.push("uniform ivec3 uOutputDim", "uniform ivec2 uTexSize") : c.push(`ivec3 uOutputDim = ivec3(${a[0]}, ${a[1]}, ${a[2]})`, `ivec2 uTexSize = ivec2(${k[0]}, ${k[1]})`), l.linesToString(c); + } + _getTextureCoordinate() { + let c = this.subKernels; + return c === null || c.length < 1 ? `varying vec2 vTexCoord; +` : `out vec2 vTexCoord; +`; + } + _getDecode32EndiannessString() { + return this.endianness === "LE" ? "" : ` texel.rgba = texel.abgr; +`; + } + _getEncode32EndiannessString() { + return this.endianness === "LE" ? "" : ` texel.rgba = texel.abgr; +`; + } + _getDivideWithIntegerCheckString() { + return this.fixIntegerDivisionAccuracy ? `float divWithIntCheck(float x, float y) { + if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) { + return float(int(x) / int(y)); + } + return x / y; + } + + float integerCorrectionModulo(float number, float divisor) { + if (number < 0.0) { + number = abs(number); + if (divisor < 0.0) { + divisor = abs(divisor); + } + return -(number - (divisor * floor(divWithIntCheck(number, divisor)))); + } + if (divisor < 0.0) { + divisor = abs(divisor); + } + return number - (divisor * floor(divWithIntCheck(number, divisor))); + }` : ""; + } + _getMainArgumentsString(c) { + let a = [], { argumentNames: k } = this; + for (let A = 0; A < k.length; A++) + a.push(this.kernelArguments[A].getSource(c[A])); + return a.join(""); + } + _getInjectedNative() { + return this.injectedNative || ""; + } + _getMainConstantsString() { + let c = [], { constants: a } = this; + if (a) { + let k = 0; + for (let A in a) + !this.constants.hasOwnProperty(A) || c.push(this.kernelConstants[k++].getSource(this.constants[A])); + } + return c.join(""); + } + getRawValueFramebuffer(c, a) { + if (this.rawValueFramebuffers[c] || (this.rawValueFramebuffers[c] = {}), !this.rawValueFramebuffers[c][a]) { + let k = this.context.createFramebuffer(); + k.width = c, k.height = a, this.rawValueFramebuffers[c][a] = k; + } + return this.rawValueFramebuffers[c][a]; + } + getKernelResultDeclaration() { + switch (this.returnType) { + case "Array(2)": + return "vec2 kernelResult"; + case "Array(3)": + return "vec3 kernelResult"; + case "Array(4)": + return "vec4 kernelResult"; + case "LiteralInteger": + case "Float": + case "Number": + case "Integer": + return "float kernelResult"; + default: + if (this.graphical) + return "float kernelResult"; + throw new Error(`unrecognized output type "${this.returnType}"`); + } + } + getKernelString() { + let c = [this.getKernelResultDeclaration()], { subKernels: a } = this; + if (a !== null) + switch (this.returnType) { + case "Number": + case "Float": + case "Integer": + for (let k = 0; k < a.length; k++) { + let A = a[k]; + c.push(A.returnType === "Integer" ? `int subKernelResult_${A.name} = 0` : `float subKernelResult_${A.name} = 0.0`); + } + break; + case "Array(2)": + for (let k = 0; k < a.length; k++) + c.push(`vec2 subKernelResult_${a[k].name}`); + break; + case "Array(3)": + for (let k = 0; k < a.length; k++) + c.push(`vec3 subKernelResult_${a[k].name}`); + break; + case "Array(4)": + for (let k = 0; k < a.length; k++) + c.push(`vec4 subKernelResult_${a[k].name}`); + break; + } + return l.linesToString(c) + this.translatedSource; + } + getMainResultGraphical() { + return l.linesToString([" threadId = indexTo3D(index, uOutputDim)", " kernel()", " gl_FragColor = actualColor"]); + } + getMainResultPackedPixels() { + switch (this.returnType) { + case "LiteralInteger": + case "Number": + case "Integer": + case "Float": + return this.getMainResultKernelPackedPixels() + this.getMainResultSubKernelPackedPixels(); + default: + throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`); + } + } + getMainResultKernelPackedPixels() { + return l.linesToString([" threadId = indexTo3D(index, uOutputDim)", " kernel()", ` gl_FragData[0] = ${this.useLegacyEncoder ? "legacyEncode32" : "encode32"}(kernelResult)`]); + } + getMainResultSubKernelPackedPixels() { + let c = []; + if (!this.subKernels) + return ""; + for (let a = 0; a < this.subKernels.length; a++) + this.subKernels[a].returnType === "Integer" ? c.push(` gl_FragData[${a + 1}] = ${this.useLegacyEncoder ? "legacyEncode32" : "encode32"}(float(subKernelResult_${this.subKernels[a].name}))`) : c.push(` gl_FragData[${a + 1}] = ${this.useLegacyEncoder ? "legacyEncode32" : "encode32"}(subKernelResult_${this.subKernels[a].name})`); + return l.linesToString(c); + } + getMainResultMemoryOptimizedFloats() { + let c = [" index *= 4"]; + switch (this.returnType) { + case "Number": + case "Integer": + case "Float": + let a = ["r", "g", "b", "a"]; + for (let k = 0; k < a.length; k++) { + let A = a[k]; + this.getMainResultKernelMemoryOptimizedFloats(c, A), this.getMainResultSubKernelMemoryOptimizedFloats(c, A), k + 1 < a.length && c.push(" index += 1"); + } + break; + default: + throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`); + } + return l.linesToString(c); + } + getMainResultKernelMemoryOptimizedFloats(c, a) { + c.push(" threadId = indexTo3D(index, uOutputDim)", " kernel()", ` gl_FragData[0].${a} = kernelResult`); + } + getMainResultSubKernelMemoryOptimizedFloats(c, a) { + if (!this.subKernels) + return c; + for (let k = 0; k < this.subKernels.length; k++) + this.subKernels[k].returnType === "Integer" ? c.push(` gl_FragData[${k + 1}].${a} = float(subKernelResult_${this.subKernels[k].name})`) : c.push(` gl_FragData[${k + 1}].${a} = subKernelResult_${this.subKernels[k].name}`); + } + getMainResultKernelNumberTexture() { + return [" threadId = indexTo3D(index, uOutputDim)", " kernel()", " gl_FragData[0][0] = kernelResult"]; + } + getMainResultSubKernelNumberTexture() { + let c = []; + if (!this.subKernels) + return c; + for (let a = 0; a < this.subKernels.length; ++a) { + let k = this.subKernels[a]; + k.returnType === "Integer" ? c.push(` gl_FragData[${a + 1}][0] = float(subKernelResult_${k.name})`) : c.push(` gl_FragData[${a + 1}][0] = subKernelResult_${k.name}`); + } + return c; + } + getMainResultKernelArray2Texture() { + return [" threadId = indexTo3D(index, uOutputDim)", " kernel()", " gl_FragData[0][0] = kernelResult[0]", " gl_FragData[0][1] = kernelResult[1]"]; + } + getMainResultSubKernelArray2Texture() { + let c = []; + if (!this.subKernels) + return c; + for (let a = 0; a < this.subKernels.length; ++a) + c.push(` gl_FragData[${a + 1}][0] = subKernelResult_${this.subKernels[a].name}[0]`, ` gl_FragData[${a + 1}][1] = subKernelResult_${this.subKernels[a].name}[1]`); + return c; + } + getMainResultKernelArray3Texture() { + return [" threadId = indexTo3D(index, uOutputDim)", " kernel()", " gl_FragData[0][0] = kernelResult[0]", " gl_FragData[0][1] = kernelResult[1]", " gl_FragData[0][2] = kernelResult[2]"]; + } + getMainResultSubKernelArray3Texture() { + let c = []; + if (!this.subKernels) + return c; + for (let a = 0; a < this.subKernels.length; ++a) + c.push(` gl_FragData[${a + 1}][0] = subKernelResult_${this.subKernels[a].name}[0]`, ` gl_FragData[${a + 1}][1] = subKernelResult_${this.subKernels[a].name}[1]`, ` gl_FragData[${a + 1}][2] = subKernelResult_${this.subKernels[a].name}[2]`); + return c; + } + getMainResultKernelArray4Texture() { + return [" threadId = indexTo3D(index, uOutputDim)", " kernel()", " gl_FragData[0] = kernelResult"]; + } + getMainResultSubKernelArray4Texture() { + let c = []; + if (!this.subKernels) + return c; + switch (this.returnType) { + case "Number": + case "Float": + case "Integer": + for (let a = 0; a < this.subKernels.length; ++a) + this.subKernels[a].returnType === "Integer" ? c.push(` gl_FragData[${a + 1}] = float(subKernelResult_${this.subKernels[a].name})`) : c.push(` gl_FragData[${a + 1}] = subKernelResult_${this.subKernels[a].name}`); + break; + case "Array(2)": + for (let a = 0; a < this.subKernels.length; ++a) + c.push(` gl_FragData[${a + 1}][0] = subKernelResult_${this.subKernels[a].name}[0]`, ` gl_FragData[${a + 1}][1] = subKernelResult_${this.subKernels[a].name}[1]`); + break; + case "Array(3)": + for (let a = 0; a < this.subKernels.length; ++a) + c.push(` gl_FragData[${a + 1}][0] = subKernelResult_${this.subKernels[a].name}[0]`, ` gl_FragData[${a + 1}][1] = subKernelResult_${this.subKernels[a].name}[1]`, ` gl_FragData[${a + 1}][2] = subKernelResult_${this.subKernels[a].name}[2]`); + break; + case "Array(4)": + for (let a = 0; a < this.subKernels.length; ++a) + c.push(` gl_FragData[${a + 1}][0] = subKernelResult_${this.subKernels[a].name}[0]`, ` gl_FragData[${a + 1}][1] = subKernelResult_${this.subKernels[a].name}[1]`, ` gl_FragData[${a + 1}][2] = subKernelResult_${this.subKernels[a].name}[2]`, ` gl_FragData[${a + 1}][3] = subKernelResult_${this.subKernels[a].name}[3]`); + break; + } + return c; + } + replaceArtifacts(c, a) { + return c.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z]*[0-9]?)*)__;\n/g, (k, A) => { + if (a.hasOwnProperty(A)) + return a[A]; + throw `unhandled artifact ${A}`; + }); + } + getFragmentShader(c) { + return this.compiledFragmentShader !== null ? this.compiledFragmentShader : this.compiledFragmentShader = this.replaceArtifacts(this.constructor.fragmentShader, this._getFragShaderArtifactMap(c)); + } + getVertexShader(c) { + return this.compiledVertexShader !== null ? this.compiledVertexShader : this.compiledVertexShader = this.replaceArtifacts(this.constructor.vertexShader, this._getVertShaderArtifactMap(c)); + } + toString() { + let c = l.linesToString(["const gl = context"]); + return i(this.constructor, arguments, this, c); + } + destroy(c) { + if (!this.context) + return; + this.buffer && this.context.deleteBuffer(this.buffer), this.framebuffer && this.context.deleteFramebuffer(this.framebuffer); + for (let k in this.rawValueFramebuffers) { + for (let A in this.rawValueFramebuffers[k]) + this.context.deleteFramebuffer(this.rawValueFramebuffers[k][A]), delete this.rawValueFramebuffers[k][A]; + delete this.rawValueFramebuffers[k]; + } + if (this.vertShader && this.context.deleteShader(this.vertShader), this.fragShader && this.context.deleteShader(this.fragShader), this.program && this.context.deleteProgram(this.program), this.texture) { + this.texture.delete(); + let k = this.textureCache.indexOf(this.texture.texture); + k > -1 && this.textureCache.splice(k, 1), this.texture = null; + } + if (this.mappedTextures && this.mappedTextures.length) { + for (let k = 0; k < this.mappedTextures.length; k++) { + let A = this.mappedTextures[k]; + A.delete(); + let N = this.textureCache.indexOf(A.texture); + N > -1 && this.textureCache.splice(N, 1); + } + this.mappedTextures = null; + } + if (this.kernelArguments) + for (let k = 0; k < this.kernelArguments.length; k++) + this.kernelArguments[k].destroy(); + if (this.kernelConstants) + for (let k = 0; k < this.kernelConstants.length; k++) + this.kernelConstants[k].destroy(); + for (; this.textureCache.length > 0; ) { + let k = this.textureCache.pop(); + this.context.deleteTexture(k); + } + if (c) { + let k = b.indexOf(this.canvas); + k >= 0 && (b[k] = null, T[k] = null); + } + if (this.destroyExtensions(), delete this.context, delete this.canvas, !this.gpu) + return; + let a = this.gpu.kernels.indexOf(this); + a !== -1 && this.gpu.kernels.splice(a, 1); + } + destroyExtensions() { + this.extensions.OES_texture_float = null, this.extensions.OES_texture_float_linear = null, this.extensions.OES_element_index_uint = null, this.extensions.WEBGL_draw_buffers = null; + } + static destroyContext(c) { + let a = c.getExtension("WEBGL_lose_context"); + a && a.loseContext(); + } + toJSON() { + let c = super.toJSON(); + return c.functionNodes = g.fromKernel(this, f).toJSON(), c.settings.threadDim = this.threadDim, c; + } + } + y.exports = { WebGLKernel: C }; + }, { "../../plugins/math-random-uniformly-distributed": 112, "../../utils": 114, "../function-builder": 9, "../gl/kernel": 13, "../gl/kernel-string": 12, "./fragment-shader": 37, "./function-node": 38, "./kernel-value-maps": 39, "./vertex-shader": 71 }], 71: [function(o, y, E) { + let p = `__FLOAT_TACTIC_DECLARATION__; + __INT_TACTIC_DECLARATION__; + __SAMPLER_2D_TACTIC_DECLARATION__; + + attribute vec2 aPos; + attribute vec2 aTexCoord; + + varying vec2 vTexCoord; + uniform vec2 ratio; + + void main(void) { + gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1); + vTexCoord = aTexCoord; + }`; + y.exports = { vertexShader: p }; + }, {}], 72: [function(o, y, E) { + let p = `#version 300 es + __HEADER__; + __FLOAT_TACTIC_DECLARATION__; + __INT_TACTIC_DECLARATION__; + __SAMPLER_2D_TACTIC_DECLARATION__; + __SAMPLER_2D_ARRAY_TACTIC_DECLARATION__; + + const int LOOP_MAX = __LOOP_MAX__; + + __PLUGINS__; + __CONSTANTS__; + + in vec2 vTexCoord; + + float atan2(float v1, float v2) { + if (v1 == 0.0 || v2 == 0.0) return 0.0; + return atan(v1 / v2); + } + + float cbrt(float x) { + if (x >= 0.0) { + return pow(x, 1.0 / 3.0); + } else { + return -pow(x, 1.0 / 3.0); + } + } + + float expm1(float x) { + return pow(${Math.E}, x) - 1.0; + } + + float fround(highp float x) { + return x; + } + + float imul(float v1, float v2) { + return float(int(v1) * int(v2)); + } + + float log10(float x) { + return log2(x) * (1.0 / log2(10.0)); + } + + float log1p(float x) { + return log(1.0 + x); + } + + float _pow(float v1, float v2) { + if (v2 == 0.0) return 1.0; + return pow(v1, v2); + } + + float _round(float x) { + return floor(x + 0.5); + } + + + const int BIT_COUNT = 32; + int modi(int x, int y) { + return x - y * (x / y); + } + + int bitwiseOr(int a, int b) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 || b > 0)) { + break; + } + } + return result; + } + int bitwiseXOR(int a, int b) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 || b > 0)) { + break; + } + } + return result; + } + int bitwiseAnd(int a, int b) { + int result = 0; + int n = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 && b > 0)) { + break; + } + } + return result; + } + int bitwiseNot(int a) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if (modi(a, 2) == 0) { + result += n; + } + a = a / 2; + n = n * 2; + } + return result; + } + int bitwiseZeroFillLeftShift(int n, int shift) { + int maxBytes = BIT_COUNT; + for (int i = 0; i < BIT_COUNT; i++) { + if (maxBytes >= n) { + break; + } + maxBytes *= 2; + } + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= shift) { + break; + } + n *= 2; + } + + int result = 0; + int byteVal = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= maxBytes) break; + if (modi(n, 2) > 0) { result += byteVal; } + n = int(n / 2); + byteVal *= 2; + } + return result; + } + + int bitwiseSignedRightShift(int num, int shifts) { + return int(floor(float(num) / pow(2.0, float(shifts)))); + } + + int bitwiseZeroFillRightShift(int n, int shift) { + int maxBytes = BIT_COUNT; + for (int i = 0; i < BIT_COUNT; i++) { + if (maxBytes >= n) { + break; + } + maxBytes *= 2; + } + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= shift) { + break; + } + n /= 2; + } + int result = 0; + int byteVal = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= maxBytes) break; + if (modi(n, 2) > 0) { result += byteVal; } + n = int(n / 2); + byteVal *= 2; + } + return result; + } + + vec2 integerMod(vec2 x, float y) { + vec2 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); + } + + vec3 integerMod(vec3 x, float y) { + vec3 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); + } + + vec4 integerMod(vec4 x, vec4 y) { + vec4 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); + } + + float integerMod(float x, float y) { + float res = floor(mod(x, y)); + return res * (res > floor(y) - 1.0 ? 0.0 : 1.0); + } + + int integerMod(int x, int y) { + return x - (y * int(x/y)); + } + + __DIVIDE_WITH_INTEGER_CHECK__; + + // Here be dragons! + // DO NOT OPTIMIZE THIS CODE + // YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE + // LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME + const vec2 MAGIC_VEC = vec2(1.0, -256.0); + const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0); + const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536 + float decode32(vec4 texel) { + __DECODE32_ENDIANNESS__; + texel *= 255.0; + vec2 gte128; + gte128.x = texel.b >= 128.0 ? 1.0 : 0.0; + gte128.y = texel.a >= 128.0 ? 1.0 : 0.0; + float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC); + float res = exp2(round(exponent)); + texel.b = texel.b - 128.0 * gte128.x; + res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res; + res *= gte128.y * -2.0 + 1.0; + return res; + } + + float decode16(vec4 texel, int index) { + int channel = integerMod(index, 2); + return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0; + } + + float decode8(vec4 texel, int index) { + int channel = integerMod(index, 4); + return texel[channel] * 255.0; + } + + vec4 legacyEncode32(float f) { + float F = abs(f); + float sign = f < 0.0 ? 1.0 : 0.0; + float exponent = floor(log2(F)); + float mantissa = (exp2(-exponent) * F); + // exponent += floor(log2(mantissa)); + vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV; + texel.rg = integerMod(texel.rg, 256.0); + texel.b = integerMod(texel.b, 128.0); + texel.a = exponent*0.5 + 63.5; + texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0; + texel = floor(texel); + texel *= 0.003921569; // 1/255 + __ENCODE32_ENDIANNESS__; + return texel; + } + + // https://github.com/gpujs/gpu.js/wiki/Encoder-details + vec4 encode32(float value) { + if (value == 0.0) return vec4(0, 0, 0, 0); + + float exponent; + float mantissa; + vec4 result; + float sgn; + + sgn = step(0.0, -value); + value = abs(value); + + exponent = floor(log2(value)); + + mantissa = value*pow(2.0, -exponent)-1.0; + exponent = exponent+127.0; + result = vec4(0,0,0,0); + + result.a = floor(exponent/2.0); + exponent = exponent - result.a*2.0; + result.a = result.a + 128.0*sgn; + + result.b = floor(mantissa * 128.0); + mantissa = mantissa - result.b / 128.0; + result.b = result.b + exponent*128.0; + + result.g = floor(mantissa*32768.0); + mantissa = mantissa - result.g/32768.0; + + result.r = floor(mantissa*8388608.0); + return result/255.0; + } + // Dragons end here + + int index; + ivec3 threadId; + + ivec3 indexTo3D(int idx, ivec3 texDim) { + int z = int(idx / (texDim.x * texDim.y)); + idx -= z * int(texDim.x * texDim.y); + int y = int(idx / texDim.x); + int x = int(integerMod(idx, texDim.x)); + return ivec3(x, y, z); + } + + float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize)); + return decode32(texel); + } + + float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + (texDim.x * (y + (texDim.y * z))); + int w = texSize.x * 2; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y)); + return decode16(texel, index); + } + + float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + (texDim.x * (y + (texDim.y * z))); + int w = texSize.x * 4; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y)); + return decode8(texel, index); + } + + float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + (texDim.x * (y + (texDim.y * z))); + int channel = integerMod(index, 4); + index = index / 4; + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + index = index / 4; + vec4 texel = texture(tex, st / vec2(texSize)); + return texel[channel]; + } + + vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + return texture(tex, st / vec2(texSize)); + } + + vec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + return texture(tex, vec3(st / vec2(texSize), z)); + } + + float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return result[0]; + } + + vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return vec2(result[0], result[1]); + } + + vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int channel = integerMod(index, 2); + index = index / 2; + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize)); + if (channel == 0) return vec2(texel.r, texel.g); + if (channel == 1) return vec2(texel.b, texel.a); + return vec2(0.0, 0.0); + } + + vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return vec3(result[0], result[1], result[2]); + } + + vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z)); + int vectorIndex = fieldIndex / 4; + int vectorOffset = fieldIndex - vectorIndex * 4; + int readY = vectorIndex / texSize.x; + int readX = vectorIndex - readY * texSize.x; + vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize)); + + if (vectorOffset == 0) { + return tex1.xyz; + } else if (vectorOffset == 1) { + return tex1.yzw; + } else { + readX++; + if (readX >= texSize.x) { + readX = 0; + readY++; + } + vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize)); + if (vectorOffset == 2) { + return vec3(tex1.z, tex1.w, tex2.x); + } else { + return vec3(tex1.w, tex2.x, tex2.y); + } + } + } + + vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + return getImage2D(tex, texSize, texDim, z, y, x); + } + + vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int channel = integerMod(index, 2); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize)); + return vec4(texel.r, texel.g, texel.b, texel.a); + } + + vec4 actualColor; + void color(float r, float g, float b, float a) { + actualColor = vec4(r,g,b,a); + } + + void color(float r, float g, float b) { + color(r,g,b,1.0); + } + + float modulo(float number, float divisor) { + if (number < 0.0) { + number = abs(number); + if (divisor < 0.0) { + divisor = abs(divisor); + } + return -mod(number, divisor); + } + if (divisor < 0.0) { + divisor = abs(divisor); + } + return mod(number, divisor); + } + + __INJECTED_NATIVE__; + __MAIN_CONSTANTS__; + __MAIN_ARGUMENTS__; + __KERNEL__; + + void main(void) { + index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x; + __MAIN_RESULT__; + }`; + y.exports = { fragmentShader: p }; + }, {}], 73: [function(o, y, E) { + let { utils: p } = o("../../utils"), { WebGLFunctionNode: g } = o("../web-gl/function-node"); + class f extends g { + astIdentifierExpression(n, s) { + if (n.type !== "Identifier") + throw this.astErrorOutput("IdentifierExpression - not an Identifier", n); + let t = this.getType(n), i = p.sanitizeName(n.name); + return n.name === "Infinity" ? s.push("intBitsToFloat(2139095039)") : t === "Boolean" ? this.argumentNames.indexOf(i) > -1 ? s.push(`bool(user_${i})`) : s.push(`user_${i}`) : s.push(`user_${i}`), s; + } + } + y.exports = { WebGL2FunctionNode: f }; + }, { "../../utils": 114, "../web-gl/function-node": 38 }], 74: [function(o, y, E) { + let { WebGL2KernelValueBoolean: p } = o("./kernel-value/boolean"), { WebGL2KernelValueFloat: g } = o("./kernel-value/float"), { WebGL2KernelValueInteger: f } = o("./kernel-value/integer"), { WebGL2KernelValueHTMLImage: l } = o("./kernel-value/html-image"), { WebGL2KernelValueDynamicHTMLImage: n } = o("./kernel-value/dynamic-html-image"), { WebGL2KernelValueHTMLImageArray: s } = o("./kernel-value/html-image-array"), { WebGL2KernelValueDynamicHTMLImageArray: t } = o("./kernel-value/dynamic-html-image-array"), { WebGL2KernelValueHTMLVideo: i } = o("./kernel-value/html-video"), { WebGL2KernelValueDynamicHTMLVideo: u } = o("./kernel-value/dynamic-html-video"), { WebGL2KernelValueSingleInput: x2 } = o("./kernel-value/single-input"), { WebGL2KernelValueDynamicSingleInput: w } = o("./kernel-value/dynamic-single-input"), { WebGL2KernelValueUnsignedInput: m } = o("./kernel-value/unsigned-input"), { WebGL2KernelValueDynamicUnsignedInput: S } = o("./kernel-value/dynamic-unsigned-input"), { WebGL2KernelValueMemoryOptimizedNumberTexture: v } = o("./kernel-value/memory-optimized-number-texture"), { WebGL2KernelValueDynamicMemoryOptimizedNumberTexture: h } = o("./kernel-value/dynamic-memory-optimized-number-texture"), { WebGL2KernelValueNumberTexture: b } = o("./kernel-value/number-texture"), { WebGL2KernelValueDynamicNumberTexture: T } = o("./kernel-value/dynamic-number-texture"), { WebGL2KernelValueSingleArray: C } = o("./kernel-value/single-array"), { WebGL2KernelValueDynamicSingleArray: V } = o("./kernel-value/dynamic-single-array"), { WebGL2KernelValueSingleArray1DI: c } = o("./kernel-value/single-array1d-i"), { WebGL2KernelValueDynamicSingleArray1DI: a } = o("./kernel-value/dynamic-single-array1d-i"), { WebGL2KernelValueSingleArray2DI: k } = o("./kernel-value/single-array2d-i"), { WebGL2KernelValueDynamicSingleArray2DI: A } = o("./kernel-value/dynamic-single-array2d-i"), { WebGL2KernelValueSingleArray3DI: N } = o("./kernel-value/single-array3d-i"), { WebGL2KernelValueDynamicSingleArray3DI: F } = o("./kernel-value/dynamic-single-array3d-i"), { WebGL2KernelValueSingleArray2: R } = o("./kernel-value/single-array2"), { WebGL2KernelValueSingleArray3: K } = o("./kernel-value/single-array3"), { WebGL2KernelValueSingleArray4: O } = o("./kernel-value/single-array4"), { WebGL2KernelValueUnsignedArray: X } = o("./kernel-value/unsigned-array"), { WebGL2KernelValueDynamicUnsignedArray: B } = o("./kernel-value/dynamic-unsigned-array"), P = { unsigned: { dynamic: { Boolean: p, Integer: f, Float: g, Array: B, "Array(2)": false, "Array(3)": false, "Array(4)": false, "Array1D(2)": false, "Array1D(3)": false, "Array1D(4)": false, "Array2D(2)": false, "Array2D(3)": false, "Array2D(4)": false, "Array3D(2)": false, "Array3D(3)": false, "Array3D(4)": false, Input: S, NumberTexture: T, "ArrayTexture(1)": T, "ArrayTexture(2)": T, "ArrayTexture(3)": T, "ArrayTexture(4)": T, MemoryOptimizedNumberTexture: h, HTMLCanvas: n, HTMLImage: n, HTMLImageArray: t, HTMLVideo: u }, static: { Boolean: p, Float: g, Integer: f, Array: X, "Array(2)": false, "Array(3)": false, "Array(4)": false, "Array1D(2)": false, "Array1D(3)": false, "Array1D(4)": false, "Array2D(2)": false, "Array2D(3)": false, "Array2D(4)": false, "Array3D(2)": false, "Array3D(3)": false, "Array3D(4)": false, Input: m, NumberTexture: b, "ArrayTexture(1)": b, "ArrayTexture(2)": b, "ArrayTexture(3)": b, "ArrayTexture(4)": b, MemoryOptimizedNumberTexture: h, HTMLCanvas: l, HTMLImage: l, HTMLImageArray: s, HTMLVideo: i } }, single: { dynamic: { Boolean: p, Integer: f, Float: g, Array: V, "Array(2)": R, "Array(3)": K, "Array(4)": O, "Array1D(2)": a, "Array1D(3)": a, "Array1D(4)": a, "Array2D(2)": A, "Array2D(3)": A, "Array2D(4)": A, "Array3D(2)": F, "Array3D(3)": F, "Array3D(4)": F, Input: w, NumberTexture: T, "ArrayTexture(1)": T, "ArrayTexture(2)": T, "ArrayTexture(3)": T, "ArrayTexture(4)": T, MemoryOptimizedNumberTexture: h, HTMLCanvas: n, HTMLImage: n, HTMLImageArray: t, HTMLVideo: u }, static: { Boolean: p, Float: g, Integer: f, Array: C, "Array(2)": R, "Array(3)": K, "Array(4)": O, "Array1D(2)": c, "Array1D(3)": c, "Array1D(4)": c, "Array2D(2)": k, "Array2D(3)": k, "Array2D(4)": k, "Array3D(2)": N, "Array3D(3)": N, "Array3D(4)": N, Input: x2, NumberTexture: b, "ArrayTexture(1)": b, "ArrayTexture(2)": b, "ArrayTexture(3)": b, "ArrayTexture(4)": b, MemoryOptimizedNumberTexture: v, HTMLCanvas: l, HTMLImage: l, HTMLImageArray: s, HTMLVideo: i } } }; + function Y(J, q, j, U) { + if (!J) + throw new Error("type missing"); + if (!q) + throw new Error("dynamic missing"); + if (!j) + throw new Error("precision missing"); + U.type && (J = U.type); + let oe = P[j][q]; + if (oe[J] === false) + return null; + if (oe[J] === void 0) + throw new Error(`Could not find a KernelValue for ${J}`); + return oe[J]; + } + y.exports = { kernelValueMaps: P, lookupKernelValueType: Y }; + }, { "./kernel-value/boolean": 75, "./kernel-value/dynamic-html-image": 77, "./kernel-value/dynamic-html-image-array": 76, "./kernel-value/dynamic-html-video": 78, "./kernel-value/dynamic-memory-optimized-number-texture": 79, "./kernel-value/dynamic-number-texture": 80, "./kernel-value/dynamic-single-array": 81, "./kernel-value/dynamic-single-array1d-i": 82, "./kernel-value/dynamic-single-array2d-i": 83, "./kernel-value/dynamic-single-array3d-i": 84, "./kernel-value/dynamic-single-input": 85, "./kernel-value/dynamic-unsigned-array": 86, "./kernel-value/dynamic-unsigned-input": 87, "./kernel-value/float": 88, "./kernel-value/html-image": 90, "./kernel-value/html-image-array": 89, "./kernel-value/html-video": 91, "./kernel-value/integer": 92, "./kernel-value/memory-optimized-number-texture": 93, "./kernel-value/number-texture": 94, "./kernel-value/single-array": 95, "./kernel-value/single-array1d-i": 96, "./kernel-value/single-array2": 97, "./kernel-value/single-array2d-i": 98, "./kernel-value/single-array3": 99, "./kernel-value/single-array3d-i": 100, "./kernel-value/single-array4": 101, "./kernel-value/single-input": 102, "./kernel-value/unsigned-array": 103, "./kernel-value/unsigned-input": 104 }], 75: [function(o, y, E) { + let { WebGLKernelValueBoolean: p } = o("../../web-gl/kernel-value/boolean"); + class g extends p { + } + y.exports = { WebGL2KernelValueBoolean: g }; + }, { "../../web-gl/kernel-value/boolean": 41 }], 76: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGL2KernelValueHTMLImageArray: g } = o("./html-image-array"); + class f extends g { + getSource() { + let n = this.getVariablePrecisionString(); + return p.linesToString([`uniform ${n} sampler2DArray ${this.id}`, `uniform ${n} ivec2 ${this.sizeId}`, `uniform ${n} ivec3 ${this.dimensionsId}`]); + } + updateValue(n) { + let { width: s, height: t } = n[0]; + this.checkSize(s, t), this.dimensions = [s, t, n.length], this.textureSize = [s, t], this.kernel.setUniform3iv(this.dimensionsId, this.dimensions), this.kernel.setUniform2iv(this.sizeId, this.textureSize), super.updateValue(n); + } + } + y.exports = { WebGL2KernelValueDynamicHTMLImageArray: f }; + }, { "../../../utils": 114, "./html-image-array": 89 }], 77: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueDynamicHTMLImage: g } = o("../../web-gl/kernel-value/dynamic-html-image"); + class f extends g { + getSource() { + let n = this.getVariablePrecisionString(); + return p.linesToString([`uniform ${n} sampler2D ${this.id}`, `uniform ${n} ivec2 ${this.sizeId}`, `uniform ${n} ivec3 ${this.dimensionsId}`]); + } + } + y.exports = { WebGL2KernelValueDynamicHTMLImage: f }; + }, { "../../../utils": 114, "../../web-gl/kernel-value/dynamic-html-image": 42 }], 78: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGL2KernelValueDynamicHTMLImage: g } = o("./dynamic-html-image"); + class f extends g { + } + y.exports = { WebGL2KernelValueDynamicHTMLVideo: f }; + }, { "../../../utils": 114, "./dynamic-html-image": 77 }], 79: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueDynamicMemoryOptimizedNumberTexture: g } = o("../../web-gl/kernel-value/dynamic-memory-optimized-number-texture"); + class f extends g { + getSource() { + return p.linesToString([`uniform sampler2D ${this.id}`, `uniform ivec2 ${this.sizeId}`, `uniform ivec3 ${this.dimensionsId}`]); + } + } + y.exports = { WebGL2KernelValueDynamicMemoryOptimizedNumberTexture: f }; + }, { "../../../utils": 114, "../../web-gl/kernel-value/dynamic-memory-optimized-number-texture": 44 }], 80: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueDynamicNumberTexture: g } = o("../../web-gl/kernel-value/dynamic-number-texture"); + class f extends g { + getSource() { + let n = this.getVariablePrecisionString(); + return p.linesToString([`uniform ${n} sampler2D ${this.id}`, `uniform ${n} ivec2 ${this.sizeId}`, `uniform ${n} ivec3 ${this.dimensionsId}`]); + } + } + y.exports = { WebGL2KernelValueDynamicNumberTexture: f }; + }, { "../../../utils": 114, "../../web-gl/kernel-value/dynamic-number-texture": 45 }], 81: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGL2KernelValueSingleArray: g } = o("../../web-gl2/kernel-value/single-array"); + class f extends g { + getSource() { + let n = this.getVariablePrecisionString(); + return p.linesToString([`uniform ${n} sampler2D ${this.id}`, `uniform ${n} ivec2 ${this.sizeId}`, `uniform ${n} ivec3 ${this.dimensionsId}`]); + } + updateValue(n) { + this.dimensions = p.getDimensions(n, true), this.textureSize = p.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio), this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio, this.checkSize(this.textureSize[0], this.textureSize[1]), this.uploadValue = new Float32Array(this.uploadArrayLength), this.kernel.setUniform3iv(this.dimensionsId, this.dimensions), this.kernel.setUniform2iv(this.sizeId, this.textureSize), super.updateValue(n); + } + } + y.exports = { WebGL2KernelValueDynamicSingleArray: f }; + }, { "../../../utils": 114, "../../web-gl2/kernel-value/single-array": 95 }], 82: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGL2KernelValueSingleArray1DI: g } = o("../../web-gl2/kernel-value/single-array1d-i"); + class f extends g { + getSource() { + let n = this.getVariablePrecisionString(); + return p.linesToString([`uniform ${n} sampler2D ${this.id}`, `uniform ${n} ivec2 ${this.sizeId}`, `uniform ${n} ivec3 ${this.dimensionsId}`]); + } + updateValue(n) { + this.setShape(n), this.kernel.setUniform3iv(this.dimensionsId, this.dimensions), this.kernel.setUniform2iv(this.sizeId, this.textureSize), super.updateValue(n); + } + } + y.exports = { WebGL2KernelValueDynamicSingleArray1DI: f }; + }, { "../../../utils": 114, "../../web-gl2/kernel-value/single-array1d-i": 96 }], 83: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGL2KernelValueSingleArray2DI: g } = o("../../web-gl2/kernel-value/single-array2d-i"); + class f extends g { + getSource() { + let n = this.getVariablePrecisionString(); + return p.linesToString([`uniform ${n} sampler2D ${this.id}`, `uniform ${n} ivec2 ${this.sizeId}`, `uniform ${n} ivec3 ${this.dimensionsId}`]); + } + updateValue(n) { + this.setShape(n), this.kernel.setUniform3iv(this.dimensionsId, this.dimensions), this.kernel.setUniform2iv(this.sizeId, this.textureSize), super.updateValue(n); + } + } + y.exports = { WebGL2KernelValueDynamicSingleArray2DI: f }; + }, { "../../../utils": 114, "../../web-gl2/kernel-value/single-array2d-i": 98 }], 84: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGL2KernelValueSingleArray3DI: g } = o("../../web-gl2/kernel-value/single-array3d-i"); + class f extends g { + getSource() { + let n = this.getVariablePrecisionString(); + return p.linesToString([`uniform ${n} sampler2D ${this.id}`, `uniform ${n} ivec2 ${this.sizeId}`, `uniform ${n} ivec3 ${this.dimensionsId}`]); + } + updateValue(n) { + this.setShape(n), this.kernel.setUniform3iv(this.dimensionsId, this.dimensions), this.kernel.setUniform2iv(this.sizeId, this.textureSize), super.updateValue(n); + } + } + y.exports = { WebGL2KernelValueDynamicSingleArray3DI: f }; + }, { "../../../utils": 114, "../../web-gl2/kernel-value/single-array3d-i": 100 }], 85: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGL2KernelValueSingleInput: g } = o("../../web-gl2/kernel-value/single-input"); + class f extends g { + getSource() { + let n = this.getVariablePrecisionString(); + return p.linesToString([`uniform ${n} sampler2D ${this.id}`, `uniform ${n} ivec2 ${this.sizeId}`, `uniform ${n} ivec3 ${this.dimensionsId}`]); + } + updateValue(n) { + let [s, t, i] = n.size; + this.dimensions = new Int32Array([s || 1, t || 1, i || 1]), this.textureSize = p.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio), this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio, this.checkSize(this.textureSize[0], this.textureSize[1]), this.uploadValue = new Float32Array(this.uploadArrayLength), this.kernel.setUniform3iv(this.dimensionsId, this.dimensions), this.kernel.setUniform2iv(this.sizeId, this.textureSize), super.updateValue(n); + } + } + y.exports = { WebGL2KernelValueDynamicSingleInput: f }; + }, { "../../../utils": 114, "../../web-gl2/kernel-value/single-input": 102 }], 86: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueDynamicUnsignedArray: g } = o("../../web-gl/kernel-value/dynamic-unsigned-array"); + class f extends g { + getSource() { + let n = this.getVariablePrecisionString(); + return p.linesToString([`uniform ${n} sampler2D ${this.id}`, `uniform ${n} ivec2 ${this.sizeId}`, `uniform ${n} ivec3 ${this.dimensionsId}`]); + } + } + y.exports = { WebGL2KernelValueDynamicUnsignedArray: f }; + }, { "../../../utils": 114, "../../web-gl/kernel-value/dynamic-unsigned-array": 51 }], 87: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueDynamicUnsignedInput: g } = o("../../web-gl/kernel-value/dynamic-unsigned-input"); + class f extends g { + getSource() { + let n = this.getVariablePrecisionString(); + return p.linesToString([`uniform ${n} sampler2D ${this.id}`, `uniform ${n} ivec2 ${this.sizeId}`, `uniform ${n} ivec3 ${this.dimensionsId}`]); + } + } + y.exports = { WebGL2KernelValueDynamicUnsignedInput: f }; + }, { "../../../utils": 114, "../../web-gl/kernel-value/dynamic-unsigned-input": 52 }], 88: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueFloat: g } = o("../../web-gl/kernel-value/float"); + class f extends g { + } + y.exports = { WebGL2KernelValueFloat: f }; + }, { "../../../utils": 114, "../../web-gl/kernel-value/float": 53 }], 89: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelArray: g } = o("../../web-gl/kernel-value/array"); + class f extends g { + constructor(n, s) { + super(n, s), this.checkSize(n[0].width, n[0].height), this.dimensions = [n[0].width, n[0].height, n.length], this.textureSize = [n[0].width, n[0].height]; + } + defineTexture() { + let { context: n } = this; + n.activeTexture(this.contextHandle), n.bindTexture(n.TEXTURE_2D_ARRAY, this.texture), n.texParameteri(n.TEXTURE_2D_ARRAY, n.TEXTURE_MAG_FILTER, n.NEAREST), n.texParameteri(n.TEXTURE_2D_ARRAY, n.TEXTURE_MIN_FILTER, n.NEAREST); + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName}; +`; + } + getSource() { + let n = this.getVariablePrecisionString(); + return p.linesToString([`uniform ${n} sampler2DArray ${this.id}`, `${n} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, `${n} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`]); + } + updateValue(n) { + let { context: s } = this; + s.activeTexture(this.contextHandle), s.bindTexture(s.TEXTURE_2D_ARRAY, this.texture), s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL, true), s.texImage3D(s.TEXTURE_2D_ARRAY, 0, s.RGBA, n[0].width, n[0].height, n.length, 0, s.RGBA, s.UNSIGNED_BYTE, null); + for (let t = 0; t < n.length; t++) + s.texSubImage3D(s.TEXTURE_2D_ARRAY, 0, 0, 0, t, n[t].width, n[t].height, 1, s.RGBA, s.UNSIGNED_BYTE, this.uploadValue = n[t]); + this.kernel.setUniform1i(this.id, this.index); + } + } + y.exports = { WebGL2KernelValueHTMLImageArray: f }; + }, { "../../../utils": 114, "../../web-gl/kernel-value/array": 40 }], 90: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueHTMLImage: g } = o("../../web-gl/kernel-value/html-image"); + class f extends g { + getSource() { + let n = this.getVariablePrecisionString(); + return p.linesToString([`uniform ${n} sampler2D ${this.id}`, `${n} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, `${n} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`]); + } + } + y.exports = { WebGL2KernelValueHTMLImage: f }; + }, { "../../../utils": 114, "../../web-gl/kernel-value/html-image": 54 }], 91: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGL2KernelValueHTMLImage: g } = o("./html-image"); + class f extends g { + } + y.exports = { WebGL2KernelValueHTMLVideo: f }; + }, { "../../../utils": 114, "./html-image": 90 }], 92: [function(o, y, E) { + let { WebGLKernelValueInteger: p } = o("../../web-gl/kernel-value/integer"); + class g extends p { + getSource(l) { + let n = this.getVariablePrecisionString(); + return this.origin === "constants" ? `const ${n} int ${this.id} = ${parseInt(l)}; +` : `uniform ${n} int ${this.id}; +`; + } + updateValue(l) { + this.origin !== "constants" && this.kernel.setUniform1i(this.id, this.uploadValue = l); + } + } + y.exports = { WebGL2KernelValueInteger: g }; + }, { "../../web-gl/kernel-value/integer": 57 }], 93: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueMemoryOptimizedNumberTexture: g } = o("../../web-gl/kernel-value/memory-optimized-number-texture"); + class f extends g { + getSource() { + let { id: n, sizeId: s, textureSize: t, dimensionsId: i, dimensions: u } = this, x2 = this.getVariablePrecisionString(); + return p.linesToString([`uniform sampler2D ${n}`, `${x2} ivec2 ${s} = ivec2(${t[0]}, ${t[1]})`, `${x2} ivec3 ${i} = ivec3(${u[0]}, ${u[1]}, ${u[2]})`]); + } + } + y.exports = { WebGL2KernelValueMemoryOptimizedNumberTexture: f }; + }, { "../../../utils": 114, "../../web-gl/kernel-value/memory-optimized-number-texture": 58 }], 94: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueNumberTexture: g } = o("../../web-gl/kernel-value/number-texture"); + class f extends g { + getSource() { + let { id: n, sizeId: s, textureSize: t, dimensionsId: i, dimensions: u } = this, x2 = this.getVariablePrecisionString(); + return p.linesToString([`uniform ${x2} sampler2D ${n}`, `${x2} ivec2 ${s} = ivec2(${t[0]}, ${t[1]})`, `${x2} ivec3 ${i} = ivec3(${u[0]}, ${u[1]}, ${u[2]})`]); + } + } + y.exports = { WebGL2KernelValueNumberTexture: f }; + }, { "../../../utils": 114, "../../web-gl/kernel-value/number-texture": 59 }], 95: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueSingleArray: g } = o("../../web-gl/kernel-value/single-array"); + class f extends g { + getSource() { + let n = this.getVariablePrecisionString(); + return p.linesToString([`uniform ${n} sampler2D ${this.id}`, `${n} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, `${n} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`]); + } + updateValue(n) { + if (n.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(n.constructor); + return; + } + let { context: s } = this; + p.flattenTo(n, this.uploadValue), s.activeTexture(this.contextHandle), s.bindTexture(s.TEXTURE_2D, this.texture), s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL, false), s.texImage2D(s.TEXTURE_2D, 0, s.RGBA32F, this.textureSize[0], this.textureSize[1], 0, s.RGBA, s.FLOAT, this.uploadValue), this.kernel.setUniform1i(this.id, this.index); + } + } + y.exports = { WebGL2KernelValueSingleArray: f }; + }, { "../../../utils": 114, "../../web-gl/kernel-value/single-array": 60 }], 96: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueSingleArray1DI: g } = o("../../web-gl/kernel-value/single-array1d-i"); + class f extends g { + updateValue(n) { + if (n.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(n.constructor); + return; + } + let { context: s } = this; + p.flattenTo(n, this.uploadValue), s.activeTexture(this.contextHandle), s.bindTexture(s.TEXTURE_2D, this.texture), s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL, false), s.texImage2D(s.TEXTURE_2D, 0, s.RGBA32F, this.textureSize[0], this.textureSize[1], 0, s.RGBA, s.FLOAT, this.uploadValue), this.kernel.setUniform1i(this.id, this.index); + } + } + y.exports = { WebGL2KernelValueSingleArray1DI: f }; + }, { "../../../utils": 114, "../../web-gl/kernel-value/single-array1d-i": 61 }], 97: [function(o, y, E) { + let { WebGLKernelValueSingleArray2: p } = o("../../web-gl/kernel-value/single-array2"); + class g extends p { + } + y.exports = { WebGL2KernelValueSingleArray2: g }; + }, { "../../web-gl/kernel-value/single-array2": 62 }], 98: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueSingleArray2DI: g } = o("../../web-gl/kernel-value/single-array2d-i"); + class f extends g { + updateValue(n) { + if (n.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(n.constructor); + return; + } + let { context: s } = this; + p.flattenTo(n, this.uploadValue), s.activeTexture(this.contextHandle), s.bindTexture(s.TEXTURE_2D, this.texture), s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL, false), s.texImage2D(s.TEXTURE_2D, 0, s.RGBA32F, this.textureSize[0], this.textureSize[1], 0, s.RGBA, s.FLOAT, this.uploadValue), this.kernel.setUniform1i(this.id, this.index); + } + } + y.exports = { WebGL2KernelValueSingleArray2DI: f }; + }, { "../../../utils": 114, "../../web-gl/kernel-value/single-array2d-i": 63 }], 99: [function(o, y, E) { + let { WebGLKernelValueSingleArray3: p } = o("../../web-gl/kernel-value/single-array3"); + class g extends p { + } + y.exports = { WebGL2KernelValueSingleArray3: g }; + }, { "../../web-gl/kernel-value/single-array3": 64 }], 100: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueSingleArray3DI: g } = o("../../web-gl/kernel-value/single-array3d-i"); + class f extends g { + updateValue(n) { + if (n.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(n.constructor); + return; + } + let { context: s } = this; + p.flattenTo(n, this.uploadValue), s.activeTexture(this.contextHandle), s.bindTexture(s.TEXTURE_2D, this.texture), s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL, false), s.texImage2D(s.TEXTURE_2D, 0, s.RGBA32F, this.textureSize[0], this.textureSize[1], 0, s.RGBA, s.FLOAT, this.uploadValue), this.kernel.setUniform1i(this.id, this.index); + } + } + y.exports = { WebGL2KernelValueSingleArray3DI: f }; + }, { "../../../utils": 114, "../../web-gl/kernel-value/single-array3d-i": 65 }], 101: [function(o, y, E) { + let { WebGLKernelValueSingleArray4: p } = o("../../web-gl/kernel-value/single-array4"); + class g extends p { + } + y.exports = { WebGL2KernelValueSingleArray4: g }; + }, { "../../web-gl/kernel-value/single-array4": 66 }], 102: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueSingleInput: g } = o("../../web-gl/kernel-value/single-input"); + class f extends g { + getSource() { + let n = this.getVariablePrecisionString(); + return p.linesToString([`uniform ${n} sampler2D ${this.id}`, `${n} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, `${n} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`]); + } + updateValue(n) { + let { context: s } = this; + p.flattenTo(n.value, this.uploadValue), s.activeTexture(this.contextHandle), s.bindTexture(s.TEXTURE_2D, this.texture), s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL, false), s.texImage2D(s.TEXTURE_2D, 0, s.RGBA32F, this.textureSize[0], this.textureSize[1], 0, s.RGBA, s.FLOAT, this.uploadValue), this.kernel.setUniform1i(this.id, this.index); + } + } + y.exports = { WebGL2KernelValueSingleInput: f }; + }, { "../../../utils": 114, "../../web-gl/kernel-value/single-input": 67 }], 103: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueUnsignedArray: g } = o("../../web-gl/kernel-value/unsigned-array"); + class f extends g { + getSource() { + let n = this.getVariablePrecisionString(); + return p.linesToString([`uniform ${n} sampler2D ${this.id}`, `${n} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, `${n} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`]); + } + } + y.exports = { WebGL2KernelValueUnsignedArray: f }; + }, { "../../../utils": 114, "../../web-gl/kernel-value/unsigned-array": 68 }], 104: [function(o, y, E) { + let { utils: p } = o("../../../utils"), { WebGLKernelValueUnsignedInput: g } = o("../../web-gl/kernel-value/unsigned-input"); + class f extends g { + getSource() { + let n = this.getVariablePrecisionString(); + return p.linesToString([`uniform ${n} sampler2D ${this.id}`, `${n} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, `${n} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`]); + } + } + y.exports = { WebGL2KernelValueUnsignedInput: f }; + }, { "../../../utils": 114, "../../web-gl/kernel-value/unsigned-input": 69 }], 105: [function(o, y, E) { + let { WebGLKernel: p } = o("../web-gl/kernel"), { WebGL2FunctionNode: g } = o("./function-node"), { FunctionBuilder: f } = o("../function-builder"), { utils: l } = o("../../utils"), { fragmentShader: n } = o("./fragment-shader"), { vertexShader: s } = o("./vertex-shader"), { lookupKernelValueType: t } = o("./kernel-value-maps"), i = null, u = null, x2 = null, w = null, m = null; + class S extends p { + static get isSupported() { + return i !== null || (this.setupFeatureChecks(), i = this.isContextMatch(x2)), i; + } + static setupFeatureChecks() { + typeof document < "u" ? u = document.createElement("canvas") : typeof OffscreenCanvas < "u" && (u = new OffscreenCanvas(0, 0)), u && (x2 = u.getContext("webgl2"), !(!x2 || !x2.getExtension) && (w = { EXT_color_buffer_float: x2.getExtension("EXT_color_buffer_float"), OES_texture_float_linear: x2.getExtension("OES_texture_float_linear") }, m = this.getFeatures())); + } + static isContextMatch(h) { + return typeof WebGL2RenderingContext < "u" ? h instanceof WebGL2RenderingContext : false; + } + static getFeatures() { + let h = this.testContext; + return Object.freeze({ isFloatRead: this.getIsFloatRead(), isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), isSpeedTacticSupported: this.getIsSpeedTacticSupported(), kernelMap: true, isTextureFloat: true, isDrawBuffers: true, channelCount: this.getChannelCount(), maxTextureSize: this.getMaxTextureSize(), lowIntPrecision: h.getShaderPrecisionFormat(h.FRAGMENT_SHADER, h.LOW_INT), lowFloatPrecision: h.getShaderPrecisionFormat(h.FRAGMENT_SHADER, h.LOW_FLOAT), mediumIntPrecision: h.getShaderPrecisionFormat(h.FRAGMENT_SHADER, h.MEDIUM_INT), mediumFloatPrecision: h.getShaderPrecisionFormat(h.FRAGMENT_SHADER, h.MEDIUM_FLOAT), highIntPrecision: h.getShaderPrecisionFormat(h.FRAGMENT_SHADER, h.HIGH_INT), highFloatPrecision: h.getShaderPrecisionFormat(h.FRAGMENT_SHADER, h.HIGH_FLOAT) }); + } + static getIsTextureFloat() { + return true; + } + static getChannelCount() { + return x2.getParameter(x2.MAX_DRAW_BUFFERS); + } + static getMaxTextureSize() { + return x2.getParameter(x2.MAX_TEXTURE_SIZE); + } + static lookupKernelValueType(h, b, T, C) { + return t(h, b, T, C); + } + static get testCanvas() { + return u; + } + static get testContext() { + return x2; + } + static get features() { + return m; + } + static get fragmentShader() { + return n; + } + static get vertexShader() { + return s; + } + initContext() { + let h = { alpha: false, depth: false, antialias: false }; + return this.canvas.getContext("webgl2", h); + } + initExtensions() { + this.extensions = { EXT_color_buffer_float: this.context.getExtension("EXT_color_buffer_float"), OES_texture_float_linear: this.context.getExtension("OES_texture_float_linear") }; + } + validateSettings(h) { + if (!this.validate) { + this.texSize = l.getKernelTextureSize({ optimizeFloatMemory: this.optimizeFloatMemory, precision: this.precision }, this.output); + return; + } + let { features: b } = this.constructor; + if (this.precision === "single" && !b.isFloatRead) + throw new Error("Float texture outputs are not supported"); + if (!this.graphical && this.precision === null && (this.precision = b.isFloatRead ? "single" : "unsigned"), this.fixIntegerDivisionAccuracy === null ? this.fixIntegerDivisionAccuracy = !b.isIntegerDivisionAccurate : this.fixIntegerDivisionAccuracy && b.isIntegerDivisionAccurate && (this.fixIntegerDivisionAccuracy = false), this.checkOutput(), !this.output || this.output.length === 0) { + if (h.length !== 1) + throw new Error("Auto output only supported for kernels with only one input"); + let T = l.getVariableType(h[0], this.strictIntegers); + switch (T) { + case "Array": + this.output = l.getDimensions(T); + break; + case "NumberTexture": + case "MemoryOptimizedNumberTexture": + case "ArrayTexture(1)": + case "ArrayTexture(2)": + case "ArrayTexture(3)": + case "ArrayTexture(4)": + this.output = h[0].output; + break; + default: + throw new Error("Auto output not supported for input type: " + T); + } + } + if (this.graphical) { + if (this.output.length !== 2) + throw new Error("Output must have 2 dimensions on graphical mode"); + this.precision === "single" && (console.warn("Cannot use graphical mode and single precision at the same time"), this.precision = "unsigned"), this.texSize = l.clone(this.output); + return; + } else + !this.graphical && this.precision === null && b.isTextureFloat && (this.precision = "single"); + this.texSize = l.getKernelTextureSize({ optimizeFloatMemory: this.optimizeFloatMemory, precision: this.precision }, this.output), this.checkTextureSize(); + } + translateSource() { + let h = f.fromKernel(this, g, { fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy }); + this.translatedSource = h.getPrototypeString("kernel"), this.setupReturnTypes(h); + } + drawBuffers() { + this.context.drawBuffers(this.drawBuffersMap); + } + getTextureFormat() { + let { context: h } = this; + switch (this.getInternalFormat()) { + case h.R32F: + return h.RED; + case h.RG32F: + return h.RG; + case h.RGBA32F: + return h.RGBA; + case h.RGBA: + return h.RGBA; + default: + throw new Error("Unknown internal format"); + } + } + getInternalFormat() { + let { context: h } = this; + if (this.precision === "single") { + if (this.pipeline) + switch (this.returnType) { + case "Number": + case "Float": + case "Integer": + return this.optimizeFloatMemory ? h.RGBA32F : h.R32F; + case "Array(2)": + return h.RG32F; + case "Array(3)": + case "Array(4)": + return h.RGBA32F; + default: + throw new Error("Unhandled return type"); + } + return h.RGBA32F; + } + return h.RGBA; + } + _setupOutputTexture() { + let h = this.context; + if (this.texture) { + h.framebufferTexture2D(h.FRAMEBUFFER, h.COLOR_ATTACHMENT0, h.TEXTURE_2D, this.texture.texture, 0); + return; + } + h.bindFramebuffer(h.FRAMEBUFFER, this.framebuffer); + let b = h.createTexture(), T = this.texSize; + h.activeTexture(h.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount), h.bindTexture(h.TEXTURE_2D, b), h.texParameteri(h.TEXTURE_2D, h.TEXTURE_WRAP_S, h.REPEAT), h.texParameteri(h.TEXTURE_2D, h.TEXTURE_WRAP_T, h.REPEAT), h.texParameteri(h.TEXTURE_2D, h.TEXTURE_MIN_FILTER, h.NEAREST), h.texParameteri(h.TEXTURE_2D, h.TEXTURE_MAG_FILTER, h.NEAREST); + let C = this.getInternalFormat(); + this.precision === "single" ? h.texStorage2D(h.TEXTURE_2D, 1, C, T[0], T[1]) : h.texImage2D(h.TEXTURE_2D, 0, C, T[0], T[1], 0, C, h.UNSIGNED_BYTE, null), h.framebufferTexture2D(h.FRAMEBUFFER, h.COLOR_ATTACHMENT0, h.TEXTURE_2D, b, 0), this.texture = new this.TextureConstructor({ texture: b, size: T, dimensions: this.threadDim, output: this.output, context: this.context, internalFormat: this.getInternalFormat(), textureFormat: this.getTextureFormat(), kernel: this }); + } + _setupSubOutputTextures() { + let h = this.context; + if (this.mappedTextures) { + for (let T = 0; T < this.subKernels.length; T++) + h.framebufferTexture2D(h.FRAMEBUFFER, h.COLOR_ATTACHMENT0 + T + 1, h.TEXTURE_2D, this.mappedTextures[T].texture, 0); + return; + } + let b = this.texSize; + this.drawBuffersMap = [h.COLOR_ATTACHMENT0], this.mappedTextures = []; + for (let T = 0; T < this.subKernels.length; T++) { + let C = this.createTexture(); + this.drawBuffersMap.push(h.COLOR_ATTACHMENT0 + T + 1), h.activeTexture(h.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + T), h.bindTexture(h.TEXTURE_2D, C), h.texParameteri(h.TEXTURE_2D, h.TEXTURE_WRAP_S, h.CLAMP_TO_EDGE), h.texParameteri(h.TEXTURE_2D, h.TEXTURE_WRAP_T, h.CLAMP_TO_EDGE), h.texParameteri(h.TEXTURE_2D, h.TEXTURE_MIN_FILTER, h.NEAREST), h.texParameteri(h.TEXTURE_2D, h.TEXTURE_MAG_FILTER, h.NEAREST); + let V = this.getInternalFormat(); + this.precision === "single" ? h.texStorage2D(h.TEXTURE_2D, 1, V, b[0], b[1]) : h.texImage2D(h.TEXTURE_2D, 0, h.RGBA, b[0], b[1], 0, h.RGBA, h.UNSIGNED_BYTE, null), h.framebufferTexture2D(h.FRAMEBUFFER, h.COLOR_ATTACHMENT0 + T + 1, h.TEXTURE_2D, C, 0), this.mappedTextures.push(new this.TextureConstructor({ texture: C, size: b, dimensions: this.threadDim, output: this.output, context: this.context, internalFormat: this.getInternalFormat(), textureFormat: this.getTextureFormat(), kernel: this })); + } + } + _getHeaderString() { + return ""; + } + _getTextureCoordinate() { + let h = this.subKernels, b = this.getVariablePrecisionString(this.texSize, this.tactic); + return h === null || h.length < 1 ? `in ${b} vec2 vTexCoord; +` : `out ${b} vec2 vTexCoord; +`; + } + _getMainArgumentsString(h) { + let b = [], T = this.argumentNames; + for (let C = 0; C < T.length; C++) + b.push(this.kernelArguments[C].getSource(h[C])); + return b.join(""); + } + getKernelString() { + let h = [this.getKernelResultDeclaration()], b = this.subKernels; + if (b !== null) + switch (h.push("layout(location = 0) out vec4 data0"), this.returnType) { + case "Number": + case "Float": + case "Integer": + for (let T = 0; T < b.length; T++) { + let C = b[T]; + h.push(C.returnType === "Integer" ? `int subKernelResult_${C.name} = 0` : `float subKernelResult_${C.name} = 0.0`, `layout(location = ${T + 1}) out vec4 data${T + 1}`); + } + break; + case "Array(2)": + for (let T = 0; T < b.length; T++) + h.push(`vec2 subKernelResult_${b[T].name}`, `layout(location = ${T + 1}) out vec4 data${T + 1}`); + break; + case "Array(3)": + for (let T = 0; T < b.length; T++) + h.push(`vec3 subKernelResult_${b[T].name}`, `layout(location = ${T + 1}) out vec4 data${T + 1}`); + break; + case "Array(4)": + for (let T = 0; T < b.length; T++) + h.push(`vec4 subKernelResult_${b[T].name}`, `layout(location = ${T + 1}) out vec4 data${T + 1}`); + break; + } + else + h.push("out vec4 data0"); + return l.linesToString(h) + this.translatedSource; + } + getMainResultGraphical() { + return l.linesToString([" threadId = indexTo3D(index, uOutputDim)", " kernel()", " data0 = actualColor"]); + } + getMainResultPackedPixels() { + switch (this.returnType) { + case "LiteralInteger": + case "Number": + case "Integer": + case "Float": + return this.getMainResultKernelPackedPixels() + this.getMainResultSubKernelPackedPixels(); + default: + throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`); + } + } + getMainResultKernelPackedPixels() { + return l.linesToString([" threadId = indexTo3D(index, uOutputDim)", " kernel()", ` data0 = ${this.useLegacyEncoder ? "legacyEncode32" : "encode32"}(kernelResult)`]); + } + getMainResultSubKernelPackedPixels() { + let h = []; + if (!this.subKernels) + return ""; + for (let b = 0; b < this.subKernels.length; b++) + this.subKernels[b].returnType === "Integer" ? h.push(` data${b + 1} = ${this.useLegacyEncoder ? "legacyEncode32" : "encode32"}(float(subKernelResult_${this.subKernels[b].name}))`) : h.push(` data${b + 1} = ${this.useLegacyEncoder ? "legacyEncode32" : "encode32"}(subKernelResult_${this.subKernels[b].name})`); + return l.linesToString(h); + } + getMainResultKernelMemoryOptimizedFloats(h, b) { + h.push(" threadId = indexTo3D(index, uOutputDim)", " kernel()", ` data0.${b} = kernelResult`); + } + getMainResultSubKernelMemoryOptimizedFloats(h, b) { + if (!this.subKernels) + return h; + for (let T = 0; T < this.subKernels.length; T++) { + let C = this.subKernels[T]; + C.returnType === "Integer" ? h.push(` data${T + 1}.${b} = float(subKernelResult_${C.name})`) : h.push(` data${T + 1}.${b} = subKernelResult_${C.name}`); + } + } + getMainResultKernelNumberTexture() { + return [" threadId = indexTo3D(index, uOutputDim)", " kernel()", " data0[0] = kernelResult"]; + } + getMainResultSubKernelNumberTexture() { + let h = []; + if (!this.subKernels) + return h; + for (let b = 0; b < this.subKernels.length; ++b) { + let T = this.subKernels[b]; + T.returnType === "Integer" ? h.push(` data${b + 1}[0] = float(subKernelResult_${T.name})`) : h.push(` data${b + 1}[0] = subKernelResult_${T.name}`); + } + return h; + } + getMainResultKernelArray2Texture() { + return [" threadId = indexTo3D(index, uOutputDim)", " kernel()", " data0[0] = kernelResult[0]", " data0[1] = kernelResult[1]"]; + } + getMainResultSubKernelArray2Texture() { + let h = []; + if (!this.subKernels) + return h; + for (let b = 0; b < this.subKernels.length; ++b) { + let T = this.subKernels[b]; + h.push(` data${b + 1}[0] = subKernelResult_${T.name}[0]`, ` data${b + 1}[1] = subKernelResult_${T.name}[1]`); + } + return h; + } + getMainResultKernelArray3Texture() { + return [" threadId = indexTo3D(index, uOutputDim)", " kernel()", " data0[0] = kernelResult[0]", " data0[1] = kernelResult[1]", " data0[2] = kernelResult[2]"]; + } + getMainResultSubKernelArray3Texture() { + let h = []; + if (!this.subKernels) + return h; + for (let b = 0; b < this.subKernels.length; ++b) { + let T = this.subKernels[b]; + h.push(` data${b + 1}[0] = subKernelResult_${T.name}[0]`, ` data${b + 1}[1] = subKernelResult_${T.name}[1]`, ` data${b + 1}[2] = subKernelResult_${T.name}[2]`); + } + return h; + } + getMainResultKernelArray4Texture() { + return [" threadId = indexTo3D(index, uOutputDim)", " kernel()", " data0 = kernelResult"]; + } + getMainResultSubKernelArray4Texture() { + let h = []; + if (!this.subKernels) + return h; + for (let b = 0; b < this.subKernels.length; ++b) + h.push(` data${b + 1} = subKernelResult_${this.subKernels[b].name}`); + return h; + } + destroyExtensions() { + this.extensions.EXT_color_buffer_float = null, this.extensions.OES_texture_float_linear = null; + } + toJSON() { + let h = super.toJSON(); + return h.functionNodes = f.fromKernel(this, g).toJSON(), h.settings.threadDim = this.threadDim, h; + } + } + y.exports = { WebGL2Kernel: S }; + }, { "../../utils": 114, "../function-builder": 9, "../web-gl/kernel": 70, "./fragment-shader": 72, "./function-node": 73, "./kernel-value-maps": 74, "./vertex-shader": 106 }], 106: [function(o, y, E) { + let p = `#version 300 es + __FLOAT_TACTIC_DECLARATION__; + __INT_TACTIC_DECLARATION__; + __SAMPLER_2D_TACTIC_DECLARATION__; + + in vec2 aPos; + in vec2 aTexCoord; + + out vec2 vTexCoord; + uniform vec2 ratio; + + void main(void) { + gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1); + vTexCoord = aTexCoord; + }`; + y.exports = { vertexShader: p }; + }, {}], 107: [function(o, y, E) { + let p = o("./index"), g = p.GPU; + for (let l in p) + !p.hasOwnProperty(l) || l !== "GPU" && (g[l] = p[l]); + typeof window < "u" && f(window), typeof self < "u" && f(self); + function f(l) { + l.GPU || Object.defineProperty(l, "GPU", { get() { + return g; + } }); + } + y.exports = p; + }, { "./index": 109 }], 108: [function(o, y, E) { + let { gpuMock: p } = o("gpu-mock.js"), { utils: g } = o("./utils"), { Kernel: f } = o("./backend/kernel"), { CPUKernel: l } = o("./backend/cpu/kernel"), { HeadlessGLKernel: n } = o("./backend/headless-gl/kernel"), { WebGL2Kernel: s } = o("./backend/web-gl2/kernel"), { WebGLKernel: t } = o("./backend/web-gl/kernel"), { kernelRunShortcut: i } = o("./kernel-run-shortcut"), u = [n, s, t], x2 = ["gpu", "cpu"], w = { headlessgl: n, webgl2: s, webgl: t }, m = true; + class S { + static disableValidation() { + m = false; + } + static enableValidation() { + m = true; + } + static get isGPUSupported() { + return u.some((b) => b.isSupported); + } + static get isKernelMapSupported() { + return u.some((b) => b.isSupported && b.features.kernelMap); + } + static get isOffscreenCanvasSupported() { + return typeof Worker < "u" && typeof OffscreenCanvas < "u" || typeof importScripts < "u"; + } + static get isWebGLSupported() { + return t.isSupported; + } + static get isWebGL2Supported() { + return s.isSupported; + } + static get isHeadlessGLSupported() { + return n.isSupported; + } + static get isCanvasSupported() { + return typeof HTMLCanvasElement < "u"; + } + static get isGPUHTMLImageArraySupported() { + return s.isSupported; + } + static get isSinglePrecisionSupported() { + return u.some((b) => b.isSupported && b.features.isFloatRead && b.features.isTextureFloat); + } + constructor(b) { + if (b = b || {}, this.canvas = b.canvas || null, this.context = b.context || null, this.mode = b.mode, this.Kernel = null, this.kernels = [], this.functions = [], this.nativeFunctions = [], this.injectedNative = null, this.mode !== "dev") { + if (this.chooseKernel(), b.functions) + for (let T = 0; T < b.functions.length; T++) + this.addFunction(b.functions[T]); + if (b.nativeFunctions) + for (let T in b.nativeFunctions) { + if (!b.nativeFunctions.hasOwnProperty(T)) + continue; + let C = b.nativeFunctions[T], { name: V, source: c } = C; + this.addNativeFunction(V, c, C); + } + } + } + chooseKernel() { + if (this.Kernel) + return; + let b = null; + if (this.context) { + for (let T = 0; T < u.length; T++) { + let C = u[T]; + if (C.isContextMatch(this.context)) { + if (!C.isSupported) + throw new Error(`Kernel type ${C.name} not supported`); + b = C; + break; + } + } + if (b === null) + throw new Error("unknown Context"); + } else if (this.mode) { + if (this.mode in w) + (!m || w[this.mode].isSupported) && (b = w[this.mode]); + else if (this.mode === "gpu") { + for (let T = 0; T < u.length; T++) + if (u[T].isSupported) { + b = u[T]; + break; + } + } else + this.mode === "cpu" && (b = l); + if (!b) + throw new Error(`A requested mode of "${this.mode}" and is not supported`); + } else { + for (let T = 0; T < u.length; T++) + if (u[T].isSupported) { + b = u[T]; + break; + } + b || (b = l); + } + this.mode || (this.mode = b.mode), this.Kernel = b; + } + createKernel(b, T) { + if (typeof b > "u") + throw new Error("Missing source parameter"); + if (typeof b != "object" && !g.isFunction(b) && typeof b != "string") + throw new Error("source parameter not a function"); + let C = this.kernels; + if (this.mode === "dev") { + let R = p(b, v(T)); + return C.push(R), R; + } + b = typeof b == "function" ? b.toString() : b; + let V = {}, c = v(T) || {}; + T && typeof T.argumentTypes == "object" && (c.argumentTypes = Object.keys(T.argumentTypes).map((R) => T.argumentTypes[R])); + function a(R) { + console.warn("Falling back to CPU"); + let K = new l(b, { argumentTypes: F.argumentTypes, constantTypes: F.constantTypes, graphical: F.graphical, loopMaxIterations: F.loopMaxIterations, constants: F.constants, dynamicOutput: F.dynamicOutput, dynamicArgument: F.dynamicArguments, output: F.output, precision: F.precision, pipeline: F.pipeline, immutable: F.immutable, optimizeFloatMemory: F.optimizeFloatMemory, fixIntegerDivisionAccuracy: F.fixIntegerDivisionAccuracy, functions: F.functions, nativeFunctions: F.nativeFunctions, injectedNative: F.injectedNative, subKernels: F.subKernels, strictIntegers: F.strictIntegers, debug: F.debug }); + K.build.apply(K, R); + let O = K.run.apply(K, R); + return F.replaceKernel(K), O; + } + function k(R, K, O) { + O.debug && console.warn("Switching kernels"); + let X = null; + if (O.signature && !V[O.signature] && (V[O.signature] = O), O.dynamicOutput) + for (let j = R.length - 1; j >= 0; j--) { + let U = R[j]; + U.type === "outputPrecisionMismatch" && (X = U.needed); + } + let B = O.constructor, P = B.getArgumentTypes(O, K), Y = B.getSignature(O, P), J = V[Y]; + if (J) + return J.onActivate(O), J; + let q = V[Y] = new B(b, { argumentTypes: P, constantTypes: O.constantTypes, graphical: O.graphical, loopMaxIterations: O.loopMaxIterations, constants: O.constants, dynamicOutput: O.dynamicOutput, dynamicArgument: O.dynamicArguments, context: O.context, canvas: O.canvas, output: X || O.output, precision: O.precision, pipeline: O.pipeline, immutable: O.immutable, optimizeFloatMemory: O.optimizeFloatMemory, fixIntegerDivisionAccuracy: O.fixIntegerDivisionAccuracy, functions: O.functions, nativeFunctions: O.nativeFunctions, injectedNative: O.injectedNative, subKernels: O.subKernels, strictIntegers: O.strictIntegers, debug: O.debug, gpu: O.gpu, validate: m, returnType: O.returnType, tactic: O.tactic, onRequestFallback: a, onRequestSwitchKernel: k, texture: O.texture, mappedTextures: O.mappedTextures, drawBuffersMap: O.drawBuffersMap }); + return q.build.apply(q, K), F.replaceKernel(q), C.push(q), q; + } + let A = Object.assign({ context: this.context, canvas: this.canvas, functions: this.functions, nativeFunctions: this.nativeFunctions, injectedNative: this.injectedNative, gpu: this, validate: m, onRequestFallback: a, onRequestSwitchKernel: k }, c), N = new this.Kernel(b, A), F = i(N); + return this.canvas || (this.canvas = N.canvas), this.context || (this.context = N.context), C.push(N), F; + } + createKernelMap() { + let b, T, C = typeof arguments[arguments.length - 2]; + if (C === "function" || C === "string" ? (b = arguments[arguments.length - 2], T = arguments[arguments.length - 1]) : b = arguments[arguments.length - 1], this.mode !== "dev" && (!this.Kernel.isSupported || !this.Kernel.features.kernelMap) && this.mode && x2.indexOf(this.mode) < 0) + throw new Error(`kernelMap not supported on ${this.Kernel.name}`); + let V = v(T); + if (T && typeof T.argumentTypes == "object" && (V.argumentTypes = Object.keys(T.argumentTypes).map((c) => T.argumentTypes[c])), Array.isArray(arguments[0])) { + V.subKernels = []; + let c = arguments[0]; + for (let a = 0; a < c.length; a++) { + let k = c[a].toString(), A = g.getFunctionNameFromString(k); + V.subKernels.push({ name: A, source: k, property: a }); + } + } else { + V.subKernels = []; + let c = arguments[0]; + for (let a in c) { + if (!c.hasOwnProperty(a)) + continue; + let k = c[a].toString(), A = g.getFunctionNameFromString(k); + V.subKernels.push({ name: A || a, source: k, property: a }); + } + } + return this.createKernel(b, V); + } + combineKernels() { + let b = arguments[0], T = arguments[arguments.length - 1]; + if (b.kernel.constructor.mode === "cpu") + return T; + let C = arguments[0].canvas, V = arguments[0].context, c = arguments.length - 1; + for (let a = 0; a < c; a++) + arguments[a].setCanvas(C).setContext(V).setPipeline(true); + return function() { + let a = T.apply(this, arguments); + return a.toArray ? a.toArray() : a; + }; + } + setFunctions(b) { + return this.functions = b, this; + } + setNativeFunctions(b) { + return this.nativeFunctions = b, this; + } + addFunction(b, T) { + return this.functions.push({ source: b, settings: T }), this; + } + addNativeFunction(b, T, C) { + if (this.kernels.length > 0) + throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.'); + return this.nativeFunctions.push(Object.assign({ name: b, source: T }, C)), this; + } + injectNative(b) { + return this.injectedNative = b, this; + } + destroy() { + return new Promise((b, T) => { + this.kernels || b(), setTimeout(() => { + try { + for (let V = 0; V < this.kernels.length; V++) + this.kernels[V].destroy(true); + let C = this.kernels[0]; + C && (C.kernel && (C = C.kernel), C.constructor.destroyContext && C.constructor.destroyContext(this.context)); + } catch (C) { + T(C); + } + b(); + }, 0); + }); + } + } + function v(h) { + if (!h) + return {}; + let b = Object.assign({}, h); + return h.hasOwnProperty("floatOutput") && (g.warnDeprecated("setting", "floatOutput", "precision"), b.precision = h.floatOutput ? "single" : "unsigned"), h.hasOwnProperty("outputToTexture") && (g.warnDeprecated("setting", "outputToTexture", "pipeline"), b.pipeline = Boolean(h.outputToTexture)), h.hasOwnProperty("outputImmutable") && (g.warnDeprecated("setting", "outputImmutable", "immutable"), b.immutable = Boolean(h.outputImmutable)), h.hasOwnProperty("floatTextures") && (g.warnDeprecated("setting", "floatTextures", "optimizeFloatMemory"), b.optimizeFloatMemory = Boolean(h.floatTextures)), b; + } + y.exports = { GPU: S, kernelOrder: u, kernelTypes: x2 }; + }, { "./backend/cpu/kernel": 8, "./backend/headless-gl/kernel": 34, "./backend/kernel": 36, "./backend/web-gl/kernel": 70, "./backend/web-gl2/kernel": 105, "./kernel-run-shortcut": 111, "./utils": 114, "gpu-mock.js": 4 }], 109: [function(o, y, E) { + let { GPU: p } = o("./gpu"), { alias: g } = o("./alias"), { utils: f } = o("./utils"), { Input: l, input: n } = o("./input"), { Texture: s } = o("./texture"), { FunctionBuilder: t } = o("./backend/function-builder"), { FunctionNode: i } = o("./backend/function-node"), { CPUFunctionNode: u } = o("./backend/cpu/function-node"), { CPUKernel: x2 } = o("./backend/cpu/kernel"), { HeadlessGLKernel: w } = o("./backend/headless-gl/kernel"), { WebGLFunctionNode: m } = o("./backend/web-gl/function-node"), { WebGLKernel: S } = o("./backend/web-gl/kernel"), { kernelValueMaps: v } = o("./backend/web-gl/kernel-value-maps"), { WebGL2FunctionNode: h } = o("./backend/web-gl2/function-node"), { WebGL2Kernel: b } = o("./backend/web-gl2/kernel"), { kernelValueMaps: T } = o("./backend/web-gl2/kernel-value-maps"), { GLKernel: C } = o("./backend/gl/kernel"), { Kernel: V } = o("./backend/kernel"), { FunctionTracer: c } = o("./backend/function-tracer"), a = o("./plugins/math-random-uniformly-distributed"); + y.exports = { alias: g, CPUFunctionNode: u, CPUKernel: x2, GPU: p, FunctionBuilder: t, FunctionNode: i, HeadlessGLKernel: w, Input: l, input: n, Texture: s, utils: f, WebGL2FunctionNode: h, WebGL2Kernel: b, webGL2KernelValueMaps: T, WebGLFunctionNode: m, WebGLKernel: S, webGLKernelValueMaps: v, GLKernel: C, Kernel: V, FunctionTracer: c, plugins: { mathRandom: a } }; + }, { "./alias": 5, "./backend/cpu/function-node": 6, "./backend/cpu/kernel": 8, "./backend/function-builder": 9, "./backend/function-node": 10, "./backend/function-tracer": 11, "./backend/gl/kernel": 13, "./backend/headless-gl/kernel": 34, "./backend/kernel": 36, "./backend/web-gl/function-node": 38, "./backend/web-gl/kernel": 70, "./backend/web-gl/kernel-value-maps": 39, "./backend/web-gl2/function-node": 73, "./backend/web-gl2/kernel": 105, "./backend/web-gl2/kernel-value-maps": 74, "./gpu": 108, "./input": 110, "./plugins/math-random-uniformly-distributed": 112, "./texture": 113, "./utils": 114 }], 110: [function(o, y, E) { + class p { + constructor(l, n) { + this.value = l, Array.isArray(n) ? this.size = n : (this.size = new Int32Array(3), n.z ? this.size = new Int32Array([n.x, n.y, n.z]) : n.y ? this.size = new Int32Array([n.x, n.y]) : this.size = new Int32Array([n.x])); + let [s, t, i] = this.size; + if (i) { + if (this.value.length !== s * t * i) + throw new Error(`Input size ${this.value.length} does not match ${s} * ${t} * ${i} = ${t * s * i}`); + } else if (t) { + if (this.value.length !== s * t) + throw new Error(`Input size ${this.value.length} does not match ${s} * ${t} = ${t * s}`); + } else if (this.value.length !== s) + throw new Error(`Input size ${this.value.length} does not match ${s}`); + } + toArray() { + let { utils: l } = o("./utils"), [n, s, t] = this.size; + return t ? l.erectMemoryOptimized3DFloat(this.value.subarray ? this.value : new Float32Array(this.value), n, s, t) : s ? l.erectMemoryOptimized2DFloat(this.value.subarray ? this.value : new Float32Array(this.value), n, s) : this.value; + } + } + function g(f, l) { + return new p(f, l); + } + y.exports = { Input: p, input: g }; + }, { "./utils": 114 }], 111: [function(o, y, E) { + let { utils: p } = o("./utils"); + function g(l) { + let n = function() { + return l.build.apply(l, arguments), n = function() { + let t = l.run.apply(l, arguments); + if (l.switchingKernels) { + let i = l.resetSwitchingKernels(), u = l.onRequestSwitchKernel(i, arguments, l); + s.kernel = l = u, t = u.run.apply(u, arguments); + } + return l.renderKernels ? l.renderKernels() : l.renderOutput ? l.renderOutput() : t; + }, n.apply(l, arguments); + }, s = function() { + return n.apply(l, arguments); + }; + return s.exec = function() { + return new Promise((t, i) => { + try { + t(n.apply(this, arguments)); + } catch (u) { + i(u); + } + }); + }, s.replaceKernel = function(t) { + l = t, f(l, s); + }, f(l, s), s; + } + function f(l, n) { + if (n.kernel) { + n.kernel = l; + return; + } + let s = p.allPropertiesOf(l); + for (let t = 0; t < s.length; t++) { + let i = s[t]; + i[0] === "_" && i[1] === "_" || (typeof l[i] == "function" ? i.substring(0, 3) === "add" || i.substring(0, 3) === "set" ? n[i] = function() { + return n.kernel[i].apply(n.kernel, arguments), n; + } : n[i] = function() { + return n.kernel[i].apply(n.kernel, arguments); + } : (n.__defineGetter__(i, () => n.kernel[i]), n.__defineSetter__(i, (u) => { + n.kernel[i] = u; + }))); + } + n.kernel = l; + } + y.exports = { kernelRunShortcut: g }; + }, { "./utils": 114 }], 112: [function(o, y, E) { + let t = { name: "math-random-uniformly-distributed", onBeforeRun: (i) => { + i.setUniform1f("randomSeed1", Math.random()), i.setUniform1f("randomSeed2", Math.random()); + }, functionMatch: "Math.random()", functionReplace: "nrand(vTexCoord)", functionReturnType: "Number", source: `// https://www.shadertoy.com/view/4t2SDh + //note: uniformly distributed, normalized rand, [0,1] + highp float randomSeedShift = 1.0; + highp float slide = 1.0; + uniform highp float randomSeed1; + uniform highp float randomSeed2; + + highp float nrand(highp vec2 n) { + highp float result = fract(sin(dot((n.xy + 1.0) * vec2(randomSeed1 * slide, randomSeed2 * randomSeedShift), vec2(12.9898, 78.233))) * 43758.5453); + randomSeedShift = result; + if (randomSeedShift > 0.5) { + slide += 0.00009; + } else { + slide += 0.0009; + } + return result; + }` }; + y.exports = t; + }, {}], 113: [function(o, y, E) { + class p { + constructor(f) { + let { texture: l, size: n, dimensions: s, output: t, context: i, type: u = "NumberTexture", kernel: x2, internalFormat: w, textureFormat: m } = f; + if (!t) + throw new Error('settings property "output" required.'); + if (!i) + throw new Error('settings property "context" required.'); + if (!l) + throw new Error('settings property "texture" required.'); + if (!x2) + throw new Error('settings property "kernel" required.'); + this.texture = l, l._refs ? l._refs++ : l._refs = 1, this.size = n, this.dimensions = s, this.output = t, this.context = i, this.kernel = x2, this.type = u, this._deleted = false, this.internalFormat = w, this.textureFormat = m; + } + toArray() { + throw new Error(`Not implemented on ${this.constructor.name}`); + } + clone() { + throw new Error(`Not implemented on ${this.constructor.name}`); + } + delete() { + throw new Error(`Not implemented on ${this.constructor.name}`); + } + clear() { + throw new Error(`Not implemented on ${this.constructor.name}`); + } + } + y.exports = { Texture: p }; + }, {}], 114: [function(o, y, E) { + let p = o("acorn"), { Input: g } = o("./input"), { Texture: f } = o("./texture"), l = /function ([^(]*)/, n = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg, s = /([^\s,]+)/g, t = { systemEndianness() { + return w; + }, getSystemEndianness() { + let m = new ArrayBuffer(4), S = new Uint32Array(m), v = new Uint8Array(m); + if (S[0] = 3735928559, v[0] === 239) + return "LE"; + if (v[0] === 222) + return "BE"; + throw new Error("unknown endianness"); + }, isFunction(m) { + return typeof m == "function"; + }, isFunctionString(m) { + return typeof m == "string" ? m.slice(0, 8).toLowerCase() === "function" : false; + }, getFunctionNameFromString(m) { + let S = l.exec(m); + return !S || S.length === 0 ? null : S[1].trim(); + }, getFunctionBodyFromString(m) { + return m.substring(m.indexOf("{") + 1, m.lastIndexOf("}")); + }, getArgumentNamesFromString(m) { + let S = m.replace(n, ""), v = S.slice(S.indexOf("(") + 1, S.indexOf(")")).match(s); + return v === null && (v = []), v; + }, clone(m) { + if (m === null || typeof m != "object" || m.hasOwnProperty("isActiveClone")) + return m; + let S = m.constructor(); + for (let v in m) + Object.prototype.hasOwnProperty.call(m, v) && (m.isActiveClone = null, S[v] = t.clone(m[v]), delete m.isActiveClone); + return S; + }, isArray(m) { + return !isNaN(m.length); + }, getVariableType(m, S) { + if (t.isArray(m)) + return m.length > 0 && m[0].nodeName === "IMG" ? "HTMLImageArray" : "Array"; + switch (m.constructor) { + case Boolean: + return "Boolean"; + case Number: + return S && Number.isInteger(m) ? "Integer" : "Float"; + case f: + return m.type; + case g: + return "Input"; + } + switch (m.nodeName) { + case "IMG": + return "HTMLImage"; + case "CANVAS": + return "HTMLImage"; + case "VIDEO": + return "HTMLVideo"; + } + return m.hasOwnProperty("type") ? m.type : "Unknown"; + }, getKernelTextureSize(m, S) { + let [v, h, b] = S, T = (v || 1) * (h || 1) * (b || 1); + return m.optimizeFloatMemory && m.precision === "single" && (v = T = Math.ceil(T / 4)), h > 1 && v * h === T ? new Int32Array([v, h]) : t.closestSquareDimensions(T); + }, closestSquareDimensions(m) { + let S = Math.sqrt(m), v = Math.ceil(S), h = Math.floor(S); + for (; v * h < m; ) + v--, h = Math.ceil(m / v); + return new Int32Array([h, Math.ceil(m / h)]); + }, getMemoryOptimizedFloatTextureSize(m, S) { + let h = t.roundTo((m[0] || 1) * (m[1] || 1) * (m[2] || 1) * (m[3] || 1), 4) / S; + return t.closestSquareDimensions(h); + }, getMemoryOptimizedPackedTextureSize(m, S) { + let [v, h, b] = m, C = t.roundTo((v || 1) * (h || 1) * (b || 1), 4) / (4 / S); + return t.closestSquareDimensions(C); + }, roundTo(m, S) { + return Math.floor((m + S - 1) / S) * S; + }, getDimensions(m, S) { + let v; + if (t.isArray(m)) { + let h = [], b = m; + for (; t.isArray(b); ) + h.push(b.length), b = b[0]; + v = h.reverse(); + } else if (m instanceof f) + v = m.output; + else if (m instanceof g) + v = m.size; + else + throw new Error(`Unknown dimensions of ${m}`); + if (S) + for (v = Array.from(v); v.length < 3; ) + v.push(1); + return new Int32Array(v); + }, flatten2dArrayTo(m, S) { + let v = 0; + for (let h = 0; h < m.length; h++) + S.set(m[h], v), v += m[h].length; + }, flatten3dArrayTo(m, S) { + let v = 0; + for (let h = 0; h < m.length; h++) + for (let b = 0; b < m[h].length; b++) + S.set(m[h][b], v), v += m[h][b].length; + }, flatten4dArrayTo(m, S) { + let v = 0; + for (let h = 0; h < m.length; h++) + for (let b = 0; b < m[h].length; b++) + for (let T = 0; T < m[h][b].length; T++) + S.set(m[h][b][T], v), v += m[h][b][T].length; + }, flattenTo(m, S) { + t.isArray(m[0]) ? t.isArray(m[0][0]) ? t.isArray(m[0][0][0]) ? t.flatten4dArrayTo(m, S) : t.flatten3dArrayTo(m, S) : t.flatten2dArrayTo(m, S) : S.set(m); + }, splitArray(m, S) { + let v = []; + for (let h = 0; h < m.length; h += S) + v.push(new m.constructor(m.buffer, h * 4 + m.byteOffset, S)); + return v; + }, getAstString(m, S) { + let v = Array.isArray(m) ? m : m.split(/\r?\n/g), h = S.loc.start, b = S.loc.end, T = []; + if (h.line === b.line) + T.push(v[h.line - 1].substring(h.column, b.column)); + else { + T.push(v[h.line - 1].slice(h.column)); + for (let C = h.line; C < b.line; C++) + T.push(v[C]); + T.push(v[b.line - 1].slice(0, b.column)); + } + return T.join(` +`); + }, allPropertiesOf(m) { + let S = []; + do + S.push.apply(S, Object.getOwnPropertyNames(m)); + while (m = Object.getPrototypeOf(m)); + return S; + }, linesToString(m) { + return m.length > 0 ? m.join(`; +`) + `; +` : ` +`; + }, warnDeprecated(m, S, v) { + console.warn(v ? `You are using a deprecated ${m} "${S}". It has been replaced with "${v}". Fixing, but please upgrade as it will soon be removed.` : `You are using a deprecated ${m} "${S}". It has been removed. Fixing, but please upgrade as it will soon be removed.`); + }, flipPixels: (m, S, v) => { + let h = v / 2 | 0, b = S * 4, T = new Uint8ClampedArray(S * 4), C = m.slice(0); + for (let V = 0; V < h; ++V) { + let c = V * b, a = (v - V - 1) * b; + T.set(C.subarray(c, c + b)), C.copyWithin(c, a, a + b), C.set(T, a); + } + return C; + }, erectPackedFloat: (m, S) => m.subarray(0, S), erect2DPackedFloat: (m, S, v) => { + let h = new Array(v); + for (let b = 0; b < v; b++) { + let T = b * S, C = T + S; + h[b] = m.subarray(T, C); + } + return h; + }, erect3DPackedFloat: (m, S, v, h) => { + let b = new Array(h); + for (let T = 0; T < h; T++) { + let C = new Array(v); + for (let V = 0; V < v; V++) { + let c = T * v * S + V * S, a = c + S; + C[V] = m.subarray(c, a); + } + b[T] = C; + } + return b; + }, erectMemoryOptimizedFloat: (m, S) => m.subarray(0, S), erectMemoryOptimized2DFloat: (m, S, v) => { + let h = new Array(v); + for (let b = 0; b < v; b++) { + let T = b * S; + h[b] = m.subarray(T, T + S); + } + return h; + }, erectMemoryOptimized3DFloat: (m, S, v, h) => { + let b = new Array(h); + for (let T = 0; T < h; T++) { + let C = new Array(v); + for (let V = 0; V < v; V++) { + let c = T * v * S + V * S; + C[V] = m.subarray(c, c + S); + } + b[T] = C; + } + return b; + }, erectFloat: (m, S) => { + let v = new Float32Array(S), h = 0; + for (let b = 0; b < S; b++) + v[b] = m[h], h += 4; + return v; + }, erect2DFloat: (m, S, v) => { + let h = new Array(v), b = 0; + for (let T = 0; T < v; T++) { + let C = new Float32Array(S); + for (let V = 0; V < S; V++) + C[V] = m[b], b += 4; + h[T] = C; + } + return h; + }, erect3DFloat: (m, S, v, h) => { + let b = new Array(h), T = 0; + for (let C = 0; C < h; C++) { + let V = new Array(v); + for (let c = 0; c < v; c++) { + let a = new Float32Array(S); + for (let k = 0; k < S; k++) + a[k] = m[T], T += 4; + V[c] = a; + } + b[C] = V; + } + return b; + }, erectArray2: (m, S) => { + let v = new Array(S), h = S * 4, b = 0; + for (let T = 0; T < h; T += 4) + v[b++] = m.subarray(T, T + 2); + return v; + }, erect2DArray2: (m, S, v) => { + let h = new Array(v), b = S * 4; + for (let T = 0; T < v; T++) { + let C = new Array(S), V = T * b, c = 0; + for (let a = 0; a < b; a += 4) + C[c++] = m.subarray(a + V, a + V + 2); + h[T] = C; + } + return h; + }, erect3DArray2: (m, S, v, h) => { + let b = S * 4, T = new Array(h); + for (let C = 0; C < h; C++) { + let V = new Array(v); + for (let c = 0; c < v; c++) { + let a = new Array(S), k = C * b * v + c * b, A = 0; + for (let N = 0; N < b; N += 4) + a[A++] = m.subarray(N + k, N + k + 2); + V[c] = a; + } + T[C] = V; + } + return T; + }, erectArray3: (m, S) => { + let v = new Array(S), h = S * 4, b = 0; + for (let T = 0; T < h; T += 4) + v[b++] = m.subarray(T, T + 3); + return v; + }, erect2DArray3: (m, S, v) => { + let h = S * 4, b = new Array(v); + for (let T = 0; T < v; T++) { + let C = new Array(S), V = T * h, c = 0; + for (let a = 0; a < h; a += 4) + C[c++] = m.subarray(a + V, a + V + 3); + b[T] = C; + } + return b; + }, erect3DArray3: (m, S, v, h) => { + let b = S * 4, T = new Array(h); + for (let C = 0; C < h; C++) { + let V = new Array(v); + for (let c = 0; c < v; c++) { + let a = new Array(S), k = C * b * v + c * b, A = 0; + for (let N = 0; N < b; N += 4) + a[A++] = m.subarray(N + k, N + k + 3); + V[c] = a; + } + T[C] = V; + } + return T; + }, erectArray4: (m, S) => { + let v = new Array(m), h = S * 4, b = 0; + for (let T = 0; T < h; T += 4) + v[b++] = m.subarray(T, T + 4); + return v; + }, erect2DArray4: (m, S, v) => { + let h = S * 4, b = new Array(v); + for (let T = 0; T < v; T++) { + let C = new Array(S), V = T * h, c = 0; + for (let a = 0; a < h; a += 4) + C[c++] = m.subarray(a + V, a + V + 4); + b[T] = C; + } + return b; + }, erect3DArray4: (m, S, v, h) => { + let b = S * 4, T = new Array(h); + for (let C = 0; C < h; C++) { + let V = new Array(v); + for (let c = 0; c < v; c++) { + let a = new Array(S), k = C * b * v + c * b, A = 0; + for (let N = 0; N < b; N += 4) + a[A++] = m.subarray(N + k, N + k + 4); + V[c] = a; + } + T[C] = V; + } + return T; + }, flattenFunctionToString: (m, S) => { + let { findDependency: v, thisLookup: h, doNotDefine: b } = S, T = S.flattened; + T || (T = S.flattened = {}); + let C = p.parse(m), V = [], c = 0; + function a(A) { + if (Array.isArray(A)) { + let N = []; + for (let F = 0; F < A.length; F++) + N.push(a(A[F])); + return N.join(""); + } + switch (A.type) { + case "Program": + return a(A.body) + (A.body[0].type === "VariableDeclaration" ? ";" : ""); + case "FunctionDeclaration": + return `function ${A.id.name}(${A.params.map(a).join(", ")}) ${a(A.body)}`; + case "BlockStatement": { + let F = []; + c += 2; + for (let R = 0; R < A.body.length; R++) { + let K = a(A.body[R]); + K && F.push(" ".repeat(c) + K, `; +`); + } + return c -= 2, `{ +${F.join("")}}`; + } + case "VariableDeclaration": + let N = t.normalizeDeclarations(A).map(a).filter((F) => F !== null); + return N.length < 1 ? "" : `${A.kind} ${N.join(",")}`; + case "VariableDeclarator": + return A.init.object && A.init.object.type === "ThisExpression" ? h(A.init.property.name, true) ? `${A.id.name} = ${a(A.init)}` : null : `${A.id.name} = ${a(A.init)}`; + case "CallExpression": { + if (A.callee.property.name === "subarray") + return `${a(A.callee.object)}.${a(A.callee.property)}(${A.arguments.map((F) => a(F)).join(", ")})`; + if (A.callee.object.name === "gl" || A.callee.object.name === "context") + return `${a(A.callee.object)}.${a(A.callee.property)}(${A.arguments.map((F) => a(F)).join(", ")})`; + if (A.callee.object.type === "ThisExpression") + return V.push(v("this", A.callee.property.name)), `${A.callee.property.name}(${A.arguments.map((F) => a(F)).join(", ")})`; + if (A.callee.object.name) { + let F = v(A.callee.object.name, A.callee.property.name); + return F === null ? `${A.callee.object.name}.${A.callee.property.name}(${A.arguments.map((R) => a(R)).join(", ")})` : (V.push(F), `${A.callee.property.name}(${A.arguments.map((R) => a(R)).join(", ")})`); + } else { + if (A.callee.object.type === "MemberExpression") + return `${a(A.callee.object)}.${A.callee.property.name}(${A.arguments.map((F) => a(F)).join(", ")})`; + throw new Error("unknown ast.callee"); + } + } + case "ReturnStatement": + return `return ${a(A.argument)}`; + case "BinaryExpression": + return `(${a(A.left)}${A.operator}${a(A.right)})`; + case "UnaryExpression": + return A.prefix ? `${A.operator} ${a(A.argument)}` : `${a(A.argument)} ${A.operator}`; + case "ExpressionStatement": + return `${a(A.expression)}`; + case "SequenceExpression": + return `(${a(A.expressions)})`; + case "ArrowFunctionExpression": + return `(${A.params.map(a).join(", ")}) => ${a(A.body)}`; + case "Literal": + return A.raw; + case "Identifier": + return A.name; + case "MemberExpression": + return A.object.type === "ThisExpression" ? h(A.property.name) : A.computed ? `${a(A.object)}[${a(A.property)}]` : a(A.object) + "." + a(A.property); + case "ThisExpression": + return "this"; + case "NewExpression": + return `new ${a(A.callee)}(${A.arguments.map((F) => a(F)).join(", ")})`; + case "ForStatement": + return `for (${a(A.init)};${a(A.test)};${a(A.update)}) ${a(A.body)}`; + case "AssignmentExpression": + return `${a(A.left)}${A.operator}${a(A.right)}`; + case "UpdateExpression": + return `${a(A.argument)}${A.operator}`; + case "IfStatement": + return `if (${a(A.test)}) ${a(A.consequent)}`; + case "ThrowStatement": + return `throw ${a(A.argument)}`; + case "ObjectPattern": + return A.properties.map(a).join(", "); + case "ArrayPattern": + return A.elements.map(a).join(", "); + case "DebuggerStatement": + return "debugger;"; + case "ConditionalExpression": + return `${a(A.test)}?${a(A.consequent)}:${a(A.alternate)}`; + case "Property": + if (A.kind === "init") + return a(A.key); + } + throw new Error(`unhandled ast.type of ${A.type}`); + } + let k = a(C); + if (V.length > 0) { + let A = []; + for (let N = 0; N < V.length; N++) { + let F = V[N]; + T[F] || (T[F] = true), F && A.push(t.flattenFunctionToString(F, S) + ` +`); + } + return A.join("") + k; + } + return k; + }, normalizeDeclarations: (m) => { + if (m.type !== "VariableDeclaration") + throw new Error('Ast is not of type "VariableDeclaration"'); + let S = []; + for (let v = 0; v < m.declarations.length; v++) { + let h = m.declarations[v]; + if (h.id && h.id.type === "ObjectPattern" && h.id.properties) { + let { properties: b } = h.id; + for (let T = 0; T < b.length; T++) { + let C = b[T]; + if (C.value.type === "ObjectPattern" && C.value.properties) + for (let V = 0; V < C.value.properties.length; V++) { + let c = C.value.properties[V]; + if (c.type === "Property") + S.push({ type: "VariableDeclarator", id: { type: "Identifier", name: c.key.name }, init: { type: "MemberExpression", object: { type: "MemberExpression", object: h.init, property: { type: "Identifier", name: C.key.name }, computed: false }, property: { type: "Identifier", name: c.key.name }, computed: false } }); + else + throw new Error("unexpected state"); + } + else if (C.value.type === "Identifier") + S.push({ type: "VariableDeclarator", id: { type: "Identifier", name: C.value && C.value.name ? C.value.name : C.key.name }, init: { type: "MemberExpression", object: h.init, property: { type: "Identifier", name: C.key.name }, computed: false } }); + else + throw new Error("unexpected state"); + } + } else if (h.id && h.id.type === "ArrayPattern" && h.id.elements) { + let { elements: b } = h.id; + for (let T = 0; T < b.length; T++) { + let C = b[T]; + if (C.type === "Identifier") + S.push({ type: "VariableDeclarator", id: { type: "Identifier", name: C.name }, init: { type: "MemberExpression", object: h.init, property: { type: "Literal", value: T, raw: T.toString(), start: C.start, end: C.end }, computed: true } }); + else + throw new Error("unexpected state"); + } + } else + S.push(h); + } + return S; + }, splitHTMLImageToRGB: (m, S) => { + let v = m.createKernel(function(V) { + return V[this.thread.y][this.thread.x].r * 255; + }, { output: [S.width, S.height], precision: "unsigned", argumentTypes: { a: "HTMLImage" } }), h = m.createKernel(function(V) { + return V[this.thread.y][this.thread.x].g * 255; + }, { output: [S.width, S.height], precision: "unsigned", argumentTypes: { a: "HTMLImage" } }), b = m.createKernel(function(V) { + return V[this.thread.y][this.thread.x].b * 255; + }, { output: [S.width, S.height], precision: "unsigned", argumentTypes: { a: "HTMLImage" } }), T = m.createKernel(function(V) { + return V[this.thread.y][this.thread.x].a * 255; + }, { output: [S.width, S.height], precision: "unsigned", argumentTypes: { a: "HTMLImage" } }), C = [v(S), h(S), b(S), T(S)]; + return C.rKernel = v, C.gKernel = h, C.bKernel = b, C.aKernel = T, C.gpu = m, C; + }, splitRGBAToCanvases: (m, S, v, h) => { + let b = m.createKernel(function(c) { + let a = c[this.thread.y][this.thread.x]; + this.color(a.r / 255, 0, 0, 255); + }, { output: [v, h], graphical: true, argumentTypes: { v: "Array2D(4)" } }); + b(S); + let T = m.createKernel(function(c) { + let a = c[this.thread.y][this.thread.x]; + this.color(0, a.g / 255, 0, 255); + }, { output: [v, h], graphical: true, argumentTypes: { v: "Array2D(4)" } }); + T(S); + let C = m.createKernel(function(c) { + let a = c[this.thread.y][this.thread.x]; + this.color(0, 0, a.b / 255, 255); + }, { output: [v, h], graphical: true, argumentTypes: { v: "Array2D(4)" } }); + C(S); + let V = m.createKernel(function(c) { + let a = c[this.thread.y][this.thread.x]; + this.color(255, 255, 255, a.a / 255); + }, { output: [v, h], graphical: true, argumentTypes: { v: "Array2D(4)" } }); + return V(S), [b.canvas, T.canvas, C.canvas, V.canvas]; + }, getMinifySafeName: (m) => { + try { + let S = p.parse(`const value = ${m.toString()}`), { init: v } = S.body[0].declarations[0]; + return v.body.name || v.body.body[0].argument.name; + } catch { + throw new Error("Unrecognized function type. Please use `() => yourFunctionVariableHere` or function() { return yourFunctionVariableHere; }"); + } + }, sanitizeName: function(m) { + return i.test(m) && (m = m.replace(i, "S_S")), u.test(m) ? m = m.replace(u, "U_U") : x2.test(m) && (m = m.replace(x2, "u_u")), m; + } }, i = /\$/, u = /__/, x2 = /_/, w = t.getSystemEndianness(); + y.exports = { utils: t }; + }, { "./input": 110, "./texture": 113, acorn: 1 }] }, {}, [107])(107); + }); + }); + var je = {}; + ii(je, { gpuUtils: () => nt, makeCanvasKrnl: () => Ct, makeKrnl: () => fe }); + var Ki = si(Et()); + function ri(L, I) { + return L + I; + } + function ai(L, I) { + return L - I; + } + function oi(L, I) { + return L * I; + } + function ui(L, I) { + return L / I; + } + function li(L, I, $, o) { + return [L + $, I + o]; + } + function hi(L, I, $, o) { + return [L - $, I - o]; + } + function ci(L, I, $, o) { + return [L * $ - I * o, L * o + I * $]; + } + function pi(L, I) { + let $ = Math.exp(L); + return [$ * Math.cos(I), $ * Math.sin(I)]; + } + function xe(L, I) { + return Math.sqrt(L * L + I * I); + } + function fi(L) { + return 0 - L; + } + function di(L) { + let I = Math.sqrt(L); + for (var $ = 3; $ <= I; ) { + if (L % $ === 0) + return $; + $ += 2; + } + } + function qe(L, I) { + for (var $ = 0, o = 0; o < I; o++) + $ += L[o]; + return $ / I; + } + function et(L, I, $) { + for (var o = 0, y = 0; y < $; y++) + o += (L[y] - I) * (L[y] - I); + return Math.sqrt(o); + } + function mi(L, I, $) { + for (var o = 0, y = 0, E = 0; E < $; E++) + y = L[E] - I, o += y * y; + return o / $; + } + function xi(L, I, $) { + for (var o = 0, y = 0, E = 0; E < $; E++) + y = L[E] - I, o += y * y; + return Math.sqrt(o / $); + } + function tt(L, I, $, o, y, E, p, g) { + for (var f = 0, l = 0; l < p; l++) { + var n = l + g, s = 0; + n < p && (s = o[n]), f += (L[l] - I) * (s - y); + } + return f / ($ * E); + } + function gi(L, I, $) { + for (var o = 0, y = 0; y < I; y++) + o += Math.exp(L[y]); + return Math.exp(L[$]) / o; + } + function $e(L, I, $) { + for (var o = 0, y = 0, E = 1 / I, p = 6.28318530718 * $ * E, g = 0; g < I; g++) { + var f = p * g; + o = o + L[g] * Math.cos(f), y = y - L[g] * Math.sin(f); + } + return [o * E, y * E]; + } + function it(L, I, $, o) { + for (var y = 0, E = 0, p = 1 / I, g = 6.28318530718 * $ * p, f = 0; f < I; f++) { + var l = g * f; + y = y + L[f + (I - 1) * o] * Math.cos(l), E = E - L[f + (I - 1) * o] * Math.sin(l); + } + return [y * p, E * p]; + } + function Me(L, I, $, o) { + var y = 0, E = 0, p = 1 / I, g = 6.28318530718 * $ * p, f = 1, l = 0, n = o * 0.25; + if ($ <= n) + for (; $ <= n; ) + n = n * 0.5, f += 1; + for (var s = 0; s < I; s += f) { + var t = s; + t > I && (t = I); + var i = g * t; + y = y + L[t] * Math.cos(i), E = E - L[t] * Math.sin(i), l += 1; + } + return [y / l, E / l]; + } + function It(L, I, $, o, y) { + var E = 0, p = 0, g = 1 / I, f = 6.28318530718 * $ * g, l = 1, n = 0, s = y * 0.25; + if ($ <= s) + for (; $ <= s; ) + s = s * 0.5, l += 1; + for (var t = 0; t < I; t += l) { + var i = t; + i > I && (i = I); + var u = f * i; + E = E + L[i + (I - 1) * o] * Math.cos(u), p = p - L[i + (I - 1) * o] * Math.sin(u), n += 1; + } + return [E / n, p / n]; + } + function Be(L, I, $) { + for (var o = 0, y = 0, E = 1 / I, p = 6.28318530718 * $ * E, g = 0; g < I; g++) { + var f = p * g; + o = o + L[g] * Math.cos(f), y = L[g] * Math.sin(f) - y; + } + return [o * E, y * E]; + } + function kt(L, I, $, o) { + for (var y = 0, E = 0, p = 1 / I, g = 6.28318530718 * $ * p, f = 0; f < I; f++) { + var l = g * f; + y = y + L[f + (I - 1) * o] * Math.cos(l), E = L[f + (I - 1) * o] * Math.sin(l) - E; + } + return [y * p, E * p]; + } + function We(L, I, $, o) { + var y = 0, E = 0, p = 1 / I, g = 6.28318530718 * $ * p, f = 1, l = 0, n = o * 0.25; + if ($ <= n) + for (; $ <= n; ) + n = n * 0.5, f += 1; + for (var s = 0; s < I; s += f) { + var t = s; + t > I && (t = I); + var i = g * t; + y = y + L[t] * Math.cos(i), E = L[t] * Math.sin(i) - E, l += 1; + } + return [y / l, E / l]; + } + function At(L, I, $, o, y) { + var E = 0, p = 0, g = 1 / I, f = 6.28318530718 * $ * g, l = 1, n = 0, s = y * 0.25; + if ($ <= s) + for (; $ <= s; ) + s = s * 0.5, l += 1; + for (var t = 0; t < I; t += l) { + var i = t; + i > I && (i = I); + var u = f * i; + E = E + L[i + (I - 1) * o] * Math.cos(u), p = L[i + (I - 1) * o] * Math.sin(u) - p, n += 1; + } + return [E / n, p / n]; + } + function yi(L, I) { + var $ = Math.floor(this.thread.x / I) * 2, o = this.thread.x - Math.floor(this.thread.x / I) * I, y = qe(L[$], I), E = qe(L[$ + 1], I), p = et(L[$], y, I), g = et(L[$ + 1], E, I), f = tt(L[$], y, p, L[$ + 1], E, g, I, o); + return f; + } + function bi(L, I, $, o) { + var y = Math.floor(this.thread.x / I) * 2, E = this.thread.x - Math.floor(this.thread.x / I) * I, p = $[y], g = $[y + 1], f = o[y], l = o[y + 1], n = tt(L[y], p, f, L[y + 1], g, l, I, E); + return n; + } + function Ti(L, I, $) { + var o = $e(L, I, this.thread.x); + return xe(o[0], o[1]) * $; + } + function vi(L, I, $) { + var o = Be(L, I, this.thread.x); + return xe(o[0], o[1]) * $; + } + function Si(L, I, $, o) { + var y = Me(L, I, this.thread.x, o); + return xe(y[0], y[1]) * $; + } + function _i(L, I, $, o) { + var y = We(L, I, this.thread.x, o); + return xe(y[0], y[1]) * $; + } + function wi(L, I) { + var $ = this.output.x, o = $e(L[this.thread.y], $, this.thread.x); + return xe(o[0], o[1]) * I; + } + function Ei(L, I, $) { + var o = [0, 0]; + if (this.thread.x <= I) + o = $e(L, I, this.thread.x); + else { + var y = Math.floor(this.thread.x / I); + o = it(L, I, this.thread.x - y * I, y); + } + return xe(o[0], o[1]) * $; + } + function Ii(L, I, $, o) { + var y = [0, 0]; + if (this.thread.x <= I) + y = Me(L, I, this.thread.x, o); + else { + var E = Math.floor(this.thread.x / I); + y = It(L, I, this.thread.x - E * I, E, o); + } + return xe(y[0], y[1]) * $; + } + function ki(L, I, $, o, y) { + var E = [0, 0], p = this.thread.x / I * (o - $) + $; + return E = $e(L, I, p), xe(E[0], E[1]) * y; + } + function Ai(L, I, $, o, y) { + var E = [0, 0], p = this.thread.x / I * (o - $) + $; + return E = Me(L, I, p), xe(E[0], E[1]) * y; + } + function Di(L, I, $, o, y) { + var E = [0, 0], p = this.thread.x / I * (o - $) + $; + return E = Be(L, I, p), xe(E[0], E[1]) * y; + } + function Ci(L, I, $, o, y) { + var E = [0, 0], p = this.thread.x / I * (o - $) + $; + return E = We(L, I, p), xe(E[0], E[1]) * y; + } + function Fi(L, I, $, o, y) { + var E = [0, 0]; + if (this.thread.x < I) { + var p = this.thread.x / I * (o - $) + $; + E = $e(L, I, p); + } else { + var g = Math.floor(this.thread.x / I), p = (this.thread.x - g * I) / I * (o - $) + $; + E = it(L, I, p - g * I, g); + } + return xe(E[0], E[1]) * y; + } + function $i(L, I, $, o, y) { + var E = [0, 0]; + if (this.thread.x < I) { + var p = this.thread.x / I * (o - $) + $; + E = Me(L, I, p, I); + } else { + var g = Math.floor(this.thread.x / I), p = (this.thread.x - g * I) / I * (o - $) + $; + E = It(L, I, p - g * I, g, I); + } + return xe(E[0], E[1]) * y; + } + function Li(L, I, $, o, y) { + var E = [0, 0]; + if (this.thread.x < I) { + var p = this.thread.x / I * (o - $) + $; + E = Be(L, I, p); + } else { + var g = Math.floor(this.thread.x / I), p = (this.thread.x - g * I) / I * (o - $) + $; + E = kt(L, I, p - g * I, g); + } + return xe(E[0] * 2, E[1] * 2) * y; + } + function Ri(L, I, $, o, y) { + var E = [0, 0]; + if (this.thread.x < I) { + var p = this.thread.x / I * (o - $) + $; + E = We(L, I, p); + } else { + var g = Math.floor(this.thread.x / I), p = (this.thread.x - g * I) / I * (o - $) + $; + E = At(L, I, p - g * I, g); + } + return xe(E[0] * 2, E[1] * 2) * y; + } + function Mi(L, I, $, o) { + for (var y = $ * Math.floor(this.thread.x / I), E = L[y][this.thread.x], p = 0; p < $; p++) + E *= L[p][this.thread.x]; + return E * o; + } + function Vi(L, I, $, o, y) { + let E = (Math.sqrt(y) - 1) / 2, p = 2 * E + 1, g = 0, f = 0, l = 0, n = -E, s = 0; + for (; n <= E; ) { + if (this.thread.x + n < 0 || this.thread.x + n >= I) { + n++; + continue; + } + let t = -E; + for (; t <= E; ) { + if (this.thread.y + t < 0 || this.thread.y + t >= $) { + t++; + continue; + } + s = (t + E) * p + n + E; + let i = o[s], u = L[this.thread.y + n][this.thread.x + t]; + g += u.r * i, f += u.g * i, l += u.b * i, t++; + } + n++; + } + this.color(g, f, l); + } + function Oi(L, I, $, o, y, E) { + let p = 0, g = 0, f = 0; + for (var l = 0; l < E; l++) { + let n = y[l], s = (Math.sqrt(n) - 1) / 2, t = 2 * s + 1, i = -s, u = 0; + for (; i <= s; ) { + if (this.thread.x + i < 0 || this.thread.x + i >= I) { + i++; + continue; + } + let x2 = -s; + for (; x2 <= s; ) { + if (this.thread.y + x2 < 0 || this.thread.y + x2 >= $) { + x2++; + continue; + } + u = (x2 + s) * t + i + s; + let w = o[l][u], m = L[this.thread.y + i][this.thread.x + x2]; + p += m.r * w, g += m.g * w, f += m.b * w, x2++; + } + i++; + } + } + this.color(p, g, f); + } + function zi(L) { + return L[this.thread.y][this.thread.x]; + } + var me = { correlogramsKern: yi, correlogramsPCKern: bi, dftKern: Ti, idftKern: vi, fftKern: Si, ifftKern: _i, dft_windowedKern: ki, idft_windowedKern: Di, fft_windowedKern: Ai, ifft_windowedKern: Ci, listdft2DKern: wi, listdft1DKern: Ei, listfft1DKern: Ii, listfft1D_windowedKern: $i, listdft1D_windowedKern: Fi, listidft1D_windowedKern: Li, listifft1D_windowedKern: Ri, bulkArrayMulKern: Mi, multiImgConv2DKern: Oi, ImgConv2DKern: Vi, transpose2DKern: zi }, Dt = [ri, ai, oi, ui, li, hi, ci, pi, xe, fi, di, qe, et, mi, xi, tt, gi, $e, it, Be, kt, Me, We, At]; + function fe(L, I, $ = { setDynamicOutput: true, setDynamicArguments: true, setPipeline: true, setImmutable: true, setGraphical: false }) { + let o = L.createKernel(I); + return $.setDynamicOutput && o.setDynamicOutput(true), $.output && o.setOutput($.output), $.setDynamicArguments && o.setDynamicArguments(true), $.setPipeline && o.setPipeline(true), $.setImmutable && o.setImmutable(true), $.setGraphical && o.setGraphical(true), o; + } + function Ct(L, I, $ = { output: [300, 300], setDynamicArguments: true, setDynamicOutput: true, setPipeline: false, setImmutable: true, setGraphical: true }, o) { + let y = fe(L, I, $), E = y.canvas; + return typeof o == "string" ? document.getElementById(toAppend).appendChild(E) : o ? toAppend.appendChild(E) : document.body.appendChild(E), y; + } + var nt = class { + constructor(I = new GPU()) { + this.gpu = I, this.kernels = /* @__PURE__ */ new Map(), this.kernel, this.PI = 3.141592653589793, this.SQRT1_2 = 0.7071067811865476, this.addFunctions(), this.imgkernels = { edgeDetection: [-1, -1, -1, -1, 8, -1, -1, -1, -1], boxBlur: [1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9], sobelLeft: [1, 0, -1, 2, 0, -2, 1, 0, -1], sobelRight: [-1, 0, 1, -2, 0, 2, -1, 0, 1], sobelTop: [1, 2, 1, 0, 0, 0, -1, -2, -1], sobelBottom: [-1, 2, 1, 0, 0, 0, 1, 2, 1], identity: [0, 0, 0, 0, 1, 0, 0, 0, 0], gaussian3x3: [1, 2, 1, 2, 4, 2, 1, 2, 1], guassian7x7: [0, 0, 0, 5, 0, 0, 0, 0, 5, 18, 32, 18, 5, 0, 0, 18, 64, 100, 64, 18, 0, 5, 32, 100, 100, 100, 32, 5, 0, 18, 64, 100, 64, 18, 0, 0, 5, 18, 32, 18, 5, 0, 0, 0, 0, 5, 0, 0, 0], emboss: [-2, -1, 0, -1, 1, 1, 0, 1, 2], sharpen: [0, -1, 0, -1, 5, -1, 0, -1, 0] }; + } + addFunction(I = function() { + }) { + this.gpu.addFunction(I); + } + addKernel(I = "", $ = function() { + }, o) { + return this.kernels.get(I) ? (console.error("Kernel already exists"), false) : (this.kernels.set(I, fe(this.gpu, $, o)), true); + } + addCanvasKernel(I, $, o, y) { + if (this.kernels.get(I)) + return console.error("Kernel already exists"), false; + { + let p = Ct(this.gpu, $, o, y); + return this.kernels.set(I, p), p; + } + } + combineKernels(I, $ = [], o = function() { + }) { + if (this.kernels.get(I)) + return console.error("Kernel already exists"), false; + { + $.forEach((p, g) => { + if (typeof p == "string") { + let f = this.kernels.get(p); + if (f) + $[g] = f; + else + return false; + } else + typeof p == "function" && (this.kernels.get(p.name) || this.addKernel(p.name, p)); + }); + let E = this.gpu.combineKernels(...$, o); + return this.kernels.set(I, E), E; + } + } + callKernel(I = "", $ = []) { + let o, y = this.kernels.get(I); + return y ? (o = y(...$), o) : (console.error("Kernel not found"), false); + } + callCanvasKernel(I = "", $ = [], o = []) { + let y, E = this.kernels.get(I); + return E ? (o.length === 2 && E.setOutput(o), y = E(...$), y) : (console.error("Kernel not found"), false); + } + hasKernel(I = "") { + return !!this.kernels.get(I); + } + addFunctions() { + Dt.forEach((y) => this.gpu.addFunction(y)), this.correlograms = fe(this.gpu, me.correlogramsKern), this.correlogramsPC = fe(this.gpu, me.correlogramsPCKern), this.dft = fe(this.gpu, me.dftKern), this.idft = fe(this.gpu, me.idftKern), this.dft_windowed = fe(this.gpu, me.dft_windowedKern), this.idft_windowed = fe(this.gpu, me.idft_windowedKern), this.fft = fe(this.gpu, me.fftKern), this.ifft = fe(this.gpu, me.ifftKern), this.fft_windowed = fe(this.gpu, me.fft_windowedKern), this.ifft_windowed = fe(this.gpu, me.ifft_windowedKern), this.listdft2D = fe(this.gpu, me.listdft2DKern), this.listdft1D = fe(this.gpu, me.listdft1DKern), this.listdft1D_windowed = fe(this.gpu, me.listdft1D_windowedKern), this.listfft1D = fe(this.gpu, me.listfft1DKern), this.listfft1D_windowed = fe(this.gpu, me.listfft1D_windowedKern), this.listidft1D_windowed = fe(this.gpu, me.listidft1D_windowedKern), this.listifft1D_windowed = fe(this.gpu, me.listifft1D_windowedKern), this.bulkArrayMul = fe(this.gpu, me.bulkArrayMulKern), [{ name: "correlograms", krnl: this.correlograms }, { name: "correlogramsPC", krnl: this.correlogramsPC }, { name: "dft", krnl: this.dft }, { name: "idft", krnl: this.idft }, { name: "dft_windowed", krnl: this.idft_windowed }, { name: "fft", krnl: this.fft }, { name: "ifft", krnl: this.ifft }, { name: "fft_windowed", krnl: this.fft_windowed }, { name: "ifft_windowed", krnl: this.ifft_windowed }, { name: "listdft2D", krnl: this.listdft2D }, { name: "listdft1D", krnl: this.listdft1D }, { name: "listdft1D_windowed", krnl: this.listdft1D_windowed }, { name: "listfft1D", krnl: this.listfft1D }, { name: "listfft1D_windowed", krnl: this.listfft1D_windowed }, { name: "listidft1D_windowed", krnl: this.listidft1D_windowed }, { name: "listifft1D_windowed", krnl: this.listifft1D_windowed }, { name: "bulkArrayMul", krnl: this.bulkArrayMul }].forEach((y) => { + this.kernels.set(y.name, y); + }); + let $ = (y, E, p, g, f) => { + var l = this.fft_windowed(y, E, p, g, f, 0), n = this.ifft_windowed(l, E, p, g, f); + return n; + }, o = (y, E, p, g, f) => { + var l = this.listdft1D_windowed(y, E, p, g, f, new Array(Math.ceil(y / E)).fill(0)), n = this.listifft1D_windowed(l, E, p, g, f); + return n; + }; + this.gpuCoherence = (y, E, p, g, f) => { + var l = this.correlograms(y), n = this.listfft1D_windowed(l, E, p, g, f, new Array(Math.ceil(y / E)).fill(0)), s = this.bulkArrayMul(n, E, 5, 1); + return s; + }; + } + gpuXCors(I, $ = false, o = false) { + var y; + if ($ === true) { + var E = [], p = []; + I.forEach((u, x2) => { + E.push(u.reduce((w, m) => m += w) / u.length), p.push(Math.sqrt(E[x2].reduce((w, m) => w += Math.pow(m - mean1, 2)))); + }); + for (var g = [], f = [], l = [], n = 0; n < I.length; n++) + for (var s = n; s < I.length; s++) + l.push(...I[n], ...I[s]), g.push(E[n], E[s]), f.push(p[n], p[s]); + this.correlogramsPC.setOutput([l.length]), this.correlogramsPC.setLoopMaxIterations(I[0].length * 2), y = this.correlogramsPC(l, I[0].length, g, f); + } else { + for (var l = [], n = 0; n < I.length; n++) + for (var s = n; s < I.length; s++) + l.push(...I[n], ...I[s]); + this.correlograms.setOutput([l.length]), this.correlograms.setLoopMaxIterations(I[0].length * 2), y = this.correlograms(l, I[0].length); + } + if (o === true) + return y; + var t = y.toArray(); + y.delete(); + for (var i = [], n = 0; n < I.length; n++) + i.push(t.splice(0, I[0].length)); + return i; + } + gpuDFT(I, $, o = 1, y = false) { + var E = I.length, p = E / $; + this.dft.setOutput([I.length]), this.dft.setLoopMaxIterations(E); + var g = this.dft(I, E, o), f = null; + if (y === false) { + var l = this.makeFrequencyDistribution(E, p), n = g.toArray(); + return g.delete(), [l, this.orderMagnitudes(n)]; + } else { + var s = g; + return g.delete(), s; + } + } + MultiChannelDFT(I, $, o = 1, y = false) { + var E = []; + I.forEach((i) => { + E.push(...i); + }); + var p = I[0].length, g = p / $; + this.listdft1D.setOutput([E.length]), this.listdft1D.setLoopMaxIterations(p); + var f = this.listdft1D(E, p, o); + if (y === false) { + var l = [], n = this.makeFrequencyDistribution(p, g); + E = f.toArray(); + for (var s = 0; s < E.length; s += p) + l.push(this.orderMagnitudes([...E.slice(s, s + p)])); + return f.delete(), [n, l]; + } else { + var t = f; + return f.delete(), t; + } + } + MultiChannelDFT_Bandpass(I = [], $, o, y, E = 1, p = false) { + var g = []; + I.forEach((i) => { + g.push(...i); + }); + var f = y * 2, l = I[0].length, n = l / $; + this.listdft1D_windowed.setOutput([g.length]), this.listdft1D_windowed.setLoopMaxIterations(l); + var s = this.listdft1D_windowed(g, n, o, f, E); + if (p === true) + return s; + g = s.toArray(), s.delete(); + var t = this.bandPassWindow(o, y, n); + return [t, this.orderBPMagnitudes(g, $, n, l)]; + } + gpuFFT(I, $, o = 1, g, E = false) { + var p = I.length, g = p / $; + this.fft.setOutput([I.length]), this.fft.setLoopMaxIterations(p); + var f = this.fft(I, p, o, g), l = null; + if (E === false) { + var n = this.makeFrequencyDistribution(p, g), s = f.toArray(); + return f.delete(), [n, this.orderMagnitudes(s)]; + } else { + var t = f; + return f.delete(), t; + } + } + MultiChannelFFT(I, $, o = 1, y = false) { + var E = []; + I.forEach((i) => { + E.push(...i); + }); + var p = I[0].length, g = p / $; + this.listfft1D.setOutput([E.length]), this.listfft1D.setLoopMaxIterations(p); + var f = this.listfft1D(E, p, o, g); + if (y === false) { + var l = [], n = this.makeFrequencyDistribution(p, g); + E = f.toArray(); + for (var s = 0; s < E.length; s += p) + l.push(this.orderMagnitudes([...E.slice(s, s + p)])); + return f.delete(), [n, l]; + } else { + var t = f; + return f.delete(), t; + } + } + MultiChannelFFT_Bandpass(I = [], $, o, y, E = 1, p = false) { + var g = []; + I.forEach((i) => { + g.push(...i); + }); + var f = y * 2, l = I[0].length, n = l / $; + this.listfft1D_windowed.setOutput([g.length]), this.listfft1D_windowed.setLoopMaxIterations(l); + var s = this.listfft1D_windowed(g, n, o, f, E); + if (p === true) + return s; + g = s.toArray(), s.delete(); + var t = this.bandPassWindow(o, y, n); + return [t, this.orderBPMagnitudes(g, $, n, l)]; + } + orderMagnitudes(I) { + return [...I.slice(Math.ceil(I.length * 0.5), I.length), ...I.slice(0, Math.ceil(I.length * 0.5))]; + } + makeFrequencyDistribution(I, $) { + for (var o = I, y = $ / o, E = [], p = -o / 2; p < o / 2; p++) { + var g = p * y; + E.push(g); + } + return E; + } + orderBPMagnitudes(I, $, o, y) { + for (var E = [], p = 0; p < I.length; p += y) + E.push([...I.slice(p, Math.ceil(y * 0.5 + p))]); + var g = [], f = 1 / o; + return $ > 1 ? (E.forEach((l, n) => { + g.push([]); + for (var s = 1 / Math.max(...l), t = 0; t < l.length; t++) + if (t == 0) + g[n] = l.slice(t, Math.floor(o)), t = Math.floor(o); + else { + var i = t - Math.floor(Math.floor(t * f) * o) - 1; + g[n][i] = g[n][i] * l[t - 1] * s; + } + g[n] = [...g[n].slice(0, Math.ceil(g[n].length * 0.5))]; + }), g) : E; + } + bandPassWindow(I, $, o, y = true) { + var E = $ * 2; + let p = (E - I) / o; + var g = []; + if (y === true) + for (var f = 0; f < Math.ceil(0.5 * o); f += p) + g.push(I + (E - I) * f / o); + else + for (var f = -Math.ceil(0.5 * o); f < Math.ceil(0.5 * o); f += p) + g.push(I + (E - I) * f / o); + return g; + } + }; + typeof globalThis.gpujsUtils < "u" ? Object.assign(globalThis.gpujsUtils, je) : globalThis.gpujsUtils = je; + })(); + var _Math2 = class { + constructor() { + } + static genSineWave(freq = 20, peakAmp = 1, nSec = 1, fs2 = 512, freq2 = 0, peakAmp2 = 1) { + var sineWave = []; + var t = []; + var increment = 1 / fs2; + for (var ti = 0; ti < nSec; ti += increment) { + var amplitude = Math.sin(2 * Math.PI * freq * ti) * peakAmp; + amplitude += Math.sin(2 * Math.PI * freq2 * ti) * peakAmp2; + sineWave.push(amplitude); + t.push(ti); + } + return [t, sineWave]; + } + static getSineAmplitude(frequency = 20, peakAmplitude = 1, ti = 0, tOffset = 0) { + return Math.sin(this.TWO_PI * frequency * ti + tOffset) * peakAmplitude; + } + static mean(arr) { + var sum = arr.reduce((prev, curr) => curr += prev); + return sum / arr.length; + } + static mode(arr) { + return arr.sort((a, b) => arr.filter((v) => v === a).length - arr.filter((v) => v === b).length).pop(); + } + static std(arr, mean = void 0) { + let avg = mean; + if (!mean) + avg = this.mean(arr); + let summed = 0; + for (let i = 0; i < arr.length; i++) { + let subbed = arr[i] - avg; + summed += subbed * subbed; + } + return Math.sqrt(summed / arr.length); + } + static relError(actual = [], forecast = [], abs = true) { + if (actual.length !== forecast.length) + throw new Error("Input arrays of same length!"); + let i = actual.length; + let d = new Array(actual.length); + for (let j = 0; j < i; j++) { + let dd = (actual[j] - forecast[j]) / actual[j]; + if (abs) + dd = Math.abs(dd); + d[j] = dd; + } + return d; + } + static informationEntropy(probabilities = []) { + let len = probabilities.length; + let entropy = new Array(len); + for (let i = 0; i < len; i++) { + let ent = probabilities[i] * Math.log(probabilities[i]); + if (isNaN(ent)) + ent = 0; + entropy[i] = ent; + } + return entropy; + } + static zscore(arr) { + let mean = this.mean(arr); + let std = this.std(arr, mean); + let z = new Array().length(arr.length); + for (let i = 0; i < arr.length; i++) { + z[i] = (arr[i] - mean) / std; + } + return z; + } + static variance(arr) { + var mean = this.mean(arr); + return arr.reduce((a, b) => a + (b - mean) ** 2, 0) / arr.length; + } + static dot(vec1, vec2) { + var dot = 0; + for (var i = 0; i < vec1.length; i++) { + dot += vec1[i] * vec2[i]; + } + return dot; + } + static cross3D(vec1, vec2) { + return [vec1[1] * vec2[2] - vec1[2] * vec2[1], vec1[2] * vec2[0] - vec1[0] * vec2[2], vec1[0] * vec2[1] - vec1[1] * vec2[0]]; + } + static magnitude(vec) { + var sqrd = 0; + vec.forEach((c) => { + sqrd += c * c; + }); + return Math.sqrt(sqrd); + } + static distance(point1, point2) { + var dsqrd = 0; + point1.forEach((c, i) => { + dsqrd += (point2[i] - c) * (point2[i] - c); + }); + return Math.sqrt(dsqrd); + } + static midpoint(point1 = [1, 2, 3], point2 = [3, 4, 5]) { + return point1.map((c, i) => { + return (c + point2[i]) * 0.5; + }); + } + static normalize(vec) { + var norm = 0; + norm = this.magnitude(vec); + var vecn = new Array(vec.length); + vec.forEach((c, i) => { + vecn[i] = c * norm; + }); + return vecn; + } + static normalizeSeries(arr = [], fromZero = true) { + let max = Math.max(...arr); + let min = Math.min(...arr); + if (fromZero == false) { + max = Math.max(max, Math.abs(min)); + min = 0; + } + if (max - min === 0) { + min = 0; + if (max === 0) + max = 1e-13; + } + return arr.map((v) => (v - min) / (max - min)); + } + static quadraticFormula(a, b, c) { + let bbmac4 = Math.sqrt(b * b - 4 * a * c); + if (!isNaN(bbmac4)) + return ["complex", "complex"]; + let _a2 = 1 / (2 * a); + if (bbmac4 === 0) + return [b * _a2]; + let nb = -b; + return [(nb + bbmac4) * _a2, (nb - bbmac4) * _a2]; + } + static newtonsMethod(foo = (x2) => { + return Math.pow(x2, 5) + x2 * x2 - x2 - 0.2; + }, start = 0, end = 1, precision = 0.01, attempts = 10) { + let roots = []; + for (let i = 0; i < attempts; i++) { + let seedx = Math.random() * (end - start); + let guess = foo(seedx); + let guess2 = foo(seedx + precision); + let slope = (guess2 - guess) / precision; + let xn = seedx + precision; + while (Math.abs(slope) > precision) { + let step = -guess / slope2; + let xn12 = xn + step; + guess = guess2; + guess2 = foo(xn12); + let slope2 = (guess2 - guess) / (xn12 - xn); + } + let idx; + let f = roots.find((root, i2) => { + if (Math.abs(xn1 - root) < precision) { + idx = i2; + return true; + } + }); + if (f) + roots[idx] = (xn1 + f) * 0.5; + else + roots.push(xn1); + } + return roots; + } + static makeVec(point1, point2) { + var vec = []; + point1.forEach((c, i) => { + vec.push(point2[i] - c); + }); + return vec; + } + static getBufferedValueByCoordinates(vb = new Array(300).fill(1), dims = [10, 10, 2], coordinate = [1, 2, 1], cardinal = void 0) { + let getIdx = (foundIdx = 0, dimIdx = 0) => { + if (dimIdx === dims.length) + return foundIdx; + if (dimIdx == 0) + foundIdx += coordinate[dimIdx]; + else if (dims[dimIdx] == 0) + dimsAt0++; + else { + let reMul = (val = coordinate[dimIdx], di = dimIdx - 1) => { + val *= dims[di]; + di--; + if (di == 0) + return val; + else + return reMul(val, di); + }; + foundIdx += reMul(coordinate[dimIdx] + 1, dimIdx - 1); + } + dimIdx++; + return getIdx(foundIdx, dimIdx); + }; + let found = getIdx(); + if (cardinal) { + if (coordinate[coordinate.length - 1] === 0) { + let lastnonzero = 0; + let idx = 0; + while (idx !== coordinate.length - 1) { + if (coordinate[idx] !== 0) + lastnonzero = idx; + idx++; + } + return vb[found - lastnonzero + cardinal]; + } + return vb[found - dims.length + cardinal]; + } else { + if (coordinate[coordinate.length - 1] === 0) { + let lastnonzero = 0; + let idx = 0; + while (idx !== coordinate.length - 1) { + if (coordinate[idx] !== 0) + lastnonzero = idx; + idx++; + } + return vb.slice(found - lastnonzero, found + 1); + } + return vb.slice(found - dims.length, found + 1); + } + } + static forBufferedMat(vb = new Array(100).fill(1), dims = [10, 10], asIndex = (v, i, x2, y) => { + return v + x2 + y; + }) { + let coordinate = []; + let idx = 0; + let recurseFor = (depth = 0, nextDepth = depth + 1) => { + let result = new Array(vb.length); + for (let di = 0; di < dims[depth]; di++) { + coordinate[depth] = di; + if (dims[nextDepth]) + recurseFor(nextDepth); + else { + result[idx] = asIndex(vb[idx], idx, ...coordinate); + idx++; + } + } + return result; + }; + let recurseForArrFuncs = (depth, nextDepth = depth + 1) => { + let result = new Array(vb.length); + for (let di = 0; di < dims[depth]; di++) { + coordinate[depth] = di; + if (dims[nextDepth]) + recurseFor(nextDepth); + else { + for (let dj = 0; dj < dims.length; dj++) { + result[idx] = asIndex[dj](vb[idx], idx, ...coordinate); + idx++; + } + } + } + return result; + }; + if (typeof asIndex === "function") { + return recurseFor(); + } else if (Array.isArray(asIndex)) { + return recurseForArrFuncs(); + } + } + static mapBufferedMat(buffer = new Array(100).fill(1), dimensions = [10, 10], asIndex = (v, idx, i, j) => { + console.log(`value:${v}, idx:${idx}, x:${i},y:${j}`); + return v + i + j; + }) { + let coordinate = new Array(dimensions.length).fill(0); + const iterateCoordinate = (coord, idx = 0) => { + if (coord[idx] >= dimensions[idx]) { + coord[idx] = 0; + idx++; + if (idx === dimensions.length) + return; + iterateCoordinate(coord, idx); + } else + coord[idx]++; + }; + let result = new Array(buffer.length); + let i = 0; + if (typeof asIndex === "function") { + while (i < buffer.length) { + result[i] = asIndex(buffer[i], i, ...coordinate); + i += dimensions.length; + iterateCoordinate(coordinate); + } + } else if (Array.isArray(asIndex)) { + while (i < buffer.length) { + asIndex.forEach((func) => { + result[i] = func(buffer[i], i, ...coordinate); + i++; + iterateCoordinate(coordinate); + }); + } + } + return result; + } + static combinations(choices = ["a", "b", "c"], vecsize = 3) { + var result = []; + if (vecsize <= 0) { + result.push([]); + } else { + _Math2.combinations(choices, vecsize - 1).forEach(function(previousComb) { + choices.forEach(function(element) { + result.push([element].concat(previousComb)); + }); + }); + } + return result; + } + static generateCoordinateSpace(upperBounds = [10, 10, 10], lowerBounds = [-10, -10, -10], steps = [1, 1, 1], mutater = void 0) { + for (let i = 0; i < upperBounds.length; i++) { + if (lowerBounds[i] > upperBounds[i]) { + let temp = upperBounds[i]; + upperBounds[i] = lowerBounds[i]; + lowerBounds[i] = temp; + } + } + let result = []; + let copy = [...upperBounds]; + let lastindex = copy.length - 1; + result.push([...copy]); + while (copy[0] >= lowerBounds[0]) { + let checkNextIndex = (decrIdx2) => { + if (copy[decrIdx2] <= lowerBounds[decrIdx2]) { + if (decrIdx2 === 0) + return; + copy[decrIdx2] = upperBounds[decrIdx2]; + decrIdx2--; + if (decrIdx2 < 0) + return; + if (typeof steps[decrIdx2] == "function") + copy[decrIdx2] -= steps[decrIdx2](copy[decrIdx2]); + else + copy[decrIdx2] -= steps[decrIdx2]; + checkNextIndex(decrIdx2); + } + }; + let decrIdx = lastindex; + if (typeof steps[decrIdx] == "function") + copy[decrIdx] -= steps[decrIdx](copy[decrIdx]); + else + copy[decrIdx] -= steps[decrIdx]; + result.push([...copy]); + checkNextIndex(decrIdx); + if (mutater) + result[result.length - 1] = mutater(result[result.length - 1]); + } + return result; + } + static calcVectorField(coordinates = [[0, 0], [0, 1], [1, 0], [1, 1]], formula = (x2, y) => { + return [x2 * 10, y * 10]; + }) { + return coordinates.map((vec) => formula(...vec)); + } + static transpose(mat) { + return mat[0].map((_, colIndex) => mat.map((row) => row[colIndex])); + } + static matmul(a, b) { + var aNumRows = a.length, aNumCols = a[0].length, bNumRows = b.length, bNumCols = b[0].length, m = new Array(aNumRows); + for (var r = 0; r < aNumRows; ++r) { + m[r] = new Array(bNumCols); + for (var c = 0; c < bNumCols; ++c) { + m[r][c] = 0; + for (var i = 0; i < aNumCols; ++i) { + m[r][c] += a[r][i] * b[i][c]; + } + } + } + return m; + } + static matscale(mat, scalar) { + let m = []; + for (var i = 0; i < mat.length; i++) { + m[i] = []; + for (let j = 0; j < mat[0].length; j++) { + m[i][j] = mat[i][j] * scalar; + } + } + return m; + } + static matadd(a, b) { + let m = []; + for (let i = 0; i < a.length; i++) { + m[i] = []; + for (var j = 0; j < a[0].length; j++) { + m[i][j] = a[i][j] + b[i][j]; + } + } + return m; + } + static matsub(a, b) { + let m = []; + for (let i = 0; i < a.length; i++) { + m[i] = []; + for (var j = 0; j < a[0].length; j++) { + m[i][j] = a[i][j] - b[i][j]; + } + } + return m; + } + static histogram(arr = [], binSize = 1, nBins = void 0) { + let copy = [...arr]; + copy.sort(function(a, b) { + return a - b; + }); + let binStart = Math.min(...copy); + if (typeof nBins === "number") { + let binEnd = Math.max(...copy); + binSize = Math.abs((binEnd - binStart) / (nBins - 1)); + } + let j = binStart; + let binx = []; + let biny = []; + for (let i = 0; i < copy.length; i++) { + let binidx = binSize * j; + if (copy[i] > binStart + binidx) { + j++; + binidx += binSize; + let binmin = binStart + binidx; + let binmid = binmin + binidx * 0.5; + binx.push(binmid); + biny.push(0); + } + biny[biny.length - 1]++; + } + return [binx, biny]; + } + static normalDistribution(samples = [], normalize = true, cutoff = 1e-4) { + let m = this.mean(samples); + let vari = this.variance(samples); + let nSamples = samples.length; + let probabilities = []; + let denom = 1 / (this.TWO_PI * vari); + let _variance = 1 / vari; + let sum = 0; + for (let i = 0; i < nSamples; i++) { + let px = Math.exp(-0.5 * Math.pow((samples[i] - m) * _variance, 2)) * denom; + if (px < cutoff) + px = 0; + probabilities.push(px); + sum += px; + } + if (normalize) { + let _sum = 1 / sum; + probabilities = probabilities.map((x2) => x2 * _sum); + } + return probabilities; + } + static expectedValue(samples = [], probabilities = this.normalDistribution(samples)) { + return samples.reduce((sum, item, idx) => sum + item * probabilities[idx]); + } + static originMoment(samples = [], probabilities = this.normalDistribution(samples), order = 1) { + return samples.reduce((sum, item, idx) => sum + Math.pow(item, order) * probabilities[idx]); + } + static centralMoment(samples = [], probabilities = this.normalDistribution(samples), order = 1) { + let m = this.mean(samples); + return samples.reduce((sum, item, idx) => sum + Math.pow(item - m, order) * probabilities[idx] / samples.length); + } + static linearDiscriminantAnalysis(samples = [], classifier = []) { + let mean = this.mean(samples); + let meank = this.mean(classifier); + let covariance = this.cov1d(samples, classifier); + let probs = this.normalDistribution(samples); + let dk = []; + for (let i = 0; i < samples.length; i++) { + dk.push(x[i] * covariance * meank - 0.5 * mean * covariance * meank + Math.log10(probs[i])); + } + return dk; + } + static conv1D(arr = [], kern = [1 / 3, 1 / 3, 1 / 3], pad = Math.floor(kern.length * 0.5)) { + let result = []; + let _n = 1 / kern.length; + if (pad > 0) { + let pads = new Array(pad).fill(0); + arr = [...pads, ...arr, ...pads]; + } + let start = Math.floor(kern.length * 0.5); + let end = arr.length - kern.length + start; + for (let i = start; i < end; i++) { + let acc = 0; + for (let j = 0; j < kern.length; j++) { + acc += arr[i - start] * kern[j]; + } + result.push(acc * _n); + } + return result; + } + static conv2D(mat = [[], [], []], kern = [[], [], []], pad = 0) { + let result = new Array(mat.length - Math.ceil(kern.length * 0.5)).fill([]); + let mat_t; + let kern_t = _Math2.transpose(kern_t); + if (pad > 0) { + let pads = new Array(pad).fill(0); + mat_t = _Math2.transpose(mat); + for (let i2 = 0; i2 < mat_t.length; i2++) { + mat_t[i2] = [...pads, ...mat_t[i2], ...pads]; + } + mat = _Math2.transpose(mat_t); + for (let j = 0; j < mat.length; j++) { + mat[j] = [...pads, ...mat[j], ...pads]; + } + } + let startr = Math.floor(kern[0].length * 0.5); + let startl = Math.floor(kern_t[0].length * 0.5); + let endr = mat[0].length - kern[0].length + startr; + let endl = mat_t[0].length - kern_t[0].length + startl; + let _n = 1 / (kern[0].length * kern_t[0].length); + let iters = endr * endl; + let i = startr; + let x2; + let y = startl; + while (i < iters) { + let acc = 0; + x2 = i % mat[0].length; + if (x2 === 0) { + y++; + } + for (let j = 0; j < kern[0].length; j++) { + for (let k = 0; k < kern_t[0].length; j++) { + acc += mat[y - startl + k][x2 - startr + j] * kern[k][j]; + } + result[y].push(acc * _n); + } + i++; + } + return result; + } + static cov2d(mat) { + var mattransposed = this.transpose(mat); + var matproducts = []; + var rowmeans = []; + var colmeans = []; + mat.forEach((row, idx) => { + rowmeans.push(this.mean(row)); + }); + mattransposed.forEach((col, idx) => { + colmeans.push(this.mean(col)); + }); + mat.forEach((row, idx) => { + matproducts.push([]); + for (var col = 0; col < row.length; col++) { + matproducts[idx].push((mat[idx][col] - rowmeans[idx]) * (mat[idx][col] - colmeans[col]) / (row.length - 1)); + } + }); + var matproductstransposed = this.transpose(matproducts); + var aNumRows = matproducts.length, aNumCols = matproducts[0].length, bNumRows = matproductstransposed.length, bNumCols = matproductstransposed[0].length, m = new Array(aNumRows); + for (var r = 0; r < aNumRows; ++r) { + m[r] = new Array(bNumCols); + for (var c = 0; c < bNumCols; ++c) { + m[r][c] = 0; + for (var i = 0; i < aNumCols; ++i) { + m[r][c] += matproducts[r][i] * matproductstransposed[i][c] / (mat[0].length - 1); + } + } + } + return m; + } + static cov1d(arr1 = [], arr2 = []) { + return this.cov2d([arr1, arr2]); + } + static cov3d(x2 = [], y = [], z = []) { + return [[this.cov1d(x2, x2), this.cov1d(x2, y), this.cov1d(x2, z)], [this.cov1d(y, x2), this.cov1d(y, y), this.cov1d(y, z)], [this.cov1d(z, x2), this.cov1d(z, y), this.cov1d(z, z)]]; + } + static covNd(dimensionalData = []) { + let covariance = []; + dimensionalData.forEach((arr, i) => { + covariance.push([]); + dimensionalData.forEach((arr2, j) => { + covariance[i].push(this.cov1d(arr, arr2)); + }); + }); + } + static eigens2x2(mat = [[1, 2], [3, 4]]) { + let det = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; + let mean = (mat[0][0] + mat[1][1]) * 0.5; + let sqrt = Math.sqrt(mean * mean - det); + let eig1 = mean + sqrt; + let eig2 = mean - sqrt; + return [eig1, eig2]; + } + static eigenvectors2x2(mat = [[1, 2], [3, 4]], eigens = [1, 2]) { + let v1 = [-mat[0][1], mat[0][0] - eigens[0]]; + if (v1[0] === 0 && v1[1] === 0) { + v1[0] = mat[1][1] - eigens[0]; + v1[1] = -mat[1][0]; + } + let v2 = [-mat[0][1], mat[0][0] - eigens[1]]; + if (v2[0] === 0 && v2[1] === 0) { + v2[0] = mat[1][1] - eigens[1]; + v2[1] = -mat[1][0]; + } + return [v1, v2]; + } + static fastpca2d(xarr, yarr) { + let cov1d = this.cov1d(xarr, yarr); + let eigs = this.eigens2x2(cov1d); + if (eigs[1] > eigs[0]) + eigs.reverse(); + let evs = this.eigenvectors2x2(cov1d, eigs); + console.log(eigs, evs); + return [eigs, evs]; + } + static crosscorrelation(arr1, arr2) { + var arr2buf = [...arr2, ...Array(arr2.length).fill(0)]; + var mean12 = this.mean(arr1); + var mean2 = this.mean(arr2); + var arr1Est = arr1.reduce((sum, item) => sum += Math.pow(item - mean12, 2)); + arr1Est = Math.sqrt(arr1Est); + var arr2Est = arr2.reduce((sum, item) => sum += Math.pow(item - mean12, 2)); + arr2Est = Math.sqrt(arr2Est); + var _arrEstsMul = 1 / (arr1Est * arr2Est); + var correlations = new Array(arr1.length).fill(0); + for (var delay = 0; delay < arr1.length; delay++) { + var r = arr1.reduce((sum, item, i) => sum += (item - mean12) * (arr2buf[delay + i] - mean2)); + correlations[delay] = r * _arrEstsMul; + } + return correlations; + } + static autocorrelation(arr1) { + var delaybuf = [...arr1, ...Array(arr1.length).fill(0)]; + var mean12 = this.mean(arr1); + var arr1Est = arr1.reduce((sum, item) => sum += Math.pow(item - mean12, 2)); + arr1Est = Math.sqrt(arr1Est); + var _arr1estsqrd = 1 / (arr1Est * arr1Est); + var correlations = new Array(arr1.length).fill(0); + for (var delay = 0; delay < arr1.length; delay++) { + var r = arr1.reduce((sum, item, i) => sum += (item - mean12) * (delaybuf[delay + i] - mean12)); + correlations[delay] = r * _arr1estsqrd; + } + return correlations; + } + static autocorrelation2dNormalized(mat2d2) { + let result = []; + for (let y = 0; y < mat2d2.length; y++) { + result.push([]); + for (let x2 = 0; x2 < mat2d2[y].length; x2++) { + let G = 0; + let _G = 0; + for (let b = 0; b < mat2d2.length; b++) { + for (let a = 0; a < mat2d2[b].length; a++) { + G += mat2d2[y][x2] * mat2d2[mat2d2.length - 1 - b][mat2d2[y].length - 1 - a]; + _G += mat2d2[y][x2] * mat2d2[mat2d2.length - 1][mat2d2[y].length - 1]; + } + } + result[y][x2] = G / _G - 1; + } + } + return result; + } + static crosscorrelation2d(mat2d1, mat2d2) { + let result = []; + for (let y = 0; y < mat2d1.length; y++) { + result.push([]); + for (let x2 = 0; x2 < mat2d1[y].length; x2++) { + let G = 0; + for (let b = 0; b < mat2d2.length; b++) { + for (let a = 0; a < mat2d2[b].length; a++) { + G += mat2d1[y][x2] * mat2d2[mat2d2.length - 1 - b][mat2d2[y].length - 1 - a]; + } + } + result[y][x2] = G; + } + } + return result; + } + static crosscorrelation2dNormalized(mat2d1, mat2d2) { + let result = []; + for (let y = 0; y < mat2d1.length; y++) { + result.push([]); + for (let x2 = 0; x2 < mat2d1[y].length; x2++) { + let G = 0; + let _G = 0; + for (let b = 0; b < mat2d2.length; b++) { + for (let a = 0; a < mat2d2[b].length; a++) { + G += mat2d1[y][x2] * mat2d2[mat2d.length - 1 - b][mat2d2[y].length - 1 - a]; + _G += mat2d1[y][x2] * mat2d2[mat2d2.length - 1][mat2d2[y].length - 1]; + } + } + result[y][x2] = G / _G - 1; + } + } + return result; + } + static correlograms(dat = [[], []]) { + var correlograms = []; + dat.forEach((row1, i) => { + dat.forEach((row2, j) => { + if (j >= i) { + correlograms.push(_Math2.crosscorrelation(row1, row2)); + } + }); + }); + return correlograms; + } + static dft(sineWave = []) { + var TWOPI = 2 * 3.141592653589793; + var real = []; + var imag = []; + var mags = []; + for (var k = 0; k < sineWave.length; k++) { + real.push(0); + imag.push(0); + for (var j = 0; j < sineWave.length; j++) { + var shared = TWOPI * k * j / sineWave.length; + real[k] = real[k] + sineWave[j] * Math.cos(shared); + imag[k] = imag[k] - sineWave[j] * Math.sin(shared); + } + mags.push(Math.sqrt(real[k] * real[k] + imag[k] * imag[k])); + } + function orderMagnitudes(unorderedMags) { + return [...unorderedMags.slice(Math.ceil(unorderedMags.length * 0.5), unorderedMags.length), ...unorderedMags.slice(0, Math.ceil(unorderedMags.length * 0.5))]; + } + mags = orderMagnitudes(mags); + let halflen = mags.length * 0.5; + let freqs = mags.map((m, i) => { + return i - halflen; + }); + return { real, imag, freqs, mags }; + } + static sma(arr = [], window2) { + var smaArr = []; + for (var i = 0; i < arr.length; i++) { + if (i == 0) { + smaArr.push(arr[0]); + } else if (i < window2) { + var arrslice = arr.slice(0, i + 1); + smaArr.push(arrslice.reduce((previous, current) => current += previous) / (i + 1)); + } else { + var arrslice = arr.slice(i - window2, i); + smaArr.push(arrslice.reduce((previous, current) => current += previous) / window2); + } + } + return smaArr; + } + static sum(arr = []) { + if (arr.length > 0) { + var sum = arr.reduce((prev, curr) => curr += prev); + return sum; + } else { + return 0; + } + } + static reduceArrByFactor(arr, factor = 2) { + let x2 = arr.filter((element, index) => { + return index % factor === 0; + }); + return x2; + } + static makeArr(startValue, stopValue, nSteps) { + var arr = []; + var step = (stopValue - startValue) / (nSteps - 1); + for (var i = 0; i < nSteps; i++) { + arr.push(startValue + step * i); + } + return arr; + } + static autoscale(array, stackedLines = 1, stackPosition = 0, centerZero = false) { + if (array?.length === 0) + return array; + let max = Math.max(...array); + let min = Math.min(...array); + let _lines = 1 / stackedLines; + let scalar; + if (centerZero) { + let absmax = Math.max(Math.abs(min), Math.abs(max)); + scalar = _lines / absmax; + return array.map((y) => y * scalar + (_lines * (stackPosition + 1) * 2 - 1 - _lines)); + } else { + scalar = _lines / (max - min); + return array.map((y) => 2 * ((y - min) * scalar - 1 / (2 * stackedLines)) + (_lines * (stackPosition + 1) * 2 - 1 - _lines)); + } + } + static absmax(array) { + return Math.max(Math.abs(Math.min(...array)), Math.max(...array)); + } + static downsample(array, fitCount, scalar = 1) { + if (array.length > fitCount) { + let output = new Array(fitCount); + let incr = array.length / fitCount; + let lastIdx = array.length - 1; + let last = 0; + let counter = 0; + for (let i = incr; i < array.length; i += incr) { + let rounded = Math.round(i); + if (rounded > lastIdx) + rounded = lastIdx; + for (let j = last; j < rounded; j++) { + output[counter] += array[j]; + } + output[counter] /= (rounded - last) * scalar; + counter++; + last = rounded; + } + return output; + } else + return array; + } + static interpolateArray(data, fitCount, scalar = 1) { + var linearInterpolate = function(before2, after2, atPoint2) { + return (before2 + (after2 - before2) * atPoint2) * scalar; + }; + var newData = new Array(); + var springFactor = new Number((data.length - 1) / (fitCount - 1)); + newData[0] = data[0]; + for (var i = 1; i < fitCount - 1; i++) { + var tmp = i * springFactor; + var before = new Number(Math.floor(tmp)).toFixed(); + var after = new Number(Math.ceil(tmp)).toFixed(); + var atPoint = tmp - before; + newData[i] = linearInterpolate(data[before], data[after], atPoint); + } + newData[fitCount - 1] = data[data.length - 1]; + return newData; + } + static isExtrema(arr, critical = "peak") { + let ref = [...arr]; + if (ref.length % 2 === 0) + ref.pop(); + if (arr.length > 1) { + let pass = true; + for (let i = 0; i < ref.length; i++) { + let val = ref[i]; + if (critical === "peak") { + if (i < Math.floor(ref.length * 0.5) && val >= ref[Math.floor(ref.length * 0.5)]) { + pass = false; + break; + } else if (i > Math.floor(ref.length * 0.5) && val >= ref[Math.floor(ref.length * 0.5)]) { + pass = false; + break; + } + } else if (critical === "valley") { + if (i < Math.floor(ref.length * 0.5) && val <= ref[Math.floor(ref.length * 0.5)]) { + pass = false; + break; + } else if (i > Math.floor(ref.length * 0.5) && val <= ref[Math.floor(ref.length * 0.5)]) { + pass = false; + break; + } + } else { + if (i < Math.floor(ref.length * 0.5) && val <= ref[Math.floor(ref.length * 0.5)]) { + pass = false; + break; + } else if (i > Math.floor(ref.length * 0.5) && val <= ref[Math.floor(ref.length * 0.5)]) { + pass = false; + break; + } + } + } + if (critical !== "peak" && critical !== "valley" && pass === false) { + pass = true; + for (let i = 0; i < ref.length; i++) { + let val = ref[i]; + if (i < Math.floor(ref.length * 0.5) && val >= ref[Math.floor(ref.length * 0.5)]) { + pass = false; + break; + } else if (i > Math.floor(ref.length * 0.5) && val >= ref[Math.floor(ref.length * 0.5)]) { + pass = false; + break; + } + } + } + return pass; + } else + return void 0; + } + static isCriticalPoint(arr, critical = "peak") { + let ref = [...arr]; + if (ref.length % 2 === 0) + ref.pop(); + if (arr.length > 1) { + let pass = true; + for (let i = 0; i < ref.length; i++) { + let val = ref[i]; + if (critical === "peak") { + if (i < ref.length * 0.5 && val <= 0) { + pass = false; + break; + } else if (i > ref.length * 0.5 && val > 0) { + pass = false; + break; + } + } else if (critical === "valley") { + if (i < ref.length * 0.5 && val >= 0) { + pass = false; + break; + } else if (i > ref.length * 0.5 && val < 0) { + pass = false; + break; + } + } else { + if (i < ref.length * 0.5 && val >= 0) { + pass = false; + break; + } else if (i > ref.length * 0.5 && val < 0) { + pass = false; + break; + } + } + } + if (critical !== "peak" && critical !== "valley" && pass === false) { + pass = true; + for (let i = 0; i < ref.length; i++) { + let val = ref[i]; + if (i < ref.length * 0.5 && val <= 0) { + pass = false; + break; + } else if (i > ref.length * 0.5 && val > 0) { + pass = false; + break; + } + } + } + return pass; + } else + return void 0; + } + static getPeakThreshold(arr, peakIndices, thresholdVar) { + let threshold; + let filtered = arr.filter((o, i) => { + if (peakIndices.indexOf(i) > -1) + return true; + }); + if (thresholdVar === 0) { + threshold = this.mean(filtered); + } else + threshold = (thresholdVar + this.mean(filtered)) * 0.5; + return threshold; + } + static column(mat, x2) { + let col = new Array(mat.length).fill(0).map(() => new Array(1).fill(0)); + for (let i = 0; i < mat.length; i++) { + col[i][0] = mat[i][x2]; + } + return col; + } + static flatten_vector(v) { + let v_new = []; + for (let i = 0; i < v.length; i++) { + v_new[i] = v[i][0]; + } + return v_new; + } + static squared_difference(v1, v2) { + let sum = 0; + for (let i = 0; i < v1.length; i++) { + sum = sum + Math.pow(v1[i] - v2[i], 2); + } + return sum; + } + static shift_deflate(mat, eigenvalue, eigenvector) { + let len = Math.sqrt(this.matmul(this.transpose(eigenvector), eigenvector)); + let U = this.matscale(eigenvector, 1 / len); + let delta = this.matscale(this.matmul(U, this.transpose(U)), eigenvalue); + let M_new = this.matsub(mat, delta); + return M_new; + } + static eigenvalue_of_vector(mat, eigenvector) { + ev = this.matmul(this.matmul(this.transpose(eigenvector), mat), eigenvector); + return ev; + } + static power_iteration(mat, tolerance = 1e-5, max_iterations = 1e3) { + let rank = mat.length; + let eigenvector = new Array(rank).fill(0).map(() => new Array(1).fill(Math.sqrt(rank))); + let eigenvalue = this.eigenvalue_of_vector(mat, eigenvector); + let epsilon = 1; + let iter = 0; + while (epsilon > tolerance && iter < max_iterations) { + let old_eigenvalue = JSON.parse(JSON.stringify(eigenvalue)); + let Mv = this.matmul(mat, eigenvector); + eigenvector = this.normalize(Mv); + eigenvalue = this.eigenvalue_of_vector(mat, eigenvector); + epsilon = Math.abs(eigenvalue - old_eigenvalue); + iter++; + } + ; + return [eigenvalue, eigenvector]; + } + static eigens(mat, tolerance = 1e-4, max_iterations = 1e3) { + let eigenvalues = []; + let eigenvectors = []; + for (let i = 0; i < mat.length; i++) { + let result = this.power_iteration(mat, tolerance, max_iterations); + let eigenvalue = result[0]; + let eigenvector = result[1]; + eigenvalues[i] = eigenvalue; + eigenvectors[i] = this.flatten_vector(eigenvector); + mat = this.shift_deflate(mat, eigenvalue, eigenvector); + } + return [eigenvalues, eigenvectors]; + } + static pca(mat, tolerance = 1e-5) { + let dims = mat.length; + let t = new Array(dims); + let p = new Array(dims); + let mat_t = this.transpose(mat); + t[0] = this.column(mat, 0); + let epsilon = 1; + let iter = 0; + while (espilon > tolerance) { + iter++; + p[0] = this.matmul(mat_t, t[0]); + let tp = this.matmul(this.transpose(t[0]), t[0]); + p[0] = this.matscale(p[0], 1 / tp); + let p_length = Math.sqrt(this.matmul(this.transpose(p[0]), p[0])); + p[0] = this.matscale(p[0], 1 / p_length); + let t_new = this.matmul(mat, p[0]); + let pp = this.matmul(this.transpose(p[0]), p[0]); + t_new = this.matscale(t_new, 1 / pp); + epsilon = this.squared_difference(t[0], t_new); + t[0] = JSON.parse(JSON.stringify(t_new)); + } + let components = this.matmul(this.transpose(t[0]), t[0]); + return components; + } + static p300(event_timestamps = [], raw_signal = [], signal_timestamps = [], sps = 256) { + let smoothingstep = Math.floor(sps / 10); + let smoothed = this.sma(raw_signal, smoothingstep); + let peaks = this.peakDetect(smoothed, "peak", smoothingstep); + let mean = this.mean(smoothed); + let std = this.std(smoothed, mean); + let p_idx = 0; + let candidates = []; + if (peaks.length > 0) { + event_timestamps.forEach((t, j) => { + while (signal_timestamps[peaks[p_idx]] < t + 200) { + p_idx++; + if (!peaks[p_idx]) + break; + } + let tempi = 0; + let tempcandidates = []; + while (signal_timestamps[peaks[p_idx + tempi]] < t + 600) { + tempcandidates.push(p_idx + tempi); + tempi++; + if (!peaks[p_idx + tempi]) + break; + } + if (tempcandidates.length > 1) { + let peakvals = []; + tempcandidates.forEach((tc) => { + peakvals.push(smoothed[peaks[tc]]); + }); + let max = Math.max(...peakvals); + let maxi = tempcandidates[peakvals.indexOf(max)]; + candidates.push({ event_timestamp: t, event_index: j, peak_timestamp: signal_timestamps[[peaks[maxi]]], signal_index: [peaks[maxi]], signal_amplitude: raw_signal[[peaks[maxi]]], zscore: (smoothed[peaks[maxi]] - mean) / std }); + } else if (tempcandidates.length === 1) + candidates.push({ event_timestamp: t, event_index: j, peak_timestamp: signal_timestamps[peaks[tempcandidates[0]]], signal_index: peaks[tempcandidates[0]], signal_amplitude: raw_signal[[peaks[tempcandidates[0]]]], zscore: (smoothed[peaks[tempcandidates[0]]] - mean) / std }); + }); + } + return candidates; + } + }; + var Math2 = _Math2; + __publicField(Math2, "TWO_PI", Math.PI * 2); + __publicField(Math2, "C", 299792458); + __publicField(Math2, "G", 66743e-15); + __publicField(Math2, "h", 662607015e-42); + __publicField(Math2, "R", 8314.32); + __publicField(Math2, "Ra", 287); + __publicField(Math2, "H", 69.3); + __publicField(Math2, "kbar", 1054571817e-43); + __publicField(Math2, "kB", 1380649e-29); + __publicField(Math2, "ke", 89875517923e-1); + __publicField(Math2, "me", 91093837015e-41); + __publicField(Math2, "mp", 167262192369e-38); + __publicField(Math2, "mn", 167492749804e-38); + __publicField(Math2, "P0", 101325); + __publicField(Math2, "T0", 288.15); + __publicField(Math2, "p0", 1.225); + __publicField(Math2, "Na", 60220978e16); + __publicField(Math2, "y", 1.405); + __publicField(Math2, "M0", 28.96643); + __publicField(Math2, "g0", 9.80665); + __publicField(Math2, "Re", 6378100); + __publicField(Math2, "B", 1458e-9); + __publicField(Math2, "S", 110.4); + __publicField(Math2, "Sigma", 365e-12); + __publicField(Math2, "imgkernels", { edgeDetection: [[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], boxBlur: [[1 / 9, 1 / 9, 1 / 9], [1 / 9, 1 / 9, 1 / 9], [1 / 9, 1 / 9, 1 / 9]], sobelLeft: [[1, 0, -1], [2, 0, -2], [1, 0, -1]], sobelRight: [[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], sobelTop: [[1, 2, 1], [0, 0, 0], [-1, -2, -1]], sobelBottom: [[-1, 2, 1], [0, 0, 0], [1, 2, 1]], identity: [[0, 0, 0], [0, 1, 0], [0, 0, 0]], gaussian3x3: [[1, 2, 1], [2, 4, 2], [1, 2, 1]], guassian7x7: [[0, 0, 0, 5, 0, 0, 0], [0, 5, 18, 32, 18, 5, 0], [0, 18, 64, 100, 64, 18, 0], [5, 32, 100, 100, 100, 32, 5], [0, 18, 64, 100, 64, 18, 0], [0, 5, 18, 32, 18, 5, 0], [0, 0, 0, 5, 0, 0, 0]], emboss: [[-2, -1, 0], [-1, 1, 1], [0, 1, 2]], sharpen: [[0, -1, 0], [-1, 5, -1], [0, -1, 0]] }); + __publicField(Math2, "integral", (func = (x2) => { + let y = x2; + return y; + }, range = [], stepx = 0.01) => { + let area = 0; + for (let i = range[0]; i < range[1]; i += stepx) { + let y = func(i); + area += y * stepx; + } + return area; + }); + __publicField(Math2, "dintegral", (func = (x2, y) => { + let z = x2 + y; + return z; + }, range = [[], []], stepx = 0.01, stepy = stepx) => { + let volume = 0; + for (let i = range[0][0] + stepx; i < range[0][1]; i += stepx) { + for (let j = range[1][0] + stepy; j < range[1][1]; j += stepy) { + let z = func(i, j); + volume += z * stepx * stepy; + } + } + return volume; + }); + __publicField(Math2, "tintegral", (func = (x2, y, z) => { + let w = x2 + y + z; + return w; + }, range = [[], [], []], stepx = 0.01, stepy = stepx, stepz = stepx) => { + let volume = 0; + for (let i = range[0][0] + stepx; i < range[0][1]; i += stepx) { + for (let j = range[1][0] + stepy; j < range[1][1]; j += stepy) { + for (let k = range[2][0] + stepz; k < range[2][1]; k += stepz) { + let w = func(i, j, k); + volume += w * stepx * stepy * stepz; + } + } + } + return volume; + }); + __publicField(Math2, "pintegral", (func = (x2) => { + let y = x2; + return y; + }, range = [], stepx = 0.01) => { + let length = 0; + let y0 = void 0; + let yi = void 0; + for (let i = range[0]; i < range[1]; i += stepx) { + y0 = yi; + yi = func(i); + if (y0) + length += _Math2.distance([0, y0], [stepx, yi]); + } + return length; + }); + __publicField(Math2, "meshgrid", _Math2.generateCoordinateSpace); + __publicField(Math2, "autocorrelation2d", (mat2d2) => { + let result = []; + for (let y = 0; y < mat2d2.length; y++) { + result.push([]); + for (let x2 = 0; x2 < mat2d2[y].length; x2++) { + let G = 0; + for (let b = 0; b < mat2d2.length; b++) { + for (let a = 0; a < mat2d2[b].length; a++) { + G += mat2d2[y][x2] * mat2d2[mat2d2.length - 1 - b][mat2d2[y].length - 1 - a]; + } + } + result[y][x2] = G; + } + } + return result; + }); + __publicField(Math2, "upsample", _Math2.interpolateArray); + __publicField(Math2, "peakDetect", (smoothedArray, type = "peak", window2 = 49) => { + let mid = Math.floor(window2 * 0.5); + let peaks = []; + for (let i = 0; i < smoothedArray.length - window2; i++) { + let isPeak = _Math2.isExtrema(smoothedArray.slice(i, i + window2), type); + if (isPeak) { + peaks.push(i + mid - 1); + } + } + return peaks; + }); + Object.assign(Math, Math2); + var GPUService = class extends Service2 { + constructor(options) { + super(options); + this.gpu = new (void 0)(); + this.addFunc = (fn) => { + if (typeof fn === "string") + fn = parseFunctionFromText2(fn); + if (typeof fn === "function") + this.gpu.addFunction(fn); + }; + this.addKernel = (name2, fn, options2) => { + if (typeof fn === "string") + fn = parseFunctionFromText2(fn); + if (typeof fn === "function") + this.gpu.addKernel(name2, fn, options2); + }; + this.callKernel = (name2, ...args) => { + this.gpu.callKernel(name2, ...args); + }; + this.dft = (signalBuffer, nSeconds, scalar) => { + if (scalar == void 0) + scalar = 1; + return this.gpu.gpuDFT(signalBuffer, nSeconds, scalar); + }; + this.multidft = (signalBuffer, nSeconds, scalar) => { + if (scalar == void 0) + scalar = 1; + return this.gpu.MultiChannelDFT(signalBuffer, nSeconds, scalar); + }; + this.multidftbandpass = (buffered, nSeconds, freqStart, freqEnd, scalar) => { + if (scalar == void 0) + scalar = 1; + return this.gpu.MultiChannelDFT_Bandpass(buffered, nSeconds, freqStart, freqEnd, scalar); + }; + this.coherence = (buffered, nSeconds, freqStart, freqEnd) => { + const correlograms = Math2.correlograms(buffered); + const buffer = [...buffered, ...correlograms]; + var dfts; + var scalar = 1; + dfts = this.gpu.MultiChannelDFT_Bandpass(buffer, nSeconds, freqStart, freqEnd, scalar); + const cordfts = dfts[1].splice(buffered.length, buffer.length - buffered.length); + const coherenceResults = []; + const nChannels = buffered.length; + var k = 0; + var l = 0; + cordfts.forEach((row, i) => { + if (l + k === nChannels) { + var temp = cordfts.splice(i, 1); + k++; + cordfts.splice(k, 0, ...temp); + l = 0; + } + l++; + }); + var autoFFTproducts = []; + k = 0; + l = 1; + cordfts.forEach((dft, i) => { + var newdft = new Array(dft.length).fill(0); + if (i < nChannels) { + dft.forEach((amp, j) => { + newdft[j] = amp; + }); + autoFFTproducts.push(newdft); + } else { + dft.forEach((amp, j) => { + newdft[j] = amp * amp / (autoFFTproducts[k][j] * autoFFTproducts[k + l][j]); + if (newdft[j] > 1) { + newdft[j] = 1; + } + }); + l++; + if (l + k === nChannels) { + k++; + l = 1; + } + coherenceResults.push(newdft); + } + }); + return [dfts[0], dfts[1], coherenceResults]; + }; + this.routes = { addFunc: this.addFunc, addKernel: this.addKernel, callKernel: this.callKernel, dft: this.dft, multidft: this.multidft, multidftbandpass: this.multidftbandpass, coherence: this.coherence }; + this.load(this.routes); + } + }; + var http = __toESM2(require("http")); + var https = __toESM2(require("https")); + var fs = __toESM2(require("fs")); + var path = __toESM2(require("path")); + var HTTPbackend2 = class extends Service2 { + constructor(options, settings) { + super(options); + this.name = "http"; + this.debug = false; + this.servers = {}; + this.mimeTypes = { ".html": "text/html", ".htm": "text/html", ".js": "text/javascript", ".css": "text/css", ".json": "application/json", ".txt": "text/plain", ".png": "image/png", ".jpg": "image/jpg", ".jpeg": "image/jpg", ".gif": "image/gif", ".svg": "image/svg+xml", ".xhtml": "application/xhtml+xml", ".bmp": "image/bmp", ".wav": "audio/wav", ".mp3": "audio/mpeg", ".mp4": "video/mp4", ".xml": "application/xml", ".webm": "video/webm", ".webp": "image/webp", ".weba": "audio/webm", ".woff": "font/woff", "woff2": "font/woff2", ".ttf": "application/font-ttf", ".eot": "application/vnd.ms-fontobject", ".otf": "application/font-otf", ".wasm": "application/wasm", ".zip": "application/zip", ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ".tif": "image/tiff", ".sh": "application/x-sh", ".csh": "application/x-csh", ".rar": "application/vnd.rar", ".ppt": "application/vnd.ms-powerpoint", ".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation", ".odt": "application/vnd.oasis.opendocument.text", ".ods": "application/vnd.oasis.opendocument.spreadsheet", ".odp": "application/vnd.oasis.opendocument.presentation", ".mpeg": "video/mpeg", ".mjs": "text/javascript", ".cjs": "text/javascript", ".jsonld": "application/ld+json", ".jar": "application/java-archive", ".ico": "image/vnd.microsoft.icon", ".gz": "application/gzip", "epub": "application/epub+zip", ".doc": "application/msword", ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", ".csv": "text/csv", ".avi": "video/x-msvideo", ".aac": "audio/aac", ".mpkg": "application/vnd.apple.installer+xml", ".oga": "audio/ogg", ".ogv": "video/ogg", "ogx": "application/ogg", ".php": "application/x-httpd-php", ".rtf": "application/rtf", ".swf": "application/x-shockwave-flash", ".7z": "application/x-7z-compressed", ".3gp": "video/3gpp" }; + this.onStarted = (protocol, host, port) => { + console.log(`\u{1F431} Node server running at + ${protocol}://${host}:${port}/`); + }; + this.setupServer = (options2 = { protocol: "http", host: "localhost", port: 8080, startpage: "index.html" }, requestListener, onStarted) => { + if (options2.pages) { + for (const key in options2.pages) { + if (typeof options2.pages[key] === "string") { + this.addPage(`${options2.port}/${key}`, options2.pages[key]); + } else if (typeof options2.pages[key] === "object") { + if (options2.pages[key].template) { + options2.pages[key].get = options2.pages[key].template; + } + if (key !== "_all") + this.load({ [`${options2.port}/${key}`]: options2.pages[key] }); + } + } + } + if (options2.protocol === "https") { + return this.setupHTTPSserver(options2, requestListener, onStarted); + } else + return this.setupHTTPserver(options2, requestListener, onStarted); + }; + this.setupHTTPserver = (options2 = { host: "localhost", port: 8080, startpage: "index.html", errpage: void 0 }, requestListener, onStarted = () => { + this.onStarted("http", options2.host, options2.port); + }) => { + const host = options2.host; + const port = options2.port; + options2.protocol = "http"; + if (!host || !port) + return; + const address = `${host}:${port}`; + if (this.servers[address]) + this.terminate(this.servers[address]); + if (!("keepState" in options2)) + options2.keepState = true; + const served = { server: void 0, type: "httpserver", address, ...options2 }; + if (!requestListener) + requestListener = (request, response) => { + let received = { args: { request, response }, method: request.method, served }; + let url = request.url.slice(1); + if (!url) + url = "/"; + if (options2.pages) { + if (typeof options2.pages[url] === "object") { + if (options2.pages[url].onrequest) { + if (typeof options2.pages[url].onrequest === "string") { + options2.pages[url].onrequest = this.nodes.get(options2.pages[url].onrequest); + } + if (typeof options2.pages[url].onrequest === "object") { + if (options2.pages[url].onrequest.run) { + options2.pages[url].onrequest.run(options2.pages[url], request, response); + } + } else if (typeof options2.pages[url].onrequest === "function") { + options2.pages[url].onrequest(this, options2.pages[url], request, response); + } + } + if (options2.pages[url].redirect) { + url = options2.pages[url].redirect; + received.redirect = url; + } + } + } + received.route = url; + this.receive(received); + }; + const server2 = http.createServer(requestListener); + served.server = server2; + this.servers[address] = served; + return new Promise((resolve, reject) => { + server2.on("error", (err) => { + console.error("Server error:", err.toString()); + reject(err); + }); + server2.listen(port, host, () => { + onStarted(); + resolve(served); + }); + }); + }; + this.setupHTTPSserver = (options2 = { host: "localhost", port: 8080, startpage: "index.html", certpath: "cert.pem", keypath: "key.pem", passphrase: "encryption", errpage: void 0 }, requestListener, onStarted = () => { + this.onStarted("https", options2.host, options2.port); + }) => { + const host = options2.host; + const port = options2.port; + options2.protocol = "https"; + if (!host || !port || !options2.certpath || !options2.keypath) + return; + if (this.servers[`${host}:${port}`]) + this.terminate(this.servers[`${host}:${port}`]); + var opts = { key: fs.readFileSync(options2.keypath), cert: fs.readFileSync(options2.certpath), passphrase: options2.passphrase }; + if (!("keepState" in options2)) + options2.keepState = true; + const served = { server: void 0, type: "httpserver", address: `${host}:${port}`, ...options2 }; + if (!requestListener) + requestListener = (request, response) => { + let received = { args: { request, response }, method: request.method, served }; + let url = request.url.slice(1); + if (!url) + url = "/"; + if (options2.pages) { + if (typeof options2.pages[url] === "object") { + if (options2.pages[url].redirect) { + url = options2.pages[url].redirect; + received.redirect = url; + } + if (options2.pages[url].onrequest) { + if (typeof options2.pages[url].onrequest === "string") { + options2.pages[url].onrequest = this.nodes.get(options2.pages[url].onrequest); + } + if (typeof options2.pages[url].onrequest === "object") { + if (options2.pages[url].onrequest.run) { + options2.pages[url].onrequest.run(options2.pages[url], request, response); + } + } else if (typeof options2.pages[url].onrequest === "function") { + options2.pages[url].onrequest(this, options2.pages[url], request, response); + } + } + } + } + received.route = url; + this.receive(received); + }; + const server2 = https.createServer(opts, requestListener); + served.server = server2; + this.servers[`${host}:${port}`] = served; + return new Promise((resolve, reject) => { + server2.on("error", (err) => { + console.error("Server error:", err.toString()); + reject(err); + }); + server2.listen(port, host, () => { + onStarted(); + resolve(served); + }); + }); + }; + this.transmit = (message, options2, ondata, onend) => { + let input = message; + if (typeof input === "object") + input = JSON.stringify(input); + if (typeof options2 === "string" && message) + return this.post(options2, message); + else if (typeof options2 === "string") + return this.get(options2); + if (!options2) { + let server2 = this.servers[Object.keys(this.servers)[0]]; + options2 = { protocol: server2.protocol, host: server2.host, port: server2.port, method: "POST", path: message.route, headers: { "Content-Type": "application/json", "Content-Length": input.length } }; + } else if (!options2.headers) { + options2.headers = { "Content-Type": "application/json", "Content-Length": input.length }; + } + return this.request(options2, input, ondata, onend); + }; + this.withResult = (response, result, message) => { + if (result && !response.writableEnded && !response.destroyed) { + if (typeof result === "string") { + if (path.extname(result) && fs.existsSync(path.join(process.cwd(), result))) { + result = fs.readFileSync(path.join(process.cwd(), result)).toString(); + } + if (result.includes("<") && result.includes(">") && result.indexOf("<") < result.indexOf(">")) { + if (message?.served?.pages?._all || message?.served?.pages?.[message.route]) { + result = this.injectPageCode(result, message.route, message.served); + } + response.writeHead(200, { "Content-Type": "text/html" }); + response.end(result, "utf-8"); + return; + } + } + let mimeType = "text/plain"; + if (typeof result === "object") { + result = stringifyWithCircularRefs2(result); + mimeType = "application/json"; + } + response.writeHead(200, { "Content-Type": mimeType }); + response.end(result, "utf-8"); + } + }; + this.injectPageCode = (templateString, url, served) => { + if (served?.pages?.[url]?.inject) { + if (typeof served.pages[url].inject === "object") + templateString = this.buildPage(served.pages[url].inject, templateString); + else if (typeof served.pages[url].inject === "function") + templateString += served.pages[url].inject(); + else if (typeof served.pages[url].inject === "string" || typeof served.pages[url].inject === "number") + templateString += served.pages[url].inject; + } + if (served?.pages?._all?.inject) { + if (typeof served.pages._all.inject === "object") + templateString = this.buildPage(served.pages._all.inject, templateString); + else if (typeof served.pages._all.inject === "function") + templateString += served.pages._all.inject(); + else if (typeof served.pages._all.inject === "string" || typeof served.pages._all.inject === "number") + templateString += served.pages._all.inject; + } + return templateString; + }; + this.receive = (message) => { + const request = message.args.request; + const response = message.args.response; + const method = message.method; + const served = message.served; + if (this.debug) + console.log(request.method, request.url); + let result = new Promise((resolve, reject) => { + response.on("error", (err) => { + if (!response.writableEnded || !response.destroyed) { + response.statusCode = 400; + response.end(void 0, void 0, () => { + reject(err); + }); + } + }); + let getFailed = () => { + if (response.writableEnded || response.destroyed) + reject(requestURL); + if (requestURL == "./" || requestURL == served?.startpage) { + let template = `

    Brains@Play Server

    `; + if (served?.pages?._all || served?.pages?.error) { + template = this.injectPageCode(template, message.route, served); + } + response.writeHead(200, { "Content-Type": "text/html" }); + response.end(template, "utf-8", () => { + resolve(template); + }); + if (served?.keepState) + this.setState({ [served.address]: template }); + } else if (this.debug) + console.log(`File ${requestURL} does not exist on path!`); + response.writeHead(500); + response.end(void 0, void 0, () => { + reject(requestURL); + }); + }; + if (method === "GET" || method === "get") { + var requestURL = "." + request.url; + if (requestURL == "./" && served?.startpage) { + requestURL = served.startpage; + } + if ((request.url !== "/" || served?.startpage) && fs.existsSync(path.join(process.cwd(), requestURL))) { + if (response.writableEnded || response.destroyed) + reject(requestURL); + fs.readFile(path.join(process.cwd(), requestURL), (error, content) => { + if (error) { + if (error.code == "ENOENT") { + if (served?.errpage) { + fs.readFile(served.errpage, (er, content2) => { + response.writeHead(404, { "Content-Type": "text/html" }); + if (served.pages?._all || served.pages?.error) { + content2 = this.injectPageCode(content2.toString(), message.route, served); + } + response.end(content2, "utf-8"); + reject(content2); + }); + } else { + response.writeHead(404, { "Content-Type": "text/html" }); + let content2 = `

    Error: ${error.code}

    `; + if (served?.pages?._all || served?.pages?.[message.route]) { + content2 = this.injectPageCode(content2.toString(), message.route, served); + } + response.end(content2, "utf-8", () => { + reject(error.code); + }); + } + } else { + response.writeHead(500); + response.end("Something went wrong: " + error.code + " ..\n", "utf-8", () => { + reject(error.code); + }); + } + } else { + var extname2 = String(path.extname(requestURL)).toLowerCase(); + var contentType = this.mimeTypes[extname2] || "application/octet-stream"; + if (contentType === "text/html" && (served?.pages?._all || served?.pages?.[message.route])) { + content = this.injectPageCode(content.toString(), message.route, served); + } + response.writeHead(200, { "Content-Type": contentType }); + response.end(content, "utf-8", () => { + resolve(content); + }); + } + }); + } else if (message.route) { + let route; + if (served) { + let rt = `${served.port}/${message.route}`; + if (this.nodes.get(rt)) + route = rt; + } + if (!route && this.nodes.get(message.route)) + route = message.route; + if (route) { + let res; + if (message.method) { + res = this.handleMethod(route, message.method, void 0, message.origin); + } else if (message.node) { + res = this.handleGraphNodeCall(message.node, void 0); + } else + res = this.handleServiceMessage({ route, args: void 0, method: message.method, origin: message.origin }); + if (res instanceof Promise) + res.then((r) => { + if (served?.keepState) + this.setState({ [served.address]: res }); + this.withResult(response, r, message); + resolve(res); + }); + else if (res) { + if (served?.keepState) + this.setState({ [served.address]: res }); + this.withResult(response, res, message); + resolve(res); + } + } else if (message.redirect) { + response.writeHead(301, { "Location": message.redirect }); + response.end(); + resolve(true); + } else + getFailed(); + } else + getFailed(); + } else { + let body = []; + request.on("data", (chunk) => { + body.push(chunk); + }).on("end", () => { + body = Buffer.concat(body).toString(); + if (typeof body === "string") { + let substr = body.substring(0, 8); + if (substr.includes("{") || substr.includes("[")) { + if (substr.includes("\\")) + body = body.replace(/\\/g, ""); + if (body[0] === '"') { + body = body.substring(1, body.length - 1); + } + ; + body = JSON.parse(body); + } + } + let route, method2, args, origin; + if (body?.route) { + route = this.routes[body.route]; + method2 = body.method; + args = body.args; + origin = body.origin; + if (!route) { + if (typeof body.route === "string") { + if (body.route.includes("/") && body.route.length > 1) + body.route = body.route.split("/").pop(); + } + route = this.routes[body.route]; + } + } + if (!route) { + if (message?.route) { + let route2 = this.routes[message.route]; + method2 = message.method; + args = message.args; + origin = message.origin; + if (!route2) { + if (typeof message.route === "string") { + if (message.route.includes("/") && message.route.length > 1) + message.route = message.route.split("/").pop(); + } + route2 = this.routes[message.route]; + } + } + } + let res = body; + if (route) { + if (body.method) { + res = this.handleMethod(route, method2, args, origin); + } else if (body.node) { + res = this.handleGraphNodeCall(body.node, body.args, body.origin); + } else + res = this.handleServiceMessage({ route, args, method: method2, origin }); + if (res instanceof Promise) { + res.then((r) => { + this.withResult(response, r, message); + if (served?.keepState) + this.setState({ [served.address]: res }); + resolve(res); + }); + } else { + this.withResult(response, res, message); + if (served?.keepState) + this.setState({ [served.address]: res }); + resolve(res); + } + } else if (!response.writableEnded || !response.destroyed) { + response.statusCode = 200; + response.end(void 0, void 0, () => { + resolve(res); + }); + } else + resolve(res); + }); + } + }).catch((er) => { + console.error("Request Error:", er); + }); + return result; + }; + this.request = (options2, send, ondata, onend) => { + let client = http; + if (options2.protocol?.includes("https")) { + client = https; + } + delete options2.protocol; + const req = client.request(options2, (res) => { + if (ondata) + res.on("data", ondata); + if (onend) + res.on("end", onend); + }); + if (options2.headers) { + for (const head in options2.headers) { + req.setHeader(head, options2.headers[head]); + } + } + if (send) + req.write(send); + req.end(); + return req; + }; + this.post = (url, data, headers) => { + let urlstring = url; + if (urlstring instanceof URL) + urlstring = url.toString(); + let protocol = urlstring.startsWith("https") ? "https" : "http"; + let host, port, path3; + let split = urlstring.split("/"); + split.forEach((s) => { + if (s.includes(":")) { + let ss = s.split(":"); + host = ss[0]; + port = ss[1]; + } + }); + if (split.length > 3) { + path3 = split.slice(3).join("/"); + } + let req = this.request({ protocol, host, port, path: path3, method: "POST", headers }, data); + return req; + }; + this.get = (url) => { + return new Promise((resolve, reject) => { + let client = http; + let urlstring = url; + if (url instanceof URL) + urlstring = url.toString(); + if (urlstring.includes("https")) { + client = https; + } + client.get(url, (resp) => { + let chunks = []; + resp.on("data", (chunk) => { + chunks.push(chunk); + }); + resp.on("end", () => { + resolve(Buffer.concat(chunks)); + }); + }).on("error", (err) => { + reject(err); + }); + }); + }; + this.terminate = (served) => { + if (typeof served === "string") + served = this.servers[served]; + if (typeof served === "object") { + served.server.close(); + } + }; + this.addPage = (path3, template) => { + if (typeof template === "string") { + if (!template.includes(""; + } + if (typeof this.routes[path3] === "object") { + this.routes[path3].get = template; + this.nodes.get(path3).get = template; + } else + this.load({ [path3]: { get: template } }); + }; + this.addHTML = (path3, template) => { + if (typeof template === "string") { + if (!template.includes("<") || !template.includes(">")) + template = "
    " + template + "
    "; + } + if (typeof this.routes[path3] === "object") { + this.routes[path3].get = template; + this.nodes.get(path3).get = template; + } else + this.load({ [path3]: { get: template } }); + }; + this.buildPage = (pageStructure, baseTemplate) => { + let result = ``; + if (baseTemplate) + result += baseTemplate; + let appendTemplate = (obj, r, res) => { + if (typeof obj[r] === "object") { + for (const key in obj) { + appendTemplate(obj, key, res); + } + } else if (this.routes[r]?.get) { + let toAdd = this.routes[r].get; + if (typeof toAdd === "function") + toAdd = toAdd(obj[r]); + if (typeof toAdd === "string") { + let lastDiv = res.lastIndexOf("<"); + if (lastDiv > 0) { + let end = res.substring(lastDiv); + res = res.substring(0, lastDiv) + toAdd + end; + } + res += toAdd; + } + } else if (typeof this.routes[r] === "function") { + let routeresult = this.routes[r](obj[r]); + if (typeof routeresult === "string") { + let lastDiv = res.lastIndexOf("<"); + if (lastDiv > 0) { + let end = res.substring(lastDiv); + res = res.substring(0, lastDiv) + routeresult + end; + } else + res += routeresult; + } + } else if (typeof this.routes[r] === "string") + res += this.routes[r]; + return res; + }; + if (Array.isArray(pageStructure)) { + pageStructure.forEach((r) => { + result = appendTemplate(pageStructure, r, result); + }); + } else if (typeof pageStructure === "object") { + for (const r in pageStructure) { + result = appendTemplate(pageStructure, r, result); + } + } else if (typeof pageStructure === "string") + result += pageStructure; + else if (typeof pageStructure === "function") + result += pageStructure(); + return result; + }; + this.routes = { setupServer: this.setupServer, terminate: (path3) => { + if (path3) + for (const address in this.servers) { + if (address.includes(`${path3}`)) { + this.terminate(this.servers[address]); + delete this.servers[address]; + } + } + }, GET: this.get, POST: this.post, addPage: this.addPage, addHTML: this.addHTML, buildPage: this.buildPage, getRequestBody: this.getRequestBody, hotreload: (socketURL = `http://localhost:8080/wss`) => { + if (socketURL instanceof URL) + socketURL = socketURL.toString(); + const HotReloadClient = (url = `http://localhost:8080/wss`) => { + let socket = new WebSocket(url); + socket.addEventListener("close", () => { + const interAttemptTimeoutMilliseconds = 100; + const maxDisconnectedTimeMilliseconds = 3e3; + const maxAttempts = Math.round(maxDisconnectedTimeMilliseconds / interAttemptTimeoutMilliseconds); + let attempts = 0; + const reloadIfCanConnect = () => { + attempts++; + if (attempts > maxAttempts) { + console.error("Could not reconnect to dev server."); + return; + } + socket = new WebSocket(url); + socket.onerror = (er) => { + console.error(`Hot reload port disconnected, will reload on reconnected. Attempt ${attempts} of ${maxAttempts}`); + }; + socket.addEventListener("error", () => { + setTimeout(reloadIfCanConnect, interAttemptTimeoutMilliseconds); + }); + socket.addEventListener("open", () => { + location.reload(); + }); + }; + reloadIfCanConnect(); + }); + }; + return ` + - - - \ No newline at end of file diff --git a/examples/loaders/basic/index.ts b/examples/loaders/basic/index.ts deleted file mode 100644 index ec19dff7..00000000 --- a/examples/loaders/basic/index.ts +++ /dev/null @@ -1,48 +0,0 @@ -import {Graph, Loader, GraphNodeProperties, Roots } from '../../../src/core/Graph' -import { loop } from '../../../src/loaders/index' - - -const roots = { - - loopNode:{ - __element:'div', - innerHTML:`
    Hello world!
    `, - __operator:function (){ - const message = `looped: ${performance.now().toFixed(1)}ms`; - this.insertAdjacentHTML('beforeend',`
    ${message}
    `) - console.log(message); - - return true; - }, - __node:{ - loop:1000, //note this doesn't result in perfect 1000ms loops due to how javascript prioritizes stuff, so it's only relative - looping:true - } - } as GraphNodeProperties - -} as Roots - -let customHTMLLoader:Loader = ( - node, -) => { - if(typeof node.__element == 'string') { - node.__props = document.createElement(node.__element); - if(node.__props instanceof HTMLElement) { - for(const key in node) { - node.__props[key] = node[key]; - } - node.__proxyObject(node.__props); - - document.body.insertAdjacentElement('beforeend',node.__props) - } - } -} - -const graph = new Graph({ - roots, - loaders:{ - customHTMLLoader, - loop //load order can matter depending on expected proxies etc like in this case - } -}); - diff --git a/examples/loaders/basic/package.json b/examples/loaders/basic/package.json deleted file mode 100644 index 0f4a02f7..00000000 --- a/examples/loaders/basic/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "tinybuildapp503", - "version": "0.0.0", - "description": "Barebones esbuild and test node server implementation. For building", - "main": "index.js", - "type": "module", - "scripts": { - "start": "tinybuild", - "build": "tinybuild build", - "serve": "tinybuild serve", - "init": "node tinybuild/init.js", - "concurrent": "concurrently \\'npm run python\\' \\'npm start\\'", - "dev": "npm run pip && npm i --save-dev concurrently && npm i --save-dev nodemon && npm run concurrent", - "startdev": "nodemon --exec \\'node tinybuild.js\\' -e ejs,js,ts,jsx,tsx,css,html,jpg,png,scss,txt,csv", - "python": "python python/server.py", - "pip": "pip install quart && pip install websockets", - "pwa": "npm i workbox-cli && workbox generateSW node_server/pwa/workbox-config.js && npm run build && npm start" - }, - "keywords": [ - "esbuild" - ], - "author": "", - "license": "LGPL-3.0-or-later", - "dependencies": {}, - "devDependencies": {}, - "nodemonConfig": { - "env": { - "NODEMON": true - }, - "ignore": [ - "dist/", - ".temp/" - ] - } -} \ No newline at end of file diff --git a/examples/loaders/basic/tinybuild.config.js b/examples/loaders/basic/tinybuild.config.js deleted file mode 100644 index 22f73fa6..00000000 --- a/examples/loaders/basic/tinybuild.config.js +++ /dev/null @@ -1,36 +0,0 @@ -const config = { - bundler: { //esbuild settings, set false to skip build step or add bundle:true to config object to only bundle (alt methods) - entryPoints: [ //entry point file(s). These can include .js, .mjs, .ts, .jsx, .tsx, or other javascript files. Make sure your entry point is a ts file if you want to generate types - "index.js" - ], - outfile: "dist/index", //exit point file, will append .js as well as indicators like .esm.js, .node.js for other build flags - //outdir:[] //exit point files, define for multiple bundle files - bundleBrowser: true, //create plain js build? Can include globals and init scripts - bundleESM: false, //create esm module js files - bundleTypes: false, //create .d.ts files, the entry point must be a typescript file! (ts, tsx, etc) - bundleNode: false, //create node platform plain js build, specify platform:'node' to do the rest of the files - bundleHTML: false, //wrap the first entry point file as a plain js script in a boilerplate html file, frontend scripts can be run standalone like a .exe! Server serves this as start page if set to true. - minify: true, - sourcemap: false - //globalThis:null //'mymodule' - //globals:{'index.js':['Graph']} - //init:{'index.js':function(bundle) { console.log('prepackaged bundle script!', bundle); }.toString(); } //pass stringified functions in to init bundle scripts in a custom way (e.g. for quick rebundling) - }, - server: { //node server settings, set false to skip server step or add serve:true to config object to only serve (alt methods) - debug: false, - protocol: "http", //'http' or 'https'. HTTPS required for Nodejs <---> Python sockets. If using http, set production to False in python/server.py as well - host: "localhost", //'localhost' or '127.0.0.1' etc. - port: 8080, //e.g. port 80, 443, 8000 - startpage: "index.html", //home page - socket_protocol: "ws", //frontend socket protocol, wss for served, ws for localhost - hotreload: 5000, //hotreload websocket server port - //watch: ['../'], //watch additional directories other than the current working directory - pwa: "dist/service-worker.js", //pwa mode? Injects service worker registry code in (see pwa README.md) - python: false,//7000, //quart server port (configured via the python server script file still) - python_node: 7001, //websocket relay port (relays messages to client from nodejs that were sent to it by python) - errpage: "node_modules/tinybuild/tinybuild/node_server/other/404.html", //default error page, etc. - certpath: "node_modules/tinybuild/tinybuild/node_server/ssl/cert.pem", //if using https, this is required. See cert.pfx.md for instructions - keypath: "node_modules/tinybuild/tinybuild/node_server/ssl/key.pem" //if using https, this is required. See cert.pfx.md for instructions - } -} -export default config; //module.exports = config; //es5 \ No newline at end of file diff --git a/examples/loaders/html/index.html b/examples/loaders/html/index.html deleted file mode 100644 index 49564abb..00000000 --- a/examples/loaders/html/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/loaders/html/index.ts b/examples/loaders/html/index.ts deleted file mode 100644 index c47c7984..00000000 --- a/examples/loaders/html/index.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { - Graph, - wchtmlloader, //includes a web component library for custom html elements - htmlloader, //basic html elements - HTMLNodeProperties -} from '../../../index' - -let component = { - __template:`
    Hello world!
    `, - __element:'web-component', - __onrender:function (elm){ - console.log('rendered!'); - (document.getElementById('wcdiv') as HTMLElement).onclick = (ev) => { - if((ev.target as HTMLElement).style.backgroundColor !== 'red') - setTimeout(()=>{(ev.target as HTMLElement).style.backgroundColor = '';},1000); - (ev.target as HTMLElement).style.backgroundColor = 'red'; - } - } -} as HTMLNodeProperties - -let roots = { - - mainbody:{ - __element:'div', - style:{backgroundColor:'green'}, - __children:{ - p:{ - __element:'p', - innerText:'Lorum ipsum', - onclick:(ev) => { - if(ev.target.style.backgroundColor !== 'red') - setTimeout(()=>{ev.target.style.backgroundColor = '';},1000); - ev.target.style.backgroundColor = 'red'; - } - } as HTMLNodeProperties, - btn:{ - __element:'button', - innerHTML:'Click Me!', - onclick:(ev) => { - if(ev.target.innerHTML !== 'Clicked!') - setTimeout(()=>{ev.target.innerHTML = 'Click Me!';},1000); - ev.target.innerHTML = 'Clicked!'; - } - } as HTMLNodeProperties, - component - } - } as HTMLNodeProperties -} - -let graph = new Graph({ - roots, - loaders:{ - //htmlloader - wchtmlloader - } -}) \ No newline at end of file diff --git a/examples/loaders/html/package-lock.json b/examples/loaders/html/package-lock.json deleted file mode 100644 index 8847d868..00000000 --- a/examples/loaders/html/package-lock.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "name": "tinybuildapp8682", - "version": "0.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "tinybuildapp8682", - "version": "0.0.0", - "license": "LGPL-3.0-or-later", - "dependencies": { - "web-worker": "^1.2.0" - }, - "devDependencies": {} - }, - "../../../../../AppData/Roaming/npm/node_modules/tinybuild": { - "version": "0.3.190", - "extraneous": true, - "license": "LGPL-3.0-or-later", - "dependencies": { - "chokidar": "~3.5.3", - "esbuild": "~0.14.49", - "ws": "^8.5.0" - }, - "bin": { - "tinybuild": "tinybuild/bin/global.js" - }, - "peerDependencies": { - "typescript": "~4.6.4" - } - }, - "node_modules/web-worker": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", - "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" - } - }, - "dependencies": { - "web-worker": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", - "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" - } - } -} diff --git a/examples/loaders/html/package.json b/examples/loaders/html/package.json deleted file mode 100644 index fcbc11a2..00000000 --- a/examples/loaders/html/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "tinybuildapp8682", - "version": "0.0.0", - "description": "Barebones esbuild and test node server implementation. For building", - "main": "index.js", - "type": "module", - "scripts": { - "start": "tinybuild", - "build": "tinybuild build", - "serve": "tinybuild serve", - "init": "node tinybuild/init.js", - "concurrent": "concurrently \\'npm run python\\' \\'npm start\\'", - "dev": "npm run pip && npm i --save-dev concurrently && npm i --save-dev nodemon && npm run concurrent", - "startdev": "nodemon --exec \\'node tinybuild.js\\' -e ejs,js,ts,jsx,tsx,css,html,jpg,png,scss,txt,csv", - "python": "python python/server.py", - "pip": "pip install quart && pip install websockets", - "pwa": "npm i workbox-cli && workbox generateSW node_server/pwa/workbox-config.js && npm run build && npm start" - }, - "keywords": [ - "esbuild" - ], - "author": "", - "license": "LGPL-3.0-or-later", - "dependencies": { - "web-worker": "^1.2.0" - }, - "nodemonConfig": { - "env": { - "NODEMON": true - }, - "ignore": [ - "dist/", - ".temp/" - ] - } -} diff --git a/examples/loaders/html/tinybuild.config.js b/examples/loaders/html/tinybuild.config.js deleted file mode 100644 index 749308ef..00000000 --- a/examples/loaders/html/tinybuild.config.js +++ /dev/null @@ -1,36 +0,0 @@ -const config = { - bundler: { //esbuild settings, set false to skip build step or add bundle:true to config object to only bundle (alt methods) - entryPoints: [ //entry point file(s). These can include .js, .mjs, .ts, .jsx, .tsx, or other javascript files. Make sure your entry point is a ts file if you want to generate types - "index.ts" - ], - outfile: "dist/index", //exit point file, will append .js as well as indicators like .esm.js, .node.js for other build flags - //outdir:[] //exit point files, define for multiple bundle files - bundleBrowser: true, //create plain js build? Can include globals and init scripts - bundleESM: false, //create esm module js files - bundleTypes: false, //create .d.ts files, the entry point must be a typescript file! (ts, tsx, etc) - bundleNode: false, //create node platform plain js build, specify platform:'node' to do the rest of the files - bundleHTML: false, //wrap the first entry point file as a plain js script in a boilerplate html file, frontend scripts can be run standalone like a .exe! Server serves this as start page if set to true. - minify: true, - sourcemap: false - //globalThis:null //'mymodule' - //globals:{'index.js':['Graph']} - //init:{'index.js':function(bundle) { console.log('prepackaged bundle script!', bundle); }.toString(); } //pass stringified functions in to init bundle scripts in a custom way (e.g. for quick rebundling) - }, - server: { //node server settings, set false to skip server step or add serve:true to config object to only serve (alt methods) - debug: false, - protocol: "http", //'http' or 'https'. HTTPS required for Nodejs <---> Python sockets. If using http, set production to False in python/server.py as well - host: "localhost", //'localhost' or '127.0.0.1' etc. - port: 8080, //e.g. port 80, 443, 8000 - startpage: "index.html", //home page - socket_protocol: "ws", //frontend socket protocol, wss for served, ws for localhost - hotreload: 5000, //hotreload websocket server port - //watch: ['../'], //watch additional directories other than the current working directory - pwa: "dist/service-worker.js", //pwa mode? Injects service worker registry code in (see pwa README.md) - python: false,//7000, //quart server port (configured via the python server script file still) - python_node: 7001, //websocket relay port (relays messages to client from nodejs that were sent to it by python) - errpage: "node_modules/tinybuild/tinybuild/node_server/other/404.html", //default error page, etc. - certpath: "node_modules/tinybuild/tinybuild/node_server/ssl/cert.pem", //if using https, this is required. See cert.pfx.md for instructions - keypath: "node_modules/tinybuild/tinybuild/node_server/ssl/key.pem" //if using https, this is required. See cert.pfx.md for instructions - } -} -export default config; //module.exports = config; //es5 \ No newline at end of file diff --git a/examples/loaders/web_components/components/draggable.js b/examples/loaders/web_components/components/draggable.js deleted file mode 100644 index e7031a78..00000000 --- a/examples/loaders/web_components/components/draggable.js +++ /dev/null @@ -1,43 +0,0 @@ -//https://www.w3schools.com/howto/howto_js_draggable.asp -// Make the DIV element draggable: - -export function makeDraggable(elmnt) { - var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; - if (document.getElementById(elmnt.id + "header")) { - // if present, the header is where you move the DIV from: - document.getElementById(elmnt.id + "header").onmousedown = dragMouseDown; - } else { - // otherwise, move the DIV from anywhere inside the DIV: - elmnt.onmousedown = dragMouseDown; - } - - function dragMouseDown(e) { - e = e || window.event; - e.preventDefault(); - // get the mouse cursor position at startup: - pos3 = e.clientX; - pos4 = e.clientY; - document.onmouseup = closeDragElement; - // call a function whenever the cursor moves: - document.onmousemove = elementDrag; - } - - function elementDrag(e) { - e = e || window.event; - e.preventDefault(); - // calculate the new cursor position: - pos1 = pos3 - e.clientX; - pos2 = pos4 - e.clientY; - pos3 = e.clientX; - pos4 = e.clientY; - // set the element's new position: - elmnt.style.top = (elmnt.offsetTop - pos2) + "px"; - elmnt.style.left = (elmnt.offsetLeft - pos1) + "px"; - } - - function closeDragElement() { - // stop moving when mouse button is released: - document.onmouseup = null; - document.onmousemove = null; - } -} \ No newline at end of file diff --git a/examples/loaders/web_components/components/node/node.css b/examples/loaders/web_components/components/node/node.css deleted file mode 100644 index 3029b896..00000000 --- a/examples/loaders/web_components/components/node/node.css +++ /dev/null @@ -1,4 +0,0 @@ -.nodeheader { /* component css tags should probably be sufficiently unique like other component libraries, or just use inline styles */ - text-align:center; - width: max-content; -} \ No newline at end of file diff --git a/examples/loaders/web_components/components/node/node.ts b/examples/loaders/web_components/components/node/node.ts deleted file mode 100644 index 12214269..00000000 --- a/examples/loaders/web_components/components/node/node.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { makeDraggable } from "../draggable"; -import { PointHTML } from "../point/point"; - -//@ts-ignore -import style from './node.css'; //in esbuild, set loader:{'.css':'text' } -//@ts-ignore -import html from './node.html'; //add to loader: {...'.html':'text'} - -export class NodeHTML { - - tagName = 'graph-node'; - - __template = '' // = html; - __css = style; - __components = { - 'custom-point-name': PointHTML - } - - draggable=true; - - style = { - position:'absolute', - padding:'10px', - display:'flex', - borderRadius:'10%', - backgroundColor:'lightblue', - cursor:'pointer' - }; - - __onrender = function() { - this.insertAdjacentHTML('beforeend', ` -
    -
    Drag ${this.__node.tag ?? 'Me'}!
    -
    -
    - - - - - - -
    -
    - `) - } - - __onconnected = function() { - makeDraggable(this); //the htmlElement properties are bound to 'this' as well as 'this.__props' so you can manipulate the node directly - }; - - // __children={ - // container:{ - // __element:'div', - // __children:{ - // header:{ - // __element:'div', - // innerHTML:'Drag Me!', - // className:'nodeheader' - // }, - // ln:{__template:'
    '}, - // body:{ - // __element:'div', - // style:{ - // display:'flex' - // }, - // __children:{ - // inputs:{ - // __element:'span', - // style:{ - // width:'12.5%' - // } - // }, - // content:{ - // __element:'span', - // style:{ - // width:'75%' - // } - // }, - // outputs:{ - // __element:'span', - // style:{ - // width:'12.5%' - // }, - // __children:{ - // point:PointHTML, - // point2:PointHTML - // } - // } - // } - // } - // } - // } - // }; - -} \ No newline at end of file diff --git a/examples/loaders/web_components/components/point/point.css b/examples/loaders/web_components/components/point/point.css deleted file mode 100644 index e06d2a6c..00000000 --- a/examples/loaders/web_components/components/point/point.css +++ /dev/null @@ -1,10 +0,0 @@ -.point { - width: 1px; - height: 1px; - border: 10px solid transparent; - border-left-color: greenyellow; - position: relative; -} -.point:hover { - border-left-color: yellow; -} diff --git a/examples/loaders/web_components/components/point/point.html b/examples/loaders/web_components/components/point/point.html deleted file mode 100644 index ad99828e..00000000 --- a/examples/loaders/web_components/components/point/point.html +++ /dev/null @@ -1,2 +0,0 @@ -
    -
    \ No newline at end of file diff --git a/examples/loaders/web_components/components/point/point.ts b/examples/loaders/web_components/components/point/point.ts deleted file mode 100644 index 88a3f6c0..00000000 --- a/examples/loaders/web_components/components/point/point.ts +++ /dev/null @@ -1,18 +0,0 @@ - -//@ts-ignore -import style from './point.css'; //in esbuild, set loader:{'.css':'text' } -//@ts-ignore -import html from './point.html'; //add to loader: {...'.html':'text'} - -export class PointHTML { - - tagName='interactive-point'; - - __template = html; - __css = style; - - __onconnected = function() { - //console.log(this); - }; - -} \ No newline at end of file diff --git a/examples/loaders/web_components/index.html b/examples/loaders/web_components/index.html deleted file mode 100644 index 49564abb..00000000 --- a/examples/loaders/web_components/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/loaders/web_components/index.ts b/examples/loaders/web_components/index.ts deleted file mode 100644 index 55cf875b..00000000 --- a/examples/loaders/web_components/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {Graph, GraphNode, wchtmlloader} from '../../../index' -import { NodeHTML } from './components/node/node'; - -new Graph({ - roots:{ - draggable: NodeHTML, - other: NodeHTML - }, - loaders:{ - wchtmlloader - } -}); \ No newline at end of file diff --git a/examples/loaders/web_components/package-lock.json b/examples/loaders/web_components/package-lock.json deleted file mode 100644 index 89434d34..00000000 --- a/examples/loaders/web_components/package-lock.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "name": "tinybuildapp5363", - "version": "0.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "tinybuildapp5363", - "version": "0.0.0", - "license": "LGPL-3.0-or-later", - "dependencies": { - "graphscript": "^0.2.80" - }, - "devDependencies": {} - }, - "../../../AppData/Roaming/npm/node_modules/tinybuild": { - "version": "0.3.202", - "extraneous": true, - "license": "LGPL-3.0-or-later", - "dependencies": { - "chokidar": "~3.5.3", - "esbuild": "~0.17.10", - "ws": "^8.5.0" - }, - "bin": { - "tinybuild": "tinybuild/bin/global.js" - }, - "peerDependencies": { - "typescript": "~4.9.5" - } - }, - "node_modules/better-sse": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/better-sse/-/better-sse-0.8.0.tgz", - "integrity": "sha512-ymOse8R0L+R2S1W85yOGkkc+yTzAmo52S4erjxPyBVwpqjpS+X228BG7hDwgKsGV/D51YhCYd+eaDwJ+sL5JhA==", - "engines": { - "node": ">=12", - "pnpm": ">=6" - } - }, - "node_modules/brainsatplay-math": { - "version": "0.0.25", - "resolved": "https://registry.npmjs.org/brainsatplay-math/-/brainsatplay-math-0.0.25.tgz", - "integrity": "sha512-J2s+/4osnjVVqqKVwuCuYbr9eGhXF4eFsGq/ImPIHICx0+1hJHoUN1XVCyiC8rOM7Nf0/8mmtVknzEeayVc7sQ==" - }, - "node_modules/bson-objectid": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/bson-objectid/-/bson-objectid-2.0.4.tgz", - "integrity": "sha512-vgnKAUzcDoa+AeyYwXCoHyF2q6u/8H46dxu5JN+4/TZeq/Dlinn0K6GvxsCLb3LHUJl0m/TLiEK31kUwtgocMQ==" - }, - "node_modules/graphscript": { - "version": "0.2.80", - "resolved": "https://registry.npmjs.org/graphscript/-/graphscript-0.2.80.tgz", - "integrity": "sha512-TU6LLYPqpS5acZqu3+wrkwp+IWZixloVhG/UNFFbxW8OcdLFeW7rpYesmemb307UVKqkCeod9iOwgz5Cgfsl0w==", - "dependencies": { - "better-sse": "^0.8.0", - "brainsatplay-math": "~0.1.0", - "bson-objectid": "~2.0.3", - "web-worker": "~1.2.0", - "ws": "~8.11.0" - } - }, - "node_modules/web-worker": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", - "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" - }, - "node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - } - }, - "dependencies": { - "better-sse": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/better-sse/-/better-sse-0.8.0.tgz", - "integrity": "sha512-ymOse8R0L+R2S1W85yOGkkc+yTzAmo52S4erjxPyBVwpqjpS+X228BG7hDwgKsGV/D51YhCYd+eaDwJ+sL5JhA==" - }, - "brainsatplay-math": { - "version": "0.0.25", - "resolved": "https://registry.npmjs.org/brainsatplay-math/-/brainsatplay-math-0.0.25.tgz", - "integrity": "sha512-J2s+/4osnjVVqqKVwuCuYbr9eGhXF4eFsGq/ImPIHICx0+1hJHoUN1XVCyiC8rOM7Nf0/8mmtVknzEeayVc7sQ==" - }, - "bson-objectid": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/bson-objectid/-/bson-objectid-2.0.4.tgz", - "integrity": "sha512-vgnKAUzcDoa+AeyYwXCoHyF2q6u/8H46dxu5JN+4/TZeq/Dlinn0K6GvxsCLb3LHUJl0m/TLiEK31kUwtgocMQ==" - }, - "graphscript": { - "version": "0.2.80", - "resolved": "https://registry.npmjs.org/graphscript/-/graphscript-0.2.80.tgz", - "integrity": "sha512-TU6LLYPqpS5acZqu3+wrkwp+IWZixloVhG/UNFFbxW8OcdLFeW7rpYesmemb307UVKqkCeod9iOwgz5Cgfsl0w==", - "requires": { - "better-sse": "^0.8.0", - "brainsatplay-math": "~0.1.0", - "bson-objectid": "~2.0.3", - "web-worker": "~1.2.0", - "ws": "~8.11.0" - } - }, - "web-worker": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", - "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" - }, - "ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", - "requires": {} - } - } -} diff --git a/examples/loaders/web_components/package.json b/examples/loaders/web_components/package.json deleted file mode 100644 index ab88c2bf..00000000 --- a/examples/loaders/web_components/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "tinybuildapp5363", - "version": "0.0.0", - "description": "Barebones esbuild and test node server implementation. For building", - "main": "index.js", - "type": "module", - "scripts": { - "start": "tinybuild", - "build": "tinybuild build", - "serve": "tinybuild serve", - "init": "node tinybuild/init.js", - "concurrent": "concurrently \\'npm run python\\' \\'npm start\\'", - "dev": "npm run pip && npm i --save-dev concurrently && npm i --save-dev nodemon && npm run concurrent", - "startdev": "nodemon --exec \\'node tinybuild.js\\' -e ejs,js,ts,jsx,tsx,css,html,jpg,png,scss,txt,csv", - "python": "python python/server.py", - "pip": "pip install quart && pip install websockets", - "pwa": "npm i workbox-cli && workbox generateSW node_server/pwa/workbox-config.js && npm run build && npm start" - }, - "keywords": [ - "esbuild" - ], - "author": "", - "license": "LGPL-3.0-or-later", - "dependencies": { - "graphscript": "^0.2.80" - }, - "nodemonConfig": { - "env": { - "NODEMON": true - }, - "ignore": [ - "dist/", - ".temp/" - ] - } -} diff --git a/examples/loaders/web_components/tinybuild.config.js b/examples/loaders/web_components/tinybuild.config.js deleted file mode 100644 index f162fe94..00000000 --- a/examples/loaders/web_components/tinybuild.config.js +++ /dev/null @@ -1,37 +0,0 @@ -const config = { - bundler: { //esbuild settings, set false to skip build step or add bundle:true to config object to only bundle (alt methods) - entryPoints: [ //entry point file(s). These can include .js, .mjs, .ts, .jsx, .tsx, or other javascript files. Make sure your entry point is a ts file if you want to generate types - "index.ts" - ], - outfile: "dist/index", //exit point file, will append .js as well as indicators like .esm.js, .node.js for other build flags - //outdir:[] //exit point files, define for multiple bundle files - bundleBrowser: true, //create plain js build? Can include globals and init scripts - bundleESM: false, //create esm module js files - bundleTypes: false, //create .d.ts files, the entry point must be a typescript file! (ts, tsx, etc) - bundleNode: false, //create node platform plain js build, specify platform:'node' to do the rest of the files - bundleHTML: false, //wrap the first entry point file as a plain js script in a boilerplate html file, frontend scripts can be run standalone like a .exe! Server serves this as start page if set to true. - minify: true, - sourcemap: false, - loader:{'.html':'text', '.css':'text' } - //globalThis:null //'mymodule' - //globals:{'index.js':['Graph']} - //init:{'index.js':function(bundle) { console.log('prepackaged bundle script!', bundle); }.toString(); } //pass stringified functions in to init bundle scripts in a custom way (e.g. for quick rebundling) - }, - server: { //node server settings, set false to skip server step or add serve:true to config object to only serve (alt methods) - debug: false, - protocol: "http", //'http' or 'https'. HTTPS required for Nodejs <---> Python sockets. If using http, set production to False in python/server.py as well - host: "localhost", //'localhost' or '127.0.0.1' etc. - port: 8080, //e.g. port 80, 443, 8000 - startpage: "index.html", //home page - socket_protocol: "ws", //frontend socket protocol, wss for served, ws for localhost - hotreload: 5000, //hotreload websocket server port - //watch: ['../'], //watch additional directories other than the current working directory - pwa: "dist/service-worker.js", //pwa mode? Injects service worker registry code in (see pwa README.md) - python: false,//7000, //quart server port (configured via the python server script file still) - python_node: 7001, //websocket relay port (relays messages to client from nodejs that were sent to it by python) - errpage: "node_modules/tinybuild/tinybuild/node_server/other/404.html", //default error page, etc. - certpath: "node_modules/tinybuild/tinybuild/node_server/ssl/cert.pem", //if using https, this is required. See cert.pfx.md for instructions - keypath: "node_modules/tinybuild/tinybuild/node_server/ssl/key.pem" //if using https, this is required. See cert.pfx.md for instructions - } -} -export default config; //module.exports = config; //es5 \ No newline at end of file diff --git a/examples/services/workers/pipelining/index.html b/examples/services/workers/pipelining/index.html deleted file mode 100644 index 49564abb..00000000 --- a/examples/services/workers/pipelining/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/services/workers/pipelining/index.ts b/examples/services/workers/pipelining/index.ts deleted file mode 100644 index cc006d41..00000000 --- a/examples/services/workers/pipelining/index.ts +++ /dev/null @@ -1,113 +0,0 @@ - -import { WorkerInfo, WorkerService, remoteGraphRoutes } from '../../../../index'; - -import worker from './worker' - -//main thread - - -const graph = new WorkerService({ - //props:{} //could set the props instead of globalThis but it really does not matter unless you want to bake in for more complex service modules - roots:{ - ...remoteGraphRoutes, - } -}); - -console.log('Worker Service', graph); - - -const worker1 = graph.addWorker({url:worker}) as WorkerInfo; -const worker2 = graph.addWorker({url:worker}) as WorkerInfo; -const worker3 = graph.addWorker({url:worker}) as WorkerInfo; - -//simulate long tasks -function taskA(input) { // SCOPE REFACTOR: Might actually need to pass self and origin... - return new Promise((res,rej) => { - setTimeout(() => { - console.log(input,42); - res(42); - }, 3000) //long task - }); -}; - -function taskB(input) { // SCOPE REFACTOR: Might actually need to pass self and origin... - return new Promise((res,rej) => { - setTimeout(() => { - console.log(input,42); - res(42); - }, 1000) //long task - }); -}; - -function taskC(input) { // SCOPE REFACTOR: Might actually need to pass self and origin... - return new Promise((res,rej) => { - setTimeout(() => { - console.log(input,42); - res(42); - }, 1500) //long task - }); -}; - -function subTaskA(input:number) { - console.log('multiplying',input,'by 10'); - return input * 10; -} - -function subTaskB(input:number) { - console.log('applying log to',input); - return Math.log(input); -} - -graph.run('transferFunction', - taskA, - worker1, - 'task' //in case of minification really -); - -graph.run('transferFunction', - taskB, - worker2, - 'task' -); - -graph.run('transferFunction', - taskC, - worker3, - 'task' -); - - -//now for a message channel pipeline. -graph.run('transferFunction', - subTaskA, - worker1, - 'subTaskA' -).then(console.log); - -graph.run('transferFunction', - subTaskB, - worker2, - 'subTaskB' -).then(console.log); - -let portId = graph.establishMessageChannel(worker1, worker2); - -//subscribe worker 2 to worker 1 directly (no overhead on main thread) -worker2.post('subscribeToWorker',[ - 'subTaskA', - portId, - 'subTaskB' -]); - -//now subscribe to the output on the main thread (or it could be a rendering thread etc., mind the rules of using threads!) -worker2.subscribe('subTaskB',(res) => { - console.log('result from worker2', res); -}).then(() => { - worker1.run('subTaskA', 42); //makes sure this runs after worker\2 is ready -}); - - - -worker1.run('task','What is the meaning of life?'); -worker2.run('task','What is the meaning of life?'); -worker3.run('task','What is the meaning of life?'); diff --git a/examples/services/workers/pipelining/package-lock.json b/examples/services/workers/pipelining/package-lock.json deleted file mode 100644 index 1e72f344..00000000 --- a/examples/services/workers/pipelining/package-lock.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "tinybuildapp9800", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "tinybuildapp9800", - "version": "0.0.0", - "license": "LGPL-3.0-or-later", - "dependencies": { - "web-worker": "^1.2.0" - }, - "devDependencies": {} - }, - "../../../../../../../AppData/Roaming/npm/node_modules/tinybuild": { - "version": "0.3.205", - "extraneous": true, - "license": "LGPL-3.0-or-later", - "dependencies": { - "chokidar": "~3.5.3", - "esbuild": "~0.17.10", - "ws": "^8.5.0" - }, - "bin": { - "tinybuild": "tinybuild/bin/global.js" - }, - "peerDependencies": { - "typescript": "~4.9.5" - } - }, - "node_modules/web-worker": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", - "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" - } - } -} diff --git a/examples/services/workers/pipelining/tinybuild.config.js b/examples/services/workers/pipelining/tinybuild.config.js deleted file mode 100644 index 749308ef..00000000 --- a/examples/services/workers/pipelining/tinybuild.config.js +++ /dev/null @@ -1,36 +0,0 @@ -const config = { - bundler: { //esbuild settings, set false to skip build step or add bundle:true to config object to only bundle (alt methods) - entryPoints: [ //entry point file(s). These can include .js, .mjs, .ts, .jsx, .tsx, or other javascript files. Make sure your entry point is a ts file if you want to generate types - "index.ts" - ], - outfile: "dist/index", //exit point file, will append .js as well as indicators like .esm.js, .node.js for other build flags - //outdir:[] //exit point files, define for multiple bundle files - bundleBrowser: true, //create plain js build? Can include globals and init scripts - bundleESM: false, //create esm module js files - bundleTypes: false, //create .d.ts files, the entry point must be a typescript file! (ts, tsx, etc) - bundleNode: false, //create node platform plain js build, specify platform:'node' to do the rest of the files - bundleHTML: false, //wrap the first entry point file as a plain js script in a boilerplate html file, frontend scripts can be run standalone like a .exe! Server serves this as start page if set to true. - minify: true, - sourcemap: false - //globalThis:null //'mymodule' - //globals:{'index.js':['Graph']} - //init:{'index.js':function(bundle) { console.log('prepackaged bundle script!', bundle); }.toString(); } //pass stringified functions in to init bundle scripts in a custom way (e.g. for quick rebundling) - }, - server: { //node server settings, set false to skip server step or add serve:true to config object to only serve (alt methods) - debug: false, - protocol: "http", //'http' or 'https'. HTTPS required for Nodejs <---> Python sockets. If using http, set production to False in python/server.py as well - host: "localhost", //'localhost' or '127.0.0.1' etc. - port: 8080, //e.g. port 80, 443, 8000 - startpage: "index.html", //home page - socket_protocol: "ws", //frontend socket protocol, wss for served, ws for localhost - hotreload: 5000, //hotreload websocket server port - //watch: ['../'], //watch additional directories other than the current working directory - pwa: "dist/service-worker.js", //pwa mode? Injects service worker registry code in (see pwa README.md) - python: false,//7000, //quart server port (configured via the python server script file still) - python_node: 7001, //websocket relay port (relays messages to client from nodejs that were sent to it by python) - errpage: "node_modules/tinybuild/tinybuild/node_server/other/404.html", //default error page, etc. - certpath: "node_modules/tinybuild/tinybuild/node_server/ssl/cert.pem", //if using https, this is required. See cert.pfx.md for instructions - keypath: "node_modules/tinybuild/tinybuild/node_server/ssl/key.pem" //if using https, this is required. See cert.pfx.md for instructions - } -} -export default config; //module.exports = config; //es5 \ No newline at end of file diff --git a/examples/services/workers/pipelining/worker.ts b/examples/services/workers/pipelining/worker.ts deleted file mode 100644 index 64639d93..00000000 --- a/examples/services/workers/pipelining/worker.ts +++ /dev/null @@ -1,21 +0,0 @@ - -import { WorkerService, remoteGraphRoutes } from '../../../../index'; - -//worker threads - -declare var WorkerGlobalScope; - -if(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) { - - const worker = new WorkerService({ - //props:{} //could set the props instead of globalThis but it really does not matter unless you want to bake in for more complex service modules - roots:{ - ...remoteGraphRoutes, - } - }); - - console.log('worker', worker) - -} - -export default self as any; diff --git a/examples/services/workers/workerECS/index.html b/examples/services/workers/workerECS/index.html deleted file mode 100644 index 49564abb..00000000 --- a/examples/services/workers/workerECS/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/services/workers/workerECS/package-lock.json b/examples/services/workers/workerECS/package-lock.json deleted file mode 100644 index a4479335..00000000 --- a/examples/services/workers/workerECS/package-lock.json +++ /dev/null @@ -1,150 +0,0 @@ -{ - "name": "tinybuildapp261", - "version": "0.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "tinybuildapp261", - "version": "0.0.0", - "license": "LGPL-3.0-or-later", - "dependencies": { - "graphscript": "~0.1.47", - "three": "^0.143.0", - "webgl-plot-utils": "^0.3.13" - } - }, - "node_modules/better-sse": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/better-sse/-/better-sse-0.8.0.tgz", - "integrity": "sha512-ymOse8R0L+R2S1W85yOGkkc+yTzAmo52S4erjxPyBVwpqjpS+X228BG7hDwgKsGV/D51YhCYd+eaDwJ+sL5JhA==", - "engines": { - "node": ">=12", - "pnpm": ">=6" - } - }, - "node_modules/brainsatplay-math": { - "version": "0.0.25", - "resolved": "https://registry.npmjs.org/brainsatplay-math/-/brainsatplay-math-0.0.25.tgz", - "integrity": "sha512-J2s+/4osnjVVqqKVwuCuYbr9eGhXF4eFsGq/ImPIHICx0+1hJHoUN1XVCyiC8rOM7Nf0/8mmtVknzEeayVc7sQ==" - }, - "node_modules/bson-objectid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/bson-objectid/-/bson-objectid-2.0.3.tgz", - "integrity": "sha512-WYwVtY9yqk179EPMNuF3vcxufdrGLEo2XwqdRVbfLVe9X6jLt7WKZQgP+ObOcprakBGbHxzl76tgTaieqsH29g==" - }, - "node_modules/graphscript": { - "version": "0.1.49", - "resolved": "https://registry.npmjs.org/graphscript/-/graphscript-0.1.49.tgz", - "integrity": "sha512-X9l63+mitFW0pxLF43jDZjxxkwE6a1SUGZJRGE4nmGoU9r599ilfQmXluBPPKuoK1B+ODcUrGi6eleAbA7C9Ow==", - "dependencies": { - "better-sse": "~0.8.0", - "brainsatplay-math": "~0.1.0", - "bson-objectid": "~2.0.3", - "web-worker": "~1.2.0", - "ws": "~8.9.0" - } - }, - "node_modules/three": { - "version": "0.143.0", - "resolved": "https://registry.npmjs.org/three/-/three-0.143.0.tgz", - "integrity": "sha512-oKcAGYHhJ46TGEuHjodo2n6TY2R6lbvrkp+feKZxqsUL/WkH7GKKaeu6RHeyb2Xjfk2dPLRKLsOP0KM2VgT8Zg==" - }, - "node_modules/web-worker": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", - "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" - }, - "node_modules/webgl-plot": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/webgl-plot/-/webgl-plot-0.7.0.tgz", - "integrity": "sha512-/prs3XMFKlXcov3qvx3LxqMws0Dg68kmmHmO82Qm6FFGpeKME7c3nuVqSe9CG47BvG9mGVPxDMjRc0DP/jTc2A==" - }, - "node_modules/webgl-plot-utils": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/webgl-plot-utils/-/webgl-plot-utils-0.3.13.tgz", - "integrity": "sha512-uXUK4kmau2HZYrZ3gGy3olKnmYAXNAMfEIzuzD28pxQrmerxZPm73scyxeTph65l06W9gJwAB4OTDWrD5n4MWg==", - "dependencies": { - "webgl-plot": "~0.7.0" - } - }, - "node_modules/ws": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz", - "integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - } - }, - "dependencies": { - "better-sse": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/better-sse/-/better-sse-0.8.0.tgz", - "integrity": "sha512-ymOse8R0L+R2S1W85yOGkkc+yTzAmo52S4erjxPyBVwpqjpS+X228BG7hDwgKsGV/D51YhCYd+eaDwJ+sL5JhA==" - }, - "brainsatplay-math": { - "version": "0.0.25", - "resolved": "https://registry.npmjs.org/brainsatplay-math/-/brainsatplay-math-0.0.25.tgz", - "integrity": "sha512-J2s+/4osnjVVqqKVwuCuYbr9eGhXF4eFsGq/ImPIHICx0+1hJHoUN1XVCyiC8rOM7Nf0/8mmtVknzEeayVc7sQ==" - }, - "bson-objectid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/bson-objectid/-/bson-objectid-2.0.3.tgz", - "integrity": "sha512-WYwVtY9yqk179EPMNuF3vcxufdrGLEo2XwqdRVbfLVe9X6jLt7WKZQgP+ObOcprakBGbHxzl76tgTaieqsH29g==" - }, - "graphscript": { - "version": "0.1.49", - "resolved": "https://registry.npmjs.org/graphscript/-/graphscript-0.1.49.tgz", - "integrity": "sha512-X9l63+mitFW0pxLF43jDZjxxkwE6a1SUGZJRGE4nmGoU9r599ilfQmXluBPPKuoK1B+ODcUrGi6eleAbA7C9Ow==", - "requires": { - "better-sse": "~0.8.0", - "brainsatplay-math": "~0.1.0", - "bson-objectid": "~2.0.3", - "web-worker": "~1.2.0", - "ws": "~8.9.0" - } - }, - "three": { - "version": "0.143.0", - "resolved": "https://registry.npmjs.org/three/-/three-0.143.0.tgz", - "integrity": "sha512-oKcAGYHhJ46TGEuHjodo2n6TY2R6lbvrkp+feKZxqsUL/WkH7GKKaeu6RHeyb2Xjfk2dPLRKLsOP0KM2VgT8Zg==" - }, - "web-worker": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", - "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" - }, - "webgl-plot": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/webgl-plot/-/webgl-plot-0.7.0.tgz", - "integrity": "sha512-/prs3XMFKlXcov3qvx3LxqMws0Dg68kmmHmO82Qm6FFGpeKME7c3nuVqSe9CG47BvG9mGVPxDMjRc0DP/jTc2A==" - }, - "webgl-plot-utils": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/webgl-plot-utils/-/webgl-plot-utils-0.3.13.tgz", - "integrity": "sha512-uXUK4kmau2HZYrZ3gGy3olKnmYAXNAMfEIzuzD28pxQrmerxZPm73scyxeTph65l06W9gJwAB4OTDWrD5n4MWg==", - "requires": { - "webgl-plot": "~0.7.0" - } - }, - "ws": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz", - "integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==", - "requires": {} - } - } -} diff --git a/examples/services/workers/workerECS/package.json b/examples/services/workers/workerECS/package.json deleted file mode 100644 index 2de0265a..00000000 --- a/examples/services/workers/workerECS/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "graphscript-workerecs-example", - "version": "0.0.0", - "description": "Barebones esbuild and test node server implementation. For building", - "main": "index.js", - "type": "module", - "scripts": { - "start": "tinybuild", - "build": "tinybuild build", - "serve": "tinybuild serve", - "init": "node tinybuild/init.js", - "concurrent": "concurrently \\'npm run python\\' \\'npm start\\'", - "dev": "npm run pip && npm i --save-dev concurrently && npm i --save-dev nodemon && npm run concurrent", - "startdev": "nodemon --exec \\'node tinybuild.js\\' -e ejs,js,ts,jsx,tsx,css,html,jpg,png,scss,txt,csv", - "python": "python python/server.py", - "pip": "pip install quart && pip install websockets", - "pwa": "npm i workbox-cli && workbox generateSW node_server/pwa/workbox-config.js && npm run build && npm start" - }, - "keywords": [ - "esbuild" - ], - "author": "", - "license": "LGPL-3.0-or-later", - "dependencies": { - "graphscript": "~0.1.47", - "three": "^0.143.0", - "webgl-plot-utils": "^0.3.13" - }, - "nodemonConfig": { - "env": { - "NODEMON": true - }, - "ignore": [ - "dist/", - ".temp/" - ] - } -} diff --git a/examples/services/workers/workerECS/tinybuild.config.js b/examples/services/workers/workerECS/tinybuild.config.js deleted file mode 100644 index 0342d1fb..00000000 --- a/examples/services/workers/workerECS/tinybuild.config.js +++ /dev/null @@ -1,36 +0,0 @@ -const config = { - bundler: { //esbuild settings, set false to skip build step or add bundle:true to config object to only bundle (alt methods) - entryPoints: [ //entry point file(s). These can include .js, .mjs, .ts, .jsx, .tsx, or other javascript files. Make sure your entry point is a ts file if you want to generate types - "ecs_test.ts" - ], - outfile: "dist/index", //exit point file, will append .js as well as indicators like .esm.js, .node.js for other build flags - //outdir:[] //exit point files, define for multiple bundle files - bundleBrowser: true, //create plain js build? Can include globals and init scripts - bundleESM: false, //create esm module js files - bundleTypes: false, //create .d.ts files, the entry point must be a typescript file! (ts, tsx, etc) - bundleNode: false, //create node platform plain js build, specify platform:'node' to do the rest of the files - bundleHTML: false, //wrap the first entry point file as a plain js script in a boilerplate html file, frontend scripts can be run standalone like a .exe! Server serves this as start page if set to true. - minify: false, - sourcemap: false - //globalThis:null //'mymodule' - //globals:{'index.js':['Graph']} - //init:{'index.js':function(bundle) { console.log('prepackaged bundle script!', bundle); }.toString(); } //pass stringified functions in to init bundle scripts in a custom way (e.g. for quick rebundling) - }, - server: { //node server settings, set false to skip server step or add serve:true to config object to only serve (alt methods) - debug: false, - protocol: "http", //'http' or 'https'. HTTPS required for Nodejs <---> Python sockets. If using http, set production to False in python/server.py as well - host: "localhost", //'localhost' or '127.0.0.1' etc. - port: 8080, //e.g. port 80, 443, 8000 - startpage: "index.html", //home page - socket_protocol: "ws", //frontend socket protocol, wss for served, ws for localhost - hotreload: 5000, //hotreload websocket server port - //watch: ['../'], //watch additional directories other than the current working directory - pwa: "dist/service-worker.js", //pwa mode? Injects service worker registry code in (see pwa README.md) - python: false,//7000, //quart server port (configured via the python server script file still) - python__node: 7001, //websocket relay port (relays messages to client from nodejs that were sent to it by python) - errpage: "node_modules/tinybuild/tinybuild/node_server/other/404.html", //default error page, etc. - certpath: "node_modules/tinybuild/tinybuild/node_server/ssl/cert.pem", //if using https, this is required. See cert.pfx.md for instructions - keypath: "node_modules/tinybuild/tinybuild/node_server/ssl/key.pem" //if using https, this is required. See cert.pfx.md for instructions - } -} -export default config; //module.exports = config; //es5 \ No newline at end of file diff --git a/examples/services/workers/workerECS/worker.ts b/examples/services/workers/workerECS/worker.ts deleted file mode 100644 index d60fb2f5..00000000 --- a/examples/services/workers/workerECS/worker.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { - WorkerService, - remoteGraphRoutes, - workerCanvasRoutes, - ECSService, - //GPUService -} from '../../../../index'/////"../../GraphServiceRouter/index";//from 'graphscript' - -import {Systems} from '../../../../src/extras/index.services' - -import { CanvasProps } from '../../../../src/services/worker/WorkerCanvas'; - -import * as THREE from 'three' -import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js' -import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js' -import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js' -import { SMAAPass } from 'three/examples/jsm/postprocessing/SMAAPass.js' -import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js' -import { PickHelper } from './PickHelper' - -declare var WorkerGlobalScope; - -if(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) { - const worker = new WorkerService({ - services:{ - //GPUService, - ECSService, - remoteGraphRoutes, //allows dynamic route loading - }, - roots:{ - ...workerCanvasRoutes, - ...remoteGraphRoutes, - receiveThreeCanvas:function(options:CanvasProps){ //modified canvas receiver that installs desired threejs modules - const ThreeProps = { //e.g. install these systems to 'self', which is the worker canvas - THREE, - OrbitControls, - EffectComposer, - RenderPass, - SMAAPass, - UnrealBloomPass, - PickHelper - } - - Object.assign(options, ThreeProps); //install desired props to our canvas's 'self' reference - - let renderId = this.__node.graph.run('setupCanvas', options); //the the base canvas tools do the rest, all ThreeJS tools are on self, for self contained ThreeJS renders - //you can use the canvas render loop by default, or don't provide a draw function and just use the init and the Three animate() callback - - //let canvasopts = this.graph.CANVASES[renderId] as WorkerCanvas; - - return renderId; - } - } - }); - - worker.run( - 'addSystems', - Systems, - ['boid','nbody','collision','collider','movement'] - ); //register desired entity component systems - - console.log(worker) -} - - - -export default self as any; \ No newline at end of file diff --git a/examples/services/workers/workercanvas/index.html b/examples/services/workers/workercanvas/index.html deleted file mode 100644 index 49564abb..00000000 --- a/examples/services/workers/workercanvas/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/services/workers/workercanvas/tinybuild.config.js b/examples/services/workers/workercanvas/tinybuild.config.js deleted file mode 100644 index 2632c80c..00000000 --- a/examples/services/workers/workercanvas/tinybuild.config.js +++ /dev/null @@ -1,36 +0,0 @@ -const config = { - bundler: { //esbuild settings, set false to skip build step or add bundle:true to config object to only bundle (alt methods) - entryPoints: [ //entry point file(s). These can include .js, .mjs, .ts, .jsx, .tsx, or other javascript files. Make sure your entry point is a ts file if you want to generate types - "index.ts" - ], - outfile: "dist/index", //exit point file, will append .js as well as indicators like .esm.js, .node.js for other build flags - //outdir:[] //exit point files, define for multiple bundle files - bundleBrowser: true, //create plain js build? Can include globals and init scripts - bundleESM: false, //create esm module js files - bundleTypes: false, //create .d.ts files, the entry point must be a typescript file! (ts, tsx, etc) - bundleNode: false, //create node platform plain js build, specify platform:'node' to do the rest of the files - bundleHTML: false, //wrap the first entry point file as a plain js script in a boilerplate html file, frontend scripts can be run standalone like a .exe! Server serves this as start page if set to true. - minify: false, - sourcemap: false - //globalThis:null //'mymodule' - //globals:{'index.js':['Graph']} - //init:{'index.js':function(bundle) { console.log('prepackaged bundle script!', bundle); }.toString(); } //pass stringified functions in to init bundle scripts in a custom way (e.g. for quick rebundling) - }, - server: { //node server settings, set false to skip server step or add serve:true to config object to only serve (alt methods) - debug: false, - protocol: "http", //'http' or 'https'. HTTPS required for Nodejs <---> Python sockets. If using http, set production to False in python/server.py as well - host: "localhost", //'localhost' or '127.0.0.1' etc. - port: 8080, //e.g. port 80, 443, 8000 - startpage: "index.html", //home page - socket_protocol: "ws", //frontend socket protocol, wss for served, ws for localhost - hotreload: 5000, //hotreload websocket server port - //watch: ['../'], //watch additional directories other than the current working directory - pwa: "dist/service-worker.js", //pwa mode? Injects service worker registry code in (see pwa README.md) - python: false,//7000, //quart server port (configured via the python server script file still) - python__node: 7001, //websocket relay port (relays messages to client from nodejs that were sent to it by python) - errpage: "node_modules/tinybuild/tinybuild/node_server/other/404.html", //default error page, etc. - certpath: "node_modules/tinybuild/tinybuild/node_server/ssl/cert.pem", //if using https, this is required. See cert.pfx.md for instructions - keypath: "node_modules/tinybuild/tinybuild/node_server/ssl/key.pem" //if using https, this is required. See cert.pfx.md for instructions - } -} -export default config; //module.exports = config; //es5 \ No newline at end of file diff --git a/examples/services/workers/workerthreejs/index.html b/examples/services/workers/workerthreejs/index.html deleted file mode 100644 index 49564abb..00000000 --- a/examples/services/workers/workerthreejs/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/examples/services/workers/workerthreejs/tinybuild.config.js b/examples/services/workers/workerthreejs/tinybuild.config.js deleted file mode 100644 index 2632c80c..00000000 --- a/examples/services/workers/workerthreejs/tinybuild.config.js +++ /dev/null @@ -1,36 +0,0 @@ -const config = { - bundler: { //esbuild settings, set false to skip build step or add bundle:true to config object to only bundle (alt methods) - entryPoints: [ //entry point file(s). These can include .js, .mjs, .ts, .jsx, .tsx, or other javascript files. Make sure your entry point is a ts file if you want to generate types - "index.ts" - ], - outfile: "dist/index", //exit point file, will append .js as well as indicators like .esm.js, .node.js for other build flags - //outdir:[] //exit point files, define for multiple bundle files - bundleBrowser: true, //create plain js build? Can include globals and init scripts - bundleESM: false, //create esm module js files - bundleTypes: false, //create .d.ts files, the entry point must be a typescript file! (ts, tsx, etc) - bundleNode: false, //create node platform plain js build, specify platform:'node' to do the rest of the files - bundleHTML: false, //wrap the first entry point file as a plain js script in a boilerplate html file, frontend scripts can be run standalone like a .exe! Server serves this as start page if set to true. - minify: false, - sourcemap: false - //globalThis:null //'mymodule' - //globals:{'index.js':['Graph']} - //init:{'index.js':function(bundle) { console.log('prepackaged bundle script!', bundle); }.toString(); } //pass stringified functions in to init bundle scripts in a custom way (e.g. for quick rebundling) - }, - server: { //node server settings, set false to skip server step or add serve:true to config object to only serve (alt methods) - debug: false, - protocol: "http", //'http' or 'https'. HTTPS required for Nodejs <---> Python sockets. If using http, set production to False in python/server.py as well - host: "localhost", //'localhost' or '127.0.0.1' etc. - port: 8080, //e.g. port 80, 443, 8000 - startpage: "index.html", //home page - socket_protocol: "ws", //frontend socket protocol, wss for served, ws for localhost - hotreload: 5000, //hotreload websocket server port - //watch: ['../'], //watch additional directories other than the current working directory - pwa: "dist/service-worker.js", //pwa mode? Injects service worker registry code in (see pwa README.md) - python: false,//7000, //quart server port (configured via the python server script file still) - python__node: 7001, //websocket relay port (relays messages to client from nodejs that were sent to it by python) - errpage: "node_modules/tinybuild/tinybuild/node_server/other/404.html", //default error page, etc. - certpath: "node_modules/tinybuild/tinybuild/node_server/ssl/cert.pem", //if using https, this is required. See cert.pfx.md for instructions - keypath: "node_modules/tinybuild/tinybuild/node_server/ssl/key.pem" //if using https, this is required. See cert.pfx.md for instructions - } -} -export default config; //module.exports = config; //es5 \ No newline at end of file diff --git a/examples/services/workers/workerthreejs/worker.ts b/examples/services/workers/workerthreejs/worker.ts deleted file mode 100644 index 6ddbd4ba..00000000 --- a/examples/services/workers/workerthreejs/worker.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { - WorkerService, - remoteGraphRoutes, - workerCanvasRoutes, - ECSService - //GPUService -} from '../../../../index'/////"../../GraphServiceRouter/index";//from 'graphscript' - -import {Systems} from '../../../../src/extras/index.services' - -import { CanvasProps } from '../../../../src/services/worker/WorkerCanvas'; - -import * as THREE from 'three' -import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js' -import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js' -import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js' -import { SMAAPass } from 'three/examples/jsm/postprocessing/SMAAPass.js' -import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js' -import { PickHelper } from './PickHelper' - -declare var WorkerGlobalScope; - -if(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) { - const worker = new WorkerService({ - services:{ - //GPUService, - ECSService, - remoteGraphRoutes, //allows dynamic route loading - }, - roots:{ - ...workerCanvasRoutes, - receiveThreeCanvas:function(options:CanvasProps){ //modified canvas receiver that installs desired threejs modules - const ThreeProps = { //e.g. install these systems to 'self', which is the worker canvas - THREE, - OrbitControls, - EffectComposer, - RenderPass, - SMAAPass, - UnrealBloomPass, - PickHelper - } - - Object.assign(options, ThreeProps); //install desired props to our canvas's 'self' reference - - console.log(this); - let renderId = this.__node.graph.run('setupCanvas', options); //the the base canvas tools do the rest, all ThreeJS tools are on self, for self contained ThreeJS renders - //you can use the canvas render loop by default, or don't provide a draw function and just use the init and the Three animate() callback - - //let canvasopts = this.graph.CANVASES[renderId] as WorkerCanvas; - - return renderId; - } - } - }); - - worker.run( - 'addSystems', - Systems, - ['boid','nbody','collision','collider','movement'] - ); //register desired entity component systems - - console.log(worker) -} - -export default self as any; \ No newline at end of file diff --git a/examples/tests/nesting/index.html b/examples/tests/nesting/index.html new file mode 100644 index 00000000..bbfdfc21 --- /dev/null +++ b/examples/tests/nesting/index.html @@ -0,0 +1,13 @@ + + + + + + + Document + + + + + + \ No newline at end of file diff --git a/examples/tests/nesting/index.ts b/examples/tests/nesting/index.ts new file mode 100644 index 00000000..18edfed7 --- /dev/null +++ b/examples/tests/nesting/index.ts @@ -0,0 +1,22 @@ +import { Graph } from "../../../Graph" +import { Router } from "../../../routers/Router" +import * as treeInfo from "../tree" + + +const input = 3 + +const graph = new Graph(treeInfo.tree, 'main') + +console.log('main graph:',graph); +console.log('nested map:',graph.nodes.get('nested').nodes) +const addChildren = graph.nodes.get('add').children +console.log('add node children:', addChildren) + +graph.subscribe('multiply', (res) => document.body.innerHTML = ` +

    Nested Graphs in Tree

    +

    Result: ${res}

    +

    Expected: ${treeInfo.expected([input])}

    +

    Test Passed: ${ res == treeInfo.expected([input])}

    +`) + +graph.run('add', input); \ No newline at end of file diff --git a/examples/basics/sync_async/package.json b/examples/tests/nesting/package.json similarity index 94% rename from examples/basics/sync_async/package.json rename to examples/tests/nesting/package.json index 77af2ce0..087e9576 100644 --- a/examples/basics/sync_async/package.json +++ b/examples/tests/nesting/package.json @@ -1,5 +1,5 @@ { - "name": "tinybuildapp442", + "name": "tinybuildapp2730", "version": "0.0.0", "description": "Barebones esbuild and test node server implementation. For building", "main": "index.js", @@ -20,7 +20,7 @@ "esbuild" ], "author": "", - "license": "LGPL-3.0-or-later", + "license": "AGPL-3.0-or-later", "dependencies": {}, "devDependencies": {}, "nodemonConfig": { diff --git a/examples/editing/tinybuild.config.js b/examples/tests/nesting/tinybuild.config.js similarity index 88% rename from examples/editing/tinybuild.config.js rename to examples/tests/nesting/tinybuild.config.js index 1f475b48..70c8cd10 100644 --- a/examples/editing/tinybuild.config.js +++ b/examples/tests/nesting/tinybuild.config.js @@ -1,3 +1,4 @@ + const config = { bundler: { //esbuild settings, set false to skip build step or add bundle:true to config object to only bundle (alt methods) entryPoints: [ //entry point file(s). These can include .js, .mjs, .ts, .jsx, .tsx, or other javascript files. Make sure your entry point is a ts file if you want to generate types @@ -11,19 +12,20 @@ const config = { bundleNode: false, //create node platform plain js build, specify platform:'node' to do the rest of the files bundleHTML: false, //wrap the first entry point file as a plain js script in a boilerplate html file, frontend scripts can be run standalone like a .exe! Server serves this as start page if set to true. minify: false, - sourcemap: false + sourcemap: false, + //platform:'node' //for bundling the node.ts file //globalThis:null //'mymodule' //globals:{'index.js':['Graph']} - //init:{'index.js':function(bundle) { console.log('prepackaged bundle script!', bundle); }.toString(); } //pass stringified functions in to init bundle scripts in a custom way (e.g. for quick rebundling) + //init:{'index.js':function(bundle) { console.log('prepackaged bundle script!', bundle); }} }, server: { //node server settings, set false to skip server step or add serve:true to config object to only serve (alt methods) debug: false, protocol: "http", //'http' or 'https'. HTTPS required for Nodejs <---> Python sockets. If using http, set production to False in python/server.py as well host: "localhost", //'localhost' or '127.0.0.1' etc. - port: 8080, //e.g. port 80, 443, 8000 + port: 8081, //e.g. port 80, 443, 8000 startpage: "index.html", //home page socket_protocol: "ws", //frontend socket protocol, wss for served, ws for localhost - hotreload: 2020, //hotreload websocket server port + hotreload: 5001, //hotreload websocket server port //watch: ['../'], //watch additional directories other than the current working directory pwa: "dist/service-worker.js", //pwa mode? Injects service worker registry code in (see pwa README.md) python: false,//7000, //quart server port (configured via the python server script file still) @@ -33,4 +35,5 @@ const config = { keypath: "node_modules/tinybuild/tinybuild/node_server/ssl/key.pem" //if using https, this is required. See cert.pfx.md for instructions } } -export default config; //module.exports = config; //es5 \ No newline at end of file + +export default config; //es5 //export default config; // \ No newline at end of file diff --git a/examples/tests/router/dist/index.js b/examples/tests/router/dist/index.js new file mode 100644 index 00000000..6bc25ad1 --- /dev/null +++ b/examples/tests/router/dist/index.js @@ -0,0 +1,3784 @@ +(() => { + var __defProp = Object.defineProperty; + var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; + var __publicField = (obj, key, value) => { + __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); + return value; + }; + + // ../../../Graph.ts + var ARGUMENT_NAMES = /([^,]*)/g; + function getFnParamInfo(fn) { + var fstr = fn.toString(); + const openPar = fstr.indexOf("("); + const closePar = fstr.indexOf(")"); + const getFirstBracket = (str, offset = 0) => { + const fb = offset + str.indexOf("{"); + if (fb < closePar && fb > openPar) { + return getFirstBracket(str.slice(fb), offset + fb); + } else + return fb; + }; + const firstBracket = getFirstBracket(fstr); + let innerMatch; + if (firstBracket === -1 || closePar < firstBracket) + innerMatch = fstr.slice(fstr.indexOf("(") + 1, fstr.indexOf(")")); + else + innerMatch = fstr.match(/([a-zA-Z]\w*|\([a-zA-Z]\w*(,\s*[a-zA-Z]\w*)*\)) =>/)?.[1]; + const matches = innerMatch.match(ARGUMENT_NAMES).filter((e) => !!e); + const info = /* @__PURE__ */ new Map(); + matches.forEach((v) => { + let [name, value] = v.split("="); + name = name.trim(); + name = name.replace(/\d+$/, ""); + try { + if (name) + info.set(name, (0, eval)(`(${value})`)); + } catch (e) { + info.set(name, void 0); + console.warn(`Argument ${name} could be parsed for`, fn.toString()); + } + }); + return info; + } + function parseFunctionFromText(method = "") { + let getFunctionBody = (methodString) => { + return methodString.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i, "$2$3$4"); + }; + let getFunctionHead = (methodString) => { + let startindex = methodString.indexOf(")"); + return methodString.slice(0, methodString.indexOf("{", startindex) + 1); + }; + let newFuncHead = getFunctionHead(method); + let newFuncBody = getFunctionBody(method); + let newFunc; + if (newFuncHead.includes("function ")) { + let varName = newFuncHead.split("(")[1].split(")")[0]; + newFunc = new Function(varName, newFuncBody); + } else { + if (newFuncHead.substring(0, 6) === newFuncBody.substring(0, 6)) { + let varName = newFuncHead.split("(")[1].split(")")[0]; + newFunc = new Function(varName, newFuncBody.substring(newFuncBody.indexOf("{") + 1, newFuncBody.length - 1)); + } else { + try { + newFunc = (0, eval)(newFuncHead + newFuncBody + "}"); + } catch { + } + } + } + return newFunc; + } + var state = { + pushToState: {}, + data: {}, + triggers: {}, + setState(updateObj) { + Object.assign(state.data, updateObj); + for (const prop of Object.getOwnPropertyNames(updateObj)) { + if (state.triggers[prop]) + state.triggers[prop].forEach((obj) => obj.onchange(state.data[prop])); + } + return state.data; + }, + subscribeTrigger(key, onchange) { + if (key) { + if (!state.triggers[key]) { + state.triggers[key] = []; + } + let l = state.triggers[key].length; + state.triggers[key].push({ idx: l, onchange }); + return state.triggers[key].length - 1; + } else + return void 0; + }, + unsubscribeTrigger(key, sub) { + let idx = void 0; + let triggers = state.triggers[key]; + if (triggers) { + if (!sub) + delete state.triggers[key]; + else { + let obj = triggers.find((o) => { + if (o.idx === sub) { + return true; + } + }); + if (obj) + triggers.splice(idx, 1); + return true; + } + } + }, + subscribeTriggerOnce(key, onchange) { + let sub; + let changed = (value) => { + onchange(value); + state.unsubscribeTrigger(key, sub); + }; + sub = state.subscribeTrigger(key, changed); + } + }; + var GraphNode = class { + constructor(properties = {}, parentNode, graph) { + this.nodes = /* @__PURE__ */ new Map(); + this.arguments = /* @__PURE__ */ new Map(); + this.initial = {}; + this.state = state; + this.isLooping = false; + this.isAnimating = false; + this.looper = void 0; + this.animation = void 0; + this.forward = true; + this.backward = false; + this.runSync = false; + this.firstRun = true; + this.DEBUGNODE = false; + this.operator = (self = this, origin, ...args) => { + return args; + }; + this.runOp = (node = this, origin = this, ...args) => { + if (node.DEBUGNODE) + console.time(node.tag); + let result = node.operator(node, origin, ...args); + if (result instanceof Promise) { + result.then((res) => { + if (res !== void 0) + this.setState({ [node.tag]: res }); + if (node.DEBUGNODE) { + console.timeEnd(node.tag); + if (result !== void 0) + console.log(`${node.tag} result:`, result); + } + ; + return res; + }); + } else { + if (result !== void 0) + this.setState({ [node.tag]: result }); + if (node.DEBUGNODE) { + console.timeEnd(node.tag); + if (result !== void 0) + console.log(`${node.tag} result:`, result); + } + ; + } + return result; + }; + this.setOperator = (operator) => { + if (typeof operator !== "function") + return operator; + let params = getFnParamInfo(operator); + const keys = params.keys(); + const paramOne = keys.next().value; + const paramTwo = keys.next().value; + const restrictedOne = ["self", "node"]; + const restrictedTwo = ["origin", "parent", "graph", "router"]; + if (!restrictedOne.includes(paramOne) && !restrictedTwo.includes(paramTwo)) { + let fn = operator; + operator = (self, origin, ...args) => { + return fn(...args); + }; + if (this.arguments) { + params.forEach((v, k) => { + if (!this.arguments.has(k)) + this.arguments.set(k, v); + }); + } + } + this.operator = operator; + return operator; + }; + this.run = (...args) => { + return this._run(this, void 0, ...args); + }; + this.runAsync = (...args) => { + return new Promise((res, rej) => { + res(this._run(this, void 0, ...args)); + }); + }; + this.transformArgs = (args = []) => args; + this._run = (node = this, origin, ...args) => { + if (typeof this.transformArgs === "function") + args = this.transformArgs(args, node); + if (!(typeof node === "object")) { + if (typeof node === "string") { + let fnd = void 0; + if (this.graph) + fnd = this.graph.nodes.get(node); + if (!fnd) + fnd = this.nodes.get(node); + node = fnd; + } + if (!node) + return void 0; + } + if (node.firstRun) { + node.firstRun = false; + if (!(node.children && node.forward || node.parent && node.backward || node.repeat || node.delay || node.frame || node.recursive || node.branch)) + node.runSync = true; + if (node.animate && !node.isAnimating) { + node.runAnimation(node.animation, args, node, origin); + } + if (node.loop && typeof node.loop === "number" && !node.isLooping) { + node.runLoop(node.looper, args, node, origin); + } + if (node.loop || node.animate) + return; + } + if (node.runSync) { + let res = node.runOp(node, origin, ...args); + return res; + } + return new Promise(async (resolve) => { + if (node) { + let run = (node2, tick = 0, ...input2) => { + return new Promise(async (r) => { + tick++; + let res = await node2.runOp(node2, origin, ...input2); + if (node2.repeat) { + while (tick < node2.repeat) { + if (node2.delay) { + setTimeout(async () => { + r(await run(node2, tick, ...input2)); + }, node2.delay); + break; + } else if (node2.frame && window?.requestAnimationFrame) { + requestAnimationFrame(async () => { + r(await run(node2, tick, ...input2)); + }); + break; + } else + res = await node2.runOp(node2, origin, ...input2); + tick++; + } + if (tick === node2.repeat) { + r(res); + return; + } + } else if (node2.recursive) { + while (tick < node2.recursive) { + if (node2.delay) { + setTimeout(async () => { + r(await run(node2, tick, ...res)); + }, node2.delay); + break; + } else if (node2.frame && window?.requestAnimationFrame) { + requestAnimationFrame(async () => { + r(await run(node2, tick, ...res)); + }); + break; + } else + res = await node2.runOp(node2, origin, ...res); + tick++; + } + if (tick === node2.recursive) { + r(res); + return; + } + } else { + r(res); + return; + } + }); + }; + let runnode = async () => { + let res = await run(node, void 0, ...args); + if (res !== void 0) { + if (node.backward && node.parent instanceof GraphNode) { + if (Array.isArray(res)) + await this.runParent(node, ...res); + else + await this.runParent(node, res); + } + if (node.children && node.forward) { + if (Array.isArray(res)) + await this.runChildren(node, ...res); + else + await this.runChildren(node, res); + } + if (node.branch) { + this.runBranch(node, res); + } + } + return res; + }; + if (node.delay) { + setTimeout(async () => { + resolve(await runnode()); + }, node.delay); + } else if (node.frame && window?.requestAnimationFrame) { + requestAnimationFrame(async () => { + resolve(await runnode()); + }); + } else { + resolve(await runnode()); + } + } else + resolve(void 0); + }); + }; + this.runParent = async (node, ...args) => { + if (node.backward && node.parent) { + if (typeof node.parent === "string") { + if (node.graph && node.graph?.get(node.parent)) { + node.parent = node.graph; + if (node.parent) + this.nodes.set(node.parent.tag, node.parent); + } else + node.parent = this.nodes.get(node.parent); + } + if (node.parent instanceof GraphNode) + await node.parent._run(node.parent, this, ...args); + } + }; + this.runChildren = async (node, ...args) => { + if (typeof node.children === "object") { + for (const key in node.children) { + if (typeof node.children[key] === "string") { + if (node.graph && node.graph?.get(node.children[key])) { + node.children[key] = node.graph.get(node.children[key]); + if (!node.nodes.get(node.children[key].tag)) + node.nodes.set(node.children[key].tag, node.children[key]); + } + if (!node.children[key] && node.nodes.get(node.children[key])) + node.children[key] = node.nodes.get(node.children[key]); + } else if (typeof node.children[key] === "undefined" || node.children[key] === true) { + if (node.graph && node.graph?.get(key)) { + node.children[key] = node.graph.get(key); + if (!node.nodes.get(node.children[key].tag)) + node.nodes.set(node.children[key].tag, node.children[key]); + } + if (!node.children[key] && node.nodes.get(key)) + node.children[key] = node.nodes.get(key); + } + if (node.children[key]?.runOp) + await node.children[key]._run(node.children[key], node, ...args); + } + } + }; + this.runBranch = async (node, output) => { + if (node.branch) { + let keys = Object.keys(node.branch); + await Promise.all(keys.map(async (k) => { + if (typeof node.branch[k].if === "object") + node.branch[k].if = stringifyFast(node.branch[k].if); + let pass = false; + if (typeof output === "object") + if (stringifyFast(output) === node.branch[k].if) + pass = true; + else if (output === node.branch[k].if) + pass = true; + else + pass = true; + if (pass) { + if (node.branch[k].then instanceof GraphNode) { + if (Array.isArray(output)) + await node.branch[k].then._run(node.branch[k].then, node, ...output); + else + await node.branch[k].then._run(node.branch[k].then, node, ...output); + } else if (typeof node.branch[k].then === "function") { + if (Array.isArray(output)) + await node.branch[k].then(...output); + else + await node.branch[k].then(output); + } else if (typeof node.branch[k].then === "string") { + if (node.graph) + node.branch[k].then = node.graph.nodes.get(node.branch[k].then); + else + node.branch[k].then = node.nodes.get(node.branch[k].then); + if (node.branch[k].then instanceof GraphNode) { + if (Array.isArray(output)) + await node.branch[k].then._run(node.branch[k].then, node, ...output); + else + await node.branch[k].then._run(node.branch[k].then, node, ...output); + } + } + } + return pass; + })); + } + }; + this.runAnimation = (animation = this.animation, args = [], node = this, origin) => { + this.animation = animation; + if (!animation) + this.animation = this.operator; + if (node.animate && !node.isAnimating && "requestAnimationFrame" in window) { + node.isAnimating = true; + let anim = async () => { + if (node.isAnimating) { + if (node.DEBUGNODE) + console.time(node.tag); + let result = this.animation(node, origin, ...args); + if (result instanceof Promise) { + result = await result; + } + if (node.DEBUGNODE) { + console.timeEnd(node.tag); + if (result !== void 0) + console.log(`${node.tag} result:`, result); + } + ; + if (result !== void 0) { + if (this.tag) + this.setState({ [this.tag]: result }); + if (node.backward && node.parent?._run) { + if (Array.isArray(result)) + await this.runParent(node, ...result); + else + await this.runParent(node, result); + } + if (node.children && node.forward) { + if (Array.isArray(result)) + await this.runChildren(node, ...result); + else + await this.runChildren(node, result); + } + if (node.branch) { + this.runBranch(node, result); + } + this.setState({ [node.tag]: result }); + } + requestAnimationFrame(anim); + } + }; + requestAnimationFrame(anim); + } + }; + this.runLoop = (loop = this.looper, args = [], node = this, origin, timeout = node.loop) => { + node.looper = loop; + if (!loop) + node.looper = node.operator; + if (typeof timeout === "number" && !node.isLooping) { + node.isLooping = true; + let looping = async () => { + if (node.isLooping) { + if (node.DEBUGNODE) + console.time(node.tag); + let result = node.looper(node, origin, ...args); + if (result instanceof Promise) { + result = await result; + } + if (node.DEBUGNODE) { + console.timeEnd(node.tag); + if (result !== void 0) + console.log(`${node.tag} result:`, result); + } + ; + if (result !== void 0) { + if (node.tag) + node.setState({ [node.tag]: result }); + if (node.backward && node.parent?._run) { + if (Array.isArray(result)) + await this.runParent(node, ...result); + else + await this.runParent(node, result); + } + if (node.children && node.forward) { + if (Array.isArray(result)) + await this.runChildren(node, ...result); + else + await this.runChildren(node, result); + } + if (node.branch) { + this.runBranch(node, result); + } + node.setState({ [node.tag]: result }); + } + setTimeout(async () => { + await looping(); + }, timeout); + } + }; + looping(); + } + }; + this.setParent = (parent) => { + this.parent = parent; + if (this.backward) + this.runSync = false; + }; + this.setChildren = (children) => { + this.children = children; + if (this.forward) + this.runSync = false; + }; + this.add = (node = {}) => { + if (typeof node === "function") + node = { operator: node }; + if (!(node instanceof GraphNode)) + node = new GraphNode(node, this, this.graph); + this.nodes.set(node.tag, node); + if (this.graph) { + this.graph.nodes.set(node.tag, node); + this.graph.nNodes++; + } + return node; + }; + this.remove = (node) => { + if (typeof node === "string") + node = this.nodes.get(node); + if (node instanceof GraphNode) { + this.nodes.delete(node.tag); + if (this.graph) { + this.graph.nodes.delete(node.tag); + this.graph.nNodes--; + } + this.nodes.forEach((n) => { + if (n.nodes.get(node.tag)) + n.nodes.delete(node.tag); + }); + } + }; + this.append = (node, parentNode = this) => { + if (typeof node === "string") + node = this.nodes.get(node); + if (node instanceof GraphNode) { + parentNode.addChildren(node); + if (node.forward) + node.runSync = false; + } + }; + this.subscribe = (callback, tag2 = this.tag) => { + if (callback instanceof GraphNode) { + return this.subscribeNode(callback); + } else + return this.state.subscribeTrigger(tag2, callback); + }; + this.unsubscribe = (sub, tag2 = this.tag) => { + this.state.unsubscribeTrigger(tag2, sub); + }; + this.addChildren = (children) => { + if (!this.children) + this.children = {}; + if (typeof children === "object") + Object.assign(this.children, children); + this.convertChildrenToNodes(); + if (this.forward) + this.runSync = false; + }; + this.callParent = (...args) => { + const origin = this; + if (typeof this.parent === "string") { + if (this.graph && this.graph?.get(this.parent)) { + this.parent = this.graph; + if (this.parent) + this.nodes.set(this.parent.tag, this.parent); + } else + this.parent = this.nodes.get(this.parent); + } + if (typeof this.parent?.operator === "function") + return this.parent.runOp(this.parent, origin, ...args); + }; + this.callChildren = (idx, ...args) => { + const origin = this; + let result; + if (typeof this.children === "object") { + for (const key in this.children) { + if (this.children[key]?.runOp) + this.children[key].runOp(this.children[key], origin, ...args); + } + } + return result; + }; + this.getProps = (node = this) => { + return { + tag: node.tag, + operator: node.operator, + graph: node.graph, + children: node.children, + parent: node.parent, + forward: node.forward, + backward: node.bacward, + loop: node.loop, + animate: node.animate, + frame: node.frame, + delay: node.delay, + recursive: node.recursive, + repeat: node.repeat, + branch: node.branch, + oncreate: node.oncreate, + DEBUGNODE: node.DEBUGNODE, + ...this.initial + }; + }; + this.setProps = (props = {}) => { + let tmp = Object.assign({}, props); + if (tmp.children) { + this.addChildren(props.children); + delete tmp.children; + } + if (tmp.operator) { + this.setOperator(props.operator); + delete tmp.operator; + } + Object.assign(tmp, props); + if (!(this.children && this.forward || this.parent && this.backward || this.repeat || this.delay || this.frame || this.recursive)) + this.runSync = true; + }; + this.removeTree = (node) => { + if (node) { + if (typeof node === "string") + node = this.nodes.get(node); + } + if (node instanceof GraphNode) { + const recursivelyRemove = (node2) => { + if (typeof node2.children === "object") { + for (const key in node2.children) { + if (node2.children[key].stopNode) + node2.children[key].stopNode(); + if (node2.children[key].tag) { + if (this.nodes.get(node2.children[key].tag)) + this.nodes.delete(node2.children[key].tag); + if (this[node2.children[key].tag] instanceof GraphNode) + delete this[node2.children[key].tag]; + } + this.nodes.forEach((n) => { + if (n.nodes.get(node2.children[key].tag)) + n.nodes.delete(node2.children[key].tag); + if (n[node2.children[key].tag] instanceof GraphNode) + delete n[node2.children[key].tag]; + }); + recursivelyRemove(node2.children[key]); + } + } + }; + if (node.stopNode) + node.stopNode(); + if (node.tag) { + this.nodes.delete(node.tag); + if (this[node.tag] instanceof GraphNode) + delete this[node.tag]; + this.nodes.forEach((n) => { + if (node?.tag) { + if (n.nodes.get(node.tag)) + n.nodes.delete(node.tag); + if (n[node.tag] instanceof GraphNode) + delete n[node.tag]; + } + }); + recursivelyRemove(node); + if (this.graph) + this.graph.removeTree(node); + } + } + }; + this.checkNodesHaveChildMapped = (node, child, checked = {}) => { + let tag2 = node.tag; + if (!tag2) + tag2 = node.name; + if (!checked[tag2]) { + checked[tag2] = true; + if (node.children) { + if (child.tag in node.children) { + if (!(node.children[child.tag] instanceof GraphNode)) + node.children[child.tag] = child; + if (!node.firstRun) + node.firstRun = true; + } + } + if (node.parent) { + if (node.parent.children) { + this.checkNodesHaveChildMapped(node.parent, child, checked); + } else if (node.nodes) { + node.nodes.forEach((n) => { + if (!checked[n.tag]) { + this.checkNodesHaveChildMapped(n, child, checked); + } + }); + } + } + if (node.graph) { + if (node.parent && node.parent.name !== node.graph.name) { + node.graph.nodes.forEach((n) => { + if (!checked[n.tag]) { + this.checkNodesHaveChildMapped(n, child, checked); + } + }); + } + } + } + }; + this.convertChildrenToNodes = (n = this) => { + if (n?.children) { + for (const key in n.children) { + if (!(n.children[key] instanceof GraphNode)) { + if (typeof n.children[key] === "object") { + if (!n.children[key].tag) + n.children[key].tag = key; + n.children[key] = new GraphNode(n.children[key], n, n.graph); + this.checkNodesHaveChildMapped(n, n.children[key]); + } else { + if (typeof n.children[key] === "undefined" || n.children[key] == true) { + n.children[key] = n.graph.get(key); + if (!n.children[key]) + n.children[key] = n.nodes.get(key); + } else if (typeof n.children[key] === "string") { + let k = n.children[key]; + n.children[key] = n.graph.get(k); + if (!n.children[key]) + n.children[key] = n.nodes.get(key); + } + if (n.children[key] instanceof GraphNode) { + if (n.graph) { + let props = n.children[key].getProps(); + delete props.parent; + delete props.graph; + if (n.source) + n.children[key] = new GraphNode(props, n, n.source); + else { + n.children[key] = new GraphNode(props, n, n.graph); + } + } else { + n.nodes.set(n.children[key].tag, n.children[key]); + this.checkNodesHaveChildMapped(n, n.children[key]); + } + if (!(n.children[key].tag in n)) + n[n.children[key].tag] = n.children[key].tag; + } + } + } + } + } + return n.children; + }; + this.stopLooping = (node = this) => { + node.isLooping = false; + }; + this.stopAnimating = (node = this) => { + node.isAnimating = false; + }; + this.stopNode = (node = this) => { + node.stopAnimating(node); + node.stopLooping(node); + }; + this.subscribeNode = (node) => { + if (node.tag) + this.nodes.set(node.tag, node); + return this.state.subscribeTrigger(this.tag, (res) => { + node._run(node, this, res); + }); + }; + this.print = (node = this, printChildren = true, nodesPrinted = []) => { + let dummyNode = new GraphNode(); + if (typeof node === "string") + node = this.nodes.get(node); + if (node instanceof GraphNode) { + nodesPrinted.push(node.tag); + let jsonToPrint = { + tag: node.tag, + operator: node.operator.toString() + }; + if (node.parent) + jsonToPrint.parent = node.parent.tag; + if (typeof node.children === "object") { + for (const key in node.children) { + if (typeof node.children[key] === "string") + return node.children[key]; + if (nodesPrinted.includes(node.children[key].tag)) + return node.children[key].tag; + else if (!printChildren) { + return node.children[key].tag; + } else + return node.children[key].print(node.children[key], printChildren, nodesPrinted); + } + } + for (const prop in node) { + if (prop === "parent" || prop === "children") + continue; + if (typeof dummyNode[prop] === "undefined") { + if (typeof node[prop] === "function") { + jsonToPrint[prop] = node[prop].toString(); + } else if (typeof node[prop] === "object") { + jsonToPrint[prop] = JSON.stringifyWithCircularRefs(node[prop]); + } else { + jsonToPrint[prop] = node[prop]; + } + } + } + return JSON.stringify(jsonToPrint); + } + }; + this.reconstruct = (json) => { + let parsed = reconstructObject(json); + if (parsed) + return this.add(parsed); + }; + this.setState = this.state.setState; + this.DEBUGNODES = (debugging = true) => { + this.DEBUGNODE = debugging; + this.nodes.forEach((n) => { + if (debugging) + n.DEBUGNODE = true; + else + n.DEBUGNODE = false; + }); + }; + if (typeof properties === "function") { + properties = { operator: properties }; + } + if (typeof properties === "object") { + if (properties instanceof GraphNode && properties.initial) + Object.assign(properties, properties.initial); + if (properties instanceof Graph) { + let source = properties; + properties = { + source, + operator: (input2) => { + if (typeof input2 === "object") { + let result = {}; + for (const key in input2) { + if (typeof source[key] === "function") { + if (Array.isArray(input2[key])) + result[key] = source[key](...input2[key]); + else + result[key] = source[key](input2[key]); + } else { + source[key] = input2[key]; + result[key] = source[key]; + } + } + return result; + } + return source; + } + }; + if (source.operator) + properties.operator = source.operator; + if (source.children) + properties.children = source.children; + if (source.forward) + properties.forward = source.forward; + if (source.backward) + properties.backward = source.backward; + if (source.repeat) + properties.repeat = source.repeat; + if (source.recursive) + properties.recursive = source.recursive; + if (source.loop) + properties.loop = source.loop; + if (source.animate) + properties.animate = source.animate; + if (source.looper) + properties.looper = source.looper; + if (source.animation) + properties.animation = source.animation; + if (source.delay) + properties.delay = source.delay; + if (source.tag) + properties.tag = source.tag; + if (source.oncreate) + properties.oncreate = source.oncreate; + if (source.node) { + if (source.node.initial) + Object.assign(properties, source.node.initial); + } + if (source.initial) + Object.assign(properties, source.initial); + this.nodes = source.nodes; + source.node = this; + if (graph) { + source.nodes.forEach((n) => { + if (!graph.nodes.get(n.tag)) { + graph.nodes.set(n.tag, n); + graph.nNodes++; + } + }); + } + } + if (properties.tag && (graph || parentNode)) { + let hasnode; + if (graph?.nodes) { + hasnode = graph.nodes.get(properties.tag); + } + if (!hasnode && parentNode?.nodes) { + hasnode = parentNode.nodes.get(properties.tag); + } + if (hasnode) { + Object.assign(this, hasnode); + if (!this.source) + this.source = hasnode; + let props = hasnode.getProps(); + delete props.graph; + delete props.parent; + Object.assign(properties, props); + } + } + if (properties?.operator) { + properties.operator = this.setOperator(properties.operator); + } + if (!properties.tag && graph) { + properties.tag = `node${graph.nNodes}`; + } else if (!properties.tag) { + properties.tag = `node${Math.floor(Math.random() * 1e10)}`; + } + if ("arguments" in properties) { + if (properties.arguments) { + for (let key in properties.arguments) { + this.arguments.set(key, properties.arguments[key]); + } + } + properties.arguments = this.arguments; + } + let keys = Object.getOwnPropertyNames(this); + for (const key in properties) { + if (!keys.includes(key)) + this.initial[key] = properties[key]; + } + if (properties.children) + this.initial.children = Object.assign({}, properties.children); + Object.assign(this, properties); + if (!this.tag) { + if (graph) { + this.tag = `node${graph.nNodes}`; + } else { + this.tag = `node${Math.floor(Math.random() * 1e10)}`; + } + } + if (parentNode) + this.parent = parentNode; + if (graph) { + this.graph = graph; + if (graph.nodes.get(this.tag)) { + parentNode.nodes.set(this.tag, this); + this.tag = `${this.tag}${graph.nNodes + 1}`; + } + graph.nodes.set(this.tag, this); + graph.nNodes++; + } + if (typeof properties.tree === "object") { + for (const key in properties.tree) { + if (typeof properties.tree[key] === "object") { + if ((!properties.tree[key]).tag) { + properties.tree[key].tag = key; + } + } + let node = new GraphNode(properties.tree[key], this, graph); + this.nodes.set(node.tag, node); + } + } + if (this.children) + this.convertChildrenToNodes(this); + if (this.parent instanceof GraphNode || this.parent instanceof Graph) + this.checkNodesHaveChildMapped(this.parent, this); + if (typeof this.oncreate === "function") + this.oncreate(this); + if (!this.firstRun) + this.firstRun = true; + } else + return properties; + } + }; + var Graph = class { + constructor(tree2, tag2, props) { + this.nNodes = 0; + this.nodes = /* @__PURE__ */ new Map(); + this.state = state; + this.tree = {}; + this.add = (node = {}) => { + let props = node; + if (!(node instanceof GraphNode)) + node = new GraphNode(props, this, this); + else + this.nNodes++; + if (node.tag) + this.tree[node.tag] = props; + this.nodes.set(node.tag, node); + return node; + }; + this.setTree = (tree2 = this.tree) => { + if (!tree2) + return; + for (const node in tree2) { + if (!this.nodes.get(node)) { + if (typeof tree2[node] === "function") { + this.add({ tag: node, operator: tree2[node] }); + } else if (typeof tree2[node] === "object" && !Array.isArray(tree2[node])) { + if (!tree2[node].tag) + tree2[node].tag = node; + let newNode = this.add(tree2[node]); + if (tree2[node].aliases) { + tree2[node].aliases.forEach((a) => { + this.nodes.set(a, newNode); + }); + } + } else { + this.add({ tag: node, operator: (self, origin, ...args) => { + return tree2[node]; + } }); + } + } else { + let n = this.nodes.get(node); + if (typeof tree2[node] === "function") { + n.setOperator(tree2[node]); + } else if (typeof tree2[node] === "object") { + if (tree2[node] instanceof GraphNode) { + if (n.tag !== tree2[node].tag) + this.add(tree2[node]); + } else if (tree2[node] instanceof Graph) { + let source = tree2[node]; + let properties = {}; + if (source.operator) + properties.operator = source.operator; + if (source.children) + properties.children = source.children; + if (source.forward) + properties.forward = source.forward; + if (source.backward) + properties.backward = source.backward; + if (source.repeat) + properties.repeat = source.repeat; + if (source.recursive) + properties.recursive = source.recursive; + if (source.loop) + properties.loop = source.loop; + if (source.animate) + properties.animate = source.animate; + if (source.looper) + properties.looper = source.looper; + if (source.animation) + properties.animation = source.animation; + if (source.delay) + properties.delay = source.delay; + if (source.tag) + properties.tag = source.tag; + if (source.oncreate) + properties.oncreate = source.oncreate; + if (source.node?.initial) + Object.assign(properties, source.node.initial); + properties.nodes = source.nodes; + properties.source = source; + n.setProps(properties); + } else { + n.setProps(tree2[node]); + } + } + } + } + this.nodes.forEach((node) => { + if (typeof node.children === "object") { + for (const key in node.children) { + if (typeof node.children[key] === "string") { + if (this.nodes.get(node.children[key])) { + node.children[key] = this.nodes.get(node.children[key]); + } + } else if (node.children[key] === true || typeof node.children[key] === "undefined") { + if (this.nodes.get(key)) { + node.children[key] = this.nodes.get(key); + } + } + if (node.children[key] instanceof GraphNode) { + node.checkNodesHaveChildMapped(node, node.children[key]); + } + } + } + if (typeof node.parent === "string") { + if (this.nodes.get(node.parent)) { + node.parent = this.nodes.get(node.parent); + node.nodes.set(node.parent.tag, node.parent); + } + } + }); + }; + this.get = (tag2) => { + return this.nodes.get(tag2); + }; + this.set = (node) => { + return this.nodes.set(node.tag, node); + }; + this.run = (node, ...args) => { + if (typeof node === "string") + node = this.nodes.get(node); + if (node instanceof GraphNode) + return node._run(node, this, ...args); + else + return void 0; + }; + this.runAsync = (node, ...args) => { + if (typeof node === "string") + node = this.nodes.get(node); + if (node instanceof GraphNode) + return new Promise((res, rej) => { + res(node._run(node, this, ...args)); + }); + else + return new Promise((res, rej) => { + res(void 0); + }); + }; + this._run = (node, origin = this, ...args) => { + if (typeof node === "string") + node = this.nodes.get(node); + if (node instanceof GraphNode) + return node._run(node, origin, ...args); + else + return void 0; + }; + this.removeTree = (node) => { + if (typeof node === "string") + node = this.nodes.get(node); + if (node instanceof GraphNode) { + const recursivelyRemove = (node2) => { + if (node2.children) { + if (Array.isArray(node2.children)) { + node2.children.forEach((c) => { + if (c.stopNode) + c.stopNode(); + if (c.tag) { + if (this.nodes.get(c.tag)) + this.nodes.delete(c.tag); + } + this.nodes.forEach((n) => { + if (n.nodes.get(c.tag)) + n.nodes.delete(c.tag); + }); + recursivelyRemove(c); + }); + } else if (typeof node2.children === "object") { + if (node2.stopNode) + node2.stopNode(); + if (node2.tag) { + if (this.nodes.get(node2.tag)) + this.nodes.delete(node2.tag); + } + this.nodes.forEach((n) => { + if (n.nodes.get(node2.tag)) + n.nodes.delete(node2.tag); + }); + recursivelyRemove(node2); + } + } + }; + if (node.stopNode) + node.stopNode(); + if (node.tag) { + this.nodes.delete(node.tag); + this.nodes.forEach((n) => { + if (n.nodes.get(node.tag)) + n.nodes.delete(node.tag); + }); + this.nNodes--; + recursivelyRemove(node); + } + } + return node; + }; + this.remove = (node) => { + if (typeof node === "string") + node = this.nodes.get(node); + if (node?.tag) { + node.stopNode(); + if (node?.tag) { + if (this.nodes.get(node.tag)) { + this.nodes.delete(node.tag); + this.nodes.forEach((n) => { + if (n.nodes.get(node.tag)) + n.nodes.delete(node.tag); + }); + } + } + } + return node; + }; + this.append = (node, parentNode) => { + parentNode.addChildren(node); + }; + this.callParent = async (node, origin = node, ...args) => { + if (node?.parent) { + return await node.callParent(node, origin, ...args); + } + }; + this.callChildren = async (node, idx, ...args) => { + if (node?.children) { + return await node.callChildren(idx, ...args); + } + }; + this.subscribe = (node, callback) => { + if (!callback) + return; + if (node instanceof GraphNode) { + return node.subscribe(callback); + } else if (typeof node == "string") + return this.state.subscribeTrigger(node, callback); + }; + this.unsubscribe = (tag2, sub) => { + this.state.unsubscribeTrigger(tag2, sub); + }; + this.subscribeNode = (inputNode, outputNode) => { + let tag2; + if (inputNode?.tag) + tag2 = inputNode.tag; + else if (typeof inputNode === "string") + tag2 = inputNode; + return this.state.subscribeTrigger(tag2, (res) => { + this.run(outputNode, inputNode, ...res); + }); + }; + this.stopNode = (node) => { + if (typeof node === "string") { + node = this.nodes.get(node); + } + if (node instanceof GraphNode) { + node.stopNode(); + } + }; + this.print = (node = void 0, printChildren = true) => { + if (node instanceof GraphNode) + return node.print(node, printChildren); + else { + let printed = `{`; + this.nodes.forEach((n) => { + printed += ` +"${n.tag}:${n.print(n, printChildren)}"`; + }); + return printed; + } + }; + this.reconstruct = (json) => { + let parsed = reconstructObject(json); + if (parsed) + return this.add(parsed); + }; + this.create = (operator, parentNode, props) => { + return createNode(operator, parentNode, props, this); + }; + this.setState = this.state.setState; + this.DEBUGNODES = (debugging = true) => { + this.nodes.forEach((n) => { + if (debugging) + n.DEBUGNODE = true; + else + n.DEBUGNODE = false; + }); + }; + this.tag = tag2 ? tag2 : `graph${Math.floor(Math.random() * 1e11)}`; + if (props) { + Object.assign(this, props); + this.initial = props; + } + if (tree2 || Object.keys(this.tree).length > 0) + this.setTree(tree2); + } + }; + function reconstructObject(json = "{}") { + try { + let parsed = typeof json === "string" ? JSON.parse(json) : json; + const parseObj = (obj) => { + for (const prop in obj) { + if (typeof obj[prop] === "string") { + let funcParsed = parseFunctionFromText(obj[prop]); + if (typeof funcParsed === "function") { + obj[prop] = funcParsed; + } + } else if (typeof obj[prop] === "object") { + parseObj(obj[prop]); + } + } + return obj; + }; + return parseObj(parsed); + } catch (err) { + console.error(err); + return void 0; + } + } + var stringifyWithCircularRefs = function() { + const refs = /* @__PURE__ */ new Map(); + const parents = []; + const path = ["this"]; + function clear() { + refs.clear(); + parents.length = 0; + path.length = 1; + } + function updateParents(key, value) { + var idx = parents.length - 1; + var prev = parents[idx]; + if (typeof prev === "object") { + if (prev[key] === value || idx === 0) { + path.push(key); + parents.push(value.pushed); + } else { + while (idx-- >= 0) { + prev = parents[idx]; + if (typeof prev === "object") { + if (prev[key] === value) { + idx += 2; + parents.length = idx; + path.length = idx; + --idx; + parents[idx] = value; + path[idx] = key; + break; + } + } + idx--; + } + } + } + } + function checkCircular(key, value) { + if (value != null) { + if (typeof value === "object") { + if (key) { + updateParents(key, value); + } + let other = refs.get(value); + if (other) { + return "[Circular Reference]" + other; + } else { + refs.set(value, path.join(".")); + } + } + } + return value; + } + return function stringifyWithCircularRefs2(obj, space) { + try { + parents.push(obj); + return JSON.stringify(obj, checkCircular, space); + } finally { + clear(); + } + }; + }(); + if (JSON.stringifyWithCircularRefs === void 0) { + JSON.stringifyWithCircularRefs = stringifyWithCircularRefs; + } + var stringifyFast = function() { + const refs = /* @__PURE__ */ new Map(); + const parents = []; + const path = ["this"]; + function clear() { + refs.clear(); + parents.length = 0; + path.length = 1; + } + function updateParents(key, value) { + var idx = parents.length - 1; + if (parents[idx]) { + var prev = parents[idx]; + if (typeof prev === "object") { + if (prev[key] === value || idx === 0) { + path.push(key); + parents.push(value.pushed); + } else { + while (idx-- >= 0) { + prev = parents[idx]; + if (typeof prev === "object") { + if (prev[key] === value) { + idx += 2; + parents.length = idx; + path.length = idx; + --idx; + parents[idx] = value; + path[idx] = key; + break; + } + } + idx++; + } + } + } + } + } + function checkValues(key, value) { + let val; + if (value != null) { + if (typeof value === "object") { + let c = value.constructor.name; + if (key && c === "Object") { + updateParents(key, value); + } + let other = refs.get(value); + if (other) { + return "[Circular Reference]" + other; + } else { + refs.set(value, path.join(".")); + } + if (c === "Array") { + if (value.length > 20) { + val = value.slice(value.length - 20); + } else + val = value; + } else if (c.includes("Set")) { + val = Array.from(value); + } else if (c !== "Object" && c !== "Number" && c !== "String" && c !== "Boolean") { + val = "instanceof_" + c; + } else if (c === "Object") { + let obj = {}; + for (const prop in value) { + if (value[prop] == null) { + obj[prop] = value[prop]; + } else if (Array.isArray(value[prop])) { + if (value[prop].length > 20) + obj[prop] = value[prop].slice(value[prop].length - 20); + else + obj[prop] = value[prop]; + } else if (value[prop].constructor.name === "Object") { + obj[prop] = {}; + for (const p in value[prop]) { + if (Array.isArray(value[prop][p])) { + if (value[prop][p].length > 20) + obj[prop][p] = value[prop][p].slice(value[prop][p].length - 20); + else + obj[prop][p] = value[prop][p]; + } else { + if (value[prop][p] != null) { + let con = value[prop][p].constructor.name; + if (con.includes("Set")) { + obj[prop][p] = Array.from(value[prop][p]); + } else if (con !== "Number" && con !== "String" && con !== "Boolean") { + obj[prop][p] = "instanceof_" + con; + } else { + obj[prop][p] = value[prop][p]; + } + } else { + obj[prop][p] = value[prop][p]; + } + } + } + } else { + let con = value[prop].constructor.name; + if (con.includes("Set")) { + obj[prop] = Array.from(value[prop]); + } else if (con !== "Number" && con !== "String" && con !== "Boolean") { + obj[prop] = "instanceof_" + con; + } else { + obj[prop] = value[prop]; + } + } + } + val = obj; + } else { + val = value; + } + } else { + val = value; + } + } + return val; + } + return function stringifyFast2(obj, space) { + parents.push(obj); + let res = JSON.stringify(obj, checkValues, space); + clear(); + return res; + }; + }(); + if (JSON.stringifyFast === void 0) { + JSON.stringifyFast = stringifyFast; + } + function createNode(operator, parentNode, props, graph) { + if (typeof props === "object") { + props.operator = operator; + return new GraphNode(props, parentNode, graph); + } + return new GraphNode({ operator }, parentNode, graph); + } + + // ../../../services/Service.ts + var Service = class extends Graph { + constructor(options = {}) { + super(void 0, options.name, options.props); + this.routes = {}; + this.loadDefaultRoutes = false; + this.name = `service${Math.floor(Math.random() * 1e14)}`; + this.keepState = true; + this.load = (routes2, includeClassName = true, routeFormat = ".") => { + if (!routes2 && !this.loadDefaultRoutes) + return; + let service; + if (!(routes2 instanceof Graph) && routes2?.name) { + if (routes2.module) { + let mod = routes2; + routes2 = {}; + Object.getOwnPropertyNames(routes2.module).forEach((prop) => { + if (includeClassName) + routes2[mod.name + routeFormat + prop] = routes2.module[prop]; + else + routes2[prop] = routes2.module[prop]; + }); + } else if (typeof routes2 === "function") { + service = new routes2({ loadDefaultRoutes: this.loadDefaultRoutes }); + service.load(); + routes2 = service.routes; + } + } else if (routes2 instanceof Graph || routes2.source instanceof Graph) { + service = routes2; + routes2 = {}; + let name; + if (includeClassName) { + name = service.name; + if (!name) { + name = service.tag; + service.name = name; + } + if (!name) { + name = `graph${Math.floor(Math.random() * 1e15)}`; + service.name = name; + service.tag = name; + } + } + service.nodes.forEach((node) => { + routes2[node.tag] = node; + let checked = {}; + let checkChildGraphNodes = (nd, prev) => { + if (!checked[nd.tag] || prev && includeClassName && !checked[prev?.tag + routeFormat + nd.tag]) { + if (!prev) + checked[nd.tag] = true; + else + checked[prev.tag + routeFormat + nd.tag] = true; + if (nd instanceof Graph || nd.source instanceof Graph) { + if (includeClassName) { + let nm = nd.name; + if (!nm) { + nm = nd.tag; + nd.name = nm; + } + if (!nm) { + nm = `graph${Math.floor(Math.random() * 1e15)}`; + nd.name = nm; + nd.tag = nm; + } + } + nd.nodes.forEach((n) => { + if (includeClassName) + routes2[nd.tag + routeFormat + n.tag] = n; + else if (!routes2[n.tag]) + routes2[n.tag] = n; + checkChildGraphNodes(n, nd); + }); + } + } + }; + checkChildGraphNodes(node); + }); + } else if (typeof routes2 === "object") { + let name = routes2.constructor.name; + if (name === "Object") { + name = Object.prototype.toString.call(routes2); + if (name) + name = name.split(" ")[1]; + if (name) + name = name.split("]")[0]; + } + if (name && name !== "Object") { + let module = routes2; + routes2 = {}; + Object.getOwnPropertyNames(module).forEach((route) => { + if (includeClassName) + routes2[name + routeFormat + route] = module[route]; + else + routes2[route] = module[route]; + }); + } + } + if (service instanceof Graph && service.name && includeClassName) { + routes2 = Object.assign({}, routes2); + for (const prop in routes2) { + let route = routes2[prop]; + delete routes2[prop]; + routes2[service.name + routeFormat + prop] = route; + } + } + if (this.loadDefaultRoutes) { + let rts = Object.assign({}, this.defaultRoutes); + if (routes2) { + Object.assign(rts, this.routes); + routes2 = Object.assign(rts, routes2); + } else + routes2 = Object.assign(rts, this.routes); + this.loadDefaultRoutes = false; + } + for (const tag2 in routes2) { + let childrenIter = (route) => { + if (typeof route?.children === "object") { + for (const key in route.children) { + if (typeof route.children[key] === "object") { + let rt = route.children[key]; + if (!rt.parent) + rt.parent = tag2; + if (rt.tag) { + routes2[rt.tag] = route.children[key]; + childrenIter(routes2[rt.tag]); + } else if (rt.id) { + rt.tag = rt.id; + routes2[rt.tag] = route.children[key]; + childrenIter(routes2[rt.tag]); + } + } + } + } + }; + childrenIter(routes2[tag2]); + } + for (const route in routes2) { + if (typeof routes2[route] === "object") { + let r = routes2[route]; + if (typeof r === "object") { + if (r.get) { + if (typeof r.get == "object") { + } + } + if (r.post) { + } + if (r.delete) { + } + if (r.put) { + } + if (r.head) { + } + if (r.patch) { + } + if (r.options) { + } + if (r.connect) { + } + if (r.trace) { + } + if (r.post && !r.operator) { + routes2[route].operator = r.post; + } else if (!r.operator && typeof r.get == "function") { + routes2[route].operator = r.get; + } + } + if (this.routes[route]) { + if (typeof this.routes[route] === "object") + Object.assign(this.routes[route], routes2[route]); + else + this.routes[route] = routes2[route]; + } else + this.routes[route] = routes2[route]; + } else if (this.routes[route]) { + if (typeof this.routes[route] === "object") + Object.assign(this.routes[route], routes2[route]); + else + this.routes[route] = routes2[route]; + } else + this.routes[route] = routes2[route]; + } + this.setTree(this.routes); + for (const prop in this.routes) { + if (this.routes[prop]?.aliases) { + let aliases = this.routes[prop].aliases; + aliases.forEach((a) => { + if (service) + routes2[service.name + routeFormat + a] = this.routes[prop]; + else + routes2[a] = this.routes[prop]; + }); + } + } + return this.routes; + }; + this.unload = (routes2 = this.routes) => { + if (!routes2) + return; + let service; + if (!(routes2 instanceof Service) && typeof routes2 === "function") { + service = new Service(); + routes2 = service.routes; + } else if (routes2 instanceof Service) { + routes2 = routes2.routes; + } + for (const r in routes2) { + delete this.routes[r]; + if (this.nodes.get(r)) + this.remove(r); + } + return this.routes; + }; + this.handleMethod = (route, method, args, origin) => { + let m = method.toLowerCase(); + if (m === "get" && this.routes[route]?.get?.transform instanceof Function) { + if (Array.isArray(args)) + return this.routes[route].get.transform(...args); + else + return this.routes[route].get.transform(args); + } + if (this.routes[route]?.[m]) { + if (!(this.routes[route][m] instanceof Function)) { + if (args) + this.routes[route][m] = args; + return this.routes[route][m]; + } else + return this.routes[route][m](args); + } else + return this.handleServiceMessage({ route, args, method, origin }); + }; + this.transmit = (...args) => { + if (typeof args[0] === "object") { + if (args[0].method) { + return this.handleMethod(args[0].route, args[0].method, args[0].args); + } else if (args[0].route) { + return this.handleServiceMessage(args[0]); + } else if (args[0].node) { + return this.handleGraphNodeCall(args[0].node, args[0].args, args[0].origin); + } else if (this.keepState) { + if (args[0].route) + this.setState({ [args[0].route]: args[0].args }); + if (args[0].node) + this.setState({ [args[0].node]: args[0].args }); + } + } else + return args; + }; + this.receive = (...args) => { + if (args[0]) { + if (typeof args[0] === "string") { + let substr = args[0].substring(0, 8); + if (substr.includes("{") || substr.includes("[")) { + if (substr.includes("\\")) + args[0] = args[0].replace(/\\/g, ""); + if (args[0][0] === '"') { + args[0] = args[0].substring(1, args[0].length - 1); + } + ; + args[0] = JSON.parse(args[0]); + } + } + } + if (typeof args[0] === "object") { + if (args[0].method) { + return this.handleMethod(args[0].route, args[0].method, args[0].args); + } else if (args[0].route) { + return this.handleServiceMessage(args[0]); + } else if (args[0].node) { + return this.handleGraphNodeCall(args[0].node, args[0].args, args[0].origin); + } else if (this.keepState) { + if (args[0].route) + this.setState({ [args[0].route]: args[0].args }); + if (args[0].node) + this.setState({ [args[0].node]: args[0].args }); + } + } else + return args; + }; + this.pipe = (source, destination, endpoint, origin, method, callback) => { + if (source instanceof GraphNode) { + if (callback) + return source.subscribe((res) => { + let mod = callback(res); + if (mod !== void 0) + this.transmit({ route: destination, args: mod, origin, method }); + else + this.transmit({ route: destination, args: res, origin, method }, endpoint); + }); + else + return this.subscribe(source, (res) => { + this.transmit({ route: destination, args: res, origin, method }, endpoint); + }); + } else if (typeof source === "string") + return this.subscribe(source, (res) => { + this.transmit({ route: destination, args: res, origin, method }, endpoint); + }); + }; + this.pipeOnce = (source, destination, endpoint, origin, method, callback) => { + if (source instanceof GraphNode) { + if (callback) + return source.state.subscribeTriggerOnce(source.tag, (res) => { + let mod = callback(res); + if (mod !== void 0) + this.transmit({ route: destination, args: mod, origin, method }); + else + this.transmit({ route: destination, args: res, origin, method }, endpoint); + }); + else + return this.state.subscribeTriggerOnce(source.tag, (res) => { + this.transmit({ route: destination, args: res, origin, method }, endpoint); + }); + } else if (typeof source === "string") + return this.state.subscribeTriggerOnce(source, (res) => { + this.transmit({ route: destination, args: res, origin, method }, endpoint); + }); + }; + this.terminate = (...args) => { + this.nodes.forEach((n) => { + n.stopNode(); + }); + }; + this.recursivelyAssign = (target, obj) => { + for (const key in obj) { + if (typeof obj[key] === "object") { + if (typeof target[key] === "object") + this.recursivelyAssign(target[key], obj[key]); + else + target[key] = this.recursivelyAssign({}, obj[key]); + } else + target[key] = obj[key]; + } + return target; + }; + this.defaultRoutes = { + "/": { + get: () => { + return this.print(); + }, + aliases: [""] + }, + ping: () => { + console.log("ping"); + return "pong"; + }, + echo: (...args) => { + this.transmit(...args); + return args; + }, + assign: (source) => { + if (typeof source === "object") { + Object.assign(this, source); + return true; + } + return false; + }, + recursivelyAssign: (source) => { + if (typeof source === "object") { + this.recursivelyAssign(this, source); + return true; + } + return false; + }, + log: { + post: (...args) => { + console.log("Log: ", ...args); + }, + aliases: ["info"] + }, + error: (message) => { + let er = new Error(message); + console.error(message); + return er; + }, + state: (key) => { + if (key) { + return this.state.data[key]; + } else + return this.state.data; + }, + printState: (key) => { + if (key) { + return stringifyWithCircularRefs(this.state.data[key]); + } else + return stringifyWithCircularRefs(this.state.data); + }, + transmit: this.transmit, + receive: this.receive, + load: this.load, + unload: this.unload, + pipe: this.pipe, + terminate: this.terminate, + run: this.run, + _run: this._run, + subscribe: this.subscribe, + unsubscribe: this.unsubscribe, + stopNode: this.stopNode, + get: this.get, + add: this.add, + remove: this.remove, + setTree: this.setTree, + setState: this.setState, + print: this.print, + reconstruct: this.reconstruct, + handleMethod: this.handleMethod, + handleServiceMessage: this.handleServiceMessage, + handleGraphNodeCall: this.handleGraphNodeCall + }; + if ("loadDefaultRoutes" in options) + this.loadDefaultRoutes = options.loadDefaultRoutes; + if (options.name) + this.name = options.name; + if (Array.isArray(options.routes)) { + options.routes.forEach((r) => { + this.load(r); + }); + } else if (options.routes) + this.load(options.routes); + } + handleServiceMessage(message) { + let call; + if (typeof message === "object") { + if (message.route) + call = message.route; + else if (message.node) + call = message.node; + } + if (call) { + if (message.origin) { + if (Array.isArray(message.args)) + return this._run(call, message.origin, ...message.args); + else + return this._run(call, message.origin, message.args); + } else { + if (Array.isArray(message.args)) + return this.run(call, ...message.args); + else + return this.run(call, message.args); + } + } else + return message; + } + handleGraphNodeCall(route, args, origin) { + if (!route) + return args; + if (args?.args) { + this.handleServiceMessage(args); + } else if (origin) { + if (Array.isArray(args)) + return this._run(route, origin, ...args); + else + return this._run(route, origin, args); + } else if (Array.isArray(args)) + return this.run(route, ...args); + else + return this.run(route, args); + } + isTypedArray(x) { + return ArrayBuffer.isView(x) && Object.prototype.toString.call(x) !== "[object DataView]"; + } + }; + + // ../../../routers/Router.ts + var Router = class { + constructor(services, options) { + this.id = `router${Math.floor(Math.random() * 1e15)}`; + this.service = new Service(); + this.nodes = this.service.nodes; + this.run = this.service.run; + this._run = this.service._run; + this.add = this.service.add; + this.remove = this.service.remove; + this.stopNode = this.service.stopNode; + this.subscribe = this.service.subscribe; + this.unsubscribe = this.service.unsubscribe; + this.get = this.service.get; + this.reconstruct = this.service.reconstruct; + this.setState = this.service.setState; + this.recursivelyAssign = this.service.recursivelyAssign; + this.state = this.service.state; + this.routes = this.service.routes; + this.services = {}; + this.loadDefaultRoutes = false; + this.load = (service, linkServices = true, includeClassName = true) => { + if (!(service instanceof Graph) && typeof service === "function") { + service = new service({ loadDefaultRoutes: this.loadDefaultRoutes }, service.name); + service.load(); + } else if (!service) + return; + if (service instanceof Graph && service.name) { + this.services[service.name] = service; + } else { + if (service.constructor.name === "Object") { + let name = Object.prototype.toString.call(service); + if (name) + name = name.split(" ")[1]; + if (name) + name = name.split("]")[0]; + if (name && name !== "Object" && name !== "Function") { + this.services[name] = service; + } + } else + this.services[service.constructor.name] = service; + } + this.service.load(service, includeClassName); + if (linkServices) { + for (const name in this.services) { + this.service.nodes.forEach((n) => { + if (this.services[name]?.nodes) { + if (!this.services[name].nodes.get(n.tag)) { + this.services[name].nodes.set(n.tag, n); + } + } + }); + } + } + return this.services[service.name]; + }; + this.pipe = (source, destination, transmitter, origin, method, callback) => { + if (!transmitter && source && destination) { + if (callback) + return this.subscribe(source, (res) => { + let mod = callback(res); + if (mod) + res = mod; + this.run(destination, res); + }); + return this.subscribe(source, (res) => { + this.run(destination, res); + }); + } + if (transmitter) { + if (transmitter === "sockets") + transmitter = "wss"; + const radio = this.services[transmitter]; + if (radio) { + if (callback) { + return this.subscribe(source, (res) => { + let mod = callback(res); + if (mod) + res = mod; + radio.transmit({ route: destination, args: res, origin, method }); + }); + } else + return this.subscribe(source, (res) => { + radio.transmit({ route: destination, args: res, origin, method }); + }); + } else { + let endpoint = this.getEndpointInfo(transmitter); + if (endpoint) { + return this.services[endpoint.service].pipe(source, destination, transmitter, origin, method, callback); + } + } + } + return false; + }; + this.pipeOnce = (source, destination, transmitter, origin, method, callback) => { + if (source instanceof GraphNode) + source = source.tag; + if (!transmitter && typeof source === "string" && destination) { + if (callback) + return this.state.subscribeTriggerOnce(source, (res) => { + let mod = callback(res); + if (mod) + res = mod; + this.run(destination, res); + }); + return this.state.subscribeTriggerOnce(source, (res) => { + this.run(destination, res); + }); + } + if (transmitter) { + if (transmitter === "sockets") + transmitter = "wss"; + const radio = this.services[transmitter]; + if (radio) { + if (callback) { + return this.state.subscribeTriggerOnce(source, (res) => { + let mod = callback(res); + if (mod) + res = mod; + radio.transmit({ route: destination, args: res, origin, method }); + }); + } else + return this.state.subscribeTriggerOnce(source, (res) => { + radio.transmit({ route: destination, args: res, origin, method }); + }); + } else { + let endpoint = this.getEndpointInfo(transmitter); + if (endpoint) { + return this.services[endpoint.service].pipeOnce(source, destination, transmitter, origin, method, callback); + } + } + } + return false; + }; + this.sendAll = (message, connections, channel) => { + let sent = false; + if (typeof connections === "object") { + for (const protocol in connections) { + for (const info in connections[protocol]) { + let obj = connections[protocol][info]; + if (obj.socket) { + if (obj.socket.readyState === 1) { + obj.socket.send(message); + sent = true; + } else + delete connections[protocol][info]; + } else if (obj.wss) { + obj.wss.clients.forEach((c) => { + c.send(message); + }); + sent = true; + } else if (obj.sessions) { + if (channel) { + obj.channel.broadcast(message, channel); + sent = true; + } else + for (const s in obj.sessions) { + if (obj.sessions[s].isConnected) { + obj.sessions[s].push(message); + sent = true; + } + } + } else if (obj.session) { + if (channel) { + obj.served.channel.broadcast(message, channel); + sent = true; + } else if (obj.session.isConnected) { + obj.session.push(message); + sent = true; + } else + delete connections[protocol][info]; + } else if (obj.rtc) { + if (channel && obj.channels[channel]) { + obj.channels[channel].send(message); + sent = true; + } else if (obj.channels.data) { + obj.channels.data.send(message); + sent = true; + } else { + let firstchannel = Object.keys(obj.channels)[0]; + obj.channels[firstchannel].send(message); + sent = true; + } + } else if (obj.server) { + if (this.services.http) { + this.services.http.transmit(message, channel); + sent = true; + } + } + } + } + } + return sent; + }; + this.getEndpointInfo = (path, service) => { + if (!path) + return void 0; + let testpath = (path2, service2) => { + if (this.services[service2]) { + if (this.services[service2].rtc?.[path2]) { + return this.services[service2].rtc[path2]; + } else if (this.services[service2].servers?.[path2]) { + return this.services[service2].servers[path2]; + } else if (this.services[service2].sockets?.[path2]) { + return this.services[service2].sockets[path2]; + } else if (this.services[service2].eventsources?.[path2]) { + return this.services[service2].eventsources[path2]; + } else if (this.services[service2].workers?.[path2]) { + return this.services[service2].workers[path2]; + } + } + return void 0; + }; + if (service) { + let found = testpath(path, service); + if (found) + return { + endpoint: found, + service + }; + } + for (const s in this.services) { + let found = testpath(path, s); + if (found) + return { + endpoint: found, + service: s + }; + } + return void 0; + }; + this.pipeFastest = (source, destination, origin, method, callback, services = this.services) => { + for (const service in services) { + if (services[service].rtc) { + return this.pipe(source, destination, "webrtc", origin, method, callback); + } + if (services[service].eventsources) { + let keys = Object.keys(services[service].eventsources); + if (keys[0]) { + if (this.services[service].eventsources[keys[0]].sessions) + return this.pipe(source, destination, "sse", origin, method, callback); + } + } + if (services[service].sockets) { + return this.pipe(source, destination, "wss", origin, method, callback); + } + if (services[service].servers) { + return this.pipe(source, destination, "http", origin, method, callback); + } + if (services[service].workers) { + return this.pipe(source, destination, "worker", origin, method, callback); + } + } + return false; + }; + this.getFirstRemoteEndpoint = (services = this.services) => { + let serviceInfo; + for (const service in services) { + if (services[service].rtc) { + serviceInfo = services[service].rtc; + } + if (services[service].eventsources && !serviceInfo) { + let keys2 = Object.keys(services[service].eventsources); + if (keys2[0]) { + if (this.services[service].eventsources[keys2[0]]?.sessions) + serviceInfo = services[service].eventsources; + } + } + if (services[service].sockets && !serviceInfo) { + serviceInfo = services[service].sockets; + } + if (services[service].servers && !serviceInfo) { + serviceInfo = services[service].servers; + } + if (services[service].workers && !serviceInfo) { + serviceInfo = services[service].workers; + } + } + let keys = Object.keys(serviceInfo); + if (keys[0]) + return serviceInfo[keys[0]]; + return false; + }; + this.STREAMLATEST = 0; + this.STREAMALLLATEST = 1; + this.streamSettings = {}; + this.streamFunctions = { + allLatestValues: (prop, setting) => { + let result = void 0; + if (Array.isArray(prop)) { + if (prop.length !== setting.lastRead) { + result = prop.slice(setting.lastRead); + setting.lastRead = prop.length; + } + } else if (typeof prop === "object") { + result = {}; + for (const p in prop) { + if (Array.isArray(prop[p])) { + if (typeof setting === "number") + setting = { [p]: { lastRead: void 0 } }; + else if (!setting[p]) + setting[p] = { lastRead: void 0 }; + if (prop[p].length !== setting[p].lastRead) { + result[p] = prop[p].slice(setting[p].lastRead); + setting[p].lastRead = prop[p].length; + } + } else { + if (typeof setting === "number") + setting = { [p]: { lastRead: void 0 } }; + else if (!setting[p]) + setting[p] = { lastRead: void 0 }; + if (setting[p].lastRead !== prop[p]) { + result[p] = prop[p]; + setting[p].lastRead = prop[p]; + } + } + } + if (Object.keys(result).length === 0) + result = void 0; + } else { + if (setting.lastRead !== prop) { + result = prop; + setting.lastRead = prop; + } + } + return result; + }, + latestValue: (prop, setting) => { + let result = void 0; + if (Array.isArray(prop)) { + if (prop.length !== setting.lastRead) { + result = prop[prop.length - 1]; + setting.lastRead = prop.length; + } + } else if (typeof prop === "object") { + result = {}; + for (const p in prop) { + if (Array.isArray(prop[p])) { + if (typeof setting === "number") + setting = { [p]: { lastRead: void 0 } }; + else if (!setting[p]) + setting[p] = { lastRead: void 0 }; + if (prop[p].length !== setting[p].lastRead) { + result[p] = prop[p][prop[p].length - 1]; + setting[p].lastRead = prop[p].length; + } + } else { + if (typeof setting === "number") + setting = { [p]: { lastRead: void 0 } }; + else if (!setting[p]) + setting[p] = { lastRead: void 0 }; + if (setting[p].lastRead !== prop[p]) { + result[p] = prop[p]; + setting[p].lastRead = prop[p]; + } + } + } + } else { + if (setting.lastRead !== prop) { + result = prop; + setting.lastRead = prop; + } + } + return result; + } + }; + this.setStreamFunc = (name, key, callback = this.streamFunctions.allLatestValues) => { + if (!this.streamSettings[name].settings[key]) + this.streamSettings[name].settings[key] = { lastRead: 0 }; + if (callback === this.STREAMLATEST) + this.streamSettings[name].settings[key].callback = this.streamFunctions.latestValue; + else if (callback === this.STREAMALLLATEST) + this.streamSettings[name].settings[key].callback = this.streamFunctions.allLatestValues; + else if (typeof callback === "string") + this.streamSettings[name].settings[key].callback = this.streamFunctions[callback]; + else if (typeof callback === "function") + this.streamSettings[name].settings[key].callback = callback; + if (!this.streamSettings[name].settings[key].callback) + this.streamSettings[name].settings[key].callback = this.streamFunctions.allLatestValues; + return true; + }; + this.addStreamFunc = (name, callback = (data) => { + }) => { + this.streamFunctions[name] = callback; + }; + this.setStream = (object = {}, settings = {}, streamName = `stream${Math.floor(Math.random() * 1e10)}`) => { + if (settings.keys) { + if (settings.keys.length === 0) { + let k = Object.keys(object); + if (k.length > 0) { + settings.keys = Array.from(k); + } + } + } else { + settings.keys = Array.from(Object.keys(object)); + } + this.streamSettings[streamName] = { + object, + settings + }; + settings.keys.forEach((prop) => { + if (settings[prop]?.callback) + this.setStreamFunc(streamName, prop, settings[prop].callback); + else + this.setStreamFunc(streamName, prop, settings.callback); + }); + return this.streamSettings[streamName]; + }; + this.removeStream = (streamName, key) => { + if (streamName && !key) + delete this.streamSettings[streamName]; + else if (key && this.streamSettings[streamName]?.settings?.keys) { + let idx = this.streamSettings[streamName].settings.keys.indexOf(key); + if (idx > -1) + this.streamSettings[streamName].settings.keys.splice(idx, 1); + if (this.streamSettings[streamName].settings[key]) + delete this.streamSettings[streamName].settings[key]; + return true; + } + return false; + }; + this.updateStreamData = (streamName, data = {}) => { + if (this.streamSettings[streamName]) { + Object.assign(this.streamSettings[streamName].object, data); + return this.streamSettings[streamName].object; + } + return false; + }; + this.streamLoop = (connections, channel) => { + let updateObj = {}; + for (const prop in this.streamSettings) { + this.streamSettings[prop].settings.keys.forEach((key) => { + if (this.streamSettings[prop].settings[key]) { + let data = this.streamSettings[prop].settings[key].callback(this.streamSettings[prop].object[key], this.streamSettings[prop].settings[key]); + if (data !== void 0) + updateObj[key] = data; + } + }); + } + if (connections) { + this.sendAll(updateObj, connections, channel); + } + return updateObj; + }; + this.receive = (message, service, ...args) => { + if (service) + for (const key in this.services) { + if (key === service || this.services[key].name === service) { + return this.services[key].receive(message, ...args); + } + } + return this.service.receive(message, ...args); + }; + this.transmit = (message, service, ...args) => { + if (service) + for (const key in this.services) { + if (key === service || this.services[key].name === service) { + return this.services[key].transmit(message, ...args); + } + } + return this.service.transmit(message, ...args); + }; + this.defaultRoutes = { + getEndpointInfo: this.getEndpointInfo, + pipeOnce: this.pipeOnce, + pipeFastest: this.pipeFastest, + setStream: this.setStream, + removeStream: this.removeStream, + updateStreamData: this.updateStreamData, + addStreamFunc: this.addStreamFunc, + setStreamFunc: this.setStreamFunc, + sendAll: this.sendAll, + streamLoop: { + operator: this.streamLoop, + loop: 10 + } + }; + if (options && "loadDefaultRoutes" in options) { + this.loadDefaultRoutes = options.loadDefaultRoutes; + } + if (this.loadDefaultRoutes) + this.load(this.defaultRoutes, options?.linkServices, options?.includeClassName); + if (Array.isArray(services)) { + services.forEach((s) => this.load(s, options?.linkServices, options?.includeClassName)); + } else if (typeof services === "object") { + Object.keys(services).forEach((s) => this.load(services[s], options?.linkServices, options?.includeClassName)); + } + } + }; + + // ../../../services/dom/DOMElement.js + var DOMElement = class extends HTMLElement { + constructor() { + super(); + __publicField(this, "template", (props, self = this) => { + return `
    Custom Fragment Props: ${JSON.stringify(props)}
    `; + }); + __publicField(this, "props", {}); + __publicField(this, "useShadow", false); + __publicField(this, "styles"); + __publicField(this, "oncreate"); + __publicField(this, "onresize"); + __publicField(this, "ondelete"); + __publicField(this, "onchanged"); + __publicField(this, "renderonchanged", false); + __publicField(this, "FRAGMENT"); + __publicField(this, "attachedShadow", false); + __publicField(this, "obsAttributes", ["props", "options", "onchanged", "onresize", "ondelete", "oncreate", "template"]); + __publicField(this, "delete", () => { + this.remove(); + if (typeof this.ondelete === "function") + this.ondelete(this.props); + }); + __publicField(this, "render", (props = this.props) => { + if (typeof this.template === "function") + this.templateResult = this.template(props, this); + else + this.templateResult = this.template; + const t = document.createElement("template"); + if (typeof this.templateResult === "string") + t.innerHTML = this.templateResult; + else if (this.templateResult instanceof HTMLElement) { + if (this.templateResult.parentNode) { + this.templateResult.parentNode.removeChild(this.templateResult); + } + t.appendChild(this.templateResult); + } + const fragment = t.content; + if (this.FRAGMENT) { + if (this.useShadow) { + this.shadowRoot.removeChild(this.FRAGMENT); + } else + this.removeChild(this.FRAGMENT); + } + if (this.useShadow) { + if (!this.attachedShadow) + this.attachShadow({ mode: "open" }); + this.shadowRoot.prepend(fragment); + this.FRAGMENT = this.shadowRoot.childNodes[0]; + } else + this.prepend(fragment); + this.FRAGMENT = this.childNodes[0]; + let rendered = new CustomEvent("rendered", { detail: { props: this.props, self: this } }); + this.dispatchEvent("rendered"); + if (this.oncreate) + this.oncreate(this, props); + }); + __publicField(this, "state", { + pushToState: {}, + data: {}, + triggers: {}, + setState(updateObj) { + Object.assign(this.pushToState, updateObj); + if (Object.keys(this.triggers).length > 0) { + for (const prop of Object.getOwnPropertyNames(this.triggers)) { + if (this.pushToState[prop]) { + this.data[prop] = this.pushToState[prop]; + delete this.pushToState[prop]; + this.triggers[prop].forEach((obj) => { + obj.onchanged(this.data[prop]); + }); + } + } + } + return this.pushToState; + }, + subscribeTrigger(key, onchanged = (res) => { + }) { + if (key) { + if (!this.triggers[key]) { + this.triggers[key] = []; + } + let l = this.triggers[key].length; + this.triggers[key].push({ idx: l, onchanged }); + return this.triggers[key].length - 1; + } else + return void 0; + }, + unsubscribeTrigger(key, sub) { + let idx = void 0; + let triggers = this.triggers[key]; + if (triggers) { + if (!sub) + delete this.triggers[key]; + else { + let obj = triggers.find((o) => { + if (o.idx === sub) { + return true; + } + }); + if (obj) + triggers.splice(idx, 1); + return true; + } + } + }, + subscribeTriggerOnce(key = void 0, onchanged = (value) => { + }) { + let sub; + let changed = (value) => { + onchanged(value); + this.unsubscribeTrigger(key, sub); + }; + sub = this.subscribeTrigger(key, changed); + } + }); + } + get observedAttributes() { + return this.obsAttributes; + } + get obsAttributes() { + return this.obsAttributes; + } + set obsAttributes(att) { + if (typeof att === "string") { + this.obsAttributes.push(att); + } else if (Array.isArray(att)) + this.obsAttributes = att; + } + static get tag() { + return this.name.toLowerCase() + "-"; + } + static addElement(tag2 = this.tag, cls = this, extend = void 0) { + addCustomElement(cls, tag2, extend); + } + attributeChangedCallback(name, old, val) { + if (name === "onchanged") { + let onchanged = val; + if (typeof onchanged === "string") + onchanged = parseFunctionFromText2(onchanged); + if (typeof onchanged === "function") { + this.onchanged = onchanged; + this.state.data.props = this.props; + this.state.unsubscribeTrigger("props"); + this.state.subscribeTrigger("props", this.onchanged); + let changed = new CustomEvent("changed", { detail: { props: this.props, self: this } }); + this.state.subscribeTrigger("props", () => { + this.dispatchEvent(changed); + }); + } + } else if (name === "onresize") { + let onresize = val; + if (typeof onresize === "string") + onresize = parseFunctionFromText2(onresize); + if (typeof onresize === "function") { + if (this.ONRESIZE) { + try { + window.removeEventListener("resize", this.ONRESIZE); + } catch (err) { + } + } + this.ONRESIZE = (ev) => { + this.onresize(this.props, this); + }; + this.onresize = onresize; + window.addEventListener("resize", this.ONRESIZE); + } + } else if (name === "ondelete") { + let ondelete = val; + if (typeof ondelete === "string") + ondelete = parseFunctionFromText2(ondelete); + if (typeof ondelete === "function") { + this.ondelete = () => { + if (this.ONRESIZE) + window.removeEventListener("resize", this.ONRESIZE); + this.state.unsubscribeTrigger("props"); + if (ondelete) + ondelete(this.props, this); + }; + } + } else if (name === "oncreate") { + let oncreate = val; + if (typeof oncreate === "string") + oncreate = parseFunctionFromText2(oncreate); + if (typeof oncreate === "function") { + this.oncreate = oncreate; + } + } else if (name === "renderonchanged") { + let rpc = val; + if (typeof this.renderonchanged === "number") + this.unsubscribeTrigger(this.renderonchanged); + if (typeof rpc === "string") + rpc = parseFunctionFromText2(rpc); + if (typeof rpc === "function") { + this.renderonchanged = this.state.subscribeTrigger("props", (p) => { + this.render(p); + rpc(this, p); + }); + } else if (rpc != false) + this.renderonchanged = this.state.subscribeTrigger("props", this.render); + } else if (name === "props") { + let newProps = val; + if (typeof newProps === "string") + newProps = JSON.parse(newProps); + Object.assign(this.props, newProps); + this.state.setState({ props: this.props }); + } else if (name === "template") { + let template = val; + this.template = template; + this.render(this.props); + let created = new CustomEvent("created", { detail: { props: this.props } }); + this.dispatchEvent(created); + } else { + let parsed = val; + if (name.includes("eval_")) { + name = name.split("_"); + name.shift(); + name = name.join(); + parsed = parseFunctionFromText2(val); + } else if (typeof val === "string") { + try { + parsed = JSON.parse(val); + } catch (err) { + parsed = val; + } + } + this[name] = parsed; + if (name !== "props") + this.props[name] = parsed; + } + } + connectedCallback() { + let newProps = this.getAttribute("props"); + if (typeof newProps === "string") + newProps = JSON.parse(newProps); + Object.assign(this.props, newProps); + this.state.setState({ props: this.props }); + Array.from(this.attributes).forEach((att) => { + let name = att.name; + let parsed = att.value; + if (name.includes("eval_")) { + name = name.split("_"); + name.shift(); + name = name.join(); + parsed = parseFunctionFromText2(att.value); + } else if (typeof att.value === "string") { + try { + parsed = JSON.parse(att.value); + } catch (err) { + parsed = att.value; + } + } + if (!this[name]) { + Object.defineProperties(this, att, { + value: parsed, + writable: true, + get() { + return this[name]; + }, + set(val) { + this.setAttribute(name, val); + } + }); + } + this[name] = parsed; + if (name !== "props") + this.props[name] = parsed; + this.obsAttributes.push(name); + }); + let resizeevent = new CustomEvent("resized", { detail: { props: this.props, self: this } }); + let changed = new CustomEvent("changed", { detail: { props: this.props, self: this } }); + let deleted = new CustomEvent("deleted", { detail: { props: this.props, self: this } }); + let created = new CustomEvent("created", { detail: { props: this.props, self: this } }); + if (this.styles) { + let elm = ` + + `; + if (this.template.indexOf(" { + this.dispatchEvent(changed); + }); + if (typeof this.onresize === "function") { + if (this.ONRESIZE) { + try { + window.removeEventListener("resize", this.ONRESIZE); + } catch (err) { + } + } + this.ONRESIZE = (ev) => { + this.onresize(this, this.props); + this.dispatchEvent(resizeevent); + }; + window.addEventListener("resize", this.ONRESIZE); + } + if (typeof this.ondelete === "function") { + let ondelete = this.ondelete; + this.ondelete = (props = this.props) => { + if (this.ONRESIZE) + window.removeEventListener("resize", this.ONRESIZE); + this.state.unsubscribeTrigger("props"); + this.dispatchEvent(deleted); + ondelete(this, props); + }; + } + if (typeof this.onchanged === "function") { + this.state.data.props = this.props; + this.state.subscribeTrigger("props", this.onchanged); + } + if (this.renderonchanged) { + let rpc = this.renderonchanged; + if (typeof this.renderonchanged === "number") + this.unsubscribeTrigger(this.renderonchanged); + if (typeof rpc === "string") + rpc = parseFunctionFromText2(rpc); + if (typeof rpc === "function") { + this.renderonchanged = this.state.subscribeTrigger("props", (p) => { + this.render(p); + rpc(this, p); + }); + } else if (rpc !== false) + this.renderonchanged = this.state.subscribeTrigger("props", this.render); + } + } + get props() { + return this.props; + } + set props(newProps = {}) { + this.setAttribute("props", newProps); + } + get template() { + return this.template; + } + set template(template) { + this.setAttribute("template", template); + } + get render() { + return this.render; + } + get delete() { + return this.delete; + } + get state() { + return this.state; + } + get onchanged() { + return this.onchanged; + } + set onchanged(onchanged) { + this.setAttribute("onchanged", onchanged); + } + get styles() { + return this.styles; + } + set styles(templateStr2) { + let elm = ` + + `; + if (this.template.indexOf(" { + return methodString.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i, "$2$3$4"); + }; + let getFunctionHead = (methodString) => { + let startindex = methodString.indexOf(")"); + return methodString.slice(0, methodString.indexOf("{", startindex) + 1); + }; + let newFuncHead = getFunctionHead(method); + let newFuncBody = getFunctionBody(method); + let newFunc; + try { + if (newFuncHead.includes("function ")) { + let varName = newFuncHead.split("(")[1].split(")")[0]; + newFunc = new Function(varName, newFuncBody); + } else { + if (newFuncHead.substring(0, 6) === newFuncBody.substring(0, 6)) { + let varName = newFuncHead.split("(")[1].split(")")[0]; + newFunc = new Function(varName, newFuncBody.substring(newFuncBody.indexOf("{") + 1, newFuncBody.length - 1)); + } else { + try { + newFunc = (0, eval)(newFuncHead + newFuncBody + "}"); + } catch (err) { + newFunc = (0, eval)(method); + } + } + } + } catch (err) { + } + return newFunc; + } + + // ../../../services/dom/DOM.service.ts + var DOMService = class extends Graph { + constructor(options, parentNode) { + super(void 0, options.name, options.props); + this.routes = {}; + this.loadDefaultRoutes = false; + this.name = `dom${Math.floor(Math.random() * 1e15)}`; + this.keepState = true; + this.parentNode = document.body; + this.elements = {}; + this.components = {}; + this.templates = {}; + this.addElement = (options, generateChildElementNodes = false) => { + let elm = this.createElement(options); + let oncreate = options.oncreate; + delete options.oncreate; + if (!options.element) + options.element = elm; + if (!options.operator) + options.operator = (node2, origin, props) => { + if (typeof props === "object") + for (const key in props) { + if (node2.element) { + if (typeof node2.element[key] === "function" && typeof props[key] !== "function") { + if (Array.isArray(props[key])) + node2.element[key](...props[key]); + else + node2.element[key](props[key]); + } else if (key === "style") { + Object.assign(node2.element[key], props[key]); + } else + node2.element[key] = props[key]; + } + } + return props; + }; + let node = new GraphNode(options, void 0, this); + elm.node = node; + let divs = Array.from(elm.querySelectorAll("*")); + if (generateChildElementNodes) { + divs = divs.map((d, i) => this.addElement({ element: d })); + } + this.elements[options.id] = { element: elm, node, parentNode: options.parentNode, divs }; + if (options.onresize) { + let onresize = options.onresize; + options.onresize = (ev) => { + onresize(ev, elm, this.elements[options.id]); + }; + window.addEventListener("resize", options.onresize); + } + if (!elm.parentNode) { + setTimeout(() => { + if (typeof options.parentNode === "object") + options.parentNode.appendChild(elm); + if (oncreate) + oncreate(elm, this.elements[options.id]); + }, 0.01); + } + return this.elements[options.id]; + }; + this.createElement = (options) => { + let elm; + if (options.element) { + if (typeof options.element === "string") { + elm = document.querySelector(options.element); + if (!elm) + elm = document.getElementById(options.element); + } else + elm = options.element; + } else if (options.tagName) + elm = document.createElement(options.tagName); + else if (options.id && document.getElementById(options.id)) + elm = document.getElementById(options.id); + if (!elm) + return void 0; + this.updateOptions(options, elm); + return elm; + }; + this.updateOptions = (options, element) => { + if (!options.id) + options.id = `${options.tagName ?? "element"}${Math.floor(Math.random() * 1e15)}`; + if (!options.id && options.tag) + options.id = options.tag; + if (!options.tag && options.id) + options.tag = options.id; + if (!options.id) + options.id = options.tagName; + if (typeof options.parentNode === "string") + options.parentNode = document.getElementById(options.parentNode); + if (!options.parentNode) { + if (!this.parentNode) + this.parentNode = document.body; + options.parentNode = this.parentNode; + } + element.id = options.id; + if (options.style) + Object.assign(element.style, options.style); + if (options.innerHTML && element.innerHTML !== options.innerHTML) + element.innerHTML = options.innerHTML; + if (options.innerText && element.innerText !== options.innerText) + element.innerText = options.innerText; + if (options.attributes) + Object.assign(element, options.attributes); + return options; + }; + this.addComponent = (options, generateChildElementNodes = true) => { + if (options.oncreate) { + let oncreate = options.oncreate; + options.oncreate = (self) => { + oncreate(self, options); + }; + } + if (options.onresize) { + let onresize = options.onresize; + options.onresize = (self) => { + onresize(self, options); + }; + } + if (options.ondelete) { + let ondelete = options.ondelete; + options.ondelete = (self) => { + ondelete(self, options); + }; + } + if (typeof options.renderonchanged === "function") { + let renderonchanged = options.renderonchanged; + options.renderonchanged = (self) => { + renderonchanged(self, options); + }; + } + class CustomElement extends DOMElement { + constructor() { + super(...arguments); + this.props = options.props; + this.styles = options.styles; + this.template = options.template; + this.oncreate = options.oncreate; + this.onresize = options.onresize; + this.ondelete = options.ondelete; + this.renderonchanged = options.renderonchanged; + } + } + delete options.oncreate; + if (!options.tagName) + options.tagName = `custom-element${Math.random() * 1e15}`; + CustomElement.addElement(options.tagName); + let elm = document.createElement(options.tagName); + let completeOptions = this.updateOptions(options, elm); + this.templates[completeOptions.id] = completeOptions; + let divs = Array.from(elm.querySelectorAll("*")); + if (generateChildElementNodes) { + divs = divs.map((d) => this.addElement({ element: d })); + } + if (!options.element) + options.element = elm; + if (!options.operator) + options.operator = (node2, origin, props) => { + if (typeof props === "object") + for (const key in props) { + if (node2.element) { + if (typeof node2.element[key] === "function" && typeof props[key] !== "function") { + if (Array.isArray(props[key])) + node2.element[key](...props[key]); + else + node2.element[key](props[key]); + } else if (key === "style") { + Object.assign(node2.element[key], props[key]); + } else + node2.element[key] = props[key]; + } + } + return props; + }; + let node = new GraphNode(options, void 0, this); + elm.node = node; + this.components[completeOptions.id] = { + element: elm, + class: CustomElement, + node, + divs, + ...completeOptions + }; + if (!elm.parentNode) { + setTimeout(() => { + if (typeof options.parentNode === "object") + options.parentNode.appendChild(elm); + }, 0.01); + } + return this.components[completeOptions.id]; + }; + this.addCanvasComponent = (options) => { + if (!options.canvas) { + options.template = ``; + } else + options.template = options.canvas; + if (options.oncreate) { + let oncreate = options.oncreate; + options.oncreate = (self) => { + oncreate(self, options); + }; + } + if (options.onresize) { + let onresize = options.onresize; + options.onresize = (self) => { + onresize(self, options); + }; + } + if (options.ondelete) { + let ondelete = options.ondelete; + options.ondelete = (self) => { + ondelete(self, options); + }; + } + if (typeof options.renderonchanged === "function") { + let renderonchanged = options.renderonchanged; + options.renderonchanged = (self) => { + renderonchanged(self, options); + }; + } + class CustomElement extends DOMElement { + constructor() { + super(...arguments); + this.props = options.props; + this.styles = options.styles; + this.template = options.template; + this.oncreate = options.oncreate; + this.onresize = options.onresize; + this.ondelete = options.ondelete; + this.renderonchanged = options.renderonchanged; + } + } + delete options.oncreate; + if (!options.tagName) + options.tagName = `custom-element${Math.random() * 1e15}`; + CustomElement.addElement(options.tagName); + let elm = document.createElement(options.tagName); + const completeOptions = this.updateOptions(options, elm); + let animation = () => { + if (this.components[completeOptions.id]?.animating) { + this.components[completeOptions.id].draw(this.components[completeOptions.id].element, this.components[completeOptions.id]); + requestAnimationFrame(animation); + } + }; + this.templates[completeOptions.id] = completeOptions; + if (!options.element) + options.element = elm; + if (!options.operator) + options.operator = (node2, origin, props) => { + if (typeof props === "object") + for (const key in props) { + if (node2.element) { + if (typeof node2.element[key] === "function" && typeof props[key] !== "function") { + if (Array.isArray(props[key])) + node2.element[key](...props[key]); + else + node2.element[key](props[key]); + } else if (key === "style") { + Object.assign(node2.element[key], props[key]); + } else + node2.element[key] = props[key]; + } + } + return props; + }; + let node = new GraphNode(options, void 0, this); + elm.node = node; + let canvas = elm.querySelector("canvas"); + if (completeOptions.style) + Object.assign(canvas.style, completeOptions.style); + let context; + if (typeof completeOptions.context === "object") + context = options.context; + else if (typeof completeOptions.context === "string") + context = canvas.getContext(completeOptions.context); + this.components[completeOptions.id] = { + element: elm, + class: CustomElement, + template: completeOptions.template, + canvas, + node, + ...completeOptions + }; + this.components[completeOptions.id].context = context; + elm.canvas = canvas; + elm.context = context; + node.canvas = canvas; + node.context = context; + if (!elm.parentNode) { + setTimeout(() => { + if (typeof options.parentNode === "object") + options.parentNode.appendChild(elm); + }, 0.01); + } + node.runAnimation(animation); + return this.components[completeOptions.id]; + }; + this.load = (routes2, includeClassName = true, routeFormat = ".") => { + if (!routes2 && !this.loadDefaultRoutes) + return; + let service; + if (!(routes2 instanceof Graph) && routes2?.name) { + if (routes2.module) { + let mod = routes2; + routes2 = {}; + Object.getOwnPropertyNames(routes2.module).forEach((prop) => { + if (includeClassName) + routes2[mod.name + routeFormat + prop] = routes2.module[prop]; + else + routes2[prop] = routes2.module[prop]; + }); + } else if (typeof routes2 === "function") { + service = new routes2({ loadDefaultRoutes: this.loadDefaultRoutes }); + service.load(); + routes2 = service.routes; + } + } else if (routes2 instanceof Graph || routes2.source instanceof Graph) { + service = routes2; + routes2 = {}; + let name; + if (includeClassName) { + name = service.name; + if (!name) { + name = service.tag; + service.name = name; + } + if (!name) { + name = `graph${Math.floor(Math.random() * 1e15)}`; + service.name = name; + service.tag = name; + } + } + service.nodes.forEach((node) => { + routes2[node.tag] = node; + let checked = {}; + let checkChildGraphNodes = (nd, prev) => { + if (!checked[nd.tag] || prev && includeClassName && !checked[prev?.tag + routeFormat + nd.tag]) { + if (!prev) + checked[nd.tag] = true; + else + checked[prev.tag + routeFormat + nd.tag] = true; + if (nd instanceof Graph || nd.source instanceof Graph) { + if (includeClassName) { + let nm = nd.name; + if (!nm) { + nm = nd.tag; + nd.name = nm; + } + if (!nm) { + nm = `graph${Math.floor(Math.random() * 1e15)}`; + nd.name = nm; + nd.tag = nm; + } + } + nd.nodes.forEach((n) => { + if (includeClassName) + routes2[nd.tag + routeFormat + n.tag] = n; + else if (!routes2[n.tag]) + routes2[n.tag] = n; + checkChildGraphNodes(n, nd); + }); + } + } + }; + checkChildGraphNodes(node); + }); + } else if (typeof routes2 === "object") { + let name = routes2.constructor.name; + if (name === "Object") { + name = Object.prototype.toString.call(routes2); + if (name) + name = name.split(" ")[1]; + if (name) + name = name.split("]")[0]; + } + if (name && name !== "Object") { + let module = routes2; + routes2 = {}; + Object.getOwnPropertyNames(module).forEach((route) => { + if (includeClassName) + routes2[name + routeFormat + route] = module[route]; + else + routes2[route] = module[route]; + }); + } + } + if (service instanceof Graph && service.name && includeClassName) { + routes2 = Object.assign({}, routes2); + for (const prop in routes2) { + let route = routes2[prop]; + delete routes2[prop]; + routes2[service.name + routeFormat + prop] = route; + } + } + if (this.loadDefaultRoutes) { + let rts = Object.assign({}, this.defaultRoutes); + if (routes2) { + Object.assign(rts, this.routes); + routes2 = Object.assign(rts, routes2); + } else + routes2 = Object.assign(rts, this.routes); + this.loadDefaultRoutes = false; + } + for (const tag2 in routes2) { + let childrenIter = (route) => { + if (typeof route?.children === "object") { + for (const key in route.children) { + if (typeof route.children[key] === "object") { + let rt = route.children[key]; + if (!rt.parent) + rt.parent = tag2; + if (rt.tag) { + routes2[rt.tag] = route.children[key]; + childrenIter(routes2[rt.tag]); + } else if (rt.id) { + rt.tag = rt.id; + routes2[rt.tag] = route.children[key]; + childrenIter(routes2[rt.tag]); + } + } + } + } + }; + childrenIter(routes2[tag2]); + } + routes2 = Object.assign({}, routes2); + for (const route in routes2) { + if (typeof routes2[route] === "object" && !(routes2[route] instanceof GraphNode)) { + let r = routes2[route]; + if (typeof r === "object") { + if (r.template) { + if (!routes2[route].tag) + routes2[route].tag = route; + this.addComponent(routes2[route], routes2[route].generateChildElementNodes); + } else if (r.context) { + if (!routes2[route].tag) + routes2[route].tag = route; + this.addCanvasComponent(routes2[route]); + } else if (r.tagName || r.element) { + if (!routes2[route].tag) + routes2[route].tag = route; + this.addElement(routes2[route], routes2[route].generateChildElementNodes); + } + if (r.get) { + if (typeof r.get == "object") { + } + } + if (r.post) { + } + if (r.delete) { + } + if (r.put) { + } + if (r.head) { + } + if (r.patch) { + } + if (r.options) { + } + if (r.connect) { + } + if (r.trace) { + } + if (r.post && !r.operator) { + routes2[route].operator = r.post; + } else if (!r.operator && typeof r.get == "function") { + routes2[route].operator = r.get; + } + } + if (this.routes[route]) { + if (typeof this.routes[route] === "object") + Object.assign(this.routes[route], routes2[route]); + else + this.routes[route] = routes2[route]; + } else + this.routes[route] = routes2[route]; + } else if (this.routes[route]) { + if (typeof this.routes[route] === "object") + Object.assign(this.routes[route], routes2[route]); + else + this.routes[route] = routes2[route]; + } else + this.routes[route] = routes2[route]; + } + this.setTree(this.routes); + for (const prop in this.routes) { + if (this.routes[prop]?.aliases) { + let aliases = this.routes[prop].aliases; + aliases.forEach((a) => { + if (service) + routes2[service.name + "/" + a] = this.routes[prop]; + else + routes2[a] = this.routes[prop]; + }); + } + } + return this.routes; + }; + this.unload = (routes2 = this.routes) => { + if (!routes2) + return; + let service; + if (!(routes2 instanceof Service) && typeof routes2 === "function") { + service = new Service(); + routes2 = service.routes; + } else if (routes2 instanceof Service) { + routes2 = routes2.routes; + } + for (const r in routes2) { + delete this.routes[r]; + if (this.nodes.get(r)) + this.remove(r); + } + return this.routes; + }; + this.handleMethod = (route, method, args, origin) => { + let m = method.toLowerCase(); + if (m === "get" && this.routes[route]?.get?.transform instanceof Function) { + if (Array.isArray(args)) + return this.routes[route].get.transform(...args); + else + return this.routes[route].get.transform(args); + } + if (this.routes[route]?.[m]) { + if (!(this.routes[route][m] instanceof Function)) { + if (args) + this.routes[route][m] = args; + return this.routes[route][m]; + } else + return this.routes[route][m](args); + } else + return this.handleServiceMessage({ route, args, method, origin }); + }; + this.transmit = (...args) => { + if (typeof args[0] === "object") { + if (args[0].method) { + return this.handleMethod(args[0].route, args[0].method, args[0].args); + } else if (args[0].route) { + return this.handleServiceMessage(args[0]); + } else if (args[0].node) { + return this.handleGraphNodeCall(args[0].node, args[0].args, args[0].origin); + } else if (this.keepState) { + if (args[0].route) + this.setState({ [args[0].route]: args[0].args }); + if (args[0].node) + this.setState({ [args[0].node]: args[0].args }); + } + } else + return args; + }; + this.receive = (...args) => { + if (args[0]) { + if (typeof args[0] === "string") { + let substr = args[0].substring(0, 8); + if (substr.includes("{") || substr.includes("[")) { + if (substr.includes("\\")) + args[0] = args[0].replace(/\\/g, ""); + if (args[0][0] === '"') { + args[0] = args[0].substring(1, args[0].length - 1); + } + ; + args[0] = JSON.parse(args[0]); + } + } + } + if (typeof args[0] === "object") { + if (args[0].method) { + return this.handleMethod(args[0].route, args[0].method, args[0].args); + } else if (args[0].route) { + return this.handleServiceMessage(args[0]); + } else if (args[0].node) { + return this.handleGraphNodeCall(args[0].node, args[0].args, args[0].origin); + } else if (this.keepState) { + if (args[0].route) + this.setState({ [args[0].route]: args[0].args }); + if (args[0].node) + this.setState({ [args[0].node]: args[0].args }); + } + } else + return args; + }; + this.pipe = (source, destination, endpoint, origin, method, callback) => { + if (source instanceof GraphNode) { + if (callback) + return source.subscribe((res) => { + let mod = callback(res); + if (mod !== void 0) + this.transmit({ route: destination, args: mod, origin, method }); + else + this.transmit({ route: destination, args: res, origin, method }, endpoint); + }); + else + return this.subscribe(source, (res) => { + this.transmit({ route: destination, args: res, origin, method }, endpoint); + }); + } else if (typeof source === "string") + return this.subscribe(source, (res) => { + this.transmit({ route: destination, args: res, origin, method }, endpoint); + }); + }; + this.pipeOnce = (source, destination, endpoint, origin, method, callback) => { + if (source instanceof GraphNode) { + if (callback) + return source.state.subscribeTriggerOnce(source.tag, (res) => { + let mod = callback(res); + if (mod !== void 0) + this.transmit({ route: destination, args: mod, origin, method }); + else + this.transmit({ route: destination, args: res, origin, method }, endpoint); + }); + else + return this.state.subscribeTriggerOnce(source.tag, (res) => { + this.transmit({ route: destination, args: res, origin, method }, endpoint); + }); + } else if (typeof source === "string") + return this.state.subscribeTriggerOnce(source, (res) => { + this.transmit({ route: destination, args: res, origin, method }, endpoint); + }); + }; + this.terminate = (element) => { + if (typeof element === "object") { + if (element.animating) + element.animating = false; + if (element.element) + element = element.element; + } else if (typeof element === "string" && this.components[element]) { + if (this.components[element].node.isAnimating) + this.components[element].node.stopNode(); + if (this.components[element].divs) + this.components[element].divs.forEach((d) => this.terminate(d)); + let temp = this.components[element].element; + delete this.components[element]; + element = temp; + } else if (typeof element === "string" && this.elements[element]) { + if (this.elements[element].divs) + this.elements[element].divs.forEach((d) => this.terminate(d)); + let temp = this.elements[element].element; + if (this.elements[element].onresize) + window.removeEventListener("resize", this.elements[element].onresize); + if (this.elements[element].ondelete) + this.elements[element].ondelete(temp, this.elements[element]); + delete this.elements[element]; + element = temp; + } + if (element) { + if (this.nodes.get(element.id)) { + this.removeTree(element.id); + } + if (element instanceof DOMElement) + element.delete(); + else if (element?.parentNode) { + element.parentNode.removeChild(element); + } + return true; + } + return false; + }; + this.recursivelyAssign = (target, obj) => { + for (const key in obj) { + if (typeof obj[key] === "object") { + if (typeof target[key] === "object") + this.recursivelyAssign(target[key], obj[key]); + else + target[key] = this.recursivelyAssign({}, obj[key]); + } else + target[key] = obj[key]; + } + return target; + }; + this.defaultRoutes = { + "/": { + get: () => { + return this.print(); + }, + aliases: [""] + }, + ping: () => { + console.log("ping"); + return "pong"; + }, + echo: (...args) => { + this.transmit(...args); + return args; + }, + assign: (source) => { + if (typeof source === "object") { + Object.assign(this, source); + return true; + } + return false; + }, + recursivelyAssign: (source) => { + if (typeof source === "object") { + this.recursivelyAssign(this, source); + return true; + } + return false; + }, + log: { + post: (...args) => { + console.log("Log: ", ...args); + }, + aliases: ["info"] + }, + error: (message) => { + let er = new Error(message); + console.error(message); + return er; + }, + state: (key) => { + if (key) { + return this.state.data[key]; + } else + return this.state.data; + }, + printState: (key) => { + if (key) { + return stringifyWithCircularRefs(this.state.data[key]); + } else + return stringifyWithCircularRefs(this.state.data); + }, + transmit: this.transmit, + receive: this.receive, + load: this.load, + unload: this.unload, + pipe: this.pipe, + terminate: this.terminate, + run: this.run, + _run: this._run, + subscribe: this.subscribe, + unsubscribe: this.unsubscribe, + stopNode: this.stopNode, + get: this.get, + add: this.add, + remove: this.remove, + setTree: this.setTree, + setState: this.setState, + print: this.print, + reconstruct: this.reconstruct, + handleMethod: this.handleMethod, + handleServiceMessage: this.handleServiceMessage, + handleGraphNodeCall: this.handleGraphNodeCall, + addElement: this.addElement, + addComponent: this.addComponent, + addCanvasComponent: this.addCanvasComponent + }; + if ("loadDefaultRoutes" in options) + this.loadDefaultRoutes = options.loadDefaultRoutes; + if (options.name) + this.name = options.name; + if (parentNode instanceof HTMLElement) + this.parentNode = parentNode; + else if (options.parentNode instanceof HTMLElement) + this.parentNode = parentNode; + if (Array.isArray(options.routes)) { + options.routes.forEach((r) => { + this.load(r); + }); + } else if (options.routes) + this.load(options.routes); + } + handleServiceMessage(message) { + let call; + if (typeof message === "object") { + if (message.route) + call = message.route; + else if (message.node) + call = message.node; + } + if (call) { + if (message.origin) { + if (Array.isArray(message.args)) + return this._run(call, message.origin, ...message.args); + else + return this._run(call, message.origin, message.args); + } else { + if (Array.isArray(message.args)) + return this.run(call, ...message.args); + else + return this.run(call, message.args); + } + } else + return message; + } + handleGraphNodeCall(route, args, origin) { + if (!route) + return args; + if (args?.args) { + this.handleServiceMessage(args); + } else if (origin) { + if (Array.isArray(args)) + return this._run(route, origin, ...args); + else + return this._run(route, origin, args); + } else if (Array.isArray(args)) + return this.run(route, ...args); + else + return this.run(route, args); + } + isTypedArray(x) { + return ArrayBuffer.isView(x) && Object.prototype.toString.call(x) !== "[object DataView]"; + } + }; + + // ../tree.ts + var operators = { + add: (a, b = 1) => { + return a + b; + }, + subtract: (a, b = 1) => { + return a - b; + }, + multiply: (a, b = 100) => { + return a * b; + } + }; + var tag = "config_1"; + var deep = new Graph({}, tag, { + tag, + arbitrary: { + hello: "world" + }, + operator: (node, arg1) => { + console.log("arbitrary property ( incorrect )", node.arbitrary, node.initial.source.arbitrary); + return arg1; + } + }); + var correctTag = tag + "_correct"; + var deep2 = new Graph({ + [correctTag]: { + arbitrary: { + hello: "world" + }, + operator: (node, arg1) => { + console.log("node", node); + console.log("arbitrary property ( correct )", node.arbitrary, node, node.initial); + return arg1; + } + } + }); + var routes = { + deep, + deep2, + add: { + children: { + "subtract": true + }, + operator: operators.add + }, + multiply: { + children: { + [tag]: true, + [correctTag]: true + }, + operator: operators.multiply + } + }; + var tree = { + subtract: { + operator: operators.subtract, + children: { + "multiply": true + } + }, + nested: new DOMService({ + name: "nested", + routes + }) + }; + var expected = (input2 = []) => operators.multiply(operators.subtract(operators.add(input2[0], input2[1]))); + + // index.ts + var input = 3; + var router = new Router(); + console.log("tree", tree); + router.load(tree); + console.log("Router", router); + router.subscribe("multiply", (res) => { + document.body.innerHTML = ` +

    Router

    +

    Result: ${res}

    +

    Expected: ${expected([input])}

    +

    Test Passed: ${res == expected([input])}

    +`; + }); + router.run("add", input); +})(); diff --git a/examples/tests/router/index.html b/examples/tests/router/index.html new file mode 100644 index 00000000..bbfdfc21 --- /dev/null +++ b/examples/tests/router/index.html @@ -0,0 +1,13 @@ + + + + + + + Document + + + + + + \ No newline at end of file diff --git a/examples/tests/router/index.ts b/examples/tests/router/index.ts new file mode 100644 index 00000000..6799f252 --- /dev/null +++ b/examples/tests/router/index.ts @@ -0,0 +1,22 @@ +import { Router } from "../../../routers/Router" +import * as treeInfo from "../tree" + + +const input = 3 + +const router = new Router() +console.log('tree', treeInfo.tree) +router.load(treeInfo.tree) +console.log('Router', router) + +router.subscribe('multiply', (res) => { + document.body.innerHTML = ` +

    Router

    +

    Result: ${res}

    +

    Expected: ${treeInfo.expected([input])}

    +

    Test Passed: ${ res == treeInfo.expected([input])}

    +` +}) + +router.run('add', input) + diff --git a/examples/basics/proxy/package.json b/examples/tests/router/package.json similarity index 94% rename from examples/basics/proxy/package.json rename to examples/tests/router/package.json index cf30608e..087e9576 100644 --- a/examples/basics/proxy/package.json +++ b/examples/tests/router/package.json @@ -1,5 +1,5 @@ { - "name": "tinybuildapp6602", + "name": "tinybuildapp2730", "version": "0.0.0", "description": "Barebones esbuild and test node server implementation. For building", "main": "index.js", @@ -20,7 +20,7 @@ "esbuild" ], "author": "", - "license": "LGPL-3.0-or-later", + "license": "AGPL-3.0-or-later", "dependencies": {}, "devDependencies": {}, "nodemonConfig": { diff --git a/examples/editing/old/tinybuild.config.js b/examples/tests/router/tinybuild.config.js similarity index 87% rename from examples/editing/old/tinybuild.config.js rename to examples/tests/router/tinybuild.config.js index 616f1938..70c8cd10 100644 --- a/examples/editing/old/tinybuild.config.js +++ b/examples/tests/router/tinybuild.config.js @@ -1,7 +1,8 @@ + const config = { bundler: { //esbuild settings, set false to skip build step or add bundle:true to config object to only bundle (alt methods) entryPoints: [ //entry point file(s). These can include .js, .mjs, .ts, .jsx, .tsx, or other javascript files. Make sure your entry point is a ts file if you want to generate types - "index.ts" + "index.ts" ], outfile: "dist/index", //exit point file, will append .js as well as indicators like .esm.js, .node.js for other build flags //outdir:[] //exit point files, define for multiple bundle files @@ -12,19 +13,19 @@ const config = { bundleHTML: false, //wrap the first entry point file as a plain js script in a boilerplate html file, frontend scripts can be run standalone like a .exe! Server serves this as start page if set to true. minify: false, sourcemap: false, - loader: { '.css':'text', '.html':'text'} + //platform:'node' //for bundling the node.ts file //globalThis:null //'mymodule' //globals:{'index.js':['Graph']} - //init:{'index.js':function(bundle) { console.log('prepackaged bundle script!', bundle); }.toString(); } //pass stringified functions in to init bundle scripts in a custom way (e.g. for quick rebundling) + //init:{'index.js':function(bundle) { console.log('prepackaged bundle script!', bundle); }} }, server: { //node server settings, set false to skip server step or add serve:true to config object to only serve (alt methods) debug: false, protocol: "http", //'http' or 'https'. HTTPS required for Nodejs <---> Python sockets. If using http, set production to False in python/server.py as well host: "localhost", //'localhost' or '127.0.0.1' etc. - port: 8080, //e.g. port 80, 443, 8000 + port: 8081, //e.g. port 80, 443, 8000 startpage: "index.html", //home page socket_protocol: "ws", //frontend socket protocol, wss for served, ws for localhost - hotreload: 5000, //hotreload websocket server port + hotreload: 5001, //hotreload websocket server port //watch: ['../'], //watch additional directories other than the current working directory pwa: "dist/service-worker.js", //pwa mode? Injects service worker registry code in (see pwa README.md) python: false,//7000, //quart server port (configured via the python server script file still) @@ -34,4 +35,5 @@ const config = { keypath: "node_modules/tinybuild/tinybuild/node_server/ssl/key.pem" //if using https, this is required. See cert.pfx.md for instructions } } -export default config; //module.exports = config; //es5 \ No newline at end of file + +export default config; //es5 //export default config; // \ No newline at end of file diff --git a/examples/tests/tree.ts b/examples/tests/tree.ts new file mode 100644 index 00000000..ef3e32ee --- /dev/null +++ b/examples/tests/tree.ts @@ -0,0 +1,74 @@ +import { Graph } from "../../Graph" +import { DOMService } from "../../services/dom/DOM.service" + +export const operators = { + add: (a, b=1) => { + return a + b + }, + subtract: (a, b=1) => { + return a - b + }, + multiply: (a, b=100) => { + return a*b + } +} + +const tag = 'config_1' + +const deep = new Graph({}, tag, { + tag, + arbitrary: { + hello: 'world' + }, + operator: function(arg1){ + console.log('arbitrary property ( incorrect )', this.arbitrary, this.source.arbitrary) + return arg1 + } +}) + +const correctTag = tag + '_correct' +const deep2 = new Graph({ + [correctTag]: { + arbitrary: { + hello: 'world' + }, + operator: function (arg1) { + console.log('node', this) + console.log('arbitrary property ( correct )', this.arbitrary, this, this._initial) + return arg1 + } + } +}) + +const routes = { + deep, + deep2, + add: { + children: { + 'subtract': true + }, + operator: operators.add, + }, + multiply: { + children: { + [tag]: true, + [correctTag]: true + }, + operator: operators.multiply, + }, +} + +export const tree = { + subtract: { + operator: operators.subtract, + children: { + 'multiply': true + }, + }, + nested: new DOMService({ + name: 'nested', + routes, + }) +} + +export const expected = (input:any[]=[]) => operators.multiply(operators.subtract(operators.add(input[0], input[1]))) diff --git a/examples/wasl.html b/examples/wasl.html new file mode 100644 index 00000000..6fa50379 --- /dev/null +++ b/examples/wasl.html @@ -0,0 +1,81 @@ + + + + + + + Standalone WASL Application + + + + +
    + + + \ No newline at end of file diff --git a/examples/advanced/webrtcrouter/README.md b/examples/webrtcrouter/README.md similarity index 100% rename from examples/advanced/webrtcrouter/README.md rename to examples/webrtcrouter/README.md diff --git a/examples/advanced/webrtcrouter/backend.ts b/examples/webrtcrouter/backend.ts similarity index 87% rename from examples/advanced/webrtcrouter/backend.ts rename to examples/webrtcrouter/backend.ts index 25177e2d..a601c893 100644 --- a/examples/advanced/webrtcrouter/backend.ts +++ b/examples/webrtcrouter/backend.ts @@ -11,15 +11,15 @@ process.on('exit', exitHandler.bind(null,{cleanup:true})); process.on('SIGINT', exitHandler.bind(null, {exit:true})); -import { Router, User } from "../../../src/services/router/Router"; -import { SocketServerProps, WSSbackend } from "../../../src/services/wss/WSS.node"; -import { SSEbackend, SSEProps } from "../../../src/services/sse/SSE.node"; -import { HTTPbackend, ServerProps } from "../../../src/services/http/HTTP.node"; -import { SessionsService } from "../../../src/services/sessions/sessions.service"; -import { scriptBoilerPlate } from "../../../src/services/http/boilerplate"; +import { Router, User } from "../../services/router/Router"; +import { SocketServerProps, WSSbackend } from "../../services/wss/WSS.node"; +import { SSEbackend, SSEProps } from "../../services/sse/SSE.node"; +import { HTTPbackend, ServerProps } from "../../services/http/HTTP.node"; +import { SessionsService } from "../../services/sessions/sessions.service"; +import { scriptBoilerPlate } from "../../services/http/boilerplate"; const router = new Router({ - graph:{ + services:{ 'sessions':SessionsService, 'wss':WSSbackend, 'sse':SSEbackend, @@ -53,8 +53,6 @@ const router = new Router({ }, onopen:(served)=>{ - console.log('server opened!'); - router.openConnection( 'wss', { @@ -108,13 +106,13 @@ const router = new Router({ } } }, + loadDefaultRoutes:true, order:['sse','wss'],//prefer certain connection sources in a certain order, defaults to load order (if appropriate callbacks are available for subscription) + syncServices:true }); //on frontend we want to prefer wss first as sse is POST-reliant from browser //router.services.sessions.users = router.users; -//console.log(Object.keys(router.services)); - router.addUser({ _id:'admin' }); @@ -132,10 +130,10 @@ let session = (router.services.sessions as SessionsService).openSharedSession( 'admin' ); -router.run('sessionLoop'); +router.run('sessions.sessionLoop'); router.subscribe('addUser', (user:User) => { - console.log('new user!', user._id); + console.log('new user!', user._id) if(typeof user === 'object') { let joined = (router.services.sessions as SessionsService).joinSession('webrtcrooms', user._id); if(joined) { @@ -144,4 +142,4 @@ router.subscribe('addUser', (user:User) => { } }); -//console.log('router nodes',router.__node.nodes.keys()) \ No newline at end of file +//console.log('router nodes',router.nodes.keys(),'\n\n wss nodes',router.services.wss.nodes.keys()) \ No newline at end of file diff --git a/examples/advanced/webrtcrouter/frontend.ts b/examples/webrtcrouter/frontend.ts similarity index 92% rename from examples/advanced/webrtcrouter/frontend.ts rename to examples/webrtcrouter/frontend.ts index c0519715..034804fa 100644 --- a/examples/advanced/webrtcrouter/frontend.ts +++ b/examples/webrtcrouter/frontend.ts @@ -1,54 +1,32 @@ -import { HTTPfrontend } from '../../../src/services/http/HTTP.browser'; -import { Router } from '../../../src/services/router/Router' -import { EventSourceProps, SSEfrontend } from '../../../src/services/sse/SSE.browser'; -import { SessionsService } from '../../../src/services/sessions/sessions.service'; -import { WebRTCfrontend, WebRTCInfo } from '../../../src/services/webrtc/WebRTC.browser'; -import { WebSocketProps, WSSfrontend } from '../../../src/services/wss/WSS.browser'; -import {Graph, htmlloader} from '../../../index' - -//how it works -//https://hacks.mozilla.org/2013/07/webrtc-and-the-ocean-of-acronyms/ - -/* Execution. A Signal channel is an intermediary to pass data, e.g. a socket server. -________________________________________________________ -| peer A | STUN | TURN | Signal channel | Peer B | - - x-whoamI-> - <--NAT---x - x---make channel--> - x----------offer sdp------------>|x------------> //make call - <---------answer sdp------------x|<------------x //accept call - x------ice candidate A---------->|x------------> //send communication stuff - <------ice candidate B----------x|<------------x //send communication stuff back - <---------------who am I?-------------x //then this stuff establishes the data channels and streams (or something) - x--------------IP and port------------> -*/ +import { HTTPfrontend } from '../../services/http/HTTP.browser'; +import { Router } from '../../services/router/Router' +import { EventSourceProps, SSEfrontend } from '../../services/sse/SSE.browser'; +import { SessionsService } from '../../services/sessions/sessions.service'; +import { WebRTCfrontend, WebRTCInfo } from '../../services/webrtc/WebRTC.browser'; +import { WebSocketProps, WSSfrontend } from '../../services/wss/WSS.browser'; +import { DOMService } from '../../services/dom/DOM.service'; const router = new Router({ - order:['webrtc','wss','sse'], - graph:{ - 'dom': new Graph({ - loaders:{ - htmlloader - }, - roots:{ + routes:{ + 'dom': new DOMService({ + routes:{ 'main':{ tagName:'div', - __children:{ + children:{ 'header':{ tagName:'h4', innerHTML:`Hello World!` }, 'webrtc':{ tagName:'div', - __children:{ + children:{ 'sessioninfo':{ tagName:'div' }, 'myrooms':{ tagName:'div', style:{borderStyle:'1px solid black'}, - __children:{ + children:{ 'open':{ tagName:'button', innerText:'Create Peer Connection' @@ -66,7 +44,12 @@ const router = new Router({ } } } - }), + }) + }, + loadDefaultRoutes:true, + syncServices:true, + order:['webrtc','wss','sse'], + services:{ 'http':HTTPfrontend, 'sessions':SessionsService, 'sse':{ @@ -80,7 +63,6 @@ const router = new Router({ } as EventSourceProps } }, - 'webrtc':WebRTCfrontend, 'wss':{ service:WSSfrontend, config:{ @@ -99,10 +81,8 @@ const router = new Router({ (router.services.sessions as SessionsService).run('userUpdateLoop',user); - user.rooms = {} as any; - user.localrtc = {} as any; - - console.log(user); + user.rooms = {}; + user.localrtc = {}; router.subscribe('joinSession', (res) => { console.log('joinSession fired', res); @@ -136,7 +116,7 @@ const router = new Router({ }, }).then((room:WebRTCInfo) => { - user.rooms[newId].hostdescription = room.description; + user.rooms[newId].hostdescription = room.hostdescription; user.localrtc[newId] = room; (document.getElementById('myrooms') as HTMLElement).insertAdjacentHTML('beforeend',` @@ -208,21 +188,21 @@ const router = new Router({ ownerId:userId, isLive:false, hostcandidates:{}, - hostdescription:remoteroom.description, + hostdescription:remoteroom.hostdescription, peercandidates:{}, peerdescription:undefined }; (router.services.webrtc as WebRTCfrontend).openRTC({ _id:roomId, - description:remoteroom.description, + hostdescription:remoteroom.hostdescription, onicecandidate:(ev) => { if(ev.candidate) user.rooms[roomId].peercandidates[`peercandidate${Math.floor(Math.random()*1000000000000000)}`] = ev.candidate; }, }).then((localroom) => { user.localrtc[roomId] = localroom; - user.rooms[roomId].peerdescription = localroom.description; + user.rooms[roomId].peerdescription = localroom.peerdescription; (user.localrtc[roomId].rtc as RTCPeerConnection).addEventListener('datachannel',(ev) => { @@ -342,10 +322,11 @@ const router = new Router({ // path:'hotreload' // } as WebSocketProps } - } + }, + 'webrtc':WebRTCfrontend } }); //router.services.sessions.users = router.users; -console.log(router.__node.nodes.keys()) \ No newline at end of file +console.log(router.nodes.keys()) \ No newline at end of file diff --git a/examples/advanced/webrtcrouter/index.html b/examples/webrtcrouter/index.html similarity index 100% rename from examples/advanced/webrtcrouter/index.html rename to examples/webrtcrouter/index.html diff --git a/examples/advanced/webrtcrouter/package-lock.json b/examples/webrtcrouter/package-lock.json similarity index 99% rename from examples/advanced/webrtcrouter/package-lock.json rename to examples/webrtcrouter/package-lock.json index cd093aaf..b9dee49d 100644 --- a/examples/advanced/webrtcrouter/package-lock.json +++ b/examples/webrtcrouter/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "tinybuildapp2273", "version": "0.0.0", - "license": "LGPL-3.0-or-later", + "license": "AGPL-3.0-or-later", "dependencies": { "better-sse": "^0.7.1", "brainsatplay-math": "^0.0.22", diff --git a/examples/advanced/webrtcrouter/package.json b/examples/webrtcrouter/package.json similarity index 95% rename from examples/advanced/webrtcrouter/package.json rename to examples/webrtcrouter/package.json index 394c4a0b..58489264 100644 --- a/examples/advanced/webrtcrouter/package.json +++ b/examples/webrtcrouter/package.json @@ -22,11 +22,11 @@ "better-sse": "^0.7.1", "brainsatplay-math": "^0.0.22", "bson-objectid": "^2.0.3", - "gpujsutils": "^1.0.12", + "gpujsutils": "^1.0.8", "web-worker": "^1.2.0", "ws": "^8.7.0"}, "author": "", - "license": "LGPL-3.0-or-later", + "license": "AGPL-3.0-or-later", "nodemonConfig": { "env": { "NODEMON": true diff --git a/examples/advanced/webrtcrouter/tinybuild.backend.js b/examples/webrtcrouter/tinybuild.backend.js similarity index 95% rename from examples/advanced/webrtcrouter/tinybuild.backend.js rename to examples/webrtcrouter/tinybuild.backend.js index fd96f098..c871eafd 100644 --- a/examples/advanced/webrtcrouter/tinybuild.backend.js +++ b/examples/webrtcrouter/tinybuild.backend.js @@ -27,7 +27,7 @@ const config = { // //watch: ['../'], //watch additional directories other than the current working directory // pwa: "dist/service-worker.js", //pwa mode? Injects service worker registry code in (see pwa README.md) // python: false,//7000, //quart server port (configured via the python server script file still) - // python__node: 7001, //websocket relay port (relays messages to client from nodejs that were sent to it by python) + // python_node: 7001, //websocket relay port (relays messages to client from nodejs that were sent to it by python) // errpage: "node_modules/tinybuild/tinybuild/node_server/other/404.html", //default error page, etc. // certpath: "node_modules/tinybuild/tinybuild/node_server/ssl/cert.pem", //if using https, this is required. See cert.pfx.md for instructions // keypath: "node_modules/tinybuild/tinybuild/node_server/ssl/key.pem" //if using https, this is required. See cert.pfx.md for instructions diff --git a/examples/advanced/webrtcrouter/tinybuild.config.js b/examples/webrtcrouter/tinybuild.config.js similarity index 94% rename from examples/advanced/webrtcrouter/tinybuild.config.js rename to examples/webrtcrouter/tinybuild.config.js index 792d7fa5..dd12cf00 100644 --- a/examples/advanced/webrtcrouter/tinybuild.config.js +++ b/examples/webrtcrouter/tinybuild.config.js @@ -27,10 +27,10 @@ const config = { // //watch: ['../'], //watch additional directories other than the current working directory // pwa: "dist/service-worker.js", //pwa mode? Injects service worker registry code in (see pwa README.md) // python: false,//7000, //quart server port (configured via the python server script file still) - // python__node: 7001, //websocket relay port (relays messages to client from nodejs that were sent to it by python) + // python_node: 7001, //websocket relay port (relays messages to client from nodejs that were sent to it by python) // errpage: "node_modules/tinybuild/tinybuild/node_server/other/404.html", //default error page, etc. // certpath: "node_modules/tinybuild/tinybuild/node_server/ssl/cert.pem", //if using https, this is required. See cert.pfx.md for instructions // keypath: "node_modules/tinybuild/tinybuild/node_server/ssl/key.pem" //if using https, this is required. See cert.pfx.md for instructions // } } -module.exports = config; //es5 \ No newline at end of file +module.exports = config; //es5 //export default config; // \ No newline at end of file diff --git a/examples/services/workers/workerECS/PickHelper.js b/examples/workerECS/PickHelper.js similarity index 100% rename from examples/services/workers/workerECS/PickHelper.js rename to examples/workerECS/PickHelper.js diff --git a/examples/services/workers/workerECS/ecs_test.ts b/examples/workerECS/ecs_test.ts similarity index 91% rename from examples/services/workers/workerECS/ecs_test.ts rename to examples/workerECS/ecs_test.ts index 5d4c049e..9597e8bf 100644 --- a/examples/services/workers/workerECS/ecs_test.ts +++ b/examples/workerECS/ecs_test.ts @@ -4,37 +4,42 @@ import { Router, WorkerService, + DOMService, workerCanvasRoutes, WorkerCanvas, WorkerCanvasControls, - WorkerInfo, - htmlloader, - HTMLNodeProperties, - remoteGraphRoutes -} from '../../../../index'//'graphscript' + WorkerInfo +} from '../../index'//'graphscript' +import { ElementProps } from 'graphscript/dist/services/dom/types/element'; import gsworker from './worker' const workers = new WorkerService(); -const router = new Router({ services:{ workers, workerCanvasRoutes, remoteGraphRoutes }, loaders:{htmlloader} }); +const router = new Router({ + routes:[ + DOMService, + workers, + workerCanvasRoutes + ] +}); -console.log(router); +console.log(router) document.body.style.height = '100vh' let ret = router.load({ 'main':{ tagName:'div', - __children:{ + children:{ 'div':{ tagName:'div', innerText:'Multithreaded canvases!' - } as HTMLNodeProperties, + } as ElementProps, 'canvas':{ tagName:'canvas', style:{width:'100%',height:'100%'}, - __onrender:function (elm){ + onrender:(elm,info)=>{ const renderer = workers.addWorker({url:gsworker}) as WorkerInfo; const entities = workers.addWorker({url:gsworker}) as WorkerInfo; const entities2 = workers.addWorker({url:gsworker}) as WorkerInfo; @@ -197,9 +202,9 @@ let ret = router.load({ const portId = workers.establishMessageChannel(renderer.worker,entities.worker); const port2Id = workers.establishMessageChannel(renderer.worker,entities2.worker); - this.renderer = renderer; - this.entities = entities; - this.entities2 = entities2; + info.renderer = renderer; + info.entities = entities; + info.entities2 = entities2; //console.log(renderer); @@ -225,7 +230,7 @@ let ret = router.load({ const OrbitControls = self.OrbitControls; const renderer = new THREE.WebGLRenderer({canvas, antialias:true}); - renderer.setPixelRatio(Math.min(canvas.width/canvas.height,2)); + renderer.setPixelRatio(Math.min(canvas.clientWidth/canvas.clientHeight,2)); const fov = 75; const aspect = canvas.clientWidth / canvas.clientHeight; @@ -247,9 +252,9 @@ let ret = router.load({ const scene = new THREE.Scene(); + canvas.addEventListener('resize', (ev) => { - //console.log('resizing', canvas.clientWidth, canvas.clientHeight) - renderer.setSize(canvas.clientWidth, canvas.clientHeight, false); + renderer.setSize(canvas.width, canvas.height, false); if(camera) { camera.aspect = canvas.clientWidth / canvas.clientHeight; camera.updateProjectionMatrix(); @@ -296,12 +301,8 @@ let ret = router.load({ const boids = new Array(nBoids); - - let arr = new Float32Array(entityCt*3); - arr.forEach((v,i) => { arr[i] = Math.random()*150 }) - let geometry = new THREE.BufferGeometry(); - geometry.setAttribute('position', new THREE.Float32BufferAttribute(arr, 3) ) + geometry.setAttribute('position', new THREE.Float32BufferAttribute(new Float32Array(entityCt*3), 3) ) geometry.setAttribute('color', new THREE.Float32BufferAttribute( colors, 3 )); let pointmat = new THREE.PointsMaterial( @@ -320,7 +321,7 @@ let ret = router.load({ scene.add(points); - //console.log(points); + console.log(points); Object.assign(self, { renderer, @@ -386,7 +387,7 @@ let ret = router.load({ function bufferPositions(entities) { // SCOPE REFACTOR: Might actually need to pass self and origin... - let positionBuffer = this.__node.graph.run( + let positionBuffer = this.graph.run( 'bufferValues', entities, 'position', @@ -394,29 +395,29 @@ let ret = router.load({ ); return { - entityId:this.__node.graph.entityId, + entityId:this.graph.entityId, positions:positionBuffer }; //typedarrays are automatically transferred }; - workers.run('transferFunction', - bufferPositions, + workers.transferFunction( entities, + bufferPositions, 'bufferPositions' ); - workers.run('transferFunction', - bufferPositions, + workers.transferFunction( entities2, + bufferPositions, 'bufferPositions' ); - - entities.post('ECSService.subscribe',[ + + entities.post('subscribe',[ 'movement', 'bufferPositions' ]); //i/o subscription - entities2.post('ECSService.subscribe',[ + entities2.post('subscribe',[ 'movement', 'bufferPositions' ]); //i/o subscription @@ -434,37 +435,43 @@ let ret = router.load({ 'updateCanvas' ]); - //console.log('entities',entities); entities.run('addEntities',[ entitySettings[0].prototype, entitySettings[0].components, entitySettings[0].ct - ]); + ]).then((r) => { + + }); entities2.run('addEntities',[ entitySettings[1].prototype, entitySettings[1].components, entitySettings[1].ct - ]); - + ]).then((r) => { + + }); entities2.run('addEntities',[ entitySettings[2].prototype, entitySettings[2].components, entitySettings[2].ct - ]); - + ]).then((r) => { + + }); entities2.run('addEntities',[ entitySettings[3].prototype, entitySettings[3].components, entitySettings[3].ct - ]); - + ]).then((r) => { + + }); entities2.run('addEntities',[ entitySettings[4].prototype, entitySettings[4].components, entitySettings[4].ct - ]); + ]).then((r) => { + + }); entities.post('setValue',['entityId',0]); entities.post('animateEntities'); @@ -473,14 +480,14 @@ let ret = router.load({ entities2.post('animateEntities'); } }, - __onremove:function (elm){ - workers.terminate(this.renderer._id); - workers.terminate(this.entities._id); - workers.terminate(this.entities2._id); + onremove:(elm,info)=>{ + workers.terminate(info.renderer._id); + workers.terminate(info.entities._id); + workers.terminate(info.entities2._id); } - } as HTMLNodeProperties + } as ElementProps } - } as HTMLNodeProperties + } as ElementProps }); //console.log(ret) \ No newline at end of file diff --git a/examples/advanced/eegnfb/index.html b/examples/workerECS/index.html similarity index 100% rename from examples/advanced/eegnfb/index.html rename to examples/workerECS/index.html diff --git a/examples/workerECS/package-lock.json b/examples/workerECS/package-lock.json new file mode 100644 index 00000000..6158b459 --- /dev/null +++ b/examples/workerECS/package-lock.json @@ -0,0 +1,165 @@ +{ + "name": "tinybuildapp261", + "version": "0.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "tinybuildapp261", + "version": "0.0.0", + "license": "AGPL-3.0-or-later", + "dependencies": { + "graphscript": "~0.0.163", + "three": "^0.143.0" + } + }, + "node_modules/better-sse": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/better-sse/-/better-sse-0.7.1.tgz", + "integrity": "sha512-2t7XGg6hQFNwtmFXKi6/jyY5K0/4fa5UoOqVSYG2W/AFbVCt8gPnFw2LHM9ude91a8KhoXtRt9zOwpVZ5f5K5g==", + "engines": { + "node": ">=12", + "pnpm": ">=6" + } + }, + "node_modules/brainsatplay-data": { + "version": "0.0.48", + "resolved": "https://registry.npmjs.org/brainsatplay-data/-/brainsatplay-data-0.0.48.tgz", + "integrity": "sha512-3xJ4C5ts0z6dKTkaEI0LrHO443gphOj/OAP9JfZARZXE5MO+kMsOIlvAgijeP7ty4btZtg7MNEEacwIBXREgbQ==", + "dependencies": { + "brainsatplay-math": "^0.0.2" + } + }, + "node_modules/brainsatplay-data/node_modules/brainsatplay-math": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/brainsatplay-math/-/brainsatplay-math-0.0.2.tgz", + "integrity": "sha512-7fjUfcmR2TcHtRh9jCds1WF1HZWhvvDytE6ngrkOUnMTQTbrDs0iAcp8NjMEiHumJRjcaD/c6PN60wIY0rjQaQ==" + }, + "node_modules/brainsatplay-math": { + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/brainsatplay-math/-/brainsatplay-math-0.0.22.tgz", + "integrity": "sha512-er+7fobi+bgtuiaN5Pcg0cpOfl/d5hrM8W8sF5lnX9VWhcs2TvyG3J0UV+pozGYSBvtqij7Evs4HhhFIh3cfbQ==" + }, + "node_modules/bson-objectid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bson-objectid/-/bson-objectid-2.0.3.tgz", + "integrity": "sha512-WYwVtY9yqk179EPMNuF3vcxufdrGLEo2XwqdRVbfLVe9X6jLt7WKZQgP+ObOcprakBGbHxzl76tgTaieqsH29g==" + }, + "node_modules/gpujsutils": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/gpujsutils/-/gpujsutils-1.0.10.tgz", + "integrity": "sha512-hn74yMSZrT4pf4nlS3SRZvUe7UaGCs3KYoi/dqhTJk3Gho2M9SScj7BHewTcNI1M2UonTkcaR/CA1KgXxekfVQ==" + }, + "node_modules/graphscript": { + "version": "0.0.163", + "resolved": "https://registry.npmjs.org/graphscript/-/graphscript-0.0.163.tgz", + "integrity": "sha512-LEhbfRPCMK56h0K0z7Wo6oG8K6mlj+aeYdhzXxl6hsXD6qUrSIagVlhAWqBRdk/wkjRfhXYzfC2dAkOJr5P1gw==", + "dependencies": { + "better-sse": "^0.7.1", + "brainsatplay-data": "^0.0.48", + "brainsatplay-math": "^0.0.22", + "bson-objectid": "^2.0.3", + "gpujsutils": "^1.0.8", + "web-worker": "^1.2.0", + "ws": "^8.7.0" + } + }, + "node_modules/three": { + "version": "0.143.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.143.0.tgz", + "integrity": "sha512-oKcAGYHhJ46TGEuHjodo2n6TY2R6lbvrkp+feKZxqsUL/WkH7GKKaeu6RHeyb2Xjfk2dPLRKLsOP0KM2VgT8Zg==" + }, + "node_modules/web-worker": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", + "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" + }, + "node_modules/ws": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", + "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + }, + "dependencies": { + "better-sse": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/better-sse/-/better-sse-0.7.1.tgz", + "integrity": "sha512-2t7XGg6hQFNwtmFXKi6/jyY5K0/4fa5UoOqVSYG2W/AFbVCt8gPnFw2LHM9ude91a8KhoXtRt9zOwpVZ5f5K5g==" + }, + "brainsatplay-data": { + "version": "0.0.48", + "resolved": "https://registry.npmjs.org/brainsatplay-data/-/brainsatplay-data-0.0.48.tgz", + "integrity": "sha512-3xJ4C5ts0z6dKTkaEI0LrHO443gphOj/OAP9JfZARZXE5MO+kMsOIlvAgijeP7ty4btZtg7MNEEacwIBXREgbQ==", + "requires": { + "brainsatplay-math": "^0.0.2" + }, + "dependencies": { + "brainsatplay-math": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/brainsatplay-math/-/brainsatplay-math-0.0.2.tgz", + "integrity": "sha512-7fjUfcmR2TcHtRh9jCds1WF1HZWhvvDytE6ngrkOUnMTQTbrDs0iAcp8NjMEiHumJRjcaD/c6PN60wIY0rjQaQ==" + } + } + }, + "brainsatplay-math": { + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/brainsatplay-math/-/brainsatplay-math-0.0.22.tgz", + "integrity": "sha512-er+7fobi+bgtuiaN5Pcg0cpOfl/d5hrM8W8sF5lnX9VWhcs2TvyG3J0UV+pozGYSBvtqij7Evs4HhhFIh3cfbQ==" + }, + "bson-objectid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bson-objectid/-/bson-objectid-2.0.3.tgz", + "integrity": "sha512-WYwVtY9yqk179EPMNuF3vcxufdrGLEo2XwqdRVbfLVe9X6jLt7WKZQgP+ObOcprakBGbHxzl76tgTaieqsH29g==" + }, + "gpujsutils": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/gpujsutils/-/gpujsutils-1.0.10.tgz", + "integrity": "sha512-hn74yMSZrT4pf4nlS3SRZvUe7UaGCs3KYoi/dqhTJk3Gho2M9SScj7BHewTcNI1M2UonTkcaR/CA1KgXxekfVQ==" + }, + "graphscript": { + "version": "0.0.163", + "resolved": "https://registry.npmjs.org/graphscript/-/graphscript-0.0.163.tgz", + "integrity": "sha512-LEhbfRPCMK56h0K0z7Wo6oG8K6mlj+aeYdhzXxl6hsXD6qUrSIagVlhAWqBRdk/wkjRfhXYzfC2dAkOJr5P1gw==", + "requires": { + "better-sse": "^0.7.1", + "brainsatplay-data": "^0.0.48", + "brainsatplay-math": "^0.0.22", + "bson-objectid": "^2.0.3", + "gpujsutils": "^1.0.8", + "web-worker": "^1.2.0", + "ws": "^8.7.0" + } + }, + "three": { + "version": "0.143.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.143.0.tgz", + "integrity": "sha512-oKcAGYHhJ46TGEuHjodo2n6TY2R6lbvrkp+feKZxqsUL/WkH7GKKaeu6RHeyb2Xjfk2dPLRKLsOP0KM2VgT8Zg==" + }, + "web-worker": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", + "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" + }, + "ws": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", + "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", + "requires": {} + } + } +} diff --git a/examples/services/workers/workerthreejs/package.json b/examples/workerECS/package.json similarity index 90% rename from examples/services/workers/workerthreejs/package.json rename to examples/workerECS/package.json index a456f1fd..1ba2b600 100644 --- a/examples/services/workers/workerthreejs/package.json +++ b/examples/workerECS/package.json @@ -1,5 +1,5 @@ { - "name": "graphscript-workerthreejs-example", + "name": "tinybuildapp261", "version": "0.0.0", "description": "Barebones esbuild and test node server implementation. For building", "main": "index.js", @@ -20,9 +20,9 @@ "esbuild" ], "author": "", - "license": "LGPL-3.0-or-later", + "license": "AGPL-3.0-or-later", "dependencies": { - "graphscript": "~0.1.47", + "graphscript": "~0.0.163", "three": "^0.143.0" }, "nodemonConfig": { diff --git a/examples/basics/listeners/tinybuild.config.js b/examples/workerECS/tinybuild.config.js similarity index 98% rename from examples/basics/listeners/tinybuild.config.js rename to examples/workerECS/tinybuild.config.js index 749308ef..eb1f849f 100644 --- a/examples/basics/listeners/tinybuild.config.js +++ b/examples/workerECS/tinybuild.config.js @@ -1,7 +1,7 @@ const config = { bundler: { //esbuild settings, set false to skip build step or add bundle:true to config object to only bundle (alt methods) entryPoints: [ //entry point file(s). These can include .js, .mjs, .ts, .jsx, .tsx, or other javascript files. Make sure your entry point is a ts file if you want to generate types - "index.ts" + "ecs_test.ts" ], outfile: "dist/index", //exit point file, will append .js as well as indicators like .esm.js, .node.js for other build flags //outdir:[] //exit point files, define for multiple bundle files @@ -10,7 +10,7 @@ const config = { bundleTypes: false, //create .d.ts files, the entry point must be a typescript file! (ts, tsx, etc) bundleNode: false, //create node platform plain js build, specify platform:'node' to do the rest of the files bundleHTML: false, //wrap the first entry point file as a plain js script in a boilerplate html file, frontend scripts can be run standalone like a .exe! Server serves this as start page if set to true. - minify: true, + minify: false, sourcemap: false //globalThis:null //'mymodule' //globals:{'index.js':['Graph']} diff --git a/examples/workerECS/worker.ts b/examples/workerECS/worker.ts new file mode 100644 index 00000000..7570bf27 --- /dev/null +++ b/examples/workerECS/worker.ts @@ -0,0 +1,68 @@ +import { + WorkerService, + unsafeRoutes, + workerCanvasRoutes, + ECSService, + //GPUService +} from '../../index'/////"../../GraphServiceRouter/index";//from 'graphscript' + +import {Systems} from '../../extras/index.services' + +import { WorkerCanvasReceiveProps } from '../../services/worker/WorkerCanvas'; + +import * as THREE from 'three' +import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js' +import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js' +import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js' +import { SMAAPass } from 'three/examples/jsm/postprocessing/SMAAPass.js' +import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js' +import { PickHelper } from './PickHelper' + +declare var WorkerGlobalScope; + +if(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) { + const worker = new WorkerService({ + routes:[ + //GPUService, + ECSService, + unsafeRoutes, //allows dynamic route loading + { + ...workerCanvasRoutes, + receiveThreeCanvas:function(options:WorkerCanvasReceiveProps){ //modified canvas receiver that installs desired threejs modules + const ThreeProps = { //e.g. install these systems to 'self', which is the worker canvas + THREE, + OrbitControls, + EffectComposer, + RenderPass, + SMAAPass, + UnrealBloomPass, + PickHelper + } + + Object.assign(options, ThreeProps); //install desired props to our canvas's 'self' reference + + let renderId = this.graph.run('receiveCanvas', options); //the the base canvas tools do the rest, all ThreeJS tools are on self, for self contained ThreeJS renders + //you can use the canvas render loop by default, or don't provide a draw function and just use the init and the Three animate() callback + + //let canvasopts = this.graph.CANVASES[renderId] as WorkerCanvas; + + return renderId; + } + } + ], + includeClassName:false, + loadDefaultRoutes:true //to get subscribe and subscribeNode routes + }); + + worker.run( + 'addSystems', + Systems, + ['boid','nbody','collision','collider','movement'] + ); //register desired entity component systems + + console.log(worker) +} + + + +export default self as any; \ No newline at end of file diff --git a/examples/workerECS/yarn.lock b/examples/workerECS/yarn.lock new file mode 100644 index 00000000..c95241ec --- /dev/null +++ b/examples/workerECS/yarn.lock @@ -0,0 +1,71 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"better-sse@^0.7.1": + "integrity" "sha512-2t7XGg6hQFNwtmFXKi6/jyY5K0/4fa5UoOqVSYG2W/AFbVCt8gPnFw2LHM9ude91a8KhoXtRt9zOwpVZ5f5K5g==" + "resolved" "https://registry.npmjs.org/better-sse/-/better-sse-0.7.1.tgz" + "version" "0.7.1" + +"brainsatplay-data@^0.0.48": + "integrity" "sha512-3xJ4C5ts0z6dKTkaEI0LrHO443gphOj/OAP9JfZARZXE5MO+kMsOIlvAgijeP7ty4btZtg7MNEEacwIBXREgbQ==" + "resolved" "https://registry.npmjs.org/brainsatplay-data/-/brainsatplay-data-0.0.48.tgz" + "version" "0.0.48" + dependencies: + "brainsatplay-math" "^0.0.2" + +"brainsatplay-math@^0.0.2": + "integrity" "sha512-7fjUfcmR2TcHtRh9jCds1WF1HZWhvvDytE6ngrkOUnMTQTbrDs0iAcp8NjMEiHumJRjcaD/c6PN60wIY0rjQaQ==" + "resolved" "https://registry.npmjs.org/brainsatplay-math/-/brainsatplay-math-0.0.2.tgz" + "version" "0.0.2" + +"brainsatplay-math@^0.0.22": + "integrity" "sha512-er+7fobi+bgtuiaN5Pcg0cpOfl/d5hrM8W8sF5lnX9VWhcs2TvyG3J0UV+pozGYSBvtqij7Evs4HhhFIh3cfbQ==" + "resolved" "https://registry.npmjs.org/brainsatplay-math/-/brainsatplay-math-0.0.22.tgz" + "version" "0.0.22" + +"bson-objectid@^2.0.3": + "integrity" "sha512-WYwVtY9yqk179EPMNuF3vcxufdrGLEo2XwqdRVbfLVe9X6jLt7WKZQgP+ObOcprakBGbHxzl76tgTaieqsH29g==" + "resolved" "https://registry.npmjs.org/bson-objectid/-/bson-objectid-2.0.3.tgz" + "version" "2.0.3" + +"gpujsutils@^1.0.8": + "integrity" "sha512-hn74yMSZrT4pf4nlS3SRZvUe7UaGCs3KYoi/dqhTJk3Gho2M9SScj7BHewTcNI1M2UonTkcaR/CA1KgXxekfVQ==" + "resolved" "https://registry.npmjs.org/gpujsutils/-/gpujsutils-1.0.10.tgz" + "version" "1.0.10" + +"graphscript@~0.0.163": + "integrity" "sha512-LEhbfRPCMK56h0K0z7Wo6oG8K6mlj+aeYdhzXxl6hsXD6qUrSIagVlhAWqBRdk/wkjRfhXYzfC2dAkOJr5P1gw==" + "resolved" "https://registry.npmjs.org/graphscript/-/graphscript-0.0.163.tgz" + "version" "0.0.163" + dependencies: + "better-sse" "^0.7.1" + "brainsatplay-data" "^0.0.48" + "brainsatplay-math" "^0.0.22" + "bson-objectid" "^2.0.3" + "gpujsutils" "^1.0.8" + "web-worker" "^1.2.0" + "ws" "^8.7.0" + +"three@^0.143.0": + "integrity" "sha512-oKcAGYHhJ46TGEuHjodo2n6TY2R6lbvrkp+feKZxqsUL/WkH7GKKaeu6RHeyb2Xjfk2dPLRKLsOP0KM2VgT8Zg==" + "resolved" "https://registry.npmjs.org/three/-/three-0.143.0.tgz" + "version" "0.143.0" + +"tinybuild@file:../../../tinybuild": + "resolved" "file:../../../tinybuild" + "version" "0.3.175" + dependencies: + "chokidar" "~3.5.3" + "esbuild" "~0.14.49" + "ws" "^8.5.0" + +"web-worker@^1.2.0": + "integrity" "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" + "resolved" "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz" + "version" "1.2.0" + +"ws@^8.7.0": + "integrity" "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==" + "resolved" "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz" + "version" "8.8.1" diff --git a/examples/workercanvas/dist/index.js b/examples/workercanvas/dist/index.js new file mode 100644 index 00000000..748650c4 --- /dev/null +++ b/examples/workercanvas/dist/index.js @@ -0,0 +1,7018 @@ +(() => { + var __create = Object.create; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __getProtoOf = Object.getPrototypeOf; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; + var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { + get: (a, b) => (typeof require !== "undefined" ? require : a)[b] + }) : x)(function(x) { + if (typeof require !== "undefined") + return require.apply(this, arguments); + throw new Error('Dynamic require of "' + x + '" is not supported'); + }); + var __commonJS = (cb, mod) => function __require2() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod + )); + var __publicField = (obj, key, value) => { + __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); + return value; + }; + + // ../../services/e2ee/sjcl.js + var require_sjcl = __commonJS({ + "../../services/e2ee/sjcl.js"(exports, module) { + "use strict"; + var sjcl2 = { cipher: {}, hash: {}, keyexchange: {}, mode: {}, misc: {}, codec: {}, exception: { corrupt: function(a) { + this.toString = function() { + return "CORRUPT: " + this.message; + }; + this.message = a; + }, invalid: function(a) { + this.toString = function() { + return "INVALID: " + this.message; + }; + this.message = a; + }, bug: function(a) { + this.toString = function() { + return "BUG: " + this.message; + }; + this.message = a; + }, notReady: function(a) { + this.toString = function() { + return "NOT READY: " + this.message; + }; + this.message = a; + } } }; + sjcl2.cipher.aes = function(a) { + this.s[0][0][0] || this.O(); + var b, c, d, e, f = this.s[0][4], g = this.s[1]; + b = a.length; + var h = 1; + if (4 !== b && 6 !== b && 8 !== b) + throw new sjcl2.exception.invalid("invalid aes key size"); + this.b = [d = a.slice(0), e = []]; + for (a = b; a < 4 * b + 28; a++) { + c = d[a - 1]; + if (0 === a % b || 8 === b && 4 === a % b) + c = f[c >>> 24] << 24 ^ f[c >> 16 & 255] << 16 ^ f[c >> 8 & 255] << 8 ^ f[c & 255], 0 === a % b && (c = c << 8 ^ c >>> 24 ^ h << 24, h = h << 1 ^ 283 * (h >> 7)); + d[a] = d[a - b] ^ c; + } + for (b = 0; a; b++, a--) + c = d[b & 3 ? a : a - 4], e[b] = 4 >= a || 4 > b ? c : g[0][f[c >>> 24]] ^ g[1][f[c >> 16 & 255]] ^ g[2][f[c >> 8 & 255]] ^ g[3][f[c & 255]]; + }; + sjcl2.cipher.aes.prototype = { encrypt: function(a) { + return t(this, a, 0); + }, decrypt: function(a) { + return t(this, a, 1); + }, s: [[[], [], [], [], []], [[], [], [], [], []]], O: function() { + var a = this.s[0], b = this.s[1], c = a[4], d = b[4], e, f, g, h = [], k = [], l, n, m, p; + for (e = 0; 256 > e; e++) + k[(h[e] = e << 1 ^ 283 * (e >> 7)) ^ e] = e; + for (f = g = 0; !c[f]; f ^= l || 1, g = k[g] || 1) + for (m = g ^ g << 1 ^ g << 2 ^ g << 3 ^ g << 4, m = m >> 8 ^ m & 255 ^ 99, c[f] = m, d[m] = f, n = h[e = h[l = h[f]]], p = 16843009 * n ^ 65537 * e ^ 257 * l ^ 16843008 * f, n = 257 * h[m] ^ 16843008 * m, e = 0; 4 > e; e++) + a[e][f] = n = n << 24 ^ n >>> 8, b[e][m] = p = p << 24 ^ p >>> 8; + for (e = 0; 5 > e; e++) + a[e] = a[e].slice(0), b[e] = b[e].slice(0); + } }; + function t(a, b, c) { + if (4 !== b.length) + throw new sjcl2.exception.invalid("invalid aes block size"); + var d = a.b[c], e = b[0] ^ d[0], f = b[c ? 3 : 1] ^ d[1], g = b[2] ^ d[2]; + b = b[c ? 1 : 3] ^ d[3]; + var h, k, l, n = d.length / 4 - 2, m, p = 4, r = [0, 0, 0, 0]; + h = a.s[c]; + a = h[0]; + var q = h[1], v = h[2], w = h[3], x = h[4]; + for (m = 0; m < n; m++) + h = a[e >>> 24] ^ q[f >> 16 & 255] ^ v[g >> 8 & 255] ^ w[b & 255] ^ d[p], k = a[f >>> 24] ^ q[g >> 16 & 255] ^ v[b >> 8 & 255] ^ w[e & 255] ^ d[p + 1], l = a[g >>> 24] ^ q[b >> 16 & 255] ^ v[e >> 8 & 255] ^ w[f & 255] ^ d[p + 2], b = a[b >>> 24] ^ q[e >> 16 & 255] ^ v[f >> 8 & 255] ^ w[g & 255] ^ d[p + 3], p += 4, e = h, f = k, g = l; + for (m = 0; 4 > m; m++) + r[c ? 3 & -m : m] = x[e >>> 24] << 24 ^ x[f >> 16 & 255] << 16 ^ x[g >> 8 & 255] << 8 ^ x[b & 255] ^ d[p++], h = e, e = f, f = g, g = b, b = h; + return r; + } + sjcl2.bitArray = { bitSlice: function(a, b, c) { + a = sjcl2.bitArray.$(a.slice(b / 32), 32 - (b & 31)).slice(1); + return void 0 === c ? a : sjcl2.bitArray.clamp(a, c - b); + }, extract: function(a, b, c) { + var d = Math.floor(-b - c & 31); + return ((b + c - 1 ^ b) & -32 ? a[b / 32 | 0] << 32 - d ^ a[b / 32 + 1 | 0] >>> d : a[b / 32 | 0] >>> d) & (1 << c) - 1; + }, concat: function(a, b) { + if (0 === a.length || 0 === b.length) + return a.concat(b); + var c = a[a.length - 1], d = sjcl2.bitArray.getPartial(c); + return 32 === d ? a.concat(b) : sjcl2.bitArray.$(b, d, c | 0, a.slice(0, a.length - 1)); + }, bitLength: function(a) { + var b = a.length; + return 0 === b ? 0 : 32 * (b - 1) + sjcl2.bitArray.getPartial(a[b - 1]); + }, clamp: function(a, b) { + if (32 * a.length < b) + return a; + a = a.slice(0, Math.ceil(b / 32)); + var c = a.length; + b = b & 31; + 0 < c && b && (a[c - 1] = sjcl2.bitArray.partial(b, a[c - 1] & 2147483648 >> b - 1, 1)); + return a; + }, partial: function(a, b, c) { + return 32 === a ? b : (c ? b | 0 : b << 32 - a) + 1099511627776 * a; + }, getPartial: function(a) { + return Math.round(a / 1099511627776) || 32; + }, equal: function(a, b) { + if (sjcl2.bitArray.bitLength(a) !== sjcl2.bitArray.bitLength(b)) + return false; + var c = 0, d; + for (d = 0; d < a.length; d++) + c |= a[d] ^ b[d]; + return 0 === c; + }, $: function(a, b, c, d) { + var e; + e = 0; + for (void 0 === d && (d = []); 32 <= b; b -= 32) + d.push(c), c = 0; + if (0 === b) + return d.concat(a); + for (e = 0; e < a.length; e++) + d.push(c | a[e] >>> b), c = a[e] << 32 - b; + e = a.length ? a[a.length - 1] : 0; + a = sjcl2.bitArray.getPartial(e); + d.push(sjcl2.bitArray.partial(b + a & 31, 32 < b + a ? c : d.pop(), 1)); + return d; + }, i: function(a, b) { + return [a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3]]; + }, byteswapM: function(a) { + var b, c; + for (b = 0; b < a.length; ++b) + c = a[b], a[b] = c >>> 24 | c >>> 8 & 65280 | (c & 65280) << 8 | c << 24; + return a; + } }; + sjcl2.codec.utf8String = { fromBits: function(a) { + var b = "", c = sjcl2.bitArray.bitLength(a), d, e; + for (d = 0; d < c / 8; d++) + 0 === (d & 3) && (e = a[d / 4]), b += String.fromCharCode(e >>> 8 >>> 8 >>> 8), e <<= 8; + return decodeURIComponent(escape(b)); + }, toBits: function(a) { + a = unescape(encodeURIComponent(a)); + var b = [], c, d = 0; + for (c = 0; c < a.length; c++) + d = d << 8 | a.charCodeAt(c), 3 === (c & 3) && (b.push(d), d = 0); + c & 3 && b.push(sjcl2.bitArray.partial(8 * (c & 3), d)); + return b; + } }; + sjcl2.codec.hex = { fromBits: function(a) { + var b = "", c; + for (c = 0; c < a.length; c++) + b += ((a[c] | 0) + 263882790666240).toString(16).substr(4); + return b.substr(0, sjcl2.bitArray.bitLength(a) / 4); + }, toBits: function(a) { + var b, c = [], d; + a = a.replace(/\s|0x/g, ""); + d = a.length; + a = a + "00000000"; + for (b = 0; b < a.length; b += 8) + c.push(parseInt(a.substr(b, 8), 16) ^ 0); + return sjcl2.bitArray.clamp(c, 4 * d); + } }; + sjcl2.codec.base32 = { B: "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", X: "0123456789ABCDEFGHIJKLMNOPQRSTUV", BITS: 32, BASE: 5, REMAINING: 27, fromBits: function(a, b, c) { + var d = sjcl2.codec.base32.BASE, e = sjcl2.codec.base32.REMAINING, f = "", g = 0, h = sjcl2.codec.base32.B, k = 0, l = sjcl2.bitArray.bitLength(a); + c && (h = sjcl2.codec.base32.X); + for (c = 0; f.length * d < l; ) + f += h.charAt((k ^ a[c] >>> g) >>> e), g < d ? (k = a[c] << d - g, g += e, c++) : (k <<= d, g -= d); + for (; f.length & 7 && !b; ) + f += "="; + return f; + }, toBits: function(a, b) { + a = a.replace(/\s|=/g, "").toUpperCase(); + var c = sjcl2.codec.base32.BITS, d = sjcl2.codec.base32.BASE, e = sjcl2.codec.base32.REMAINING, f = [], g, h = 0, k = sjcl2.codec.base32.B, l = 0, n, m = "base32"; + b && (k = sjcl2.codec.base32.X, m = "base32hex"); + for (g = 0; g < a.length; g++) { + n = k.indexOf(a.charAt(g)); + if (0 > n) { + if (!b) + try { + return sjcl2.codec.base32hex.toBits(a); + } catch (p) { + } + throw new sjcl2.exception.invalid("this isn't " + m + "!"); + } + h > e ? (h -= e, f.push(l ^ n >>> h), l = n << c - h) : (h += d, l ^= n << c - h); + } + h & 56 && f.push(sjcl2.bitArray.partial(h & 56, l, 1)); + return f; + } }; + sjcl2.codec.base32hex = { fromBits: function(a, b) { + return sjcl2.codec.base32.fromBits(a, b, 1); + }, toBits: function(a) { + return sjcl2.codec.base32.toBits(a, 1); + } }; + sjcl2.codec.base64 = { B: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", fromBits: function(a, b, c) { + var d = "", e = 0, f = sjcl2.codec.base64.B, g = 0, h = sjcl2.bitArray.bitLength(a); + c && (f = f.substr(0, 62) + "-_"); + for (c = 0; 6 * d.length < h; ) + d += f.charAt((g ^ a[c] >>> e) >>> 26), 6 > e ? (g = a[c] << 6 - e, e += 26, c++) : (g <<= 6, e -= 6); + for (; d.length & 3 && !b; ) + d += "="; + return d; + }, toBits: function(a, b) { + a = a.replace(/\s|=/g, ""); + var c = [], d, e = 0, f = sjcl2.codec.base64.B, g = 0, h; + b && (f = f.substr(0, 62) + "-_"); + for (d = 0; d < a.length; d++) { + h = f.indexOf(a.charAt(d)); + if (0 > h) + throw new sjcl2.exception.invalid("this isn't base64!"); + 26 < e ? (e -= 26, c.push(g ^ h >>> e), g = h << 32 - e) : (e += 6, g ^= h << 32 - e); + } + e & 56 && c.push(sjcl2.bitArray.partial(e & 56, g, 1)); + return c; + } }; + sjcl2.codec.base64url = { fromBits: function(a) { + return sjcl2.codec.base64.fromBits(a, 1, 1); + }, toBits: function(a) { + return sjcl2.codec.base64.toBits(a, 1); + } }; + sjcl2.hash.sha256 = function(a) { + this.b[0] || this.O(); + a ? (this.F = a.F.slice(0), this.A = a.A.slice(0), this.l = a.l) : this.reset(); + }; + sjcl2.hash.sha256.hash = function(a) { + return new sjcl2.hash.sha256().update(a).finalize(); + }; + sjcl2.hash.sha256.prototype = { blockSize: 512, reset: function() { + this.F = this.Y.slice(0); + this.A = []; + this.l = 0; + return this; + }, update: function(a) { + "string" === typeof a && (a = sjcl2.codec.utf8String.toBits(a)); + var b, c = this.A = sjcl2.bitArray.concat(this.A, a); + b = this.l; + a = this.l = b + sjcl2.bitArray.bitLength(a); + if (9007199254740991 < a) + throw new sjcl2.exception.invalid("Cannot hash more than 2^53 - 1 bits"); + if ("undefined" !== typeof Uint32Array) { + var d = new Uint32Array(c), e = 0; + for (b = 512 + b - (512 + b & 511); b <= a; b += 512) + u(this, d.subarray( + 16 * e, + 16 * (e + 1) + )), e += 1; + c.splice(0, 16 * e); + } else + for (b = 512 + b - (512 + b & 511); b <= a; b += 512) + u(this, c.splice(0, 16)); + return this; + }, finalize: function() { + var a, b = this.A, c = this.F, b = sjcl2.bitArray.concat(b, [sjcl2.bitArray.partial(1, 1)]); + for (a = b.length + 2; a & 15; a++) + b.push(0); + b.push(Math.floor(this.l / 4294967296)); + for (b.push(this.l | 0); b.length; ) + u(this, b.splice(0, 16)); + this.reset(); + return c; + }, Y: [], b: [], O: function() { + function a(a2) { + return 4294967296 * (a2 - Math.floor(a2)) | 0; + } + for (var b = 0, c = 2, d, e; 64 > b; c++) { + e = true; + for (d = 2; d * d <= c; d++) + if (0 === c % d) { + e = false; + break; + } + e && (8 > b && (this.Y[b] = a(Math.pow(c, 0.5))), this.b[b] = a(Math.pow(c, 1 / 3)), b++); + } + } }; + function u(a, b) { + var c, d, e, f = a.F, g = a.b, h = f[0], k = f[1], l = f[2], n = f[3], m = f[4], p = f[5], r = f[6], q = f[7]; + for (c = 0; 64 > c; c++) + 16 > c ? d = b[c] : (d = b[c + 1 & 15], e = b[c + 14 & 15], d = b[c & 15] = (d >>> 7 ^ d >>> 18 ^ d >>> 3 ^ d << 25 ^ d << 14) + (e >>> 17 ^ e >>> 19 ^ e >>> 10 ^ e << 15 ^ e << 13) + b[c & 15] + b[c + 9 & 15] | 0), d = d + q + (m >>> 6 ^ m >>> 11 ^ m >>> 25 ^ m << 26 ^ m << 21 ^ m << 7) + (r ^ m & (p ^ r)) + g[c], q = r, r = p, p = m, m = n + d | 0, n = l, l = k, k = h, h = d + (k & l ^ n & (k ^ l)) + (k >>> 2 ^ k >>> 13 ^ k >>> 22 ^ k << 30 ^ k << 19 ^ k << 10) | 0; + f[0] = f[0] + h | 0; + f[1] = f[1] + k | 0; + f[2] = f[2] + l | 0; + f[3] = f[3] + n | 0; + f[4] = f[4] + m | 0; + f[5] = f[5] + p | 0; + f[6] = f[6] + r | 0; + f[7] = f[7] + q | 0; + } + sjcl2.mode.ccm = { name: "ccm", G: [], listenProgress: function(a) { + sjcl2.mode.ccm.G.push(a); + }, unListenProgress: function(a) { + a = sjcl2.mode.ccm.G.indexOf(a); + -1 < a && sjcl2.mode.ccm.G.splice(a, 1); + }, fa: function(a) { + var b = sjcl2.mode.ccm.G.slice(), c; + for (c = 0; c < b.length; c += 1) + b[c](a); + }, encrypt: function(a, b, c, d, e) { + var f, g = b.slice(0), h = sjcl2.bitArray, k = h.bitLength(c) / 8, l = h.bitLength(g) / 8; + e = e || 64; + d = d || []; + if (7 > k) + throw new sjcl2.exception.invalid("ccm: iv must be at least 7 bytes"); + for (f = 2; 4 > f && l >>> 8 * f; f++) + ; + f < 15 - k && (f = 15 - k); + c = h.clamp( + c, + 8 * (15 - f) + ); + b = sjcl2.mode.ccm.V(a, b, c, d, e, f); + g = sjcl2.mode.ccm.C(a, g, c, b, e, f); + return h.concat(g.data, g.tag); + }, decrypt: function(a, b, c, d, e) { + e = e || 64; + d = d || []; + var f = sjcl2.bitArray, g = f.bitLength(c) / 8, h = f.bitLength(b), k = f.clamp(b, h - e), l = f.bitSlice(b, h - e), h = (h - e) / 8; + if (7 > g) + throw new sjcl2.exception.invalid("ccm: iv must be at least 7 bytes"); + for (b = 2; 4 > b && h >>> 8 * b; b++) + ; + b < 15 - g && (b = 15 - g); + c = f.clamp(c, 8 * (15 - b)); + k = sjcl2.mode.ccm.C(a, k, c, l, e, b); + a = sjcl2.mode.ccm.V(a, k.data, c, d, e, b); + if (!f.equal(k.tag, a)) + throw new sjcl2.exception.corrupt("ccm: tag doesn't match"); + return k.data; + }, na: function(a, b, c, d, e, f) { + var g = [], h = sjcl2.bitArray, k = h.i; + d = [h.partial(8, (b.length ? 64 : 0) | d - 2 << 2 | f - 1)]; + d = h.concat(d, c); + d[3] |= e; + d = a.encrypt(d); + if (b.length) + for (c = h.bitLength(b) / 8, 65279 >= c ? g = [h.partial(16, c)] : 4294967295 >= c && (g = h.concat([h.partial(16, 65534)], [c])), g = h.concat(g, b), b = 0; b < g.length; b += 4) + d = a.encrypt(k(d, g.slice(b, b + 4).concat([0, 0, 0]))); + return d; + }, V: function(a, b, c, d, e, f) { + var g = sjcl2.bitArray, h = g.i; + e /= 8; + if (e % 2 || 4 > e || 16 < e) + throw new sjcl2.exception.invalid("ccm: invalid tag length"); + if (4294967295 < d.length || 4294967295 < b.length) + throw new sjcl2.exception.bug("ccm: can't deal with 4GiB or more data"); + c = sjcl2.mode.ccm.na(a, d, c, e, g.bitLength(b) / 8, f); + for (d = 0; d < b.length; d += 4) + c = a.encrypt(h(c, b.slice(d, d + 4).concat([0, 0, 0]))); + return g.clamp(c, 8 * e); + }, C: function(a, b, c, d, e, f) { + var g, h = sjcl2.bitArray; + g = h.i; + var k = b.length, l = h.bitLength(b), n = k / 50, m = n; + c = h.concat([h.partial(8, f - 1)], c).concat([0, 0, 0]).slice(0, 4); + d = h.bitSlice(g(d, a.encrypt(c)), 0, e); + if (!k) + return { tag: d, data: [] }; + for (g = 0; g < k; g += 4) + g > n && (sjcl2.mode.ccm.fa(g / k), n += m), c[3]++, e = a.encrypt(c), b[g] ^= e[0], b[g + 1] ^= e[1], b[g + 2] ^= e[2], b[g + 3] ^= e[3]; + return { tag: d, data: h.clamp(b, l) }; + } }; + sjcl2.mode.ocb2 = { name: "ocb2", encrypt: function(a, b, c, d, e, f) { + if (128 !== sjcl2.bitArray.bitLength(c)) + throw new sjcl2.exception.invalid("ocb iv must be 128 bits"); + var g, h = sjcl2.mode.ocb2.S, k = sjcl2.bitArray, l = k.i, n = [0, 0, 0, 0]; + c = h(a.encrypt(c)); + var m, p = []; + d = d || []; + e = e || 64; + for (g = 0; g + 4 < b.length; g += 4) + m = b.slice(g, g + 4), n = l(n, m), p = p.concat(l(c, a.encrypt(l(c, m)))), c = h(c); + m = b.slice(g); + b = k.bitLength(m); + g = a.encrypt(l(c, [0, 0, 0, b])); + m = k.clamp(l(m.concat([0, 0, 0]), g), b); + n = l(n, l(m.concat([0, 0, 0]), g)); + n = a.encrypt(l(n, l(c, h(c)))); + d.length && (n = l(n, f ? d : sjcl2.mode.ocb2.pmac(a, d))); + return p.concat(k.concat(m, k.clamp(n, e))); + }, decrypt: function(a, b, c, d, e, f) { + if (128 !== sjcl2.bitArray.bitLength(c)) + throw new sjcl2.exception.invalid("ocb iv must be 128 bits"); + e = e || 64; + var g = sjcl2.mode.ocb2.S, h = sjcl2.bitArray, k = h.i, l = [0, 0, 0, 0], n = g(a.encrypt(c)), m, p, r = sjcl2.bitArray.bitLength(b) - e, q = []; + d = d || []; + for (c = 0; c + 4 < r / 32; c += 4) + m = k(n, a.decrypt(k(n, b.slice(c, c + 4)))), l = k(l, m), q = q.concat(m), n = g(n); + p = r - 32 * c; + m = a.encrypt(k(n, [0, 0, 0, p])); + m = k(m, h.clamp(b.slice(c), p).concat([ + 0, + 0, + 0 + ])); + l = k(l, m); + l = a.encrypt(k(l, k(n, g(n)))); + d.length && (l = k(l, f ? d : sjcl2.mode.ocb2.pmac(a, d))); + if (!h.equal(h.clamp(l, e), h.bitSlice(b, r))) + throw new sjcl2.exception.corrupt("ocb: tag doesn't match"); + return q.concat(h.clamp(m, p)); + }, pmac: function(a, b) { + var c, d = sjcl2.mode.ocb2.S, e = sjcl2.bitArray, f = e.i, g = [0, 0, 0, 0], h = a.encrypt([0, 0, 0, 0]), h = f(h, d(d(h))); + for (c = 0; c + 4 < b.length; c += 4) + h = d(h), g = f(g, a.encrypt(f(h, b.slice(c, c + 4)))); + c = b.slice(c); + 128 > e.bitLength(c) && (h = f(h, d(h)), c = e.concat(c, [-2147483648, 0, 0, 0])); + g = f(g, c); + return a.encrypt(f(d(f(h, d(h))), g)); + }, S: function(a) { + return [a[0] << 1 ^ a[1] >>> 31, a[1] << 1 ^ a[2] >>> 31, a[2] << 1 ^ a[3] >>> 31, a[3] << 1 ^ 135 * (a[0] >>> 31)]; + } }; + sjcl2.mode.gcm = { name: "gcm", encrypt: function(a, b, c, d, e) { + var f = b.slice(0); + b = sjcl2.bitArray; + d = d || []; + a = sjcl2.mode.gcm.C(true, a, f, d, c, e || 128); + return b.concat(a.data, a.tag); + }, decrypt: function(a, b, c, d, e) { + var f = b.slice(0), g = sjcl2.bitArray, h = g.bitLength(f); + e = e || 128; + d = d || []; + e <= h ? (b = g.bitSlice(f, h - e), f = g.bitSlice(f, 0, h - e)) : (b = f, f = []); + a = sjcl2.mode.gcm.C(false, a, f, d, c, e); + if (!g.equal(a.tag, b)) + throw new sjcl2.exception.corrupt("gcm: tag doesn't match"); + return a.data; + }, ka: function(a, b) { + var c, d, e, f, g, h = sjcl2.bitArray.i; + e = [ + 0, + 0, + 0, + 0 + ]; + f = b.slice(0); + for (c = 0; 128 > c; c++) { + (d = 0 !== (a[Math.floor(c / 32)] & 1 << 31 - c % 32)) && (e = h(e, f)); + g = 0 !== (f[3] & 1); + for (d = 3; 0 < d; d--) + f[d] = f[d] >>> 1 | (f[d - 1] & 1) << 31; + f[0] >>>= 1; + g && (f[0] ^= -520093696); + } + return e; + }, j: function(a, b, c) { + var d, e = c.length; + b = b.slice(0); + for (d = 0; d < e; d += 4) + b[0] ^= 4294967295 & c[d], b[1] ^= 4294967295 & c[d + 1], b[2] ^= 4294967295 & c[d + 2], b[3] ^= 4294967295 & c[d + 3], b = sjcl2.mode.gcm.ka(b, a); + return b; + }, C: function(a, b, c, d, e, f) { + var g, h, k, l, n, m, p, r, q = sjcl2.bitArray; + m = c.length; + p = q.bitLength(c); + r = q.bitLength(d); + h = q.bitLength(e); + g = b.encrypt([0, 0, 0, 0]); + 96 === h ? (e = e.slice(0), e = q.concat(e, [1])) : (e = sjcl2.mode.gcm.j(g, [0, 0, 0, 0], e), e = sjcl2.mode.gcm.j(g, e, [0, 0, Math.floor(h / 4294967296), h & 4294967295])); + h = sjcl2.mode.gcm.j(g, [0, 0, 0, 0], d); + n = e.slice(0); + d = h.slice(0); + a || (d = sjcl2.mode.gcm.j(g, h, c)); + for (l = 0; l < m; l += 4) + n[3]++, k = b.encrypt(n), c[l] ^= k[0], c[l + 1] ^= k[1], c[l + 2] ^= k[2], c[l + 3] ^= k[3]; + c = q.clamp(c, p); + a && (d = sjcl2.mode.gcm.j(g, h, c)); + a = [Math.floor(r / 4294967296), r & 4294967295, Math.floor(p / 4294967296), p & 4294967295]; + d = sjcl2.mode.gcm.j(g, d, a); + k = b.encrypt(e); + d[0] ^= k[0]; + d[1] ^= k[1]; + d[2] ^= k[2]; + d[3] ^= k[3]; + return { tag: q.bitSlice(d, 0, f), data: c }; + } }; + sjcl2.misc.hmac = function(a, b) { + this.W = b = b || sjcl2.hash.sha256; + var c = [[], []], d, e = b.prototype.blockSize / 32; + this.w = [new b(), new b()]; + a.length > e && (a = b.hash(a)); + for (d = 0; d < e; d++) + c[0][d] = a[d] ^ 909522486, c[1][d] = a[d] ^ 1549556828; + this.w[0].update(c[0]); + this.w[1].update(c[1]); + this.R = new b(this.w[0]); + }; + sjcl2.misc.hmac.prototype.encrypt = sjcl2.misc.hmac.prototype.mac = function(a) { + if (this.aa) + throw new sjcl2.exception.invalid("encrypt on already updated hmac called!"); + this.update(a); + return this.digest(a); + }; + sjcl2.misc.hmac.prototype.reset = function() { + this.R = new this.W(this.w[0]); + this.aa = false; + }; + sjcl2.misc.hmac.prototype.update = function(a) { + this.aa = true; + this.R.update(a); + }; + sjcl2.misc.hmac.prototype.digest = function() { + var a = this.R.finalize(), a = new this.W(this.w[1]).update(a).finalize(); + this.reset(); + return a; + }; + sjcl2.misc.pbkdf2 = function(a, b, c, d, e) { + c = c || 1e4; + if (0 > d || 0 > c) + throw new sjcl2.exception.invalid("invalid params to pbkdf2"); + "string" === typeof a && (a = sjcl2.codec.utf8String.toBits(a)); + "string" === typeof b && (b = sjcl2.codec.utf8String.toBits(b)); + e = e || sjcl2.misc.hmac; + a = new e(a); + var f, g, h, k, l = [], n = sjcl2.bitArray; + for (k = 1; 32 * l.length < (d || 1); k++) { + e = f = a.encrypt(n.concat(b, [k])); + for (g = 1; g < c; g++) + for (f = a.encrypt(f), h = 0; h < f.length; h++) + e[h] ^= f[h]; + l = l.concat(e); + } + d && (l = n.clamp(l, d)); + return l; + }; + sjcl2.prng = function(a) { + this.c = [new sjcl2.hash.sha256()]; + this.m = [0]; + this.P = 0; + this.H = {}; + this.N = 0; + this.U = {}; + this.Z = this.f = this.o = this.ha = 0; + this.b = [0, 0, 0, 0, 0, 0, 0, 0]; + this.h = [0, 0, 0, 0]; + this.L = void 0; + this.M = a; + this.D = false; + this.K = { progress: {}, seeded: {} }; + this.u = this.ga = 0; + this.I = 1; + this.J = 2; + this.ca = 65536; + this.T = [0, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024]; + this.da = 3e4; + this.ba = 80; + }; + sjcl2.prng.prototype = { + randomWords: function(a, b) { + var c = [], d; + d = this.isReady(b); + var e; + if (d === this.u) + throw new sjcl2.exception.notReady("generator isn't seeded"); + if (d & this.J) { + d = !(d & this.I); + e = []; + var f = 0, g; + this.Z = e[0] = new Date().valueOf() + this.da; + for (g = 0; 16 > g; g++) + e.push(4294967296 * Math.random() | 0); + for (g = 0; g < this.c.length && (e = e.concat(this.c[g].finalize()), f += this.m[g], this.m[g] = 0, d || !(this.P & 1 << g)); g++) + ; + this.P >= 1 << this.c.length && (this.c.push(new sjcl2.hash.sha256()), this.m.push(0)); + this.f -= f; + f > this.o && (this.o = f); + this.P++; + this.b = sjcl2.hash.sha256.hash(this.b.concat(e)); + this.L = new sjcl2.cipher.aes(this.b); + for (d = 0; 4 > d && (this.h[d] = this.h[d] + 1 | 0, !this.h[d]); d++) + ; + } + for (d = 0; d < a; d += 4) + 0 === (d + 1) % this.ca && y(this), e = z(this), c.push(e[0], e[1], e[2], e[3]); + y(this); + return c.slice(0, a); + }, + setDefaultParanoia: function(a, b) { + if (0 === a && "Setting paranoia=0 will ruin your security; use it only for testing" !== b) + throw new sjcl2.exception.invalid("Setting paranoia=0 will ruin your security; use it only for testing"); + this.M = a; + }, + addEntropy: function(a, b, c) { + c = c || "user"; + var d, e, f = new Date().valueOf(), g = this.H[c], h = this.isReady(), k = 0; + d = this.U[c]; + void 0 === d && (d = this.U[c] = this.ha++); + void 0 === g && (g = this.H[c] = 0); + this.H[c] = (this.H[c] + 1) % this.c.length; + switch (typeof a) { + case "number": + void 0 === b && (b = 1); + this.c[g].update([d, this.N++, 1, b, f, 1, a | 0]); + break; + case "object": + c = Object.prototype.toString.call(a); + if ("[object Uint32Array]" === c) { + e = []; + for (c = 0; c < a.length; c++) + e.push(a[c]); + a = e; + } else + for ("[object Array]" !== c && (k = 1), c = 0; c < a.length && !k; c++) + "number" !== typeof a[c] && (k = 1); + if (!k) { + if (void 0 === b) + for (c = b = 0; c < a.length; c++) + for (e = a[c]; 0 < e; ) + b++, e = e >>> 1; + this.c[g].update([d, this.N++, 2, b, f, a.length].concat(a)); + } + break; + case "string": + void 0 === b && (b = a.length); + this.c[g].update([d, this.N++, 3, b, f, a.length]); + this.c[g].update(a); + break; + default: + k = 1; + } + if (k) + throw new sjcl2.exception.bug("random: addEntropy only supports number, array of numbers or string"); + this.m[g] += b; + this.f += b; + h === this.u && (this.isReady() !== this.u && A("seeded", Math.max(this.o, this.f)), A("progress", this.getProgress())); + }, + isReady: function(a) { + a = this.T[void 0 !== a ? a : this.M]; + return this.o && this.o >= a ? this.m[0] > this.ba && new Date().valueOf() > this.Z ? this.J | this.I : this.I : this.f >= a ? this.J | this.u : this.u; + }, + getProgress: function(a) { + a = this.T[a ? a : this.M]; + return this.o >= a ? 1 : this.f > a ? 1 : this.f / a; + }, + startCollectors: function() { + if (!this.D) { + this.a = { loadTimeCollector: B(this, this.ma), mouseCollector: B(this, this.oa), keyboardCollector: B(this, this.la), accelerometerCollector: B(this, this.ea), touchCollector: B(this, this.qa) }; + if (window.addEventListener) + window.addEventListener( + "load", + this.a.loadTimeCollector, + false + ), window.addEventListener("mousemove", this.a.mouseCollector, false), window.addEventListener("keypress", this.a.keyboardCollector, false), window.addEventListener("devicemotion", this.a.accelerometerCollector, false), window.addEventListener("touchmove", this.a.touchCollector, false); + else if (document.attachEvent) + document.attachEvent("onload", this.a.loadTimeCollector), document.attachEvent("onmousemove", this.a.mouseCollector), document.attachEvent("keypress", this.a.keyboardCollector); + else + throw new sjcl2.exception.bug("can't attach event"); + this.D = true; + } + }, + stopCollectors: function() { + this.D && (window.removeEventListener ? (window.removeEventListener("load", this.a.loadTimeCollector, false), window.removeEventListener("mousemove", this.a.mouseCollector, false), window.removeEventListener("keypress", this.a.keyboardCollector, false), window.removeEventListener("devicemotion", this.a.accelerometerCollector, false), window.removeEventListener("touchmove", this.a.touchCollector, false)) : document.detachEvent && (document.detachEvent("onload", this.a.loadTimeCollector), document.detachEvent( + "onmousemove", + this.a.mouseCollector + ), document.detachEvent("keypress", this.a.keyboardCollector)), this.D = false); + }, + addEventListener: function(a, b) { + this.K[a][this.ga++] = b; + }, + removeEventListener: function(a, b) { + var c, d, e = this.K[a], f = []; + for (d in e) + e.hasOwnProperty(d) && e[d] === b && f.push(d); + for (c = 0; c < f.length; c++) + d = f[c], delete e[d]; + }, + la: function() { + C(this, 1); + }, + oa: function(a) { + var b, c; + try { + b = a.x || a.clientX || a.offsetX || 0, c = a.y || a.clientY || a.offsetY || 0; + } catch (d) { + c = b = 0; + } + 0 != b && 0 != c && this.addEntropy([b, c], 2, "mouse"); + C(this, 0); + }, + qa: function(a) { + a = a.touches[0] || a.changedTouches[0]; + this.addEntropy([a.pageX || a.clientX, a.pageY || a.clientY], 1, "touch"); + C(this, 0); + }, + ma: function() { + C(this, 2); + }, + ea: function(a) { + a = a.accelerationIncludingGravity.x || a.accelerationIncludingGravity.y || a.accelerationIncludingGravity.z; + if (window.orientation) { + var b = window.orientation; + "number" === typeof b && this.addEntropy(b, 1, "accelerometer"); + } + a && this.addEntropy(a, 2, "accelerometer"); + C(this, 0); + } + }; + function A(a, b) { + var c, d = sjcl2.random.K[a], e = []; + for (c in d) + d.hasOwnProperty(c) && e.push(d[c]); + for (c = 0; c < e.length; c++) + e[c](b); + } + function C(a, b) { + "undefined" !== typeof window && window.performance && "function" === typeof window.performance.now ? a.addEntropy(window.performance.now(), b, "loadtime") : a.addEntropy(new Date().valueOf(), b, "loadtime"); + } + function y(a) { + a.b = z(a).concat(z(a)); + a.L = new sjcl2.cipher.aes(a.b); + } + function z(a) { + for (var b = 0; 4 > b && (a.h[b] = a.h[b] + 1 | 0, !a.h[b]); b++) + ; + return a.L.encrypt(a.h); + } + function B(a, b) { + return function() { + b.apply(a, arguments); + }; + } + sjcl2.random = new sjcl2.prng(6); + a: + try { + if (G = "undefined" !== typeof module && module.exports) { + try { + H = __require("crypto"); + } catch (a) { + H = null; + } + G = E = H; + } + if (G && E.randomBytes) + D = E.randomBytes(128), D = new Uint32Array(new Uint8Array(D).buffer), sjcl2.random.addEntropy(D, 1024, "crypto['randomBytes']"); + else if ("undefined" !== typeof window && "undefined" !== typeof Uint32Array) { + F = new Uint32Array(32); + if (window.crypto && window.crypto.getRandomValues) + window.crypto.getRandomValues(F); + else if (window.msCrypto && window.msCrypto.getRandomValues) + window.msCrypto.getRandomValues(F); + else + break a; + sjcl2.random.addEntropy(F, 1024, "crypto['getRandomValues']"); + } + } catch (a) { + "undefined" !== typeof window && window.console && (console.log("There was an error collecting entropy from the browser:"), console.log(a)); + } + var D; + var E; + var F; + var G; + var H; + sjcl2.json = { defaults: { v: 1, iter: 1e4, ks: 128, ts: 64, mode: "ccm", adata: "", cipher: "aes" }, ja: function(a, b, c, d) { + c = c || {}; + d = d || {}; + var e = sjcl2.json, f = e.g({ iv: sjcl2.random.randomWords(4, 0) }, e.defaults), g; + e.g(f, c); + c = f.adata; + "string" === typeof f.salt && (f.salt = sjcl2.codec.base64.toBits(f.salt)); + "string" === typeof f.iv && (f.iv = sjcl2.codec.base64.toBits(f.iv)); + if (!sjcl2.mode[f.mode] || !sjcl2.cipher[f.cipher] || "string" === typeof a && 100 >= f.iter || 64 !== f.ts && 96 !== f.ts && 128 !== f.ts || 128 !== f.ks && 192 !== f.ks && 256 !== f.ks || 2 > f.iv.length || 4 < f.iv.length) + throw new sjcl2.exception.invalid("json encrypt: invalid parameters"); + "string" === typeof a ? (g = sjcl2.misc.cachedPbkdf2(a, f), a = g.key.slice(0, f.ks / 32), f.salt = g.salt) : sjcl2.ecc && a instanceof sjcl2.ecc.elGamal.publicKey && (g = a.kem(), f.kemtag = g.tag, a = g.key.slice(0, f.ks / 32)); + "string" === typeof b && (b = sjcl2.codec.utf8String.toBits(b)); + "string" === typeof c && (f.adata = c = sjcl2.codec.utf8String.toBits(c)); + g = new sjcl2.cipher[f.cipher](a); + e.g(d, f); + d.key = a; + f.ct = "ccm" === f.mode && sjcl2.arrayBuffer && sjcl2.arrayBuffer.ccm && b instanceof ArrayBuffer ? sjcl2.arrayBuffer.ccm.encrypt(g, b, f.iv, c, f.ts) : sjcl2.mode[f.mode].encrypt(g, b, f.iv, c, f.ts); + return f; + }, encrypt: function(a, b, c, d) { + var e = sjcl2.json, f = e.ja.apply(e, arguments); + return e.encode(f); + }, ia: function(a, b, c, d) { + c = c || {}; + d = d || {}; + var e = sjcl2.json; + b = e.g(e.g(e.g({}, e.defaults), b), c, true); + var f, g; + f = b.adata; + "string" === typeof b.salt && (b.salt = sjcl2.codec.base64.toBits(b.salt)); + "string" === typeof b.iv && (b.iv = sjcl2.codec.base64.toBits(b.iv)); + if (!sjcl2.mode[b.mode] || !sjcl2.cipher[b.cipher] || "string" === typeof a && 100 >= b.iter || 64 !== b.ts && 96 !== b.ts && 128 !== b.ts || 128 !== b.ks && 192 !== b.ks && 256 !== b.ks || !b.iv || 2 > b.iv.length || 4 < b.iv.length) + throw new sjcl2.exception.invalid("json decrypt: invalid parameters"); + "string" === typeof a ? (g = sjcl2.misc.cachedPbkdf2(a, b), a = g.key.slice(0, b.ks / 32), b.salt = g.salt) : sjcl2.ecc && a instanceof sjcl2.ecc.elGamal.secretKey && (a = a.unkem(sjcl2.codec.base64.toBits(b.kemtag)).slice(0, b.ks / 32)); + "string" === typeof f && (f = sjcl2.codec.utf8String.toBits(f)); + g = new sjcl2.cipher[b.cipher](a); + f = "ccm" === b.mode && sjcl2.arrayBuffer && sjcl2.arrayBuffer.ccm && b.ct instanceof ArrayBuffer ? sjcl2.arrayBuffer.ccm.decrypt(g, b.ct, b.iv, b.tag, f, b.ts) : sjcl2.mode[b.mode].decrypt(g, b.ct, b.iv, f, b.ts); + e.g(d, b); + d.key = a; + return 1 === c.raw ? f : sjcl2.codec.utf8String.fromBits(f); + }, decrypt: function(a, b, c, d) { + var e = sjcl2.json; + return e.ia(a, e.decode(b), c, d); + }, encode: function(a) { + var b, c = "{", d = ""; + for (b in a) + if (a.hasOwnProperty(b)) { + if (!b.match(/^[a-z0-9]+$/i)) + throw new sjcl2.exception.invalid("json encode: invalid property name"); + c += d + '"' + b + '":'; + d = ","; + switch (typeof a[b]) { + case "number": + case "boolean": + c += a[b]; + break; + case "string": + c += '"' + escape(a[b]) + '"'; + break; + case "object": + c += '"' + sjcl2.codec.base64.fromBits(a[b], 0) + '"'; + break; + default: + throw new sjcl2.exception.bug("json encode: unsupported type"); + } + } + return c + "}"; + }, decode: function(a) { + a = a.replace(/\s/g, ""); + if (!a.match(/^\{.*\}$/)) + throw new sjcl2.exception.invalid("json decode: this isn't json!"); + a = a.replace(/^\{|\}$/g, "").split(/,/); + var b = {}, c, d; + for (c = 0; c < a.length; c++) { + if (!(d = a[c].match(/^\s*(?:(["']?)([a-z][a-z0-9]*)\1)\s*:\s*(?:(-?\d+)|"([a-z0-9+\/%*_.@=\-]*)"|(true|false))$/i))) + throw new sjcl2.exception.invalid("json decode: this isn't json!"); + null != d[3] ? b[d[2]] = parseInt(d[3], 10) : null != d[4] ? b[d[2]] = d[2].match(/^(ct|adata|salt|iv)$/) ? sjcl2.codec.base64.toBits(d[4]) : unescape(d[4]) : null != d[5] && (b[d[2]] = "true" === d[5]); + } + return b; + }, g: function(a, b, c) { + void 0 === a && (a = {}); + if (void 0 === b) + return a; + for (var d in b) + if (b.hasOwnProperty(d)) { + if (c && void 0 !== a[d] && a[d] !== b[d]) + throw new sjcl2.exception.invalid("required parameter overridden"); + a[d] = b[d]; + } + return a; + }, sa: function(a, b) { + var c = {}, d; + for (d in a) + a.hasOwnProperty(d) && a[d] !== b[d] && (c[d] = a[d]); + return c; + }, ra: function(a, b) { + var c = {}, d; + for (d = 0; d < b.length; d++) + void 0 !== a[b[d]] && (c[b[d]] = a[b[d]]); + return c; + } }; + sjcl2.encrypt = sjcl2.json.encrypt; + sjcl2.decrypt = sjcl2.json.decrypt; + sjcl2.misc.pa = {}; + sjcl2.misc.cachedPbkdf2 = function(a, b) { + var c = sjcl2.misc.pa, d; + b = b || {}; + d = b.iter || 1e3; + c = c[a] = c[a] || {}; + d = c[d] = c[d] || { firstSalt: b.salt && b.salt.length ? b.salt.slice(0) : sjcl2.random.randomWords(2, 0) }; + c = void 0 === b.salt ? d.firstSalt : b.salt; + d[c] = d[c] || sjcl2.misc.pbkdf2(a, c, b.iter); + return { key: d[c].slice(0), salt: c.slice(0) }; + }; + "undefined" !== typeof module && module.exports && (module.exports = sjcl2); + "function" === typeof define && define([], function() { + return sjcl2; + }); + } + }); + + // ../../node_modules/web-worker/cjs/browser.js + var require_browser = __commonJS({ + "../../node_modules/web-worker/cjs/browser.js"(exports, module) { + module.exports = Worker; + } + }); + + // ../../Graph.ts + function parseFunctionFromText(method = "") { + let getFunctionBody = (methodString) => { + return methodString.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i, "$2$3$4"); + }; + let getFunctionHead = (methodString) => { + let startindex = methodString.indexOf("=>") + 1; + if (startindex <= 0) { + startindex = methodString.indexOf("){"); + } + if (startindex <= 0) { + startindex = methodString.indexOf(") {"); + } + return methodString.slice(0, methodString.indexOf("{", startindex) + 1); + }; + let newFuncHead = getFunctionHead(method); + let newFuncBody = getFunctionBody(method); + let newFunc; + if (newFuncHead.includes("function")) { + let varName = newFuncHead.split("(")[1].split(")")[0]; + newFunc = new Function(varName, newFuncBody); + } else { + if (newFuncHead.substring(0, 6) === newFuncBody.substring(0, 6)) { + let varName = newFuncHead.split("(")[1].split(")")[0]; + newFunc = new Function(varName, newFuncBody.substring(newFuncBody.indexOf("{") + 1, newFuncBody.length - 1)); + } else { + try { + newFunc = (0, eval)(newFuncHead + newFuncBody + "}"); + } catch { + } + } + } + return newFunc; + } + var state = { + pushToState: {}, + data: {}, + triggers: {}, + setState(updateObj) { + Object.assign(state.data, updateObj); + for (const prop of Object.getOwnPropertyNames(updateObj)) { + if (state.triggers[prop]) + state.triggers[prop].forEach((obj) => obj.onchange(state.data[prop])); + } + return state.data; + }, + subscribeTrigger(key, onchange) { + if (key) { + if (!state.triggers[key]) { + state.triggers[key] = []; + } + let l = state.triggers[key].length; + state.triggers[key].push({ idx: l, onchange }); + return state.triggers[key].length - 1; + } else + return void 0; + }, + unsubscribeTrigger(key, sub) { + let idx = void 0; + let triggers = state.triggers[key]; + if (triggers) { + if (!sub) + delete state.triggers[key]; + else { + let obj = triggers.find((o) => { + if (o.idx === sub) { + return true; + } + }); + if (obj) + triggers.splice(idx, 1); + return true; + } + } + }, + subscribeTriggerOnce(key, onchange) { + let sub; + let changed = (value) => { + onchange(value); + state.unsubscribeTrigger(key, sub); + }; + sub = state.subscribeTrigger(key, changed); + } + }; + var GraphNode = class { + constructor(properties = {}, parentNode, graph) { + this.nodes = /* @__PURE__ */ new Map(); + this._initial = {}; + this.state = state; + this.isLooping = false; + this.isAnimating = false; + this.looper = void 0; + this.animation = void 0; + this.forward = true; + this.backward = false; + this.runSync = false; + this.firstRun = true; + this.DEBUGNODE = false; + this.operator = (...args) => { + return args; + }; + this.runOp = (...args) => { + if (this.DEBUGNODE) + console.time(this.tag); + let result = this.operator(...args); + if (result instanceof Promise) { + result.then((res) => { + if (res !== void 0) + this.setState({ [this.tag]: res }); + if (this.DEBUGNODE) { + console.timeEnd(this.tag); + if (result !== void 0) + console.log(`${this.tag} result:`, result); + } + ; + return res; + }); + } else { + if (result !== void 0) + this.setState({ [this.tag]: result }); + if (this.DEBUGNODE) { + console.timeEnd(this.tag); + if (result !== void 0) + console.log(`${this.tag} result:`, result); + } + ; + } + return result; + }; + this.setOperator = (operator) => { + if (typeof operator !== "function") + return operator; + this.operator = operator.bind(this); + return operator; + }; + this.runAsync = (...args) => { + return new Promise((res, rej) => { + res(this.run(...args)); + }); + }; + this.transformArgs = (args = []) => args; + this.run = (...args) => { + if (typeof this.transformArgs === "function") + args = this.transformArgs(args, this); + if (this.firstRun) { + this.firstRun = false; + if (!(this.children && this.forward || this.parent && this.backward || this.repeat || this.delay || this.frame || this.recursive || this.branch)) + this.runSync = true; + if (this.animate && !this.isAnimating) { + this.runAnimation(this.animation, args); + } + if (this.loop && typeof this.loop === "number" && !this.isLooping) { + this.runLoop(this.looper, args); + } + if (this.loop || this.animate) + return; + } + if (this.runSync) { + let res = this.runOp(...args); + return res; + } + return new Promise(async (resolve) => { + if (this) { + let run = (node, tick = 0, ...input) => { + return new Promise(async (r) => { + tick++; + let res = await node.runOp(...input); + if (node.repeat) { + while (tick < node.repeat) { + if (node.delay) { + setTimeout(async () => { + r(await run(node, tick, ...input)); + }, node.delay); + break; + } else if (node.frame && window?.requestAnimationFrame) { + requestAnimationFrame(async () => { + r(await run(node, tick, ...input)); + }); + break; + } else + res = await node.runOp(...input); + tick++; + } + if (tick === node.repeat) { + r(res); + return; + } + } else if (node.recursive) { + while (tick < node.recursive) { + if (node.delay) { + setTimeout(async () => { + r(await run(node, tick, ...res)); + }, node.delay); + break; + } else if (node.frame && window?.requestAnimationFrame) { + requestAnimationFrame(async () => { + r(await run(node, tick, ...res)); + }); + break; + } else + res = await node.runOp(...res); + tick++; + } + if (tick === node.recursive) { + r(res); + return; + } + } else { + r(res); + return; + } + }); + }; + let runnode = async () => { + let res = await run(this, void 0, ...args); + if (res !== void 0) { + if (this.backward && this.parent instanceof GraphNode) { + if (Array.isArray(res)) + await this.runParent(this, ...res); + else + await this.runParent(this, res); + } + if (this.children && this.forward) { + if (Array.isArray(res)) + await this.runChildren(this, ...res); + else + await this.runChildren(this, res); + } + if (this.branch) { + this.runBranch(this, res); + } + } + return res; + }; + if (this.delay) { + setTimeout(async () => { + resolve(await runnode()); + }, this.delay); + } else if (this.frame && window?.requestAnimationFrame) { + requestAnimationFrame(async () => { + resolve(await runnode()); + }); + } else { + resolve(await runnode()); + } + } else + resolve(void 0); + }); + }; + this.runParent = async (n, ...args) => { + if (n.backward && n.parent) { + if (typeof n.parent === "string") { + if (n.graph && n.graph?.get(n.parent)) { + n.parent = n.graph; + if (n.parent) + this.nodes.set(n.parent.tag, n.parent); + } else + n.parent = this.nodes.get(n.parent); + } + if (n.parent instanceof GraphNode) + await n.parent.run(...args); + } + }; + this.runChildren = async (n, ...args) => { + if (typeof n.children === "object") { + for (const key in n.children) { + if (typeof n.children[key] === "string") { + if (n.graph && n.graph?.get(n.children[key])) { + n.children[key] = n.graph.get(n.children[key]); + if (!n.nodes.get(n.children[key].tag)) + n.nodes.set(n.children[key].tag, n.children[key]); + } + if (!n.children[key] && n.nodes.get(n.children[key])) + n.children[key] = n.nodes.get(n.children[key]); + } else if (typeof n.children[key] === "undefined" || n.children[key] === true) { + if (n.graph && n.graph?.get(key)) { + n.children[key] = n.graph.get(key); + if (!n.nodes.get(n.children[key].tag)) + n.nodes.set(n.children[key].tag, n.children[key]); + } + if (!n.children[key] && n.nodes.get(key)) + n.children[key] = n.nodes.get(key); + } + if (n.children[key]?.runOp) + await n.children[key].run(...args); + } + } + }; + this.runBranch = async (n, output) => { + if (n.branch) { + let keys = Object.keys(n.branch); + await Promise.all(keys.map(async (k) => { + if (typeof n.branch[k].if === "object") + n.branch[k].if = stringifyFast(n.branch[k].if); + let pass = false; + if (typeof n.branch[k].if === "function") { + pass = n.branch[k].if(output); + } else { + if (typeof output === "object") { + if (stringifyFast(output) === n.branch[k].if) + pass = true; + } else if (output === n.branch[k].if) + pass = true; + } + if (pass) { + if (n.branch[k].then.run) { + if (Array.isArray(output)) + await n.branch[k].then.run(...output); + else + await n.branch[k].then.run(...output); + } else if (typeof n.branch[k].then === "function") { + if (Array.isArray(output)) + await n.branch[k].then(...output); + else + await n.branch[k].then(output); + } else if (typeof n.branch[k].then === "string") { + if (n.graph) + n.branch[k].then = n.graph.nodes.get(n.branch[k].then); + else + n.branch[k].then = n.nodes.get(n.branch[k].then); + if (n.branch[k].then.run) { + if (Array.isArray(output)) + await n.branch[k].then.run(...output); + else + await n.branch[k].then.run(...output); + } + } + } + return pass; + })); + } + }; + this.runAnimation = (animation = this.animation, args = []) => { + this.animation = animation; + if (!animation) + this.animation = this.operator; + if (this.animate && !this.isAnimating && "requestAnimationFrame" in window) { + this.isAnimating = true; + let anim = async () => { + if (this.isAnimating) { + if (this.DEBUGNODE) + console.time(this.tag); + let result = this.animation.call(this, ...args); + if (result instanceof Promise) { + result = await result; + } + if (this.DEBUGNODE) { + console.timeEnd(this.tag); + if (result !== void 0) + console.log(`${this.tag} result:`, result); + } + ; + if (result !== void 0) { + if (this.tag) + this.setState({ [this.tag]: result }); + if (this.backward && this.parent?.run) { + if (Array.isArray(result)) + await this.runParent(this, ...result); + else + await this.runParent(this, result); + } + if (this.children && this.forward) { + if (Array.isArray(result)) + await this.runChildren(this, ...result); + else + await this.runChildren(this, result); + } + if (this.branch) { + this.runBranch(this, result); + } + this.setState({ [this.tag]: result }); + } + requestAnimationFrame(anim); + } + }; + requestAnimationFrame(anim); + } + }; + this.runLoop = (loop = this.looper, args = [], timeout = this.loop) => { + this.looper = loop; + if (!loop) + this.looper = this.operator; + if (typeof timeout === "number" && !this.isLooping) { + this.isLooping = true; + let looping = async () => { + if (this.isLooping) { + if (this.DEBUGNODE) + console.time(this.tag); + let result = this.looper.call(this, ...args); + if (result instanceof Promise) { + result = await result; + } + if (this.DEBUGNODE) { + console.timeEnd(this.tag); + if (result !== void 0) + console.log(`${this.tag} result:`, result); + } + ; + if (result !== void 0) { + if (this.tag) + this.setState({ [this.tag]: result }); + if (this.backward && this.parent?.run) { + if (Array.isArray(result)) + await this.runParent(this, ...result); + else + await this.runParent(this, result); + } + if (this.children && this.forward) { + if (Array.isArray(result)) + await this.runChildren(this, ...result); + else + await this.runChildren(this, result); + } + if (this.branch) { + this.runBranch(this, result); + } + this.setState({ [this.tag]: result }); + } + setTimeout(async () => { + await looping(); + }, timeout); + } + }; + looping(); + } + }; + this.setParent = (parent) => { + this.parent = parent; + if (this.backward) + this.runSync = false; + }; + this.setChildren = (children) => { + this.children = children; + if (this.forward) + this.runSync = false; + }; + this.add = (n = {}) => { + if (typeof n === "function") + n = { operator: n }; + if (!(n instanceof GraphNode)) + n = new GraphNode(n, this, this.graph); + this.nodes.set(n.tag, n); + if (this.graph) { + this.graph.nodes.set(n.tag, n); + this.graph.nNodes = this.graph.nodes.size; + } + return n; + }; + this.remove = (n) => { + if (typeof n === "string") + n = this.nodes.get(n); + if (n?.tag) { + this.nodes.delete(n.tag); + if (this.children[n.tag]) + delete this.children[n.tag]; + if (this.graph) { + this.graph.nodes.delete(n.tag); + this.graph.nNodes = this.graph.nodes.size; + } + this.nodes.forEach((n2) => { + if (n2.nodes.get(n2.tag)) { + n2.nodes.delete(n2.tag); + if (n2.children[n2.tag]) + delete n2.children[n2.tag]; + if (n2.parent?.tag === n2.tag) + delete n2.parent; + } + }); + if (n.ondelete) + n.ondelete(n); + } + }; + this.append = (n, parentNode = this) => { + if (typeof n === "string") + n = this.nodes.get(n); + if (n?.nodes) { + parentNode.addChildren(n); + if (n.forward) + n.runSync = false; + } + }; + this.subscribe = (callback, tag = this.tag) => { + if (callback.run) { + return this.subscribeNode(callback); + } else + return this.state.subscribeTrigger(tag, callback); + }; + this.unsubscribe = (sub, tag = this.tag) => { + return this.state.unsubscribeTrigger(tag, sub); + }; + this.addChildren = (children) => { + if (!this.children) + this.children = {}; + if (typeof children === "object") { + Object.assign(this.children, children); + } + this.convertChildrenToNodes(); + if (this.forward) + this.runSync = false; + }; + this.callParent = (...args) => { + if (typeof this.parent === "string") { + if (this.graph && this.graph?.get(this.parent)) { + this.parent = this.graph; + if (this.parent) + this.nodes.set(this.parent.tag, this.parent); + } else + this.parent = this.nodes.get(this.parent); + } + if (typeof this.parent?.operator === "function") + return this.parent.runOp(...args); + }; + this.callChildren = (...args) => { + let result; + if (typeof this.children === "object") { + for (const key in this.children) { + if (this.children[key]?.runOp) + this.children[key].runOp(...args); + } + } + return result; + }; + this.getProps = (n = this) => { + return { + tag: n.tag, + operator: n.operator, + graph: n.graph, + children: n.children, + parent: n.parent, + forward: n.forward, + backward: n.bacward, + loop: n.loop, + animate: n.animate, + frame: n.frame, + delay: n.delay, + recursive: n.recursive, + repeat: n.repeat, + branch: n.branch, + oncreate: n.oncreate, + DEBUGNODE: n.DEBUGNODE, + ...this._initial + }; + }; + this.setProps = (props = {}) => { + let tmp = Object.assign({}, props); + if (tmp.children) { + this.addChildren(props.children); + delete tmp.children; + } + if (tmp.operator) { + this.setOperator(props.operator); + delete tmp.operator; + } + Object.assign(tmp, props); + if (!(this.children && this.forward || this.parent && this.backward || this.repeat || this.delay || this.frame || this.recursive)) + this.runSync = true; + }; + this.removeTree = (n) => { + if (n) { + if (typeof n === "string") + n = this.nodes.get(n); + } + if (n?.nodes) { + let checked = {}; + const recursivelyRemove = (node) => { + if (typeof node.children === "object" && !checked[node.tag]) { + checked[node.tag] = true; + for (const key in node.children) { + if (node.children[key].stopNode) + node.children[key].stopNode(); + if (node.children[key].tag) { + if (this.nodes.get(node.children[key].tag)) + this.nodes.delete(node.children[key].tag); + this.nodes.forEach((n2) => { + if (n2.nodes.get(node.children[key].tag)) + n2.nodes.delete(node.children[key].tag); + if (n2.children[key] instanceof GraphNode) + delete n2.children[key]; + }); + recursivelyRemove(node.children[key]); + } + } + } + }; + if (n.stopNode) + n.stopNode(); + if (n.tag) { + this.nodes.delete(n.tag); + if (this.children[n.tag]) + delete this.children[n.tag]; + if (this.parent?.tag === n.tag) + delete this.parent; + if (this[n.tag] instanceof GraphNode) + delete this[n.tag]; + this.nodes.forEach((n2) => { + if (n2?.tag) { + if (n2.nodes.get(n2.tag)) + n2.nodes.delete(n2.tag); + if (n2.children[n2.tag] instanceof GraphNode) + delete n2.children[n2.tag]; + } + }); + recursivelyRemove(n); + if (this.graph) + this.graph.removeTree(n, checked); + else if (n.ondelete) + n.ondelete(n); + } + } + }; + this.checkNodesHaveChildMapped = (n, child, checked = {}) => { + let tag = n.tag; + if (!tag) + tag = n.name; + if (!checked[tag]) { + checked[tag] = true; + if (n.children) { + if (child.tag in n.children) { + if (n.children[child.tag] instanceof GraphNode) { + if (!n.nodes.get(child.tag)) + n.nodes.set(child.tag, child); + n.children[child.tag] = child; + if (!n.firstRun) + n.firstRun = true; + } + } + } + if (n.parent instanceof GraphNode) { + if (n.nodes.get(child.tag) && !n.parent.nodes.get(child.tag)) + n.parent.nodes.set(child.tag, child); + if (n.parent.children) { + this.checkNodesHaveChildMapped(n.parent, child, checked); + } else if (n.nodes) { + n.nodes.forEach((n2) => { + if (!checked[n2.tag]) { + this.checkNodesHaveChildMapped(n2, child, checked); + } + }); + } + } + if (n.graph) { + if (n.parent && n.parent.name !== n.graph.name) { + n.graph.nodes.forEach((n2) => { + if (!checked[n2.tag]) { + this.checkNodesHaveChildMapped(n2, child, checked); + } + }); + } + } + } + }; + this.convertChildrenToNodes = (n = this) => { + if (n?.children) { + for (const key in n.children) { + if (!(n.children[key] instanceof GraphNode)) { + if (typeof n.children[key] === "object") { + if (!n.children[key].tag) + n.children[key].tag = key; + if (!n.nodes.get(n.children[key].tag)) { + n.children[key] = new GraphNode(n.children[key], n, n.graph); + this.checkNodesHaveChildMapped(n, n.children[key]); + } + } else { + if (typeof n.children[key] === "undefined" || n.children[key] == true) { + n.children[key] = n.graph.get(key); + if (!n.children[key]) + n.children[key] = n.nodes.get(key); + } else if (typeof n.children[key] === "string") { + let k = n.children[key]; + n.children[key] = n.graph.get(k); + if (!n.children[key]) + n.children[key] = n.nodes.get(key); + } + if (n.children[key] instanceof GraphNode) { + if (n.graph) { + let props = n.children[key].getProps(); + delete props.parent; + delete props.graph; + if (n.source instanceof Graph) { + n.children[key] = new GraphNode(props, n, n.source); + } else { + n.children[key] = new GraphNode(props, n, n.graph); + } + } + n.nodes.set(n.children[key].tag, n.children[key]); + this.checkNodesHaveChildMapped(n, n.children[key]); + if (!(n.children[key].tag in n)) + n[n.children[key].tag] = n.children[key]; + } + } + } + } + } + return n.children; + }; + this.stopLooping = (n = this) => { + n.isLooping = false; + }; + this.stopAnimating = (n = this) => { + n.isAnimating = false; + }; + this.stopNode = (n = this) => { + n.stopAnimating(n); + n.stopLooping(n); + }; + this.subscribeNode = (n) => { + if (typeof n === "string") + n = this.nodes.get(n); + if (n.tag) + this.nodes.set(n.tag, n); + if (n) + return this.state.subscribeTrigger( + this.tag, + (res) => { + if (Array.isArray(res)) + n.run(...res); + else + n.run(res); + } + ); + }; + this.print = (n = this, printChildren = true, nodesPrinted = []) => { + let dummyNode = new GraphNode(); + if (typeof n === "string") + n = this.nodes.get(n); + if (n instanceof GraphNode) { + nodesPrinted.push(n.tag); + let jsonToPrint = { + tag: n.tag, + operator: n.operator.toString() + }; + if (n.parent) + jsonToPrint.parent = n.parent.tag; + if (typeof n.children === "object") { + for (const key in n.children) { + if (typeof n.children[key] === "string") + return n.children[key]; + if (nodesPrinted.includes(n.children[key].tag)) + return n.children[key].tag; + else if (!printChildren) { + return n.children[key].tag; + } else + return n.children[key].print(n.children[key], printChildren, nodesPrinted); + } + } + for (const prop in n) { + if (prop === "parent" || prop === "children") + continue; + if (typeof dummyNode[prop] === "undefined") { + if (typeof n[prop] === "function") { + jsonToPrint[prop] = n[prop].toString(); + } else if (typeof n[prop] === "object") { + jsonToPrint[prop] = JSON.stringifyWithCircularRefs(n[prop]); + } else { + jsonToPrint[prop] = n[prop]; + } + } + } + return JSON.stringify(jsonToPrint); + } + }; + this.reconstruct = (json) => { + let parsed = reconstructObject(json); + if (parsed) + return this.add(parsed); + }; + this.setState = this.state.setState; + this.DEBUGNODES = (debugging = true) => { + this.DEBUGNODE = debugging; + this.nodes.forEach((n) => { + if (debugging) + n.DEBUGNODE = true; + else + n.DEBUGNODE = false; + }); + }; + if (typeof properties === "function") { + properties = { operator: properties }; + } + if (typeof properties === "object") { + if (properties instanceof GraphNode && properties._initial) + Object.assign(properties, properties._initial); + if (properties instanceof Graph) { + let source = properties; + properties = { + source, + operator: (input) => { + if (typeof input === "object") { + let result = {}; + for (const key in input) { + if (typeof source[key] === "function") { + if (Array.isArray(input[key])) + result[key] = source[key](...input[key]); + else + result[key] = source[key](input[key]); + } else { + source[key] = input[key]; + result[key] = source[key]; + } + } + return result; + } + return source; + } + }; + if (source.operator) + properties.operator = source.operator; + if (source.children) + properties.children = source.children; + if (source.forward) + properties.forward = source.forward; + if (source.backward) + properties.backward = source.backward; + if (source.repeat) + properties.repeat = source.repeat; + if (source.recursive) + properties.recursive = source.recursive; + if (source.loop) + properties.loop = source.loop; + if (source.animate) + properties.animate = source.animate; + if (source.looper) + properties.looper = source.looper; + if (source.animation) + properties.animation = source.animation; + if (source.delay) + properties.delay = source.delay; + if (source.tag) + properties.tag = source.tag; + if (source.oncreate) + properties.oncreate = source.oncreate; + if (source.node) { + if (source.node._initial) + Object.assign(properties, source.node._initial); + } + if (source._initial) + Object.assign(properties, source._initial); + this.nodes = source.nodes; + source.node = this; + if (graph) { + source.nodes.forEach((n) => { + if (!graph.nodes.get(n.tag)) { + graph.nodes.set(n.tag, n); + graph.nNodes++; + } + }); + } + } + if (properties.tag && (graph || parentNode)) { + let hasnode; + if (graph?.nodes) { + hasnode = graph.nodes.get(properties.tag); + } + if (!hasnode && parentNode?.nodes) { + hasnode = parentNode.nodes.get(properties.tag); + } + if (hasnode) { + for (let k in hasnode) + this[k] = hasnode[k]; + if (!this.source) + this.source = hasnode; + let props = hasnode.getProps(); + delete props.graph; + delete props.parent; + for (let k in props) + properties[k] = props[k]; + } + } + if (properties?.operator) { + properties.operator = this.setOperator(properties.operator); + } + if (!properties.tag && graph) { + properties.tag = `node${graph.nNodes}`; + } else if (!properties.tag) { + properties.tag = `node${Math.floor(Math.random() * 1e10)}`; + } + let keys = Object.getOwnPropertyNames(this); + for (const key in properties) { + if (!keys.includes(key)) + this._initial[key] = properties[key]; + } + if (properties.children) + this._initial.children = Object.assign({}, properties.children); + for (let k in properties) + this[k] = properties[k]; + if (!this.tag) { + if (graph) { + this.tag = `node${graph.nNodes}`; + } else { + this.tag = `node${Math.floor(Math.random() * 1e10)}`; + } + } + if (graph) { + this.graph = graph; + if (graph.nodes.get(this.tag)) { + this.tag = `${this.tag}${graph.nNodes + 1}`; + } + graph.nodes.set(this.tag, this); + graph.nNodes++; + } + if (parentNode) { + this.parent = parentNode; + if (parentNode instanceof GraphNode || parentNode instanceof Graph) + parentNode.nodes.set(this.tag, this); + } + if (typeof properties.tree === "object") { + for (const key in properties.tree) { + if (typeof properties.tree[key] === "object") { + if ((!properties.tree[key]).tag) { + properties.tree[key].tag = key; + } + } + let node = new GraphNode(properties.tree[key], this, graph); + this.nodes.set(node.tag, node); + } + } + if (this.children) + this.convertChildrenToNodes(this); + if (this.parent instanceof GraphNode || this.parent instanceof Graph) + this.checkNodesHaveChildMapped(this.parent, this); + if (typeof this.oncreate === "function") + this.oncreate(this); + if (!this.firstRun) + this.firstRun = true; + } else + return properties; + } + }; + var Graph = class { + constructor(tree, tag, props) { + this.nNodes = 0; + this.nodes = /* @__PURE__ */ new Map(); + this.state = state; + this.tree = {}; + this.add = (n = {}) => { + let props = n; + if (!(n instanceof GraphNode)) + n = new GraphNode(props, this, this); + else { + this.nNodes = this.nodes.size; + if (n.tag) { + this.tree[n.tag] = props; + this.nodes.set(n.tag, n); + } + } + return n; + }; + this.setTree = (tree = this.tree) => { + if (!tree) + return; + for (const node in tree) { + const n = this.nodes.get(node); + if (!n) { + if (typeof tree[node] === "function") { + this.add({ tag: node, operator: tree[node] }); + } else if (typeof tree[node] === "object" && !Array.isArray(tree[node])) { + if (!tree[node].tag) + tree[node].tag = node; + let newNode = this.add(tree[node]); + if (tree[node].aliases) { + tree[node].aliases.forEach((a) => { + this.nodes.set(a, newNode); + }); + } + } else { + this.add({ tag: node, operator: (...args) => { + return tree[node]; + } }); + } + } else { + if (typeof tree[node] === "function") { + n.setOperator(tree[node]); + } else if (typeof tree[node] === "object") { + if (tree[node] instanceof GraphNode) { + this.add(tree[node]); + } else if (tree[node] instanceof Graph) { + let source = tree[node]; + let properties = {}; + if (source.operator) + properties.operator = source.operator; + if (source.children) + properties.children = source.children; + if (source.forward) + properties.forward = source.forward; + if (source.backward) + properties.backward = source.backward; + if (source.repeat) + properties.repeat = source.repeat; + if (source.recursive) + properties.recursive = source.recursive; + if (source.loop) + properties.loop = source.loop; + if (source.animate) + properties.animate = source.animate; + if (source.looper) + properties.looper = source.looper; + if (source.animation) + properties.animation = source.animation; + if (source.delay) + properties.delay = source.delay; + if (source.tag) + properties.tag = source.tag; + if (source.oncreate) + properties.oncreate = source.oncreate; + if (source.node?._initial) + Object.assign(properties, source.node._initial); + properties.nodes = source.nodes; + properties.source = source; + n.setProps(properties); + } else { + n.setProps(tree[node]); + } + } + } + } + this.nodes.forEach((node) => { + if (typeof node.children === "object") { + for (const key in node.children) { + if (typeof node.children[key] === "string") { + if (this.nodes.get(node.children[key])) { + node.children[key] = this.nodes.get(node.children[key]); + } + } else if (node.children[key] === true || typeof node.children[key] === "undefined") { + if (this.nodes.get(key)) { + node.children[key] = this.nodes.get(key); + } + } + if (node.children[key] instanceof GraphNode) { + node.checkNodesHaveChildMapped(node, node.children[key]); + } + } + } + if (typeof node.parent === "string") { + if (this.nodes.get(node.parent)) { + node.parent = this.nodes.get(node.parent); + node.nodes.set(node.parent.tag, node.parent); + } + } + }); + }; + this.get = (tag) => { + return this.nodes.get(tag); + }; + this.set = (n) => { + return this.nodes.set(n.tag, n); + }; + this.run = (n, ...args) => { + if (typeof n === "string") + n = this.nodes.get(n); + if (n?.run) + return n.run(...args); + else + return void 0; + }; + this.runAsync = (n, ...args) => { + if (typeof n === "string") + n = this.nodes.get(n); + if (n?.run) + return new Promise((res, rej) => { + res(n.run(...args)); + }); + else + return new Promise((res, rej) => { + res(void 0); + }); + }; + this.removeTree = (n, checked) => { + if (typeof n === "string") + n = this.nodes.get(n); + if (n?.nodes) { + if (!checked) + checked = {}; + const recursivelyRemove = (node) => { + if (node.children && !checked[node.tag]) { + checked[node.tag] = true; + if (Array.isArray(node.children)) { + node.children.forEach((c) => { + if (c.stopNode) + c.stopNode(); + if (c.tag) { + if (this.nodes.get(c.tag)) + this.nodes.delete(c.tag); + } + this.nodes.forEach((n2) => { + if (n2.nodes.get(c.tag)) + n2.nodes.delete(c.tag); + }); + recursivelyRemove(c); + }); + } else if (typeof node.children === "object") { + if (node.stopNode) + node.stopNode(); + if (node.tag) { + if (this.nodes.get(node.tag)) + this.nodes.delete(node.tag); + } + this.nodes.forEach((n2) => { + if (n2.nodes.get(node.tag)) + n2.nodes.delete(node.tag); + }); + recursivelyRemove(node); + } + } + }; + if (n.stopNode) + n.stopNode(); + if (n.tag) { + this.nodes.delete(n.tag); + this.nodes.forEach((n2) => { + if (n2.nodes.get(n2.tag)) + n2.nodes.delete(n2.tag); + }); + this.nNodes = this.nodes.size; + recursivelyRemove(n); + } + if (n.ondelete) + n.ondelete(n); + } + return n; + }; + this.remove = (n) => { + if (typeof n === "string") + n = this.nodes.get(n); + if (n?.nodes) { + if (n.stopNode) + n.stopNode(); + if (n?.tag) { + if (this.nodes.get(n.tag)) { + this.nodes.delete(n.tag); + this.nodes.forEach((n2) => { + if (n2.nodes.get(n2.tag)) + n2.nodes.delete(n2.tag); + }); + } + } + if (n.ondelete) + n.ondelete(n); + } + return n; + }; + this.append = (n, parentNode) => { + parentNode.addChildren(n); + }; + this.callParent = async (n, ...args) => { + if (n?.parent) { + return await n.callParent(...args); + } + }; + this.callChildren = async (n, ...args) => { + if (n?.children) { + return await n.callChildren(...args); + } + }; + this.subscribe = (n, callback) => { + if (!callback) + return; + if (n?.subscribe && typeof callback === "function") { + return n.subscribe(callback); + } else if (callback instanceof GraphNode || typeof callback === "string") + return this.subscribeNode(n, callback); + else if (typeof n == "string") { + return this.state.subscribeTrigger(n, callback); + } + }; + this.unsubscribe = (tag, sub) => { + return this.state.unsubscribeTrigger(tag, sub); + }; + this.subscribeNode = (inputNode, outputNode) => { + let tag; + if (inputNode?.tag) + tag = inputNode.tag; + else if (typeof inputNode === "string") + tag = inputNode; + if (typeof outputNode === "string") + outputNode = this.nodes.get(outputNode); + if (inputNode && outputNode) { + let sub = this.state.subscribeTrigger(tag, (res) => { + if (Array.isArray(res)) + outputNode.run(...res); + else + outputNode.run(res); + }); + return sub; + } + }; + this.stopNode = (n) => { + if (typeof n === "string") { + n = this.nodes.get(n); + } + if (n?.stopNode) { + n.stopNode(); + } + }; + this.print = (n, printChildren = true) => { + if (n?.print) + return n.print(n, printChildren); + else { + let printed = `{`; + this.nodes.forEach((n2) => { + printed += ` +"${n2.tag}:${n2.print(n2, printChildren)}"`; + }); + return printed; + } + }; + this.reconstruct = (json) => { + let parsed = reconstructObject(json); + if (parsed) + return this.add(parsed); + }; + this.create = (operator, parentNode, props) => { + return createNode(operator, parentNode, props, this); + }; + this.setState = this.state.setState; + this.DEBUGNODES = (debugging = true) => { + this.nodes.forEach((n) => { + if (debugging) + n.DEBUGNODE = true; + else + n.DEBUGNODE = false; + }); + }; + this.tag = tag ? tag : `graph${Math.floor(Math.random() * 1e11)}`; + if (props) { + for (let k in props) + this[k] = props[k]; + this._initial = props; + } + if (tree || Object.keys(this.tree).length > 0) + this.setTree(tree); + } + }; + function reconstructObject(json = "{}") { + try { + let parsed = typeof json === "string" ? JSON.parse(json) : json; + const parseObj = (obj) => { + for (const prop in obj) { + if (typeof obj[prop] === "string") { + let funcParsed = parseFunctionFromText(obj[prop]); + if (typeof funcParsed === "function") { + obj[prop] = funcParsed; + } + } else if (typeof obj[prop] === "object") { + parseObj(obj[prop]); + } + } + return obj; + }; + return parseObj(parsed); + } catch (err) { + console.error(err); + return void 0; + } + } + var stringifyWithCircularRefs = function() { + const refs = /* @__PURE__ */ new Map(); + const parents = []; + const path = ["this"]; + function clear() { + refs.clear(); + parents.length = 0; + path.length = 1; + } + function updateParents(key, value) { + var idx = parents.length - 1; + var prev = parents[idx]; + if (typeof prev === "object") { + if (prev[key] === value || idx === 0) { + path.push(key); + parents.push(value.pushed); + } else { + while (idx-- >= 0) { + prev = parents[idx]; + if (typeof prev === "object") { + if (prev[key] === value) { + idx += 2; + parents.length = idx; + path.length = idx; + --idx; + parents[idx] = value; + path[idx] = key; + break; + } + } + idx--; + } + } + } + } + function checkCircular(key, value) { + if (value != null) { + if (typeof value === "object") { + if (key) { + updateParents(key, value); + } + let other = refs.get(value); + if (other) { + return "[Circular Reference]" + other; + } else { + refs.set(value, path.join(".")); + } + } + } + return value; + } + return function stringifyWithCircularRefs2(obj, space) { + try { + parents.push(obj); + return JSON.stringify(obj, checkCircular, space); + } finally { + clear(); + } + }; + }(); + if (JSON.stringifyWithCircularRefs === void 0) { + JSON.stringifyWithCircularRefs = stringifyWithCircularRefs; + } + var stringifyFast = function() { + const refs = /* @__PURE__ */ new Map(); + const parents = []; + const path = ["this"]; + function clear() { + refs.clear(); + parents.length = 0; + path.length = 1; + } + function updateParents(key, value) { + var idx = parents.length - 1; + if (parents[idx]) { + var prev = parents[idx]; + if (typeof prev === "object") { + if (prev[key] === value || idx === 0) { + path.push(key); + parents.push(value.pushed); + } else { + while (idx-- >= 0) { + prev = parents[idx]; + if (typeof prev === "object") { + if (prev[key] === value) { + idx += 2; + parents.length = idx; + path.length = idx; + --idx; + parents[idx] = value; + path[idx] = key; + break; + } + } + idx++; + } + } + } + } + } + function checkValues(key, value) { + let val; + if (value != null) { + if (typeof value === "object") { + let c = value.constructor.name; + if (key && c === "Object") { + updateParents(key, value); + } + let other = refs.get(value); + if (other) { + return "[Circular Reference]" + other; + } else { + refs.set(value, path.join(".")); + } + if (c === "Array") { + if (value.length > 20) { + val = value.slice(value.length - 20); + } else + val = value; + } else if (c.includes("Set")) { + val = Array.from(value); + } else if (c !== "Object" && c !== "Number" && c !== "String" && c !== "Boolean") { + val = "instanceof_" + c; + } else if (c === "Object") { + let obj = {}; + for (const prop in value) { + if (value[prop] == null) { + obj[prop] = value[prop]; + } else if (Array.isArray(value[prop])) { + if (value[prop].length > 20) + obj[prop] = value[prop].slice(value[prop].length - 20); + else + obj[prop] = value[prop]; + } else if (value[prop].constructor.name === "Object") { + obj[prop] = {}; + for (const p in value[prop]) { + if (Array.isArray(value[prop][p])) { + if (value[prop][p].length > 20) + obj[prop][p] = value[prop][p].slice(value[prop][p].length - 20); + else + obj[prop][p] = value[prop][p]; + } else { + if (value[prop][p] != null) { + let con = value[prop][p].constructor.name; + if (con.includes("Set")) { + obj[prop][p] = Array.from(value[prop][p]); + } else if (con !== "Number" && con !== "String" && con !== "Boolean") { + obj[prop][p] = "instanceof_" + con; + } else { + obj[prop][p] = value[prop][p]; + } + } else { + obj[prop][p] = value[prop][p]; + } + } + } + } else { + let con = value[prop].constructor.name; + if (con.includes("Set")) { + obj[prop] = Array.from(value[prop]); + } else if (con !== "Number" && con !== "String" && con !== "Boolean") { + obj[prop] = "instanceof_" + con; + } else { + obj[prop] = value[prop]; + } + } + } + val = obj; + } else { + val = value; + } + } else { + val = value; + } + } + return val; + } + return function stringifyFast2(obj, space) { + parents.push(obj); + let res = JSON.stringify(obj, checkValues, space); + clear(); + return res; + }; + }(); + if (JSON.stringifyFast === void 0) { + JSON.stringifyFast = stringifyFast; + } + function createNode(operator, parentNode, props, graph) { + if (typeof props === "object") { + props.operator = operator; + return new GraphNode(props, parentNode, graph); + } + return new GraphNode({ operator }, parentNode, graph); + } + + // ../../services/Service.ts + var Service = class extends Graph { + constructor(options = {}) { + super(void 0, options.name ? options.name : `service${Math.floor(Math.random() * 1e14)}`, options.props); + this.routes = {}; + this.loadDefaultRoutes = false; + this.keepState = true; + this.firstLoad = true; + this.customRoutes = {}; + this.customChildren = {}; + this.init = (options) => { + if (options) + options = Object.assign({}, options); + else + options = {}; + if (options.customRoutes) + Object.assign(options.customRoutes, this.customRoutes); + else + options.customRoutes = this.customRoutes; + if (options.customChildren) + Object.assign(options.customChildren, this.customChildren); + else + options.customChildren = this.customChildren; + if (Array.isArray(options.routes)) { + options.routes.forEach((r) => { + this.load( + r, + options.includeClassName, + options.routeFormat, + options.customRoutes, + options.customChildren + ); + }); + } else if (options.routes || (Object.keys(this.routes).length > 0 || this.loadDefaultRoutes) && this.firstLoad) + this.load( + options.routes, + options.includeClassName, + options.routeFormat, + options.customRoutes, + options.customChildren + ); + }; + this.load = (routes, includeClassName = true, routeFormat = ".", customRoutes, customChildren) => { + if (!routes && !this.loadDefaultRoutes && (Object.keys(this.routes).length > 0 || this.firstLoad)) + return; + if (this.firstLoad) + this.firstLoad = false; + if (customRoutes) + customRoutes = Object.assign(this.customRoutes, customRoutes); + else + customRoutes = this.customRoutes; + let service; + let allRoutes = {}; + if (routes) { + if (!(routes instanceof Graph) && routes?.name && !routes.setTree) { + if (routes.module) { + let mod = routes; + routes = {}; + Object.getOwnPropertyNames(routes.module).forEach((prop) => { + if (includeClassName) + routes[mod.name + routeFormat + prop] = routes.module[prop]; + else + routes[prop] = routes.module[prop]; + }); + } else if (typeof routes === "function") { + service = new routes({ loadDefaultRoutes: this.loadDefaultRoutes }); + service.load(); + routes = service.routes; + if (service.customRoutes && !this.customRoutes) + this.customRoutes = service.customRoutes; + else if (service.customRoutes && this.customRoutes) + Object.assign(this.customRoutes, service.customRoutes); + if (service.customChildren && !this.customChildren) + this.customChildren = service.customChildren; + else if (service.customChildren && this.customChildren) + Object.assign(this.customChildren, service.customChildren); + } + } else if (routes instanceof Graph || routes.source instanceof Graph || routes.setTree) { + service = routes; + routes = {}; + if (includeClassName) { + let name = service.name; + if (!name) { + name = service.tag; + service.name = name; + } + if (!name) { + name = `graph${Math.floor(Math.random() * 1e15)}`; + service.name = name; + service.tag = name; + } + } + if (service.customRoutes && !this.customRoutes) + this.customRoutes = service.customRoutes; + else if (service.customRoutes && this.customRoutes) + Object.assign(this.customRoutes, service.customRoutes); + if (service.customChildren && !this.customChildren) + this.customChildren = service.customChildren; + else if (service.customChildren && this.customChildren) + Object.assign(this.customChildren, service.customChildren); + service.nodes.forEach((node) => { + routes[node.tag] = node; + let checked = {}; + let checkChildGraphNodes = (nd, par) => { + if (!checked[nd.tag] || par && includeClassName && !checked[par?.tag + routeFormat + nd.tag]) { + if (!par) + checked[nd.tag] = true; + else + checked[par.tag + routeFormat + nd.tag] = true; + if (nd instanceof Graph || nd.source instanceof Graph || nd.nodes) { + if (includeClassName) { + let nm = nd.name; + if (!nm) { + nm = nd.tag; + nd.name = nm; + } + if (!nm) { + nm = `graph${Math.floor(Math.random() * 1e15)}`; + nd.name = nm; + nd.tag = nm; + } + } + nd.nodes.forEach((n) => { + if (includeClassName && !routes[nd.tag + routeFormat + n.tag]) + routes[nd.tag + routeFormat + n.tag] = n; + else if (!routes[n.tag]) + routes[n.tag] = n; + checkChildGraphNodes(n, nd); + }); + } + } + }; + checkChildGraphNodes(node); + }); + } else if (typeof routes === "object") { + let name = routes.constructor.name; + if (name === "Object") { + name = Object.prototype.toString.call(routes); + if (name) + name = name.split(" ")[1]; + if (name) + name = name.split("]")[0]; + } + if (name && name !== "Object") { + let module = routes; + routes = {}; + Object.getOwnPropertyNames(module).forEach((route) => { + if (includeClassName) + routes[name + routeFormat + route] = module[route]; + else + routes[route] = module[route]; + }); + } + } + if ((service instanceof Graph || service?.setTree) && service.name && includeClassName) { + routes = Object.assign({}, routes); + for (const prop in routes) { + let route = routes[prop]; + delete routes[prop]; + routes[service.name + routeFormat + prop] = route; + } + } + } + if (this.loadDefaultRoutes) { + let rts = Object.assign({}, this.defaultRoutes); + if (routes) { + Object.assign(rts, this.routes); + routes = Object.assign(rts, routes); + } else + routes = Object.assign(rts, this.routes); + this.loadDefaultRoutes = false; + } + if (!routes) + routes = this.routes; + let incr = 0; + for (const tag in routes) { + incr++; + let childrenIter = (route, routeKey) => { + if (typeof route === "object") { + if (!route.tag) + route.tag = routeKey; + if (typeof route?.children === "object") { + nested: + for (const key in route.children) { + incr++; + if (typeof route.children[key] === "object") { + let rt = route.children[key]; + if (rt.tag && allRoutes[rt.tag]) + continue; + if (customChildren) { + for (const k2 in customChildren) { + rt = customChildren[k2](rt, key, route, routes, allRoutes); + if (!rt) + continue nested; + } + } + if (rt.id && !rt.tag) { + rt.tag = rt.id; + } + let k; + if (rt.tag) { + if (allRoutes[rt.tag]) { + let randkey = `${rt.tag}${incr}`; + allRoutes[randkey] = rt; + rt.tag = randkey; + childrenIter(allRoutes[randkey], key); + k = randkey; + } else { + allRoutes[rt.tag] = rt; + childrenIter(allRoutes[rt.tag], key); + k = rt.tag; + } + } else { + if (allRoutes[key]) { + let randkey = `${key}${incr}`; + allRoutes[randkey] = rt; + rt.tag = randkey; + childrenIter(allRoutes[randkey], key); + k = randkey; + } else { + allRoutes[key] = rt; + childrenIter(allRoutes[key], key); + k = key; + } + } + if (service?.name && includeClassName) { + allRoutes[service.name + routeFormat + k] = rt; + delete allRoutes[k]; + } else + allRoutes[k] = rt; + } + } + } + } + }; + allRoutes[tag] = routes[tag]; + childrenIter(routes[tag], tag); + } + top: + for (const route in allRoutes) { + if (typeof allRoutes[route] === "object") { + let r = allRoutes[route]; + if (typeof r === "object") { + if (customRoutes) { + for (const key in customRoutes) { + r = customRoutes[key](r, route, allRoutes); + if (!r) + continue top; + } + } + if (r.get) { + if (typeof r.get == "object") { + } + } + if (r.post) { + } + if (r.delete) { + } + if (r.put) { + } + if (r.head) { + } + if (r.patch) { + } + if (r.options) { + } + if (r.connect) { + } + if (r.trace) { + } + if (r.post && !r.operator) { + allRoutes[route].operator = r.post; + } else if (!r.operator && typeof r.get == "function") { + allRoutes[route].operator = r.get; + } + } + } + } + for (const route in routes) { + if (typeof routes[route] === "object") { + if (this.routes[route]) { + if (typeof this.routes[route] === "object") + Object.assign(this.routes[route], routes[route]); + else + this.routes[route] = routes[route]; + } else + this.routes[route] = routes[route]; + } else if (this.routes[route]) { + if (typeof this.routes[route] === "object") + Object.assign(this.routes[route], routes[route]); + else + this.routes[route] = routes[route]; + } else + this.routes[route] = routes[route]; + } + if (service) { + for (const key in this.routes) { + if (this.routes[key] instanceof GraphNode || this.routes[key].constructor.name.includes("GraphNode")) { + this.nodes.set(key, this.routes[key]); + this.nNodes = this.nodes.size; + } + } + } else + this.setTree(this.routes); + for (const prop in this.routes) { + if (this.routes[prop]?.aliases) { + let aliases = this.routes[prop].aliases; + aliases.forEach((a) => { + if (service?.name && includeClassName) + routes[service.name + routeFormat + a] = this.routes[prop]; + else + routes[a] = this.routes[prop]; + }); + } + } + return this.routes; + }; + this.unload = (routes = this.routes) => { + if (!routes) + return; + let service; + if (!(routes instanceof Service) && typeof routes === "function") { + service = new Service(); + routes = service.routes; + } else if (routes instanceof Service) { + routes = routes.routes; + } + for (const r in routes) { + delete this.routes[r]; + if (this.nodes.get(r)) + this.remove(r); + } + return this.routes; + }; + this.handleMethod = (route, method, args) => { + let m = method.toLowerCase(); + let src = this.nodes.get(route); + if (!src) { + src = this.routes[route]; + if (!src) + src = this.tree[route]; + } + if (src?.[m]) { + if (!(src[m] instanceof Function)) { + if (args) + src[m] = args; + return src[m]; + } else + return src[m](args); + } else + return this.handleServiceMessage({ route, args, method }); + }; + this.transmit = (...args) => { + if (typeof args[0] === "object") { + if (args[0].method) { + return this.handleMethod(args[0].route, args[0].method, args[0].args); + } else if (args[0].route) { + return this.handleServiceMessage(args[0]); + } else if (args[0].node) { + return this.handleGraphNodeCall(args[0].node, args[0].args); + } else if (this.keepState) { + if (args[0].route) + this.setState({ [args[0].route]: args[0].args }); + if (args[0].node) + this.setState({ [args[0].node]: args[0].args }); + } + return args; + } else + return args; + }; + this.receive = (...args) => { + if (args[0]) { + if (typeof args[0] === "string") { + let substr = args[0].substring(0, 8); + if (substr.includes("{") || substr.includes("[")) { + if (substr.includes("\\")) + args[0] = args[0].replace(/\\/g, ""); + if (args[0][0] === '"') { + args[0] = args[0].substring(1, args[0].length - 1); + } + ; + args[0] = JSON.parse(args[0]); + } + } + } + if (typeof args[0] === "object") { + if (args[0].method) { + return this.handleMethod(args[0].route, args[0].method, args[0].args); + } else if (args[0].route) { + return this.handleServiceMessage(args[0]); + } else if (args[0].node) { + return this.handleGraphNodeCall(args[0].node, args[0].args); + } else if (this.keepState) { + if (args[0].route) + this.setState({ [args[0].route]: args[0].args }); + if (args[0].node) + this.setState({ [args[0].node]: args[0].args }); + } + return args; + } else + return args; + }; + this.pipe = (source, destination, endpoint, method, callback) => { + if (source instanceof GraphNode) { + if (callback) + return source.subscribe((res) => { + let mod = callback(res); + if (mod !== void 0) + this.transmit({ route: destination, args: mod, method }); + else + this.transmit({ route: destination, args: res, method }, endpoint); + }); + else + return this.subscribe(source, (res) => { + this.transmit({ route: destination, args: res, method }, endpoint); + }); + } else if (typeof source === "string") + return this.subscribe(source, (res) => { + this.transmit({ route: destination, args: res, method }, endpoint); + }); + }; + this.pipeOnce = (source, destination, endpoint, method, callback) => { + if (source instanceof GraphNode) { + if (callback) + return source.state.subscribeTriggerOnce(source.tag, (res) => { + let mod = callback(res); + if (mod !== void 0) + this.transmit({ route: destination, args: mod, method }); + else + this.transmit({ route: destination, args: res, method }, endpoint); + }); + else + return this.state.subscribeTriggerOnce(source.tag, (res) => { + this.transmit({ route: destination, args: res, method }, endpoint); + }); + } else if (typeof source === "string") + return this.state.subscribeTriggerOnce(source, (res) => { + this.transmit({ route: destination, args: res, method }, endpoint); + }); + }; + this.terminate = (...args) => { + this.nodes.forEach((n) => { + n.stopNode(); + }); + }; + this.recursivelyAssign = (target, obj) => { + for (const key in obj) { + if (typeof obj[key] === "object") { + if (typeof target[key] === "object") + this.recursivelyAssign(target[key], obj[key]); + else + target[key] = this.recursivelyAssign({}, obj[key]); + } else + target[key] = obj[key]; + } + return target; + }; + this.defaultRoutes = { + "/": { + get: () => { + return this.print(); + }, + aliases: [""] + }, + ping: () => { + console.log("ping"); + return "pong"; + }, + echo: (...args) => { + this.transmit(...args); + return args; + }, + assign: (source) => { + if (typeof source === "object") { + Object.assign(this, source); + return true; + } + return false; + }, + recursivelyAssign: (source) => { + if (typeof source === "object") { + this.recursivelyAssign(this, source); + return true; + } + return false; + }, + log: { + post: (...args) => { + console.log("Log: ", ...args); + }, + aliases: ["info"] + }, + error: (message) => { + let er = new Error(message); + console.error(message); + return er; + }, + state: (key) => { + if (key) { + return this.state.data[key]; + } else + return this.state.data; + }, + printState: (key) => { + if (key) { + return stringifyWithCircularRefs(this.state.data[key]); + } else + return stringifyWithCircularRefs(this.state.data); + }, + spliceTypedArray: this.spliceTypedArray, + transmit: this.transmit, + receive: this.receive, + load: this.load, + unload: this.unload, + pipe: this.pipe, + terminate: this.terminate, + run: this.run, + subscribe: this.subscribe, + subscribeNode: this.subscribeNode, + unsubscribe: this.unsubscribe, + stopNode: this.stopNode, + get: this.get, + add: this.add, + remove: this.remove, + setTree: this.setTree, + setState: this.setState, + print: this.print, + reconstruct: this.reconstruct, + handleMethod: this.handleMethod, + handleServiceMessage: this.handleServiceMessage, + handleGraphNodeCall: this.handleGraphNodeCall + }; + if (options.name) + this.name = options.name; + else + options.name = this.tag; + if ("loadDefaultRoutes" in options) { + this.loadDefaultRoutes = options.loadDefaultRoutes; + this.routes = Object.assign(this.defaultRoutes, this.routes); + } + if (options || Object.keys(this.routes).length > 0) + this.init(options); + } + handleServiceMessage(message) { + let call; + if (typeof message === "object") { + if (message.route) + call = message.route; + else if (message.node) + call = message.node; + } + if (call) { + if (Array.isArray(message.args)) + return this.run(call, ...message.args); + else + return this.run(call, message.args); + } else + return message; + } + handleGraphNodeCall(route, args) { + if (!route) + return args; + if (args?.args) { + this.handleServiceMessage(args); + } else if (Array.isArray(args)) + return this.run(route, ...args); + else + return this.run(route, args); + } + isTypedArray(x) { + return ArrayBuffer.isView(x) && Object.prototype.toString.call(x) !== "[object DataView]"; + } + spliceTypedArray(arr, start, end) { + let s = arr.subarray(0, start); + let e; + if (end) { + e = arr.subarray(end + 1); + } + let n; + if (s.length > 0 || e?.length > 0) + n = new arr.constructor(s.length + e.length); + if (s.length > 0) + n.set(s); + if (e && e.length > 0) + n.set(e, s.length); + return n; + } + }; + + // ../../services/ecs/ECS.systems.ts + var Systems = { + collision: { + tag: "collision", + setupEntities: function(entities) { + for (const key in entities) { + const entity = entities[key]; + if (entity.components) { + if (!entity.components[this.tag]) + continue; + } + this.setupEntity(entity); + } + return entities; + }, + setupEntity: function(entity) { + if (!("collisionEnabled" in entity)) + entity.collisionEnabled = true; + if (!entity.collisionType) + entity.collisionType = "sphere"; + if (!entity.collisionRadius) + entity.collisionRadius = 1; + if (!entity.collisionBoundsScale) + entity.collisionBoundsScale = { x: 1, y: 1, z: 1 }; + if (!entity.colliding) + entity.colliding = {}; + if (!entity.position) + entity.position = { x: 0, y: 0, z: 0 }; + return entity; + }, + operator: function(entities) { + let keys = this.entityKeys; + for (let i = 0; i < keys.length; i++) { + const entity1 = entities[keys[i]]; + if (entity1.components) { + if (!entity1.components[this.tag] || !entity1.collisionEnabled) + continue; + } + if (!entity1.collisionEnabled) + continue; + for (let j = 0; j < keys.length; j++) { + if (i === j) + continue; + const entity2 = entities[keys[j]]; + if (entity2.components) { + if (!entity2.components[this.tag]) + continue; + } + if (!entity2.collisionEnabled) + continue; + let colliding = Systems.collision.collisionCheck(entity1, entity2); + if (colliding !== false) { + if (!entity1.colliding) + entity1.colliding = {}; + if (!entity2.colliding) + entity2.colliding = {}; + entity1.colliding[entity2.tag] = colliding; + entity2.colliding[entity1.tag] = colliding; + } + } + } + return entities; + }, + collisionCheck: (body1, body2) => { + if (body1.collisionEnabled === false || body2.collisionEnabled === false) + return false; + const dist = Systems.collision.distance(body1.position, body2.position); + if (dist < Math.max(...Object.values(body1.collisionBoundsScale)) * body1.collisionRadius + Math.max(...Object.values(body2.collisionBoundsScale)) * body2.collisionRadius) { + let isColliding = false; + if (body1.collisionType === "sphere") { + if (body2.collisionType === "sphere") { + isColliding = Systems.collision.sphereCollisionCheck(body1, body2, dist); + } else if (body2.collisionType === "box") { + isColliding = Systems.collision.sphereBoxCollisionCheck(body1, body2, dist); + } else if (body2.collisionType === "point") { + isColliding = Systems.collision.isPointInsideSphere(body2.position, body1, dist); + } + } else if (body1.collisionType === "box") { + if (body2.collisionType === "sphere") { + isColliding = Systems.collision.sphereBoxCollisionCheck(body2, body1, dist); + } else if (body2.collisionType === "box") { + isColliding = Systems.collision.boxCollisionCheck(body1, body2); + } else if (body2.collisionType === "point") { + isColliding = Systems.collision.isPointInsideBox(body1.position, body1); + } + } else if (body1.collisionType === "point") { + if (body2.collisionType === "sphere") { + isColliding = Systems.collision.isPointInsideSphere(body1.position, body2, dist); + } else if (body2.collisionType === "box") { + isColliding = Systems.collision.isPointInsideBox(body1.position, body2); + } + } + if (isColliding) + return dist; + } + return false; + }, + sphereCollisionCheck: (body1, body2, dist) => { + if (dist === void 0) + dist = Systems.collision.distance(body1.position, body2.position); + return dist < body1.collisionRadius + body2.collisionRadius; + }, + boxCollisionCheck: (body1, body2) => { + let body1minX = (body1.position.x - body1.collisionRadius) * body1.collisionBoundsScale.x; + let body1maxX = (body1.position.x + body1.collisionRadius) * body1.collisionBoundsScale.x; + let body1minY = (body1.position.y - body1.collisionRadius) * body1.collisionBoundsScale.y; + let body1maxY = (body1.position.y + body1.collisionRadius) * body1.collisionBoundsScale.y; + let body1minZ = (body1.position.z - body1.collisionRadius) * body1.collisionBoundsScale.z; + let body1maxZ = (body1.position.z + body1.collisionRadius) * body1.collisionBoundsScale.z; + let body2minX = (body2.position.x - body2.collisionRadius) * body1.collisionBoundsScale.x; + let body2maxX = (body2.position.x + body2.collisionRadius) * body1.collisionBoundsScale.x; + let body2minY = (body2.position.y - body2.collisionRadius) * body1.collisionBoundsScale.y; + let body2maxY = (body2.position.y + body2.collisionRadius) * body1.collisionBoundsScale.y; + let body2minZ = (body2.position.z - body2.collisionRadius) * body1.collisionBoundsScale.z; + let body2maxZ = (body2.position.z + body2.collisionRadius) * body1.collisionBoundsScale.z; + return (body1maxX <= body2maxX && body1maxX >= body2minX || body1minX <= body2maxX && body1minX >= body2minX) && (body1maxY <= body2maxY && body1maxY >= body2minY || body1minY <= body2maxY && body1minY >= body2minY) && (body1maxZ <= body2maxZ && body1maxZ >= body2minZ || body1minZ <= body2maxZ && body1minZ >= body2minZ); + }, + sphereBoxCollisionCheck: (sphere, box, dist) => { + let boxMinX = (box.position.x - box.collisionRadius) * box.collisionBoundsScale.x; + let boxMaxX = (box.position.x + box.collisionRadius) * box.collisionBoundsScale.x; + let boxMinY = (box.position.y - box.collisionRadius) * box.collisionBoundsScale.y; + let boxMaxY = (box.position.y + box.collisionRadius) * box.collisionBoundsScale.y; + let boxMinZ = (box.position.z - box.collisionRadius) * box.collisionBoundsScale.z; + let boxMaxZ = (box.position.z + box.collisionRadius) * box.collisionBoundsScale.z; + let clamp = { + x: Math.max(boxMinX, Math.min(sphere.position.x, boxMaxX)), + y: Math.max(boxMinY, Math.min(sphere.position.y, boxMaxY)), + z: Math.max(boxMinZ, Math.min(sphere.position.z, boxMaxZ)) + }; + if (dist === void 0) + dist = Systems.collision.distance(sphere.position, clamp); + return dist > sphere.collisionRadius; + }, + isPointInsideSphere: (point, sphere, dist) => { + if (dist === void 0) + dist = Systems.collision.distance(point, sphere.position); + return dist < sphere.collisionRadius; + }, + isPointInsideBox: (point, box) => { + let boxminX = (box.position.x - box.collisionRadius) * box.collisionBoundsScale.x; + let boxmaxX = (box.position.x + box.collisionRadius) * box.collisionBoundsScale.x; + let boxminY = (box.position.y - box.collisionRadius) * box.collisionBoundsScale.x; + let boxmaxY = (box.position.y + box.collisionRadius) * box.collisionBoundsScale.x; + let boxminZ = (box.position.z - box.collisionRadius) * box.collisionBoundsScale.x; + let boxmaxZ = (box.position.z + box.collisionRadius) * box.collisionBoundsScale.x; + return point.x >= boxminX && point.x <= boxmaxX && (point.y >= boxminY && point.y <= boxmaxY) && (point.z >= boxminZ && point.z <= boxmaxZ); + }, + closestPointOnLine: (point, lineStart, lineEnd) => { + let a = { x: lineEnd.x - lineStart.x, y: lineEnd.y - lineStart.y, z: lineEnd.z - lineStart.z }; + let b = { x: lineStart.x - point.x, y: lineStart.y - point.y, z: lineStart.z - point.z }; + let c = { x: lineEnd.x - point.x, y: lineEnd.y - point.y, z: lineEnd.z - point.z }; + let bdota = Systems.collision.dot(b, a); + if (bdota <= 0) + return lineStart; + let cdota = Systems.collision.dot(c, a); + if (cdota <= 0) + return lineEnd; + let _bdotapluscdota = 1 / (bdota + cdota); + return { + x: lineStart.x + (lineEnd.x - lineStart.x) * bdota * _bdotapluscdota, + y: lineStart.y + (lineEnd.y - lineStart.y) * bdota * _bdotapluscdota, + z: lineStart.z + (lineEnd.z - lineStart.z) * bdota * _bdotapluscdota + }; + }, + closestPointOnPolygon: (point, t0, t1, t2) => { + let n = Systems.collision.calcNormal(t0, t1, t2); + let dist = Systems.collision.dot(point, n) - Systems.collision.dot(t0, n); + let projection = Systems.collision.vecadd(point, Systems.collision.vecscale(n, -dist)); + let v0x = t2[0] - t0[0]; + let v0y = t2[1] - t0[1]; + let v0z = t2[2] - t0[2]; + let v1x = t1[0] - t0[0]; + let v1y = t1[1] - t0[1]; + let v1z = t1[2] - t0[2]; + let v2x = projection[0] - t0[0]; + let v2y = projection[1] - t0[1]; + let v2z = projection[2] - t0[2]; + let dot00 = v0x * v0x + v0y * v0y + v0z * v0z; + let dot01 = v0x * v1x + v0y * v1y + v0z * v1z; + let dot02 = v0x * v2x + v0y * v2y + v0z * v2z; + let dot11 = v1x * v1x + v1y * v1y + v1z * v1z; + let dot12 = v1x * v2x + v1y * v2y + v1z * v2z; + let denom = dot00 * dot11 - dot01 * dot01; + if (Math.abs(denom) < 1e-30) { + return void 0; + } + let _denom = 1 / denom; + let u = (dot11 * dot02 - dot01 * dot12) * _denom; + let v = (dot00 * dot12 - dot01 * dot02) * _denom; + if (u >= 0 && v >= 0 && u + v < 1) { + return projection; + } else + return void 0; + }, + calcNormal: (t0, t1, t2, positive = true) => { + var QR = Systems.collision.makeVec(t0, t1); + var QS = Systems.collision.makeVec(t0, t2); + if (positive === true) { + return Systems.collision.normalize(Systems.collision.cross3D(QR, QS)); + } else { + return Systems.collision.normalize(Systems.collision.cross3D(QS, QR)); + } + }, + dot: (v1, v2) => { + let dot = 0; + for (const key in v1) { + dot += v1[key] * v2[key]; + } + return dot; + }, + makeVec(p1, p2) { + return { + x: p2.x - p1.x, + y: p2.y - p1.y, + z: p2.z - p1.z + }; + }, + vecadd: (v1, v2) => { + let result = Object.assign({}, v1); + for (const key in result) { + result[key] += v2[key]; + } + return result; + }, + vecsub: (v1, v2) => { + let result = Object.assign({}, v1); + for (const key in result) { + result[key] -= v2[key]; + } + return result; + }, + vecmul: (v1, v2) => { + let result = Object.assign({}, v1); + for (const key in result) { + result[key] *= v2[key]; + } + return result; + }, + vecdiv: (v1, v2) => { + let result = Object.assign({}, v1); + for (const key in result) { + result[key] /= v2[key]; + } + return result; + }, + vecscale: (v1, scalar) => { + let result = Object.assign({}, v1); + for (const key in result) { + result[key] *= scalar; + } + return result; + }, + distance: (v1, v2) => { + let distance = 0; + for (const key in v1) { + distance += Math.pow(v1[key] - v2[key], 2); + } + return Math.sqrt(distance); + }, + magnitude: (v) => { + let magnitude = 0; + for (const key in v) { + magnitude += v[key] * v[key]; + } + return Math.sqrt(magnitude); + }, + normalize: (v) => { + let magnitude = Systems.collision.magnitude(v); + let _mag = magnitude ? 1 / magnitude : 0; + let vn = Object.assign({}, v); + for (const key in v) { + vn[key] = v[key] * _mag; + } + return vn; + }, + distance3D(v1, v2) { + return Math.sqrt((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y) + (v1.z - v2.z) * (v1.z - v2.z)); + }, + cross3D(v1, v2) { + return { + x: v1.y * v2.z - v1.z * v2.y, + y: v1.z * v2.x - v1.x * v2.z, + z: v1.x * v2.y - v1.y * v2.x + }; + }, + nearestNeighborSearch(entities, isWithinRadius = 1e15) { + var tree = {}; + ; + for (const key in entities) { + let newnode = { + tag: key, + position: void 0, + neighbors: [] + }; + newnode.position = entities[key].position; + tree[key] = newnode; + } + for (const i in tree) { + for (const j in tree) { + var dist = Systems.collision.distance3D(tree[i].position, tree[j].position); + if (dist < isWithinRadius) { + var newNeighbori = { + tag: j, + position: entities[j].position, + dist + }; + tree[i].neighbors.push(newNeighbori); + var newNeighborj = { + tag: j, + position: entities[i].position, + dist + }; + tree[j].neighbors.push(newNeighborj); + } + } + tree[i].neighbors.sort(function(a, b) { + return a.dist - b.dist; + }); + } + return tree; + }, + generateBoundingVolumeTree(entities, mode = "octree", withinRadius = 1e15, minEntities = 3) { + let dynamicBoundingVolumeTree = { + proto: { + parent: void 0, + children: {}, + entities: {}, + collisionType: "box", + collisionRadius: 1, + collisionBoundsScale: { x: 1, y: 1, z: 1 }, + position: { x: 0, y: 0, z: 0 } + }, + tree: {} + }; + let maxX, maxY, maxZ; + let minX = 0, minY = 0, minZ = 0; + let positions = {}; + let minRadius = withinRadius; + for (const key in entities) { + const body = entities[key]; + let xx = body.position.x + body.collisionRadius * body.collisionBoundsScale.x; + let yy = body.position.y + body.collisionRadius * body.collisionBoundsScale.y; + let zz = body.position.z + body.collisionRadius * body.collisionBoundsScale.z; + if (maxX < xx) + maxX = xx; + if (minX > xx) + minX = xx; + if (maxY < yy) + maxY = yy; + if (minY > yy) + minY = yy; + if (maxZ < zz) + maxZ = zz; + if (minZ > zz) + minZ = zz; + if (minRadius > body.collisionRadius) + minRadius = body.collisionRadius; + positions[key] = body.position; + } + ; + let head = JSON.parse(JSON.stringify(dynamicBoundingVolumeTree.proto)); + let boxpos = { x: (maxX + minX) * 0.5, y: (maxY + minY) * 0.5, z: (maxZ + minZ) * 0.5 }; + let boxbounds = { x: maxX - boxpos.x, y: maxY - boxpos.y, z: maxZ - boxpos.z }; + head.position = boxpos; + head.collisionBoundsScale = boxbounds; + head.entities = entities; + dynamicBoundingVolumeTree.tree = head; + minRadius *= 2; + if (mode === "octree") { + let genOct = function(parentPos, halfbounds) { + let oct1 = { x: parentPos.x + halfbounds.x, y: parentPos.y + halfbounds.y, z: parentPos.z + halfbounds.z }; + let oct2 = { x: parentPos.x - halfbounds.x, y: parentPos.y + halfbounds.y, z: parentPos.z + halfbounds.z }; + let oct3 = { x: parentPos.x + halfbounds.x, y: parentPos.y - halfbounds.y, z: parentPos.z + halfbounds.z }; + let oct4 = { x: parentPos.x + halfbounds.x, y: parentPos.y + halfbounds.y, z: parentPos.z - halfbounds.z }; + let oct5 = { x: parentPos.x - halfbounds.x, y: parentPos.y - halfbounds.y, z: parentPos.z + halfbounds.z }; + let oct6 = { x: parentPos.x - halfbounds.x, y: parentPos.y + halfbounds.y, z: parentPos.z - halfbounds.z }; + let oct7 = { x: parentPos.x + halfbounds.x, y: parentPos.y - halfbounds.y, z: parentPos.z - halfbounds.z }; + let oct8 = { x: parentPos.x - halfbounds.x, y: parentPos.y - halfbounds.y, z: parentPos.z - halfbounds.z }; + return [oct1, oct2, oct3, oct4, oct5, oct6, oct7, oct8]; + }, genOctTree = function(head2) { + let halfbounds = { + x: head2.collisionBoundsScale.x * 0.5, + y: head2.collisionBoundsScale.y * 0.5, + z: head2.collisionBoundsScale.z * 0.5 + }; + let octPos = genOct(head2.position, halfbounds); + let check = Object.assign({}, head2.bodies); + for (let i = 0; i < 8; i++) { + let octquadrant = Object.assign( + JSON.parse(JSON.stringify(dynamicBoundingVolumeTree.proto)), + { position: octPos[i], collisionBoundsScale: halfbounds } + ); + octquadrant.parent = head2; + for (const j in check) { + let collided = Systems.collision.collisionCheck(check[j], octquadrant); + if (collided) { + octquadrant.entities[j] = check[j]; + delete check[j]; + } + } + if (Object.keys(octquadrant.entities).length > minEntities - 1) { + head2.children[i] = octquadrant; + octquadrant.parent = head2; + if (Object.keys(octquadrant.entities).length > minEntities && octquadrant.collisionRadius * 0.5 > minRadius) { + genOctTree(octquadrant); + } + } + } + }; + genOctTree(head); + return head; + } else { + let tree = Systems.collision.nearestNeighborSearch(positions, withinRadius); + let keys = Object.keys(tree); + let tag = keys[Math.floor(Math.random() * keys.length)]; + let searching = true; + let count = 0; + let genBoundingBoxLevel = (tree2, volumes) => { + let newVolumes = {}; + let foundidxs = {}; + let treekeys = Object.keys(tree2); + while (searching && count < treekeys.length) { + let node = tree2[tag]; + let i = 0; + let j = 0; + let ux = positions[node.tag].x - volumes[node.tag].collisionBoundsScale.x, uy = positions[node.tag].y - volumes[node.tag].collisionBoundsScale.y, uz = positions[node.tag].z - volumes[node.tag].collisionBoundsScale.z, mx = positions[node.tag].x + volumes[node.tag].collisionBoundsScale.x, my = positions[node.tag].y + volumes[node.tag].collisionBoundsScale.y, mz = positions[node.tag].z + volumes[node.tag].collisionBoundsScale.z; + let newvolume = JSON.parse(JSON.stringify(dynamicBoundingVolumeTree.proto)); + newvolume.tag = `bound${Math.floor(Math.random() * 1e15)}`; + newvolume.children[node.tag] = volumes[node.tag]; + newvolume.bodies[node.tag] = entities[node.tag]; + volumes[node.tag].parent = newvolume; + foundidxs[node.tag] = true; + i++; + j++; + let nkeys = Object.keys(node.neighbors); + while (i < nkeys.length && j < 3) { + if (foundidxs[node.neighbors[i].tag]) { + i++; + continue; + } + let uxn = positions[node.neighbors[i].tag].x - volumes[node.neighbors[i].tag].collisionBoundsScale.x, uyn = positions[node.neighbors[i].tag].y - volumes[node.neighbors[i].tag].collisionBoundsScale.y, uzn = positions[node.neighbors[i].tag].z - volumes[node.neighbors[i].tag].collisionBoundsScale.z, mxn = positions[node.neighbors[i].tag].x + volumes[node.neighbors[i].tag].collisionBoundsScale.x, myn = positions[node.neighbors[i].tag].y + volumes[node.neighbors[i].tag].collisionBoundsScale.y, mzn = positions[node.neighbors[i].tag].z + volumes[node.neighbors[i].tag].collisionBoundsScale.z; + if (ux > uxn) + ux = uxn; + if (mx < mxn) + mx = mxn; + if (uy > uyn) + uy = uyn; + if (my < myn) + my = myn; + if (uz > uzn) + uz = uzn; + if (mz < mzn) + mz = mzn; + newvolume.children[node.neighbors[i].tag] = volumes[node.neighbors[i].tag]; + newvolume.entities[node.neighbors[i].tag] = entities[node.neighbors[i].tag]; + volumes[node.neighbors[i].tag].parent = newvolume; + foundidxs[node.neighbors[i].tag] = true; + i++; + j++; + } + let pos = { x: (mx + ux) * 0.5, y: (my + uy) * 0.5, z: (mz + uz) * 0.5 }; + let bounds = { x: mx - pos.x, y: my - pos.y, z: mz - pos.z }; + newvolume.position = pos; + newvolume.collisionBoundsScale = bounds; + if (newvolume.bodies.length === 1) + newvolume = node; + newVolumes[newvolume.tag] = newvolume; + while (i < node.neighbors.length) { + if (!foundidxs[node.neighbors[i].tag]) + break; + i++; + } + if (i < node.neighbors.length) { + tag = node.neighbors[i].tag; + } else if (Object.keys(foundidxs).length < Object.keys(tree2).length) { + tag = keys[0]; + } else + searching = false; + count++; + } + return newVolumes; + }; + let result = genBoundingBoxLevel(tree, entities); + while (Object.keys(result).length > 2) { + let nextTree = Systems.collision.nearestNeighborSearch(result, withinRadius); + result = genBoundingBoxLevel(nextTree, result); + } + head.children = result; + head.children.forEach((n) => { + n.parent = head; + }); + return head; + } + } + }, + collider: { + tag: "collider", + lastTime: performance.now(), + setupEntities: function(entities) { + for (const key in entities) { + const entity = entities[key]; + if (entity.components) { + if (!entity.components[this.tag]) + continue; + } + this.setupEntity(entity); + } + return entities; + }, + setupEntity: function(entity) { + if (!("collisionEnabled" in entity)) + Systems.collision.setupEntity(entity); + if (!("boundingBox" in entity)) + entity.boundingBox = { + bot: 0, + top: 100, + left: 0, + right: 100, + front: 0, + back: 100 + }; + if (!("position" in entity)) { + Systems.movement.setupEntity(entity); + } + if (!("restitution" in entity)) + entity.restitution = 1; + if (!("useBoundingBox" in entity)) + entity.useBoundingBox = true; + if (!entity.position.x && !entity.position.y && !entity.position.z) { + entity.position.x = Math.random() * entity.boundingBox.right; + entity.position.y = Math.random() * entity.boundingBox.back; + entity.position.z = Math.random() * entity.boundingBox.top; + } + return entity; + }, + operator: function(entities) { + let keys = this.entityKeys; + for (let i = 0; i < keys.length; i++) { + const entity1 = entities[keys[i]]; + if (entity1.components) { + if (!entity1.components[this.tag] || !entity1.collisionEnabled) + continue; + } + if (entity1.useBoundingBox) + this.checkBoundingBox(entity1); + if (!entity1.collisionEnabled) + continue; + if (entity1.colliding) { + for (const key2 in entity1.colliding) { + const entity2 = entities[key2]; + if (entity1.colliding[key2] === false) { + delete entity1.colliding[key2]; + delete entity2.colliding[entity1.tag]; + continue; + } + if (!entity2.collisionEnabled) + continue; + if (entity2.collisionType === "box") { + this.resolveBoxCollision(entity1, entity2, entity1.colliding[key2]); + } else { + if (entity1.collisionType === "box") { + entity1.fixed = true; + this.resolveSphereCollisions(entity1, entity2, entity1.colliding[key2]); + entity1.fixed = false; + } else { + this.resolveSphereCollisions(entity1, entity2, entity1.colliding[key2]); + delete entity2.colliding[entity1.tag]; + } + } + delete entity1.colliding[entity2.tag]; + } + delete entity1.colliding; + } + } + return entities; + }, + checkBoundingBox: (entity) => { + const xsize = entity.collisionRadius * entity.collisionBoundsScale.x; + const ysize = entity.collisionRadius * entity.collisionBoundsScale.y; + const zsize = entity.collisionRadius * entity.collisionBoundsScale.z; + if (entity.position.y - ysize <= entity.boundingBox.front) { + entity.velocity.y *= -entity.restitution; + entity.position.y = entity.boundingBox.front + ysize; + } + if (entity.position.y + ysize >= entity.boundingBox.back) { + entity.velocity.y *= -entity.restitution; + entity.position.y = entity.boundingBox.back - ysize; + } + if (entity.position.x - xsize <= entity.boundingBox.left) { + entity.velocity.x *= -entity.restitution; + entity.position.x = entity.boundingBox.left + xsize; + } + if (entity.position.x + xsize >= entity.boundingBox.right) { + entity.velocity.x *= -entity.restitution; + entity.position.x = entity.boundingBox.right - xsize; + } + if (entity.position.z - zsize <= entity.boundingBox.bot) { + entity.velocity.z *= -entity.restitution; + entity.position.z = entity.boundingBox.bot + zsize; + } + if (entity.position.z + zsize >= entity.boundingBox.top) { + entity.velocity.z *= -entity.restitution; + entity.position.z = entity.boundingBox.top - zsize; + } + }, + resolveBoxCollision: (body1, box, negate) => { + let positionVec = Systems.collision.makeVec(body1.position, box.position); + var directionVec = Object.values(positionVec); + let closestSide; + let closestDist = Infinity; + let mul = -1; + if (directionVec[idx] < 0) + mul = 1; + if (negate) + mul = -mul; + for (const key in body1.position) { + let dist = Math.abs(box.position[key] - body1.position[key]); + if (dist < closestDist && Math.abs(box.position[key] - body1.position[key] + body1.velocity[key] * 1e-17) < dist) { + closestSide = key; + closestDist = dist; + } + } + var idx = directionVec.indexOf(closestSide); + if (idx === 0) + idx = "x"; + if (idx === 1) + idx = "y"; + if (idx === 2) + idx = "z"; + if (idx === 3) + idx = "w"; + let boxEdgeAxisPosition = box.position[idx] + box.collisionRadius * box.collisionBoundsScale[idx] * mul; + if (negate) { + let body1Offset = boxEdgeAxisPosition - body1.collisionRadius * body1.collisionBoundsScale[idx] * mul; + body1.position[idx] = body1Offset; + } else { + let body1Offset = boxEdgeAxisPosition + body1.collisionRadius * body1.collisionBoundsScale[idx] * mul; + body1.position[idx] = body1Offset; + } + body1.velocity[idx] = -body1.velocity[idx] * body1.restitution; + if (negate) + body1.force[idx] = -body1.velocity[idx]; + var body2AccelMag = Systems.collision.magnitude(box.acceleration); + var body2AccelNormal = Systems.collision.normalize(box.acceleration); + body1.force[idx] = -body2AccelNormal[idx] * body2AccelMag * box.mass; + if (negate) + body1.force[idx] = -body1.force[idx]; + }, + resolveSphereCollisions: (entity1, entity2, dist) => { + if (dist === void 0) + dist = Systems.collision.distance(entity1.position, entity2.position); + let vecn = Systems.collision.normalize(Systems.collision.makeVec(entity1.position, entity2.position)); + let sumMass = entity1.mass + entity2.mass; + let ratio = entity1.mass / sumMass; + let rmin = 1 - ratio; + if (entity1.fixed === false) { + entity1.position.x += vecn.x * rmin * 1.01; + entity1.position.y += vecn.y * rmin * 1.01; + entity1.position.z += vecn.z * rmin * 1.001; + } else { + entity2.position.x -= vecn.x * 1.01; + entity2.position.y -= vecn.y * 1.01; + entity2.position.z -= vecn.z * 1.01; + } + if (entity2.fixed === false) { + entity2.position.x += vecn.x * ratio * 1.01; + entity2.position.y += vecn.y * ratio * 1.01; + entity2.position.z += vecn.z * ratio * 1.01; + } else { + entity1.position.x += vecn.x * 1.01; + entity1.position.y += vecn.y * 1.01; + entity1.position.z += vecn.z * 1.01; + } + dist = Systems.collision.distance(entity1.position, entity2.position); + let vrel = { + x: entity1.velocity.x - entity2.velocity.x, + y: entity1.velocity.y - entity2.velocity.y, + z: entity1.velocity.z - entity2.velocity.z + }; + let speed = vrel.x * vecn.x + vrel.y * vecn.y + vrel.z * vecn.z; + if (speed > 0) { + let impulse = 2 * speed / sumMass; + if (entity1.fixed === false) { + entity1.velocity.x -= impulse * vecn.x * entity2.mass * entity1.restitution; + entity1.velocity.y -= impulse * vecn.y * entity2.mass * entity1.restitution; + entity1.velocity.z -= impulse * vecn.z * entity2.mass * entity1.restitution; + } + if (entity2.fixed === false) { + entity2.velocity.x += impulse * vecn.x * entity2.mass * entity2.restitution / entity2.mass; + entity2.velocity.y += impulse * vecn.y * entity2.mass * entity2.restitution / entity2.mass; + entity2.velocity.z += impulse * vecn.z * entity2.mass * entity2.restitution / entity2.mass; + } + } + } + }, + nbody: { + tag: "nbody", + lastTime: performance.now(), + G: 6674e-14, + frameMax: 10, + setupEntities: function(entities) { + for (const key in entities) { + const entity = entities[key]; + if (entity.components) { + if (!entity.components[this.tag]) + continue; + } + this.setupEntity(entity); + } + return entities; + }, + setupEntity: function(entity) { + if (!("collisionEnabled" in entity)) + Systems.collider.setupEntity(entity); + entity.isAttractor = true; + if (!("attractorGroup" in entity)) + entity.attractorGroup = 0; + if (!("attractorGroupRules" in entity)) + entity.attractorGroupRules = { + 0: this.G + }; + return entity; + }, + operator: function(entities) { + let keys = this.entityKeys; + for (let i = 0; i < keys.length; i++) { + const entity = entities[keys[i]]; + if (entity.components) { + if (!entity.components[this.tag]) + continue; + } + if (!entity.mass) + continue; + let nSearched = 0; + nested: + for (let j = 0; j < keys.length; j++) { + let randKey = keys[Math.floor(Math.random() * keys.length)]; + nSearched++; + const entity2 = entities[randKey]; + if (nSearched > this.frameMax) + break nested; + if (entity2.components) { + if (!entity2.components[this.tag]) + continue nested; + } + if (!entity2.mass || !entity2.isAttractor) + continue nested; + this.attract( + entity, + entity2, + void 0, + this.G + ); + } + } + return entities; + }, + attract: function(body1, body2, dist, G = this.G, vecn) { + if (dist === void 0) + dist = Systems.collision.distance3D(body1.position, body2.position); + if (vecn === void 0) + vecn = Systems.collision.normalize( + Systems.collision.makeVec(body1.position, body2.position) + ); + let Fg = 0; + if (dist < 0.1) + dist = 0.1; + if (body1.attractorGroupRules[body2.attractorGroup]) { + Fg = body1.attractorGroupRules[body2.attractorGroup] * body1.mass * body2.mass / (dist * dist); + } else + Fg = G * body1.mass * body2.mass / (dist * dist); + body1.force.x += vecn.x * Fg; + body1.force.y += vecn.y * Fg; + body1.force.z += vecn.z * Fg; + body2.force.x -= vecn.x * Fg; + body2.force.y -= vecn.y * Fg; + body2.force.z -= vecn.z * Fg; + } + }, + boid: { + tag: "boid", + lastTime: performance.now(), + defaultAnchor: { x: Math.random(), y: Math.random(), z: Math.random(), mul: 6e-3 }, + setupEntities: function(entities) { + for (const key in entities) { + const entity = entities[key]; + this.setupEntity(entity); + } + return entities; + }, + setupEntity: function(entity) { + if (!entity.position) { + Systems.collider.setupEntity(entity); + } + let adjustedAnchor = Object.assign({}, this.defaultAnchor); + adjustedAnchor.x *= entity.boundingBox.right; + adjustedAnchor.y *= entity.boundingBox.back; + adjustedAnchor.z *= entity.boundingBox.top; + let boidDefaults = { + cohesion: 1e-5, + separation: 1e-4, + alignment: 6e-3, + swirl: adjustedAnchor, + attractor: Object.assign(adjustedAnchor, { mul: 2e-3 }), + useCohesion: true, + useSeparation: true, + useAlignment: true, + useSwirl: true, + useAttractor: true, + useAttraction: false, + groupRadius: 200, + groupSize: 5, + searchLimit: 5 + }; + if (!entity.boid) { + entity.boid = boidDefaults; + } else + entity.boid = Object.assign(boidDefaults, entity.boid); + if (this.entityKeys.length > 1e3) { + entity.boid.groupSize = 1; + entity.boid.searchLimit = 1; + } + return entity; + }, + operator: function(entities) { + let now = performance.now(); + let timeStep = now - this.lastTime; + this.lastTime = now; + let keys = this.entityKeys; + let length = keys.length; + let _timeStep = 1 / timeStep; + let w = -1; + outer: + for (let i = 0; i < keys.length; i++) { + w++; + let p0 = entities[keys[i]]; + const inRange = []; + const distances = []; + const boidVelocities = [ + p0.position.x, + p0.position.y, + p0.position.z, + 0, + 0, + 0, + p0.velocity.x, + p0.velocity.y, + p0.velocity.z, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ]; + let groupCount = 1; + let k = -1; + nested: + for (let j = 0; j < keys.length; j++) { + k++; + if (distances.length > p0.boid.groupSize || k > p0.boid.searchLimit) { + break nested; + } + let randj = keys[Math.floor(Math.random() * length)]; + if (k === w || randj === keys[i] || inRange.indexOf(randj) > -1) { + continue nested; + } else { + let pr = entities[randj]; + let disttemp = Math.sqrt( + (p0.position.x - pr.position.x) * (p0.position.x - pr.position.x) + (p0.position.y - pr.position.y) * (p0.position.y - pr.position.y) + (p0.position.z - pr.position.z) * (p0.position.z - pr.position.z) + ); + if (disttemp > p0.boid.groupRadius) { + continue nested; + } else { + distances.push(disttemp); + inRange.push(randj); + let distInv; + if (p0.boid.useSeparation || p0.boid.useAlignment) { + distInv = p0.boid.groupRadius / (disttemp * disttemp); + if (distInv > p0.maxSpeed) + distInv = p0.maxSpeed; + else if (distInv < -p0.maxSpeed) + distInv = -p0.maxSpeed; + } + if (p0.boid.useCohesion) { + boidVelocities[0] += (pr.position.x - p0.position.x) * 0.5 * disttemp * _timeStep; + boidVelocities[1] += (pr.position.y - p0.position.y) * 0.5 * disttemp * _timeStep; + boidVelocities[2] += (pr.position.z - p0.position.z) * 0.5 * disttemp * _timeStep; + } + if (isNaN(disttemp) || isNaN(boidVelocities[0]) || isNaN(pr.position.x)) { + console.log(disttemp, i, randj, p0.position, pr.position, boidVelocities); + p0.position.x = NaN; + return; + } + if (p0.boid.useSeparation) { + boidVelocities[3] = boidVelocities[3] + (p0.position.x - pr.position.x) * distInv; + boidVelocities[4] = boidVelocities[4] + (p0.position.y - pr.position.y) * distInv; + boidVelocities[5] = boidVelocities[5] + (p0.position.z - pr.position.z) * distInv; + } + if (p0.boid.useAttraction && pr.boid.useAttraction) { + Systems.nbody.attract(p0, pr, disttemp); + } + if (p0.boid.useAlignment) { + boidVelocities[6] = boidVelocities[6] + pr.velocity.x * distInv; + boidVelocities[7] = boidVelocities[7] + pr.velocity.y * distInv; + boidVelocities[8] = boidVelocities[8] + pr.velocity.z * distInv; + } + groupCount++; + } + } + } + let _groupCount = 1 / groupCount; + if (p0.boid.useCohesion) { + boidVelocities[0] = p0.boid.cohesion * (boidVelocities[0] * _groupCount); + boidVelocities[1] = p0.boid.cohesion * (boidVelocities[1] * _groupCount); + boidVelocities[2] = p0.boid.cohesion * (boidVelocities[2] * _groupCount); + } else { + boidVelocities[0] = 0; + boidVelocities[1] = 0; + boidVelocities[2] = 0; + } + if (p0.boid.useSeparation) { + boidVelocities[3] = p0.boid.separation * boidVelocities[3]; + boidVelocities[4] = p0.boid.separation * boidVelocities[4]; + boidVelocities[5] = p0.boid.separation * boidVelocities[5]; + } else { + boidVelocities[3] = 0; + boidVelocities[4] = 0; + boidVelocities[5] = 0; + } + if (p0.boid.useAlignment) { + boidVelocities[6] = -(p0.boid.alignment * boidVelocities[6] * _groupCount); + boidVelocities[7] = p0.boid.alignment * boidVelocities[7] * _groupCount; + boidVelocities[8] = p0.boid.alignment * boidVelocities[8] * _groupCount; + } else { + boidVelocities[6] = 0; + boidVelocities[7] = 0; + boidVelocities[8] = 0; + } + const swirlVec = [0, 0, 0]; + if (p0.boid.useSwirl == true) { + boidVelocities[9] = -(p0.position.y - p0.boid.swirl.y) * p0.boid.swirl.mul; + boidVelocities[10] = (p0.position.z - p0.boid.swirl.z) * p0.boid.swirl.mul; + boidVelocities[11] = (p0.position.x - p0.boid.swirl.x) * p0.boid.swirl.mul; + } + const attractorVec = [0, 0, 0]; + if (p0.boid.useAttractor == true) { + boidVelocities[12] = (p0.boid.attractor.x - p0.position.x) * p0.boid.attractor.mul; + if (p0.position.x > p0.boundingBox.left || p0.position.x < p0.boundingBox.right) { + boidVelocities[12] *= 3; + } + boidVelocities[13] = (p0.boid.attractor.y - p0.position.y) * p0.boid.attractor.mul; + if (p0.position.y > p0.boundingBox.top || p0.position.y < p0.boundingBox.bottom) { + boidVelocities[13] *= 3; + } + boidVelocities[14] = (p0.boid.attractor.z - p0.position.z) * p0.boid.attractor.mul; + if (p0.position.z > p0.boundingBox.front || p0.position.z < p0.boundingBox.back) { + boidVelocities[14] *= 3; + } + } + p0.velocity.x = p0.velocity.x + boidVelocities[0] + boidVelocities[3] + boidVelocities[6] + boidVelocities[9] + boidVelocities[12] + boidVelocities[15], p0.velocity.y = p0.velocity.y + boidVelocities[1] + boidVelocities[4] + boidVelocities[7] + boidVelocities[10] + boidVelocities[13] + boidVelocities[16], p0.velocity.z = p0.velocity.z + boidVelocities[2] + boidVelocities[5] + boidVelocities[8] + boidVelocities[11] + boidVelocities[14] + boidVelocities[17]; + if (isNaN(p0.velocity.x)) + console.error(p0, i, groupCount, p0.position, p0.velocity, swirlVec, attractorVec); + } + return entities; + } + }, + movement: { + tag: "movement", + lastTime: performance.now(), + setupEntities: function(entities) { + for (const key in entities) { + const entity = entities[key]; + if (entity.components) { + if (!entity.components[this.tag]) + continue; + } + this.setupEntity(entity); + } + }, + setupEntity: function(entity) { + if (!("mass" in entity)) + entity.mass = 1; + if (!("fixed" in entity)) + entity.fixed = false; + if (!entity.force) + entity.force = { x: 0, y: 0, z: 0 }; + if (!("mass" in entity)) + entity.mass = 1; + if (!("gravity" in entity)) + entity.gravity = -9.81; + if (!entity.acceleration) + entity.acceleration = { x: 0, y: 0, z: 0 }; + if (!entity.velocity) + entity.velocity = { x: 0, y: 0, z: 0 }; + if (!("maxSpeed" in entity)) + entity.maxSpeed = 10; + if (!entity.position) + entity.position = { x: 0, y: 0, z: 0 }; + return entity; + }, + operator: function(entities) { + let now = performance.now(); + let timeStep = (now - this.lastTime) * 1e-3; + this.lastTime = now; + let keys = this.entityKeys; + for (let i = 0; i < keys.length; i++) { + const entity = entities[keys[i]]; + if (entity.components) { + if (!entity.components[this.tag]) + continue; + } + if (entity.fixed) + continue; + if (entity.mass) { + if (entity.force.x) { + entity.acceleration.x += entity.force.x / entity.mass; + entity.force.x = 0; + } + if (entity.force.y) { + entity.acceleration.y += entity.force.y / entity.mass; + entity.force.y = 0; + } + if (entity.force.z) { + entity.acceleration.z += entity.force.z / entity.mass + entity.gravity; + entity.force.z = 0; + } + } + if (entity.drag) { + if (entity.acceleration.x) + entity.acceleration.x -= entity.acceleration.x * entity.drag * timeStep; + if (entity.acceleration.y) + entity.acceleration.y -= entity.acceleration.y * entity.drag * timeStep; + if (entity.acceleration.z) + entity.acceleration.z -= entity.acceleration.z * entity.drag * timeStep; + } + if (entity.acceleration.x) + entity.velocity.x += entity.acceleration.x * timeStep; + if (entity.acceleration.y) + entity.velocity.y += entity.acceleration.y * timeStep; + if (entity.acceleration.z) + entity.velocity.z += entity.acceleration.z * timeStep; + if (entity.maxSpeed > 0) { + let magnitude = Systems.collision.magnitude(entity.velocity); + if (magnitude > entity.maxSpeed) { + let scalar = entity.maxSpeed / magnitude; + entity.velocity.x *= scalar; + entity.velocity.y *= scalar; + entity.velocity.z *= scalar; + } + } + if (entity.velocity.x) + entity.position.x += entity.velocity.x * timeStep; + if (entity.velocity.y) + entity.position.y += entity.velocity.y * timeStep; + if (entity.velocity.z) + entity.position.z += entity.velocity.z * timeStep; + } + return entities; + } + } + }; + + // ../../services/dom/DOMElement.js + var DOMElement = class extends HTMLElement { + constructor() { + super(); + __publicField(this, "template", function(self2 = this, props) { + return `
    Custom Fragment Props: ${JSON.stringify(props)}
    `; + }); + __publicField(this, "props", {}); + __publicField(this, "useShadow", false); + __publicField(this, "styles"); + __publicField(this, "oncreate"); + __publicField(this, "onresize"); + __publicField(this, "ondelete"); + __publicField(this, "onchanged"); + __publicField(this, "renderonchanged", false); + __publicField(this, "FRAGMENT"); + __publicField(this, "STYLE"); + __publicField(this, "attachedShadow", false); + __publicField(this, "obsAttributes", ["props", "options", "onchanged", "onresize", "ondelete", "oncreate", "template"]); + __publicField(this, "attributeChangedCallback", (name, old, val) => { + if (name === "onchanged") { + let onchanged = val; + if (typeof onchanged === "string") + onchanged = parseFunctionFromText2(onchanged); + if (typeof onchanged === "function") { + this.onchanged = onchanged; + this.state.data.props = this.props; + this.state.unsubscribeTrigger("props"); + this.state.subscribeTrigger("props", this.onchanged); + let changed = new CustomEvent("changed", { detail: { props: this.props, self: this } }); + this.state.subscribeTrigger("props", () => { + this.dispatchEvent(changed); + }); + } + } else if (name === "onresize") { + let onresize = val; + if (typeof onresize === "string") + onresize = parseFunctionFromText2(onresize); + if (typeof onresize === "function") { + if (this.ONRESIZE) { + try { + window.removeEventListener("resize", this.ONRESIZE); + } catch (err) { + } + } + this.ONRESIZE = (ev) => { + this.onresize(this.props, this); + }; + this.onresize = onresize; + window.addEventListener("resize", this.ONRESIZE); + } + } else if (name === "ondelete") { + let ondelete = val; + if (typeof ondelete === "string") + ondelete = parseFunctionFromText2(ondelete); + if (typeof ondelete === "function") { + this.ondelete = () => { + if (this.ONRESIZE) + window.removeEventListener("resize", this.ONRESIZE); + this.state.unsubscribeTrigger("props"); + if (ondelete) + ondelete(this.props, this); + }; + } + } else if (name === "oncreate") { + let oncreate = val; + if (typeof oncreate === "string") + oncreate = parseFunctionFromText2(oncreate); + if (typeof oncreate === "function") { + this.oncreate = oncreate; + } + } else if (name === "renderonchanged") { + let rpc = val; + if (typeof this.renderonchanged === "number") + this.unsubscribeTrigger(this.renderonchanged); + if (typeof rpc === "string") + rpc = parseFunctionFromText2(rpc); + if (typeof rpc === "function") { + this.renderonchanged = this.state.subscribeTrigger("props", (p) => { + this.render(p); + rpc(this, p); + }); + } else if (rpc != false) + this.renderonchanged = this.state.subscribeTrigger("props", this.render); + } else if (name === "props") { + let newProps = val; + if (typeof newProps === "string") + newProps = JSON.parse(newProps); + Object.assign(this.props, newProps); + this.state.setState({ props: this.props }); + } else if (name === "template") { + let template = val; + this.template = template; + this.render(this.props); + let created = new CustomEvent("created", { detail: { props: this.props } }); + this.dispatchEvent(created); + } else { + let parsed = val; + if (name.includes("eval_")) { + name = name.split("_"); + name.shift(); + name = name.join(); + parsed = parseFunctionFromText2(val); + } else if (typeof val === "string") { + try { + parsed = JSON.parse(val); + } catch (err) { + parsed = val; + } + } + this[name] = parsed; + if (name !== "props" && this.props) + this.props[name] = parsed; + } + }); + __publicField(this, "delete", () => { + this.remove(); + if (typeof this.ondelete === "function") + this.ondelete(this.props); + }); + __publicField(this, "render", (props = this.props) => { + if (typeof this.template === "function") + this.templateResult = this.template(this, props); + else + this.templateResult = this.template; + if (this.styles) + this.templateResult = `${this.templateResult}`; + const t = document.createElement("template"); + if (typeof this.templateResult === "string") + t.innerHTML = this.templateResult; + else if (this.templateResult instanceof HTMLElement) { + if (this.templateResult.parentNode) { + this.templateResult.parentNode.removeChild(this.templateResult); + } + t.appendChild(this.templateResult); + } + const fragment = t.content; + if (this.FRAGMENT) { + if (this.useShadow) { + if (this.STYLE) + this.shadowRoot.removeChild(this.STYLE); + this.shadowRoot.removeChild(this.FRAGMENT); + } else + this.removeChild(this.FRAGMENT); + } + if (this.useShadow) { + if (!this.attachedShadow) { + this.attachShadow({ mode: "open" }).innerHTML = ""; + this.attachedShadow = true; + } + if (this.styles) { + let style = document.createElement("style"); + style.textContent = this.styles; + this.shadowRoot.prepend(style); + this.STYLE = style; + } + this.shadowRoot.prepend(fragment); + this.FRAGMENT = this.shadowRoot.childNodes[0]; + } else { + this.prepend(fragment); + this.FRAGMENT = this.childNodes[0]; + } + let rendered = new CustomEvent("rendered", { detail: { props: this.props, self: this } }); + this.dispatchEvent(rendered); + if (this.oncreate) + this.oncreate(this, props); + }); + __publicField(this, "state", { + pushToState: {}, + data: {}, + triggers: {}, + setState(updateObj) { + Object.assign(this.pushToState, updateObj); + if (Object.keys(this.triggers).length > 0) { + for (const prop of Object.getOwnPropertyNames(this.triggers)) { + if (this.pushToState[prop]) { + this.data[prop] = this.pushToState[prop]; + delete this.pushToState[prop]; + this.triggers[prop].forEach((obj) => { + obj.onchanged(this.data[prop]); + }); + } + } + } + return this.pushToState; + }, + subscribeTrigger(key, onchanged = (res) => { + }) { + if (key) { + if (!this.triggers[key]) { + this.triggers[key] = []; + } + let l = this.triggers[key].length; + this.triggers[key].push({ idx: l, onchanged }); + return this.triggers[key].length - 1; + } else + return void 0; + }, + unsubscribeTrigger(key, sub) { + let idx = void 0; + let triggers = this.triggers[key]; + if (triggers) { + if (!sub) + delete this.triggers[key]; + else { + let obj = triggers.find((o) => { + if (o.idx === sub) { + return true; + } + }); + if (obj) + triggers.splice(idx, 1); + return true; + } + } + }, + subscribeTriggerOnce(key = void 0, onchanged = (value) => { + }) { + let sub; + let changed = (value) => { + onchanged(value); + this.unsubscribeTrigger(key, sub); + }; + sub = this.subscribeTrigger(key, changed); + } + }); + } + get observedAttributes() { + return this.obsAttributes; + } + get obsAttributes() { + return this.obsAttributes; + } + set obsAttributes(att) { + if (typeof att === "string") { + this.obsAttributes.push(att); + } else if (Array.isArray(att)) + this.obsAttributes = att; + } + static get tag() { + return this.name.toLowerCase() + "-"; + } + static addElement(tag = this.tag, cls = this, extend = void 0) { + addCustomElement(cls, tag, extend); + } + connectedCallback() { + if (!this.props) + this.props = {}; + let newProps = this.getAttribute("props"); + if (typeof newProps === "string") + newProps = JSON.parse(newProps); + Object.assign(this.props, newProps); + this.state.setState({ props: this.props }); + Array.from(this.attributes).forEach((att) => { + let name = att.name; + let parsed = att.value; + if (name.includes("eval_") || name.includes("()")) { + if (name.includes("eval_")) + name = name.split("_"); + else if (name.includes("()")) + name = name.substring(0, name.indexOf("(")); + name.shift(); + name = name.join(); + parsed = parseFunctionFromText2(att.value); + } else if (typeof att.value === "string") { + try { + parsed = JSON.parse(att.value); + } catch (err) { + parsed = att.value; + } + } + if (!this[name]) { + Object.defineProperties( + this, + att, + { + value: parsed, + writable: true, + get() { + return this[name]; + }, + set(val) { + this.setAttribute(name, val); + } + } + ); + } + this[name] = parsed; + if (name !== "props") + this.props[name] = parsed; + this.obsAttributes.push(name); + }); + let resizeevent = new CustomEvent("resized", { detail: { props: this.props, self: this } }); + let changed = new CustomEvent("changed", { detail: { props: this.props, self: this } }); + let deleted = new CustomEvent("deleted", { detail: { props: this.props, self: this } }); + let created = new CustomEvent("created", { detail: { props: this.props, self: this } }); + this.render(this.props); + this.dispatchEvent(created); + this.state.subscribeTrigger("props", () => { + this.dispatchEvent(changed); + }); + if (typeof this.onresize === "function") { + if (this.ONRESIZE) { + try { + window.removeEventListener("resize", this.ONRESIZE); + } catch (err) { + } + } + this.ONRESIZE = (ev) => { + this.onresize(this, this.props); + this.dispatchEvent(resizeevent); + }; + window.addEventListener("resize", this.ONRESIZE); + } + if (typeof this.ondelete === "function") { + let ondelete = this.ondelete; + this.ondelete = (props = this.props) => { + if (this.ONRESIZE) + window.removeEventListener("resize", this.ONRESIZE); + this.state.unsubscribeTrigger("props"); + this.dispatchEvent(deleted); + ondelete(this, props); + }; + } + if (typeof this.onchanged === "function") { + this.state.data.props = this.props; + this.state.subscribeTrigger("props", this.onchanged); + } + if (this.renderonchanged) { + let rpc = this.renderonchanged; + if (typeof this.renderonchanged === "number") + this.unsubscribeTrigger(this.renderonchanged); + if (typeof rpc === "string") + rpc = parseFunctionFromText2(rpc); + if (typeof rpc === "function") { + this.renderonchanged = this.state.subscribeTrigger("props", (p) => { + this.render(p); + rpc(this, p); + }); + } else if (rpc !== false) + this.renderonchanged = this.state.subscribeTrigger("props", this.render); + } + } + get props() { + return this.props; + } + set props(newProps = {}) { + this.setAttribute("props", newProps); + } + get template() { + return this.template; + } + set template(template) { + this.setAttribute("template", template); + } + get render() { + return this.render; + } + get delete() { + return this.delete; + } + get state() { + return this.state; + } + get onchanged() { + return this.onchanged; + } + set onchanged(onchanged) { + this.setAttribute("onchanged", onchanged); + } + get styles() { + return this.styles; + } + set styles(templateStr) { + this.styles = templateStr; + if (this.querySelector("style")) { + this.querySelector("style").innerHTML = templateStr; + } else { + this.render(); + } + } + get renderonchanged() { + return this.renderonchanged; + } + set renderonchanged(onchanged) { + this.setAttribute("renderonchanged", onchanged); + } + get onresize() { + return this.props; + } + set onresize(onresize) { + this.setAttribute("onresize", onresize); + } + get ondelete() { + return this.props; + } + set ondelete(ondelete) { + this.setAttribute("ondelete", ondelete); + } + get oncreate() { + return this.oncreate; + } + set oncreate(oncreate) { + this.setAttribute("oncreated", oncreate); + } + }; + function addCustomElement(cls, tag, extend = null) { + try { + if (extend) { + if (tag) + window.customElements.define(tag, cls, { extends: extend }); + else + window.customElements.define(cls.name.toLowerCase() + "-", cls, { extends: extend }); + } else { + if (tag) + window.customElements.define(tag, cls); + else + window.customElements.define(cls.name.toLowerCase() + "-", cls); + } + } catch (err) { + } + } + function parseFunctionFromText2(method) { + let getFunctionBody = (methodString) => { + return methodString.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i, "$2$3$4"); + }; + let getFunctionHead = (methodString) => { + let startindex = methodString.indexOf(")"); + return methodString.slice(0, methodString.indexOf("{", startindex) + 1); + }; + let newFuncHead = getFunctionHead(method); + let newFuncBody = getFunctionBody(method); + let newFunc; + try { + if (newFuncHead.includes("function")) { + let varName = newFuncHead.split("(")[1].split(")")[0]; + newFunc = new Function(varName, newFuncBody); + } else { + if (newFuncHead.substring(0, 6) === newFuncBody.substring(0, 6)) { + let varName = newFuncHead.split("(")[1].split(")")[0]; + newFunc = new Function(varName, newFuncBody.substring(newFuncBody.indexOf("{") + 1, newFuncBody.length - 1)); + } else { + try { + newFunc = (0, eval)(newFuncHead + newFuncBody + "}"); + } catch (err) { + newFunc = (0, eval)(method); + } + } + } + } catch (err) { + } + return newFunc; + } + + // ../../services/dom/DOM.service.ts + var DOMService = class extends Service { + constructor(options, parentNode, interpreters) { + super({ props: options?.props, name: options?.name ? options.name : `dom${Math.floor(Math.random() * 1e15)}` }); + this.loadDefaultRoutes = false; + this.keepState = true; + this.parentNode = document.body; + this.interpreters = { + md: (template, options) => { + if (typeof markdownit === "undefined") { + document.head.insertAdjacentHTML( + "beforeend", + ` + diff --git a/index.node.ts b/index.node.ts index 6ae17440..ffe3dbe4 100644 --- a/index.node.ts +++ b/index.node.ts @@ -1,38 +1,34 @@ //frontend (browser-compatible) exports -export * from './src/core/Graph' -export * from './src/core/EventHandler' -export * from './src/loaders' +export * from './Graph' -export { methodstrings } from './src/loaders/methodstrings' +export * from './services/Service' +export * from './services/unsafe/Unsafe.service' -export * from './src/services/Service' -export * from './src/services/remote/remote.routes' - -export * from './src/services/ecs/ECS.service' +export * from './services/ecs/ECS.service' // export * from './services/dom/DOM.service' // export * from './services/dom/components/index' -export * from './src/services/e2ee/E2EE.service' +export * from './services/e2ee/E2EE.service' //export * from './services/gpu/GPU.service' -export * from './src/services/http/HTTP.node' +export * from './services/http/HTTP.node' -export * from './src/services/sse/SSE.node' +export * from './services/sse/SSE.node' -export * from './src/services/wss/WSS.node' +export * from './services/wss/WSS.node' -export * from './src/services/cmd/CMD.node' +export * from './services/cmd/CMD.node' -//export * from './src/services/struct/Struct.frontend' +//export * from './services/struct/Struct.frontend' -// export * from './src/services/webrtc/WebRTC.browser' +// export * from './services/webrtc/WebRTC.browser' -//export * from './src/services/worker/Worker.service' //this needs a polyfill to work in nodejs -//export * from './src/services/worker/Subprocess' +export * from './services/worker/Worker.node.service' +export * from './services/worker/Subprocess' -export * from './src/services/sessions/sessions.service' +export * from './services/sessions/sessions.service' -export * from './src/services/router/Router' \ No newline at end of file +export * from './services/router/Router' \ No newline at end of file diff --git a/index.ts b/index.ts index cebf97cd..1f4922cb 100644 --- a/index.ts +++ b/index.ts @@ -1,43 +1,34 @@ //frontend (browser-compatible) exports +export * from './Graph' -export * from './src/core/Graph' -export * from './src/core/EventHandler' -export * from './src/loaders' -export * from './src/services/utils' +export * from './services/Service' +export * from './services/unsafe/Unsafe.service' -export { methodstrings } from './src/loaders/methodstrings' +export * from './services/ecs/ECS.service' -export * from './src/services/Service' -export * from './src/services/remote/remote.routes' +export * from './services/dom/DOM.service' +export { DOMElement, addCustomElement } from './services/dom/DOMElement' -export * from './src/services/ecs/ECS.service' - -export {html, xml} from './src/loaders/html/html' -export * from './src/loaders/html/html.loader' - -export { DOMElement, addCustomElement } from './src/loaders/html/DOMElement' -export * from './src/loaders/html/wc.loader' //includes the web component spec, html loader is a little leaner otherwise - -export * from './src/services/e2ee/E2EE.service' +export * from './services/e2ee/E2EE.service' //export * from './services/gpu/GPU.service' -export * from './src/services/http/HTTP.browser' +export * from './services/http/HTTP.browser' -export * from './src/services/sse/SSE.browser' +export * from './services/sse/SSE.browser' -export * from './src/services/wss/WSS.browser' +export * from './services/wss/WSS.browser' //export * from './services/struct/Struct.frontend' -export * from './src/services/webrtc/WebRTC.browser' +export * from './services/webrtc/WebRTC.browser' -export * from './src/services/worker/Worker.service' -export * from './src/services/worker/ProxyListener' -export * from './src/services/worker/WorkerCanvas' -//export * from './src/services/worker/Subprocess' +export * from './services/worker/Worker.service' +export * from './services/worker/ProxyListener' +export * from './services/worker/WorkerCanvas' +export * from './services/worker/Subprocess' -export * from './src/services/sessions/sessions.service' +export * from './services/sessions/sessions.service' -export * from './src/services/router/Router' \ No newline at end of file +export * from './services/router/Router' \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 5e09c1ee..12a8ccae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,28 +1,31 @@ { - "name": "graphscript", - "version": "0.3.1", + "name": "graphscript-node", + "version": "0.0.125", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "graphscript", - "version": "0.3.1", - "license": "LGPL-3.0-or-later", + "name": "graphscript-node", + "version": "0.0.125", + "license": "AGPL-3.0-or-later", "dependencies": { - "better-sse": "~0.11.0", - "brainsatplay-math": "~0.1.0", - "web-worker": "~1.3.0", - "ws": "~8.16.0" + "better-sse": "^0.7.1", + "brainsatplay-data": "^0.0.48", + "brainsatplay-math": "^0.0.22", + "bson-objectid": "^2.0.3", + "gpujsutils": "^1.0.8", + "web-worker": "^1.2.0", + "ws": "^8.7.0" }, "devDependencies": { - "@types/node": "~18.7.15", - "@types/ws": "~8.5.3" + "@types/node": "^17.0.36", + "@types/ws": "^8.5.3" } }, "../../../AppData/Roaming/npm/node_modules/tinybuild": { "version": "0.3.127", "extraneous": true, - "license": "LGPL-3.0-or-later", + "license": "AGPL-3.0-or-later", "dependencies": { "chokidar": "~3.5.3", "esbuild": "~0.14.41", @@ -37,49 +40,72 @@ } }, "node_modules/@types/node": { - "version": "18.7.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.19.tgz", - "integrity": "sha512-Sq1itGUKUX1ap7GgZlrzdBydjbsJL/NSQt/4wkAxUJ7/OS5c2WkoN6WSpWc2Yc5wtKMZOUA0VCs/j2XJadN3HA==", + "version": "17.0.36", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.36.tgz", + "integrity": "sha512-V3orv+ggDsWVHP99K3JlwtH20R7J4IhI1Kksgc+64q5VxgfRkQG8Ws3MFm/FZOKDYGy9feGFlZ70/HpCNe9QaA==", "dev": true }, "node_modules/@types/ws": { - "version": "8.5.4", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz", - "integrity": "sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==", + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", + "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/better-sse": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/better-sse/-/better-sse-0.11.0.tgz", - "integrity": "sha512-xY5Nmn9XyO5PiMw4//C+mNCUknaueugBqXMoMdEp2s9oNDVI4Vu6nhjduxA6yOxJVm/O6u3YC3FbLMHEvTzk3Q==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/better-sse/-/better-sse-0.7.1.tgz", + "integrity": "sha512-2t7XGg6hQFNwtmFXKi6/jyY5K0/4fa5UoOqVSYG2W/AFbVCt8gPnFw2LHM9ude91a8KhoXtRt9zOwpVZ5f5K5g==", "engines": { "node": ">=12", "pnpm": ">=6" } }, + "node_modules/brainsatplay-data": { + "version": "0.0.48", + "resolved": "https://registry.npmjs.org/brainsatplay-data/-/brainsatplay-data-0.0.48.tgz", + "integrity": "sha512-3xJ4C5ts0z6dKTkaEI0LrHO443gphOj/OAP9JfZARZXE5MO+kMsOIlvAgijeP7ty4btZtg7MNEEacwIBXREgbQ==", + "dependencies": { + "brainsatplay-math": "^0.0.2" + } + }, + "node_modules/brainsatplay-data/node_modules/brainsatplay-math": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/brainsatplay-math/-/brainsatplay-math-0.0.2.tgz", + "integrity": "sha512-7fjUfcmR2TcHtRh9jCds1WF1HZWhvvDytE6ngrkOUnMTQTbrDs0iAcp8NjMEiHumJRjcaD/c6PN60wIY0rjQaQ==" + }, "node_modules/brainsatplay-math": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/brainsatplay-math/-/brainsatplay-math-0.1.0.tgz", - "integrity": "sha512-V95piSmlNtqf6vYXrhg/wu/IuTSQnM1jj5LXKHh68zVGYV9x2EEiR4TqcRMw3URbRHzME4DHkWNXJ1l2vwDhYg==" + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/brainsatplay-math/-/brainsatplay-math-0.0.22.tgz", + "integrity": "sha512-er+7fobi+bgtuiaN5Pcg0cpOfl/d5hrM8W8sF5lnX9VWhcs2TvyG3J0UV+pozGYSBvtqij7Evs4HhhFIh3cfbQ==" + }, + "node_modules/bson-objectid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bson-objectid/-/bson-objectid-2.0.3.tgz", + "integrity": "sha512-WYwVtY9yqk179EPMNuF3vcxufdrGLEo2XwqdRVbfLVe9X6jLt7WKZQgP+ObOcprakBGbHxzl76tgTaieqsH29g==" + }, + "node_modules/gpujsutils": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/gpujsutils/-/gpujsutils-1.0.8.tgz", + "integrity": "sha512-TEWBNXDclnohXSgPs/Ofl5NDCD9PPquShftbhUDE78CsFypsK7wjExvK2z7yn8ZUqSRf/4htFUNXXBalRIV1TQ==" }, "node_modules/web-worker": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz", - "integrity": "sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", + "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" }, "node_modules/ws": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz", + "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==", "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" + "utf-8-validate": "^5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -93,39 +119,64 @@ }, "dependencies": { "@types/node": { - "version": "18.7.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.19.tgz", - "integrity": "sha512-Sq1itGUKUX1ap7GgZlrzdBydjbsJL/NSQt/4wkAxUJ7/OS5c2WkoN6WSpWc2Yc5wtKMZOUA0VCs/j2XJadN3HA==", + "version": "17.0.36", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.36.tgz", + "integrity": "sha512-V3orv+ggDsWVHP99K3JlwtH20R7J4IhI1Kksgc+64q5VxgfRkQG8Ws3MFm/FZOKDYGy9feGFlZ70/HpCNe9QaA==", "dev": true }, "@types/ws": { - "version": "8.5.4", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz", - "integrity": "sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==", + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", + "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", "dev": true, "requires": { "@types/node": "*" } }, "better-sse": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/better-sse/-/better-sse-0.11.0.tgz", - "integrity": "sha512-xY5Nmn9XyO5PiMw4//C+mNCUknaueugBqXMoMdEp2s9oNDVI4Vu6nhjduxA6yOxJVm/O6u3YC3FbLMHEvTzk3Q==" + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/better-sse/-/better-sse-0.7.1.tgz", + "integrity": "sha512-2t7XGg6hQFNwtmFXKi6/jyY5K0/4fa5UoOqVSYG2W/AFbVCt8gPnFw2LHM9ude91a8KhoXtRt9zOwpVZ5f5K5g==" + }, + "brainsatplay-data": { + "version": "0.0.48", + "resolved": "https://registry.npmjs.org/brainsatplay-data/-/brainsatplay-data-0.0.48.tgz", + "integrity": "sha512-3xJ4C5ts0z6dKTkaEI0LrHO443gphOj/OAP9JfZARZXE5MO+kMsOIlvAgijeP7ty4btZtg7MNEEacwIBXREgbQ==", + "requires": { + "brainsatplay-math": "^0.0.2" + }, + "dependencies": { + "brainsatplay-math": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/brainsatplay-math/-/brainsatplay-math-0.0.2.tgz", + "integrity": "sha512-7fjUfcmR2TcHtRh9jCds1WF1HZWhvvDytE6ngrkOUnMTQTbrDs0iAcp8NjMEiHumJRjcaD/c6PN60wIY0rjQaQ==" + } + } }, "brainsatplay-math": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/brainsatplay-math/-/brainsatplay-math-0.1.0.tgz", - "integrity": "sha512-V95piSmlNtqf6vYXrhg/wu/IuTSQnM1jj5LXKHh68zVGYV9x2EEiR4TqcRMw3URbRHzME4DHkWNXJ1l2vwDhYg==" + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/brainsatplay-math/-/brainsatplay-math-0.0.22.tgz", + "integrity": "sha512-er+7fobi+bgtuiaN5Pcg0cpOfl/d5hrM8W8sF5lnX9VWhcs2TvyG3J0UV+pozGYSBvtqij7Evs4HhhFIh3cfbQ==" + }, + "bson-objectid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bson-objectid/-/bson-objectid-2.0.3.tgz", + "integrity": "sha512-WYwVtY9yqk179EPMNuF3vcxufdrGLEo2XwqdRVbfLVe9X6jLt7WKZQgP+ObOcprakBGbHxzl76tgTaieqsH29g==" + }, + "gpujsutils": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/gpujsutils/-/gpujsutils-1.0.8.tgz", + "integrity": "sha512-TEWBNXDclnohXSgPs/Ofl5NDCD9PPquShftbhUDE78CsFypsK7wjExvK2z7yn8ZUqSRf/4htFUNXXBalRIV1TQ==" }, "web-worker": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz", - "integrity": "sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", + "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" }, "ws": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz", + "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==", "requires": {} } } diff --git a/package.json b/package.json index 8a9b9da1..303eaeda 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "graphscript", - "version": "0.3.12", + "version": "0.1.37", "description": "Comprehensive acyclic-graph based application architecture with microservices and networking", "main": "dist/index.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts", "scripts": { - "start": "tinybuild && tinybuild path=tinybuild.node.config.js && tinybuild path=tinybuild.core.config.js && cd src/extras && npm start", + "start": "tinybuild && tinybuild path=tinybuild.node.config.js && tinybuild path=tinybuild.core.config.js && cd extras && tinybuild path=tinybuild.config.js", "build": "tinybuild build", "serve": "tinybuild serve", "init": "node tinybuild/init.js", @@ -21,14 +21,13 @@ "esbuild" ], "author": "Joshua Brewster", - "license": "LGPL-3.0-or-later", - "devDependencies": { - "better-sse": "~0.11.0", - "brainsatplay-math": "~0.1.0", - "web-worker": "~1.3.0", - "ws": "~8.16.0", - "@types/node": "~18.7.15", - "@types/ws": "~8.5.3" + "license": "AGPL-3.0-or-later", + "dependencies": { + "better-sse": "~0.8.0", + "brainsatplay-math": "~0.0.22", + "bson-objectid": "~2.0.3", + "web-worker": "~1.2.0", + "ws": "~8.8.1" }, "nodemonConfig": { "env": { @@ -38,5 +37,9 @@ "dist/", ".temp/" ] + }, + "devDependencies": { + "@types/node": "~18.7.15", + "@types/ws": "~8.5.3" } } diff --git a/_old/_oldService.ts b/services/Service.ts similarity index 98% rename from _old/_oldService.ts rename to services/Service.ts index 89a2addc..93556ba3 100644 --- a/_old/_oldService.ts +++ b/services/Service.ts @@ -132,8 +132,8 @@ export class Service extends Graph { routes?:Service|Graph|Routes|{name:string,module:{[key:string]:any}}|any, includeClassName:boolean=true, //enumerate routes with the service or class name so they are run as e.g. 'http/createServer' so services don't accidentally overlap routeFormat:string='.', - customRoutes:ServiceOptions["customRoutes"]=this.customRoutes, - customChildren:ServiceOptions["customChildren"]=this.customChildren, + customRoutes?:ServiceOptions["customRoutes"], + customChildren?:ServiceOptions["customChildren"], sharedState:boolean = true ) => { if(!routes && !this.loadDefaultRoutes && (Object.keys(this.routes).length > 0 || this.firstLoad)) return; @@ -352,7 +352,7 @@ export class Service extends Graph { if(customRoutes) { //mutate routes or run custom node creation functions for(const key in customRoutes) { - //console.log(r, r.constructor.name) + console.log(r, r.constructor.name) r = customRoutes[key](r,route,allRoutes); if(!r) continue top; //nothing returned so continue } @@ -404,14 +404,16 @@ export class Service extends Graph { } else this.setTree(this.routes); - for(const prop in routes) { //now set the aliases on the routes, the aliases share the same node otherwise - if((routes[prop] as any)?.aliases) { - let aliases = (routes[prop] as any).aliases; + for(const prop in this.routes) { //now set the aliases on the routes, the aliases share the same node otherwise + if((this.routes[prop] as any)?.aliases) { + let aliases = (this.routes[prop] as any).aliases; aliases.forEach((a:string) => { - if(service?.name && includeClassName) this.routes[service.name+routeFormat+a] = routes[prop]; //we're just gonna copy the routes to the aliases for simplicity - else this.routes[a] = routes[prop]; + if(service?.name && includeClassName) routes[service.name+routeFormat+a] = this.routes[prop]; //we're just gonna copy the routes to the aliases for simplicity + else routes[a] = this.routes[prop]; }); + } + } //console.log(this.name,this.routes); diff --git a/src/services/cmd/CMD.node.ts b/services/cmd/CMD.node.ts similarity index 89% rename from src/services/cmd/CMD.node.ts rename to services/cmd/CMD.node.ts index a9d4bf1b..001644c6 100644 --- a/src/services/cmd/CMD.node.ts +++ b/services/cmd/CMD.node.ts @@ -1,7 +1,7 @@ //for running parallel processes (with their own memory, as opposed to workers which share memory) in node.js import {ChildProcess, fork, Serializable, spawn} from 'child_process' -import { Service, ServiceMessage, ServiceOptions } from '../Service'; -import { Graph, GraphNode, GraphNodeProperties } from '../../core/Graph'; +import { Route, Routes, Service, ServiceMessage, ServiceOptions } from '../Service'; +import { GraphNodeProperties } from '../../Graph'; import path from 'path'; //enable message passing between child processes. @@ -27,7 +27,7 @@ export type CMDInfo = { request:(message:ServiceMessage|any,method?:string) => Promise, post:(route:string, args:any, method?:string) => boolean, run:(route:any, args?:any, method?:string) => Promise, - subscribe:(route:any, callback?:((res:any)=>void)|string, args?:any[], key?:string, subInput?:boolean) => number, + subscribe:(route:any, callback?:((res:any)=>void)|string) => number, unsubscribe:(route:any, sub:number) => Promise } & CMDRoute @@ -43,24 +43,23 @@ export class CMDService extends Service { } connections = { //higher level reference for Router - processes:undefined as any + processes:this.processess } - subprocessloader = { - 'process':(node: CMDRoute & GraphNode, parent: GraphNode, graph: Graph, roots:any, properties:any) => { - if((node as CMDRoute).command) { - this.createProcess((node as CMDRoute)); + customRoutes:ServiceOptions['customRoutes']={ + 'process':(route: CMDRoute|Route, routeKey: string, routes: Routes) => { + if((route as CMDRoute).command) { + this.createProcess((route as CMDRoute)); } + return route; } } constructor(options?:ServiceOptions) { super(options) - this.load(this); + this.load(this.routes); - this.connections.processes = this.processes; - - if(process?.stdin) { + if(process.stdin) { process.stdin.on('data', (data) => { let str = data.toString(); this.receive(str); @@ -152,8 +151,8 @@ export class CMDService extends Service { } - newprocess.subscribe = (route:any, callback?:((res:any)=>void)|string, args?:any[], key?:string, subInput?:boolean) => { - return this.subscribeToProcess(route, newprocess._id, callback, args, key, subInput); + newprocess.subscribe = (route:any, callback?:((res:any)=>void)|string) => { + return this.subscribeToProcess(route, newprocess._id, callback); } newprocess.unsubscribe = (route:any, sub:number) => { @@ -170,8 +169,6 @@ export class CMDService extends Service { return newprocess; } - open = this.createProcess; - abort = (childprocess:ChildProcess|CMDInfo) => { if((childprocess as CMDInfo).controller) (childprocess as CMDInfo).controller.abort(); @@ -226,8 +223,7 @@ export class CMDService extends Service { return res; } - subscribeProcess(route:string, childprocess:ChildProcess|string, args?:any[], key?:string, subInput?:boolean) { - if(this.restrict?.[route]) return undefined; + subscribeProcess(route:string, childprocess:ChildProcess|string) { if(typeof childprocess === 'string' && this.processes[childprocess]) { childprocess = this.processes[childprocess].process; } @@ -240,12 +236,12 @@ export class CMDService extends Service { } else { (childprocess as ChildProcess).send(JSON.stringify({args:res, callbackId:route})); } - },args,key,subInput); + }); } - subscribeToProcess(route:string, processId:string, callback?:((res:any)=>void)|string, args?:any[], key?:string, subInput?:boolean) { + subscribeToProcess(route:string, processId:string, callback?:((res:any)=>void)|string) { if(typeof processId === 'string' && this.processes[processId]) { - this.__node.state.subscribeEvent(processId, (res) => { + this.subscribe(processId, (res) => { if(res?.callbackId === route) { if(!callback) this.setState({[processId]:res.args}); //just set state else if(typeof callback === 'string') { //run a local node @@ -254,8 +250,19 @@ export class CMDService extends Service { else callback(res.args); } }); - return this.processes[processId].request(JSON.stringify({route:'subscribeSocket', args:[route,processId,args,key,subInput]})); + return this.processes[processId].request(JSON.stringify({route:'subscribeSocket', args:[route,processId]})); } } + routes:Routes={ + createProcess:this.createProcess, + abort:this.abort, + send:this.send, + request:this.request, + runRequest:this.runRequest, + subscribeProcess:this.subscribeProcess, + subscribeToProcess:this.subscribeToProcess, + unsubscribe:this.unsubscribe + } + } \ No newline at end of file diff --git a/src/services/cmd/childprocess.js b/services/cmd/childprocess.js similarity index 68% rename from src/services/cmd/childprocess.js rename to services/cmd/childprocess.js index 3f346950..8f19efe6 100644 --- a/src/services/cmd/childprocess.js +++ b/services/cmd/childprocess.js @@ -1,10 +1,10 @@ //stock child process that runs services import { CMDService } from "./CMD.node"; -import { remoteGraphRoutes } from '../remote/remote.routes'; +import { unsafeRoutes } from '../unsafe/Unsafe.service'; const service = new CMDService({ - routes:[remoteGraphRoutes] + routes:[unsafeRoutes] }); //now we can send/receive messages console.log("Child process listening...") \ No newline at end of file diff --git a/_old/__oldDOM.service.ts b/services/dom/DOM.service.ts similarity index 85% rename from _old/__oldDOM.service.ts rename to services/dom/DOM.service.ts index 2992ced2..bff5a83c 100644 --- a/_old/__oldDOM.service.ts +++ b/services/dom/DOM.service.ts @@ -1,6 +1,6 @@ import { DOMElement } from "./DOMElement"; //https://github.com/joshbrew/DOMElement <---- this is the special sauce -import { Graph, GraphNode } from '../../Graph'; -import { Service, ServiceOptions } from "../Service"; +import { Graph, GraphNode, GraphNodeProperties, OperatorType } from '../../Graph'; +import { RouteProp, Service, ServiceOptions } from "../Service"; import {CompleteOptions, ElementInfo, ElementProps, ComponentProps, ComponentInfo, CanvasElementProps, CanvasOptions, CanvasElementInfo} from './types/index'; @@ -12,6 +12,21 @@ export type DOMRouteProp = ComponentProps | CanvasElementProps +export type DOMServiceRoute = + GraphNode | + GraphNodeProperties | + Graph | + OperatorType | + ((...args)=>any|void) | + { aliases?:string[] } & GraphNodeProperties | + RouteProp | + DOMRouteProp + + +export type DOMRoutes = { + [key:string]:DOMServiceRoute +} + export class DOMService extends Service { @@ -61,35 +76,45 @@ export class DOMService extends Service { } } - domloader = { - 'dom':(r:DOMRouteProp & GraphNode, parent:GraphNode & DOMRouteProp, graph:Graph, tree:any, props:any,key:string) => { + customRoutes:ServiceOptions["customRoutes"] = { + 'dom':(r:DOMServiceRoute|any, route:string, routes:DOMRoutes|any) => { // console.log(r) + if(!(r instanceof GraphNode)) { + if(r.element?.parentNode?.id && r.graph?.parentNode?.id) { + if(r.graph.parentNode.id === r.element.id) { + r.parentNode = this.parentNode; //triggers the setter to reparent + } + } + else { + if(r.template) { //assume its a component node + if(!r.tag) r.tag = route; + this.addComponent(r,r.generateChildElementNodes); + } + else if(r.context) { //assume its a canvas node + if(!r.tag) r.tag = route; + this.addCanvasComponent(r); + } + else if(r.tagName || r.element) { //assume its an element node + if(!r.tag) r.tag = route; + this.addElement(r,r.generateChildElementNodes); + } + } - if((parent.__node.tag || parent.id) && (parent.template || parent.context || parent.tagName || parent.element) && (r.template || r.context || r.tagName || r.element) && !r.parentNode) { - if(parent.__node.tag) r.parentNode = parent.__node.tag; - if(parent.id) r.parentNode = parent.id; } - if(r.element?.parentNode?.id && r.graph?.parentNode?.id) { - if(r.graph.parentNode.id === r.element.id) { - r.parentNode = this.parentNode; //triggers the setter to reparent - } - } - else { - if(r.template) { //assume its a component node - r.id = key; - this.addComponent(r as any,r.generateChildElementNodes); - } - else if(r.context) { //assume its a canvas node - r.id = key; - this.addCanvasComponent(r as any); - } - else if(r.tagName || r.element) { //assume its an element node - r.id = key; - this.addElement(r as any,r.generateChildElementNodes); - } + return r; + } + } + + customChildren:ServiceOptions["customChildren"] = { + 'dom':(rt:DOMServiceRoute|any, routeKey:string, parent:any, routes:DOMRoutes, checked:DOMRoutes) => { + //automatically parent children html routes to parent html routes without needing explicit parentNode definitions + if((parent.tag || parent.id) && (parent.template || parent.context || parent.tagName || parent.element) && (rt.template || rt.context || rt.tagName || rt.element) && !rt.parentNode) { + if(parent.tag) rt.parentNode = parent.tag; + if(parent.id) rt.parentNode = parent.id; } + return rt; } } @@ -98,8 +123,8 @@ export class DOMService extends Service { parentNode?:HTMLElement, interpreters?:{[key:string]:(template:string,options:ComponentProps) => void} ) { - super(); - if(options?.services) this.addServices(options.services); + super({props:options?.props,name:options?.name ? options.name : `dom${Math.floor(Math.random()*1000000000000000)}`}); + if(options?.parentNode) parentNode = options.parentNode; if(typeof parentNode === 'string') parentNode = document.getElementById(parentNode); if(parentNode instanceof HTMLElement) this.parentNode = parentNode; @@ -110,9 +135,7 @@ export class DOMService extends Service { //console.log('init domservice', options) - this.setLoaders(this.domloader); - this.setTree(this); - if(options) this.init(options); + this.init(options); } @@ -139,7 +162,7 @@ export class DOMService extends Service { let elm:HTMLElement = this.createElement(options); if(!options.element) options.element = elm; - if(!options.__operator) options.__operator = function (props:{[key:string]:any}){ + if(!options.operator) options.operator = function (props:{[key:string]:any}){ if(typeof props === 'object') for(const key in props) { if(this.element) { @@ -167,7 +190,7 @@ export class DOMService extends Service { this.elements[options.id] = {element:elm, node, parentNode: (options as CompleteOptions).parentNode, divs}; - if(!node.__ondisconnected) node.__ondisconnected = (node) => { + if(!node.ondelete) node.ondelete = (node) => { elm.remove(); if(options.onremove) options.onremove.call(this.elements[options.id].node, elm, this.elements[options.id]); } //in this case we need to remove the element from the dom via the node and run callbacks here due to elements lacking an 'onremove' event @@ -205,8 +228,8 @@ export class DOMService extends Service { updateOptions = (options, element): CompleteOptions => { - if(!options.id && options.__node.tag) options.id = options.__node.tag; - if(!options.__node.tag && options.id) options.__node.tag = options.id; + if(!options.id && options.tag) options.id = options.tag; + if(!options.tag && options.id) options.tag = options.id; if(!options.id) options.id = `${options.tagName ?? 'element'}${Math.floor(Math.random()*1000000000000000)}`; let p = options.parentNode; @@ -250,25 +273,32 @@ export class DOMService extends Service { // if(options.parentNode.shadowRoot) { // console.log(options.parentNode.shadowRoot) // options.parentNode.shadowRoot.appendChild(elm); - // } else + // } else parentNode.appendChild(elm); } if(oncreate) oncreate.call(elm.node, elm, this.elements[options.id]); + if(elm.node.animation || elm.node.animate) { + elm.node.runAnimation(); + } + if(elm.node.looper || typeof elm.node.loop === 'number' && elm.node.loop) { + elm.node.runLoop() + } },0.01); //small timeout makes sure the elements all load before executing node utilities } } resolveGraphNode = (element, options) => { - let node: GraphNode & DOMRouteProp; - if(this.__node.nodes.get(options.id)?.element?.parentNode?.id === options.parentNode || this.__node.nodes.get(options.id)?.parentNode === options.parentNode) { - node = this.__node.nodes.get(options.id); + + let node: GraphNode + if(this.nodes.get(options.id)?.element?.parentNode?.id === options.parentNode || this.nodes.get(options.id)?.parentNode === options.parentNode) { + node = this.nodes.get(options.id); } else { let parentId = options.parentNode instanceof HTMLElement ? options.parentNode?.id : typeof options.parentNode === 'string' ? options.parentNode : undefined; let parent; - if(parentId) parent = this.__node.nodes.get(parentId); + if(parentId) parent = this.nodes.get(parentId); node = new GraphNode( options instanceof Graph ? options : Object.assign({},options), parent, @@ -290,7 +320,7 @@ export class DOMService extends Service { }); // Use Graph Elements as Parent Nodes - if (!node['element']) Object.defineProperty(node, 'element', { + Object.defineProperty(node, 'element', { get: () => element, set: (v) => { element = v @@ -382,7 +412,7 @@ export class DOMService extends Service { } if(!options.element) options.element = elm; - if(!options.__operator) options.__operator = function op(props:{[key:string]:any}){ + if(!options.operator) options.operator = function op(props:{[key:string]:any}){ if(typeof props === 'object') for(const key in props) { if(this.element) { @@ -403,7 +433,7 @@ export class DOMService extends Service { let node = this.resolveGraphNode(elm, options); - node.__addOndisconnected((node) => { (elm as DOMElement).delete(); }); + if(!node.ondelete) node.ondelete = (node) => { (elm as DOMElement).delete(); } this.components[completeOptions.id] = { @@ -483,7 +513,7 @@ export class DOMService extends Service { this.templates[completeOptions.id] = completeOptions; if(!options.element) options.element = elm; - if(!options.__operator) options.__operator = function op(props:{[key:string]:any}){ + if(!options.operator) options.operator = function op(props:{[key:string]:any}){ if(typeof props === 'object') for(const key in props) { if(this.element) { @@ -503,7 +533,7 @@ export class DOMService extends Service { let node = this.resolveGraphNode(elm, options); - node.__addOndisconnected((node) => { (elm as DOMElement).delete(); }); + if(!node.ondelete) node.ondelete = (node) => { (elm as DOMElement).delete(); } let canvas = elm.querySelector('canvas'); if(completeOptions.style) Object.assign(canvas.style,completeOptions.style); //assign the style object @@ -541,8 +571,8 @@ export class DOMService extends Service { if((element as ComponentInfo|CanvasElementInfo).element) element = (element as ComponentInfo|CanvasElementInfo).element; } else if(typeof element === 'string' && this.components[element]) { - if((this.components[element] as CanvasElementInfo).node.__node.isAnimating) - (this.components[element] as CanvasElementInfo).node.__node.isAnimating = false; + if((this.components[element] as CanvasElementInfo).node.isAnimating) + (this.components[element] as CanvasElementInfo).node.stopNode(); if((this.components[element] as ComponentInfo).divs) (this.components[element] as ComponentInfo).divs.forEach((d) => this.terminate(d)); @@ -561,7 +591,7 @@ export class DOMService extends Service { } if(element) { - if(this.__node.nodes.get((element as any).id)) { + if(this.nodes.get((element as any).id)) { this.removeTree((element as any).id); } @@ -576,6 +606,13 @@ export class DOMService extends Service { return false; } + defaultRoutes:DOMRoutes = { //declared at the end so everything on this class is defined to pass through as node props + addElement:this.addElement, + addComponent:this.addComponent, + addCanvasComponent:this.addCanvasComponent, + terminate:this.terminate + } + } /** diff --git a/dist/src/loaders/html/DOMElement.d.ts b/services/dom/DOMElement.d.ts similarity index 61% rename from dist/src/loaders/html/DOMElement.d.ts rename to services/dom/DOMElement.d.ts index f0ad10a8..538004c8 100644 --- a/dist/src/loaders/html/DOMElement.d.ts +++ b/services/dom/DOMElement.d.ts @@ -1,22 +1,27 @@ + +//todo: make this the permanent version so I can stop copying manually each build export function addCustomElement(cls: any, tag: any, extend?: any): void; export function randomId(tag?: string): string; export function parseFunctionFromText(method: any): any; export class DOMElement extends HTMLElement { static get tag(): string; static addElement(tag?: string, cls?: typeof DOMElement, extend?: any): void; + template: ((self: DOMElement, props: any) => (string|HTMLElement)) | string | HTMLElement; + props: {[key:string]:any}; useShadow: boolean; + styles: string; + oncreate: ((self: DOMElement, props: any) => void); + onresize: ((self: DOMElement, props: any) => void)|any; + ondelete: ((self: DOMElement, props: any) => void); + onchanged: ((self: DOMElement, props: any) => void); + renderonchanged: boolean | ((self: DOMElement, props: any) => void); FRAGMENT: any; STYLE: any; attachedShadow: boolean; obsAttributes: string[]; - props: {}; + get observedAttributes(): string[]; attributeChangedCallback: (name: any, old: any, val: any) => void; - onchanged: any; - ONRESIZE: ((ev: any) => void) | ((ev: any) => void); - ondelete: (() => void) | ((props?: {}) => void); - oncreate: any; - renderonchanged: number; - template: any; + ONRESIZE: (ev: any) => void; connectedCallback(): void; delete: () => void; render: (props?: {}) => void; diff --git a/src/loaders/html/DOMElement.js b/services/dom/DOMElement.js similarity index 81% rename from src/loaders/html/DOMElement.js rename to services/dom/DOMElement.js index b7761d33..65746270 100644 --- a/src/loaders/html/DOMElement.js +++ b/services/dom/DOMElement.js @@ -1,31 +1,41 @@ -import { html } from "./html"; -let dummy = html``; - -//from 'fragelement' on npm by Joshua Brewster (LGPL v3.0) +//from 'fragelement' on npm by Joshua Brewster (AGPL v3.0) export class DOMElement extends HTMLElement { - // template = function(self=this, props){ //return a string or html node - // return `
    Custom Fragment Props: ${JSON.stringify(props)}
    ` - // }; //override the default template string by extending the class, or use options.template if calling the base class - // props = {}; + template = function(self=this, props){ //return a string or html node + return `
    Custom Fragment Props: ${JSON.stringify(props)}
    ` + }; //override the default template string by extending the class, or use options.template if calling the base class + props = {}; useShadow = false; //can set to attach a shadow DOM instead (local styles) - // styles; //can set a style sheet which will toggle the shadow dom by default + styles; //can set a style sheet which will toggle the shadow dom by default // NOTE: Referencing this inside one of these events will give you the GraphNode - // oncreate; //(self,props) => {} fires on element creation (e.g. to set up logic) - // onresize; //(self,props) => {} fires on window resize - // ondelete; //(self,props) => {} fires after element is deleted - // onchanged; //(props) => {} fires when props change - //renderonchanged=false; //(self,props) => {} fires after rerendering on props change + oncreate; //(self,props) => {} fires on element creation (e.g. to set up logic) + onresize; //(self,props) => {} fires on window resize + ondelete; //(self,props) => {} fires after element is deleted + onchanged; //(props) => {} fires when props change + renderonchanged=false; //(self,props) => {} fires after rerendering on props change FRAGMENT; STYLE; attachedShadow = false; - static get tag(){return this.name.toLowerCase()+'-'} //tagName, default 'classname-'. Set as a static variable for the internal addElement to reference - obsAttributes=["props","options","onchanged","onresize","ondelete","oncreate","template"] - props = {}; + get observedAttributes() { + return this.obsAttributes; + } + + get obsAttributes() { + return this.obsAttributes; + } + + set obsAttributes(att) { + if(typeof att === 'string') { + this.obsAttributes.push(att); + } else if (Array.isArray(att)) this.obsAttributes=att; + } + + static get tag(){return this.name.toLowerCase()+'-'} //tagName, default 'classname-'. Set as a static variable for the internal addElement to reference + //add self or a specified class to the window which can be used via html like //will default be the classname with a '-' at the end if no tag supplied static addElement(tag=this.tag,cls=this,extend=undefined) { @@ -237,38 +247,31 @@ export class DOMElement extends HTMLElement { render = (props=this.props) => { - const t = document.createElement('template'); - - let usingHTMLFunction = this.template.prototype?.constructor?.name == dummy.prototype.constructor.name; - if(typeof this.template === 'function') { - if(usingHTMLFunction) { //html function - this.template(t.content); - } - else this.templateResult = this.template(this, props); - } //can pass a function + if(typeof this.template === 'function') this.templateResult = this.template(this, props); //can pass a function else this.templateResult = this.template; if(this.styles) this.templateResult = `${this.templateResult}`; //this.innerHTML = this.templateResult; - if(!usingHTMLFunction) { - if(typeof this.templateResult === 'string') t.innerHTML = this.templateResult; - else if(this.templateResult instanceof HTMLElement || this.templateResult instanceof DocumentFragment) { - if(this.templateResult.parentNode) { - this.templateResult.parentNode.removeChild(this.templateResult); //swap to the new component - } - t.content.appendChild(this.templateResult); + const t = document.createElement('template'); + + if(typeof this.templateResult === 'string') t.innerHTML = this.templateResult; + else if(this.templateResult instanceof HTMLElement) { + if(this.templateResult.parentNode) { + this.templateResult.parentNode.removeChild(this.templateResult); //swap to the new component } + t.appendChild(this.templateResult); } + const fragment = t.content; if(this.FRAGMENT) { //will reappend the fragment without reappending the whole node if already rendered once if(this.useShadow) { //this.removeChild(this.shadowRoot) if(this.STYLE) this.shadowRoot.removeChild(this.STYLE); - this.FRAGMENT.forEach((c) => {this.shadowRoot.removeChild(c);}); + this.shadowRoot.removeChild(this.FRAGMENT); } - else this.FRAGMENT.forEach((c) => {this.removeChild(c)}); + else this.removeChild(this.FRAGMENT); } if(this.useShadow) { if(!this.attachedShadow) { @@ -282,15 +285,13 @@ export class DOMElement extends HTMLElement { this.STYLE = style; } - let len = fragment.childNodes.length; this.shadowRoot.prepend(fragment); //now you need to use the shadowRoot.querySelector etc. - this.FRAGMENT = Array.from(this.shadowRoot.childNodes).slice(0,len) + this.FRAGMENT = this.shadowRoot.childNodes[0]; //this.prepend(this.shadowRoot) } else { - let len = fragment.childNodes.length; this.prepend(fragment); - this.FRAGMENT = Array.from(this.childNodes).slice(0,len) + this.FRAGMENT = this.childNodes[0]; } @@ -357,6 +358,95 @@ export class DOMElement extends HTMLElement { } } + get props() { + return this.props; + } + + set props(newProps={}) { + this.setAttribute('props',newProps); + } + + get template() { + return this.template; + } + + set template(template) { + this.setAttribute('template',template); + } + + get render() { + return this.render; + } + + get delete() { + return this.delete; + } + + get state() { + return this.state; + } + + //past tense just so it can't conflict with onchange + get onchanged() { + return this.onchanged; + } + + set onchanged(onchanged) { + this.setAttribute('onchanged',onchanged); + } + + get styles() { + return this.styles + } + + set styles(templateStr) { + + this.styles = templateStr; + + if(this.querySelector('style')) { //get the top style + // if(!this.useShadow) { + // this.useShadow = true; + // this.render() + // } else + this.querySelector('style').innerHTML = templateStr; + + } else { + //this.useShadow = true; + this.render(); + } + } + + get renderonchanged() { + return this.renderonchanged; + } + + set renderonchanged(onchanged) { + this.setAttribute('renderonchanged',onchanged); + } + + get onresize() { + return this.props; + } + + set onresize(onresize) { + this.setAttribute('onresize',onresize); + } + + get ondelete() { + return this.props; + } + + set ondelete(ondelete) { + this.setAttribute('ondelete',ondelete); + } + + get oncreate() { + return this.oncreate; + } + + set oncreate(oncreate) { + this.setAttribute('oncreated',oncreate); + } } //extend the DOMElement class with an new name, this name determines the element name (always lower case in the html regardless of class name cases) diff --git a/_old/types/canvascomponent.ts b/services/dom/types/canvascomponent.ts similarity index 100% rename from _old/types/canvascomponent.ts rename to services/dom/types/canvascomponent.ts diff --git a/_old/types/component.ts b/services/dom/types/component.ts similarity index 100% rename from _old/types/component.ts rename to services/dom/types/component.ts diff --git a/_old/types/element.ts b/services/dom/types/element.ts similarity index 100% rename from _old/types/element.ts rename to services/dom/types/element.ts diff --git a/_old/types/general.ts b/services/dom/types/general.ts similarity index 100% rename from _old/types/general.ts rename to services/dom/types/general.ts diff --git a/_old/types/index.ts b/services/dom/types/index.ts similarity index 100% rename from _old/types/index.ts rename to services/dom/types/index.ts diff --git a/src/services/e2ee/E2EE.service.ts b/services/e2ee/E2EE.service.ts similarity index 94% rename from src/services/e2ee/E2EE.service.ts rename to services/e2ee/E2EE.service.ts index 460c79dd..99fabe53 100644 --- a/src/services/e2ee/E2EE.service.ts +++ b/services/e2ee/E2EE.service.ts @@ -1,7 +1,7 @@ //End to end encryption using sjcl and keygen stuff, should involve webworkers -import { GraphNode } from "../../core/Graph"; -import { Service, ServiceMessage, ServiceOptions } from "../Service"; +import { GraphNode } from "../../Graph"; +import { Service, Routes, ServiceMessage, ServiceOptions } from "../Service"; import sjcl from "./sjcl"; //stanford javascript cryptography library, super minimal! //End to end encryption service, this will redirect transmits/receives through an encoder/decoder framework @@ -33,8 +33,6 @@ export class E2EEService extends Service { } else Object.assign(this.keys,keys); } - - this.load(this); } addKey = ( @@ -170,7 +168,7 @@ export class E2EEService extends Service { return this.handleServiceMessage(message); } else if ((typeof message.node === 'string' || message.node instanceof GraphNode)) { return this.handleGraphNodeCall(message.node, message.args); - } else if(this.__node.keepState) { + } else if(this.keepState) { if(message.route) this.setState({[message.route]:message.args}); if(message.node) @@ -180,4 +178,12 @@ export class E2EEService extends Service { } // + routes:Routes={ + encryptRoute:this.encryptRoute, + decryptRoute:this.decryptRoute, + encrypt:this.encrypt, + decrypt:this.decrypt, + generateSecret:E2EEService.generateSecret, + addKey:this.addKey + } } \ No newline at end of file diff --git a/services/e2ee/sjcl.d.ts b/services/e2ee/sjcl.d.ts new file mode 100644 index 00000000..2f1d140f --- /dev/null +++ b/services/e2ee/sjcl.d.ts @@ -0,0 +1,685 @@ +// Type definitions for sjcl v1.0.8 +// Project: http://crypto.stanford.edu/sjcl/ +// Definitions by: Eugene Chernyshov , Vytautas Mizgiris +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +export = sjcl; +export as namespace sjcl; + +declare namespace sjcl { + export var arrayBuffer: SjclArrayBufferModes; + export var bn: BigNumberStatic; + export var bitArray: BitArrayStatic; + export var codec: SjclCodecs; + export var hash: SjclHashes; + export var exception: SjclExceptions; + export var cipher: SjclCiphers; + export var mode: SjclModes; + export var misc: SjclMisc; + export var ecc: SjclEllipticCurveCryptography; + export var random: SjclRandom; + export var prng: SjclRandomStatic; + export var keyexchange: SjclKeyExchange; + export var json: SjclJson; + export var encrypt: SjclConvenienceEncryptor; + export var decrypt: SjclConvenienceDecryptor; + + // ________________________________________________________________________ + + interface BigNumber { + radix: number; + maxMul: number; + + copy(): BigNumber; + + /// Initializes this with it, either as a bn, a number, or a hex string. + initWith: TypeHelpers.BigNumberBinaryOperator; + + /// Returns true if "this" and "that" are equal. Calls fullReduce(). + /// Equality test is in constant time. + equals(that: BigNumber | number): boolean; + + /// Get the i'th limb of this, zero if i is too large. + getLimb(index: number): number; + + /// Constant time comparison function. + /// Returns 1 if this >= that, or zero otherwise. + greaterEquals(that: BigNumber | number): boolean; + + /// Convert to a hex string. + toString(): string; + + /// this += that. Does not normalize. + addM: TypeHelpers.BigNumberBinaryOperator; + + /// this *= 2. Requires normalized; ends up normalized. + doubleM(): BigNumber; + + /// this /= 2, rounded down. Requires normalized; ends up normalized. + halveM(): BigNumber; + + /// this -= that. Does not normalize. + subM: TypeHelpers.BigNumberBinaryOperator; + + mod: TypeHelpers.BigNumberBinaryOperator; + + /// return inverse mod prime p. p must be odd. Binary extended Euclidean algorithm mod p. + inverseMod: TypeHelpers.BigNumberBinaryOperator; + + /// this + that. Does not normalize. + add: TypeHelpers.BigNumberBinaryOperator; + + /// this - that. Does not normalize. + sub: TypeHelpers.BigNumberBinaryOperator; + + /// this * that. Normalizes and reduces. + mul: TypeHelpers.BigNumberBinaryOperator; + + /// this ^ 2. Normalizes and reduces. + square(): BigNumber; + + /// this ^ n. Uses square-and-multiply. Normalizes and reduces. + power(n: BigNumber | number[] | number): BigNumber; + + /// this * that mod N + mulmod: TypeHelpers.BigNumberTrinaryOperator; + + /// this ^ x mod N + powermod: TypeHelpers.BigNumberTrinaryOperator; + + /// this ^ x mod N with Montomery reduction + montpowermod: TypeHelpers.BigNumberTrinaryOperator; + + trim(): BigNumber; + + /// Reduce mod a modulus. Stubbed for subclassing. + reduce(): BigNumber; + + /// Reduce and normalize. + fullReduce(): BigNumber; + + /// Propagate carries. + normalize(): BigNumber; + + /// Constant-time normalize. Does not allocate additional space. + cnormalize(): BigNumber; + + /// Serialize to a bit array + toBits(len?: number): BitArray; + + /// Return the length in bits, rounded up to the nearest byte. + bitLength(): number; + } + + interface BigNumberStatic { + new (): BigNumber; + new (n: BigNumber | number | string): BigNumber; + + fromBits(bits: BitArray): BigNumber; + random: TypeHelpers.Bind1; + prime: { + p127: PseudoMersennePrimeStatic; + // Bernstein's prime for Curve25519 + p25519: PseudoMersennePrimeStatic; + // Koblitz primes + p192k: PseudoMersennePrimeStatic; + p224k: PseudoMersennePrimeStatic; + p256k: PseudoMersennePrimeStatic; + // NIST primes + p192: PseudoMersennePrimeStatic; + p224: PseudoMersennePrimeStatic; + p256: PseudoMersennePrimeStatic; + p384: PseudoMersennePrimeStatic; + p521: PseudoMersennePrimeStatic; + }; + + pseudoMersennePrime(exponent: number, coeff: number[][]): PseudoMersennePrimeStatic; + } + + interface PseudoMersennePrime extends BigNumber { + reduce(): PseudoMersennePrime; + fullReduce(): PseudoMersennePrime; + inverse(): PseudoMersennePrime; + } + + interface PseudoMersennePrimeStatic extends BigNumberStatic { + new (): PseudoMersennePrime; + new (n: BigNumber | number | string): PseudoMersennePrime; + } + + // ________________________________________________________________________ + + interface BitArray extends Array {} + + interface BitArrayStatic { + /// Array slices in units of bits. + bitSlice(a: BitArray, bstart: number, bend: number): BitArray; + + /// Extract a number packed into a bit array. + extract(a: BitArray, bstart: number, blength: number): number; + + /// Concatenate two bit arrays. + concat(a1: BitArray, a2: BitArray): BitArray; + + /// Find the length of an array of bits. + bitLength(a: BitArray): number; + + /// Truncate an array. + clamp(a: BitArray, len: number): BitArray; + + /// Make a partial word for a bit array. + partial(len: number, x: number, _end?: number): number; + + /// Get the number of bits used by a partial word. + getPartial(x: number): number; + + /// Compare two arrays for equality in a predictable amount of time. + equal(a: BitArray, b: BitArray): boolean; + + /// Shift an array right. + _shiftRight(a: BitArray, shift: number, carry?: number, out?: BitArray): BitArray; + + /// xor a block of 4 words together. + _xor4(x: number[], y: number[]): number[]; + + /// byteswap a word array inplace. (does not handle partial words) + byteswapM(a: BitArray): BitArray; + } + + // ________________________________________________________________________ + + interface SjclCodec { + fromBits(bits: BitArray): T; + toBits(value: T): BitArray; + } + + interface SjclArrayBufferCodec extends SjclCodec { + fromBits(bits: BitArray, padding?: boolean, padding_count?: number): ArrayBuffer; + hexDumpBuffer(buffer: ArrayBuffer): void; + } + + interface SjclCodecs { + arrayBuffer: SjclArrayBufferCodec; + utf8String: SjclCodec; + hex: SjclCodec; + bytes: SjclCodec; + base32: SjclCodec; + base32hex: SjclCodec; + base64: SjclCodec; + base64url: SjclCodec; + z85: SjclCodec; + } + + // ________________________________________________________________________ + + interface SjclHash { + reset(): SjclHash; + update(data: BitArray | string): SjclHash; + finalize(): BitArray; + } + + interface SjclHashStatic { + new (hash?: SjclHash): SjclHash; + hash(data: BitArray | string): BitArray; + } + + interface SjclHashes { + sha1: SjclHashStatic; + sha256: SjclHashStatic; + sha512: SjclHashStatic; + ripemd160: SjclHashStatic; + } + + // ________________________________________________________________________ + + interface SjclExceptions { + corrupt: SjclExceptionFactory; + invalid: SjclExceptionFactory; + bug: SjclExceptionFactory; + notReady: SjclExceptionFactory; + } + + interface SjclExceptionFactory { + new (message: string): Error; + } + + // ________________________________________________________________________ + + interface SjclCiphers { + aes: SjclCipherStatic; + } + + interface SjclCipher { + encrypt(data: number[]): number[]; + decrypt(data: number[]): number[]; + } + + interface SjclCipherStatic { + new (key: number[]): SjclCipher; + } + + // ________________________________________________________________________ + + interface SjclModes { + gcm: SjclGCMMode; + ccm: SjclCCMMode; + ocb2: SjclOCB2Mode; + ocb2progressive: SjclOCB2ProgressiveMode; + cbc: SjclCBCMode; + ctr: SjclCTRMode; + } + + interface SjclArrayBufferModes { + ccm: SjclArrayBufferCCMMode; + } + + interface SjclGCMMode { + encrypt(prf: SjclCipher, plaintext: BitArray, iv: BitArray, adata?: BitArray, tlen?: number): BitArray; + decrypt(prf: SjclCipher, ciphertext: BitArray, iv: BitArray, adata?: BitArray, tlen?: number): BitArray; + } + + interface SjclArrayBufferCCMMode { + compat_encrypt(prf: SjclCipher, plaintext: BitArray, iv: BitArray, adata?: BitArray, tlen?: number): BitArray; + compat_decrypt(prf: SjclCipher, ciphertext: BitArray, iv: BitArray, adata?: BitArray, tlen?: number): BitArray; + encrypt( + prf: SjclCipher, + plaintext_buffer: ArrayBuffer, + iv: BitArray, + adata?: ArrayBuffer, + tlen?: number, + ol?: number, + ): ArrayBuffer; + decrypt( + prf: SjclCipher, + ciphertext_buffer: ArrayBuffer, + iv: BitArray, + tag: BitArray, + adata?: ArrayBuffer, + tlen?: number, + ol?: number, + ): ArrayBuffer; + } + + interface SjclCCMMode { + listenProgress(cb: (val: number) => void): void; + unListenProgress(cb: (val: number) => void): void; + encrypt(prf: SjclCipher, plaintext: BitArray, iv: BitArray, adata?: BitArray, tlen?: number): BitArray; + decrypt(prf: SjclCipher, ciphertext: BitArray, iv: BitArray, adata?: BitArray, tlen?: number): BitArray; + } + + interface SjclOCB2Mode { + encrypt( + prf: SjclCipher, + plaintext: BitArray, + iv: BitArray, + adata?: BitArray, + tlen?: number, + premac?: boolean, + ): BitArray; + decrypt( + prf: SjclCipher, + ciphertext: BitArray, + iv: BitArray, + adata?: BitArray, + tlen?: number, + premac?: boolean, + ): BitArray; + pmac(prf: SjclCipher, adata: BitArray): number[]; + } + + interface SjclOCB2ProgressiveProcessor { + process(data: BitArray): BitArray; + finalize(): BitArray; + } + + interface SjclOCB2ProgressiveMode { + createEncryptor( + prp: SjclCipher, + iv: BitArray, + adata?: BitArray, + tlen?: number, + premac?: boolean, + ): SjclOCB2ProgressiveProcessor; + createDecryptor( + prp: SjclCipher, + iv: BitArray, + adata?: BitArray, + tlen?: number, + premac?: boolean, + ): SjclOCB2ProgressiveProcessor; + } + + interface SjclCBCMode { + encrypt(prf: SjclCipher, plaintext: BitArray, iv: BitArray, adata?: BitArray): BitArray; + decrypt(prf: SjclCipher, ciphertext: BitArray, iv: BitArray, adata?: BitArray): BitArray; + } + + interface SjclCTRMode { + encrypt(prf: SjclCipher, plaintext: BitArray, iv: BitArray, adata?: BitArray): BitArray; + decrypt(prf: SjclCipher, ciphertext: BitArray, iv: BitArray, adata?: BitArray): BitArray; + } + + // ________________________________________________________________________ + + interface PBKDF2Params { + iter?: number | undefined; + salt?: BitArray | undefined; + } + + interface SjclMisc { + pbkdf2( + password: BitArray | string, + salt: BitArray | string, + count?: number, + length?: number, + Prff?: SjclPRFFamilyStatic, + ): BitArray; + hmac: SjclHMACStatic; + cachedPbkdf2( + password: string, + obj?: PBKDF2Params, + ): { + key: BitArray; + salt: BitArray; + }; + hkdf( + ikm: BitArray, + keyBitLength: number, + salt: BitArray | string, + info: BitArray | string, + Hash?: SjclHashStatic, + ): BitArray; + scrypt( + password: BitArray | string, + salt: BitArray | string, + N?: number, + r?: number, + p?: number, + length?: number, + Prff?: SjclPRFFamilyStatic, + ): BitArray; + } + + class SjclPRFFamily { + encrypt(data: BitArray | string): BitArray; + } + + interface SjclHMAC extends SjclPRFFamily { + mac(data: BitArray | string): BitArray; + reset(): void; + update(data: BitArray | string): void; + digest(): BitArray; + } + + interface SjclPRFFamilyStatic { + new (key: BitArray): SjclPRFFamily; + } + + interface SjclHMACStatic { + new (key: BitArray, Hash?: SjclHashStatic): SjclHMAC; + } + + // ________________________________________________________________________ + + interface SjclEllipticCurveCryptography { + point: SjclEllipticalPointStatic; + pointJac: SjclPointJacobianStatic; + curve: SjclEllipticalCurveStatic; + curves: { + c192: SjclEllipticalCurve; + c224: SjclEllipticalCurve; + c256: SjclEllipticalCurve; + c384: SjclEllipticalCurve; + c521: SjclEllipticalCurve; + k192: SjclEllipticalCurve; + k224: SjclEllipticalCurve; + k256: SjclEllipticalCurve; + }; + curveName(curve: SjclEllipticalCurve): string; + deserialize(key: SjclECCKeyPairData): SjclECCPublicKey; + deserialize(key: SjclECCKeyPairData): SjclECCSecretKey; + basicKey: SjclECCBasic; + elGamal: SjclElGamal; + ecdsa: SjclECDSA; + } + + interface SjclEllipticalPoint { + toJac(): SjclPointJacobian; + mult(k: BigNumber): SjclEllipticalPoint; + mult2(k: BigNumber, k2: BigNumber, affine2: SjclEllipticalPoint): SjclEllipticalPoint; + multiples(): Array; + negate(): SjclEllipticalPoint; + isValid(): boolean; + toBits(): BitArray; + } + + interface SjclEllipticalPointStatic { + new (curve: SjclEllipticalCurve, x?: BigNumber, y?: BigNumber): SjclEllipticalPoint; + } + + interface SjclPointJacobian { + add(T: SjclEllipticalPoint): SjclPointJacobian; + doubl(): SjclPointJacobian; + toAffine(): SjclEllipticalPoint; + mult(k: BigNumber, affine: SjclEllipticalPoint): SjclPointJacobian; + mult2( + k1: BigNumber, + affine: SjclEllipticalPoint, + k2: BigNumber, + affine2: SjclEllipticalPoint, + ): SjclPointJacobian; + negate(): SjclPointJacobian; + isValid(): boolean; + } + + interface SjclPointJacobianStatic { + new (curve: SjclEllipticalCurve, x?: BigNumber, y?: BigNumber, z?: BigNumber): SjclPointJacobian; + toAffineMultiple(points: Array): Array; + } + + interface SjclEllipticalCurve { + fromBits(bits: BitArray): SjclEllipticalPoint; + } + + interface SjclEllipticalCurveStatic { + new ( + Field: BigNumber, + r: BigNumber, + a: BigNumber, + b: BigNumber, + x: BigNumber, + y: BigNumber, + ): SjclEllipticalCurve; + } + + interface SjclKeyPair

    { + pub: P; + sec: S; + } + + interface SjclKeysGenerator

    { + (curve: SjclEllipticalCurve | number, paranoia: number, sec?: BigNumber): SjclKeyPair; + } + + interface SjclECCKeyPairData { + type: string; + secretKey: boolean; + point: string; + curve: string; + } + + interface SjclECCPublicKeyData { + x: BitArray; + y: BitArray; + } + + class SjclECCPublicKey { + serialize(): SjclECCKeyPairData; + get(): SjclECCPublicKeyData; + getType(): string; + } + + class SjclECCSecretKey { + serialize(): SjclECCKeyPairData; + get(): BitArray; + getType(): string; + } + + interface SjclECCPublicKeyFactory { + new (curve: SjclEllipticalCurve, point: SjclEllipticalPoint | BitArray): T; + } + + interface SjclECCSecretKeyFactory { + new (curve: SjclEllipticalCurve, exponent: BigNumber): T; + } + + interface SjclECCBasic { + publicKey: SjclECCPublicKeyFactory; + secretKey: SjclECCSecretKeyFactory; + generateKeys(cn: string): SjclKeysGenerator; + } + + class SjclElGamalPublicKey extends SjclECCPublicKey { + kem( + paranoia: number, + ): { + key: BitArray; + tag: BitArray; + }; + } + + class SjclElGamalSecretKey extends SjclECCSecretKey { + unkem(tag: BitArray): BitArray; + dh(pk: SjclECCPublicKey): BitArray; + dhJavaEc(pk: SjclECCPublicKey): BitArray; + } + + interface SjclElGamal { + publicKey: SjclECCPublicKeyFactory; + secretKey: SjclECCSecretKeyFactory; + generateKeys: SjclKeysGenerator; + } + + class SjclECDSAPublicKey extends SjclECCPublicKey { + verify(hash: BitArray, rs: BitArray, fakeLegacyVersion: boolean): boolean; + } + + class SjclECDSASecretKey extends SjclECCSecretKey { + sign(hash: BitArray, paranoia: number, fakeLegacyVersion: boolean, fixedKForTesting?: BigNumber): BitArray; + } + + interface SjclECDSA { + publicKey: SjclECCPublicKeyFactory; + secretKey: SjclECCSecretKeyFactory; + generateKeys: SjclKeysGenerator; + } + + // ________________________________________________________________________ + + interface SjclRandom { + randomWords(nwords: number, paranoia?: number): BitArray; + setDefaultParanoia(paranoia: number, allowZeroParanoia: string): void; + addEntropy(data: number | number[] | string, estimatedEntropy: number, source: string): void; + isReady(paranoia?: number): boolean; + getProgress(paranoia?: number): number; + startCollectors(): void; + stopCollectors(): void; + addEventListener(name: string, cb: Function): void; + removeEventListener(name: string, cb: Function): void; + } + + interface SjclRandomStatic { + new (defaultParanoia: number): SjclRandom; + } + + // ________________________________________________________________________ + + interface SjclKeyExchange { + srp: SjclSecureRemotePassword; + } + + interface SjclSRPGroup { + N: BigNumber; + g: BigNumber; + } + + interface SjclSecureRemotePassword { + makeVerifier(username: string, password: string, salt: BitArray, group: SjclSRPGroup): BitArray; + makeX(username: string, password: string, salt: BitArray): BitArray; + knownGroup(i: number | string): SjclSRPGroup; + } + + // ________________________________________________________________________ + + interface SjclCipherParams { + v?: number | undefined; + iter?: number | undefined; + ks?: number | undefined; + ts?: number | undefined; + mode?: string | undefined; + adata?: string | undefined; + cipher?: string | undefined; + } + + interface SjclCipherEncryptParams extends SjclCipherParams { + salt: BitArray; + iv: BitArray; + } + + interface SjclCipherDecryptParams extends SjclCipherParams { + salt?: BitArray | undefined; + iv?: BitArray | undefined; + } + + interface SjclCipherEncrypted extends SjclCipherEncryptParams { + kemtag?: BitArray | undefined; + ct: BitArray; + } + + interface SjclCipherDecrypted extends SjclCipherEncrypted { + key: BitArray; + } + + interface SjclConvenienceEncryptor { + ( + password: SjclElGamalPublicKey | BitArray | string, + plaintext: string, + params?: SjclCipherEncryptParams, + rp?: SjclCipherEncrypted, + ): SjclCipherEncrypted; + } + + interface SjclConvenienceDecryptor { + ( + password: SjclElGamalSecretKey | BitArray | string, + ciphertext: SjclCipherEncrypted | string, + params?: SjclCipherDecryptParams, + rp?: SjclCipherDecrypted, + ): string; + } + + interface SjclJson { + encrypt: SjclConvenienceEncryptor; + decrypt: SjclConvenienceDecryptor; + encode(obj: Object): string; + decode(obj: string): Object; + } + + // ________________________________________________________________________ + + namespace TypeHelpers { + interface One { + (value: T): BigNumber; + } + + interface BigNumberBinaryOperator extends One, One, One {} + + interface Two { + (x: T1, N: T2): BigNumber; + } + + interface Bind1 extends Two, Two, Two {} + + interface BigNumberTrinaryOperator extends Bind1, Bind1, Bind1 {} + } +} diff --git a/src/services/e2ee/sjcl.js b/services/e2ee/sjcl.js similarity index 99% rename from src/services/e2ee/sjcl.js rename to services/e2ee/sjcl.js index f7ee4499..c3c3ea97 100644 --- a/src/services/e2ee/sjcl.js +++ b/services/e2ee/sjcl.js @@ -57,8 +57,4 @@ b.mode&&sjcl.arrayBuffer&&sjcl.arrayBuffer.ccm&&b.ct instanceof ArrayBuffer?sjcl b+'":';d=",";switch(typeof a[b]){case "number":case "boolean":c+=a[b];break;case "string":c+='"'+escape(a[b])+'"';break;case "object":c+='"'+sjcl.codec.base64.fromBits(a[b],0)+'"';break;default:throw new sjcl.exception.bug("json encode: unsupported type");}}return c+"}"},decode:function(a){a=a.replace(/\s/g,"");if(!a.match(/^\{.*\}$/))throw new sjcl.exception.invalid("json decode: this isn't json!");a=a.replace(/^\{|\}$/g,"").split(/,/);var b={},c,d;for(c=0;cany, +export type SystemProps = (RouteProp & { + operator:(entities:{[key:string]:Entity})=>any, setupEntities:(entities:{[key:string]:Entity})=>{[key:string]:Entity}, setupEntity:(entity:Entity)=>Entity })|GraphNode @@ -24,11 +24,10 @@ export type Entity = { components:{ //which systems should call these entities? [key:string]:any //use the system key as the key, value can be a boolean or an object with values etc. use however just helps filter entities }, - [key:string]:any } & GraphNode export type System = { - __operator:(entities:{[key:string]:Entity})=>any, + operator:(entities:{[key:string]:Entity})=>any, setupEntities:(entities:{[key:string]:Entity})=>{[key:string]:Entity}, setupEntity:(entity:Entity)=>Entity, remove?:(entity:Entity,entitities:{[key:string]:Entity})=>Entity, @@ -43,19 +42,18 @@ export type ECSOptions = { systems:{ [key:string]:SystemProps }, - order?:string[], //system order of execution by key - [key:string]:any + order?:string[] //system order of execution by key } & ServiceOptions export class ECSService extends Service { entities:{ [key:string]:Entity - } = {}; + } = {} systems:{ [key:string]: System - } = {}; + } = {} entityMap = new Map(); //maps of filtered entity objects based on system tag. e.g. this.maps.get('boids')['entity3']; entityKeyMap = new Map(); //arrays of keys of entities belonging to each system, for lookup @@ -69,14 +67,14 @@ export class ECSService extends Service { constructor(options?:ECSOptions) { super(options); - this.load(this); + if(this.routes) this.load(this.routes); - if(options?.systems) + if(options.systems) for(const key in options.systems) { this.addSystem(options.systems[key], undefined, undefined, undefined, undefined, options.order); } - if(options?.entities) { + if(options.entities) { for(const key in options.entities) { this.addEntity(options.entities[key],options.entities[key].components) } @@ -96,7 +94,7 @@ export class ECSService extends Service { if(filter) { if(debug) debug = performance.now(); if(this.entityKeyMap.get(k).length > 0) - (this.systems[k] as GraphNode).__operator( + (this.systems[k] as GraphNode).run( this.entityMap.get(k) ); if(debug) @@ -104,7 +102,7 @@ export class ECSService extends Service { } else { if(debug) debug = performance.now(); if(this.entityKeyMap.get(k).length > 0) - (this.systems[k] as GraphNode).__operator( + (this.systems[k] as GraphNode).run( this.entities ); //unfiltered, it's faster to handle this in the system with lots of entities if(debug) @@ -116,9 +114,8 @@ export class ECSService extends Service { //console.log('updated',this.entities,this.systems) } - animateEntities = (filter:boolean=true,order?:string[]) => { - //console.log('animate entities') - if(!this.animating) { + animate = (filter:boolean=true,order?:string[]) => { + if(this.animating === false) { this.animating = true; if(typeof requestAnimationFrame !== 'undefined') { let anim = () => { @@ -126,7 +123,6 @@ export class ECSService extends Service { if(this.animating){ this.updateEntities(order,filter); anim(); - } }); } @@ -150,7 +146,7 @@ export class ECSService extends Service { } start = (filter?:boolean) => { - this.animateEntities(filter); + this.animate(filter); } addEntities = ( //add multiple entities from the same prototype; @@ -162,14 +158,13 @@ export class ECSService extends Service { let newEntities = {}; - while(i < count) { let entity = this.addEntity( prototype, components ); - newEntities[entity.__node.tag] = entity; + newEntities[entity.tag] = entity; i++; } @@ -182,40 +177,38 @@ export class ECSService extends Service { components:{[key:string]:any}={} ) => { if(!prototype) return; - const entity = this.recursivelyAssign({},prototype) as Entity; + const entity = this.recursivelyAssign({},prototype); entity.components = components; if(Object.keys(components).length === 0) { Object.keys(this.systems).forEach((k)=>{ //default init all systems if none provided, can let you quickly dump empty objects to setup entities components[k] = true; }) } - if(!entity.__node) entity.__node = {} as any; - if(entity.__node.tag && this.entities[entity.__node.tag]) { + if(entity.tag && this.entities[entity.tag]) { this.entityCt++; - let tag = entity.__node.tag+this.entityCt; - while(this.entities[entity.__node.tag]) { + let tag = entity.tag+this.entityCt; + while(this.entities[entity.tag]) { this.entityCt++; - entity.__node.tag = `${tag}${this.entityCt}`; + entity.tag = `${tag}${this.entityCt}`; } - } else if(!entity.__node.tag) entity.__node.tag = `entity${Math.floor(Math.random()*1000000000000000)}`; + } else if(!entity.tag) entity.tag = `entity${Math.floor(Math.random()*1000000000000000)}`; this.add(entity); - this.entities[entity.__node.tag] = this.__node.nodes.get(entity.__node.tag) as any; + this.entities[entity.tag] = this.nodes.get(entity.tag) as any; //console.log(entity,'added') - this.setupEntity(this.entities[entity.__node.tag]) + this.setupEntity(this.entities[entity.tag]) - return this.entities[entity.__node.tag]; + return this.entities[entity.tag]; } addSystems = ( systems:{[key:string]:SystemProps}={}, order?:string[] ) => { - for(const key in systems) { - systems[key].__node.tag = key; + systems[key].tag = key; this.addSystem(systems[key],undefined,undefined,undefined,undefined,order) } return this.systems; @@ -230,38 +223,38 @@ export class ECSService extends Service { order?:string[] ) => { if(!prototype) return; - const system = this.recursivelyAssign({},prototype) as System; + const system = this.recursivelyAssign({},prototype); if(setupEntities) system.setupEntities = setupEntities; if(setupEntity) system.setupEntity = setupEntity; - if(operator) system.__operator = operator; + if(operator) system.operator = operator; if(remove) system.remove = remove; - if(system.__node.tag && this.systems[system.__node.tag]) { + if(system.tag && this.systems[system.tag]) { this.systemCt++; - let tag = system.__node.tag+this.systemCt; - while(this.systems[system.__node.tag]) { + let tag = system.tag+this.systemCt; + while(this.systems[system.tag]) { this.systemCt++; - system.__node.tag = `${tag}${this.systemCt}`; + system.tag = `${tag}${this.systemCt}`; } - } else if(!system.__node.tag) system.__node.tag = `system${Math.floor(Math.random()*1000000000000000)}`; + } else if(!system.tag) system.tag = `system${Math.floor(Math.random()*1000000000000000)}`; this.add(system); - this.systems[system.__node.tag] = this.__node.nodes.get(system.__node.tag) as any; + this.systems[system.tag] = this.nodes.get(system.tag) as any; - if(!this.entityMap.get(system.__node.tag)) this.entityMap.set(system.__node.tag, {}); //map to track local entities - if(!this.entityKeyMap.get(system.__node.tag)) this.entityKeyMap.set(system.__node.tag, []); //map to track arrays of entity keys to remove redundancy - this.systems[system.__node.tag].entities = this.entityMap.get(system.__node.tag); //shared object ref - this.systems[system.__node.tag].entityKeys = this.entityKeyMap.get(system.__node.tag); //shared key ref - if(this.systems[system.__node.tag]?.setupEntities && Object.keys(this.entities).length > 1) { - let filtered = this.filterObject(this.entities,(key,v)=>{if(v.components[system.__node.tag]) return true;}); - this.systems[system.__node.tag].setupEntities(filtered); - Object.assign(this.entityMap.get(system.__node.tag),filtered); + if(!this.entityMap.get(system.tag)) this.entityMap.set(system.tag, {}); //map to track local entities + if(!this.entityKeyMap.get(system.tag)) this.entityKeyMap.set(system.tag, []); //map to track arrays of entity keys to remove redundancy + this.systems[system.tag].entities = this.entityMap.get(system.tag); //shared object ref + this.systems[system.tag].entityKeys = this.entityKeyMap.get(system.tag); //shared key ref + if(this.systems[system.tag]?.setupEntities) { + let filtered = this.filterObject(this.entities,(key,v)=>{if(v.components[system.tag]) return true;}); + this.systems[system.tag].setupEntities(filtered); + Object.assign(this.entityMap.get(system.tag),filtered); } - if(!order) this.order.push(system.__node.tag); + if(!order) this.order.push(system.tag); else this.order = order; - return this.systems[system.__node.tag]; + return this.systems[system.tag]; } setupEntity = (entity:Entity) => { @@ -269,8 +262,8 @@ export class ECSService extends Service { for(const key in entity.components) { if(this.systems[key]) { this.systems[key].setupEntity(entity); - this.entityMap.get(key)[entity.__node.tag] = entity; - this.entityKeyMap.get(key).push(entity.__node.tag); + this.entityMap.get(key)[entity.tag] = entity; + this.entityKeyMap.get(key).push(entity.tag); // entity.nodes.set(key,this.systems[key]); //this is really probably gonna slow things down when adding/subtracting so we can use the local objects in the service which are pretty straightforward // this.systems[key].nodes.set(entity.tag,entity); } @@ -282,8 +275,8 @@ export class ECSService extends Service { const entity = this.entities[tag]; for(const key in entity.components) { if (this.entityMap.get(key)) { - delete this.entityMap.get(key)[entity.__node.tag]; - this.entityKeyMap.get(key).splice(this.entityKeyMap.get(key).indexOf(entity.__node.tag),1); + delete this.entityMap.get(key)[entity.tag]; + this.entityKeyMap.get(key).splice(this.entityKeyMap.get(key).indexOf(entity.tag),1); } if(this.systems[key]?.remove) { this.systems[key].remove(entity,this.entityMap.get(key)); @@ -380,5 +373,23 @@ export class ECSService extends Service { return buffer; } + + routes:Routes = { + animateEntities:this.animate, + startEntityAnimation:this.start, + stopEntityAnimation:this.stop, + addEntity:this.addEntity, + addSystem:this.addSystem, + addSystems:this.addSystems, + removeEntity:this.removeEntity, + removeEntities:this.removeEntities, + removeSystem:this.removeSystem, + setupEntity:this.setupEntity, + addEntities:this.addEntities, + filterObject:this.filterObject, + bufferValues:this.bufferValues, + setEntity:this.setEntity, + setEntities:this.setEntities + } } diff --git a/src/services/http/HTTP.browser.ts b/services/http/HTTP.browser.ts similarity index 94% rename from src/services/http/HTTP.browser.ts rename to services/http/HTTP.browser.ts index 3c30c76d..a6191bcb 100644 --- a/src/services/http/HTTP.browser.ts +++ b/services/http/HTTP.browser.ts @@ -1,5 +1,5 @@ -import { GraphNode } from "../../core/Graph"; -import { Service, ServiceMessage, ServiceOptions } from "../Service"; +import { GraphNode } from "../../Graph"; +import { Routes, Service, ServiceMessage, ServiceOptions } from "../Service"; export type RequestOptions = { //frontend request options (not http or https) @@ -27,7 +27,7 @@ export class HTTPfrontend extends Service { constructor(options?:ServiceOptions, path?:string, fetched?: (clone: Response, args: any[], response: Response) => Promise) { super(options); - this.load(this); + this.load(this.routes); this.listen(path,fetched); } @@ -87,7 +87,7 @@ export class HTTPfrontend extends Service { type:XMLHttpRequestResponseType='', mimeType?:string|undefined ) => { - if(typeof message === 'object' && !message.byteLength && (type === 'json' || type === 'text' || !type)) { + if(typeof message === 'object' && (type === 'json' || type === 'text' || !type)) { message = JSON.stringify(message); } @@ -118,11 +118,11 @@ export class HTTPfrontend extends Service { url:string|URL ) => { let obj = message; - if(typeof obj === 'object' && !obj.byteLength) { + if(typeof obj === 'object') { message = JSON.stringify(obj); } if(obj?.method?.toLowerCase() == 'get' || message?.toLowerCase() === 'get') return this.GET(url); - return this.POST(message,url); + return this.post(message,url); } @@ -241,9 +241,17 @@ export class HTTPfrontend extends Service { } else { if(!listener) delete this.listening[path]; - else delete this.listening[listener] + else delete this.listeners[listener] } } + routes:Routes={ + request:this.request, + GET:this.GET, + POST:this.POST, + transponder:this.transponder, + listen:this.listen, + stopListening:this.stopListening + } } \ No newline at end of file diff --git a/services/http/HTTP.node.ts b/services/http/HTTP.node.ts new file mode 100644 index 00000000..63592b04 --- /dev/null +++ b/services/http/HTTP.node.ts @@ -0,0 +1,998 @@ +import { RouteProp, Routes, Service, ServiceMessage, ServiceOptions } from "../Service"; +import * as http from 'http' +import * as https from 'https' +import * as fs from 'fs' +import * as path from 'path' +import { GraphNode } from "../../Graph"; + + +export type ServerProps = { + host:string, + port:number, + certpath?:string, + keypath?:string, + passphrase?:string, + startpage?: string, + errpage?:string, + pages?:{ + [key:'all'|string]:string|{ //objects get loaded as nodes which you can modify props on + template?:string, + onrequest?:GraphNode|string|((self:HTTPbackend, node:GraphNode, request:http.IncomingMessage, response:http.ServerResponse)=>void), //run a function or node? the template, request and response are passed as arguments, you can write custom node logic within this function to customize inputs etc. + redirect?:string, // can redirect the url to call a different route instead, e.g. '/':{redirect:'home'} sets the route passed to the receiver as 'home' + inject?:{[key:string]:{}|null}|string[]|string| ((...args:any)=>any) //append html + } & RouteProp + }, + protocol?:'http'|'https', + type?:'httpserver'|string, + keepState?:boolean, //setState whenever a route is run? State will be available at the address (same key of the object storing it here) + onopen?:(served:ServerInfo)=>void, //onopen callback + onclose?:(served:ServerInfo)=>void, //server close callback + _id?:string, + [key:string]:any +} + +export type ServerInfo = { + server:https.Server|http.Server, + address:string, + terminate:()=>void, + graph:HTTPbackend, + _id:string +} & ServerProps + +export type ReqOptions = { + protocol:'http'|'https'|string + host:string, + port:number, + method:string, + path?:string, + headers?:{ + [key:string]:any, + 'Content-Type'?:string, //e.g... + 'Content-Length'?:number + } +} + +//http/s server +export class HTTPbackend extends Service { + + name='http'; + + server:any + + debug:boolean=false + + servers:{ + [key:string]:ServerInfo + }={} + + mimeTypes:{[key:string]:string} = { + '.html': 'text/html', '.htm': 'text/html', '.js': 'text/javascript', '.css': 'text/css', '.json': 'application/json', '.txt':'text/plain', + '.png': 'image/png', '.jpg': 'image/jpg', '.jpeg': 'image/jpg','.gif': 'image/gif', '.svg': 'image/svg+xml', '.xhtml':'application/xhtml+xml', '.bmp':'image/bmp', + '.wav': 'audio/wav', '.mp3':'audio/mpeg', '.mp4': 'video/mp4', '.xml':'application/xml', '.webm':'video/webm', '.webp':'image/webp', '.weba':'audio/webm', + '.woff': 'font/woff', 'woff2':'font/woff2', '.ttf': 'application/font-ttf', '.eot': 'application/vnd.ms-fontobject', '.otf': 'application/font-otf', + '.wasm': 'application/wasm', '.zip':'application/zip','.xlsx':'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', '.tif':'image/tiff', + '.sh':'application/x-sh', '.csh':'application/x-csh', '.rar':'application/vnd.rar','.ppt':'application/vnd.ms-powerpoint', '.pptx':'application/vnd.openxmlformats-officedocument.presentationml.presentation', + '.odt':'application/vnd.oasis.opendocument.text','.ods':'application/vnd.oasis.opendocument.spreadsheet','.odp':'application/vnd.oasis.opendocument.presentation', + '.mpeg':'video/mpeg','.mjs':'text/javascript','.cjs':'text/javascript','.jsonld':'application/ld+json', '.jar':'application/java-archive', '.ico':'image/vnd.microsoft.icon', + '.gz':'application/gzip', 'epub':'application/epub+zip', '.doc':'application/msword', '.docx':'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + '.csv':'text/csv', '.avi':'video/x-msvideo', '.aac':'audio/aac', '.mpkg':'application/vnd.apple.installer+xml','.oga':'audio/ogg','.ogv':'video/ogg','ogx':'application/ogg', + '.php':'application/x-httpd-php', '.rtf':'application/rtf', '.swf':'application/x-shockwave-flash', '.7z':'application/x-7z-compressed', '.3gp':'video/3gpp' + }; + + constructor( + options?:ServiceOptions, + settings?:{ host?:string, port?:number, protocol?:'http'|'https', certpath?:string, keypath?:string } + ) { + super(options); + this.load(this.routes); + + //console.log(settings); + if(settings) { + if(settings.protocol === 'https') { + this.setupHTTPSserver( settings as any ) + } else this.setupHTTPserver( settings as any); + } + + } + + //on server started + onStarted = (protocol:'http'|'https'|string,host:string,port:number) => { + console.log(`🐱 Node server running at + ${protocol}://${host}:${port}/` + ); + } + + setupServer = ( + options:ServerProps={ + protocol:'http', + host:'localhost', + port:8080, + startpage:'index.html' + }, + requestListener?:http.RequestListener, + onStarted?:()=>void + )=>{ + console.log(options); + if(options.pages) { + for(const key in options.pages) { + if (typeof options.pages[key] === 'string') { + this.addPage(`${options.port}/${key}`,options.pages[key] as string) + } else if (typeof options.pages[key] === 'object') { + if((options.pages[key] as any).template) { + (options.pages[key] as any).get = (options.pages[key] as any).template; + } + if(key !== '_all') this.load({[`${options.port}/${key}`]:options.pages[key]}); + } + } + } + + if(options.protocol === 'https') { + return this.setupHTTPSserver(options as any,requestListener, onStarted); + } + else + return this.setupHTTPserver(options, requestListener, onStarted); + } + + //insecure server + setupHTTPserver = ( + options:ServerProps={ + host:'localhost' as string, + port:8080 as number, + startpage:'index.html', + errpage:undefined + }, + requestListener?:http.RequestListener, + onStarted:()=>void = ()=>{this.onStarted('http',options.host,options.port)} + ) => { + + const host = options.host; + const port = options.port; + options.protocol = 'http'; + + if(!host || !port) return; + + const address = `${host}:${port}`; + + if(this.servers[address]) this.terminate(this.servers[address]); + + if(!('keepState' in options)) options.keepState = true; //default true + + const served = { + server:undefined as any, + type:'httpserver', + address, + ...options + } as ServerInfo + + if(!requestListener) requestListener = (request:http.IncomingMessage,response:http.ServerResponse) => { + + let received:any = { + args:{request, response}, + method:request.method, + served + } + + let url = (request as any).url.slice(1); + if(!url) url = '/'; + if(options.pages) { + if(typeof options.pages[url] === 'object') { + if((options.pages[url] as any).onrequest) { + if(typeof (options.pages[url] as any).onrequest === 'string') { + (options.pages[url] as any).onrequest = this.nodes.get((options.pages[url] as any).onrequest); + } + if(typeof (options.pages[url] as any).onrequest === 'object') { + if((options.pages[url] as any).onrequest.run) { + ((options.pages[url] as any).onrequest as GraphNode).run(options.pages[url], request, response); + } + } else if(typeof (options.pages[url] as any).onrequest === 'function') { + (options.pages[url] as any).onrequest(this,options.pages[url], request, response); + } + } + if((options.pages[url] as any).redirect) { + url = (options.pages[url] as any).redirect; + received.redirect = url; + } + } + } + received.route = url; + this.receive(received); + } //default requestListener + + //var http = require('http'); + const server = http.createServer( + requestListener + ); + + served.server = server; + served.terminate = () => { + this.terminate(served); + } + served.service = this; + + // server.on('upgrade', (request, socket, head) => { + // this.onUpgrade(request, socket, head); + // }); + + this.servers[address] = served; + served._id = options._id ? options._id : address; + + //SITE AVAILABLE ON PORT: + return new Promise((resolve,reject) => { + server.on('error',(err)=>{ + console.error('Server error:', err.toString()); + reject(err); + }); + server.listen( + port,host, + ()=>{ + onStarted(); + if(served.onopen) served.onopen(served); + resolve(served); + } + ); + }) as Promise ; + } + + //secure server + setupHTTPSserver = ( + options:ServerProps = { + host:'localhost' as string, + port:8080 as number, + startpage:'index.html', + certpath:'cert.pem' as string, + keypath:'key.pem' as string, + passphrase:'encryption' as string, + errpage:undefined as undefined|string + }, + requestListener?:http.RequestListener, + onStarted:()=>void = ()=>{this.onStarted('https',options.host,options.port)} + ) => { + + const host = options.host; + const port = options.port; + options.protocol = 'https'; + + if(!host || !port || !options.certpath || !options.keypath) return; + + if(this.servers[`${host}:${port}`]) this.terminate(this.servers[`${host}:${port}`]) + + var opts = { + key: fs.readFileSync(options.keypath), + cert: fs.readFileSync(options.certpath), + passphrase:options.passphrase + }; + + if(!('keepState' in options)) options.keepState = true; //default true + + const address = `${host}:${port}`; + + const served = { + server:undefined as any, + type:'httpserver', + address, + ...options + } as ServerInfo; + + //default requestListener + if(!requestListener) requestListener = (request:http.IncomingMessage,response:http.ServerResponse) => { + + let received:any = { + args:{request, response}, + method:request.method, + served + } + + let url = (request as any).url.slice(1); + if(!url) url = '/'; + if(options.pages) { + if(typeof options.pages[url] === 'object') { + if((options.pages[url] as any).redirect) { + url = (options.pages[url] as any).redirect; + received.redirect = url; + } + if((options.pages[url] as any).onrequest) { + if(typeof (options.pages[url] as any).onrequest === 'string') { + (options.pages[url] as any).onrequest = this.nodes.get((options.pages[url] as any).onrequest); + } + if(typeof (options.pages[url] as any).onrequest === 'object') { + if((options.pages[url] as any).onrequest.run) { + ((options.pages[url] as any).onrequest as GraphNode).run(options.pages[url], request, response); + } + } else if(typeof (options.pages[url] as any).onrequest === 'function') { + (options.pages[url] as any).onrequest(this,options.pages[url], request, response); + } + } + } + } + received.route = url; + this.receive(received); + } //default requestListener + + + //var http = require('http'); + const server = https.createServer( + opts, + requestListener + ); + + served.server = server; + served.terminate = () => { + this.terminate(served); + } + served.service = this; + + // server.on('upgrade', (request, socket, head) => { + // this.onUpgrade(request, socket, head); + // }); + + this.servers[address] = served; + served._id = options._id ? options._id : address; + + //SITE AVAILABLE ON PORT: + return new Promise((resolve,reject) => { + server.on('error',(err)=>{ + console.error('Server error:', err.toString()); + reject(err); + }) + server.listen( + port,host, + ()=>{ + onStarted(); + if(served.onopen) served.onopen(served); + resolve(served); + } + ); + }) as Promise; + } + + transmit = ( //generalized http request. The default will try to post back to the first server in the list + message:any | ServiceMessage, + options:string|{ + protocol:'http'|'https'|string + host:string, + port:number, + method:string, + path?:string, + headers?:{ + [key:string]:any, + 'Content-Type'?:string, + 'Content-Length'?:number + } + }, + ondata?:(chunk:any)=>void, + onend?:()=>void + + ) => { + let input = message; + if(typeof input === 'object') input = JSON.stringify(input); + + if(typeof options === 'string' && message) return this.post(options,message); + else if(typeof options === 'string') return this.get(options); + + if(!options) { //fill a generic post request for the first server if none provided + let server = this.servers[Object.keys(this.servers)[0]]; + options = { + protocol:server.protocol as any, + host:server.host, + port:server.port, + method:'POST', + path:message.route, + headers:{ + 'Content-Type':'application/json', + 'Content-Length':input.length + } + }; + } //get first server and use its settings for a generic post request + else if (!options.headers) { + options.headers = { + 'Content-Type':'application/json', + 'Content-Length':input.length + } + } + + return this.request(options,input,ondata,onend); + } + + withResult = ( + response:http.ServerResponse, + result:any, + message:{ + route:string, + args:{request:http.IncomingMessage,response:http.ServerResponse}, //data will be an object containing request, response + method?:string, + served?:ServerInfo //server deets + } + ) => { + if(result && !response.writableEnded && !response.destroyed) { + + let mimeType = 'text/plain'; + + if(typeof result === 'string') { + let extname = path.extname(result); + + if(extname && fs.existsSync(path.join(process.cwd(),result))) { //load file paths if returned + mimeType = this.mimeTypes[extname] || 'application/octet-stream'; + + result = fs.readFileSync(path.join(process.cwd(),result)); + + if(mimeType === 'text/html' && (message.served?.pages?._all || message.served?.pages?.[message.route])) { + result = this.injectPageCode(result.toString(),message.route,message.served as any) as any; + } + } + if(typeof result === 'string' && result.includes('<') && result.includes('>') && (result.indexOf('<') < result.indexOf('>'))) //probably an html template + { + if(message?.served?.pages?._all || message?.served?.pages?.[message.route]) { + result = this.injectPageCode(result,message.route,message.served) as any; + } + response.writeHead(200,{'Content-Type':'text/html'}); + response.end(result,'utf-8'); + return; + } + } else if(typeof result === 'object') { + result = JSON.stringify(result); + mimeType = 'application/json' + } + + response.writeHead(200,{'Content-Type':mimeType}); + response.end(result,'utf-8'); + } + } + + injectPageCode = ( + templateString:string, + url:string, + served:ServerInfo + ) => { + + if ((served?.pages?.[url] as any)?.inject) { //inject per url + if(typeof (served as any).pages[url].inject === 'object') + templateString = this.buildPage((served as any).pages[url].inject as any, templateString); + else if (typeof (served as any).pages[url].inject === 'function') + templateString += ((served as any).pages[url].inject as any)(); + else if (typeof (served as any).pages[url].inject === 'string' || typeof (served as any).pages[url].inject === 'number') + templateString += (served as any).pages[url].inject; + } + if((served?.pages?._all as any)?.inject) { //any per server + if(typeof (served.pages as any)._all.inject === 'object') + templateString = this.buildPage((served as any).pages._all.inject, templateString); + else if (typeof (served as any).pages._all.inject === 'function') + templateString += (served as any).pages._all.inject(); + else if (typeof (served as any).pages._all.inject === 'string' || typeof (served as any).pages._all.inject === 'number') + templateString += (served as any).pages._all.inject; + } + return templateString; + } + + receive = ( //our fancy request response handler + message:{ + route:string, + args:{request:http.IncomingMessage,response:http.ServerResponse}, //data will be an object containing request, response + method?:string, + node?:string, // alt for route + served?:ServerInfo, //server deets + redirect?:string //if we redirected the route according to page options + } + ) => { + const request = message.args.request; + const response = message.args.response; + const method = message.method; + const served = message.served; + + if(this.debug) console.log(request.method, request.url); + //console.log(request); //debug + + let result = new Promise((resolve,reject) => { + + response.on('error', (err) => { + if(!response.writableEnded || !response.destroyed ) { + response.statusCode = 400; + response.end(undefined,undefined as any,()=>{ + reject(err); + }); + } + }); + + let getFailed = () => { + if(response.writableEnded || response.destroyed) reject(requestURL); + if(requestURL == './' || requestURL == served?.startpage) { + let template = `

    Brains@Play Server

    `; //start page dummy + if(served?.pages?._all || served?.pages?.error) { + template = this.injectPageCode(template,message.route,served) as any; + } + response.writeHead(200, { 'Content-Type': 'text/html' }); + response.end(template,'utf-8',() => { + resolve(template); + }); //write some boilerplate server page, we should make this an interactive debug page + if(served?.keepState) this.setState({[served.address]:template}); + //return; + } + else if(this.debug) console.log(`File ${requestURL} does not exist on path!`); + response.writeHead(500); //set response headers + response.end(undefined,undefined as any,()=>{ + reject(requestURL); + }); + + //return; + } + + if(method === 'GET' || method === 'get') { + //process the request, in this case simply reading a file based on the request url + var requestURL = '.' + request.url; + + if (requestURL == './' && served?.startpage) { //root should point to start page + requestURL = served.startpage; //point to the start page + } + + if((request.url !== '/' || served?.startpage) && fs.existsSync(path.join(process.cwd(),requestURL))) { + + if(response.writableEnded || response.destroyed) reject(requestURL); + //read the file on the server + fs.readFile(path.join(process.cwd(),requestURL), (error, content) => { + if (error) { + if(error.code == 'ENOENT') { //page not found: 404 + if(served?.errpage) { + fs.readFile(served.errpage, (er, content) => { + response.writeHead(404, { 'Content-Type': 'text/html' }); //set response headers + + + //add hot reload if specified + // if(process.env.HOTRELOAD && requestURL.endsWith('.html') && cfg.hotreload) { + // content = addHotReloadClient(content,`${cfg.socket_protocol}://${cfg.host}:${cfg.port}/hotreload`); + // } + + if(served.pages?._all || served.pages?.error) { + content = this.injectPageCode(content.toString(),message.route,served) as any; + } + + response.end(content, 'utf-8'); //set response content + reject(content); + //console.log(content); //debug + }); + } + else { + response.writeHead(404, { 'Content-Type': 'text/html' }); + let content = `

    Error: ${error.code}

    ` + if(served?.pages?._all || served?.pages?.[message.route]) { + content = this.injectPageCode(content.toString(),message.route,served as any) as any; + } + response.end(content,'utf-8', () => { + reject(error.code); + }); + //return; + } + } + else { //other error + response.writeHead(500); //set response headers + response.end('Something went wrong: '+error.code+' ..\n','utf-8', () => { + reject(error.code); + }); //set response content + //return; + } + } + else { //file read successfully, serve the content back + + //set content type based on file path extension for the browser to read it properly + var extname = String(path.extname(requestURL)).toLowerCase(); + + var contentType = this.mimeTypes[extname] || 'application/octet-stream'; + + if(contentType === 'text/html' && (served?.pages?._all || served?.pages?.[message.route])) { + content = this.injectPageCode(content.toString(),message.route,served as any) as any; + } + + response.writeHead(200, { 'Content-Type': contentType }); //set response headers + response.end(content, 'utf-8', () => { + //console.log(response,content,contentType); + resolve(content); + }); //set response content + + //console.log(content); //debug + //return; + } + }); + } else if (message.route) { + let route; + if(served) { + let rt = `${served.port}/${message.route}`; + if(this.nodes.get(rt)) route = rt + } + if(!route && this.nodes.get(message.route)) route = message.route; + + if(route) { + let res:any; + if(message.method) { + res = this.handleMethod(route, message.method, undefined); //these methods are being passed request/response in the data here, post methods will parse the command objects instead while this can be used to get html templates or play with req/res custom callbakcs + } + else if (message.node) { + res = this.handleGraphNodeCall(message.node, undefined); + } + else res = this.handleServiceMessage({route,args:undefined,method:message.method}); + + if(res instanceof Promise) res.then((r) => { + if(served?.keepState) this.setState({[served.address]:res}); + this.withResult(response,r,message); + resolve(res); + + //return; + }) + else if(res) { + if(served?.keepState) this.setState({[served.address]:res}); + this.withResult(response,res,message); + resolve(res); + // return; + } //else we can move on to check the get post + } + else if (message.redirect) { + response.writeHead(301, {'Location':message.redirect}); + response.end(); + resolve(true); + } + else getFailed(); + } else getFailed(); + } else { + //get post/put/etc body if any + let body:any = []; + request.on('data',(chunk)=>{ //https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/ + body.push(chunk); + }).on('end',() => { + body = Buffer.concat(body).toString(); //now it's a string + + if(typeof body === 'string') { + let substr = body.substring(0,8); + if(substr.includes('{') || substr.includes('[')) { + if(substr.includes('\\')) body = body.replace(/\\/g,""); + if(body[0] === '"') { body = body.substring(1,body.length-1)}; + body = JSON.parse(body); //parse stringified args, this is safer in a step + } + } + + let route,method,args; + if(body?.route){ //if arguments were posted + route = this.routes[body.route]; + method = body.method; + args = body.args; + if(!route) { + if(typeof body.route === 'string') if(body.route.includes('/') && body.route.length > 1) body.route = body.route.split('/').pop(); + route = this.routes[body.route]; + } + } + if(!route) { //body post did not provide argument so use the request route + if (message?.route) { + let route = this.routes[message.route]; + method = message.method; + args = message.args; + if(!route) { + if(typeof message.route === 'string') if(message.route.includes('/') && message.route.length > 1) message.route = message.route.split('/').pop() as string; + route = this.routes[message.route]; + } + } + } + let res:any = body; + if(route) { + if(body.method) { + res = this.handleMethod(route, method, args); + } + else if (body.node) { + res = this.handleGraphNodeCall(body.node, body.args); + } + else res = this.handleServiceMessage({route, args:args, method:method}); + + if(res instanceof Promise) { + res.then((r) => { + this.withResult(response,r,message); + if(served?.keepState) this.setState({[served.address]:res}); + resolve(res); + }); + } else { + this.withResult(response,res,message); + if(served?.keepState) this.setState({[served.address]:res}); + resolve(res); + } + } + else if(!response.writableEnded || !response.destroyed) { + response.statusCode = 200; + response.end(undefined,undefined as any, () => { + resolve(res); + }); //posts etc. shouldn't return anything but a 200 usually + } else resolve(res); //get requests resolve first and return otherwise this will resolve + }); + + } + + + }).catch((er)=>{ console.error("Request Error:", er); }); + + return result; + } + + request = ( + options:ReqOptions|any, + send?:any, + ondata?:(chunk:any)=>void, + onend?:()=>void + ) => { + + let client = http; + + if ((options.protocol as string)?.includes('https')) { + client = https as any; + } + + delete options.protocol; + + const req = client.request(options,(res)=>{ + if(ondata) res.on('data',ondata) + if(onend) res.on('end',onend); + }); + + if(options.headers) { + for(const head in options.headers) { + req.setHeader(head,options.headers[head]) + } + } + + if(send) req.write(send); + req.end(); + + return req; + } + + post = ( + url:string|URL, + data:any, + headers?:{ + 'Content-Type'?:string, + 'Content-Length'?:number, + [key:string]:any + } + ) => { + + let urlstring = url; + if(urlstring instanceof URL) urlstring = url.toString(); + let protocol = urlstring.startsWith('https') ? 'https' : 'http'; + let host, port,path; + let split = urlstring.split('/'); + split.forEach((s) => { + if(s.includes(':')) { + let ss = s.split(':'); + host = ss[0]; port = ss[1]; + } + }); + + if(split.length > 3) { + path = split.slice(3).join('/'); + } + + let req = this.request( + { + protocol, + host, + port, + path, + method:'POST', + headers + }, + data + ); + + return req; + } + + get = (url:string|URL|http.RequestOptions) => { + return new Promise((resolve, reject) => { + + let client = http; + + let urlstring = url; + if(url instanceof URL) urlstring = url.toString(); + + if ((urlstring as string).includes('https')) { + client = https as any; + } + + client.get(url, (resp) => { + let chunks:any[] = []; + + // A chunk of data has been recieved. + resp.on('data', (chunk) => { + chunks.push(chunk); + }); + + // The whole response has been received. Print out the result. + resp.on('end', () => { + resolve(Buffer.concat(chunks)); + }); + + }).on("error", (err) => { + reject(err); + }); + }); + } + + terminate = (served:string|ServerInfo) => { + if(typeof served === 'string') served = this.servers[served]; + + if(typeof served === 'object') { + served.server.close(); + if(served.onclose) served.onclose(served); + } + } + + getRequestBody(req:http.IncomingMessage) { + let chunks:any[] = []; + return new Promise((resolve,reject) => { + req.on('data',(chunk) => { + chunks.push(chunk); + }).on('end',() => { + resolve(Buffer.concat(chunks)); + }).on('error',(er)=>{ + reject(er); + }) + }); + } + + //??? just need a way to pass a fake request/response in + // spoofRequest = (url:string, body:any, type:string='json', server:http.Server|https.Server) => { + // return this.receive({ + // route:url, + // args:{request:{ + // url, + // } as http.IncomingMessage, response:{} as http.ServerResponse}, + // method:'GET' + // }) + // } + + addPage = (path:string, template:string) => { //add an html page template as a get + if(typeof template === 'string') { + if(!template.includes(''; //add a root + } + if(typeof this.routes[path] === 'object') { + (this.routes[path] as any).get = template; + this.nodes.get(path).get = template; + } + else this.load({ + [path]: { + get:template + } + }); + } + + addHTML = (path:string, template:string) => { //add an html component template e.g. route: component/button then set up logic to chain + if(typeof template === 'string') { + if(!template.includes('<') || (!template.includes('>'))) template = '
    '+template+'
    '; + } + if(typeof this.routes[path] === 'object') { + (this.routes[path] as any).get = template; + this.nodes.get(path).get = template; + } + else this.load({ + [path]: { + get:template + } + }); + } + + buildPage = (pageStructure:{[key:string]:{}|null|any} | string[] | string | ((...args:any)=>any), baseTemplate:string) => { //construct a page from available components, child component templates will be inserted before the last '<' symbol or at end of the previous string depending + let result = ``; if(baseTemplate) result += baseTemplate; + + let appendTemplate = (obj:{[key:string]:{}|null|any}|string[],r:string|any, res:string) => { + //console.log(obj,r,res) + if(typeof obj[r] === 'object') { + for(const key in obj) { + appendTemplate(obj,key,res); //recursive append + } + } else if((this.routes[r] as RouteProp)?.get) { + let toAdd = (this.routes[r] as RouteProp).get; + if(typeof toAdd === 'function') toAdd = toAdd(obj[r]); + if(typeof toAdd === 'string') { + let lastDiv = res.lastIndexOf('<'); + if(lastDiv > 0) { + let end = res.substring(lastDiv) + res = res.substring(0,lastDiv) + toAdd + end; + } res += toAdd; + } + + } else if (typeof this.routes[r] === 'function') { + let routeresult = (this.routes[r] as Function)(obj[r]); //template function, pass props + if(typeof routeresult === 'string') { + let lastDiv = res.lastIndexOf('<'); + if(lastDiv > 0) { + let end = res.substring(lastDiv) + res = res.substring(0,lastDiv) + routeresult + end; + } + else res += routeresult; + //console.log(lastDiv, res, routeresult) + } + //console.log(routeresult) + } else if (typeof this.routes[r] === 'string') res += this.routes[r]; + return res; + } + + if(Array.isArray(pageStructure)) { + pageStructure.forEach((r)=>{ + result = appendTemplate(pageStructure,r,result); + }) + } else if (typeof pageStructure === 'object') { + for(const r in pageStructure) { + result = appendTemplate(pageStructure,r,result); + } + } else if (typeof pageStructure === 'string') result += pageStructure; + else if (typeof pageStructure === 'function') result += pageStructure(); + //console.log(result,pageStructure,this.routes) + return result; + } + + routes:Routes={ + setupServer:{ + operator:this.setupServer, + aliases:['open'] + }, + terminate:(path:string|number)=>{ + if(path) for(const address in this.servers) { + if(address.includes(`${path}`)) { + this.terminate(this.servers[address]); + delete this.servers[address]; + } + } + }, + GET:this.get, //generic get from url + POST:this.post, //generic post to url + addPage:this.addPage, + addHTML:this.addHTML, + buildPage:this.buildPage, + getRequestBody:this.getRequestBody, + + // provides injectable browser websocket-based hot reload template, + // you still need to enable a websocket server separately + hotreload:(socketURL:string|URL=`http://localhost:8080/wss`) => { + + if(socketURL instanceof URL) socketURL = socketURL.toString(); + + const HotReloadClient = (url=`http://localhost:8080/wss`) => { + //hot reload code injected from backend + //const socketUrl = `ws://${cfg.host}:${cfg.hotreload}`; + let socket = new WebSocket(url); + socket.addEventListener('close',()=>{ + // Then the server has been turned off, + // either due to file-change-triggered reboot, + // or to truly being turned off. + + // Attempt to re-establish a connection until it works, + // failing after a few seconds (at that point things are likely + // turned off/permanantly broken instead of rebooting) + const interAttemptTimeoutMilliseconds = 100; + const maxDisconnectedTimeMilliseconds = 3000; + const maxAttempts = Math.round(maxDisconnectedTimeMilliseconds/interAttemptTimeoutMilliseconds); + let attempts = 0; + const reloadIfCanConnect = ()=>{ + attempts ++ ; + if(attempts > maxAttempts){ + console.error("Could not reconnect to dev server."); + return; + } + socket = new WebSocket(url); + socket.onerror = (er) => { + console.error(`Hot reload port disconnected, will reload on reconnected. Attempt ${attempts} of ${maxAttempts}`); + } + socket.addEventListener('error',()=>{ + setTimeout(reloadIfCanConnect,interAttemptTimeoutMilliseconds); + }); + socket.addEventListener('open',()=>{ + location.reload(); + }); + }; + reloadIfCanConnect(); + }); + } + + return ` + + ` + }, + pwa:(serviceWorkerPath:string|URL, manifestPath?:string|URL) => {} //pwa template injector + } + +} \ No newline at end of file diff --git a/services/http/boilerplate/index.ts b/services/http/boilerplate/index.ts new file mode 100644 index 00000000..14dc6f16 --- /dev/null +++ b/services/http/boilerplate/index.ts @@ -0,0 +1,28 @@ + +export function htmlBodyBoilerPlate(html:string|string[]) { + let template = `` + if(Array.isArray(html)) { + html.forEach((src) => { + template += src; + }) + } else { + template += html; + } + template += `` + return template; +} + +export function scriptBoilerPlate(scripts:string|string[]) { + let template = `` + if(Array.isArray(scripts)) { + scripts.forEach((src) => { + template += ``; + }) + } else { + template += ``; + } + template += `` + return template; +} + + diff --git a/src/services/router/Router.ts b/services/router/Router.ts similarity index 65% rename from src/services/router/Router.ts rename to services/router/Router.ts index 5f112e49..5a4ff486 100644 --- a/src/services/router/Router.ts +++ b/services/router/Router.ts @@ -1,5 +1,5 @@ -import { Graph, GraphNode } from "../../core/Graph" -import { Service, ServiceMessage, ServiceOptions } from "../Service" +import { Graph, GraphNode } from "../../Graph" +import { Routes, Service, ServiceMessage, ServiceOptions } from "../Service" /* Goals of router: @@ -18,38 +18,17 @@ Frontend 1 Frontend 2 */ -//TODO: -//Make this simpler or maybe rethink some of the base organization in the Service to accomodate more of this level of functionality. - - export type User = { //users have macros to call grouped connections generically, based on what's available _id:string, - - //work with available connections, you can set the preferred order (e.g. sse, websockets, http) send:(...args:any[])=>any, request:(...args:any[])=>Promise|Promise[]|undefined, post:(...args:any[])=>void, run:(...args:any[])=>Promise|Promise[]|undefined, subscribe:(...args:any[])=>Promise|Promise[]|undefined, unsubscribe:(...args:any[])=>Promise|Promise[]|undefined, - - //can work with all of the connections associated with a user if you use the Router's connection management system - sendAll?:(...args:any[])=>any, - requestAll?:(...args:any[])=>Promise|undefined, - postAll?:(...args:any[])=>void, - runAll?:(...args:any[])=>Promise|undefined, - subscribeAll?:(...args:any[])=>Promise|undefined, - unsubscribeAll?:(...args:any[])=>Promise|undefined, - terminate:(...args:any[]) => boolean, - - //specific to a service connection if we wrap a sub-service connection instead of going thru Router - onmessage?:(...args:any[])=>void, - onerror?:(...args:any[])=>void, - //You can set a new onclose function specific to router scope - onclose?:((user:User)=>void)|((...args:any[])=>void), - - [key:string]:any //w/e else, it's just a data structure for general use with some methods + onclose?:(user:User)=>void, + [key:string]:any } @@ -72,16 +51,16 @@ export type ConnectionInfo = { request?:(message:any, method?:any,...a:any[])=>Promise|Promise[], post?:(route:any, args?:any, method?:string, ...a:any[])=>void, run?:(route:any, args?:any, method?:string, ...a:any[])=>Promise|Promise[], - subscribe?:(route:any, callback?:((res:any)=>void)|string, ...a:any[])=>Promise|undefined, + subscribe?:(route:any, callback?:((res:any)=>void)|string, ...a:any[])=>Promise|Promise[]|undefined, unsubscribe?:(route:any, sub:number, ...arrayBuffer:any[])=>Promise|Promise[], terminate:(...a:any[]) => boolean, onclose?:(connection:ConnectionInfo,...args:any[])=>void } -export type RouterOptions = { - graph?:{ - [key:string]:Service|Graph|any|{ - service:Service|Graph|any, +export type RouterOptions = ServiceOptions & { + services?:{ + [key:string]:Service|any|{ + service:Service|any, connections:string[]|{[key:string]:any}, config?:{ //configure connections per service [key:string]:{ //configure multiple connection instances using the generic 'open' function @@ -94,17 +73,16 @@ export type RouterOptions = { }, //configure new connections after adding the relevant services? } //can be a service constructor } - timeout?:number, //timeout for user connections - order?:string[], - [key:string]:any -} & ServiceOptions + syncServices?:boolean, + order?:string[] +} export class Router extends Service { name = 'router' //we need to store connection settings and available endpoints - connections:{ //this is a flattened reference with ALL active connections from each respective service + connections:{ [key:string]:ConnectionInfo //the services/graphs/nodes and connections by which to send on, these will be the corresponding info objects and the create/terminate functions for the appropriate services }={} @@ -124,35 +102,57 @@ export class Router extends Service { users:{[key:string]:User} = {}; //jsonifiable information - userTimeout = 10000; - order:string[]; //execute connections in preferred order constructor(options?:RouterOptions){ super(options); - this.load(this); + this.load(this.routes); if(options) { if(options.order) this.order = options.order; - if(options.timeout) this.userTimeout = options.timeout; - - if(options.graph) { - for(const key in options.graph) { - let opt = (options.graph[key] as any); - if (typeof opt === 'function') opt = new opt() as Service; //instantiate a class prototype - if(opt?.__node?.nodes) { - opt.name = key; opt.__node.tag = key; - this.addServices({[opt.name]:opt}); - this.routeService(opt, (opt as any).connections); - } else { - if(typeof opt?.service === 'function') opt.service = new opt.service(); - if(opt?.service?.__node?.nodes) { - opt.service.name = key; opt.service.__node.tag = key; - this.addServices({[opt.service.name]:opt.service}); - this.routeService( - opt.service + + if(options.services) { + for(const key in options.services) { + let opt = (options.services[key] as any); + if(opt instanceof Service) { + opt.service.name = key; opt.service.tag = key; + this.addService(opt.service, opt.connections, options.includeClassName, options.routeFormat, options.syncServices); + } else if (typeof opt === 'function') { + let service = new opt() as Service; //instantiate a class prototype + service.name = key; service.tag = key; + if(service) + this.addService( + service, + service.connections, + options.includeClassName, + options.routeFormat, + options.syncServices + ); + } + else { + if (typeof opt.service === 'function') { + let service = new opt.service({name:key}) as Service; //instantiate a class prototype + service.name = key; service.tag = key; + if(service) + this.addService( + service, + undefined, + options.includeClassName, + options.routeFormat, + options.syncServices + ); + opt.service = service; + } + else if(opt.service instanceof Service) { + opt.service.name = key; opt.service.tag = key; + this.addService( + opt.service, + undefined, + options.includeClassName, + options.routeFormat, + options.syncServices ); } - if(typeof opt?.service === 'object') { + if(typeof opt.service === 'object') { if(opt.connections) { if(Array.isArray(opt.connections)) { (opt.connections as any).forEach((k) => { @@ -191,16 +191,11 @@ export class Router extends Service { }, //configure new connections after adding the relevant services? receiving?:boolean //is this the receiving router? ) => { - - let user:User if(!info._id) { info._id = `user${Math.floor(Math.random()*1000000000000000)}`; - } - if(this.users[info._id]) { - user = this.users[info._id]; //existing user - } else { - user = Object.assign({}, info) as any;//Profile(info._id,info) as User; } + + let user:User = Object.assign({},info) as any;//Profile(info._id,info) as User; if(connections){ for(const key in connections) { @@ -210,7 +205,7 @@ export class Router extends Service { let start = performance.now(); let checker = () => { if(!(connections[key] as any).connection._id) { - if(performance.now() - start > this.userTimeout) { + if(performance.now() - start > 3000) { delete connections[key]; rej(false); } else { @@ -235,9 +230,6 @@ export class Router extends Service { connections[key] = this.addConnection(connections[key], user._id) as any; } } - - - if(config) { for(const c in config) { this.openConnection( @@ -249,106 +241,50 @@ export class Router extends Service { } } + let send = (message:any, ...a:any[]) => { + let connection = this.getConnection(user._id, 'send'); + if(connection?.send) return connection.send(message, ...a); + } - if(!this.users[info._id]) { - let send = (message:any, ...a:any[]) => { - let connection = this.getConnection(user._id, 'send'); - if(connection?.send) return connection.send(message, ...a); - } - - let sendAll = (message:any, ...a:any[]) => { - let connections = this.getConnections(user._id, 'send'); - for(const key in connections) - if(connections[key]?.send) return connections[key].send(message, ...a); - } - - let request = (message:any, method?:any, ...a:any[]) => { - let connection = this.getConnection(user._id, 'request'); - if(connection?.request) return connection.request(message, method, ...a); - } - - let requestAll = (message:any, method?:any, ...a:any[]) => { - let connections = this.getConnections(user._id, 'request'); - let results = []; - for(const key in connections) - if(connections[key]?.request) results.push(connections[key].request(message, method, ...a)); - return Promise.all(results); - } - - let post = (route:any, args?:any, method?:string, ...a:any[]) => { - let connection = this.getConnection(user._id, 'post'); - if(connection?.post) return connection.post(route, args, method, ...a); - } - - let postAll = (route:any, args?:any, method?:string, ...a:any[]) => { - let connections = this.getConnections(user._id, 'post'); - for(const key in connections) - if(connections[key]?.post) connections[key].post(route, args, method, ...a); - } - - let run = (route:any, args?:any, method?:string, ...a:any[]) => { - let connection = this.getConnection(user._id, 'run'); - if(connection?.run) return connection.run(route, args, method, ...a); - } + let request = (message:any, method?:any, ...a:any[]) => { + let connection = this.getConnection(user._id, 'request'); + if(connection?.request) return connection.request(message, method, ...a); + } - let runAll = (route:any, args?:any, method?:string, ...a:any[]) => { - let connections = this.getConnections(user._id, 'run'); - let results = []; - for(const key in connections) - if(connections[key]?.run) results.push(connections[key].run(route, args, method, ...a)); - return Promise.all(results); - } + let post = (route:any, args?:any, method?:string, ...a:any[]) => { + let connection = this.getConnection(user._id, 'post'); + if(connection?.post) return connection.post(route, args, method, ...a); + } - let subscribe = (route:any, callback?:((res:any)=>void)|string, ...a:any[]) => { - let connection = this.getConnection(user._id, 'subscribe'); - if(connection?.subscribe) return connection.subscribe(route, callback, ...a); - } + let run = (route:any, args?:any, method?:string, ...a:any[]) => { + let connection = this.getConnection(user._id, 'run'); + if(connection?.run) return connection.run(route, args, method, ...a); + } - let subscribeAll = (route:any, callback?:((res:any)=>void)|string, ...a:any[]) => { - let connections = this.getConnections(user._id, 'subscribe'); - let results = []; - for(const key in connections) - if(connections[key]?.post) results.push(connections[key].subscribe(route, callback, ...a)); - return Promise.all(results) as Promise; - } + let subscribe = (route:any, callback?:((res:any)=>void)|string,...a:any[]) => { + let connection = this.getConnection(user._id, 'subscribe'); + if(connection?.subscribe) return connection.subscribe(route, callback, ...a); + } - let unsubscribe = (route:any, sub:number, ...a:any[]) => { - let connection = this.getConnection(user._id, 'unsubscribe'); - if(connection?.unsubscribe) return connection.unsubscribe(route, sub, ...a); - } + let unsubscribe = (route:any, sub:number, ...a:any[]) => { + let connection = this.getConnection(user._id, 'unsubscribe'); + if(connection?.unsubscribe) return connection.unsubscribe(route, sub, ...a); + } - let unsubscribeAll = (route:any, subs?:{[key:string]:number}, ...a:any[]) => { - let connections = this.getConnections(user._id, 'unsubscribe'); - let results = []; - for(const key in connections) - if(connections[key]?.post && subs[key]) results.push(connections[key].unsubscribe(route, subs[key], ...a)); - return Promise.all(results) as Promise; - } + let terminate = () => { + return this.removeUser(user) + } - let terminate = () => { - return this.removeUser(user) - } + user.send = send; + user.request = request; + user.post = post; + user.run = run; + user.subscribe = subscribe; + user.unsubscribe = unsubscribe; + user.terminate = terminate; + //these are macros to get available connections - user.send = send; - user.request = request; - user.post = post; - user.run = run; - user.subscribe = subscribe; - user.unsubscribe = unsubscribe; - user.terminate = terminate; - - user.sendAll = sendAll; - user.requestAll = requestAll; - user.postAll = postAll; - user.runAll = runAll; - user.subscribeAll = subscribeAll; - user.unsubscribeAll = unsubscribeAll; - user.terminateAll = terminate; - //these are macros to get available connections - - - this.users[user._id] = user; - } + this.users[user._id] = user; if(connections && !receiving) { let connectionIds = {}; @@ -360,6 +296,7 @@ export class Router extends Service { } }); if(pass) { + //console.log(user._id,connectionIds) user.send({ route:'addUser', args:[ @@ -392,53 +329,30 @@ export class Router extends Service { } //pick the preferred connection by service name if passing a source, or pick the connection by id if not a source - getConnection = (sourceId:string, hasMethod?:string, connectionId?:string):User|ConnectionInfo|undefined => { - - if(this.connections[sourceId]) { - return this.connections[sourceId]; //regardless of method, as this is a direct connection reference - } - else if(this.sources[sourceId]) { + getConnection = (sourceId:string, hasMethod?:string):ConnectionInfo|undefined => { + if(this.sources[sourceId]) { //console.log(this.sources[sourceId]); - if(hasMethod?.includes('All')) return this.users[sourceId]; - - if(connectionId) { - if(hasMethod) { - if(this.sources[sourceId][connectionId]?.[hasMethod]) - return this.sources[sourceId][connectionId]; - } - else if(this.sources[sourceId][connectionId]) - return this.sources[sourceId][connectionId]; - else return undefined; - } - else if (this.order) { + if (this.order) { for(let i = 0; i < this.order.length; i++) { let k = this.order[i]; for(const key in this.sources[sourceId as string]) { if(this.sources[sourceId as string][key].service) { if(typeof this.sources[sourceId as string][key].service === 'object') { - if((this.sources[sourceId as string][key].service as Graph).__node.tag === k) { + if((this.sources[sourceId as string][key].service as Graph).tag === k) { if(this.sources[sourceId as string][key].connectionType && (this.sources[sourceId as string][key].service as any)?.name) { if(!this.serviceConnections[(this.sources[sourceId as string][key] as any).service.name]) { this.removeConnection(this.sources[sourceId as string][key]); //some auto cleanup continue; } } - if(hasMethod) { - if(this.sources[sourceId as string][key][hasMethod]) - return this.sources[sourceId as string][key]; - } - else return this.sources[sourceId as string][key]; + return this.sources[sourceId as string][key]; } } else if (this.sources[sourceId as string][key].service === k) { if(this.sources[sourceId as string][key].connectionType && (this.sources[sourceId as string][key].service as any)?.name) { if(!this.serviceConnections[(this.sources[sourceId as string][key] as any).service.name]) this.removeConnection(this.sources[sourceId as string][key]); //some auto cleanup continue; } - if(hasMethod) { - if(this.sources[sourceId as string][key][hasMethod]) - return this.sources[sourceId as string][key]; - } - else return this.sources[sourceId as string][key]; + return this.sources[sourceId as string][key]; } } } @@ -453,9 +367,8 @@ export class Router extends Service { continue; } } - if(hasMethod) { - if(this.sources[sourceId as string][k][hasMethod]) - return this.sources[sourceId as string][k]; + if(hasMethod && this.sources[sourceId as string][k][hasMethod]) { + return this.sources[sourceId as string][k]; } else { return this.sources[sourceId as string][k]; @@ -463,7 +376,7 @@ export class Router extends Service { } } - } else if (this.order && !this.connections[sourceId]) { + } else if (this.order) { for(let i = 0; i < this.order.length; i++) { let k = this.order[i]; if(this.sources[k]?.[sourceId]) { @@ -473,8 +386,7 @@ export class Router extends Service { continue; } } - if(hasMethod) { - if(this.sources[k][sourceId][hasMethod]) + if(hasMethod && this.sources[k][sourceId as string]?.[hasMethod]) { return this.sources[k][sourceId as string]; } else { @@ -484,6 +396,9 @@ export class Router extends Service { } } + if(typeof sourceId === 'string' && this.connections[sourceId] && this.connections[sourceId].send) { + return this.connections[sourceId]; //regardless of method, as this is a direct connection reference + } } @@ -500,113 +415,59 @@ export class Router extends Service { if(typeof this.sources[sourceId][key][k] === 'object') { let pass = true; if(hasMethod && !this.sources[sourceId][key][k][hasMethod]) pass = false; - if(props) { - for(const p in props) { - if(typeof this.sources[sourceId][key][k][p] === 'object' && typeof props[p] === 'object') { - //check one level down - for(const pp in props[p]) { - if(props[p][pp] !== this.sources[sourceId][key][k][p][pp]) { - pass = false; - break; - } + for(const p in props) { + if(typeof this.sources[sourceId][key][k][p] === 'object' && typeof props[p] === 'object') { + //check one level down + for(const pp in props[p]) { + if(props[p][pp] !== this.sources[sourceId][key][k][p][pp]) { + pass = false; + break; } } - else if(this.sources[sourceId][key][k][p] !== props[p]) { - pass = false; - } else { - pass = false; - break; - } + } + else if(this.sources[sourceId][key][k][p] !== props[p]) { + pass = false; + } else { + pass = false; + break; } } if(pass) { found[this.sources[sourceId][key][k]._id] = this.sources[sourceId][key][k]; - } + } } } } else { let pass = true; if(hasMethod && !this.sources[sourceId][key][hasMethod]) pass = false; - if(props) { - for(const p in props) { - if(typeof this.sources[sourceId][key][p] === 'object' && typeof props[p] === 'object') { - //check one level down - for(const pp in props[p]) { - if(props[p][pp] !== this.sources[sourceId][key][p][pp]) { - pass = false; - break; - } + for(const p in props) { + if(typeof this.sources[sourceId][key][p] === 'object' && typeof props[p] === 'object') { + //check one level down + for(const pp in props[p]) { + if(props[p][pp] !== this.sources[sourceId][key][p][pp]) { + pass = false; + break; } } - else if(this.sources[sourceId][key][p] !== props[p]) { - pass = false; - } else { - pass = false; - break; - } + } + else if(this.sources[sourceId][key][p] !== props[p]) { + pass = false; + } else { + pass = false; + break; } } if(pass) { - found[this.sources[sourceId][key]._id] = this.sources[sourceId][key]; + if(this.getConnection(this.sources[sourceId][key] as any, hasMethod)) + found[this.sources[sourceId][key]._id] = this.sources[sourceId][key]; } } } } - return found; - } - } - - - //e.g. from a user endpoint, run 'runConnection' on another user Id to interact with them - runConnection = async ( - userId:string, - method:'run'|'post'|'subscribe'|'unsubscribe'|'terminate'|'send'|'request'| - 'runAll'|'postAll'|'subscribeAll'|'unsubscribeAll'|'sendAll'|'requestAll', - args:any[], - connectionId?:string - ) => { - let sendTo; - if(method.indexOf('All') > -1) { - sendTo = this.users[userId]; - } else { - sendTo = this.getConnection(userId, method, connectionId); - } - if(sendTo) { - let res = (sendTo[method] as Function)(...args); - res = await res; - return res; } } - subscribeThroughConnection = ( - route:string, //the route on the endpoint we want to subscribe to outputs from - remoteRelay:string|ConnectionInfo, //the endpoint/user Id linking a router we are trying to relay messages through - remoteEndpoint:string, //the endpoint/user on the other router that we want to subscribe to through the router - callback:string|((res:any)=>void), - ...args:any[] - ) => { - if(typeof remoteRelay === 'string') { - remoteRelay = this.getConnection(remoteRelay, 'run') as ConnectionInfo; - } - - if(typeof remoteRelay === 'object') - return new Promise((res,rej) => { - (remoteRelay as any).run('routeConnections',[route,remoteEndpoint,(remoteRelay as any)._id,...args]).then((sub) => { - this.__node.state.subscribeEvent(remoteEndpoint, (res) => { - if(res?.callbackId === route) { - if(!callback) this.setState({[remoteEndpoint]:res.args}); - else if(typeof callback === 'string') { //just set state - this.setState({[callback]:res.args}); - } - else callback(res.args); - } - }); - res(sub); - }).catch(rej); - }); - } - - addConnection = (options:ConnectionProps|ConnectionInfo|string,source?:string, autoRemove=true) => { + addConnection = (options:ConnectionProps|ConnectionInfo|string,source?:string) => { let settings:ConnectionInfo = {} as any; if(typeof options === 'string') { if (this.connections[options]) { @@ -624,10 +485,10 @@ export class Router extends Service { } } } - if(typeof options === 'string' && this.__node.nodes.get(options)) options = {connection:this.__node.nodes.get(options)}; + if(typeof options === 'string' && this.nodes.get(options)) options = {connection:this.nodes.get(options)}; } if(!options || typeof options === 'string') return undefined; - + if(source) settings.source = source; if(options.connection instanceof GraphNode) { @@ -639,10 +500,9 @@ export class Router extends Service { return node[message.method]?.(...message.args) } else return node[message.method]?.(message.args) } else { - if(!node.__operator) return; if(Array.isArray(message.args)) { - return node.__operator(...message.args) - } else return node.__operator(message.args) + return node.run(...message.args) + } else return node.run(message.args) } } settings.request = async (message:any,method?:string) => { @@ -651,23 +511,22 @@ export class Router extends Service { return node[method]?.(...message.args) } else return node[method]?.(message.args) } else { - if(!node.__operator) return; if(Array.isArray(message.args)) { - return node.__operator(...message.args) - } else return node.__operator(message.args) + return node.run(...message.args) + } else return node.run(message.args) } } settings.post = async (route?:string, args?:any, method?:string) => { - if(route && node.__node.graph.get(route)) { - let n = node.__node.graph.get(route); + if(route && node.get(route)) { + let n = node.get(route); if(method) { if(Array.isArray(args)) { return n[method]?.(...args) } else return n[method]?.(args) } else { if(Array.isArray(args)) { - return n.__operator(...args) - } else return n.__operator(args) + return n.run(...args) + } else return n.run(args) } } else { @@ -677,28 +536,30 @@ export class Router extends Service { } else return node[method]?.(args) } else { if(Array.isArray(args)) { - return node.__operator(...args) - } else return node.__operator(args) + return node.run(...args) + } else return node.run(args) } } } settings.run = settings.post as any; - settings.subscribe = async (callback:((res:any)=>void)) => { - return node.__subscribe(callback) as number; + settings.subscribe = async (route:string|undefined, callback:((res:any)=>void)) => { + return node.subscribe(callback,route) as number; }; - settings.unsubscribe = async (sub:number) => { - return node.__unsubscribe(sub) as boolean; + settings.unsubscribe = async (route:any, sub:number) => { + return node.unsubscribe(sub,route) as boolean; } settings.terminate = () => { - node.__node.graph.remove(node); + node.graph.remove(node); return true; } settings.onclose = options.onclose; if(settings.onclose) { - node.__addOndisconnected((n:GraphNode) => { if(settings.onclose) settings.onclose(settings,n); }) + let oldondelete; + if(node.ondelete) oldondelete = node.ondelete; + node.ondelete = (n:GraphNode) => { if(settings.onclose) settings.onclose(settings,n); if(oldondelete) oldondelete(n); } } } else if (options.connection instanceof Graph) { - if(options.connection.__node.nodes.get('open')) + if(options.connection.nodes.get('open')) settings.service = options.connection; let graph = settings.connection as Graph; settings.send = async (message:ServiceMessage) => { @@ -710,8 +571,8 @@ export class Router extends Service { if(!message.route) return undefined; if(method) { if(Array.isArray(message.args)) { - return graph.__node.nodes.get(message.route)[method]?.(...message.args) - } else return graph.__node.nodes.get(message.route)[method]?.(message.args) + return graph.nodes.get(message.route)[method]?.(...message.args) + } else return graph.nodes.get(message.route)[method]?.(message.args) } else { if(Array.isArray(message.args)) { return graph.run(message.route,...message.args) @@ -753,10 +614,10 @@ export class Router extends Service { options.service = this.services[options.service]; } if(typeof options.service === 'object') { - if((options.service as any).connections) { //reference we have on available services - for(const key in (options.service as any).connections) { - if((options.service as any).connections[key][c as string]) { - c = (options.service as any).connections[key][c as string]; + if(options.service.connections) { //reference we have on available services + for(const key in options.service.connections) { + if(options.service.connections[key][c as string]) { + c = options.service.connections[key][c as string]; settings.connectionType = key; settings.connectionsKey = c as string; break; @@ -780,7 +641,6 @@ export class Router extends Service { } if(typeof c !== 'object') return undefined; settings._id = c._id; - settings.connection = options.connection as any; settings.send = c.send; settings.request = c.request; settings.run = c.run; @@ -796,12 +656,7 @@ export class Router extends Service { let oldonclose = c.onclose; c.onclose = (...args:any[]) => { if(settings.onclose) settings.onclose(settings, ...args); - if( - autoRemove && - settings.source && - this.users[settings.source] && - Object.keys(this.sources[settings.source]).length === 0 - ) { + if(this.users[settings.source] && Object.keys(this.sources[settings.source]).length === 0) { this.removeUser(settings.source, false); } if(oldonclose) oldonclose(...args); @@ -811,12 +666,7 @@ export class Router extends Service { let oldonclose = c.onclose; c.onclose = (...args:any[]) => { this.removeConnection(settings); - if( - autoRemove && - settings.source && - this.users[settings.source] && - Object.keys(this.sources[settings.source]).length === 0 - ) { //automatically clear a user if all of their connections + if(this.users[settings.source] && Object.keys(this.sources[settings.source]).length === 0) { this.removeUser(settings.source, false); } if(oldonclose) oldonclose(...args); @@ -834,7 +684,7 @@ export class Router extends Service { settings.source = options.source; } else if(!settings.source && options.service) { - settings.source = typeof options.service === 'object' ? (options.service as any)?.name : undefined; + settings.source = typeof options.service === 'object' ? options.service.name : undefined; } else if (!settings.source && (settings.connection instanceof GraphNode || settings.connection instanceof Graph)) { settings.source = 'local'; if(!this.order.indexOf('local')) this.order.unshift('local'); @@ -882,21 +732,18 @@ export class Router extends Service { } } - routeService = ( + addService = ( service:Service, - connections?:any, //the object on the service we want to associate connections with + connections?:any, //the object on the service we want to associate connections wtih + includeClassName?:boolean, + routeFormat?:string, + syncServices?:boolean, source?:string, order?:string[], ) => { //console.log(service) + this.load(service,includeClassName,routeFormat,this.customRoutes,this.customChildren); this.services[service.name] = service; - if(service.__node?.nodes) this.__node.nodes.forEach((n,k) => { - if(!service.__node?.nodes.get(k)) - { - service.__node?.nodes.set(k,n); - } else service.__node?.nodes.set(this.name + '.' + k,n); - }); - if(service.users) service.users = this.users; //needed for sessions service rn, should find more elegant solution if(connections) { if(typeof connections === 'string') this.addServiceConnections(service,connections,source); else { @@ -905,10 +752,11 @@ export class Router extends Service { } } } + if(syncServices) this.syncServices(); //maps all uncommon nodes to each service if(order) this.order = order; else { if(!this.order) this.order = []; - this.order.push((service as any).name); + this.order.push(service.name); } } @@ -945,18 +793,55 @@ export class Router extends Service { if(typeof service === 'string') { service = this.services[service]; } - if(service?.__node.nodes) { + if(service instanceof Service) { let connection = service.run('open', options, ...args); if(connection instanceof Promise) { return connection.then(async (info) => { if(!info._id) { - await connectionHasId(info,this.userTimeout); + await new Promise((res,rej) => { + let start = performance.now(); + let checker = () => { + if(!info._id) { + if(performance.now() - start > 3000) { + rej(false); + } else { + setTimeout(()=>{ + checker(); + },100); //check every 100ms + } + } else { + res(true); + } + } + + checker(); + + }).catch((er) => {console.error('Connections timed out:', er); }); } if(info._id) this.addConnection({connection:info, service}, source); }) } else if(connection) { if(!connection._id) { - await connectionHasId(connection,this.userTimeout); + await new Promise((res,rej) => { + + let start = performance.now(); + let checker = () => { + if(!connection._id) { + if(performance.now() - start > 3000) { + rej(false); + } else { + setTimeout(()=>{ + checker(); + },100); //check every 100ms + } + } else { + res(true); + } + } + + checker(); + + }).catch((er) => {console.error('Connections timed out:', er); }); } if(connection._id) return this.addConnection({connection, service}, source); } @@ -968,6 +853,34 @@ export class Router extends Service { return connection.terminate(); } + subscribeThroughConnection = ( + route:string, //the route on the endpoint we want to subscribe to outputs from + relay:string|ConnectionInfo, //the router we are trying to relay messages through + endpoint:string, //the endpoint on the router that we want to subscribe to through the router + callback:string|((res:any)=>void), + ...args:any[] + ) => { + if(typeof relay === 'string') { + relay = this.getConnection(relay,'run') as ConnectionInfo; + } + + if(typeof relay === 'object') + return new Promise((res,rej) => { + (relay as any).run('routeConnections',[route,endpoint,(relay as any)._id,...args]).then((sub) => { + this.subscribe(endpoint, (res) => { + if(res?.callbackId === route) { + if(!callback) this.setState({[endpoint]:res.args}); + else if(typeof callback === 'string') { //just set state + this.setState({[callback]:res.args}); + } + else callback(res.args); + } + }); + res(sub); + }).catch(rej); + }); + } + //we will use the router to relay subscriptions between endpoints generically routeConnections = ( route:string, //the route on the endpoint we want to subscribe to outputs from @@ -996,8 +909,9 @@ export class Router extends Service { if((transmitter as ConnectionInfo)?.subscribe && (receiver as ConnectionInfo)?.send) { let res:Promise = new Promise((res,rej) => { - (transmitter as ConnectionInfo).subscribe( + (transmitter as any).subscribe( route, + (transmitter as any)._id, (res:any) => { if(!this.connections[(receiver as any)._id] && rxsrc) { if(this.sources[rxsrc]) { @@ -1022,6 +936,21 @@ export class Router extends Service { } } + //tie node references together across service node maps so they can call each other's relative routes + syncServices = () => { + for(const name in this.services) { + if('users' in this.services[name]) this.services[name].users = this.users; + this.nodes.forEach((n,tag) => { + if(!this.services[name].nodes.get(n.tag)) { + this.services[name].nodes.set(n.tag,n); + } else { + if(!this.services[name].nodes.get(tag) && n._UNIQUE !== this.services[name].nodes.get(n.tag)._UNIQUE) //use the remapped key if it's not the same node + this.services[name].nodes.set(tag,n); + } + }); + } + } + setUserData = (user:string|User, data:{[key:string]:any}|string) => { if(user) if(typeof user === 'string') { @@ -1040,28 +969,19 @@ export class Router extends Service { //console.log(user,props) } + routes:Routes={ + addUser:this.addUser, + removeUser:this.removeUser, + getConnection:this.getConnection, + addConnection:this.addConnection, + removeConnection:this.removeConnection, + addService:this.addService, + addServiceConnections:this.addServiceConnections, + openConnection:this.openConnection, + terminate:this.terminate, + routeConnections:this.routeConnections, + subscribeThroughConnection:this.subscribeThroughConnection, + syncServices:this.syncServices + } -} - -//e.g. check if a websocket etc has the id so its ready for sending commands -export function connectionHasId(connection:{_id?:string, [key:string]:any}, timeout=10000) { - return new Promise((res,rej) => { - let start = performance.now(); - let checker = () => { - if(!connection._id) { - if(performance.now() - start > timeout) { - rej(false); - } else { - setTimeout(()=>{ - checker(); - },100); //check every 100ms - } - } else { - res(true); - } - } - - checker(); - }).catch((er) => {console.error('Connection timed out:', er); }) as Promise; - } \ No newline at end of file diff --git a/src/services/sessions/sessions.service.ts b/services/sessions/sessions.service.ts similarity index 50% rename from src/services/sessions/sessions.service.ts rename to services/sessions/sessions.service.ts index 1861086f..b645f078 100644 --- a/src/services/sessions/sessions.service.ts +++ b/services/sessions/sessions.service.ts @@ -1,24 +1,9 @@ -import { stringifyFast } from "../utils"; -import { Service, ServiceOptions } from "../Service"; +import { stringifyFast } from "../../Graph"; +import { Routes, Service, ServiceOptions } from "../Service"; import { User } from "../router/Router"; -import { loaders } from "../../loaders/index"; - -/** - * Sessions are a way to run a loop that monitors data structures to know procedurally when and what to update - * - * OneWaySession: source sends props to listener, define listener, source default is creating user - * SharedSession: two modes: - * Hosted: Host receives props from all users based on propnames, users receive hostprops - * Shared: All users receive the same props based on their own updates - * - * There's also these older stream API functions that are more pure for monitoring objects/arrays and updating new data e.g. out of a buffer. - * Need to esplain/demo all that too.... @@__@@ - */ - //parse from this object/endpoint and send to that object/endpoint, e.g. single users -//todo: make this hurt brain less to reconstruct the usage -export type OneWaySessionProps = { +export type PrivateSessionProps = { _id?:string, settings?:{ listener:string, @@ -28,10 +13,9 @@ export type OneWaySessionProps = { moderators?:{[key:string]:boolean}, password?:string, ownerId?:string, - onopen?:(session:OneWaySessionProps)=>void, - onhasupdate?:(session:OneWaySessionProps, updated:any)=>void, //host-side - onmessage?:(session:OneWaySessionProps, updated:any)=>void, //user-side - onclose?:(session:OneWaySessionProps)=>void, + onopen?:(session:PrivateSessionProps)=>void, + onmessage?:(session:PrivateSessionProps)=>void, + onclose?:(session:PrivateSessionProps)=>void, [key:string]:any //arbitrary props e.g. settings, passwords }, data?:{ @@ -44,14 +28,8 @@ export type OneWaySessionProps = { export type SessionUser = { _id:string, //unique identifier for user, used as key in users object and in general sessions:{[key:string]:any}, - sessionSubs:{[key:string]:{ - onopenSub?:number, - onmessage?:(session:SharedSessionProps, update:any, user:SessionUser)=>void, - onopen?:(session:SharedSessionProps, user:SessionUser)=>void, - onclose?:(session:SharedSessionProps, user:SessionUser)=>void - }} [key:string]:any -} & User //extend base users on the router or just wrapping a connection from another service +} & Partial //sessions for shared user data and game/app logic for synchronous and asynchronous sessions to stream selected properties on user objects as they are updated export type SharedSessionProps = { @@ -60,18 +38,16 @@ export type SharedSessionProps = { name:string, propnames:{[key:string]:boolean}, users?:{[key:string]:boolean}, - host?:string, //if there is a host, all users only receive from the host's prop updates and vise versa + host?:string, //if there is a host, all users only receive from the host's prop updates hostprops?:{[key:string]:boolean}, - inheritHostData?:boolean, //new hosts adopt old host data? Default true admins?:{[key:string]:boolean}, moderators?:{[key:string]:boolean}, spectators?:{[key:string]:boolean}, banned?:{[key:string]:boolean}, password?:string, ownerId?:string, - onhasupdate?:(session:SharedSessionProps, updated:any)=>void, //host-side onopen?:(session:SharedSessionProps)=>void, - onmessage?:(session:SharedSessionProps, updated:any)=>void, + onmessage?:(session:SharedSessionProps)=>void, onclose?:(session:SharedSessionProps)=>void, [key:string]:any //arbitrary props e.g. settings, passwords }, @@ -81,7 +57,7 @@ export type SharedSessionProps = { [key:string]:any } }, - oneWay?:{ //host driven sessions will share only what the host shares to all users, while hosts will receive hidden data + private?:{ //host driven sessions will share only what the host shares to all users, while hosts will receive hidden data [key:string]:any }, [key:string]:any @@ -104,7 +80,6 @@ export type StreamInfo = { } } -//Todo: streamline, we don't *really* need 3 types of streaming data structures but on the other hand everything is sort of optimized so just keep it export class SessionsService extends Service { name='sessions'; @@ -113,45 +88,34 @@ export class SessionsService extends Service { //complex user sessions with some premade rulesets sessions:{ - oneWay:{[key:string]:OneWaySessionProps}, //sync user props <--> user props + private:{[key:string]:PrivateSessionProps}, //sync user props <--> user props shared:{[key:string]:SharedSessionProps}//sync user props <--> all other users props } = { - oneWay:{}, + private:{}, shared:{} } - invites:{ - [key:string]:{ //userId - [key:string]:{//session Id - session:OneWaySessionProps|SharedSessionProps|string, - endpoint?:string //userid to send joinSession call to - } //session options - } - } = {} - - - constructor(options?:ServiceOptions, users?:{[key:string]:SessionUser}) { + constructor(options:ServiceOptions, users?:{[key:string]:SessionUser}) { super(options); - this.setLoaders(loaders); - this.load(this); + this.load(this.routes); if(users) this.users = users; } getSessionInfo = ( - sessionIdOrName?:string, //id or name (on shared sessions) + sessionId?:string, //id or name (on shared sessions) userId?:string ) => { - if(!sessionIdOrName) { + if(!sessionId) { return this.sessions.shared; } else { - if(this.sessions.oneWay[sessionIdOrName]) { - let s = this.sessions.oneWay[sessionIdOrName]; + if(this.sessions.private[sessionId]) { + let s = this.sessions.private[sessionId]; if(s.settings) if(s.settings.source === userId || s.settings.listener === userId || s.settings.ownerId === userId || s.settings.admins?.[userId as string] || s.settings.moderators?.[userId as string]) - return {oneWay:{[sessionIdOrName]:s}}; - } else if(this.sessions.shared[sessionIdOrName]) { - return {shared:{[sessionIdOrName]:this.sessions.shared[sessionIdOrName]}}; + return {private:{[sessionId]:s}}; + } else if(this.sessions.shared[sessionId]) { + return {shared:{[sessionId]:this.sessions.shared[sessionId]}}; } else { let res = {}; for(const id in this.sessions.shared) { @@ -163,43 +127,31 @@ export class SessionsService extends Service { } } - openOneWaySession = ( - options:OneWaySessionProps={}, - sourceUserId?:string, - listenerUserId?:string + openPrivateSession = ( + options:PrivateSessionProps={}, + userId?:string ) => { if(!options._id) { - options._id = `oneWay${Math.floor(Math.random()*1000000000000000)}`; - if(this.sessions.oneWay[options._id]) { + options._id = `private${Math.floor(Math.random()*1000000000000000)}`; + if(this.sessions.private[options._id]) { delete options._id; - this.openOneWaySession(options,sourceUserId); //regen id + this.openPrivateSession(options,userId); //regen id } } - if(options._id && sourceUserId && this.users[sourceUserId]) { - if(sourceUserId){ - if(!options.settings) - options.settings = { - listener:sourceUserId, - source:sourceUserId, - propnames:{latency:true}, - admins:{[sourceUserId]:true}, - ownerId:sourceUserId - }; - if(!options.settings.listener) - options.settings.listener = listenerUserId ? listenerUserId : sourceUserId; - if(!options.settings.source) - options.settings.source = sourceUserId; - if(!this.users[sourceUserId].sessions) - this.users[sourceUserId].sessions = {}; - this.users[sourceUserId].sessions[options._id] = options; + if(options._id && userId && this.users[userId]) { + if(userId){ + if(!options.settings) options.settings = { listener:userId, source:userId, propnames:{latency:true}, admins:{[userId]:true}, ownerId:userId }; + if(!options.settings.listener) options.settings.listener = userId; + if(!options.settings.source) options.settings.source = userId; + if(!this.users[userId].sessions) this.users[userId].sessions = {}; + this.users[userId].sessions[options._id] = options; } if(!options.data) options.data = {}; - if(options.onopen) options.onopen(options); - if(this.sessions.oneWay[options._id]) { - return this.updateSession(options,sourceUserId); + if(this.sessions.private[options._id]) { + return this.updateSession(options,userId); } else if(options.settings?.listener && options.settings.source) - this.sessions.oneWay[options._id] = options; //need the bare min in here + this.sessions.private[options._id] = options; //need the bare min in here } return options; } @@ -212,41 +164,21 @@ export class SessionsService extends Service { options._id = `shared${Math.floor(Math.random()*1000000000000000)}`; if(this.sessions.shared[options._id]) { delete options._id; - return this.openSharedSession(options,userId); //regen id + this.openSharedSession(options,userId); //regen id } } if(options._id && userId && this.users[userId]){ if(typeof userId === 'string') { - if(!options.settings) - options.settings = { - name:'shared', - propnames:{latency:true}, - users:{[userId]:true}, - admins:{[userId]:true}, - ownerId:userId - }; + if(!options.settings) options.settings = { name:'shared', propnames:{latency:true}, users:{[userId]:true}, admins:{[userId]:true}, ownerId:userId }; - if(!options.settings.users) - options.settings.users = {[userId]:true}; - if(!options.settings.admins) - options.settings.admins = {[userId]:true}; - if(!options.settings.ownerId) - options.settings.ownerId = userId; - if(!this.users[userId].sessions) - this.users[userId].sessions = {}; + if(!options.settings.users) options.settings.users = {[userId]:true}; + if(!options.settings.admins) options.settings.admins = {[userId]:true}; + if(!options.settings.ownerId) options.settings.ownerId = userId; + if(!this.users[userId].sessions) this.users[userId].sessions = {}; this.users[userId].sessions[options._id] = options; - } - else if (!options.settings) - options.settings = { - name:'shared', - propnames:{latency:true}, - users:{} - }; - if(!options.data) - options.data = { oneWay:{}, shared:{} }; - if(!options.settings.name) - options.name = options.id; - if(options.onopen) options.onopen(options); + } else if (!options.settings) options.settings = {name:'shared', propnames:{latency:true}, users:{}}; + if(!options.data) options.data = { private:{}, shared:{} }; + if(!options.settings.name) options.name = options.id; if(this.sessions.shared[options._id]) { return this.updateSession(options,userId); } @@ -255,50 +187,37 @@ export class SessionsService extends Service { return options; } - open = (options:any,userId?:string) => { - if(options.listener) this.openOneWaySession(options,userId); - else this.openSharedSession(options,userId); - } - //update session properties, also invoke basic permissions checks for who is updating updateSession = ( - options:OneWaySessionProps | SharedSessionProps, + options:PrivateSessionProps | SharedSessionProps, userId?:string ) => { //add permissions checks based on which user ID is submitting the update let session:any; if(options._id){ - session = this.sessions.oneWay[options._id]; - if(!session) - session = this.sessions.shared[options._id]; - if(session && userId) { - if(session.settings && ( - session?.settings.source === userId || - session.settings.admins?.[userId] || - session.settings.moderators?.[userId] || - session.settings.ownerId === userId - )) { - return this.recursivelyAssign(session, options); + session = this.sessions.private[options._id]; + if(!session) session = this.sessions.shared[options._id]; + if(this.sesh.private[options._id] && userId) { + let sesh = this.sessions.shared[options._id]; + if(sesh.settings && (sesh?.settings.source === userId || sesh.settings.admins?.[userId] || sesh.settings.moderators?.[userId] || sesh.settings.ownerId === userId)) { + return Object.assign(this.session.shared[options._id],options); } } else if(options.settings?.source) { - return this.openOneWaySession(options as OneWaySessionProps,userId); + return this.openPrivateSession(options as PrivateSessionProps,userId); } else return this.openSharedSession(options as SharedSessionProps,userId); } return false; } - //add a user id to a session, Run this at the session host location and clientside if separate. remoteUser will take care of this on either endpoint for you - //supply options e.g. to make them a moderator or update properties to be streamed dynamically + //add a user id to a session, supply options e.g. to make them a moderator or update properties to be streamed dynamically joinSession = ( sessionId:string, userId:string, - options?:SharedSessionProps|OneWaySessionProps, - remoteUser:boolean=true //ignored if no endpoint on user object - ):SharedSessionProps|OneWaySessionProps|false => { + options?:SharedSessionProps|PrivateSessionProps + ) => { if(!userId && !this.users[userId]) return false; if(!this.users[userId].sessions) this.users[userId].sessions = {}; - let sesh = this.sessions.shared[sessionId] as SharedSessionProps|OneWaySessionProps; - if(!sesh) sesh = this.sessions.oneWay[sessionId]; + let sesh = this.sessions.shared[sessionId]; //console.log(sessionId,userId,sesh,this.sessions); if(sesh?.settings) { if(sesh.settings?.banned) { @@ -309,233 +228,70 @@ export class SessionsService extends Service { if(options.settings.password !== sesh.settings.password) return false } (sesh.settings.users as any)[userId] = true; - sesh.settings.newUser = true; this.users[userId].sessions[sessionId] = sesh; if(options) { return this.updateSession(options,userId); }; //console.log(sesh) - if(remoteUser && this.users[userId]?.send) { - this.users[userId].send({route:'joinSession',args:[sessionId,userId,sesh]}); //callbacks on the sesh should disappear with json.stringify() in the send calls when necessary - } - return sesh; - } - else if (options?.source || options?.listener) { - sesh = this.openOneWaySession(options as OneWaySessionProps,userId); - if(remoteUser && this.users[userId]?.send) { - this.users[userId].send({route:'joinSession',args:[sessionId,userId,sesh]}); - } return sesh; - } - else if (options) { - sesh = this.openSharedSession(options as SharedSessionProps,userId); - if(remoteUser && this.users[userId]?.send) { - this.users[userId].send({route:'joinSession',args:[sessionId,userId,sesh]}); - } - return sesh; - } + } else if (options?.source || options?.listener) return this.openPrivateSession(options as PrivateSessionProps,userId); + else if (options) return this.openSharedSession(options as SharedSessionProps,userId); return false; } - inviteToSession = ( - session:OneWaySessionProps|SharedSessionProps|string, - userInvited:string, - inviteEndpoint?:string, //your user/this socket endpoint's ID as configured on router - remoteUser:boolean=true - ) => { - if(remoteUser && this.users[userInvited]?.send) { - this.users[userInvited]?.send({route:'receiveSessionInvite', args:[ - session, - userInvited, - inviteEndpoint - ]}); - } else { - this.receiveSessionInvite(session,userInvited,inviteEndpoint); - } - } - - //subscribe to this clientside to do stuff when getting notified - receiveSessionInvite = ( - session:OneWaySessionProps|SharedSessionProps|string, //this session - userInvited:string, //invite this user - endpoint?:string //is the session on another endpoint (user or other?)? - ) => { - if(!this.invites[userInvited]) this.invites[userInvited] = {}; - let id = typeof session === 'string' ? session : session._id; - this.invites[userInvited][id] = {session, endpoint}; - - return id; - } - - acceptInvite = ( //will wait for endpoint to come back if remote invitation - session:OneWaySessionProps|SharedSessionProps|string, //session id is minimum - userInvited:string, - remoteUser=true - ):Promise => { - let id = typeof session === 'string' ? session : session._id; - let invite = this.invites[userInvited]?.[id]; - let endpoint; - if(invite) { - session = invite.session; - endpoint = invite.endpoint; - delete this.invites[userInvited]?.[id]; - } - return new Promise((res,rej) => { - if(!id) res(false); - if(remoteUser && endpoint && this.users[endpoint]?.send) { - //wait for the remote joinSession call to come back - let resolved; - let timeout = setTimeout(()=>{ - if(!resolved) { - this.unsubscribe('joinSession',subbed); rej(new Error('Session join timed out')); - } - },10000); - let subbed = this.subscribe('joinSession', (result:SharedSessionProps|OneWaySessionProps|false)=>{ - if(typeof result === 'object' && result?._id === id) { - if(result.setting?.users?.includes(userInvited)) { - //we've joined the session - this.unsubscribe('joinSession', subbed); - resolved = true; - if(timeout) clearTimeout(timeout); - res(result); - } - } - }); - this.users[endpoint]?.send({route:'joinSession',args:[id,userInvited,undefined,true]}); - //10sec timeout - } else res(this.joinSession(id, userInvited, typeof session === 'object' ? session : undefined)); - }); - } - - rejectInvite = ( - session:OneWaySessionProps|SharedSessionProps|string, - userInvited:string, - remoteUser=true - ) => { - let id = typeof session === 'string' ? session : session._id; - if(this.invites[userInvited]?.[id]) { - let endpoint = this.invites[userInvited][id].endpoint; - delete this.invites[userInvited][id]; - if(remoteUser && endpoint && this.users[endpoint]?.send) { - this.users[endpoint].send({route:'rejectInvite',args:[id,userInvited]}); //listen on host end too to know if invite was rejected - } - return true; - } - } - - //Remove a user from a session. OneWay sessions will be closed - //Run this at the session host location leaveSession = ( - session:OneWaySessionProps|SharedSessionProps|string, + sessionId:string, userId:string, - clear:boolean=true, //clear all data related to this user incl permissions - remoteUser:boolean=true //send user an all-clear to unsubscribe on their end + clear:boolean=true //clear all data related to this user incl permissions ) => { - let sessionId:string|undefined; - if(typeof session === 'string') { - sessionId = session; - session = this.sessions.oneWay[sessionId]; - if(!session) session = this.sessions.shared[sessionId]; - } else sessionId = session._id; + let session:any = this.sessions.private[sessionId]; + if(!session) session = this.sessions.shared[sessionId]; if(session) { - if(this.sessions.oneWay[sessionId]) { - if( userId === session.settings.source || - userId === session.settings.listener || - session.settings.admins?.[userId] || - session.settings.moderators?.[userId] - ) { - delete this.sessions.oneWay[sessionId]; - delete this.users[userId]?.sessions[sessionId]; - delete this.users[userId]?.sessionSubs?.[sessionId]; + if(this.sessions.private[sessionId]) { + if(userId === session.settings.source || userId === session.settings.listener || session.settings.admins?.[userId] || session.settings.moderators?.[userId]) { + delete this.sessions.private[sessionId]; + delete this.users[userId].sessions[sessionId]; if(clear) { if(session.settings.admins?.[userId]) delete (this.sessions.shared[sessionId].settings?.admins as any)[userId]; if(session.settings.moderators?.[userId]) delete (this.sessions.shared[sessionId].settings?.moderators as any)[userId]; } - if(remoteUser && this.users[userId]?.send) { - this.users[userId].send({route:'unsubscribeFromSession',args:[session._id, userId, clear]}); - } else { - this.unsubsribeFromSession(session, userId, clear); - } } } else if (this.sessions.shared[sessionId]) { delete this.sessions.shared.settings.users[userId]; - delete this.users[userId]?.sessions[sessionId]; - delete this.users[userId]?.sessionSubs?.[sessionId]; + delete this.users[userId].sessions[sessionId]; if(clear) { if(session.settings.admins?.[userId]) delete (this.sessions.shared[sessionId].settings?.admins as any)[userId]; if(session.settings.moderators?.[userId]) delete (this.sessions.shared[sessionId].settings?.moderators as any)[userId]; if(session.data.shared[userId]) delete this.sessions.shared[sessionId].data?.shared[userId]; if(session.settings.host === userId) { - this.swapHost(session, undefined, true); - delete session.data.shared[userId]; + delete session.settings.host; + delete session.data.shared; + session.data.shared = {}; + this.swapHost(session); } } - if(remoteUser && this.users[userId]?.send) { - this.users[userId].send({route:'unsubscribeFromSession',args:[session._id, userId, clear]}); - } else { - this.unsubsribeFromSession(session, userId, clear); - } } return true; } return false; } - //Delete a session. Run this at the session host location - deleteSession = (session:string|OneWaySessionProps|SharedSessionProps, userId:string, remoteUsers=true) => { - - if(typeof session === 'string') { - let id = session; - session = this.sessions.oneWay[id]; - if(!session) session = this.sessions.shared[id]; - } - if(session) { - if(session.source === userId || session.listener === userId || session.admins?.[userId] || session.ownerId === userId) { - for(const user in session.settings.users) { - if(this.users[user]?.sessions) delete this.users[user].sessions[session._id]; - if(this.users[user]?.sessionSubs) delete this.users[user].sessionSubs[session._id]; - if(remoteUsers) { - if(session.users) { - for(const key in session.users) { - if(this.users[key]?.send) - this.users[key].send({route:'unsubscribeFromSession',args:[session._id, key]}); - } - } - else if(session.listener) { - if(this.users[session.listener]?.send) - this.users[session.listener].send({route:'unsubscribeFromSession',args:[session._id, session.listener]}); - } else if (this.users[userId]?.send) { - this.users[userId].send({route:'unsubscribeFromSession',args:[session._id, userId]}); - } - } else { - this.unsubsribeFromSession(session, user); - } - } - if(this.sessions.oneWay[session._id]) delete this.sessions.oneWay[session._id]; - else if(this.sessions.shared[session._id]) delete this.sessions.oneWay[session._id]; - if(session.onclose) session.onclose(session); - } - } - return true; - } - getFirstMatch(obj1:{[key:string]:any},obj2:{[key:string]:any}) { for(const i in obj1) { - if(i in obj2) return i; + for(const j in obj2) { + if(i === j) return i; + } } return false; } swapHost = ( - session:OneWaySessionProps|SharedSessionProps|string, - newHostId?:string, - adoptData:boolean=true, //copy original session hosts data? - remoteUser=true + session:PrivateSessionProps|SharedSessionProps|string, + newHostId?:string ) => { if(typeof session === 'string') { - if(this.sessions.oneWay[session]) session = this.sessions.oneWay[session]; + if(this.sessions.private[session]) session = this.sessions.private[session]; else if(this.sessions.shared[session]) session = this.sessions.shared[session]; } if(typeof session === 'object' && session.settings) { - let oldHost = session.settings.host; delete session.settings.host; if(newHostId) { if(session.settings.users[newHostId]) session.settings.host = newHostId; @@ -552,112 +308,71 @@ export class SessionsService extends Service { if(match) session.settings.host = match; }//sendAll leadership when host swapping if(!session.settings.host) session.settings.host = Object.keys(session.settings.users)[0]; //replace host - if(adoptData && oldHost && session.settings.inheritHostData !== false) { - if(session.data?.shared[oldHost]) { //oneWay data will stay the same - if(session.data?.shared[oldHost]) { - session.data.shared[session.settings.host] = Object.assign( - session.data.shared[session.settings.host] ? session.data.shared[session.settings.host] : {}, - session.data.shared[oldHost] - ); - if(remoteUser) { + return true; + } + return false; + } - } - } + deleteSession = (sessionId:string, userId:string) => { + let session:any = this.sessions.private[sessionId]; + if(!session) session = this.sessions.shared[sessionId]; + if(session) { + if(session.source === userId || session.listener === userId || session.admins?.[userId] || session.ownerId === userId) { + for(const user in session.settings.users) { + if(this.users[user].sessions) delete this.users[user].sessions[sessionId]; } + if(this.sessions.private[sessionId]) delete this.sessions.private[sessionId] + else if(this.sessions.shared[sessionId]) delete this.sessions.private[sessionId] } - return true; } - return false; + return true; } - //run these on the clientside user subscribeToSession = ( - session:SharedSessionProps|OneWaySessionProps|string, + session:SharedSessionProps|PrivateSessionProps|string, userId:string, - onmessage?:(session:SharedSessionProps|OneWaySessionProps, update:any, user:SessionUser)=>void, - onopen?:(session:SharedSessionProps|OneWaySessionProps, user:SessionUser)=>void, - onclose?:(session:SharedSessionProps|OneWaySessionProps, user:SessionUser)=>void + onmessage?:(session:SharedSessionProps|PrivateSessionProps, userId:string)=>void, + onopen?:(session:SharedSessionProps|PrivateSessionProps, userId:string)=>void, + onclose?:(session:SharedSessionProps|PrivateSessionProps, userId:string)=>void ) => { if(typeof session === 'string') { - let s = this.sessions.oneWay[session]; + let s = this.sessions.private[session]; if(!s) s = this.sessions.shared[session] as any; if(!s) return undefined; session = s; - } - - let user = this.users[userId]; - if(!user) return undefined; - if(!user.sessionSubs) user.sessionSubs = {}; - if(!user.sessionSubs[session._id]) user.sessionSubs[session._id] = {}; - - if(onmessage) user.sessionSubs[session._id].onmessage = onmessage; - if(onopen) this.sessionSubs[userId][session._id].onopen = onopen; - if(onclose) user.sessionSubs[session._id].onclose = onclose; - if(typeof onopen === 'function') { + } + + if(typeof session.onopen === 'function') { let sub = this.subscribe('joinSession',(res) => { - if(res._id === (session as any)._id) - this.sessionSubs[userId][(session as any)._id].onopen(session as any, user); + if(res._id === (session as any)._id) (session as any).onopen(session, userId); this.unsubscribe('joinSession', sub as number); - }); - user.sessionSubs[session._id].onopenSub = sub; + }) } - - return session; - } - //run these on the clientside user - unsubsribeFromSession = ( - session:SharedSessionProps|OneWaySessionProps|string, - userId?:string, - clear=true //clear session data (default true) - ) => { - if(typeof session === 'string') { - let s = this.sessions.oneWay[session]; - if(!s) s = this.sessions.shared[session] as any; - if(!s) return undefined; - session = s; - } + if(typeof session === 'object') { //we need to fire onmessage events when the session updates (setState for sessionId) and when the user updates - const clearSessionSubs = (Id:string, s:SharedSessionProps|OneWaySessionProps) => { - let u = this.users[Id]; - if(!u) return undefined; - if(u.sessionSubs?.[s._id]) { - if(u.sessionSubs[s._id].onopenSub) { - this.unsubscribe('joinSession', u.sessionSubs[s._id].onopenSub as number); - } - } - if(u.sessionSubs[s._id].onclose) u.sessionSubs[s._id].onclose(s as any, u); - delete u.sessionSubs[s._id]; - } - - if(userId) { - clearSessionSubs(userId, session); - } else { - for(const key in this.users) { - clearSessionSubs(key, session); - } - } + if(onmessage) session.onmessage = onmessage; + if(onopen) session.onclose = onopen; + if(onclose) session.onclose = onclose; - if(clear) { - if(this.sessions.oneWay[session._id]) delete this.sessions.oneWay[session._id]; - else if(this.sessions.shared[session._id]) delete this.sessions.shared[session._id]; + + // if(typeof session.onmessage === 'function') + // this.subscribe(session._id,(session)=>{ session.onmessage(session,userId); }); + + // this.setState({[session._id]:session}); } + return session; } //iterate all subscriptions, e.g. run on backend - sessionUpdateCheck = ( - sessionHasUpdate?:( - session:OneWaySessionProps|SharedSessionProps, - update:{shared?:any,oneWay?:any} - )=>void,transmit=true - ) => { + sessionUpdateCheck = (transmit=true) => { let updates:any = { - oneWay:{}, + private:{}, shared:{} }; - for(const session in this.sessions.oneWay) { - const sesh = this.sessions.oneWay[session]; + for(const session in this.sessions.private) { + const sesh = this.sessions.private[session]; const updateObj = { _id:sesh._id, settings:{ @@ -667,31 +382,27 @@ export class SessionsService extends Service { data:{} } as any; //pull user's updated props and send to listener if(!this.users[sesh.source]) { - delete this.sessions.oneWay[session]; - continue; - } + delete this.sessions.private[session] + break; + } if(sesh.settings && sesh.data) { for(const prop in sesh.settings.propnames) { - if(prop in this.users[sesh.source]) { - if(this.sessions.oneWay[session].data) { + if( this.users[sesh.source][prop]) { + if(this.sessions.private[session].data) { if(typeof sesh.data[prop] === 'object') { if(this.users[sesh.source][prop] && (stringifyFast(sesh.data[prop]) !== stringifyFast(this.users[sesh.source][prop]) || !(prop in sesh.data))) updateObj.data[prop] = this.users[sesh.source][prop]; } - else if(prop in this.users[sesh.source] && (sesh.data[prop] !== this.users[sesh.source][prop] || !(prop in sesh.data))) + else if(this.users[sesh.source][prop] && (sesh.data[prop] !== this.users[sesh.source][prop] || !(prop in sesh.data))) updateObj.data[prop] = this.users[sesh.source][prop]; } else updateObj.data[prop] = this.users[sesh.source][prop]; - } else if(this.sessions.oneWay[session]?.data && prop in this.sessions.oneWay[session]?.data) - delete (this.sessions.oneWay[session].data as any)[prop]; + } else if(this.sessions.private[session]?.data?.[prop]) delete (this.sessions.private[session].data as any)[prop]; } } if(Object.keys(updateObj.data).length > 0) { - this.recursivelyAssign(this.sessions.oneWay[session].data, updateObj.data); //set latest data on the source object as reference - updates.oneWay[sesh._id as string] = updateObj; - - if(sessionHasUpdate) sessionHasUpdate(sesh,updateObj); - if(sesh.settings.onhasupdate) sesh.onhasupdate(sesh,updateObj); + this.recursivelyAssign(this.sessions.private[session].data, updateObj.data); //set latest data on the source object as reference + updates.private[sesh._id as string] = updateObj; } } @@ -706,99 +417,85 @@ export class SessionsService extends Service { } as any; if(sesh.settings?.host) { //host receives object of all other users - const oneWayData = {}; //host receives all users' props + const privateData = {}; //host receives all users' props const sharedData = {}; //users receive host props for(const user in sesh.settings.users) { - if(!this.users[user]) { //if no user found assume they're to be kicked from session + if(!this.users[user]) { delete sesh.settings.users[user]; //dont need to delete admins, mods, etc as they might want to come back <_< - if( sesh.settings.host === user ) - this.swapHost(sesh, undefined, true); - if( sesh.data?.shared[user] ) - delete sesh.data.shared[user]; - if( sesh.data?.oneWay?.[user] ) - delete sesh.data.shared[user]; + if( sesh.data?.shared[user]) delete sesh.data.shared[user]; + if( sesh.data?.private?.[user]) delete sesh.data.shared[user]; + if(sesh.settings.host === user) this.swapHost(sesh); updateObj.settings.users = sesh.settings.users; updateObj.settings.host = sesh.settings.host; continue; - } else if (sesh.settings.newUser) { //propagate who joined the room too - updateObj.settings.users = sesh.settings.users; - updateObj.settings.host = sesh.settings.host; - sesh.settings.newUser = false; } - if(user !== sesh.settings.host) { //the host will receive the oneWay data - oneWayData[user] = {}; + if(user !== sesh.settings.host) { + privateData[user] = {}; for(const prop in sesh.settings.propnames) { - if(prop in this.users[user]) { - if(sesh.data?.oneWay && !(user in sesh.data.oneWay)) { - if(typeof this.users[user][prop] === 'object') - oneWayData[user][prop] = this.recursivelyAssign({},this.users[user][prop]); - else oneWayData[user][prop] = this.users[user][prop]; - } else if(typeof oneWayData[user][prop] === 'object' && sesh.data) { - if(prop in this.users[user][prop] && (stringifyFast(sesh.data?.shared[user][prop]) !== stringifyFast(this.users[user][prop]) || !(prop in sesh.data))) - oneWayData[user][prop] = this.users[user][prop]; + if(this.users[user][prop]) { + if(sesh.data?.private && !(user in sesh.data.private)) { + if(typeof this.users[user][prop] === 'object') privateData[user][prop] = this.recursivelyAssign({},this.users[user][prop]); + else privateData[user][prop] = this.users[user][prop]; + } else if(typeof privateData[user][prop] === 'object' && sesh.data) { + if(this.users[user][prop] && (stringifyFast(sesh.data?.shared[user][prop]) !== stringifyFast(this.users[user][prop]) || !(prop in sesh.data))) + privateData[user][prop] = this.users[user][prop]; } - else if(this.users[user][prop] && sesh.data?.oneWay?.[prop] !== this.users[user][prop]) - oneWayData[user][prop] = this.users[user][prop]; - } else if (sesh.data?.oneWay?.[user] && prop in sesh.data?.oneWay?.[user]) - delete sesh.data.oneWay[user][prop]; //if user deleted the prop, session can delete it + else if(this.users[user][prop] && sesh.data?.private?.[prop] !== this.users[user][prop]) + privateData[user][prop] = this.users[user][prop]; + } else if (sesh.data?.private?.[user]?.[prop]) delete sesh.data.private[user][prop]; //if user deleted the prop, session can delete it } - if(Object.keys(oneWayData[user]).length === 0) - delete oneWayData[user]; - } else { //the rest of the users will receive the shared data + if(Object.keys(privateData[user]).length === 0) delete privateData[user]; + } else { sharedData[user] = {}; for(const prop in sesh.settings.hostprops) { - if(prop in this.users[user]) { + if(this.users[user][prop]) { if(sesh.data && !(user in sesh.data.shared)) { - if(typeof this.users[user][prop] === 'object') - sharedData[user][prop] = this.recursivelyAssign({},this.users[user][prop]); + if(typeof this.users[user][prop] === 'object') sharedData[user][prop] = this.recursivelyAssign({},this.users[user][prop]); else sharedData[user][prop] = this.users[user][prop]; } else if(typeof sharedData[user][prop] === 'object' && sesh.data) { - if((stringifyFast(sesh.data?.shared[user][prop]) !== stringifyFast(this.users[user][prop]) || !(prop in sesh.data.shared[user]))) + if(this.users[user][prop] && (stringifyFast(sesh.data?.shared[user][prop]) !== stringifyFast(this.users[user][prop]) || !(prop in sesh.data.shared[user]))) sharedData[user][prop] = this.users[user][prop]; - } else if(sesh.data?.shared[user][prop] !== this.users[user][prop]) + } + else if(this.users[user][prop] && sesh.data?.shared[user][prop] !== this.users[user][prop]) sharedData[user][prop] = this.users[user][prop]; - } else if (sesh.data?.shared[user] && prop in sesh.data?.shared[user]) - delete sesh.data.shared[user][prop]; //if user deleted the prop, session can delete it + } else if (sesh.data?.shared[user]?.[prop]) delete sesh.data.shared[user][prop]; //if user deleted the prop, session can delete it } } } - if(Object.keys(oneWayData).length > 0) { - updateObj.data.oneWay = oneWayData; + if(Object.keys(privateData).length > 0) { + updateObj.data.private = privateData; } if(Object.keys(sharedData).length > 0) { updateObj.data.shared = sharedData; } - } else { //all users receive the same update via shared data when no host set + } else { //all users receive the same update when no host set const sharedData = {}; //users receive all other user's props if(sesh.settings?.users) { for(const user in sesh.settings.users) { - if(!this.users[user]) { //if no user found assume they're to be kicked from session + if(!this.users[user]) { delete sesh.settings.users[user]; //dont need to delete admins, mods, etc as they might want to come back <_< - if( sesh.settings.host === user ) - this.swapHost(sesh, undefined, true); - if( sesh.data?.shared[user] ) - delete sesh.data.shared[user]; - if( sesh.data?.oneWay?.[user] ) - delete sesh.data.shared[user]; + if( sesh.data?.shared[user]) delete sesh.data.shared[user]; + if( sesh.data?.private?.[user]) delete sesh.data.shared[user]; + if(sesh.settings.host === user) this.swapHost(sesh); updateObj.settings.users = sesh.settings.users; updateObj.settings.host = sesh.settings.host; continue; } sharedData[user] = {}; for(const prop in sesh.settings.propnames) { - if(prop in this.users[user]) { + if(this.users[user][prop]) { if(sesh.data && !(user in sesh.data.shared)) { if(typeof this.users[user][prop] === 'object') sharedData[user][prop] = this.recursivelyAssign({},this.users[user][prop]); else sharedData[user][prop] = this.users[user][prop]; - } else if(typeof sesh.data?.shared[user]?.[prop] === 'object') { + } else if(typeof sesh.data?.shared[user][prop] === 'object') { if((stringifyFast(sesh.data.shared[user][prop]) !== stringifyFast(this.users[user][prop]) || !(prop in sesh.data.shared[user]))) { //if(stringifyFast(this.users[user][prop]).includes('peer')) console.log(stringifyFast(this.users[user][prop])) sharedData[user][prop] = this.users[user][prop]; } - } else if(sesh.data?.shared[user]?.[prop] !== this.users[user][prop]) + } + else if(sesh.data?.shared[user][prop] !== this.users[user][prop]) sharedData[user][prop] = this.users[user][prop]; - } else if (sesh.data?.shared[user] && prop in sesh.data?.shared[user]) - delete sesh.data.shared[user][prop]; //if user deleted the prop, session can delete it + } else if (sesh.data?.shared[user]?.[prop]) delete sesh.data.shared[user][prop]; //if user deleted the prop, session can delete it } if(Object.keys(sharedData[user]).length === 0) delete sharedData[user]; } @@ -806,26 +503,24 @@ export class SessionsService extends Service { //console.log(sharedData); updateObj.data.shared = sharedData; } - } + } } - if(updateObj.data.shared || updateObj.data.oneWay) { + if(updateObj.data.shared || updateObj.data.private) updates.shared[sesh._id as string] = updateObj; - if(updateObj.data.shared) { - Object.assign(this.sessions.shared[session].data?.shared, updateObj.data.shared); - //set latest data on the source object as reference - } - if(updateObj.data.oneWay) { - Object.assign(this.sessions.shared[session].data?.oneWay, updateObj.data.oneWay); - //set latest data on the source object as reference - } - if(sessionHasUpdate) sessionHasUpdate(sesh,updateObj); - if(sesh.settings.onhasupdate) sesh.settings.onhasupdate(sesh,updateObj); + + if(updateObj.data.shared) { + this.recursivelyAssign(this.sessions.shared[session].data?.shared,updateObj.data.shared) + //set latest data on the source object as reference + } + if(updateObj.data.private) { + this.recursivelyAssign(this.sessions.shared[session].data?.private,updateObj.data.private) + //set latest data on the source object as reference } } - if(Object.keys(updates.oneWay).length === 0) delete updates.oneWay; + if(Object.keys(updates.private).length === 0) delete updates.private; if(Object.keys(updates.shared).length === 0) delete updates.shared; if(Object.keys(updates).length === 0) return undefined; @@ -838,82 +533,91 @@ export class SessionsService extends Service { } - //transmit updates to users and setState locally based on userId. Todo: this could be more efficient + //transmit updates to users and setState locally based on userId transmitSessionUpdates = (updates:{ - oneWay:{[key:string]:any}, + private:{[key:string]:any}, shared:{[key:string]:any} }) => { let users = {}; - if(updates.oneWay) { - for(const s in updates.oneWay) { //oneWay session ids - let session = this.sessions.oneWay[s]; + if(updates.private) { + for(const s in updates.private) { + let session = this.sessions.private[s]; if(session?.settings) { - let u = session.settings.listener; //single user listener - if(!users[u]) users[u] = {}; - users[u].oneWay[s] = updates.oneWay[s]; + let u = session.settings.listener; + if(!users[u]) users[u] = {private:{}}; + else if(!users[u].private) users[u].private = {}; + users[u].private[s] = updates.private[s]; } } } if(updates.shared) { - for(const s in updates.shared) { //shared session ids + for(const s in updates.shared) { let session = this.sessions.shared[s]; if(session?.settings) { - for(const u in session.settings.users) { //for users in session - if(!users[u]) users[u] = {}; - users[u].shared[s] = updates.shared[s]; + let copy; + if(session.settings.host) { + copy = Object.assign({},updates.shared[s]); + delete copy.data.private; + } + for(const u in session.settings.users) { + if(!users[u]) users[u] = {shared:{}}; + else if(!users[u].shared) users[u].shared = {}; + if(session.settings.host) { + if(u !== session.settings.host) { + users[u].shared[s] = copy; + } else users[u].shared[s] = updates.shared[s]; + } + else users[u].shared[s] = updates.shared[s]; } } } } - //each user will receive an update for all sessions they are subscribed to //console.log(users) let message = {route:'receiveSessionUpdates', args:null as any} for(const u in users) { message.args = [u, users[u]]; - if((this.users[u] as any)?.send) (this.users[u] as any).send(JSON.stringify(message)); + if((this.users[u] as any).send) (this.users[u] as any).send(JSON.stringify(message)); this.setState({[u]:Object.create(message)}) } return users; } - //receive updates as a user - receiveSessionUpdates = (origin:any, update:{oneWay:{[key:string]:any},shared:{[key:string]:any}}|string) => { //following operator format we get the origin passed + //receive updates as users + receiveSessionUpdates = (origin:any, update:{private:{[key:string]:any},shared:{[key:string]:any}}|string) => { //following operator format we get the origin passed if(update) if(typeof update === 'string') update = JSON.parse(update as string); if(typeof update === 'object') { let user = this.users[origin]; - if(user) { - if(!user.sessions) user.sessions = {oneWay:{},shared:{}}; - if(!user.sessionSubs) user.sessionSubs = {}; - } - - if(update.oneWay) { - for(const key in update.oneWay) { - this.recursivelyAssign(this.sessions.oneWay[key].data, update.oneWay[key].data); - if(this.sessions.oneWay[key]?.settings.onmessage) - this.sessions.oneWay[key].settings.onmessage(this.sessions.oneWay[key], update.oneWay[key]); - if(user?.sessionSubs[user._id]?.[key]?.onmessage) - user.sessionSubs[user._id][key].onmessage(user.sessions[key], update, user); + if(!user) return undefined; + if(!user.sessions) user.sessions = {}; + + if(update.private) { + for(const key in update.private) { + if(!user.sessions[key]) continue; + this.recursivelyAssign(user.sessions[key].data,update.private[key].data); + if(user.sessions[key].onmessage) + user.sessions[key].onmessage(user.sessions[key],user._id) } } if(update.shared) { for(const key in update.shared) { - if(update.shared[key].settings.users) this.sessions.shared[key].settings.users = update.shared[key].settings.users; - if(update.shared[key].settings.host) this.sessions.shared[key].settings.host = update.shared[key].settings.host; - if(update.shared[key].data.oneWay) this.recursivelyAssign(this.sessions.shared[key].data.oneWay, update.shared[key].data.oneWay); - if(update.shared[key].data.shared) this.recursivelyAssign(this.sessions.shared[key].data.shared, update.shared[key].data.shared); - if(this.sessions.shared[key]?.settings.onmessage) - this.sessions.shared[key].settings.onmessage(this.sessions.shared[key], update.shared[key]); - if(user?.sessionSubs[user._id]?.[key]?.onmessage) - user.sessionSubs[user._id][key].onmessage(user.sessions[key], update, user); + if(!user.sessions[key]) continue; + if(update.shared[key].settings.users) user.sessions[key].settings.users = update.shared[key].settings.users; + if(update.shared[key].settings.host) user.sessions[key].settings.host = update.shared[key].settings.host; + if(update.shared[key].data.private) this.recursivelyAssign(user.sessions[key].data.private, update.shared[key].data.private); + if(update.shared[key].data.shared) this.recursivelyAssign(user.sessions[key].data.shared, update.shared[key].data.shared); + if(user.sessions[key].onmessage) + user.sessions[key].onmessage(user.sessions[key],user._id) } } return user; } } + //you either need to run this loop on a session to + // pass updates up to the server from your user manually getUpdatedUserData = (user:SessionUser) => { const updateObj = {}; for(const key in user.sessions) { @@ -962,8 +666,7 @@ export class SessionsService extends Service { } //e.g. run on frontend - userUpdateCheck = (user:SessionUser, onupdate?:(user:SessionUser, updateObj:{[key:string]:any})=>void) => { - //console.log('checking',user, this); + userUpdateCheck = (user:SessionUser) => { if(user.sessions) { const updateObj = this.getUpdatedUserData(user); @@ -972,8 +675,7 @@ export class SessionsService extends Service { if(Object.keys(updateObj).length > 0) { let message = { route:'setUserProps', args:[user._id, updateObj] }; if(user.send) user.send(message); - this.setState({[user._id]:message}); - if(onupdate) { onupdate(user, updateObj) }; + this.setState({[user._id]:message}) return updateObj; } } @@ -995,17 +697,6 @@ export class SessionsService extends Service { return true; } - userUpdateLoop = { //this node loop will run separately from the one below it - __operator:this.userUpdateCheck, - __node:{loop:10}//this will set state each iteration so we can trigger subscriptions on session updates :O - } - - sessionLoop = { - __operator:this.sessionUpdateCheck, - __node:{loop:10}//this will set state each iteration so we can trigger subscriptions on session updates :O - } - - //more general object streaming //more rudimentary object streaming than the above sessions @@ -1169,7 +860,7 @@ export class SessionsService extends Service { // if(!settings.callback) settings.callback = this.STREAMALLLATEST; - this.subscribe(streamName, (res:any)=>{ + this.subscribe('streamName',(res:any)=>{ if(this.streamSettings[streamName].onupdate) (this.streamSettings[streamName] as any).onupdate(res,this.streamSettings[streamName]); }); @@ -1188,7 +879,7 @@ export class SessionsService extends Service { //can remove a whole stream or just a key from a stream if supplied removeStream = (streamName,key) => { - if(streamName && this.streamSettings[streamName] && !key) { + if(streamName && !key) { if(this.streamSettings[streamName].onclose) (this.streamSettings[streamName] as any).onclose(this.streamSettings[streamName]); this.unsubscribe(streamName); //remove the subscriptions to this stream @@ -1241,9 +932,42 @@ export class SessionsService extends Service { } - streamLoop = { - __operator:this.getAllStreamUpdates, - __node:{loop:10} + + routes:Routes = { + getSessionInfo:this.getSessionInfo, + openPrivateSession:this.openPrivateSession, + openSharedSession:this.openSharedSession, + updateSession:this.updateSession, + joinSession:this.joinSession, + setUserProps:this.setUserProps, + leaveSession:this.leaveSession, + getFirstMatch:this.getFirstMatch, + swapHost:this.swapHost, + deleteSession:this.deleteSession, + subscribeToSession:this.subscribeToSession, + transmitSessionUpdates:this.transmitSessionUpdates, + receiveSessionUpdates:this.receiveSessionUpdates, + getUpdatedUserData:this.getUpdatedUserData, + userUpdateCheck:this.userUpdateCheck, + userUpdateLoop:{ //this node loop will run separately from the one below it + operator:this.userUpdateCheck, + loop:10//this will set state each iteration so we can trigger subscriptions on session updates :O + }, + sessionLoop:{ + operator:this.sessionUpdateCheck, + loop:10//this will set state each iteration so we can trigger subscriptions on session updates :O + }, + setStreamFunc:this.setStreamFunc, + addStreamFunc:this.addStreamFunc, + setStream:this.setStream, + removeStream:this.removeStream, + updateStreamData:this.updateStreamData, + getStreamUpdate:this.getStreamUpdate, + getAllStreamUpdates:this.getAllStreamUpdates, + streamLoop:{ + operator:this.getAllStreamUpdates, + loop:10 + } } diff --git a/src/services/sse/SSE.browser.ts b/services/sse/SSE.browser.ts similarity index 83% rename from src/services/sse/SSE.browser.ts rename to services/sse/SSE.browser.ts index cdd35c15..814b48db 100644 --- a/src/services/sse/SSE.browser.ts +++ b/services/sse/SSE.browser.ts @@ -1,5 +1,5 @@ import { HTTPfrontend, RequestOptions } from "../http/HTTP.browser"; -import { Service, ServiceMessage, ServiceOptions } from "../Service"; +import { Service, Routes, ServiceOptions, ServiceMessage } from "../Service"; export type EventSourceProps = { url:string, @@ -27,7 +27,7 @@ export type EventSourceInfo = { request:(message:any, method?:string)=>Promise, post:(route:any, args?:any)=>void, run:(route:any, args?:any, method?:string)=>Promise, - subscribe:(route:any, callback?:((res:any)=>void)|string, args?:any[], key?:string, subInput?:boolean)=>any, + subscribe:(route:any, callback?:((res:any)=>void)|string)=>any, unsubscribe:(route:any, sub:number)=>Promise, terminate:() => void, graph:SSEfrontend @@ -47,7 +47,7 @@ export class SSEfrontend extends Service { constructor(options?:ServiceOptions) { super(options); - this.load(this); + this.load(this.routes); } openSSE = ( @@ -64,36 +64,26 @@ export class SSEfrontend extends Service { if(!('keepState' in options)) options.keepState = true; //default true if(!options.events) options.events = {}; - let close; if(options.events.close) { - close = options.events.close; + let close = options.events.close; + options.events.close = (ev) => { if(sse.onclose) sse.onclose(ev,sse); close(ev,sse); }; } - options.events.close = (ev) => { - if(sse.onclose) sse.onclose(ev, sse); - if(close) close(ev,sse); - delete this.eventsources[options.url]; - }; - - let open; if(options.events.open) { - open = options.events.open; + let open = options.events.open; + options.events.open = (ev) => { if(sse.onopen) sse.onopen(ev,sse); open(ev,sse); }; } - options.events.open = (ev) => { if(sse.onopen) sse.onopen(ev,sse); if(open) open(ev,sse); }; - - let error; if(options.events.error) { - error = options.events.error; + let error = options.events.error; + options.events.error = (ev) => { if(sse.onerror) sse.onerror(ev,sse); error(ev,sse); }; } - options.events.error = (ev) => { if(sse.onerror) sse.onerror(ev,sse); if(error) error(ev,sse); }; - - let message; if(options.events.message) { - message = options.events.message; + let message = options.events.message; + options.events.message = (ev) => { if(sse.onmessage) sse.onmessage(ev,sse); message(ev,sse); }; } - if(!sse.onmessage) { - //default hook - sse.onmessage = (ev, sse) => { + if(!options.events.message) { + options.events.message = (ev, sse) => { + let data = ev.data; if(data) if(typeof data === 'string') { @@ -103,7 +93,7 @@ export class SSEfrontend extends Service { if(data[0] === '"') { data = data.substring(1,data.length-1)}; //console.log(message) data = JSON.parse(data); //parse stringified objects - + if(data.route === 'setId' && sse) { sse._id = data.args; options.events.message = (e, sse) => { //clear extra logic after id is set @@ -113,18 +103,11 @@ export class SSEfrontend extends Service { } } } - + const result = this.receive(ev.data,sse); - if(options.keepState) this.setState({[options.url]:data}); + if(options.keepState) this.setState({[options.url]:data}); } } - - options.events.message = (ev) => { - if(sse.onmessage) sse.onmessage(ev,sse); - if(message) message(ev,sse); - }; - - if(!options.events.error) options.events.error = (ev, sse) => { this.terminate(sse as any); delete this.eventsources[options.url]; @@ -151,7 +134,7 @@ export class SSEfrontend extends Service { } let request = (message:ServiceMessage|any, method?:string, sessionId?:string) => { - return this.request(message, options.url, method, sessionId); + return this.request(message, options.url, sessionId, method); } let post = (route:any, args?:any, method?:string) => { @@ -169,8 +152,8 @@ export class SSEfrontend extends Service { return this.request({route,args}, options.url, method, sessionId); } - let subscribe = (route:any, callback?:((res:any)=>void)|string, args?:any[], key?:string, subInput?:boolean):Promise => { - return this.subscribeToSSE(route, options.url, callback, args, key, subInput, sse._id); + let subscribe = (route:any, callback?:((res:any)=>void)|string):Promise => { + return this.subscribeToSSE(route, options.url, callback, sse._id); } let unsubscribe = (route:any, sub:number):Promise => { @@ -196,15 +179,13 @@ export class SSEfrontend extends Service { return sse; } - open = this.openSSE; - POST = ( message:any|ServiceMessage, url:string|URL='http://localhost:8080/echo', type:XMLHttpRequestResponseType='', mimeType?:string|undefined ) => { - if(typeof message === 'number' || (typeof message === 'object' && !message.byteLength && (type === 'json' || type === 'text' || !type))) { + if(typeof message === 'object' && (type === 'json' || type === 'text' || !type)) { message = JSON.stringify(message); } @@ -285,22 +266,15 @@ export class SSEfrontend extends Service { return res; } - subscribeSSE = ( - route:string, - url:string, - args?:any[], - key?:string, - subInput?:boolean - ) => { - if(this.restrict?.[route]) return undefined; + subscribeSSE = (route:string,url:string) => { return this.subscribe(route,(res) => { this.POST(res,url,'json'); - },args,key,subInput) + }) } - subscribeToSSE = (route:string, url:string, callback?:string|((res:any)=>void), args?:any[], key?:string, subInput?:boolean, sessionId?:string) => { + subscribeToSSE = (route:string, url:string, callback?:string|((res:any)=>void), sessionId?:string) => { if(url) { - this.__node.state.subscribeEvent(url,(res) => { + this.subscribe(url,(res) => { let msg = JSON.parse(res); if(msg?.callbackId === route) { if(!callback) this.setState({[url]:msg.args}); //just set state @@ -311,7 +285,7 @@ export class SSEfrontend extends Service { } }); - return this.eventsources[url].run('subscribeSSE',[route,url,args,key,subInput,sessionId]); + return this.eventsources[url].run('subscribeSSE',[route,url,sessionId]) } } @@ -333,4 +307,17 @@ export class SSEfrontend extends Service { } } + routes:Routes = { + openSSE:{ + operator:this.openSSE, + aliases:['open'] + }, + request:this.request, + runRequest:this.runRequest, + transmit:this.transmit, + POST:this.POST, + terminate:this.terminate, + subscribeToSSE:this.subscribeToSSE, //outgoing subscriptions + subscribeSSE:this.subscribeSSE, //incoming subcriptions + } } \ No newline at end of file diff --git a/src/services/sse/SSE.node.ts b/services/sse/SSE.node.ts similarity index 88% rename from src/services/sse/SSE.node.ts rename to services/sse/SSE.node.ts index f4a26ce5..6806ec66 100644 --- a/src/services/sse/SSE.node.ts +++ b/services/sse/SSE.node.ts @@ -1,5 +1,5 @@ -import { Service, ServiceMessage, ServiceOptions } from "../Service"; -import {createSession, createChannel, Session, Channel} from 'better-sse'; //third party lib. SSEs really just push notifications to an http endpoint but it's minimal overhead +import { Routes, Service, ServiceMessage, ServiceOptions } from "../Service"; +import {createSession, createChannel, Session, SessionState, Channel} from 'better-sse'; //third party lib. SSEs really just push notifications to an http endpoint but it's minimal overhead import http from 'http' import https from 'https' import { Readable } from "node:stream"; @@ -21,14 +21,14 @@ export type SSEProps = { export type SSEChannelInfo = { channel: Channel>, sessions:{ - [key:string]:Session + [key:string]:Session }, requests:{[key:string]:Function}, //outstanding request promises send:(message:any, eventName?:string, sessionId?:string)=>any, request:(message:any, method?:string, sessionId?:string, eventName?:string)=>Promise|Promise[], post:(route:any, args?:any, method?:string, sessionId?:string, eventName?:string)=>void, run:(route:any, args?:any, method?:string, sessionId?:string, eventName?:string)=>Promise|Promise[], - subscribe:(route:any, callback?:((res:any)=>void)|string,args?:any[],key?:string,subInput?:boolean,sessionId?:string,eventName?:string)=>Promise|Promise[]|undefined, + subscribe:(route:any, callback?:((res:any)=>void)|string, sessionId?:string)=>Promise|Promise[]|undefined, unsubscribe:(route:any, sub:number, sessionId?:string, eventName?:string)=>Promise|Promise[], terminate:() => boolean, _id:string, @@ -37,14 +37,13 @@ export type SSEChannelInfo = { export type SSEClientInfo = { _id:string, - session:Session, + session:Session, served:SSEChannelInfo, send:(message:any, eventName?:string)=>any, request:(message:any, method?:string, eventName?:string)=>Promise, post:(route:any, args?:any, method?:string, eventName?:string)=>void, run:(route:any, args?:any, method?:string, eventName?:string)=>Promise, - subscribe:(route:any, callback?:((res:any)=>void)|string, - args?:any[],key?:string,subInput?:boolean,sessionId?:string,eventName?:string)=>any, + subscribe:(route:any, callback?:((res:any)=>void)|string)=>any, unsubscribe:(route:any, sub:number, eventName?:string)=>Promise, terminate:() => boolean, onclose?:(session:any,sseinfo:any,_id:string,req:http.IncomingMessage,res:http.ServerResponse)=>void, @@ -72,10 +71,10 @@ export class SSEbackend extends Service { constructor(options?:ServiceOptions) { super(options) - this.load(this); + this.load(this.routes); } - openSSE = (options:SSEProps) => { + setupSSE = (options:SSEProps) => { const server = options.server; let path = options.path; @@ -98,7 +97,9 @@ export class SSEbackend extends Service { sse._id = options._id ? options._id : path; - + if(!sse.onconnectionclose) sse.onconnectionclose = (session,sse,id,req,res) => { + delete sse.sessions[id]; + } const send = ( message:any, //the data you want to send @@ -146,10 +147,8 @@ export class SSEbackend extends Service { return this.request(r, path, method, sessionId, eventName) } - let subscribe = (route:any, callback?:((res:any)=>void)|string, - args?:any[],key?:string,subInput?:boolean, - sessionId?:string, eventName?:string):Promise|Promise[]|undefined => { - return this.subscribeToSSE(route, options.url, callback, args, key, subInput, sessionId, eventName); + let subscribe = (route:any, callback?:((res:any)=>void)|string, sessionId?:string):Promise|Promise[]|undefined => { + return this.subscribeToSSE(route, options.url, callback, sessionId); } let unsubscribe = (route:any, sub:number, sessionId?:string, eventName?:string):Promise|Promise[] => { @@ -194,7 +193,7 @@ export class SSEbackend extends Service { return run(route,args,method,_id,eventName); }, subscribe:(route,callback?)=>{ - return subscribe(route,callback,undefined,_id); + return subscribe(route,callback,_id); }, unsubscribe:(route,sub,eventName?)=>{ return unsubscribe(route,sub,_id,eventName); @@ -204,22 +203,12 @@ export class SSEbackend extends Service { delete sse.sessions[_id]; return true; }, - onclose:(session,sse,_id,req,res)=>{ - if(sse.onconnectionclose) sse.onconnectionclose(session,sse,_id,req,res); - }, + onclose:()=>options.onconnectionclose, graph:this } as SSEClientInfo; session.push(JSON.stringify({route:'setId',args:_id})); //associate this user's connection with a server generated id - session.on('close',()=>{ - let obj = this.eventsources[_id]; - let onclose = obj.onclose; - - delete this.eventsources[_id]; - - if(onclose) - (obj as any).onclose(session,sse,_id,req,response); - }) + session.on('close',()=>{if(this.eventsources[_id].onclose) (this.eventsources[_id] as any).onclose(session,sse,_id,req,response)}) if(sse.onconnection) {sse.onconnection(session,sse,_id,req,response);} }); @@ -249,7 +238,7 @@ export class SSEbackend extends Service { if(typeof body.route === 'string') { if(body.route.includes('/') && body.route.length > 1) body.route = body.route.split('/').pop(); - route = this.__node.roots?.[body.route]; + route = this.routes[body.route]; } } @@ -258,7 +247,7 @@ export class SSEbackend extends Service { } else if (callbackId && sse.requests[callbackId]) { sse.requests[callbackId](args); } - if(this.__node.keepState) this.setState({[path]:body}); + if(this.keepState) this.setState({[path]:body}); }); } } @@ -295,8 +284,6 @@ export class SSEbackend extends Service { } - open = this.openSSE; - streamIterable = ( path:string, iterable:Iterable|AsyncIterable, @@ -347,8 +334,8 @@ export class SSEbackend extends Service { eventName?:string, //event name? default is 'message' sessionId?:string //particular client? ) => { - if(!path && ((typeof data === 'object' && !data.byteLength) || typeof data === 'number')) { - if(data?.route) { + if(!path && typeof data === 'object') { + if(data.route) { let keys = Object.keys(this.servers) if(keys.length > 0) { @@ -454,15 +441,13 @@ export class SSEbackend extends Service { subscribeSSE = ( route:string, path:string, - args?:any[],key?:string,subInput?:boolean, sessionId?:string, eventName?:string ) => { - if(this.restrict?.[route]) return undefined; if(this.servers[path]) { return this.subscribe(route, (res) => { this.servers[path].send({args:res, callbackId:route}, eventName, sessionId); - }, args, key, subInput); + }) } } @@ -470,12 +455,12 @@ export class SSEbackend extends Service { route:string, path:string, callback?:string|((res:any)=>void), - args?:any[],key?:string,subInput?:boolean, sessionId?:string, eventName?:string ) => { if(this.servers[path]) { - this.__node.state.subscribeEvent(path,(res) => { + + this.subscribe(path,(res) => { if(res?.callbackId === route) { if(!callback) this.setState({[path]:res.args}); //just set state else if(typeof callback === 'string') { //run a local node @@ -489,18 +474,18 @@ export class SSEbackend extends Service { if(this.servers[path].sessions[sessionId]) { return this.eventsources[sessionId].run( 'subscribeSSE', - {route:'subscribeSSE',args:[route,path,args,key,subInput]}, + {route:'subscribeSSE',args:[route,path]}, undefined, eventName ) as Promise } } else { let promises:Promise[] = []; - for(const k in this.servers[path].sessions) { + for(const key in this.servers[path].sessions) { promises.push( - this.eventsources[k].run( + this.eventsources[key].run( 'subscribeSSE', - {route:'subscribeSSE',args:[route,path,args,key,subInput]}, + {route:'subscribeSSE',args:[route,path]}, undefined, eventName ) as Promise @@ -521,4 +506,17 @@ export class SSEbackend extends Service { return true; } + routes:Routes = { + setupSSE:{ + operator:this.setupSSE, + aliases:['open'] + }, + terminate:this.terminate, + transmit:this.transmit, + request:this.request, + runRequest:this.runRequest, + streamReadable:this.streamReadable, + streamIterable:this.streamIterable + } + } \ No newline at end of file diff --git a/src/services/todo/BLE.service.ts b/services/todo/BLE.service.ts similarity index 100% rename from src/services/todo/BLE.service.ts rename to services/todo/BLE.service.ts diff --git a/src/services/todo/FS.browser.ts b/services/todo/FS.browser.ts similarity index 100% rename from src/services/todo/FS.browser.ts rename to services/todo/FS.browser.ts diff --git a/src/services/todo/FS.node.ts b/services/todo/FS.node.ts similarity index 100% rename from src/services/todo/FS.node.ts rename to services/todo/FS.node.ts diff --git a/src/services/todo/README.txt b/services/todo/README.txt similarity index 100% rename from src/services/todo/README.txt rename to services/todo/README.txt diff --git a/src/services/todo/Serial.service.ts b/services/todo/Serial.service.ts similarity index 100% rename from src/services/todo/Serial.service.ts rename to services/todo/Serial.service.ts diff --git a/services/unsafe/Unsafe.service.ts b/services/unsafe/Unsafe.service.ts new file mode 100644 index 00000000..897d1323 --- /dev/null +++ b/services/unsafe/Unsafe.service.ts @@ -0,0 +1,152 @@ +import { parseFunctionFromText } from "../../Graph" +import { Graph } from "../../Graph" +import { Service } from "../Service"; + +//Contains evals and other things you probably don't want wide open on an API +export const unsafeRoutes = { + + //add a route and parse it from text + setRoute:function(fn:string|((...args:[])=>any),fnName?:string){ + //console.log(fn, fnName) + //if(fnName === 'setupChart') console.log(fn); + if(typeof fn === 'string') fn = parseFunctionFromText(fn); + //if(fnName === 'setupChart') console.log(fn); + if(typeof fn === 'function') { + if(!fnName) fnName = fn.name; + if(this.graph.get(fnName)) { + this.graph.get(fnName).setOperator(fn.bind(this.graph.get(fnName))); //overwrite operator + } + else { + let node = (this.graph as Graph).add({tag:fnName,operator:fn}); + if(this.graph instanceof Service) this.graph.load({[fnName]:node}); + } + return true; + } + return false; + }, + setNode:function(fn:string|((...args:[])=>any),fnName?:string){ + //console.log(fn, fnName) + if(typeof fn === 'string') fn = parseFunctionFromText(fn); + //console.log(fn); + if(typeof fn === 'function') { + if(!fnName) fnName = fn.name; + if(this.graph.get(fnName)) { + this.graph.get(fnName).setOperator(fn); //overwrite operator + } + else (this.graph as Graph).add({tag:fnName,operator:fn}); + //console.log(this) + return true; + } + return false; + }, + setMethod:function(route:string,fn:string|((...args:[])=>any),fnName?:string){ //set a method on a route + //console.log(fn, fnName) + if(typeof fn === 'string') fn = parseFunctionFromText(fn); + //console.log(fn); + if(typeof fn === 'function') { + if(!fnName) fnName = fn.name; + if(this.graph.get(route)) { + this.graph.get(route)[fnName] = fn; //overwrite method + } + else (this.graph as Graph).add({tag:fnName,[fnName]:fn}); + //console.log(this) + return true; + } + return false; + }, + assignRoute:function(route:string,source:{[key:string]:any}) { //set values on a route + //console.log(fn, fnName) + if(this.graph.get(route) && typeof source === 'object') { + Object.assign(this.graph.get(route),source); + } + }, + transferClass:(classObj:any, className?:string)=>{ //send a class over a remote service + if(typeof classObj === 'object') { + let str = classObj.toString();//needs to be a class prototype + let message = {route:'receiveClass',args:[str,className]}; + + return message; + } + return false; + }, + receiveClass:function(stringified:string, className?:string){ //eval a class string and set it as a key on the local graph by class name, so this.graph.method exists + if(typeof stringified === 'string') { + //console.log(stringified) + if(stringified.indexOf('class') === 0) { + let cls = (0,eval)('('+stringified+')'); + let name = className; + + if(!name) + name = cls.name; //get classname + this.graph[name] = cls; + + return true; + } + } + return false; + }, + setGlobal:(key:string, value:any) => { //set a value on the globalThis scope + globalThis[key] = value; + return true; + }, + assignGlobalObject:(target:string, source:{[key:string]:any}) => { //assign a value on an object on the globalThis scope + if(!globalThis[target]) return false; + if(typeof source === 'object') Object.assign(globalThis[target],source); + return true; + }, + setValue:function(key:string, value:any) { //set a value on the globalThis scope + this.graph[key] = value; + return true; + }, + assignObject:function(target:string, source:{[key:string]:any}){ //assign a value on an object on the globalThis scope + if(!this.graph[target]) return false; + if(typeof source === 'object') Object.assign( this.graph[target],source); + return true; + }, + setGlobalFunction:(fn:any, fnName?:string) => { //set a value on the globalThis scope + if(typeof fn === 'string') fn = parseFunctionFromText(fn); + //console.log(fn); + if(typeof fn === 'function') { + if(!fnName) fnName = fn.name; + globalThis[fnName] = fn; + //console.log(this) + return true; + } + return false; + }, + assignFunctionToGlobalObject:function (globalObjectName:string, fn:any, fnName:any) { //assign a value on an object on the globalThis scope + if(! globalThis[globalObjectName]) return false; + if(typeof fn === 'string') fn = parseFunctionFromText(fn); + //console.log(fn); + if(typeof fn === 'function') { + if(!fnName) fnName = fn.name; + this.graph[globalObjectName][fnName] = fn; + //console.log(this) + return true; + } + return false; + }, + setFunction:function(fn:any, fnName?:string){ //set a value on the globalThis scope + if(typeof fn === 'string') fn = parseFunctionFromText(fn); + //console.log(fn); + if(typeof fn === 'function') { + if(!fnName) fnName = fn.name; + this.graph[fnName] = fn; + //console.log(this) + return true; + } + return false; + }, + assignFunctionToObject:function(objectName:string, fn:any, fnName:any) { //assign a value on an object on the globalThis scope + if(! this.graph[objectName]) return false; + if(typeof fn === 'string') fn = parseFunctionFromText(fn); + //console.log(fn); + if(typeof fn === 'function') { + if(!fnName) fnName = fn.name; + this.graph[objectName][fnName] = fn; + //console.log(this) + return true; + } + return false; + } +} \ No newline at end of file diff --git a/services/webrtc/WebRTC.browser.ts b/services/webrtc/WebRTC.browser.ts new file mode 100644 index 00000000..909c661f --- /dev/null +++ b/services/webrtc/WebRTC.browser.ts @@ -0,0 +1,553 @@ +import { Service, Routes, ServiceMessage, ServiceOptions } from "../Service"; + +export type WebRTCProps = { + _id?:string, + channels?:{ + [key:string]:(true|RTCDataChannelInit|RTCDataChannel) + }, + config?:RTCConfiguration, + hostdescription?:RTCSessionDescriptionInit|string, + peerdescription?:RTCSessionDescriptionInit|string, + offer?:RTCOfferOptions, + hostcandidates?:{[key:string]:RTCIceCandidate}, + peercandidates?:{[key:string]:RTCIceCandidate}, + answer?:RTCAnswerOptions, + ontrack?:(ev:RTCTrackEvent)=>void, + onicecandidate?:(ev:RTCPeerConnectionIceEvent)=>void, + onicecandidateerror?:(ev:Event)=>void, + onnegotiationneeded?:(ev:Event)=>void, + ondatachannel?:(ev:RTCDataChannelEvent)=>void, + ondata?:(ev:MessageEvent, channel:RTCDataChannel, room)=>void, + onconnectionstatechange?:(ev:Event)=>void, + oniceconnectionstatechange?:(ev:Event)=>void, + onclose?:(rtc:WebRTCInfo)=>void //custom callback +} + +export type WebRTCInfo = { + _id:string, + rtc:RTCPeerConnection, + send:(message:any)=>void, //these callbacks work on the first available data channel to call to other webrtc services + request:(message:any, method?:string)=>Promise, + post:(route:any, args?:any)=>void, + run:(route:any, args?:any, method?:string)=>Promise, + subscribe:(route:any, callback?:((res:any)=>void)|string)=>Promise, + unsubscribe:(route:any, sub:number)=>Promise, + terminate:()=>boolean, + graph:WebRTCfrontend +} & WebRTCProps + +//webrtc establishes secure P2P contexts between two users directly. +// However, we need a backend as a way to list available connections. +export class WebRTCfrontend extends Service { + + name='webrtc' + + rtc:{ + [key:string]:WebRTCInfo + } = {} + + iceServers:{urls:string[]}[] = [ + { urls: ['stun:stun.l.google.com:19302'] }, + { urls: ['stun:stun1.l.google.com:19302'] }, + { urls: ['stun:stun2.l.google.com:19302'] }, + { urls: ['stun:stun3.l.google.com:19302'] }, + { urls: ['stun:stun4.l.google.com:19302'] } + ]; + + connections = { //higher level reference for router + rtc:this.rtc + } + + constructor( + options?:ServiceOptions, + iceServers?:{urls:string[]}[] + ) { + super(options); + this.load(this.routes); + + if(iceServers) this.iceServers = iceServers; + } + + createStream = ( //use navigator.mediaDevices.getUserMedia({audio:true,video:true}) for audio/video streams + options:{ + [key:string]:{ + track:MediaStreamTrack|MediaTrackConstraints, + onended:(ev)=>void, + onmute:(ev)=>void, + onunmute:(ev)=>void + } + } + ) => { + let stream = new MediaStream(); + for(const key in options) { + let track = options[key].track; + if(!(track instanceof MediaStreamTrack) && typeof track === 'object') { + track = new MediaStreamTrack(); + track.applyConstraints(options[key].track as MediaTrackConstraints) + stream.addTrack(track); + } + + if(track instanceof MediaStreamTrack) { + stream.addTrack(track as MediaStreamTrack); + track.onmute = options[key].onmute; + track.onunmute = options[key].onunmute; + track.onended = options[key].onended; + + } + } + return stream; + } + + openRTC = async ( + options?:WebRTCProps + ):Promise => { + if(!options) options = {}; + if(!options._id) options._id = `rtc${Math.floor(Math.random()*1000000000000000)}`; + if(!options.config) options.config = {iceServers:this.iceServers}; + + let rtc = new RTCPeerConnection(options.config); + + + if(!this.rtc[options._id]) { + + if(!options.channels) options.channels = { 'data':true }; //need one channel at least for the default service stuff to work + + let firstChannel; + for(const key in options.channels) { + firstChannel = key; + break; + } + + let send = (message:any) => { + //console.log('sent', message) + return this.transmit(message,options._id,options.channels[firstChannel] as RTCDataChannel); + } + + let post = (route:any,args?:any, method?:string) => { + //console.log('sent', message) + let message:any = { + route, + args + }; + if(method) message.method = method; + + return this.transmit(message,options._id,options.channels[firstChannel] as RTCDataChannel); + } + + let run = (route:any,args?:any, method?:string):Promise => { + return new Promise ((res,rej) => { + let callbackId = Math.random(); + let req = {route:'runRequest', args:[{route, args}, options._id, callbackId]} as any; + //console.log(req) + if(method) req.args[0].method = method; + + let sub; + let ondata = (data:any)=>{ + if(typeof data === 'string' && data.indexOf('{') > -1) data = JSON.parse(data); + if(typeof data === 'object') { + if(data.callbackId === callbackId) { + //(options.channels[firstChannel] as RTCDataChannel).removeEventListener('message',onmessage); + this.unsubscribe(options._id,sub); + res(data.args); //resolve the request with the corresponding message + } + } + } + + sub = this.subscribe(options._id,ondata); + + //(options.channels[firstChannel] as RTCDataChannel).addEventListener('message',onmessage) + this.transmit(req, options._id,options.channels[firstChannel] as RTCDataChannel); + }); + } + + let request = (message:ServiceMessage|any, method?:string):Promise => { + return new Promise ((res,rej) => { + let callbackId = Math.random(); + let req = {route:'runRequest', args:[message,options._id,callbackId]} as any; + //console.log(req) + if(method) req.method = method; + + let sub; + let ondata = (data:any)=>{ + if(typeof data === 'string' && data.indexOf('{') > -1) data = JSON.parse(data); + if(typeof data === 'object') { + if(data.callbackId === callbackId) { + //(options.channels[firstChannel] as RTCDataChannel).removeEventListener('message',onmessage); + this.unsubscribe(options._id,sub); + res(data.args); //resolve the request with the corresponding message + } + } + } + + sub = this.subscribe(options._id,ondata); + this.transmit(req, options._id,options.channels[firstChannel] as RTCDataChannel); + }); + } + + let subscribe = (route:any, callback?:((res:any)=>void)|string) => { + return this.subscribeToRTC(route, options._id, firstChannel, callback); + } + + let unsubscribe = (route:any, sub:number) => { + return run('unsubscribe',[route,sub]); + } + + let terminate = () => { + return this.terminate(options._id); + } + + this.rtc[options._id] = { + rtc, + _id:options._id, + request, + run, + post, + send, + subscribe, + unsubscribe, + terminate, + graph:this, + ...options + } + + //console.log('opening webrtc channel',this.rtc) + if(!options.ondatachannel) options.ondatachannel = (ev:RTCDataChannelEvent) => { + this.rtc[options._id].channels[ev.channel.label] = ev.channel; + if(!options.ondata) { + ev.channel.addEventListener('message', (mev) => { + //console.log('message on data channel', mev); + this.receive(mev.data, ev.channel, this.rtc[options._id]); + this.setState({[options._id]:mev.data}); + }); + } + else ev.channel.addEventListener('message', (mev) => { options.ondata(mev.data, ev.channel, this.rtc[options._id]); }); + + } + + if(options.channels) { + for(const channel in options.channels) { + if(options.channels[channel] instanceof RTCDataChannel) { + //OK + } + else if( typeof options.channels[channel] === 'object') { + options.channels[channel] = this.addDataChannel(rtc,channel,(options.channels)[channel] as any); + } else { + options.channels[channel] = this.addDataChannel(rtc,channel); + } + + (options.channels[channel] as RTCDataChannel).addEventListener('message', (mev) => { + //console.log('message on data channel', mev); + this.receive(mev.data, channel, this.rtc[options._id]); + this.setState({[options._id]:mev.data}); + }); + } + } + + + rtc.ontrack = options.ontrack; + rtc.onicecandidate = options.onicecandidate; + rtc.onicecandidateerror = options.onicecandidateerror; + rtc.ondatachannel = options.ondatachannel; + rtc.onnegotiationneeded = options.onnegotiationneeded; + rtc.oniceconnectionstatechange = options.oniceconnectionstatechange; + rtc.onconnectionstatechange = options.onconnectionstatechange; + rtc.addEventListener('connectionstatechange', (ev) => { + if(rtc.connectionState === 'closed' || rtc.connectionState === 'failed') { + if(this.rtc[options._id].onclose) { + this.rtc[options._id].onclose(this.rtc[options._id]); + } + } + }) + + } else { + Object.assign(this.rtc[options._id],options); + } + + if(options.hostdescription && !options.peerdescription) { + if(!options.onicecandidate) options.onicecandidate = (ev:RTCPeerConnectionIceEvent) => { + if(ev.candidate) { + let icecandidate = ev.candidate; + + if(!this.rtc[options._id].peercandidates) this.rtc[options._id].peercandidates = {}; + this.rtc[options._id].peercandidates[`peercandidate${Math.floor(Math.random()*1000000000000000)}`] = icecandidate; + + } + } + + // console.log(options.hostdescription) + return await new Promise((res,rej) => { + //console.log('desc', options.hostdescription) + if(typeof options.hostdescription === 'string') { + options.hostdescription = JSON.parse(decodeURIComponent(options.hostdescription)); + } + const description = new RTCSessionDescription(options.hostdescription as RTCSessionDescriptionInit); + //console.log('desc2', description) + + options.hostdescription = description + rtc.setRemoteDescription(description).then(()=>{ + if(options.hostcandidates) { + for(const prop in options.hostcandidates) { + const candidate = new RTCIceCandidate(options.hostcandidates[prop]) + rtc.addIceCandidate(candidate).catch(console.error); + } + } + rtc.createAnswer(options.answer) + .then((answer)=> rtc.setLocalDescription(answer)) + .then(()=>{ + this.rtc[options._id].peerdescription = encodeURIComponent(JSON.stringify(rtc.localDescription)); + res(this.rtc[options._id]); + }); + }).catch(rej); //we can now receive data + }); + } + + if(options.peerdescription) { + this.answerPeer(rtc,options); + } + + if(!options.onicecandidate && !this.rtc[options._id]?.onicecandidate) options.onicecandidate = (ev:RTCPeerConnectionIceEvent) => { + if(ev.candidate) { + let icecandidate = ev.candidate; + + if(!this.rtc[options._id].hostcandidates) this.rtc[options._id].hostcandidates = {}; + this.rtc[options._id].hostcandidates[`hostcandidate${Math.floor(Math.random()*1000000000000000)}`] = icecandidate; + + } + } + + return await new Promise((res,rej) => { + rtc.createOffer(options.offer) + .then((offer) => rtc.setLocalDescription(offer)) + .then(()=>{ + this.rtc[options._id].hostdescription = encodeURIComponent(JSON.stringify(rtc.localDescription)); + res(this.rtc[options._id]); //this is to be transmitted to the user + }); + }); + + } + + addIceCandidate(rtc:RTCPeerConnection, candidate:RTCIceCandidate) { + return rtc.addIceCandidate(candidate); + } + + //use the + answerPeer(rtc:RTCPeerConnection,options:WebRTCProps) { + return new Promise((res,rej) => { + if(typeof options.peerdescription === 'string') { + options.peerdescription = JSON.parse(decodeURIComponent(options.peerdescription)); + } + const description = new RTCSessionDescription(options.peerdescription as RTCSessionDescriptionInit); + options.peerdescription = description; + + if(this.rtc[options._id]) this.rtc[options._id].peerdescription = description; + rtc.setRemoteDescription(description).then(()=>{ + if(options.peercandidates) { + for(const prop in options.peercandidates) { + const candidate = new RTCIceCandidate(options.peercandidates[prop]) + if(this.rtc[options._id]) this.rtc[options._id].peercandidates[prop] = options.peercandidates[prop]; + rtc.addIceCandidate(candidate).catch(console.error); + } + } + res(this.rtc[options._id] ? this.rtc[options._id] : rtc); + }).catch(rej); //we can now receive data + }); + } + + addUserMedia = ( + rtc:RTCPeerConnection, + options:MediaStreamConstraints={ + audio:false, + video:{ + optional:[ + {minWidth: 320}, + {minWidth: 640}, + {minWidth: 1024}, + {minWidth: 1280}, + {minWidth: 1920}, + {minWidth: 2560}, + ] + } as MediaTrackConstraints + } + ) => { + let senders:any[] = []; + navigator.mediaDevices.getUserMedia(options) + .then((stream) => { + let tracks = stream.getTracks() + tracks.forEach((track) => { + senders.push(rtc.addTrack(track,stream)); + }); + } + ) + return senders; + } + + //add media streams to the dat channel + addTrack = (rtc:RTCPeerConnection, track:MediaStreamTrack, stream:MediaStream) => { + rtc.addTrack(track,stream); + return true; + } + + removeTrack = (rtc:RTCPeerConnection,sender:RTCRtpSender) => { + rtc.removeTrack(sender); //e.g. remove the senders removed by addUserMedia + return true; + } + + addDataChannel = ( //send arbitrary strings + rtc:RTCPeerConnection, + name:string, + options?:RTCDataChannelInit//{ negotiated: false } + ) => { + return rtc.createDataChannel(name,options); + } + + //send data on a data channel + transmit = (data:ServiceMessage|any, id?:string, channel?:string|RTCDataChannel ) => { + if(typeof data === 'object' || typeof data === 'number') + data = JSON.stringify(data); //we need strings + + if(!channel && id) { //select first channel + let keys = Object.keys(this.rtc[id].channels); + if(keys[0]) + channel = this.rtc[id].channels[keys[0]] as RTCDataChannel; + } + + if(typeof channel === 'string') { + if(id) { + channel = this.rtc[id].channels[channel] as RTCDataChannel; + } else { //send on all channels on all rooms + for(const id in this.rtc) { + if(this.rtc[id].channels[channel] instanceof RTCDataChannel) + (this.rtc[id].channels[channel] as RTCDataChannel).send(data); + } + } + } + + if(channel instanceof RTCDataChannel) + channel.send(data); + + //console.log('sending',channel,data) + + return true; + } + + //close a channel + terminate = (rtc:RTCPeerConnection|WebRTCInfo|string) => { + let tx; + if(typeof rtc === 'string') { + let room = this.rtc[rtc]; + delete this.rtc[rtc]; + if(room) { + tx = room.rtc; + } + } + else if (typeof rtc === 'object') { + tx = (rtc as WebRTCInfo).rtc; + } + + if(rtc instanceof RTCPeerConnection) { + rtc.close(); + } else if(tx) { + if(tx) tx.close(); + } + + return true; + } + + request = (message:ServiceMessage|any, channel:RTCDataChannel, _id:string,method?:string) => { //return a promise which can resolve with a server route result through the socket + let callbackId = `${Math.random()}`; + let req:any = {route:'runRequest', args:[message,_id,callbackId]}; + if(method) req.method = method; + return new Promise((res,rej) => { + let onmessage = (ev:any) => { + let data = ev.data; + if(typeof data === 'string' && data.indexOf('{') > -1) data = JSON.parse(ev.data); + if(typeof data === 'object') if(data.callbackId === callbackId) { + channel.removeEventListener('message',onmessage); + res(data.args); + } + } + + channel.addEventListener('message',onmessage); + channel.send(JSON.stringify(req)); + }); + } + + runRequest = (message:any, channel:RTCDataChannel|string, callbackId:string|number) => { //send result back + let res = this.receive(message); + if(channel) { + if(typeof channel === 'string') { + for(const key in this.rtc) { + if(key === channel) {channel = this.rtc[key].channels.data as RTCDataChannel; break;} + } + } + if(res instanceof Promise) + res.then((v) => { + res = {args:v, callbackId}; + if(channel instanceof RTCDataChannel) channel.send(JSON.stringify(res)); + + return res; + }) + else { + res = {args:res, callbackId}; + if(channel instanceof RTCDataChannel) channel.send(JSON.stringify(res)); + } + } + return res; + } + + subscribeRTC = (route:string, rtcId:string, channel:string|RTCDataChannel) => { + if(typeof channel === 'string' && this.rtc[rtcId]) { + channel = this.rtc[rtcId].channels[channel] as RTCDataChannel; + } + return this.subscribe(route, (res:any) => { + //console.log('running request', message, 'for worker', worker, 'callback', callbackId) + if(res instanceof Promise) { + res.then((r) => { + (channel as RTCDataChannel).send(JSON.stringify({args:r, callbackId:route})); + }); + } else { + (channel as RTCDataChannel).send(JSON.stringify({args:res, callbackId:route})); + } + }); + } + + subscribeToRTC = (route:string, rtcId:string, channelId:string, callback?:string|((res:any)=>void)) => { + if(typeof channelId === 'string' && this.rtc[rtcId]) { + let c = this.rtc[rtcId]; + let channel = c.channels[channelId]; + + if(channel) { + this.subscribe(rtcId, (res) => { + if(res?.callbackId === route) { + if(!callback) this.setState({[rtcId]:res.args}); //just set state + else if(typeof callback === 'string') { //run a local node + this.run(callback,res.args); + } + else callback(res.args); + } + }) + return c.request({route:'subscribeRTC', args:[route,channelId]}); + } + } + } + + routes:Routes = { + //just echos webrtc info for server subscriptions to grab onto + openRTC:{ + operator:this.openRTC, + aliases:['open'] + }, + request:this.request, + runRequest:this.runRequest, + createStream:this.createStream, + addUserMedia:this.addUserMedia, + addTrack:this.addTrack, + removeTrack:this.removeTrack, + addDataChannel:this.addDataChannel, + subscribeRTC:this.subscribeRTC, + subscribeToRTC:this.subscribeToRTC, + unsubscribe:this.unsubscribe, + terminate:this.terminate + } + +} \ No newline at end of file diff --git a/src/services/worker/ProxyListener.ts b/services/worker/ProxyListener.ts similarity index 53% rename from src/services/worker/ProxyListener.ts rename to services/worker/ProxyListener.ts index c3ca33ae..3ad2e7a6 100644 --- a/src/services/worker/ProxyListener.ts +++ b/services/worker/ProxyListener.ts @@ -1,116 +1,79 @@ //from UI thread -declare var WorkerGlobalScope; - /////////////https://threejsfundamentals.org/threejs/lessons/threejs-offscreencanvas.html const mouseEventHandler = makeSendPropertiesHandler([ 'ctrlKey', 'metaKey', - 'altKey', 'shiftKey', 'button', - 'which', 'pointerType', 'clientX', 'clientY', 'pageX', 'pageY', - 'movementX', - 'movementY', - 'x', - 'y', - 'which', - 'timeStamp' ]); - -const wheelEventHandlerImpl = makeSendPropertiesHandler([ - 'deltaX', - 'deltaY', -]); - -const keydownEventHandler = makeSendPropertiesHandler([ - 'ctrlKey', - 'metaKey', - 'shiftKey', - 'altKey', - 'isComposing', - 'keyCode', - 'key', - 'code', - 'repeat', - 'timeStamp' -]); - -function focusEventHandler(event, sendFn) { - const data = { type:event.type } as any; - data.isTrusted = event.isTrusted; - data.bubbles = event.bubbles; - data.cancelBubble = event.cancelBubble; - data.cancelable = event.cancelable; - data.composed = event.composed; - data.defaultPrevent = event.defaultPrevented; - data.eventPhase = event.eventPhase; - data.returnValue = event.returnValue; - - data.currentTarget = event.currentTarget.id ? event.currentTarget.id : event.currentTarget.constructor.name; - data.target = data.currentTarget; - data.srcElement = data.currentTarget; - - sendFn(data); -} - -function wheelEventHandler(event, sendFn, preventDefault) { - if(preventDefault && event.preventDefault) event.preventDefault(); - wheelEventHandlerImpl(event, sendFn); -} - -function preventDefaultHandler(event, sendFn, preventDefault) { - if(preventDefault && event.preventDefault) event.preventDefault(); -} - -function copyProperties(src, properties, dst) { - for (const name of properties) { - dst[name] = src[name]; + const wheelEventHandlerImpl = makeSendPropertiesHandler([ + 'deltaX', + 'deltaY', + ]); + const keydownEventHandler = makeSendPropertiesHandler([ + 'ctrlKey', + 'metaKey', + 'shiftKey', + 'keyCode', + ]); + + function wheelEventHandler(event, sendFn) { + event.preventDefault(); + wheelEventHandlerImpl(event, sendFn); } -} - -function makeSendPropertiesHandler(properties) { - return function sendProperties(event, sendFn) { - const data = {type: event.type}; - copyProperties(event, properties, data); + + function preventDefaultHandler(event) { + event.preventDefault(); + } + + function copyProperties(src, properties, dst) { + for (const name of properties) { + dst[name] = src[name]; + } + } + + function makeSendPropertiesHandler(properties) { + return function sendProperties(event, sendFn) { + const data = {type: event.type}; + copyProperties(event, properties, data); + sendFn(data); + }; + } + + function touchEventHandler(event, sendFn) { + const touches = []; + const data = {type: event.type, touches}; + for (let i = 0; i < event.touches.length; ++i) { + const touch = event.touches[i]; + touches.push({ + pageX: touch.pageX, + pageY: touch.pageY, + }); + } sendFn(data); - }; -} - -function touchEventHandler(event, sendFn, preventDefault) { - if(preventDefault && event.preventDefault) event.preventDefault(); - const touches = []; - const data = {type: event.type, touches}; - for (let i = 0; i < event.touches.length; ++i) { - const touch = event.touches[i]; - touches.push({ - pageX: touch.pageX, - pageY: touch.pageY, - }); } - sendFn(data); -} - -let i = 1; -let keys = {}; -while(i < 222) { //proxy all key events - keys[i] = true; //avoid F keys - i++; -} - + + // The four arrow keys + const orbitKeys = { + '37': true, // left + '38': true, // up + '39': true, // right + '40': true, // down + }; -function filteredKeydownEventHandler(event, sendFn, preventDefault) { - let {keyCode} = event; - if (keys[keyCode]) { - if(preventDefault && event.preventDefault && (keyCode < 110 || keyCode > 123)) event.preventDefault(); - keydownEventHandler(event, sendFn); + function filteredKeydownEventHandler(event, sendFn) { + const {keyCode} = event; + if (orbitKeys[keyCode]) { + event.preventDefault(); + keydownEventHandler(event, sendFn); + } } -} export const eventHandlers = { //you can register more event handlers in this object contextmenu: preventDefaultHandler, @@ -120,28 +83,20 @@ export const eventHandlers = { //you can register more event handlers in this ob pointerdown: mouseEventHandler, pointermove: mouseEventHandler, pointerup: mouseEventHandler, - pointerlockchange: mouseEventHandler, - webkitpointerlockchange: mouseEventHandler, - focus: focusEventHandler, - blur: focusEventHandler, - pointerout: mouseEventHandler, touchstart: touchEventHandler, touchmove: touchEventHandler, touchend: touchEventHandler, wheel: wheelEventHandler, keydown: filteredKeydownEventHandler, - keyup: filteredKeydownEventHandler }; //do this on main thread -export function initProxyElement(element, worker, id, preventDefault?:boolean) { +export function initProxyElement(element, worker, id) { if( !id ) id = 'proxy'+Math.floor(Math.random()*1000000000000000); const sendEvent = (data) => { - if(!worker) { - handleProxyEvent(data,id); - } else worker.postMessage({route:'handleProxyEvent',args:[data,id]}); //for use with our service syntax + worker.postMessage({route:'handleProxyEvent',args:[data,id]}); //for use with our service syntax }; // register an id @@ -151,34 +106,10 @@ export function initProxyElement(element, worker, id, preventDefault?:boolean) { for (const [eventName, handler] of entries) { element.addEventListener(eventName, function(event) { //add all of the event listeners we care about - handler(event, sendEvent, preventDefault); + handler(event, sendEvent); }); } - if(eventHandlers.keydown) { - globalThis.addEventListener('keydown', function(ev) { - eventHandlers.keydown(ev, sendEvent, preventDefault); - }) - } - - if(eventHandlers.keyup) { - globalThis.addEventListener('keyup', function(ev) { - eventHandlers.keyup(ev, sendEvent, preventDefault); - }) - } - - // if(eventHandlers.focus) { - // globalThis.addEventListener('focus', function(ev) { - // eventHandlers.focus(ev, sendEvent); - // }) - // } - - // if(eventHandlers.blur) { - // globalThis.addEventListener('blur', function(ev) { - // eventHandlers.blur(ev, sendEvent); - // }) - // } - const sendSize = () => { const rect = element.getBoundingClientRect(); @@ -205,13 +136,12 @@ export function initProxyElement(element, worker, id, preventDefault?:boolean) { /////////////https://threejsfundamentals.org/threejs/lessons/threejs-offscreencanvas.html export class EventDispatcher { - __listeners:any; + _listeners:any; addEventListener( type, listener ) { - //console.log(type,listener); - if ( this.__listeners === undefined ) this.__listeners = {}; - const listeners = this.__listeners; + if ( this._listeners === undefined ) this._listeners = {}; + const listeners = this._listeners; if ( listeners[ type ] === undefined ) { listeners[ type ] = []; } @@ -223,14 +153,14 @@ export class EventDispatcher { } hasEventListener( type, listener ) { - if ( this.__listeners === undefined ) return false; - const listeners = this.__listeners; + if ( this._listeners === undefined ) return false; + const listeners = this._listeners; return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1; } removeEventListener( type, listener ) { - if ( this.__listeners === undefined ) return; - const listeners = this.__listeners; + if ( this._listeners === undefined ) return; + const listeners = this._listeners; const listenerArray = listeners[ type ]; if ( listenerArray !== undefined ) { const index = listenerArray.indexOf( listener ); @@ -241,9 +171,9 @@ export class EventDispatcher { } dispatchEvent( event, target ) { - //console.log(event,this.__listeners); - if ( this.__listeners === undefined ) return; - const listeners = this.__listeners; + //console.log(event,this._listeners); + if ( this._listeners === undefined ) return; + const listeners = this._listeners; const listenerArray = listeners[ event.type ]; if ( listenerArray !== undefined ) { if(!target) @@ -254,16 +184,17 @@ export class EventDispatcher { for ( let i = 0, l = array.length; i < l; i ++ ) { array[ i ].call( this, event ); } - //event.target = null; + event.target = null; } } } -function noop() {}; +function noop() { +}; /////////////https://threejsfundamentals.org/threejs/lessons/threejs-offscreencanvas.html export class ElementProxyReceiver extends EventDispatcher { - __listeners:any = {}; + _listeners:any = {}; proxied:any; style:any = {}; width:any; @@ -306,9 +237,9 @@ export class ElementProxyReceiver extends EventDispatcher { this.width = data.width; this.height = data.height; - if(typeof this.proxied === 'object') { //provide size information to the object for resize functions to use on a thread - this.proxied.style.width = this.width + 'px'; - this.proxied.style.height = this.height + 'px'; + if(typeof this.proxied === 'object') { //auto resize + this.proxied.width = this.width; + this.proxied.height = this.height; this.proxied.clientWidth = this.width; this.proxied.clientHeight = this.height; } @@ -320,8 +251,6 @@ export class ElementProxyReceiver extends EventDispatcher { focus() {} - blur() {} - } /////////////https://threejsfundamentals.org/threejs/lessons/threejs-offscreencanvas.html @@ -330,11 +259,7 @@ export class ProxyManager { targets:any={}; constructor() { - if(!globalThis.document) globalThis.document = { - elementFromPoint:(...args:any[])=>{ //hax - return this.targets[Object.keys(this.targets)[0]].proxied; - } - } as any; //threejs hack for workers + if(!globalThis.document) globalThis.document = {} as any; //threejs hack for workers } makeProxy = (id, addTo=undefined) => { //addTo installs the desirable functions to the object you want @@ -350,19 +275,17 @@ export class ProxyManager { addTo.proxy = proxy; proxy.proxied = addTo; - //console.log(proxy, addTo); - - if(typeof WorkerGlobalScope !== 'undefined') addTo.style = proxy.style; + console.log(proxy, addTo); + addTo.style = proxy.style; if(proxy.width) { - addTo.style.width = proxy.width + 'px'; + addTo.width = proxy.width; addTo.clientWidth = proxy.width; } if(proxy.height) { - addTo.style.height = proxy.height + 'px'; + addTo.height = proxy.height; addTo.clientHeight = proxy.height; } - addTo.setPointerCapture = proxy.setPointerCapture.bind(proxy); addTo.releasePointerCapture = proxy.releasePointerCapture.bind(proxy); addTo.getBoundingClientRect = proxy.getBoundingClientRect.bind(proxy); @@ -371,7 +294,6 @@ export class ProxyManager { addTo.handleEvent = proxy.handleEvent.bind(proxy); addTo.dispatchEvent = proxy.dispatchEvent.bind(proxy); addTo.focus = proxy.focus.bind(proxy); - addTo.blur = proxy.blur.bind(proxy); } } @@ -390,37 +312,21 @@ export class ProxyManager { } } -function makeProxy(id, elm?) { - - if(this?.__node?.graph) { - - if(!this.__node.graph.ProxyManager) this.__node.graph.ProxyManager = new ProxyManager(); - - this.__node.graph.ProxyManager.makeProxy(id, elm); - - } - else { - if(!globalThis.ProxyManager) globalThis.ProxyManager = new ProxyManager(); - - globalThis.ProxyManager.makeProxy(id, elm); - } - return id; -} -function handleProxyEvent( data, id){ - if(this?.__node?.graph) { - if(!this.__node.graph.ProxyManager) this.__node.graph.ProxyManager = new ProxyManager(); - if(this.__node.graph.ProxyManager.handleEvent(data, id)) return data; - } else { - if(!globalThis.ProxyManager) globalThis.ProxyManager = new ProxyManager(); - if(globalThis.ProxyManager.handleEvent(data, id)) return data; - } -} //just load these into the worker service front and back. These are integrated in the worker canvas routes as well export const proxyElementWorkerRoutes = { initProxyElement:initProxyElement, - makeProxy:makeProxy, - handleProxyEvent:handleProxyEvent + makeProxy:function(id, elm?) { + if(!this.graph.ProxyManager) this.graph.ProxyManager = new ProxyManager(); + + this.graph.ProxyManager.makeProxy(id, elm); + + return id; + }, + handleProxyEvent:function( data, id){ + if(!this.graph.ProxyManager) this.graph.ProxyManager = new ProxyManager(); + if(this.graph.ProxyManager.handleEvent(data, id)) return data; + } } diff --git a/_old/Subprocess.ts b/services/worker/Subprocess.ts similarity index 67% rename from _old/Subprocess.ts rename to services/worker/Subprocess.ts index b13fcadd..597a9f2a 100644 --- a/_old/Subprocess.ts +++ b/services/worker/Subprocess.ts @@ -1,11 +1,8 @@ -import { parseFunctionFromText } from '../src/services/utils'; -import { WorkerInfo, WorkerService } from '../src/services/worker/Worker.service'; -import { remoteGraphRoutes } from '../src/services/remote/remote.routes'; -import { Graph, GraphNodeProperties } from '../src/core/Graph'; -import {methodstrings} from '../src/loaders/methodstrings' -export type Subprocess = (context:SubprocessContext,data:{[key:string]:any}|any)=>{[key:string]:any}|undefined +import { Graph, parseFunctionFromText } from '../../Graph'; +import { WorkerInfo, WorkerService } from './Worker.service'; +import { unsafeRoutes } from '../unsafe/Unsafe.service'; -//deprecated, just use remoteRoutes and normal node routines +export type Subprocess = (context:SubprocessContext,data:{[key:string]:any}|any)=>{[key:string]:any}|undefined export type SubprocessContextProps = { ondata:Subprocess, @@ -38,16 +35,14 @@ export type SubprocessWorkerProps = { //use secondary workers to run processes a init?:string, initArgs?:any[], otherArgs?:any[], //do we need to call an init function before running the callbacks? The results of this init will set the otherArgs callback?:string|((data:any)=>any), //do we want to do something with the subprocess output (if any) on the main thread? pipeTo?:{ //pipe outputs (if any) from the suprocesses to a specific route on main thread or a known route on another thread? - worker?:WorkerInfo, portId?:string, - route:string, otherArgs?:any[], - init?:string, initArgs?:any[], + portId:string, + route:string, otherArgs:any[], }, //can pipe the results to a specific route on main thread or other threads via message ports worker?:WorkerInfo, url?:any, //need one or the other stopped?:boolean //you can subscribe the subprocess later by calling start(); } export type SubprocessWorkerInfo = { //use secondary workers to run processes and report results back to the main thread or other sub:number, - blocking?:boolean, //if piping, is the pipe blocking? stop:()=>void, //unsubscribe subprocess to stop updating it start:()=>void, //subscribe subprocess to continue updating it terminate:()=>void, //terminate the worker @@ -104,16 +99,17 @@ let recursivelyAssign = (target,obj) => { } + export const subprocessRoutes = { - ...remoteGraphRoutes, + ...unsafeRoutes, loadAlgorithms:loadAlgorithms, - 'initSubprocesses':async function initSubprocesses( //requires remoteGraphRoutes + 'initSubprocesses':async function initSubprocesses( //requires unsafeRoutes subprocesses:{ //use secondary workers to run processes and report results back to the main thread or other [key:string]:SubprocessWorkerProps }, - service?:WorkerService //defaults to this.__node.graph (assumed to be workerservice) + service?:WorkerService //defaults to this.graph (assumed to be workerservice) ) { - if(!service) service = this.__node.graph; + if(!service) service = this.graph; if(!service) return undefined; for(const p in subprocesses) { @@ -161,56 +157,29 @@ export const subprocessRoutes = { if(s.pipeTo) { w.run('setValue',['routeProxy', s.route]); //set the route we want to run through our proxy function below w.run('setValue',['pipeRoute', s.pipeTo.route]); //set the route to pipe results to - - //create dedicated worker if not specified - if(s.url && !s.pipeTo.worker) { - let w2 = service.addWorker({url:s.url}); - s.pipeTo.portId = service.establishMessageChannel(w.worker,w2.worker) as string; - s.pipeTo.worker = w2; - } - - if(s.pipeTo.init) { - s.pipeTo.otherArgs = await s.pipeTo.worker.run(s.pipeTo.init, s.pipeTo.initArgs); - } - - w.run('setValue',['pipePort', s.pipeTo.portId]); //set the pipe port + if(s.pipeTo.portId) w.run('setValue',['pipePort', s.pipeTo.portId]); //set the pipe port if(s.pipeTo.otherArgs) w.run('setValue',['otherPipeArgs', s.pipeTo.otherArgs]); //set additional args to pipe with the results service.transferFunction( w, function pipeResults(data){ //console.log('piping', data); let inp = data; - if(this.__node.graph.otherArgsProxy) inp = [data, ...this.__node.graph.otherArgsProxy] - let r = this.__node.graph.run(this.__node.graph.routeProxy, inp); - - if(!s.blocking) return new Promise((res) => { - if(r instanceof Promise) { - r.then((rr) => { - if(rr !== undefined) { - let args = rr; if(this.__node.graph.otherPipeArgs) args = [rr, ...this.__node.graph.otherPipeArgs]; - if(this.workers[this.__node.graph.pipePort]) { - s.blocking = true; - (this.workers[this.__node.graph.pipePort] as WorkerInfo).run(this.__node.graph.pipeRoute,args).then((result)=>{ - s.blocking = false; - res(result); - }); //will report to main thread if pipePort undefined (if not set in this init) - } - - } - }); - } else if(r !== undefined) { - let args = r; if(this.__node.graph.otherPipeArgs) args = [r, ...this.__node.graph.otherPipeArgs]; - if(this.workers[this.__node.graph.pipePort]){ - s.blocking = true; - (this.workers[this.__node.graph.pipePort] as WorkerInfo).run(this.__node.graph.pipeRoute,args).then((result)=>{ - s.blocking = false; - res(result); //this really isn't that efficient since the tertiary thread will report back to main thread through this thread. Better would be to proxy the third thread as well - }); //will report to main thread if pipePort undefined (if not set in this init) - }//this.transmit({route:this.__node.graph.pipeRoute, args}, this.__node.graph.pipePort); - } - }); + if(this.graph.otherArgsProxy) inp = [data, ...this.graph.otherArgsProxy] + let r = this.graph.run(this.graph.routeProxy, inp); + + if(r instanceof Promise) { + r.then((rr) => { + if(rr !== undefined) { + let args = rr; if(this.graph.otherPipeArgs) args = [rr, ...this.graph.otherPipeArgs]; + this.transmit({route:this.graph.pipeRoute, args}, this.graph.pipePort); //will report to main thread if pipePort undefined (if not set in this init) + } + }); + } else if(r !== undefined) { + let args = r; if(this.graph.otherPipeArgs) args = [r, ...this.graph.otherPipeArgs]; + this.transmit({route:this.graph.pipeRoute, args}, this.graph.pipePort); + } - return undefined; + return r; }, s.route+'_pipeResults' @@ -226,16 +195,16 @@ export const subprocessRoutes = { w, function routeProxy(data:any) { let r; - if(this.__node.graph.otherArgsProxy) r = this.__node.graph.nodes.get(this.__node.graph.routeProxy).__operator(data, ...this.__node.graph.otherArgsProxy); - else r = this.__node.graph.nodes.get(this.__node.graph.routeProxy).__operator(data); + if(this.graph.otherArgsProxy) r = this.graph.nodes.get(this.graph.routeProxy).operator(data, ...this.graph.otherArgsProxy); + else r = this.graph.nodes.get(this.graph.routeProxy).operator(data); - if(this.__node.graph.state.triggers[this.__node.graph.routeProxy]) { + if(this.graph.state.triggers[this.graph.routeProxy]) { if(r instanceof Promise) { r.then((rr) => { - this.setState({[this.__node.graph.routeProxy]:rr}); + this.setState({[this.graph.routeProxy]:rr}); }) } - else this.setState({[this.__node.graph.routeProxy]:r}); //so we can subscribe to the original route + else this.setState({[this.graph.routeProxy]:r}); //so we can subscribe to the original route } return r; }, @@ -259,7 +228,7 @@ export const subprocessRoutes = { } s.start = async () => { - if(typeof s.sub !== 'number') return w.run('subscribeToWorker', [s.subscribeRoute, wpId, s.route, s.blocking]).then((sub) => { + if(typeof s.sub !== 'number') return w.run('subscribeToWorker', [s.subscribeRoute, wpId, s.route]).then((sub) => { s.sub = sub; }); } @@ -282,13 +251,10 @@ export const subprocessRoutes = { if(s.source?.worker && typeof s.sub === 'number') { s.source.post('unsubscribe',s.sub); } - if(s.pipeTo?.worker) { - s.pipeTo.worker.terminate(); - } } if(s.callback) w.subscribe(s.route, (res) => { //we can change thisfrom the initial definition too - if(typeof s.callback === 'string') this.__node.graph.run(s.callback,res); + if(typeof s.callback === 'string') this.graph.run(s.callback,res); else s.callback(res); }); @@ -324,18 +290,18 @@ export const subprocessRoutes = { structs:{}, _id?:string ) { - if(!this.__node.graph.ALGORITHMS) this.__node.graph.ALGORITHMS = {}; + if(!this.graph.ALGORITHMS) this.graph.ALGORITHMS = {}; - if(!_id) _id = Object.keys(this.__node.graph.ALGORITHMS)[0]; //run the first key if none specified + if(!_id) _id = Object.keys(this.graph.ALGORITHMS)[0]; //run the first key if none specified if(!_id) return; - Object.assign(this.__node.graph.ALGORITHMS[_id],structs); //e.g. update sample rate or sensitivity + Object.assign(this.graph.ALGORITHMS[_id],structs); //e.g. update sample rate or sensitivity }, 'createSubprocess': function creatsubprocess( //returns id of algorithm for calling it on server options:SubprocessContextProps|string, inputs?:{[key:string]:any} //e.g. set the sample rate for this run ){ - if(!this.__node.graph.ALGORITHMS) this.__node.graph.ALGORITHMS = {}; + if(!this.graph.ALGORITHMS) this.graph.ALGORITHMS = {}; if(typeof options === 'string') { options = algorithms[options]; } @@ -345,9 +311,7 @@ export const subprocessRoutes = { let ctx; if(typeof options?.ondata === 'function') ctx = createSubprocess(options,inputs); - if(ctx) this.__node.graph.ALGORITHMS[ctx._id] = ctx; - - //console.log(ctx,options); + if(ctx) this.graph.ALGORITHMS[ctx._id] = ctx; if(ctx) return ctx._id; } @@ -358,23 +322,21 @@ export const subprocessRoutes = { data:{[key:string]:any}, _id?:string ){ - //console.log(data); - if(!this.__node.graph.ALGORITHMS) this.__node.graph.ALGORITHMS = {}; + if(!this.graph.ALGORITHMS) this.graph.ALGORITHMS = {}; - if(!_id) _id = Object.keys(this.__node.graph.ALGORITHMS)[0]; //run the first key if none specified + if(!_id) _id = Object.keys(this.graph.ALGORITHMS)[0]; //run the first key if none specified if(!_id) return; - let res = this.__node.graph.ALGORITHMS[_id].run(data); + let res = this.graph.ALGORITHMS[_id].run(data); - //console.log(_id,data,res); - //console.log(this.__node.graph.ALGORITHMS[_id]); + //console.log(this.graph.ALGORITHMS[_id]); if(res !== undefined) { if(Array.isArray(res)) { let pass:any[] = []; res.forEach((r) => { if(r !== undefined) { pass.push(r); - this.__node.graph.setState({[_id as string]:r}); + this.graph.setState({[_id as string]:r}); } }); if(pass.length > 0) { @@ -382,7 +344,7 @@ export const subprocessRoutes = { } } else { - this.__node.graph.setState({[_id as string]:res}); + this.graph.setState({[_id as string]:res}); return res; } } diff --git a/services/worker/Three.service.ts b/services/worker/Three.service.ts new file mode 100644 index 00000000..fda0fe00 --- /dev/null +++ b/services/worker/Three.service.ts @@ -0,0 +1 @@ +//Threejs service! \ No newline at end of file diff --git a/services/worker/Worker.node.service.ts b/services/worker/Worker.node.service.ts new file mode 100644 index 00000000..662e153e --- /dev/null +++ b/services/worker/Worker.node.service.ts @@ -0,0 +1,468 @@ +import { Service, Routes, ServiceMessage, ServiceOptions, Route } from "../Service"; +import Worker from 'web-worker' //cross platform for node and browser +import { GraphNodeProperties } from "../../Graph"; + +declare var WorkerGlobalScope; + +export type WorkerRoute = { + worker?:WorkerInfo + workerUrl?: string|URL|Blob, + workerId?: string, + transferFunctions?:{[key:string]:Function}, + transferClasses?:{[key:string]:Function}, + parentRoute?:string, //if a child of a worker node, subscribe to a route on a parent worker? + callback?:string //Run this route on the worker when the operator is called. If this route is a child of another node, run this node on the child worker when it receives a message. +} & GraphNodeProperties & WorkerProps + +export type WorkerProps = { + worker:WorkerInfo, + workerUrl?: string|URL|Blob, + url?:URL|string|Blob, + _id?:string, + port?:MessagePort, //message channel for this instance + onmessage?:(ev)=>void, + onerror?:(ev)=>void +} + +export type WorkerInfo = { + worker:Worker, + send:(message:any,transfer?:any)=>void, + request:(message:any, transfer?:any, method?:string)=>Promise, + post:(route:any, args?:any, transfer?:any)=>void, + run:(route:any, args?:any, transfer?:any, method?:string)=>Promise + subscribe:(route:any, callback?:((res:any)=>void)|string)=>any, + unsubscribe:(route:any, sub:number)=>Promise +} & WorkerProps & WorkerRoute + +//this spawns the workers +export class WorkerService extends Service { + + name='worker' + + workers:{ + [key:string]:WorkerInfo + }={} + + threadRot = 0; //thread rotation if not specifying + + constructor(options?:ServiceOptions) { + super(options); + this.load(this.routes); + + if(typeof WorkerGlobalScope !== 'undefined' && globalThis instanceof WorkerGlobalScope) { + globalThis.onmessage = (ev:MessageEvent) => { + let result = this.receive(ev.data); //this will handle graph logic and can run requests for the window or messsage ports etc etc. + //console.log(JSON.stringify(ev.data), JSON.stringify(result),JSON.stringify(Array.from((self as any).SERVICE.nodes.keys()))) + //console.log(result); + if(this.keepState) this.setState({[this.name]:result}); //subscribe to all outputs + } + } + } + + customRoutes:ServiceOptions["customRoutes"] = { + 'worker':(route:Route | WorkerRoute,routeKey:string, routes:Routes) => { + let rt = route as WorkerRoute; + if(rt?.worker || rt?.workerId) { //each set of props with a worker will instantiate a new worker, else you can use the same worker elsewhere by passing the corresponding tag + if(rt.workerUrl) rt.url = rt.workerUrl; + if(rt.workerId) rt.tag = rt.workerId; + if(!rt.tag) rt.tag = routeKey; + rt._id = rt.tag; + + let worker:WorkerInfo; + if(this.workers[rt._id]) worker = this.workers[rt._id]; + + //@ts-ignore //what a dumb ts error + if(!worker) worker = this.addWorker(rt); + rt.worker = worker; + + //requires unsafeservice on the worker (enabled on the default worker) + if(rt.transferFunctions) { + for(const prop in rt.transferFunctions) { + this.transferFunction(worker,rt.transferFunctions[prop],prop) + } + } + if(rt.transferClasses) { + for(const prop in rt.transferClasses) { + this.transferClass(worker,rt.transferClasses[prop],prop) + } + } + + if(worker) { + if(!rt.operator) { + rt.operator = (...args) => { + if(rt.callback) { + if(!this.nodes.get(rt.tag)?.children) worker.post(rt.callback,args); + else return worker.run(rt.callback,args); + } else { + if(!this.nodes.get(rt.tag)?.children) worker.send(args); + else return worker.request(args); + } + } + } + } + } + } + } + + customChildren:ServiceOptions["customChildren"] = { + 'worker':(child: WorkerRoute, childRouteKey: string, parent: WorkerRoute, routes: Routes, checked: Routes) => { + + let worker; + if((child as WorkerRoute)?.worker || (child as WorkerRoute)?.workerId) { + if(child.workerUrl) child.url = child.workerUrl; + if(child.workerId) child.tag = child.workerId; + if(!child.tag) child.tag = childRouteKey; + child._id = child.tag; + + if(this.workers[child._id]) worker = this.workers[child._id]; + if(!worker) worker = this.addWorker(child); + child.worker = worker; + + //requires unsafeservice on the worker (enabled on the default worker) + if(child.transferFunctions) { + for(const prop in child.transferFunctions) { + this.transferFunction(worker,child.transferFunctions[prop],prop) + } + } + if(child.transferClasses) { + for(const prop in child.transferClasses) { + this.transferClass(worker,child.transferClasses[prop],prop) + } + } + + if(worker) { + if(!child.operator) { + child.operator = (...args) => { + if(child.callback) { + if(!this.nodes.get(child.tag)?.children) worker.post(child.callback,args); + else return worker.run(child.callback,args); + } else { //just post whatever + if(!this.nodes.get(child.tag)?.children) worker.send(args); + else return worker.request(args); + } + } + } + } + } + if(child.parentRoute && ((parent as WorkerRoute)?.worker || (parent as WorkerRoute)?.workerId)) { + + if(worker) { + let portId = this.establishMessageChannel(worker,parent.worker.worker) + worker.post('subscribeToWorker', child.parentRoute, portId, child.callback); + } else { + parent.worker.subscribe(child.parentRoute,(result) => {this.nodes.get(child.tag ? child.tag : childRouteKey).run(result)}); + } + } + } + } as any//todo, create message ports between workers with parent/child relationships and set up pipes + + addWorker = (options:{ + url?:URL|string|Blob, + port?:MessagePort, + _id?:string, + onmessage?:(ev)=>void, + onerror?:(ev)=>void + }) => { //pass file location, web url, or javascript dataurl string + let worker; + + if(!options._id) + options._id = `worker${Math.floor(Math.random()*1000000000000000)}`; + + if(options.url) worker = new Worker(options.url); + else if (options.port) { + worker = options.port; + } else if (this.workers[options._id]) { + if(this.workers[options._id].port) worker = this.workers[options._id].port; + else worker = this.workers[options._id].worker; + } + + if(!worker) return; + + let send = (message:any,transfer?:any) => { + //console.log('sent', message) + return this.transmit(message,worker,transfer); + } + + let post = (route:any,args?:any,transfer?:any,method?:string) => { + //console.log('sent', message) + let message:any = { + route, + args + }; + if(method) message.method = method; + + return this.transmit(message,worker,transfer); + } + + let run = (route:any,args?:any, transfer?:any, method?:string) => { + return new Promise ((res,rej) => { + let callbackId = Math.random(); + let req = {route:'runRequest', args:[{route, args}, options._id, callbackId]} as any; + //console.log(req) + if(method) req.args[0].method = method; + let onmessage = (ev)=>{ + if(typeof ev.data === 'object') { + if(ev.data.callbackId === callbackId) { + worker.removeEventListener('message',onmessage); + res(ev.data.args); //resolve the request with the corresponding message + } + } + } + worker.addEventListener('message',onmessage) + this.transmit(req, worker, transfer); + }); + } + + let request = (message:ServiceMessage|any, transfer?:any, method?:string) => { + return new Promise ((res,rej) => { + let callbackId = Math.random(); + let req = {route:'runRequest', args:[message,options._id,callbackId]} as any; + //console.log(req) + if(method) req.method = method; + let onmessage = (ev)=>{ + if(typeof ev.data === 'object') { + if(ev.data.callbackId === callbackId) { + worker.removeEventListener('message',onmessage); + res(ev.data.args); //resolve the request with the corresponding message + } + } + } + worker.addEventListener('message',onmessage) + this.transmit(req, worker, transfer); + }); + } + + let subscribe = (route:any, callback?:((res:any)=>void)|string) => { + return this.subscribeToWorker(route, options._id as string, callback); + } + + let unsubscribe = (route:any, sub:number):Promise => { + return run('unsubscribe',[route,sub]); + } + + if(!options.onmessage) options.onmessage = (ev) => { + this.receive(ev.data); + this.setState({[options._id as string]:ev.data}); + } + + if(!options.onerror) { + options.onerror = (ev) => { + console.error(ev.data); + } + } + + worker.onmessage = options.onmessage; + worker.onerror = options.onerror; + + this.workers[options._id] = { + worker, + send, + post, + run, + request, + subscribe, + unsubscribe, + ...options + } + + return this.workers[options._id]; + } + + //new Worker(urlFromString) + toObjectURL = (scriptTemplate:string) => { + const { Blob } = require('buffer') + let blob = new Blob([scriptTemplate],{type:'text/javascript'}); + return URL.createObjectURL(blob); + } + + transmit = (message:ServiceMessage|any, worker?:Worker|MessagePort|string, transfer?:StructuredSerializeOptions ) => { + if(worker instanceof Worker || worker instanceof MessagePort) { + worker.postMessage(message,transfer); + } else if(typeof worker === 'string') { + if(this.workers[worker as string]) { + if(this.workers[worker as string].port) + (this.workers[worker as string].port as any).postMessage(message,transfer); + else if (this.workers[worker as string].worker) + this.workers[worker as string].worker.postMessage(message,transfer); + } + } else { + let keys = Object.keys(this.workers); + this.workers[keys[this.threadRot]].worker.postMessage(message,transfer); + this.threadRot++; + if(this.threadRot === keys.length) this.threadRot = 0; + } + return message; + } + + terminate = (worker:Worker|MessagePort|string) => { + if(typeof worker === 'string') { + let obj = this.workers[worker]; + if(obj) delete this.workers[worker]; + worker = obj.worker; + } + if(worker instanceof Worker) { + worker.terminate(); + return true; + } + if(worker instanceof MessagePort) { + worker.close(); + return true; + } + return false; + } + + //if no second id provided, message channel will exist to this thread + establishMessageChannel = (worker:Worker|string|MessagePort, worker2?:Worker|string|MessagePort) => { + + let workerId; + if(typeof worker === 'string') { + workerId = worker; + if(this.workers[worker]){ + if(this.workers[worker].port) worker = this.workers[worker].port as any; + else worker2 = this.workers[worker].worker; + } + } + if(typeof worker2 === 'string') { + if(this.workers[worker2]){ + if(this.workers[worker2].port) worker2 = this.workers[worker2].port; + else worker2 = this.workers[worker2].worker; + } + } + + if(worker instanceof Worker || worker instanceof MessagePort) { + let channel = new MessageChannel(); + let portId = `port${Math.floor(Math.random()*1000000000000000)}`; + + worker.postMessage({route:'addWorker',args:{port:channel.port1, _id:portId}},[channel.port1]); + + if(worker2 instanceof Worker || worker2 instanceof MessagePort) { + worker2.postMessage({route:'addWorker',args:{port:channel.port2, _id:portId}},[channel.port2]); + } else if(workerId && this.workers[workerId]) this.workers[workerId].port = channel.port2; + + return portId; + } + + return false; + + } + + request = (message:ServiceMessage|any, workerId:string, transfer?:any, method?:string) => { + let worker = this.workers[workerId].worker; + return new Promise ((res,rej) => { + let callbackId = Math.random(); + let req = {route:'runRequest', args:[message, callbackId]} as any; + if(method) req.method = method; + let onmessage = (ev)=>{ + if(typeof ev.data === 'object') { + if(ev.data.callbackId === callbackId) { + worker.removeEventListener('message',onmessage); + res(ev.data.args); //resolve the request with the corresponding message + } + } + } + worker.addEventListener('message',onmessage) + this.transmit(req, worker, transfer); + }); + } + + runRequest = (message:ServiceMessage|any, worker:undefined|string|Worker|MessagePort, callbackId:string|number) => { + let res = this.receive(message); + if(typeof worker === 'string' && this.workers[worker]) { + if(this.workers[worker].port) worker = this.workers[worker].port; + else worker = this.workers[worker].worker; + } + //console.log('running request', message, 'for worker', worker, 'callback', callbackId) + if(res instanceof Promise) { + res.then((r) => { + if(worker instanceof Worker || worker instanceof MessagePort) + worker.postMessage({args:r,callbackId}) + else if(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) + globalThis.postMessage({args:r,callbackId}); + }); + } else { + if(worker instanceof Worker || worker instanceof MessagePort) + worker.postMessage({args:res,callbackId}) + else if(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) + globalThis.postMessage({args:res,callbackId}); + } + + return res; + } + + subscribeWorker = (route:string, worker:Worker|string|MessagePort) => { + //console.log('subscribed!',worker, this.workers, WorkerGlobalScope); + if(typeof worker === 'string' && this.workers[worker]) { + if(this.workers[worker].port) worker = this.workers[worker].port as any; + else worker = this.workers[worker].worker; + } + return this.subscribe(route, (res:any) => { + //console.log('running request', message, 'for worker', worker, 'callback', callbackId) + //console.log('subscription triggered for', route, 'to', worker instanceof Worker ? worker : 'window', 'result:', res); + if(res instanceof Promise) { + res.then((r) => { + if((worker as any)?.postMessage) + (worker as any).postMessage({args:r,route}) + else if(globalThis.postMessage) + globalThis.postMessage({args:r,callbackId:route}); + }); + } else { + if((worker as any)?.postMessage) + (worker as any).postMessage({args:res,route}) + else if(globalThis.postMessage) + globalThis.postMessage({args:res,callbackId:route}); + } + }); + } + + subscribeToWorker = (route:string, workerId:string, callback?:((res:any)=>void)|string) => { + if(typeof workerId === 'string' && this.workers[workerId]) { + this.subscribe(workerId, (res) => { + if(res?.callbackId === route) { + if(!callback) this.setState({[workerId]:res.args}); //just set state + else if(typeof callback === 'string') { //run a local node + this.run(callback,res.args); + } + else callback(res.args); + } + }); + return this.workers[workerId].run('subscribeWorker', [route, workerId]); + } + } + + //requires unsafe service to load on other end + transferFunction(worker:WorkerInfo, fn:Function, fnName?:string) { + if(!fnName) fnName = fn.name; + return worker.request({ + route:'setRoute', + args:[ + fn.toString(), + fnName + ] + } as ServiceMessage); + } + + //requires unsafe service to load on other end + transferClass(worker:WorkerInfo, cls:Function, className?:string) { + if(!className) className = cls.name; + return worker.request({ + route:'receiveClass', + args:[ + cls.toString(), + className + ] + } as ServiceMessage); + } + + + routes:Routes={ + addWorker:this.addWorker, + toObjectURL:this.toObjectURL, + request:this.request, + runRequest:this.runRequest, + establishMessageChannel:this.establishMessageChannel, + subscribeWorker:this.subscribeWorker, + subscribeToWorker:this.subscribeToWorker, + unsubscribe:this.unsubscribe + } + +} \ No newline at end of file diff --git a/services/worker/Worker.service.ts b/services/worker/Worker.service.ts new file mode 100644 index 00000000..46c7d6a6 --- /dev/null +++ b/services/worker/Worker.service.ts @@ -0,0 +1,611 @@ +import { Service, Routes, ServiceMessage, ServiceOptions, Route } from "../Service"; +import Worker from 'web-worker' //cross platform for node and browser +import { GraphNodeProperties } from "../../Graph"; + +declare var WorkerGlobalScope; + +export type WorkerRoute = { + worker?:WorkerInfo + workerUrl?: string|URL|Blob, + workerId?: string, + transferFunctions?:{[key:string]:Function}, + transferClasses?:{[key:string]:Function}, + parentRoute?:string, //if a child of a worker node, subscribe to a route on a parent worker? + callback?:string //Run this route on the worker when the operator is called. If this route is a child of another node, run this node on the child worker when it receives a message. +} & GraphNodeProperties & WorkerProps + +export type WorkerProps = { + worker:WorkerInfo, + workerUrl?: string|URL|Blob, + url?:URL|string|Blob, + _id?:string, + port?:MessagePort, //message channel for this instance + onmessage?:(ev)=>void, + onerror?:(ev)=>void, + onclose?:(worker:Worker|MessagePort)=>void +} + +export type WorkerInfo = { + worker:Worker|MessagePort, + send:(message:any,transfer?:any)=>void, + request:(message:any, transfer?:any, method?:string)=>Promise, + post:(route:any, args?:any, transfer?:any)=>void, + run:(route:any, args?:any, transfer?:any, method?:string)=>Promise + subscribe:(route:any, callback?:((res:any)=>void)|string)=>any, + unsubscribe:(route:any, sub:number)=>Promise, + terminate:()=>boolean, + graph:WorkerService, + _id:string +} & WorkerProps & WorkerRoute + +//this spawns the workers +export class WorkerService extends Service { + + name='worker' + + workers:{ + [key:string]:WorkerInfo + }={} + + threadRot = 0; //thread rotation if not specifying + + connections = { //higher level reference for Router + workers:this.workers + } + + constructor(options?:ServiceOptions) { + super(options); + this.load(this.routes); + + if(typeof WorkerGlobalScope !== 'undefined' && globalThis instanceof WorkerGlobalScope) { + this.addDefaultMessageListener(); + } + } + + customRoutes:ServiceOptions["customRoutes"] = { + 'worker':(route:Route | WorkerRoute,routeKey:string, routes:Routes) => { + let rt = route as WorkerRoute; + if(rt?.worker || rt?.workerId) { //each set of props with a worker will instantiate a new worker, else you can use the same worker elsewhere by passing the corresponding tag + if(rt.workerUrl) rt.url = rt.workerUrl; + if(rt.workerId) rt.tag = rt.workerId; + if(!rt.tag) rt.tag = routeKey; + rt._id = rt.tag; + + let worker:WorkerInfo; + if(this.workers[rt._id]) worker = this.workers[rt._id]; + if(!worker) worker = this.addWorker(rt); + rt.worker = worker; + + //requires unsafeservice on the worker (enabled on the default worker) + if(rt.transferFunctions) { + for(const prop in rt.transferFunctions) { + this.transferFunction(worker,rt.transferFunctions[prop],prop) + } + } + if(rt.transferClasses) { + for(const prop in rt.transferClasses) { + this.transferClass(worker,rt.transferClasses[prop],prop) + } + } + + if(worker) { + if(!rt.operator) { + rt.operator = (...args) => { + //console.log('operator', args) + if(rt.callback) { + if(!this.nodes.get(rt.tag)?.children) worker.post(rt.callback,args); + else return worker.run(rt.callback,args); + } else { + if(!this.nodes.get(rt.tag)?.children) worker.send(args); + else return worker.request(args); + } + } + } + } + } + + return rt; + } + } + + customChildren:ServiceOptions["customChildren"] = { + 'worker':(child: WorkerRoute, childRouteKey: string, parent: WorkerRoute, routes: Routes, checked: Routes) => { + + let worker; + if((child as WorkerRoute)?.worker || (child as WorkerRoute)?.workerId) { + if(child.workerUrl) child.url = child.workerUrl; + if(child.workerId) child.tag = child.workerId; + if(!child.tag) child.tag = childRouteKey; + child._id = child.tag; + + if(this.workers[child._id]) worker = this.workers[child._id]; + if(!worker) worker = this.addWorker(child); + child.worker = worker; + + //requires unsafeservice on the worker (enabled on the default worker) + if(child.transferFunctions) { + for(const prop in child.transferFunctions) { + this.transferFunction(worker,child.transferFunctions[prop],prop) + } + } + if(child.transferClasses) { + for(const prop in child.transferClasses) { + this.transferClass(worker,child.transferClasses[prop],prop) + } + } + + if(worker) { + if(!child.operator) { + child.operator = (...args) => { + //console.log('operator', args) + + if(child.callback) { + if(!this.nodes.get(child.tag)?.children) worker.post(child.callback,args); + else return worker.run(child.callback,args); + } else { //just post whatever + if(!this.nodes.get(child.tag)?.children) worker.send(args); + else return worker.request(args); + } + } + } + } + } + if(child.parentRoute && ((parent as WorkerRoute)?.worker || (parent as WorkerRoute)?.workerId)) { + + if(worker) { + let portId = this.establishMessageChannel(worker,parent.worker.worker) + worker.post('subscribeToWorker', child.parentRoute, portId, child.callback); + } else { + parent.worker.subscribe(child.parentRoute,(result) => {this.nodes.get(child.tag ? child.tag : childRouteKey).run(result)}); + } + } + } + } //todo, create message ports between workers with parent/child relationships and set up pipes + + //works in window as well (caution) + addDefaultMessageListener() { + globalThis.onmessage = (ev:MessageEvent) => { + let result = this.receive(ev.data); //this will handle graph logic and can run requests for the window or messsage ports etc etc. + //console.log(JSON.stringify(ev.data), JSON.stringify(result),JSON.stringify(Array.from((self as any).SERVICE.nodes.keys()))) + //console.log(result); + if(this.keepState) this.setState({[this.name]:result}); //subscribe to all outputs + } //this will work for iframes too + } + + //post messages to workers or to window (or self as worker) + postMessage = (message:any, target:string, transfer?:Transferable[]) => { + if(this.workers[target]) { + this.workers[target].send(message,transfer); + } else { + globalThis.postMessage(message, target, transfer) + } + } + + addWorker = (options:{ + url?:URL|string|Blob, + port?:MessagePort, + _id?:string, + onmessage?:(ev)=>void, + onerror?:(ev)=>void + }) => { //pass file location, web url, or javascript dataurl string + let worker:Worker|MessagePort; + + if(!options._id) + options._id = `worker${Math.floor(Math.random()*1000000000000000)}`; + + if(options.url) worker = new Worker(options.url); + else if (options.port) { + worker = options.port; + } else if (this.workers[options._id]) { + if(this.workers[options._id].port) worker = this.workers[options._id].port; + else worker = this.workers[options._id].worker; + } + + if(!worker) return; + + let send = (message:any,transfer?:any) => { + //console.log('sent', message) + return this.transmit(message,worker,transfer); + } + + let post = (route:any,args?:any,transfer?:any, method?:string) => { + //console.log('sent', message) + let message:any = { + route, + args + }; + if(method) message.method = method; + + return this.transmit(message,worker,transfer); + } + + let run = (route:any,args?:any, transfer?:any, method?:string) => { + return new Promise ((res,rej) => { + let callbackId = Math.random(); + let req = {route:'runRequest', args:[{route, args}, options._id, callbackId]} as any; + //console.log(req) + if(method) req.args[0].method = method; + let onmessage = (ev)=>{ + if(typeof ev.data === 'object') { + if(ev.data.callbackId === callbackId) { + worker.removeEventListener('message',onmessage); + res(ev.data.args); //resolve the request with the corresponding message + } + } + } + worker.addEventListener('message',onmessage) + this.transmit(req, worker, transfer); + }); + } + + let request = (message:ServiceMessage|any, transfer?:any, method?:string) => { + return new Promise ((res,rej) => { + let callbackId = Math.random(); + let req = {route:'runRequest', args:[message,options._id,callbackId]} as any; + //console.log(req) + if(method) req.method = method; + let onmessage = (ev)=>{ + if(typeof ev.data === 'object') { + if(ev.data.callbackId === callbackId) { + worker.removeEventListener('message',onmessage); + res(ev.data.args); //resolve the request with the corresponding message + } + } + } + worker.addEventListener('message',onmessage) + this.transmit(req, worker, transfer); + }); + } + + let subscribe = (route:any, callback?:((res:any)=>void)|string) => { + return this.subscribeToWorker(route, options._id, callback); + } + + let unsubscribe = (route:any, sub:number):Promise => { + return run('unsubscribe',[route,sub]); + } + + let terminate = () => { + return this.terminate(options._id); + } + + if(!options.onmessage) options.onmessage = (ev) => { + this.receive(ev.data); + this.setState({[options._id as string]:ev.data}); + } + + if(!options.onerror) { + options.onerror = (ev) => { + console.error(ev.data); + } + } + + worker.onmessage = options.onmessage; + (worker as Worker).onerror = options.onerror; + + this.workers[options._id] = { + worker:(worker as any), + send, + post, + run, + request, + subscribe, + unsubscribe, + terminate, + graph:this, + ...options + } as WorkerInfo; + + return this.workers[options._id]; + } + + //new Worker(urlFromString) + toObjectURL = (scriptTemplate:string) => { + let blob = new Blob([scriptTemplate],{type:'text/javascript'}); + return URL.createObjectURL(blob); + } + + getTransferable(message:any) { + //automatic dataview/typedarray/arraybuffer transferring. + // There are more transferable types but we start to slow things + // down if we check too many cases so make transfer explicit in general! This is mainly for automating subscriptions + let transfer; + if(typeof message === 'object') { + if(message.args) { + if (message.args.constructor?.name === 'Object') { + for(const key in message.args) { + if(ArrayBuffer.isView(message.args[key])) { + if(!transfer) + transfer = [message.args[key].buffer] as StructuredSerializeOptions; + else + (transfer as any[]).push(message.args[key].buffer); + } else if (message.args[key]?.constructor?.name === 'ArrayBuffer') { + if(!transfer) + transfer = [message.args[key]] as StructuredSerializeOptions; + else + (transfer as any[]).push(message.args[key]); + } + } + } + else if(Array.isArray(message.args) && message.args.length < 11) { //lets check any argument less size 10 or less for typed array inputs + message.args.forEach((arg) => { + if(ArrayBuffer.isView(arg)) { + transfer = [arg.buffer] as StructuredSerializeOptions; + } else if (arg.constructor?.name === 'ArrayBuffer') + transfer = [arg] as StructuredSerializeOptions; + }); + } + else if(ArrayBuffer.isView(message.args)) { + transfer = [message.args.buffer] as StructuredSerializeOptions; + } + else if (message.args.constructor?.name === 'ArrayBuffer') { + transfer = [message] as StructuredSerializeOptions; + } + } + else if (message.constructor?.name === 'Object') { + for(const key in message) { + if(ArrayBuffer.isView(message[key])) { + if(!transfer) + transfer = [message[key].buffer] as StructuredSerializeOptions; + else + (transfer as any[]).push(message[key].buffer); + } else if (message[key]?.constructor?.name === 'ArrayBuffer') { + if(!transfer) + transfer = [message[key]] as StructuredSerializeOptions; + else + (transfer as any[]).push(message[key]); + } + } + } + else if(Array.isArray(message) && message.length < 11) { //lets check any argument size 10 or less for typed array inputs + message.forEach((arg) => { + if(ArrayBuffer.isView(arg)) { + transfer = [arg.buffer] as StructuredSerializeOptions; + } else if (arg.constructor?.name === 'ArrayBuffer') + transfer = [arg] as StructuredSerializeOptions; + }); + } + else if(ArrayBuffer.isView(message)) { + transfer = [message.buffer] as StructuredSerializeOptions; + } + else if (message.constructor?.name === 'ArrayBuffer') { + transfer = [message] as StructuredSerializeOptions; + } + } + + return transfer; + } + + transmit = (message:ServiceMessage|any, worker?:Worker|MessagePort|string, transfer?:StructuredSerializeOptions ) => { + + if(!transfer) { + transfer = this.getTransferable(message); //automatically transfer arraybuffers + } + + //console.log(message) + + if(worker instanceof Worker || worker instanceof MessagePort) { + worker.postMessage(message,transfer); + } else if(typeof worker === 'string') { + if(this.workers[worker as string]) { + if(this.workers[worker as string].port) + (this.workers[worker as string].port as any).postMessage(message,transfer); + else if (this.workers[worker as string].worker) + this.workers[worker as string].worker.postMessage(message,transfer); + } + } else { + let keys = Object.keys(this.workers); + this.workers[keys[this.threadRot]].worker.postMessage(message,transfer); + this.threadRot++; + if(this.threadRot === keys.length) this.threadRot = 0; + } + return message; + } + + terminate = (worker:Worker|MessagePort|string) => { + let onclose; + if(typeof worker === 'string') { + let obj = this.workers[worker]; + if(obj) delete this.workers[worker]; + worker = obj.worker; + if(obj.onclose) onclose = obj.onclose; + } + if(worker instanceof Worker) { + worker.terminate(); + if(onclose) onclose(worker); + return true; + } + if(worker instanceof MessagePort) { + worker.close(); + if(onclose) onclose(worker); + return true; + } + return false; + } + + //if no second id provided, message channel will exist to this thread + establishMessageChannel = (worker:Worker|string|MessagePort, worker2?:Worker|string|MessagePort) => { + + let workerId; + if(typeof worker === 'string') { + workerId = worker; + if(this.workers[worker]){ + if(this.workers[worker].port) worker = this.workers[worker].port; + else worker2 = this.workers[worker].worker; + } + } + if(typeof worker2 === 'string') { + if(this.workers[worker2]){ + if(this.workers[worker2].port) worker2 = this.workers[worker2].port; + else worker2 = this.workers[worker2].worker; + } + } + + if(worker instanceof Worker || worker instanceof MessagePort) { + let channel = new MessageChannel(); + let portId = `port${Math.floor(Math.random()*1000000000000000)}`; + + worker.postMessage({route:'addWorker',args:{port:channel.port1, _id:portId}},[channel.port1]); + + if(worker2 instanceof Worker || worker2 instanceof MessagePort) { + worker2.postMessage({route:'addWorker',args:{port:channel.port2, _id:portId}},[channel.port2]); + } else if(workerId && this.workers[workerId]) { + channel.port2.onmessage = this.workers[workerId].onmessage; + this.workers[workerId].port = channel.port2; + } + + return portId; + } + + return false; + + } + + request = (message:ServiceMessage|any, workerId:string, transfer?:any, method?:string) => { + let worker = this.workers[workerId].worker; + return new Promise ((res,rej) => { + let callbackId = Math.random(); + let req = {route:'runRequest', args:[message, callbackId]} as any; + if(method) req.method = method; + let onmessage = (ev)=>{ + if(typeof ev.data === 'object') { + if(ev.data.callbackId === callbackId) { + worker.removeEventListener('message',onmessage); + res(ev.data.args); //resolve the request with the corresponding message + } + } + } + worker.addEventListener('message',onmessage) + this.transmit(req, worker, transfer); + }); + } + + runRequest = (message:ServiceMessage|any, worker:undefined|string|Worker|MessagePort, callbackId:string|number) => { + let res = this.receive(message); + if(typeof worker === 'string' && this.workers[worker]) { + if(this.workers[worker].port) worker = this.workers[worker].port; + else worker = this.workers[worker].worker; + } + //console.log('running request', message, 'for worker', worker, 'callback', callbackId) + if(res instanceof Promise) { + res.then((r) => { + if(worker instanceof Worker || worker instanceof MessagePort) + worker.postMessage({args:r,callbackId}) + else if(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) + globalThis.postMessage({args:r,callbackId}); + }); + } else { + if(worker instanceof Worker || worker instanceof MessagePort) + worker.postMessage({args:res,callbackId}) + else if(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) + globalThis.postMessage({args:res,callbackId}); + } + + return res; + } + + subscribeWorker = (route:string, worker:Worker|string|MessagePort) => { + //console.log('subscribed!',worker, this.workers, WorkerGlobalScope); + if(typeof worker === 'string' && this.workers[worker]) { + if(this.workers[worker].port) worker = this.workers[worker].port; + else worker = this.workers[worker].worker; + } + return this.subscribe(route, (res:any) => { + //console.log('running request', message, 'for worker', worker, 'callback', callbackId) + //console.log('subscription triggered for', route, 'to', worker instanceof Worker ? worker : 'window', 'result:', res); + if(res instanceof Promise) { + res.then((r) => { + if((worker as any)?.postMessage) + (worker as any).postMessage({args:r,callbackId:route}) + else if(globalThis.postMessage) + globalThis.postMessage({args:r,callbackId:route}); + }); + } else { + if((worker as any)?.postMessage) + (worker as any).postMessage({args:res,callbackId:route}) + else if(globalThis.postMessage) + globalThis.postMessage({args:res,callbackId:route}); + } + }); + } + + subscribeToWorker = (route:string, workerId:string, callback?:((res:any)=>void)|string) => { + if(typeof workerId === 'string' && this.workers[workerId]) { + this.subscribe(workerId, (res) => { + if(res?.callbackId === route) { + if(!callback) this.setState({[workerId]:res.args}); //just set state + else if(typeof callback === 'string') { //run a local node + this.run(callback,res.args); + } + else callback(res.args); + } + }); + return this.workers[workerId].run('subscribeWorker', [route, workerId]); + } + } + + pipeWorkers = ( //worker a listens to worker b, be sure to unsubscribe on the source when terminating + sourceWorker:WorkerInfo, + listenerWorker:WorkerInfo, + sourceRoute:string, + listenerRoute:string, + portId?:string + ) => { + if(!portId) { + portId = this.establishMessageChannel(sourceWorker.worker,listenerWorker.worker) as string; + } + return listenerWorker.run('subscribeToWorker',[sourceRoute,portId,listenerRoute]) as Promise; //just run .unsubscribe on worker2. + } + + unpipeWorkers = ( + sourceWorker:WorkerInfo, + sourceRoute:string, + sub:number + ) => { + return sourceWorker.run('unsubscribe',[sourceRoute,sub]); + } + + //requires unsafe service to load on other end + transferFunction(worker:WorkerInfo, fn:Function, fnName?:string) { + if(!fnName) fnName = fn.name; + return worker.request({ + route:'setRoute', + args:[ + fn.toString(), + fnName + ] + } as ServiceMessage); + } + + //requires unsafe service to load on other end + transferClass(worker:WorkerInfo, cls:Function, className?:string) { + if(!className) className = cls.name; + return worker.request({ + route:'receiveClass', + args:[ + cls.toString(), + className + ] + } as ServiceMessage); + } + + + routes:Routes={ + addWorker:{ + operator:this.addWorker, + aliases:['open'] + }, + toObjectURL:this.toObjectURL, + request:this.request, + runRequest:this.runRequest, + establishMessageChannel:this.establishMessageChannel, + subscribeWorker:this.subscribeWorker, + subscribeToWorker:this.subscribeToWorker, + unsubscribe:(route,sub)=>{ + //console.log('unsubbing',route,sub,this.state.triggers,this.nodes.keys()); + this.unsubscribe(route,sub); + }, + terminate:this.terminate + } + +} \ No newline at end of file diff --git a/src/services/worker/Worker.ts b/services/worker/Worker.ts similarity index 64% rename from src/services/worker/Worker.ts rename to services/worker/Worker.ts index 97210ada..c7d5780e 100644 --- a/src/services/worker/Worker.ts +++ b/services/worker/Worker.ts @@ -2,8 +2,8 @@ import { WorkerService } from './Worker.service'; //import { GPUService } from '../gpu/GPU.service'; import { workerCanvasRoutes } from './WorkerCanvas'; -import { remoteGraphRoutes } from '../remote/remote.routes'; -import { Math2 } from 'brainsatplay-math'; +import { unsafeRoutes } from '../unsafe/Unsafe.service'; +import { ECSService } from '../ecs/ECS.service'; //wonder if we can have a scheme to dynamic import within the services? e.g. to bring in node-only or browser-only services without additional workers @@ -11,12 +11,14 @@ declare var WorkerGlobalScope; if(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) { (self as any).SERVICE = new WorkerService({ - services:{ + routes:[ + (self as any).SERVICE, + //GPUService, workerCanvasRoutes, - remoteGraphRoutes, //allows dynamic route loading - Math, - Math2 - } + ECSService, + unsafeRoutes //allows dynamic route loading + ], + includeClassName:false }); } diff --git a/services/worker/WorkerCanvas.ts b/services/worker/WorkerCanvas.ts new file mode 100644 index 00000000..f0a27f4a --- /dev/null +++ b/services/worker/WorkerCanvas.ts @@ -0,0 +1,329 @@ +//provide routes for applying canvases to workers + +import { Graph, parseFunctionFromText } from "../../Graph"; +import { proxyElementWorkerRoutes } from "./ProxyListener"; + +export type WorkerCanvasTransferProps = { //defined in main thread to send to worker + canvas:HTMLCanvasElement, + context?:string, + _id?:string, + draw?:string|((self:any,canvas:any,context:any)=>void), + update?:string|((self:any,canvas:any,context:any,input:any)=>void), + init?:string|((self,canvas:any,context:any)=>void), + clear?:string|((self,canvas:any,context:any)=>void), + animating?:boolean, //animation will start automatically, else you can call draw conditionally + [key:string]:any //any transferrable props you want to use in your animation +} + +export type WorkerCanvasReceiveProps = { //defined in worker thread + canvas:any, //offscreen canvas + context:string|CanvasRenderingContext2D|WebGL2RenderingContext|WebGLRenderingContext, + _id?:string, + width?:number, + height?:number, + init?:string, + update?:string, + draw?:string, + clear?:string, + animating?:boolean, + [key:string]:any +} + +export type WorkerCanvasControls = { + _id:string, + worker:Worker|MessagePort, + draw:(props?:any)=>void, + update:(props:{[key:string]:any})=>void, + clear:()=>void, + init:()=>void, + stop:()=>void, + start:()=>void, + set:(newDrawProps:WorkerCanvasReceiveProps)=>void +} +export type WorkerCanvas = { //this is the object stored on the worker to track this canvas context + graph:Graph, + canvas:any, //OffscreenCanvas + context?:CanvasRenderingContext2D|WebGL2RenderingContext|WebGLRenderingContext, + _id:string, + draw?:((self:WorkerCanvas,canvas:WorkerCanvas['canvas'],context:WorkerCanvas['context'])=>void), //runs in animation loop or on drawFrame calls + update?:((self:WorkerCanvas,canvas:WorkerCanvas['canvas'],context:WorkerCanvas['context'],input:any)=>void), + init?:((self:WorkerCanvas,canvas:WorkerCanvas['canvas'],context:WorkerCanvas['context'])=>void), + clear?:((self:WorkerCanvas,canvas:WorkerCanvas['canvas'],context:WorkerCanvas['context'])=>void), + animating:boolean, //animation will start automatically, else you can call draw conditionally + [key:string]:any //any transferrable props you want to use in your animation +} + + +//load on front and backend +export const workerCanvasRoutes = { + ...proxyElementWorkerRoutes, + transferCanvas:function( + worker:Worker|MessagePort, + options:WorkerCanvasTransferProps, + route?:string //we can reroute from the default 'receiveCanvas' e.g. for other rendering init processes like in threejs + ){ + + + if(!options) return undefined; + if(!options._id) options._id = `canvas${Math.floor(Math.random()*1000000000000000)}`; + + let offscreen = (options.canvas as any).transferControlToOffscreen(); + + let message:any = {route:route ? route : 'receiveCanvas',args:{canvas:offscreen, context: options.context, _id:options._id}}; + + this.graph.run('initProxyElement', options.canvas, worker, options._id); //initiate an element proxy + + if(options.draw) { + if(typeof options.draw === 'function') message.args.draw = options.draw.toString() + else message.args.draw = options.draw; + } + if(options.update) { + if(typeof options.update === 'function') message.args.update = options.update.toString() + else message.args.update = options.update; + } + if(options.init) { + if(typeof options.init === 'function') message.args.init = options.init.toString() + else message.args.init = options.init; + } + if(options.clear) { + if(typeof options.clear === 'function') message.args.clear = options.clear.toString() + else message.args.clear = options.clear; + } + + worker.postMessage(message,[offscreen]); + + //lets add some utilities to make it easy to update the thread + const workercontrols = { + _id:options._id, + worker, + draw:(props?:any)=>{ + worker.postMessage({route:'drawFrame',args:[options._id,props]}); + }, + update:(props:{[key:string]:any})=>{ + worker.postMessage({route:'updateCanvas',args:[options._id, props]}) + }, + clear:()=>{ + worker.postMessage({route:'clearCanvas',args:options._id}) + }, + init:()=>{ + console.log('Posting init') + worker.postMessage({route:'initCanvas',args:options._id}); + }, + stop:()=>{ + worker.postMessage({route:'stopAnim',args:options._id}) + }, + start:()=>{ + worker.postMessage({route:'startAnim',args:options._id}) + }, + set:(newDrawProps:WorkerCanvasReceiveProps)=>{ + worker.postMessage({route:'setDraw',args:[newDrawProps,options._id]}); + } + } + + return workercontrols as WorkerCanvasControls; + }, + receiveCanvas:function( + options:WorkerCanvasReceiveProps + ){ + + if(!this.graph.CANVASES) this.graph.CANVASES = {} as {[key:string]:WorkerCanvas}; + + let canvasOptions = options; + + options._id ? canvasOptions._id = options._id : canvasOptions._id = `canvas${Math.floor(Math.random()*1000000000000000)}`; + typeof options.context === 'string' ? canvasOptions.context = options.canvas.getContext(options.context) : canvasOptions.context = options.context; //get the rendering context based on string passed + ('animating' in options) ? canvasOptions.animating = options.animating : canvasOptions.animating = true; + + if(this.graph.CANVASES[canvasOptions._id]) { + this.graph.run('setDraw',canvasOptions); + } + else { + + canvasOptions.graph = this.graph; + this.graph.CANVASES[canvasOptions._id] = canvasOptions; + + //create an element proxy to add event listener functionality + this.graph.run('makeProxy', canvasOptions._id, canvasOptions.canvas); + //now the canvas can handle mouse and resize events, more can be implemented + + if(options.width) canvasOptions.canvas.width = options.width; + if(options.height) canvasOptions.canvas.height = options.height; + + if(typeof canvasOptions.draw === 'string') { + canvasOptions.draw = parseFunctionFromText(canvasOptions.draw); + } + if(typeof canvasOptions.update === 'string') { + canvasOptions.update = parseFunctionFromText(canvasOptions.update); + } + if(typeof canvasOptions.init === 'string') { + canvasOptions.init = parseFunctionFromText(canvasOptions.init); + } + if(typeof canvasOptions.clear === 'string') { + canvasOptions.clear = parseFunctionFromText(canvasOptions.clear); + } + + if(typeof canvasOptions.init === 'function') + (canvasOptions.init as any)(canvasOptions, canvasOptions.canvas,canvasOptions.context); + + if(typeof canvasOptions.draw === 'function' && canvasOptions.animating) { + let draw = (s,canvas,context) => { + if(s.animating) { + s.draw(s,canvas,context); + requestAnimationFrame(()=>{ + draw(s,canvas,context); + }); + } + } + + draw(canvasOptions, canvasOptions.canvas,canvasOptions.context); + + } + } + + return canvasOptions._id; + }, + setDraw:function( + settings:WorkerCanvasReceiveProps, + _id?:string + ){ + let canvasopts; + if(_id) canvasopts = this.graph.CANVASES?.[settings._id]; + else if(settings._id) canvasopts = this.graph.CANVASES?.[settings._id]; + else canvasopts = this.graph.CANVASES?.[Object.keys(this.graph.CANVASES)[0]]; + + if(canvasopts) { + if(settings.canvas) { + canvasopts.canvas = settings.canvas; + + //create an element proxy to add event listener functionality + this.graph.run('makeProxy', canvasopts._id, canvasopts.canvas); + //now the canvas can handle mouse and resize events, more can be implemented + } + if(typeof settings.context === 'string') canvasopts.context = canvasopts.canvas.getContext(settings.context); + else if(settings.context) canvasopts.context = settings.context; + + if(settings.width) canvasopts.canvas.width = settings.width; + if(settings.height) canvasopts.canvas.height = settings.height; + if(typeof settings.draw === 'string') settings.draw = parseFunctionFromText(settings.draw); + if(typeof settings.draw === 'function') { + canvasopts.draw = settings.draw; + } + if(typeof settings.update === 'string') settings.update = parseFunctionFromText(settings.update); + if(typeof settings.update === 'function') { + canvasopts.update = settings.update; + } + if(typeof settings.init === 'string') settings.init = parseFunctionFromText(settings.init); + if(typeof settings.init === 'function') { + canvasopts.init = settings.init; + } + if(typeof settings.clear === 'string') settings.clear = parseFunctionFromText(settings.clear); + if(typeof settings.clear === 'function') { + canvasopts.clear = settings.clear; + } + return settings._id; + } + return undefined; + }, + drawFrame: function(props?:{[key:string]:any},_id?:string) { //can update props when calling draw + let canvasopts; + if(!_id) canvasopts = this.graph.CANVASES?.[Object.keys(this.graph.CANVASES)[0]]; + else canvasopts = this.graph.CANVASES?.[_id]; + if(canvasopts) { + if(props) Object.assign(canvasopts,props); + if(canvasopts.draw) { + canvasopts.draw(canvasopts,canvasopts.canvas,canvasopts.context); + return _id; + } + } + return undefined; + }, + clearCanvas: function(_id?:string) { + let canvasopts; + if(!_id) canvasopts = this.graph.CANVASES?.[Object.keys(this.graph.CANVASES)[0]]; + else canvasopts = this.graph.CANVASES?.[_id]; + + if(canvasopts?.clear) { + canvasopts.clear(canvasopts,canvasopts.canvas,canvasopts.context); + return _id; + } + return undefined; + }, + initCanvas:function(_id?:string){ + let canvasopts; + if(!_id) canvasopts = this.graph.CANVASES?.[Object.keys(this.graph.CANVASES)[0]]; + else canvasopts = this.graph.CANVASES?.[_id]; + + if(canvasopts?.init) { + canvasopts.init(canvasopts,canvasopts.canvas,canvasopts.context); + return _id; + } + return undefined; + }, + updateCanvas:function(input?:any,_id?:string){ + let canvasopts; + if(!_id) canvasopts = this.graph.CANVASES?.[Object.keys(this.graph.CANVASES)[0]]; + else canvasopts = this.graph.CANVASES?.[_id]; + if(canvasopts?.update) { + canvasopts.update(canvasopts,canvasopts.canvas,canvasopts.context,input); + return _id; + } + return undefined; + }, + setProps:function(props?:{[key:string]:any},_id?:string,){ //update animation props, e.g. the radius or color of a circle you are drawing with a stored value + let canvasopts; + if(!_id) canvasopts = this.graph.CANVASES?.[Object.keys(this.graph.CANVASES)[0]]; + else canvasopts = this.graph.CANVASES?.[_id]; + if(canvasopts) { + Object.assign(canvasopts,props); + if(props.width) canvasopts.canvas.width = props.width; + if(props.height) canvasopts.canvas.height = props.height; + return _id; + } + return undefined; + }, + startAnim:function(_id?:string, draw?:string|((this:any,canvas:any,context:any)=>void)){ //run the draw function applied to the animation or provide a new one + + let canvasopts; + if(!_id) canvasopts = this.graph.CANVASES?.[Object.keys(this.graph.CANVASES)[0]]; + else canvasopts = this.graph.CANVASES?.[_id]; + canvasopts.animating = true; + if(canvasopts && draw) { + if(typeof draw === 'string') draw = parseFunctionFromText(draw); + if(typeof draw === 'function') { + canvasopts.draw = draw; + } + return _id; + } + + if(typeof canvasopts?.draw === 'function') { + let draw = (s,canvas,context) => { + if(s.animating) { + s.draw(s,canvas,context); + requestAnimationFrame(()=>{ + draw(s,canvas,context); + }) + } + } + + if(typeof canvasopts.clear === 'function') (canvasopts.clear as any)(canvasopts, canvasopts.canvas, canvasopts.context); + if(typeof canvasopts.init === 'function') (canvasopts.init as any)(canvasopts, canvasopts.canvas, canvasopts.context); + + draw(canvasopts,canvasopts.canvas,canvasopts.context); + return _id; + } + return undefined; + }, + stopAnim:function(_id?:string){ + let canvasopts; + if(!_id) canvasopts = this.graph.CANVASES?.[Object.keys(this.graph.CANVASES)[0]]; + else canvasopts = this.graph.CANVASES?.[_id]; + if(canvasopts) { + canvasopts.animating = false; + if(typeof canvasopts.clear === 'function') canvasopts.clear(canvasopts, canvasopts.canvas, canvasopts.context); + return _id; + } + return undefined; + } +} + +//todo: threejs \ No newline at end of file diff --git a/services/wss/WSS.browser.ts b/services/wss/WSS.browser.ts new file mode 100644 index 00000000..9d693239 --- /dev/null +++ b/services/wss/WSS.browser.ts @@ -0,0 +1,345 @@ +import { Service, Routes, ServiceMessage, ServiceOptions } from "../Service"; + +export type WebSocketProps = { + host:string, + port:number, + path?:string, + onmessage?:(data:string | ArrayBufferLike | Blob | ArrayBufferView, ws:WebSocket, wsinfo:WebSocketInfo)=>void, //will use this.receive as default + onopen?:(ev:any, ws:WebSocket, wsinfo:WebSocketInfo)=>void, + onclose?:(ev:any, ws:WebSocket, wsinfo:WebSocketInfo)=>void, + onerror?:(ev:any, ws:WebSocket, wsinfo:WebSocketInfo)=>void + protocol?:'ws'|'wss', + keepState?:boolean, + type?:'socket', + _id?:string, + [key:string]:any +} + +export type WebSocketInfo = { + socket:WebSocket, + address:string, + send:(message:any)=>void, + request:(message:any, method?:string)=>Promise, + post:(route:any, args?:any)=>void, + run:(route:any, args?:any, method?:string)=>Promise, + subscribe:(route:any, callback?:((res:any)=>void)|string)=>any, + unsubscribe:(route:any, sub:number)=>Promise, + terminate:()=>boolean, + _id?:string, + graph:WSSfrontend +} & WebSocketProps + +//browser side websockets +export class WSSfrontend extends Service { + + name='wss' + + sockets:{ + [key:string]:WebSocketInfo + } = { } + + connections = { //higher level reference for Router + sockets:this.sockets + } + + + constructor(options?:ServiceOptions) { + super(options) + this.load(this.routes); + } + + openWS = ( + options:WebSocketProps = { + host:'localhost', + port:7000, + path:undefined, + protocol:'ws', + onclose:(ev:any,socket:WebSocket,wsinfo:WebSocketInfo)=>{ + if(ev.target.url) delete this.sockets[ev.target.url]; + } + } + ) => { + let protocol = options.protocol; + if(!protocol) protocol = 'ws'; + let address = `${protocol}://${options.host}`; + + if(!('keepState' in options)) options.keepState = true; + if(options.port) address+= ':'+options.port; + if(options.path && !options.path?.startsWith('/')) address += '/'; + if(options.path) address += options.path; + + if(this.sockets[address]?.socket) + if(this.sockets[address].socket.readyState === this.sockets[address].socket.OPEN) + this.sockets[address].socket.close(); //we'll try refresh the socket + + const socket = new WebSocket(address); + + if(!options.onmessage) { + if(!options._id){ + options.onmessage = (data:any, ws:WebSocket, wsinfo:WebSocketInfo) => { + if(data) if(typeof data === 'string') { + let substr = data.substring(0,8); + if(substr.includes('{') || substr.includes('[')) { + if(substr.includes('\\')) data = data.replace(/\\/g,""); + if(data[0] === '"') { data = data.substring(1,data.length-1)}; + //console.log(message) + data = JSON.parse(data); //parse stringified objects + + if(data.route === 'setId') { + this.sockets[address]._id = data.args; + options.onmessage = (data:any, ws:WebSocket, wsinfo:WebSocketInfo) => { //clear extra logic after id is set + this.receive(data); + if(options.keepState) { + this.setState({[address as string]:data}); + } + } + } + } + } + + let res = this.receive(data); + if(options.keepState) this.setState({[address]:data}); + } //default onmessage + } + else { + options.onmessage = (data:any, ws:WebSocket, wsinfo:WebSocketInfo)=> { + this.receive(data,socket,this.sockets[address]); + if(options.keepState) { + this.setState({[address]:data}); + } + }; //clear this extra logic after id is set + } + } + + if((options as any).onmessage) { + socket.addEventListener('message',(ev)=>{ + (this.sockets[address] as any).onmessage(ev.data, socket, this.sockets[address]); + }); + } + socket.addEventListener('open',(ev)=>{if(this.sockets[address].onopen) (this.sockets[address] as any).onopen(ev,socket, this.sockets[address]);}); + socket.addEventListener('close',(ev)=>{if(this.sockets[address].onclose) (this.sockets[address] as any).onclose(ev,socket, this.sockets[address]);}); + socket.addEventListener('error',(ev)=>{if(this.sockets[address].onerror) (this.sockets[address] as any).onerror(ev,socket, this.sockets[address]);}); + + + let send = (message:ServiceMessage|any) => { + //console.log('sent', message) + return this.transmit(message,socket); + } + + let post = (route:any,args?:any, method?:string) => { + //console.log('sent', message) + let message:any = { + route, + args + }; + if(method) message.method = method; + + return this.transmit(message,socket); + } + + let run = (route:any,args?:any,method?:string) => { + return new Promise ((res,rej) => { + let callbackId = Math.random(); + let req = {route:'runRequest', args:[{route, args}, options._id, callbackId]} as any; + //console.log(req) + if(method) req.args[0].method = method; + let onmessage = (ev)=>{ + if(typeof ev.data === 'string' && ev.data.indexOf('{') > -1) ev.data = JSON.parse(ev.data); + if(typeof ev.data === 'object') { + if(ev.data.callbackId === callbackId) { + socket.removeEventListener('message',onmessage); + res(ev.data.args); //resolve the request with the corresponding message + } + } + } + socket.addEventListener('message',onmessage) + this.transmit(req, socket); + }); + } + + let request = (message:ServiceMessage|any, method?:string) => { + return new Promise ((res,rej) => { + let callbackId = Math.random(); + let req = {route:'runRequest', args:[message,options._id,callbackId]} as any; + //console.log(req) + if(method) req.method = method; + let onmessage = (ev)=>{ + if(typeof ev.data === 'string' && ev.data.indexOf('{') > -1) ev.data = JSON.parse(ev.data); + if(typeof ev.data === 'object') { + if(ev.data.callbackId === callbackId) { + socket.removeEventListener('message',onmessage); + res(ev.data.args); //resolve the request with the corresponding message + } + } + } + socket.addEventListener('message',onmessage) + this.transmit(req, socket); + }); + } + + let subscribe = (route:any, callback?:((res:any)=>void)|string):Promise => { + return this.subscribeToSocket(route, options._id, callback); + } + + let unsubscribe = (route:any, sub:number):Promise => { + return run('unsubscribe',[route,sub]); + } + + let terminate = () => { + return this.terminate(options._id); + } + + this.sockets[address] = { + type:'socket', + socket, + address, + send, + post, + run, + request, + subscribe, + unsubscribe, + terminate, + graph:this, + ...options + }; + + return this.sockets[address]; + } + + transmit = ( + data:string | ArrayBufferLike | Blob | ArrayBufferView | ServiceMessage, + ws:WebSocket + ) => { + if(typeof data === 'object') data = JSON.stringify(data); + if(!ws) { + let s = this.sockets[Object.keys(this.sockets)[0]]; + if(s) ws = s.socket; + } + if(ws instanceof WebSocket && ws?.readyState === 1) ws.send(data); + + return true; + } + + terminate = (ws:WebSocket|string) => { + if(!ws) { + let key = Object.keys(this.sockets)[0] + if(key) ws = this.sockets[key].socket; + } + else if(typeof ws === 'string') { + for(const k in this.sockets) { + if(k.includes(ws)) { + ws = this.sockets[k].socket; + break; + } + } + } + + if(ws instanceof WebSocket) + if(ws.readyState === ws.OPEN) + ws.close(); + + return true; + } + + request = ( + message:ServiceMessage|any, + ws:WebSocket, + _id:string, + method?:string + ) => { //return a promise which can resolve with a server route result through the socket + let callbackId = `${Math.random()}`; + let req:any = {route:'runRequest', args:[message,_id,callbackId]}; + if(method) req.method = method; + return new Promise((res,rej) => { + let onmessage = (ev:any) => { + let data = ev.data; + if(typeof data === 'string') if(data.includes('callbackId')) data = JSON.parse(data); + if(typeof data === 'object') if(data.callbackId === callbackId) { + ws.removeEventListener('message',onmessage); + res(data.args); + } + } + + ws.addEventListener('message',onmessage); + ws.send(JSON.stringify(req)); + }) + } + + runRequest = ( + message:any, + ws:WebSocket|string, + callbackId:string|number + ) => { //send result back + let res = this.receive(message); + if(typeof ws === 'string') { + for(const s in this.sockets) { + if(s === ws) {ws = this.sockets[s].socket; break;} + } + } + if(ws) { + if(res instanceof Promise) { + res.then((v) => { + res = {args:v, callbackId}; + if(ws instanceof WebSocket) ws.send(JSON.stringify(res)); + }) + } + else { + res = {args:res, callbackId}; + if(ws instanceof WebSocket) ws.send(JSON.stringify(res)); + } + } + + return res; + } + + subscribeSocket = (route:string, socket:WebSocket|string) => { + if(typeof socket === 'string' && this.sockets[socket]) { + socket = this.sockets[socket].socket; + } + + if(typeof socket === 'object') + return this.subscribe(route, (res:any) => { + //console.log('running request', message, 'for worker', worker, 'callback', callbackId) + if((socket as WebSocket).readyState === (socket as WebSocket).OPEN) { + if(res instanceof Promise) { + res.then((r) => { + (socket as WebSocket).send(JSON.stringify({args:r, callbackId:route})); + }); + } else { + (socket as WebSocket).send(JSON.stringify({args:res, callbackId:route})); + } + } + }); + } + + subscribeToSocket = (route:string, socketId:string, callback?:((res:any)=>void)|string) => { + if(typeof socketId === 'string' && this.sockets[socketId]) { + this.subscribe(socketId, (res) => { + let msg = JSON.parse(res); + if(msg?.callbackId === route) { + if(!callback) this.setState({[socketId]:msg.args}); //just set state + else if(typeof callback === 'string') { //run a local node + this.run(callback,msg.args); + } + else callback(msg.args); + } + }); + return this.sockets[socketId].request({route:'subscribeSocket', args:[route,socketId]}); + } + } + + routes:Routes = { + openWS:{ + operator:this.openWS, + aliases:['open'] + }, + request:this.request, + runRequest:this.runRequest, + terminate:this.terminate, + subscribeSocket:this.subscribeSocket, + subscribeToSocket:this.subscribeToSocket, + unsubscribe:this.unsubscribe + } + +} diff --git a/src/services/wss/WSS.node.ts b/services/wss/WSS.node.ts similarity index 67% rename from src/services/wss/WSS.node.ts rename to services/wss/WSS.node.ts index 544732e4..487ee5b9 100644 --- a/src/services/wss/WSS.node.ts +++ b/services/wss/WSS.node.ts @@ -1,17 +1,14 @@ -import { Service, ServiceMessage, ServiceOptions } from "../Service"; -import WebSocket, { PerMessageDeflateOptions, WebSocketServer } from 'ws'; //third party lib. //createWebSocketStream <-- use this for cross-node instance communication +import { Routes, Service, ServiceMessage, ServiceOptions } from "../Service"; +import WebSocket, { WebSocketServer } from 'ws'; //third party lib. //createWebSocketStream <-- use this for cross-node instance communication import http from 'http' import https from 'https' -import { GraphNodeProperties } from "../../core/Graph"; //import { GraphNode } from "../Graph"; export type SocketServerProps = { - server?:http.Server|https.Server|true, //set to true to indicate you want a wss when using the open() command if not providing a server... - port?:7000|number, - path?:'wss'|'hotreload'|'python'|string, - noServer?:boolean, - host?:'localhost'|'127.0.0.1'|string, //for matching upgrade urls - perMessageDeflate?:PerMessageDeflateOptions, + server:http.Server|https.Server, + host:'localhost'|'127.0.0.1'|string, + port:7000|number, + path:'wss'|'hotreload'|'python'|string, onmessage?:(data:any, ws:WebSocket, serverinfo:SocketServerInfo)=>void, onclose?:(wss:WebSocketServer, serverinfo:SocketServerInfo)=>void, onconnection?:(ws:WebSocket,request:http.IncomingMessage, serverinfo:SocketServerInfo, clientId:string)=>void, @@ -20,10 +17,8 @@ export type SocketServerProps = { onupgrade?:(ws:WebSocket, serverinfo:SocketServerInfo, request:http.IncomingMessage, socket:any, head:Buffer)=>void, //after handleUpgrade is called keepState?:boolean, type?:'wss', - debug?:boolean - serverOptions?:WebSocket.ServerOptions, [key:string]:any -} & GraphNodeProperties +} export type SocketServerInfo = { wss:WebSocketServer, @@ -45,7 +40,6 @@ export type SocketProps = { path?:string, socket?:WebSocket, address?:string, - debug?:boolean, serverOptions?:WebSocket.ServerOptions onmessage?:(data:string | ArrayBufferLike | Blob | ArrayBufferView | Buffer[], ws:WebSocket,wsinfo:SocketProps)=>void, //will use this.receive as default onopen?:(ws:WebSocket,wsinfo:SocketProps)=>void, @@ -55,7 +49,7 @@ export type SocketProps = { type?:'socket', _id?:string, keepState?:boolean -} & GraphNodeProperties +} export type SocketInfo = { socket:WebSocket, @@ -64,7 +58,7 @@ export type SocketInfo = { request:(message:any, method?:string)=>Promise, post:(route:any, args?:any, method?:string)=>void, run:(route:any, args?:any, method?:string)=>Promise, - subscribe:(route:any, callback?:((res:any)=>void)|string, args?:any[], key?:string, subInput?:boolean)=>any, + subscribe:(route:any, callback?:((res:any)=>void)|string)=>any, unsubscribe:(route:any, sub:number)=>Promise, terminate:()=>void, graph:WSSbackend @@ -93,48 +87,32 @@ export class WSSbackend extends Service { constructor(options?:ServiceOptions) { super(options) - this.load(this); - } - - open = (options:SocketServerProps | SocketProps) => { - if((options as SocketServerProps)?.server) { - return this.setupWSS(options as SocketServerProps); - } else return this.openWS(options as SocketProps); + this.load(this.routes); } setupWSS = ( options:SocketServerProps, ) => { - let port = options.port; + const host = options.host; + const port = options.port; let path = options.path; - const server = typeof options.server === 'object' ? options.server : undefined; - let host = options.host; + const server = options.server; delete (options as any).server if(!('keepState' in options)) options.keepState = true; - let opts = {} as any; - if(options.noServer) opts.noServer = true; - else if(port) { - if(port) opts.port = port; - } - else if(server) opts.server = server; - if(options.perMessageDeflate) opts.perMessageDeflate = options.perMessageDeflate; + let opts = { + host, + port + }; - if(typeof options.serverOptions) Object.assign(opts,options.serverOptions); + if(typeof options.serverOptions) Object.assign(opts,options.serverOptions) const wss = new WebSocketServer(opts); - let address = ''; - if(!host && server) { - let addr = server.address() as any; - if(!port) port = addr.port; - address = addr.address; - - } else if(host) address = host; - if(port) address += ':'+port; + let address = `${host}:${port}/`; if(path) { - if(!path.startsWith('/')) path = '/'+path; + if(path.startsWith('/')) path = path.substring(1); address += path; } @@ -148,10 +126,6 @@ export class WSSbackend extends Service { if(!options.onmessage) options.onmessage = (data) => { //default onmessage if(data instanceof Buffer) data = data.toString(); - - if(options.debug) { - console.log(data); - } //console.log(data); const result = this.receive(data, wss, this.servers[address]); //console.log(result) @@ -159,7 +133,7 @@ export class WSSbackend extends Service { } - wss.addListener('connection',(ws,request) => { + wss.on('connection',(ws,request) => { if(this.debug) console.log(`New socket connection on ${address}`); let clientId = `socket${Math.floor(Math.random()*1000000000000)}`; @@ -167,28 +141,20 @@ export class WSSbackend extends Service { ws.send(JSON.stringify({ route:'setId', args:clientId })); - this.openWS({ + let info = this.openWS({ socket:ws, address:clientId, - _id:clientId, - debug:options.debug, - onclose:(code,reason) => { - if(this.servers[address].onconnectionclosed) - (this.servers[address] as any).onconnectionclosed(code, reason, ws, this.servers[address], clientId); - - delete this.servers[address].clients[clientId]; //delete by default onclose (memory saving) - } + _id:clientId }); //add send/receive etc functionality - if(options.debug) { - let time = getHoursAndMinutes(new Date()); - console.log(time, ' | ', clientId, ' | Number of live sockets: ', Object.keys(this.servers[address].clients).length); - } - if((this.servers[address] as any).onconnection) (this.servers[address] as any).onconnection(ws,request,this.servers[address], clientId);//can overwrite the default onmesssage response - + + if((this.servers[address] as any).onconnectionclosed) + ws.on('close',(code,reason)=>{ + if(this.servers[address].onconnectionclosed) (this.servers[address] as any).onconnectionclosed(code,reason,ws, this.servers[address], clientId); + }); }); wss.on('error',(err) => { @@ -197,46 +163,32 @@ export class WSSbackend extends Service { else console.error(err); }) - let onUpgrade = (request:http.IncomingMessage, socket:any, head:Buffer) => { //https://github.com/websockets/ws + let onUpgrade = (request:http.IncomingMessage,socket:any,head:Buffer) => { //https://github.com/websockets/ws if(request.headers && request.url) { if(this.debug) console.log("Upgrade request at: ", request.url); - let pass = false; - - if(path && request.url === path) pass = true; - else { - let addr = (request as any).headers.host.split(':')[0]; - if(port) addr += ':'+port; - if(addr === address) pass = true; - else { - addr += request.url.split('?')[0]; - if(addr === address) pass = true; - } - } - - if(pass && this.servers[address]) { - this.servers[address].wss.handleUpgrade(request,socket,head, (ws) => { - if((this.servers[address] as any).onupgrade) - (this.servers[address] as any).onupgrade(ws, this.servers[address], request, socket, head); - this.servers[address].wss.emit('connection', ws, request); + let addr = (request as any).headers.host.split(':')[0]; + addr += ':'+port; + addr += request.url.split('?')[0]; + + if(addr === address && this.servers[addr]) { + this.servers[addr].wss.handleUpgrade(request,socket,head, (ws) => { + if((this.servers[address] as any).onupgrade) (this.servers[address] as any).onupgrade(ws, this.servers[address], request, socket, head); + this.servers[addr].wss.emit('connection',ws,request); }); } } } - if(server) - server.addListener('upgrade', onUpgrade); + server.addListener('upgrade',onUpgrade); - wss.addListener('close',()=> { - if(server) server.removeListener('upgrade',onUpgrade); + wss.on('close',()=> { + server.removeListener('upgrade',onUpgrade); if((this.servers[address] as any).onclose) (this.servers[address] as any).onclose(wss, this.servers[address]); else console.log(`wss closed: ${address}`); - - delete this.servers[address]; }); let send = (message:any, socketId?:string) => { - if(typeof message === 'object') message = JSON.stringify(message); if(!socketId) { for(const key in this.servers[address].clients) { this.sockets[key].send(message); @@ -272,14 +224,14 @@ export class WSSbackend extends Service { } else return this.sockets[socketId].run(route,args, method); }; - let subscribe = (route:any, callback?:((res:any)=>void)|string,socketId?:string, args?:any[], key?:string, subInput?:boolean) => { + let subscribe = (route:any, callback?:((res:any)=>void)|string,socketId?:string) => { if(!socketId) { let promises:any=[] - for(const k in this.servers[address].clients) { - promises.push(this.sockets[k].subscribe(route,callback,args,key,subInput)); + for(const key in this.servers[address].clients) { + promises.push(this.sockets[key].subscribe(route,callback)); } return promises; - } else this.sockets[socketId].subscribe(route,callback,args,key,subInput); + } else this.sockets[socketId].subscribe(route,callback); }; let unsubscribe = (route:any, sub:number,socketId?:string) => { @@ -330,29 +282,11 @@ export class WSSbackend extends Service { if(!('keepState' in options)) options.keepState = true; - if(options.onmessage) { - socket.on( - 'message', - (data)=>{( - this.sockets[address] as any).onmessage( - data, - socket, - this.sockets[address] - ); - } - ); - } - + if(options.onmessage) socket.on('message',(data)=>{(this.sockets[address] as any).onmessage(data,socket,this.sockets[address]);}); else if (options._id) { - socket.addListener('message', (data:any)=> { + socket.on('message', (data:any)=> { if(ArrayBuffer.isView(data)) data = data.toString(); - - if(options.debug) { - console.log("Message from ",options._id, ": ", data); - } - - this.receive(data,socket, this.sockets[address]); - //console.log('socket received',data,Array.from(this.__node.nodes.keys())); + this.receive(data,socket,this.sockets[address]); if(options.keepState) { this.setState({[address]:data}); } @@ -362,9 +296,6 @@ export class WSSbackend extends Service { let socketonmessage = (data:any)=>{ if(ArrayBuffer.isView(data)) data = data.toString(); if(data) { - if(options.debug) { - console.log("Message from ",address, ": ", data); - } if(typeof data === 'string') { //pulling this out of receive to check if setId was called let substr = data.substring(0,8); if(substr.includes('{') || substr.includes('[')) { @@ -375,16 +306,9 @@ export class WSSbackend extends Service { if(data.route === 'setId') { this.sockets[address]._id = data.args; - socket.removeEventListener( - 'message', - socketonmessage - ); - + socket.removeEventListener('message',socketonmessage); socket.on('message', (data:any)=> { if(ArrayBuffer.isView(data)) data = data.toString(); - if(options.debug) { - console.log("Message from ",this.sockets[address]._id, ": ", data); - } this.receive(data,socket,this.sockets[address]); if(options.keepState) { this.setState({[address]:data}); @@ -398,27 +322,13 @@ export class WSSbackend extends Service { this.receive(data,socket,this.sockets[address]); if(options.keepState) this.setState({[address]:data}); } - socket.addListener('message',socketonmessage); //add default callback if none specified + socket.on('message',socketonmessage); //add default callback if none specified options.onmessage = socketonmessage; } - - socket.addListener('open',()=>{ - if(this.sockets[address].onopen) (this.sockets[address] as any).onopen(socket,this.sockets[address]); - }); - - socket.addListener('close',(code,reason)=>{ - let obj = this.sockets[address]; - let onclose = obj.onclose; - - delete this.sockets[address]; //delete by default onclose (memory saving) - - if(onclose) onclose(code,reason,socket,obj); - }); - - - socket.on('error',(er)=>{ - if(this.sockets[address].onerror) (this.sockets[address] as any).onerror(er,socket,this.sockets[address]); - }); + socket.on('open',()=>{if(this.sockets[address].onopen) (this.sockets[address] as any).onopen(socket,this.sockets[address]);}); + socket.on('close',(code,reason)=>{ + if(this.sockets[address].onclose) (this.sockets[address] as any).onclose(code,reason,socket,this.sockets[address]);}); + socket.on('error',(er)=>{if(this.sockets[address].onerror) (this.sockets[address] as any).onerror(er,socket,this.sockets[address]);}); let send = (message:any) => { //console.log('sent', message) @@ -439,16 +349,15 @@ export class WSSbackend extends Service { let run = (route:any,args?:any, method?:string):Promise => { return new Promise ((res,rej) => { let callbackId = Math.random(); - let req = {route:'runRequest', args:[{route, args}, this.sockets[address]._id, callbackId]} as any; + let req = {route:'runRequest', args:[{route, args}, address, callbackId]} as any; + //console.log(req) if(method) req.args[0].method = method; let onmessage = (ev)=>{ - let data = ev.data; - if(typeof data === 'string' && data.indexOf('{') > -1) - data = JSON.parse(data); - if(typeof data === 'object') { - if(data.callbackId === callbackId) { + if(typeof ev.data === 'string' && ev.data.indexOf('{') > -1) ev.data = JSON.parse(ev.data); + if(typeof ev.data === 'object') { + if(ev.data.callbackId === callbackId) { socket.removeEventListener('message',onmessage); - res(data.args); //resolve the request with the corresponding message + res(ev.data.args); //resolve the request with the corresponding message } } } @@ -458,11 +367,11 @@ export class WSSbackend extends Service { } let request = (message:ServiceMessage|any, method?:string):Promise => { - return this.request(message,socket, this.sockets[address]._id as string, method); + return this.request(message,socket, address, method); } let subscribe = (route:any, callback?:((res:any)=>void)|string) => { - return this.subscribeToSocket(route, this.sockets[address]._id as string, callback); + return this.subscribeToSocket(route, address, callback); } let unsubscribe = (route:any, sub:number):Promise => { @@ -470,7 +379,7 @@ export class WSSbackend extends Service { } let terminate = () => { - this.terminate(this.sockets[address]._id as string); + this.terminate(address); } this.sockets[address] = { @@ -484,7 +393,6 @@ export class WSSbackend extends Service { unsubscribe, terminate, graph:this, - __node:{tag:address}, ...options } @@ -495,14 +403,7 @@ export class WSSbackend extends Service { message:string | ArrayBufferLike | Blob | ArrayBufferView | Buffer[] | ServiceMessage, ws:WebSocketServer|WebSocket, ) => { - if( - (typeof message === 'object' && - (((message as ServiceMessage)?.route || ((message as ServiceMessage)?.node)) || ( - typeof (message as Blob).arrayBuffer !== 'function' && - typeof (message as ArrayBufferLike).byteLength !== 'number' && - typeof (message as Buffer[])[0]?.byteLength !== 'number' - ))) || typeof message === 'number' - ) message = JSON.stringify(message); + if(typeof message === 'object') message = JSON.stringify(message); if(!ws) { @@ -514,9 +415,9 @@ export class WSSbackend extends Service { }; } if(ws instanceof WebSocketServer) { //broadcast to all clients - ws.clients.forEach((c:WebSocket) => {c.send(message as string)}) + ws.clients.forEach((c:WebSocket) => {c.send(message)}) } - else if(ws instanceof WebSocket) ws.send(message as string); + else if(ws instanceof WebSocket) ws.send(message); } closeWS = (ws:WebSocket|string) => { @@ -542,22 +443,13 @@ export class WSSbackend extends Service { } terminate = (ws:WebSocketServer|WebSocket|string) => { - - let str; if(!ws) { - let served = Object.keys(this.servers); - for(const key in served) { - this.terminate(key); - } - let sockets = Object.keys(this.sockets); - for(const key in sockets) { - this.terminate(key) - } + let served = this.servers[Object.keys(this.servers)[0]]; + if(served) ws = served.wss; //select first websocket server to transmit to all clients } else if(typeof ws === 'string') { - str = ws; for(const k in this.servers) { - if(k.includes(ws) || this.servers[k]._id === ws) { + if(k.includes(ws)) { ws = this.servers[k].wss; for(const key in this.servers[k].clients) { this.closeWS(this.servers[k].clients[key]); @@ -568,25 +460,21 @@ export class WSSbackend extends Service { } if(!ws) { for(const k in this.sockets) { - if(k.includes(ws as string) || this.sockets[k]._id === ws) { + if(k.includes(ws as string)) { ws = this.sockets[k].socket; delete this.sockets[k]; break; } } } - } if(ws instanceof WebSocketServer) { ws.close((er) => {if(er) console.error(er);}); } - else if(ws instanceof WebSocket) { + else if(ws instanceof WebSocket) if(ws.readyState === ws.OPEN) ws.close(); - - if(this.get(str ? str : ws.url)) this.remove(str ? str : ws.url); - } return true; } @@ -620,7 +508,7 @@ export class WSSbackend extends Service { ws:WebSocket|string, callbackId:string|number ) => { //send result back - let res = this.receive(message); + let res = this.receive(message); if(ws) { if(typeof ws === 'string') { for(const key in this.servers) { @@ -633,7 +521,7 @@ export class WSSbackend extends Service { if(s === ws) {ws = this.sockets[s].socket; break;} } } - } + } if(res instanceof Promise) { res.then((v) => { @@ -652,8 +540,7 @@ export class WSSbackend extends Service { return res; } - subscribeSocket = (route:string, socket:WebSocket|string, args?:any[], key?:string, subInput?:boolean) => { - if(this.restrict?.[route]) return undefined; + subscribeSocket = (route:string, socket:WebSocket|string) => { if(typeof socket === 'string') { if(this.sockets[socket]) socket = this.sockets[socket].socket; else { @@ -664,7 +551,7 @@ export class WSSbackend extends Service { } } - if(typeof socket === 'object') { + if(typeof socket === 'object') return this.subscribe(route, (res:any) => { //console.log('running request', message, 'for worker', worker, 'callback', callbackId) if((socket as WebSocket).readyState === (socket as WebSocket).OPEN) { @@ -676,13 +563,12 @@ export class WSSbackend extends Service { (socket as WebSocket).send(JSON.stringify({args:res, callbackId:route})); } } - },args,key,subInput); - } + }); } - subscribeToSocket = (route:string, socketId:string, callback?:string|((res:any)=>void), args?:any[], key?:string, subInput?:boolean) => { + subscribeToSocket = (route:string, socketId:string, callback?:string|((res:any)=>void)) => { if(typeof socketId === 'string' && this.sockets[socketId]) { - this.__node.state.subscribeEvent(socketId, (res) => { + this.subscribe(socketId, (res) => { if(res?.callbackId === route) { if(!callback) this.setState({[socketId]:res.args}); else if(typeof callback === 'string') { //just set state @@ -691,26 +577,24 @@ export class WSSbackend extends Service { else callback(res.args); } }) - return this.sockets[socketId].request({route:'subscribeSocket', args:[route,socketId,args,key,subInput]}); + return this.sockets[socketId].request({route:'subscribeSocket', args:[route,socketId]}); } } -} - - - - - - - - -function getHoursAndMinutes(date) { - let hours = date.getHours(); - let minutes = date.getMinutes(); - - // Convert the hours and minutes to two digits - hours = hours < 10 ? '0' + hours : hours; - minutes = minutes < 10 ? '0' + minutes : minutes; + routes:Routes={ + open:(options:SocketServerProps|SocketProps) => { + if((options as SocketServerProps).server) return this.setupWSS(options as SocketServerProps); + else return this.openWS(options as SocketProps); + }, + setupWSS:this.setupWSS, + openWS:this.openWS, + closeWS:this.closeWS, + request:this.request, + runRequest:this.runRequest, + terminate:this.terminate, + subscribeSocket:this.subscribeSocket, + subscribeToSocket:this.subscribeToSocket, + unsubscribe:this.unsubscribe + } - return `${hours}:${minutes}`; } \ No newline at end of file diff --git a/src/core/EventHandler.ts b/src/core/EventHandler.ts deleted file mode 100644 index 1ba81a51..00000000 --- a/src/core/EventHandler.ts +++ /dev/null @@ -1,129 +0,0 @@ -//mini state event handler for arbitrary data event callback handling - -//a graph representing a callstack of nodes which can be arranged arbitrarily with forward and backprop or propagation to wherever -export class EventHandler { - - data={} as {[key:string]:any} - triggers={} as {[key:string]:{sub:number,onchange:Function,[key:string]:any}[]} - ctr = 0; //sub counter, always ensures unique values - - constructor(data?:{[key:string]:any}) { if(typeof data === 'object') this.data = data; } - - setState = (updateObj:{[key:string]:any}) => { - Object.assign(this.data, updateObj); - - let props = Object.getOwnPropertyNames(updateObj) - for (const prop of props) { - this.triggerEvent(prop, this.data[prop]); - } - if(this.triggers[statesubKey]) { - let run = (fn) => { fn(updateObj); } - const l = this.triggers[statesubKey].length; - for (let i = l - 1; i >= 0; i--) { - run(this.triggers[statesubKey][i].onchange); //go in reverse in case a trigger pops - } - } - - return this.data; - } - setValue = (key, value) => { - this.data[key] = value; - this.triggerEvent(key,value); - } - triggerEvent = (key, value) => { - if(this.triggers[key]) { - let fn = (obj) => { obj.onchange(value); }; - const l = this.triggers[key].length; - for (let i = l - 1; i >= 0; i--) { - fn(this.triggers[key][i]); //go in reverse in case a trigger pops - } - } - } - subscribeState = (onchange:(res:any)=>void) => { - return this.subscribeEvent(statesubKey, onchange); - } - unsubscribeState = (sub:number) => { - return this.unsubscribeEvent(statesubKey, sub); - } - subscribeEvent = (key:string,onchange:(res:any)=>void, refObject?:{[key:string]:any}, refKey?:string) => { - if(key) { - if(refObject && refKey && !this.triggers[key]) { - //this acts more like an observer rather than needing to hard copy stuff - Object.defineProperty(this.data,key,{ - get:()=>{ - return refObject[refKey]; - }, - set:(value) => { - refObject[refKey] = value; - }, - enumerable:true, - configurable:true - }); - } - - if(!this.triggers[key]) { - this.triggers[key] = []; - } - - let l = this.ctr; - this.ctr++; - - this.triggers[key].push({sub:l, onchange}); - return l; - } else return undefined; - } - unsubscribeEvent = (key:string,sub?:number) => { - let triggers = this.triggers[key]; - if (triggers){ - if(sub === undefined) { - delete this.triggers[key]; - delete this.data[key]; //garbage collect useless data - } - else { - let idx = undefined; - let obj = triggers.find((o,i)=>{ - if(o.sub===sub) { - idx = i; - return true; - } - }); - - if(obj) triggers.splice(idx,1); - if(Object.keys(triggers).length === 0) { - delete this.triggers[key]; - delete this.data[key]; //garbage collect useless data - } - - if(this.onRemoved) this.onRemoved(obj); - return true; - } - } - } - subscribeEventOnce = (key:string, onchange:(res:any)=>void) => { - let sub; - - let changed = (value) => { - onchange(value); - this.unsubscribeEvent(key, sub); - } - sub = this.subscribeEvent(key,changed); - - return sub; - } - getEvent = (key,sub?) => { - if(typeof sub !== 'number') return this.triggers[key]; - for(const s in this.triggers[key]) { - if(this.triggers[key][s].sub === sub) return this.triggers[key][s]; - } - } - getSnapshot = () => { //shallow copies the current state - const snapshot = {}; - for(const key in this.data) { - snapshot[key] = this.data[key]; //runs getters etc if data not set explicitly in state but passed by reference from a source object - } - } - onRemoved:(trigger:{sub:number, onchange:Function})=>void; -} - -let statesubKey = '*s'; - diff --git a/src/core/Graph.ts b/src/core/Graph.ts deleted file mode 100644 index a9b071ac..00000000 --- a/src/core/Graph.ts +++ /dev/null @@ -1,1526 +0,0 @@ -//graphnodes but we are going to define graph nodes as scopes and graphs as instances of scopes, -// then the execution behaviors will be made plugins to recognize settings on the objects optionally. This is more generic - -import { EventHandler } from "./EventHandler"; - -export const state = new EventHandler(); //default shared global state - - -export type GraphNodeProperties = { - __props?:Function|{[key:string]:any}|GraphNodeProperties|GraphNode, //Proxy objects or from a class constructor function (calls 'new x()') or an object we want to proxy all of the methods on this node. E.g. an html element gains 'this' access through operators and listeners on this node. - __operator?:((...args:any[])=>any)|string, //The 'main' function of the graph node, children will call this function if triggered by a parent. Functions passed as graphnodeproperties become the operator which can set state. - __children?:{[key:string]:any}, //child nodes belonging to this node, e.g. for propagating results - __listeners?:{[key:string]:true|string|((result)=>void)|{__callback:string|((result)=>void)|true, subInput?:boolean,[key:string]:any}}|{[key:string]:((result)=>void)|true|string}, //subscribe by tag to nodes or their specific properties and method outputs - __onconnected?:((node)=>void|((node)=>void)[]), //what happens once the node is created? - __ondisconnected?:((node)=>void|((node)=>void)[]), //what happens when the node is deleted? - __node?:{ //node specific properties, can contain a lot more things - tag?:string, - state?:EventHandler, //by default has a global shared state - [key:string]:any - }, - __args?:any[], //can structure input arguments, include '__result' when generically calling operators for where to pass the original input in in a set of arguments - __callable?:boolean, //we can have the graphnode return itself as a callable function with private properties - [key:string]:any -} - -export type Loader = ( - node:GraphNode, - parent:Graph|GraphNode, - graph:Graph, - roots:any, - properties:GraphNodeProperties, - key:string -)=>void; - -export type Roots = { - [key:string]:any -} //node definitions - -export type GraphOptions = { - roots?:Roots, //node definitions - loaders?:{ - [key:string]:Loader|{ - init?:Loader, - connected?:(node)=>void, - disconnected?:(node)=>void} - }, - state?:EventHandler, - mapGraphs?:false, //if adding a Graph as a node, do we want to map all the graph's nodes with the parent graph tag denoting it (for uniqueness)? - [key:string]:any -} - -export type argObject = { - __input?:string|((...args)=>any), __callback:string|((...args)=>any), //interchangeable - __args?:any[], //can use this instead of __output in general. - __output?:string|argObject|((...args)=>any) //another way to pass args from the input/callback results -} - -export type Listener = { - __callback?:string, //prototype callback - __args?:(argObject|Function|string)[], //prototype arguments - sub:number, - node:GraphNode, //owning node (source node) - graph:Graph, //owning graph - source?:string, //source node (owning node) - key?:string, //source key - target?:string, //target node - tkey?:string, //target key - arguments?:Function[] //wrapped arguments, hot swappable - subInput?:boolean, - onchange:Function //internal function called by the event handler, wrapped by graphscript -} - - -//Call node __operators like so: let node = graph.get('abc'); let result = node(input); -export class Callable extends Function { - - __bound:Callable; - __call:((...args:any[])=>any); - [key:string]:any; - - constructor() { - super('return this.__bound.__call.apply(this.__bound, arguments)') - this.__bound = this.bind(this) - return this.__bound; - } - -} - -//this is a scope -export class GraphNode { - - __node:{ - tag:string, - unique:string, - state:EventHandler, - [key:string]:any - } = { //GraphNode-specific properties - tag:`node${Math.floor(Math.random()*1000000000000000)}`, - unique:`${Math.floor(Math.random()*1000000000000000)}`, - state, - // graph: undefined as any, - // localState: undefined as any, - // source:undefined as any// source graph if a graph is passed as properties - } - - __children?:{[key:string]:GraphNode}; - __parent?:Graph|GraphNode; - __operator?; - __listeners?; - __props?; - __args:any[] //can structure input arguments, include '__result' when generically calling operators for where to pass the original input in in a set of arguments - // __onconnected:undefined as any, //function or array of functions - // __ondisconnected:undefined as any, //function or array of functions - [key:string]:any - - //pass GraphNodeProperties, functions, or tags of other nodes - constructor(properties:GraphNodeProperties, parent?:{[key:string]:any}, graph?:Graph) { - //super(); - this.__setProperties(properties,parent,graph); - - // Check if the properties are a function or denote the GraphNode to be callable (but all properties private!!) - if (typeof properties === 'function' || properties?.__callable) { //assuming operator is defined - const callableInstance = new Callable(); - callableInstance.__call = (...args) => this.__operator(...args); - - // Create a proxy to delegate function calls to callableInstance and properties to this - const proxy = new Proxy(callableInstance, { //experimental - get: (target, prop, receiver) => { - if (Reflect.has(this, prop)) { - return Reflect.get(this, prop, receiver); - } - return Reflect.get(target, prop, receiver); - }, - set: (target, prop, value, receiver) => { - if (Reflect.has(this, prop)) { - return Reflect.set(this, prop, value, receiver); - } - return Reflect.set(target, prop, value, receiver); - } - }); - Object.setPrototypeOf(proxy,this); //pass instanceof checks - - //@ts-ignore - return proxy; - } - } - - //slightly more convenient than doing this.__node.graph - get __graph() { - return this.__node?.graph; - } - - set __graph(graph) { - this.__node.graph = graph; - } - - __setProperties = (properties, parent, graph) => { - - let enforceProperties = () => { - let orig = properties; - if(typeof properties === 'function') { - if(isNativeClass(properties)) { //works on custom classes - //console.log(properties); - properties = new properties(); //this is a class that returns a node definition - } else properties = { - __operator:properties, - __node:{ - forward:true, //propagate operator results to children - tag:properties.name - } - }; - } else if (typeof properties === 'string') { - if(graph?.get(properties)) { - properties = graph.get(properties); - } - } - if(!('__node' in properties)) properties.__node = {}; - if(!properties.__node.initial) properties.__node.initial = orig; //original object or function - } - - enforceProperties(); - - if(typeof properties === 'object') { - - let assignState = () => { - if(properties.__node?.state) this.__node.state = properties.__node.state; //make sure we're subscribing to the right state if we're passing a custom one in - else if(graph) { - properties.__node.state = graph.__node.state; //make sure the node has the graph's state - } - } - - let setProps = () => { - if(properties.__props) { //e.g. some generic javascript object or class constructor that we want to proxy. Functions passed here are treated as constructors. E.g. pass an HTML canvas element for the node then set this.width on the node to set the canvas width - if (typeof properties.__props === 'function') properties.__props = new properties.__props(); - if (typeof properties.__props === 'object') { - this.__proxyObject(properties.__props); - } - } - } - - let setTag = () => { - if(!properties.__node.tag) { - if(properties.__operator?.name) - properties.__node.tag = properties.__operator.name; - else - properties.__node.tag = `node${Math.floor(Math.random()*1000000000000000)}`; - } - } - - - let setNode = () => { - if (typeof properties.__node === 'string') { - //copy - if(graph?.get(properties.__node.tag)) { - properties = graph.get(properties.__node.tag); - } else properties.__node = {} - } else if(!properties.__node) properties.__node = {}; - if(graph) { - properties.__node.graph = graph; - } - if(properties instanceof Graph) properties.__node.source = properties; //keep tabs on source graphs passed to make nodes - } - - - let setParent = () => { - //child/branch nodes get their parent tags prepended in their tag - if(!properties.__parent && parent) properties.__parent = parent; - if(parent?.__node && (!(parent instanceof Graph || properties instanceof Graph))) - properties.__node.tag = parent.__node.tag + '.' + properties.__node.tag; //load parents first - if(parent instanceof Graph && properties instanceof Graph) { - if(properties.__node.loaders) Object.assign(parent.__node.loaders ? parent.__node.loaders : {}, properties.__node.loaders); //let the parent graph adopt the child graph's loaders - if(parent.__node.mapGraphs) { - //do we still want to register the child graph's nodes on the parent graph with unique tags for navigation? Need to add cleanup in this case - properties.__node.nodes.forEach((n) => {parent.set(properties.__node.tag+'.'+n.__node.tag,n)}); - let ondelete = () => { properties.__node.nodes.forEach((n) => {parent.__node.nodes.delete(properties.__node.tag+'.'+n.__node.tag)}); } - this.__addOndisconnected(ondelete); - } - } - } - - let setOp = () => { - if(typeof properties.default === 'function' && !properties.__operator) { - properties.__operator = properties.default; - } //handle a default export treated as an operator - if(properties.__operator) { - if (typeof properties.__operator === 'string') { - if(graph) { - let n = graph.get(properties.__operator); - if(n) properties.__operator = n.__operator; - if(!properties.__node.tag && (properties.__operator as Function).name) - properties.__node.tag = (properties.__operator as Function).name; - } - } - if(typeof properties.__operator === 'function') - properties.__operator = this.__setOperator(properties.__operator); - if(properties.default) properties.default = properties.__operator; - } - } - - let assignProps = () => { - properties.__node = Object.assign(this.__node,properties.__node); - let keys = Object.getOwnPropertyNames(properties).filter((v)=>{if(!objProps[v]) return true;}); - for(const key of keys) { if(key in properties && key !== 'name') this[key] = properties[key]; } - - } - - let bindCallbacks = () => { - if(this.__onconnected) { - if(typeof this.__onconnected === 'function') { - this.__onconnected = this.__onconnected.bind(this); - } else if (Array.isArray(this.__onconnected)) { - this.__onconnected = this.__onconnected.map((f) => { return f.bind(this); }) - } - if(typeof this.__ondisconnected === 'function') { - this.__ondisconnected = this.__ondisconnected.bind(this); - } else if (Array.isArray(this.__ondisconnected)) { - this.__ondisconnected = this.__ondisconnected.map((f) => { return f.bind(this); }) - } - } - } - - - //specific load order!! - assignState(); - setTag(); - setProps(); - setNode(); - setParent(); - assignProps(); - bindCallbacks(); - setOp(); - - } - } - - //subscribe an output or input with an arbitrary callback - __subscribe = (callback:string|GraphNode|((res)=>void), key?:string, subInput?:boolean, target?:string, tkey?:string, args?:any[], callbackStr?:string) => { - - //console.log('subbing', this.__node.tag, key) - const subscribeToFunction = (k, setTarget = (callback, target?) => (target ? target : callback), triggerCallback=callback as (res: any) => void) => { - - let wrappedArgs; - if(args) { - let wrapped = wrapArgs(triggerCallback, args, this.__node.graph); - triggerCallback = wrapped.__callback; - wrappedArgs = wrapped.__args; - } - let sub = this.__node.state.subscribeEvent(k, triggerCallback, this, key); - - // Add details to trigger - let trigger = this.__node.state.getEvent(k,sub) as any as Listener; - if(!this.__listeners) this.__listeners = {}; - this.__listeners[k] = this.__node.state.triggers[k]; - - - if(!trigger) return sub; - trigger.source = this.__node.tag; //source being subscribed too - if(key) trigger.key = key; //source key being subscribed to - trigger.target = setTarget(callback, target); // target is node subscribing to source - if(tkey) trigger.tkey = tkey; //e.g. function or variable on the target receiving the subscription output - if(subInput) trigger.subInput = subInput; - if(args) { - trigger.arguments = wrappedArgs; //wrapped argument functions, hot swappable - trigger.__args = args; //prototype args - } - if(callbackStr) trigger.__callback = callbackStr; - - trigger.node = this; - trigger.graph = this.__node.graph; - - return sub; - } - - const getCallbackFromGraph = (callback) => { - let fn = this.__node.graph.get(callback); - if(!fn && callback.includes('.')) { - target = callback.substring(0,callback.lastIndexOf('.')); - let n = this.__node.graph.get(callback.substring(0,target)); - tkey = callback.lastIndexOf('.')+1; - if(n && typeof n[key] === 'function') callback = (...args) => { return n[tkey](...args); }; - //console.log(n, fn); - } else if (fn.__operator) { - callback = fn.__operator; - tkey = '__operator'; - } - return callback; - } - - if(key) { - // console.log(key,this.__node.tag, 'callback:', callback); - if(!this.__node.localState || !this.__node.localState[key]) { - this.__addLocalState(this, key); - } - - if(typeof callback === 'string') { - callbackStr = this.__node.tag+'.'+callback; - tkey = callback; - if(target) { - if(this.__node.graph?.get(target)) { - let n = this.__node.graph?.get(target); - if(typeof n[callback] === 'function') { - let fn = n[callback]; - callback = (...inp) => { fn(...inp); }; - } else { - let k = callback; - let setter = (inp) => { - n[k] = inp; //this callback is now a setter for a property on the target node - } - callback = setter; - } - } - } - else if(typeof this[callback] === 'function') { - let fn = this[callback]; - callback = (...inp) => {fn(...inp);}; - } else if(this.__node.graph?.get(callback)) callback = getCallbackFromGraph(callback); - if(typeof callback !== 'function') return undefined; - } - - let sub; - - let k = subInput ? this.__node.unique+'.'+key+'input' : this.__node.unique+'.'+key; - if(typeof callback === 'function' && !(callback as any)?.__node) - sub = subscribeToFunction(k, (callback, target) => (target ? target : callback), callback as (...res:any)=>void) - else if((callback as GraphNode)?.__node) sub = subscribeToFunction(k, - (callback, target) => (target ? target : (callback as GraphNode).__node.unique), - (...inp:any)=>{ if((callback as any).__operator) (callback as any).__operator(...inp); } - ) - - return sub; - } - else { - - // Get node based on the graph - if(typeof callback === 'string') { - callbackStr = callback; - if(!target) target = callback as string; - if(this.__node.graph.get(callback)) callback = this.__node.graph.get(callback); - tkey = '__operator'; - if(typeof callback !== 'object') return undefined; - } - - let sub; - - let k = subInput ? this.__node.unique+'input' : this.__node.unique; - - if(typeof callback === 'function' && !(callback as any)?.__node) sub = subscribeToFunction(k, (callback, target) => (target ? target : callback), callback as (...res:any)=>void) - else if((callback as GraphNode)?.__node) { - sub = subscribeToFunction(k, - (callback, target) => target ? target : (callback as GraphNode).__node.unique, - (...inp:any)=>{ if((callback as any).__operator) (callback as any).__operator(...inp); } - ); - } - - return sub; - } - } - - //unsub the callback - __unsubscribe = (sub?:number, key?:string, unsubInput?:boolean) => { - - //console.log('unsubbing', this.__node.tag, sub, key) - if(key) { - return this.__node.state.unsubscribeEvent( - unsubInput ? this.__node.unique+'.'+key+'input' : this.__node.unique+'.'+key, - sub - ); - } - else - return this.__node.state.unsubscribeEvent( - unsubInput ? this.__node.unique+'input' : this.__node.unique, sub - ); - } - - __setOperator = (fn:(...args:any[])=>any) => { - fn = fn.bind(this); - if(this.__args && this.__node.graph) { fn = wrapArgs(fn, this.__args, this.__node.graph).__callback; } - let inpstr = `${this.__node.unique}input`; - this.__operator = (...args) => { - if(this.__node.state.triggers[inpstr]) this.__node.state.setValue(inpstr,args); - let result = fn(...args); - if(this.__node.state.triggers[this.__node.unique]) { //don't set state (i.e. copy the result) if no subscriptions - if(typeof result?.then === 'function') { - result.then((res)=>{ if(res !== undefined) this.__node.state.setValue( this.__node.unique,res ) }).catch(console.error); - } else if(result !== undefined) this.__node.state.setValue(this.__node.unique, result); - } - return result; - } - - if(this.__parent instanceof GraphNode && !this.__subscribedToParent) { //for child nodes - if(this.__parent.__operator) { - let sub = this.__parent.__subscribe(this); - let ondelete = () => { this.__parent?.__unsubscribe(sub); delete this.__subscribedToParent;} - this.__addOndisconnected(ondelete); - this.__subscribedToParent = true; - } - } - - return this.__operator; - } - - __addLocalState = (props?:{[key:string]:any}, key?:string) => { //add easy state functionality to properties on this node using getters/setters or function wrappers - if(!props) return; - if(!this.__node.localState) { - this.__node.localState = {}; - } - const localState = this.__node.localState; - const initState = (props,k) => { - let str = this.__node.unique+'.'+k; - let inpstr = `${str}input`; //for input tracking - let get:()=>any, set:(v)=>void; - let obj, descriptor; - if(typeof props[k] === 'function' && k !== '__operator') { - if(this.__props?.[k]) { - obj = this.__props; - } - else { - obj = localState; - } - - get = () => { - return obj[k]; - } - set = (fn:Function) => { - if(!this.__props?.[k]) fn = fn.bind(this); //make sure function remains bound to node if not for a proxy - obj[k] = (...args) => { - if(this.__node.state.triggers[inpstr]) this.__node.state.setValue(inpstr,args); - let result = fn(...args); - if(this.__node.state.triggers[str]) { - if(typeof result?.then === 'function') { //assume promise (faster than instanceof) - result.then((res)=>{ this.__node.state.triggerEvent( str, res ) }).catch(console.error); - } else this.__node.state.triggerEvent(str,result); - } - - return result; - } - } - - localState[k] = props[k].bind(this) as Function; - - descriptor = { - get, set, - enumerable: true, - configurable: true - }; - - } else if (k !== '__graph') { - let get:()=>any, set:(v)=>void; - let obj; - if(this.__props?.[k]) { - obj = this.__props; - } else { - obj = localState; - } - - get = () => { - return obj[k]; - }; - - set = (v) => { - //if(this.__node.state.triggers[inpstr]) this.__node.state.setValue(inpstr,v); - obj[k] = v; - if(this.__node.state.triggers[str]) this.__node.state.triggerEvent(str,v); //this will update localState and trigger local key subscriptions - }; - - localState[k] = props[k]; - //console.log(k, localState[k]); - - descriptor = { - get, set, - enumerable: true, - configurable: true - }; - } - - - Object.defineProperty(props, k, descriptor); - - if(typeof this.__node.initial === 'object') { - let dec = Object.getOwnPropertyDescriptor(this.__node.initial,k); - if(dec === undefined || dec?.configurable) { - Object.defineProperty(this.__node.initial, k, descriptor); - } - } - } - - if(key) initState(props,key); - else { - for (let k in props) {initState(props,k);} - } - } - - //we can proxy an original object and function outputs on the node - __proxyObject = (obj) => { - const allProps = getAllProperties(obj); - - for(const k of allProps) { - //if(!(k in this)) { - const descriptor = { - get:()=>{return obj[k]}, - set:(value) => { - obj[k] = value; - }, - enumerable: true, - configurable: true - } - - Object.defineProperty(this, k, descriptor); - - if(typeof this.__node.initial === 'object') { - let dec = Object.getOwnPropertyDescriptor(this.__node.initial,k); - if(dec === undefined || dec?.configurable) { - Object.defineProperty(this.__node.initial, k, descriptor); - } - } - //} - } - } - - __addOnconnected(callback:(node)=>void) { - callback = callback.bind(this); - if(Array.isArray(this.__onconnected)) { this.__onconnected.push(callback); } - else if (typeof this.__onconnected === 'function') { this.__onconnected = [callback,this.__onconnected] } - else this.__onconnected = callback; - } - - __addOndisconnected(callback:(node)=>void) { - callback = callback.bind(this); - if(Array.isArray(this.__ondisconnected)) { this.__ondisconnected.push(callback); } - else if (typeof this.__ondisconnected === 'function') { this.__ondisconnected = [callback,this.__ondisconnected] } - else this.__ondisconnected = callback; - } - - __callConnected(node=this) { - if(typeof this.__onconnected === 'function') { this.__onconnected(this); } - else if (Array.isArray(this.__onconnected)) { - let fn = (o:Function) => { o(this); } - this.__onconnected.forEach(fn) - } - } - - __callDisconnected(node=this) { - if(typeof this.__ondisconnected === 'function') this.__ondisconnected(this); - else if (Array.isArray(this.__ondisconnected)) { - let fn = (o:Function) => {o(this)}; - this.__ondisconnected.forEach(fn); - } - } - -} - -export class Graph { - - [key:string]:any; - - __node:{ - tag:string, - unique:string, - state:EventHandler, - nodes:Map, - roots:{[key:string]:any}, - mapGraphs?:boolean, - [key:string]:any - } = { - tag:`graph${Math.floor(Math.random()*1000000000000000)}`, - unique:`${Math.random()}`, - nodes:new Map(), - state, - roots:{} - // mapGraphs:false //if adding a Graph as a node, do we want to map all the graph's nodes with the parent graph tag denoting it (for uniqueness)? - // roots:undefined as any, - // loaders:undefined as any, - } - - - constructor( - options?:GraphOptions - ) { - this.init(options); - } - - init = (options?:GraphOptions) => { - if(options) { - let cpy = Object.assign({},options); - delete cpy.roots; //prevent overflow - recursivelyAssign(this.__node, cpy); //assign loaders etc - if(options.roots) this.load(options.roots); - } - } - - load = (roots:{[key:string]:any}, overwrite = false) => { - function recursivelyAssignChildren (target, obj, inChildren=true, top=true) { - if(top) { - if(!target) target = {}; - for(const key in obj) { - if(!key.startsWith('__') && obj[key] && typeof obj[key] === 'object') { - //test for node keys - //if(obj[key].__operator || obj[key].__node || obj[key].__props || obj[key].__children || obj[key].__parent) { - target[key] = obj[key]; - if(obj[key]?.__children) { - recursivelyAssignChildren({},obj[key].__children,false,false); - } - //} - } else if(typeof obj[key] === 'function') target[key] = obj[key]; //only copy functions for now - } - recursivelyAssignChildren(target,obj,true,false); - } else { - if(obj?.__children && !inChildren) { - if(obj.__children?.constructor.name === 'Object') { - if(target.__children?.constructor.name === 'Object') - target.__children = recursivelyAssignChildren(target.__children, obj.__children, true, false); - else target.__children = recursivelyAssignChildren({},obj.__children, true, false); - } else { - target.__children = obj.__children; - //if(typeof target[key] === 'function') target[key] = target[key].bind(this); - } - } else if (inChildren) { - for(const key in obj) { - if(!key.startsWith('__') && obj[key] && typeof obj[key] === 'object') { - //test for node keys - //if(obj[key].__operator || obj[key].__node || obj[key].__props || obj[key].__children || obj[key].__parent) { - target[key] = Object.assign({}, obj[key]); - if(obj[key]?.__children) { - target[key].__children = recursivelyAssignChildren({},obj[key].__children,false,false); - } - //} - } else if(typeof obj[key] === 'function') target[key] = obj[key]; //only copy functions for now - } - } - } - - return target; - } - - this.__node.roots = recursivelyAssignChildren(this.__node.roots ? this.__node.roots : {}, roots); - - //console.log('ROOTS',this.__node.roots); - - let cpy = Object.assign({}, roots); - if(cpy.__node) delete cpy.__node; //we can specify __node behaviors on the roots too to specify listeners - - let listeners = this.recursiveSet(cpy,this,undefined,roots,overwrite); - - //make the root a node - if(roots.__node) { - if(!roots.__node.tag) roots.__node._tag = `roots${Math.floor(Math.random()*1000000000000000)}`; - else if (!this.get(roots.__node.tag)) { - let node = new GraphNode(roots,this,this); //blank node essentially for creating listeners - this.set(node.__node.tag,node); - - this.runLoaders(node,this, roots, roots.__node.tag); - if(node.__listeners) { - listeners[node.__node.tag] = node.__listeners; - } //now the roots can specify nodes - } - } else if (roots.__listeners) { - this.setListeners(roots.__listeners) - } - - //now setup event listeners - this.setListeners(listeners); - - return cpy; //should be the node roots - - } - - setLoaders = (loaders:{[key:string]:(node:GraphNode,parent:Graph|GraphNode,graph:Graph,roots:any,props:any,key:string)=>void}, replace?:boolean) => { - if(replace) this.__node.loaders = loaders; - else Object.assign(this.__node.loaders,loaders); - - return this.__node.loaders; - } - - runLoaders = (node, parent, properties, key) => { - for(const l in this.__node.loaders) { - if(typeof this.__node.loaders[l] === 'object') { - if(this.__node.loaders[l].init) this.__node.loaders[l](node, parent, this,this.__node.roots,properties, key); - if(this.__node.loaders[l].connected) node.__addOnconnected(this.__node.loaders[l].connect); - if(this.__node.loaders[l].disconnected) node.__addOndisconnected(this.__node.loaders[l].disconnect); - } else if (typeof this.__node.loaders[l] === 'function') this.__node.loaders[l](node, parent, this, this.__node.roots, properties, key); } //run any passes on the nodes to set things up further - } - - add = (properties:any, parent?:GraphNode|string, overwrite=true):GraphNode => { - - let listeners = {}; //collect listener props declared - if(typeof parent === 'string') parent = this.get(parent); - - let instanced; - if(typeof properties === 'function') { - if(isNativeClass(properties)) { //works on custom classes - if(properties.prototype instanceof GraphNode) { properties = properties.prototype.constructor(properties,parent,this); instanced = true; } //reinstantiate a new node with the old node's props - else properties = new properties(); //this is a class that returns a node definition - } else properties = { __operator:properties, __callable:true }; - } - else if (typeof properties === 'string') { - properties = this.__node.roots[properties]; - } - if(!properties) return; - - if(!instanced) { - let keys = Object.getOwnPropertyNames(properties); //lets us copy e.g. Math - let nonArrowFunctions = Object.getOwnPropertyNames(Object.getPrototypeOf(properties)); - keys.push(...nonArrowFunctions); - keys = keys.filter(v => !objProps.includes(v) ); - let cpy = {}; - for(const key of keys) { cpy[key] = properties[key]; } //make sure we don't mutate the original object - properties = cpy; - } - - if(!properties.__node) properties.__node = {}; - properties.__node.initial = properties; - - if(typeof properties === 'object' && this.get(properties.__node.tag)) { - if(overwrite) this.remove(properties.__node.tag, true); //clear the previous node and the subscriptions - else return; - } else if(properties.__node.tag && this.get(properties.__node.tag)) return this.get(properties.__node.tag); - - let node; - let root = recursivelyAssign({},properties,2); - if(instanced) node = properties; - else node = new GraphNode(properties, parent as GraphNode, this); - this.set(node.__node.tag,node); - this.runLoaders(node, parent, properties, node.__node.tag); - this.__node.roots[node.__node.tag] = root; //reference the original props by tag in the roots for children - //console.log('old:',properties.__node,'new:',node.__node); - - if(node.__children) { - node.__children = Object.assign({},node.__children); - this.recursiveSet(node.__children, node, listeners,node.__children); - } - - if(node.__listeners) { - listeners[node.__node.tag] = Object.assign({},node.__listeners); - for(const key in node.__listeners) { - let listener = node.__listeners[key]; - if(node[key]) { //subscribe to a key on the node - delete listeners[node.__node.tag][key]; - listeners[node.__node.tag][node.__node.tag+'.'+key] = listener; - } - if (typeof listener === 'string') { - if(node.__children?.[listener]) { - listeners[node.__node.tag][key] = node.__node.tag+'.'+listener; - } else if (parent instanceof GraphNode && (parent.__node.tag === listener || (parent.__node.tag.includes('.') && parent.__node.tag.split('.').pop() === listener))) { - listeners[node.__node.tag][key] = parent.__node.tag; - } - } - - } - } - - //now setup event listeners - this.setListeners(listeners); - - node.__callConnected(); - return node; - - } - - recursiveSet = (originCpy, parent, listeners:any={}, origin, overwrite=false) => { - let keys = Object.getOwnPropertyNames(origin).filter((v) => !objProps.includes(v)); - let nonArrowFunctions = Object.getOwnPropertyNames(Object.getPrototypeOf(origin)).filter((v) => !objProps.includes(v)); - keys.push(...nonArrowFunctions); //this is weird but it works - - for(const key of keys) { - if(key.includes('__')) continue; - let p = origin[key]; - if(Array.isArray(p)) continue; - let instanced; - if(typeof p === 'function') { - if(isNativeClass(p)) { //works on custom classes - p = new p(); //this is a class that returns a node definition - if(p instanceof GraphNode) { p = p.prototype.constructor(p,parent,this); instanced = true; } //re-instance a new node - } else p = { __operator:p, __callable:true }; - } else if (typeof p === 'string') { - if(this.__node.nodes.get(p)) p = this.__node.nodes.get(p); - else p = this.__node.roots[p]; - } else if (typeof p === 'boolean') { - if(this.__node.nodes.get(key)) p = this.__node.nodes.get(key); - else p = this.__node.roots[key]; - } - - if(p && typeof p === 'object') { - if(!instanced && !(p instanceof GraphNode)) { - let ks = Object.getOwnPropertyNames(p).filter((v) => !objProps.includes(v)); //lets us copy e.g. Math - let nonArrowFunctions = Object.getOwnPropertyNames(Object.getPrototypeOf(p)).filter((v) => !objProps.includes(v)); - nonArrowFunctions.splice(nonArrowFunctions.indexOf('constructor'),1); - ks.push(...nonArrowFunctions); - let cpy = {}; - for(const key of ks) { cpy[key] = p[key]; } //make sure we don't mutate the original object - p = cpy; - } - if(!p.__node) p.__node = {}; - if(!p.__node.tag) p.__node.tag = key; - if(!p.__node.initial) p.__node.initial = originCpy[key]; - if(overwrite && this.get(p.__node.tag)) { - this.remove(p.__node.tag, true); //clear the previous node - } - else if(( - ( - this.get(p.__node.tag) && - !(!(parent instanceof Graph) && - parent?.__node) - ) || - ( - parent?.__node && - this.get(parent.__node.tag + '.' + p.__node.tag) - ) - )) continue; //don't duplicate a node we already have in the graph by tag, todo: maybe rethink this a little bit - - let node: GraphNode; - let newnode = false; - let root = recursivelyAssign({},p,2); //preserve an unwrapped prototype, as the initial props will gain the getters/setters of the node if possible - if(instanced || p instanceof GraphNode) { - node = p; - } else { - node = new GraphNode(p, parent as GraphNode, this); - newnode = true; - } - if(!newnode && p instanceof GraphNode && !instanced && parent instanceof GraphNode) { //make sure this node is subscribed to the parent, can use this to subscribe a node multiple times as a child - let sub = this.subscribe(parent.__node.tag, node.__node.tag); - let ondelete = (node) => {this.unsubscribe(parent.__node.tag, sub);} - node.__addOndisconnected(ondelete); //cleanup sub - } else if(node) { //fresh node, run loaders etc. - //console.log(node, instanced, newnode); - this.set(node.__node.tag,node); - this.runLoaders(node, parent, originCpy[key], key); //run any passes on the nodes to set things up further - originCpy[key] = node; //replace child with a graphnode - this.__node.roots[node.__node.tag] = root; //reference the original node props by tag in the root - - if(node.__children) { - node.__children = Object.assign({}, node.__children); - this.recursiveSet(node.__children, node, listeners,node.__children); - } - - if(node.__listeners) { - listeners[node.__node.tag] = Object.assign({},node.__listeners); - for(const key in node.__listeners) { - let listener = node.__listeners[key]; - let k = key; - if(node[key]) { //subscribe to a key on the node - delete listeners[node.__node.tag][key]; - k = node.__node.tag+'.'+key; - listeners[node.__node.tag][k] = listener; - } - if (typeof listener === 'string') { - if(node.__children?.[listener]) { - listeners[node.__node.tag][k] = node.__node.tag+'.'+listener; - } else if (parent instanceof GraphNode && (parent.__node.tag === listener || (parent.__node.tag.includes('.') && parent.__node.tag.split('.').pop() === listener))) { - listeners[node.__node.tag][k] = parent.__node.tag; - } - } - } - } - - node.__callConnected(); - } - } - } - return listeners; - } - - remove = (node:GraphNode|string, clearListeners:boolean=true) => { - - this.unsubscribe(node); - - if(typeof node === 'string') node = this.get(node); - - if(node instanceof GraphNode) { - this.delete(node.__node.tag); - delete this.__node.roots[node.__node.tag]; - - if(clearListeners) { - this.clearListeners(node); - } - - node.__callDisconnected(); - - const recursiveRemove = (t) => { - for(const key in t) { - this.unsubscribe(t[key]); - this.delete(t[key].__node.tag); - delete this.__node.roots[t[key].__node.tag] - this.delete(key); - delete this.__node.roots[key] - - //console.log(key, 'removing child',t[key]); - t[key].__node.tag = t[key].__node.tag.substring(t[key].__node.tag.lastIndexOf('.')+1); - - if(clearListeners) { - this.clearListeners(t[key]); - } - - //console.log(key,t[key].__listeners); - - t[key].__callDisconnected(); - - if(t[key].__children) { - recursiveRemove(t[key].__children); - } - - // console.log('removed!', t[key]) - } - } - - if(node.__children) { - recursiveRemove(node.__children); - } - } - - if((node as GraphNode)?.__node.tag && (node as GraphNode)?.__parent) { - delete (node as GraphNode)?.__parent; - (node as GraphNode).__node.tag = (node as GraphNode).__node.tag.substring((node as GraphNode).__node.tag.indexOf('.')+1); - } - - if((node as GraphNode)?.__node.graph) (node as GraphNode).__node.graph = undefined; - - return node; - } - - run = (node:string|GraphNode, ...args:any[]) => { - - if(typeof node === 'string') { - let nd = this.get(node); - if(!nd && node.includes('.')) { - nd = this.get(node.substring(0,node.lastIndexOf('.'))); - if(typeof nd?.[node.substring(node.lastIndexOf('.')+1)] === 'function') return nd[node.substring(node.lastIndexOf('.')+1)](...args); - } else if(nd?.__operator) return nd.__operator(...args); - } - if((node as GraphNode)?.__operator) { - return (node as GraphNode)?.__operator(...args); - } - } - - -/** - * - * Listeners are an object where each key is a node tag, and each value is an object specifying callbacks or multiple callback for events on the graph, e.g. function outputs or variable changes. - * { - * [node.__node.tag (or arbitrary)]:{ - * [node.key (key optional)]:{__callback:string|Function, __args?:[], subInput?:boolean} | Function (bound to main node tag if specified) | string - * } - * } - * - * __args can be strings referencing other nodes/methods or values to pass correct inputs into the callback if more than one is required, else the output of the thing listened to is used by default - */ - setListeners = (listeners:{[key:string]:{[key:string]:any}}) => { - - /** - * type Listener = { - * source: the source node (if any) - * key: the source key listened to (if any) - * target: the target node (if any), - * tkey: the target method key (if any) - * sub: the number for the subscription in state - * __callback:Function, - * __args:Function[], wrapped argument functions that get iterated over when a trigger is called - * arguments:any[] //the original arguments - * } - */ - - //now setup event listeners - for(const key in listeners) { - let node = this.get(key); - if(typeof listeners[key] === 'object') { - for(const k in listeners[key]) { - let n = this.get(k); - let sub; - if( typeof listeners[key][k] !== 'object' ) - listeners[key][k] = { __callback:listeners[key][k] }; - else if(!listeners[key][k].__callback) { - for(const kk in listeners[key][k]) { - if(typeof listeners[key][k][kk] !== 'object') { - listeners[key][k][kk] = {__callback: listeners[key][k][kk]} - if(node.__operator && - (listeners[key][k][kk].__callback === true || - typeof listeners[key][k][kk].__callback === 'undefined') - ) - listeners[key][k][kk].__callback = node.__operator; - } - let nn = this.get(kk); - - if(!nn) { - let tag = k.substring(0,k.lastIndexOf('.')); - nn = this.get(tag); - if(nn) { - let prop = k.substring(k.lastIndexOf('.')+1); - sub = this.subscribe( - nn, - listeners[key][k][kk].__callback, - listeners[key][k][kk].__args, - prop, - listeners[key][k][kk].subInput, - key //if the key as the target is a node tag, this lets you specify callbacks as keys of that node so e.g. {console:{'Button.onclick':'log'}} - ); - } - } else { - sub = this.subscribe( - nn, - listeners[key][k][kk].__callback, - listeners[key][k][kk].__args, - undefined, - listeners[key][k][kk].subInput, - key - ); - - } - } - } - if('__callback' in listeners[key][k]) { - if(node){ - if(listeners[key][k].__callback === true || typeof listeners[key][k].__callback === 'undefined') listeners[key][k].__callback = node.__operator; - if( typeof listeners[key][k].__callback === 'function') listeners[key][k].__callback = listeners[key][k].__callback.bind(node); - } - if(!n) { - let tag = k.substring(0,k.lastIndexOf('.')); - n = this.get(tag); - if(n) { - sub = this.subscribe( - n, - listeners[key][k].__callback, - listeners[key][k].__args, - k.substring(k.lastIndexOf('.')+1), - listeners[key][k].subInput, - key - ); - - } - } else { - sub = this.subscribe( - n, - listeners[key][k].__callback, - listeners[key][k].__args, - undefined, - listeners[key][k].subInput, - key - ); - - } - } - } - } - } - } - - clearListeners = (node:GraphNode|string, listener?:string) => { - if(typeof node === 'string') node = this.get(node) as GraphNode; - if(node?.__listeners) { - //console.log(node?.__listeners); - for(const key in node.__listeners) { - if(listener && key !== listener) continue; - if(typeof node.__listeners[key]?.sub !== 'number') continue; - let n = this.get(key); - if(!n) { - n = this.get(key.substring(0,key.lastIndexOf('.'))); - //console.log(key.substring(0,key.lastIndexOf('.')),key,n,node.__listeners[key]); - if(n) { - if(typeof node.__listeners[key] === 'object' && !node.__listeners[key]?.__callback) { - for(const k in node.__listeners[key]) { - if(typeof node.__listeners[key][k]?.sub === 'number') { - this.unsubscribe(n,node.__listeners[key][k].sub, key.substring(key.lastIndexOf('.')+1), node.__listeners[key][k].subInput); - node.__listeners[key][k].sub = undefined; - } - } - } else if(typeof node.__listeners[key]?.sub === 'number') { - this.unsubscribe(n,node.__listeners[key].sub, key.substring(key.lastIndexOf('.')+1), node.__listeners[key].subInput); - node.__listeners[key].sub = undefined; - } - } - } else { - if(typeof !node.__listeners[key]?.__callback === 'number') { - for(const k in node.__listeners[key]) { - if(node.__listeners[key][k]?.sub) { - this.unsubscribe(n,node.__listeners[key][k].sub, undefined, node.__listeners[key][k].subInput); - node.__listeners[key][k].sub = undefined; - } - } - } else if(typeof node.__listeners[key]?.sub === 'number') { - this.unsubscribe(n,node.__listeners[key].sub, undefined, node.__listeners[key].subInput); - node.__listeners[key].sub = undefined; - } - } - } - } - } - - get = (tag:string) => { return this.__node.nodes.get(tag); }; - getByUnique = (unique:string) => { return Array.from(this.__node.nodes.values()).find((node) => { if(node.__node.unique === unique) return true; })} //just in case we want to source a node by state keys - set = (tag:string,node:GraphNode) => { return this.__node.nodes.set(tag, node); }; - delete = (tag:string) => { return this.__node.nodes.delete(tag); } - list = () => { return Array.from(this.__node.nodes.keys()); } //list loaded nodes - getListener = (nodeTag:string,key?:string,sub?:number) => { - let node = this.get(nodeTag); - if(node) { - let k = node.__node.unique; - if(key) { k += '.'+key } - return this.__node.state.getEvent(k,sub) as any as Listener; - } - } - - getProps = (node:GraphNode|string, getInitial?:boolean) => { - if(typeof node === 'string') node = this.get(node); - if(node instanceof GraphNode) { - let cpy; - if(getInitial) cpy = Object.assign({}, this.__node.roots[node.__node.tag]); - else { - cpy = Object.assign({},node) as any; - //remove graphnode methods to return the arbitrary props - for(const key in cpy) { - if(key.includes('__')) delete cpy[key]; //remove node methods - } - } - } - } - - subscribe = ( - nodeEvent:GraphNode|string, - onEvent:string|GraphNode|((...res:any)=>void), - args?:any[], - key?:string|undefined, - subInput?:boolean, - target?:string|GraphNode, - tkey?:string - ) => { - - let nd = nodeEvent; - if(typeof nodeEvent === 'string') { - nd = this.get(nodeEvent); - if(!nd && nodeEvent.includes('.')) { - nd = this.get(nodeEvent.substring(0,nodeEvent.lastIndexOf('.'))) - key = nodeEvent.substring(nodeEvent.lastIndexOf('.')+1); - } - } - - if(target instanceof GraphNode) target = target.__node.tag; - - let callbackStr; - if(typeof onEvent === 'string') { - //console.log(node, callback, this.__node.nodes.keys()); - callbackStr = onEvent; - let setOnEventFromString = (onEvent:any) => { - if(this.get(onEvent)?.__operator) { - let node = this.get(onEvent); - target = onEvent; - onEvent = function(...inp) { return node.__operator(...inp); }; - } else if(onEvent.includes('.')) { - target = onEvent.substring(0,onEvent.lastIndexOf('.')); - let n = this.get(target as string); - let k = onEvent.substring(onEvent.lastIndexOf('.')+1); - tkey = k; - if(typeof n[k] === 'function') { - if(n[k] instanceof GraphNode) onEvent = n[k]; - else onEvent = function(...inp) { return n[k](...inp); }; - } else { - onEvent = function(inp) { n[k] = inp; return n[k]; }; //setter - } - //console.log(n, fn); - } - return onEvent; - } - - if(target) { - let node = this.get(target); - if(typeof node?.[onEvent] === 'function') { - tkey = onEvent; - onEvent = function(...inp) { return node[key](...inp)}; - } else if(node?.[key]) { - tkey = key; - if(node[key] instanceof GraphNode) onEvent = node[key]; - else onEvent = function(inp) { node[key] = inp; return node[key]; } //setter - } else { - onEvent = setOnEventFromString(onEvent); - } - } else { - onEvent = setOnEventFromString(onEvent); - } - } - - let sub:number; - - //TODO: clean up all this samey stuff - - if(nd instanceof GraphNode) { - const doSub = () => { - sub = (nd as GraphNode).__subscribe(onEvent, key, subInput, target as string, tkey, args, callbackStr); - - let ondelete = () => { - if(sub !== undefined) (nd as GraphNode).__unsubscribe(sub, key, subInput); - sub = undefined; - } - - (nd as GraphNode).__addOndisconnected(()=>{ - ondelete(); - (nd as GraphNode).__addOnconnected(() => { //need to update the listener object on the listening node - if(sub === undefined && (nd as GraphNode).__node.graph.__node.tag === this.__node.tag) doSub(); - - //console.log(key,bound,this.get(target as string).__listeners[bound]); - }) - }); - - if(typeof onEvent === 'string' && this.get(onEvent)) onEvent = this.get(onEvent); - if(onEvent instanceof GraphNode) { - onEvent.__addOndisconnected(() => { - ondelete(); - }); - } - } - - doSub(); - - } else if (typeof nodeEvent === 'string') { - let node = this.get(nodeEvent) as GraphNode; - if(node) { - if(onEvent instanceof GraphNode && onEvent.__operator) { - const doSub = () => { - sub = node.__subscribe((onEvent as GraphNode).__operator, key, subInput, target as string, tkey, args, callbackStr); - - let ondelete = () => { - if(sub !== undefined) node.__unsubscribe(sub, key, subInput); - } - - node.__addOndisconnected(()=>{ - ondelete(); - (node as GraphNode).__addOnconnected(() => { //if reconnected - if(sub === undefined && node.__node.graph.__node.tag === this.__node.tag) doSub(); - }); - }); - - (onEvent as GraphNode).__addOndisconnected(ondelete); - } - - doSub(); - } - else if (typeof onEvent === 'function' || typeof onEvent === 'string') { - const doSub = () => { - sub = node.__subscribe(onEvent, key, subInput, target as string, tkey, args, callbackStr); - - let ondelete = () => { - if(sub !== undefined) node.__unsubscribe(sub, key, subInput); - sub = undefined; - } - - node.__addOndisconnected(()=>{ - ondelete(); - //console.log('unsubscribed', key) - (node as GraphNode).__addOnconnected(() => { //if reconnected - if(sub === undefined && node.__node.graph.__node.tag === this.__node.tag) doSub(); - }); - }); - - if(typeof onEvent === 'string' && this.get(onEvent)) this.get(onEvent).__addOndisconnected(ondelete); - - } - - doSub(); - } - } else { - if(typeof onEvent === 'string') onEvent = this.__node.nodes.get(onEvent).__operator; - if(typeof onEvent === 'function' && !(onEvent as any)?.__node) sub = this.__node.state.subscribeEvent(nodeEvent, onEvent as (...res:any)=>void); - } - } - return sub; - } - - unsubscribe = ( node:GraphNode|string, sub?:number, key?:string, subInput?:boolean) => { - - if(node instanceof GraphNode) { - return node.__unsubscribe(sub,key,subInput); - } - else return this.get(node)?.__unsubscribe(sub,key,subInput); - } - - setState = (update:{[key:string]:any}) => { - this.__node.state.setState(update); - } - -} - - -function recursivelyAssign (target,obj, maxDepth=Infinity,curDepth=0) { - for(const key in obj) { - if(obj[key]?.constructor.name === 'Object' && curDepth < maxDepth) { - curDepth++; - if(target[key]?.constructor.name === 'Object') - recursivelyAssign(target[key], obj[key], maxDepth, curDepth); - else target[key] = recursivelyAssign({},obj[key],maxDepth, curDepth); - } else { - target[key] = obj[key]; - //if(typeof target[key] === 'function') target[key] = target[key].bind(this); - } - } - - return target; -} - - -export function getAllProperties(obj){ //https://stackoverflow.com/questions/8024149/is-it-possible-to-get-the-non-enumerable-inherited-property-names-of-an-object - var allProps = [] as any[], curr = obj - do{ - var props = Object.getOwnPropertyNames(curr); - let fn = function(prop){ - if (allProps.indexOf(prop) === -1) - allProps.push(prop) - } - props.forEach(fn) - } while(curr = Object.getPrototypeOf(curr)) - return allProps; -} - -export function instanceObject(obj) { - let props = getAllProperties(obj); //e.g. Math - let instance = {} as any; - for(const key of props) { - instance[key] = obj[key]; - } - - return instance; - //simply copies methods, nested objects will not be instanced to limit recursion, unless someone wants to add circular reference detection >___> ... <___< -} - -export function isNativeClass (thing: any) { - return isFunction(thing) === 'class' -} - -export function isFunction(x: any) { - const res = typeof x === 'function' - ? x.prototype - ? Object.getOwnPropertyDescriptor(x, 'prototype')?.writable - ? 'function' - : 'class' - : x.constructor.name === 'AsyncFunction' - ? 'async' - : 'arrow' - : ''; - - return res -} - -// export default Graph - -//we can provide an argument list to structure inputs into a function from a set of getters for other node properties and functions etc. -//e.g. argOrder = ['__output','nodeA.x','nodeB.z'] - - -export let getCallbackFromString = (a, graph) => { - if(graph.get(a)?.__operator) { - let node = graph.get(a); - return (...inp) => { node.__operator(...inp); }; - } else if(a.includes('.')) { - let split = a.split('.'); - let popped = split.pop() as any; - let joined = split.join('.'); - let node = graph.get(joined); - if(typeof graph.get(joined)?.[popped] === 'function') { - return (...inp) => { return node[popped](...inp); }; - } else return () => { return node[popped]; }; - } else if (graph.get(a)) { //return the node itself (pass by reference :D) - let node = graph.get(a); - return () => { return node; }; - } else { - let arg = a; - return () => { return arg; }; - } -} - -export const wrapArgs = (callback,argOrder,graph) => { - let args = [] as any[]; - //set up getters - - - let forArg = (a,i) => { - if(a === '__output' || a === '__input' || a === '__callback') { - args[i] = {__callback:(inp) => { return inp; }, __args:undefined, idx:i}; - } else if(typeof a === 'string') { - args[i] = {__callback:getCallbackFromString(a, graph), __args:undefined, idx:i}; - } else if (typeof a === 'function') { - let fn = a; - args[i] = {__callback:(...inp) => { return fn(...inp); }, __args:undefined, idx:i} - } else if (typeof a === 'object' && (a.__input || a.__callback)) { - //wrap i/o functions and get methods from nodes, - // recursively set arguments and the last nested - // input will resolve a value - function recursivelyCreateCallback (c:argObject) { - let input = c.__input ? c.__input : c.__callback as any; - if(typeof c.__input === 'string') { - input = {__callback:getCallbackFromString(c.__input, graph), __args:undefined, idx:i}; - //console.log('input',input); - } - if(c.__args) { - let wrapped = wrapArgs(input, c.__args, graph); - input = {__callback:wrapped.__callback, __args:wrapped.__args, idx:i}; - } else { - input = {__callback:input, __args:undefined, idx:i}; - } - if(c.__output) { - let output = c.__output as any; - if(typeof c.__output === 'string') { - output = {__callback:getCallbackFromString(output, graph), __args:undefined, idx:i}; - } else if (typeof a.__output === 'object') { - output = recursivelyCreateCallback(output as argObject); - } - if(typeof output?.__callback === 'function') { - let fn = input.__callback; - let callback = output.__callback; - input = {__callback:(...inp) => { return (callback as Function)((fn as Function)(...inp));}, __args:output.__args, idx:i} - } - } - return input; - } - args[i] = recursivelyCreateCallback(a); - } else { - let arg = a; - args[i] = {__callback:() => { return arg; }, __args: undefined, idx:i}; - } - } - - argOrder.forEach(forArg); - - if(typeof callback === 'string') callback = {__callback:getCallbackFromString(callback,graph), __args:undefined}; - - let fn = typeof callback === 'function' ? callback : callback.__callback; - callback = function (...inp) { - let mapArg = (arg) => { - return arg.__callback(...inp); - }; - const result = fn(...args.map(mapArg)); - return result; - } - - return {__callback:callback, __args:args}; //args enable hot-swapping nested function calls - -} - -let objProps = Object.getOwnPropertyNames(Object.getPrototypeOf({})); - - - - - -// class AnotherCallable extends Callable { -// constructor() { -// super() -// this.person = 'Dean' -// } - -// suffix(arg) { -// return `${this.person} ${arg || ''}` -// } - -// _call(arg) { -// return `${this.person} ${arg || ''}` -// } -// } - - -// var obj1 = new AnotherCallable() - -// // Method and prop access is maintained. -// console.log('Method and prop access is maintained:') -// console.log(obj1.person, obj1.suffix('Venture'), obj1('Venture')) - -// // Inheritance is correctly maintained. -// console.log('\nInheritance is maintained:') -// console.log(obj1 instanceof Function) // true -// console.log(obj1 instanceof Callable) // true -// console.log(obj1 instanceof AnotherCallable) // true - \ No newline at end of file diff --git a/src/extras/README.md b/src/extras/README.md deleted file mode 100644 index 4dc34cc1..00000000 --- a/src/extras/README.md +++ /dev/null @@ -1,5 +0,0 @@ -Keep the bloatware here so it's out of the main NPM dist - -TODO: We still need to break up the dists so the NPM all doesn't have the same files - -Also need to fix types dist \ No newline at end of file diff --git a/src/extras/____package.json b/src/extras/____package.json deleted file mode 100644 index 7de86a76..00000000 --- a/src/extras/____package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "graphscript-services-node", - "version": "0.3.2", - "description": "Extra services for graphscript.", - "main": "dist/index.services.node.js", - "types": "dist/src/extras/index.services.d.ts", - "scripts": { - "start": "tinybuild path=tinybuild.config.js && tinybuild path=tinybuild.gpu.config.js && tinybuild path=tinybuild.storage.config.js", - "build": "tinybuild build", - "serve": "tinybuild serve", - "init": "node tinybuild/init.js", - "concurrent": "concurrently \"npm run python\" \"npm start\"", - "dev": "npm run pip && npm i --save-dev concurrently && npm i --save-dev nodemon && npm run concurrent", - "startdev": "nodemon --exec \"node tinybuild.js\" -e ejs,js,ts,jsx,tsx,css,html,jpg,png,scss,txt,csv", - "python": "python python/server.py", - "pip": "pip install quart && pip install websockets", - "pwa": "npm i workbox-cli && workbox generateSW node_server/pwa/workbox-config.js && npm run build && npm start" - }, - "keywords": [ - "esbuild" - ], - "author": "Joshua Brewster", - "license": "LGPL-3.0-or-later", - "dependencies": { - "brainsatplay-math": "~0.1.0", - "browserfs": "~1.4.3", - "gpujsutils": "~1.0.15", - "web-worker": "~1.2.0", - "webgl-plot-utils": "~0.4.2" - }, - "nodemonConfig": { - "env": { - "NODEMON": true - }, - "ignore": [ - "dist/", - ".temp/" - ] - }, - "devDependencies": { - "@types/node": "~18.7.15" - } -} diff --git a/src/extras/___package.json b/src/extras/___package.json deleted file mode 100644 index 1d05fe29..00000000 --- a/src/extras/___package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "graphscript-services.gpu", - "version": "0.3.2", - "description": "Extra services for graphscript.", - "main": "dist/index.gpu.services.js", - "module": "dist/index.gpu.services.esm.js", - "types": "dist/index.gpu.services.d.ts", - "scripts": { - "start": "tinybuild path=tinybuild.config.js && tinybuild path=tinybuild.gpu.config.js && tinybuild path=tinybuild.storage.config.js", - "build": "tinybuild build", - "serve": "tinybuild serve", - "init": "node tinybuild/init.js", - "concurrent": "concurrently \"npm run python\" \"npm start\"", - "dev": "npm run pip && npm i --save-dev concurrently && npm i --save-dev nodemon && npm run concurrent", - "startdev": "nodemon --exec \"node tinybuild.js\" -e ejs,js,ts,jsx,tsx,css,html,jpg,png,scss,txt,csv", - "python": "python python/server.py", - "pip": "pip install quart && pip install websockets", - "pwa": "npm i workbox-cli && workbox generateSW node_server/pwa/workbox-config.js && npm run build && npm start" - }, - "keywords": [ - "esbuild" - ], - "author": "Joshua Brewster", - "license": "LGPL-3.0-or-later", - "dependencies": { - "brainsatplay-math": "~0.1.0", - "browserfs": "^1.4.3", - "webgl-plot-utils":"~0.4.2", - "gpujsutils":"~1.0.15" - }, - "nodemonConfig": { - "env": { - "NODEMON": true - }, - "ignore": [ - "dist/", - ".temp/" - ] - }, - "devDependencies": { - "@types/node": "~18.7.15" - } -} diff --git a/src/extras/__package.json b/src/extras/__package.json deleted file mode 100644 index 32f52858..00000000 --- a/src/extras/__package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "graphscript-services.storage", - "version": "0.3.2", - "description": "Extra services for graphscript.", - "main": "dist/index.storage.services.js", - "module": "dist/index.storage.services.esm.js", - "types": "dist/index.storage.services.d.ts", - "scripts": { - "start": "tinybuild path=tinybuild.config.js && tinybuild path=tinybuild.gpu.config.js && tinybuild path=tinybuild.storage.config.js", - "build": "tinybuild build", - "serve": "tinybuild serve", - "init": "node tinybuild/init.js", - "concurrent": "concurrently \"npm run python\" \"npm start\"", - "dev": "npm run pip && npm i --save-dev concurrently && npm i --save-dev nodemon && npm run concurrent", - "startdev": "nodemon --exec \"node tinybuild.js\" -e ejs,js,ts,jsx,tsx,css,html,jpg,png,scss,txt,csv", - "python": "python python/server.py", - "pip": "pip install quart && pip install websockets", - "pwa": "npm i workbox-cli && workbox generateSW node_server/pwa/workbox-config.js && npm run build && npm start" - }, - "keywords": [ - "esbuild" - ], - "author": "Joshua Brewster", - "license": "LGPL-3.0-or-later", - "dependencies": { - "brainsatplay-math": "~0.1.0", - "browserfs": "^1.4.3", - "webgl-plot-utils":"~0.4.2" - }, - "nodemonConfig": { - "env": { - "NODEMON": true - }, - "ignore": [ - "dist/", - ".temp/" - ] - }, - "devDependencies": { - "@types/node": "~18.7.15" - } -} diff --git a/src/extras/algorithms/beat_detect.ts b/src/extras/algorithms/beat_detect.ts deleted file mode 100644 index 67280e8b..00000000 --- a/src/extras/algorithms/beat_detect.ts +++ /dev/null @@ -1,232 +0,0 @@ -//AlgorithmContext implementation for a basic low-pass peak finding algorithm with some basic error correction -import { Math2 } from 'brainsatplay-math'; -import { Biquad } from './util/BiquadFilters'; -import { GraphNodeProperties } from '../../core/Graph'; - -export const beat_detect = { - refdata:[] as any, - lowpass:undefined, - smoothed:[] as any, - //dsmoothed:[] as any, //slope - timestamp:[] as any, - peaks:[] as any, - valleys:[] as any, - peak_distances:[] as any, - valley_distances:[] as any, - beats:[] as any, - lastPeak:0, - lastValley:0, - sps:100, //set the sample rate, e.g. 100 - maxFreq:4, //the max frequency of peaks we want to detect, we will create a moving average and peak finding interval based on this and the sample rate. //e.g. 4hz for heart rate, or 1/3rd hz for breathing - limit:10, //limit number of last-values stored on the peak/valley/beat arrays to save memory, can just collect externally when a beat is returned - __onconnected:function() { - if(!this.lowpass) { //init lowpass filter with up to date sample rate - let freq = this.maxFreq; - if(!freq) freq = 1; - if(freq > 1) freq *= 0.5; //helps smooth more on faster sine waves, for low freqs this starts to be too smooth - - //lowpass filter constraints - this.lowpass = new Biquad('lowpass', this.maxFreq, this.sps); - - this.peakFinderWindow = Math.floor(this.sps/this.maxFreq) - if(this.peakFinderWindow%2 === 0) this.peakFinderWindow+=1; - if(this.peakFinderWindow < 5) this.peakFinderWindow = 5; - this.midpoint = Math.round(this.peakFinderWindow*.5); - - } - }, - __operator:function( - data:{ - //general use data key - raw?:number|number[], - - //pulse ox or fnirs data - red?:number|number[], //could be any LED really but we are using red and IR predominantly - ir?:number|number[], - heg?:number|number[], //e.g. the Peanut only gives us the HEG in a usable way - - //used for frequency finding - timestamp?:number|number[] - } - ){ - - if(!('red' in data) && !('heg' in data) && !('raw' in data)) return undefined; //invalid data - - let refdata = data.red ? data.red : data.heg? data.heg : data.raw; - - if(!('timestamp' in data)) { //generate timestamps if none, assuming latest data is at time of the ondata callback - if(Array.isArray(refdata)) { //assume timestamp - let now = Date.now(); - let len; - if(refdata) len = (refdata as number[]).length; - let toInterp = [now - (refdata as number[]).length*this.sps*1000, now]; - data.timestamp = Math2.upsample(toInterp,(refdata as number[]).length); - } else { - data.timestamp = Date.now(); - } - } - - let pass = (amplitude, timestamp) => { - if(amplitude) { - this.refdata.push(amplitude); - } - this.timestamp.push(timestamp); - - let beat; - - if(this.refdata.length > this.peakFinderWindow) { //we only need to store enough data in a buffer to run the algorithm (to limit buffer overflow) - this.refdata.shift(); - this.timestamp.shift(); - } - - - this.smoothed.push( - this.lowpass.applyFilter(this.refdata[this.refdata.length - 1]) - ); - - if(this.smoothed.length > this.peakFinderWindow) { - this.smoothed.shift(); - } - - - if(this.smoothed.length === this.peakFinderWindow) { - // context.dsmoothed.push( - // ( context.refdata[context.refdata.length-1] - - // context.refdata[context.refdata.length-2] - // ) / context.timestamp[context.timestamp[context.timestamp.length-1]] - // ); - - //context.smoothed.indexOf(Math.max(...context.smoothed)) === context.midpoint - if(Math2.isExtrema(this.smoothed,'valley')) { - this.valleys.push({ - value:this.smoothed[this.smoothed.length - this.midpoint ? this.midpoint : 1], - timestamp:this.timestamp[this.timestamp.length - this.midpoint ? this.midpoint : 1] - }); - } else if (Math2.isExtrema(this.smoothed,'peak')) { - this.peaks.push({ - value:this.smoothed[this.smoothed.length - this.midpoint ? this.midpoint : 1], - timestamp:this.timestamp[this.timestamp.length - this.midpoint ? this.midpoint : 1] - }); - } - - - if(this.valleys.length > 2 && this.peaks.length > 2) { - - //if we have 3+ peaks or 3+ valleys in front of the previous peak or valley, we need to shave them off as we are looking for a sine wave (1 peak 1 valley). - if(this.valleys[this.valleys.length-1].timestamp < this.peaks[this.peaks.length - 2].timestamp) - this.peaks.splice(this.peaks.length-1); - if(this.peaks[this.peaks.length-1].timestamp < this.valleys[this.valleys.length - 2].timestamp) - this.valleys.splice(this.valleys.length-1); - - this.valley_distances.push({ - distance:this.valleys[this.valleys.length - 1].timestamp - this.valleys[this.valleys.length - 2].timestamp, - timestamp:this.valleys[this.valleys.length - 1].timestamp, - peak0:this.valleys[this.valleys.length - 1].value, - peak1:this.valleys[this.valleys.length - 2].value - }); - - this.peak_distances.push({ - distance:this.peaks[this.peaks.length - 1].timestamp - this.peaks[this.peaks.length - 2].timestamp, - timestamp:this.peaks[this.peaks.length - 1].timestamp, - peak0:this.peaks[this.peaks.length - 1].value, - peak1:this.peaks[this.peaks.length - 2].value - }); - - if(this.peak_distances.length > 1 && this.valley_distances.length > 1) { - if(this.lastPeak < this.peaks[this.peaks.length-1].timestamp && this.lastValley < this.peaks[this.peaks.length-1].timestamp) { - if(this.valley_distances[this.valley_distances.length -1].timestamp > this.peak_distances[this.peak_distances.length-1].timestamp) { - let bpm, change = 0; - if(this.beats.length < 1) { - bpm = 60/(0.0005 * (this.peak_distances[this.peak_distances.length-1].distance + - this.valley_distances[this.valley_distances.length-1].distance)); - - } else if (this.beats[this.beats.length-1].timestamp !== this.peak_distances[this.peak_distances.length-1].timestamp) { - bpm = 60/(0.0005*(this.peak_distances[this.peak_distances.length-1].dt + this.valley_distances[this.valley_distances.length-1].dt)); - change = Math.abs(bpm - this.beats[this.beats.length - 1].bpm); - } - - beat = { - timestamp:this.peak_distances[this.peak_distances.length - 1].timestamp, - change, - bpm, - height0:this.peak_distances[this.peak_distances.length-1].peak0 - - this.valley_distances[this.valley_distances.length-1].peak0, - height1:this.peak_distances[this.peak_distances.length-1].peak1 - - this.valley_distances[this.valley_distances.length-1].peak1 - }; - - this.beats.push(beat); - - this.lastPeak = this.peaks[this.peaks.length-1].timestamp; - this.lastValley = this.peaks[this.peaks.length-1].timestamp; - } else { - let bpm, change = 0; - if(this.beats.length < 2) { - bpm = 60/(0.0005*(this.peak_distances[this.peak_distances.length-2].distance + this.valley_distances[this.valley_distances.length-2].distance)); //(averaged peak + valley distance (msec)) * msec/sec * 60sec/min - } else if(this.beats[this.beats.length-1].timestamp !== this.peak_distances[this.peak_distances.length-2].timestamp) { - bpm = 60/(0.0005*(this.peak_distances[this.peak_distances.length-2].distance + this.valley_distances[this.valley_distances.length-2].distance)); - change = Math.abs(bpm-this.beats[this.beats.length-2].bpm); - } - - beat = { - timestamp:this.peak_distances[this.peak_distances.length-2].timestamp, - change, - bpm, - height0:this.peak_distances[this.peak_distances.length-2].peak0-this.valley_distances[this.valley_distances.length-2].peak0, - height1:this.peak_distances[this.peak_distances.length-2].peak1-this.valley_distances[this.valley_distances.length-2].peak1 - }; - if(Array.isArray(beat.timestamp)) beat.timestamp = beat.timestamp[0]; //some kind of bug - - this.beats.push(beat); - - this.lastPeak = this.peaks[this.peaks.length-1].timestamp; - this.lastValley = this.peaks[this.peaks.length-1].timestamp; - } - } - } - - //limits memory usage - if(this.peaks.length > this.limit) { this.peaks.shift(); } - if(this.valleys.length > this.limit) { this.valleys.shift(); } - if(this.peak_distances.length > this.limit) { this.peak_distances.shift(); } - if(this.valley_distances.length > this.limit) { this.valley_distances.shift(); } - if(this.beats.length > this.limit) { this.beats.shift(); } - - } - } - - return beat; - } - - //console.log(context); - - if(data.red) { - if(('ir' in data) && !Array.isArray(data.red)) return pass((data.red as number)+(data.ir as number),data.timestamp); - - let result; - if(data.ir) result = (data.red as number[]).map((v,i) => { - return pass(v+(data as any).ir[i],(data.timestamp as number[])[i]); - }).filter(v => {if(v) return true;}); - else result = (data.red as number[]).map((v,i) => { - return pass(v,(data.timestamp as number[])[i]); - }).filter(v => {if(v) return true;}); - - return result; //will return an array, defined results will be - - } else if (data.raw) { - if(!Array.isArray(data.raw)) return pass(data.raw,data.timestamp); - let result = data.raw.map((v,i) => { - return pass(v,(data.timestamp as number[])[i]); - }).filter(v => {if(v) return true;}); - return result; //will return an array - } else if (Array.isArray(data.heg)) { - if(!Array.isArray(data.heg)) return pass(data.heg,data.timestamp); - let result = data.heg.map((v,i) => { - return pass(v,(data.timestamp as number[])[i]); - }).filter(v => {if(v) return true;}); - return result; //will return an array - - } - //returns a beat when one is detected with the latest data passed in, else returns undefined - } -} as GraphNodeProperties; \ No newline at end of file diff --git a/src/extras/algorithms/blink.ts b/src/extras/algorithms/blink.ts deleted file mode 100644 index bb4d55fc..00000000 --- a/src/extras/algorithms/blink.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { GraphNodeProperties } from '../../core/Graph'; -import { Biquad } from './util/BiquadFilters'; -import { Math2 } from 'brainsatplay-math'; - - -export const blink_detect = { - sps:250, - intervals:{}, - watch:['0'], - tolerance:0.2, //e.g. mV - __onconnected:(node) => { - node.watch.forEach((ch) => node.intervals[ch] = { - lowpass:new Biquad('lowpass',20,node.sps), - filtered:[] as number[], - averaged:[] as number[] - }) - }, - __operator:function(data:{ - [key:string]:number|number[] - }) { - let checkCt = 5; - let averageCt = 50; - - let found = {}; - let passed = false; - - - let pass = (key,n) => { - let next = this.intervals[key].lowpass.applyFilter(n) - this.intervals[key].filtered.push(next); - this.intervals[key].averaged.push(next); - if(this.intervals[key].filtered.length > checkCt) { - if(this.intervals[key].averaged.length > averageCt) { - this.intervals[key].averaged.splice(0,checkCt); - let mean = Math2.mean(this.intervals[key].averaged); - if(Math.abs(Math.min(...this.intervals[key].filtered)) > Math.abs(mean) + this.tolerance) { - this.intervals[key].filtered.length = 0; //reset - passed = true; - found[key] = true; - } - } else - this.intervals[key].filtered.shift(); - } - } - - - for(const key in this.intervals) { - if(data[key]) { - if(Array.isArray(data[key])) { - (data[key] as any).forEach((n) => { - pass(key,n); - }); - } else if(typeof data[key] === 'number') pass(key,data[key]); - } - } - - if(passed) return found; - - } -} as GraphNodeProperties \ No newline at end of file diff --git a/src/extras/algorithms/buffering.ts b/src/extras/algorithms/buffering.ts deleted file mode 100644 index 504944a1..00000000 --- a/src/extras/algorithms/buffering.ts +++ /dev/null @@ -1,33 +0,0 @@ -//we need to buffer before doing bulk blocking operations on separate threads sometimes (ffts in our case) so we are splitting this into 2 algos - -import { GraphNodeProperties } from '../../core/Graph'; -import { ByteParser } from './util/ByteParser'; - - -export const circularBuffer2d:GraphNodeProperties = { - bufferSize:250, //e.g. sps * nsec of data to buffer - watch:['0','1','2','3'], - data:{}, - blocking:false, - - __onconnected:function (node) { - for(const key in node.watch) { - node.data[key] = new Array(node.bufferSize).fill(0); - } - }, - __operator:function (data) { - - let buffer2d = [] as number[][]; - - this.watch.forEach((key) => { - if(data[key]) { - ByteParser.circularBuffer(this.data[key], data[key]) - buffer2d.push(this.data[key]) - } - }); - - //console.log('buffered', buffer2d) - - return buffer2d; - } -} \ No newline at end of file diff --git a/src/extras/algorithms/coherence.ts b/src/extras/algorithms/coherence.ts deleted file mode 100644 index dfb96641..00000000 --- a/src/extras/algorithms/coherence.ts +++ /dev/null @@ -1,54 +0,0 @@ - -import { GraphNodeProperties } from '../../core/Graph'; -import { GPUService } from '../gpu/GPU.service'; - -if(!globalThis.gpu) globalThis.gpu = new GPUService(); // contains macros for persistent kernels (programs) on the gpu using an instance of gpujs, using the same instance lets us reuse the same kernel instances - -export const coherence:GraphNodeProperties = { - sps:250, //sample rate of data - nSec:1, //number of seconds of data to buffer - freqStart:0, - freqEnd:125, //default full nyquist range - tags:['0','1','2','3'], - coherenceTags:[] as any[], - __onconnected:function (node) { - node.tags.forEach((tag,i) => { - if(i !== node.tags.length-1){ - for(let j = i+1; j < node.tags.length; j++) { - node.coherenceTags.push(node.tags[i]+'_'+node.tags[j]); - } - } - }) - }, - __operator:function(arraybuffer) { - - let ts = Date.now(); - - //console.log('buffer', arraybuffer) - let results = (globalThis.gpu as GPUService).coherence( - arraybuffer, - this.nSec, - this.freqStart, - this.freqEnd - ) as [number[],number[][],number[][]] //frequency (x), power spectrums (y), coherence per channel (in order of channels) - - let dft = {}; - - this.tags.forEach((tag,i) => { - dft[tag] = results[1][i]; - }); - - let coherence = {}; - - this.coherenceTags.forEach((tag,i) => { - coherence[tag] = results[2][i]; - }); - - return { - timestamp:ts, - frequencies:results[0], - dft, - coherence - }; - } -} \ No newline at end of file diff --git a/src/extras/algorithms/dft.ts b/src/extras/algorithms/dft.ts deleted file mode 100644 index f9356062..00000000 --- a/src/extras/algorithms/dft.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { GraphNodeProperties } from '../../core/Graph'; -import { GPUService } from '../gpu/GPU.service'; - -if(!globalThis.gpu) globalThis.gpu = new GPUService(); // contains macros for persistent kernels (programs) on the gpu using an instance of gpujs, using the same instance lets us reuse the same kernel instances - -export const dft:GraphNodeProperties = { - sps:250, //sample rate of data - nSec:1, //number of seconds of data to buffer - freqStart:0, - freqEnd:125, //default full nyquist range - watch:['0','1','2','3'], - blocking:false, - //__onconnected:(ctx) => {}, - __operator:function (arraybuffer) { - - //console.log('buffer', arraybuffer) - let results = (globalThis.gpu as GPUService).multidftbandpass( - arraybuffer, - this.nSec, - this.freqStart, - this.freqEnd, - 1 - ) as [number[],number[][],number[][]] //frequency (x), power spectrums (y), coherence per channel (in order of channels) - - let dft = {}; - - this.watch.forEach((tag,i) => { - dft[tag] = results[1][i]; - }); - - - return { - frequencies: results[0], - dft - } - } -} \ No newline at end of file diff --git a/src/extras/algorithms/index.gpu.ts b/src/extras/algorithms/index.gpu.ts deleted file mode 100644 index 6dec9663..00000000 --- a/src/extras/algorithms/index.gpu.ts +++ /dev/null @@ -1,8 +0,0 @@ - -import { dft } from './dft'; -import { coherence } from './coherence'; - -export const gpualgorithms = { - dft, - coherence -} diff --git a/src/extras/algorithms/rms.ts b/src/extras/algorithms/rms.ts deleted file mode 100644 index bbe26d21..00000000 --- a/src/extras/algorithms/rms.ts +++ /dev/null @@ -1,44 +0,0 @@ -//root mean square doer thinger - -import { GraphNodeProperties } from "../../core/Graph"; -import { ByteParser } from "./util/ByteParser"; - -export const rms:GraphNodeProperties = { - sps:250, //sample rate of data - nSec:1, //number of seconds of data to buffer - watch:['0','1','2','3'], - data:{}, - rms:{}, - //__onconnected:(node) => { }, - __operator:function (data) { - - this.watch.forEach((key) => { - if(data[key]) { - if(!this.data[key]) { - if(Array.isArray(data[key])) { - this.data[key] = new Array(Math.floor(this.sps*this.nSec)).fill(data[key][0]); - } else this.data[key] = new Array(Math.floor(this.sps*this.nSec)).fill(data[key]); - } - ByteParser.circularBuffer(this.data[key],data[key]); - } - }); - - if(data.timestamp) { - if(Array.isArray(data.timestamp)) { - this.rms.timestamp = data.timestamp[data.timestamp.length - 1]; - } else this.rms.timestamp = data.timestamp; - } else this.rms.timestamp = Date.now(); - - //console.log(ctx.rms,ctx.data); - - return new Promise(async res => { - await Promise.all(this.watch.map(async (key) => { - if(this.data[key]) this.rms[key] = Math.sqrt(Math.abs((this.data[key] as number[]).reduce((p,v,i) => p + v*v )/this.data[key].length)); //root mean square sum - else delete this.rms[key]; - })) - - res(this.rms); - }) - - } -} \ No newline at end of file diff --git a/src/extras/dist/Worker.js b/src/extras/dist/Worker.js deleted file mode 100644 index 2de70544..00000000 --- a/src/extras/dist/Worker.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf;var __hasOwnProp=Object.prototype.hasOwnProperty;var __commonJS=(cb,mod)=>function __require(){return mod||(0,cb[__getOwnPropNames(cb)[0]])((mod={exports:{}}).exports,mod),mod.exports};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from==="object"||typeof from==="function"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:true}):target,mod));var require_browser=__commonJS({"../../node_modules/web-worker/cjs/browser.js"(exports,module){module.exports=Worker}});var EventHandler=class{constructor(data){this.pushToState={};this.data={};this.triggers={};this.setState=updateObj=>{Object.assign(this.data,updateObj);let props=Object.getOwnPropertyNames(updateObj);for(const prop of props){this.triggerEvent(prop,this.data[prop])}if(this.triggers["__state__"])this.triggers["__state__"].forEach(fn=>{fn(updateObj)});return this.data};this.setValue=(key,value)=>{this.data[key]=value;this.triggerEvent(key,value)};this.triggerEvent=(key,value)=>{if(this.triggers[key]){let fn=obj=>obj.onchange(value);this.triggers[key].forEach(fn)}};this.subscribeState=onchange=>{return this.subscribeEvent("__state__",onchange)};this.unsubscribeState=sub=>{return this.unsubscribeEvent("__state__",sub)};this.subscribeEvent=(key,onchange,refObject,refKey)=>{if(key){if(refObject&&refKey&&!this.triggers[key]){Object.defineProperty(this.data,key,{get:()=>{return refObject[refKey]},set:value=>{refObject[refKey]=value},enumerable:true,configurable:true})}if(!this.triggers[key]){this.triggers[key]=[]}let biggest=0;for(const trigger of this.triggers[key]){if(trigger.sub>biggest)biggest=trigger.sub}let l=biggest+1;this.triggers[key].push({sub:l,onchange});return this.triggers[key].length-1}else return void 0};this.unsubscribeEvent=(key,sub)=>{let triggers=this.triggers[key];if(triggers){if(!sub){delete this.triggers[key];delete this.data[key]}else{let sub2=void 0;let obj=triggers.find((o,i2)=>{if(o.sub===sub2){sub2=i2;return true}});if(obj)triggers.splice(sub2,1);if(Object.keys(triggers).length===0){delete this.triggers[key];delete this.data[key]}if(this.onRemoved)this.onRemoved(obj);return true}}};this.subscribeEventOnce=(key,onchange)=>{let sub;let changed=value=>{onchange(value);this.unsubscribeEvent(key,sub)};sub=this.subscribeEvent(key,changed)};this.getEvent=(key,sub)=>{for(const s in this.triggers[key]){if(this.triggers[key][s].sub===sub)return this.triggers[key][s]}};this.getSnapshot=()=>{const snapshot={};for(const key in this.data){snapshot[key]=this.data[key]}};if(typeof data==="object")this.data=data}};var state=new EventHandler;var GraphNode=class{constructor(properties,parent,graph){this.__node={tag:`node${Math.floor(Math.random()*1e15)}`,unique:`${Math.floor(Math.random()*1e15)}`,state};this.__setProperties=(properties,parent,graph)=>{let enforceProperties=()=>{let orig=properties;if(typeof properties==="function"){if(isNativeClass(properties)){properties=new properties}else properties={__operator:properties,__node:{forward:true,tag:properties.name}}}else if(typeof properties==="string"){if(graph?.get(properties)){properties=graph.get(properties)}}if(!properties.__node.initial)properties.__node.initial=orig};enforceProperties();if(typeof properties==="object"){let assignState=()=>{if(properties.__node?.state)this.__node.state=properties.__node.state};let setProps2=()=>{if(properties.__props){if(typeof properties.__props==="function")properties.__props=new properties.__props;if(typeof properties.__props==="object"){this.__proxyObject(properties.__props)}}};let setTag=()=>{if(!properties.__node.tag){if(properties.__operator?.name)properties.__node.tag=properties.__operator.name;else properties.__node.tag=`node${Math.floor(Math.random()*1e15)}`}};let setNode=()=>{if(typeof properties.__node==="string"){if(graph?.get(properties.__node.tag)){properties=graph.get(properties.__node.tag)}else properties.__node={}}else if(!properties.__node)properties.__node={};if(graph){properties.__node.graph=graph}if(properties instanceof Graph)properties.__node.source=properties};let setParent=()=>{if(!properties.__parent&&parent)properties.__parent=parent;if(parent?.__node&&!(parent instanceof Graph||properties instanceof Graph))properties.__node.tag=parent.__node.tag+"."+properties.__node.tag;if(parent instanceof Graph&&properties instanceof Graph){if(properties.__node.loaders)Object.assign(parent.__node.loaders?parent.__node.loaders:{},properties.__node.loaders);if(parent.__node.mapGraphs){properties.__node.nodes.forEach(n=>{parent.set(properties.__node.tag+"."+n.__node.tag,n)});let ondelete=()=>{properties.__node.nodes.forEach(n=>{parent.__node.nodes.delete(properties.__node.tag+"."+n.__node.tag)})};this.__addOndisconnected(ondelete)}}};let setOp=()=>{if(typeof properties.default==="function"&&!properties.__operator){properties.__operator=properties.default}if(properties.__operator){if(typeof properties.__operator==="string"){if(graph){let n=graph.get(properties.__operator);if(n)properties.__operator=n.__operator;if(!properties.__node.tag&&properties.__operator.name)properties.__node.tag=properties.__operator.name}}if(typeof properties.__operator==="function")properties.__operator=this.__setOperator(properties.__operator);if(properties.default)properties.default=properties.__operator}};let assignProps=()=>{properties.__node=Object.assign(this.__node,properties.__node);let keys2=Object.getOwnPropertyNames(properties);for(const key of keys2){this[key]=properties[key]}};let bindCallbacks=()=>{if(this.__onconnected){if(typeof this.__onconnected==="function"){this.__onconnected=this.__onconnected.bind(this)}else if(Array.isArray(this.__onconnected)){this.__onconnected=this.__onconnected.map(f=>{return f.bind(this)})}if(typeof this.__ondisconnected==="function"){this.__ondisconnected=this.__ondisconnected.bind(this)}else if(Array.isArray(this.__ondisconnected)){this.__ondisconnected=this.__ondisconnected.map(f=>{return f.bind(this)})}}};assignState();setTag();setProps2();setNode();setParent();assignProps();bindCallbacks();setOp()}};this.__subscribe=(callback,key,subInput,bound,target)=>{const subscribeToFunction=(k,setTarget=(callback2,target2)=>callback2,triggerCallback=callback)=>{let sub=this.__node.state.subscribeEvent(k,triggerCallback,this,key);let trigger=this.__node.state.getEvent(k,sub);trigger.source=this.__node.tag;if(key)trigger.key=key;trigger.target=setTarget(callback);if(bound)trigger.bound=bound;return sub};const subscribeToGraph=callback2=>{let fn=this.__node.graph.get(callback2);if(!fn&&callback2.includes(".")){let n=this.__node.graph.get(callback2.substring(0,callback2.lastIndexOf(".")));let key2=callback2.substring(callback2.lastIndexOf(".")+1);if(n&&typeof n[key2]==="function")callback2=(...args)=>{return n[key2](...args)}}};if(key){if(!this.__node.localState||!this.__node.localState[key]){this.__addLocalState(this,key)}if(typeof callback==="string"){if(target){if(this.__node.graph?.get(target)){let n=this.__node.graph?.get(target);if(typeof n[callback]==="function"){let fn=n[callback];callback=(...inp)=>{fn(...inp)}}else{let k2=callback;let setter=inp=>{n[k2]=inp};callback=setter}}}else if(typeof this[callback]==="function"){let fn=this[callback];callback=(...inp)=>{fn(...inp)}}else if(this.__node.graph?.get(callback))subscribeToGraph(callback);if(typeof callback!=="function")return void 0}let sub;let k=subInput?this.__node.unique+"."+key+"input":this.__node.unique+"."+key;if(typeof callback==="function")sub=subscribeToFunction(k);else if(callback?.__node)sub=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2.__node.unique,(...inp)=>{if(callback.__operator)callback.__operator(...inp)});return sub}else{if(typeof callback==="string"){if(this.__node.graph.get(callback))callback=this.__node.graph.get(callback);if(typeof callback!=="object")return void 0}let sub;let k=subInput?this.__node.unique+"input":this.__node.unique;if(typeof callback==="function")sub=subscribeToFunction(k);else if(callback?.__node)sub=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2.__node.unique,(...inp)=>{if(callback.__operator)callback.__operator(...inp)});return sub}};this.__unsubscribe=(sub,key,unsubInput)=>{if(key)return this.__node.state.unsubscribeEvent(unsubInput?this.__node.unique+"."+key+"input":this.__node.unique+"."+key,sub);else return this.__node.state.unsubscribeEvent(unsubInput?this.__node.unique+"input":this.__node.unique,sub)};this.__setOperator=fn=>{fn=fn.bind(this);if(this.__args&&this.__node.graph){fn=wrapArgs(fn,this.__args,this.__node.graph)}let inpstr=`${this.__node.unique}input`;this.__operator=(...args)=>{if(this.__node.state.triggers[inpstr])this.__node.state.setValue(inpstr,args);let result=fn(...args);if(this.__node.state.triggers[this.__node.unique]){if(typeof result?.then==="function"){result.then(res=>{if(res!==void 0)this.__node.state.setValue(this.__node.unique,res)}).catch(console.error)}else if(result!==void 0)this.__node.state.setValue(this.__node.unique,result)}return result};if(this.__parent instanceof GraphNode&&!this.__subscribedToParent){if(this.__parent.__operator){let sub=this.__parent.__subscribe(this);let ondelete=()=>{this.__parent?.__unsubscribe(sub);delete this.__subscribedToParent};this.__addOndisconnected(ondelete);this.__subscribedToParent=true}}return this.__operator};this.__addLocalState=(props,key)=>{if(!props)return;if(!this.__node.localState){this.__node.localState={}}const localState=this.__node.localState;const initState=(props2,k)=>{let str=this.__node.unique+"."+k;let inpstr=`${str}input`;if(typeof props2[k]==="function"&&k!=="__operator"){let fn=props2[k].bind(this);props2[k]=(...args)=>{if(this.__node.state.triggers[inpstr])this.__node.state.setValue(inpstr,args);let result=fn(...args);if(this.__node.state.triggers[str]){if(typeof result?.then==="function"){result.then(res=>{this.__node.state.triggerEvent(str,res)}).catch(console.error)}else this.__node.state.triggerEvent(str,result)}return result}}else{let get,set;if(this.__props?.[k]){get=()=>{return this.__props[k]};set=v=>{this.__props[k]=v;if(this.__node.state.triggers[str])this.__node.state.triggerEvent(str,v)}}else{localState[k]=props2[k];get=()=>{return localState[k]};set=v=>{localState[k]=v;if(this.__node.state.triggers[str])this.__node.state.triggerEvent(str,v)}}const descriptor={get,set,enumerable:true,configurable:true};Object.defineProperty(props2,k,descriptor);if(typeof this.__node.initial==="object"){let dec=Object.getOwnPropertyDescriptor(this.__node.initial,k);if(dec===void 0||dec?.configurable){Object.defineProperty(this.__node.initial,k,descriptor)}}}};if(key)initState(props,key);else{for(let k in props){initState(props,k)}}};this.__proxyObject=obj=>{const allProps=getAllProperties(obj);for(const k of allProps){if(typeof obj[k]==="function"){this[k]=(...args)=>{return obj[k](...args)}}else{const descriptor={get:()=>{return obj[k]},set:value=>{obj[k]=value},enumerable:true,configurable:true};Object.defineProperty(this,k,descriptor);if(typeof this.__node.initial==="object"){let dec=Object.getOwnPropertyDescriptor(this.__node.initial,k);if(dec===void 0||dec?.configurable){Object.defineProperty(this.__node.initial,k,descriptor)}}}}};this.__setProperties(properties,parent,graph)}__addOnconnected(callback){callback=callback.bind(this);if(Array.isArray(this.__onconnected)){this.__onconnected.push(callback)}else if(typeof this.__onconnected==="function"){this.__onconnected=[callback,this.__onconnected]}else this.__onconnected=callback}__addOndisconnected(callback){callback=callback.bind(this);if(Array.isArray(this.__ondisconnected)){this.__ondisconnected.push(callback)}else if(typeof this.__ondisconnected==="function"){this.__ondisconnected=[callback,this.__ondisconnected]}else this.__ondisconnected=callback}__callConnected(node=this){if(typeof this.__onconnected==="function"){this.__onconnected(this)}else if(Array.isArray(this.__onconnected)){let fn=o=>{o(this)};this.__onconnected.forEach(fn)}}__callDisconnected(node=this){if(typeof this.__ondisconnected==="function")this.__ondisconnected(this);else if(Array.isArray(this.__ondisconnected)){let fn=o=>{o(this)};this.__ondisconnected.forEach(fn)}}};var Graph=class{constructor(options){this.__node={tag:`graph${Math.floor(Math.random()*1e15)}`,unique:`${Math.random()}`,nodes:new Map,state,roots:{}};this.init=options=>{if(options){let cpy=Object.assign({},options);delete cpy.roots;recursivelyAssign(this.__node,cpy);if(options.roots)this.load(options.roots)}};this.load=roots=>{function recursivelyAssignChildren(target,obj,inChildren=true,top=true){if(top){if(target)Object.assign(target,obj);else target=Object.assign({},obj);recursivelyAssignChildren(target,obj,true,false)}if(obj.__children&&!inChildren){if(obj.__children?.constructor.name==="Object"){if(target.__children?.constructor.name==="Object")recursivelyAssignChildren(target.__children,obj.__children,true,false);else target.__children=recursivelyAssignChildren({},obj.__children,true,false)}else{target.__children=obj.__children}}else if(inChildren){for(const key in obj){target[key]=Object.assign({},obj[key]);if(obj[key].__children){recursivelyAssignChildren({},obj[key].__children,false,false)}}}return target}this.__node.roots=recursivelyAssignChildren(this.__node.roots?this.__node.roots:{},roots);let cpy=Object.assign({},roots);if(cpy.__node)delete cpy.__node;let listeners=this.recursiveSet(cpy,this,void 0,roots);if(roots.__node){if(!roots.__node.tag)roots.__node._tag=`roots${Math.floor(Math.random()*1e15)}`;else if(!this.get(roots.__node.tag)){let node=new GraphNode(roots,this,this);this.set(node.__node.tag,node);this.runLoaders(node,this,roots,roots.__node.tag);if(node.__listeners){listeners[node.__node.tag]=node.__listeners}}}else if(roots.__listeners){this.setListeners(roots.__listeners)}this.setListeners(listeners);return cpy};this.setLoaders=(loaders2,replace)=>{if(replace)this.__node.loaders=loaders2;else Object.assign(this.__node.loaders,loaders2);return this.__node.loaders};this.runLoaders=(node,parent,properties,key)=>{for(const l in this.__node.loaders){if(typeof this.__node.loaders[l]==="object"){if(this.__node.loaders[l].init)this.__node.loaders[l](node,parent,this,this.__node.roots,properties,key);if(this.__node.loaders[l].connected)node.__addOnconnected(this.__node.loaders[l].connect);if(this.__node.loaders[l].disconnected)node.__addOndisconnected(this.__node.loaders[l].disconnect)}else if(typeof this.__node.loaders[l]==="function")this.__node.loaders[l](node,parent,this,this.__node.roots,properties,key)}};this.add=(properties,parent)=>{let listeners={};if(typeof parent==="string")parent=this.get(parent);let instanced;if(typeof properties==="function"){if(isNativeClass(properties)){if(properties.prototype instanceof GraphNode){properties=properties.prototype.constructor(properties,parent,this);instanced=true}else properties=new properties}else properties={__operator:properties}}else if(typeof properties==="string"){properties=this.__node.roots[properties]}if(!properties)return;if(!instanced){let keys2=Object.getOwnPropertyNames(properties);let cpy={};for(const key of keys2){cpy[key]=properties[key]}properties=cpy}if(!properties.__node)properties.__node={};properties.__node.initial=properties;if(typeof properties==="object"&&(!properties?.__node?.tag||!this.get(properties.__node.tag))){let node;if(instanced)node=properties;else node=new GraphNode(properties,parent,this);this.set(node.__node.tag,node);this.runLoaders(node,parent,properties,node.__node.tag);this.__node.roots[node.__node.tag]=properties;if(node.__children){node.__children=Object.assign({},node.__children);this.recursiveSet(node.__children,node,listeners,node.__children)}if(node.__listeners){listeners[node.__node.tag]=Object.assign({},node.__listeners);for(const key in node.__listeners){let listener=node.__listeners[key];if(node[key]){delete listeners[node.__node.tag][key];listeners[node.__node.tag][node.__node.tag+"."+key]=listener}if(typeof listener==="string"){if(node.__children?.[listener]){listeners[node.__node.tag][key]=node.__node.tag+"."+listener}else if(parent instanceof GraphNode&&(parent.__node.tag===listener||parent.__node.tag.includes(".")&&parent.__node.tag.split(".").pop()===listener)){listeners[node.__node.tag][key]=parent.__node.tag}}}}this.setListeners(listeners);node.__callConnected();return node}return};this.recursiveSet=(t,parent,listeners={},origin)=>{let keys2=Object.getOwnPropertyNames(origin);for(const key of keys2){if(key.includes("__"))continue;let p=origin[key];if(Array.isArray(p))continue;let instanced;if(typeof p==="function"){if(isNativeClass(p)){p=new p;if(p instanceof GraphNode){p=p.prototype.constructor(p,parent,this);instanced=true}}else p={__operator:p}}else if(typeof p==="string"){if(this.__node.nodes.get(p))p=this.__node.nodes.get(p);else p=this.__node.roots[p]}else if(typeof p==="boolean"){if(this.__node.nodes.get(key))p=this.__node.nodes.get(key);else p=this.__node.roots[key]}if(typeof p==="object"){if(!instanced&&!(p instanceof GraphNode)){let keys3=Object.getOwnPropertyNames(p);let cpy={};for(const key2 of keys3){cpy[key2]=p[key2]}p=cpy}if(!p.__node)p.__node={};if(!p.__node.tag)p.__node.tag=key;if(!p.__node.initial)p.__node.initial=t[key];if(this.get(p.__node.tag)&&!(!(parent instanceof Graph)&&parent?.__node)||parent?.__node&&this.get(parent.__node.tag+"."+p.__node.tag))continue;let node;let newnode=false;if(instanced||p instanceof GraphNode){node=p}else{node=new GraphNode(p,parent,this);newnode=true}if(!newnode&&p instanceof GraphNode&&!instanced&&parent instanceof GraphNode){let sub=this.subscribe(parent.__node.tag,node.__node.tag);let ondelete=node2=>{this.unsubscribe(parent.__node.tag,sub)};node.__addOndisconnected(ondelete)}else{this.set(node.__node.tag,node);this.runLoaders(node,parent,t[key],key);t[key]=node;this.__node.roots[node.__node.tag]=p;if(node.__children){node.__children=Object.assign({},node.__children);this.recursiveSet(node.__children,node,listeners,node.__children)}if(node.__listeners){listeners[node.__node.tag]=Object.assign({},node.__listeners);for(const key2 in node.__listeners){let listener=node.__listeners[key2];let k=key2;if(node[key2]){delete listeners[node.__node.tag][key2];k=node.__node.tag+"."+key2;listeners[node.__node.tag][k]=listener}if(typeof listener==="string"){if(node.__children?.[listener]){listeners[node.__node.tag][k]=node.__node.tag+"."+listener}else if(parent instanceof GraphNode&&(parent.__node.tag===listener||parent.__node.tag.includes(".")&&parent.__node.tag.split(".").pop()===listener)){listeners[node.__node.tag][k]=parent.__node.tag}}}}node.__callConnected()}}}return listeners};this.remove=(node,clearListeners=true)=>{this.unsubscribe(node);if(typeof node==="string")node=this.get(node);if(node instanceof GraphNode){this.delete(node.__node.tag);delete this.__node.roots[node.__node.tag];if(clearListeners){this.clearListeners(node)}node.__callDisconnected();const recursiveRemove=t=>{for(const key in t){this.unsubscribe(t[key]);this.delete(t[key].__node.tag);delete this.__node.roots[t[key].__node.tag];this.delete(key);delete this.__node.roots[key];t[key].__node.tag=t[key].__node.tag.substring(t[key].__node.tag.lastIndexOf(".")+1);if(clearListeners){this.clearListeners(t[key])}console.log(key,t[key].__listeners);t[key].__callDisconnected();if(t[key].__children){recursiveRemove(t[key].__children)}}};if(node.__children){recursiveRemove(node.__children)}}if(node?.__node.tag&&node?.__parent){delete node?.__parent;node.__node.tag=node.__node.tag.substring(node.__node.tag.indexOf(".")+1)}return node};this.run=(node,...args)=>{if(typeof node==="string"){let nd=this.get(node);if(!nd&&node.includes(".")){nd=this.get(node.substring(0,node.lastIndexOf(".")));if(typeof nd?.[node.substring(node.lastIndexOf(".")+1)]==="function")return nd[node.substring(node.lastIndexOf(".")+1)](...args)}else if(nd?.__operator)return nd.__operator(...args)}if(node?.__operator){return node?.__operator(...args)}};this.setListeners=listeners=>{for(const key in listeners){let node=this.get(key);if(typeof listeners[key]==="object"){for(const k in listeners[key]){let n=this.get(k);let sub;if(typeof listeners[key][k]!=="object")listeners[key][k]={__callback:listeners[key][k]};else if(!listeners[key][k].__callback){for(const kk in listeners[key][k]){if(typeof listeners[key][k][kk]!=="object"){listeners[key][k][kk]={__callback:listeners[key][k][kk]};if(listeners[key][k][kk].__callback===true||typeof listeners[key][k][kk].__callback==="undefined")listeners[key][k][kk].__callback=node.__operator}let nn=this.get(kk);if(nn){if(!nn){let tag=k.substring(0,k.lastIndexOf("."));nn=this.get(tag);if(n){sub=this.subscribe(nn,listeners[key][k][kk].__callback,listeners[key][k][kk].__args,k.substring(k.lastIndexOf(".")+1),listeners[key][k][kk].inputState,key,k);if(typeof node.__listeners[k][kk]!=="object")node.__listeners[k][kk]={__callback:listeners[key][k][kk].__callback,inputState:listeners[key][k][kk]?.inputState};node.__listeners[k][kk].sub=sub}}else{sub=this.subscribe(nn,listeners[key][k][kk].__callback,listeners[key][k].__args,void 0,listeners[key][k].inputState,key,k);if(typeof node.__listeners[k][kk]!=="object")node.__listeners[k][kk]={__callback:listeners[key][k][kk].__callback,inputState:listeners[key][k][kk]?.inputState};node.__listeners[k][kk].sub=sub}}}}if("__callback"in listeners[key][k]){if(listeners[key][k].__callback===true||typeof listeners[key][k].__callback==="undefined")listeners[key][k].__callback=node.__operator;if(typeof listeners[key][k].__callback==="function")listeners[key][k].__callback=listeners[key][k].__callback.bind(node);if(typeof node.__listeners!=="object")node.__listeners={};if(!n){let tag=k.substring(0,k.lastIndexOf("."));n=this.get(tag);if(n){sub=this.subscribe(n,listeners[key][k].__callback,listeners[key][k].__args,k.substring(k.lastIndexOf(".")+1),listeners[key][k].inputState,key,k);if(typeof node.__listeners[k]!=="object")node.__listeners[k]={__callback:listeners[key][k].__callback,inputState:listeners[key][k]?.inputState};node.__listeners[k].sub=sub}}else{sub=this.subscribe(n,listeners[key][k].__callback,listeners[key][k].__args,void 0,listeners[key][k].inputState,key,k);if(typeof node.__listeners[k]!=="object")node.__listeners[k]={__callback:listeners[key][k].__callback,inputState:listeners[key][k]?.inputState};node.__listeners[k].sub=sub}}}}}};this.clearListeners=(node,listener)=>{if(typeof node==="string")node=this.get(node);if(node?.__listeners){for(const key in node.__listeners){if(listener&&key!==listener)continue;if(typeof node.__listeners[key]?.sub!=="number")continue;let n=this.get(key);if(!n){n=this.get(key.substring(0,key.lastIndexOf(".")));if(n){if(typeof node.__listeners[key]==="object"&&!node.__listeners[key]?.__callback){for(const k in node.__listeners[key]){if(typeof node.__listeners[key][k]?.sub==="number"){this.unsubscribe(n,node.__listeners[key][k].sub,key.substring(key.lastIndexOf(".")+1),node.__listeners[key][k].inputState);node.__listeners[key][k].sub=void 0}}}else if(typeof node.__listeners[key]?.sub==="number"){this.unsubscribe(n,node.__listeners[key].sub,key.substring(key.lastIndexOf(".")+1),node.__listeners[key].inputState);node.__listeners[key].sub=void 0}}}else{if(typeof!node.__listeners[key]?.__callback==="number"){for(const k in node.__listeners[key]){if(node.__listeners[key][k]?.sub){this.unsubscribe(n,node.__listeners[key][k].sub,void 0,node.__listeners[key][k].inputState);node.__listeners[key][k].sub=void 0}}}else if(typeof node.__listeners[key]?.sub==="number"){this.unsubscribe(n,node.__listeners[key].sub,void 0,node.__listeners[key].inputState);node.__listeners[key].sub=void 0}}}}};this.get=tag=>{return this.__node.nodes.get(tag)};this.set=(tag,node)=>{return this.__node.nodes.set(tag,node)};this.delete=tag=>{return this.__node.nodes.delete(tag)};this.getProps=(node,getInitial)=>{if(typeof node==="string")node=this.get(node);if(node instanceof GraphNode){let cpy;if(getInitial)cpy=Object.assign({},this.__node.roots[node.__node.tag]);else{cpy=Object.assign({},node);for(const key in cpy){if(key.includes("__"))delete cpy[key]}}}};this.subscribe=(nodeEvent,onEvent,args,key,subInput,target,bound)=>{let nd=nodeEvent;if(typeof nodeEvent==="string"){nd=this.get(nodeEvent);if(!nd&&nodeEvent.includes(".")){nd=this.get(nodeEvent.substring(0,nodeEvent.lastIndexOf(".")));key=nodeEvent.substring(nodeEvent.lastIndexOf(".")+1)}}let sub;if(target instanceof GraphNode)target=target.__node.tag;if(typeof onEvent==="string"){let key2=onEvent;let setOnEventFromString=onEvent2=>{if(this.get(onEvent2)?.__operator){let node=this.get(onEvent2);onEvent2=function(...inp){return node.__operator(...inp)}}else if(onEvent2.includes(".")){let n=this.get(onEvent2.substring(0,onEvent2.lastIndexOf(".")));let key3=onEvent2.substring(onEvent2.lastIndexOf(".")+1);if(typeof n[key3]==="function"){if(n[key3]instanceof GraphNode)onEvent2=n[key3];else onEvent2=function(...inp){return n[key3](...inp)}}else{onEvent2=function(inp){n[key3]=inp;return n[key3]}}}return onEvent2};if(target){let node=this.get(target);if(typeof node?.[onEvent]==="function"){onEvent=function(...inp){return node[key2](...inp)}}else if(node[key2]){if(node[key2]instanceof GraphNode)onEvent=node[key2];else onEvent=function(inp){node[key2]=inp;return node[key2]}}else{onEvent=setOnEventFromString(onEvent)}}else{onEvent=setOnEventFromString(onEvent)}}if((typeof onEvent==="function"||onEvent instanceof GraphNode)&&args){if(onEvent instanceof GraphNode&&onEvent.__operator)onEvent=function(inp){return onEvent.__operator(inp)};onEvent=wrapArgs(onEvent,args,this)}if(nd instanceof GraphNode){sub=nd.__subscribe(onEvent,key,subInput,target,bound);let ondelete=()=>{nd.__unsubscribe(sub,key,subInput)};nd.__addOndisconnected(ondelete)}else if(typeof nodeEvent==="string"){if(this.get(nodeEvent)){if(onEvent instanceof GraphNode&&onEvent.__operator){sub=this.get(nodeEvent).__subscribe(onEvent.__operator,key,subInput,target,bound);let ondelete=()=>{this.get(nodeEvent).__unsubscribe(sub)};onEvent.__addOndisconnected(ondelete)}else if(typeof onEvent==="function"||typeof onEvent==="string"){sub=this.get(nodeEvent).__subscribe(onEvent,key,subInput,target,bound);this.__node.state.getEvent(this.get(nodeEvent).__node.unique,sub).source=nodeEvent}}else{if(typeof onEvent==="string")onEvent=this.__node.nodes.get(onEvent).__operator;if(typeof onEvent==="function")sub=this.__node.state.subscribeEvent(nodeEvent,onEvent)}}return sub};this.unsubscribe=(node,sub,key,subInput)=>{if(node instanceof GraphNode){return node.__unsubscribe(sub,key,subInput)}else return this.get(node)?.__unsubscribe(sub,key,subInput)};this.setState=update=>{this.__node.state.setState(update)};this.init(options)}};function recursivelyAssign(target,obj){for(const key in obj){if(obj[key]?.constructor.name==="Object"){if(target[key]?.constructor.name==="Object")recursivelyAssign(target[key],obj[key]);else target[key]=recursivelyAssign({},obj[key])}else{target[key]=obj[key]}}return target}function getAllProperties(obj){var allProps=[],curr=obj;do{var props=Object.getOwnPropertyNames(curr);let fn=function(prop){if(allProps.indexOf(prop)===-1)allProps.push(prop)};props.forEach(fn)}while(curr=Object.getPrototypeOf(curr));return allProps}function isNativeClass(thing){return isFunction(thing)==="class"}function isFunction(x2){const res=typeof x2==="function"?x2.prototype?Object.getOwnPropertyDescriptor(x2,"prototype")?.writable?"function":"class":x2.constructor.name==="AsyncFunction"?"async":"arrow":"";return res}var wrapArgs=(callback,argOrder,graph)=>{let args=[];let getCallbackFromString=a=>{if(graph.get(a)?.__operator){let node=graph.get(a);return(...inp)=>{node.__operator(...inp)}}else if(a.includes(".")){let split=a.split(".");let popped=split.pop();let joined=split.join(".");let node=graph.get(joined);if(typeof graph.get(joined)?.[popped]==="function"){return(...inp)=>{return node[popped](...inp)}}else return()=>{return node[popped]}}else if(graph.get(a)){let node=graph.get(a);return()=>{return node}}else{let arg=a;return()=>{return arg}}};let forArg=(a,i2)=>{if(a==="__output"){args[i2]=inp=>{return inp}}else if(typeof a==="string"){args[i2]=getCallbackFromString(a)}else if(typeof a==="function"){let fn2=a;args[i2]=(...inp)=>{return fn2(...inp)}}else if(typeof a==="object"&&a.__input){let recursivelyCreateCallback=function(c){let input=c.__input;if(typeof c.__input==="string"){input=getCallbackFromString(c.__input)}if(c.__args){input=wrapArgs(input,c.__args,graph)}if(c.__output){let output=c.__output;if(typeof c.__output==="string"){output=getCallbackFromString(output)}else if(typeof a.__output==="object"){output=recursivelyCreateCallback(output)}if(typeof output==="function"){let fn2=input;input=(...inp)=>{return output(fn2(...inp))}}}return input};args[i2]=recursivelyCreateCallback(a)}else{let arg=a;args[i2]=()=>{return arg}}};argOrder.forEach(forArg);if(typeof callback==="string")callback=getCallbackFromString(callback);let fn=callback;callback=function(...inp){let mapArg=arg=>{return arg(...inp)};return fn(...args.map(mapArg))};return callback};var backprop=(node,parent,graph)=>{if(node.__node.backward&&parent instanceof GraphNode){graph.setListeners({[parent.__node.tag]:{[node.__node.tag]:parent}})}};var loop=(node,parent,graph)=>{if(node.__operator&&!node.__node.looperSet){if(typeof node.__node.delay==="number"){let fn=node.__operator;node.__setOperator((...args)=>{return new Promise((res,rej)=>{setTimeout(async()=>{res(await fn(...args))},node.__node.delay)})})}else if(node.__node.frame===true){let fn=node.__operator;node.__setOperator((...args)=>{return new Promise((res,rej)=>{requestAnimationFrame(async()=>{res(await fn(...args))})})})}if(typeof node.__node.repeat==="number"||typeof node.__node.recursive==="number"){let fn=node.__operator;node.__setOperator(async(...args)=>{let i2=node.__node.repeat?node.__node.repeat:node.__node.recursive;let result;let repeater=async(tick,...inp)=>{while(tick>0){if(node.__node.delay||node.__node.frame){fn(...inp).then(async res=>{if(node.__node.recursive){await repeater(tick,res)}else await repeater(tick,...inp)});break}else result=await fn(...args);tick--}};await repeater(i2,...args);return result})}if(node.__node.loop&&typeof node.__node.loop==="number"){node.__node.looperSet=true;let fn=node.__operator;node.__setOperator((...args)=>{if(!("looping"in node.__node))node.__node.looping=true;if(node.__node.looping){fn(...args);setTimeout(()=>{node.__operator(...args)},node.__node.loop)}});if(node.__node.looping)node.__operator();let ondelete=node2=>{if(node2.__node.looping)node2.__node.looping=false};node.__addOndisconnected(ondelete)}}};var animate=(node,parent,graph)=>{if(node.__node.animate===true||node.__animation){let fn=node.__operator;node.__setOperator((...args)=>{if(!("animating"in node.__node))node.__node.animating=true;if(node.__node.animating){if(typeof node.__animation==="function")node.__animation(...args);else fn(...args);requestAnimationFrame(()=>{node.__operator(...args)})}});if(node.__node.animating||(!("animating"in node.__node)||node.__node.animating)&&node.__animation)setTimeout(()=>{requestAnimationFrame(node.__operator)},10);let ondelete=node2=>{if(node2.__node.animating)node2.__node.animating=false};node.__addOndisconnected(ondelete)}};var branching=(node,parent,graph)=>{if(typeof node.__branch==="object"&&node.__operator&&!node.__branchApplied){let fn=node.__operator;node.__branchApplied=true;node.__operator=(...args)=>{let result=fn(...args);for(const key in node.__branch){let triggered=()=>{if(typeof node.__branch[key].then==="function"){node.__branch[key].then(result)}else if(node.__branch[key].then instanceof GraphNode&&node.__branch[key].then.__operator){node.__branch[key].then.__operator(result)}else result=node.__branch[key].then};if(typeof node.__branch[key].if==="function"){if(node.__branch[key].if(result)==true){triggered()}}else if(node.__branch[key].if===result){triggered()}}return result}}if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(node.__listeners[key].branch&&!node.__listeners[key].branchApplied){let fn=node.__listeners[key].callback;node.__listeners[key].branchApplied=true;node.__listeners.callback=ret=>{let triggered=()=>{if(typeof node.__listeners[key].branch.then==="function"){ret=node.__listeners[key].branch.then(ret)}else if(node.__listeners[key].branch.then instanceof GraphNode&&node.__listeners[key].branch.then.__operator){ret=node.__listeners[key].branch.then.__operator(ret)}else ret=node.__listeners[key].branch.then};if(typeof node.__listeners[key].branch.if==="function"){if(node.__listeners[key].branch.if(ret)){triggered()}}else if(node.__listeners[key].branch.if===ret){triggered()}return fn(ret)}}}}}};var triggerListenerOncreate=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(node.__listeners[key].oncreate){node.__listeners[key].callback(node.__listeners[key].oncreate)}}}}};var bindListener=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(typeof node.__listeners[key].binding==="object"){node.__listeners.callback=node.__listeners.callback.bind(node.__listeners[key].binding)}}}}};var transformListenerResult=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(typeof node.__listeners[key].transform==="function"&&!node.__listeners[key].transformApplied){let fn=node.__listeners[key].callback;node.__listeners[key].transformApplied=true;node.__listeners.callback=ret=>{ret=node.__listeners[key].transform(ret);return fn(ret)}}}}}};var substitute__operator=(node,parent,graph)=>{if(node.post&&!node.__operator){node.__setOperator(node.post)}else if(!node.__operator&&typeof node.get=="function"){node.__setOperator(node.get)}if(!node.get&&node.__operator){node.get=node.__operator}if(node.aliases){node.aliases.forEach(a=>{graph.set(a,node);let ondelete=node2=>{graph.__node.nodes.delete(a)};node.__addOndisconnected(ondelete)})}if(typeof graph.__node.roots?.[node.__node.tag]==="object"&&node.get)graph.__node.roots[node.__node.tag].get=node.get};var loaders={backprop,loop,animate,branching,triggerListenerOncreate,bindListener,transformListenerResult,substitute__operator};var Service=class extends Graph{constructor(options){super({...options,loaders:options?.loaders?Object.assign({...loaders},options.loaders):{...loaders}});this.name=`service${Math.floor(Math.random()*1e15)}`;this.addServices=services=>{for(const s in services){if(typeof services[s]==="function")services[s]=new services[s];if(services[s]?.__node?.loaders)Object.assign(this.__node.loaders,services[s].__node.loaders);if(services[s]?.__node?.nodes){services[s].__node.nodes.forEach((n,tag)=>{if(!this.get(tag)){this.set(tag,n)}else this.set(s+"."+tag,n)});this.__node.nodes.forEach((n,k)=>{if(!services[s].__node.nodes.get(k))services[s].__node.nodes.set(k,n)});let set=this.set;this.set=(tag,node)=>{services[s].set(tag,node);return set(tag,node)};let del=this.delete;this.delete=tag=>{services[s].delete(tag);return del(tag)}}else if(typeof services[s]==="object"){this.load(services[s])}}};this.handleMethod=(route,method,args)=>{let m=method.toLowerCase();let src=this.__node.nodes.get(route);if(!src){src=this.__node.roots[route]}if(src?.[m]){if(typeof src[m]!=="function"){if(args){if(Array.isArray(args)&&args.length===1)src[m]=args[0];else src[m]=args;return}return src[m]}else{if(Array.isArray(args))return src[m](...args);else return src[m](args)}}else return this.handleServiceMessage({route,args,method})};this.transmit=(...args)=>{if(typeof args[0]==="object"){if(args[0].method){return this.handleMethod(args[0].route,args[0].method,args[0].args)}else if(args[0].route){return this.handleServiceMessage(args[0])}else if(args[0].node){return this.handleGraphNodeCall(args[0].node,args[0].args)}else if(this.__node.keepState){if(args[0].route)this.setState({[args[0].route]:args[0].args});if(args[0].node)this.setState({[args[0].node]:args[0].args})}return args}else return args};this.receive=(...args)=>{if(args[0]){if(typeof args[0]==="string"){let substr=args[0].substring(0,8);if(substr.includes("{")||substr.includes("[")){if(substr.includes("\\"))args[0]=args[0].replace(/\\/g,"");if(args[0][0]==='"'){args[0]=args[0].substring(1,args[0].length-1)};args[0]=JSON.parse(args[0])}}}if(typeof args[0]==="object"){if(args[0].method){return this.handleMethod(args[0].route,args[0].method,args[0].args)}else if(args[0].route){return this.handleServiceMessage(args[0])}else if(args[0].node){return this.handleGraphNodeCall(args[0].node,args[0].args)}else if(this.__node.keepState){if(args[0].route)this.setState({[args[0].route]:args[0].args});if(args[0].node)this.setState({[args[0].node]:args[0].args})}return args}else return args};this.pipe=(source,destination,endpoint,method,callback)=>{if(source instanceof GraphNode){if(callback)return this.subscribe(source,res=>{let mod=callback(res);if(mod!==void 0)this.transmit({route:destination,args:mod,method});else this.transmit({route:destination,args:res,method},endpoint)});else return this.subscribe(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})}else if(typeof source==="string")return this.subscribe(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})};this.pipeOnce=(source,destination,endpoint,method,callback)=>{if(source instanceof GraphNode){if(callback)return source.__node.state.subscribeEventOnce(source.__node.unique,res=>{let mod=callback(res);if(mod!==void 0)this.transmit({route:destination,args:mod,method});else this.transmit({route:destination,args:res,method},endpoint)});else return this.__node.state.subscribeEventOnce(source.__node.unique,res=>{this.transmit({route:destination,args:res,method},endpoint)})}else if(typeof source==="string")return this.__node.state.subscribeEventOnce(this.__node.nodes.get(source).__node.unique,res=>{this.transmit({route:destination,args:res,method},endpoint)})};this.terminate=(...args)=>{};this.isTypedArray=isTypedArray;this.recursivelyAssign=recursivelyAssign2;this.spliceTypedArray=spliceTypedArray;this.ping=()=>{console.log("pinged!");return"pong"};this.echo=(...args)=>{this.transmit(...args);return args};if(options?.services)this.addServices(options.services);this.load(this)}handleServiceMessage(message){let call;if(typeof message==="object"){if(message.route)call=message.route;else if(message.node)call=message.node}if(call){if(Array.isArray(message.args))return this.run(call,...message.args);else return this.run(call,message.args)}else return message}handleGraphNodeCall(route,args){if(!route)return args;if(args?.args){this.handleServiceMessage(args)}else if(Array.isArray(args))return this.run(route,...args);else return this.run(route,args)}};function isTypedArray(x2){return ArrayBuffer.isView(x2)&&Object.prototype.toString.call(x2)!=="[object DataView]"}var recursivelyAssign2=(target,obj)=>{for(const key in obj){if(obj[key]?.constructor.name==="Object"&&!Array.isArray(obj[key])){if(target[key]?.constructor.name==="Object"&&!Array.isArray(target[key]))recursivelyAssign2(target[key],obj[key]);else target[key]=recursivelyAssign2({},obj[key])}else target[key]=obj[key]}return target};function spliceTypedArray(arr,start,end){let s=arr.subarray(0,start);let e;if(end){e=arr.subarray(end+1)}let ta;if(s.length>0||e?.length>0)ta=new arr.constructor(s.length+e.length);if(ta){if(s.length>0)ta.set(s);if(e&&e.length>0)ta.set(e,s.length)}return ta}var import_web_worker=__toESM(require_browser());var WorkerService=class extends Service{constructor(options){super();this.name="worker";this.workers={};this.threadRot=0;this.loadWorkerRoute=(rt,routeKey)=>{if(rt.workerUrl)rt.url=rt.workerUrl;if(rt.workerId)rt.__node.tag=rt.workerId;if(!rt.__node.tag)rt.__node.tag=routeKey;rt._id=rt.__node.tag;let worker;if(this.workers[rt._id])worker=this.workers[rt._id];else if(rt.worker)worker=rt.worker;if(!worker){worker=this.addWorker(rt)}rt.worker=worker;if(!rt.worker.__ondisconnected){let ondelete=rt2=>{rt2.worker?.terminate()};rt.__addOndisconnected(ondelete)}if(rt.transferFunctions){for(const prop in rt.transferFunctions){this.transferFunction(worker,rt.transferFunctions[prop],prop)}}if(rt.transferClasses){for(const prop in rt.transferClasses){this.transferClass(worker,rt.transferClasses[prop],prop)}}if(worker){if(!rt.__operator){rt.__operator=(...args)=>{if(rt.callback){if(!this.__node.nodes.get(rt.__node.tag)?.__children)worker.post(rt.callback,args);else return worker.run(rt.callback,args)}else{if(!this.__node.nodes.get(rt.__node.tag)?.__children)worker.send(args);else return worker.request(args)}}}if(rt.init){worker.run(rt.init,rt.initArgs,void 0,rt.initTransfer)}return worker}};this.workerloader={"workers":(node,parent,graph,roots)=>{let rt=node;if(!node.parentRoute&&(parent?.callback&&parent?.worker))node.parentRoute=parent?.callback;if(rt?.worker||rt?.workerId||rt?.workerUrl){let worker=this.loadWorkerRoute(rt,rt.__node.tag);if(worker){if(!rt.parentRoute&&rt.__parent?.callback)rt.parentRoute=rt.__parent.callback;if(rt.__parent&&!rt.portId){if(typeof rt.__parent==="string"){if(rt.__node.tag!==rt.__parent&&worker._id!==rt.__parent)rt.portId=this.establishMessageChannel(worker,rt.__parent)}else if(rt.__node.tag!==rt.__parent?.__node?.tag&&worker._id!==rt.__parent?.tag){rt.portId=this.establishMessageChannel(worker,rt.__parent.worker)}};if(rt.parentRoute){if(!rt.stopped){if(typeof rt.__parent==="string"&&rt.__parent===worker._id){worker.run("subscribe",[rt.parentRoute,void 0,void 0,rt.callback])}else if(rt.__node.tag===rt.__parent?.__node?.tag||worker._id===rt.__parent?.__node?.tag){worker.run("subscribe",[rt.parentRoute,void 0,void 0,rt.callback])}else worker.run("subscribeToWorker",[rt.parentRoute,rt.portId,void 0,rt.callback,void 0,void 0,rt.blocking]).then(sub=>{worker.workerSubs[rt.parentRoute+rt.portId].sub=sub})}if(!(typeof rt.__parent==="string"&&rt.__parent===worker._id)&&!(rt.__node.tag===rt.__parent?.__node?.tag||worker._id===rt.__parent?.__node?.tag))worker.workerSubs[rt.parentRoute+rt.portId]={sub:null,route:rt.parentRoute,portId:rt.portId,callback:rt.callback,blocking:rt.blocking}}else if(rt.__parent){if(typeof rt.__parent==="string"){if(!rt.stopped){if(rt.__parent===worker._id){worker.run("subscribe",[rt.__parent,void 0,rt.callback])}else worker.run("subscribeToWorker",[rt.__parent,rt.portId,void 0,rt.callback,void 0,void 0,rt.blocking]).then(sub=>{worker.workerSubs[rt.__parent+rt.portId].sub=sub})}if(!(typeof rt.__parent==="string"&&rt.__parent===worker._id))worker.workerSubs[rt.__parent+rt.portId]={sub:null,route:worker._id,portId:rt.portId,callback:rt.callback,blocking:rt.blocking}}else if(rt.__parent?.__node?.tag&&rt.__parent?.worker){if(!rt.stopped){if(rt.__node.tag===rt.__parent.__node.tag||worker._id===rt.__parent.__node.tag){worker.run("subscribe",[rt.__parent.__node.tag,void 0,void 0,rt.callback])}else worker.run("subscribeToWorker",[rt.__parent.__node.tag,rt.portId,void 0,rt.callback,void 0,void 0,rt.blocking]).then(sub=>{worker.workerSubs[rt.__parent.__node.tag+rt.portId].sub=sub})}if(!(rt.__node.tag===rt.__parent?.__node?.tag||worker._id===rt.__parent?.__node?.tag))worker.workerSubs[rt.__parent.__node.tag+rt.portId]={sub:null,route:rt.__parent.__node.tag,portId:rt.portId,callback:rt.callback,blocking:rt.blocking}}}}}else if(rt.__parent&&rt.parentRoute){if(typeof rt.__parent==="string"&&roots[rt.__parent]?.worker){roots[rt.__parent].worker.subscribe(rt.parentRoute,rt.__operator,void 0,void 0,void 0,rt.blocking)}else if(rt.__parent?.worker){rt.__parent.worker.subscribe(rt.parentRoute,rt.__operator,void 0,void 0,void 0,rt.blocking)}}return rt}};this.addDefaultMessageListener=()=>{globalThis.onmessage=ev2=>{let result=this.receive(ev2.data);if(this.__node.keepState)this.setState({[this.name]:result})}};this.postMessage=(message,target,transfer)=>{if(this.workers[target]){this.workers[target].send(message,transfer)}else{globalThis.postMessage(message,target,transfer)}};this.addWorker=options=>{let worker;if(!options._id)options._id=`worker${Math.floor(Math.random()*1e15)}`;if(options.url)worker=new import_web_worker.default(options.url);else if(options.port){worker=options.port}else if(this.workers[options._id]){if(this.workers[options._id].port)worker=this.workers[options._id].port;else worker=this.workers[options._id].worker}if(!worker)return;let send=(message,transfer)=>{return this.transmit(message,worker,transfer)};let post=(route,args,method,transfer)=>{let message={route,args};if(method)message.method=method;return this.transmit(message,worker,transfer)};let run=(route,args,method,transfer)=>{return new Promise((res,rej)=>{let callbackId=Math.random();let req={route:"runRequest",args:[{route,args},options._id,callbackId]};if(method)req.args[0].method=method;let onmessage=ev2=>{if(typeof ev2.data==="object"){if(ev2.data.callbackId===callbackId){worker.removeEventListener("message",onmessage);res(ev2.data.args)}}};worker.addEventListener("message",onmessage);this.transmit(req,worker,transfer)})};let request=(message,method,transfer)=>{return new Promise((res,rej)=>{let callbackId=Math.random();let req={route:"runRequest",args:[message,options._id,callbackId]};if(method)req.method=method;let onmessage=ev2=>{if(typeof ev2.data==="object"){if(ev2.data.callbackId===callbackId){worker.removeEventListener("message",onmessage);res(ev2.data.args)}}};worker.addEventListener("message",onmessage);this.transmit(req,worker,transfer)})};let workerSubs={};let subscribe=(route,callback,args,key,subInput,blocking)=>{return this.subscribeToWorker(route,options._id,callback,args,key,subInput,blocking)};let unsubscribe=(route,sub)=>{return run("unsubscribe",[route,sub])};let start=async(route,portId,callback,blocking)=>{if(route)await run("subscribeToWorker",[route,portId,void 0,callback,blocking]).then(sub=>{if(sub)workerSubs[route+portId]={sub,route,portId,callback,blocking}});else for(const key in workerSubs){if(typeof workerSubs[key].sub!=="number")await run("subscribeToWorker",[workerSubs[key].route,workerSubs[key].portId,void 0,workerSubs[key].callback,void 0,workerSubs[key].blocking]).then(sub=>{workerSubs[key].sub=sub});console.log(JSON.stringify(workerSubs))}return true};let stop=async(route,portId)=>{if(route&&portId&&workerSubs[route+portId]){await run("unsubscribe",[route,workerSubs[route+portId].sub]);workerSubs[route+portId].sub=false}else{for(const key in workerSubs){if(typeof workerSubs[key].sub==="number"){await run("unpipeWorkers",[workerSubs[key].route,workerSubs[key].portId,workerSubs[key].sub]).then(console.log)}workerSubs[key].sub=false}}return true};let terminate=()=>{for(const key in workerSubs){if(typeof workerSubs[key].sub==="number"){run("unpipeWorkers",[workerSubs[key].route,workerSubs[key].portId,workerSubs[key].sub])}workerSubs[key].sub=false}return this.terminate(options._id)};if(!options.onmessage)options.onmessage=ev2=>{this.receive(ev2.data);this.setState({[options._id]:ev2.data})};if(!options.onerror){options.onerror=ev2=>{console.error(ev2.data)}}worker.onmessage=options.onmessage;worker.onerror=options.onerror;this.workers[options._id]={worker,send,post,run,request,subscribe,unsubscribe,terminate,start,stop,postMessage:worker.postMessage,workerSubs,graph:this,...options};return this.workers[options._id]};this.open=this.addWorker;this.toObjectURL=scriptTemplate=>{let blob=new Blob([scriptTemplate],{type:"text/javascript"});return URL.createObjectURL(blob)};this.transmit=(message,worker,transfer)=>{if(!transfer){transfer=this.getTransferable(message)}if(worker instanceof import_web_worker.default||worker instanceof MessagePort){worker.postMessage(message,transfer)}else if(typeof worker==="string"){if(this.workers[worker]){if(this.workers[worker].port)this.workers[worker].port.postMessage(message,transfer);else if(this.workers[worker].worker)this.workers[worker].worker.postMessage(message,transfer)}}else{let keys2=Object.keys(this.workers);this.workers[keys2[this.threadRot]].worker.postMessage(message,transfer);this.threadRot++;if(this.threadRot===keys2.length)this.threadRot=0}return message};this.terminate=worker=>{let onclose;if(typeof worker==="string"){let obj=this.workers[worker];if(obj){delete this.workers[worker];worker=obj.worker;if(obj.onclose)onclose=obj.onclose}}else if(typeof worker==="object"){if(worker?._id){worker=worker.worker;delete this.workers[worker?._id]}}if(worker instanceof import_web_worker.default){worker.terminate();if(onclose)onclose(worker);return true}if(worker instanceof MessagePort){worker.close();if(onclose)onclose(worker);return true}return false};this.establishMessageChannel=(worker,worker2)=>{let workerId;if(typeof worker==="string"){workerId=worker;if(this.workers[worker]){if(this.workers[worker].port)worker=this.workers[worker].port;else worker2=this.workers[worker].worker}}else if(worker?.worker){worker=worker.worker}if(typeof worker2==="string"){if(this.workers[worker2]){if(this.workers[worker2].port)worker2=this.workers[worker2].port;else worker2=this.workers[worker2].worker}}else if(worker2?.worker){worker2=worker2.worker}if(worker instanceof import_web_worker.default||worker instanceof MessagePort){let channel=new MessageChannel;let portId=`port${Math.floor(Math.random()*1e15)}`;worker.postMessage({route:"addWorker",args:{port:channel.port1,_id:portId}},[channel.port1]);if(worker2 instanceof import_web_worker.default||worker2 instanceof MessagePort){worker2.postMessage({route:"addWorker",args:{port:channel.port2,_id:portId}},[channel.port2])}else if(workerId&&this.workers[workerId]){channel.port2.onmessage=this.workers[workerId].onmessage;this.workers[workerId].port=channel.port2}return portId}return false};this.request=(message,workerId,transfer,method)=>{let worker=this.workers[workerId].worker;return new Promise((res,rej)=>{let callbackId=Math.random();let req={route:"runRequest",args:[message,callbackId]};if(method)req.method=method;let onmessage=ev2=>{if(typeof ev2.data==="object"){if(ev2.data.callbackId===callbackId){worker.removeEventListener("message",onmessage);res(ev2.data.args)}}};worker.addEventListener("message",onmessage);this.transmit(req,worker,transfer)})};this.runRequest=(message,worker,callbackId)=>{let res=this.receive(message);if(typeof worker==="string"&&this.workers[worker]){if(this.workers[worker].port)worker=this.workers[worker].port;else worker=this.workers[worker].worker}if(res instanceof Promise){res.then(r=>{if(worker instanceof import_web_worker.default||worker instanceof MessagePort)worker.postMessage({args:r,callbackId});else if(typeof WorkerGlobalScope!=="undefined"&&self instanceof WorkerGlobalScope)globalThis.postMessage({args:r,callbackId})})}else{if(worker instanceof import_web_worker.default||worker instanceof MessagePort)worker.postMessage({args:res,callbackId});else if(typeof WorkerGlobalScope!=="undefined"&&self instanceof WorkerGlobalScope)globalThis.postMessage({args:res,callbackId})}return res};this.subscribeWorker=(route,worker,args,key,subInput,blocking)=>{let callback;if(blocking){let blocked=false;callback=res=>{if(!blocked){blocked=true;if(res instanceof Promise){res.then(r=>{if(worker?.run)worker.run("triggerSubscription",[route,worker._id,r]).then(ret=>{blocked=false})})}else{if(worker?.run)worker.run("triggerSubscription",[route,worker._id,res]).then(ret=>{blocked=false})}}}}else{callback=res=>{if(res instanceof Promise){res.then(r=>{if(worker?.postMessage)worker.postMessage({args:r,callbackId:route});else if(globalThis.postMessage)globalThis.postMessage({args:r,callbackId:route})})}else{if(worker?.postMessage)worker.postMessage({args:res,callbackId:route});else if(globalThis.postMessage)globalThis.postMessage({args:res,callbackId:route})}}}if(!blocking&&worker?.port){worker=worker.port}else if(!blocking&&worker?.worker){worker=worker.worker}else if(typeof worker==="string"&&this.workers[worker]){if(blocking)worker=this.workers[worker];else if(this.workers[worker].port)worker=this.workers[worker].port;else worker=this.workers[worker].worker}return this.subscribe(route,callback,args,key,subInput)};this.subscribeToWorker=(route,workerId,callback,args,key,subInput,blocking)=>{if(typeof workerId==="string"&&this.workers[workerId]){this.__node.state.subscribeEvent(workerId,res=>{if(res?.callbackId===route){if(!callback)this.setState({[workerId]:res.args});else if(typeof callback==="string"){this.run(callback,res.args)}else callback(res.args)}});return this.workers[workerId].run("subscribeWorker",[route,workerId,args,key,subInput,blocking])}};this.triggerSubscription=async(route,workerId,result)=>{if(this.__node.state.triggers[workerId])for(let i2=0;i2{if(typeof sourceWorker==="string")sourceWorker=this.workers[sourceWorker];if(typeof listenerWorker==="string")listenerWorker=this.workers[listenerWorker];if(!portId){portId=this.establishMessageChannel(sourceWorker.worker,listenerWorker.worker)}return listenerWorker.run("subscribeToWorker",[sourceRoute,portId,listenerRoute,args,key,subInput,blocking])};this.unpipeWorkers=(sourceRoute,sourceWorker,sub)=>{if(typeof sourceWorker==="string")sourceWorker=this.workers[sourceWorker];if(typeof sourceWorker==="object"){return sourceWorker.run("unsubscribe",[sourceRoute,sub])}};this.connections={workers:this.workers};if(options?.services)this.addServices(options.services);this.load(this);this.setLoaders(this.workerloader);if(options)this.init(options);if(typeof WorkerGlobalScope!=="undefined"&&globalThis instanceof WorkerGlobalScope){this.addDefaultMessageListener()}}getTransferable(message){let transfer;if(typeof message==="object"){if(message.args){if(message.args?.constructor?.name==="Object"){for(const key in message.args){if(ArrayBuffer.isView(message.args[key])){if(!transfer)transfer=[message.args[key].buffer];else transfer.push(message.args[key].buffer)}else if(message.args[key]?.constructor?.name==="ArrayBuffer"){if(!transfer)transfer=[message.args[key]];else transfer.push(message.args[key])}}}else if(Array.isArray(message.args)&&message.args.length<11){message.args.forEach(arg=>{if(ArrayBuffer.isView(arg)){transfer=[arg.buffer]}else if(arg?.constructor?.name==="ArrayBuffer")transfer=[arg]})}else if(ArrayBuffer.isView(message.args)){transfer=[message.args.buffer]}else if(message.args?.constructor?.name==="ArrayBuffer"){transfer=[message]}}else if(message?.constructor?.name==="Object"){for(const key in message){if(ArrayBuffer.isView(message[key])){if(!transfer)transfer=[message[key].buffer];else transfer.push(message[key].buffer)}else if(message[key]?.constructor?.name==="ArrayBuffer"){if(!transfer)transfer=[message[key]];else transfer.push(message[key])}}}else if(Array.isArray(message)&&message.length<11){message.forEach(arg=>{if(ArrayBuffer.isView(arg)){transfer=[arg.buffer]}else if(arg.constructor?.name==="ArrayBuffer")transfer=[arg]})}else if(ArrayBuffer.isView(message)){transfer=[message.buffer]}else if(message.constructor?.name==="ArrayBuffer"){transfer=[message]}}return transfer}};var mouseEventHandler=makeSendPropertiesHandler(["ctrlKey","metaKey","altKey","shiftKey","button","which","pointerType","clientX","clientY","pageX","pageY","movementX","movementY","x","y","which","timeStamp"]);var wheelEventHandlerImpl=makeSendPropertiesHandler(["deltaX","deltaY"]);var keydownEventHandler=makeSendPropertiesHandler(["ctrlKey","metaKey","shiftKey","altKey","isComposing","keyCode","key","code","repeat","timeStamp"]);function focusEventHandler(event,sendFn){const data={type:event.type};data.isTrusted=event.isTrusted;data.bubbles=event.bubbles;data.cancelBubble=event.cancelBubble;data.cancelable=event.cancelable;data.composed=event.composed;data.defaultPrevent=event.defaultPrevented;data.eventPhase=event.eventPhase;data.returnValue=event.returnValue;data.currentTarget=event.currentTarget.id?event.currentTarget.id:event.currentTarget.constructor.name;data.target=data.currentTarget;data.srcElement=data.currentTarget;sendFn(data)}function wheelEventHandler(event,sendFn){if(event.preventDefault)event.preventDefault();wheelEventHandlerImpl(event,sendFn)}function preventDefaultHandler(event){if(event.preventDefault)event.preventDefault()}function copyProperties(src,properties,dst){for(const name2 of properties){dst[name2]=src[name2]}}function makeSendPropertiesHandler(properties){return function sendProperties(event,sendFn){const data={type:event.type};copyProperties(event,properties,data);sendFn(data)}}function touchEventHandler(event,sendFn){const touches=[];const data={type:event.type,touches};for(let i2=0;i2123))event.preventDefault();keydownEventHandler(event,sendFn)}}var eventHandlers={contextmenu:preventDefaultHandler,mousedown:mouseEventHandler,mousemove:mouseEventHandler,mouseup:mouseEventHandler,pointerdown:mouseEventHandler,pointermove:mouseEventHandler,pointerup:mouseEventHandler,pointerlockchange:mouseEventHandler,webkitpointerlockchange:mouseEventHandler,focus:focusEventHandler,blur:focusEventHandler,pointerout:mouseEventHandler,touchstart:touchEventHandler,touchmove:touchEventHandler,touchend:touchEventHandler,wheel:wheelEventHandler,keydown:filteredKeydownEventHandler,keyup:filteredKeydownEventHandler};function initProxyElement(element,worker,id){if(!id)id="proxy"+Math.floor(Math.random()*1e15);const sendEvent=data=>{if(!worker){handleProxyEvent(data,id)}else worker.postMessage({route:"handleProxyEvent",args:[data,id]})};let entries=Object.entries(eventHandlers);for(const[eventName,handler]of entries){element.addEventListener(eventName,function(event){handler(event,sendEvent)})}if(eventHandlers.keydown){globalThis.addEventListener("keydown",function(ev2){eventHandlers.keydown(ev2,sendEvent)})}if(eventHandlers.keyup){globalThis.addEventListener("keyup",function(ev2){eventHandlers.keyup(ev2,sendEvent)})}const sendSize=()=>{const rect=element.getBoundingClientRect();sendEvent({type:"resize",left:rect.left,top:rect.top,width:element.clientWidth,height:element.clientHeight})};sendSize();globalThis.addEventListener("resize",sendSize);return id}var EventDispatcher=class{addEventListener(type,listener){if(this.__listeners===void 0)this.__listeners={};const listeners=this.__listeners;if(listeners[type]===void 0){listeners[type]=[]}if(listeners[type].indexOf(listener)===-1){listeners[type].push(listener)}}hasEventListener(type,listener){if(this.__listeners===void 0)return false;const listeners=this.__listeners;return listeners[type]!==void 0&&listeners[type].indexOf(listener)!==-1}removeEventListener(type,listener){if(this.__listeners===void 0)return;const listeners=this.__listeners;const listenerArray=listeners[type];if(listenerArray!==void 0){const index=listenerArray.indexOf(listener);if(index!==-1){listenerArray.splice(index,1)}}}dispatchEvent(event,target){if(this.__listeners===void 0)return;const listeners=this.__listeners;const listenerArray=listeners[event.type];if(listenerArray!==void 0){if(!target)event.target=this;else event.target=target;const array=listenerArray.slice(0);for(let i2=0,l=array.length;i2{};this.releasePointerCapture=()=>{};this.getBoundingClientRect=()=>{return{left:this.left,top:this.top,width:this.width,height:this.height,right:this.left+this.width,bottom:this.top+this.height}};this.handleEvent=data=>{if(data.type==="resize"){this.left=data.left;this.top=data.top;this.width=data.width;this.height=data.height;if(typeof this.proxied==="object"){this.proxied.style.width=this.width+"px";this.proxied.style.height=this.height+"px";this.proxied.clientWidth=this.width;this.proxied.clientHeight=this.height}}data.preventDefault=noop;data.stopPropagation=noop;this.dispatchEvent(data,this.proxied)};this.style={}}get clientWidth(){return this.width}get clientHeight(){return this.height}focus(){}blur(){}};var ProxyManager=class{constructor(){this.targets={};this.makeProxy=(id,addTo=void 0)=>{if(!id)id=`proxyReceiver${Math.floor(Math.random()*1e15)}`;let proxy;if(this.targets[id])proxy=this.targets[id];else{proxy=new ElementProxyReceiver;this.targets[id]=proxy}if(typeof addTo==="object"){addTo.proxy=proxy;proxy.proxied=addTo;if(typeof WorkerGlobalScope!=="undefined")addTo.style=proxy.style;if(proxy.width){addTo.style.width=proxy.width+"px";addTo.clientWidth=proxy.width}if(proxy.height){addTo.style.height=proxy.height+"px";addTo.clientHeight=proxy.height}addTo.setPointerCapture=proxy.setPointerCapture.bind(proxy);addTo.releasePointerCapture=proxy.releasePointerCapture.bind(proxy);addTo.getBoundingClientRect=proxy.getBoundingClientRect.bind(proxy);addTo.addEventListener=proxy.addEventListener.bind(proxy);addTo.removeEventListener=proxy.removeEventListener.bind(proxy);addTo.handleEvent=proxy.handleEvent.bind(proxy);addTo.dispatchEvent=proxy.dispatchEvent.bind(proxy);addTo.focus=proxy.focus.bind(proxy);addTo.blur=proxy.blur.bind(proxy)}};this.getProxy=id=>{return this.targets[id]};this.handleEvent=(data,id)=>{if(!this.targets[id])this.makeProxy(id);if(this.targets[id]){this.targets[id].handleEvent(data);return true}return void 0};if(!globalThis.document)globalThis.document={elementFromPoint:(...args)=>{return this.targets[Object.keys(this.targets)[0]].proxied}}}};function makeProxy(id,elm){if(this?.__node?.graph){if(!this.__node.graph.ProxyManager)this.__node.graph.ProxyManager=new ProxyManager;this.__node.graph.ProxyManager.makeProxy(id,elm)}else{if(!globalThis.ProxyManager)globalThis.ProxyManager=new ProxyManager;globalThis.ProxyManager.makeProxy(id,elm)}return id}function handleProxyEvent(data,id){if(this?.__node?.graph){if(!this.__node.graph.ProxyManager)this.__node.graph.ProxyManager=new ProxyManager;if(this.__node.graph.ProxyManager.handleEvent(data,id))return data}else{if(!globalThis.ProxyManager)globalThis.ProxyManager=new ProxyManager;if(globalThis.ProxyManager.handleEvent(data,id))return data}}var proxyElementWorkerRoutes={initProxyElement,makeProxy,handleProxyEvent};function Renderer(options){if(options.worker){let worker=options.worker;let route=options.route;if(worker instanceof Blob||typeof worker==="string"){worker=new Worker(worker)}delete options.worker;delete options.route;return transferCanvas(worker,options,route)}else{initProxyElement(options.canvas,void 0,options._id);return setupCanvas(options)}}function transferCanvas(worker,options,route){console.log(options);if(!options)return void 0;if(!options._id)options._id=`canvas${Math.floor(Math.random()*1e15)}`;let offscreen=options.canvas.transferControlToOffscreen();if(!options.width)options.width=options.canvas.clientWidth;if(!options.height)options.height=options.canvas.clientHeight;let message={route:route?route:"setupCanvas",args:{...options,canvas:offscreen}};if(this?.__node?.graph)this.__node.graph.run("initProxyElement",options.canvas,worker,options._id);else initProxyElement(options.canvas,worker,options._id);if(options.draw){if(typeof options.draw==="function")message.args.draw=options.draw.toString();else message.args.draw=options.draw}if(options.update){if(typeof options.update==="function")message.args.update=options.update.toString();else message.args.update=options.update}if(options.init){if(typeof options.init==="function")message.args.init=options.init.toString();else message.args.init=options.init}if(options.clear){if(typeof options.clear==="function")message.args.clear=options.clear.toString();else message.args.clear=options.clear}let tr=[offscreen];if(options.transfer){tr.push(...options.transfer);delete options.transfer}worker.postMessage(message,tr);const canvascontrols={_id:options._id,width:options.width,height:options.height,worker,draw:(props,transfer)=>{worker.postMessage({route:"drawFrame",args:[props,options._id]},transfer)},update:(props,transfer)=>{worker.postMessage({route:"updateCanvas",args:[props,options._id]},transfer)},clear:()=>{worker.postMessage({route:"clearCanvas",args:options._id})},init:()=>{worker.postMessage({route:"initCanvas",args:options._id})},stop:()=>{worker.postMessage({route:"stopAnim",args:options._id})},start:()=>{worker.postMessage({route:"startAnim",args:options._id})},set:(newDrawProps,transfer)=>{worker.postMessage({route:"setDraw",args:[newDrawProps,options._id]},transfer)},terminate:()=>{worker.terminate()}};return canvascontrols}function setDraw(settings,_id){let canvasopts;if(this?.__node?.graph){if(_id)canvasopts=this.__node.graph.CANVASES?.[settings._id];else if(settings._id)canvasopts=this.__node.graph.CANVASES?.[settings._id];else canvasopts=this.__node.graph.CANVASES?.[Object.keys(this.__node.graph.CANVASES)[0]]}else{if(_id)canvasopts=globalThis.CANVASES?.[settings._id];else if(settings._id)canvasopts=globalThis.CANVASES?.[settings._id];else canvasopts=globalThis.CANVASES?.[Object.keys(globalThis.CANVASES)[0]]}if(canvasopts){if(settings.canvas){canvasopts.canvas=settings.canvas;if(this?.__node?.graph)this.__node.graph.run("makeProxy",canvasopts._id,canvasopts.canvas);else proxyElementWorkerRoutes.makeProxy(canvasopts._id,canvasopts.canvas)}if(typeof settings.context==="string")canvasopts.context=canvasopts.canvas.getContext(settings.context);else if(settings.context)canvasopts.context=settings.context;if(settings.width)canvasopts.canvas.width=settings.width;if(settings.height)canvasopts.canvas.height=settings.height;if(typeof settings.draw==="string")settings.draw=parseFunctionFromText(settings.draw);if(typeof settings.draw==="function"){canvasopts.draw=settings.draw.bind(settings)}if(typeof settings.update==="string")settings.update=parseFunctionFromText(settings.update);if(typeof settings.update==="function"){canvasopts.update=settings.update.bind(settings)}if(typeof settings.init==="string")settings.init=parseFunctionFromText(settings.init);if(typeof settings.init==="function"){canvasopts.init=settings.init.bind(settings)}if(typeof settings.clear==="string")settings.clear=parseFunctionFromText(settings.clear);if(typeof settings.clear==="function"){canvasopts.clear=settings.clear.bind(settings)}return settings._id}return void 0}function setupCanvas(options){if(this?.__node?.graph){if(!this.__node.graph.CANVASES)this.__node.graph.CANVASES={}}else if(!globalThis.CANVASES)globalThis.CANVASES={};let canvasOptions=options;options._id?canvasOptions._id=options._id:canvasOptions._id=`canvas${Math.floor(Math.random()*1e15)}`;typeof options.context==="string"?canvasOptions.context=options.canvas.getContext(options.context):canvasOptions.context=options.context;"animating"in options?canvasOptions.animating=options.animating:canvasOptions.animating=true;if(this?.__node?.graph?.CANVASES[canvasOptions._id]){this.__node.graph.run("setDraw",canvasOptions)}else if(globalThis.CANVASES?.[canvasOptions._id]){setDraw(canvasOptions)}else{if(this?.__node?.graph){canvasOptions.graph=this.__node.graph;if(!canvasOptions.__node){canvasOptions.__node={}}if(!canvasOptions.__node.tag)canvasOptions.__node.tag=canvasOptions._id;canvasOptions=this.__node.graph.add(canvasOptions);canvasOptions.__addOndisconnected=()=>{canvasOptions.stop();delete this.__node.graph.CANVASES[canvasOptions._id]}}if(this?.__node?.graph)this.__node.graph.CANVASES[canvasOptions._id]=canvasOptions;else globalThis.CANVASES[canvasOptions._id]=canvasOptions;if(this?.__node?.graph)this.__node.graph.run("makeProxy",canvasOptions._id,canvasOptions.canvas);else proxyElementWorkerRoutes.makeProxy(canvasOptions._id,canvasOptions.canvas);if(options.width)canvasOptions.canvas.width=options.width;if(options.height)canvasOptions.canvas.height=options.height;if(typeof canvasOptions.draw==="string"){canvasOptions.draw=parseFunctionFromText(canvasOptions.draw)}else if(typeof canvasOptions.draw==="function"){canvasOptions.draw=canvasOptions.draw.bind(canvasOptions)}if(typeof canvasOptions.update==="string"){canvasOptions.update=parseFunctionFromText(canvasOptions.update)}else if(typeof canvasOptions.update==="function"){canvasOptions.update=canvasOptions.update.bind(canvasOptions)}if(typeof canvasOptions.init==="string"){canvasOptions.init=parseFunctionFromText(canvasOptions.init)}else if(typeof canvasOptions.init==="function"){canvasOptions.init=canvasOptions.init.bind(canvasOptions)}if(typeof canvasOptions.clear==="string"){canvasOptions.clear=parseFunctionFromText(canvasOptions.clear)}else if(typeof canvasOptions.clear==="function"){canvasOptions.clear=canvasOptions.clear.bind(canvasOptions)}if(typeof canvasOptions.init==="function")canvasOptions.init(canvasOptions,canvasOptions.canvas,canvasOptions.context);canvasOptions.stop=()=>{stopAnim(canvasOptions._id)};canvasOptions.start=draw=>{startAnim(canvasOptions._id,draw)};canvasOptions.set=settings=>{setDraw(settings,canvasOptions._id)};if(typeof canvasOptions.draw==="function"&&canvasOptions.animating){let draw=(s,canvas,context)=>{if(s.animating){s.draw(s,canvas,context);requestAnimationFrame(()=>{draw(s,canvas,context)})}};draw(canvasOptions,canvasOptions.canvas,canvasOptions.context)}}if(typeof WorkerGlobalScope!=="undefined"&&self instanceof WorkerGlobalScope)return canvasOptions._id;else{const canvascontrols={_id:options._id,width:options.width,height:options.height,draw:props=>{drawFrame(props,options._id)},update:props=>{updateCanvas(props,options._id)},clear:()=>{clearCanvas(options._id)},init:()=>{initCanvas(options._id)},stop:()=>{stopAnim(options._id)},start:()=>{startAnim(options._id)},set:newDrawProps=>{setDraw(newDrawProps,options._id)},terminate:()=>{if(this.__node?.graph)this.__node.graph.remove(options._id);else{stopAnim(options._id);if(this?.__node?.graph)delete this.__node.graph.CANVASES[canvasOptions._id];else delete globalThis.CANVASES[canvasOptions._id]}}};return canvascontrols}}function drawFrame(props,_id){let canvasopts=getCanvas.call(this,_id);if(canvasopts){if(props)Object.assign(canvasopts,props);if(canvasopts.draw){canvasopts.draw(canvasopts,canvasopts.canvas,canvasopts.context);return _id}}return void 0}function clearCanvas(_id){let canvasopts=getCanvas.call(this,_id);if(canvasopts?.clear){canvasopts.clear(canvasopts,canvasopts.canvas,canvasopts.context);return _id}return void 0}function initCanvas(_id){let canvasopts=getCanvas.call(this,_id);if(canvasopts?.init){canvasopts.init(canvasopts,canvasopts.canvas,canvasopts.context);return _id}return void 0}function updateCanvas(input,_id){let canvasopts=getCanvas.call(this,_id);if(canvasopts?.update){canvasopts.update(canvasopts,canvasopts.canvas,canvasopts.context,input);return _id}return void 0}function setProps(props,_id){let canvasopts=getCanvas.call(this,_id);if(canvasopts){Object.assign(canvasopts,props);if(props.width)canvasopts.canvas.width=props.width;if(props.height)canvasopts.canvas.height=props.height;return _id}return void 0}function startAnim(_id,draw){let canvasopts=getCanvas.call(this,_id);canvasopts.animating=true;if(canvasopts&&draw){if(typeof draw==="string")draw=parseFunctionFromText(draw);if(typeof draw==="function"){canvasopts.draw=draw}return _id}if(typeof canvasopts?.draw==="function"){let draw2=(s,canvas,context)=>{if(s.animating){s.draw(s,canvas,context);requestAnimationFrame(()=>{draw2(s,canvas,context)})}};if(typeof canvasopts.clear==="function")canvasopts.clear(canvasopts,canvasopts.canvas,canvasopts.context);if(typeof canvasopts.init==="function")canvasopts.init(canvasopts,canvasopts.canvas,canvasopts.context);draw2(canvasopts,canvasopts.canvas,canvasopts.context);return _id}return void 0}function stopAnim(_id){let canvasopts=getCanvas.call(this,_id);if(canvasopts){canvasopts.animating=false;if(typeof canvasopts.clear==="function")requestAnimationFrame(canvasopts.clear(canvasopts,canvasopts.canvas,canvasopts.context));return _id}return void 0}function getCanvas(_id){let canvasopts;if(this?.__node?.graph){if(!_id)canvasopts=this.__node.graph.CANVASES?.[Object.keys(this.__node.graph.CANVASES)[0]];else canvasopts=this.__node.graph.CANVASES?.[_id]}else{if(!_id)canvasopts=globalThis.CANVASES?.[Object.keys(globalThis.CANVASES)[0]];else canvasopts=globalThis.CANVASES?.[_id]}return canvasopts}var workerCanvasRoutes={...proxyElementWorkerRoutes,Renderer,transferCanvas,setupCanvas,setDraw,drawFrame,clearCanvas,initCanvas,updateCanvas,setProps,startAnim,stopAnim,getCanvas};function parseFunctionFromText(method=""){let getFunctionBody=methodString=>{return methodString.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i,"$2$3$4")};let getFunctionHead=methodString=>{let startindex=methodString.indexOf("=>")+1;if(startindex<=0){startindex=methodString.indexOf("){")}if(startindex<=0){startindex=methodString.indexOf(") {")}return methodString.slice(0,methodString.indexOf("{",startindex)+1)};let newFuncHead=getFunctionHead(method);let newFuncBody=getFunctionBody(method);let newFunc;if(newFuncHead.includes("function")){let varName=newFuncHead.split("(")[1].split(")")[0];newFunc=new Function(varName,newFuncBody)}else{if(newFuncHead.substring(0,6)===newFuncBody.substring(0,6)){let varName=newFuncHead.split("(")[1].split(")")[0];newFunc=new Function(varName,newFuncBody.substring(newFuncBody.indexOf("{")+1,newFuncBody.length-1))}else{try{newFunc=(0,eval)(newFuncHead+newFuncBody+"}")}catch{}}}return newFunc}var recursivelyStringifyFunctions=obj=>{let cpy={};for(const key in obj){if(typeof obj[key]==="object"){cpy[key]=recursivelyStringifyFunctions(obj[key])}else if(typeof obj[key]==="function"){cpy[key]=obj[key].toString()}else cpy[key]=obj[key]}return cpy};function parseFunctionFromText2(method=""){let getFunctionBody=methodString=>{return methodString.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i,"$2$3$4")};let getFunctionHead=methodString=>{let startindex=methodString.indexOf("=>")+1;if(startindex<=0){startindex=methodString.indexOf("){")}if(startindex<=0){startindex=methodString.indexOf(") {")}return methodString.slice(0,methodString.indexOf("{",startindex)+1)};let newFuncHead=getFunctionHead(method);let newFuncBody=getFunctionBody(method);let newFunc;if(newFuncHead.includes("function")){let varName=newFuncHead.split("(")[1].split(")")[0];newFunc=new Function(varName,newFuncBody)}else{if(newFuncHead.substring(0,6)===newFuncBody.substring(0,6)){let varName=newFuncHead.split("(")[1].split(")")[0];newFunc=new Function(varName,newFuncBody.substring(newFuncBody.indexOf("{")+1,newFuncBody.length-1))}else{try{newFunc=(0,eval)(method)}catch{}}}return newFunc}var stringifyWithCircularRefs=function(){const refs=new Map;const parents=[];const path=["this"];function clear(){refs.clear();parents.length=0;path.length=1}function updateParents(key,value){var idx=parents.length-1;var prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value||idx===0){path.push(key);parents.push(value.pushed)}else{while(idx-->=0){prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value){idx+=2;parents.length=idx;path.length=idx;--idx;parents[idx]=value;path[idx]=key;break}}idx--}}}}function checkCircular(key,value){if(value!=null){if(typeof value==="object"){if(key){updateParents(key,value)}let other=refs.get(value);if(other){return"[Circular Reference]"+other}else{refs.set(value,path.join("."))}}}return value}return function stringifyWithCircularRefs2(obj,space){try{parents.push(obj);return JSON.stringify(obj,checkCircular,space)}finally{clear()}}}();if(JSON.stringifyWithCircularRefs===void 0){JSON.stringifyWithCircularRefs=stringifyWithCircularRefs}var stringifyFast=function(){const refs=new Map;const parents=[];const path=["this"];function clear(){refs.clear();parents.length=0;path.length=1}function updateParents(key,value){var idx=parents.length-1;if(parents[idx]){var prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value||idx===0){path.push(key);parents.push(value.pushed)}else{while(idx-->=0){prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value){idx+=2;parents.length=idx;path.length=idx;--idx;parents[idx]=value;path[idx]=key;break}}idx++}}}}}function checkValues(key,value){let val;if(value!=null){if(typeof value==="object"){let c=value.constructor.name;if(key&&c==="Object"){updateParents(key,value)}let other=refs.get(value);if(other){return"[Circular Reference]"+other}else{refs.set(value,path.join("."))}if(c==="Array"){if(value.length>20){val=value.slice(value.length-20)}else val=value}else if(c.includes("Set")){val=Array.from(value)}else if(c!=="Object"&&c!=="Number"&&c!=="String"&&c!=="Boolean"){val="instanceof_"+c}else if(c==="Object"){let obj={};for(const prop in value){if(value[prop]==null){obj[prop]=value[prop]}else if(Array.isArray(value[prop])){if(value[prop].length>20)obj[prop]=value[prop].slice(value[prop].length-20);else obj[prop]=value[prop]}else if(value[prop].constructor.name==="Object"){obj[prop]={};for(const p in value[prop]){if(Array.isArray(value[prop][p])){if(value[prop][p].length>20)obj[prop][p]=value[prop][p].slice(value[prop][p].length-20);else obj[prop][p]=value[prop][p]}else{if(value[prop][p]!=null){let con=value[prop][p].constructor.name;if(con.includes("Set")){obj[prop][p]=Array.from(value[prop][p])}else if(con!=="Number"&&con!=="String"&&con!=="Boolean"){obj[prop][p]="instanceof_"+con}else{obj[prop][p]=value[prop][p]}}else{obj[prop][p]=value[prop][p]}}}}else{let con=value[prop].constructor.name;if(con.includes("Set")){obj[prop]=Array.from(value[prop])}else if(con!=="Number"&&con!=="String"&&con!=="Boolean"){obj[prop]="instanceof_"+con}else{obj[prop]=value[prop]}}}val=obj}else{val=value}}else{val=value}}return val}return function stringifyFast2(obj,space){parents.push(obj);let res=JSON.stringify(obj,checkValues,space);clear();return res}}();if(JSON.stringifyFast===void 0){JSON.stringifyFast=stringifyFast}function methodstrings(node){if(typeof node.__methods==="object"){for(const key in node.__methods){let fstr=node.__methods[key];let fn=typeof fstr==="function"?fstr:parseFunctionFromText2(fstr);if(key==="__operator"){node.__setOperator(fn)}else{node[key]=fn.bind(node)}}}}var nodeTemplates={};var remoteGraphRoutes={transferNode:(properties,connection,name2)=>{let str;if(typeof properties==="object"){if(!properties.__node){properties.__node={}}if(name2)properties.__node.tag=name2;for(const key in properties){if(typeof properties[key]==="function"){if(!properties.__methods)properties.__methods={};properties.__methods[key]=properties[key].toString()}}str=recursivelyStringifyFunctions(properties)}else if(typeof properties==="function")str=properties.toString();else if(typeof properties==="string")str=properties;if(str){if(connection.run)return connection.run("setNode",[str]);else if(connection.postMessage){connection.postMessage({route:"setNode",args:str},void 0);return new Promise(r=>r(name2))}else if(connection.send){connection.send(JSON.stringify({route:"setNode",args:str}));return new Promise(r=>r(name2))}}},setNode:function(properties,name2){console.log("setting node",properties);if(typeof properties==="object"){if(properties.__methods){if(!this.__node.graph.__node.loaders.methodstrings){this.__node.graph.__node.loaders.methodstrings=methodstrings}}}if(typeof properties==="string"){let f=parseFunctionFromText2(properties);if(typeof f==="function")properties={__operator:f,__node:{tag:name2?name2:f.name}};else{f=JSON.parse(properties);if(typeof f==="object")properties=f}}if(typeof properties==="object"||typeof properties==="function"){let template={};if(typeof properties==="object")Object.assign(template,properties);else template.__operator=properties;let node=this.__node.graph.add(properties);nodeTemplates[node.__node.tag]=template;return node.__node.tag}else return false},proxyRemoteNode:function(name2,connection){return new Promise((res,rej)=>{connection.run("getNodeProperties",name2).then(props=>{let proxy={};if(typeof props==="object"){for(const key in props){if(props[key]==="function"){proxy[key]=(...args)=>{return new Promise(r=>{connection.run(name2,args,key).then(r)})}}else{Object.defineProperty(proxy,key,{get:()=>{return new Promise(r=>{connection.run(name2,void 0,key).then(r)})},set:value=>{connection.post(name2,value,key)},configurable:true,enumerable:true})}}}res(proxy)})})},makeNodeTransferrable:function(properties,name2){if(!properties.__node){properties.__node={}}if(name2)properties.__node.tag=name2;for(const key in properties){if(typeof properties[key]==="function"){if(!properties.__methods)properties.__methods={};properties.__methods[key]=properties[key].toString()}}const str=recursivelyStringifyFunctions(properties);return str},setTemplate:function(properties,name2){if(typeof properties==="object"){if(properties.__methods){if(!this.__node.graph.__node.loaders.methodstrings){this.__node.graph.__node.loaders.methodstrings=methodstrings}}}if(typeof properties==="string"){let f=parseFunctionFromText2(properties);if(typeof f==="function"){if(!name2)name2=f.name;properties={__operator:f,__node:{tag:name2}}}else{f=JSON.parse(properties);if(typeof f==="object"){properties=f;if(!name2&&f.__node?.tag)name2=f.__node.tag}}}if(!name2)name2=`node${Math.floor(Math.random()*1e15)}`;if(typeof properties==="object"||typeof properties==="function"){nodeTemplates[name2]=properties;return name2}else return false},loadFromTemplate:function(templateName,name2,properties){if(nodeTemplates[templateName]){let cpy=recursivelyAssign2({},nodeTemplates[templateName]);if(name2){if(!cpy.__node)cpy.__node={};cpy.__node.tag=name2}if(properties)Object.assign(cpy,properties);let node=this.__node.graph.add(cpy);return node.__node.tag}},setMethod:function(nodeTag,fn,methodKey){if(typeof fn==="string"){let f=parseFunctionFromText2(fn);if(typeof f==="function")fn=f}if(!methodKey&&typeof fn==="function")methodKey=fn.name;if(this.__node.graph.get(nodeTag)){this.__node.graph.get(nodeTag)[methodKey]=fn}else this.__node.graph.add({__node:{tag:methodKey,[methodKey]:fn}});return true},assignNode:function(nodeTag,source){if(this.__node.graph.get(nodeTag)&&typeof source==="object"){Object.assign(this.__node.graph.get(nodeTag),source)}},getNodeProperties:function(nodeTag){let node=this.__node.graph.get(nodeTag);if(node){let properties=Object.getOwnPropertyNames(node);let result={};for(const key in properties){result[key]=typeof node[key]}return result}return void 0},transferClass:(classObj,connection,className)=>{if(typeof classObj==="object"){let str=classObj.toString();let message={route:"receiveClass",args:[str,className]};if(connection.run)return connection.run("receiveClass",[str,className]);else if(connection.postMessage){connection.postMessage({route:"receiveClass",args:[str,className]},void 0);return new Promise(r=>r(name))}else if(connection.send){connection.send(JSON.stringify({route:"receiveClass",args:[str,className]}));return new Promise(r=>r(name))}return message}return false},receiveClass:function(stringified,className){if(typeof stringified==="string"){if(stringified.indexOf("class")===0){let cls=(0,eval)("("+stringified+")");let name2=className;if(!name2)name2=cls.name;this.__node.graph[name2]=cls;return true}}return false},transferFunction:(fn,connection,fnName)=>{if(!fnName)fnName=fn.name;let str=fn.toString();let message={route:"setNode",args:[str,fnName]};if(connection.run)return connection.run("setNode",[str,fnName]);else if(connection.postMessage){connection.postMessage({route:"setNode",args:[str,fnName]},void 0);return new Promise(r=>r(name))}else if(connection.send){connection.send(JSON.stringify({route:"setNode",args:[str,fnName]}));return new Promise(r=>r(name))}return message},setGlobal:(key,value)=>{globalThis[key]=value;return true},assignGlobalObject:(target,source)=>{if(!globalThis[target])return false;if(typeof source==="object")Object.assign(globalThis[target],source);return true},setValue:function(key,value){this.__node.graph[key]=value;return true},assignObject:function(target,source){if(!this.__node.graph[target])return false;if(typeof source==="object")Object.assign(this.__node.graph[target],source);return true},setGlobalFunction:(fn,fnName)=>{if(typeof fn==="string")fn=parseFunctionFromText2(fn);if(typeof fn==="function"){if(!fnName)fnName=fn.name;globalThis[fnName]=fn;return true}return false},setGraphFunction:function(fn,fnName){if(typeof fn==="string")fn=parseFunctionFromText2(fn);if(typeof fn==="function"){if(!fnName)fnName=fn.name;this.__node.graph[fnName]=fn;return true}return false}};var __defProp2=Object.defineProperty;var __defNormalProp=(obj,key,value)=>key in obj?__defProp2(obj,key,{enumerable:true,configurable:true,writable:true,value}):obj[key]=value;var __publicField=(obj,key,value)=>{__defNormalProp(obj,typeof key!=="symbol"?key+"":key,value);return value};var _Math2=class{constructor(){}static genSineWave(freq=20,peakAmp=1,nSec=1,fs=512,freq2=0,peakAmp2=1){var sineWave=[];var t=[];var increment=1/fs;for(var ti=0;ticurr+=prev);return sum/arr.length}static mode(arr){return arr.sort((a,b)=>arr.filter(v=>v===a).length-arr.filter(v=>v===b).length).pop()}static std(arr,mean=void 0){let avg=mean;if(!mean)avg=this.mean(arr);let summed=0;for(let i2=0;i2a+(b-mean)**2,0)/arr.length}static dot(vec1,vec2){var dot=0;for(var i2=0;i2{sqrd+=c*c});return Math.sqrt(sqrd)}static distance(point1,point2){var dsqrd=0;point1.forEach((c,i2)=>{dsqrd+=(point2[i2]-c)*(point2[i2]-c)});return Math.sqrt(dsqrd)}static midpoint(point1=[1,2,3],point2=[3,4,5]){return point1.map((c,i2)=>{return(c+point2[i2])*.5})}static normalize(vec){var norm=0;norm=this.magnitude(vec);var vecn=new Array(vec.length);vec.forEach((c,i2)=>{vecn[i2]=c*norm});return vecn}static normalizeSeries(arr=[],fromZero=true){let max=Math.max(...arr);let min=Math.min(...arr);if(fromZero==false){max=Math.max(max,Math.abs(min));min=0}if(max-min===0){min=0;if(max===0)max=1e-13}return arr.map(v=>(v-min)/(max-min))}static quadraticFormula(a,b,c){let bbmac4=Math.sqrt(b*b-4*a*c);if(!isNaN(bbmac4))return["complex","complex"];let _a2=1/(2*a);if(bbmac4===0)return[b*_a2];let nb=-b;return[(nb+bbmac4)*_a2,(nb-bbmac4)*_a2]}static newtonsMethod(foo=x2=>{return Math.pow(x2,5)+x2*x2-x2-.2},start=0,end=1,precision=.01,attempts=10){let roots=[];for(let i2=0;i2precision){let step=-guess/slope2;let xn12=xn+step;guess=guess2;guess2=foo(xn12);let slope2=(guess2-guess)/(xn12-xn)}let idx;let f=roots.find((root,i22)=>{if(Math.abs(xn1-root){vec.push(point2[i2]-c)});return vec}static getBufferedValueByCoordinates(vb=new Array(300).fill(1),dims=[10,10,2],coordinate=[1,2,1],cardinal=void 0){let getIdx=(foundIdx=0,dimIdx=0)=>{if(dimIdx===dims.length)return foundIdx;if(dimIdx==0)foundIdx+=coordinate[dimIdx];else if(dims[dimIdx]==0)dimsAt0++;else{let reMul=(val=coordinate[dimIdx],di=dimIdx-1)=>{val*=dims[di];di--;if(di==0)return val;else return reMul(val,di)};foundIdx+=reMul(coordinate[dimIdx]+1,dimIdx-1)}dimIdx++;return getIdx(foundIdx,dimIdx)};let found=getIdx();if(cardinal){if(coordinate[coordinate.length-1]===0){let lastnonzero=0;let idx=0;while(idx!==coordinate.length-1){if(coordinate[idx]!==0)lastnonzero=idx;idx++}return vb[found-lastnonzero+cardinal]}return vb[found-dims.length+cardinal]}else{if(coordinate[coordinate.length-1]===0){let lastnonzero=0;let idx=0;while(idx!==coordinate.length-1){if(coordinate[idx]!==0)lastnonzero=idx;idx++}return vb.slice(found-lastnonzero,found+1)}return vb.slice(found-dims.length,found+1)}}static forBufferedMat(vb=new Array(100).fill(1),dims=[10,10],asIndex=(v,i2,x2,y)=>{return v+x2+y}){let coordinate=[];let idx=0;let recurseFor=(depth=0,nextDepth=depth+1)=>{let result=new Array(vb.length);for(let di=0;di{let result=new Array(vb.length);for(let di=0;di{console.log(`value:${v}, idx:${idx}, x:${i2},y:${j}`);return v+i2+j}){let coordinate=new Array(dimensions.length).fill(0);const iterateCoordinate=(coord,idx=0)=>{if(coord[idx]>=dimensions[idx]){coord[idx]=0;idx++;if(idx===dimensions.length)return;iterateCoordinate(coord,idx)}else coord[idx]++};let result=new Array(buffer.length);let i2=0;if(typeof asIndex==="function"){while(i2{result[i2]=func(buffer[i2],i2,...coordinate);i2++;iterateCoordinate(coordinate)})}}return result}static combinations(choices=["a","b","c"],vecsize=3){var result=[];if(vecsize<=0){result.push([])}else{_Math2.combinations(choices,vecsize-1).forEach(function(previousComb){choices.forEach(function(element){result.push([element].concat(previousComb))})})}return result}static generateCoordinateSpace(upperBounds=[10,10,10],lowerBounds=[-10,-10,-10],steps=[1,1,1],mutater=void 0){for(let i2=0;i2upperBounds[i2]){let temp=upperBounds[i2];upperBounds[i2]=lowerBounds[i2];lowerBounds[i2]=temp}}let result=[];let copy=[...upperBounds];let lastindex=copy.length-1;result.push([...copy]);while(copy[0]>=lowerBounds[0]){let checkNextIndex=decrIdx2=>{if(copy[decrIdx2]<=lowerBounds[decrIdx2]){if(decrIdx2===0)return;copy[decrIdx2]=upperBounds[decrIdx2];decrIdx2--;if(decrIdx2<0)return;if(typeof steps[decrIdx2]=="function")copy[decrIdx2]-=steps[decrIdx2](copy[decrIdx2]);else copy[decrIdx2]-=steps[decrIdx2];checkNextIndex(decrIdx2)}};let decrIdx=lastindex;if(typeof steps[decrIdx]=="function")copy[decrIdx]-=steps[decrIdx](copy[decrIdx]);else copy[decrIdx]-=steps[decrIdx];result.push([...copy]);checkNextIndex(decrIdx);if(mutater)result[result.length-1]=mutater(result[result.length-1])}return result}static calcVectorField(coordinates=[[0,0],[0,1],[1,0],[1,1]],formula=(x2,y)=>{return[x2*10,y*10]}){return coordinates.map(vec=>formula(...vec))}static transpose(mat){return mat[0].map((_,colIndex)=>mat.map(row=>row[colIndex]))}static matmul(a,b){var aNumRows=a.length,aNumCols=a[0].length,bNumRows=b.length,bNumCols=b[0].length,m=new Array(aNumRows);for(var r=0;rbinStart+binidx){j++;binidx+=binSize;let binmin=binStart+binidx;let binmid=binmin+binidx*.5;binx.push(binmid);biny.push(0)}biny[biny.length-1]++}return[binx,biny]}static normalDistribution(samples=[],normalize=true,cutoff=1e-4){let m=this.mean(samples);let vari=this.variance(samples);let nSamples=samples.length;let probabilities=[];let denom=1/(this.TWO_PI*vari);let _variance=1/vari;let sum=0;for(let i2=0;i2x2*_sum)}return probabilities}static expectedValue(samples=[],probabilities=this.normalDistribution(samples)){return samples.reduce((sum,item,idx)=>sum+item*probabilities[idx])}static originMoment(samples=[],probabilities=this.normalDistribution(samples),order=1){return samples.reduce((sum,item,idx)=>sum+Math.pow(item,order)*probabilities[idx])}static centralMoment(samples=[],probabilities=this.normalDistribution(samples),order=1){let m=this.mean(samples);return samples.reduce((sum,item,idx)=>sum+Math.pow(item-m,order)*probabilities[idx]/samples.length)}static linearDiscriminantAnalysis(samples=[],classifier=[]){let mean=this.mean(samples);let meank=this.mean(classifier);let covariance=this.cov1d(samples,classifier);let probs=this.normalDistribution(samples);let dk=[];for(let i2=0;i20){let pads=new Array(pad).fill(0);arr=[...pads,...arr,...pads]}let start=Math.floor(kern.length*.5);let end=arr.length-kern.length+start;for(let i2=start;i20){let pads=new Array(pad).fill(0);mat_t=_Math2.transpose(mat);for(let i22=0;i22{rowmeans.push(this.mean(row))});mattransposed.forEach((col,idx)=>{colmeans.push(this.mean(col))});mat.forEach((row,idx)=>{matproducts.push([]);for(var col=0;col{covariance.push([]);dimensionalData.forEach((arr2,j)=>{covariance[i2].push(this.cov1d(arr,arr2))})})}static eigens2x2(mat=[[1,2],[3,4]]){let det=mat[0][0]*mat[1][1]-mat[0][1]*mat[1][0];let mean=(mat[0][0]+mat[1][1])*.5;let sqrt=Math.sqrt(mean*mean-det);let eig1=mean+sqrt;let eig2=mean-sqrt;return[eig1,eig2]}static eigenvectors2x2(mat=[[1,2],[3,4]],eigens=[1,2]){let v1=[-mat[0][1],mat[0][0]-eigens[0]];if(v1[0]===0&&v1[1]===0){v1[0]=mat[1][1]-eigens[0];v1[1]=-mat[1][0]}let v2=[-mat[0][1],mat[0][0]-eigens[1]];if(v2[0]===0&&v2[1]===0){v2[0]=mat[1][1]-eigens[1];v2[1]=-mat[1][0]}return[v1,v2]}static fastpca2d(xarr,yarr){let cov1d=this.cov1d(xarr,yarr);let eigs=this.eigens2x2(cov1d);if(eigs[1]>eigs[0])eigs.reverse();let evs=this.eigenvectors2x2(cov1d,eigs);console.log(eigs,evs);return[eigs,evs]}static crosscorrelation(arr1,arr2){var arr2buf=[...arr2,...Array(arr2.length).fill(0)];var mean1=this.mean(arr1);var mean2=this.mean(arr2);var arr1Est=arr1.reduce((sum,item)=>sum+=Math.pow(item-mean1,2));arr1Est=Math.sqrt(Math.abs(arr1Est));var arr2Est2=arr2.reduce((sum,item)=>sum+=Math.pow(item-mean1,2));arr2Est2=Math.sqrt(Math.abs(arr2Est2));let denom=arr1Est*arr2Est2;if(denom===0)denom=1e-26;var _arrEstsMul=1/denom;var correlations=new Array(arr1.length).fill(0);for(var delay=0;delaysum+=(item-mean1)*(arr2buf[delay+i2]-mean2));correlations[delay]=r*_arrEstsMul}return correlations}static autocorrelation(arr1){var delaybuf=[...arr1,...Array(arr1.length).fill(0)];var mean1=this.mean(arr1);var arr1Est=arr1.reduce((sum,item)=>sum+=Math.pow(item-mean1,2));arr1Est=Math.sqrt(Math.abs(arr1Est));let denom=arr1Est*arr2Est;if(denom===0)denom=1e-26;var _arr1estsqrd=1/denom;var correlations=new Array(arr1.length).fill(0);for(var delay=0;delaysum+=(item-mean1)*(delaybuf[delay+i2]-mean1));correlations[delay]=r*_arr1estsqrd}return correlations}static autocorrelation2dNormalized(mat2d2){let result=[];for(let y=0;y{dat.forEach((row2,j)=>{if(j>=i2){correlograms.push(_Math2.crosscorrelation(row1,row2))}})});return correlograms}static dft(sineWave=[]){var TWOPI=2*3.141592653589793;var real=[];var imag=[];var mags=[];for(var k=0;k{return i2-halflen});return{real,imag,freqs,mags}}static sma(arr=[],window){var smaArr=[];for(var i2=0;i2current+=previous)/(i2+1))}else{var arrslice=arr.slice(i2-window,i2);smaArr.push(arrslice.reduce((previous,current)=>current+=previous)/window)}}return smaArr}static sum(arr=[]){if(arr.length>0){var sum=arr.reduce((prev,curr)=>curr+=prev);return sum}else{return 0}}static reduceArrByFactor(arr,factor=2){let x2=arr.filter((element,index)=>{return index%factor===0});return x2}static makeArr(startValue,stopValue,nSteps){var arr=[];var step=(stopValue-startValue)/(nSteps-1);for(var i2=0;i2y*scalar+(_lines*(stackPosition+1)*2-1-_lines))}else{scalar=_lines/(max-min);return array.map(y=>2*((y-min)*scalar-1/(2*stackedLines))+(_lines*(stackPosition+1)*2-1-_lines))}}static absmax(array){return Math.max(Math.abs(Math.min(...array)),Math.max(...array))}static downsample(array,fitCount,scalar=1){if(array.length>fitCount){let output=new Array(fitCount);let incr=array.length/fitCount;let lastIdx=array.length-1;let last=0;let counter=0;for(let i2=incr;i2lastIdx)rounded=lastIdx;for(let j=last;j1){let pass=true;for(let i2=0;i2=ref[Math.floor(ref.length*.5)]){pass=false;break}else if(i2>Math.floor(ref.length*.5)&&val>=ref[Math.floor(ref.length*.5)]){pass=false;break}}else if(critical==="valley"){if(i2Math.floor(ref.length*.5)&&val<=ref[Math.floor(ref.length*.5)]){pass=false;break}}else{if(i2Math.floor(ref.length*.5)&&val<=ref[Math.floor(ref.length*.5)]){pass=false;break}}}if(critical!=="peak"&&critical!=="valley"&&pass===false){pass=true;for(let i2=0;i2=ref[Math.floor(ref.length*.5)]){pass=false;break}else if(i2>Math.floor(ref.length*.5)&&val>=ref[Math.floor(ref.length*.5)]){pass=false;break}}}return pass}else return void 0}static isCriticalPoint(arr,critical="peak"){let ref=[...arr];if(ref.length%2===0)ref.pop();if(arr.length>1){let pass=true;for(let i2=0;i2ref.length*.5&&val>0){pass=false;break}}else if(critical==="valley"){if(i2=0){pass=false;break}else if(i2>ref.length*.5&&val<0){pass=false;break}}else{if(i2=0){pass=false;break}else if(i2>ref.length*.5&&val<0){pass=false;break}}}if(critical!=="peak"&&critical!=="valley"&&pass===false){pass=true;for(let i2=0;i2ref.length*.5&&val>0){pass=false;break}}}return pass}else return void 0}static getPeakThreshold(arr,peakIndices,thresholdVar){let threshold;let filtered=arr.filter((o,i2)=>{if(peakIndices.indexOf(i2)>-1)return true});if(thresholdVar===0){threshold=this.mean(filtered)}else threshold=(thresholdVar+this.mean(filtered))*.5;return threshold}static column(mat,x2){let col=new Array(mat.length).fill(0).map(()=>new Array(1).fill(0));for(let i2=0;i2new Array(1).fill(Math.sqrt(rank)));let eigenvalue=this.eigenvalue_of_vector(mat,eigenvector);let epsilon=1;let iter=0;while(epsilon>tolerance&&itertolerance){iter++;p[0]=this.matmul(mat_t,t[0]);let tp=this.matmul(this.transpose(t[0]),t[0]);p[0]=this.matscale(p[0],1/tp);let p_length=Math.sqrt(this.matmul(this.transpose(p[0]),p[0]));p[0]=this.matscale(p[0],1/p_length);let t_new=this.matmul(mat,p[0]);let pp=this.matmul(this.transpose(p[0]),p[0]);t_new=this.matscale(t_new,1/pp);epsilon=this.squared_difference(t[0],t_new);t[0]=JSON.parse(JSON.stringify(t_new))}let components=this.matmul(this.transpose(t[0]),t[0]);return components}static circularBuffer(arr,newEntries){if(Array.isArray(newEntries)){if(newEntries.lengtharr.length){let len=arr.length;arr.splice(0,len,newEntries.slice(len-newEntries.length))}else{arr.splice(0,arr.length,...newEntries)}}else{arr.push(newEntries);arr.shift()}return arr}static HSLToRGB(h,s,l,scalar=255){s/=100;l/=100;let c=(1-Math.abs(2*l-1))*s,x2=c*(1-Math.abs(h/60%2-1)),m=l-c/2,r=0,g=0,b=0;if(0<=h&&h<60){r=c;g=x2;b=0}else if(60<=h&&h<120){r=x2;g=c;b=0}else if(120<=h&&h<180){r=0;g=c;b=x2}else if(180<=h&&h<240){r=0;g=x2;b=c}else if(240<=h&&h<300){r=x2;g=0;b=c}else if(300<=h&&h<360){r=c;g=0;b=x2}r=(r+m)*scalar;g=(g+m)*scalar;b=(b+m)*scalar;return[r,g,b]}static p300(event_timestamps=[],raw_signal=[],signal_timestamps=[],sps=256){let smoothingstep=Math.floor(sps/10);let smoothed=this.sma(raw_signal,smoothingstep);let peaks=this.peakDetect(smoothed,"peak",smoothingstep);let mean=this.mean(smoothed);let std=this.std(smoothed,mean);let p_idx=0;let candidates=[];if(peaks.length>0){event_timestamps.forEach((t,j)=>{while(signal_timestamps[peaks[p_idx]]1){let peakvals=[];tempcandidates.forEach(tc=>{peakvals.push(smoothed[peaks[tc]])});let max=Math.max(...peakvals);let maxi=tempcandidates[peakvals.indexOf(max)];candidates.push({event_timestamp:t,event_index:j,peak_timestamp:signal_timestamps[[peaks[maxi]]],signal_index:[peaks[maxi]],signal_amplitude:raw_signal[[peaks[maxi]]],zscore:(smoothed[peaks[maxi]]-mean)/std})}else if(tempcandidates.length===1)candidates.push({event_timestamp:t,event_index:j,peak_timestamp:signal_timestamps[peaks[tempcandidates[0]]],signal_index:peaks[tempcandidates[0]],signal_amplitude:raw_signal[[peaks[tempcandidates[0]]]],zscore:(smoothed[peaks[tempcandidates[0]]]-mean)/std})})}return candidates}};var Math2=_Math2;__publicField(Math2,"TWO_PI",Math.PI*2);__publicField(Math2,"C",299792458);__publicField(Math2,"G",66743e-15);__publicField(Math2,"h",662607015e-42);__publicField(Math2,"R",8314.32);__publicField(Math2,"Ra",287);__publicField(Math2,"H",69.3);__publicField(Math2,"kbar",1054571817e-43);__publicField(Math2,"kB",1380649e-29);__publicField(Math2,"ke",89875517923e-1);__publicField(Math2,"me",91093837015e-41);__publicField(Math2,"mp",167262192369e-38);__publicField(Math2,"mn",167492749804e-38);__publicField(Math2,"P0",101325);__publicField(Math2,"T0",288.15);__publicField(Math2,"p0",1.225);__publicField(Math2,"Na",60220978e16);__publicField(Math2,"y",1.405);__publicField(Math2,"M0",28.96643);__publicField(Math2,"g0",9.80665);__publicField(Math2,"Re",6378100);__publicField(Math2,"B",1458e-9);__publicField(Math2,"S",110.4);__publicField(Math2,"Sigma",365e-12);__publicField(Math2,"imgkernels",{edgeDetection:[[-1,-1,-1],[-1,8,-1],[-1,-1,-1]],boxBlur:[[1/9,1/9,1/9],[1/9,1/9,1/9],[1/9,1/9,1/9]],sobelLeft:[[1,0,-1],[2,0,-2],[1,0,-1]],sobelRight:[[-1,0,1],[-2,0,2],[-1,0,1]],sobelTop:[[1,2,1],[0,0,0],[-1,-2,-1]],sobelBottom:[[-1,2,1],[0,0,0],[1,2,1]],identity:[[0,0,0],[0,1,0],[0,0,0]],gaussian3x3:[[1,2,1],[2,4,2],[1,2,1]],guassian7x7:[[0,0,0,5,0,0,0],[0,5,18,32,18,5,0],[0,18,64,100,64,18,0],[5,32,100,100,100,32,5],[0,18,64,100,64,18,0],[0,5,18,32,18,5,0],[0,0,0,5,0,0,0]],emboss:[[-2,-1,0],[-1,1,1],[0,1,2]],sharpen:[[0,-1,0],[-1,5,-1],[0,-1,0]]});__publicField(Math2,"integral",(func=x2=>{let y=x2;return y},range=[],stepx=.01)=>{let area=0;for(let i2=range[0];i2{let z=x2+y;return z},range=[[],[]],stepx=.01,stepy=stepx)=>{let volume=0;for(let i2=range[0][0]+stepx;i2{let w=x2+y+z;return w},range=[[],[],[]],stepx=.01,stepy=stepx,stepz=stepx)=>{let volume=0;for(let i2=range[0][0]+stepx;i2{let y=x2;return y},range=[],stepx=.01)=>{let length=0;let y0=void 0;let yi=void 0;for(let i2=range[0];i2{let result=[];for(let y=0;y{function lerp(v02,v12,t){return(1-t)*v02+t*v12}function interpolerp(v02,v12,fit2,floor2=true){if(fit2<=2)return[v02,v12];let a=1/fit2;let result=new Array(fit2);result[0]=v02;for(let i2=1;i2<=fit2;i2++){result[i2]=lerp(v02,v12,a*i2);if(floor2)result[i2]=Math.floor(result[i2])}return result}});__publicField(Math2,"peakDetect",(smoothedArray,type="peak",window=49)=>{let mid=Math.floor(window*.5);let peaks=[];for(let i2=0;i2 { - [key: string]: any; - }; - setValue: (key: any, value: any) => void; - triggerEvent: (key: any, value: any) => void; - subscribeState: (onchange: (res: any) => void) => number; - unsubscribeState: (sub: number) => boolean; - subscribeEvent: (key: string, onchange: (res: any) => void, refObject?: { - [key: string]: any; - }, refKey?: string) => number; - unsubscribeEvent: (key: string, sub?: number) => boolean; - subscribeEventOnce: (key: string, onchange: (res: any) => void) => any; - getEvent: (key: any, sub?: any) => { - [key: string]: any; - sub: number; - onchange: Function; - } | { - [key: string]: any; - sub: number; - onchange: Function; - }[]; - getSnapshot: () => void; - onRemoved: (trigger: { - sub: number; - onchange: Function; - }) => void; -} diff --git a/src/extras/dist/core/Graph.d.ts b/src/extras/dist/core/Graph.d.ts deleted file mode 100644 index f77b09bd..00000000 --- a/src/extras/dist/core/Graph.d.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { EventHandler } from "./EventHandler"; -export declare const state: EventHandler; -export type GraphNodeProperties = { - __props?: Function | { - [key: string]: any; - } | GraphNodeProperties | GraphNode; - __operator?: ((...args: any[]) => any) | string; - __children?: { - [key: string]: any; - }; - __listeners?: { - [key: string]: true | string | ((result: any) => void) | { - __callback: string | ((result: any) => void) | true; - subInput?: boolean; - [key: string]: any; - }; - } | { - [key: string]: ((result: any) => void) | true | string; - }; - __onconnected?: ((node: any) => void | ((node: any) => void)[]); - __ondisconnected?: ((node: any) => void | ((node: any) => void)[]); - __node?: { - tag?: string; - state?: EventHandler; - [key: string]: any; - }; - __args?: any[]; - __callable?: boolean; - [key: string]: any; -}; -export type Loader = (node: GraphNode, parent: Graph | GraphNode, graph: Graph, roots: any, properties: GraphNodeProperties, key: string) => void; -export type Roots = { - [key: string]: any; -}; -export type GraphOptions = { - roots?: Roots; - loaders?: { - [key: string]: Loader | { - init?: Loader; - connected?: (node: any) => void; - disconnected?: (node: any) => void; - }; - }; - state?: EventHandler; - mapGraphs?: false; - [key: string]: any; -}; -export type argObject = { - __input?: string | ((...args: any[]) => any); - __callback: string | ((...args: any[]) => any); - __args?: any[]; - __output?: string | argObject | ((...args: any[]) => any); -}; -export type Listener = { - __callback?: string; - __args?: (argObject | Function | string)[]; - sub: number; - node: GraphNode; - graph: Graph; - source?: string; - key?: string; - target?: string; - tkey?: string; - arguments?: Function[]; - subInput?: boolean; - onchange: Function; -}; -export declare class Callable extends Function { - __bound: Callable; - __call: ((...args: any[]) => any); - [key: string]: any; - constructor(); -} -export declare class GraphNode { - __node: { - tag: string; - unique: string; - state: EventHandler; - [key: string]: any; - }; - __children?: { - [key: string]: GraphNode; - }; - __parent?: Graph | GraphNode; - __operator?: any; - __listeners?: any; - __props?: any; - __args: any[]; - [key: string]: any; - constructor(properties: GraphNodeProperties, parent?: { - [key: string]: any; - }, graph?: Graph); - get __graph(): any; - set __graph(graph: any); - __setProperties: (properties: any, parent: any, graph: any) => void; - __subscribe: (callback: string | GraphNode | ((res: any) => void), key?: string, subInput?: boolean, target?: string, tkey?: string, args?: any[], callbackStr?: string) => any; - __unsubscribe: (sub?: number, key?: string, unsubInput?: boolean) => boolean; - __setOperator: (fn: (...args: any[]) => any) => any; - __addLocalState: (props?: { - [key: string]: any; - }, key?: string) => void; - __proxyObject: (obj: any) => void; - __addOnconnected(callback: (node: any) => void): void; - __addOndisconnected(callback: (node: any) => void): void; - __callConnected(node?: this): void; - __callDisconnected(node?: this): void; -} -export declare class Graph { - [key: string]: any; - __node: { - tag: string; - unique: string; - state: EventHandler; - nodes: Map; - roots: { - [key: string]: any; - }; - mapGraphs?: boolean; - [key: string]: any; - }; - constructor(options?: GraphOptions); - init: (options?: GraphOptions) => void; - load: (roots: { - [key: string]: any; - }, overwrite?: boolean) => { - [key: string]: any; - }; - setLoaders: (loaders: { - [key: string]: (node: GraphNode, parent: Graph | GraphNode, graph: Graph, roots: any, props: any, key: string) => void; - }, replace?: boolean) => any; - runLoaders: (node: any, parent: any, properties: any, key: any) => void; - add: (properties: any, parent?: GraphNode | string, overwrite?: boolean) => GraphNode; - recursiveSet: (originCpy: any, parent: any, listeners: any, origin: any, overwrite?: boolean) => any; - remove: (node: GraphNode | string, clearListeners?: boolean) => string | GraphNode; - run: (node: string | GraphNode, ...args: any[]) => any; - /** - * - * Listeners are an object where each key is a node tag, and each value is an object specifying callbacks or multiple callback for events on the graph, e.g. function outputs or variable changes. - * { - * [node.__node.tag (or arbitrary)]:{ - * [node.key (key optional)]:{__callback:string|Function, __args?:[], subInput?:boolean} | Function (bound to main node tag if specified) | string - * } - * } - * - * __args can be strings referencing other nodes/methods or values to pass correct inputs into the callback if more than one is required, else the output of the thing listened to is used by default - */ - setListeners: (listeners: { - [key: string]: { - [key: string]: any; - }; - }) => void; - clearListeners: (node: GraphNode | string, listener?: string) => void; - get: (tag: string) => any; - getByUnique: (unique: string) => any; - set: (tag: string, node: GraphNode) => Map; - delete: (tag: string) => boolean; - list: () => string[]; - getListener: (nodeTag: string, key?: string, sub?: number) => Listener; - getProps: (node: GraphNode | string, getInitial?: boolean) => void; - subscribe: (nodeEvent: GraphNode | string, onEvent: string | GraphNode | ((...res: any) => void), args?: any[], key?: string | undefined, subInput?: boolean, target?: string | GraphNode, tkey?: string) => number; - unsubscribe: (node: GraphNode | string, sub?: number, key?: string, subInput?: boolean) => any; - setState: (update: { - [key: string]: any; - }) => void; -} -export declare function getAllProperties(obj: any): any[]; -export declare function instanceObject(obj: any): any; -export declare function isNativeClass(thing: any): boolean; -export declare function isFunction(x: any): "function" | "class" | "async" | "arrow" | ""; -export declare let getCallbackFromString: (a: any, graph: any) => (...inp: any[]) => any; -export declare const wrapArgs: (callback: any, argOrder: any, graph: any) => { - __callback: any; - __args: any[]; -}; diff --git a/src/extras/dist/extras/algorithms/accel_gyro.d.ts b/src/extras/dist/extras/algorithms/accel_gyro.d.ts deleted file mode 100644 index c98cb706..00000000 --- a/src/extras/dist/extras/algorithms/accel_gyro.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { GraphNodeProperties } from '../../core/Graph'; -export declare const accel_gyro: GraphNodeProperties; diff --git a/src/extras/dist/extras/algorithms/beat_detect.d.ts b/src/extras/dist/extras/algorithms/beat_detect.d.ts deleted file mode 100644 index bc3fb33d..00000000 --- a/src/extras/dist/extras/algorithms/beat_detect.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { GraphNodeProperties } from '../../core/Graph'; -export declare const beat_detect: GraphNodeProperties; diff --git a/src/extras/dist/extras/algorithms/blink.d.ts b/src/extras/dist/extras/algorithms/blink.d.ts deleted file mode 100644 index 4743de8d..00000000 --- a/src/extras/dist/extras/algorithms/blink.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { GraphNodeProperties } from '../../core/Graph'; -export declare const blink_detect: GraphNodeProperties; diff --git a/src/extras/dist/extras/algorithms/buffering.d.ts b/src/extras/dist/extras/algorithms/buffering.d.ts deleted file mode 100644 index 71e1efac..00000000 --- a/src/extras/dist/extras/algorithms/buffering.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { GraphNodeProperties } from '../../core/Graph'; -export declare const circularBuffer2d: GraphNodeProperties; diff --git a/src/extras/dist/extras/algorithms/coherence.d.ts b/src/extras/dist/extras/algorithms/coherence.d.ts deleted file mode 100644 index 0b35b736..00000000 --- a/src/extras/dist/extras/algorithms/coherence.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { GraphNodeProperties } from '../../core/Graph'; -export declare const coherence: GraphNodeProperties; diff --git a/src/extras/dist/extras/algorithms/dft.d.ts b/src/extras/dist/extras/algorithms/dft.d.ts deleted file mode 100644 index ccd239c3..00000000 --- a/src/extras/dist/extras/algorithms/dft.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { GraphNodeProperties } from '../../core/Graph'; -export declare const dft: GraphNodeProperties; diff --git a/src/extras/dist/extras/algorithms/index.d.ts b/src/extras/dist/extras/algorithms/index.d.ts deleted file mode 100644 index c3ec990e..00000000 --- a/src/extras/dist/extras/algorithms/index.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { GraphNodeProperties } from "../../core/Graph"; -declare const algorithms: { - [key: string]: GraphNodeProperties; -}; -export { algorithms }; diff --git a/src/extras/dist/extras/algorithms/index.gpu.d.ts b/src/extras/dist/extras/algorithms/index.gpu.d.ts deleted file mode 100644 index fcfc3ef0..00000000 --- a/src/extras/dist/extras/algorithms/index.gpu.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -export declare const gpualgorithms: { - dft: import("../../core/Graph").GraphNodeProperties; - coherence: import("../../core/Graph").GraphNodeProperties; -}; diff --git a/src/extras/dist/extras/algorithms/rms.d.ts b/src/extras/dist/extras/algorithms/rms.d.ts deleted file mode 100644 index 39ad84d0..00000000 --- a/src/extras/dist/extras/algorithms/rms.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { GraphNodeProperties } from "../../core/Graph"; -export declare const rms: GraphNodeProperties; diff --git a/src/extras/dist/extras/algorithms/util/ArrayManip.d.ts b/src/extras/dist/extras/algorithms/util/ArrayManip.d.ts deleted file mode 100644 index b6d5e3ad..00000000 --- a/src/extras/dist/extras/algorithms/util/ArrayManip.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array; -export declare class ArrayManip { - static autoscale(array: any, lineIdx?: number, nLines?: number, centerZero?: boolean, ymin?: number, ymax?: number, clamp?: boolean): any; - static genTimestamps(ct: any, sps: any): any[]; - static absmax(array: any): number; - static downsample(array: any, fitCount: any, scalar?: number): any; - static upsample(array: any, fitCount: any, scalar?: number): any[]; - static interpolate(array: number[], fitCount: number, scalar?: number): any; - static HSLToRGB(h: any, s: any, l: any, scalar?: number): [number, number, number]; - static circularBuffer(arr: any[], newEntries: any[]): any[]; - static reformatData(data: { - [key: string]: number[] | number | { - values: number[] | number; - [key: string]: any; - }; - } | string | ((number | number[])[]) | number, key?: string): string | number | { - [key: string]: number | number[] | { - [key: string]: any; - values: number[] | number; - }; - } | (number | number[])[]; - static padTime(data: number[], //new data, assumed to be sequential between a gap - lastValue: number, //the last data point before the gap - time: number, //interval that's passed to determine slope between samples - targetFit: number): number[]; - static interpolateForTime(data: number[], //new data, assumed to be evenly spread over a time interval - time: number, //the time interval passed (s) - targetSPS: number): any; - static bufferValues: (objects: { - [key: string]: { - [key: string]: any; - }; - }, property: string, keys?: string[] | { - [key: string]: any; - }, buffer?: ArrayBufferLike) => ArrayBufferLike; - isTypedArray(x: any): boolean; - recursivelyAssign: (target: any, obj: any) => any; - spliceTypedArray(arr: TypedArray, start: number, end?: number): TypedArray; -} diff --git a/src/extras/dist/extras/algorithms/util/BiquadFilters.d.ts b/src/extras/dist/extras/algorithms/util/BiquadFilters.d.ts deleted file mode 100644 index fd1d4fc9..00000000 --- a/src/extras/dist/extras/algorithms/util/BiquadFilters.d.ts +++ /dev/null @@ -1,88 +0,0 @@ -export type FilterSettings = { - sps: number; - useSMA4?: boolean; - useNotch50?: boolean; - useNotch60?: boolean; - useLowpass?: boolean; - lowpassHz?: number; - useBandpass?: boolean; - bandpassLower?: number; - bandpassUpper?: number; - useDCBlock?: boolean; - DCBresonance?: number; - useScaling?: boolean; - scalar?: number; - trimOutliers?: boolean; - outlierTolerance?: number; -}; -export declare class BiquadChannelFilterer { - idx: number; - sps: number; - bandpassLower?: number; - bandpassUpper?: number; - useSMA4?: boolean; - last4?: number[]; - filtered: number; - trimOutliers?: boolean; - outlierTolerance?: number; - useNotch50?: boolean; - useNotch60?: boolean; - useLowpass?: boolean; - lowpassHz?: number; - useBandpass?: boolean; - useDCBlock?: boolean; - DCBresonance?: number; - useScaling?: boolean; - scalar?: number; - notch50?: any; - notch60?: any; - lp1?: any; - bp1?: any; - dcb?: any; - constructor(options?: FilterSettings); - reset(sps?: number): void; - setBandpass(bandpassLower?: number, bandpassUpper?: number, sps?: number): void; - apply(latestData?: number): number; -} -export declare class Biquad { - type: string; - freq: number; - sps: number; - Q: number; - dbGain: number; - a0: number; - a1: number; - a2: number; - b0: number; - b1: number; - b2: number; - x1: number; - x2: number; - y1: number; - y2: number; - constructor(type: 'lowpass' | 'highpass' | 'bandpass' | 'notch' | 'peak' | 'lowshelf' | 'highshelf', freq: number, sps: number, Q?: number, dbGain?: number); - lowpass(A: any, sn: any, cs: any, alpha: any, beta: any): void; - highpass(A: any, sn: any, cs: any, alpha: any, beta: any): void; - bandpass(A: any, sn: any, cs: any, alpha: any, beta: any): void; - notch(A: any, sn: any, cs: any, alpha: any, beta: any): void; - peak(A: any, sn: any, cs: any, alpha: any, beta: any): void; - lowshelf(A: any, sn: any, cs: any, alpha: any, beta: any): void; - highshelf(A: any, sn: any, cs: any, alpha: any, beta: any): void; - applyFilter(signal_step: any): number; - zResult(freq: any): number; - static calcCenterFrequency(freqStart: any, freqEnd: any): number; - static calcBandwidth(freqStart: any, freqEnd: any): number; - static calcBandpassQ(frequency: any, bandwidth: any, resonance?: number): number; - static calcNotchQ(frequency: any, bandwidth: any, resonance?: number): number; -} -export declare class DCBlocker { - r: number; - x1: number; - x2: number; - y1: number; - y2: number; - constructor(r?: number); - applyFilter(signal_step: any): number; -} -export declare const makeNotchFilter: (frequency: any, sps: any, bandwidth: any) => Biquad; -export declare const makeBandpassFilter: (freqStart: any, freqEnd: any, sps: any, resonance?: number) => Biquad; diff --git a/src/extras/dist/extras/algorithms/util/ByteParser.d.ts b/src/extras/dist/extras/algorithms/util/ByteParser.d.ts deleted file mode 100644 index 178a7329..00000000 --- a/src/extras/dist/extras/algorithms/util/ByteParser.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { ArrayManip } from "./ArrayManip"; -export declare class ByteParser extends ArrayManip { - static codes: { - '\\n': number; - '\\r': number; - '\\t': number; - '\\s': number; - '\\b': number; - '\\f': number; - '\\': number; - }; - static toDataView(value: string | number | ArrayBufferLike | DataView | number[]): DataView; - static searchBuffer(buffer: number[] | ArrayBuffer, searchString: Uint8Array, limit?: number): any[]; - static bytesToInt16(x0: number, x1: number): number; - static bytesToUInt16(x0: number, x1: number): number; - static Uint16ToBytes(y: number): number[]; - static bytesToInt24(x0: number, x1: number, x2: number): number; - static bytesToUInt24(x0: number, x1: number, x2: number): number; - static Uint24ToBytes(y: number): number[]; - static bytesToInt32(x0: number, x1: number, x2: number, x3: number): number; - static bytesToUInt32(x0: number, x1: number, x2: number, x3: number): number; - static Uint32ToBytes(y: number): number[]; - static get2sCompliment(val: number, nbits: number): number; - static getSignedInt(...args: number[]): number; - static asUint8Array(input: any): Uint8Array; - static boyerMoore(patternBuffer: any): any; - static struct(format: string): Readonly<{ - unpack: (arrb: any) => any[]; - pack: (...values: any[]) => ArrayBuffer; - unpack_from: (arrb: any, offs: any) => any[]; - pack_into: (arrb: any, offs: any, ...values: any[]) => void; - iter_unpack: (arrb: any) => Generator; - format: string; - size: number; - }>; -} diff --git a/src/extras/dist/extras/ecs/ECS.systems.d.ts b/src/extras/dist/extras/ecs/ECS.systems.d.ts deleted file mode 100644 index 34de4406..00000000 --- a/src/extras/dist/extras/ecs/ECS.systems.d.ts +++ /dev/null @@ -1,383 +0,0 @@ -import { Entity } from "../../services/ecs/ECS.service"; -export declare const Systems: { - collision: { - setupEntities: (entities: { - [key: string]: Entity; - }) => { - [key: string]: Entity; - }; - setupEntity: (entity: Entity) => Entity; - __node: { - tag: string; - }; - __operator: (entities: { - [key: string]: Entity; - }) => { - [key: string]: Entity; - }; - collisionCheck: (body1: { - [key: string]: any; - position: { - x: number; - y: number; - z: number; - }; - collisionEnabled?: boolean; - collisionType: 'sphere' | 'box' | 'point'; - collisionRadius: number; - collisionBoundsScale: { - x: number; - y: number; - z: number; - }; - }, body2: { - [key: string]: any; - position: { - x: number; - y: number; - z: number; - }; - collisionEnabled?: boolean; - collisionType: 'sphere' | 'box' | 'point'; - collisionRadius: number; - collisionBoundsScale: { - x: number; - y: number; - z: number; - }; - }) => number | false; - sphereCollisionCheck: (body1: { - [key: string]: any; - position: { - x: number; - y: number; - z: number; - }; - collisionRadius: number; - collisionBoundsScale: { - x: number; - y: number; - z: number; - }; - }, body2: { - [key: string]: any; - position: { - x: number; - y: number; - z: number; - }; - collisionRadius: number; - collisionBoundsScale: { - x: number; - y: number; - z: number; - }; - }, dist?: number) => boolean; - boxCollisionCheck: (body1: { - [key: string]: any; - position: { - x: number; - y: number; - z: number; - }; - collisionRadius: number; - collisionBoundsScale: { - x: number; - y: number; - z: number; - }; - }, body2: { - [key: string]: any; - position: { - x: number; - y: number; - z: number; - }; - collisionRadius: number; - collisionBoundsScale: { - x: number; - y: number; - z: number; - }; - }) => boolean; - sphereBoxCollisionCheck: (sphere: { - [key: string]: any; - position: { - x: number; - y: number; - z: number; - }; - collisionRadius: number; - collisionBoundsScale: { - x: number; - y: number; - z: number; - }; - }, box: { - [key: string]: any; - position: { - x: number; - y: number; - z: number; - }; - collisionRadius: number; - collisionBoundsScale: { - x: number; - y: number; - z: number; - }; - }, dist?: number) => boolean; - isPointInsideSphere: (point: { - x: number; - y: number; - z: number; - }, sphere: { - [key: string]: any; - position: { - x: number; - y: number; - z: number; - }; - collisionRadius: number; - collisionBoundsScale: { - x: number; - y: number; - z: number; - }; - }, dist?: number) => boolean; - isPointInsideBox: (point: { - x: number; - y: number; - z: number; - }, box: { - [key: string]: any; - position: { - x: number; - y: number; - z: number; - }; - collisionRadius: number; - collisionBoundsScale: { - x: number; - y: number; - z: number; - }; - }) => boolean; - closestPointOnLine: (point: { - x: number; - y: number; - z: number; - }, lineStart: { - x: number; - y: number; - z: number; - }, lineEnd: { - x: number; - y: number; - z: number; - }) => { - x: number; - y: number; - z: number; - }; - closestPointOnPolygon: (point: { - x: number; - y: number; - z: number; - }, t0: { - x: number; - y: number; - z: number; - }, t1: { - x: number; - y: number; - z: number; - }, t2: { - x: number; - y: number; - z: number; - }) => { - [key: string]: number; - }; - calcNormal: (t0: { - x: number; - y: number; - z: number; - }, t1: { - x: number; - y: number; - z: number; - }, t2: { - x: number; - y: number; - z: number; - }, positive?: boolean) => {}; - dot: (v1: { - [key: string]: number; - }, v2: { - [key: string]: number; - }) => number; - makeVec(p1: { - x: number; - y: number; - z: number; - }, p2: { - x: number; - y: number; - z: number; - }): { - x: number; - y: number; - z: number; - }; - vecadd: (v1: { - [key: string]: number; - }, v2: { - [key: string]: number; - }) => { - [key: string]: number; - }; - vecsub: (v1: { - [key: string]: number; - }, v2: { - [key: string]: number; - }) => { - [key: string]: number; - }; - vecmul: (v1: { - [key: string]: number; - }, v2: { - [key: string]: number; - }) => { - [key: string]: number; - }; - vecdiv: (v1: { - [key: string]: number; - }, v2: { - [key: string]: number; - }) => { - [key: string]: number; - }; - vecscale: (v1: { - [key: string]: number; - }, scalar: number) => { - [key: string]: number; - }; - distance: (v1: { - [key: string]: number; - }, v2: { - [key: string]: number; - }) => number; - magnitude: (v: { - [key: string]: number; - }) => number; - normalize: (v: { - [key: string]: number; - }) => {}; - distance3D(v1: { - x: number; - y: number; - z: number; - }, v2: { - x: number; - y: number; - z: number; - }): number; - cross3D(v1: { - x: number; - y: number; - z: number; - }, v2: { - x: number; - y: number; - z: number; - }): { - x: number; - y: number; - z: number; - }; - nearestNeighborSearch(entities: { - [key: string]: Entity; - }, isWithinRadius?: number): {}; - generateBoundingVolumeTree(entities: { - [key: string]: Entity; - }, mode?: 'octree' | 'aabb', withinRadius?: number, minEntities?: number): any; - }; - collider: { - lastTime: number; - setupEntities: (entities: { - [key: string]: Entity; - }) => { - [key: string]: Entity; - }; - setupEntity: (entity: Entity) => Entity; - __operator: (entities: { - [key: string]: Entity; - }) => { - [key: string]: Entity; - }; - __node: { - tag: string; - }; - checkBoundingBox: (entity: any) => void; - resolveBoxCollision: (body1: Entity, box: Entity, negate?: boolean) => void; - resolveSphereCollisions: (entity1: Entity, entity2: Entity, dist?: number) => void; - }; - nbody: { - lastTime: number; - G: number; - setupEntities: (entities: { - [key: string]: Entity; - }) => { - [key: string]: Entity; - }; - setupEntity: (entity: Entity) => Entity; - __operator: (entities: { - [key: string]: Entity; - }) => { - [key: string]: Entity; - }; - __node: { - tag: string; - }; - attract: (body1: any, body2: any, dist?: number, G?: any, vecn?: { - x: number; - y: number; - z: number; - }) => void; - }; - boid: { - lastTime: number; - defaultAnchor: { - x: number; - y: number; - z: number; - mul: number; - }; - setupEntities: (entities: any) => any; - setupEntity: (entity: Entity) => Entity; - __operator: (entities: { - [key: string]: Entity; - }) => { - [key: string]: Entity; - }; - __node: { - tag: string; - }; - }; - movement: { - __node: { - tag: string; - }; - lastTime: number; - setupEntities: (entities: { - [key: string]: Entity; - }) => void; - setupEntity: (entity: Entity) => Entity; - __operator: (entities: { - [key: string]: Entity; - }) => { - [key: string]: Entity; - }; - }; -}; diff --git a/src/extras/dist/extras/index.gpu.services.d.ts b/src/extras/dist/extras/index.gpu.services.d.ts deleted file mode 100644 index a1d3d930..00000000 --- a/src/extras/dist/extras/index.gpu.services.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './gpu/GPU.service'; -export { gpualgorithms } from './algorithms/index.gpu'; diff --git a/src/extras/dist/extras/index.services.d.ts b/src/extras/dist/extras/index.services.d.ts deleted file mode 100644 index 4c38107e..00000000 --- a/src/extras/dist/extras/index.services.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './struct/Struct.frontend'; -export * from './struct/Struct.backend'; -export * from './struct/genTimestamps'; -export * from './ecs/ECS.systems'; -export * from './webgl-plot/webglplot.routes'; -export { algorithms } from './algorithms/index'; diff --git a/src/extras/dist/extras/struct/Struct.backend.d.ts b/src/extras/dist/extras/struct/Struct.backend.d.ts deleted file mode 100644 index 278d1ebe..00000000 --- a/src/extras/dist/extras/struct/Struct.backend.d.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { ObjectId } from "./datastructures/bson.cjs"; -import { AuthorizationStruct, GroupStruct, ProfileStruct } from "./datastructures/types"; -import { TimeSpecifier } from './genTimestamps'; -import { Service } from "../../services/Service"; -import { User } from '../../services/router/Router'; -export declare const toObjectId: (str: any) => any; -export declare const getStringId: (mongoid: string | ObjectId) => any; -type CollectionsType = { - [x: string]: CollectionType; -}; -type CollectionType = any | { - instance?: any; - reference: { - [key: string]: any; - }; -}; -export declare class StructBackend extends Service { - name: string; - debug: boolean; - db: any; - users: { - [key: string]: User; - }; - collections: CollectionsType; - mode: 'local' | 'mongo' | string; - useAuths: boolean; - useAccessTokens: boolean; - useRefreshTokens: boolean; - accessTokens: Map; - refreshTokens: Map; - constructor(options?: any, dboptions?: { - users?: { - [key: string]: User; - }; - mode?: 'local' | 'mongo' | string; - db?: any; - collections?: CollectionsType; - useAuths?: boolean; - debug?: boolean; - useAccessTokens?: boolean; - useRefreshTokens?: boolean; - }); - initDB: (dboptions: any) => void; - query: (requestingUserId: string, collection?: any, queryObj?: any, findOne?: boolean, skip?: number, token?: string) => Promise; - getUser: (requestingUserId: string, lookupId: string, basicInfo?: boolean, token?: string) => Promise; - setUser: (requestingUserId: string, struct: Partial, token: string) => Promise; - getUsersByIds: (requestingUserId: string, userIds: string[], basicInfo?: boolean) => Promise; - getUsersByRole: (requestingUserId: string, role: string) => Promise; - deleteUser: (requestingUserId: string, userId: string, deleteData?: boolean, token?: string) => Promise; - setData: (requestingUserId: string, structs: any[], notify?: boolean, token?: string) => Promise; - getData: (requestingUserId: string, collection?: string, ownerId?: string, dict?: any, limit?: number, skip?: number, token?: string) => Promise; - getDataByIds: (requestingUserId: string, structIds: string[], ownerId?: string, collection?: string, token?: string) => Promise; - getAllData: (requestingUserId: string, ownerId: string, excludedCollections?: string[], timeRange?: [number | TimeSpecifier, number | TimeSpecifier], token?: string) => Promise; - deleteData: (requestingUserId: string, structIds: string[], token?: string) => Promise; - getUserGroups: (requestingUserId: string, userId?: string, groupId?: string) => Promise; - deleteGroup: (requestingUserId: string, groupId: string, token?: string) => Promise; - getAuthorizations: (requestingUserId: string, ownerId?: string, authId?: string, token?: string) => Promise; - deleteAuthorization: (requestingUserId: string, authId: string, token?: string) => Promise; - getToken: (user: Partial) => string; - notificationStruct: (parentStruct?: any) => { - structType: string; - timestamp: number; - _id: string; - note: string; - alert: boolean; - ownerId: string; - parentUserId: string; - parent: { - structType: any; - _id: any; - }; - }; - checkToNotify: (user: Partial, structs?: any[], mode?: string) => Promise; - queryMongo: (user: Partial, collection: string, queryObj?: any, findOne?: boolean, skip?: number, token?: string) => Promise; - setMongoData: (user: Partial, structs?: any[], notify?: boolean, token?: string) => Promise; - setMongoUser: (user: Partial, struct: Partial, token?: string) => Promise; - setGroup: (user: Partial, struct: any, mode?: string, token?: string) => Promise; - getMongoUser: (user: Partial, info?: string, requireAuth?: boolean, basicInfo?: boolean, token?: string) => Promise<{} | { - user: ProfileStruct; - authorizations: AuthorizationStruct[]; - groups: GroupStruct[] | { - user: ProfileStruct; - }; - }>; - queryUsers: (user: Partial, info?: string, limit?: number, skip?: number, requireAuth?: boolean, token?: string) => Promise<{} | { - user: ProfileStruct; - authorizations: AuthorizationStruct[]; - groups: GroupStruct[] | { - user: ProfileStruct; - }; - }>; - getMongoUsersByIds: (user: Partial, userIds?: any[], basicInfo?: boolean) => Promise; - getMongoUsersByRole: (user: Partial, role: string) => Promise; - getMongoDataByIds: (user: Partial, structIds: string[], ownerId: string | undefined, collection: string | undefined, token?: string) => Promise; - getMongoData: (user: Partial, collection: string | undefined, ownerId: string | undefined, dict?: any | undefined, limit?: number, skip?: number, token?: string) => Promise; - getAllUserMongoData: (user: Partial, ownerId: any, excluded?: any[], timeRange?: [number | TimeSpecifier, number | TimeSpecifier], token?: string) => Promise; - getMongoDataByRefs: (user: Partial, structRefs?: any[], token?: string) => Promise; - getMongoAuthorizations: (user: Partial, ownerId?: any, authId?: string, token?: string) => Promise; - getMongoGroups: (user: Partial, userId?: any, groupId?: string) => Promise; - deleteMongoData: (user: Partial, structRefs?: any[], token?: string) => Promise; - deleteMongoUser: (user: Partial, userId: any, deleteData?: boolean, token?: string) => Promise; - deleteMongoGroup: (user: Partial, groupId: any, token?: string) => Promise; - deleteMongoAuthorization: (user: Partial, authId: any, token?: string) => Promise; - setAuthorization: (user: Partial, authStruct: any, token?: string) => Promise; - checkAuthorization: (user: string | Partial | { - _id: string; - }, struct: any, request?: string, token?: string) => Promise; - wipeDB: () => Promise; - overwriteLocalData: (structs: any) => void; - setLocalData: (structs: any) => void; - getLocalData: (collection: any, query?: any) => any; - deleteLocalData: (struct: any) => boolean; -} -export {}; diff --git a/src/extras/dist/extras/struct/datastructures/bson.d.cts b/src/extras/dist/extras/struct/datastructures/bson.d.cts deleted file mode 100644 index 2efd64df..00000000 --- a/src/extras/dist/extras/struct/datastructures/bson.d.cts +++ /dev/null @@ -1,419 +0,0 @@ -declare var bson: Readonly<{ - __proto__: any; - Code: typeof Code; - BSONSymbol: typeof BSONSymbol; - DBRef: typeof DBRef; - Binary: typeof Binary; - ObjectId: typeof ObjectId; - UUID: typeof UUID; - Long: typeof Long; - Timestamp: typeof Timestamp; - Double: typeof Double; - Int32: typeof Int32; - MinKey: typeof MinKey; - MaxKey: typeof MaxKey; - BSONRegExp: typeof BSONRegExp; - Decimal128: typeof Decimal128; - setInternalBufferSize: typeof setInternalBufferSize; - serialize: typeof serialize; - serializeWithBufferAndIndex: typeof serializeWithBufferAndIndex; - deserialize: typeof deserialize; - calculateObjectSize: typeof calculateObjectSize; - deserializeStream: typeof deserializeStream; - BSONValue: typeof BSONValue; - BSONError: typeof BSONError; - BSONVersionError: typeof BSONVersionError; - BSONRuntimeError: typeof BSONRuntimeError; - BSONType: Readonly<{ - double: 1; - string: 2; - object: 3; - array: 4; - binData: 5; - undefined: 6; - objectId: 7; - bool: 8; - date: 9; - null: 10; - regex: 11; - dbPointer: 12; - javascript: 13; - symbol: 14; - javascriptWithScope: 15; - int: 16; - timestamp: 17; - long: 18; - decimal: 19; - minKey: -1; - maxKey: 127; - }>; - EJSON: any; -}>; -export class BSONError extends Error { - static isBSONError(value: any): boolean; - constructor(message: any); - get bsonError(): boolean; - get name(): string; -} -export class BSONRegExp extends BSONValue { - static parseOptions(options: any): any; - static fromExtendedJSON(doc: any): any; - constructor(pattern: any, options: any); - get _bsontype(): string; - pattern: any; - options: any; - toExtendedJSON(options: any): { - $regex: any; - $options: any; - $regularExpression?: undefined; - } | { - $regularExpression: { - pattern: any; - options: any; - }; - $regex?: undefined; - $options?: undefined; - }; - inspect(): string; -} -export class BSONRuntimeError extends BSONError { -} -export class BSONSymbol extends BSONValue { - static fromExtendedJSON(doc: any): BSONSymbol; - constructor(value: any); - get _bsontype(): string; - value: any; - valueOf(): any; - toString(): any; - inspect(): string; - toJSON(): any; - toExtendedJSON(): { - $symbol: any; - }; -} -export const BSONType: Readonly<{ - double: 1; - string: 2; - object: 3; - array: 4; - binData: 5; - undefined: 6; - objectId: 7; - bool: 8; - date: 9; - null: 10; - regex: 11; - dbPointer: 12; - javascript: 13; - symbol: 14; - javascriptWithScope: 15; - int: 16; - timestamp: 17; - long: 18; - decimal: 19; - minKey: -1; - maxKey: 127; -}>; -export class BSONValue { -} -export class BSONVersionError extends BSONError { - constructor(); -} -export class Binary extends BSONValue { - static fromExtendedJSON(doc: any, options: any): Binary; - constructor(buffer: any, subType: any); - get _bsontype(): string; - sub_type: any; - buffer: any; - position: any; - put(byteValue: any): void; - write(sequence: any, offset: any): void; - read(position: any, length: any): any; - value(asRaw: any): any; - length(): any; - toJSON(): any; - toString(encoding: any): any; - toExtendedJSON(options: any): { - $binary: any; - $type: string; - } | { - $binary: { - base64: any; - subType: string; - }; - $type?: undefined; - }; - toUUID(): UUID; - inspect(): string; -} -export namespace Binary { - let BSON_BINARY_SUBTYPE_DEFAULT: number; - let BUFFER_SIZE: number; - let SUBTYPE_DEFAULT: number; - let SUBTYPE_FUNCTION: number; - let SUBTYPE_BYTE_ARRAY: number; - let SUBTYPE_UUID_OLD: number; - let SUBTYPE_UUID: number; - let SUBTYPE_MD5: number; - let SUBTYPE_ENCRYPTED: number; - let SUBTYPE_COLUMN: number; - let SUBTYPE_USER_DEFINED: number; -} -export class Code extends BSONValue { - static fromExtendedJSON(doc: any): Code; - constructor(code: any, scope: any); - get _bsontype(): string; - code: any; - scope: any; - toJSON(): { - code: any; - scope: any; - } | { - code: any; - scope?: undefined; - }; - toExtendedJSON(): { - $code: any; - $scope: any; - } | { - $code: any; - $scope?: undefined; - }; - inspect(): string; -} -export class DBRef extends BSONValue { - static fromExtendedJSON(doc: any): DBRef; - constructor(collection: any, oid: any, db: any, fields: any); - get _bsontype(): string; - collection: any; - oid: any; - db: any; - fields: any; - set namespace(value: any); - get namespace(): any; - toJSON(): any; - toExtendedJSON(options: any): { - $ref: any; - $id: any; - }; - inspect(): string; -} -export class Decimal128 extends BSONValue { - static fromString(representation: any): Decimal128; - static fromExtendedJSON(doc: any): Decimal128; - constructor(bytes: any); - get _bsontype(): string; - bytes: any; - toJSON(): { - $numberDecimal: string; - }; - toExtendedJSON(): { - $numberDecimal: string; - }; - inspect(): string; -} -export class Double extends BSONValue { - static fromExtendedJSON(doc: any, options: any): number | Double; - constructor(value: any); - get _bsontype(): string; - value: number; - valueOf(): number; - toJSON(): number; - toString(radix: any): string; - toExtendedJSON(options: any): number | { - $numberDouble: string; - }; - inspect(): string; -} -export const EJSON: any; -export class Int32 extends BSONValue { - static fromExtendedJSON(doc: any, options: any): number | Int32; - constructor(value: any); - get _bsontype(): string; - value: number; - valueOf(): number; - toString(radix: any): string; - toJSON(): number; - toExtendedJSON(options: any): number | { - $numberInt: string; - }; - inspect(): string; -} -export class Long extends BSONValue { - static fromBits(lowBits: any, highBits: any, unsigned: any): Long; - static fromInt(value: any, unsigned: any): any; - static fromNumber(value: any, unsigned: any): any; - static fromBigInt(value: any, unsigned: any): any; - static fromString(str: any, unsigned: any, radix: any): any; - static fromBytes(bytes: any, unsigned: any, le: any): Long; - static fromBytesLE(bytes: any, unsigned: any): Long; - static fromBytesBE(bytes: any, unsigned: any): Long; - static isLong(value: any): boolean; - static fromValue(val: any, unsigned: any): any; - static fromExtendedJSON(doc: any, options: any): any; - constructor(low: number, high: any, unsigned: any); - get _bsontype(): string; - get __isLong__(): boolean; - low: number; - high: number; - unsigned: boolean; - add(addend: any): Long; - and(other: any): Long; - compare(other: any): 0 | 1 | -1; - comp(other: any): 0 | 1 | -1; - divide(divisor: any): any; - div(divisor: any): any; - equals(other: any): boolean; - eq(other: any): boolean; - getHighBits(): number; - getHighBitsUnsigned(): number; - getLowBits(): number; - getLowBitsUnsigned(): number; - getNumBitsAbs(): any; - greaterThan(other: any): boolean; - gt(other: any): boolean; - greaterThanOrEqual(other: any): boolean; - gte(other: any): boolean; - ge(other: any): boolean; - isEven(): boolean; - isNegative(): boolean; - isOdd(): boolean; - isPositive(): boolean; - isZero(): boolean; - lessThan(other: any): boolean; - lt(other: any): boolean; - lessThanOrEqual(other: any): boolean; - lte(other: any): boolean; - modulo(divisor: any): Long; - mod(divisor: any): Long; - rem(divisor: any): Long; - multiply(multiplier: any): any; - mul(multiplier: any): any; - negate(): Long; - neg(): Long; - not(): Long; - notEquals(other: any): boolean; - neq(other: any): boolean; - ne(other: any): boolean; - or(other: any): Long; - shiftLeft(numBits: any): Long; - shl(numBits: any): Long; - shiftRight(numBits: any): Long; - shr(numBits: any): Long; - shiftRightUnsigned(numBits: any): Long; - shr_u(numBits: any): Long; - shru(numBits: any): Long; - subtract(subtrahend: any): Long; - sub(subtrahend: any): Long; - toInt(): number; - toNumber(): number; - toBigInt(): bigint; - toBytes(le: any): number[]; - toBytesLE(): number[]; - toBytesBE(): number[]; - toSigned(): Long; - toString(radix: any): any; - toUnsigned(): Long; - xor(other: any): Long; - eqz(): boolean; - le(other: any): boolean; - toExtendedJSON(options: any): number | { - $numberLong: any; - }; - inspect(): string; -} -export namespace Long { - let TWO_PWR_24: any; - let MAX_UNSIGNED_VALUE: Long; - let ZERO: any; - let UZERO: any; - let ONE: any; - let UONE: any; - let NEG_ONE: any; - let MAX_VALUE: Long; - let MIN_VALUE: Long; -} -export class MaxKey extends BSONValue { - static fromExtendedJSON(): MaxKey; - get _bsontype(): string; - toExtendedJSON(): { - $maxKey: number; - }; - inspect(): string; -} -export class MinKey extends BSONValue { - static fromExtendedJSON(): MinKey; - get _bsontype(): string; - toExtendedJSON(): { - $minKey: number; - }; - inspect(): string; -} -export class ObjectId extends BSONValue { - static getInc(): number; - static generate(time: any): any; - static createPk(): ObjectId; - static createFromTime(time: any): ObjectId; - static createFromHexString(hexString: any): ObjectId; - static isValid(id: any): boolean; - static fromExtendedJSON(doc: any): ObjectId; - constructor(inputId: any); - get _bsontype(): string; - __id: any; - set id(value: any); - get id(): any; - toHexString(): any; - toString(encoding: any): any; - toJSON(): any; - equals(otherId: any): any; - getTimestamp(): Date; - toExtendedJSON(): { - $oid: any; - }; - inspect(): string; - [kId]: any; -} -export namespace ObjectId { - let index: number; -} -export class Timestamp extends Long { - static fromInt(value: any): Timestamp; - static fromNumber(value: any): Timestamp; - static fromBits(lowBits: any, highBits: any): Timestamp; - static fromString(str: any, optRadix: any): Timestamp; - static fromExtendedJSON(doc: any): Timestamp; - constructor(low: any); - toJSON(): { - $timestamp: any; - }; - toExtendedJSON(): { - $timestamp: { - t: number; - i: number; - }; - }; -} -export namespace Timestamp { - import MAX_VALUE_1 = Long.MAX_UNSIGNED_VALUE; - export { MAX_VALUE_1 as MAX_VALUE }; -} -export class UUID extends Binary { - static generate(): any; - static isValid(input: any): boolean; - static createFromHexString(hexString: any): UUID; - constructor(input: any); - __id: any; - set id(value: any); - get id(): any; - toHexString(includeDashes?: boolean): any; - equals(otherId: any): any; - toBinary(): Binary; -} -export function calculateObjectSize(object: any, options?: {}): number; -export function deserialize(buffer: any, options?: {}): {}; -export function deserializeStream(data: any, startIndex: any, numberOfDocuments: any, documents: any, docStartIndex: any, options: any): any; -export function serialize(object: any, options?: {}): any; -export function serializeWithBufferAndIndex(object: any, finalBuffer: any, options?: {}): number; -export function setInternalBufferSize(size: any): void; -declare const kId: unique symbol; -export { bson as BSON }; diff --git a/src/extras/dist/extras/struct/datastructures/types.d.ts b/src/extras/dist/extras/struct/datastructures/types.d.ts deleted file mode 100644 index ddb01f54..00000000 --- a/src/extras/dist/extras/struct/datastructures/types.d.ts +++ /dev/null @@ -1,243 +0,0 @@ -export type ArbitraryObject = { - [x: string | number]: any; -}; -export type Struct = { - _id: string; - structType?: string | number; - timestamp?: string | number; - ownerId?: string | number; - parent?: { - structType: string; - _id: string | number; - }; - [key: string]: any; -}; -export type DataTypes = 'byTime' | 'notes' | 'events' | 'sleep' | 'food' | 'rx' | 'hr' | 'ppg' | 'hrv' | 'ecg' | 'emg' | 'eeg' | 'fnirs' | string | number | undefined; -export type StructTypes = LooseStructTypes | DataTypes | 'data' | 'struct' | string | number | undefined; -export type LooseStructTypes = 'coherence' | 'imu' | 'eyetracker' | 'profile' | 'authorization' | 'group' | 'event' | 'chatroom' | 'comment' | 'notification' | 'schedule' | 'date' | string | number | undefined; -export type Data = { - type: string; - data: any; - timestamp?: string | number; -}; -export type DataStruct = { - title?: string; - author?: string; - expires: boolean | number | string; - type: string; - data: Data[]; - tag?: string | number; -} & Struct; -export type EventStruct = { - event: string; - author: string; - startTime: string; - endTime?: string; - grade?: string | number; - value?: any; - units?: string; - notes?: string; - location?: any; - attachments?: Data | string | number[]; - users?: { - [key: string]: true; - }; - tag?: string | number; -} & Struct; -export type ChatroomStruct = { - message: string; - topic: string; - author: string; - attachments: Data | string | number[]; - comments: string[]; - replies: string[]; - users: { - [key: string]: true; - }; - audioChatActive: boolean; - videoChatActive: boolean; - tag?: string | number; -} & Struct; -export type CommentStruct = { - author: string; - replyTo: string; - attachments: Data | string | number[]; - replies: string[]; - users: { - [key: string]: true; - }; - tag?: string | number; -} & Struct; -export type NotificationStruct = { - note: string; - parentUserId: string; - tag?: string | number; -} & Struct; -export type ScheduleStruct = { - title: string; - author: string; - attachments: Data | string | number[]; - dates: string[]; - tag?: string | number; -} & Struct; -export type DateStruct = { - timeSet: string | number; - notes: string; - recurs: number | string | boolean; - attachments: Data | string | number[]; - tag?: string | number; -} & Struct; -export type ProfileStruct = { - username?: string; - name?: string; - firstName?: string; - lastName?: string; - fullName?: string; - email?: string; - phone?: string; - sex?: string; - birthday?: string; - userRoles?: {}; - socials?: {}; - data?: {}; - type?: string; - hidden?: boolean; - pictureUrl: string; - accessToken?: string; - refreshToken?: string; - tag?: string | number; -} & Struct; -export type AuthorizationStruct = { - authorizedId: string; - authorizedName: string; - authorizerId: string; - authorizerName: string; - authorizations: {}; - structs: {}; - excluded: {}; - groups: {}; - status: "PENDING" | "OKAY"; - expires: string | boolean; - associatedAuthId: string | number; - tag?: string | number; -} & Struct; -export type GroupStruct = { - name: string; - details: string; - admins: {}; - peers: {}; - clients: {}; - users: {}; - tag?: string | number; -} & Struct; -type FreqBand = [number[], number[]]; -export type FrequencyBandNames = 'scp' | 'delta' | 'theta' | 'alpha1' | 'alpha2' | 'beta' | 'lowgamma' | 'highgamma'; -export type FrequencyBandsStruct = { - scp: FreqBand | []; - delta: FreqBand | []; - theta: FreqBand | []; - alpha1: FreqBand | []; - alpha2: FreqBand | []; - beta: FreqBand | []; - lowgamma: FreqBand | []; - highgamma: FreqBand | []; -}; -export type EEGStruct = { - position: { - x: number; - y: number; - z: number; - }; - count: number; - times: number[]; - raw: number[]; - filtered: number[]; - fftCount: number; - fftTimes: number[]; - ffts: [][]; - slices: FrequencyBandsStruct; - means: FrequencyBandsStruct; - startTime: number | string; - tag?: string | number; -} & Struct; -export type CoherenceStruct = { - x0: number; - y0: number; - z0: number; - x1: number; - y1: number; - z1: number; - fftCount: number; - fftTimes: number[]; - ffts: [][]; - slices: FrequencyBandsStruct; - means: FrequencyBandsStruct; - startTime: number | string; - tag?: string | number; -} & Struct; -export type FNIRSStruct = { - position: { - x: number; - y: number; - z: number; - }; - count: number; - times: number[]; - red: number[]; - ir: number[]; - ir2: number[]; - ambient: number[]; - ratio: number[]; - temp: number[]; - beat_detect: { - beats: any[]; - breaths: any[]; - rir: any[]; - rir2: any[]; - drir_dt: any[]; - localmins: any[]; - localmaxs: any[]; - val_dists: any[]; - peak_dists: any[]; - localmins2: any[]; - localmaxs2: any[]; - val_dists2: any[]; - peak_dists2: any[]; - }; - startTime: number | string; - tag?: string | number; -} & Struct; -export type IMUStruct = { - Ax: number[]; - Ay: number[]; - Az: number[]; - Gx: number[]; - Gy: number[]; - Gz: number[]; - startTime: number | string; - tag?: string | number; -} & Struct; -export type EyeTrackerStruct = { - count: number; - times: number[]; - x: number[]; - y: number[]; - smax: number[]; - smay: number[]; - startTime: number | string; - tag?: string | number; -} & Struct; -export type ECGStruct = { - count: number; - times: number[]; - raw: number[]; - filtered: number[]; - bpm: number[]; - hrv: number[]; - startTime: number | string; - tag?: string | number; -} & Struct; -export type PPGStruct = FNIRSStruct; -export type HRVStruct = ECGStruct; -export type EMGStruct = EEGStruct; -export {}; diff --git a/src/extras/dist/extras/struct/genTimestamps.d.ts b/src/extras/dist/extras/struct/genTimestamps.d.ts deleted file mode 100644 index 69253e3d..00000000 --- a/src/extras/dist/extras/struct/genTimestamps.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export type TimeUnit = 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year' | 'decade' | 'century' | 'millennium' | 'microsecond' | 'nanosecond'; -type Plural = `${T}s`; -export type TimeSpecifier = `now` | `last ${string} ${Plural}` | `last ${TimeUnit}`; -export declare let defaultSpecifiers: (TimeUnit | "now")[]; -export declare function genTimeSpecifiers(specifiers?: (TimeUnit | "now")[]): string[]; -export declare function genTimestampFromString(specifier: TimeSpecifier): number; -export {}; diff --git a/src/extras/dist/extras/webgl-plot/webglplot.routes.d.ts b/src/extras/dist/extras/webgl-plot/webglplot.routes.d.ts deleted file mode 100644 index 26ef2e6b..00000000 --- a/src/extras/dist/extras/webgl-plot/webglplot.routes.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { WorkerInfo } from '../../services/worker/Worker.service'; -import { WebglLinePlotInfo, WebglLinePlotProps, WebglLinePlotUtil, WebglLineProps } from "webgl-plot-utils"; -import { FilterSettings } from "../algorithms/util/BiquadFilters"; -export { WebglLinePlotUtil, WebglLineProps, WebglLinePlotProps, WebglLinePlotInfo }; -export declare const webglPlotRoutes: { - setupChart: (settings: WebglLinePlotProps) => any; - updateChartData: (plot: WebglLinePlotInfo | string, lines?: { - [key: string]: number[] | WebglLineProps | { - [key: string]: any; - values: number[]; - }; - }, draw?: boolean) => boolean; - clearChart: (plot: WebglLinePlotInfo | string) => boolean; - resetChart: (plot: WebglLinePlotInfo | string, settings: WebglLinePlotProps) => any; - getChartSettings: (plotId: any) => any; -}; -export declare function setSignalControls(controlsDiv: HTMLElement, plotId: string, streamworker: WorkerInfo, chartworker: WorkerInfo, chartSettings: Partial, filterSettings: FilterSettings): Promise; diff --git a/src/extras/dist/index.gpu.services.d.ts b/src/extras/dist/index.gpu.services.d.ts deleted file mode 100644 index ab57cca9..00000000 --- a/src/extras/dist/index.gpu.services.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './extras/gpu/GPU.service'; -export { gpualgorithms } from './extras/algorithms/index.gpu'; diff --git a/src/extras/dist/index.gpu.services.esm.js b/src/extras/dist/index.gpu.services.esm.js deleted file mode 100644 index cdca3039..00000000 --- a/src/extras/dist/index.gpu.services.esm.js +++ /dev/null @@ -1,1300 +0,0 @@ -var __require=(x2=>typeof require!=="undefined"?require:typeof Proxy!=="undefined"?new Proxy(x2,{get:(a,b)=>(typeof require!=="undefined"?require:a)[b]}):x2)(function(x2){if(typeof require!=="undefined")return require.apply(this,arguments);throw Error('Dynamic require of "'+x2+'" is not supported')});var EventHandler=class{data={};triggers={};ctr=0;constructor(data){if(typeof data==="object")this.data=data}setState=updateObj=>{Object.assign(this.data,updateObj);let props=Object.getOwnPropertyNames(updateObj);for(const prop of props){this.triggerEvent(prop,this.data[prop])}if(this.triggers[statesubKey]){let run=fn=>{fn(updateObj)};const l=this.triggers[statesubKey].length;for(let i=l-1;i>=0;i--){run(this.triggers[statesubKey][i].onchange)}}return this.data};setValue=(key,value2)=>{this.data[key]=value2;this.triggerEvent(key,value2)};triggerEvent=(key,value2)=>{if(this.triggers[key]){let fn=obj=>{obj.onchange(value2)};const l=this.triggers[key].length;for(let i=l-1;i>=0;i--){fn(this.triggers[key][i])}}};subscribeState=onchange=>{return this.subscribeEvent(statesubKey,onchange)};unsubscribeState=sub2=>{return this.unsubscribeEvent(statesubKey,sub2)};subscribeEvent=(key,onchange,refObject,refKey)=>{if(key){if(refObject&&refKey&&!this.triggers[key]){Object.defineProperty(this.data,key,{get:()=>{return refObject[refKey]},set:value2=>{refObject[refKey]=value2},enumerable:true,configurable:true})}if(!this.triggers[key]){this.triggers[key]=[]}let l=this.ctr;this.ctr++;this.triggers[key].push({sub:l,onchange});return l}else return void 0};unsubscribeEvent=(key,sub2)=>{let triggers=this.triggers[key];if(triggers){if(sub2===void 0){delete this.triggers[key];delete this.data[key]}else{let idx=void 0;let obj=triggers.find((o,i)=>{if(o.sub===sub2){idx=i;return true}});if(obj)triggers.splice(idx,1);if(Object.keys(triggers).length===0){delete this.triggers[key];delete this.data[key]}if(this.onRemoved)this.onRemoved(obj);return true}}};subscribeEventOnce=(key,onchange)=>{let sub2;let changed=value2=>{onchange(value2);this.unsubscribeEvent(key,sub2)};sub2=this.subscribeEvent(key,changed);return sub2};getEvent=(key,sub2)=>{if(typeof sub2!=="number")return this.triggers[key];for(const s in this.triggers[key]){if(this.triggers[key][s].sub===sub2)return this.triggers[key][s]}};getSnapshot=()=>{const snapshot={};for(const key in this.data){snapshot[key]=this.data[key]}};onRemoved};var statesubKey="*s";var state=new EventHandler;var Callable=class extends Function{__bound;__call;constructor(){super("return this.__bound.__call.apply(this.__bound, arguments)");this.__bound=this.bind(this);return this.__bound}};var GraphNode=class _GraphNode{__node={tag:`node${Math.floor(Math.random()*1e15)}`,unique:`${Math.floor(Math.random()*1e15)}`,state};__children;__parent;__operator;__listeners;__props;__args;constructor(properties,parent,graph){this.__setProperties(properties,parent,graph);if(typeof properties==="function"||properties?.__callable){const callableInstance=new Callable;callableInstance.__call=(...args)=>this.__operator(...args);const proxy=new Proxy(callableInstance,{get:(target,prop,receiver)=>{if(Reflect.has(this,prop)){return Reflect.get(this,prop,receiver)}return Reflect.get(target,prop,receiver)},set:(target,prop,value2,receiver)=>{if(Reflect.has(this,prop)){return Reflect.set(this,prop,value2,receiver)}return Reflect.set(target,prop,value2,receiver)}});Object.setPrototypeOf(proxy,this);return proxy}}get __graph(){return this.__node?.graph}set __graph(graph){this.__node.graph=graph}__setProperties=(properties,parent,graph)=>{let enforceProperties=()=>{let orig=properties;if(typeof properties==="function"){if(isNativeClass(properties)){properties=new properties}else properties={__operator:properties,__node:{forward:true,tag:properties.name}}}else if(typeof properties==="string"){if(graph?.get(properties)){properties=graph.get(properties)}}if(!("__node"in properties))properties.__node={};if(!properties.__node.initial)properties.__node.initial=orig};enforceProperties();if(typeof properties==="object"){let assignState=()=>{if(properties.__node?.state)this.__node.state=properties.__node.state;else if(graph){properties.__node.state=graph.__node.state}};let setProps=()=>{if(properties.__props){if(typeof properties.__props==="function")properties.__props=new properties.__props;if(typeof properties.__props==="object"){this.__proxyObject(properties.__props)}}};let setTag=()=>{if(!properties.__node.tag){if(properties.__operator?.name)properties.__node.tag=properties.__operator.name;else properties.__node.tag=`node${Math.floor(Math.random()*1e15)}`}};let setNode=()=>{if(typeof properties.__node==="string"){if(graph?.get(properties.__node.tag)){properties=graph.get(properties.__node.tag)}else properties.__node={}}else if(!properties.__node)properties.__node={};if(graph){properties.__node.graph=graph}if(properties instanceof Graph)properties.__node.source=properties};let setParent=()=>{if(!properties.__parent&&parent)properties.__parent=parent;if(parent?.__node&&!(parent instanceof Graph||properties instanceof Graph))properties.__node.tag=parent.__node.tag+"."+properties.__node.tag;if(parent instanceof Graph&&properties instanceof Graph){if(properties.__node.loaders)Object.assign(parent.__node.loaders?parent.__node.loaders:{},properties.__node.loaders);if(parent.__node.mapGraphs){properties.__node.nodes.forEach(n=>{parent.set(properties.__node.tag+"."+n.__node.tag,n)});let ondelete=()=>{properties.__node.nodes.forEach(n=>{parent.__node.nodes.delete(properties.__node.tag+"."+n.__node.tag)})};this.__addOndisconnected(ondelete)}}};let setOp=()=>{if(typeof properties.default==="function"&&!properties.__operator){properties.__operator=properties.default}if(properties.__operator){if(typeof properties.__operator==="string"){if(graph){let n=graph.get(properties.__operator);if(n)properties.__operator=n.__operator;if(!properties.__node.tag&&properties.__operator.name)properties.__node.tag=properties.__operator.name}}if(typeof properties.__operator==="function")properties.__operator=this.__setOperator(properties.__operator);if(properties.default)properties.default=properties.__operator}};let assignProps=()=>{properties.__node=Object.assign(this.__node,properties.__node);let keys=Object.getOwnPropertyNames(properties).filter(v=>{if(!objProps[v])return true});for(const key of keys){if(key in properties&&key!=="name")this[key]=properties[key]}};let bindCallbacks=()=>{if(this.__onconnected){if(typeof this.__onconnected==="function"){this.__onconnected=this.__onconnected.bind(this)}else if(Array.isArray(this.__onconnected)){this.__onconnected=this.__onconnected.map(f=>{return f.bind(this)})}if(typeof this.__ondisconnected==="function"){this.__ondisconnected=this.__ondisconnected.bind(this)}else if(Array.isArray(this.__ondisconnected)){this.__ondisconnected=this.__ondisconnected.map(f=>{return f.bind(this)})}}};assignState();setTag();setProps();setNode();setParent();assignProps();bindCallbacks();setOp()}};__subscribe=(callback,key,subInput,target,tkey,args,callbackStr)=>{const subscribeToFunction=(k,setTarget=(callback2,target2)=>target2?target2:callback2,triggerCallback=callback)=>{let wrappedArgs;if(args){let wrapped=wrapArgs(triggerCallback,args,this.__node.graph);triggerCallback=wrapped.__callback;wrappedArgs=wrapped.__args}let sub2=this.__node.state.subscribeEvent(k,triggerCallback,this,key);let trigger=this.__node.state.getEvent(k,sub2);if(!this.__listeners)this.__listeners={};this.__listeners[k]=this.__node.state.triggers[k];if(!trigger)return sub2;trigger.source=this.__node.tag;if(key)trigger.key=key;trigger.target=setTarget(callback,target);if(tkey)trigger.tkey=tkey;if(subInput)trigger.subInput=subInput;if(args){trigger.arguments=wrappedArgs;trigger.__args=args}if(callbackStr)trigger.__callback=callbackStr;trigger.node=this;trigger.graph=this.__node.graph;return sub2};const getCallbackFromGraph=callback2=>{let fn=this.__node.graph.get(callback2);if(!fn&&callback2.includes(".")){target=callback2.substring(0,callback2.lastIndexOf("."));let n=this.__node.graph.get(callback2.substring(0,target));tkey=callback2.lastIndexOf(".")+1;if(n&&typeof n[key]==="function")callback2=(...args2)=>{return n[tkey](...args2)}}else if(fn.__operator){callback2=fn.__operator;tkey="__operator"}return callback2};if(key){if(!this.__node.localState||!this.__node.localState[key]){this.__addLocalState(this,key)}if(typeof callback==="string"){callbackStr=this.__node.tag+"."+callback;tkey=callback;if(target){if(this.__node.graph?.get(target)){let n=this.__node.graph?.get(target);if(typeof n[callback]==="function"){let fn=n[callback];callback=(...inp)=>{fn(...inp)}}else{let k2=callback;let setter=inp=>{n[k2]=inp};callback=setter}}}else if(typeof this[callback]==="function"){let fn=this[callback];callback=(...inp)=>{fn(...inp)}}else if(this.__node.graph?.get(callback))callback=getCallbackFromGraph(callback);if(typeof callback!=="function")return void 0}let sub2;let k=subInput?this.__node.unique+"."+key+"input":this.__node.unique+"."+key;if(typeof callback==="function"&&!callback?.__node)sub2=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2,callback);else if(callback?.__node)sub2=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2.__node.unique,(...inp)=>{if(callback.__operator)callback.__operator(...inp)});return sub2}else{if(typeof callback==="string"){callbackStr=callback;if(!target)target=callback;if(this.__node.graph.get(callback))callback=this.__node.graph.get(callback);tkey="__operator";if(typeof callback!=="object")return void 0}let sub2;let k=subInput?this.__node.unique+"input":this.__node.unique;if(typeof callback==="function"&&!callback?.__node)sub2=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2,callback);else if(callback?.__node){sub2=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2.__node.unique,(...inp)=>{if(callback.__operator)callback.__operator(...inp)})}return sub2}};__unsubscribe=(sub2,key,unsubInput)=>{if(key){return this.__node.state.unsubscribeEvent(unsubInput?this.__node.unique+"."+key+"input":this.__node.unique+"."+key,sub2)}else return this.__node.state.unsubscribeEvent(unsubInput?this.__node.unique+"input":this.__node.unique,sub2)};__setOperator=fn=>{fn=fn.bind(this);if(this.__args&&this.__node.graph){fn=wrapArgs(fn,this.__args,this.__node.graph).__callback}let inpstr=`${this.__node.unique}input`;this.__operator=(...args)=>{if(this.__node.state.triggers[inpstr])this.__node.state.setValue(inpstr,args);let result=fn(...args);if(this.__node.state.triggers[this.__node.unique]){if(typeof result?.then==="function"){result.then(res=>{if(res!==void 0)this.__node.state.setValue(this.__node.unique,res)}).catch(console.error)}else if(result!==void 0)this.__node.state.setValue(this.__node.unique,result)}return result};if(this.__parent instanceof _GraphNode&&!this.__subscribedToParent){if(this.__parent.__operator){let sub2=this.__parent.__subscribe(this);let ondelete=()=>{this.__parent?.__unsubscribe(sub2);delete this.__subscribedToParent};this.__addOndisconnected(ondelete);this.__subscribedToParent=true}}return this.__operator};__addLocalState=(props,key)=>{if(!props)return;if(!this.__node.localState){this.__node.localState={}}const localState=this.__node.localState;const initState=(props2,k)=>{let str=this.__node.unique+"."+k;let inpstr=`${str}input`;let get,set;let obj,descriptor;if(typeof props2[k]==="function"&&k!=="__operator"){if(this.__props?.[k]){obj=this.__props}else{obj=localState}get=()=>{return obj[k]};set=fn=>{if(!this.__props?.[k])fn=fn.bind(this);obj[k]=(...args)=>{if(this.__node.state.triggers[inpstr])this.__node.state.setValue(inpstr,args);let result=fn(...args);if(this.__node.state.triggers[str]){if(typeof result?.then==="function"){result.then(res=>{this.__node.state.triggerEvent(str,res)}).catch(console.error)}else this.__node.state.triggerEvent(str,result)}return result}};localState[k]=props2[k].bind(this);descriptor={get,set,enumerable:true,configurable:true}}else if(k!=="__graph"){let get2,set2;let obj2;if(this.__props?.[k]){obj2=this.__props}else{obj2=localState}get2=()=>{return obj2[k]};set2=v=>{obj2[k]=v;if(this.__node.state.triggers[str])this.__node.state.triggerEvent(str,v)};localState[k]=props2[k];descriptor={get:get2,set:set2,enumerable:true,configurable:true}}Object.defineProperty(props2,k,descriptor);if(typeof this.__node.initial==="object"){let dec=Object.getOwnPropertyDescriptor(this.__node.initial,k);if(dec===void 0||dec?.configurable){Object.defineProperty(this.__node.initial,k,descriptor)}}};if(key)initState(props,key);else{for(let k in props){initState(props,k)}}};__proxyObject=obj=>{const allProps=getAllProperties(obj);for(const k of allProps){const descriptor={get:()=>{return obj[k]},set:value2=>{obj[k]=value2},enumerable:true,configurable:true};Object.defineProperty(this,k,descriptor);if(typeof this.__node.initial==="object"){let dec=Object.getOwnPropertyDescriptor(this.__node.initial,k);if(dec===void 0||dec?.configurable){Object.defineProperty(this.__node.initial,k,descriptor)}}}};__addOnconnected(callback){callback=callback.bind(this);if(Array.isArray(this.__onconnected)){this.__onconnected.push(callback)}else if(typeof this.__onconnected==="function"){this.__onconnected=[callback,this.__onconnected]}else this.__onconnected=callback}__addOndisconnected(callback){callback=callback.bind(this);if(Array.isArray(this.__ondisconnected)){this.__ondisconnected.push(callback)}else if(typeof this.__ondisconnected==="function"){this.__ondisconnected=[callback,this.__ondisconnected]}else this.__ondisconnected=callback}__callConnected(node=this){if(typeof this.__onconnected==="function"){this.__onconnected(this)}else if(Array.isArray(this.__onconnected)){let fn=o=>{o(this)};this.__onconnected.forEach(fn)}}__callDisconnected(node=this){if(typeof this.__ondisconnected==="function")this.__ondisconnected(this);else if(Array.isArray(this.__ondisconnected)){let fn=o=>{o(this)};this.__ondisconnected.forEach(fn)}}};var Graph=class _Graph{__node={tag:`graph${Math.floor(Math.random()*1e15)}`,unique:`${Math.random()}`,nodes:new Map,state,roots:{}};constructor(options){this.init(options)}init=options=>{if(options){let cpy=Object.assign({},options);delete cpy.roots;recursivelyAssign(this.__node,cpy);if(options.roots)this.load(options.roots)}};load=(roots,overwrite=false)=>{function recursivelyAssignChildren(target,obj,inChildren=true,top=true){if(top){if(!target)target={};for(const key in obj){if(!key.startsWith("__")&&obj[key]&&typeof obj[key]==="object"){target[key]=obj[key];if(obj[key]?.__children){recursivelyAssignChildren({},obj[key].__children,false,false)}}else if(typeof obj[key]==="function")target[key]=obj[key]}recursivelyAssignChildren(target,obj,true,false)}else{if(obj?.__children&&!inChildren){if(obj.__children?.constructor.name==="Object"){if(target.__children?.constructor.name==="Object")target.__children=recursivelyAssignChildren(target.__children,obj.__children,true,false);else target.__children=recursivelyAssignChildren({},obj.__children,true,false)}else{target.__children=obj.__children}}else if(inChildren){for(const key in obj){if(!key.startsWith("__")&&obj[key]&&typeof obj[key]==="object"){target[key]=Object.assign({},obj[key]);if(obj[key]?.__children){target[key].__children=recursivelyAssignChildren({},obj[key].__children,false,false)}}else if(typeof obj[key]==="function")target[key]=obj[key]}}}return target}this.__node.roots=recursivelyAssignChildren(this.__node.roots?this.__node.roots:{},roots);let cpy=Object.assign({},roots);if(cpy.__node)delete cpy.__node;let listeners=this.recursiveSet(cpy,this,void 0,roots,overwrite);if(roots.__node){if(!roots.__node.tag)roots.__node._tag=`roots${Math.floor(Math.random()*1e15)}`;else if(!this.get(roots.__node.tag)){let node=new GraphNode(roots,this,this);this.set(node.__node.tag,node);this.runLoaders(node,this,roots,roots.__node.tag);if(node.__listeners){listeners[node.__node.tag]=node.__listeners}}}else if(roots.__listeners){this.setListeners(roots.__listeners)}this.setListeners(listeners);return cpy};setLoaders=(loaders2,replace)=>{if(replace)this.__node.loaders=loaders2;else Object.assign(this.__node.loaders,loaders2);return this.__node.loaders};runLoaders=(node,parent,properties,key)=>{for(const l in this.__node.loaders){if(typeof this.__node.loaders[l]==="object"){if(this.__node.loaders[l].init)this.__node.loaders[l](node,parent,this,this.__node.roots,properties,key);if(this.__node.loaders[l].connected)node.__addOnconnected(this.__node.loaders[l].connect);if(this.__node.loaders[l].disconnected)node.__addOndisconnected(this.__node.loaders[l].disconnect)}else if(typeof this.__node.loaders[l]==="function")this.__node.loaders[l](node,parent,this,this.__node.roots,properties,key)}};add=(properties,parent,overwrite=true)=>{let listeners={};if(typeof parent==="string")parent=this.get(parent);let instanced;if(typeof properties==="function"){if(isNativeClass(properties)){if(properties.prototype instanceof GraphNode){properties=properties.prototype.constructor(properties,parent,this);instanced=true}else properties=new properties}else properties={__operator:properties,__callable:true}}else if(typeof properties==="string"){properties=this.__node.roots[properties]}if(!properties)return;if(!instanced){let keys=Object.getOwnPropertyNames(properties);let nonArrowFunctions=Object.getOwnPropertyNames(Object.getPrototypeOf(properties));keys.push(...nonArrowFunctions);keys=keys.filter(v=>!objProps.includes(v));let cpy={};for(const key of keys){cpy[key]=properties[key]}properties=cpy}if(!properties.__node)properties.__node={};properties.__node.initial=properties;if(typeof properties==="object"&&this.get(properties.__node.tag)){if(overwrite)this.remove(properties.__node.tag,true);else return}else if(properties.__node.tag&&this.get(properties.__node.tag))return this.get(properties.__node.tag);let node;let root=recursivelyAssign({},properties,2);if(instanced)node=properties;else node=new GraphNode(properties,parent,this);this.set(node.__node.tag,node);this.runLoaders(node,parent,properties,node.__node.tag);this.__node.roots[node.__node.tag]=root;if(node.__children){node.__children=Object.assign({},node.__children);this.recursiveSet(node.__children,node,listeners,node.__children)}if(node.__listeners){listeners[node.__node.tag]=Object.assign({},node.__listeners);for(const key in node.__listeners){let listener=node.__listeners[key];if(node[key]){delete listeners[node.__node.tag][key];listeners[node.__node.tag][node.__node.tag+"."+key]=listener}if(typeof listener==="string"){if(node.__children?.[listener]){listeners[node.__node.tag][key]=node.__node.tag+"."+listener}else if(parent instanceof GraphNode&&(parent.__node.tag===listener||parent.__node.tag.includes(".")&&parent.__node.tag.split(".").pop()===listener)){listeners[node.__node.tag][key]=parent.__node.tag}}}}this.setListeners(listeners);node.__callConnected();return node};recursiveSet=(originCpy,parent,listeners={},origin,overwrite=false)=>{let keys=Object.getOwnPropertyNames(origin).filter(v=>!objProps.includes(v));let nonArrowFunctions=Object.getOwnPropertyNames(Object.getPrototypeOf(origin)).filter(v=>!objProps.includes(v));keys.push(...nonArrowFunctions);for(const key of keys){if(key.includes("__"))continue;let p=origin[key];if(Array.isArray(p))continue;let instanced;if(typeof p==="function"){if(isNativeClass(p)){p=new p;if(p instanceof GraphNode){p=p.prototype.constructor(p,parent,this);instanced=true}}else p={__operator:p,__callable:true}}else if(typeof p==="string"){if(this.__node.nodes.get(p))p=this.__node.nodes.get(p);else p=this.__node.roots[p]}else if(typeof p==="boolean"){if(this.__node.nodes.get(key))p=this.__node.nodes.get(key);else p=this.__node.roots[key]}if(p&&typeof p==="object"){if(!instanced&&!(p instanceof GraphNode)){let ks=Object.getOwnPropertyNames(p).filter(v=>!objProps.includes(v));let nonArrowFunctions2=Object.getOwnPropertyNames(Object.getPrototypeOf(p)).filter(v=>!objProps.includes(v));nonArrowFunctions2.splice(nonArrowFunctions2.indexOf("constructor"),1);ks.push(...nonArrowFunctions2);let cpy={};for(const key2 of ks){cpy[key2]=p[key2]}p=cpy}if(!p.__node)p.__node={};if(!p.__node.tag)p.__node.tag=key;if(!p.__node.initial)p.__node.initial=originCpy[key];if(overwrite&&this.get(p.__node.tag)){this.remove(p.__node.tag,true)}else if(this.get(p.__node.tag)&&!(!(parent instanceof _Graph)&&parent?.__node)||parent?.__node&&this.get(parent.__node.tag+"."+p.__node.tag))continue;let node;let newnode=false;let root=recursivelyAssign({},p,2);if(instanced||p instanceof GraphNode){node=p}else{node=new GraphNode(p,parent,this);newnode=true}if(!newnode&&p instanceof GraphNode&&!instanced&&parent instanceof GraphNode){let sub2=this.subscribe(parent.__node.tag,node.__node.tag);let ondelete=node2=>{this.unsubscribe(parent.__node.tag,sub2)};node.__addOndisconnected(ondelete)}else if(node){this.set(node.__node.tag,node);this.runLoaders(node,parent,originCpy[key],key);originCpy[key]=node;this.__node.roots[node.__node.tag]=root;if(node.__children){node.__children=Object.assign({},node.__children);this.recursiveSet(node.__children,node,listeners,node.__children)}if(node.__listeners){listeners[node.__node.tag]=Object.assign({},node.__listeners);for(const key2 in node.__listeners){let listener=node.__listeners[key2];let k=key2;if(node[key2]){delete listeners[node.__node.tag][key2];k=node.__node.tag+"."+key2;listeners[node.__node.tag][k]=listener}if(typeof listener==="string"){if(node.__children?.[listener]){listeners[node.__node.tag][k]=node.__node.tag+"."+listener}else if(parent instanceof GraphNode&&(parent.__node.tag===listener||parent.__node.tag.includes(".")&&parent.__node.tag.split(".").pop()===listener)){listeners[node.__node.tag][k]=parent.__node.tag}}}}node.__callConnected()}}}return listeners};remove=(node,clearListeners=true)=>{this.unsubscribe(node);if(typeof node==="string")node=this.get(node);if(node instanceof GraphNode){this.delete(node.__node.tag);delete this.__node.roots[node.__node.tag];if(clearListeners){this.clearListeners(node)}node.__callDisconnected();const recursiveRemove=t=>{for(const key in t){this.unsubscribe(t[key]);this.delete(t[key].__node.tag);delete this.__node.roots[t[key].__node.tag];this.delete(key);delete this.__node.roots[key];t[key].__node.tag=t[key].__node.tag.substring(t[key].__node.tag.lastIndexOf(".")+1);if(clearListeners){this.clearListeners(t[key])}t[key].__callDisconnected();if(t[key].__children){recursiveRemove(t[key].__children)}}};if(node.__children){recursiveRemove(node.__children)}}if(node?.__node.tag&&node?.__parent){delete node?.__parent;node.__node.tag=node.__node.tag.substring(node.__node.tag.indexOf(".")+1)}if(node?.__node.graph)node.__node.graph=void 0;return node};run=(node,...args)=>{if(typeof node==="string"){let nd=this.get(node);if(!nd&&node.includes(".")){nd=this.get(node.substring(0,node.lastIndexOf(".")));if(typeof nd?.[node.substring(node.lastIndexOf(".")+1)]==="function")return nd[node.substring(node.lastIndexOf(".")+1)](...args)}else if(nd?.__operator)return nd.__operator(...args)}if(node?.__operator){return node?.__operator(...args)}};setListeners=listeners=>{for(const key in listeners){let node=this.get(key);if(typeof listeners[key]==="object"){for(const k in listeners[key]){let n=this.get(k);let sub2;if(typeof listeners[key][k]!=="object")listeners[key][k]={__callback:listeners[key][k]};else if(!listeners[key][k].__callback){for(const kk in listeners[key][k]){if(typeof listeners[key][k][kk]!=="object"){listeners[key][k][kk]={__callback:listeners[key][k][kk]};if(node.__operator&&(listeners[key][k][kk].__callback===true||typeof listeners[key][k][kk].__callback==="undefined"))listeners[key][k][kk].__callback=node.__operator}let nn=this.get(kk);if(!nn){let tag=k.substring(0,k.lastIndexOf("."));nn=this.get(tag);if(nn){let prop=k.substring(k.lastIndexOf(".")+1);sub2=this.subscribe(nn,listeners[key][k][kk].__callback,listeners[key][k][kk].__args,prop,listeners[key][k][kk].subInput,key)}}else{sub2=this.subscribe(nn,listeners[key][k][kk].__callback,listeners[key][k][kk].__args,void 0,listeners[key][k][kk].subInput,key)}}}if("__callback"in listeners[key][k]){if(node){if(listeners[key][k].__callback===true||typeof listeners[key][k].__callback==="undefined")listeners[key][k].__callback=node.__operator;if(typeof listeners[key][k].__callback==="function")listeners[key][k].__callback=listeners[key][k].__callback.bind(node)}if(!n){let tag=k.substring(0,k.lastIndexOf("."));n=this.get(tag);if(n){sub2=this.subscribe(n,listeners[key][k].__callback,listeners[key][k].__args,k.substring(k.lastIndexOf(".")+1),listeners[key][k].subInput,key)}}else{sub2=this.subscribe(n,listeners[key][k].__callback,listeners[key][k].__args,void 0,listeners[key][k].subInput,key)}}}}}};clearListeners=(node,listener)=>{if(typeof node==="string")node=this.get(node);if(node?.__listeners){for(const key in node.__listeners){if(listener&&key!==listener)continue;if(typeof node.__listeners[key]?.sub!=="number")continue;let n=this.get(key);if(!n){n=this.get(key.substring(0,key.lastIndexOf(".")));if(n){if(typeof node.__listeners[key]==="object"&&!node.__listeners[key]?.__callback){for(const k in node.__listeners[key]){if(typeof node.__listeners[key][k]?.sub==="number"){this.unsubscribe(n,node.__listeners[key][k].sub,key.substring(key.lastIndexOf(".")+1),node.__listeners[key][k].subInput);node.__listeners[key][k].sub=void 0}}}else if(typeof node.__listeners[key]?.sub==="number"){this.unsubscribe(n,node.__listeners[key].sub,key.substring(key.lastIndexOf(".")+1),node.__listeners[key].subInput);node.__listeners[key].sub=void 0}}}else{if(typeof!node.__listeners[key]?.__callback==="number"){for(const k in node.__listeners[key]){if(node.__listeners[key][k]?.sub){this.unsubscribe(n,node.__listeners[key][k].sub,void 0,node.__listeners[key][k].subInput);node.__listeners[key][k].sub=void 0}}}else if(typeof node.__listeners[key]?.sub==="number"){this.unsubscribe(n,node.__listeners[key].sub,void 0,node.__listeners[key].subInput);node.__listeners[key].sub=void 0}}}}};get=tag=>{return this.__node.nodes.get(tag)};getByUnique=unique=>{return Array.from(this.__node.nodes.values()).find(node=>{if(node.__node.unique===unique)return true})};set=(tag,node)=>{return this.__node.nodes.set(tag,node)};delete=tag=>{return this.__node.nodes.delete(tag)};list=()=>{return Array.from(this.__node.nodes.keys())};getListener=(nodeTag,key,sub2)=>{let node=this.get(nodeTag);if(node){let k=node.__node.unique;if(key){k+="."+key}return this.__node.state.getEvent(k,sub2)}};getProps=(node,getInitial)=>{if(typeof node==="string")node=this.get(node);if(node instanceof GraphNode){let cpy;if(getInitial)cpy=Object.assign({},this.__node.roots[node.__node.tag]);else{cpy=Object.assign({},node);for(const key in cpy){if(key.includes("__"))delete cpy[key]}}}};subscribe=(nodeEvent,onEvent,args,key,subInput,target,tkey)=>{let nd=nodeEvent;if(typeof nodeEvent==="string"){nd=this.get(nodeEvent);if(!nd&&nodeEvent.includes(".")){nd=this.get(nodeEvent.substring(0,nodeEvent.lastIndexOf(".")));key=nodeEvent.substring(nodeEvent.lastIndexOf(".")+1)}}if(target instanceof GraphNode)target=target.__node.tag;let callbackStr;if(typeof onEvent==="string"){callbackStr=onEvent;let setOnEventFromString=onEvent2=>{if(this.get(onEvent2)?.__operator){let node=this.get(onEvent2);target=onEvent2;onEvent2=function(...inp){return node.__operator(...inp)}}else if(onEvent2.includes(".")){target=onEvent2.substring(0,onEvent2.lastIndexOf("."));let n=this.get(target);let k=onEvent2.substring(onEvent2.lastIndexOf(".")+1);tkey=k;if(typeof n[k]==="function"){if(n[k]instanceof GraphNode)onEvent2=n[k];else onEvent2=function(...inp){return n[k](...inp)}}else{onEvent2=function(inp){n[k]=inp;return n[k]}}}return onEvent2};if(target){let node=this.get(target);if(typeof node?.[onEvent]==="function"){tkey=onEvent;onEvent=function(...inp){return node[key](...inp)}}else if(node?.[key]){tkey=key;if(node[key]instanceof GraphNode)onEvent=node[key];else onEvent=function(inp){node[key]=inp;return node[key]}}else{onEvent=setOnEventFromString(onEvent)}}else{onEvent=setOnEventFromString(onEvent)}}let sub2;if(nd instanceof GraphNode){const doSub=()=>{sub2=nd.__subscribe(onEvent,key,subInput,target,tkey,args,callbackStr);let ondelete=()=>{if(sub2!==void 0)nd.__unsubscribe(sub2,key,subInput);sub2=void 0};nd.__addOndisconnected(()=>{ondelete();nd.__addOnconnected(()=>{if(sub2===void 0&&nd.__node.graph.__node.tag===this.__node.tag)doSub()})});if(typeof onEvent==="string"&&this.get(onEvent))onEvent=this.get(onEvent);if(onEvent instanceof GraphNode){onEvent.__addOndisconnected(()=>{ondelete()})}};doSub()}else if(typeof nodeEvent==="string"){let node=this.get(nodeEvent);if(node){if(onEvent instanceof GraphNode&&onEvent.__operator){const doSub=()=>{sub2=node.__subscribe(onEvent.__operator,key,subInput,target,tkey,args,callbackStr);let ondelete=()=>{if(sub2!==void 0)node.__unsubscribe(sub2,key,subInput)};node.__addOndisconnected(()=>{ondelete();node.__addOnconnected(()=>{if(sub2===void 0&&node.__node.graph.__node.tag===this.__node.tag)doSub()})});onEvent.__addOndisconnected(ondelete)};doSub()}else if(typeof onEvent==="function"||typeof onEvent==="string"){const doSub=()=>{sub2=node.__subscribe(onEvent,key,subInput,target,tkey,args,callbackStr);let ondelete=()=>{if(sub2!==void 0)node.__unsubscribe(sub2,key,subInput);sub2=void 0};node.__addOndisconnected(()=>{ondelete();node.__addOnconnected(()=>{if(sub2===void 0&&node.__node.graph.__node.tag===this.__node.tag)doSub()})});if(typeof onEvent==="string"&&this.get(onEvent))this.get(onEvent).__addOndisconnected(ondelete)};doSub()}}else{if(typeof onEvent==="string")onEvent=this.__node.nodes.get(onEvent).__operator;if(typeof onEvent==="function"&&!onEvent?.__node)sub2=this.__node.state.subscribeEvent(nodeEvent,onEvent)}}return sub2};unsubscribe=(node,sub2,key,subInput)=>{if(node instanceof GraphNode){return node.__unsubscribe(sub2,key,subInput)}else return this.get(node)?.__unsubscribe(sub2,key,subInput)};setState=update=>{this.__node.state.setState(update)}};function recursivelyAssign(target,obj,maxDepth=Infinity,curDepth=0){for(const key in obj){if(obj[key]?.constructor.name==="Object"&&curDepth{if(graph.get(a)?.__operator){let node=graph.get(a);return(...inp)=>{node.__operator(...inp)}}else if(a.includes(".")){let split=a.split(".");let popped=split.pop();let joined=split.join(".");let node=graph.get(joined);if(typeof graph.get(joined)?.[popped]==="function"){return(...inp)=>{return node[popped](...inp)}}else return()=>{return node[popped]}}else if(graph.get(a)){let node=graph.get(a);return()=>{return node}}else{let arg=a;return()=>{return arg}}};var wrapArgs=(callback,argOrder,graph)=>{let args=[];let forArg=(a,i)=>{if(a==="__output"||a==="__input"||a==="__callback"){args[i]={__callback:inp=>{return inp},__args:void 0,idx:i}}else if(typeof a==="string"){args[i]={__callback:getCallbackFromString(a,graph),__args:void 0,idx:i}}else if(typeof a==="function"){let fn2=a;args[i]={__callback:(...inp)=>{return fn2(...inp)},__args:void 0,idx:i}}else if(typeof a==="object"&&(a.__input||a.__callback)){let recursivelyCreateCallback=function(c){let input=c.__input?c.__input:c.__callback;if(typeof c.__input==="string"){input={__callback:getCallbackFromString(c.__input,graph),__args:void 0,idx:i}}if(c.__args){let wrapped=wrapArgs(input,c.__args,graph);input={__callback:wrapped.__callback,__args:wrapped.__args,idx:i}}else{input={__callback:input,__args:void 0,idx:i}}if(c.__output){let output=c.__output;if(typeof c.__output==="string"){output={__callback:getCallbackFromString(output,graph),__args:void 0,idx:i}}else if(typeof a.__output==="object"){output=recursivelyCreateCallback(output)}if(typeof output?.__callback==="function"){let fn2=input.__callback;let callback2=output.__callback;input={__callback:(...inp)=>{return callback2(fn2(...inp))},__args:output.__args,idx:i}}}return input};args[i]=recursivelyCreateCallback(a)}else{let arg=a;args[i]={__callback:()=>{return arg},__args:void 0,idx:i}}};argOrder.forEach(forArg);if(typeof callback==="string")callback={__callback:getCallbackFromString(callback,graph),__args:void 0};let fn=typeof callback==="function"?callback:callback.__callback;callback=function(...inp){let mapArg=arg=>{return arg.__callback(...inp)};const result=fn(...args.map(mapArg));return result};return{__callback:callback,__args:args}};var objProps=Object.getOwnPropertyNames(Object.getPrototypeOf({}));var backprop=(node,parent,graph)=>{if(node.__node.backward&&parent instanceof GraphNode){graph.setListeners({[parent.__node.tag]:{[node.__node.tag]:parent}})}};var loop=(node,parent,graph)=>{if(node.__operator){let loopId=Math.random();if(!node.__node.loops)node.__node.loops={};if(typeof node.__node.delay==="number"){let fn=node.__operator;node.__setOperator((...args)=>{return new Promise((res,rej)=>{node.__node.loops[loopId]=setTimeout(async()=>{res(await fn(...args))},node.__node.delay)})})}else if(node.__node.frame===true){let fn=node.__operator;node.__setOperator((...args)=>{return new Promise((res,rej)=>{node.__node.loops[loopId]=requestAnimationFrame(async()=>{res(await fn(...args))})})})}if(typeof node.__node.repeat==="number"||typeof node.__node.recursive==="number"){let fn=node.__operator;node.__setOperator(async(...args)=>{let i=node.__node.repeat?node.__node.repeat:node.__node.recursive;let result;let repeater=async(tick,...inp)=>{while(tick>0){if(node.__node.delay||node.__node.frame){fn(...inp).then(async res=>{if(node.__node.recursive){await repeater(tick,res)}else await repeater(tick,...inp)});break}else result=await fn(...args);tick--}};await repeater(i,...args);return result})}if(node.__node.loop&&typeof node.__node.loop==="number"){let fn=node.__operator;let time=node.__node.loop;node.__setOperator((...args)=>{if(!("looping"in node.__node))node.__node.looping=true;if(node.__node.looping){let last=performance.now();fn(...args);node.__node.loops[loopId]=setTimeout(()=>{let now=performance.now();let overshoot=now-last-node.__node.loop;if(overshoot>0)time=node.__node.loop-overshoot;else time=node.__node.loop;if(time<=0)time=node.__node.loop;node.__operator(...args)},time)}});if(node.__node.looping)node.__operator();let ondelete=node2=>{if(node2.__node.looping)node2.__node.looping=false;if(node2.__node.loops[loopId]){clearTimeout(node2.__node.loops[loopId]);cancelAnimationFrame(node2.__node.loops[loopId])}};node.__addOndisconnected(ondelete)}}};var animate=(node,parent,graph)=>{if(node.__node.animate===true||node.__animation){let fn=node.__operator;node.__setOperator((...args)=>{if(!("animating"in node.__node))node.__node.animating=true;if(node.__node.animating){if(typeof node.__animation==="function")node.__animation(...args);else fn(...args);node.__node.animationFrame=requestAnimationFrame(()=>{node.__operator(...args)})}});if(node.__node.animating||(!("animating"in node.__node)||node.__node.animating)&&node.__animation)setTimeout(()=>{node.__node.animationFrame=requestAnimationFrame(node.__operator)},10);let ondelete=node2=>{if(node2.__node.animating)node2.__node.animating=false;if(node2.__node.animationFrame)cancelAnimationFrame(node2.__node.animationFrame)};node.__addOndisconnected(ondelete)}};var branching=(node,parent,graph)=>{if(typeof node.__branch==="object"&&node.__operator&&!node.__branchApplied){let fn=node.__operator;node.__branchApplied=true;node.__operator=(...args)=>{let result=fn(...args);for(const key in node.__branch){let triggered=()=>{if(typeof node.__branch[key].then==="function"){node.__branch[key].then(result)}else if(node.__branch[key].then instanceof GraphNode&&node.__branch[key].then.__operator){node.__branch[key].then.__operator(result)}else result=node.__branch[key].then};if(typeof node.__branch[key].if==="function"){if(node.__branch[key].if(result)==true){triggered()}}else if(node.__branch[key].if===result){triggered()}}return result}}if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(node.__listeners[key].branch&&!node.__listeners[key].branchApplied){let fn=node.__listeners[key].callback;node.__listeners[key].branchApplied=true;node.__listeners.callback=ret=>{let triggered=()=>{if(typeof node.__listeners[key].branch.then==="function"){ret=node.__listeners[key].branch.then(ret)}else if(node.__listeners[key].branch.then instanceof GraphNode&&node.__listeners[key].branch.then.__operator){ret=node.__listeners[key].branch.then.__operator(ret)}else ret=node.__listeners[key].branch.then};if(typeof node.__listeners[key].branch.if==="function"){if(node.__listeners[key].branch.if(ret)){triggered()}}else if(node.__listeners[key].branch.if===ret){triggered()}return fn(ret)}}}}}};var triggerListenerOncreate=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(node.__listeners[key].oncreate){node.__listeners[key].callback(node.__listeners[key].oncreate)}}}}};var bindListener=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(typeof node.__listeners[key].binding==="object"){node.__listeners.callback=node.__listeners.callback.bind(node.__listeners[key].binding)}}}}};var transformListenerResult=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(typeof node.__listeners[key].transform==="function"&&!node.__listeners[key].transformApplied){let fn=node.__listeners[key].callback;node.__listeners[key].transformApplied=true;node.__listeners.callback=ret=>{ret=node.__listeners[key].transform(ret);return fn(ret)}}}}}};var substitute__operator=(node,parent,graph)=>{if(node.post&&!node.__operator){node.__setOperator(node.post)}else if(!node.__operator&&typeof node.get=="function"){node.__setOperator(node.get)}if(!node.get&&node.__operator){}if(node.aliases){node.aliases.forEach(a=>{graph.set(a,node);let ondelete=node2=>{graph.__node.nodes.delete(a)};node.__addOndisconnected(ondelete)})}if(typeof graph.__node.roots?.[node.__node.tag]==="object"&&node.get)graph.__node.roots[node.__node.tag].get=node.get};var loaders={backprop,loop,animate,branching,triggerListenerOncreate,bindListener,transformListenerResult,substitute__operator};var Service=class extends Graph{name=`service${Math.floor(Math.random()*1e15)}`;restrict;constructor(options){super({...options,loaders:options?.loaders?Object.assign({...loaders},options.loaders):{...loaders}});if(options?.services)this.addServices(options.services);if(options?.restrict)this.restrict=options.restrict;this.load(this)}addServices=services=>{for(const s in services){if(typeof services[s]==="function")services[s]=new services[s];if(services[s]?.__node?.loaders)Object.assign(this.__node.loaders,services[s].__node.loaders);if(services[s]?.__node?.nodes){services[s].__node.nodes.forEach((n,tag)=>{if(!this.get(tag)){this.set(tag,n)}else this.set(s+"."+tag,n)});this.__node.nodes.forEach((n,k)=>{if(!services[s].__node.nodes.get(k))services[s].__node.nodes.set(k,n)});let set=this.set;this.set=(tag,node)=>{services[s].set(tag,node);return set(tag,node)};let del=this.delete;this.delete=tag=>{services[s].delete(tag);return del(tag)}}else if(typeof services[s]==="object"){this.load(services[s])}}};handleMethod=(route,method,args)=>{let m=method.toLowerCase();let src=this.__node.nodes.get(route);if(!src){src=this.__node.roots[route]}if(src?.[m]){if(typeof src[m]!=="function"){if(args){if(Array.isArray(args)&&args.length===1)src[m]=args[0];else src[m]=args;return}return src[m]}else{if(Array.isArray(args))return src[m](...args);else return src[m](args)}}else return this.handleServiceMessage({route,args,method})};handleServiceMessage(message){let call;if(typeof message==="object"){if(message.route)call=message.route;else if(message.node)call=message.node}if(call){if(Array.isArray(message.args))return this.run(call,...message.args);else return this.run(call,message.args)}else return message}handleGraphNodeCall(route,args){if(!route)return args;if(args?.args){this.handleServiceMessage(args)}else if(Array.isArray(args))return this.run(route,...args);else return this.run(route,args)}transmit=(...args)=>{if(typeof args[0]==="object"){const message=args[0];if(message.method){return this.handleMethod(message.route,message.method,message.args)}else if(message.route){return this.handleServiceMessage(message)}else if(message.node){return this.handleGraphNodeCall(message.node,message.args)}else if(this.__node.keepState){if(message.route)this.setState({[message.route]:message.args});if(message.node)this.setState({[message.node]:message.args})}return void 0}else return void 0};receive=(...args)=>{if(args[0]){let message=args[0];if(typeof message==="string"){let substr=message.substring(0,8);if(substr.includes("{")||substr.includes("[")){if(substr.includes("\\"))message=message.replace(/\\/g,"");if(message[0]==='"'){message=message.substring(1,message.length-1)};message=JSON.parse(message)}}if(typeof message==="object"){if(message.method){if(this.restrict?.[message.route])return void 0;return this.handleMethod(message.route,message.method,message.args)}else if(message.route){if(this.restrict?.[message.route])return void 0;return this.handleServiceMessage(message)}else if(message.node){if(typeof message.node==="string"&&this.restrict?.[message.node])return void 0;return this.handleGraphNodeCall(message.node,message.args)}else if(this.__node.keepState){if(message.route)this.setState({[message.route]:message.args});if(message.node)this.setState({[message.node]:message.args})}return void 0}}return void 0};pipe=(source,destination,endpoint,method,callback)=>{if(source instanceof GraphNode){if(callback)return this.subscribe(source,res=>{let mod=callback(res);if(mod!==void 0)this.transmit({route:destination,args:mod,method});else this.transmit({route:destination,args:res,method},endpoint)});else return this.subscribe(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})}else if(typeof source==="string")return this.subscribe(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})};pipeOnce=(source,destination,endpoint,method,callback)=>{if(source instanceof GraphNode){if(callback)return source.__node.state.subscribeEventOnce(source.__node.unique,res=>{let mod=callback(res);if(mod!==void 0)this.transmit({route:destination,args:mod,method});else this.transmit({route:destination,args:res,method},endpoint)});else return this.__node.state.subscribeEventOnce(source.__node.unique,res=>{this.transmit({route:destination,args:res,method},endpoint)})}else if(typeof source==="string")return this.__node.state.subscribeEventOnce(this.__node.nodes.get(source).__node.unique,res=>{this.transmit({route:destination,args:res,method},endpoint)})};terminate=(...args)=>{};isTypedArray=isTypedArray;recursivelyAssign=recursivelyAssign2;spliceTypedArray=spliceTypedArray;ping=()=>{console.log("pinged!");return"pong"};echo=(...args)=>{this.transmit(...args);return args};log=(...args)=>{console.log(...args);return true};error=(...args)=>{console.error(...args);return true}};function isTypedArray(x2){return ArrayBuffer.isView(x2)&&Object.prototype.toString.call(x2)!=="[object DataView]"}var recursivelyAssign2=(target,obj)=>{for(const key in obj){if(obj[key]?.constructor.name==="Object"&&!Array.isArray(obj[key])){if(target[key]?.constructor.name==="Object"&&!Array.isArray(target[key]))recursivelyAssign2(target[key],obj[key]);else target[key]=recursivelyAssign2({},obj[key])}else target[key]=obj[key]}return target};function spliceTypedArray(arr,start,end){let s=arr.subarray(0,start);let e;if(end){e=arr.subarray(end+1)}let ta;if(s.length>0||e?.length>0)ta=new arr.constructor(s.length+e.length);if(ta){if(s.length>0)ta.set(s);if(e&&e.length>0)ta.set(e,s.length)}return ta}var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf;var __hasOwnProp=Object.prototype.hasOwnProperty;var __require2=(x2=>typeof __require!=="undefined"?__require:typeof Proxy!=="undefined"?new Proxy(x2,{get:(a,b)=>(typeof __require!=="undefined"?__require:a)[b]}):x2)(function(x2){if(typeof __require!=="undefined")return __require.apply(this,arguments);throw Error('Dynamic require of "'+x2+'" is not supported')});var __commonJS=(cb,mod)=>function __require22(){return mod||(0,cb[__getOwnPropNames(cb)[0]])((mod={exports:{}}).exports,mod),mod.exports};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from==="object"||typeof from==="function"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:true}):target,mod));var require_gpu_browser_min=__commonJS({"src/gpu-browser.min.js"(exports,module){"use strict";(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}f()}})(function(){var define2,module2,exports2;return function(){function r(e,n,t){function o(i2,f){if(!n[i2]){if(!e[i2]){var c="function"==typeof __require2&&__require2;if(!f&&c)return c(i2,true);if(u)return u(i2,true);var a=new Error("Cannot find module '"+i2+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i2]={exports:{}};e[i2][0].call(p.exports,function(r2){var n2=e[i2][1][r2];return o(n2||r2)},p,p.exports,r,e,n,t)}return n[i2].exports}for(var u="function"==typeof __require2&&__require2,i=0;icode){return false}pos+=set[i+1];if(pos>=code){return true}}}function isIdentifierStart(code,astral){if(code<65){return code===36}if(code<91){return true}if(code<97){return code===95}if(code<123){return true}if(code<=65535){return code>=170&&nonASCIIidentifierStart.test(String.fromCharCode(code))}if(astral===false){return false}return isInAstralSet(code,astralIdentifierStartCodes)}function isIdentifierChar(code,astral){if(code<48){return code===36}if(code<58){return true}if(code<65){return false}if(code<91){return true}if(code<97){return code===95}if(code<123){return true}if(code<=65535){return code>=170&&nonASCIIidentifier.test(String.fromCharCode(code))}if(astral===false){return false}return isInAstralSet(code,astralIdentifierStartCodes)||isInAstralSet(code,astralIdentifierCodes)}var TokenType=function TokenType2(label,conf){if(conf===void 0)conf={};this.label=label;this.keyword=conf.keyword;this.beforeExpr=!!conf.beforeExpr;this.startsExpr=!!conf.startsExpr;this.isLoop=!!conf.isLoop;this.isAssign=!!conf.isAssign;this.prefix=!!conf.prefix;this.postfix=!!conf.postfix;this.binop=conf.binop||null;this.updateContext=null};function binop(name2,prec){return new TokenType(name2,{beforeExpr:true,binop:prec})}var beforeExpr={beforeExpr:true},startsExpr={startsExpr:true};var keywords$1={};function kw(name2,options){if(options===void 0)options={};options.keyword=name2;return keywords$1[name2]=new TokenType(name2,options)}var types={num:new TokenType("num",startsExpr),regexp:new TokenType("regexp",startsExpr),string:new TokenType("string",startsExpr),name:new TokenType("name",startsExpr),eof:new TokenType("eof"),bracketL:new TokenType("[",{beforeExpr:true,startsExpr:true}),bracketR:new TokenType("]"),braceL:new TokenType("{",{beforeExpr:true,startsExpr:true}),braceR:new TokenType("}"),parenL:new TokenType("(",{beforeExpr:true,startsExpr:true}),parenR:new TokenType(")"),comma:new TokenType(",",beforeExpr),semi:new TokenType(";",beforeExpr),colon:new TokenType(":",beforeExpr),dot:new TokenType("."),question:new TokenType("?",beforeExpr),arrow:new TokenType("=>",beforeExpr),template:new TokenType("template"),invalidTemplate:new TokenType("invalidTemplate"),ellipsis:new TokenType("...",beforeExpr),backQuote:new TokenType("`",startsExpr),dollarBraceL:new TokenType("${",{beforeExpr:true,startsExpr:true}),eq:new TokenType("=",{beforeExpr:true,isAssign:true}),assign:new TokenType("_=",{beforeExpr:true,isAssign:true}),incDec:new TokenType("++/--",{prefix:true,postfix:true,startsExpr:true}),prefix:new TokenType("!/~",{beforeExpr:true,prefix:true,startsExpr:true}),logicalOR:binop("||",1),logicalAND:binop("&&",2),bitwiseOR:binop("|",3),bitwiseXOR:binop("^",4),bitwiseAND:binop("&",5),equality:binop("==/!=/===/!==",6),relational:binop("/<=/>=",7),bitShift:binop("<>/>>>",8),plusMin:new TokenType("+/-",{beforeExpr:true,binop:9,prefix:true,startsExpr:true}),modulo:binop("%",10),star:binop("*",10),slash:binop("/",10),starstar:new TokenType("**",{beforeExpr:true}),_break:kw("break"),_case:kw("case",beforeExpr),_catch:kw("catch"),_continue:kw("continue"),_debugger:kw("debugger"),_default:kw("default",beforeExpr),_do:kw("do",{isLoop:true,beforeExpr:true}),_else:kw("else",beforeExpr),_finally:kw("finally"),_for:kw("for",{isLoop:true}),_function:kw("function",startsExpr),_if:kw("if"),_return:kw("return",beforeExpr),_switch:kw("switch"),_throw:kw("throw",beforeExpr),_try:kw("try"),_var:kw("var"),_const:kw("const"),_while:kw("while",{isLoop:true}),_with:kw("with"),_new:kw("new",{beforeExpr:true,startsExpr:true}),_this:kw("this",startsExpr),_super:kw("super",startsExpr),_class:kw("class",startsExpr),_extends:kw("extends",beforeExpr),_export:kw("export"),_import:kw("import",startsExpr),_null:kw("null",startsExpr),_true:kw("true",startsExpr),_false:kw("false",startsExpr),_in:kw("in",{beforeExpr:true,binop:7}),_instanceof:kw("instanceof",{beforeExpr:true,binop:7}),_typeof:kw("typeof",{beforeExpr:true,prefix:true,startsExpr:true}),_void:kw("void",{beforeExpr:true,prefix:true,startsExpr:true}),_delete:kw("delete",{beforeExpr:true,prefix:true,startsExpr:true})};var lineBreak=/\r\n?|\n|\u2028|\u2029/;var lineBreakG=new RegExp(lineBreak.source,"g");function isNewLine(code,ecma2019String){return code===10||code===13||!ecma2019String&&(code===8232||code===8233)}var nonASCIIwhitespace=/[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/;var skipWhiteSpace=/(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;var ref=Object.prototype;var hasOwnProperty=ref.hasOwnProperty;var toString=ref.toString;function has(obj,propName){return hasOwnProperty.call(obj,propName)}var isArray=Array.isArray||function(obj){return toString.call(obj)==="[object Array]"};function wordsRegexp(words){return new RegExp("^(?:"+words.replace(/ /g,"|")+")$")}var Position=function Position2(line,col){this.line=line;this.column=col};Position.prototype.offset=function offset(n){return new Position(this.line,this.column+n)};var SourceLocation=function SourceLocation2(p,start,end){this.start=start;this.end=end;if(p.sourceFile!==null){this.source=p.sourceFile}};function getLineInfo(input,offset){for(var line=1,cur=0;;){lineBreakG.lastIndex=cur;var match=lineBreakG.exec(input);if(match&&match.index=2015){options.ecmaVersion-=2009}if(options.allowReserved==null){options.allowReserved=options.ecmaVersion<5}if(isArray(options.onToken)){var tokens=options.onToken;options.onToken=function(token){return tokens.push(token)}}if(isArray(options.onComment)){options.onComment=pushComment(options,options.onComment)}return options}function pushComment(options,array){return function(block,text,start,end,startLoc,endLoc){var comment={type:block?"Block":"Line",value:text,start,end};if(options.locations){comment.loc=new SourceLocation(this,startLoc,endLoc)}if(options.ranges){comment.range=[start,end]}array.push(comment)}}var SCOPE_TOP=1,SCOPE_FUNCTION=2,SCOPE_VAR=SCOPE_TOP|SCOPE_FUNCTION,SCOPE_ASYNC=4,SCOPE_GENERATOR=8,SCOPE_ARROW=16,SCOPE_SIMPLE_CATCH=32,SCOPE_SUPER=64,SCOPE_DIRECT_SUPER=128;function functionFlags(async,generator){return SCOPE_FUNCTION|(async?SCOPE_ASYNC:0)|(generator?SCOPE_GENERATOR:0)}var BIND_NONE=0,BIND_VAR=1,BIND_LEXICAL=2,BIND_FUNCTION=3,BIND_SIMPLE_CATCH=4,BIND_OUTSIDE=5;var Parser=function Parser2(options,input,startPos){this.options=options=getOptions(options);this.sourceFile=options.sourceFile;this.keywords=wordsRegexp(keywords[options.ecmaVersion>=6?6:options.sourceType==="module"?"5module":5]);var reserved="";if(options.allowReserved!==true){for(var v=options.ecmaVersion;;v--){if(reserved=reservedWords[v]){break}}if(options.sourceType==="module"){reserved+=" await"}}this.reservedWords=wordsRegexp(reserved);var reservedStrict=(reserved?reserved+" ":"")+reservedWords.strict;this.reservedWordsStrict=wordsRegexp(reservedStrict);this.reservedWordsStrictBind=wordsRegexp(reservedStrict+" "+reservedWords.strictBind);this.input=String(input);this.containsEsc=false;if(startPos){this.pos=startPos;this.lineStart=this.input.lastIndexOf("\n",startPos-1)+1;this.curLine=this.input.slice(0,this.lineStart).split(lineBreak).length}else{this.pos=this.lineStart=0;this.curLine=1}this.type=types.eof;this.value=null;this.start=this.end=this.pos;this.startLoc=this.endLoc=this.curPosition();this.lastTokEndLoc=this.lastTokStartLoc=null;this.lastTokStart=this.lastTokEnd=this.pos;this.context=this.initialContext();this.exprAllowed=true;this.inModule=options.sourceType==="module";this.strict=this.inModule||this.strictDirective(this.pos);this.potentialArrowAt=-1;this.yieldPos=this.awaitPos=this.awaitIdentPos=0;this.labels=[];this.undefinedExports={};if(this.pos===0&&options.allowHashBang&&this.input.slice(0,2)==="#!"){this.skipLineComment(2)}this.scopeStack=[];this.enterScope(SCOPE_TOP);this.regexpState=null};var prototypeAccessors={inFunction:{configurable:true},inGenerator:{configurable:true},inAsync:{configurable:true},allowSuper:{configurable:true},allowDirectSuper:{configurable:true},treatFunctionsAsVar:{configurable:true}};Parser.prototype.parse=function parse2(){var node=this.options.program||this.startNode();this.nextToken();return this.parseTopLevel(node)};prototypeAccessors.inFunction.get=function(){return(this.currentVarScope().flags&SCOPE_FUNCTION)>0};prototypeAccessors.inGenerator.get=function(){return(this.currentVarScope().flags&SCOPE_GENERATOR)>0};prototypeAccessors.inAsync.get=function(){return(this.currentVarScope().flags&SCOPE_ASYNC)>0};prototypeAccessors.allowSuper.get=function(){return(this.currentThisScope().flags&SCOPE_SUPER)>0};prototypeAccessors.allowDirectSuper.get=function(){return(this.currentThisScope().flags&SCOPE_DIRECT_SUPER)>0};prototypeAccessors.treatFunctionsAsVar.get=function(){return this.treatFunctionsAsVarInScope(this.currentScope())};Parser.prototype.inNonArrowFunction=function inNonArrowFunction(){return(this.currentThisScope().flags&SCOPE_FUNCTION)>0};Parser.extend=function extend(){var plugins=[],len=arguments.length;while(len--)plugins[len]=arguments[len];var cls=this;for(var i=0;i-1){this.raiseRecoverable(refDestructuringErrors.trailingComma,"Comma is not permitted after the rest element")}var parens=isAssign?refDestructuringErrors.parenthesizedAssign:refDestructuringErrors.parenthesizedBind;if(parens>-1){this.raiseRecoverable(parens,"Parenthesized pattern")}};pp.checkExpressionErrors=function(refDestructuringErrors,andThrow){if(!refDestructuringErrors){return false}var shorthandAssign=refDestructuringErrors.shorthandAssign;var doubleProto=refDestructuringErrors.doubleProto;if(!andThrow){return shorthandAssign>=0||doubleProto>=0}if(shorthandAssign>=0){this.raise(shorthandAssign,"Shorthand property assignments are valid only in destructuring patterns")}if(doubleProto>=0){this.raiseRecoverable(doubleProto,"Redefinition of __proto__ property")}};pp.checkYieldAwaitInDefaultParams=function(){if(this.yieldPos&&(!this.awaitPos||this.yieldPos=6){this.unexpected()}return this.parseFunctionStatement(node,false,!context);case types._class:if(context){this.unexpected()}return this.parseClass(node,true);case types._if:return this.parseIfStatement(node);case types._return:return this.parseReturnStatement(node);case types._switch:return this.parseSwitchStatement(node);case types._throw:return this.parseThrowStatement(node);case types._try:return this.parseTryStatement(node);case types._const:case types._var:kind=kind||this.value;if(context&&kind!=="var"){this.unexpected()}return this.parseVarStatement(node,kind);case types._while:return this.parseWhileStatement(node);case types._with:return this.parseWithStatement(node);case types.braceL:return this.parseBlock(true,node);case types.semi:return this.parseEmptyStatement(node);case types._export:case types._import:if(this.options.ecmaVersion>10&&starttype===types._import){skipWhiteSpace.lastIndex=this.pos;var skip=skipWhiteSpace.exec(this.input);var next=this.pos+skip[0].length,nextCh=this.input.charCodeAt(next);if(nextCh===40){return this.parseExpressionStatement(node,this.parseExpression())}}if(!this.options.allowImportExportEverywhere){if(!topLevel){this.raise(this.start,"'import' and 'export' may only appear at the top level")}if(!this.inModule){this.raise(this.start,"'import' and 'export' may appear only with 'sourceType: module'")}}return starttype===types._import?this.parseImport(node):this.parseExport(node,exports5);default:if(this.isAsyncFunction()){if(context){this.unexpected()}this.next();return this.parseFunctionStatement(node,true,!context)}var maybeName=this.value,expr=this.parseExpression();if(starttype===types.name&&expr.type==="Identifier"&&this.eat(types.colon)){return this.parseLabeledStatement(node,maybeName,expr,context)}else{return this.parseExpressionStatement(node,expr)}}};pp$1.parseBreakContinueStatement=function(node,keyword){var isBreak=keyword==="break";this.next();if(this.eat(types.semi)||this.insertSemicolon()){node.label=null}else if(this.type!==types.name){this.unexpected()}else{node.label=this.parseIdent();this.semicolon()}var i=0;for(;i=6){this.eat(types.semi)}else{this.semicolon()}return this.finishNode(node,"DoWhileStatement")};pp$1.parseForStatement=function(node){this.next();var awaitAt=this.options.ecmaVersion>=9&&(this.inAsync||!this.inFunction&&this.options.allowAwaitOutsideFunction)&&this.eatContextual("await")?this.lastTokStart:-1;this.labels.push(loopLabel);this.enterScope(0);this.expect(types.parenL);if(this.type===types.semi){if(awaitAt>-1){this.unexpected(awaitAt)}return this.parseFor(node,null)}var isLet=this.isLet();if(this.type===types._var||this.type===types._const||isLet){var init$1=this.startNode(),kind=isLet?"let":this.value;this.next();this.parseVar(init$1,true,kind);this.finishNode(init$1,"VariableDeclaration");if((this.type===types._in||this.options.ecmaVersion>=6&&this.isContextual("of"))&&init$1.declarations.length===1){if(this.options.ecmaVersion>=9){if(this.type===types._in){if(awaitAt>-1){this.unexpected(awaitAt)}}else{node.await=awaitAt>-1}}return this.parseForIn(node,init$1)}if(awaitAt>-1){this.unexpected(awaitAt)}return this.parseFor(node,init$1)}var refDestructuringErrors=new DestructuringErrors;var init=this.parseExpression(true,refDestructuringErrors);if(this.type===types._in||this.options.ecmaVersion>=6&&this.isContextual("of")){if(this.options.ecmaVersion>=9){if(this.type===types._in){if(awaitAt>-1){this.unexpected(awaitAt)}}else{node.await=awaitAt>-1}}this.toAssignable(init,false,refDestructuringErrors);this.checkLVal(init);return this.parseForIn(node,init)}else{this.checkExpressionErrors(refDestructuringErrors,true)}if(awaitAt>-1){this.unexpected(awaitAt)}return this.parseFor(node,init)};pp$1.parseFunctionStatement=function(node,isAsync,declarationPosition){this.next();return this.parseFunction(node,FUNC_STATEMENT|(declarationPosition?0:FUNC_HANGING_STATEMENT),false,isAsync)};pp$1.parseIfStatement=function(node){this.next();node.test=this.parseParenExpression();node.consequent=this.parseStatement("if");node.alternate=this.eat(types._else)?this.parseStatement("if"):null;return this.finishNode(node,"IfStatement")};pp$1.parseReturnStatement=function(node){if(!this.inFunction&&!this.options.allowReturnOutsideFunction){this.raise(this.start,"'return' outside of function")}this.next();if(this.eat(types.semi)||this.insertSemicolon()){node.argument=null}else{node.argument=this.parseExpression();this.semicolon()}return this.finishNode(node,"ReturnStatement")};pp$1.parseSwitchStatement=function(node){this.next();node.discriminant=this.parseParenExpression();node.cases=[];this.expect(types.braceL);this.labels.push(switchLabel);this.enterScope(0);var cur;for(var sawDefault=false;this.type!==types.braceR;){if(this.type===types._case||this.type===types._default){var isCase=this.type===types._case;if(cur){this.finishNode(cur,"SwitchCase")}node.cases.push(cur=this.startNode());cur.consequent=[];this.next();if(isCase){cur.test=this.parseExpression()}else{if(sawDefault){this.raiseRecoverable(this.lastTokStart,"Multiple default clauses")}sawDefault=true;cur.test=null}this.expect(types.colon)}else{if(!cur){this.unexpected()}cur.consequent.push(this.parseStatement(null))}}this.exitScope();if(cur){this.finishNode(cur,"SwitchCase")}this.next();this.labels.pop();return this.finishNode(node,"SwitchStatement")};pp$1.parseThrowStatement=function(node){this.next();if(lineBreak.test(this.input.slice(this.lastTokEnd,this.start))){this.raise(this.lastTokEnd,"Illegal newline after throw")}node.argument=this.parseExpression();this.semicolon();return this.finishNode(node,"ThrowStatement")};var empty=[];pp$1.parseTryStatement=function(node){this.next();node.block=this.parseBlock();node.handler=null;if(this.type===types._catch){var clause=this.startNode();this.next();if(this.eat(types.parenL)){clause.param=this.parseBindingAtom();var simple=clause.param.type==="Identifier";this.enterScope(simple?SCOPE_SIMPLE_CATCH:0);this.checkLVal(clause.param,simple?BIND_SIMPLE_CATCH:BIND_LEXICAL);this.expect(types.parenR)}else{if(this.options.ecmaVersion<10){this.unexpected()}clause.param=null;this.enterScope(0)}clause.body=this.parseBlock(false);this.exitScope();node.handler=this.finishNode(clause,"CatchClause")}node.finalizer=this.eat(types._finally)?this.parseBlock():null;if(!node.handler&&!node.finalizer){this.raise(node.start,"Missing catch or finally clause")}return this.finishNode(node,"TryStatement")};pp$1.parseVarStatement=function(node,kind){this.next();this.parseVar(node,false,kind);this.semicolon();return this.finishNode(node,"VariableDeclaration")};pp$1.parseWhileStatement=function(node){this.next();node.test=this.parseParenExpression();this.labels.push(loopLabel);node.body=this.parseStatement("while");this.labels.pop();return this.finishNode(node,"WhileStatement")};pp$1.parseWithStatement=function(node){if(this.strict){this.raise(this.start,"'with' in strict mode")}this.next();node.object=this.parseParenExpression();node.body=this.parseStatement("with");return this.finishNode(node,"WithStatement")};pp$1.parseEmptyStatement=function(node){this.next();return this.finishNode(node,"EmptyStatement")};pp$1.parseLabeledStatement=function(node,maybeName,expr,context){for(var i$1=0,list=this.labels;i$1=0;i--){var label$1=this.labels[i];if(label$1.statementStart===node.start){label$1.statementStart=this.start;label$1.kind=kind}else{break}}this.labels.push({name:maybeName,kind,statementStart:this.start});node.body=this.parseStatement(context?context.indexOf("label")===-1?context+"label":context:"label");this.labels.pop();node.label=expr;return this.finishNode(node,"LabeledStatement")};pp$1.parseExpressionStatement=function(node,expr){node.expression=expr;this.semicolon();return this.finishNode(node,"ExpressionStatement")};pp$1.parseBlock=function(createNewLexicalScope,node){if(createNewLexicalScope===void 0)createNewLexicalScope=true;if(node===void 0)node=this.startNode();node.body=[];this.expect(types.braceL);if(createNewLexicalScope){this.enterScope(0)}while(!this.eat(types.braceR)){var stmt=this.parseStatement(null);node.body.push(stmt)}if(createNewLexicalScope){this.exitScope()}return this.finishNode(node,"BlockStatement")};pp$1.parseFor=function(node,init){node.init=init;this.expect(types.semi);node.test=this.type===types.semi?null:this.parseExpression();this.expect(types.semi);node.update=this.type===types.parenR?null:this.parseExpression();this.expect(types.parenR);node.body=this.parseStatement("for");this.exitScope();this.labels.pop();return this.finishNode(node,"ForStatement")};pp$1.parseForIn=function(node,init){var isForIn=this.type===types._in;this.next();if(init.type==="VariableDeclaration"&&init.declarations[0].init!=null&&(!isForIn||this.options.ecmaVersion<8||this.strict||init.kind!=="var"||init.declarations[0].id.type!=="Identifier")){this.raise(init.start,(isForIn?"for-in":"for-of")+" loop variable declaration may not have an initializer")}else if(init.type==="AssignmentPattern"){this.raise(init.start,"Invalid left-hand side in for-loop")}node.left=init;node.right=isForIn?this.parseExpression():this.parseMaybeAssign();this.expect(types.parenR);node.body=this.parseStatement("for");this.exitScope();this.labels.pop();return this.finishNode(node,isForIn?"ForInStatement":"ForOfStatement")};pp$1.parseVar=function(node,isFor,kind){node.declarations=[];node.kind=kind;for(;;){var decl=this.startNode();this.parseVarId(decl,kind);if(this.eat(types.eq)){decl.init=this.parseMaybeAssign(isFor)}else if(kind==="const"&&!(this.type===types._in||this.options.ecmaVersion>=6&&this.isContextual("of"))){this.unexpected()}else if(decl.id.type!=="Identifier"&&!(isFor&&(this.type===types._in||this.isContextual("of")))){this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value")}else{decl.init=null}node.declarations.push(this.finishNode(decl,"VariableDeclarator"));if(!this.eat(types.comma)){break}}return node};pp$1.parseVarId=function(decl,kind){decl.id=this.parseBindingAtom();this.checkLVal(decl.id,kind==="var"?BIND_VAR:BIND_LEXICAL,false)};var FUNC_STATEMENT=1,FUNC_HANGING_STATEMENT=2,FUNC_NULLABLE_ID=4;pp$1.parseFunction=function(node,statement,allowExpressionBody,isAsync){this.initFunction(node);if(this.options.ecmaVersion>=9||this.options.ecmaVersion>=6&&!isAsync){if(this.type===types.star&&statement&FUNC_HANGING_STATEMENT){this.unexpected()}node.generator=this.eat(types.star)}if(this.options.ecmaVersion>=8){node.async=!!isAsync}if(statement&FUNC_STATEMENT){node.id=statement&FUNC_NULLABLE_ID&&this.type!==types.name?null:this.parseIdent();if(node.id&&!(statement&FUNC_HANGING_STATEMENT)){this.checkLVal(node.id,this.strict||node.generator||node.async?this.treatFunctionsAsVar?BIND_VAR:BIND_LEXICAL:BIND_FUNCTION)}}var oldYieldPos=this.yieldPos,oldAwaitPos=this.awaitPos,oldAwaitIdentPos=this.awaitIdentPos;this.yieldPos=0;this.awaitPos=0;this.awaitIdentPos=0;this.enterScope(functionFlags(node.async,node.generator));if(!(statement&FUNC_STATEMENT)){node.id=this.type===types.name?this.parseIdent():null}this.parseFunctionParams(node);this.parseFunctionBody(node,allowExpressionBody,false);this.yieldPos=oldYieldPos;this.awaitPos=oldAwaitPos;this.awaitIdentPos=oldAwaitIdentPos;return this.finishNode(node,statement&FUNC_STATEMENT?"FunctionDeclaration":"FunctionExpression")};pp$1.parseFunctionParams=function(node){this.expect(types.parenL);node.params=this.parseBindingList(types.parenR,false,this.options.ecmaVersion>=8);this.checkYieldAwaitInDefaultParams()};pp$1.parseClass=function(node,isStatement){this.next();var oldStrict=this.strict;this.strict=true;this.parseClassId(node,isStatement);this.parseClassSuper(node);var classBody=this.startNode();var hadConstructor=false;classBody.body=[];this.expect(types.braceL);while(!this.eat(types.braceR)){var element=this.parseClassElement(node.superClass!==null);if(element){classBody.body.push(element);if(element.type==="MethodDefinition"&&element.kind==="constructor"){if(hadConstructor){this.raise(element.start,"Duplicate constructor in the same class")}hadConstructor=true}}}node.body=this.finishNode(classBody,"ClassBody");this.strict=oldStrict;return this.finishNode(node,isStatement?"ClassDeclaration":"ClassExpression")};pp$1.parseClassElement=function(constructorAllowsSuper){var this$1=this;if(this.eat(types.semi)){return null}var method=this.startNode();var tryContextual=function(k,noLineBreak){if(noLineBreak===void 0)noLineBreak=false;var start=this$1.start,startLoc=this$1.startLoc;if(!this$1.eatContextual(k)){return false}if(this$1.type!==types.parenL&&(!noLineBreak||!this$1.canInsertSemicolon())){return true}if(method.key){this$1.unexpected()}method.computed=false;method.key=this$1.startNodeAt(start,startLoc);method.key.name=k;this$1.finishNode(method.key,"Identifier");return false};method.kind="method";method.static=tryContextual("static");var isGenerator=this.eat(types.star);var isAsync=false;if(!isGenerator){if(this.options.ecmaVersion>=8&&tryContextual("async",true)){isAsync=true;isGenerator=this.options.ecmaVersion>=9&&this.eat(types.star)}else if(tryContextual("get")){method.kind="get"}else if(tryContextual("set")){method.kind="set"}}if(!method.key){this.parsePropertyName(method)}var key=method.key;var allowsDirectSuper=false;if(!method.computed&&!method.static&&(key.type==="Identifier"&&key.name==="constructor"||key.type==="Literal"&&key.value==="constructor")){if(method.kind!=="method"){this.raise(key.start,"Constructor can't have get/set modifier")}if(isGenerator){this.raise(key.start,"Constructor can't be a generator")}if(isAsync){this.raise(key.start,"Constructor can't be an async method")}method.kind="constructor";allowsDirectSuper=constructorAllowsSuper}else if(method.static&&key.type==="Identifier"&&key.name==="prototype"){this.raise(key.start,"Classes may not have a static property named prototype")}this.parseClassMethod(method,isGenerator,isAsync,allowsDirectSuper);if(method.kind==="get"&&method.value.params.length!==0){this.raiseRecoverable(method.value.start,"getter should have no params")}if(method.kind==="set"&&method.value.params.length!==1){this.raiseRecoverable(method.value.start,"setter should have exactly one param")}if(method.kind==="set"&&method.value.params[0].type==="RestElement"){this.raiseRecoverable(method.value.params[0].start,"Setter cannot use rest params")}return method};pp$1.parseClassMethod=function(method,isGenerator,isAsync,allowsDirectSuper){method.value=this.parseMethod(isGenerator,isAsync,allowsDirectSuper);return this.finishNode(method,"MethodDefinition")};pp$1.parseClassId=function(node,isStatement){if(this.type===types.name){node.id=this.parseIdent();if(isStatement){this.checkLVal(node.id,BIND_LEXICAL,false)}}else{if(isStatement===true){this.unexpected()}node.id=null}};pp$1.parseClassSuper=function(node){node.superClass=this.eat(types._extends)?this.parseExprSubscripts():null};pp$1.parseExport=function(node,exports5){this.next();if(this.eat(types.star)){this.expectContextual("from");if(this.type!==types.string){this.unexpected()}node.source=this.parseExprAtom();this.semicolon();return this.finishNode(node,"ExportAllDeclaration")}if(this.eat(types._default)){this.checkExport(exports5,"default",this.lastTokStart);var isAsync;if(this.type===types._function||(isAsync=this.isAsyncFunction())){var fNode=this.startNode();this.next();if(isAsync){this.next()}node.declaration=this.parseFunction(fNode,FUNC_STATEMENT|FUNC_NULLABLE_ID,false,isAsync)}else if(this.type===types._class){var cNode=this.startNode();node.declaration=this.parseClass(cNode,"nullableID")}else{node.declaration=this.parseMaybeAssign();this.semicolon()}return this.finishNode(node,"ExportDefaultDeclaration")}if(this.shouldParseExportStatement()){node.declaration=this.parseStatement(null);if(node.declaration.type==="VariableDeclaration"){this.checkVariableExport(exports5,node.declaration.declarations)}else{this.checkExport(exports5,node.declaration.id.name,node.declaration.id.start)}node.specifiers=[];node.source=null}else{node.declaration=null;node.specifiers=this.parseExportSpecifiers(exports5);if(this.eatContextual("from")){if(this.type!==types.string){this.unexpected()}node.source=this.parseExprAtom()}else{for(var i=0,list=node.specifiers;i=6&&node){switch(node.type){case"Identifier":if(this.inAsync&&node.name==="await"){this.raise(node.start,"Cannot use 'await' as identifier inside an async function")}break;case"ObjectPattern":case"ArrayPattern":case"RestElement":break;case"ObjectExpression":node.type="ObjectPattern";if(refDestructuringErrors){this.checkPatternErrors(refDestructuringErrors,true)}for(var i=0,list=node.properties;i=8&&!containsEsc&&id.name==="async"&&!this.canInsertSemicolon()&&this.eat(types._function)){return this.parseFunction(this.startNodeAt(startPos,startLoc),0,false,true)}if(canBeArrow&&!this.canInsertSemicolon()){if(this.eat(types.arrow)){return this.parseArrowExpression(this.startNodeAt(startPos,startLoc),[id],false)}if(this.options.ecmaVersion>=8&&id.name==="async"&&this.type===types.name&&!containsEsc){id=this.parseIdent(false);if(this.canInsertSemicolon()||!this.eat(types.arrow)){this.unexpected()}return this.parseArrowExpression(this.startNodeAt(startPos,startLoc),[id],true)}}return id;case types.regexp:var value2=this.value;node=this.parseLiteral(value2.value);node.regex={pattern:value2.pattern,flags:value2.flags};return node;case types.num:case types.string:return this.parseLiteral(this.value);case types._null:case types._true:case types._false:node=this.startNode();node.value=this.type===types._null?null:this.type===types._true;node.raw=this.type.keyword;this.next();return this.finishNode(node,"Literal");case types.parenL:var start=this.start,expr=this.parseParenAndDistinguishExpression(canBeArrow);if(refDestructuringErrors){if(refDestructuringErrors.parenthesizedAssign<0&&!this.isSimpleAssignTarget(expr)){refDestructuringErrors.parenthesizedAssign=start}if(refDestructuringErrors.parenthesizedBind<0){refDestructuringErrors.parenthesizedBind=start}}return expr;case types.bracketL:node=this.startNode();this.next();node.elements=this.parseExprList(types.bracketR,true,true,refDestructuringErrors);return this.finishNode(node,"ArrayExpression");case types.braceL:return this.parseObj(false,refDestructuringErrors);case types._function:node=this.startNode();this.next();return this.parseFunction(node,0);case types._class:return this.parseClass(this.startNode(),false);case types._new:return this.parseNew();case types.backQuote:return this.parseTemplate();case types._import:if(this.options.ecmaVersion>=11){return this.parseExprImport()}else{return this.unexpected()}default:this.unexpected()}};pp$3.parseExprImport=function(){var node=this.startNode();this.next();switch(this.type){case types.parenL:return this.parseDynamicImport(node);default:this.unexpected()}};pp$3.parseDynamicImport=function(node){this.next();node.source=this.parseMaybeAssign();if(!this.eat(types.parenR)){var errorPos=this.start;if(this.eat(types.comma)&&this.eat(types.parenR)){this.raiseRecoverable(errorPos,"Trailing comma is not allowed in import()")}else{this.unexpected(errorPos)}}return this.finishNode(node,"ImportExpression")};pp$3.parseLiteral=function(value2){var node=this.startNode();node.value=value2;node.raw=this.input.slice(this.start,this.end);if(node.raw.charCodeAt(node.raw.length-1)===110){node.bigint=node.raw.slice(0,-1)}this.next();return this.finishNode(node,"Literal")};pp$3.parseParenExpression=function(){this.expect(types.parenL);var val=this.parseExpression();this.expect(types.parenR);return val};pp$3.parseParenAndDistinguishExpression=function(canBeArrow){var startPos=this.start,startLoc=this.startLoc,val,allowTrailingComma=this.options.ecmaVersion>=8;if(this.options.ecmaVersion>=6){this.next();var innerStartPos=this.start,innerStartLoc=this.startLoc;var exprList=[],first=true,lastIsComma=false;var refDestructuringErrors=new DestructuringErrors,oldYieldPos=this.yieldPos,oldAwaitPos=this.awaitPos,spreadStart;this.yieldPos=0;this.awaitPos=0;while(this.type!==types.parenR){first?first=false:this.expect(types.comma);if(allowTrailingComma&&this.afterTrailingComma(types.parenR,true)){lastIsComma=true;break}else if(this.type===types.ellipsis){spreadStart=this.start;exprList.push(this.parseParenItem(this.parseRestBinding()));if(this.type===types.comma){this.raise(this.start,"Comma is not permitted after the rest element")}break}else{exprList.push(this.parseMaybeAssign(false,refDestructuringErrors,this.parseParenItem))}}var innerEndPos=this.start,innerEndLoc=this.startLoc;this.expect(types.parenR);if(canBeArrow&&!this.canInsertSemicolon()&&this.eat(types.arrow)){this.checkPatternErrors(refDestructuringErrors,false);this.checkYieldAwaitInDefaultParams();this.yieldPos=oldYieldPos;this.awaitPos=oldAwaitPos;return this.parseParenArrowList(startPos,startLoc,exprList)}if(!exprList.length||lastIsComma){this.unexpected(this.lastTokStart)}if(spreadStart){this.unexpected(spreadStart)}this.checkExpressionErrors(refDestructuringErrors,true);this.yieldPos=oldYieldPos||this.yieldPos;this.awaitPos=oldAwaitPos||this.awaitPos;if(exprList.length>1){val=this.startNodeAt(innerStartPos,innerStartLoc);val.expressions=exprList;this.finishNodeAt(val,"SequenceExpression",innerEndPos,innerEndLoc)}else{val=exprList[0]}}else{val=this.parseParenExpression()}if(this.options.preserveParens){var par=this.startNodeAt(startPos,startLoc);par.expression=val;return this.finishNode(par,"ParenthesizedExpression")}else{return val}};pp$3.parseParenItem=function(item){return item};pp$3.parseParenArrowList=function(startPos,startLoc,exprList){return this.parseArrowExpression(this.startNodeAt(startPos,startLoc),exprList)};var empty$1=[];pp$3.parseNew=function(){if(this.containsEsc){this.raiseRecoverable(this.start,"Escape sequence in keyword new")}var node=this.startNode();var meta=this.parseIdent(true);if(this.options.ecmaVersion>=6&&this.eat(types.dot)){node.meta=meta;var containsEsc=this.containsEsc;node.property=this.parseIdent(true);if(node.property.name!=="target"||containsEsc){this.raiseRecoverable(node.property.start,"The only valid meta property for new is new.target")}if(!this.inNonArrowFunction()){this.raiseRecoverable(node.start,"new.target can only be used in functions")}return this.finishNode(node,"MetaProperty")}var startPos=this.start,startLoc=this.startLoc,isImport=this.type===types._import;node.callee=this.parseSubscripts(this.parseExprAtom(),startPos,startLoc,true);if(isImport&&node.callee.type==="ImportExpression"){this.raise(startPos,"Cannot use new with import()")}if(this.eat(types.parenL)){node.arguments=this.parseExprList(types.parenR,this.options.ecmaVersion>=8,false)}else{node.arguments=empty$1}return this.finishNode(node,"NewExpression")};pp$3.parseTemplateElement=function(ref2){var isTagged=ref2.isTagged;var elem=this.startNode();if(this.type===types.invalidTemplate){if(!isTagged){this.raiseRecoverable(this.start,"Bad escape sequence in untagged template literal")}elem.value={raw:this.value,cooked:null}}else{elem.value={raw:this.input.slice(this.start,this.end).replace(/\r\n?/g,"\n"),cooked:this.value}}this.next();elem.tail=this.type===types.backQuote;return this.finishNode(elem,"TemplateElement")};pp$3.parseTemplate=function(ref2){if(ref2===void 0)ref2={};var isTagged=ref2.isTagged;if(isTagged===void 0)isTagged=false;var node=this.startNode();this.next();node.expressions=[];var curElt=this.parseTemplateElement({isTagged});node.quasis=[curElt];while(!curElt.tail){if(this.type===types.eof){this.raise(this.pos,"Unterminated template literal")}this.expect(types.dollarBraceL);node.expressions.push(this.parseExpression());this.expect(types.braceR);node.quasis.push(curElt=this.parseTemplateElement({isTagged}))}this.next();return this.finishNode(node,"TemplateLiteral")};pp$3.isAsyncProp=function(prop){return!prop.computed&&prop.key.type==="Identifier"&&prop.key.name==="async"&&(this.type===types.name||this.type===types.num||this.type===types.string||this.type===types.bracketL||this.type.keyword||this.options.ecmaVersion>=9&&this.type===types.star)&&!lineBreak.test(this.input.slice(this.lastTokEnd,this.start))};pp$3.parseObj=function(isPattern,refDestructuringErrors){var node=this.startNode(),first=true,propHash={};node.properties=[];this.next();while(!this.eat(types.braceR)){if(!first){this.expect(types.comma);if(this.options.ecmaVersion>=5&&this.afterTrailingComma(types.braceR)){break}}else{first=false}var prop=this.parseProperty(isPattern,refDestructuringErrors);if(!isPattern){this.checkPropClash(prop,propHash,refDestructuringErrors)}node.properties.push(prop)}return this.finishNode(node,isPattern?"ObjectPattern":"ObjectExpression")};pp$3.parseProperty=function(isPattern,refDestructuringErrors){var prop=this.startNode(),isGenerator,isAsync,startPos,startLoc;if(this.options.ecmaVersion>=9&&this.eat(types.ellipsis)){if(isPattern){prop.argument=this.parseIdent(false);if(this.type===types.comma){this.raise(this.start,"Comma is not permitted after the rest element")}return this.finishNode(prop,"RestElement")}if(this.type===types.parenL&&refDestructuringErrors){if(refDestructuringErrors.parenthesizedAssign<0){refDestructuringErrors.parenthesizedAssign=this.start}if(refDestructuringErrors.parenthesizedBind<0){refDestructuringErrors.parenthesizedBind=this.start}}prop.argument=this.parseMaybeAssign(false,refDestructuringErrors);if(this.type===types.comma&&refDestructuringErrors&&refDestructuringErrors.trailingComma<0){refDestructuringErrors.trailingComma=this.start}return this.finishNode(prop,"SpreadElement")}if(this.options.ecmaVersion>=6){prop.method=false;prop.shorthand=false;if(isPattern||refDestructuringErrors){startPos=this.start;startLoc=this.startLoc}if(!isPattern){isGenerator=this.eat(types.star)}}var containsEsc=this.containsEsc;this.parsePropertyName(prop);if(!isPattern&&!containsEsc&&this.options.ecmaVersion>=8&&!isGenerator&&this.isAsyncProp(prop)){isAsync=true;isGenerator=this.options.ecmaVersion>=9&&this.eat(types.star);this.parsePropertyName(prop,refDestructuringErrors)}else{isAsync=false}this.parsePropertyValue(prop,isPattern,isGenerator,isAsync,startPos,startLoc,refDestructuringErrors,containsEsc);return this.finishNode(prop,"Property")};pp$3.parsePropertyValue=function(prop,isPattern,isGenerator,isAsync,startPos,startLoc,refDestructuringErrors,containsEsc){if((isGenerator||isAsync)&&this.type===types.colon){this.unexpected()}if(this.eat(types.colon)){prop.value=isPattern?this.parseMaybeDefault(this.start,this.startLoc):this.parseMaybeAssign(false,refDestructuringErrors);prop.kind="init"}else if(this.options.ecmaVersion>=6&&this.type===types.parenL){if(isPattern){this.unexpected()}prop.kind="init";prop.method=true;prop.value=this.parseMethod(isGenerator,isAsync)}else if(!isPattern&&!containsEsc&&this.options.ecmaVersion>=5&&!prop.computed&&prop.key.type==="Identifier"&&(prop.key.name==="get"||prop.key.name==="set")&&(this.type!==types.comma&&this.type!==types.braceR)){if(isGenerator||isAsync){this.unexpected()}prop.kind=prop.key.name;this.parsePropertyName(prop);prop.value=this.parseMethod(false);var paramCount=prop.kind==="get"?0:1;if(prop.value.params.length!==paramCount){var start=prop.value.start;if(prop.kind==="get"){this.raiseRecoverable(start,"getter should have no params")}else{this.raiseRecoverable(start,"setter should have exactly one param")}}else{if(prop.kind==="set"&&prop.value.params[0].type==="RestElement"){this.raiseRecoverable(prop.value.params[0].start,"Setter cannot use rest params")}}}else if(this.options.ecmaVersion>=6&&!prop.computed&&prop.key.type==="Identifier"){if(isGenerator||isAsync){this.unexpected()}this.checkUnreserved(prop.key);if(prop.key.name==="await"&&!this.awaitIdentPos){this.awaitIdentPos=startPos}prop.kind="init";if(isPattern){prop.value=this.parseMaybeDefault(startPos,startLoc,prop.key)}else if(this.type===types.eq&&refDestructuringErrors){if(refDestructuringErrors.shorthandAssign<0){refDestructuringErrors.shorthandAssign=this.start}prop.value=this.parseMaybeDefault(startPos,startLoc,prop.key)}else{prop.value=prop.key}prop.shorthand=true}else{this.unexpected()}};pp$3.parsePropertyName=function(prop){if(this.options.ecmaVersion>=6){if(this.eat(types.bracketL)){prop.computed=true;prop.key=this.parseMaybeAssign();this.expect(types.bracketR);return prop.key}else{prop.computed=false}}return prop.key=this.type===types.num||this.type===types.string?this.parseExprAtom():this.parseIdent(this.options.allowReserved!=="never")};pp$3.initFunction=function(node){node.id=null;if(this.options.ecmaVersion>=6){node.generator=node.expression=false}if(this.options.ecmaVersion>=8){node.async=false}};pp$3.parseMethod=function(isGenerator,isAsync,allowDirectSuper){var node=this.startNode(),oldYieldPos=this.yieldPos,oldAwaitPos=this.awaitPos,oldAwaitIdentPos=this.awaitIdentPos;this.initFunction(node);if(this.options.ecmaVersion>=6){node.generator=isGenerator}if(this.options.ecmaVersion>=8){node.async=!!isAsync}this.yieldPos=0;this.awaitPos=0;this.awaitIdentPos=0;this.enterScope(functionFlags(isAsync,node.generator)|SCOPE_SUPER|(allowDirectSuper?SCOPE_DIRECT_SUPER:0));this.expect(types.parenL);node.params=this.parseBindingList(types.parenR,false,this.options.ecmaVersion>=8);this.checkYieldAwaitInDefaultParams();this.parseFunctionBody(node,false,true);this.yieldPos=oldYieldPos;this.awaitPos=oldAwaitPos;this.awaitIdentPos=oldAwaitIdentPos;return this.finishNode(node,"FunctionExpression")};pp$3.parseArrowExpression=function(node,params,isAsync){var oldYieldPos=this.yieldPos,oldAwaitPos=this.awaitPos,oldAwaitIdentPos=this.awaitIdentPos;this.enterScope(functionFlags(isAsync,false)|SCOPE_ARROW);this.initFunction(node);if(this.options.ecmaVersion>=8){node.async=!!isAsync}this.yieldPos=0;this.awaitPos=0;this.awaitIdentPos=0;node.params=this.toAssignableList(params,true);this.parseFunctionBody(node,true,false);this.yieldPos=oldYieldPos;this.awaitPos=oldAwaitPos;this.awaitIdentPos=oldAwaitIdentPos;return this.finishNode(node,"ArrowFunctionExpression")};pp$3.parseFunctionBody=function(node,isArrowFunction,isMethod){var isExpression=isArrowFunction&&this.type!==types.braceL;var oldStrict=this.strict,useStrict=false;if(isExpression){node.body=this.parseMaybeAssign();node.expression=true;this.checkParams(node,false)}else{var nonSimple=this.options.ecmaVersion>=7&&!this.isSimpleParamList(node.params);if(!oldStrict||nonSimple){useStrict=this.strictDirective(this.end);if(useStrict&&nonSimple){this.raiseRecoverable(node.start,"Illegal 'use strict' directive in function with non-simple parameter list")}}var oldLabels=this.labels;this.labels=[];if(useStrict){this.strict=true}this.checkParams(node,!oldStrict&&!useStrict&&!isArrowFunction&&!isMethod&&this.isSimpleParamList(node.params));node.body=this.parseBlock(false);node.expression=false;this.adaptDirectivePrologue(node.body.body);this.labels=oldLabels}this.exitScope();if(this.strict&&node.id){this.checkLVal(node.id,BIND_OUTSIDE)}this.strict=oldStrict};pp$3.isSimpleParamList=function(params){for(var i=0,list=params;i-1||scope.functions.indexOf(name2)>-1||scope.var.indexOf(name2)>-1;scope.lexical.push(name2);if(this.inModule&&scope.flags&SCOPE_TOP){delete this.undefinedExports[name2]}}else if(bindingType===BIND_SIMPLE_CATCH){var scope$1=this.currentScope();scope$1.lexical.push(name2)}else if(bindingType===BIND_FUNCTION){var scope$2=this.currentScope();if(this.treatFunctionsAsVar){redeclared=scope$2.lexical.indexOf(name2)>-1}else{redeclared=scope$2.lexical.indexOf(name2)>-1||scope$2.var.indexOf(name2)>-1}scope$2.functions.push(name2)}else{for(var i=this.scopeStack.length-1;i>=0;--i){var scope$3=this.scopeStack[i];if(scope$3.lexical.indexOf(name2)>-1&&!(scope$3.flags&SCOPE_SIMPLE_CATCH&&scope$3.lexical[0]===name2)||!this.treatFunctionsAsVarInScope(scope$3)&&scope$3.functions.indexOf(name2)>-1){redeclared=true;break}scope$3.var.push(name2);if(this.inModule&&scope$3.flags&SCOPE_TOP){delete this.undefinedExports[name2]}if(scope$3.flags&SCOPE_VAR){break}}}if(redeclared){this.raiseRecoverable(pos,"Identifier '"+name2+"' has already been declared")}};pp$5.checkLocalExport=function(id){if(this.scopeStack[0].lexical.indexOf(id.name)===-1&&this.scopeStack[0].var.indexOf(id.name)===-1){this.undefinedExports[id.name]=id}};pp$5.currentScope=function(){return this.scopeStack[this.scopeStack.length-1]};pp$5.currentVarScope=function(){for(var i=this.scopeStack.length-1;;i--){var scope=this.scopeStack[i];if(scope.flags&SCOPE_VAR){return scope}}};pp$5.currentThisScope=function(){for(var i=this.scopeStack.length-1;;i--){var scope=this.scopeStack[i];if(scope.flags&SCOPE_VAR&&!(scope.flags&SCOPE_ARROW)){return scope}}};var Node=function Node2(parser,pos,loc){this.type="";this.start=pos;this.end=0;if(parser.options.locations){this.loc=new SourceLocation(parser,loc)}if(parser.options.directSourceFile){this.sourceFile=parser.options.directSourceFile}if(parser.options.ranges){this.range=[pos,0]}};var pp$6=Parser.prototype;pp$6.startNode=function(){return new Node(this,this.start,this.startLoc)};pp$6.startNodeAt=function(pos,loc){return new Node(this,pos,loc)};function finishNodeAt(node,type,pos,loc){node.type=type;node.end=pos;if(this.options.locations){node.loc.end=loc}if(this.options.ranges){node.range[1]=pos}return node}pp$6.finishNode=function(node,type){return finishNodeAt.call(this,node,type,this.lastTokEnd,this.lastTokEndLoc)};pp$6.finishNodeAt=function(node,type,pos,loc){return finishNodeAt.call(this,node,type,pos,loc)};var TokContext=function TokContext2(token,isExpr,preserveSpace,override,generator){this.token=token;this.isExpr=!!isExpr;this.preserveSpace=!!preserveSpace;this.override=override;this.generator=!!generator};var types$1={b_stat:new TokContext("{",false),b_expr:new TokContext("{",true),b_tmpl:new TokContext("${",false),p_stat:new TokContext("(",false),p_expr:new TokContext("(",true),q_tmpl:new TokContext("`",true,true,function(p){return p.tryReadTemplateToken()}),f_stat:new TokContext("function",false),f_expr:new TokContext("function",true),f_expr_gen:new TokContext("function",true,false,null,true),f_gen:new TokContext("function",false,false,null,true)};var pp$7=Parser.prototype;pp$7.initialContext=function(){return[types$1.b_stat]};pp$7.braceIsBlock=function(prevType){var parent=this.curContext();if(parent===types$1.f_expr||parent===types$1.f_stat){return true}if(prevType===types.colon&&(parent===types$1.b_stat||parent===types$1.b_expr)){return!parent.isExpr}if(prevType===types._return||prevType===types.name&&this.exprAllowed){return lineBreak.test(this.input.slice(this.lastTokEnd,this.start))}if(prevType===types._else||prevType===types.semi||prevType===types.eof||prevType===types.parenR||prevType===types.arrow){return true}if(prevType===types.braceL){return parent===types$1.b_stat}if(prevType===types._var||prevType===types._const||prevType===types.name){return false}return!this.exprAllowed};pp$7.inGeneratorContext=function(){for(var i=this.context.length-1;i>=1;i--){var context=this.context[i];if(context.token==="function"){return context.generator}}return false};pp$7.updateContext=function(prevType){var update,type=this.type;if(type.keyword&&prevType===types.dot){this.exprAllowed=false}else if(update=type.updateContext){update.call(this,prevType)}else{this.exprAllowed=type.beforeExpr}};types.parenR.updateContext=types.braceR.updateContext=function(){if(this.context.length===1){this.exprAllowed=true;return}var out=this.context.pop();if(out===types$1.b_stat&&this.curContext().token==="function"){out=this.context.pop()}this.exprAllowed=!out.isExpr};types.braceL.updateContext=function(prevType){this.context.push(this.braceIsBlock(prevType)?types$1.b_stat:types$1.b_expr);this.exprAllowed=true};types.dollarBraceL.updateContext=function(){this.context.push(types$1.b_tmpl);this.exprAllowed=true};types.parenL.updateContext=function(prevType){var statementParens=prevType===types._if||prevType===types._for||prevType===types._with||prevType===types._while;this.context.push(statementParens?types$1.p_stat:types$1.p_expr);this.exprAllowed=true};types.incDec.updateContext=function(){};types._function.updateContext=types._class.updateContext=function(prevType){if(prevType.beforeExpr&&prevType!==types.semi&&prevType!==types._else&&!(prevType===types._return&&lineBreak.test(this.input.slice(this.lastTokEnd,this.start)))&&!((prevType===types.colon||prevType===types.braceL)&&this.curContext()===types$1.b_stat)){this.context.push(types$1.f_expr)}else{this.context.push(types$1.f_stat)}this.exprAllowed=false};types.backQuote.updateContext=function(){if(this.curContext()===types$1.q_tmpl){this.context.pop()}else{this.context.push(types$1.q_tmpl)}this.exprAllowed=false};types.star.updateContext=function(prevType){if(prevType===types._function){var index=this.context.length-1;if(this.context[index]===types$1.f_expr){this.context[index]=types$1.f_expr_gen}else{this.context[index]=types$1.f_gen}}this.exprAllowed=true};types.name.updateContext=function(prevType){var allowed=false;if(this.options.ecmaVersion>=6&&prevType!==types.dot){if(this.value==="of"&&!this.exprAllowed||this.value==="yield"&&this.inGeneratorContext()){allowed=true}}this.exprAllowed=allowed};var ecma9BinaryProperties="ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS";var ecma10BinaryProperties=ecma9BinaryProperties+" Extended_Pictographic";var ecma11BinaryProperties=ecma10BinaryProperties;var unicodeBinaryProperties={9:ecma9BinaryProperties,10:ecma10BinaryProperties,11:ecma11BinaryProperties};var unicodeGeneralCategoryValues="Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu";var ecma9ScriptValues="Adlam Adlm Ahom Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb";var ecma10ScriptValues=ecma9ScriptValues+" Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd";var ecma11ScriptValues=ecma10ScriptValues+" Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho";var unicodeScriptValues={9:ecma9ScriptValues,10:ecma10ScriptValues,11:ecma11ScriptValues};var data={};function buildUnicodeData(ecmaVersion){var d=data[ecmaVersion]={binary:wordsRegexp(unicodeBinaryProperties[ecmaVersion]+" "+unicodeGeneralCategoryValues),nonBinary:{General_Category:wordsRegexp(unicodeGeneralCategoryValues),Script:wordsRegexp(unicodeScriptValues[ecmaVersion])}};d.nonBinary.Script_Extensions=d.nonBinary.Script;d.nonBinary.gc=d.nonBinary.General_Category;d.nonBinary.sc=d.nonBinary.Script;d.nonBinary.scx=d.nonBinary.Script_Extensions}buildUnicodeData(9);buildUnicodeData(10);buildUnicodeData(11);var pp$8=Parser.prototype;var RegExpValidationState=function RegExpValidationState2(parser){this.parser=parser;this.validFlags="gim"+(parser.options.ecmaVersion>=6?"uy":"")+(parser.options.ecmaVersion>=9?"s":"");this.unicodeProperties=data[parser.options.ecmaVersion>=11?11:parser.options.ecmaVersion];this.source="";this.flags="";this.start=0;this.switchU=false;this.switchN=false;this.pos=0;this.lastIntValue=0;this.lastStringValue="";this.lastAssertionIsQuantifiable=false;this.numCapturingParens=0;this.maxBackReference=0;this.groupNames=[];this.backReferenceNames=[]};RegExpValidationState.prototype.reset=function reset(start,pattern,flags){var unicode=flags.indexOf("u")!==-1;this.start=start|0;this.source=pattern+"";this.flags=flags;this.switchU=unicode&&this.parser.options.ecmaVersion>=6;this.switchN=unicode&&this.parser.options.ecmaVersion>=9};RegExpValidationState.prototype.raise=function raise(message){this.parser.raiseRecoverable(this.start,"Invalid regular expression: /"+this.source+"/: "+message)};RegExpValidationState.prototype.at=function at(i){var s=this.source;var l=s.length;if(i>=l){return-1}var c=s.charCodeAt(i);if(!this.switchU||c<=55295||c>=57344||i+1>=l){return c}var next=s.charCodeAt(i+1);return next>=56320&&next<=57343?(c<<10)+next-56613888:c};RegExpValidationState.prototype.nextIndex=function nextIndex(i){var s=this.source;var l=s.length;if(i>=l){return l}var c=s.charCodeAt(i),next;if(!this.switchU||c<=55295||c>=57344||i+1>=l||(next=s.charCodeAt(i+1))<56320||next>57343){return i+1}return i+2};RegExpValidationState.prototype.current=function current(){return this.at(this.pos)};RegExpValidationState.prototype.lookahead=function lookahead(){return this.at(this.nextIndex(this.pos))};RegExpValidationState.prototype.advance=function advance(){this.pos=this.nextIndex(this.pos)};RegExpValidationState.prototype.eat=function eat(ch){if(this.current()===ch){this.advance();return true}return false};function codePointToString(ch){if(ch<=65535){return String.fromCharCode(ch)}ch-=65536;return String.fromCharCode((ch>>10)+55296,(ch&1023)+56320)}pp$8.validateRegExpFlags=function(state2){var validFlags=state2.validFlags;var flags=state2.flags;for(var i=0;i-1){this.raise(state2.start,"Duplicate regular expression flag")}}};pp$8.validateRegExpPattern=function(state2){this.regexp_pattern(state2);if(!state2.switchN&&this.options.ecmaVersion>=9&&state2.groupNames.length>0){state2.switchN=true;this.regexp_pattern(state2)}};pp$8.regexp_pattern=function(state2){state2.pos=0;state2.lastIntValue=0;state2.lastStringValue="";state2.lastAssertionIsQuantifiable=false;state2.numCapturingParens=0;state2.maxBackReference=0;state2.groupNames.length=0;state2.backReferenceNames.length=0;this.regexp_disjunction(state2);if(state2.pos!==state2.source.length){if(state2.eat(41)){state2.raise("Unmatched ')'")}if(state2.eat(93)||state2.eat(125)){state2.raise("Lone quantifier brackets")}}if(state2.maxBackReference>state2.numCapturingParens){state2.raise("Invalid escape")}for(var i=0,list=state2.backReferenceNames;i=9){lookbehind=state2.eat(60)}if(state2.eat(61)||state2.eat(33)){this.regexp_disjunction(state2);if(!state2.eat(41)){state2.raise("Unterminated group")}state2.lastAssertionIsQuantifiable=!lookbehind;return true}}state2.pos=start;return false};pp$8.regexp_eatQuantifier=function(state2,noError){if(noError===void 0)noError=false;if(this.regexp_eatQuantifierPrefix(state2,noError)){state2.eat(63);return true}return false};pp$8.regexp_eatQuantifierPrefix=function(state2,noError){return state2.eat(42)||state2.eat(43)||state2.eat(63)||this.regexp_eatBracedQuantifier(state2,noError)};pp$8.regexp_eatBracedQuantifier=function(state2,noError){var start=state2.pos;if(state2.eat(123)){var min=0,max=-1;if(this.regexp_eatDecimalDigits(state2)){min=state2.lastIntValue;if(state2.eat(44)&&this.regexp_eatDecimalDigits(state2)){max=state2.lastIntValue}if(state2.eat(125)){if(max!==-1&&max=9){this.regexp_groupSpecifier(state2)}else if(state2.current()===63){state2.raise("Invalid group")}this.regexp_disjunction(state2);if(state2.eat(41)){state2.numCapturingParens+=1;return true}state2.raise("Unterminated group")}return false};pp$8.regexp_eatExtendedAtom=function(state2){return state2.eat(46)||this.regexp_eatReverseSolidusAtomEscape(state2)||this.regexp_eatCharacterClass(state2)||this.regexp_eatUncapturingGroup(state2)||this.regexp_eatCapturingGroup(state2)||this.regexp_eatInvalidBracedQuantifier(state2)||this.regexp_eatExtendedPatternCharacter(state2)};pp$8.regexp_eatInvalidBracedQuantifier=function(state2){if(this.regexp_eatBracedQuantifier(state2,true)){state2.raise("Nothing to repeat")}return false};pp$8.regexp_eatSyntaxCharacter=function(state2){var ch=state2.current();if(isSyntaxCharacter(ch)){state2.lastIntValue=ch;state2.advance();return true}return false};function isSyntaxCharacter(ch){return ch===36||ch>=40&&ch<=43||ch===46||ch===63||ch>=91&&ch<=94||ch>=123&&ch<=125}pp$8.regexp_eatPatternCharacters=function(state2){var start=state2.pos;var ch=0;while((ch=state2.current())!==-1&&!isSyntaxCharacter(ch)){state2.advance()}return state2.pos!==start};pp$8.regexp_eatExtendedPatternCharacter=function(state2){var ch=state2.current();if(ch!==-1&&ch!==36&&!(ch>=40&&ch<=43)&&ch!==46&&ch!==63&&ch!==91&&ch!==94&&ch!==124){state2.advance();return true}return false};pp$8.regexp_groupSpecifier=function(state2){if(state2.eat(63)){if(this.regexp_eatGroupName(state2)){if(state2.groupNames.indexOf(state2.lastStringValue)!==-1){state2.raise("Duplicate capture group name")}state2.groupNames.push(state2.lastStringValue);return}state2.raise("Invalid group")}};pp$8.regexp_eatGroupName=function(state2){state2.lastStringValue="";if(state2.eat(60)){if(this.regexp_eatRegExpIdentifierName(state2)&&state2.eat(62)){return true}state2.raise("Invalid capture group name")}return false};pp$8.regexp_eatRegExpIdentifierName=function(state2){state2.lastStringValue="";if(this.regexp_eatRegExpIdentifierStart(state2)){state2.lastStringValue+=codePointToString(state2.lastIntValue);while(this.regexp_eatRegExpIdentifierPart(state2)){state2.lastStringValue+=codePointToString(state2.lastIntValue)}return true}return false};pp$8.regexp_eatRegExpIdentifierStart=function(state2){var start=state2.pos;var ch=state2.current();state2.advance();if(ch===92&&this.regexp_eatRegExpUnicodeEscapeSequence(state2)){ch=state2.lastIntValue}if(isRegExpIdentifierStart(ch)){state2.lastIntValue=ch;return true}state2.pos=start;return false};function isRegExpIdentifierStart(ch){return isIdentifierStart(ch,true)||ch===36||ch===95}pp$8.regexp_eatRegExpIdentifierPart=function(state2){var start=state2.pos;var ch=state2.current();state2.advance();if(ch===92&&this.regexp_eatRegExpUnicodeEscapeSequence(state2)){ch=state2.lastIntValue}if(isRegExpIdentifierPart(ch)){state2.lastIntValue=ch;return true}state2.pos=start;return false};function isRegExpIdentifierPart(ch){return isIdentifierChar(ch,true)||ch===36||ch===95||ch===8204||ch===8205}pp$8.regexp_eatAtomEscape=function(state2){if(this.regexp_eatBackReference(state2)||this.regexp_eatCharacterClassEscape(state2)||this.regexp_eatCharacterEscape(state2)||state2.switchN&&this.regexp_eatKGroupName(state2)){return true}if(state2.switchU){if(state2.current()===99){state2.raise("Invalid unicode escape")}state2.raise("Invalid escape")}return false};pp$8.regexp_eatBackReference=function(state2){var start=state2.pos;if(this.regexp_eatDecimalEscape(state2)){var n=state2.lastIntValue;if(state2.switchU){if(n>state2.maxBackReference){state2.maxBackReference=n}return true}if(n<=state2.numCapturingParens){return true}state2.pos=start}return false};pp$8.regexp_eatKGroupName=function(state2){if(state2.eat(107)){if(this.regexp_eatGroupName(state2)){state2.backReferenceNames.push(state2.lastStringValue);return true}state2.raise("Invalid named reference")}return false};pp$8.regexp_eatCharacterEscape=function(state2){return this.regexp_eatControlEscape(state2)||this.regexp_eatCControlLetter(state2)||this.regexp_eatZero(state2)||this.regexp_eatHexEscapeSequence(state2)||this.regexp_eatRegExpUnicodeEscapeSequence(state2)||!state2.switchU&&this.regexp_eatLegacyOctalEscapeSequence(state2)||this.regexp_eatIdentityEscape(state2)};pp$8.regexp_eatCControlLetter=function(state2){var start=state2.pos;if(state2.eat(99)){if(this.regexp_eatControlLetter(state2)){return true}state2.pos=start}return false};pp$8.regexp_eatZero=function(state2){if(state2.current()===48&&!isDecimalDigit(state2.lookahead())){state2.lastIntValue=0;state2.advance();return true}return false};pp$8.regexp_eatControlEscape=function(state2){var ch=state2.current();if(ch===116){state2.lastIntValue=9;state2.advance();return true}if(ch===110){state2.lastIntValue=10;state2.advance();return true}if(ch===118){state2.lastIntValue=11;state2.advance();return true}if(ch===102){state2.lastIntValue=12;state2.advance();return true}if(ch===114){state2.lastIntValue=13;state2.advance();return true}return false};pp$8.regexp_eatControlLetter=function(state2){var ch=state2.current();if(isControlLetter(ch)){state2.lastIntValue=ch%32;state2.advance();return true}return false};function isControlLetter(ch){return ch>=65&&ch<=90||ch>=97&&ch<=122}pp$8.regexp_eatRegExpUnicodeEscapeSequence=function(state2){var start=state2.pos;if(state2.eat(117)){if(this.regexp_eatFixedHexDigits(state2,4)){var lead=state2.lastIntValue;if(state2.switchU&&lead>=55296&&lead<=56319){var leadSurrogateEnd=state2.pos;if(state2.eat(92)&&state2.eat(117)&&this.regexp_eatFixedHexDigits(state2,4)){var trail=state2.lastIntValue;if(trail>=56320&&trail<=57343){state2.lastIntValue=(lead-55296)*1024+(trail-56320)+65536;return true}}state2.pos=leadSurrogateEnd;state2.lastIntValue=lead}return true}if(state2.switchU&&state2.eat(123)&&this.regexp_eatHexDigits(state2)&&state2.eat(125)&&isValidUnicode(state2.lastIntValue)){return true}if(state2.switchU){state2.raise("Invalid unicode escape")}state2.pos=start}return false};function isValidUnicode(ch){return ch>=0&&ch<=1114111}pp$8.regexp_eatIdentityEscape=function(state2){if(state2.switchU){if(this.regexp_eatSyntaxCharacter(state2)){return true}if(state2.eat(47)){state2.lastIntValue=47;return true}return false}var ch=state2.current();if(ch!==99&&(!state2.switchN||ch!==107)){state2.lastIntValue=ch;state2.advance();return true}return false};pp$8.regexp_eatDecimalEscape=function(state2){state2.lastIntValue=0;var ch=state2.current();if(ch>=49&&ch<=57){do{state2.lastIntValue=10*state2.lastIntValue+(ch-48);state2.advance()}while((ch=state2.current())>=48&&ch<=57);return true}return false};pp$8.regexp_eatCharacterClassEscape=function(state2){var ch=state2.current();if(isCharacterClassEscape(ch)){state2.lastIntValue=-1;state2.advance();return true}if(state2.switchU&&this.options.ecmaVersion>=9&&(ch===80||ch===112)){state2.lastIntValue=-1;state2.advance();if(state2.eat(123)&&this.regexp_eatUnicodePropertyValueExpression(state2)&&state2.eat(125)){return true}state2.raise("Invalid property name")}return false};function isCharacterClassEscape(ch){return ch===100||ch===68||ch===115||ch===83||ch===119||ch===87}pp$8.regexp_eatUnicodePropertyValueExpression=function(state2){var start=state2.pos;if(this.regexp_eatUnicodePropertyName(state2)&&state2.eat(61)){var name2=state2.lastStringValue;if(this.regexp_eatUnicodePropertyValue(state2)){var value2=state2.lastStringValue;this.regexp_validateUnicodePropertyNameAndValue(state2,name2,value2);return true}}state2.pos=start;if(this.regexp_eatLoneUnicodePropertyNameOrValue(state2)){var nameOrValue=state2.lastStringValue;this.regexp_validateUnicodePropertyNameOrValue(state2,nameOrValue);return true}return false};pp$8.regexp_validateUnicodePropertyNameAndValue=function(state2,name2,value2){if(!has(state2.unicodeProperties.nonBinary,name2)){state2.raise("Invalid property name")}if(!state2.unicodeProperties.nonBinary[name2].test(value2)){state2.raise("Invalid property value")}};pp$8.regexp_validateUnicodePropertyNameOrValue=function(state2,nameOrValue){if(!state2.unicodeProperties.binary.test(nameOrValue)){state2.raise("Invalid property name")}};pp$8.regexp_eatUnicodePropertyName=function(state2){var ch=0;state2.lastStringValue="";while(isUnicodePropertyNameCharacter(ch=state2.current())){state2.lastStringValue+=codePointToString(ch);state2.advance()}return state2.lastStringValue!==""};function isUnicodePropertyNameCharacter(ch){return isControlLetter(ch)||ch===95}pp$8.regexp_eatUnicodePropertyValue=function(state2){var ch=0;state2.lastStringValue="";while(isUnicodePropertyValueCharacter(ch=state2.current())){state2.lastStringValue+=codePointToString(ch);state2.advance()}return state2.lastStringValue!==""};function isUnicodePropertyValueCharacter(ch){return isUnicodePropertyNameCharacter(ch)||isDecimalDigit(ch)}pp$8.regexp_eatLoneUnicodePropertyNameOrValue=function(state2){return this.regexp_eatUnicodePropertyValue(state2)};pp$8.regexp_eatCharacterClass=function(state2){if(state2.eat(91)){state2.eat(94);this.regexp_classRanges(state2);if(state2.eat(93)){return true}state2.raise("Unterminated character class")}return false};pp$8.regexp_classRanges=function(state2){while(this.regexp_eatClassAtom(state2)){var left=state2.lastIntValue;if(state2.eat(45)&&this.regexp_eatClassAtom(state2)){var right=state2.lastIntValue;if(state2.switchU&&(left===-1||right===-1)){state2.raise("Invalid character class")}if(left!==-1&&right!==-1&&left>right){state2.raise("Range out of order in character class")}}}};pp$8.regexp_eatClassAtom=function(state2){var start=state2.pos;if(state2.eat(92)){if(this.regexp_eatClassEscape(state2)){return true}if(state2.switchU){var ch$1=state2.current();if(ch$1===99||isOctalDigit(ch$1)){state2.raise("Invalid class escape")}state2.raise("Invalid escape")}state2.pos=start}var ch=state2.current();if(ch!==93){state2.lastIntValue=ch;state2.advance();return true}return false};pp$8.regexp_eatClassEscape=function(state2){var start=state2.pos;if(state2.eat(98)){state2.lastIntValue=8;return true}if(state2.switchU&&state2.eat(45)){state2.lastIntValue=45;return true}if(!state2.switchU&&state2.eat(99)){if(this.regexp_eatClassControlLetter(state2)){return true}state2.pos=start}return this.regexp_eatCharacterClassEscape(state2)||this.regexp_eatCharacterEscape(state2)};pp$8.regexp_eatClassControlLetter=function(state2){var ch=state2.current();if(isDecimalDigit(ch)||ch===95){state2.lastIntValue=ch%32;state2.advance();return true}return false};pp$8.regexp_eatHexEscapeSequence=function(state2){var start=state2.pos;if(state2.eat(120)){if(this.regexp_eatFixedHexDigits(state2,2)){return true}if(state2.switchU){state2.raise("Invalid escape")}state2.pos=start}return false};pp$8.regexp_eatDecimalDigits=function(state2){var start=state2.pos;var ch=0;state2.lastIntValue=0;while(isDecimalDigit(ch=state2.current())){state2.lastIntValue=10*state2.lastIntValue+(ch-48);state2.advance()}return state2.pos!==start};function isDecimalDigit(ch){return ch>=48&&ch<=57}pp$8.regexp_eatHexDigits=function(state2){var start=state2.pos;var ch=0;state2.lastIntValue=0;while(isHexDigit(ch=state2.current())){state2.lastIntValue=16*state2.lastIntValue+hexToInt(ch);state2.advance()}return state2.pos!==start};function isHexDigit(ch){return ch>=48&&ch<=57||ch>=65&&ch<=70||ch>=97&&ch<=102}function hexToInt(ch){if(ch>=65&&ch<=70){return 10+(ch-65)}if(ch>=97&&ch<=102){return 10+(ch-97)}return ch-48}pp$8.regexp_eatLegacyOctalEscapeSequence=function(state2){if(this.regexp_eatOctalDigit(state2)){var n1=state2.lastIntValue;if(this.regexp_eatOctalDigit(state2)){var n2=state2.lastIntValue;if(n1<=3&&this.regexp_eatOctalDigit(state2)){state2.lastIntValue=n1*64+n2*8+state2.lastIntValue}else{state2.lastIntValue=n1*8+n2}}else{state2.lastIntValue=n1}return true}return false};pp$8.regexp_eatOctalDigit=function(state2){var ch=state2.current();if(isOctalDigit(ch)){state2.lastIntValue=ch-48;state2.advance();return true}state2.lastIntValue=0;return false};function isOctalDigit(ch){return ch>=48&&ch<=55}pp$8.regexp_eatFixedHexDigits=function(state2,length){var start=state2.pos;state2.lastIntValue=0;for(var i=0;i=this.input.length){return this.finishToken(types.eof)}if(curContext.override){return curContext.override(this)}else{this.readToken(this.fullCharCodeAtPos())}};pp$9.readToken=function(code){if(isIdentifierStart(code,this.options.ecmaVersion>=6)||code===92){return this.readWord()}return this.getTokenFromCode(code)};pp$9.fullCharCodeAtPos=function(){var code=this.input.charCodeAt(this.pos);if(code<=55295||code>=57344){return code}var next=this.input.charCodeAt(this.pos+1);return(code<<10)+next-56613888};pp$9.skipBlockComment=function(){var startLoc=this.options.onComment&&this.curPosition();var start=this.pos,end=this.input.indexOf("*/",this.pos+=2);if(end===-1){this.raise(this.pos-2,"Unterminated comment")}this.pos=end+2;if(this.options.locations){lineBreakG.lastIndex=start;var match;while((match=lineBreakG.exec(this.input))&&match.index8&&ch<14||ch>=5760&&nonASCIIwhitespace.test(String.fromCharCode(ch))){++this.pos}else{break loop}}}};pp$9.finishToken=function(type,val){this.end=this.pos;if(this.options.locations){this.endLoc=this.curPosition()}var prevType=this.type;this.type=type;this.value=val;this.updateContext(prevType)};pp$9.readToken_dot=function(){var next=this.input.charCodeAt(this.pos+1);if(next>=48&&next<=57){return this.readNumber(true)}var next2=this.input.charCodeAt(this.pos+2);if(this.options.ecmaVersion>=6&&next===46&&next2===46){this.pos+=3;return this.finishToken(types.ellipsis)}else{++this.pos;return this.finishToken(types.dot)}};pp$9.readToken_slash=function(){var next=this.input.charCodeAt(this.pos+1);if(this.exprAllowed){++this.pos;return this.readRegexp()}if(next===61){return this.finishOp(types.assign,2)}return this.finishOp(types.slash,1)};pp$9.readToken_mult_modulo_exp=function(code){var next=this.input.charCodeAt(this.pos+1);var size=1;var tokentype=code===42?types.star:types.modulo;if(this.options.ecmaVersion>=7&&code===42&&next===42){++size;tokentype=types.starstar;next=this.input.charCodeAt(this.pos+2)}if(next===61){return this.finishOp(types.assign,size+1)}return this.finishOp(tokentype,size)};pp$9.readToken_pipe_amp=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===code){return this.finishOp(code===124?types.logicalOR:types.logicalAND,2)}if(next===61){return this.finishOp(types.assign,2)}return this.finishOp(code===124?types.bitwiseOR:types.bitwiseAND,1)};pp$9.readToken_caret=function(){var next=this.input.charCodeAt(this.pos+1);if(next===61){return this.finishOp(types.assign,2)}return this.finishOp(types.bitwiseXOR,1)};pp$9.readToken_plus_min=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===code){if(next===45&&!this.inModule&&this.input.charCodeAt(this.pos+2)===62&&(this.lastTokEnd===0||lineBreak.test(this.input.slice(this.lastTokEnd,this.pos)))){this.skipLineComment(3);this.skipSpace();return this.nextToken()}return this.finishOp(types.incDec,2)}if(next===61){return this.finishOp(types.assign,2)}return this.finishOp(types.plusMin,1)};pp$9.readToken_lt_gt=function(code){var next=this.input.charCodeAt(this.pos+1);var size=1;if(next===code){size=code===62&&this.input.charCodeAt(this.pos+2)===62?3:2;if(this.input.charCodeAt(this.pos+size)===61){return this.finishOp(types.assign,size+1)}return this.finishOp(types.bitShift,size)}if(next===33&&code===60&&!this.inModule&&this.input.charCodeAt(this.pos+2)===45&&this.input.charCodeAt(this.pos+3)===45){this.skipLineComment(4);this.skipSpace();return this.nextToken()}if(next===61){size=2}return this.finishOp(types.relational,size)};pp$9.readToken_eq_excl=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===61){return this.finishOp(types.equality,this.input.charCodeAt(this.pos+2)===61?3:2)}if(code===61&&next===62&&this.options.ecmaVersion>=6){this.pos+=2;return this.finishToken(types.arrow)}return this.finishOp(code===61?types.eq:types.prefix,1)};pp$9.getTokenFromCode=function(code){switch(code){case 46:return this.readToken_dot();case 40:++this.pos;return this.finishToken(types.parenL);case 41:++this.pos;return this.finishToken(types.parenR);case 59:++this.pos;return this.finishToken(types.semi);case 44:++this.pos;return this.finishToken(types.comma);case 91:++this.pos;return this.finishToken(types.bracketL);case 93:++this.pos;return this.finishToken(types.bracketR);case 123:++this.pos;return this.finishToken(types.braceL);case 125:++this.pos;return this.finishToken(types.braceR);case 58:++this.pos;return this.finishToken(types.colon);case 63:++this.pos;return this.finishToken(types.question);case 96:if(this.options.ecmaVersion<6){break}++this.pos;return this.finishToken(types.backQuote);case 48:var next=this.input.charCodeAt(this.pos+1);if(next===120||next===88){return this.readRadixNumber(16)}if(this.options.ecmaVersion>=6){if(next===111||next===79){return this.readRadixNumber(8)}if(next===98||next===66){return this.readRadixNumber(2)}}case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return this.readNumber(false);case 34:case 39:return this.readString(code);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo_exp(code);case 124:case 38:return this.readToken_pipe_amp(code);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(code);case 60:case 62:return this.readToken_lt_gt(code);case 61:case 33:return this.readToken_eq_excl(code);case 126:return this.finishOp(types.prefix,1)}this.raise(this.pos,"Unexpected character '"+codePointToString$1(code)+"'")};pp$9.finishOp=function(type,size){var str=this.input.slice(this.pos,this.pos+size);this.pos+=size;return this.finishToken(type,str)};pp$9.readRegexp=function(){var escaped,inClass,start=this.pos;for(;;){if(this.pos>=this.input.length){this.raise(start,"Unterminated regular expression")}var ch=this.input.charAt(this.pos);if(lineBreak.test(ch)){this.raise(start,"Unterminated regular expression")}if(!escaped){if(ch==="["){inClass=true}else if(ch==="]"&&inClass){inClass=false}else if(ch==="/"&&!inClass){break}escaped=ch==="\\"}else{escaped=false}++this.pos}var pattern=this.input.slice(start,this.pos);++this.pos;var flagsStart=this.pos;var flags=this.readWord1();if(this.containsEsc){this.unexpected(flagsStart)}var state2=this.regexpState||(this.regexpState=new RegExpValidationState(this));state2.reset(start,pattern,flags);this.validateRegExpFlags(state2);this.validateRegExpPattern(state2);var value2=null;try{value2=new RegExp(pattern,flags)}catch(e){}return this.finishToken(types.regexp,{pattern,flags,value:value2})};pp$9.readInt=function(radix,len){var start=this.pos,total=0;for(var i=0,e=len==null?Infinity:len;i=97){val=code-97+10}else if(code>=65){val=code-65+10}else if(code>=48&&code<=57){val=code-48}else{val=Infinity}if(val>=radix){break}++this.pos;total=total*radix+val}if(this.pos===start||len!=null&&this.pos-start!==len){return null}return total};pp$9.readRadixNumber=function(radix){var start=this.pos;this.pos+=2;var val=this.readInt(radix);if(val==null){this.raise(this.start+2,"Expected number in radix "+radix)}if(this.options.ecmaVersion>=11&&this.input.charCodeAt(this.pos)===110){val=typeof BigInt!=="undefined"?BigInt(this.input.slice(start,this.pos)):null;++this.pos}else if(isIdentifierStart(this.fullCharCodeAtPos())){this.raise(this.pos,"Identifier directly after number")}return this.finishToken(types.num,val)};pp$9.readNumber=function(startsWithDot){var start=this.pos;if(!startsWithDot&&this.readInt(10)===null){this.raise(start,"Invalid number")}var octal=this.pos-start>=2&&this.input.charCodeAt(start)===48;if(octal&&this.strict){this.raise(start,"Invalid number")}var next=this.input.charCodeAt(this.pos);if(!octal&&!startsWithDot&&this.options.ecmaVersion>=11&&next===110){var str$1=this.input.slice(start,this.pos);var val$1=typeof BigInt!=="undefined"?BigInt(str$1):null;++this.pos;if(isIdentifierStart(this.fullCharCodeAtPos())){this.raise(this.pos,"Identifier directly after number")}return this.finishToken(types.num,val$1)}if(octal&&/[89]/.test(this.input.slice(start,this.pos))){octal=false}if(next===46&&!octal){++this.pos;this.readInt(10);next=this.input.charCodeAt(this.pos)}if((next===69||next===101)&&!octal){next=this.input.charCodeAt(++this.pos);if(next===43||next===45){++this.pos}if(this.readInt(10)===null){this.raise(start,"Invalid number")}}if(isIdentifierStart(this.fullCharCodeAtPos())){this.raise(this.pos,"Identifier directly after number")}var str=this.input.slice(start,this.pos);var val=octal?parseInt(str,8):parseFloat(str);return this.finishToken(types.num,val)};pp$9.readCodePoint=function(){var ch=this.input.charCodeAt(this.pos),code;if(ch===123){if(this.options.ecmaVersion<6){this.unexpected()}var codePos=++this.pos;code=this.readHexChar(this.input.indexOf("}",this.pos)-this.pos);++this.pos;if(code>1114111){this.invalidStringToken(codePos,"Code point out of bounds")}}else{code=this.readHexChar(4)}return code};function codePointToString$1(code){if(code<=65535){return String.fromCharCode(code)}code-=65536;return String.fromCharCode((code>>10)+55296,(code&1023)+56320)}pp$9.readString=function(quote){var out="",chunkStart=++this.pos;for(;;){if(this.pos>=this.input.length){this.raise(this.start,"Unterminated string constant")}var ch=this.input.charCodeAt(this.pos);if(ch===quote){break}if(ch===92){out+=this.input.slice(chunkStart,this.pos);out+=this.readEscapedChar(false);chunkStart=this.pos}else{if(isNewLine(ch,this.options.ecmaVersion>=10)){this.raise(this.start,"Unterminated string constant")}++this.pos}}out+=this.input.slice(chunkStart,this.pos++);return this.finishToken(types.string,out)};var INVALID_TEMPLATE_ESCAPE_ERROR={};pp$9.tryReadTemplateToken=function(){this.inTemplateElement=true;try{this.readTmplToken()}catch(err){if(err===INVALID_TEMPLATE_ESCAPE_ERROR){this.readInvalidTemplateToken()}else{throw err}}this.inTemplateElement=false};pp$9.invalidStringToken=function(position,message){if(this.inTemplateElement&&this.options.ecmaVersion>=9){throw INVALID_TEMPLATE_ESCAPE_ERROR}else{this.raise(position,message)}};pp$9.readTmplToken=function(){var out="",chunkStart=this.pos;for(;;){if(this.pos>=this.input.length){this.raise(this.start,"Unterminated template")}var ch=this.input.charCodeAt(this.pos);if(ch===96||ch===36&&this.input.charCodeAt(this.pos+1)===123){if(this.pos===this.start&&(this.type===types.template||this.type===types.invalidTemplate)){if(ch===36){this.pos+=2;return this.finishToken(types.dollarBraceL)}else{++this.pos;return this.finishToken(types.backQuote)}}out+=this.input.slice(chunkStart,this.pos);return this.finishToken(types.template,out)}if(ch===92){out+=this.input.slice(chunkStart,this.pos);out+=this.readEscapedChar(true);chunkStart=this.pos}else if(isNewLine(ch)){out+=this.input.slice(chunkStart,this.pos);++this.pos;switch(ch){case 13:if(this.input.charCodeAt(this.pos)===10){++this.pos}case 10:out+="\n";break;default:out+=String.fromCharCode(ch);break}if(this.options.locations){++this.curLine;this.lineStart=this.pos}chunkStart=this.pos}else{++this.pos}}};pp$9.readInvalidTemplateToken=function(){for(;this.pos=48&&ch<=55){var octalStr=this.input.substr(this.pos-1,3).match(/^[0-7]+/)[0];var octal=parseInt(octalStr,8);if(octal>255){octalStr=octalStr.slice(0,-1);octal=parseInt(octalStr,8)}this.pos+=octalStr.length-1;ch=this.input.charCodeAt(this.pos);if((octalStr!=="0"||ch===56||ch===57)&&(this.strict||inTemplate)){this.invalidStringToken(this.pos-1-octalStr.length,inTemplate?"Octal literal in template string":"Octal literal in strict mode")}return String.fromCharCode(octal)}if(isNewLine(ch)){return""}return String.fromCharCode(ch)}};pp$9.readHexChar=function(len){var codePos=this.pos;var n=this.readInt(16,len);if(n===null){this.invalidStringToken(codePos,"Bad character escape sequence")}return n};pp$9.readWord1=function(){this.containsEsc=false;var word="",first=true,chunkStart=this.pos;var astral=this.options.ecmaVersion>=6;while(this.pos0){recording.pop()}}function insertVariable(name2,value2){variables[name2]=value2}function getEntity(value2){const name2=entityNames[value2];if(name2){return contextName+"."+name2}return value2}function setIndent(spaces){indent=" ".repeat(spaces)}function addVariable(value2,source){const variableName=`${contextName}Variable${contextVariables.length}`;recording.push(`${indent}const ${variableName} = ${source};`);contextVariables.push(value2);return variableName}function writePPM(width,height){const sourceVariable=`${contextName}Variable${contextVariables.length}`;const imageVariable=`imageDatum${imageCount}`;recording.push(`${indent}let ${imageVariable} = ["P3\\n# ${readPixelsFile}.ppm\\n", ${width}, ' ', ${height}, "\\n255\\n"].join("");`);recording.push(`${indent}for (let i = 0; i < ${imageVariable}.length; i += 4) {`);recording.push(`${indent} ${imageVariable} += ${sourceVariable}[i] + ' ' + ${sourceVariable}[i + 1] + ' ' + ${sourceVariable}[i + 2] + ' ';`);recording.push(`${indent}}`);recording.push(`${indent}if (typeof require !== "undefined") {`);recording.push(`${indent} require('fs').writeFileSync('./${readPixelsFile}.ppm', ${imageVariable});`);recording.push(`${indent}}`);imageCount++}function addComment(value2){recording.push(`${indent}// ${value2}`)}function checkThrowError(){recording.push(`${indent}(() => { - ${indent}const error = ${contextName}.getError(); - ${indent}if (error !== ${contextName}.NONE) { - ${indent} const names = Object.getOwnPropertyNames(gl); - ${indent} for (let i = 0; i < names.length; i++) { - ${indent} const name = names[i]; - ${indent} if (${contextName}[name] === error) { - ${indent} throw new Error('${contextName} threw ' + name); - ${indent} } - ${indent} } - ${indent}} - ${indent}})();`)}function methodCallToString(method,args){return`${contextName}.${method}(${argumentsToString(args,{contextName,contextVariables,getEntity,addVariable,variables,onUnrecognizedArgumentLookup})})`}function getVariableName(value2){if(variables){for(const name2 in variables){if(variables[name2]===value2){return name2}}}return null}function getContextVariableName(value2){const i=contextVariables.indexOf(value2);if(i!==-1){return`${contextName}Variable${i}`}return null}}function glExtensionWiretap(extension,options){const proxy=new Proxy(extension,{get:listen});const extensionEntityNames={};const{contextName,contextVariables,getEntity,useTrackablePrimitives,recording,variables,indent,onUnrecognizedArgumentLookup}=options;return proxy;function listen(obj,property){if(typeof obj[property]==="function"){return function(){switch(property){case"drawBuffersWEBGL":recording.push(`${indent}${contextName}.drawBuffersWEBGL([${argumentsToString(arguments[0],{contextName,contextVariables,getEntity:getExtensionEntity,addVariable,variables,onUnrecognizedArgumentLookup})}]);`);return extension.drawBuffersWEBGL(arguments[0])}let result=extension[property].apply(extension,arguments);switch(typeof result){case"undefined":recording.push(`${indent}${methodCallToString(property,arguments)};`);return;case"number":case"boolean":if(useTrackablePrimitives&&contextVariables.indexOf(trackablePrimitive(result))===-1){recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property,arguments)};`);contextVariables.push(result=trackablePrimitive(result))}else{recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property,arguments)};`);contextVariables.push(result)}break;default:if(result===null){recording.push(`${methodCallToString(property,arguments)};`)}else{recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property,arguments)};`)}contextVariables.push(result)}return result}}extensionEntityNames[extension[property]]=property;return extension[property]}function getExtensionEntity(value2){if(extensionEntityNames.hasOwnProperty(value2)){return`${contextName}.${extensionEntityNames[value2]}`}return getEntity(value2)}function methodCallToString(method,args){return`${contextName}.${method}(${argumentsToString(args,{contextName,contextVariables,getEntity:getExtensionEntity,addVariable,variables,onUnrecognizedArgumentLookup})})`}function addVariable(value2,source){const variableName=`${contextName}Variable${contextVariables.length}`;contextVariables.push(value2);recording.push(`${indent}const ${variableName} = ${source};`);return variableName}}function argumentsToString(args,options){const{variables,onUnrecognizedArgumentLookup}=options;return Array.from(args).map(arg=>{const variableName=getVariableName(arg);if(variableName){return variableName}return argumentToString(arg,options)}).join(", ");function getVariableName(value2){if(variables){for(const name2 in variables){if(!variables.hasOwnProperty(name2))continue;if(variables[name2]===value2){return name2}}}if(onUnrecognizedArgumentLookup){return onUnrecognizedArgumentLookup(value2)}return null}}function argumentToString(arg,options){const{contextName,contextVariables,getEntity,addVariable,onUnrecognizedArgumentLookup}=options;if(typeof arg==="undefined"){return"undefined"}if(arg===null){return"null"}const i=contextVariables.indexOf(arg);if(i>-1){return`${contextName}Variable${i}`}switch(arg.constructor.name){case"String":const hasLines=/\n/.test(arg);const hasSingleQuotes=/'/.test(arg);const hasDoubleQuotes=/"/.test(arg);if(hasLines){return"`"+arg+"`"}else if(hasSingleQuotes&&!hasDoubleQuotes){return'"'+arg+'"'}else if(!hasSingleQuotes&&hasDoubleQuotes){return"'"+arg+"'"}else{return"'"+arg+"'"}case"Number":return getEntity(arg);case"Boolean":return getEntity(arg);case"Array":return addVariable(arg,`new ${arg.constructor.name}([${Array.from(arg).join(",")}])`);case"Float32Array":case"Uint8Array":case"Uint16Array":case"Int32Array":return addVariable(arg,`new ${arg.constructor.name}(${JSON.stringify(Array.from(arg))})`);default:if(onUnrecognizedArgumentLookup){const instantiationString=onUnrecognizedArgumentLookup(arg);if(instantiationString){return instantiationString}}throw new Error(`unrecognized argument type ${arg.constructor.name}`)}}function trackablePrimitive(value2){return new value2.constructor(value2)}if(typeof module3!=="undefined"){module3.exports={glWiretap,glExtensionWiretap}}if(typeof window!=="undefined"){glWiretap.glExtensionWiretap=glExtensionWiretap;window.glWiretap=glWiretap}},{}],4:[function(require2,module3,exports3){function setupArguments(args){const newArguments=new Array(args.length);for(let i=0;i{kernel.output=setupOutput(output);if(kernel.graphical){setupGraphical(kernel)}};kernel.toJSON=()=>{throw new Error("Not usable with gpuMock")};kernel.setConstants=flag=>{kernel.constants=flag;return kernel};kernel.setGraphical=flag=>{kernel.graphical=flag;return kernel};kernel.setCanvas=flag=>{kernel.canvas=flag;return kernel};kernel.setContext=flag=>{kernel.context=flag;return kernel};kernel.destroy=()=>{};kernel.validateSettings=()=>{};if(kernel.graphical&&kernel.output){setupGraphical(kernel)}kernel.exec=function(){return new Promise((resolve,reject)=>{try{resolve(kernel.apply(kernel,arguments))}catch(e){reject(e)}})};kernel.getPixels=flip=>{const{x:x2,y}=kernel.output;return flip?flipPixels(kernel._imageData.data,x2,y):kernel._imageData.data.slice(0)};kernel.color=function(r,g,b,a){if(typeof a==="undefined"){a=1}r=Math.floor(r*255);g=Math.floor(g*255);b=Math.floor(b*255);a=Math.floor(a*255);const width=kernel.output.x;const height=kernel.output.y;const x2=kernel.thread.x;const y=height-kernel.thread.y-1;const index=x2+y*width;kernel._colorData[index*4+0]=r;kernel._colorData[index*4+1]=g;kernel._colorData[index*4+2]=b;kernel._colorData[index*4+3]=a};const mockMethod=()=>kernel;const methods=["setWarnVarUsage","setArgumentTypes","setTactic","setOptimizeFloatMemory","setDebug","setLoopMaxIterations","setConstantTypes","setFunctions","setNativeFunctions","setInjectedNative","setPipeline","setPrecision","setOutputToTexture","setImmutable","setStrictIntegers","setDynamicOutput","setHardcodeConstants","setDynamicArguments","setUseLegacyEncoder","setWarnVarUsage","addSubKernel"];for(let i=0;i0){retArr.push(", ")}retArr.push("user_");retArr.push(argumentName)}retArr.push(") {\n")}for(let i=0;i0){retArr.push(initArr.join(""),";\n")}retArr.push(`for (let ${iVariableName}=0;${iVariableName}0){retArr.push(`if (!${testArr.join("")}) break; -`)}retArr.push(bodyArr.join(""));retArr.push(` -${updateArr.join("")};`);retArr.push("}\n")}return retArr}astWhileStatement(whileNode,retArr){if(whileNode.type!=="WhileStatement"){throw this.astErrorOutput("Invalid while statement",whileNode)}retArr.push("for (let i = 0; i < LOOP_MAX; i++) {");retArr.push("if (");this.astGeneric(whileNode.test,retArr);retArr.push(") {\n");this.astGeneric(whileNode.body,retArr);retArr.push("} else {\n");retArr.push("break;\n");retArr.push("}\n");retArr.push("}\n");return retArr}astDoWhileStatement(doWhileNode,retArr){if(doWhileNode.type!=="DoWhileStatement"){throw this.astErrorOutput("Invalid while statement",doWhileNode)}retArr.push("for (let i = 0; i < LOOP_MAX; i++) {");this.astGeneric(doWhileNode.body,retArr);retArr.push("if (!");this.astGeneric(doWhileNode.test,retArr);retArr.push(") {\n");retArr.push("break;\n");retArr.push("}\n");retArr.push("}\n");return retArr}astAssignmentExpression(assNode,retArr){const declaration=this.getDeclaration(assNode.left);if(declaration&&!declaration.assignable){throw this.astErrorOutput(`Variable ${assNode.left.name} is not assignable here`,assNode)}this.astGeneric(assNode.left,retArr);retArr.push(assNode.operator);this.astGeneric(assNode.right,retArr);return retArr}astBlockStatement(bNode,retArr){if(this.isState("loop-body")){this.pushState("block-body");for(let i=0;i0){retArr.push(",")}const declaration=declarations[i];const info=this.getDeclaration(declaration.id);if(!info.valueType){info.valueType=this.getType(declaration.init)}this.astGeneric(declaration,retArr)}if(!this.isState("in-for-loop-init")){retArr.push(";")}return retArr}astIfStatement(ifNode,retArr){retArr.push("if (");this.astGeneric(ifNode.test,retArr);retArr.push(")");if(ifNode.consequent.type==="BlockStatement"){this.astGeneric(ifNode.consequent,retArr)}else{retArr.push(" {\n");this.astGeneric(ifNode.consequent,retArr);retArr.push("\n}\n")}if(ifNode.alternate){retArr.push("else ");if(ifNode.alternate.type==="BlockStatement"||ifNode.alternate.type==="IfStatement"){this.astGeneric(ifNode.alternate,retArr)}else{retArr.push(" {\n");this.astGeneric(ifNode.alternate,retArr);retArr.push("\n}\n")}}return retArr}astSwitchStatement(ast,retArr){const{discriminant,cases}=ast;retArr.push("switch (");this.astGeneric(discriminant,retArr);retArr.push(") {\n");for(let i=0;i0){retArr.push("break;\n")}continue}retArr.push("case ");this.astGeneric(cases[i].test,retArr);retArr.push(":\n");if(cases[i].consequent&&cases[i].consequent.length>0){this.astGeneric(cases[i].consequent,retArr);retArr.push("break;\n")}}retArr.push("\n}")}astThisExpression(tNode,retArr){retArr.push("_this");return retArr}astMemberExpression(mNode,retArr){const{signature,type,property,xProperty,yProperty,zProperty,name:name2,origin}=this.getMemberExpressionDetails(mNode);switch(signature){case"this.thread.value":retArr.push(`_this.thread.${name2}`);return retArr;case"this.output.value":switch(name2){case"x":retArr.push("outputX");break;case"y":retArr.push("outputY");break;case"z":retArr.push("outputZ");break;default:throw this.astErrorOutput("Unexpected expression",mNode)}return retArr;case"value":throw this.astErrorOutput("Unexpected expression",mNode);case"value[]":case"value[][]":case"value[][][]":case"value.value":if(origin==="Math"){retArr.push(Math[name2]);return retArr}switch(property){case"r":retArr.push(`user_${name2}[0]`);return retArr;case"g":retArr.push(`user_${name2}[1]`);return retArr;case"b":retArr.push(`user_${name2}[2]`);return retArr;case"a":retArr.push(`user_${name2}[3]`);return retArr}break;case"this.constants.value":case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":break;case"fn()[]":this.astGeneric(mNode.object,retArr);retArr.push("[");this.astGeneric(mNode.property,retArr);retArr.push("]");return retArr;case"fn()[][]":this.astGeneric(mNode.object.object,retArr);retArr.push("[");this.astGeneric(mNode.object.property,retArr);retArr.push("]");retArr.push("[");this.astGeneric(mNode.property,retArr);retArr.push("]");return retArr;default:throw this.astErrorOutput("Unexpected expression",mNode)}if(!mNode.computed){switch(type){case"Number":case"Integer":case"Float":case"Boolean":retArr.push(`${origin}_${name2}`);return retArr}}const markupName=`${origin}_${name2}`;switch(type){case"Array(2)":case"Array(3)":case"Array(4)":case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":case"HTMLImageArray":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":case"HTMLImage":default:let size;let isInput;if(origin==="constants"){const constant=this.constants[name2];isInput=this.constantTypes[name2]==="Input";size=isInput?constant.size:null}else{isInput=this.isInput(name2);size=isInput?this.argumentSizes[this.argumentNames.indexOf(name2)]:null}retArr.push(`${markupName}`);if(zProperty&&yProperty){if(isInput){retArr.push("[(");this.astGeneric(zProperty,retArr);retArr.push(`*${this.dynamicArguments?"(outputY * outputX)":size[1]*size[0]})+(`);this.astGeneric(yProperty,retArr);retArr.push(`*${this.dynamicArguments?"outputX":size[0]})+`);this.astGeneric(xProperty,retArr);retArr.push("]")}else{retArr.push("[");this.astGeneric(zProperty,retArr);retArr.push("]");retArr.push("[");this.astGeneric(yProperty,retArr);retArr.push("]");retArr.push("[");this.astGeneric(xProperty,retArr);retArr.push("]")}}else if(yProperty){if(isInput){retArr.push("[(");this.astGeneric(yProperty,retArr);retArr.push(`*${this.dynamicArguments?"outputX":size[0]})+`);this.astGeneric(xProperty,retArr);retArr.push("]")}else{retArr.push("[");this.astGeneric(yProperty,retArr);retArr.push("]");retArr.push("[");this.astGeneric(xProperty,retArr);retArr.push("]")}}else if(typeof xProperty!=="undefined"){retArr.push("[");this.astGeneric(xProperty,retArr);retArr.push("]")}}return retArr}astCallExpression(ast,retArr){if(ast.type!=="CallExpression"){throw this.astErrorOutput("Unknown CallExpression",ast)}let functionName=this.astMemberExpressionUnroll(ast.callee);if(this.calledFunctions.indexOf(functionName)<0){this.calledFunctions.push(functionName)}const isMathFunction=this.isAstMathFunction(ast);if(this.onFunctionCall){this.onFunctionCall(this.name,functionName,ast.arguments)}retArr.push(functionName);retArr.push("(");const targetTypes=this.lookupFunctionArgumentTypes(functionName)||[];for(let i=0;i0){retArr.push(", ")}this.astGeneric(argument,retArr)}retArr.push(")");return retArr}astArrayExpression(arrNode,retArr){const returnType=this.getType(arrNode);const arrLen=arrNode.elements.length;const elements=[];for(let i=0;i{switch(propertyName){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(cpuKernel[propertyName])},findDependency:(object,name3)=>{return null}});const getPixelsFn=utils.flattenFunctionToString((useFunctionKeyword?"function ":"")+cpuKernel.getPixels.toString(),{thisLookup:propertyName=>{switch(propertyName){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(cpuKernel[propertyName])},findDependency:()=>{return null}});thisProperties.push(" _imageData,"," _colorData,",` color: ${colorFn},`);beforeReturn.push(` kernel.getPixels = ${getPixelsFn};`)}const constantTypes=[];const constantKeys=Object.keys(cpuKernel.constantTypes);for(let i=0;i{if(object==="this"){return(useFunctionKeyword?"function ":"")+cpuKernel[name3].toString()}return null},thisLookup:propertyName=>{switch(propertyName){case"canvas":return;case"context":return"context"}}});beforeReturn.push(flattenedImageTo3DArray);thisProperties.push(` _mediaTo2DArray,`);thisProperties.push(` _imageTo3DArray,`)}else if(cpuKernel.argumentTypes.indexOf("HTMLImage")!==-1||constantTypes.indexOf("HTMLImage")!==-1){const flattenedImageTo2DArray=utils.flattenFunctionToString((useFunctionKeyword?"function ":"")+cpuKernel._mediaTo2DArray.toString(),{findDependency:(object,name3)=>{return null},thisLookup:propertyName=>{switch(propertyName){case"canvas":return"settings.canvas";case"context":return"settings.context"}throw new Error("unhandled thisLookup")}});beforeReturn.push(flattenedImageTo2DArray);thisProperties.push(` _mediaTo2DArray,`)}return`function(settings) { - ${header.join("\n")} - for (const p in _constantTypes) { - if (!_constantTypes.hasOwnProperty(p)) continue; - const type = _constantTypes[p]; - switch (type) { - case 'Number': - case 'Integer': - case 'Float': - case 'Boolean': - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - case 'Matrix(2)': - case 'Matrix(3)': - case 'Matrix(4)': - if (incomingConstants.hasOwnProperty(p)) { - console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned'); - } - continue; - } - if (!incomingConstants.hasOwnProperty(p)) { - throw new Error('constant ' + p + ' not found'); - } - _constants[p] = incomingConstants[p]; - } - const kernel = (function() { - ${cpuKernel._kernelString} - }) - .apply({ ${thisProperties.join("\n")} }); - ${beforeReturn.join("\n")} - return kernel; - }`}module3.exports={cpuKernelString}},{"../../utils":114}],8:[function(require2,module3,exports3){const{Kernel}=require2("../kernel");const{FunctionBuilder}=require2("../function-builder");const{CPUFunctionNode}=require2("./function-node");const{utils}=require2("../../utils");const{cpuKernelString}=require2("./kernel-string");class CPUKernel extends Kernel{static getFeatures(){return this.features}static get features(){return Object.freeze({kernelMap:true,isIntegerDivisionAccurate:true})}static get isSupported(){return true}static isContextMatch(context){return false}static get mode(){return"cpu"}static nativeFunctionArguments(){return null}static nativeFunctionReturnType(){throw new Error(`Looking up native function return type not supported on ${this.name}`)}static combineKernels(combinedKernel){return combinedKernel}static getSignature(kernel,argumentTypes){return"cpu"+(argumentTypes.length>0?":"+argumentTypes.join(","):"")}constructor(source,settings){super(source,settings);this.mergeSettings(source.settings||settings);this._imageData=null;this._colorData=null;this._kernelString=null;this._prependedString=[];this.thread={x:0,y:0,z:0};this.translatedSources=null}initCanvas(){if(typeof document!=="undefined"){return document.createElement("canvas")}else if(typeof OffscreenCanvas!=="undefined"){return new OffscreenCanvas(0,0)}}initContext(){if(!this.canvas)return null;return this.canvas.getContext("2d")}initPlugins(settings){return[]}validateSettings(args){if(!this.output||this.output.length===0){if(args.length!==1){throw new Error("Auto output only supported for kernels with only one input")}const argType=utils.getVariableType(args[0],this.strictIntegers);if(argType==="Array"){this.output=utils.getDimensions(argType)}else if(argType==="NumberTexture"||argType==="ArrayTexture(4)"){this.output=args[0].output}else{throw new Error("Auto output not supported for input type: "+argType)}}if(this.graphical){if(this.output.length!==2){throw new Error("Output must have 2 dimensions on graphical mode")}}this.checkOutput()}translateSource(){this.leadingReturnStatement=this.output.length>1?"resultX[x] = ":"result[x] = ";if(this.subKernels){const followingReturnStatement=[];for(let i=0;i1?`resultX_${name2}[x] = subKernelResult_${name2}; -`:`result_${name2}[x] = subKernelResult_${name2}; -`)}this.followingReturnStatement=followingReturnStatement.join("")}const functionBuilder=FunctionBuilder.fromKernel(this,CPUFunctionNode);this.translatedSources=functionBuilder.getPrototypes("kernel");if(!this.graphical&&!this.returnType){this.returnType=functionBuilder.getKernelResultType()}}build(){if(this.built)return;this.setupConstants();this.setupArguments(arguments);this.validateSettings(arguments);this.translateSource();if(this.graphical){const{canvas,output}=this;if(!canvas){throw new Error("no canvas available for using graphical output")}const width=output[0];const height=output[1]||1;canvas.width=width;canvas.height=height;this._imageData=this.context.createImageData(width,height);this._colorData=new Uint8ClampedArray(width*height*4)}const kernelString=this.getKernelString();this.kernelString=kernelString;if(this.debug){console.log("Function output:");console.log(kernelString)}try{this.run=new Function([],kernelString).bind(this)()}catch(e){console.error("An error occurred compiling the javascript: ",e)}this.buildSignature(arguments);this.built=true}color(r,g,b,a){if(typeof a==="undefined"){a=1}r=Math.floor(r*255);g=Math.floor(g*255);b=Math.floor(b*255);a=Math.floor(a*255);const width=this.output[0];const height=this.output[1];const x2=this.thread.x;const y=height-this.thread.y-1;const index=x2+y*width;this._colorData[index*4+0]=r;this._colorData[index*4+1]=g;this._colorData[index*4+2]=b;this._colorData[index*4+3]=a}getKernelString(){if(this._kernelString!==null)return this._kernelString;let kernelThreadString=null;let{translatedSources}=this;if(translatedSources.length>1){translatedSources=translatedSources.filter(fn=>{if(/^function/.test(fn))return fn;kernelThreadString=fn;return false})}else{kernelThreadString=translatedSources.shift()}return this._kernelString=` const LOOP_MAX = ${this._getLoopMaxString()}; - ${this.injectedNative||""} - const _this = this; - ${this._resultKernelHeader()} - ${this._processConstants()} - return (${this.argumentNames.map(argumentName=>"user_"+argumentName).join(", ")}) => { - ${this._prependedString.join("")} - ${this._earlyThrows()} - ${this._processArguments()} - ${this.graphical?this._graphicalKernelBody(kernelThreadString):this._resultKernelBody(kernelThreadString)} - ${translatedSources.length>0?translatedSources.join("\n"):""} - };`}toString(){return cpuKernelString(this)}_getLoopMaxString(){return this.loopMaxIterations?` ${parseInt(this.loopMaxIterations)};`:" 1000;"}_processConstants(){if(!this.constants)return"";const result=[];for(let p in this.constants){const type=this.constantTypes[p];switch(type){case"HTMLCanvas":case"HTMLImage":case"HTMLVideo":result.push(` const constants_${p} = this._mediaTo2DArray(this.constants.${p}); -`);break;case"HTMLImageArray":result.push(` const constants_${p} = this._imageTo3DArray(this.constants.${p}); -`);break;case"Input":result.push(` const constants_${p} = this.constants.${p}.value; -`);break;default:result.push(` const constants_${p} = this.constants.${p}; -`)}}return result.join("")}_earlyThrows(){if(this.graphical)return"";if(this.immutable)return"";if(!this.pipeline)return"";const arrayArguments=[];for(let i=0;i`user_${argumentName} === result_${subKernel.name}`).join(" || ");checks.push(`user_${argumentName} === result${checkSubKernels?` || ${checkSubKernels}`:""}`)}return`if (${checks.join(" || ")}) throw new Error('Source and destination arrays are the same. Use immutable = true');`}_processArguments(){const result=[];for(let i=0;i0?media.width:media.videoWidth;const height=media.height>0?media.height:media.videoHeight;if(canvas.width=0;y--){const row=imageArray[y]=new Array(width);for(let x2=0;x2`const result_${subKernel.name} = new ${constructorString}(outputX); -`).join(" ")} - ${this._mapSubKernels(subKernel=>`let subKernelResult_${subKernel.name}; -`).join(" ")} - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - this.thread.y = 0; - this.thread.z = 0; - ${kernelString} - }`}_mutableKernel1DResults(){const constructorString=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0]; - const result = new ${constructorString}(outputX); - ${this._mapSubKernels(subKernel=>`const result_${subKernel.name} = new ${constructorString}(outputX); -`).join(" ")} - ${this._mapSubKernels(subKernel=>`let subKernelResult_${subKernel.name}; -`).join(" ")}`}_resultMutableKernel1DLoop(kernelString){return` const outputX = _this.output[0]; - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - this.thread.y = 0; - this.thread.z = 0; - ${kernelString} - }`}_resultImmutableKernel2DLoop(kernelString){const constructorString=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0]; - const outputY = _this.output[1]; - const result = new Array(outputY); - ${this._mapSubKernels(subKernel=>`const result_${subKernel.name} = new Array(outputY); -`).join(" ")} - ${this._mapSubKernels(subKernel=>`let subKernelResult_${subKernel.name}; -`).join(" ")} - for (let y = 0; y < outputY; y++) { - this.thread.z = 0; - this.thread.y = y; - const resultX = result[y] = new ${constructorString}(outputX); - ${this._mapSubKernels(subKernel=>`const resultX_${subKernel.name} = result_${subKernel.name}[y] = new ${constructorString}(outputX); -`).join("")} - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${kernelString} - } - }`}_mutableKernel2DResults(){const constructorString=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0]; - const outputY = _this.output[1]; - const result = new Array(outputY); - ${this._mapSubKernels(subKernel=>`const result_${subKernel.name} = new Array(outputY); -`).join(" ")} - ${this._mapSubKernels(subKernel=>`let subKernelResult_${subKernel.name}; -`).join(" ")} - for (let y = 0; y < outputY; y++) { - const resultX = result[y] = new ${constructorString}(outputX); - ${this._mapSubKernels(subKernel=>`const resultX_${subKernel.name} = result_${subKernel.name}[y] = new ${constructorString}(outputX); -`).join("")} - }`}_resultMutableKernel2DLoop(kernelString){const constructorString=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0]; - const outputY = _this.output[1]; - for (let y = 0; y < outputY; y++) { - this.thread.z = 0; - this.thread.y = y; - const resultX = result[y]; - ${this._mapSubKernels(subKernel=>`const resultX_${subKernel.name} = result_${subKernel.name}[y] = new ${constructorString}(outputX); -`).join("")} - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${kernelString} - } - }`}_graphicalKernel2DLoop(kernelString){return` const outputX = _this.output[0]; - const outputY = _this.output[1]; - for (let y = 0; y < outputY; y++) { - this.thread.z = 0; - this.thread.y = y; - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${kernelString} - } - }`}_resultImmutableKernel3DLoop(kernelString){const constructorString=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0]; - const outputY = _this.output[1]; - const outputZ = _this.output[2]; - const result = new Array(outputZ); - ${this._mapSubKernels(subKernel=>`const result_${subKernel.name} = new Array(outputZ); -`).join(" ")} - ${this._mapSubKernels(subKernel=>`let subKernelResult_${subKernel.name}; -`).join(" ")} - for (let z = 0; z < outputZ; z++) { - this.thread.z = z; - const resultY = result[z] = new Array(outputY); - ${this._mapSubKernels(subKernel=>`const resultY_${subKernel.name} = result_${subKernel.name}[z] = new Array(outputY); -`).join(" ")} - for (let y = 0; y < outputY; y++) { - this.thread.y = y; - const resultX = resultY[y] = new ${constructorString}(outputX); - ${this._mapSubKernels(subKernel=>`const resultX_${subKernel.name} = resultY_${subKernel.name}[y] = new ${constructorString}(outputX); -`).join(" ")} - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${kernelString} - } - } - }`}_mutableKernel3DResults(){const constructorString=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0]; - const outputY = _this.output[1]; - const outputZ = _this.output[2]; - const result = new Array(outputZ); - ${this._mapSubKernels(subKernel=>`const result_${subKernel.name} = new Array(outputZ); -`).join(" ")} - ${this._mapSubKernels(subKernel=>`let subKernelResult_${subKernel.name}; -`).join(" ")} - for (let z = 0; z < outputZ; z++) { - const resultY = result[z] = new Array(outputY); - ${this._mapSubKernels(subKernel=>`const resultY_${subKernel.name} = result_${subKernel.name}[z] = new Array(outputY); -`).join(" ")} - for (let y = 0; y < outputY; y++) { - const resultX = resultY[y] = new ${constructorString}(outputX); - ${this._mapSubKernels(subKernel=>`const resultX_${subKernel.name} = resultY_${subKernel.name}[y] = new ${constructorString}(outputX); -`).join(" ")} - } - }`}_resultMutableKernel3DLoop(kernelString){return` const outputX = _this.output[0]; - const outputY = _this.output[1]; - const outputZ = _this.output[2]; - for (let z = 0; z < outputZ; z++) { - this.thread.z = z; - const resultY = result[z]; - for (let y = 0; y < outputY; y++) { - this.thread.y = y; - const resultX = resultY[y]; - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${kernelString} - } - } - }`}_kernelOutput(){if(!this.subKernels){return"\n return result;"}return` - return { - result: result, - ${this.subKernels.map(subKernel=>`${subKernel.property}: result_${subKernel.name}`).join(",\n ")} - };`}_mapSubKernels(fn){return this.subKernels===null?[""]:this.subKernels.map(fn)}destroy(removeCanvasReference){if(removeCanvasReference){delete this.canvas}}static destroyContext(context){}toJSON(){const json=super.toJSON();json.functionNodes=FunctionBuilder.fromKernel(this,CPUFunctionNode).toJSON();return json}setOutput(output){super.setOutput(output);const[width,height]=this.output;if(this.graphical){this._imageData=this.context.createImageData(width,height);this._colorData=new Uint8ClampedArray(width*height*4)}}prependString(value2){if(this._kernelString)throw new Error("Kernel already built");this._prependedString.push(value2)}hasPrependString(value2){return this._prependedString.indexOf(value2)>-1}}module3.exports={CPUKernel}},{"../../utils":114,"../function-builder":9,"../kernel":36,"./function-node":6,"./kernel-string":7}],9:[function(require2,module3,exports3){class FunctionBuilder{static fromKernel(kernel,FunctionNode,extraNodeOptions){const{kernelArguments,kernelConstants,argumentNames,argumentSizes,argumentBitRatios,constants,constantBitRatios,debug,loopMaxIterations,nativeFunctions,output,optimizeFloatMemory,precision,plugins,source,subKernels,functions,leadingReturnStatement,followingReturnStatement,dynamicArguments,dynamicOutput}=kernel;const argumentTypes=new Array(kernelArguments.length);const constantTypes={};for(let i=0;i{return functionBuilder.needsArgumentType(functionName,index)};const assignArgumentType=(functionName,index,type)=>{functionBuilder.assignArgumentType(functionName,index,type)};const lookupReturnType=(functionName,ast,requestingNode)=>{return functionBuilder.lookupReturnType(functionName,ast,requestingNode)};const lookupFunctionArgumentTypes=functionName=>{return functionBuilder.lookupFunctionArgumentTypes(functionName)};const lookupFunctionArgumentName=(functionName,argumentIndex)=>{return functionBuilder.lookupFunctionArgumentName(functionName,argumentIndex)};const lookupFunctionArgumentBitRatio=(functionName,argumentName)=>{return functionBuilder.lookupFunctionArgumentBitRatio(functionName,argumentName)};const triggerImplyArgumentType=(functionName,i,argumentType,requestingNode)=>{functionBuilder.assignArgumentType(functionName,i,argumentType,requestingNode)};const triggerImplyArgumentBitRatio=(functionName,argumentName,calleeFunctionName,argumentIndex)=>{functionBuilder.assignArgumentBitRatio(functionName,argumentName,calleeFunctionName,argumentIndex)};const onFunctionCall=(functionName,calleeFunctionName,args)=>{functionBuilder.trackFunctionCall(functionName,calleeFunctionName,args)};const onNestedFunction=(ast,source2)=>{const argumentNames2=[];for(let i=0;inew FunctionNode(fn.source,{returnType:fn.returnType,argumentTypes:fn.argumentTypes,output,plugins,constants,constantTypes,constantBitRatios,optimizeFloatMemory,precision,lookupReturnType,lookupFunctionArgumentTypes,lookupFunctionArgumentName,lookupFunctionArgumentBitRatio,needsArgumentType,assignArgumentType,triggerImplyArgumentType,triggerImplyArgumentBitRatio,onFunctionCall,onNestedFunction}))}let subKernelNodes=null;if(subKernels){subKernelNodes=subKernels.map(subKernel=>{const{name:name2,source:source2}=subKernel;return new FunctionNode(source2,Object.assign({},nodeOptions,{name:name2,isSubKernel:true,isRootKernel:false}))})}const functionBuilder=new FunctionBuilder({kernel,rootNode,functionNodes,nativeFunctions,subKernelNodes});return functionBuilder}constructor(settings){settings=settings||{};this.kernel=settings.kernel;this.rootNode=settings.rootNode;this.functionNodes=settings.functionNodes||[];this.subKernelNodes=settings.subKernelNodes||[];this.nativeFunctions=settings.nativeFunctions||[];this.functionMap={};this.nativeFunctionNames=[];this.lookupChain=[];this.functionNodeDependencies={};this.functionCalls={};if(this.rootNode){this.functionMap["kernel"]=this.rootNode}if(this.functionNodes){for(let i=0;i-1){const nativeFunctionIndex=retList.indexOf(functionName);if(nativeFunctionIndex===-1){retList.push(functionName)}else{const dependantNativeFunctionName=retList.splice(nativeFunctionIndex,1)[0];retList.push(dependantNativeFunctionName)}return retList}const functionNode=this.functionMap[functionName];if(functionNode){const functionIndex=retList.indexOf(functionName);if(functionIndex===-1){retList.push(functionName);functionNode.toString();for(let i=0;i-1){ret.push(this.nativeFunctions[functionIndex].source);continue}const node=this.functionMap[functionName];if(node){ret.push(node.toString())}}return ret}toJSON(){return this.traceFunctionCalls(this.rootNode.name).reverse().map(name2=>{const nativeIndex=this.nativeFunctions.indexOf(name2);if(nativeIndex>-1){return{name:name2,source:this.nativeFunctions[nativeIndex].source}}else if(this.functionMap[name2]){return this.functionMap[name2].toJSON()}else{throw new Error(`function ${name2} not found`)}})}fromJSON(jsonFunctionNodes,FunctionNode){this.functionMap={};for(let i=0;i0){const args=ast.arguments;for(let j=0;j0&&this.argumentTypes.length!==this.argumentNames.length){throw new Error(`argumentTypes count of ${this.argumentTypes.length} exceeds ${this.argumentNames.length}`)}if(this.output.length<1){throw new Error("this.output is not big enough")}}isIdentifierConstant(name2){if(!this.constants)return false;return this.constants.hasOwnProperty(name2)}isInput(argumentName){return this.argumentTypes[this.argumentNames.indexOf(argumentName)]==="Input"}pushState(state2){this.states.push(state2)}popState(state2){if(this.state!==state2){throw new Error(`Cannot popState ${state2} when in ${this.state}`)}this.states.pop()}isState(state2){return this.state===state2}get state(){return this.states[this.states.length-1]}astMemberExpressionUnroll(ast){if(ast.type==="Identifier"){return ast.name}else if(ast.type==="ThisExpression"){return"this"}if(ast.type==="MemberExpression"){if(ast.object&&ast.property){if(ast.object.hasOwnProperty("name")&&ast.object.name!=="Math"){return this.astMemberExpressionUnroll(ast.property)}return this.astMemberExpressionUnroll(ast.object)+"."+this.astMemberExpressionUnroll(ast.property)}}if(ast.hasOwnProperty("expressions")){const firstExpression=ast.expressions[0];if(firstExpression.type==="Literal"&&firstExpression.value===0&&ast.expressions.length===2){return this.astMemberExpressionUnroll(ast.expressions[1])}}throw this.astErrorOutput("Unknown astMemberExpressionUnroll",ast)}getJsAST(inParser){if(this.ast){return this.ast}if(typeof this.source==="object"){this.traceFunctionAST(this.source);return this.ast=this.source}inParser=inParser||acorn;if(inParser===null){throw new Error("Missing JS to AST parser")}const ast=Object.freeze(inParser.parse(`const parser_${this.name} = ${this.source};`,{locations:true}));const functionAST=ast.body[0].declarations[0].init;this.traceFunctionAST(functionAST);if(!ast){throw new Error("Failed to parse JS code")}return this.ast=functionAST}traceFunctionAST(ast){const{contexts,declarations,functions,identifiers,functionCalls}=new FunctionTracer(ast);this.contexts=contexts;this.identifiers=identifiers;this.functionCalls=functionCalls;this.functions=functions;for(let i=0;i":case"<":return"Boolean";case"&":case"|":case"^":case"<<":case">>":case">>>":return"Integer"}const type=this.getType(ast.left);if(this.isState("skip-literal-correction"))return type;if(type==="LiteralInteger"){const rightType=this.getType(ast.right);if(rightType==="LiteralInteger"){if(ast.left.value%1===0){return"Integer"}else{return"Float"}}return rightType}return typeLookupMap[type]||type;case"UpdateExpression":return this.getType(ast.argument);case"UnaryExpression":if(ast.operator==="~"){return"Integer"}return this.getType(ast.argument);case"VariableDeclaration":{const declarations=ast.declarations;let lastType;for(let i=0;i-1}isAstMathFunction(ast){const mathFunctions=["abs","acos","acosh","asin","asinh","atan","atan2","atanh","cbrt","ceil","clz32","cos","cosh","expm1","exp","floor","fround","imul","log","log2","log10","log1p","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc"];return ast.type==="CallExpression"&&ast.callee&&ast.callee.type==="MemberExpression"&&ast.callee.object&&ast.callee.object.type==="Identifier"&&ast.callee.object.name==="Math"&&ast.callee.property&&ast.callee.property.type==="Identifier"&&mathFunctions.indexOf(ast.callee.property.name)>-1}isAstVariable(ast){return ast.type==="Identifier"||ast.type==="MemberExpression"}isSafe(ast){return this.isSafeDependencies(this.getDependencies(ast))}isSafeDependencies(dependencies){return dependencies&&dependencies.every?dependencies.every(dependency=>dependency.isSafe):true}getDependencies(ast,dependencies,isNotSafe){if(!dependencies){dependencies=[]}if(!ast)return null;if(Array.isArray(ast)){for(let i=0;i-Infinity&&ast.value-1){dependencies.push({name:ast.name,origin:"argument",isSafe:false})}else if(this.strictTypingChecking){throw new Error(`Cannot find identifier origin "${ast.name}"`)}break;case"FunctionDeclaration":return this.getDependencies(ast.body.body[ast.body.body.length-1],dependencies,isNotSafe);case"ReturnStatement":return this.getDependencies(ast.argument,dependencies);case"BinaryExpression":case"LogicalExpression":isNotSafe=ast.operator==="/"||ast.operator==="*";this.getDependencies(ast.left,dependencies,isNotSafe);this.getDependencies(ast.right,dependencies,isNotSafe);return dependencies;case"UnaryExpression":case"UpdateExpression":return this.getDependencies(ast.argument,dependencies,isNotSafe);case"VariableDeclaration":return this.getDependencies(ast.declarations,dependencies,isNotSafe);case"ArrayExpression":dependencies.push({origin:"declaration",isSafe:true});return dependencies;case"CallExpression":dependencies.push({origin:"function",isSafe:true});return dependencies;case"MemberExpression":const details=this.getMemberExpressionDetails(ast);switch(details.signature){case"value[]":this.getDependencies(ast.object,dependencies,isNotSafe);break;case"value[][]":this.getDependencies(ast.object.object,dependencies,isNotSafe);break;case"value[][][]":this.getDependencies(ast.object.object.object,dependencies,isNotSafe);break;case"this.output.value":if(this.dynamicOutput){dependencies.push({name:details.name,origin:"output",isSafe:false})}break}if(details){if(details.property){this.getDependencies(details.property,dependencies,isNotSafe)}if(details.xProperty){this.getDependencies(details.xProperty,dependencies,isNotSafe)}if(details.yProperty){this.getDependencies(details.yProperty,dependencies,isNotSafe)}if(details.zProperty){this.getDependencies(details.zProperty,dependencies,isNotSafe)}return dependencies}case"SequenceExpression":return this.getDependencies(ast.expressions,dependencies,isNotSafe);default:throw this.astErrorOutput(`Unhandled type ${ast.type} in getDependencies`,ast)}return dependencies}getVariableSignature(ast,returnRawValue){if(!this.isAstVariable(ast)){throw new Error(`ast of type "${ast.type}" is not a variable signature`)}if(ast.type==="Identifier"){return"value"}const signature=[];while(true){if(!ast)break;if(ast.computed){signature.push("[]")}else if(ast.type==="ThisExpression"){signature.unshift("this")}else if(ast.property&&ast.property.name){if(ast.property.name==="x"||ast.property.name==="y"||ast.property.name==="z"){signature.unshift(returnRawValue?"."+ast.property.name:".value")}else if(ast.property.name==="constants"||ast.property.name==="thread"||ast.property.name==="output"){signature.unshift("."+ast.property.name)}else{signature.unshift(returnRawValue?"."+ast.property.name:".value")}}else if(ast.name){signature.unshift(returnRawValue?ast.name:"value")}else if(ast.callee&&ast.callee.name){signature.unshift(returnRawValue?ast.callee.name+"()":"fn()")}else if(ast.elements){signature.unshift("[]")}else{signature.unshift("unknown")}ast=ast.object}const signatureString=signature.join("");if(returnRawValue){return signatureString}const allowedExpressions=["value","value[]","value[][]","value[][][]","value[][][][]","value.value","value.thread.value","this.thread.value","this.output.value","this.constants.value","this.constants.value[]","this.constants.value[][]","this.constants.value[][][]","this.constants.value[][][][]","fn()[]","fn()[][]","fn()[][][]","[][]"];if(allowedExpressions.indexOf(signatureString)>-1){return signatureString}return null}build(){return this.toString().length>0}astGeneric(ast,retArr){if(ast===null){throw this.astErrorOutput("NULL ast",ast)}else{if(Array.isArray(ast)){for(let i=0;i0?splitLines[splitLines.length-1]:0;return new Error(`${error} on line ${splitLines.length}, position ${lineBefore.length}: - ${debugString}`)}astDebuggerStatement(arrNode,retArr){return retArr}astConditionalExpression(ast,retArr){if(ast.type!=="ConditionalExpression"){throw this.astErrorOutput("Not a conditional expression",ast)}retArr.push("(");this.astGeneric(ast.test,retArr);retArr.push("?");this.astGeneric(ast.consequent,retArr);retArr.push(":");this.astGeneric(ast.alternate,retArr);retArr.push(")");return retArr}astFunction(ast,retArr){throw new Error(`"astFunction" not defined on ${this.constructor.name}`)}astFunctionDeclaration(ast,retArr){if(this.isChildFunction(ast)){return retArr}return this.astFunction(ast,retArr)}astFunctionExpression(ast,retArr){if(this.isChildFunction(ast)){return retArr}return this.astFunction(ast,retArr)}isChildFunction(ast){for(let i=0;i1){retArr.push("(",sequenceResult.join(","),")")}else{retArr.push(sequenceResult[0])}return retArr}astUnaryExpression(uNode,retArr){const unaryResult=this.checkAndUpconvertBitwiseUnary(uNode,retArr);if(unaryResult){return retArr}if(uNode.prefix){retArr.push(uNode.operator);this.astGeneric(uNode.argument,retArr)}else{this.astGeneric(uNode.argument,retArr);retArr.push(uNode.operator)}return retArr}checkAndUpconvertBitwiseUnary(uNode,retArr){}astUpdateExpression(uNode,retArr){if(uNode.prefix){retArr.push(uNode.operator);this.astGeneric(uNode.argument,retArr)}else{this.astGeneric(uNode.argument,retArr);retArr.push(uNode.operator)}return retArr}astLogicalExpression(logNode,retArr){retArr.push("(");this.astGeneric(logNode.left,retArr);retArr.push(logNode.operator);this.astGeneric(logNode.right,retArr);retArr.push(")");return retArr}astMemberExpression(ast,retArr){return retArr}astCallExpression(ast,retArr){return retArr}astArrayExpression(ast,retArr){return retArr}getMemberExpressionDetails(ast){if(ast.type!=="MemberExpression"){throw this.astErrorOutput(`Expression ${ast.type} not a MemberExpression`,ast)}let name2=null;let type=null;const variableSignature=this.getVariableSignature(ast);switch(variableSignature){case"value":return null;case"value.thread.value":case"this.thread.value":case"this.output.value":return{signature:variableSignature,type:"Integer",name:ast.property.name};case"value[]":if(typeof ast.object.name!=="string"){throw this.astErrorOutput("Unexpected expression",ast)}name2=ast.object.name;return{name:name2,origin:"user",signature:variableSignature,type:this.getVariableType(ast.object),xProperty:ast.property};case"value[][]":if(typeof ast.object.object.name!=="string"){throw this.astErrorOutput("Unexpected expression",ast)}name2=ast.object.object.name;return{name:name2,origin:"user",signature:variableSignature,type:this.getVariableType(ast.object.object),yProperty:ast.object.property,xProperty:ast.property};case"value[][][]":if(typeof ast.object.object.object.name!=="string"){throw this.astErrorOutput("Unexpected expression",ast)}name2=ast.object.object.object.name;return{name:name2,origin:"user",signature:variableSignature,type:this.getVariableType(ast.object.object.object),zProperty:ast.object.object.property,yProperty:ast.object.property,xProperty:ast.property};case"value[][][][]":if(typeof ast.object.object.object.object.name!=="string"){throw this.astErrorOutput("Unexpected expression",ast)}name2=ast.object.object.object.object.name;return{name:name2,origin:"user",signature:variableSignature,type:this.getVariableType(ast.object.object.object.object),zProperty:ast.object.object.property,yProperty:ast.object.property,xProperty:ast.property};case"value.value":if(typeof ast.property.name!=="string"){throw this.astErrorOutput("Unexpected expression",ast)}if(this.isAstMathVariable(ast)){name2=ast.property.name;return{name:name2,origin:"Math",type:"Number",signature:variableSignature}}switch(ast.property.name){case"r":case"g":case"b":case"a":name2=ast.object.name;return{name:name2,property:ast.property.name,origin:"user",signature:variableSignature,type:"Number"};default:throw this.astErrorOutput("Unexpected expression",ast)}case"this.constants.value":if(typeof ast.property.name!=="string"){throw this.astErrorOutput("Unexpected expression",ast)}name2=ast.property.name;type=this.getConstantType(name2);if(!type){throw this.astErrorOutput("Constant has no type",ast)}return{name:name2,type,origin:"constants",signature:variableSignature};case"this.constants.value[]":if(typeof ast.object.property.name!=="string"){throw this.astErrorOutput("Unexpected expression",ast)}name2=ast.object.property.name;type=this.getConstantType(name2);if(!type){throw this.astErrorOutput("Constant has no type",ast)}return{name:name2,type,origin:"constants",signature:variableSignature,xProperty:ast.property};case"this.constants.value[][]":{if(typeof ast.object.object.property.name!=="string"){throw this.astErrorOutput("Unexpected expression",ast)}name2=ast.object.object.property.name;type=this.getConstantType(name2);if(!type){throw this.astErrorOutput("Constant has no type",ast)}return{name:name2,type,origin:"constants",signature:variableSignature,yProperty:ast.object.property,xProperty:ast.property}}case"this.constants.value[][][]":{if(typeof ast.object.object.object.property.name!=="string"){throw this.astErrorOutput("Unexpected expression",ast)}name2=ast.object.object.object.property.name;type=this.getConstantType(name2);if(!type){throw this.astErrorOutput("Constant has no type",ast)}return{name:name2,type,origin:"constants",signature:variableSignature,zProperty:ast.object.object.property,yProperty:ast.object.property,xProperty:ast.property}}case"fn()[]":case"fn()[][]":case"[][]":return{signature:variableSignature,property:ast.property};default:throw this.astErrorOutput("Unexpected expression",ast)}}findIdentifierOrigin(astToFind){const stack=[this.ast];while(stack.length>0){const atNode=stack[0];if(atNode.type==="VariableDeclarator"&&atNode.id&&atNode.id.name&&atNode.id.name===astToFind.name){return atNode}stack.shift();if(atNode.argument){stack.push(atNode.argument)}else if(atNode.body){stack.push(atNode.body)}else if(atNode.declarations){stack.push(atNode.declarations)}else if(Array.isArray(atNode)){for(let i=0;i0){const atNode=stack.pop();if(atNode.type==="ReturnStatement"){return atNode}if(atNode.type==="FunctionDeclaration"){continue}if(atNode.argument){stack.push(atNode.argument)}else if(atNode.body){stack.push(atNode.body)}else if(atNode.declarations){stack.push(atNode.declarations)}else if(Array.isArray(atNode)){for(let i=0;i0?array[array.length-1]:null}const states={trackIdentifiers:"trackIdentifiers",memberExpression:"memberExpression",inForLoopInit:"inForLoopInit"};class FunctionTracer{constructor(ast){this.runningContexts=[];this.functionContexts=[];this.contexts=[];this.functionCalls=[];this.declarations=[];this.identifiers=[];this.functions=[];this.returnStatements=[];this.trackedIdentifiers=null;this.states=[];this.newFunctionContext();this.scan(ast)}isState(state2){return this.states[this.states.length-1]===state2}hasState(state2){return this.states.indexOf(state2)>-1}pushState(state2){this.states.push(state2)}popState(state2){if(this.isState(state2)){this.states.pop()}else{throw new Error(`Cannot pop the non-active state "${state2}"`)}}get currentFunctionContext(){return last(this.functionContexts)}get currentContext(){return last(this.runningContexts)}newFunctionContext(){const newContext={"@contextType":"function"};this.contexts.push(newContext);this.functionContexts.push(newContext)}newContext(run){const newContext=Object.assign({"@contextType":"const/let"},this.currentContext);this.contexts.push(newContext);this.runningContexts.push(newContext);run();const{currentFunctionContext}=this;for(const p in currentFunctionContext){if(!currentFunctionContext.hasOwnProperty(p)||newContext.hasOwnProperty(p))continue;newContext[p]=currentFunctionContext[p]}this.runningContexts.pop();return newContext}useFunctionContext(run){const functionContext=last(this.functionContexts);this.runningContexts.push(functionContext);run();this.runningContexts.pop()}getIdentifiers(run){const trackedIdentifiers=this.trackedIdentifiers=[];this.pushState(states.trackIdentifiers);run();this.trackedIdentifiers=null;this.popState(states.trackIdentifiers);return trackedIdentifiers}getDeclaration(name2){const{currentContext,currentFunctionContext,runningContexts}=this;const declaration=currentContext[name2]||currentFunctionContext[name2]||null;if(!declaration&¤tContext===currentFunctionContext&&runningContexts.length>0){const previousRunningContext=runningContexts[runningContexts.length-2];if(previousRunningContext[name2]){return previousRunningContext[name2]}}return declaration}scan(ast){if(!ast)return;if(Array.isArray(ast)){for(let i=0;i{this.scan(ast.body)});break;case"BlockStatement":this.newContext(()=>{this.scan(ast.body)});break;case"AssignmentExpression":case"LogicalExpression":this.scan(ast.left);this.scan(ast.right);break;case"BinaryExpression":this.scan(ast.left);this.scan(ast.right);break;case"UpdateExpression":if(ast.operator==="++"){const declaration=this.getDeclaration(ast.argument.name);if(declaration){declaration.suggestedType="Integer"}}this.scan(ast.argument);break;case"UnaryExpression":this.scan(ast.argument);break;case"VariableDeclaration":if(ast.kind==="var"){this.useFunctionContext(()=>{ast.declarations=utils.normalizeDeclarations(ast);this.scan(ast.declarations)})}else{ast.declarations=utils.normalizeDeclarations(ast);this.scan(ast.declarations)}break;case"VariableDeclarator":{const{currentContext}=this;const inForLoopInit=this.hasState(states.inForLoopInit);const declaration={ast,context:currentContext,name:ast.id.name,origin:"declaration",inForLoopInit,inForLoopTest:null,assignable:currentContext===this.currentFunctionContext||!inForLoopInit&&!currentContext.hasOwnProperty(ast.id.name),suggestedType:null,valueType:null,dependencies:null,isSafe:null};if(!currentContext[ast.id.name]){currentContext[ast.id.name]=declaration}this.declarations.push(declaration);this.scan(ast.id);this.scan(ast.init);break}case"FunctionExpression":case"FunctionDeclaration":if(this.runningContexts.length===0){this.scan(ast.body)}else{this.functions.push(ast)}break;case"IfStatement":this.scan(ast.test);this.scan(ast.consequent);if(ast.alternate)this.scan(ast.alternate);break;case"ForStatement":{let testIdentifiers;const context=this.newContext(()=>{this.pushState(states.inForLoopInit);this.scan(ast.init);this.popState(states.inForLoopInit);testIdentifiers=this.getIdentifiers(()=>{this.scan(ast.test)});this.scan(ast.update);this.newContext(()=>{this.scan(ast.body)})});if(testIdentifiers){for(const p in context){if(p==="@contextType")continue;if(testIdentifiers.indexOf(p)>-1){context[p].inForLoopTest=true}}}break}case"DoWhileStatement":case"WhileStatement":this.newContext(()=>{this.scan(ast.body);this.scan(ast.test)});break;case"Identifier":{if(this.isState(states.trackIdentifiers)){this.trackedIdentifiers.push(ast.name)}this.identifiers.push({context:this.currentContext,declaration:this.getDeclaration(ast.name),ast});break}case"ReturnStatement":this.returnStatements.push(ast);this.scan(ast.argument);break;case"MemberExpression":this.pushState(states.memberExpression);this.scan(ast.object);this.scan(ast.property);this.popState(states.memberExpression);break;case"ExpressionStatement":this.scan(ast.expression);break;case"SequenceExpression":this.scan(ast.expressions);break;case"CallExpression":this.functionCalls.push({context:this.currentContext,ast});this.scan(ast.arguments);break;case"ArrayExpression":this.scan(ast.elements);break;case"ConditionalExpression":this.scan(ast.test);this.scan(ast.alternate);this.scan(ast.consequent);break;case"SwitchStatement":this.scan(ast.discriminant);this.scan(ast.cases);break;case"SwitchCase":this.scan(ast.test);this.scan(ast.consequent);break;case"ThisExpression":case"Literal":case"DebuggerStatement":case"EmptyStatement":case"BreakStatement":case"ContinueStatement":break;default:throw new Error(`unhandled type "${ast.type}"`)}}}module3.exports={FunctionTracer}},{"../utils":114}],12:[function(require2,module3,exports3){const{glWiretap}=require2("gl-wiretap");const{utils}=require2("../../utils");function toStringWithoutUtils(fn){return fn.toString().replace("=>","").replace(/^function /,"").replace(/utils[.]/g,"/*utils.*/")}function glKernelString(Kernel,args,originKernel,setupContextString,destroyContextString){if(!originKernel.built){originKernel.build.apply(originKernel,args)}args=args?Array.from(args).map(arg=>{switch(typeof arg){case"boolean":return new Boolean(arg);case"number":return new Number(arg);default:return arg}}):null;const uploadedValues=[];const postResult=[];const context=glWiretap(originKernel.context,{useTrackablePrimitives:true,onReadPixels:targetName=>{if(kernel.subKernels){if(!subKernelsResultVariableSetup){postResult.push(` const result = { result: ${getRenderString(targetName,kernel)} };`);subKernelsResultVariableSetup=true}else{const property=kernel.subKernels[subKernelsResultIndex++].property;postResult.push(` result${isNaN(property)?"."+property:`[${property}]`} = ${getRenderString(targetName,kernel)};`)}if(subKernelsResultIndex===kernel.subKernels.length){postResult.push(" return result;")}return}if(targetName){postResult.push(` return ${getRenderString(targetName,kernel)};`)}else{postResult.push(` return null;`)}},onUnrecognizedArgumentLookup:argument=>{const argumentName=findKernelValue(argument,kernel.kernelArguments,[],context,uploadedValues);if(argumentName){return argumentName}const constantName=findKernelValue(argument,kernel.kernelConstants,constants?Object.keys(constants).map(key=>constants[key]):[],context,uploadedValues);if(constantName){return constantName}return null}});let subKernelsResultVariableSetup=false;let subKernelsResultIndex=0;const{source,canvas,output,pipeline,graphical,loopMaxIterations,constants,optimizeFloatMemory,precision,fixIntegerDivisionAccuracy,functions,nativeFunctions,subKernels,immutable,argumentTypes,constantTypes,kernelArguments,kernelConstants,tactic}=originKernel;const kernel=new Kernel(source,{canvas,context,checkContext:false,output,pipeline,graphical,loopMaxIterations,constants,optimizeFloatMemory,precision,fixIntegerDivisionAccuracy,functions,nativeFunctions,subKernels,immutable,argumentTypes,constantTypes,tactic});let result=[];context.setIndent(2);kernel.build.apply(kernel,args);result.push(context.toString());context.reset();kernel.kernelArguments.forEach((kernelArgument,i)=>{switch(kernelArgument.type){case"Integer":case"Boolean":case"Number":case"Float":case"Array":case"Array(2)":case"Array(3)":case"Array(4)":case"HTMLCanvas":case"HTMLImage":case"HTMLVideo":context.insertVariable(`uploadValue_${kernelArgument.name}`,kernelArgument.uploadValue);break;case"HTMLImageArray":for(let imageIndex=0;imageIndexkernelArgument.varName).join(", ")}) {`);context.setIndent(4);kernel.run.apply(kernel,args);if(kernel.renderKernels){kernel.renderKernels()}else if(kernel.renderOutput){kernel.renderOutput()}result.push(" /** start setup uploads for kernel values **/");kernel.kernelArguments.forEach(kernelArgument=>{result.push(" "+kernelArgument.getStringValueHandler().split("\n").join("\n "))});result.push(" /** end setup uploads for kernel values **/");result.push(context.toString());if(kernel.renderOutput===kernel.renderTexture){context.reset();const framebufferName=context.getContextVariableName(kernel.framebuffer);if(kernel.renderKernels){const results=kernel.renderKernels();const textureName=context.getContextVariableName(kernel.texture.texture);result.push(` return { - result: { - texture: ${textureName}, - type: '${results.result.type}', - toArray: ${getToArrayString(results.result,textureName,framebufferName)} - },`);const{subKernels:subKernels2,mappedTextures}=kernel;for(let i=0;i{constantsUpload.push(`${kernelConstant.getStringValueHandler()}`)});return`function kernel(settings) { - const { context, constants } = settings; - ${constantsUpload.join("")} - ${setupContextString?setupContextString:""} - ${result.join("\n")} - }`}function getRenderString(targetName,kernel){const readBackValue=kernel.precision==="single"?targetName:`new Float32Array(${targetName}.buffer)`;if(kernel.output[2]){return`renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]}, ${kernel.output[2]})`}if(kernel.output[1]){return`renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]})`}return`renderOutput(${readBackValue}, ${kernel.output[0]})`}function getGetPixelsString(kernel){const getPixels=kernel.getPixels.toString();const useFunctionKeyword=!/^function/.test(getPixels);return utils.flattenFunctionToString(`${useFunctionKeyword?"function ":""}${getPixels}`,{findDependency:(object,name2)=>{if(object==="utils"){return`const ${name2} = ${utils[name2].toString()};`}return null},thisLookup:property=>{if(property==="context"){return null}if(kernel.hasOwnProperty(property)){return JSON.stringify(kernel[property])}throw new Error(`unhandled thisLookup ${property}`)}})}function getToArrayString(kernelResult,textureName,framebufferName){const toArray=kernelResult.toArray.toString();const useFunctionKeyword=!/^function/.test(toArray);const flattenedFunctions=utils.flattenFunctionToString(`${useFunctionKeyword?"function ":""}${toArray}`,{findDependency:(object,name2)=>{if(object==="utils"){return`const ${name2} = ${utils[name2].toString()};`}else if(object==="this"){if(name2==="framebuffer"){return""}return`${useFunctionKeyword?"function ":""}${kernelResult[name2].toString()}`}else{throw new Error("unhandled fromObject")}},thisLookup:(property,isDeclaration)=>{if(property==="texture"){return textureName}if(property==="context"){if(isDeclaration)return null;return"gl"}if(kernelResult.hasOwnProperty(property)){return JSON.stringify(kernelResult[property])}throw new Error(`unhandled thisLookup ${property}`)}});return`() => { - function framebuffer() { return ${framebufferName}; }; - ${flattenedFunctions} - return toArray(); - }`}function findKernelValue(argument,kernelValues,values,context,uploadedValues){if(argument===null)return null;if(kernelValues===null)return null;switch(typeof argument){case"boolean":case"number":return null}if(typeof HTMLImageElement!=="undefined"&&argument instanceof HTMLImageElement){for(let i=0;i0?":"+argumentTypes.join(","):"")}setFixIntegerDivisionAccuracy(fix){this.fixIntegerDivisionAccuracy=fix;return this}setPrecision(flag){this.precision=flag;return this}setFloatTextures(flag){utils.warnDeprecated("method","setFloatTextures","setOptimizeFloatMemory");this.floatTextures=flag;return this}static nativeFunctionArguments(source){const argumentTypes=[];const argumentNames=[];const states=[];const isStartingVariableName=/^[a-zA-Z_]/;const isVariableChar=/[a-zA-Z_0-9]/;let i=0;let argumentName=null;let argumentType=null;while(i0?states[states.length-1]:null;if(state2==="FUNCTION_ARGUMENTS"&&char==="/"&&nextChar==="*"){states.push("MULTI_LINE_COMMENT");i+=2;continue}else if(state2==="MULTI_LINE_COMMENT"&&char==="*"&&nextChar==="/"){states.pop();i+=2;continue}else if(state2==="FUNCTION_ARGUMENTS"&&char==="/"&&nextChar==="/"){states.push("COMMENT");i+=2;continue}else if(state2==="COMMENT"&&char==="\n"){states.pop();i++;continue}else if(state2===null&&char==="("){states.push("FUNCTION_ARGUMENTS");i++;continue}else if(state2==="FUNCTION_ARGUMENTS"){if(char===")"){states.pop();break}if(char==="f"&&nextChar==="l"&&source[i+2]==="o"&&source[i+3]==="a"&&source[i+4]==="t"&&source[i+5]===" "){states.push("DECLARE_VARIABLE");argumentType="float";argumentName="";i+=6;continue}else if(char==="i"&&nextChar==="n"&&source[i+2]==="t"&&source[i+3]===" "){states.push("DECLARE_VARIABLE");argumentType="int";argumentName="";i+=4;continue}else if(char==="v"&&nextChar==="e"&&source[i+2]==="c"&&source[i+3]==="2"&&source[i+4]===" "){states.push("DECLARE_VARIABLE");argumentType="vec2";argumentName="";i+=5;continue}else if(char==="v"&&nextChar==="e"&&source[i+2]==="c"&&source[i+3]==="3"&&source[i+4]===" "){states.push("DECLARE_VARIABLE");argumentType="vec3";argumentName="";i+=5;continue}else if(char==="v"&&nextChar==="e"&&source[i+2]==="c"&&source[i+3]==="4"&&source[i+4]===" "){states.push("DECLARE_VARIABLE");argumentType="vec4";argumentName="";i+=5;continue}}else if(state2==="DECLARE_VARIABLE"){if(argumentName===""){if(char===" "){i++;continue}if(!isStartingVariableName.test(char)){throw new Error("variable name is not expected string")}}argumentName+=char;if(!isVariableChar.test(nextChar)){states.pop();argumentNames.push(argumentName);argumentTypes.push(typeMap[argumentType])}}i++}if(states.length>0){throw new Error("GLSL function was not parsable")}return{argumentNames,argumentTypes}}static nativeFunctionReturnType(source){return typeMap[source.match(/int|float|vec[2-4]/)[0]]}static combineKernels(combinedKernel,lastKernel){combinedKernel.apply(null,arguments);const{texSize,context,threadDim}=lastKernel.texSize;let result;if(lastKernel.precision==="single"){const w=texSize[0];const h=Math.ceil(texSize[1]/4);result=new Float32Array(w*h*4*4);context.readPixels(0,0,w,h*4,context.RGBA,context.FLOAT,result)}else{const bytes=new Uint8Array(texSize[0]*texSize[1]*4);context.readPixels(0,0,texSize[0],texSize[1],context.RGBA,context.UNSIGNED_BYTE,bytes);result=new Float32Array(bytes.buffer)}result=result.subarray(0,threadDim[0]*threadDim[1]*threadDim[2]);if(lastKernel.output.length===1){return result}else if(lastKernel.output.length===2){return utils.splitArray(result,lastKernel.output[0])}else if(lastKernel.output.length===3){const cube=utils.splitArray(result,lastKernel.output[0]*lastKernel.output[1]);return cube.map(function(x2){return utils.splitArray(x2,lastKernel.output[0])})}}constructor(source,settings){super(source,settings);this.transferValues=null;this.formatValues=null;this.TextureConstructor=null;this.renderOutput=null;this.renderRawOutput=null;this.texSize=null;this.translatedSource=null;this.compiledFragmentShader=null;this.compiledVertexShader=null;this.switchingKernels=null;this._textureSwitched=null;this._mappedTextureSwitched=null}checkTextureSize(){const{features}=this.constructor;if(this.texSize[0]>features.maxTextureSize||this.texSize[1]>features.maxTextureSize){throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${features.maxTextureSize},${features.maxTextureSize}]`)}}translateSource(){throw new Error(`"translateSource" not defined on ${this.constructor.name}`)}pickRenderStrategy(args){if(this.graphical){this.renderRawOutput=this.readPackedPixelsToUint8Array;this.transferValues=pixels=>pixels;this.TextureConstructor=GLTextureGraphical;return null}if(this.precision==="unsigned"){this.renderRawOutput=this.readPackedPixelsToUint8Array;this.transferValues=this.readPackedPixelsToFloat32Array;if(this.pipeline){this.renderOutput=this.renderTexture;if(this.subKernels!==null){this.renderKernels=this.renderKernelsToTextures}switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":if(this.output[2]>0){this.TextureConstructor=GLTextureUnsigned3D;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureUnsigned2D;return null}else{this.TextureConstructor=GLTextureUnsigned;return null}case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(args)}}else{if(this.subKernels!==null){this.renderKernels=this.renderKernelsToArrays}switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":this.renderOutput=this.renderValues;if(this.output[2]>0){this.TextureConstructor=GLTextureUnsigned3D;this.formatValues=utils.erect3DPackedFloat;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureUnsigned2D;this.formatValues=utils.erect2DPackedFloat;return null}else{this.TextureConstructor=GLTextureUnsigned;this.formatValues=utils.erectPackedFloat;return null}case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(args)}}}else if(this.precision==="single"){this.renderRawOutput=this.readFloatPixelsToFloat32Array;this.transferValues=this.readFloatPixelsToFloat32Array;if(this.pipeline){this.renderOutput=this.renderTexture;if(this.subKernels!==null){this.renderKernels=this.renderKernelsToTextures}switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":{if(this.optimizeFloatMemory){if(this.output[2]>0){this.TextureConstructor=GLTextureMemoryOptimized3D;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureMemoryOptimized2D;return null}else{this.TextureConstructor=GLTextureMemoryOptimized;return null}}else{if(this.output[2]>0){this.TextureConstructor=GLTextureFloat3D;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureFloat2D;return null}else{this.TextureConstructor=GLTextureFloat;return null}}}case"Array(2)":{if(this.output[2]>0){this.TextureConstructor=GLTextureArray2Float3D;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureArray2Float2D;return null}else{this.TextureConstructor=GLTextureArray2Float;return null}}case"Array(3)":{if(this.output[2]>0){this.TextureConstructor=GLTextureArray3Float3D;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureArray3Float2D;return null}else{this.TextureConstructor=GLTextureArray3Float;return null}}case"Array(4)":{if(this.output[2]>0){this.TextureConstructor=GLTextureArray4Float3D;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureArray4Float2D;return null}else{this.TextureConstructor=GLTextureArray4Float;return null}}}}this.renderOutput=this.renderValues;if(this.subKernels!==null){this.renderKernels=this.renderKernelsToArrays}if(this.optimizeFloatMemory){switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":{if(this.output[2]>0){this.TextureConstructor=GLTextureMemoryOptimized3D;this.formatValues=utils.erectMemoryOptimized3DFloat;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureMemoryOptimized2D;this.formatValues=utils.erectMemoryOptimized2DFloat;return null}else{this.TextureConstructor=GLTextureMemoryOptimized;this.formatValues=utils.erectMemoryOptimizedFloat;return null}}case"Array(2)":{if(this.output[2]>0){this.TextureConstructor=GLTextureArray2Float3D;this.formatValues=utils.erect3DArray2;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureArray2Float2D;this.formatValues=utils.erect2DArray2;return null}else{this.TextureConstructor=GLTextureArray2Float;this.formatValues=utils.erectArray2;return null}}case"Array(3)":{if(this.output[2]>0){this.TextureConstructor=GLTextureArray3Float3D;this.formatValues=utils.erect3DArray3;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureArray3Float2D;this.formatValues=utils.erect2DArray3;return null}else{this.TextureConstructor=GLTextureArray3Float;this.formatValues=utils.erectArray3;return null}}case"Array(4)":{if(this.output[2]>0){this.TextureConstructor=GLTextureArray4Float3D;this.formatValues=utils.erect3DArray4;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureArray4Float2D;this.formatValues=utils.erect2DArray4;return null}else{this.TextureConstructor=GLTextureArray4Float;this.formatValues=utils.erectArray4;return null}}}}else{switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":{if(this.output[2]>0){this.TextureConstructor=GLTextureFloat3D;this.formatValues=utils.erect3DFloat;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureFloat2D;this.formatValues=utils.erect2DFloat;return null}else{this.TextureConstructor=GLTextureFloat;this.formatValues=utils.erectFloat;return null}}case"Array(2)":{if(this.output[2]>0){this.TextureConstructor=GLTextureArray2Float3D;this.formatValues=utils.erect3DArray2;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureArray2Float2D;this.formatValues=utils.erect2DArray2;return null}else{this.TextureConstructor=GLTextureArray2Float;this.formatValues=utils.erectArray2;return null}}case"Array(3)":{if(this.output[2]>0){this.TextureConstructor=GLTextureArray3Float3D;this.formatValues=utils.erect3DArray3;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureArray3Float2D;this.formatValues=utils.erect2DArray3;return null}else{this.TextureConstructor=GLTextureArray3Float;this.formatValues=utils.erectArray3;return null}}case"Array(4)":{if(this.output[2]>0){this.TextureConstructor=GLTextureArray4Float3D;this.formatValues=utils.erect3DArray4;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureArray4Float2D;this.formatValues=utils.erect2DArray4;return null}else{this.TextureConstructor=GLTextureArray4Float;this.formatValues=utils.erectArray4;return null}}}}}else{throw new Error(`unhandled precision of "${this.precision}"`)}throw new Error(`unhandled return type "${this.returnType}"`)}getKernelString(){throw new Error(`abstract method call`)}getMainResultTexture(){switch(this.returnType){case"LiteralInteger":case"Float":case"Integer":case"Number":return this.getMainResultNumberTexture();case"Array(2)":return this.getMainResultArray2Texture();case"Array(3)":return this.getMainResultArray3Texture();case"Array(4)":return this.getMainResultArray4Texture();default:throw new Error(`unhandled returnType type ${this.returnType}`)}}getMainResultKernelNumberTexture(){throw new Error(`abstract method call`)}getMainResultSubKernelNumberTexture(){throw new Error(`abstract method call`)}getMainResultKernelArray2Texture(){throw new Error(`abstract method call`)}getMainResultSubKernelArray2Texture(){throw new Error(`abstract method call`)}getMainResultKernelArray3Texture(){throw new Error(`abstract method call`)}getMainResultSubKernelArray3Texture(){throw new Error(`abstract method call`)}getMainResultKernelArray4Texture(){throw new Error(`abstract method call`)}getMainResultSubKernelArray4Texture(){throw new Error(`abstract method call`)}getMainResultGraphical(){throw new Error(`abstract method call`)}getMainResultMemoryOptimizedFloats(){throw new Error(`abstract method call`)}getMainResultPackedPixels(){throw new Error(`abstract method call`)}getMainResultString(){if(this.graphical){return this.getMainResultGraphical()}else if(this.precision==="single"){if(this.optimizeFloatMemory){return this.getMainResultMemoryOptimizedFloats()}return this.getMainResultTexture()}else{return this.getMainResultPackedPixels()}}getMainResultNumberTexture(){return utils.linesToString(this.getMainResultKernelNumberTexture())+utils.linesToString(this.getMainResultSubKernelNumberTexture())}getMainResultArray2Texture(){return utils.linesToString(this.getMainResultKernelArray2Texture())+utils.linesToString(this.getMainResultSubKernelArray2Texture())}getMainResultArray3Texture(){return utils.linesToString(this.getMainResultKernelArray3Texture())+utils.linesToString(this.getMainResultSubKernelArray3Texture())}getMainResultArray4Texture(){return utils.linesToString(this.getMainResultKernelArray4Texture())+utils.linesToString(this.getMainResultSubKernelArray4Texture())}getFloatTacticDeclaration(){const variablePrecision=this.getVariablePrecisionString(this.texSize,this.tactic);return`precision ${variablePrecision} float; -`}getIntTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic,true)} int; -`}getSampler2DTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} sampler2D; -`}getSampler2DArrayTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} sampler2DArray; -`}renderTexture(){return this.immutable?this.texture.clone():this.texture}readPackedPixelsToUint8Array(){if(this.precision!=="unsigned")throw new Error('Requires this.precision to be "unsigned"');const{texSize,context:gl}=this;const result=new Uint8Array(texSize[0]*texSize[1]*4);gl.readPixels(0,0,texSize[0],texSize[1],gl.RGBA,gl.UNSIGNED_BYTE,result);return result}readPackedPixelsToFloat32Array(){return new Float32Array(this.readPackedPixelsToUint8Array().buffer)}readFloatPixelsToFloat32Array(){if(this.precision!=="single")throw new Error('Requires this.precision to be "single"');const{texSize,context:gl}=this;const w=texSize[0];const h=texSize[1];const result=new Float32Array(w*h*4);gl.readPixels(0,0,w,h,gl.RGBA,gl.FLOAT,result);return result}getPixels(flip){const{context:gl,output}=this;const[width,height]=output;const pixels=new Uint8Array(width*height*4);gl.readPixels(0,0,width,height,gl.RGBA,gl.UNSIGNED_BYTE,pixels);return new Uint8ClampedArray((flip?pixels:utils.flipPixels(pixels,width,height)).buffer)}renderKernelsToArrays(){const result={result:this.renderOutput()};for(let i=0;i0){for(let i=0;i0){const{mappedTextures}=this;for(let i=0;i1){this.newTexture();return true}return false}cloneTexture(){this.texture._refs--;const{context:gl,size,texture,kernel}=this;if(kernel.debug){console.warn("cloning internal texture")}gl.bindFramebuffer(gl.FRAMEBUFFER,this.framebuffer());selectTexture(gl,texture);gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D,texture,0);const target=gl.createTexture();selectTexture(gl,target);gl.texImage2D(gl.TEXTURE_2D,0,this.internalFormat,size[0],size[1],0,this.textureFormat,this.textureType,null);gl.copyTexSubImage2D(gl.TEXTURE_2D,0,0,0,0,0,size[0],size[1]);target._refs=1;this.texture=target}newTexture(){this.texture._refs--;const gl=this.context;const size=this.size;const kernel=this.kernel;if(kernel.debug){console.warn("new internal texture")}const target=gl.createTexture();selectTexture(gl,target);gl.texImage2D(gl.TEXTURE_2D,0,this.internalFormat,size[0],size[1],0,this.textureFormat,this.textureType,null);target._refs=1;this.texture=target}clear(){if(this.texture._refs){this.texture._refs--;const gl2=this.context;const target=this.texture=gl2.createTexture();selectTexture(gl2,target);const size=this.size;target._refs=1;gl2.texImage2D(gl2.TEXTURE_2D,0,this.internalFormat,size[0],size[1],0,this.textureFormat,this.textureType,null)}const{context:gl,texture}=this;gl.bindFramebuffer(gl.FRAMEBUFFER,this.framebuffer());gl.bindTexture(gl.TEXTURE_2D,texture);selectTexture(gl,texture);gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D,texture,0);gl.clearColor(0,0,0,0);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT)}delete(){if(this._deleted)return;this._deleted=true;if(this.texture._refs){this.texture._refs--;if(this.texture._refs)return}this.context.deleteTexture(this.texture)}framebuffer(){if(!this._framebuffer){this._framebuffer=this.kernel.getRawValueFramebuffer(this.size[0],this.size[1])}return this._framebuffer}}function selectTexture(gl,texture){gl.activeTexture(gl.TEXTURE15);gl.bindTexture(gl.TEXTURE_2D,texture);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.NEAREST);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.NEAREST)}module3.exports={GLTexture}},{"../../../texture":113}],28:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{GLTextureFloat}=require2("./float");class GLTextureMemoryOptimized2D extends GLTextureFloat{constructor(settings){super(settings);this.type="MemoryOptimizedNumberTexture"}toArray(){return utils.erectMemoryOptimized2DFloat(this.renderValues(),this.output[0],this.output[1])}}module3.exports={GLTextureMemoryOptimized2D}},{"../../../utils":114,"./float":25}],29:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{GLTextureFloat}=require2("./float");class GLTextureMemoryOptimized3D extends GLTextureFloat{constructor(settings){super(settings);this.type="MemoryOptimizedNumberTexture"}toArray(){return utils.erectMemoryOptimized3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}module3.exports={GLTextureMemoryOptimized3D}},{"../../../utils":114,"./float":25}],30:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{GLTextureFloat}=require2("./float");class GLTextureMemoryOptimized extends GLTextureFloat{constructor(settings){super(settings);this.type="MemoryOptimizedNumberTexture"}toArray(){return utils.erectMemoryOptimizedFloat(this.renderValues(),this.output[0])}}module3.exports={GLTextureMemoryOptimized}},{"../../../utils":114,"./float":25}],31:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{GLTextureUnsigned}=require2("./unsigned");class GLTextureUnsigned2D extends GLTextureUnsigned{constructor(settings){super(settings);this.type="NumberTexture"}toArray(){return utils.erect2DPackedFloat(this.renderValues(),this.output[0],this.output[1])}}module3.exports={GLTextureUnsigned2D}},{"../../../utils":114,"./unsigned":33}],32:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{GLTextureUnsigned}=require2("./unsigned");class GLTextureUnsigned3D extends GLTextureUnsigned{constructor(settings){super(settings);this.type="NumberTexture"}toArray(){return utils.erect3DPackedFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}module3.exports={GLTextureUnsigned3D}},{"../../../utils":114,"./unsigned":33}],33:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{GLTexture}=require2("./index");class GLTextureUnsigned extends GLTexture{get textureType(){return this.context.UNSIGNED_BYTE}constructor(settings){super(settings);this.type="NumberTexture"}renderRawOutput(){const{context:gl}=this;gl.bindFramebuffer(gl.FRAMEBUFFER,this.framebuffer());gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D,this.texture,0);const result=new Uint8Array(this.size[0]*this.size[1]*4);gl.readPixels(0,0,this.size[0],this.size[1],gl.RGBA,gl.UNSIGNED_BYTE,result);return result}renderValues(){if(this._deleted)return null;return new Float32Array(this.renderRawOutput().buffer)}toArray(){return utils.erectPackedFloat(this.renderValues(),this.output[0])}}module3.exports={GLTextureUnsigned}},{"../../../utils":114,"./index":27}],34:[function(require2,module3,exports3){const getContext=require2("gl");const{WebGLKernel}=require2("../web-gl/kernel");const{glKernelString}=require2("../gl/kernel-string");let isSupported=null;let testCanvas=null;let testContext=null;let testExtensions=null;let features=null;class HeadlessGLKernel extends WebGLKernel{static get isSupported(){if(isSupported!==null)return isSupported;this.setupFeatureChecks();isSupported=testContext!==null;return isSupported}static setupFeatureChecks(){testCanvas=null;testExtensions=null;if(typeof getContext!=="function")return;try{testContext=getContext(2,2,{preserveDrawingBuffer:true});if(!testContext||!testContext.getExtension)return;testExtensions={STACKGL_resize_drawingbuffer:testContext.getExtension("STACKGL_resize_drawingbuffer"),STACKGL_destroy_context:testContext.getExtension("STACKGL_destroy_context"),OES_texture_float:testContext.getExtension("OES_texture_float"),OES_texture_float_linear:testContext.getExtension("OES_texture_float_linear"),OES_element_index_uint:testContext.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:testContext.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:testContext.getExtension("WEBGL_color_buffer_float")};features=this.getFeatures()}catch(e){console.warn(e)}}static isContextMatch(context){try{return context.getParameter(context.RENDERER)==="ANGLE"}catch(e){return false}}static getIsTextureFloat(){return Boolean(testExtensions.OES_texture_float)}static getIsDrawBuffers(){return Boolean(testExtensions.WEBGL_draw_buffers)}static getChannelCount(){return testExtensions.WEBGL_draw_buffers?testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL):1}static getMaxTextureSize(){return testContext.getParameter(testContext.MAX_TEXTURE_SIZE)}static get testCanvas(){return testCanvas}static get testContext(){return testContext}static get features(){return features}initCanvas(){return{}}initContext(){return getContext(2,2,{preserveDrawingBuffer:true})}initExtensions(){this.extensions={STACKGL_resize_drawingbuffer:this.context.getExtension("STACKGL_resize_drawingbuffer"),STACKGL_destroy_context:this.context.getExtension("STACKGL_destroy_context"),OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers")}}build(){super.build.apply(this,arguments);if(!this.fallbackRequested){this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1])}}destroyExtensions(){this.extensions.STACKGL_resize_drawingbuffer=null;this.extensions.STACKGL_destroy_context=null;this.extensions.OES_texture_float=null;this.extensions.OES_texture_float_linear=null;this.extensions.OES_element_index_uint=null;this.extensions.WEBGL_draw_buffers=null}static destroyContext(context){const extension=context.getExtension("STACKGL_destroy_context");if(extension&&extension.destroy){extension.destroy()}}toString(){const setupContextString=`const gl = context || require('gl')(1, 1); -`;const destroyContextString=` if (!context) { gl.getExtension('STACKGL_destroy_context').destroy(); } -`;return glKernelString(this.constructor,arguments,this,setupContextString,destroyContextString)}setOutput(output){super.setOutput(output);if(this.graphical&&this.extensions.STACKGL_resize_drawingbuffer){this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1])}return this}}module3.exports={HeadlessGLKernel}},{"../gl/kernel-string":12,"../web-gl/kernel":70,"gl":2}],35:[function(require2,module3,exports3){class KernelValue{constructor(value2,settings){const{name:name2,kernel,context,checkContext,onRequestContextHandle,onUpdateValueMismatch,origin,strictIntegers,type,tactic}=settings;if(!name2){throw new Error("name not set")}if(!type){throw new Error("type not set")}if(!origin){throw new Error("origin not set")}if(origin!=="user"&&origin!=="constants"){throw new Error(`origin must be "user" or "constants" value is "${origin}"`)}if(!onRequestContextHandle){throw new Error("onRequestContextHandle is not set")}this.name=name2;this.origin=origin;this.tactic=tactic;this.varName=origin==="constants"?`constants.${name2}`:name2;this.kernel=kernel;this.strictIntegers=strictIntegers;this.type=value2.type||type;this.size=value2.size||null;this.index=null;this.context=context;this.checkContext=checkContext!==null&&checkContext!==void 0?checkContext:true;this.contextHandle=null;this.onRequestContextHandle=onRequestContextHandle;this.onUpdateValueMismatch=onUpdateValueMismatch;this.forceUploadEachRun=null}get id(){return`${this.origin}_${name}`}getSource(){throw new Error(`"getSource" not defined on ${this.constructor.name}`)}updateValue(value2){throw new Error(`"updateValue" not defined on ${this.constructor.name}`)}}module3.exports={KernelValue}},{}],36:[function(require2,module3,exports3){const{utils}=require2("../utils");const{Input}=require2("../input");class Kernel{static get isSupported(){throw new Error(`"isSupported" not implemented on ${this.name}`)}static isContextMatch(context){throw new Error(`"isContextMatch" not implemented on ${this.name}`)}static getFeatures(){throw new Error(`"getFeatures" not implemented on ${this.name}`)}static destroyContext(context){throw new Error(`"destroyContext" called on ${this.name}`)}static nativeFunctionArguments(){throw new Error(`"nativeFunctionArguments" called on ${this.name}`)}static nativeFunctionReturnType(){throw new Error(`"nativeFunctionReturnType" called on ${this.name}`)}static combineKernels(){throw new Error(`"combineKernels" called on ${this.name}`)}constructor(source,settings){if(typeof source!=="object"){if(typeof source!=="string"){throw new Error("source not a string")}if(!utils.isFunctionString(source)){throw new Error("source not a function string")}}this.useLegacyEncoder=false;this.fallbackRequested=false;this.onRequestFallback=null;this.argumentNames=typeof source==="string"?utils.getArgumentNamesFromString(source):null;this.argumentTypes=null;this.argumentSizes=null;this.argumentBitRatios=null;this.kernelArguments=null;this.kernelConstants=null;this.forceUploadKernelConstants=null;this.source=source;this.output=null;this.debug=false;this.graphical=false;this.loopMaxIterations=0;this.constants=null;this.constantTypes=null;this.constantBitRatios=null;this.dynamicArguments=false;this.dynamicOutput=false;this.canvas=null;this.context=null;this.checkContext=null;this.gpu=null;this.functions=null;this.nativeFunctions=null;this.injectedNative=null;this.subKernels=null;this.validate=true;this.immutable=false;this.pipeline=false;this.precision=null;this.tactic=null;this.plugins=null;this.returnType=null;this.leadingReturnStatement=null;this.followingReturnStatement=null;this.optimizeFloatMemory=null;this.strictIntegers=false;this.fixIntegerDivisionAccuracy=null;this.built=false;this.signature=null}mergeSettings(settings){for(let p in settings){if(!settings.hasOwnProperty(p)||!this.hasOwnProperty(p))continue;switch(p){case"output":if(!Array.isArray(settings.output)){this.setOutput(settings.output);continue}break;case"functions":this.functions=[];for(let i=0;iplugin.name):null,returnType:this.returnType}}}buildSignature(args){const Constructor=this.constructor;this.signature=Constructor.getSignature(this,Constructor.getArgumentTypes(this,args))}static getArgumentTypes(kernel,args){const argumentTypes=new Array(args.length);for(let i=0;isettings.argumentTypes[name2])||[]}else{argumentTypes=settings.argumentTypes||[]}return{name:utils.getFunctionNameFromString(sourceString)||null,source:sourceString,argumentTypes,returnType:settings.returnType||null}}onActivate(previousKernel){}}function splitArgumentTypes(argumentTypesObject){const argumentNames=Object.keys(argumentTypesObject);const argumentTypes=[];for(let i=0;i= 0.0) { - return pow(x, 1.0 / 3.0); - } else { - return -pow(x, 1.0 / 3.0); - } - } - - float cosh(float x) { - return (pow(${Math.E}, x) + pow(${Math.E}, -x)) / 2.0; - } - - float expm1(float x) { - return pow(${Math.E}, x) - 1.0; - } - - float fround(highp float x) { - return x; - } - - float imul(float v1, float v2) { - return float(int(v1) * int(v2)); - } - - float log10(float x) { - return log2(x) * (1.0 / log2(10.0)); - } - - float log1p(float x) { - return log(1.0 + x); - } - - float _pow(float v1, float v2) { - if (v2 == 0.0) return 1.0; - return pow(v1, v2); - } - - float tanh(float x) { - float e = exp(2.0 * x); - return (e - 1.0) / (e + 1.0); - } - - float trunc(float x) { - if (x >= 0.0) { - return floor(x); - } else { - return ceil(x); - } - } - - vec4 _round(vec4 x) { - return floor(x + 0.5); - } - - float _round(float x) { - return floor(x + 0.5); - } - - const int BIT_COUNT = 32; - int modi(int x, int y) { - return x - y * (x / y); - } - - int bitwiseOr(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; - } - } - return result; - } - int bitwiseXOR(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; - } - } - return result; - } - int bitwiseAnd(int a, int b) { - int result = 0; - int n = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 && b > 0)) { - break; - } - } - return result; - } - int bitwiseNot(int a) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if (modi(a, 2) == 0) { - result += n; - } - a = a / 2; - n = n * 2; - } - return result; - } - int bitwiseZeroFillLeftShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; - } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; - } - n *= 2; - } - - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; - } - - int bitwiseSignedRightShift(int num, int shifts) { - return int(floor(float(num) / pow(2.0, float(shifts)))); - } - - int bitwiseZeroFillRightShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; - } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; - } - n /= 2; - } - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; - } - - vec2 integerMod(vec2 x, float y) { - vec2 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); - } - - vec3 integerMod(vec3 x, float y) { - vec3 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); - } - - vec4 integerMod(vec4 x, vec4 y) { - vec4 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); - } - - float integerMod(float x, float y) { - float res = floor(mod(x, y)); - return res * (res > floor(y) - 1.0 ? 0.0 : 1.0); - } - - int integerMod(int x, int y) { - return x - (y * int(x / y)); - } - - __DIVIDE_WITH_INTEGER_CHECK__; - - // Here be dragons! - // DO NOT OPTIMIZE THIS CODE - // YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE - // LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME - const vec2 MAGIC_VEC = vec2(1.0, -256.0); - const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0); - const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536 - float decode32(vec4 texel) { - __DECODE32_ENDIANNESS__; - texel *= 255.0; - vec2 gte128; - gte128.x = texel.b >= 128.0 ? 1.0 : 0.0; - gte128.y = texel.a >= 128.0 ? 1.0 : 0.0; - float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC); - float res = exp2(_round(exponent)); - texel.b = texel.b - 128.0 * gte128.x; - res = dot(texel, SCALE_FACTOR) * exp2(_round(exponent-23.0)) + res; - res *= gte128.y * -2.0 + 1.0; - return res; - } - - float decode16(vec4 texel, int index) { - int channel = integerMod(index, 2); - if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0; - if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0; - return 0.0; - } - - float decode8(vec4 texel, int index) { - int channel = integerMod(index, 4); - if (channel == 0) return texel.r * 255.0; - if (channel == 1) return texel.g * 255.0; - if (channel == 2) return texel.b * 255.0; - if (channel == 3) return texel.a * 255.0; - return 0.0; - } - - vec4 legacyEncode32(float f) { - float F = abs(f); - float sign = f < 0.0 ? 1.0 : 0.0; - float exponent = floor(log2(F)); - float mantissa = (exp2(-exponent) * F); - // exponent += floor(log2(mantissa)); - vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV; - texel.rg = integerMod(texel.rg, 256.0); - texel.b = integerMod(texel.b, 128.0); - texel.a = exponent*0.5 + 63.5; - texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0; - texel = floor(texel); - texel *= 0.003921569; // 1/255 - __ENCODE32_ENDIANNESS__; - return texel; - } - - // https://github.com/gpujs/gpu.js/wiki/Encoder-details - vec4 encode32(float value) { - if (value == 0.0) return vec4(0, 0, 0, 0); - - float exponent; - float mantissa; - vec4 result; - float sgn; - - sgn = step(0.0, -value); - value = abs(value); - - exponent = floor(log2(value)); - - mantissa = value*pow(2.0, -exponent)-1.0; - exponent = exponent+127.0; - result = vec4(0,0,0,0); - - result.a = floor(exponent/2.0); - exponent = exponent - result.a*2.0; - result.a = result.a + 128.0*sgn; - - result.b = floor(mantissa * 128.0); - mantissa = mantissa - result.b / 128.0; - result.b = result.b + exponent*128.0; - - result.g = floor(mantissa*32768.0); - mantissa = mantissa - result.g/32768.0; - - result.r = floor(mantissa*8388608.0); - return result/255.0; - } - // Dragons end here - - int index; - ivec3 threadId; - - ivec3 indexTo3D(int idx, ivec3 texDim) { - int z = int(idx / (texDim.x * texDim.y)); - idx -= z * int(texDim.x * texDim.y); - int y = int(idx / texDim.x); - int x = int(integerMod(idx, texDim.x)); - return ivec3(x, y, z); - } - - float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - return decode32(texel); - } - - float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x * 2; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y)); - return decode16(texel, index); - } - - float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x * 4; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y)); - return decode8(texel, index); - } - - float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 4); - index = index / 4; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - if (channel == 0) return texel.r; - if (channel == 1) return texel.g; - if (channel == 2) return texel.b; - if (channel == 3) return texel.a; - return 0.0; - } - - vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - return texture2D(tex, st / vec2(texSize)); - } - - float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return result[0]; - } - - vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec2(result[0], result[1]); - } - - vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int channel = integerMod(index, 2); - index = index / 2; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - if (channel == 0) return vec2(texel.r, texel.g); - if (channel == 1) return vec2(texel.b, texel.a); - return vec2(0.0, 0.0); - } - - vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec3(result[0], result[1], result[2]); - } - - vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z)); - int vectorIndex = fieldIndex / 4; - int vectorOffset = fieldIndex - vectorIndex * 4; - int readY = vectorIndex / texSize.x; - int readX = vectorIndex - readY * texSize.x; - vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize)); - - if (vectorOffset == 0) { - return tex1.xyz; - } else if (vectorOffset == 1) { - return tex1.yzw; - } else { - readX++; - if (readX >= texSize.x) { - readX = 0; - readY++; - } - vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize)); - if (vectorOffset == 2) { - return vec3(tex1.z, tex1.w, tex2.x); - } else { - return vec3(tex1.w, tex2.x, tex2.y); - } - } - } - - vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - return getImage2D(tex, texSize, texDim, z, y, x); - } - - vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 2); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - return vec4(texel.r, texel.g, texel.b, texel.a); - } - - vec4 actualColor; - void color(float r, float g, float b, float a) { - actualColor = vec4(r,g,b,a); - } - - void color(float r, float g, float b) { - color(r,g,b,1.0); - } - - void color(sampler2D image) { - actualColor = texture2D(image, vTexCoord); - } - - float modulo(float number, float divisor) { - if (number < 0.0) { - number = abs(number); - if (divisor < 0.0) { - divisor = abs(divisor); - } - return -mod(number, divisor); - } - if (divisor < 0.0) { - divisor = abs(divisor); - } - return mod(number, divisor); - } - - __INJECTED_NATIVE__; - __MAIN_CONSTANTS__; - __MAIN_ARGUMENTS__; - __KERNEL__; - - void main(void) { - index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x; - __MAIN_RESULT__; - }`;module3.exports={fragmentShader}},{}],38:[function(require2,module3,exports3){const{utils}=require2("../../utils");const{FunctionNode}=require2("../function-node");class WebGLFunctionNode extends FunctionNode{constructor(source,settings){super(source,settings);if(settings&&settings.hasOwnProperty("fixIntegerDivisionAccuracy")){this.fixIntegerDivisionAccuracy=settings.fixIntegerDivisionAccuracy}}astConditionalExpression(ast,retArr){if(ast.type!=="ConditionalExpression"){throw this.astErrorOutput("Not a conditional expression",ast)}const consequentType=this.getType(ast.consequent);const alternateType=this.getType(ast.alternate);if(consequentType===null&&alternateType===null){retArr.push("if (");this.astGeneric(ast.test,retArr);retArr.push(") {");this.astGeneric(ast.consequent,retArr);retArr.push(";");retArr.push("} else {");this.astGeneric(ast.alternate,retArr);retArr.push(";");retArr.push("}");return retArr}retArr.push("(");this.astGeneric(ast.test,retArr);retArr.push("?");this.astGeneric(ast.consequent,retArr);retArr.push(":");this.astGeneric(ast.alternate,retArr);retArr.push(")");return retArr}astFunction(ast,retArr){if(this.isRootKernel){retArr.push("void")}else{if(!this.returnType){const lastReturn=this.findLastReturn();if(lastReturn){this.returnType=this.getType(ast.body);if(this.returnType==="LiteralInteger"){this.returnType="Number"}}}const{returnType}=this;if(!returnType){retArr.push("void")}else{const type=typeMap[returnType];if(!type){throw new Error(`unknown type ${returnType}`)}retArr.push(type)}}retArr.push(" ");retArr.push(this.name);retArr.push("(");if(!this.isRootKernel){for(let i=0;i0){retArr.push(", ")}let argumentType=this.argumentTypes[this.argumentNames.indexOf(argumentName)];if(!argumentType){throw this.astErrorOutput(`Unknown argument ${argumentName} type`,ast)}if(argumentType==="LiteralInteger"){this.argumentTypes[i]=argumentType="Number"}const type=typeMap[argumentType];if(!type){throw this.astErrorOutput("Unexpected expression",ast)}const name2=utils.sanitizeName(argumentName);if(type==="sampler2D"||type==="sampler2DArray"){retArr.push(`${type} user_${name2},ivec2 user_${name2}Size,ivec3 user_${name2}Dim`)}else{retArr.push(`${type} user_${name2}`)}}}retArr.push(") {\n");for(let i=0;i"||ast.operator==="<"&&ast.right.type==="Literal"){if(!Number.isInteger(ast.right.value)){this.pushState("building-float");this.castValueToFloat(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.astGeneric(ast.right,retArr);this.popState("building-float");break}}this.pushState("building-integer");this.astGeneric(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.pushState("casting-to-integer");if(ast.right.type==="Literal"){const literalResult=[];this.astGeneric(ast.right,literalResult);const literalType=this.getType(ast.right);if(literalType==="Integer"){retArr.push(literalResult.join(""))}else{throw this.astErrorOutput(`Unhandled binary expression with literal`,ast)}}else{retArr.push("int(");this.astGeneric(ast.right,retArr);retArr.push(")")}this.popState("casting-to-integer");this.popState("building-integer");break;case"Integer & LiteralInteger":this.pushState("building-integer");this.astGeneric(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.castLiteralToInteger(ast.right,retArr);this.popState("building-integer");break;case"Number & Integer":this.pushState("building-float");this.astGeneric(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.castValueToFloat(ast.right,retArr);this.popState("building-float");break;case"Float & LiteralInteger":case"Number & LiteralInteger":this.pushState("building-float");this.astGeneric(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.castLiteralToFloat(ast.right,retArr);this.popState("building-float");break;case"LiteralInteger & Float":case"LiteralInteger & Number":if(this.isState("casting-to-integer")){this.pushState("building-integer");this.castLiteralToInteger(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.castValueToInteger(ast.right,retArr);this.popState("building-integer")}else{this.pushState("building-float");this.astGeneric(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.pushState("casting-to-float");this.astGeneric(ast.right,retArr);this.popState("casting-to-float");this.popState("building-float")}break;case"LiteralInteger & Integer":this.pushState("building-integer");this.castLiteralToInteger(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.astGeneric(ast.right,retArr);this.popState("building-integer");break;case"Boolean & Boolean":this.pushState("building-boolean");this.astGeneric(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.astGeneric(ast.right,retArr);this.popState("building-boolean");break;case"Float & Integer":this.pushState("building-float");this.astGeneric(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.castValueToFloat(ast.right,retArr);this.popState("building-float");break;default:throw this.astErrorOutput(`Unhandled binary expression between ${key}`,ast)}retArr.push(")");return retArr}checkAndUpconvertOperator(ast,retArr){const bitwiseResult=this.checkAndUpconvertBitwiseOperators(ast,retArr);if(bitwiseResult){return bitwiseResult}const upconvertableOperators={"%":this.fixIntegerDivisionAccuracy?"integerCorrectionModulo":"modulo","**":"pow"};const foundOperator=upconvertableOperators[ast.operator];if(!foundOperator)return null;retArr.push(foundOperator);retArr.push("(");switch(this.getType(ast.left)){case"Integer":this.castValueToFloat(ast.left,retArr);break;case"LiteralInteger":this.castLiteralToFloat(ast.left,retArr);break;default:this.astGeneric(ast.left,retArr)}retArr.push(",");switch(this.getType(ast.right)){case"Integer":this.castValueToFloat(ast.right,retArr);break;case"LiteralInteger":this.castLiteralToFloat(ast.right,retArr);break;default:this.astGeneric(ast.right,retArr)}retArr.push(")");return retArr}checkAndUpconvertBitwiseOperators(ast,retArr){const upconvertableOperators={"&":"bitwiseAnd","|":"bitwiseOr","^":"bitwiseXOR","<<":"bitwiseZeroFillLeftShift",">>":"bitwiseSignedRightShift",">>>":"bitwiseZeroFillRightShift"};const foundOperator=upconvertableOperators[ast.operator];if(!foundOperator)return null;retArr.push(foundOperator);retArr.push("(");const leftType=this.getType(ast.left);switch(leftType){case"Number":case"Float":this.castValueToInteger(ast.left,retArr);break;case"LiteralInteger":this.castLiteralToInteger(ast.left,retArr);break;default:this.astGeneric(ast.left,retArr)}retArr.push(",");const rightType=this.getType(ast.right);switch(rightType){case"Number":case"Float":this.castValueToInteger(ast.right,retArr);break;case"LiteralInteger":this.castLiteralToInteger(ast.right,retArr);break;default:this.astGeneric(ast.right,retArr)}retArr.push(")");return retArr}checkAndUpconvertBitwiseUnary(ast,retArr){const upconvertableOperators={"~":"bitwiseNot"};const foundOperator=upconvertableOperators[ast.operator];if(!foundOperator)return null;retArr.push(foundOperator);retArr.push("(");switch(this.getType(ast.argument)){case"Number":case"Float":this.castValueToInteger(ast.argument,retArr);break;case"LiteralInteger":this.castLiteralToInteger(ast.argument,retArr);break;default:this.astGeneric(ast.argument,retArr)}retArr.push(")");return retArr}castLiteralToInteger(ast,retArr){this.pushState("casting-to-integer");this.astGeneric(ast,retArr);this.popState("casting-to-integer");return retArr}castLiteralToFloat(ast,retArr){this.pushState("casting-to-float");this.astGeneric(ast,retArr);this.popState("casting-to-float");return retArr}castValueToInteger(ast,retArr){this.pushState("casting-to-integer");retArr.push("int(");this.astGeneric(ast,retArr);retArr.push(")");this.popState("casting-to-integer");return retArr}castValueToFloat(ast,retArr){this.pushState("casting-to-float");retArr.push("float(");this.astGeneric(ast,retArr);retArr.push(")");this.popState("casting-to-float");return retArr}astIdentifierExpression(idtNode,retArr){if(idtNode.type!=="Identifier"){throw this.astErrorOutput("IdentifierExpression - not an Identifier",idtNode)}const type=this.getType(idtNode);const name2=utils.sanitizeName(idtNode.name);if(idtNode.name==="Infinity"){retArr.push("3.402823466e+38")}else if(type==="Boolean"){if(this.argumentNames.indexOf(name2)>-1){retArr.push(`bool(user_${name2})`)}else{retArr.push(`user_${name2}`)}}else{retArr.push(`user_${name2}`)}return retArr}astForStatement(forNode,retArr){if(forNode.type!=="ForStatement"){throw this.astErrorOutput("Invalid for statement",forNode)}const initArr=[];const testArr=[];const updateArr=[];const bodyArr=[];let isSafe=null;if(forNode.init){const{declarations}=forNode.init;if(declarations.length>1){isSafe=false}this.astGeneric(forNode.init,initArr);for(let i=0;i0){retArr.push(initArr.join(""),"\n")}retArr.push(`for (int ${iVariableName}=0;${iVariableName}0){retArr.push(`if (!${testArr.join("")}) break; -`)}retArr.push(bodyArr.join(""));retArr.push(` -${updateArr.join("")};`);retArr.push("}\n")}return retArr}astWhileStatement(whileNode,retArr){if(whileNode.type!=="WhileStatement"){throw this.astErrorOutput("Invalid while statement",whileNode)}const iVariableName=this.getInternalVariableName("safeI");retArr.push(`for (int ${iVariableName}=0;${iVariableName}0){declarationSets.push(declarationSet.join(","))}result.push(declarationSets.join(";"));retArr.push(result.join(""));retArr.push(";");return retArr}astIfStatement(ifNode,retArr){retArr.push("if (");this.astGeneric(ifNode.test,retArr);retArr.push(")");if(ifNode.consequent.type==="BlockStatement"){this.astGeneric(ifNode.consequent,retArr)}else{retArr.push(" {\n");this.astGeneric(ifNode.consequent,retArr);retArr.push("\n}\n")}if(ifNode.alternate){retArr.push("else ");if(ifNode.alternate.type==="BlockStatement"||ifNode.alternate.type==="IfStatement"){this.astGeneric(ifNode.alternate,retArr)}else{retArr.push(" {\n");this.astGeneric(ifNode.alternate,retArr);retArr.push("\n}\n")}}return retArr}astSwitchStatement(ast,retArr){if(ast.type!=="SwitchStatement"){throw this.astErrorOutput("Invalid switch statement",ast)}const{discriminant,cases}=ast;const type=this.getType(discriminant);const varName=`switchDiscriminant${this.astKey(ast,"_")}`;switch(type){case"Float":case"Number":retArr.push(`float ${varName} = `);this.astGeneric(discriminant,retArr);retArr.push(";\n");break;case"Integer":retArr.push(`int ${varName} = `);this.astGeneric(discriminant,retArr);retArr.push(";\n");break}if(cases.length===1&&!cases[0].test){this.astGeneric(cases[0].consequent,retArr);return retArr}let fallingThrough=false;let defaultResult=[];let movingDefaultToEnd=false;let pastFirstIf=false;for(let i=0;ii+1){movingDefaultToEnd=true;this.astGeneric(cases[i].consequent,defaultResult);continue}else{retArr.push(" else {\n")}}else{if(i===0||!pastFirstIf){pastFirstIf=true;retArr.push(`if (${varName} == `)}else{if(fallingThrough){retArr.push(`${varName} == `);fallingThrough=false}else{retArr.push(` else if (${varName} == `)}}if(type==="Integer"){const testType=this.getType(cases[i].test);switch(testType){case"Number":case"Float":this.castValueToInteger(cases[i].test,retArr);break;case"LiteralInteger":this.castLiteralToInteger(cases[i].test,retArr);break}}else if(type==="Float"){const testType=this.getType(cases[i].test);switch(testType){case"LiteralInteger":this.castLiteralToFloat(cases[i].test,retArr);break;case"Integer":this.castValueToFloat(cases[i].test,retArr);break}}else{throw new Error("unhanlded")}if(!cases[i].consequent||cases[i].consequent.length===0){fallingThrough=true;retArr.push(" || ");continue}retArr.push(`) { -`)}this.astGeneric(cases[i].consequent,retArr);retArr.push("\n}")}if(movingDefaultToEnd){retArr.push(" else {");retArr.push(defaultResult.join(""));retArr.push("}")}return retArr}astThisExpression(tNode,retArr){retArr.push("this");return retArr}astMemberExpression(mNode,retArr){const{property,name:name2,signature,origin,type,xProperty,yProperty,zProperty}=this.getMemberExpressionDetails(mNode);switch(signature){case"value.thread.value":case"this.thread.value":if(name2!=="x"&&name2!=="y"&&name2!=="z"){throw this.astErrorOutput("Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`",mNode)}retArr.push(`threadId.${name2}`);return retArr;case"this.output.value":if(this.dynamicOutput){switch(name2){case"x":if(this.isState("casting-to-float")){retArr.push("float(uOutputDim.x)")}else{retArr.push("uOutputDim.x")}break;case"y":if(this.isState("casting-to-float")){retArr.push("float(uOutputDim.y)")}else{retArr.push("uOutputDim.y")}break;case"z":if(this.isState("casting-to-float")){retArr.push("float(uOutputDim.z)")}else{retArr.push("uOutputDim.z")}break;default:throw this.astErrorOutput("Unexpected expression",mNode)}}else{switch(name2){case"x":if(this.isState("casting-to-integer")){retArr.push(this.output[0])}else{retArr.push(this.output[0],".0")}break;case"y":if(this.isState("casting-to-integer")){retArr.push(this.output[1])}else{retArr.push(this.output[1],".0")}break;case"z":if(this.isState("casting-to-integer")){retArr.push(this.output[2])}else{retArr.push(this.output[2],".0")}break;default:throw this.astErrorOutput("Unexpected expression",mNode)}}return retArr;case"value":throw this.astErrorOutput("Unexpected expression",mNode);case"value[]":case"value[][]":case"value[][][]":case"value[][][][]":case"value.value":if(origin==="Math"){retArr.push(Math[name2]);return retArr}const cleanName=utils.sanitizeName(name2);switch(property){case"r":retArr.push(`user_${cleanName}.r`);return retArr;case"g":retArr.push(`user_${cleanName}.g`);return retArr;case"b":retArr.push(`user_${cleanName}.b`);return retArr;case"a":retArr.push(`user_${cleanName}.a`);return retArr}break;case"this.constants.value":if(typeof xProperty==="undefined"){switch(type){case"Array(2)":case"Array(3)":case"Array(4)":retArr.push(`constants_${utils.sanitizeName(name2)}`);return retArr}}case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":case"this.constants.value[][][][]":break;case"fn()[]":this.astCallExpression(mNode.object,retArr);retArr.push("[");retArr.push(this.memberExpressionPropertyMarkup(property));retArr.push("]");return retArr;case"fn()[][]":this.astCallExpression(mNode.object.object,retArr);retArr.push("[");retArr.push(this.memberExpressionPropertyMarkup(mNode.object.property));retArr.push("]");retArr.push("[");retArr.push(this.memberExpressionPropertyMarkup(mNode.property));retArr.push("]");return retArr;case"[][]":this.astArrayExpression(mNode.object,retArr);retArr.push("[");retArr.push(this.memberExpressionPropertyMarkup(property));retArr.push("]");return retArr;default:throw this.astErrorOutput("Unexpected expression",mNode)}if(mNode.computed===false){switch(type){case"Number":case"Integer":case"Float":case"Boolean":retArr.push(`${origin}_${utils.sanitizeName(name2)}`);return retArr}}const markupName=`${origin}_${utils.sanitizeName(name2)}`;switch(type){case"Array(2)":case"Array(3)":case"Array(4)":this.astGeneric(mNode.object,retArr);retArr.push("[");retArr.push(this.memberExpressionPropertyMarkup(xProperty));retArr.push("]");break;case"HTMLImageArray":retArr.push(`getImage3D(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")");break;case"ArrayTexture(1)":retArr.push(`getFloatFromSampler2D(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")");break;case"Array1D(2)":case"Array2D(2)":case"Array3D(2)":retArr.push(`getMemoryOptimizedVec2(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")");break;case"ArrayTexture(2)":retArr.push(`getVec2FromSampler2D(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")");break;case"Array1D(3)":case"Array2D(3)":case"Array3D(3)":retArr.push(`getMemoryOptimizedVec3(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")");break;case"ArrayTexture(3)":retArr.push(`getVec3FromSampler2D(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")");break;case"Array1D(4)":case"Array2D(4)":case"Array3D(4)":retArr.push(`getMemoryOptimizedVec4(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")");break;case"ArrayTexture(4)":case"HTMLCanvas":case"HTMLImage":case"HTMLVideo":retArr.push(`getVec4FromSampler2D(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")");break;case"NumberTexture":case"Array":case"Array2D":case"Array3D":case"Array4D":case"Input":case"Number":case"Float":case"Integer":if(this.precision==="single"){retArr.push(`getMemoryOptimized32(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")")}else{const bitRatio=origin==="user"?this.lookupFunctionArgumentBitRatio(this.name,name2):this.constantBitRatios[name2];switch(bitRatio){case 1:retArr.push(`get8(${markupName}, ${markupName}Size, ${markupName}Dim, `);break;case 2:retArr.push(`get16(${markupName}, ${markupName}Size, ${markupName}Dim, `);break;case 4:case 0:retArr.push(`get32(${markupName}, ${markupName}Size, ${markupName}Dim, `);break;default:throw new Error(`unhandled bit ratio of ${bitRatio}`)}this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")")}break;case"MemoryOptimizedNumberTexture":retArr.push(`getMemoryOptimized32(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")");break;case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":retArr.push(`${markupName}[${this.memberExpressionPropertyMarkup(yProperty)}]`);if(yProperty){retArr.push(`[${this.memberExpressionPropertyMarkup(xProperty)}]`)}break;default:throw new Error(`unhandled member expression "${type}"`)}return retArr}astCallExpression(ast,retArr){if(!ast.callee){throw this.astErrorOutput("Unknown CallExpression",ast)}let functionName=null;const isMathFunction=this.isAstMathFunction(ast);if(isMathFunction||ast.callee.object&&ast.callee.object.type==="ThisExpression"){functionName=ast.callee.property.name}else if(ast.callee.type==="SequenceExpression"&&ast.callee.expressions[0].type==="Literal"&&!isNaN(ast.callee.expressions[0].raw)){functionName=ast.callee.expressions[1].property.name}else{functionName=ast.callee.name}if(!functionName){throw this.astErrorOutput(`Unhandled function, couldn't find name`,ast)}switch(functionName){case"pow":functionName="_pow";break;case"round":functionName="_round";break}if(this.calledFunctions.indexOf(functionName)<0){this.calledFunctions.push(functionName)}if(functionName==="random"&&this.plugins&&this.plugins.length>0){for(let i=0;i0){retArr.push(", ")}switch(argumentType){case"Integer":this.castValueToFloat(argument,retArr);break;default:this.astGeneric(argument,retArr);break}}}else{const targetTypes=this.lookupFunctionArgumentTypes(functionName)||[];for(let i=0;i0){retArr.push(", ")}const argumentType=this.getType(argument);if(!targetType){this.triggerImplyArgumentType(functionName,i,argumentType,this);targetType=argumentType}switch(argumentType){case"Boolean":this.astGeneric(argument,retArr);continue;case"Number":case"Float":if(targetType==="Integer"){retArr.push("int(");this.astGeneric(argument,retArr);retArr.push(")");continue}else if(targetType==="Number"||targetType==="Float"){this.astGeneric(argument,retArr);continue}else if(targetType==="LiteralInteger"){this.castLiteralToFloat(argument,retArr);continue}break;case"Integer":if(targetType==="Number"||targetType==="Float"){retArr.push("float(");this.astGeneric(argument,retArr);retArr.push(")");continue}else if(targetType==="Integer"){this.astGeneric(argument,retArr);continue}break;case"LiteralInteger":if(targetType==="Integer"){this.castLiteralToInteger(argument,retArr);continue}else if(targetType==="Number"||targetType==="Float"){this.castLiteralToFloat(argument,retArr);continue}else if(targetType==="LiteralInteger"){this.astGeneric(argument,retArr);continue}break;case"Array(2)":case"Array(3)":case"Array(4)":if(targetType===argumentType){if(argument.type==="Identifier"){retArr.push(`user_${utils.sanitizeName(argument.name)}`)}else if(argument.type==="ArrayExpression"||argument.type==="MemberExpression"||argument.type==="CallExpression"){this.astGeneric(argument,retArr)}else{throw this.astErrorOutput(`Unhandled argument type ${argument.type}`,ast)}continue}break;case"HTMLCanvas":case"HTMLImage":case"HTMLImageArray":case"HTMLVideo":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":case"Array":case"Input":if(targetType===argumentType){if(argument.type!=="Identifier")throw this.astErrorOutput(`Unhandled argument type ${argument.type}`,ast);this.triggerImplyArgumentBitRatio(this.name,argument.name,functionName,i);const name2=utils.sanitizeName(argument.name);retArr.push(`user_${name2},user_${name2}Size,user_${name2}Dim`);continue}break}throw this.astErrorOutput(`Unhandled argument combination of ${argumentType} and ${targetType} for argument named "${argument.name}"`,ast)}}retArr.push(")");return retArr}astArrayExpression(arrNode,retArr){const returnType=this.getType(arrNode);const arrLen=arrNode.elements.length;switch(returnType){case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":retArr.push(`mat${arrLen}(`);break;default:retArr.push(`vec${arrLen}(`)}for(let i=0;i0){retArr.push(", ")}const subNode=arrNode.elements[i];this.astGeneric(subNode,retArr)}retArr.push(")");return retArr}memberExpressionXYZ(x2,y,z,retArr){if(z){retArr.push(this.memberExpressionPropertyMarkup(z),", ")}else{retArr.push("0, ")}if(y){retArr.push(this.memberExpressionPropertyMarkup(y),", ")}else{retArr.push("0, ")}retArr.push(this.memberExpressionPropertyMarkup(x2));return retArr}memberExpressionPropertyMarkup(property){if(!property){throw new Error("Property not set")}const type=this.getType(property);const result=[];switch(type){case"Number":case"Float":this.castValueToInteger(property,result);break;case"LiteralInteger":this.castLiteralToInteger(property,result);break;default:this.astGeneric(property,result)}return result.join("")}}const typeMap={"Array":"sampler2D","Array(2)":"vec2","Array(3)":"vec3","Array(4)":"vec4","Matrix(2)":"mat2","Matrix(3)":"mat3","Matrix(4)":"mat4","Array2D":"sampler2D","Array3D":"sampler2D","Boolean":"bool","Float":"float","Input":"sampler2D","Integer":"int","Number":"float","LiteralInteger":"float","NumberTexture":"sampler2D","MemoryOptimizedNumberTexture":"sampler2D","ArrayTexture(1)":"sampler2D","ArrayTexture(2)":"sampler2D","ArrayTexture(3)":"sampler2D","ArrayTexture(4)":"sampler2D","HTMLVideo":"sampler2D","HTMLCanvas":"sampler2D","HTMLImage":"sampler2D","HTMLImageArray":"sampler2DArray"};const operatorMap={"===":"==","!==":"!="};module3.exports={WebGLFunctionNode}},{"../../utils":114,"../function-node":10}],39:[function(require2,module3,exports3){const{WebGLKernelValueBoolean}=require2("./kernel-value/boolean");const{WebGLKernelValueFloat}=require2("./kernel-value/float");const{WebGLKernelValueInteger}=require2("./kernel-value/integer");const{WebGLKernelValueHTMLImage}=require2("./kernel-value/html-image");const{WebGLKernelValueDynamicHTMLImage}=require2("./kernel-value/dynamic-html-image");const{WebGLKernelValueHTMLVideo}=require2("./kernel-value/html-video");const{WebGLKernelValueDynamicHTMLVideo}=require2("./kernel-value/dynamic-html-video");const{WebGLKernelValueSingleInput}=require2("./kernel-value/single-input");const{WebGLKernelValueDynamicSingleInput}=require2("./kernel-value/dynamic-single-input");const{WebGLKernelValueUnsignedInput}=require2("./kernel-value/unsigned-input");const{WebGLKernelValueDynamicUnsignedInput}=require2("./kernel-value/dynamic-unsigned-input");const{WebGLKernelValueMemoryOptimizedNumberTexture}=require2("./kernel-value/memory-optimized-number-texture");const{WebGLKernelValueDynamicMemoryOptimizedNumberTexture}=require2("./kernel-value/dynamic-memory-optimized-number-texture");const{WebGLKernelValueNumberTexture}=require2("./kernel-value/number-texture");const{WebGLKernelValueDynamicNumberTexture}=require2("./kernel-value/dynamic-number-texture");const{WebGLKernelValueSingleArray}=require2("./kernel-value/single-array");const{WebGLKernelValueDynamicSingleArray}=require2("./kernel-value/dynamic-single-array");const{WebGLKernelValueSingleArray1DI}=require2("./kernel-value/single-array1d-i");const{WebGLKernelValueDynamicSingleArray1DI}=require2("./kernel-value/dynamic-single-array1d-i");const{WebGLKernelValueSingleArray2DI}=require2("./kernel-value/single-array2d-i");const{WebGLKernelValueDynamicSingleArray2DI}=require2("./kernel-value/dynamic-single-array2d-i");const{WebGLKernelValueSingleArray3DI}=require2("./kernel-value/single-array3d-i");const{WebGLKernelValueDynamicSingleArray3DI}=require2("./kernel-value/dynamic-single-array3d-i");const{WebGLKernelValueSingleArray2}=require2("./kernel-value/single-array2");const{WebGLKernelValueSingleArray3}=require2("./kernel-value/single-array3");const{WebGLKernelValueSingleArray4}=require2("./kernel-value/single-array4");const{WebGLKernelValueUnsignedArray}=require2("./kernel-value/unsigned-array");const{WebGLKernelValueDynamicUnsignedArray}=require2("./kernel-value/dynamic-unsigned-array");const kernelValueMaps={unsigned:{dynamic:{"Boolean":WebGLKernelValueBoolean,"Integer":WebGLKernelValueInteger,"Float":WebGLKernelValueFloat,"Array":WebGLKernelValueDynamicUnsignedArray,"Array(2)":false,"Array(3)":false,"Array(4)":false,"Array1D(2)":false,"Array1D(3)":false,"Array1D(4)":false,"Array2D(2)":false,"Array2D(3)":false,"Array2D(4)":false,"Array3D(2)":false,"Array3D(3)":false,"Array3D(4)":false,"Input":WebGLKernelValueDynamicUnsignedInput,"NumberTexture":WebGLKernelValueDynamicNumberTexture,"ArrayTexture(1)":WebGLKernelValueDynamicNumberTexture,"ArrayTexture(2)":WebGLKernelValueDynamicNumberTexture,"ArrayTexture(3)":WebGLKernelValueDynamicNumberTexture,"ArrayTexture(4)":WebGLKernelValueDynamicNumberTexture,"MemoryOptimizedNumberTexture":WebGLKernelValueDynamicMemoryOptimizedNumberTexture,"HTMLCanvas":WebGLKernelValueDynamicHTMLImage,"HTMLImage":WebGLKernelValueDynamicHTMLImage,"HTMLImageArray":false,"HTMLVideo":WebGLKernelValueDynamicHTMLVideo},static:{"Boolean":WebGLKernelValueBoolean,"Float":WebGLKernelValueFloat,"Integer":WebGLKernelValueInteger,"Array":WebGLKernelValueUnsignedArray,"Array(2)":false,"Array(3)":false,"Array(4)":false,"Array1D(2)":false,"Array1D(3)":false,"Array1D(4)":false,"Array2D(2)":false,"Array2D(3)":false,"Array2D(4)":false,"Array3D(2)":false,"Array3D(3)":false,"Array3D(4)":false,"Input":WebGLKernelValueUnsignedInput,"NumberTexture":WebGLKernelValueNumberTexture,"ArrayTexture(1)":WebGLKernelValueNumberTexture,"ArrayTexture(2)":WebGLKernelValueNumberTexture,"ArrayTexture(3)":WebGLKernelValueNumberTexture,"ArrayTexture(4)":WebGLKernelValueNumberTexture,"MemoryOptimizedNumberTexture":WebGLKernelValueMemoryOptimizedNumberTexture,"HTMLCanvas":WebGLKernelValueHTMLImage,"HTMLImage":WebGLKernelValueHTMLImage,"HTMLImageArray":false,"HTMLVideo":WebGLKernelValueHTMLVideo}},single:{dynamic:{"Boolean":WebGLKernelValueBoolean,"Integer":WebGLKernelValueInteger,"Float":WebGLKernelValueFloat,"Array":WebGLKernelValueDynamicSingleArray,"Array(2)":WebGLKernelValueSingleArray2,"Array(3)":WebGLKernelValueSingleArray3,"Array(4)":WebGLKernelValueSingleArray4,"Array1D(2)":WebGLKernelValueDynamicSingleArray1DI,"Array1D(3)":WebGLKernelValueDynamicSingleArray1DI,"Array1D(4)":WebGLKernelValueDynamicSingleArray1DI,"Array2D(2)":WebGLKernelValueDynamicSingleArray2DI,"Array2D(3)":WebGLKernelValueDynamicSingleArray2DI,"Array2D(4)":WebGLKernelValueDynamicSingleArray2DI,"Array3D(2)":WebGLKernelValueDynamicSingleArray3DI,"Array3D(3)":WebGLKernelValueDynamicSingleArray3DI,"Array3D(4)":WebGLKernelValueDynamicSingleArray3DI,"Input":WebGLKernelValueDynamicSingleInput,"NumberTexture":WebGLKernelValueDynamicNumberTexture,"ArrayTexture(1)":WebGLKernelValueDynamicNumberTexture,"ArrayTexture(2)":WebGLKernelValueDynamicNumberTexture,"ArrayTexture(3)":WebGLKernelValueDynamicNumberTexture,"ArrayTexture(4)":WebGLKernelValueDynamicNumberTexture,"MemoryOptimizedNumberTexture":WebGLKernelValueDynamicMemoryOptimizedNumberTexture,"HTMLCanvas":WebGLKernelValueDynamicHTMLImage,"HTMLImage":WebGLKernelValueDynamicHTMLImage,"HTMLImageArray":false,"HTMLVideo":WebGLKernelValueDynamicHTMLVideo},static:{"Boolean":WebGLKernelValueBoolean,"Float":WebGLKernelValueFloat,"Integer":WebGLKernelValueInteger,"Array":WebGLKernelValueSingleArray,"Array(2)":WebGLKernelValueSingleArray2,"Array(3)":WebGLKernelValueSingleArray3,"Array(4)":WebGLKernelValueSingleArray4,"Array1D(2)":WebGLKernelValueSingleArray1DI,"Array1D(3)":WebGLKernelValueSingleArray1DI,"Array1D(4)":WebGLKernelValueSingleArray1DI,"Array2D(2)":WebGLKernelValueSingleArray2DI,"Array2D(3)":WebGLKernelValueSingleArray2DI,"Array2D(4)":WebGLKernelValueSingleArray2DI,"Array3D(2)":WebGLKernelValueSingleArray3DI,"Array3D(3)":WebGLKernelValueSingleArray3DI,"Array3D(4)":WebGLKernelValueSingleArray3DI,"Input":WebGLKernelValueSingleInput,"NumberTexture":WebGLKernelValueNumberTexture,"ArrayTexture(1)":WebGLKernelValueNumberTexture,"ArrayTexture(2)":WebGLKernelValueNumberTexture,"ArrayTexture(3)":WebGLKernelValueNumberTexture,"ArrayTexture(4)":WebGLKernelValueNumberTexture,"MemoryOptimizedNumberTexture":WebGLKernelValueMemoryOptimizedNumberTexture,"HTMLCanvas":WebGLKernelValueHTMLImage,"HTMLImage":WebGLKernelValueHTMLImage,"HTMLImageArray":false,"HTMLVideo":WebGLKernelValueHTMLVideo}}};function lookupKernelValueType(type,dynamic,precision,value2){if(!type){throw new Error("type missing")}if(!dynamic){throw new Error("dynamic missing")}if(!precision){throw new Error("precision missing")}if(value2.type){type=value2.type}const types=kernelValueMaps[precision][dynamic];if(types[type]===false){return null}else if(types[type]===void 0){throw new Error(`Could not find a KernelValue for ${type}`)}return types[type]}module3.exports={lookupKernelValueType,kernelValueMaps}},{"./kernel-value/boolean":41,"./kernel-value/dynamic-html-image":42,"./kernel-value/dynamic-html-video":43,"./kernel-value/dynamic-memory-optimized-number-texture":44,"./kernel-value/dynamic-number-texture":45,"./kernel-value/dynamic-single-array":46,"./kernel-value/dynamic-single-array1d-i":47,"./kernel-value/dynamic-single-array2d-i":48,"./kernel-value/dynamic-single-array3d-i":49,"./kernel-value/dynamic-single-input":50,"./kernel-value/dynamic-unsigned-array":51,"./kernel-value/dynamic-unsigned-input":52,"./kernel-value/float":53,"./kernel-value/html-image":54,"./kernel-value/html-video":55,"./kernel-value/integer":57,"./kernel-value/memory-optimized-number-texture":58,"./kernel-value/number-texture":59,"./kernel-value/single-array":60,"./kernel-value/single-array1d-i":61,"./kernel-value/single-array2":62,"./kernel-value/single-array2d-i":63,"./kernel-value/single-array3":64,"./kernel-value/single-array3d-i":65,"./kernel-value/single-array4":66,"./kernel-value/single-input":67,"./kernel-value/unsigned-array":68,"./kernel-value/unsigned-input":69}],40:[function(require2,module3,exports3){const{WebGLKernelValue}=require2("./index");const{Input}=require2("../../../input");class WebGLKernelArray extends WebGLKernelValue{checkSize(width,height){if(!this.kernel.validate)return;const{maxTextureSize}=this.kernel.constructor.features;if(width>maxTextureSize||height>maxTextureSize){if(width>height){throw new Error(`Argument texture width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`)}else if(widthpluginName===plugin.name);if(usePlugin){pluginsToUse.push(plugin)}}}}return pluginsToUse}initExtensions(){this.extensions={OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:this.context.getExtension("WEBGL_color_buffer_float")}}validateSettings(args){if(!this.validate){this.texSize=utils.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output);return}const{features:features2}=this.constructor;if(this.optimizeFloatMemory===true&&!features2.isTextureFloat){throw new Error("Float textures are not supported")}else if(this.precision==="single"&&!features2.isFloatRead){throw new Error("Single precision not supported")}else if(!this.graphical&&this.precision===null&&features2.isTextureFloat){this.precision=features2.isFloatRead?"single":"unsigned"}if(this.subKernels&&this.subKernels.length>0&&!this.extensions.WEBGL_draw_buffers){throw new Error("could not instantiate draw buffers extension")}if(this.fixIntegerDivisionAccuracy===null){this.fixIntegerDivisionAccuracy=!features2.isIntegerDivisionAccurate}else if(this.fixIntegerDivisionAccuracy&&features2.isIntegerDivisionAccurate){this.fixIntegerDivisionAccuracy=false}this.checkOutput();if(!this.output||this.output.length===0){if(args.length!==1){throw new Error("Auto output only supported for kernels with only one input")}const argType=utils.getVariableType(args[0],this.strictIntegers);switch(argType){case"Array":this.output=utils.getDimensions(argType);break;case"NumberTexture":case"MemoryOptimizedNumberTexture":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":this.output=args[0].output;break;default:throw new Error("Auto output not supported for input type: "+argType)}}if(this.graphical){if(this.output.length!==2){throw new Error("Output must have 2 dimensions on graphical mode")}if(this.precision==="precision"){this.precision="unsigned";console.warn("Cannot use graphical mode and single precision at the same time")}this.texSize=utils.clone(this.output);return}else if(this.precision===null&&features2.isTextureFloat){this.precision="single"}this.texSize=utils.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output);this.checkTextureSize()}updateMaxTexSize(){const{texSize,canvas}=this;if(this.maxTexSize===null){let canvasIndex=canvases.indexOf(canvas);if(canvasIndex===-1){canvasIndex=canvases.length;canvases.push(canvas);maxTexSizes[canvasIndex]=[texSize[0],texSize[1]]}this.maxTexSize=maxTexSizes[canvasIndex]}if(this.maxTexSize[0]this.argumentNames.length){throw new Error("too many arguments for kernel")}const{context:gl}=this;let textureIndexes=0;const onRequestTexture=()=>{return this.createTexture()};const onRequestIndex=()=>{return this.constantTextureCount+textureIndexes++};const onUpdateValueMismatch=constructor=>{this.switchKernels({type:"argumentMismatch",needed:constructor})};const onRequestContextHandle=()=>{return gl.TEXTURE0+this.constantTextureCount+this.argumentTextureCount++};for(let index=0;index{return this.createTexture()},onRequestIndex:()=>{return textureIndexes++},onRequestContextHandle:()=>{return gl.TEXTURE0+this.constantTextureCount++}});this.constantBitRatios[name2]=kernelValue.bitRatio;this.kernelConstants.push(kernelValue);kernelValue.setup();if(kernelValue.forceUploadEachRun){this.forceUploadKernelConstants.push(kernelValue)}}}build(){if(this.built)return;this.initExtensions();this.validateSettings(arguments);this.setupConstants(arguments);if(this.fallbackRequested)return;this.setupArguments(arguments);if(this.fallbackRequested)return;this.updateMaxTexSize();this.translateSource();const failureResult=this.pickRenderStrategy(arguments);if(failureResult){return failureResult}const{texSize,context:gl,canvas}=this;gl.enable(gl.SCISSOR_TEST);if(this.pipeline&&this.precision==="single"){gl.viewport(0,0,this.maxTexSize[0],this.maxTexSize[1]);canvas.width=this.maxTexSize[0];canvas.height=this.maxTexSize[1]}else{gl.viewport(0,0,this.maxTexSize[0],this.maxTexSize[1]);canvas.width=this.maxTexSize[0];canvas.height=this.maxTexSize[1]}const threadDim=this.threadDim=Array.from(this.output);while(threadDim.length<3){threadDim.push(1)}const compiledVertexShader=this.getVertexShader(arguments);const vertShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertShader,compiledVertexShader);gl.compileShader(vertShader);this.vertShader=vertShader;const compiledFragmentShader=this.getFragmentShader(arguments);const fragShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragShader,compiledFragmentShader);gl.compileShader(fragShader);this.fragShader=fragShader;if(this.debug){console.log("GLSL Shader Output:");console.log(compiledFragmentShader)}if(!gl.getShaderParameter(vertShader,gl.COMPILE_STATUS)){throw new Error("Error compiling vertex shader: "+gl.getShaderInfoLog(vertShader))}if(!gl.getShaderParameter(fragShader,gl.COMPILE_STATUS)){throw new Error("Error compiling fragment shader: "+gl.getShaderInfoLog(fragShader))}const program=this.program=gl.createProgram();gl.attachShader(program,vertShader);gl.attachShader(program,fragShader);gl.linkProgram(program);this.framebuffer=gl.createFramebuffer();this.framebuffer.width=texSize[0];this.framebuffer.height=texSize[1];this.rawValueFramebuffers={};const vertices=new Float32Array([-1,-1,1,-1,-1,1,1,1]);const texCoords=new Float32Array([0,0,1,0,0,1,1,1]);const texCoordOffset=vertices.byteLength;let buffer=this.buffer;if(!buffer){buffer=this.buffer=gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER,buffer);gl.bufferData(gl.ARRAY_BUFFER,vertices.byteLength+texCoords.byteLength,gl.STATIC_DRAW)}else{gl.bindBuffer(gl.ARRAY_BUFFER,buffer)}gl.bufferSubData(gl.ARRAY_BUFFER,0,vertices);gl.bufferSubData(gl.ARRAY_BUFFER,texCoordOffset,texCoords);const aPosLoc=gl.getAttribLocation(this.program,"aPos");gl.enableVertexAttribArray(aPosLoc);gl.vertexAttribPointer(aPosLoc,2,gl.FLOAT,false,0,0);const aTexCoordLoc=gl.getAttribLocation(this.program,"aTexCoord");gl.enableVertexAttribArray(aTexCoordLoc);gl.vertexAttribPointer(aTexCoordLoc,2,gl.FLOAT,false,0,texCoordOffset);gl.bindFramebuffer(gl.FRAMEBUFFER,this.framebuffer);let i=0;gl.useProgram(this.program);for(let p in this.constants){this.kernelConstants[i++].updateValue(this.constants[p])}this._setupOutputTexture();if(this.subKernels!==null&&this.subKernels.length>0){this._mappedTextureSwitched={};this._setupSubOutputTextures()}this.buildSignature(arguments);this.built=true}translateSource(){const functionBuilder=FunctionBuilder.fromKernel(this,WebGLFunctionNode,{fixIntegerDivisionAccuracy:this.fixIntegerDivisionAccuracy});this.translatedSource=functionBuilder.getPrototypeString("kernel");this.setupReturnTypes(functionBuilder)}setupReturnTypes(functionBuilder){if(!this.graphical&&!this.returnType){this.returnType=functionBuilder.getKernelResultType()}if(this.subKernels&&this.subKernels.length>0){for(let i=0;iplugin.source&&this.source.match(plugin.functionMatch)?plugin.source:"").join("\n")}_getConstantsString(){const result=[];const{threadDim,texSize}=this;if(this.dynamicOutput){result.push("uniform ivec3 uOutputDim","uniform ivec2 uTexSize")}else{result.push(`ivec3 uOutputDim = ivec3(${threadDim[0]}, ${threadDim[1]}, ${threadDim[2]})`,`ivec2 uTexSize = ivec2(${texSize[0]}, ${texSize[1]})`)}return utils.linesToString(result)}_getTextureCoordinate(){const subKernels=this.subKernels;if(subKernels===null||subKernels.length<1){return"varying vec2 vTexCoord;\n"}else{return"out vec2 vTexCoord;\n"}}_getDecode32EndiannessString(){return this.endianness==="LE"?"":" texel.rgba = texel.abgr;\n"}_getEncode32EndiannessString(){return this.endianness==="LE"?"":" texel.rgba = texel.abgr;\n"}_getDivideWithIntegerCheckString(){return this.fixIntegerDivisionAccuracy?`float divWithIntCheck(float x, float y) { - if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) { - return float(int(x) / int(y)); - } - return x / y; - } - - float integerCorrectionModulo(float number, float divisor) { - if (number < 0.0) { - number = abs(number); - if (divisor < 0.0) { - divisor = abs(divisor); - } - return -(number - (divisor * floor(divWithIntCheck(number, divisor)))); - } - if (divisor < 0.0) { - divisor = abs(divisor); - } - return number - (divisor * floor(divWithIntCheck(number, divisor))); - }`:""}_getMainArgumentsString(args){const results=[];const{argumentNames}=this;for(let i=0;i{if(map.hasOwnProperty(artifact)){return map[artifact]}throw`unhandled artifact ${artifact}`})}getFragmentShader(args){if(this.compiledFragmentShader!==null){return this.compiledFragmentShader}return this.compiledFragmentShader=this.replaceArtifacts(this.constructor.fragmentShader,this._getFragShaderArtifactMap(args))}getVertexShader(args){if(this.compiledVertexShader!==null){return this.compiledVertexShader}return this.compiledVertexShader=this.replaceArtifacts(this.constructor.vertexShader,this._getVertShaderArtifactMap(args))}toString(){const setupContextString=utils.linesToString([`const gl = context`]);return glKernelString(this.constructor,arguments,this,setupContextString)}destroy(removeCanvasReferences){if(!this.context)return;if(this.buffer){this.context.deleteBuffer(this.buffer)}if(this.framebuffer){this.context.deleteFramebuffer(this.framebuffer)}for(const width in this.rawValueFramebuffers){for(const height in this.rawValueFramebuffers[width]){this.context.deleteFramebuffer(this.rawValueFramebuffers[width][height]);delete this.rawValueFramebuffers[width][height]}delete this.rawValueFramebuffers[width]}if(this.vertShader){this.context.deleteShader(this.vertShader)}if(this.fragShader){this.context.deleteShader(this.fragShader)}if(this.program){this.context.deleteProgram(this.program)}if(this.texture){this.texture.delete();const textureCacheIndex=this.textureCache.indexOf(this.texture.texture);if(textureCacheIndex>-1){this.textureCache.splice(textureCacheIndex,1)}this.texture=null}if(this.mappedTextures&&this.mappedTextures.length){for(let i2=0;i2-1){this.textureCache.splice(textureCacheIndex,1)}}this.mappedTextures=null}if(this.kernelArguments){for(let i2=0;i20){const texture=this.textureCache.pop();this.context.deleteTexture(texture)}if(removeCanvasReferences){const idx=canvases.indexOf(this.canvas);if(idx>=0){canvases[idx]=null;maxTexSizes[idx]=null}}this.destroyExtensions();delete this.context;delete this.canvas;if(!this.gpu)return;const i=this.gpu.kernels.indexOf(this);if(i===-1)return;this.gpu.kernels.splice(i,1)}destroyExtensions(){this.extensions.OES_texture_float=null;this.extensions.OES_texture_float_linear=null;this.extensions.OES_element_index_uint=null;this.extensions.WEBGL_draw_buffers=null}static destroyContext(context){const extension=context.getExtension("WEBGL_lose_context");if(extension){extension.loseContext()}}toJSON(){const json=super.toJSON();json.functionNodes=FunctionBuilder.fromKernel(this,WebGLFunctionNode).toJSON();json.settings.threadDim=this.threadDim;return json}}module3.exports={WebGLKernel}},{"../../plugins/math-random-uniformly-distributed":112,"../../utils":114,"../function-builder":9,"../gl/kernel":13,"../gl/kernel-string":12,"./fragment-shader":37,"./function-node":38,"./kernel-value-maps":39,"./vertex-shader":71}],71:[function(require2,module3,exports3){const vertexShader=`__FLOAT_TACTIC_DECLARATION__; - __INT_TACTIC_DECLARATION__; - __SAMPLER_2D_TACTIC_DECLARATION__; - - attribute vec2 aPos; - attribute vec2 aTexCoord; - - varying vec2 vTexCoord; - uniform vec2 ratio; - - void main(void) { - gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1); - vTexCoord = aTexCoord; - }`;module3.exports={vertexShader}},{}],72:[function(require2,module3,exports3){const fragmentShader=`#version 300 es - __HEADER__; - __FLOAT_TACTIC_DECLARATION__; - __INT_TACTIC_DECLARATION__; - __SAMPLER_2D_TACTIC_DECLARATION__; - __SAMPLER_2D_ARRAY_TACTIC_DECLARATION__; - - const int LOOP_MAX = __LOOP_MAX__; - - __PLUGINS__; - __CONSTANTS__; - - in vec2 vTexCoord; - - float atan2(float v1, float v2) { - if (v1 == 0.0 || v2 == 0.0) return 0.0; - return atan(v1 / v2); - } - - float cbrt(float x) { - if (x >= 0.0) { - return pow(x, 1.0 / 3.0); - } else { - return -pow(x, 1.0 / 3.0); - } - } - - float expm1(float x) { - return pow(${Math.E}, x) - 1.0; - } - - float fround(highp float x) { - return x; - } - - float imul(float v1, float v2) { - return float(int(v1) * int(v2)); - } - - float log10(float x) { - return log2(x) * (1.0 / log2(10.0)); - } - - float log1p(float x) { - return log(1.0 + x); - } - - float _pow(float v1, float v2) { - if (v2 == 0.0) return 1.0; - return pow(v1, v2); - } - - float _round(float x) { - return floor(x + 0.5); - } - - - const int BIT_COUNT = 32; - int modi(int x, int y) { - return x - y * (x / y); - } - - int bitwiseOr(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; - } - } - return result; - } - int bitwiseXOR(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; - } - } - return result; - } - int bitwiseAnd(int a, int b) { - int result = 0; - int n = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 && b > 0)) { - break; - } - } - return result; - } - int bitwiseNot(int a) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if (modi(a, 2) == 0) { - result += n; - } - a = a / 2; - n = n * 2; - } - return result; - } - int bitwiseZeroFillLeftShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; - } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; - } - n *= 2; - } - - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; - } - - int bitwiseSignedRightShift(int num, int shifts) { - return int(floor(float(num) / pow(2.0, float(shifts)))); - } - - int bitwiseZeroFillRightShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; - } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; - } - n /= 2; - } - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; - } - - vec2 integerMod(vec2 x, float y) { - vec2 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); - } - - vec3 integerMod(vec3 x, float y) { - vec3 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); - } - - vec4 integerMod(vec4 x, vec4 y) { - vec4 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); - } - - float integerMod(float x, float y) { - float res = floor(mod(x, y)); - return res * (res > floor(y) - 1.0 ? 0.0 : 1.0); - } - - int integerMod(int x, int y) { - return x - (y * int(x/y)); - } - - __DIVIDE_WITH_INTEGER_CHECK__; - - // Here be dragons! - // DO NOT OPTIMIZE THIS CODE - // YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE - // LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME - const vec2 MAGIC_VEC = vec2(1.0, -256.0); - const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0); - const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536 - float decode32(vec4 texel) { - __DECODE32_ENDIANNESS__; - texel *= 255.0; - vec2 gte128; - gte128.x = texel.b >= 128.0 ? 1.0 : 0.0; - gte128.y = texel.a >= 128.0 ? 1.0 : 0.0; - float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC); - float res = exp2(round(exponent)); - texel.b = texel.b - 128.0 * gte128.x; - res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res; - res *= gte128.y * -2.0 + 1.0; - return res; - } - - float decode16(vec4 texel, int index) { - int channel = integerMod(index, 2); - return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0; - } - - float decode8(vec4 texel, int index) { - int channel = integerMod(index, 4); - return texel[channel] * 255.0; - } - - vec4 legacyEncode32(float f) { - float F = abs(f); - float sign = f < 0.0 ? 1.0 : 0.0; - float exponent = floor(log2(F)); - float mantissa = (exp2(-exponent) * F); - // exponent += floor(log2(mantissa)); - vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV; - texel.rg = integerMod(texel.rg, 256.0); - texel.b = integerMod(texel.b, 128.0); - texel.a = exponent*0.5 + 63.5; - texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0; - texel = floor(texel); - texel *= 0.003921569; // 1/255 - __ENCODE32_ENDIANNESS__; - return texel; - } - - // https://github.com/gpujs/gpu.js/wiki/Encoder-details - vec4 encode32(float value) { - if (value == 0.0) return vec4(0, 0, 0, 0); - - float exponent; - float mantissa; - vec4 result; - float sgn; - - sgn = step(0.0, -value); - value = abs(value); - - exponent = floor(log2(value)); - - mantissa = value*pow(2.0, -exponent)-1.0; - exponent = exponent+127.0; - result = vec4(0,0,0,0); - - result.a = floor(exponent/2.0); - exponent = exponent - result.a*2.0; - result.a = result.a + 128.0*sgn; - - result.b = floor(mantissa * 128.0); - mantissa = mantissa - result.b / 128.0; - result.b = result.b + exponent*128.0; - - result.g = floor(mantissa*32768.0); - mantissa = mantissa - result.g/32768.0; - - result.r = floor(mantissa*8388608.0); - return result/255.0; - } - // Dragons end here - - int index; - ivec3 threadId; - - ivec3 indexTo3D(int idx, ivec3 texDim) { - int z = int(idx / (texDim.x * texDim.y)); - idx -= z * int(texDim.x * texDim.y); - int y = int(idx / texDim.x); - int x = int(integerMod(idx, texDim.x)); - return ivec3(x, y, z); - } - - float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize)); - return decode32(texel); - } - - float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int w = texSize.x * 2; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y)); - return decode16(texel, index); - } - - float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int w = texSize.x * 4; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y)); - return decode8(texel, index); - } - - float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int channel = integerMod(index, 4); - index = index / 4; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - index = index / 4; - vec4 texel = texture(tex, st / vec2(texSize)); - return texel[channel]; - } - - vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - return texture(tex, st / vec2(texSize)); - } - - vec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - return texture(tex, vec3(st / vec2(texSize), z)); - } - - float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return result[0]; - } - - vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec2(result[0], result[1]); - } - - vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 2); - index = index / 2; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize)); - if (channel == 0) return vec2(texel.r, texel.g); - if (channel == 1) return vec2(texel.b, texel.a); - return vec2(0.0, 0.0); - } - - vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec3(result[0], result[1], result[2]); - } - - vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z)); - int vectorIndex = fieldIndex / 4; - int vectorOffset = fieldIndex - vectorIndex * 4; - int readY = vectorIndex / texSize.x; - int readX = vectorIndex - readY * texSize.x; - vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize)); - - if (vectorOffset == 0) { - return tex1.xyz; - } else if (vectorOffset == 1) { - return tex1.yzw; - } else { - readX++; - if (readX >= texSize.x) { - readX = 0; - readY++; - } - vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize)); - if (vectorOffset == 2) { - return vec3(tex1.z, tex1.w, tex2.x); - } else { - return vec3(tex1.w, tex2.x, tex2.y); - } - } - } - - vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - return getImage2D(tex, texSize, texDim, z, y, x); - } - - vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 2); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize)); - return vec4(texel.r, texel.g, texel.b, texel.a); - } - - vec4 actualColor; - void color(float r, float g, float b, float a) { - actualColor = vec4(r,g,b,a); - } - - void color(float r, float g, float b) { - color(r,g,b,1.0); - } - - float modulo(float number, float divisor) { - if (number < 0.0) { - number = abs(number); - if (divisor < 0.0) { - divisor = abs(divisor); - } - return -mod(number, divisor); - } - if (divisor < 0.0) { - divisor = abs(divisor); - } - return mod(number, divisor); - } - - __INJECTED_NATIVE__; - __MAIN_CONSTANTS__; - __MAIN_ARGUMENTS__; - __KERNEL__; - - void main(void) { - index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x; - __MAIN_RESULT__; - }`;module3.exports={fragmentShader}},{}],73:[function(require2,module3,exports3){const{utils}=require2("../../utils");const{WebGLFunctionNode}=require2("../web-gl/function-node");class WebGL2FunctionNode extends WebGLFunctionNode{astIdentifierExpression(idtNode,retArr){if(idtNode.type!=="Identifier"){throw this.astErrorOutput("IdentifierExpression - not an Identifier",idtNode)}const type=this.getType(idtNode);const name2=utils.sanitizeName(idtNode.name);if(idtNode.name==="Infinity"){retArr.push("intBitsToFloat(2139095039)")}else if(type==="Boolean"){if(this.argumentNames.indexOf(name2)>-1){retArr.push(`bool(user_${name2})`)}else{retArr.push(`user_${name2}`)}}else{retArr.push(`user_${name2}`)}return retArr}}module3.exports={WebGL2FunctionNode}},{"../../utils":114,"../web-gl/function-node":38}],74:[function(require2,module3,exports3){const{WebGL2KernelValueBoolean}=require2("./kernel-value/boolean");const{WebGL2KernelValueFloat}=require2("./kernel-value/float");const{WebGL2KernelValueInteger}=require2("./kernel-value/integer");const{WebGL2KernelValueHTMLImage}=require2("./kernel-value/html-image");const{WebGL2KernelValueDynamicHTMLImage}=require2("./kernel-value/dynamic-html-image");const{WebGL2KernelValueHTMLImageArray}=require2("./kernel-value/html-image-array");const{WebGL2KernelValueDynamicHTMLImageArray}=require2("./kernel-value/dynamic-html-image-array");const{WebGL2KernelValueHTMLVideo}=require2("./kernel-value/html-video");const{WebGL2KernelValueDynamicHTMLVideo}=require2("./kernel-value/dynamic-html-video");const{WebGL2KernelValueSingleInput}=require2("./kernel-value/single-input");const{WebGL2KernelValueDynamicSingleInput}=require2("./kernel-value/dynamic-single-input");const{WebGL2KernelValueUnsignedInput}=require2("./kernel-value/unsigned-input");const{WebGL2KernelValueDynamicUnsignedInput}=require2("./kernel-value/dynamic-unsigned-input");const{WebGL2KernelValueMemoryOptimizedNumberTexture}=require2("./kernel-value/memory-optimized-number-texture");const{WebGL2KernelValueDynamicMemoryOptimizedNumberTexture}=require2("./kernel-value/dynamic-memory-optimized-number-texture");const{WebGL2KernelValueNumberTexture}=require2("./kernel-value/number-texture");const{WebGL2KernelValueDynamicNumberTexture}=require2("./kernel-value/dynamic-number-texture");const{WebGL2KernelValueSingleArray}=require2("./kernel-value/single-array");const{WebGL2KernelValueDynamicSingleArray}=require2("./kernel-value/dynamic-single-array");const{WebGL2KernelValueSingleArray1DI}=require2("./kernel-value/single-array1d-i");const{WebGL2KernelValueDynamicSingleArray1DI}=require2("./kernel-value/dynamic-single-array1d-i");const{WebGL2KernelValueSingleArray2DI}=require2("./kernel-value/single-array2d-i");const{WebGL2KernelValueDynamicSingleArray2DI}=require2("./kernel-value/dynamic-single-array2d-i");const{WebGL2KernelValueSingleArray3DI}=require2("./kernel-value/single-array3d-i");const{WebGL2KernelValueDynamicSingleArray3DI}=require2("./kernel-value/dynamic-single-array3d-i");const{WebGL2KernelValueSingleArray2}=require2("./kernel-value/single-array2");const{WebGL2KernelValueSingleArray3}=require2("./kernel-value/single-array3");const{WebGL2KernelValueSingleArray4}=require2("./kernel-value/single-array4");const{WebGL2KernelValueUnsignedArray}=require2("./kernel-value/unsigned-array");const{WebGL2KernelValueDynamicUnsignedArray}=require2("./kernel-value/dynamic-unsigned-array");const kernelValueMaps={unsigned:{dynamic:{"Boolean":WebGL2KernelValueBoolean,"Integer":WebGL2KernelValueInteger,"Float":WebGL2KernelValueFloat,"Array":WebGL2KernelValueDynamicUnsignedArray,"Array(2)":false,"Array(3)":false,"Array(4)":false,"Array1D(2)":false,"Array1D(3)":false,"Array1D(4)":false,"Array2D(2)":false,"Array2D(3)":false,"Array2D(4)":false,"Array3D(2)":false,"Array3D(3)":false,"Array3D(4)":false,"Input":WebGL2KernelValueDynamicUnsignedInput,"NumberTexture":WebGL2KernelValueDynamicNumberTexture,"ArrayTexture(1)":WebGL2KernelValueDynamicNumberTexture,"ArrayTexture(2)":WebGL2KernelValueDynamicNumberTexture,"ArrayTexture(3)":WebGL2KernelValueDynamicNumberTexture,"ArrayTexture(4)":WebGL2KernelValueDynamicNumberTexture,"MemoryOptimizedNumberTexture":WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,"HTMLCanvas":WebGL2KernelValueDynamicHTMLImage,"HTMLImage":WebGL2KernelValueDynamicHTMLImage,"HTMLImageArray":WebGL2KernelValueDynamicHTMLImageArray,"HTMLVideo":WebGL2KernelValueDynamicHTMLVideo},static:{"Boolean":WebGL2KernelValueBoolean,"Float":WebGL2KernelValueFloat,"Integer":WebGL2KernelValueInteger,"Array":WebGL2KernelValueUnsignedArray,"Array(2)":false,"Array(3)":false,"Array(4)":false,"Array1D(2)":false,"Array1D(3)":false,"Array1D(4)":false,"Array2D(2)":false,"Array2D(3)":false,"Array2D(4)":false,"Array3D(2)":false,"Array3D(3)":false,"Array3D(4)":false,"Input":WebGL2KernelValueUnsignedInput,"NumberTexture":WebGL2KernelValueNumberTexture,"ArrayTexture(1)":WebGL2KernelValueNumberTexture,"ArrayTexture(2)":WebGL2KernelValueNumberTexture,"ArrayTexture(3)":WebGL2KernelValueNumberTexture,"ArrayTexture(4)":WebGL2KernelValueNumberTexture,"MemoryOptimizedNumberTexture":WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,"HTMLCanvas":WebGL2KernelValueHTMLImage,"HTMLImage":WebGL2KernelValueHTMLImage,"HTMLImageArray":WebGL2KernelValueHTMLImageArray,"HTMLVideo":WebGL2KernelValueHTMLVideo}},single:{dynamic:{"Boolean":WebGL2KernelValueBoolean,"Integer":WebGL2KernelValueInteger,"Float":WebGL2KernelValueFloat,"Array":WebGL2KernelValueDynamicSingleArray,"Array(2)":WebGL2KernelValueSingleArray2,"Array(3)":WebGL2KernelValueSingleArray3,"Array(4)":WebGL2KernelValueSingleArray4,"Array1D(2)":WebGL2KernelValueDynamicSingleArray1DI,"Array1D(3)":WebGL2KernelValueDynamicSingleArray1DI,"Array1D(4)":WebGL2KernelValueDynamicSingleArray1DI,"Array2D(2)":WebGL2KernelValueDynamicSingleArray2DI,"Array2D(3)":WebGL2KernelValueDynamicSingleArray2DI,"Array2D(4)":WebGL2KernelValueDynamicSingleArray2DI,"Array3D(2)":WebGL2KernelValueDynamicSingleArray3DI,"Array3D(3)":WebGL2KernelValueDynamicSingleArray3DI,"Array3D(4)":WebGL2KernelValueDynamicSingleArray3DI,"Input":WebGL2KernelValueDynamicSingleInput,"NumberTexture":WebGL2KernelValueDynamicNumberTexture,"ArrayTexture(1)":WebGL2KernelValueDynamicNumberTexture,"ArrayTexture(2)":WebGL2KernelValueDynamicNumberTexture,"ArrayTexture(3)":WebGL2KernelValueDynamicNumberTexture,"ArrayTexture(4)":WebGL2KernelValueDynamicNumberTexture,"MemoryOptimizedNumberTexture":WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,"HTMLCanvas":WebGL2KernelValueDynamicHTMLImage,"HTMLImage":WebGL2KernelValueDynamicHTMLImage,"HTMLImageArray":WebGL2KernelValueDynamicHTMLImageArray,"HTMLVideo":WebGL2KernelValueDynamicHTMLVideo},static:{"Boolean":WebGL2KernelValueBoolean,"Float":WebGL2KernelValueFloat,"Integer":WebGL2KernelValueInteger,"Array":WebGL2KernelValueSingleArray,"Array(2)":WebGL2KernelValueSingleArray2,"Array(3)":WebGL2KernelValueSingleArray3,"Array(4)":WebGL2KernelValueSingleArray4,"Array1D(2)":WebGL2KernelValueSingleArray1DI,"Array1D(3)":WebGL2KernelValueSingleArray1DI,"Array1D(4)":WebGL2KernelValueSingleArray1DI,"Array2D(2)":WebGL2KernelValueSingleArray2DI,"Array2D(3)":WebGL2KernelValueSingleArray2DI,"Array2D(4)":WebGL2KernelValueSingleArray2DI,"Array3D(2)":WebGL2KernelValueSingleArray3DI,"Array3D(3)":WebGL2KernelValueSingleArray3DI,"Array3D(4)":WebGL2KernelValueSingleArray3DI,"Input":WebGL2KernelValueSingleInput,"NumberTexture":WebGL2KernelValueNumberTexture,"ArrayTexture(1)":WebGL2KernelValueNumberTexture,"ArrayTexture(2)":WebGL2KernelValueNumberTexture,"ArrayTexture(3)":WebGL2KernelValueNumberTexture,"ArrayTexture(4)":WebGL2KernelValueNumberTexture,"MemoryOptimizedNumberTexture":WebGL2KernelValueMemoryOptimizedNumberTexture,"HTMLCanvas":WebGL2KernelValueHTMLImage,"HTMLImage":WebGL2KernelValueHTMLImage,"HTMLImageArray":WebGL2KernelValueHTMLImageArray,"HTMLVideo":WebGL2KernelValueHTMLVideo}}};function lookupKernelValueType(type,dynamic,precision,value2){if(!type){throw new Error("type missing")}if(!dynamic){throw new Error("dynamic missing")}if(!precision){throw new Error("precision missing")}if(value2.type){type=value2.type}const types=kernelValueMaps[precision][dynamic];if(types[type]===false){return null}else if(types[type]===void 0){throw new Error(`Could not find a KernelValue for ${type}`)}return types[type]}module3.exports={kernelValueMaps,lookupKernelValueType}},{"./kernel-value/boolean":75,"./kernel-value/dynamic-html-image":77,"./kernel-value/dynamic-html-image-array":76,"./kernel-value/dynamic-html-video":78,"./kernel-value/dynamic-memory-optimized-number-texture":79,"./kernel-value/dynamic-number-texture":80,"./kernel-value/dynamic-single-array":81,"./kernel-value/dynamic-single-array1d-i":82,"./kernel-value/dynamic-single-array2d-i":83,"./kernel-value/dynamic-single-array3d-i":84,"./kernel-value/dynamic-single-input":85,"./kernel-value/dynamic-unsigned-array":86,"./kernel-value/dynamic-unsigned-input":87,"./kernel-value/float":88,"./kernel-value/html-image":90,"./kernel-value/html-image-array":89,"./kernel-value/html-video":91,"./kernel-value/integer":92,"./kernel-value/memory-optimized-number-texture":93,"./kernel-value/number-texture":94,"./kernel-value/single-array":95,"./kernel-value/single-array1d-i":96,"./kernel-value/single-array2":97,"./kernel-value/single-array2d-i":98,"./kernel-value/single-array3":99,"./kernel-value/single-array3d-i":100,"./kernel-value/single-array4":101,"./kernel-value/single-input":102,"./kernel-value/unsigned-array":103,"./kernel-value/unsigned-input":104}],75:[function(require2,module3,exports3){const{WebGLKernelValueBoolean}=require2("../../web-gl/kernel-value/boolean");class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean{}module3.exports={WebGL2KernelValueBoolean}},{"../../web-gl/kernel-value/boolean":41}],76:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGL2KernelValueHTMLImageArray}=require2("./html-image-array");class WebGL2KernelValueDynamicHTMLImageArray extends WebGL2KernelValueHTMLImageArray{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2DArray ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}updateValue(images){const{width,height}=images[0];this.checkSize(width,height);this.dimensions=[width,height,images.length];this.textureSize=[width,height];this.kernel.setUniform3iv(this.dimensionsId,this.dimensions);this.kernel.setUniform2iv(this.sizeId,this.textureSize);super.updateValue(images)}}module3.exports={WebGL2KernelValueDynamicHTMLImageArray}},{"../../../utils":114,"./html-image-array":89}],77:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGLKernelValueDynamicHTMLImage}=require2("../../web-gl/kernel-value/dynamic-html-image");class WebGL2KernelValueDynamicHTMLImage extends WebGLKernelValueDynamicHTMLImage{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2D ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}}module3.exports={WebGL2KernelValueDynamicHTMLImage}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-html-image":42}],78:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGL2KernelValueDynamicHTMLImage}=require2("./dynamic-html-image");class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage{}module3.exports={WebGL2KernelValueDynamicHTMLVideo}},{"../../../utils":114,"./dynamic-html-image":77}],79:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGLKernelValueDynamicMemoryOptimizedNumberTexture}=require2("../../web-gl/kernel-value/dynamic-memory-optimized-number-texture");class WebGL2KernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueDynamicMemoryOptimizedNumberTexture{getSource(){return utils.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}}module3.exports={WebGL2KernelValueDynamicMemoryOptimizedNumberTexture}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-memory-optimized-number-texture":44}],80:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGLKernelValueDynamicNumberTexture}=require2("../../web-gl/kernel-value/dynamic-number-texture");class WebGL2KernelValueDynamicNumberTexture extends WebGLKernelValueDynamicNumberTexture{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2D ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}}module3.exports={WebGL2KernelValueDynamicNumberTexture}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-number-texture":45}],81:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGL2KernelValueSingleArray}=require2("../../web-gl2/kernel-value/single-array");class WebGL2KernelValueDynamicSingleArray extends WebGL2KernelValueSingleArray{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2D ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}updateValue(value2){this.dimensions=utils.getDimensions(value2,true);this.textureSize=utils.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio);this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio;this.checkSize(this.textureSize[0],this.textureSize[1]);this.uploadValue=new Float32Array(this.uploadArrayLength);this.kernel.setUniform3iv(this.dimensionsId,this.dimensions);this.kernel.setUniform2iv(this.sizeId,this.textureSize);super.updateValue(value2)}}module3.exports={WebGL2KernelValueDynamicSingleArray}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array":95}],82:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGL2KernelValueSingleArray1DI}=require2("../../web-gl2/kernel-value/single-array1d-i");class WebGL2KernelValueDynamicSingleArray1DI extends WebGL2KernelValueSingleArray1DI{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2D ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}updateValue(value2){this.setShape(value2);this.kernel.setUniform3iv(this.dimensionsId,this.dimensions);this.kernel.setUniform2iv(this.sizeId,this.textureSize);super.updateValue(value2)}}module3.exports={WebGL2KernelValueDynamicSingleArray1DI}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array1d-i":96}],83:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGL2KernelValueSingleArray2DI}=require2("../../web-gl2/kernel-value/single-array2d-i");class WebGL2KernelValueDynamicSingleArray2DI extends WebGL2KernelValueSingleArray2DI{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2D ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}updateValue(value2){this.setShape(value2);this.kernel.setUniform3iv(this.dimensionsId,this.dimensions);this.kernel.setUniform2iv(this.sizeId,this.textureSize);super.updateValue(value2)}}module3.exports={WebGL2KernelValueDynamicSingleArray2DI}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array2d-i":98}],84:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGL2KernelValueSingleArray3DI}=require2("../../web-gl2/kernel-value/single-array3d-i");class WebGL2KernelValueDynamicSingleArray3DI extends WebGL2KernelValueSingleArray3DI{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2D ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}updateValue(value2){this.setShape(value2);this.kernel.setUniform3iv(this.dimensionsId,this.dimensions);this.kernel.setUniform2iv(this.sizeId,this.textureSize);super.updateValue(value2)}}module3.exports={WebGL2KernelValueDynamicSingleArray3DI}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array3d-i":100}],85:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGL2KernelValueSingleInput}=require2("../../web-gl2/kernel-value/single-input");class WebGL2KernelValueDynamicSingleInput extends WebGL2KernelValueSingleInput{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2D ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}updateValue(value2){let[w,h,d]=value2.size;this.dimensions=new Int32Array([w||1,h||1,d||1]);this.textureSize=utils.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio);this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio;this.checkSize(this.textureSize[0],this.textureSize[1]);this.uploadValue=new Float32Array(this.uploadArrayLength);this.kernel.setUniform3iv(this.dimensionsId,this.dimensions);this.kernel.setUniform2iv(this.sizeId,this.textureSize);super.updateValue(value2)}}module3.exports={WebGL2KernelValueDynamicSingleInput}},{"../../../utils":114,"../../web-gl2/kernel-value/single-input":102}],86:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGLKernelValueDynamicUnsignedArray}=require2("../../web-gl/kernel-value/dynamic-unsigned-array");class WebGL2KernelValueDynamicUnsignedArray extends WebGLKernelValueDynamicUnsignedArray{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2D ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}}module3.exports={WebGL2KernelValueDynamicUnsignedArray}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-unsigned-array":51}],87:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGLKernelValueDynamicUnsignedInput}=require2("../../web-gl/kernel-value/dynamic-unsigned-input");class WebGL2KernelValueDynamicUnsignedInput extends WebGLKernelValueDynamicUnsignedInput{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2D ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}}module3.exports={WebGL2KernelValueDynamicUnsignedInput}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-unsigned-input":52}],88:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGLKernelValueFloat}=require2("../../web-gl/kernel-value/float");class WebGL2KernelValueFloat extends WebGLKernelValueFloat{}module3.exports={WebGL2KernelValueFloat}},{"../../../utils":114,"../../web-gl/kernel-value/float":53}],89:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGLKernelArray}=require2("../../web-gl/kernel-value/array");class WebGL2KernelValueHTMLImageArray extends WebGLKernelArray{constructor(value2,settings){super(value2,settings);this.checkSize(value2[0].width,value2[0].height);this.dimensions=[value2[0].width,value2[0].height,value2.length];this.textureSize=[value2[0].width,value2[0].height]}defineTexture(){const{context:gl}=this;gl.activeTexture(this.contextHandle);gl.bindTexture(gl.TEXTURE_2D_ARRAY,this.texture);gl.texParameteri(gl.TEXTURE_2D_ARRAY,gl.TEXTURE_MAG_FILTER,gl.NEAREST);gl.texParameteri(gl.TEXTURE_2D_ARRAY,gl.TEXTURE_MIN_FILTER,gl.NEAREST)}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName}; -`}getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2DArray ${this.id}`,`${variablePrecision} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${variablePrecision} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(images){const{context:gl}=this;gl.activeTexture(this.contextHandle);gl.bindTexture(gl.TEXTURE_2D_ARRAY,this.texture);gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true);gl.texImage3D(gl.TEXTURE_2D_ARRAY,0,gl.RGBA,images[0].width,images[0].height,images.length,0,gl.RGBA,gl.UNSIGNED_BYTE,null);for(let i=0;iKernel2.isSupported)}static get isKernelMapSupported(){return kernelOrder.some(Kernel2=>Kernel2.isSupported&&Kernel2.features.kernelMap)}static get isOffscreenCanvasSupported(){return typeof Worker!=="undefined"&&typeof OffscreenCanvas!=="undefined"||typeof importScripts!=="undefined"}static get isWebGLSupported(){return WebGLKernel.isSupported}static get isWebGL2Supported(){return WebGL2Kernel.isSupported}static get isHeadlessGLSupported(){return HeadlessGLKernel.isSupported}static get isCanvasSupported(){return typeof HTMLCanvasElement!=="undefined"}static get isGPUHTMLImageArraySupported(){return WebGL2Kernel.isSupported}static get isSinglePrecisionSupported(){return kernelOrder.some(Kernel2=>Kernel2.isSupported&&Kernel2.features.isFloatRead&&Kernel2.features.isTextureFloat)}constructor(settings){settings=settings||{};this.canvas=settings.canvas||null;this.context=settings.context||null;this.mode=settings.mode;this.Kernel=null;this.kernels=[];this.functions=[];this.nativeFunctions=[];this.injectedNative=null;if(this.mode==="dev")return;this.chooseKernel();if(settings.functions){for(let i=0;isettings.argumentTypes[argumentName])}function onRequestFallback(args){console.warn("Falling back to CPU");const fallbackKernel=new CPUKernel(source,{argumentTypes:kernelRun.argumentTypes,constantTypes:kernelRun.constantTypes,graphical:kernelRun.graphical,loopMaxIterations:kernelRun.loopMaxIterations,constants:kernelRun.constants,dynamicOutput:kernelRun.dynamicOutput,dynamicArgument:kernelRun.dynamicArguments,output:kernelRun.output,precision:kernelRun.precision,pipeline:kernelRun.pipeline,immutable:kernelRun.immutable,optimizeFloatMemory:kernelRun.optimizeFloatMemory,fixIntegerDivisionAccuracy:kernelRun.fixIntegerDivisionAccuracy,functions:kernelRun.functions,nativeFunctions:kernelRun.nativeFunctions,injectedNative:kernelRun.injectedNative,subKernels:kernelRun.subKernels,strictIntegers:kernelRun.strictIntegers,debug:kernelRun.debug});fallbackKernel.build.apply(fallbackKernel,args);const result=fallbackKernel.run.apply(fallbackKernel,args);kernelRun.replaceKernel(fallbackKernel);return result}function onRequestSwitchKernel(reasons,args,_kernel){if(_kernel.debug){console.warn("Switching kernels")}let newOutput=null;if(_kernel.signature&&!switchableKernels[_kernel.signature]){switchableKernels[_kernel.signature]=_kernel}if(_kernel.dynamicOutput){for(let i=reasons.length-1;i>=0;i--){const reason=reasons[i];if(reason.type==="outputPrecisionMismatch"){newOutput=reason.needed}}}const Constructor=_kernel.constructor;const argumentTypes=Constructor.getArgumentTypes(_kernel,args);const signature=Constructor.getSignature(_kernel,argumentTypes);const existingKernel=switchableKernels[signature];if(existingKernel){existingKernel.onActivate(_kernel);return existingKernel}const newKernel=switchableKernels[signature]=new Constructor(source,{argumentTypes,constantTypes:_kernel.constantTypes,graphical:_kernel.graphical,loopMaxIterations:_kernel.loopMaxIterations,constants:_kernel.constants,dynamicOutput:_kernel.dynamicOutput,dynamicArgument:_kernel.dynamicArguments,context:_kernel.context,canvas:_kernel.canvas,output:newOutput||_kernel.output,precision:_kernel.precision,pipeline:_kernel.pipeline,immutable:_kernel.immutable,optimizeFloatMemory:_kernel.optimizeFloatMemory,fixIntegerDivisionAccuracy:_kernel.fixIntegerDivisionAccuracy,functions:_kernel.functions,nativeFunctions:_kernel.nativeFunctions,injectedNative:_kernel.injectedNative,subKernels:_kernel.subKernels,strictIntegers:_kernel.strictIntegers,debug:_kernel.debug,gpu:_kernel.gpu,validate,returnType:_kernel.returnType,tactic:_kernel.tactic,onRequestFallback,onRequestSwitchKernel,texture:_kernel.texture,mappedTextures:_kernel.mappedTextures,drawBuffersMap:_kernel.drawBuffersMap});newKernel.build.apply(newKernel,args);kernelRun.replaceKernel(newKernel);kernels.push(newKernel);return newKernel}const mergedSettings=Object.assign({context:this.context,canvas:this.canvas,functions:this.functions,nativeFunctions:this.nativeFunctions,injectedNative:this.injectedNative,gpu:this,validate,onRequestFallback,onRequestSwitchKernel},settingsCopy);const kernel=new this.Kernel(source,mergedSettings);const kernelRun=kernelRunShortcut(kernel);if(!this.canvas){this.canvas=kernel.canvas}if(!this.context){this.context=kernel.context}kernels.push(kernel);return kernelRun}createKernelMap(){let fn;let settings;const argument2Type=typeof arguments[arguments.length-2];if(argument2Type==="function"||argument2Type==="string"){fn=arguments[arguments.length-2];settings=arguments[arguments.length-1]}else{fn=arguments[arguments.length-1]}if(this.mode!=="dev"){if(!this.Kernel.isSupported||!this.Kernel.features.kernelMap){if(this.mode&&kernelTypes.indexOf(this.mode)<0){throw new Error(`kernelMap not supported on ${this.Kernel.name}`)}}}const settingsCopy=upgradeDeprecatedCreateKernelSettings(settings);if(settings&&typeof settings.argumentTypes==="object"){settingsCopy.argumentTypes=Object.keys(settings.argumentTypes).map(argumentName=>settings.argumentTypes[argumentName])}if(Array.isArray(arguments[0])){settingsCopy.subKernels=[];const functions=arguments[0];for(let i=0;i0){throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.')}this.nativeFunctions.push(Object.assign({name:name2,source},settings));return this}injectNative(source){this.injectedNative=source;return this}destroy(){return new Promise((resolve,reject)=>{if(!this.kernels){resolve()}setTimeout(()=>{try{for(let i=0;i{try{accept(run.apply(this,arguments))}catch(e){reject(e)}})};shortcut.replaceKernel=function(replacementKernel){kernel=replacementKernel;bindKernelToShortcut(kernel,shortcut)};bindKernelToShortcut(kernel,shortcut);return shortcut}function bindKernelToShortcut(kernel,shortcut){if(shortcut.kernel){shortcut.kernel=kernel;return}const properties=utils.allPropertiesOf(kernel);for(let i=0;ishortcut.kernel[property]);shortcut.__defineSetter__(property,value2=>{shortcut.kernel[property]=value2})}}shortcut.kernel=kernel}module3.exports={kernelRunShortcut}},{"./utils":114}],112:[function(require2,module3,exports3){const source=`// https://www.shadertoy.com/view/4t2SDh - //note: uniformly distributed, normalized rand, [0,1] - highp float randomSeedShift = 1.0; - highp float slide = 1.0; - uniform highp float randomSeed1; - uniform highp float randomSeed2; - - highp float nrand(highp vec2 n) { - highp float result = fract(sin(dot((n.xy + 1.0) * vec2(randomSeed1 * slide, randomSeed2 * randomSeedShift), vec2(12.9898, 78.233))) * 43758.5453); - randomSeedShift = result; - if (randomSeedShift > 0.5) { - slide += 0.00009; - } else { - slide += 0.0009; - } - return result; - }`;const name2="math-random-uniformly-distributed";const functionMatch=`Math.random()`;const functionReplace=`nrand(vTexCoord)`;const functionReturnType="Number";const onBeforeRun=kernel=>{kernel.setUniform1f("randomSeed1",Math.random());kernel.setUniform1f("randomSeed2",Math.random())};const plugin={name:name2,onBeforeRun,functionMatch,functionReplace,functionReturnType,source};module3.exports=plugin},{}],113:[function(require2,module3,exports3){class Texture{constructor(settings){const{texture,size,dimensions,output,context,type="NumberTexture",kernel,internalFormat,textureFormat}=settings;if(!output)throw new Error('settings property "output" required.');if(!context)throw new Error('settings property "context" required.');if(!texture)throw new Error('settings property "texture" required.');if(!kernel)throw new Error('settings property "kernel" required.');this.texture=texture;if(texture._refs){texture._refs++}else{texture._refs=1}this.size=size;this.dimensions=dimensions;this.output=output;this.context=context;this.kernel=kernel;this.type=type;this._deleted=false;this.internalFormat=internalFormat;this.textureFormat=textureFormat}toArray(){throw new Error(`Not implemented on ${this.constructor.name}`)}clone(){throw new Error(`Not implemented on ${this.constructor.name}`)}delete(){throw new Error(`Not implemented on ${this.constructor.name}`)}clear(){throw new Error(`Not implemented on ${this.constructor.name}`)}}module3.exports={Texture}},{}],114:[function(require2,module3,exports3){const acorn=require2("acorn");const{Input}=require2("./input");const{Texture}=require2("./texture");const FUNCTION_NAME=/function ([^(]*)/;const STRIP_COMMENTS=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;const ARGUMENT_NAMES=/([^\s,]+)/g;const utils={systemEndianness(){return _systemEndianness},getSystemEndianness(){const b=new ArrayBuffer(4);const a=new Uint32Array(b);const c=new Uint8Array(b);a[0]=3735928559;if(c[0]===239)return"LE";if(c[0]===222)return"BE";throw new Error("unknown endianness")},isFunction(funcObj){return typeof funcObj==="function"},isFunctionString(fn){if(typeof fn==="string"){return fn.slice(0,"function".length).toLowerCase()==="function"}return false},getFunctionNameFromString(funcStr){const result=FUNCTION_NAME.exec(funcStr);if(!result||result.length===0)return null;return result[1].trim()},getFunctionBodyFromString(funcStr){return funcStr.substring(funcStr.indexOf("{")+1,funcStr.lastIndexOf("}"))},getArgumentNamesFromString(fn){const fnStr=fn.replace(STRIP_COMMENTS,"");let result=fnStr.slice(fnStr.indexOf("(")+1,fnStr.indexOf(")")).match(ARGUMENT_NAMES);if(result===null){result=[]}return result},clone(obj){if(obj===null||typeof obj!=="object"||obj.hasOwnProperty("isActiveClone"))return obj;const temp=obj.constructor();for(let key in obj){if(Object.prototype.hasOwnProperty.call(obj,key)){obj.isActiveClone=null;temp[key]=utils.clone(obj[key]);delete obj.isActiveClone}}return temp},isArray(array){return!isNaN(array.length)},getVariableType(value2,strictIntegers){if(utils.isArray(value2)){if(value2.length>0&&value2[0].nodeName==="IMG"){return"HTMLImageArray"}return"Array"}switch(value2.constructor){case Boolean:return"Boolean";case Number:if(strictIntegers&&Number.isInteger(value2)){return"Integer"}return"Float";case Texture:return value2.type;case Input:return"Input"}switch(value2.nodeName){case"IMG":return"HTMLImage";case"CANVAS":return"HTMLImage";case"VIDEO":return"HTMLVideo"}if(value2.hasOwnProperty("type")){return value2.type}return"Unknown"},getKernelTextureSize(settings,dimensions){let[w,h,d]=dimensions;let texelCount=(w||1)*(h||1)*(d||1);if(settings.optimizeFloatMemory&&settings.precision==="single"){w=texelCount=Math.ceil(texelCount/4)}if(h>1&&w*h===texelCount){return new Int32Array([w,h])}return utils.closestSquareDimensions(texelCount)},closestSquareDimensions(length){const sqrt=Math.sqrt(length);let high=Math.ceil(sqrt);let low=Math.floor(sqrt);while(high*low0){return lines.join(";\n")+";\n"}else{return"\n"}},warnDeprecated(type,oldName,newName){if(newName){console.warn(`You are using a deprecated ${type} "${oldName}". It has been replaced with "${newName}". Fixing, but please upgrade as it will soon be removed.`)}else{console.warn(`You are using a deprecated ${type} "${oldName}". It has been removed. Fixing, but please upgrade as it will soon be removed.`)}},flipPixels:(pixels,width,height)=>{const halfHeight=height/2|0;const bytesPerRow=width*4;const temp=new Uint8ClampedArray(width*4);const result=pixels.slice(0);for(let y=0;y{return array.subarray(0,width)},erect2DPackedFloat:(array,width,height)=>{const yResults=new Array(height);for(let y=0;y{const zResults=new Array(depth);for(let z=0;z{return array.subarray(0,width)},erectMemoryOptimized2DFloat:(array,width,height)=>{const yResults=new Array(height);for(let y=0;y{const zResults=new Array(depth);for(let z=0;z{const xResults=new Float32Array(width);let i=0;for(let x2=0;x2{const yResults=new Array(height);let i=0;for(let y=0;y{const zResults=new Array(depth);let i=0;for(let z=0;z{const xResults=new Array(width);const xResultsMax=width*4;let i=0;for(let x2=0;x2{const yResults=new Array(height);const XResultsMax=width*4;for(let y=0;y{const xResultsMax=width*4;const zResults=new Array(depth);for(let z=0;z{const xResults=new Array(width);const xResultsMax=width*4;let i=0;for(let x2=0;x2{const xResultsMax=width*4;const yResults=new Array(height);for(let y=0;y{const xResultsMax=width*4;const zResults=new Array(depth);for(let z=0;z{const xResults=new Array(array);const xResultsMax=width*4;let i=0;for(let x2=0;x2{const xResultsMax=width*4;const yResults=new Array(height);for(let y=0;y{const xResultsMax=width*4;const zResults=new Array(depth);for(let z=0;z{const{findDependency,thisLookup,doNotDefine}=settings;let flattened=settings.flattened;if(!flattened){flattened=settings.flattened={}}const ast=acorn.parse(source);const functionDependencies=[];let indent=0;function flatten2(ast2){if(Array.isArray(ast2)){const results=[];for(let i=0;ir!==null);if(declarations.length<1){return""}else{return`${ast2.kind} ${declarations.join(",")}`}case"VariableDeclarator":if(ast2.init.object&&ast2.init.object.type==="ThisExpression"){const lookup=thisLookup(ast2.init.property.name,true);if(lookup){return`${ast2.id.name} = ${flatten2(ast2.init)}`}else{return null}}else{return`${ast2.id.name} = ${flatten2(ast2.init)}`}case"CallExpression":{if(ast2.callee.property.name==="subarray"){return`${flatten2(ast2.callee.object)}.${flatten2(ast2.callee.property)}(${ast2.arguments.map(value2=>flatten2(value2)).join(", ")})`}if(ast2.callee.object.name==="gl"||ast2.callee.object.name==="context"){return`${flatten2(ast2.callee.object)}.${flatten2(ast2.callee.property)}(${ast2.arguments.map(value2=>flatten2(value2)).join(", ")})`}if(ast2.callee.object.type==="ThisExpression"){functionDependencies.push(findDependency("this",ast2.callee.property.name));return`${ast2.callee.property.name}(${ast2.arguments.map(value2=>flatten2(value2)).join(", ")})`}else if(ast2.callee.object.name){const foundSource=findDependency(ast2.callee.object.name,ast2.callee.property.name);if(foundSource===null){return`${ast2.callee.object.name}.${ast2.callee.property.name}(${ast2.arguments.map(value2=>flatten2(value2)).join(", ")})`}else{functionDependencies.push(foundSource);return`${ast2.callee.property.name}(${ast2.arguments.map(value2=>flatten2(value2)).join(", ")})`}}else if(ast2.callee.object.type==="MemberExpression"){return`${flatten2(ast2.callee.object)}.${ast2.callee.property.name}(${ast2.arguments.map(value2=>flatten2(value2)).join(", ")})`}else{throw new Error("unknown ast.callee")}}case"ReturnStatement":return`return ${flatten2(ast2.argument)}`;case"BinaryExpression":return`(${flatten2(ast2.left)}${ast2.operator}${flatten2(ast2.right)})`;case"UnaryExpression":if(ast2.prefix){return`${ast2.operator} ${flatten2(ast2.argument)}`}else{return`${flatten2(ast2.argument)} ${ast2.operator}`}case"ExpressionStatement":return`${flatten2(ast2.expression)}`;case"SequenceExpression":return`(${flatten2(ast2.expressions)})`;case"ArrowFunctionExpression":return`(${ast2.params.map(flatten2).join(", ")}) => ${flatten2(ast2.body)}`;case"Literal":return ast2.raw;case"Identifier":return ast2.name;case"MemberExpression":if(ast2.object.type==="ThisExpression"){return thisLookup(ast2.property.name)}if(ast2.computed){return`${flatten2(ast2.object)}[${flatten2(ast2.property)}]`}return flatten2(ast2.object)+"."+flatten2(ast2.property);case"ThisExpression":return"this";case"NewExpression":return`new ${flatten2(ast2.callee)}(${ast2.arguments.map(value2=>flatten2(value2)).join(", ")})`;case"ForStatement":return`for (${flatten2(ast2.init)};${flatten2(ast2.test)};${flatten2(ast2.update)}) ${flatten2(ast2.body)}`;case"AssignmentExpression":return`${flatten2(ast2.left)}${ast2.operator}${flatten2(ast2.right)}`;case"UpdateExpression":return`${flatten2(ast2.argument)}${ast2.operator}`;case"IfStatement":return`if (${flatten2(ast2.test)}) ${flatten2(ast2.consequent)}`;case"ThrowStatement":return`throw ${flatten2(ast2.argument)}`;case"ObjectPattern":return ast2.properties.map(flatten2).join(", ");case"ArrayPattern":return ast2.elements.map(flatten2).join(", ");case"DebuggerStatement":return"debugger;";case"ConditionalExpression":return`${flatten2(ast2.test)}?${flatten2(ast2.consequent)}:${flatten2(ast2.alternate)}`;case"Property":if(ast2.kind==="init"){return flatten2(ast2.key)}}throw new Error(`unhandled ast.type of ${ast2.type}`)}const result=flatten2(ast);if(functionDependencies.length>0){const flattenedFunctionDependencies=[];for(let i=0;i{if(ast.type!=="VariableDeclaration")throw new Error('Ast is not of type "VariableDeclaration"');const normalizedDeclarations=[];for(let declarationIndex=0;declarationIndex{const rKernel=gpu.createKernel(function(a){const pixel=a[this.thread.y][this.thread.x];return pixel.r*255},{output:[image.width,image.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}});const gKernel=gpu.createKernel(function(a){const pixel=a[this.thread.y][this.thread.x];return pixel.g*255},{output:[image.width,image.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}});const bKernel=gpu.createKernel(function(a){const pixel=a[this.thread.y][this.thread.x];return pixel.b*255},{output:[image.width,image.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}});const aKernel=gpu.createKernel(function(a){const pixel=a[this.thread.y][this.thread.x];return pixel.a*255},{output:[image.width,image.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}});const result=[rKernel(image),gKernel(image),bKernel(image),aKernel(image)];result.rKernel=rKernel;result.gKernel=gKernel;result.bKernel=bKernel;result.aKernel=aKernel;result.gpu=gpu;return result},splitRGBAToCanvases:(gpu,rgba,width,height)=>{const visualKernelR=gpu.createKernel(function(v){const pixel=v[this.thread.y][this.thread.x];this.color(pixel.r/255,0,0,255)},{output:[width,height],graphical:true,argumentTypes:{v:"Array2D(4)"}});visualKernelR(rgba);const visualKernelG=gpu.createKernel(function(v){const pixel=v[this.thread.y][this.thread.x];this.color(0,pixel.g/255,0,255)},{output:[width,height],graphical:true,argumentTypes:{v:"Array2D(4)"}});visualKernelG(rgba);const visualKernelB=gpu.createKernel(function(v){const pixel=v[this.thread.y][this.thread.x];this.color(0,0,pixel.b/255,255)},{output:[width,height],graphical:true,argumentTypes:{v:"Array2D(4)"}});visualKernelB(rgba);const visualKernelA=gpu.createKernel(function(v){const pixel=v[this.thread.y][this.thread.x];this.color(255,255,255,pixel.a/255)},{output:[width,height],graphical:true,argumentTypes:{v:"Array2D(4)"}});visualKernelA(rgba);return[visualKernelR.canvas,visualKernelG.canvas,visualKernelB.canvas,visualKernelA.canvas]},getMinifySafeName:fn=>{try{const ast=acorn.parse(`const value = ${fn.toString()}`);const{init}=ast.body[0].declarations[0];return init.body.name||init.body.body[0].argument.name}catch(e){throw new Error("Unrecognized function type. Please use `() => yourFunctionVariableHere` or function() { return yourFunctionVariableHere; }")}},sanitizeName:function(name2){if(dollarSign.test(name2)){name2=name2.replace(dollarSign,"S_S")}if(doubleUnderscore.test(name2)){name2=name2.replace(doubleUnderscore,"U_U")}else if(singleUnderscore.test(name2)){name2=name2.replace(singleUnderscore,"u_u")}return name2}};const dollarSign=/\$/;const doubleUnderscore=/__/;const singleUnderscore=/_/;const _systemEndianness=utils.getSystemEndianness();module3.exports={utils}},{"./input":110,"./texture":113,"acorn":1}]},{},[107])(107)})}});var import_gpu_browser_min=__toESM(require_gpu_browser_min());function add(a,b){return a+b}function sub(a,b){return a-b}function mul(a,b){return a*b}function div(a,b){return a/b}function cadd(a_real,a_imag,b_real,b_imag){return[a_real+b_real,a_imag+b_imag]}function csub(a_real,a_imag,b_real,b_imag){return[a_real-b_real,a_imag-b_imag]}function cmul(a_real,a_imag,b_real,b_imag){return[a_real*b_real-a_imag*b_imag,a_real*b_imag+a_imag*b_real]}function cexp(a_real,a_imag){const er=Math.exp(a_real);return[er*Math.cos(a_imag),er*Math.sin(a_imag)]}function mag(a,b){return Math.sqrt(a*a+b*b)}function conj(imag){return 0-imag}function lof(n){const sqrt_n=Math.sqrt(n);var factor=3;while(factor<=sqrt_n){if(n%factor===0)return factor;factor+=2}}function mean(arr,len){var mean2=0;for(var i=0;ilen){j=len}var sharedi=shared*j;real=real+signal[j]*Math.cos(sharedi);imag=imag-signal[j]*Math.sin(sharedi);N+=1}return[real/N,imag/N]}function FFTlist(signals,len,freq,n,sr){var real=0;var imag=0;var _len=1/len;var shared=6.28318530718*freq*_len;var skip=1;var N=0;var factor=sr*.25;if(freq<=factor){while(freq<=factor){factor=factor*.5;skip+=1}}for(var i=0;ilen){j=len}var sharedi=shared*j;real=real+signals[j+(len-1)*n]*Math.cos(sharedi);imag=imag-signals[j+(len-1)*n]*Math.sin(sharedi);N+=1}return[real/N,imag/N]}function iDFT(fft,len,freq){var real=0;var imag=0;var _len=1/len;var shared=6.28318530718*freq*_len;for(var i=0;ilen){j=len}var sharedi=shared*j;real=real+fft[j]*Math.cos(sharedi);imag=fft[j]*Math.sin(sharedi)-imag;N+=1}return[real/N,imag/N]}function iFFTlist(signals,len,freq,n,sr){var real=0;var imag=0;var _len=1/len;var shared=6.28318530718*freq*_len;var skip=1;var N=0;var factor=sr*.25;if(freq<=factor){while(freq<=factor){factor=factor*.5;skip+=1}}for(var i=0;ilen){j=len}var sharedi=shared*j;real=real+signals[j+(len-1)*n]*Math.cos(sharedi);imag=signals[j+(len-1)*n]*Math.sin(sharedi)-imag;N+=1}return[real/N,imag/N]}function correlogramsKern(arrays,len){var k=Math.floor(this.thread.x/len)*2;var delay=this.thread.x-Math.floor(this.thread.x/len)*len;var arr1mean=mean(arrays[k],len);var arr2mean=mean(arrays[k+1],len);var arr1Est=est(arrays[k],arr1mean,len);var arr2Est2=est(arrays[k+1],arr2mean,len);var y_x=xcor(arrays[k],arr1mean,arr1Est,arrays[k+1],arr2mean,arr2Est2,len,delay);return y_x}function correlogramsPCKern(arrays,len,means,estimators){var k=Math.floor(this.thread.x/len)*2;var delay=this.thread.x-Math.floor(this.thread.x/len)*len;var arr1mean=means[k];var arr2mean=means[k+1];var arr1Est=estimators[k];var arr2Est2=estimators[k+1];var y_x=xcor(arrays[k],arr1mean,arr1Est,arrays[k+1],arr2mean,arr2Est2,len,delay);return y_x}function dftKern(signal,len,scalar){var result=DFT(signal,len,this.thread.x);return mag(result[0],result[1])*scalar}function idftKern(amplitudes,len,scalar){var result=iDFT(amplitudes,len,this.thread.x);return mag(result[0],result[1])*scalar}function fftKern(signal,len,scalar,sampleRate){var result=FFT(signal,len,this.thread.x,sampleRate);return mag(result[0],result[1])*scalar}function ifftKern(amplitudes,len,scalar,sampleRate){var result=iFFT(amplitudes,len,this.thread.x,sampleRate);return mag(result[0],result[1])*scalar}function listdft2DKern(signals,scalar){var len=this.output.x;var result=DFT(signals[this.thread.y],len,this.thread.x);return mag(result[0],result[1])*scalar}function listdft1DKern(signals,len,scalar){var result=[0,0];if(this.thread.x<=len){result=DFT(signals,len,this.thread.x)}else{var n=Math.floor(this.thread.x/len);result=DFTlist(signals,len,this.thread.x-n*len,n)}return mag(result[0],result[1])*scalar}function listfft1DKern(signals,len,scalar,sps){var result=[0,0];if(this.thread.x<=len){result=FFT(signals,len,this.thread.x,sps)}else{var n=Math.floor(this.thread.x/len);result=FFTlist(signals,len,this.thread.x-n*len,n,sps)}return mag(result[0],result[1])*scalar}function dft_windowedKern(signal,sampleRate,freqStart,freqEnd,scalar){var result=[0,0];var freq=this.thread.x/sampleRate*(freqEnd-freqStart)+freqStart;result=DFT(signal,sampleRate,freq);return mag(result[0],result[1])*scalar}function fft_windowedKern(signal,sampleRate,freqStart,freqEnd,scalar){var result=[0,0];var freq=this.thread.x/sampleRate*(freqEnd-freqStart)+freqStart;result=FFT(signal,sampleRate,freq);return mag(result[0],result[1])*scalar}function idft_windowedKern(amplitudes,sampleRate,freqStart,freqEnd,scalar){var result=[0,0];var freq=this.thread.x/sampleRate*(freqEnd-freqStart)+freqStart;result=iDFT(amplitudes,sampleRate,freq);return mag(result[0],result[1])*scalar}function ifft_windowedKern(amplitudes,sampleRate,freqStart,freqEnd,scalar){var result=[0,0];var freq=this.thread.x/sampleRate*(freqEnd-freqStart)+freqStart;result=iFFT(amplitudes,sampleRate,freq);return mag(result[0],result[1])*scalar}function listdft1D_windowedKern(signals,sampleRate,freqStart,freqEnd,scalar){var result=[0,0];if(this.thread.x=width){i++;continue}let j=-kernelRadius;while(j<=kernelRadius){if(this.thread.y+j<0||this.thread.y+j>=height){j++;continue}kernelOffset=(j+kernelRadius)*kSize+i+kernelRadius;const weights=kernel[kernelOffset];const pixel=img[this.thread.y+i][this.thread.x+j];r+=pixel.r*weights;g+=pixel.g*weights;b+=pixel.b*weights;j++}i++}this.color(r,g,b)}function multiImgConv2DKern(img,width,height,kernels,kernelLengths,nKernels){let r=0,g=0,b=0;for(var i=0;i=width){k++;continue}let j=-kernelRadius;while(j<=kernelRadius){if(this.thread.y+j<0||this.thread.y+j>=height){j++;continue}kernelOffset=(j+kernelRadius)*kSize+k+kernelRadius;const weights=kernels[i][kernelOffset];const pixel=img[this.thread.y+k][this.thread.x+j];r+=pixel.r*weights;g+=pixel.g*weights;b+=pixel.b*weights;j++}k++}}this.color(r,g,b)}function transpose2DKern(mat2){return mat2[this.thread.y][this.thread.x]}var createGpuKernels={correlogramsKern,correlogramsPCKern,dftKern,idftKern,fftKern,ifftKern,dft_windowedKern,idft_windowedKern,fft_windowedKern,ifft_windowedKern,listdft2DKern,listdft1DKern,listfft1DKern,listfft1D_windowedKern,listdft1D_windowedKern,listidft1D_windowedKern,listifft1D_windowedKern,bulkArrayMulKern,multiImgConv2DKern,ImgConv2DKern,transpose2DKern};var addGpuFunctions=[add,sub,mul,div,cadd,csub,cmul,cexp,mag,conj,lof,mean,est,mse,rms,xcor,softmax,DFT,DFTlist,iDFT,iDFTlist,FFT,iFFT,iFFTlist];function makeKrnl(gpu,f,opts={setDynamicOutput:true,setDynamicArguments:true,setPipeline:true,setImmutable:true,setGraphical:false}){const k=gpu.createKernel(f);if(opts.setDynamicOutput)k.setDynamicOutput(true);if(opts.output)k.setOutput(opts.output);if(opts.setDynamicArguments)k.setDynamicArguments(true);if(opts.setPipeline)k.setPipeline(true);if(opts.setImmutable)k.setImmutable(true);if(opts.setGraphical)k.setGraphical(true);return k}function makeCanvasKrnl(gpu,f,opts={output:[300,300],setDynamicArguments:true,setDynamicOutput:true,setPipeline:false,setImmutable:true,setGraphical:true},divId){const k=makeKrnl(gpu,f,opts);const canvas=k.canvas;if(typeof divId==="string")document.getElementById(toAppend).appendChild(canvas);else if(divId)toAppend.appendChild(canvas);else document.body.appendChild(canvas);return k}var gpuUtils=class{constructor(gpu=new GPUjs){this.gpu=gpu;this.kernels=new Map;this.kernel;this.PI=3.141592653589793;this.SQRT1_2=.7071067811865476;this.addFunctions();this.imgkernels={edgeDetection:[-1,-1,-1,-1,8,-1,-1,-1,-1],boxBlur:[1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9],sobelLeft:[1,0,-1,2,0,-2,1,0,-1],sobelRight:[-1,0,1,-2,0,2,-1,0,1],sobelTop:[1,2,1,0,0,0,-1,-2,-1],sobelBottom:[-1,2,1,0,0,0,1,2,1],identity:[0,0,0,0,1,0,0,0,0],gaussian3x3:[1,2,1,2,4,2,1,2,1],guassian7x7:[0,0,0,5,0,0,0,0,5,18,32,18,5,0,0,18,64,100,64,18,0,5,32,100,100,100,32,5,0,18,64,100,64,18,0,0,5,18,32,18,5,0,0,0,0,5,0,0,0],emboss:[-2,-1,0,-1,1,1,0,1,2],sharpen:[0,-1,0,-1,5,-1,0,-1,0]}}addFunction(func=function f(){}){this.gpu.addFunction(func)}addKernel(name2="",krnl=function foo(){},opts){let found=this.kernels.get(name2);if(!found){this.kernels.set(name2,makeKrnl(this.gpu,krnl,opts));return true}else{console.error("Kernel already exists");return false}}addCanvasKernel(name2,f,opts,divId){let found=this.kernels.get(name2);if(!found){let krnl=makeCanvasKrnl(this.gpu,f,opts,divId);this.kernels.set(name2,krnl);return krnl}else{console.error("Kernel already exists");return false}}combineKernels(name2,fs=[],ckrnl=function foo(){}){let found=this.kernels.get(name2);if(!found){fs.forEach((f,i)=>{if(typeof f==="string"){let found2=this.kernels.get(f);if(found2)fs[i]=found2;else return false}else if(typeof f==="function"){if(this.kernels.get(f.name)){}else{this.addKernel(f.name,f)}}});let krnl=this.gpu.combineKernels(...fs,ckrnl);this.kernels.set(name2,krnl);return krnl}else{console.error("Kernel already exists");return false}}callKernel(name2="",args=[]){let result;let krnl=this.kernels.get(name2);if(!krnl){console.error("Kernel not found");return false}result=krnl(...args);return result}callCanvasKernel(name2="",args=[],outputDims=[]){let result;let krnl=this.kernels.get(name2);if(!krnl){console.error("Kernel not found");return false}else{if(outputDims.length===2)krnl.setOutput(outputDims);result=krnl(...args);return result}}hasKernel(name2=""){let found=this.kernels.get(name2);if(!found){return false}else return true}addFunctions(){addGpuFunctions.forEach(f=>this.gpu.addFunction(f));this.correlograms=makeKrnl(this.gpu,createGpuKernels.correlogramsKern);this.correlogramsPC=makeKrnl(this.gpu,createGpuKernels.correlogramsPCKern);this.dft=makeKrnl(this.gpu,createGpuKernels.dftKern);this.idft=makeKrnl(this.gpu,createGpuKernels.idftKern);this.dft_windowed=makeKrnl(this.gpu,createGpuKernels.dft_windowedKern);this.idft_windowed=makeKrnl(this.gpu,createGpuKernels.idft_windowedKern);this.fft=makeKrnl(this.gpu,createGpuKernels.fftKern);this.ifft=makeKrnl(this.gpu,createGpuKernels.ifftKern);this.fft_windowed=makeKrnl(this.gpu,createGpuKernels.fft_windowedKern);this.ifft_windowed=makeKrnl(this.gpu,createGpuKernels.ifft_windowedKern);this.listdft2D=makeKrnl(this.gpu,createGpuKernels.listdft2DKern);this.listdft1D=makeKrnl(this.gpu,createGpuKernels.listdft1DKern);this.listdft1D_windowed=makeKrnl(this.gpu,createGpuKernels.listdft1D_windowedKern);this.listfft1D=makeKrnl(this.gpu,createGpuKernels.listfft1DKern);this.listfft1D_windowed=makeKrnl(this.gpu,createGpuKernels.listfft1D_windowedKern);this.listidft1D_windowed=makeKrnl(this.gpu,createGpuKernels.listidft1D_windowedKern);this.listifft1D_windowed=makeKrnl(this.gpu,createGpuKernels.listifft1D_windowedKern);this.bulkArrayMul=makeKrnl(this.gpu,createGpuKernels.bulkArrayMulKern);let kernels=[{name:"correlograms",krnl:this.correlograms},{name:"correlogramsPC",krnl:this.correlogramsPC},{name:"dft",krnl:this.dft},{name:"idft",krnl:this.idft},{name:"dft_windowed",krnl:this.idft_windowed},{name:"fft",krnl:this.fft},{name:"ifft",krnl:this.ifft},{name:"fft_windowed",krnl:this.fft_windowed},{name:"ifft_windowed",krnl:this.ifft_windowed},{name:"listdft2D",krnl:this.listdft2D},{name:"listdft1D",krnl:this.listdft1D},{name:"listdft1D_windowed",krnl:this.listdft1D_windowed},{name:"listfft1D",krnl:this.listfft1D},{name:"listfft1D_windowed",krnl:this.listfft1D_windowed},{name:"listidft1D_windowed",krnl:this.listidft1D_windowed},{name:"listifft1D_windowed",krnl:this.listifft1D_windowed},{name:"bulkArrayMul",krnl:this.bulkArrayMul}];kernels.forEach(k=>{this.kernels.set(k.name,k)});const signalBandpass=(signal,sampleRate,freqStart,freqEnd,scalar)=>{var dft2=this.fft_windowed(signal,sampleRate,freqStart,freqEnd,scalar,0);var filtered_signal=this.ifft_windowed(dft2,sampleRate,freqStart,freqEnd,scalar);return filtered_signal};const signalBandpassMulti=(signals,sampleRate,freqStart,freqEnd,scalar)=>{var dfts=this.listdft1D_windowed(signals,sampleRate,freqStart,freqEnd,scalar,new Array(Math.ceil(signals/sampleRate)).fill(0));var filtered_signals=this.listifft1D_windowed(dfts,sampleRate,freqStart,freqEnd,scalar);return filtered_signals};this.gpuCoherence=(signals,sampleRate,freqStart,freqEnd,scalar)=>{var xcors=this.correlograms(signals);var dfts=this.listfft1D_windowed(xcors,sampleRate,freqStart,freqEnd,scalar,new Array(Math.ceil(signals/sampleRate)).fill(0));var products=this.bulkArrayMul(dfts,sampleRate,5,1);return products}}gpuXCors(arrays,precompute=false,texOut=false){var outputTex;if(precompute===true){var means=[];var ests=[];arrays.forEach((arr,i2)=>{means.push(arr.reduce((prev,curr)=>curr+=prev)/arr.length);ests.push(Math.sqrt(means[i2].reduce((sum,item)=>sum+=Math.pow(item-mean1,2))))});var meansbuf=[];var estsbuf=[];var buffer=[];for(var i=0;i{signalBufferProcessed.push(...row)});var nSamplesPerChannel=signalBuffer[0].length;var sampleRate=nSamplesPerChannel/nSeconds;this.listdft1D.setOutput([signalBufferProcessed.length]);this.listdft1D.setLoopMaxIterations(nSamplesPerChannel);var outputTex=this.listdft1D(signalBufferProcessed,nSamplesPerChannel,scalar);if(texOut===false){var orderedMagsList=[];var freqDist=this.makeFrequencyDistribution(nSamplesPerChannel,sampleRate);signalBufferProcessed=outputTex.toArray();for(var i=0;i{signalBufferProcessed.push(...row)});var freqEnd_nyquist=freqEnd*2;var nSamplesPerChannel=signalBuffer[0].length;var sampleRate=nSamplesPerChannel/nSeconds;this.listdft1D_windowed.setOutput([signalBufferProcessed.length]);this.listdft1D_windowed.setLoopMaxIterations(nSamplesPerChannel);var outputTex=this.listdft1D_windowed(signalBufferProcessed,sampleRate,freqStart,freqEnd_nyquist,scalar);if(texOut===true){return outputTex}signalBufferProcessed=outputTex.toArray();outputTex.delete();var freqDist=this.bandPassWindow(freqStart,freqEnd,sampleRate);return[freqDist,this.orderBPMagnitudes(signalBufferProcessed,nSeconds,sampleRate,nSamplesPerChannel)]}gpuFFT(signalBuffer,nSeconds,scalar=1,sampleRate,texOut=false){var nSamples=signalBuffer.length;var sampleRate=nSamples/nSeconds;this.fft.setOutput([signalBuffer.length]);this.fft.setLoopMaxIterations(nSamples);var outputTex=this.fft(signalBuffer,nSamples,scalar,sampleRate);var output=null;if(texOut===false){var freqDist=this.makeFrequencyDistribution(nSamples,sampleRate);var signalBufferProcessed=outputTex.toArray();outputTex.delete();return[freqDist,this.orderMagnitudes(signalBufferProcessed)]}else{var tex=outputTex;outputTex.delete();return tex}}MultiChannelFFT(signalBuffer,nSeconds,scalar=1,texOut=false){var signalBufferProcessed=[];signalBuffer.forEach(row=>{signalBufferProcessed.push(...row)});var nSamplesPerChannel=signalBuffer[0].length;var sampleRate=nSamplesPerChannel/nSeconds;this.listfft1D.setOutput([signalBufferProcessed.length]);this.listfft1D.setLoopMaxIterations(nSamplesPerChannel);var outputTex=this.listfft1D(signalBufferProcessed,nSamplesPerChannel,scalar,sampleRate);if(texOut===false){var orderedMagsList=[];var freqDist=this.makeFrequencyDistribution(nSamplesPerChannel,sampleRate);signalBufferProcessed=outputTex.toArray();for(var i=0;i{signalBufferProcessed.push(...row)});var freqEnd_nyquist=freqEnd*2;var nSamplesPerChannel=signalBuffer[0].length;var sampleRate=nSamplesPerChannel/nSeconds;this.listfft1D_windowed.setOutput([signalBufferProcessed.length]);this.listfft1D_windowed.setLoopMaxIterations(nSamplesPerChannel);var outputTex=this.listfft1D_windowed(signalBufferProcessed,sampleRate,freqStart,freqEnd_nyquist,scalar);if(texOut===true){return outputTex}signalBufferProcessed=outputTex.toArray();outputTex.delete();var freqDist=this.bandPassWindow(freqStart,freqEnd,sampleRate);return[freqDist,this.orderBPMagnitudes(signalBufferProcessed,nSeconds,sampleRate,nSamplesPerChannel)]}orderMagnitudes(unorderedMags){return[...unorderedMags.slice(Math.ceil(unorderedMags.length*.5),unorderedMags.length),...unorderedMags.slice(0,Math.ceil(unorderedMags.length*.5))]}makeFrequencyDistribution(FFTlength,sampleRate){var N=FFTlength;var df=sampleRate/N;var freqDist=[];for(var i=-N/2;i1){magList.forEach((row,k)=>{summedMags.push([]);var _max=1/Math.max(...row);for(var i2=0;i2{s/=100;l/=100;let c=(1-Math.abs(2*l-1))*s,x2=c*(1-Math.abs(h/60%2-1)),m=l-c/2,r=0,g=0,b=0;if(0<=h&&h<60){r=c;g=x2;b=0}else if(60<=h&&h<120){r=x2;g=c;b=0}else if(120<=h&&h<180){r=0;g=c;b=x2}else if(180<=h&&h<240){r=0;g=x2;b=c}else if(240<=h&&h<300){r=x2;g=0;b=c}else if(300<=h&&h<360){r=c;g=0;b=x2}r=(r+m)*scalar;g=(g+m)*scalar;b=(b+m)*scalar;return[r,g,b]};static genSineWave=(freq=20,peakAmp=1,nSec=1,fs=512,freq2=0,peakAmp2=1)=>{var sineWave=[];var t=[];var increment=1/fs;for(var ti=0;ti{return Math.sin(this.TWO_PI*frequency*ti+tOffset)*peakAmplitude};static mean=arr=>{var sum=arr.reduce((prev,curr)=>curr+=prev);return sum/arr.length};static median=data=>{const sortedData=data.slice().sort((a,b)=>a-b);const middle=Math.floor(sortedData.length/2);if(sortedData.length%2===0){return(sortedData[middle-1]+sortedData[middle])/2}else{return sortedData[middle]}};static mode=arr=>{return arr.sort((a,b)=>arr.filter(v=>v===a).length-arr.filter(v=>v===b).length).pop()};static range=data=>{return Math.max(...data)-Math.min(...data)};static std=(arr,mean2=void 0)=>{let avg=mean2;if(!mean2)avg=this.mean(arr);let summed=0;for(let i=0;i{if(actual.length!==forecast.length)throw new Error("Input arrays of same length!");let i=actual.length;let d=new Array(actual.length);for(let j=0;j{let len=probabilities.length;let entropy=new Array(len);for(let i=0;i{let mean2=this.mean(arr);let std=this.std(arr,mean2);let z=new Array(arr.length);for(let i=0;ia+(b-mean2)**2,0)/arr.length}static coeffVariation=(arr,populationMean)=>{let mean2=this.mean(arr);let std=this.std(arr,mean2);return populationMean?std/populationMean:std/mean2};static coeffDetermination=(observed,expected)=>{const meanY=this.mean(observed);const ssTotal=observed.reduce((acc,y)=>acc+Math.pow(y-meanY,2),0);const ssResidual=observed.reduce((acc,y,i)=>acc+Math.pow(y-expected[i],2),0);return 1-ssResidual/ssTotal};static percentile=(arr,p)=>{const sortedData=arr.slice().sort((a,b)=>a-b);const index=Math.ceil(p*(sortedData.length-1));return sortedData[index]};static interquartileRange=arr=>{const sortedData=arr.slice().sort((a,b)=>a-b);const index=Math.ceil(.25*(sortedData.length-1));const index2=Math.ceil(.75*(sortedData.length-1));const q1=sortedData[index];const q3=sortedData[index2];return q3-q1};static skewness=arr=>{const n=arr.length;const meanValue=this.mean(arr);const stdDevValue=this.std(arr);const sumCubedDeviation=arr.reduce((acc,value2)=>acc+Math.pow(value2-meanValue,3),0);const skew=sumCubedDeviation/(n*Math.pow(stdDevValue,3));return skew};static kurtosis=arr=>{const n=arr.length;const meanValue=this.mean(arr);const stdDevValue=this.std(arr);const sumFourthDeviation=arr.reduce((acc,value2)=>acc+Math.pow(value2-meanValue,4),0);const kurt=sumFourthDeviation/(n*Math.pow(stdDevValue,4))-3;return kurt};static chiSquareTest=(observed,expected)=>{const chiSquared=observed.reduce((acc,obs,i)=>{const exp=expected[i];return acc+Math.pow(obs-exp,2)/exp},0);return chiSquared};static simpleLinearRegression=(xCoords,yCoords)=>{const n=xCoords.length;const sumX=xCoords.reduce((sum,x2)=>sum+x2,0);const sumY=yCoords.reduce((sum,y)=>sum+y,0);const sumXY=xCoords.reduce((sum,x2,i)=>sum+x2*yCoords[i],0);const sumX2=xCoords.reduce((sum,x2)=>sum+x2*x2,0);const slope=(n*sumXY-sumX*sumY)/(n*sumX2-sumX*sumX);const intercept=(sumY-slope*sumX)/n;return{slope,intercept}};static pad=(arr,pad=1,padValue=0)=>{if(Array.isArray(arr[0]))return pad2D(arr,pad);if(pad>0){let pads=new Array(pad).fill(padValue);arr=[...pads,...arr,...pads]}return arr};static pad2D=(array,pad,padValue=0)=>{let pads=new Array(pad).fill(padValue);const paddedArray=array.map(row=>{return[...pads,...row,...pads]});const paddedRow=new Array(array[0].length+2*pad).fill(padValue);for(let i=0;i{const firstElem=array[0];const lastElem=array[array.length-1];const startPadding=new Array(padSize).fill(firstElem);const endPadding=new Array(padSize).fill(lastElem);return startPadding.concat(array,endPadding)};static edgePad2D=(matrix,padSize)=>{const topRows=Array(padSize).fill(matrix[0]);const bottomRows=Array(padSize).fill(matrix[matrix.length-1]);const paddedMatrix=topRows.concat(matrix,bottomRows);for(let i=0;i{const nVecs=vectors.length;return vectors[0].map((v,i)=>{for(let j=1;j{const nVecs=vectors.length;return vectors[0].map((v,i)=>{for(let j=1;j{return vec.map((v,i)=>v-subvec[i])};static vecdiv=(numvec,denvec)=>{return numvec.map((v,i)=>v/denvec[i])};static vecscale=(vec,scalar)=>{return vec.map((v,i)=>v*scalar)};static vecaddScalar=(vec,scalar)=>{return vec.map((v,i)=>v+scalar)};static vecmulScalar=(vec,scalar)=>{return vec.map((v,i)=>v*scalar)};static vecsubScalar=(vec,scalar)=>{return vec.map((v,i)=>v-scalar)};static vecdivScalar=(vec,scalar)=>{return vec.map((v,i)=>v/scalar)};static dot=(vec1,vec2)=>{var dot=0;for(var i=0;i{return[vec1[1]*vec2[2]-vec1[2]*vec2[1],vec1[2]*vec2[0]-vec1[0]*vec2[2],vec1[0]*vec2[1]-vec1[1]*vec2[0]]};static sphericalToCartesian=(r,theta,phi)=>{return{x:r*Math.sin(phi)*Math.cos(theta),y:r*Math.sin(phi)*Math.sin(theta),z:r*Math.cos(phi)}};static cartesianToSpherical=(x2,y,z)=>{var r=Math.sqrt(x2*x2+y*y+z*z);var theta=Math.atan2(y,x2);var phi=Math.acos(z/r);return{r,theta,phi}};static magnitude=vec=>{var sqrd=0;vec.forEach(c=>{sqrd+=c*c});return Math.sqrt(sqrd)};static distance=(point1,point2)=>{var dsqrd=0;point1.forEach((c,i)=>{dsqrd+=(point2[i]-c)*(point2[i]-c)});return Math.sqrt(dsqrd)};static midpoint=(point1=[1,2,3],point2=[3,4,5])=>{return point1.map((c,i)=>{return(c+point2[i])*.5})};static project=(vec1,vec2)=>{const dot=this.dot(vec1,vec2);const magSqrd=this.magnitude(vec2)**2;return this.vecmulScalar(vec2,dot/magSqrd)};static angleBetween=(vec1,vec2)=>{const dotProduct=this.dot(vec1,vec2);const magProduct=this.magnitude(vec1)*this.magnitude(vec2);return Math.acos(dotProduct/magProduct)};static normalize=vec=>{var norm=0;norm=1/this.magnitude(vec);var vecn=new Array(vec.length);vec.forEach((c,i)=>{vecn[i]=c*norm});return vecn};static normalizeSeries=(arr=[],fromZero=true)=>{let max=Math.max(...arr);let min=Math.min(...arr);if(fromZero==false){max=Math.max(max,Math.abs(min));min=0}if(max-min===0){min=0;if(max===0)max=1e-13}return arr.map(v=>(v-min)/(max-min))};static quadraticFormula=(a,b,c)=>{let bbmac4=Math.sqrt(b*b-4*a*c);if(!isNaN(bbmac4))return["complex","complex"];let _a2=1/(2*a);if(bbmac4===0)return[b*_a2];let nb=-b;return[(nb+bbmac4)*_a2,(nb-bbmac4)*_a2]};static newtonsMethod1D=(foo=x2=>{return Math.pow(x2,5)+x2*x2-x2-.2},start=0,end=1,precision=.01,attempts=10)=>{let roots=[];for(let i=0;iprecision){let step=-guess/slope2;let xn12=xn+step;guess=guess2;guess2=foo(xn12);let slope2=(guess2-guess)/(xn12-xn)}let idx;let f=roots.find((root,i2)=>{if(Math.abs(xn1-root){let y=x2;return y},range=[0,1],stepx=.01)=>{let area=0;for(let i=range[0];i{let z=x2+y;return z},range=[[0,1],[0,1]],stepx=.01,stepy=stepx)=>{let volume=0;for(let i=range[0][0]+stepx;i{let w=x2+y+z;return w},range=[[0,1],[0,1],[0,1]],stepx=.01,stepy=stepx,stepz=stepx)=>{let volume=0;for(let i=range[0][0]+stepx;i{let y=x2;return y},range=[0,1],stepx=.01)=>{let length=0;let y0=func(range[0]);for(let i=range[0]+stepx;i<=range[1];i+=stepx){let yi=func(i);length+=Math.sqrt(stepx**2+(yi-y0)**2);y0=yi}return length};static pathIntegral2D=(xFunc=t=>{let x2=Math.cos(t);return x2},yFunc=t=>{let y=Math.sin(t);return y},range=[[0,1],[0,1]],stept=.01)=>{let length=0;let x0=xFunc(range[0][0]);let y0=yFunc(range[1][0]);let tMaxX=range[0][1];let tMaxY=range[1][1];let tMax=Math.max(tMaxX,tMaxY);for(let t=0;t<=tMax;t+=stept){let xi=xFunc(Math.min(t,tMaxX));let yi=yFunc(Math.min(t,tMaxY));length+=Math.sqrt((xi-x0)**2+(yi-y0)**2);x0=xi;y0=yi}return length};static pathIntegral3D=(xFunc=(u,v)=>u,yFunc=(u,v)=>v,zFunc=(u,v)=>u+v,rangeU=[0,1],rangeV=[0,1],stepU=.01,stepV=.01)=>{let area=0;for(let u=rangeU[0];u{var vec=[];point1.forEach((c,i)=>{vec.push(point2[i]-c)});return vec};static getBufferedValueByCoordinates=(vb=new Array(300).fill(1),dims=[10,10,2],coordinate=[1,2,1],cardinal=void 0)=>{let getIdx=(foundIdx=0,dimIdx=0)=>{if(dimIdx===dims.length)return foundIdx;if(dimIdx==0)foundIdx+=coordinate[dimIdx];else if(dims[dimIdx]==0)dimsAt0++;else{let reMul=(val=coordinate[dimIdx],di=dimIdx-1)=>{val*=dims[di];di--;if(di==0)return val;else return reMul(val,di)};foundIdx+=reMul(coordinate[dimIdx]+1,dimIdx-1)}dimIdx++;return getIdx(foundIdx,dimIdx)};let found=getIdx();if(cardinal){if(coordinate[coordinate.length-1]===0){let lastnonzero=0;let idx=0;while(idx!==coordinate.length-1){if(coordinate[idx]!==0)lastnonzero=idx;idx++}return vb[found-lastnonzero+cardinal]}return vb[found-dims.length+cardinal]}else{if(coordinate[coordinate.length-1]===0){let lastnonzero=0;let idx=0;while(idx!==coordinate.length-1){if(coordinate[idx]!==0)lastnonzero=idx;idx++}return vb.slice(found-lastnonzero,found+1)}return vb.slice(found-dims.length,found+1)}};static forBufferedMat=(vb=new Array(100).fill(1),dims=[10,10],asIndex=(v,i,x2,y)=>{return v+x2+y})=>{let coordinate=[];let idx=0;let recurseFor=(depth=0,nextDepth=depth+1)=>{let result=new Array(vb.length);for(let di=0;di{let result=new Array(vb.length);for(let di=0;di{console.log(`value:${v}, idx:${idx}, x:${i},y:${j}`);return v+i+j})=>{let coordinate=new Array(dimensions.length).fill(0);const iterateCoordinate=(coord,idx=0)=>{if(coord[idx]>=dimensions[idx]){coord[idx]=0;idx++;if(idx===dimensions.length)return;iterateCoordinate(coord,idx)}else coord[idx]++};let result=new Array(buffer.length);let i=0;if(typeof asIndex==="function"){while(i{result[i]=func(buffer[i],i,...coordinate);i++;iterateCoordinate(coordinate)})}}return result};static combinations=(choices=["a","b","c"],vecsize=3)=>{var result=[];if(vecsize<=0){result.push([])}else{_Math2.combinations(choices,vecsize-1).forEach(function(previousComb){choices.forEach(function(element){result.push([element].concat(previousComb))})})}return result};static generateCoordinateSpace=(upperBounds=[10,10,10],lowerBounds=[-10,-10,-10],steps=[1,1,1],mutater=void 0)=>{for(let i=0;iupperBounds[i]){let temp=upperBounds[i];upperBounds[i]=lowerBounds[i];lowerBounds[i]=temp}}let result=[];let copy=[...upperBounds];let lastindex=copy.length-1;result.push([...copy]);while(copy[0]>=lowerBounds[0]){let checkNextIndex=decrIdx2=>{if(copy[decrIdx2]<=lowerBounds[decrIdx2]){if(decrIdx2===0)return;copy[decrIdx2]=upperBounds[decrIdx2];decrIdx2--;if(decrIdx2<0)return;if(typeof steps[decrIdx2]=="function")copy[decrIdx2]-=steps[decrIdx2](copy[decrIdx2]);else copy[decrIdx2]-=steps[decrIdx2];checkNextIndex(decrIdx2)}};let decrIdx=lastindex;if(typeof steps[decrIdx]=="function")copy[decrIdx]-=steps[decrIdx](copy[decrIdx]);else copy[decrIdx]-=steps[decrIdx];result.push([...copy]);checkNextIndex(decrIdx);if(mutater)result[result.length-1]=mutater(result[result.length-1])}return result};static meshgrid=_Math2.generateCoordinateSpace;static calcVectorField=(coordinates=[[0,0],[0,1],[1,0],[1,1]],formula=(x2,y)=>{return[x2*10,y*10]})=>{return coordinates.map(vec=>formula(...vec))};static randomMatrix=(rows,cols)=>{return Array.from({length:rows},()=>Array.from({length:cols},()=>Math.random()))};static identityMatrix=size=>{return Array.from({length:size},(_,i)=>Array.from({length:size},(_2,j)=>i===j?1:0))};static diagonalMatrix=values=>{return values.map((value2,index)=>{const row=Array(values.length).fill(0);row[index]=value2;return row})};static householderMatrix=v=>{const size=v.length;const vvT=v.map(rowVal=>v.map(colVal=>rowVal*colVal));const vTv=this.normalize(v)**2;return Array.from({length:size},(_,i)=>Array.from({length:size},(_2,j)=>(i===j?1:0)-2*vvT[i][j]/vTv))};static transpose=mat=>{return mat[0].map((_,colIndex)=>mat.map(row=>row[colIndex]))};static clone=mat=>{return mat.map(row=>{if(Array.isArray(row[0]))return this.clone(row);else return[...row]})};static getColumn(matrix,col){return matrix.map(row=>row[col])}static matmul=(A,B)=>{return A.map(row=>B[0].map((_,colIndex)=>row.reduce((sum,cell,rowIndex)=>sum+cell*B[rowIndex][colIndex],0)))};static matscale=(mat,scalar)=>{return mat.map(row=>row.map(cell=>cell*scalar))};static matadd=(A,B)=>{return A.map((row,rowIndex)=>row.map((cell,colIndex)=>cell+B[rowIndex][colIndex]))};static matsub=(A,B)=>{return A.map((row,rowIndex)=>row.map((cell,colIndex)=>cell-B[rowIndex][colIndex]))};static inverse=matrix=>{const numRows=matrix.length;const numCols=matrix[0].length;if(numRows!==numCols){throw new Error("Matrix must be square to compute its inverse.")}const augmentedMatrix=matrix.map((row,rowIndex)=>{const identityRow=Array(numRows).fill(0);identityRow[rowIndex]=1;return row.concat(identityRow)});for(let pivotRow=0;pivotRowrow.slice(numCols))};static pseudoInverse=matrix=>{const numRows=matrix.length;const numCols=matrix[0].length;if(numRows>numCols){const ata=this.matmul(this.transpose(matrix),matrix);const ataInv=this.inverse(ata);return this.matmul(ataInv,this.transpose(matrix))}else{const aat=this.matmul(matrix,this.transpose(matrix));const aatInv=this.inverse(aat);return this.matmul(this.transpose(matrix),aatInv)}};static histogram=(arr=[],binSize=1,nBins=void 0)=>{let copy=[...arr];copy.sort(function(a,b){return a-b});let binStart=Math.min(...copy);if(typeof nBins==="number"){let binEnd=Math.max(...copy);binSize=Math.abs((binEnd-binStart)/(nBins-1))}let j=binStart;let binx=[];let biny=[];for(let i=0;ibinStart+binidx){j++;binidx+=binSize;let binmin=binStart+binidx;let binmid=binmin+binidx*.5;binx.push(binmid);biny.push(0)}biny[biny.length-1]++}return[binx,biny]};static normalDistribution=(samples=[],normalize=true,cutoff=1e-4)=>{let m=this.mean(samples);let vari=this.variance(samples);let nSamples=samples.length;let probabilities=[];let denom=1/(this.TWO_PI*vari);let _variance=1/vari;let sum=0;for(let i=0;ix2*_sum)}return probabilities};static expectedValue=(samples=[],probabilities=this.normalDistribution(samples))=>{return samples.reduce((sum,item,idx)=>sum+item*probabilities[idx])};static originMoment=(samples=[],probabilities=this.normalDistribution(samples),order=1)=>{return samples.reduce((sum,item,idx)=>sum+Math.pow(item,order)*probabilities[idx])};static centralMoment=(samples=[],probabilities=this.normalDistribution(samples),order=1)=>{let m=this.mean(samples);return samples.reduce((sum,item,idx)=>sum+Math.pow(item-m,order)*probabilities[idx]/samples.length)};static linearDiscriminantAnalysis=(samples=[],classifier=[])=>{let mean2=this.mean(samples);let meank=this.mean(classifier);let covariance=this.cov1d(samples,classifier);let probs=this.normalDistribution(samples);let dk=[];for(let i=0;i{const padlen=deconstructionLowPass.length;let sg=this.edgePad(signal,padlen);let approxCoeffs=this.conv1D(sg,deconstructionLowPass).slice(1+padlen,-padlen).filter((_,idx)=>idx%2===0);let detailCoeffs=this.conv1D(sg,deconstructionHighPass).slice(1+padlen,-padlen).filter((_,idx)=>idx%2===0);let results=[detailCoeffs];for(let i=0;iidx%2===0));approxCoeffs=this.conv1D(approxCoeffs,deconstructionLowPass).slice(1+padlen,-padlen).filter((_,idx)=>idx%2===0)}return[approxCoeffs].concat(results.reverse())};static idwt=(approxCoeffs=[],detailCoeffs=[],reconstructionHighPass=[],reconstructionLowPass=[])=>{if(approxCoeffs.length!==detailCoeffs.length){approxCoeffs.pop()}const _ca=this.dyadicUpsample(approxCoeffs,true);const _cd=this.dyadicUpsample(detailCoeffs,true);const halfa=this.conv1D(_ca,reconstructionLowPass);const halfb=this.conv1D(_cd,reconstructionHighPass);const sig=halfa.map((val,idx)=>val+halfb[idx]);const padlen=reconstructionLowPass.length;const lo=padlen-1;const hi=sig.length-(padlen-2);return sig.slice(lo,hi)};static dwtMaxLevel=(dataLength,waveletLength)=>{return Math.floor(Math.log2(dataLength/(waveletLength-1)))};static minMaxScaler=data=>{const min=Math.min(...data);const max=Math.max(...data);return data.map(value2=>(value2-min)/(max-min))};static garroteThreshold=(data,value2)=>{return data.map(x2=>{if(Math.abs(x2)<=value2){return 0}else{return x2-value2*value2/x2}})};static conv1D=(s,kernel)=>{const revKernel=[...kernel].reverse();const padsize=kernel.length-1;const paddedS=new Array(padsize).fill(0).concat(s).concat(new Array(padsize).fill(0));const nSteps=paddedS.length-kernel.length+1;const result=new Array(nSteps).fill(0);const nKer=kernel.length;for(let i=0;i{const rows=matrix.length;const cols=matrix[0].length;const kRows=kernel.length;const kCols=kernel[0].length;const halfKRows=Math.floor(kRows/2);const halfKCols=Math.floor(kCols/2);const output=new Array(rows).fill(0).map(()=>new Array(cols).fill(0));for(let i=0;i=0&&xi=0&&yj{if(matrix.length===0||kernel.length===0)return[];function getShape(arr){const shape=[];while(Array.isArray(arr)){shape.push(arr.length);arr=arr[0]}return shape}function convolveRecurse(mat,ker,matrixShape2,kernelShape2,matIndices=[],kerIndices=[]){const depth=matIndices.length;if(depth===matrixShape2.length){let sum=0;for(let i=0;i=0&&matIndex{const mean12=this.mean(arr1);const mean2=this.mean(arr2);return arr1.map((v,i)=>(v-mean12)*(arr2[i]-mean2))};static cov1d=(arr1,arr2)=>{this.mean(this.covVec(arr1,arr2))};static cov2d=mat=>{var mattransposed=this.transpose(mat);var matproducts=[];var rowmeans=[];var colmeans=[];mat.forEach((row,idx)=>{rowmeans.push(this.mean(row))});mattransposed.forEach((col,idx)=>{colmeans.push(this.mean(col))});mat.forEach((row,idx)=>{matproducts.push([]);for(var col=0;col{return[[this.cov1d(x2,x2),this.cov1d(x2,y),this.cov1d(x2,z)],[this.cov1d(y,x2),this.cov1d(y,y),this.cov1d(y,z)],[this.cov1d(z,x2),this.cov1d(z,y),this.cov1d(z,z)]]};static covNd=(dimensionalData=[])=>{let covariance=[];dimensionalData.forEach((arr,i)=>{covariance.push([]);dimensionalData.forEach((arr2,j)=>{covariance[i].push(this.cov1d(arr,arr2))})})};static correlationCoeff=(arr1,arr2)=>{const cov=this.cov1d(arr1,arr2);const stdDev1=this.std(arr1);const stdDev2=this.std(arr2);return cov/(stdDev1*stdDev2)};static pearsonCorrelation=(arr1,arr2)=>{let sumX=0,sumY=0,sumXY=0,sumX2=0,sumY2=0;const n=arr1.length>arr2.length?arr2.length:arr1.length;for(let i=0;i{let det=mat[0][0]*mat[1][1]-mat[0][1]*mat[1][0];let mean2=(mat[0][0]+mat[1][1])*.5;let sqrt=Math.sqrt(mean2*mean2-det);let eig1=mean2+sqrt;let eig2=mean2-sqrt;return[eig1,eig2]};static eigenvectors2x2=(mat=[[1,2],[3,4]],eigens=[1,2])=>{let v1=[-mat[0][1],mat[0][0]-eigens[0]];if(v1[0]===0&&v1[1]===0){v1[0]=mat[1][1]-eigens[0];v1[1]=-mat[1][0]}let v2=[-mat[0][1],mat[0][0]-eigens[1]];if(v2[0]===0&&v2[1]===0){v2[0]=mat[1][1]-eigens[1];v2[1]=-mat[1][0]}return[v1,v2]};static fastpca2d=(xarr,yarr)=>{let covMat=this.cov2d(xarr,yarr);let eigs=this.eigens2x2(covMat);if(eigs[1]>eigs[0])eigs.reverse();let evs=this.eigenvectors2x2(covMat,eigs);return[eigs,evs]};static centerData=data=>{const mean2=data.reduce((sum,val)=>sum+val,0)/data.length;return data.map(v=>v-mean2)};static crosscorrelation=(signalA,signalB,posOnly=false)=>{const N=signalA.length;const M=signalB.length;const result=[];const normFactor=1/Math.sqrt(signalA.reduce((acc,val)=>acc+val*val,0)*signalB.reduce((acc,val)=>acc+val*val,0));if(posOnly){result.length=signalA.length;for(let lag=0;lag=0&&m{const lags=[];const timeResolution=samplingRate?1/samplingRate:0;const center=centered?correlogram.length/2:null;const len=correlogram.length-1;for(let i=1;icorrelogram[i-1]&&correlogram[i]>correlogram[i+1]){let lag={offset:centered?i-center:i,value:correlogram[i]};if(timeResolution)lag.offset*=timeResolution;lags.push(lag)}}if(getMax)return lags.reduce((maxObj,currentObj)=>{return currentObj.value>maxObj.value?currentObj:maxObj},lags[0]);else return lags};static autocorrelation=arr1=>{var delaybuf=[...arr1,...Array(arr1.length).fill(0)];var mean12=this.mean(arr1);var arr1Est=arr1.reduce((sum,item)=>sum+=Math.pow(item-mean12,2));arr1Est=Math.sqrt(Math.abs(arr1Est));let denom=arr1Est*arr2Est;if(denom===0)denom=1e-26;var _arr1estsqrd=1/denom;var correlations=new Array(arr1.length).fill(0);for(var delay=0;delaysum+=(item-mean12)*(delaybuf[delay+i]-mean12));correlations[delay]=r*_arr1estsqrd}return correlations};static autocorrelation2d=mat2d2=>{let result=[];for(let y=0;y{let result=[];for(let y=0;y{let result=[];for(let y=0;y{let result=[];for(let y=0;y{var correlograms=[];dat.forEach((row1,i)=>{dat.forEach((row2,j)=>{if(j>=i){correlograms.push(_Math2.crosscorrelation(row1,row2))}})});return correlograms};static dft=(sineWave=[],sampleRate=250,frequencyResolution=.25)=>{const N=sineWave.length;const NyquistLimit=Math.floor(sampleRate/2);const totalFreqs=Math.floor(NyquistLimit/frequencyResolution);const Npadded=Math.ceil(sampleRate/frequencyResolution);const TWOPI=2*3.141592653589793;const real=new Array(Npadded).fill(0);const imag=new Array(Npadded).fill(0);const amplitudes=new Array(Npadded);const zerosToAdd=Npadded-N;if(zerosToAdd<0){throw new Error("Desired resolution is not achievable with current sample size.")}const paddedSineWave=zerosToAdd?[...sineWave,...Array(zerosToAdd).fill(0)]:sineWave;let orderedFrequencies;if(totalFreqs%2===0){orderedFrequencies=[...new Array(totalFreqs).fill(0).map((x2,i)=>-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs).fill(0).map((x2,i)=>i*frequencyResolution)]}else{orderedFrequencies=[...new Array(totalFreqs).fill(0).map((x2,i)=>-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs+1).fill(0).map((x2,i)=>i*frequencyResolution)]}for(let k=0;k-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs).fill(0).map((x2,i)=>(i+1)*frequencyResolution)]}else{orderedMagnitudes=[...amplitudes.slice(totalFreqs,2*totalFreqs),...amplitudes.slice(0,totalFreqs+1)];orderedFrequencies=[...new Array(totalFreqs).fill(0).map((x2,i)=>-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs+1).fill(0).map((x2,i)=>i*frequencyResolution)]}return{real,imag,freqs:orderedFrequencies,amplitudes:orderedMagnitudes}};static eulerTransform=(dataSeries=[],timeTransform=(j,dataSeries2,real,imag,magnitudes)=>{return dataSeries2[j]},stepTransform=(k,j,length,real,imag,magnitudes)=>{return 2*Math.PI*k*j/length},kN=dataSeries.length)=>{var real=[];var imag=[];var magnitudes=[];for(var k=0;k{var smaArr=[];for(var i=0;icurrent+=previous)/(i+1))}else{var arrslice=arr.slice(i-window2,i);smaArr.push(arrslice.reduce((previous,current)=>current+=previous)/window2)}}return smaArr};static sum=(arr=[])=>{if(arr.length>0){var sum=arr.reduce((prev,curr)=>curr+=prev);return sum}else{return 0}};static reduceArrByFactor=(arr,factor=2)=>{let x2=arr.filter((element,index)=>{return index%factor===0});return x2};static makeArr=(startValue,stopValue,nSteps)=>{var arr=[];var step=(stopValue-startValue)/(nSteps-1);for(var i=0;i{if(array?.length===0)return array;let max=Math.max(...array);let min=Math.min(...array);let _lines=1/stackedLines;let scalar;if(centerZero){let absmax=Math.max(Math.abs(min),Math.abs(max));scalar=_lines/absmax;return array.map(y=>y*scalar+(_lines*(stackPosition+1)*2-1-_lines))}else{scalar=_lines/(max-min);return array.map(y=>2*((y-min)*scalar-1/(2*stackedLines))+(_lines*(stackPosition+1)*2-1-_lines))}};static absmax=array=>{return Math.max(Math.abs(Math.min(...array)),Math.max(...array))};static downsample=(array,fitCount,scalar=1)=>{if(array.length>fitCount){let output=new Array(fitCount);let incr=array.length/fitCount;let lastIdx=array.length-1;let last=0;let counter=0;for(let i=incr;ilastIdx)rounded=lastIdx;for(let j=last;j{var linearInterpolate=function(before2,after2,atPoint2){return(before2+(after2-before2)*atPoint2)*scalar};var newData=new Array;var springFactor=(array.length-1)/(fitCount-1);newData[0]=array[0];for(var i=1;i{const start=even?1:0;const out=new Array(a.length*2).fill(0);for(let i=0;i{if(array.length===fitCount)return array;if(array.length>fitCount){return this.downsample(array,fitCount,scalar)}else{return this.upsample(array,fitCount,scalar)}};static lerp=(v0,v1,t)=>{return(1-t)*v0+t*v1};static linspace=(start,end,num,floor=false)=>{const arr=new Array(num);const step=(end-start)/(num-1);for(let i=0;i{let ref=[...arr];if(ref.length%2===0)ref.pop();if(arr.length>1){let pass=true;for(let i=0;i=ref[Math.floor(ref.length*.5)]){pass=false;break}else if(i>Math.floor(ref.length*.5)&&val>=ref[Math.floor(ref.length*.5)]){pass=false;break}}else if(critical==="valley"){if(iMath.floor(ref.length*.5)&&val<=ref[Math.floor(ref.length*.5)]){pass=false;break}}else{if(iMath.floor(ref.length*.5)&&val<=ref[Math.floor(ref.length*.5)]){pass=false;break}}}if(critical!=="peak"&&critical!=="valley"&&pass===false){pass=true;for(let i=0;i=ref[Math.floor(ref.length*.5)]){pass=false;break}else if(i>Math.floor(ref.length*.5)&&val>=ref[Math.floor(ref.length*.5)]){pass=false;break}}}return pass}else return void 0};static isCriticalPoint=(arr,critical="peak")=>{let ref=[...arr];if(ref.length%2===0)ref.pop();if(arr.length>1){let pass=true;for(let i=0;iref.length*.5&&val>0){pass=false;break}}else if(critical==="valley"){if(i=0){pass=false;break}else if(i>ref.length*.5&&val<0){pass=false;break}}else{if(i=0){pass=false;break}else if(i>ref.length*.5&&val<0){pass=false;break}}}if(critical!=="peak"&&critical!=="valley"&&pass===false){pass=true;for(let i=0;iref.length*.5&&val>0){pass=false;break}}}return pass}else return void 0};static peakDetect=(smoothedArray,type="peak",window2=49)=>{let mid=Math.floor(window2*.5);let peaks=[];for(let i=0;i{let threshold;let filtered=arr.filter((o,i)=>{if(peakIndices.indexOf(i)>-1)return true});if(thresholdVar===0){threshold=this.mean(filtered)}else threshold=(thresholdVar+this.mean(filtered))*.5;return threshold};static column=(mat,x2)=>{let col=new Array(mat.length).fill(0).map(()=>new Array(1).fill(0));for(let i=0;i{let v_new=[];for(let i=0;i{let sum=0;for(let i=0;i{let len=Math.sqrt(this.matmul(this.transpose(eigenvector),eigenvector));let U=this.matscale(eigenvector,1/len);let delta=this.matscale(this.matmul(U,this.transpose(U)),eigenvalue);let M_new=this.matsub(mat,delta);return M_new};static eigenvalue_of_vector=(mat,eigenvector)=>{ev=this.matmul(this.matmul(this.transpose(eigenvector),mat),eigenvector);return ev};static power_iteration=(A,numIter=100)=>{let b=Array(A.length).fill(1);for(let i=0;i{let eigenvalues=[];let eigenvectors=[];for(let i=0;i{if(A[0].length>A.length){A=this.transpose(A)}const m=A.length;const n=A[0].length;const prec=Number.EPSILON;const tolerance=1e-64/prec;const itmax=50;const leftSingularVectors=this.clone(A);const offDiagonalValues=Array(n).fill(0);const singularValues=Array(n).fill(0);const rightSingularVectors=Array.from({length:n},()=>Array(n).fill(0));function pythag(a,b){if(a===0||b===0)return a+b;const absA=Math.abs(a),absB=Math.abs(b);if(absA>absB){const t=absB/absA;return absA*Math.sqrt(1+t*t)}else{const t=absA/absB;return absB*Math.sqrt(1+t*t)}}let scaleFactorF=0;let scaleFactorG=0;let scaleFactorH=0;let maxMagnitude=0;let intermediateY=0;let intermediateZ=0;let sumValue=0;let cosineTheta=0;let limitIndex=0;for(let i=0;i=0)scaleFactorG=-scaleFactorG;scaleFactorH=scaleFactorF*scaleFactorG-sumValue;leftSingularVectors[i][i]=scaleFactorF-scaleFactorG;for(let j=limitIndex;j=0)scaleFactorG=-scaleFactorG;scaleFactorH=scaleFactorF*scaleFactorG-sumValue;leftSingularVectors[i][i+1]=scaleFactorF-scaleFactorG;for(let j=limitIndex;jmaxMagnitude)maxMagnitude=intermediateY}for(let i=n-1;i>=0;i--){if(scaleFactorG!==0){scaleFactorH=scaleFactorG*leftSingularVectors[i][i+1];for(let j=limitIndex;j=0;i--){limitIndex=i+1;scaleFactorG=singularValues[i];for(let j=limitIndex;j=0;k--){for(let iteration=0;iteration=0;limitIndex--){if(Math.abs(offDiagonalValues[limitIndex])<=eps){testConvergence=true;break}if(Math.abs(singularValues[limitIndex-1])<=eps)break}if(!testConvergence){cosineTheta=0;sumValue=1;const l1=limitIndex-1;for(let i=limitIndex;i=itmax-1)throw new Error("No convergence.");maxMagnitude=singularValues[limitIndex];intermediateY=singularValues[k-1];scaleFactorG=offDiagonalValues[k-1];scaleFactorH=offDiagonalValues[k];scaleFactorF=((intermediateY-intermediateZ)*(intermediateY+intermediateZ)+(scaleFactorG-scaleFactorH)*(scaleFactorG+scaleFactorH))/(2*scaleFactorH*intermediateY);scaleFactorG=pythag(scaleFactorF,1);if(scaleFactorF<0)scaleFactorF=((maxMagnitude-intermediateZ)*(maxMagnitude+intermediateZ)+scaleFactorH*(intermediateY/(scaleFactorF-scaleFactorG)-scaleFactorH))/maxMagnitude;else scaleFactorF=((maxMagnitude-intermediateZ)*(maxMagnitude+intermediateZ)+scaleFactorH*(intermediateY/(scaleFactorF+scaleFactorG)-scaleFactorH))/maxMagnitude;cosineTheta=1;sumValue=1;for(let i=limitIndex+1;i=0;j--){if(singularValues[j]row.slice());for(let k=0;k0?-this.normalize(x2):this.normalize(x2);const u=this.vecsub(x2,e);const normU=this.normalize(u);const v=u.map(val=>val/normU);const Qk=this.householderMatrix(v);const QkFull=this.identityMatrix(numRows);for(let row=k;row{const numRowsOriginal=matrixA.length;const numColsOriginal=matrixA[0].length;if(!numComponents){numComponents=Math.min(numRowsOriginal,numColsOriginal)}let matrixACopy=[...matrixA.map(row=>[...row])];if(numRowsOriginal>numColsOriginal){matrixA=this.matmul(this.transpose(matrixA),matrixA)}else if(numRowsOriginalsum+row.reduce((rowSum,val)=>rowSum+val*val,0),0);previousMatrixQ=matrixQ;if(errorMath.sqrt(row[row.indexOf(Math.max(...row))]));let leftVectors,rightVectors;if(numRowsOriginalval*val)}else{rightVectors=this.transpose(matrixQ);leftVectors=this.matmul(this.matmul(matrixACopy,rightVectors),this.inverse(this.diagonalMatrix(singularValues)))}return{U:leftVectors,S:singularValues,V:rightVectors}};static pca=(mat,tolerance=1e-5)=>{let dims=mat.length;let t=new Array(dims);let p=new Array(dims);let mat_t=this.transpose(mat);t[0]=this.column(mat,0);let epsilon=1;let iter=0;while(espilon>tolerance){iter++;p[0]=this.matmul(mat_t,t[0]);let tp=this.matmul(this.transpose(t[0]),t[0]);p[0]=this.matscale(p[0],1/tp);let p_length=Math.sqrt(this.matmul(this.transpose(p[0]),p[0]));p[0]=this.matscale(p[0],1/p_length);let t_new=this.matmul(mat,p[0]);let pp=this.matmul(this.transpose(p[0]),p[0]);t_new=this.matscale(t_new,1/pp);epsilon=this.squared_difference(t[0],t_new);t[0]=JSON.parse(JSON.stringify(t_new))}let components=this.matmul(this.transpose(t[0]),t[0]);return components};static circularBuffer=(arr,newEntries)=>{if(Array.isArray(newEntries)){if(newEntries.lengtharr.length){let len=arr.length;arr.splice(0,len,newEntries.slice(len-newEntries.length))}else{arr.splice(0,arr.length,...newEntries)}}else{arr.push(newEntries);arr.shift()}return arr};static reshape=(arr,shape)=>{const totalSize=shape.reduce((acc,val)=>acc*val,1);const flatArr=this.flatten(arr);if(flatArr.length!==totalSize){throw new Error("The given shape is incompatible with the array size.")}function buildArray(shape2,flatData){const dim=shape2[0];if(shape2.length===1){return flatData.splice(0,dim)}let result=[];for(let i=0;i{if(!Array.isArray(arr)){return[arr]}return arr.reduce((acc,val)=>acc.concat(flatten(val)),[])};static p300=(event_timestamps=[],raw_signal=[],signal_timestamps=[],sps=256)=>{let smoothingstep=Math.floor(sps/10);let smoothed=this.sma(raw_signal,smoothingstep);let peaks=this.peakDetect(smoothed,"peak",smoothingstep);let mean2=this.mean(smoothed);let std=this.std(smoothed,mean2);let p_idx=0;let candidates=[];if(peaks.length>0){event_timestamps.forEach((t,j)=>{while(signal_timestamps[peaks[p_idx]]1){let peakvals=[];tempcandidates.forEach(tc=>{peakvals.push(smoothed[peaks[tc]])});let max=Math.max(...peakvals);let maxi=tempcandidates[peakvals.indexOf(max)];candidates.push({event_timestamp:t,event_index:j,peak_timestamp:signal_timestamps[[peaks[maxi]]],signal_index:[peaks[maxi]],signal_amplitude:raw_signal[[peaks[maxi]]],zscore:(smoothed[peaks[maxi]]-mean2)/std})}else if(tempcandidates.length===1)candidates.push({event_timestamp:t,event_index:j,peak_timestamp:signal_timestamps[peaks[tempcandidates[0]]],signal_index:peaks[tempcandidates[0]],signal_amplitude:raw_signal[[peaks[tempcandidates[0]]]],zscore:(smoothed[peaks[tempcandidates[0]]]-mean2)/std})})}return candidates};static dec_lo=[-.07576571478927333,-.02963552764599851,.49761866763201545,.8037387518059161,.29785779560527736,-.09921954357684722,-.012603967262037833,.0322231006040427];static dec_hi=[-.0322231006040427,-.012603967262037833,.09921954357684722,.29785779560527736,-.8037387518059161,.49761866763201545,.02963552764599851,-.07576571478927333];static rec_lo=[.0322231006040427,-.012603967262037833,-.09921954357684722,.29785779560527736,.8037387518059161,.49761866763201545,-.02963552764599851,-.07576571478927333];static rec_hi=[-.07576571478927333,.02963552764599851,.49761866763201545,-.8037387518059161,.29785779560527736,.09921954357684722,-.012603967262037833,-.0322231006040427];static waveletFiltering=(signal=[],wavelets={dec_hi:this.dec_hi,dec_lo:this.dec_lo,rec_hi:this.rec_hi,rec_lo:this.rec_lo})=>{let maxlevel=this.dwtMaxLevel(signal.length,wavelets.dec_lo.length);let decomposed=this.decompose(signal,maxlevel,wavelets.dec_hi,wavelets.dec_lo);for(let i=2;i{let startindex=methodString.indexOf("=>")+1;if(startindex<=0){startindex=methodString.indexOf("){")}if(startindex<=0){startindex=methodString.indexOf(") {")}return methodString.slice(0,methodString.indexOf("{",startindex)+1)};function parseFunctionFromText(method=""){let getFunctionBody=methodString=>{return methodString.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i,"$2$3$4")};let newFuncHead=getFunctionHead(method);let newFuncBody=getFunctionBody(method);let newFunc;if(newFuncHead.includes("function")){let varName=newFuncHead.substring(newFuncHead.indexOf("(")+1,newFuncHead.lastIndexOf(")"));newFunc=new Function(varName,newFuncBody)}else{if(newFuncHead.substring(0,6)===newFuncBody.substring(0,6)){let varName=newFuncHead.substring(newFuncHead.indexOf("(")+1,newFuncHead.lastIndexOf(")"));newFunc=new Function(varName,newFuncBody.substring(newFuncBody.indexOf("{")+1,newFuncBody.length-1))}else{try{newFunc=(0,eval)(method)}catch{}}}return newFunc}var stringifyWithCircularRefs=function(){const refs=new Map;const parents=[];const path=["this"];function clear(){refs.clear();parents.length=0;path.length=1}function updateParents(key,value2){var idx=parents.length-1;var prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value2||idx===0){path.push(key);parents.push(value2.pushed)}else{while(idx-->=0){prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value2){idx+=2;parents.length=idx;path.length=idx;--idx;parents[idx]=value2;path[idx]=key;break}}idx--}}}}function checkCircular(key,value2){if(value2!=null){if(typeof value2==="object"){if(key){updateParents(key,value2)}let other=refs.get(value2);if(other){return"[Circular Reference]"+other}else{refs.set(value2,path.join("."))}}}return value2}return function stringifyWithCircularRefs2(obj,space){try{parents.push(obj);return JSON.stringify(obj,checkCircular,space)}finally{clear()}}}();if(JSON.stringifyWithCircularRefs===void 0){JSON.stringifyWithCircularRefs=stringifyWithCircularRefs}var stringifyWithFunctionsAndCircularRefs=function(){const refs=new Map;const parents=[];const path=["this"];function clear(){refs.clear();parents.length=0;path.length=1}function updateParents(key,value2){var idx=parents.length-1;var prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value2||idx===0){path.push(key);parents.push(value2.pushed)}else{while(idx-->=0){prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value2){idx+=2;parents.length=idx;path.length=idx;--idx;parents[idx]=value2;path[idx]=key;break}}idx--}}}}function checkCircular(key,value2){if(value2!=null){if(typeof value2==="object"){if(key){updateParents(key,value2)}let other=refs.get(value2);if(other){return"[Circular Reference]"+other}else{refs.set(typeof value2==="function"?value2.toString():value2,path.join("."))}}}return typeof value2==="function"?value2.toString():value2}return function stringifyWithFunctionsAndCircularRefs2(obj,space){try{parents.push(obj);return JSON.stringify(obj,checkCircular,space)}finally{clear()}}}();if(JSON.stringifyWithFunctionsAndCircularRefs===void 0){JSON.stringifyWithFunctionsAndCircularRefs=stringifyWithFunctionsAndCircularRefs}var stringifyFast=function(){const refs=new Map;const parents=[];const path=["this"];function clear(){refs.clear();parents.length=0;path.length=1}function updateParents(key,value2){var idx=parents.length-1;if(parents[idx]){var prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value2||idx===0){path.push(key);parents.push(value2.pushed)}else{while(idx-->=0){prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value2){idx+=2;parents.length=idx;path.length=idx;--idx;parents[idx]=value2;path[idx]=key;break}}idx++}}}}}function checkValues(key,value2){let val;if(value2!=null){if(typeof value2==="object"){let c=value2.constructor.name;if(key&&c==="Object"){updateParents(key,value2)}let other=refs.get(value2);if(other){return"[Circular Reference]"+other}else{refs.set(value2,path.join("."))}if(c==="Array"){if(value2.length>20){val=value2.slice(value2.length-20)}else val=value2}else if(c.includes("Set")){val=Array.from(value2)}else if(c!=="Object"&&c!=="Number"&&c!=="String"&&c!=="Boolean"){val="instanceof_"+c}else if(c==="Object"){let obj={};for(const prop in value2){if(value2[prop]==null){obj[prop]=value2[prop]}else if(Array.isArray(value2[prop])){if(value2[prop].length>20)obj[prop]=value2[prop].slice(value2[prop].length-20);else obj[prop]=value2[prop]}else if(value2[prop].constructor.name==="Object"){obj[prop]={};for(const p in value2[prop]){if(Array.isArray(value2[prop][p])){if(value2[prop][p].length>20)obj[prop][p]=value2[prop][p].slice(value2[prop][p].length-20);else obj[prop][p]=value2[prop][p]}else{if(value2[prop][p]!=null){let con=value2[prop][p].constructor.name;if(con.includes("Set")){obj[prop][p]=Array.from(value2[prop][p])}else if(con!=="Number"&&con!=="String"&&con!=="Boolean"){obj[prop][p]="instanceof_"+con}else{obj[prop][p]=value2[prop][p]}}else{obj[prop][p]=value2[prop][p]}}}}else{let con=value2[prop].constructor.name;if(con.includes("Set")){obj[prop]=Array.from(value2[prop])}else if(con!=="Number"&&con!=="String"&&con!=="Boolean"){obj[prop]="instanceof_"+con}else{obj[prop]=value2[prop]}}}val=obj}else{val=value2}}else{val=value2}}return val}return function stringifyFast2(obj,space){parents.push(obj);let res=JSON.stringify(obj,checkValues,space);clear();return res}}();if(JSON.stringifyFast===void 0){JSON.stringifyFast=stringifyFast}var GPUService=class extends Service{gpu=new gpuUtils;constructor(options){super(options);this.load(this)}addFunc=fn=>{if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function")this.gpu.addFunction(fn)};addKernel=(name2,fn,options)=>{if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function")this.gpu.addKernel(name2,fn,options)};combineKernels=(name2,fs,ckrnl)=>{for(let i=0;i{this.gpu.callKernel(name2,args)};dft=(signalBuffer,nSeconds,scalar)=>{if(scalar==void 0)scalar=1;return this.gpu.gpuDFT(signalBuffer,nSeconds,scalar)};multidft=(signalBuffer,nSeconds,scalar)=>{if(scalar==void 0)scalar=1;return this.gpu.MultiChannelDFT(signalBuffer,nSeconds,scalar)};multidftbandpass=(buffered,nSeconds,freqStart,freqEnd,scalar)=>{if(scalar==void 0)scalar=1;return this.gpu.MultiChannelDFT_Bandpass(buffered,nSeconds,freqStart,freqEnd,scalar)};coherence=(buffered,nSeconds,freqStart,freqEnd)=>{const correlograms=Math2.correlograms(buffered);const buffer=[...buffered,...correlograms];var dfts;var scalar=1;dfts=this.gpu.MultiChannelDFT_Bandpass(buffer,nSeconds,freqStart,freqEnd,scalar);const cordfts=dfts[1].splice(buffered.length,buffer.length-buffered.length);const coherenceResults=[];const nChannels=buffered.length;var k=0;var l=0;cordfts.forEach((row,i)=>{if(l+k===nChannels){var temp=cordfts.splice(i,1);k++;cordfts.splice(k,0,...temp);l=0}l++});var autoFFTproducts=[];k=0;l=1;cordfts.forEach((dft2,i)=>{var newdft=new Array(dft2.length).fill(0);if(i{newdft[j]=amp});autoFFTproducts.push(newdft)}else{dft2.forEach((amp,j)=>{let denom=autoFFTproducts[k][j]*autoFFTproducts[k+l][j];if(denom!==0)newdft[j]=amp*amp/denom;else newdft[j]=0;if(newdft[j]>1){newdft[j]=1}});l++;if(l+k===nChannels){k++;l=1}coherenceResults.push(newdft)}});return[dfts[0],dfts[1],coherenceResults]}};if(!globalThis.gpu)globalThis.gpu=new GPUService;var dft={sps:250,nSec:1,freqStart:0,freqEnd:125,watch:["0","1","2","3"],blocking:false,__operator:function(arraybuffer){let results=globalThis.gpu.multidftbandpass(arraybuffer,this.nSec,this.freqStart,this.freqEnd,1);let dft2={};this.watch.forEach((tag,i)=>{dft2[tag]=results[1][i]});return{frequencies:results[0],dft:dft2}}};if(!globalThis.gpu)globalThis.gpu=new GPUService;var coherence={sps:250,nSec:1,freqStart:0,freqEnd:125,tags:["0","1","2","3"],coherenceTags:[],__onconnected:function(node){node.tags.forEach((tag,i)=>{if(i!==node.tags.length-1){for(let j=i+1;j{dft2[tag]=results[1][i]});let coherence2={};this.coherenceTags.forEach((tag,i)=>{coherence2[tag]=results[2][i]});return{timestamp:ts,frequencies:results[0],dft:dft2,coherence:coherence2}}};var gpualgorithms={dft,coherence};export{GPUService,gpualgorithms}; -/*! Bundled license information: - -gpujsutils/dist/index.esm.js: - (** - * gpu.js - * http://gpu.rocks/ - * - * GPU Accelerated JavaScript - * - * @version 2.11.0 - * @date Tue Jan 05 2021 15:55:59 GMT-0500 (Eastern Standard Time) - * - * @license MIT - * The MIT License - * - * Copyright (c) 2021 gpu.js Team - *) -*/ diff --git a/src/extras/dist/index.gpu.services.js b/src/extras/dist/index.gpu.services.js deleted file mode 100644 index 90bf9273..00000000 --- a/src/extras/dist/index.gpu.services.js +++ /dev/null @@ -1,1300 +0,0 @@ -(()=>{var __require=(x2=>typeof require!=="undefined"?require:typeof Proxy!=="undefined"?new Proxy(x2,{get:(a,b)=>(typeof require!=="undefined"?require:a)[b]}):x2)(function(x2){if(typeof require!=="undefined")return require.apply(this,arguments);throw Error('Dynamic require of "'+x2+'" is not supported')});var EventHandler=class{data={};triggers={};ctr=0;constructor(data){if(typeof data==="object")this.data=data}setState=updateObj=>{Object.assign(this.data,updateObj);let props=Object.getOwnPropertyNames(updateObj);for(const prop of props){this.triggerEvent(prop,this.data[prop])}if(this.triggers[statesubKey]){let run=fn=>{fn(updateObj)};const l=this.triggers[statesubKey].length;for(let i=l-1;i>=0;i--){run(this.triggers[statesubKey][i].onchange)}}return this.data};setValue=(key,value2)=>{this.data[key]=value2;this.triggerEvent(key,value2)};triggerEvent=(key,value2)=>{if(this.triggers[key]){let fn=obj=>{obj.onchange(value2)};const l=this.triggers[key].length;for(let i=l-1;i>=0;i--){fn(this.triggers[key][i])}}};subscribeState=onchange=>{return this.subscribeEvent(statesubKey,onchange)};unsubscribeState=sub2=>{return this.unsubscribeEvent(statesubKey,sub2)};subscribeEvent=(key,onchange,refObject,refKey)=>{if(key){if(refObject&&refKey&&!this.triggers[key]){Object.defineProperty(this.data,key,{get:()=>{return refObject[refKey]},set:value2=>{refObject[refKey]=value2},enumerable:true,configurable:true})}if(!this.triggers[key]){this.triggers[key]=[]}let l=this.ctr;this.ctr++;this.triggers[key].push({sub:l,onchange});return l}else return void 0};unsubscribeEvent=(key,sub2)=>{let triggers=this.triggers[key];if(triggers){if(sub2===void 0){delete this.triggers[key];delete this.data[key]}else{let idx=void 0;let obj=triggers.find((o,i)=>{if(o.sub===sub2){idx=i;return true}});if(obj)triggers.splice(idx,1);if(Object.keys(triggers).length===0){delete this.triggers[key];delete this.data[key]}if(this.onRemoved)this.onRemoved(obj);return true}}};subscribeEventOnce=(key,onchange)=>{let sub2;let changed=value2=>{onchange(value2);this.unsubscribeEvent(key,sub2)};sub2=this.subscribeEvent(key,changed);return sub2};getEvent=(key,sub2)=>{if(typeof sub2!=="number")return this.triggers[key];for(const s in this.triggers[key]){if(this.triggers[key][s].sub===sub2)return this.triggers[key][s]}};getSnapshot=()=>{const snapshot={};for(const key in this.data){snapshot[key]=this.data[key]}};onRemoved};var statesubKey="*s";var state=new EventHandler;var Callable=class extends Function{__bound;__call;constructor(){super("return this.__bound.__call.apply(this.__bound, arguments)");this.__bound=this.bind(this);return this.__bound}};var GraphNode=class _GraphNode{__node={tag:`node${Math.floor(Math.random()*1e15)}`,unique:`${Math.floor(Math.random()*1e15)}`,state};__children;__parent;__operator;__listeners;__props;__args;constructor(properties,parent,graph){this.__setProperties(properties,parent,graph);if(typeof properties==="function"||properties?.__callable){const callableInstance=new Callable;callableInstance.__call=(...args)=>this.__operator(...args);const proxy=new Proxy(callableInstance,{get:(target,prop,receiver)=>{if(Reflect.has(this,prop)){return Reflect.get(this,prop,receiver)}return Reflect.get(target,prop,receiver)},set:(target,prop,value2,receiver)=>{if(Reflect.has(this,prop)){return Reflect.set(this,prop,value2,receiver)}return Reflect.set(target,prop,value2,receiver)}});Object.setPrototypeOf(proxy,this);return proxy}}get __graph(){return this.__node?.graph}set __graph(graph){this.__node.graph=graph}__setProperties=(properties,parent,graph)=>{let enforceProperties=()=>{let orig=properties;if(typeof properties==="function"){if(isNativeClass(properties)){properties=new properties}else properties={__operator:properties,__node:{forward:true,tag:properties.name}}}else if(typeof properties==="string"){if(graph?.get(properties)){properties=graph.get(properties)}}if(!("__node"in properties))properties.__node={};if(!properties.__node.initial)properties.__node.initial=orig};enforceProperties();if(typeof properties==="object"){let assignState=()=>{if(properties.__node?.state)this.__node.state=properties.__node.state;else if(graph){properties.__node.state=graph.__node.state}};let setProps=()=>{if(properties.__props){if(typeof properties.__props==="function")properties.__props=new properties.__props;if(typeof properties.__props==="object"){this.__proxyObject(properties.__props)}}};let setTag=()=>{if(!properties.__node.tag){if(properties.__operator?.name)properties.__node.tag=properties.__operator.name;else properties.__node.tag=`node${Math.floor(Math.random()*1e15)}`}};let setNode=()=>{if(typeof properties.__node==="string"){if(graph?.get(properties.__node.tag)){properties=graph.get(properties.__node.tag)}else properties.__node={}}else if(!properties.__node)properties.__node={};if(graph){properties.__node.graph=graph}if(properties instanceof Graph)properties.__node.source=properties};let setParent=()=>{if(!properties.__parent&&parent)properties.__parent=parent;if(parent?.__node&&!(parent instanceof Graph||properties instanceof Graph))properties.__node.tag=parent.__node.tag+"."+properties.__node.tag;if(parent instanceof Graph&&properties instanceof Graph){if(properties.__node.loaders)Object.assign(parent.__node.loaders?parent.__node.loaders:{},properties.__node.loaders);if(parent.__node.mapGraphs){properties.__node.nodes.forEach(n=>{parent.set(properties.__node.tag+"."+n.__node.tag,n)});let ondelete=()=>{properties.__node.nodes.forEach(n=>{parent.__node.nodes.delete(properties.__node.tag+"."+n.__node.tag)})};this.__addOndisconnected(ondelete)}}};let setOp=()=>{if(typeof properties.default==="function"&&!properties.__operator){properties.__operator=properties.default}if(properties.__operator){if(typeof properties.__operator==="string"){if(graph){let n=graph.get(properties.__operator);if(n)properties.__operator=n.__operator;if(!properties.__node.tag&&properties.__operator.name)properties.__node.tag=properties.__operator.name}}if(typeof properties.__operator==="function")properties.__operator=this.__setOperator(properties.__operator);if(properties.default)properties.default=properties.__operator}};let assignProps=()=>{properties.__node=Object.assign(this.__node,properties.__node);let keys=Object.getOwnPropertyNames(properties).filter(v=>{if(!objProps[v])return true});for(const key of keys){if(key in properties&&key!=="name")this[key]=properties[key]}};let bindCallbacks=()=>{if(this.__onconnected){if(typeof this.__onconnected==="function"){this.__onconnected=this.__onconnected.bind(this)}else if(Array.isArray(this.__onconnected)){this.__onconnected=this.__onconnected.map(f=>{return f.bind(this)})}if(typeof this.__ondisconnected==="function"){this.__ondisconnected=this.__ondisconnected.bind(this)}else if(Array.isArray(this.__ondisconnected)){this.__ondisconnected=this.__ondisconnected.map(f=>{return f.bind(this)})}}};assignState();setTag();setProps();setNode();setParent();assignProps();bindCallbacks();setOp()}};__subscribe=(callback,key,subInput,target,tkey,args,callbackStr)=>{const subscribeToFunction=(k,setTarget=(callback2,target2)=>target2?target2:callback2,triggerCallback=callback)=>{let wrappedArgs;if(args){let wrapped=wrapArgs(triggerCallback,args,this.__node.graph);triggerCallback=wrapped.__callback;wrappedArgs=wrapped.__args}let sub2=this.__node.state.subscribeEvent(k,triggerCallback,this,key);let trigger=this.__node.state.getEvent(k,sub2);if(!this.__listeners)this.__listeners={};this.__listeners[k]=this.__node.state.triggers[k];if(!trigger)return sub2;trigger.source=this.__node.tag;if(key)trigger.key=key;trigger.target=setTarget(callback,target);if(tkey)trigger.tkey=tkey;if(subInput)trigger.subInput=subInput;if(args){trigger.arguments=wrappedArgs;trigger.__args=args}if(callbackStr)trigger.__callback=callbackStr;trigger.node=this;trigger.graph=this.__node.graph;return sub2};const getCallbackFromGraph=callback2=>{let fn=this.__node.graph.get(callback2);if(!fn&&callback2.includes(".")){target=callback2.substring(0,callback2.lastIndexOf("."));let n=this.__node.graph.get(callback2.substring(0,target));tkey=callback2.lastIndexOf(".")+1;if(n&&typeof n[key]==="function")callback2=(...args2)=>{return n[tkey](...args2)}}else if(fn.__operator){callback2=fn.__operator;tkey="__operator"}return callback2};if(key){if(!this.__node.localState||!this.__node.localState[key]){this.__addLocalState(this,key)}if(typeof callback==="string"){callbackStr=this.__node.tag+"."+callback;tkey=callback;if(target){if(this.__node.graph?.get(target)){let n=this.__node.graph?.get(target);if(typeof n[callback]==="function"){let fn=n[callback];callback=(...inp)=>{fn(...inp)}}else{let k2=callback;let setter=inp=>{n[k2]=inp};callback=setter}}}else if(typeof this[callback]==="function"){let fn=this[callback];callback=(...inp)=>{fn(...inp)}}else if(this.__node.graph?.get(callback))callback=getCallbackFromGraph(callback);if(typeof callback!=="function")return void 0}let sub2;let k=subInput?this.__node.unique+"."+key+"input":this.__node.unique+"."+key;if(typeof callback==="function"&&!callback?.__node)sub2=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2,callback);else if(callback?.__node)sub2=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2.__node.unique,(...inp)=>{if(callback.__operator)callback.__operator(...inp)});return sub2}else{if(typeof callback==="string"){callbackStr=callback;if(!target)target=callback;if(this.__node.graph.get(callback))callback=this.__node.graph.get(callback);tkey="__operator";if(typeof callback!=="object")return void 0}let sub2;let k=subInput?this.__node.unique+"input":this.__node.unique;if(typeof callback==="function"&&!callback?.__node)sub2=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2,callback);else if(callback?.__node){sub2=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2.__node.unique,(...inp)=>{if(callback.__operator)callback.__operator(...inp)})}return sub2}};__unsubscribe=(sub2,key,unsubInput)=>{if(key){return this.__node.state.unsubscribeEvent(unsubInput?this.__node.unique+"."+key+"input":this.__node.unique+"."+key,sub2)}else return this.__node.state.unsubscribeEvent(unsubInput?this.__node.unique+"input":this.__node.unique,sub2)};__setOperator=fn=>{fn=fn.bind(this);if(this.__args&&this.__node.graph){fn=wrapArgs(fn,this.__args,this.__node.graph).__callback}let inpstr=`${this.__node.unique}input`;this.__operator=(...args)=>{if(this.__node.state.triggers[inpstr])this.__node.state.setValue(inpstr,args);let result=fn(...args);if(this.__node.state.triggers[this.__node.unique]){if(typeof result?.then==="function"){result.then(res=>{if(res!==void 0)this.__node.state.setValue(this.__node.unique,res)}).catch(console.error)}else if(result!==void 0)this.__node.state.setValue(this.__node.unique,result)}return result};if(this.__parent instanceof _GraphNode&&!this.__subscribedToParent){if(this.__parent.__operator){let sub2=this.__parent.__subscribe(this);let ondelete=()=>{this.__parent?.__unsubscribe(sub2);delete this.__subscribedToParent};this.__addOndisconnected(ondelete);this.__subscribedToParent=true}}return this.__operator};__addLocalState=(props,key)=>{if(!props)return;if(!this.__node.localState){this.__node.localState={}}const localState=this.__node.localState;const initState=(props2,k)=>{let str=this.__node.unique+"."+k;let inpstr=`${str}input`;let get,set;let obj,descriptor;if(typeof props2[k]==="function"&&k!=="__operator"){if(this.__props?.[k]){obj=this.__props}else{obj=localState}get=()=>{return obj[k]};set=fn=>{if(!this.__props?.[k])fn=fn.bind(this);obj[k]=(...args)=>{if(this.__node.state.triggers[inpstr])this.__node.state.setValue(inpstr,args);let result=fn(...args);if(this.__node.state.triggers[str]){if(typeof result?.then==="function"){result.then(res=>{this.__node.state.triggerEvent(str,res)}).catch(console.error)}else this.__node.state.triggerEvent(str,result)}return result}};localState[k]=props2[k].bind(this);descriptor={get,set,enumerable:true,configurable:true}}else if(k!=="__graph"){let get2,set2;let obj2;if(this.__props?.[k]){obj2=this.__props}else{obj2=localState}get2=()=>{return obj2[k]};set2=v=>{obj2[k]=v;if(this.__node.state.triggers[str])this.__node.state.triggerEvent(str,v)};localState[k]=props2[k];descriptor={get:get2,set:set2,enumerable:true,configurable:true}}Object.defineProperty(props2,k,descriptor);if(typeof this.__node.initial==="object"){let dec=Object.getOwnPropertyDescriptor(this.__node.initial,k);if(dec===void 0||dec?.configurable){Object.defineProperty(this.__node.initial,k,descriptor)}}};if(key)initState(props,key);else{for(let k in props){initState(props,k)}}};__proxyObject=obj=>{const allProps=getAllProperties(obj);for(const k of allProps){const descriptor={get:()=>{return obj[k]},set:value2=>{obj[k]=value2},enumerable:true,configurable:true};Object.defineProperty(this,k,descriptor);if(typeof this.__node.initial==="object"){let dec=Object.getOwnPropertyDescriptor(this.__node.initial,k);if(dec===void 0||dec?.configurable){Object.defineProperty(this.__node.initial,k,descriptor)}}}};__addOnconnected(callback){callback=callback.bind(this);if(Array.isArray(this.__onconnected)){this.__onconnected.push(callback)}else if(typeof this.__onconnected==="function"){this.__onconnected=[callback,this.__onconnected]}else this.__onconnected=callback}__addOndisconnected(callback){callback=callback.bind(this);if(Array.isArray(this.__ondisconnected)){this.__ondisconnected.push(callback)}else if(typeof this.__ondisconnected==="function"){this.__ondisconnected=[callback,this.__ondisconnected]}else this.__ondisconnected=callback}__callConnected(node=this){if(typeof this.__onconnected==="function"){this.__onconnected(this)}else if(Array.isArray(this.__onconnected)){let fn=o=>{o(this)};this.__onconnected.forEach(fn)}}__callDisconnected(node=this){if(typeof this.__ondisconnected==="function")this.__ondisconnected(this);else if(Array.isArray(this.__ondisconnected)){let fn=o=>{o(this)};this.__ondisconnected.forEach(fn)}}};var Graph=class _Graph{__node={tag:`graph${Math.floor(Math.random()*1e15)}`,unique:`${Math.random()}`,nodes:new Map,state,roots:{}};constructor(options){this.init(options)}init=options=>{if(options){let cpy=Object.assign({},options);delete cpy.roots;recursivelyAssign(this.__node,cpy);if(options.roots)this.load(options.roots)}};load=(roots,overwrite=false)=>{function recursivelyAssignChildren(target,obj,inChildren=true,top=true){if(top){if(!target)target={};for(const key in obj){if(!key.startsWith("__")&&obj[key]&&typeof obj[key]==="object"){target[key]=obj[key];if(obj[key]?.__children){recursivelyAssignChildren({},obj[key].__children,false,false)}}else if(typeof obj[key]==="function")target[key]=obj[key]}recursivelyAssignChildren(target,obj,true,false)}else{if(obj?.__children&&!inChildren){if(obj.__children?.constructor.name==="Object"){if(target.__children?.constructor.name==="Object")target.__children=recursivelyAssignChildren(target.__children,obj.__children,true,false);else target.__children=recursivelyAssignChildren({},obj.__children,true,false)}else{target.__children=obj.__children}}else if(inChildren){for(const key in obj){if(!key.startsWith("__")&&obj[key]&&typeof obj[key]==="object"){target[key]=Object.assign({},obj[key]);if(obj[key]?.__children){target[key].__children=recursivelyAssignChildren({},obj[key].__children,false,false)}}else if(typeof obj[key]==="function")target[key]=obj[key]}}}return target}this.__node.roots=recursivelyAssignChildren(this.__node.roots?this.__node.roots:{},roots);let cpy=Object.assign({},roots);if(cpy.__node)delete cpy.__node;let listeners=this.recursiveSet(cpy,this,void 0,roots,overwrite);if(roots.__node){if(!roots.__node.tag)roots.__node._tag=`roots${Math.floor(Math.random()*1e15)}`;else if(!this.get(roots.__node.tag)){let node=new GraphNode(roots,this,this);this.set(node.__node.tag,node);this.runLoaders(node,this,roots,roots.__node.tag);if(node.__listeners){listeners[node.__node.tag]=node.__listeners}}}else if(roots.__listeners){this.setListeners(roots.__listeners)}this.setListeners(listeners);return cpy};setLoaders=(loaders2,replace)=>{if(replace)this.__node.loaders=loaders2;else Object.assign(this.__node.loaders,loaders2);return this.__node.loaders};runLoaders=(node,parent,properties,key)=>{for(const l in this.__node.loaders){if(typeof this.__node.loaders[l]==="object"){if(this.__node.loaders[l].init)this.__node.loaders[l](node,parent,this,this.__node.roots,properties,key);if(this.__node.loaders[l].connected)node.__addOnconnected(this.__node.loaders[l].connect);if(this.__node.loaders[l].disconnected)node.__addOndisconnected(this.__node.loaders[l].disconnect)}else if(typeof this.__node.loaders[l]==="function")this.__node.loaders[l](node,parent,this,this.__node.roots,properties,key)}};add=(properties,parent,overwrite=true)=>{let listeners={};if(typeof parent==="string")parent=this.get(parent);let instanced;if(typeof properties==="function"){if(isNativeClass(properties)){if(properties.prototype instanceof GraphNode){properties=properties.prototype.constructor(properties,parent,this);instanced=true}else properties=new properties}else properties={__operator:properties,__callable:true}}else if(typeof properties==="string"){properties=this.__node.roots[properties]}if(!properties)return;if(!instanced){let keys=Object.getOwnPropertyNames(properties);let nonArrowFunctions=Object.getOwnPropertyNames(Object.getPrototypeOf(properties));keys.push(...nonArrowFunctions);keys=keys.filter(v=>!objProps.includes(v));let cpy={};for(const key of keys){cpy[key]=properties[key]}properties=cpy}if(!properties.__node)properties.__node={};properties.__node.initial=properties;if(typeof properties==="object"&&this.get(properties.__node.tag)){if(overwrite)this.remove(properties.__node.tag,true);else return}else if(properties.__node.tag&&this.get(properties.__node.tag))return this.get(properties.__node.tag);let node;let root=recursivelyAssign({},properties,2);if(instanced)node=properties;else node=new GraphNode(properties,parent,this);this.set(node.__node.tag,node);this.runLoaders(node,parent,properties,node.__node.tag);this.__node.roots[node.__node.tag]=root;if(node.__children){node.__children=Object.assign({},node.__children);this.recursiveSet(node.__children,node,listeners,node.__children)}if(node.__listeners){listeners[node.__node.tag]=Object.assign({},node.__listeners);for(const key in node.__listeners){let listener=node.__listeners[key];if(node[key]){delete listeners[node.__node.tag][key];listeners[node.__node.tag][node.__node.tag+"."+key]=listener}if(typeof listener==="string"){if(node.__children?.[listener]){listeners[node.__node.tag][key]=node.__node.tag+"."+listener}else if(parent instanceof GraphNode&&(parent.__node.tag===listener||parent.__node.tag.includes(".")&&parent.__node.tag.split(".").pop()===listener)){listeners[node.__node.tag][key]=parent.__node.tag}}}}this.setListeners(listeners);node.__callConnected();return node};recursiveSet=(originCpy,parent,listeners={},origin,overwrite=false)=>{let keys=Object.getOwnPropertyNames(origin).filter(v=>!objProps.includes(v));let nonArrowFunctions=Object.getOwnPropertyNames(Object.getPrototypeOf(origin)).filter(v=>!objProps.includes(v));keys.push(...nonArrowFunctions);for(const key of keys){if(key.includes("__"))continue;let p=origin[key];if(Array.isArray(p))continue;let instanced;if(typeof p==="function"){if(isNativeClass(p)){p=new p;if(p instanceof GraphNode){p=p.prototype.constructor(p,parent,this);instanced=true}}else p={__operator:p,__callable:true}}else if(typeof p==="string"){if(this.__node.nodes.get(p))p=this.__node.nodes.get(p);else p=this.__node.roots[p]}else if(typeof p==="boolean"){if(this.__node.nodes.get(key))p=this.__node.nodes.get(key);else p=this.__node.roots[key]}if(p&&typeof p==="object"){if(!instanced&&!(p instanceof GraphNode)){let ks=Object.getOwnPropertyNames(p).filter(v=>!objProps.includes(v));let nonArrowFunctions2=Object.getOwnPropertyNames(Object.getPrototypeOf(p)).filter(v=>!objProps.includes(v));nonArrowFunctions2.splice(nonArrowFunctions2.indexOf("constructor"),1);ks.push(...nonArrowFunctions2);let cpy={};for(const key2 of ks){cpy[key2]=p[key2]}p=cpy}if(!p.__node)p.__node={};if(!p.__node.tag)p.__node.tag=key;if(!p.__node.initial)p.__node.initial=originCpy[key];if(overwrite&&this.get(p.__node.tag)){this.remove(p.__node.tag,true)}else if(this.get(p.__node.tag)&&!(!(parent instanceof _Graph)&&parent?.__node)||parent?.__node&&this.get(parent.__node.tag+"."+p.__node.tag))continue;let node;let newnode=false;let root=recursivelyAssign({},p,2);if(instanced||p instanceof GraphNode){node=p}else{node=new GraphNode(p,parent,this);newnode=true}if(!newnode&&p instanceof GraphNode&&!instanced&&parent instanceof GraphNode){let sub2=this.subscribe(parent.__node.tag,node.__node.tag);let ondelete=node2=>{this.unsubscribe(parent.__node.tag,sub2)};node.__addOndisconnected(ondelete)}else if(node){this.set(node.__node.tag,node);this.runLoaders(node,parent,originCpy[key],key);originCpy[key]=node;this.__node.roots[node.__node.tag]=root;if(node.__children){node.__children=Object.assign({},node.__children);this.recursiveSet(node.__children,node,listeners,node.__children)}if(node.__listeners){listeners[node.__node.tag]=Object.assign({},node.__listeners);for(const key2 in node.__listeners){let listener=node.__listeners[key2];let k=key2;if(node[key2]){delete listeners[node.__node.tag][key2];k=node.__node.tag+"."+key2;listeners[node.__node.tag][k]=listener}if(typeof listener==="string"){if(node.__children?.[listener]){listeners[node.__node.tag][k]=node.__node.tag+"."+listener}else if(parent instanceof GraphNode&&(parent.__node.tag===listener||parent.__node.tag.includes(".")&&parent.__node.tag.split(".").pop()===listener)){listeners[node.__node.tag][k]=parent.__node.tag}}}}node.__callConnected()}}}return listeners};remove=(node,clearListeners=true)=>{this.unsubscribe(node);if(typeof node==="string")node=this.get(node);if(node instanceof GraphNode){this.delete(node.__node.tag);delete this.__node.roots[node.__node.tag];if(clearListeners){this.clearListeners(node)}node.__callDisconnected();const recursiveRemove=t=>{for(const key in t){this.unsubscribe(t[key]);this.delete(t[key].__node.tag);delete this.__node.roots[t[key].__node.tag];this.delete(key);delete this.__node.roots[key];t[key].__node.tag=t[key].__node.tag.substring(t[key].__node.tag.lastIndexOf(".")+1);if(clearListeners){this.clearListeners(t[key])}t[key].__callDisconnected();if(t[key].__children){recursiveRemove(t[key].__children)}}};if(node.__children){recursiveRemove(node.__children)}}if(node?.__node.tag&&node?.__parent){delete node?.__parent;node.__node.tag=node.__node.tag.substring(node.__node.tag.indexOf(".")+1)}if(node?.__node.graph)node.__node.graph=void 0;return node};run=(node,...args)=>{if(typeof node==="string"){let nd=this.get(node);if(!nd&&node.includes(".")){nd=this.get(node.substring(0,node.lastIndexOf(".")));if(typeof nd?.[node.substring(node.lastIndexOf(".")+1)]==="function")return nd[node.substring(node.lastIndexOf(".")+1)](...args)}else if(nd?.__operator)return nd.__operator(...args)}if(node?.__operator){return node?.__operator(...args)}};setListeners=listeners=>{for(const key in listeners){let node=this.get(key);if(typeof listeners[key]==="object"){for(const k in listeners[key]){let n=this.get(k);let sub2;if(typeof listeners[key][k]!=="object")listeners[key][k]={__callback:listeners[key][k]};else if(!listeners[key][k].__callback){for(const kk in listeners[key][k]){if(typeof listeners[key][k][kk]!=="object"){listeners[key][k][kk]={__callback:listeners[key][k][kk]};if(node.__operator&&(listeners[key][k][kk].__callback===true||typeof listeners[key][k][kk].__callback==="undefined"))listeners[key][k][kk].__callback=node.__operator}let nn=this.get(kk);if(!nn){let tag=k.substring(0,k.lastIndexOf("."));nn=this.get(tag);if(nn){let prop=k.substring(k.lastIndexOf(".")+1);sub2=this.subscribe(nn,listeners[key][k][kk].__callback,listeners[key][k][kk].__args,prop,listeners[key][k][kk].subInput,key)}}else{sub2=this.subscribe(nn,listeners[key][k][kk].__callback,listeners[key][k][kk].__args,void 0,listeners[key][k][kk].subInput,key)}}}if("__callback"in listeners[key][k]){if(node){if(listeners[key][k].__callback===true||typeof listeners[key][k].__callback==="undefined")listeners[key][k].__callback=node.__operator;if(typeof listeners[key][k].__callback==="function")listeners[key][k].__callback=listeners[key][k].__callback.bind(node)}if(!n){let tag=k.substring(0,k.lastIndexOf("."));n=this.get(tag);if(n){sub2=this.subscribe(n,listeners[key][k].__callback,listeners[key][k].__args,k.substring(k.lastIndexOf(".")+1),listeners[key][k].subInput,key)}}else{sub2=this.subscribe(n,listeners[key][k].__callback,listeners[key][k].__args,void 0,listeners[key][k].subInput,key)}}}}}};clearListeners=(node,listener)=>{if(typeof node==="string")node=this.get(node);if(node?.__listeners){for(const key in node.__listeners){if(listener&&key!==listener)continue;if(typeof node.__listeners[key]?.sub!=="number")continue;let n=this.get(key);if(!n){n=this.get(key.substring(0,key.lastIndexOf(".")));if(n){if(typeof node.__listeners[key]==="object"&&!node.__listeners[key]?.__callback){for(const k in node.__listeners[key]){if(typeof node.__listeners[key][k]?.sub==="number"){this.unsubscribe(n,node.__listeners[key][k].sub,key.substring(key.lastIndexOf(".")+1),node.__listeners[key][k].subInput);node.__listeners[key][k].sub=void 0}}}else if(typeof node.__listeners[key]?.sub==="number"){this.unsubscribe(n,node.__listeners[key].sub,key.substring(key.lastIndexOf(".")+1),node.__listeners[key].subInput);node.__listeners[key].sub=void 0}}}else{if(typeof!node.__listeners[key]?.__callback==="number"){for(const k in node.__listeners[key]){if(node.__listeners[key][k]?.sub){this.unsubscribe(n,node.__listeners[key][k].sub,void 0,node.__listeners[key][k].subInput);node.__listeners[key][k].sub=void 0}}}else if(typeof node.__listeners[key]?.sub==="number"){this.unsubscribe(n,node.__listeners[key].sub,void 0,node.__listeners[key].subInput);node.__listeners[key].sub=void 0}}}}};get=tag=>{return this.__node.nodes.get(tag)};getByUnique=unique=>{return Array.from(this.__node.nodes.values()).find(node=>{if(node.__node.unique===unique)return true})};set=(tag,node)=>{return this.__node.nodes.set(tag,node)};delete=tag=>{return this.__node.nodes.delete(tag)};list=()=>{return Array.from(this.__node.nodes.keys())};getListener=(nodeTag,key,sub2)=>{let node=this.get(nodeTag);if(node){let k=node.__node.unique;if(key){k+="."+key}return this.__node.state.getEvent(k,sub2)}};getProps=(node,getInitial)=>{if(typeof node==="string")node=this.get(node);if(node instanceof GraphNode){let cpy;if(getInitial)cpy=Object.assign({},this.__node.roots[node.__node.tag]);else{cpy=Object.assign({},node);for(const key in cpy){if(key.includes("__"))delete cpy[key]}}}};subscribe=(nodeEvent,onEvent,args,key,subInput,target,tkey)=>{let nd=nodeEvent;if(typeof nodeEvent==="string"){nd=this.get(nodeEvent);if(!nd&&nodeEvent.includes(".")){nd=this.get(nodeEvent.substring(0,nodeEvent.lastIndexOf(".")));key=nodeEvent.substring(nodeEvent.lastIndexOf(".")+1)}}if(target instanceof GraphNode)target=target.__node.tag;let callbackStr;if(typeof onEvent==="string"){callbackStr=onEvent;let setOnEventFromString=onEvent2=>{if(this.get(onEvent2)?.__operator){let node=this.get(onEvent2);target=onEvent2;onEvent2=function(...inp){return node.__operator(...inp)}}else if(onEvent2.includes(".")){target=onEvent2.substring(0,onEvent2.lastIndexOf("."));let n=this.get(target);let k=onEvent2.substring(onEvent2.lastIndexOf(".")+1);tkey=k;if(typeof n[k]==="function"){if(n[k]instanceof GraphNode)onEvent2=n[k];else onEvent2=function(...inp){return n[k](...inp)}}else{onEvent2=function(inp){n[k]=inp;return n[k]}}}return onEvent2};if(target){let node=this.get(target);if(typeof node?.[onEvent]==="function"){tkey=onEvent;onEvent=function(...inp){return node[key](...inp)}}else if(node?.[key]){tkey=key;if(node[key]instanceof GraphNode)onEvent=node[key];else onEvent=function(inp){node[key]=inp;return node[key]}}else{onEvent=setOnEventFromString(onEvent)}}else{onEvent=setOnEventFromString(onEvent)}}let sub2;if(nd instanceof GraphNode){const doSub=()=>{sub2=nd.__subscribe(onEvent,key,subInput,target,tkey,args,callbackStr);let ondelete=()=>{if(sub2!==void 0)nd.__unsubscribe(sub2,key,subInput);sub2=void 0};nd.__addOndisconnected(()=>{ondelete();nd.__addOnconnected(()=>{if(sub2===void 0&&nd.__node.graph.__node.tag===this.__node.tag)doSub()})});if(typeof onEvent==="string"&&this.get(onEvent))onEvent=this.get(onEvent);if(onEvent instanceof GraphNode){onEvent.__addOndisconnected(()=>{ondelete()})}};doSub()}else if(typeof nodeEvent==="string"){let node=this.get(nodeEvent);if(node){if(onEvent instanceof GraphNode&&onEvent.__operator){const doSub=()=>{sub2=node.__subscribe(onEvent.__operator,key,subInput,target,tkey,args,callbackStr);let ondelete=()=>{if(sub2!==void 0)node.__unsubscribe(sub2,key,subInput)};node.__addOndisconnected(()=>{ondelete();node.__addOnconnected(()=>{if(sub2===void 0&&node.__node.graph.__node.tag===this.__node.tag)doSub()})});onEvent.__addOndisconnected(ondelete)};doSub()}else if(typeof onEvent==="function"||typeof onEvent==="string"){const doSub=()=>{sub2=node.__subscribe(onEvent,key,subInput,target,tkey,args,callbackStr);let ondelete=()=>{if(sub2!==void 0)node.__unsubscribe(sub2,key,subInput);sub2=void 0};node.__addOndisconnected(()=>{ondelete();node.__addOnconnected(()=>{if(sub2===void 0&&node.__node.graph.__node.tag===this.__node.tag)doSub()})});if(typeof onEvent==="string"&&this.get(onEvent))this.get(onEvent).__addOndisconnected(ondelete)};doSub()}}else{if(typeof onEvent==="string")onEvent=this.__node.nodes.get(onEvent).__operator;if(typeof onEvent==="function"&&!onEvent?.__node)sub2=this.__node.state.subscribeEvent(nodeEvent,onEvent)}}return sub2};unsubscribe=(node,sub2,key,subInput)=>{if(node instanceof GraphNode){return node.__unsubscribe(sub2,key,subInput)}else return this.get(node)?.__unsubscribe(sub2,key,subInput)};setState=update=>{this.__node.state.setState(update)}};function recursivelyAssign(target,obj,maxDepth=Infinity,curDepth=0){for(const key in obj){if(obj[key]?.constructor.name==="Object"&&curDepth{if(graph.get(a)?.__operator){let node=graph.get(a);return(...inp)=>{node.__operator(...inp)}}else if(a.includes(".")){let split=a.split(".");let popped=split.pop();let joined=split.join(".");let node=graph.get(joined);if(typeof graph.get(joined)?.[popped]==="function"){return(...inp)=>{return node[popped](...inp)}}else return()=>{return node[popped]}}else if(graph.get(a)){let node=graph.get(a);return()=>{return node}}else{let arg=a;return()=>{return arg}}};var wrapArgs=(callback,argOrder,graph)=>{let args=[];let forArg=(a,i)=>{if(a==="__output"||a==="__input"||a==="__callback"){args[i]={__callback:inp=>{return inp},__args:void 0,idx:i}}else if(typeof a==="string"){args[i]={__callback:getCallbackFromString(a,graph),__args:void 0,idx:i}}else if(typeof a==="function"){let fn2=a;args[i]={__callback:(...inp)=>{return fn2(...inp)},__args:void 0,idx:i}}else if(typeof a==="object"&&(a.__input||a.__callback)){let recursivelyCreateCallback=function(c){let input=c.__input?c.__input:c.__callback;if(typeof c.__input==="string"){input={__callback:getCallbackFromString(c.__input,graph),__args:void 0,idx:i}}if(c.__args){let wrapped=wrapArgs(input,c.__args,graph);input={__callback:wrapped.__callback,__args:wrapped.__args,idx:i}}else{input={__callback:input,__args:void 0,idx:i}}if(c.__output){let output=c.__output;if(typeof c.__output==="string"){output={__callback:getCallbackFromString(output,graph),__args:void 0,idx:i}}else if(typeof a.__output==="object"){output=recursivelyCreateCallback(output)}if(typeof output?.__callback==="function"){let fn2=input.__callback;let callback2=output.__callback;input={__callback:(...inp)=>{return callback2(fn2(...inp))},__args:output.__args,idx:i}}}return input};args[i]=recursivelyCreateCallback(a)}else{let arg=a;args[i]={__callback:()=>{return arg},__args:void 0,idx:i}}};argOrder.forEach(forArg);if(typeof callback==="string")callback={__callback:getCallbackFromString(callback,graph),__args:void 0};let fn=typeof callback==="function"?callback:callback.__callback;callback=function(...inp){let mapArg=arg=>{return arg.__callback(...inp)};const result=fn(...args.map(mapArg));return result};return{__callback:callback,__args:args}};var objProps=Object.getOwnPropertyNames(Object.getPrototypeOf({}));var backprop=(node,parent,graph)=>{if(node.__node.backward&&parent instanceof GraphNode){graph.setListeners({[parent.__node.tag]:{[node.__node.tag]:parent}})}};var loop=(node,parent,graph)=>{if(node.__operator){let loopId=Math.random();if(!node.__node.loops)node.__node.loops={};if(typeof node.__node.delay==="number"){let fn=node.__operator;node.__setOperator((...args)=>{return new Promise((res,rej)=>{node.__node.loops[loopId]=setTimeout(async()=>{res(await fn(...args))},node.__node.delay)})})}else if(node.__node.frame===true){let fn=node.__operator;node.__setOperator((...args)=>{return new Promise((res,rej)=>{node.__node.loops[loopId]=requestAnimationFrame(async()=>{res(await fn(...args))})})})}if(typeof node.__node.repeat==="number"||typeof node.__node.recursive==="number"){let fn=node.__operator;node.__setOperator(async(...args)=>{let i=node.__node.repeat?node.__node.repeat:node.__node.recursive;let result;let repeater=async(tick,...inp)=>{while(tick>0){if(node.__node.delay||node.__node.frame){fn(...inp).then(async res=>{if(node.__node.recursive){await repeater(tick,res)}else await repeater(tick,...inp)});break}else result=await fn(...args);tick--}};await repeater(i,...args);return result})}if(node.__node.loop&&typeof node.__node.loop==="number"){let fn=node.__operator;let time=node.__node.loop;node.__setOperator((...args)=>{if(!("looping"in node.__node))node.__node.looping=true;if(node.__node.looping){let last=performance.now();fn(...args);node.__node.loops[loopId]=setTimeout(()=>{let now=performance.now();let overshoot=now-last-node.__node.loop;if(overshoot>0)time=node.__node.loop-overshoot;else time=node.__node.loop;if(time<=0)time=node.__node.loop;node.__operator(...args)},time)}});if(node.__node.looping)node.__operator();let ondelete=node2=>{if(node2.__node.looping)node2.__node.looping=false;if(node2.__node.loops[loopId]){clearTimeout(node2.__node.loops[loopId]);cancelAnimationFrame(node2.__node.loops[loopId])}};node.__addOndisconnected(ondelete)}}};var animate=(node,parent,graph)=>{if(node.__node.animate===true||node.__animation){let fn=node.__operator;node.__setOperator((...args)=>{if(!("animating"in node.__node))node.__node.animating=true;if(node.__node.animating){if(typeof node.__animation==="function")node.__animation(...args);else fn(...args);node.__node.animationFrame=requestAnimationFrame(()=>{node.__operator(...args)})}});if(node.__node.animating||(!("animating"in node.__node)||node.__node.animating)&&node.__animation)setTimeout(()=>{node.__node.animationFrame=requestAnimationFrame(node.__operator)},10);let ondelete=node2=>{if(node2.__node.animating)node2.__node.animating=false;if(node2.__node.animationFrame)cancelAnimationFrame(node2.__node.animationFrame)};node.__addOndisconnected(ondelete)}};var branching=(node,parent,graph)=>{if(typeof node.__branch==="object"&&node.__operator&&!node.__branchApplied){let fn=node.__operator;node.__branchApplied=true;node.__operator=(...args)=>{let result=fn(...args);for(const key in node.__branch){let triggered=()=>{if(typeof node.__branch[key].then==="function"){node.__branch[key].then(result)}else if(node.__branch[key].then instanceof GraphNode&&node.__branch[key].then.__operator){node.__branch[key].then.__operator(result)}else result=node.__branch[key].then};if(typeof node.__branch[key].if==="function"){if(node.__branch[key].if(result)==true){triggered()}}else if(node.__branch[key].if===result){triggered()}}return result}}if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(node.__listeners[key].branch&&!node.__listeners[key].branchApplied){let fn=node.__listeners[key].callback;node.__listeners[key].branchApplied=true;node.__listeners.callback=ret=>{let triggered=()=>{if(typeof node.__listeners[key].branch.then==="function"){ret=node.__listeners[key].branch.then(ret)}else if(node.__listeners[key].branch.then instanceof GraphNode&&node.__listeners[key].branch.then.__operator){ret=node.__listeners[key].branch.then.__operator(ret)}else ret=node.__listeners[key].branch.then};if(typeof node.__listeners[key].branch.if==="function"){if(node.__listeners[key].branch.if(ret)){triggered()}}else if(node.__listeners[key].branch.if===ret){triggered()}return fn(ret)}}}}}};var triggerListenerOncreate=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(node.__listeners[key].oncreate){node.__listeners[key].callback(node.__listeners[key].oncreate)}}}}};var bindListener=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(typeof node.__listeners[key].binding==="object"){node.__listeners.callback=node.__listeners.callback.bind(node.__listeners[key].binding)}}}}};var transformListenerResult=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(typeof node.__listeners[key].transform==="function"&&!node.__listeners[key].transformApplied){let fn=node.__listeners[key].callback;node.__listeners[key].transformApplied=true;node.__listeners.callback=ret=>{ret=node.__listeners[key].transform(ret);return fn(ret)}}}}}};var substitute__operator=(node,parent,graph)=>{if(node.post&&!node.__operator){node.__setOperator(node.post)}else if(!node.__operator&&typeof node.get=="function"){node.__setOperator(node.get)}if(!node.get&&node.__operator){}if(node.aliases){node.aliases.forEach(a=>{graph.set(a,node);let ondelete=node2=>{graph.__node.nodes.delete(a)};node.__addOndisconnected(ondelete)})}if(typeof graph.__node.roots?.[node.__node.tag]==="object"&&node.get)graph.__node.roots[node.__node.tag].get=node.get};var loaders={backprop,loop,animate,branching,triggerListenerOncreate,bindListener,transformListenerResult,substitute__operator};var Service=class extends Graph{name=`service${Math.floor(Math.random()*1e15)}`;restrict;constructor(options){super({...options,loaders:options?.loaders?Object.assign({...loaders},options.loaders):{...loaders}});if(options?.services)this.addServices(options.services);if(options?.restrict)this.restrict=options.restrict;this.load(this)}addServices=services=>{for(const s in services){if(typeof services[s]==="function")services[s]=new services[s];if(services[s]?.__node?.loaders)Object.assign(this.__node.loaders,services[s].__node.loaders);if(services[s]?.__node?.nodes){services[s].__node.nodes.forEach((n,tag)=>{if(!this.get(tag)){this.set(tag,n)}else this.set(s+"."+tag,n)});this.__node.nodes.forEach((n,k)=>{if(!services[s].__node.nodes.get(k))services[s].__node.nodes.set(k,n)});let set=this.set;this.set=(tag,node)=>{services[s].set(tag,node);return set(tag,node)};let del=this.delete;this.delete=tag=>{services[s].delete(tag);return del(tag)}}else if(typeof services[s]==="object"){this.load(services[s])}}};handleMethod=(route,method,args)=>{let m=method.toLowerCase();let src=this.__node.nodes.get(route);if(!src){src=this.__node.roots[route]}if(src?.[m]){if(typeof src[m]!=="function"){if(args){if(Array.isArray(args)&&args.length===1)src[m]=args[0];else src[m]=args;return}return src[m]}else{if(Array.isArray(args))return src[m](...args);else return src[m](args)}}else return this.handleServiceMessage({route,args,method})};handleServiceMessage(message){let call;if(typeof message==="object"){if(message.route)call=message.route;else if(message.node)call=message.node}if(call){if(Array.isArray(message.args))return this.run(call,...message.args);else return this.run(call,message.args)}else return message}handleGraphNodeCall(route,args){if(!route)return args;if(args?.args){this.handleServiceMessage(args)}else if(Array.isArray(args))return this.run(route,...args);else return this.run(route,args)}transmit=(...args)=>{if(typeof args[0]==="object"){const message=args[0];if(message.method){return this.handleMethod(message.route,message.method,message.args)}else if(message.route){return this.handleServiceMessage(message)}else if(message.node){return this.handleGraphNodeCall(message.node,message.args)}else if(this.__node.keepState){if(message.route)this.setState({[message.route]:message.args});if(message.node)this.setState({[message.node]:message.args})}return void 0}else return void 0};receive=(...args)=>{if(args[0]){let message=args[0];if(typeof message==="string"){let substr=message.substring(0,8);if(substr.includes("{")||substr.includes("[")){if(substr.includes("\\"))message=message.replace(/\\/g,"");if(message[0]==='"'){message=message.substring(1,message.length-1)};message=JSON.parse(message)}}if(typeof message==="object"){if(message.method){if(this.restrict?.[message.route])return void 0;return this.handleMethod(message.route,message.method,message.args)}else if(message.route){if(this.restrict?.[message.route])return void 0;return this.handleServiceMessage(message)}else if(message.node){if(typeof message.node==="string"&&this.restrict?.[message.node])return void 0;return this.handleGraphNodeCall(message.node,message.args)}else if(this.__node.keepState){if(message.route)this.setState({[message.route]:message.args});if(message.node)this.setState({[message.node]:message.args})}return void 0}}return void 0};pipe=(source,destination,endpoint,method,callback)=>{if(source instanceof GraphNode){if(callback)return this.subscribe(source,res=>{let mod=callback(res);if(mod!==void 0)this.transmit({route:destination,args:mod,method});else this.transmit({route:destination,args:res,method},endpoint)});else return this.subscribe(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})}else if(typeof source==="string")return this.subscribe(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})};pipeOnce=(source,destination,endpoint,method,callback)=>{if(source instanceof GraphNode){if(callback)return source.__node.state.subscribeEventOnce(source.__node.unique,res=>{let mod=callback(res);if(mod!==void 0)this.transmit({route:destination,args:mod,method});else this.transmit({route:destination,args:res,method},endpoint)});else return this.__node.state.subscribeEventOnce(source.__node.unique,res=>{this.transmit({route:destination,args:res,method},endpoint)})}else if(typeof source==="string")return this.__node.state.subscribeEventOnce(this.__node.nodes.get(source).__node.unique,res=>{this.transmit({route:destination,args:res,method},endpoint)})};terminate=(...args)=>{};isTypedArray=isTypedArray;recursivelyAssign=recursivelyAssign2;spliceTypedArray=spliceTypedArray;ping=()=>{console.log("pinged!");return"pong"};echo=(...args)=>{this.transmit(...args);return args};log=(...args)=>{console.log(...args);return true};error=(...args)=>{console.error(...args);return true}};function isTypedArray(x2){return ArrayBuffer.isView(x2)&&Object.prototype.toString.call(x2)!=="[object DataView]"}var recursivelyAssign2=(target,obj)=>{for(const key in obj){if(obj[key]?.constructor.name==="Object"&&!Array.isArray(obj[key])){if(target[key]?.constructor.name==="Object"&&!Array.isArray(target[key]))recursivelyAssign2(target[key],obj[key]);else target[key]=recursivelyAssign2({},obj[key])}else target[key]=obj[key]}return target};function spliceTypedArray(arr,start,end){let s=arr.subarray(0,start);let e;if(end){e=arr.subarray(end+1)}let ta;if(s.length>0||e?.length>0)ta=new arr.constructor(s.length+e.length);if(ta){if(s.length>0)ta.set(s);if(e&&e.length>0)ta.set(e,s.length)}return ta}var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf;var __hasOwnProp=Object.prototype.hasOwnProperty;var __require2=(x2=>typeof __require!=="undefined"?__require:typeof Proxy!=="undefined"?new Proxy(x2,{get:(a,b)=>(typeof __require!=="undefined"?__require:a)[b]}):x2)(function(x2){if(typeof __require!=="undefined")return __require.apply(this,arguments);throw Error('Dynamic require of "'+x2+'" is not supported')});var __commonJS=(cb,mod)=>function __require22(){return mod||(0,cb[__getOwnPropNames(cb)[0]])((mod={exports:{}}).exports,mod),mod.exports};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from==="object"||typeof from==="function"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:true}):target,mod));var require_gpu_browser_min=__commonJS({"src/gpu-browser.min.js"(exports,module){"use strict";(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}f()}})(function(){var define2,module2,exports2;return function(){function r(e,n,t){function o(i2,f){if(!n[i2]){if(!e[i2]){var c="function"==typeof __require2&&__require2;if(!f&&c)return c(i2,true);if(u)return u(i2,true);var a=new Error("Cannot find module '"+i2+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i2]={exports:{}};e[i2][0].call(p.exports,function(r2){var n2=e[i2][1][r2];return o(n2||r2)},p,p.exports,r,e,n,t)}return n[i2].exports}for(var u="function"==typeof __require2&&__require2,i=0;icode){return false}pos+=set[i+1];if(pos>=code){return true}}}function isIdentifierStart(code,astral){if(code<65){return code===36}if(code<91){return true}if(code<97){return code===95}if(code<123){return true}if(code<=65535){return code>=170&&nonASCIIidentifierStart.test(String.fromCharCode(code))}if(astral===false){return false}return isInAstralSet(code,astralIdentifierStartCodes)}function isIdentifierChar(code,astral){if(code<48){return code===36}if(code<58){return true}if(code<65){return false}if(code<91){return true}if(code<97){return code===95}if(code<123){return true}if(code<=65535){return code>=170&&nonASCIIidentifier.test(String.fromCharCode(code))}if(astral===false){return false}return isInAstralSet(code,astralIdentifierStartCodes)||isInAstralSet(code,astralIdentifierCodes)}var TokenType=function TokenType2(label,conf){if(conf===void 0)conf={};this.label=label;this.keyword=conf.keyword;this.beforeExpr=!!conf.beforeExpr;this.startsExpr=!!conf.startsExpr;this.isLoop=!!conf.isLoop;this.isAssign=!!conf.isAssign;this.prefix=!!conf.prefix;this.postfix=!!conf.postfix;this.binop=conf.binop||null;this.updateContext=null};function binop(name2,prec){return new TokenType(name2,{beforeExpr:true,binop:prec})}var beforeExpr={beforeExpr:true},startsExpr={startsExpr:true};var keywords$1={};function kw(name2,options){if(options===void 0)options={};options.keyword=name2;return keywords$1[name2]=new TokenType(name2,options)}var types={num:new TokenType("num",startsExpr),regexp:new TokenType("regexp",startsExpr),string:new TokenType("string",startsExpr),name:new TokenType("name",startsExpr),eof:new TokenType("eof"),bracketL:new TokenType("[",{beforeExpr:true,startsExpr:true}),bracketR:new TokenType("]"),braceL:new TokenType("{",{beforeExpr:true,startsExpr:true}),braceR:new TokenType("}"),parenL:new TokenType("(",{beforeExpr:true,startsExpr:true}),parenR:new TokenType(")"),comma:new TokenType(",",beforeExpr),semi:new TokenType(";",beforeExpr),colon:new TokenType(":",beforeExpr),dot:new TokenType("."),question:new TokenType("?",beforeExpr),arrow:new TokenType("=>",beforeExpr),template:new TokenType("template"),invalidTemplate:new TokenType("invalidTemplate"),ellipsis:new TokenType("...",beforeExpr),backQuote:new TokenType("`",startsExpr),dollarBraceL:new TokenType("${",{beforeExpr:true,startsExpr:true}),eq:new TokenType("=",{beforeExpr:true,isAssign:true}),assign:new TokenType("_=",{beforeExpr:true,isAssign:true}),incDec:new TokenType("++/--",{prefix:true,postfix:true,startsExpr:true}),prefix:new TokenType("!/~",{beforeExpr:true,prefix:true,startsExpr:true}),logicalOR:binop("||",1),logicalAND:binop("&&",2),bitwiseOR:binop("|",3),bitwiseXOR:binop("^",4),bitwiseAND:binop("&",5),equality:binop("==/!=/===/!==",6),relational:binop("/<=/>=",7),bitShift:binop("<>/>>>",8),plusMin:new TokenType("+/-",{beforeExpr:true,binop:9,prefix:true,startsExpr:true}),modulo:binop("%",10),star:binop("*",10),slash:binop("/",10),starstar:new TokenType("**",{beforeExpr:true}),_break:kw("break"),_case:kw("case",beforeExpr),_catch:kw("catch"),_continue:kw("continue"),_debugger:kw("debugger"),_default:kw("default",beforeExpr),_do:kw("do",{isLoop:true,beforeExpr:true}),_else:kw("else",beforeExpr),_finally:kw("finally"),_for:kw("for",{isLoop:true}),_function:kw("function",startsExpr),_if:kw("if"),_return:kw("return",beforeExpr),_switch:kw("switch"),_throw:kw("throw",beforeExpr),_try:kw("try"),_var:kw("var"),_const:kw("const"),_while:kw("while",{isLoop:true}),_with:kw("with"),_new:kw("new",{beforeExpr:true,startsExpr:true}),_this:kw("this",startsExpr),_super:kw("super",startsExpr),_class:kw("class",startsExpr),_extends:kw("extends",beforeExpr),_export:kw("export"),_import:kw("import",startsExpr),_null:kw("null",startsExpr),_true:kw("true",startsExpr),_false:kw("false",startsExpr),_in:kw("in",{beforeExpr:true,binop:7}),_instanceof:kw("instanceof",{beforeExpr:true,binop:7}),_typeof:kw("typeof",{beforeExpr:true,prefix:true,startsExpr:true}),_void:kw("void",{beforeExpr:true,prefix:true,startsExpr:true}),_delete:kw("delete",{beforeExpr:true,prefix:true,startsExpr:true})};var lineBreak=/\r\n?|\n|\u2028|\u2029/;var lineBreakG=new RegExp(lineBreak.source,"g");function isNewLine(code,ecma2019String){return code===10||code===13||!ecma2019String&&(code===8232||code===8233)}var nonASCIIwhitespace=/[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/;var skipWhiteSpace=/(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;var ref=Object.prototype;var hasOwnProperty=ref.hasOwnProperty;var toString=ref.toString;function has(obj,propName){return hasOwnProperty.call(obj,propName)}var isArray=Array.isArray||function(obj){return toString.call(obj)==="[object Array]"};function wordsRegexp(words){return new RegExp("^(?:"+words.replace(/ /g,"|")+")$")}var Position=function Position2(line,col){this.line=line;this.column=col};Position.prototype.offset=function offset(n){return new Position(this.line,this.column+n)};var SourceLocation=function SourceLocation2(p,start,end){this.start=start;this.end=end;if(p.sourceFile!==null){this.source=p.sourceFile}};function getLineInfo(input,offset){for(var line=1,cur=0;;){lineBreakG.lastIndex=cur;var match=lineBreakG.exec(input);if(match&&match.index=2015){options.ecmaVersion-=2009}if(options.allowReserved==null){options.allowReserved=options.ecmaVersion<5}if(isArray(options.onToken)){var tokens=options.onToken;options.onToken=function(token){return tokens.push(token)}}if(isArray(options.onComment)){options.onComment=pushComment(options,options.onComment)}return options}function pushComment(options,array){return function(block,text,start,end,startLoc,endLoc){var comment={type:block?"Block":"Line",value:text,start,end};if(options.locations){comment.loc=new SourceLocation(this,startLoc,endLoc)}if(options.ranges){comment.range=[start,end]}array.push(comment)}}var SCOPE_TOP=1,SCOPE_FUNCTION=2,SCOPE_VAR=SCOPE_TOP|SCOPE_FUNCTION,SCOPE_ASYNC=4,SCOPE_GENERATOR=8,SCOPE_ARROW=16,SCOPE_SIMPLE_CATCH=32,SCOPE_SUPER=64,SCOPE_DIRECT_SUPER=128;function functionFlags(async,generator){return SCOPE_FUNCTION|(async?SCOPE_ASYNC:0)|(generator?SCOPE_GENERATOR:0)}var BIND_NONE=0,BIND_VAR=1,BIND_LEXICAL=2,BIND_FUNCTION=3,BIND_SIMPLE_CATCH=4,BIND_OUTSIDE=5;var Parser=function Parser2(options,input,startPos){this.options=options=getOptions(options);this.sourceFile=options.sourceFile;this.keywords=wordsRegexp(keywords[options.ecmaVersion>=6?6:options.sourceType==="module"?"5module":5]);var reserved="";if(options.allowReserved!==true){for(var v=options.ecmaVersion;;v--){if(reserved=reservedWords[v]){break}}if(options.sourceType==="module"){reserved+=" await"}}this.reservedWords=wordsRegexp(reserved);var reservedStrict=(reserved?reserved+" ":"")+reservedWords.strict;this.reservedWordsStrict=wordsRegexp(reservedStrict);this.reservedWordsStrictBind=wordsRegexp(reservedStrict+" "+reservedWords.strictBind);this.input=String(input);this.containsEsc=false;if(startPos){this.pos=startPos;this.lineStart=this.input.lastIndexOf("\n",startPos-1)+1;this.curLine=this.input.slice(0,this.lineStart).split(lineBreak).length}else{this.pos=this.lineStart=0;this.curLine=1}this.type=types.eof;this.value=null;this.start=this.end=this.pos;this.startLoc=this.endLoc=this.curPosition();this.lastTokEndLoc=this.lastTokStartLoc=null;this.lastTokStart=this.lastTokEnd=this.pos;this.context=this.initialContext();this.exprAllowed=true;this.inModule=options.sourceType==="module";this.strict=this.inModule||this.strictDirective(this.pos);this.potentialArrowAt=-1;this.yieldPos=this.awaitPos=this.awaitIdentPos=0;this.labels=[];this.undefinedExports={};if(this.pos===0&&options.allowHashBang&&this.input.slice(0,2)==="#!"){this.skipLineComment(2)}this.scopeStack=[];this.enterScope(SCOPE_TOP);this.regexpState=null};var prototypeAccessors={inFunction:{configurable:true},inGenerator:{configurable:true},inAsync:{configurable:true},allowSuper:{configurable:true},allowDirectSuper:{configurable:true},treatFunctionsAsVar:{configurable:true}};Parser.prototype.parse=function parse2(){var node=this.options.program||this.startNode();this.nextToken();return this.parseTopLevel(node)};prototypeAccessors.inFunction.get=function(){return(this.currentVarScope().flags&SCOPE_FUNCTION)>0};prototypeAccessors.inGenerator.get=function(){return(this.currentVarScope().flags&SCOPE_GENERATOR)>0};prototypeAccessors.inAsync.get=function(){return(this.currentVarScope().flags&SCOPE_ASYNC)>0};prototypeAccessors.allowSuper.get=function(){return(this.currentThisScope().flags&SCOPE_SUPER)>0};prototypeAccessors.allowDirectSuper.get=function(){return(this.currentThisScope().flags&SCOPE_DIRECT_SUPER)>0};prototypeAccessors.treatFunctionsAsVar.get=function(){return this.treatFunctionsAsVarInScope(this.currentScope())};Parser.prototype.inNonArrowFunction=function inNonArrowFunction(){return(this.currentThisScope().flags&SCOPE_FUNCTION)>0};Parser.extend=function extend(){var plugins=[],len=arguments.length;while(len--)plugins[len]=arguments[len];var cls=this;for(var i=0;i-1){this.raiseRecoverable(refDestructuringErrors.trailingComma,"Comma is not permitted after the rest element")}var parens=isAssign?refDestructuringErrors.parenthesizedAssign:refDestructuringErrors.parenthesizedBind;if(parens>-1){this.raiseRecoverable(parens,"Parenthesized pattern")}};pp.checkExpressionErrors=function(refDestructuringErrors,andThrow){if(!refDestructuringErrors){return false}var shorthandAssign=refDestructuringErrors.shorthandAssign;var doubleProto=refDestructuringErrors.doubleProto;if(!andThrow){return shorthandAssign>=0||doubleProto>=0}if(shorthandAssign>=0){this.raise(shorthandAssign,"Shorthand property assignments are valid only in destructuring patterns")}if(doubleProto>=0){this.raiseRecoverable(doubleProto,"Redefinition of __proto__ property")}};pp.checkYieldAwaitInDefaultParams=function(){if(this.yieldPos&&(!this.awaitPos||this.yieldPos=6){this.unexpected()}return this.parseFunctionStatement(node,false,!context);case types._class:if(context){this.unexpected()}return this.parseClass(node,true);case types._if:return this.parseIfStatement(node);case types._return:return this.parseReturnStatement(node);case types._switch:return this.parseSwitchStatement(node);case types._throw:return this.parseThrowStatement(node);case types._try:return this.parseTryStatement(node);case types._const:case types._var:kind=kind||this.value;if(context&&kind!=="var"){this.unexpected()}return this.parseVarStatement(node,kind);case types._while:return this.parseWhileStatement(node);case types._with:return this.parseWithStatement(node);case types.braceL:return this.parseBlock(true,node);case types.semi:return this.parseEmptyStatement(node);case types._export:case types._import:if(this.options.ecmaVersion>10&&starttype===types._import){skipWhiteSpace.lastIndex=this.pos;var skip=skipWhiteSpace.exec(this.input);var next=this.pos+skip[0].length,nextCh=this.input.charCodeAt(next);if(nextCh===40){return this.parseExpressionStatement(node,this.parseExpression())}}if(!this.options.allowImportExportEverywhere){if(!topLevel){this.raise(this.start,"'import' and 'export' may only appear at the top level")}if(!this.inModule){this.raise(this.start,"'import' and 'export' may appear only with 'sourceType: module'")}}return starttype===types._import?this.parseImport(node):this.parseExport(node,exports5);default:if(this.isAsyncFunction()){if(context){this.unexpected()}this.next();return this.parseFunctionStatement(node,true,!context)}var maybeName=this.value,expr=this.parseExpression();if(starttype===types.name&&expr.type==="Identifier"&&this.eat(types.colon)){return this.parseLabeledStatement(node,maybeName,expr,context)}else{return this.parseExpressionStatement(node,expr)}}};pp$1.parseBreakContinueStatement=function(node,keyword){var isBreak=keyword==="break";this.next();if(this.eat(types.semi)||this.insertSemicolon()){node.label=null}else if(this.type!==types.name){this.unexpected()}else{node.label=this.parseIdent();this.semicolon()}var i=0;for(;i=6){this.eat(types.semi)}else{this.semicolon()}return this.finishNode(node,"DoWhileStatement")};pp$1.parseForStatement=function(node){this.next();var awaitAt=this.options.ecmaVersion>=9&&(this.inAsync||!this.inFunction&&this.options.allowAwaitOutsideFunction)&&this.eatContextual("await")?this.lastTokStart:-1;this.labels.push(loopLabel);this.enterScope(0);this.expect(types.parenL);if(this.type===types.semi){if(awaitAt>-1){this.unexpected(awaitAt)}return this.parseFor(node,null)}var isLet=this.isLet();if(this.type===types._var||this.type===types._const||isLet){var init$1=this.startNode(),kind=isLet?"let":this.value;this.next();this.parseVar(init$1,true,kind);this.finishNode(init$1,"VariableDeclaration");if((this.type===types._in||this.options.ecmaVersion>=6&&this.isContextual("of"))&&init$1.declarations.length===1){if(this.options.ecmaVersion>=9){if(this.type===types._in){if(awaitAt>-1){this.unexpected(awaitAt)}}else{node.await=awaitAt>-1}}return this.parseForIn(node,init$1)}if(awaitAt>-1){this.unexpected(awaitAt)}return this.parseFor(node,init$1)}var refDestructuringErrors=new DestructuringErrors;var init=this.parseExpression(true,refDestructuringErrors);if(this.type===types._in||this.options.ecmaVersion>=6&&this.isContextual("of")){if(this.options.ecmaVersion>=9){if(this.type===types._in){if(awaitAt>-1){this.unexpected(awaitAt)}}else{node.await=awaitAt>-1}}this.toAssignable(init,false,refDestructuringErrors);this.checkLVal(init);return this.parseForIn(node,init)}else{this.checkExpressionErrors(refDestructuringErrors,true)}if(awaitAt>-1){this.unexpected(awaitAt)}return this.parseFor(node,init)};pp$1.parseFunctionStatement=function(node,isAsync,declarationPosition){this.next();return this.parseFunction(node,FUNC_STATEMENT|(declarationPosition?0:FUNC_HANGING_STATEMENT),false,isAsync)};pp$1.parseIfStatement=function(node){this.next();node.test=this.parseParenExpression();node.consequent=this.parseStatement("if");node.alternate=this.eat(types._else)?this.parseStatement("if"):null;return this.finishNode(node,"IfStatement")};pp$1.parseReturnStatement=function(node){if(!this.inFunction&&!this.options.allowReturnOutsideFunction){this.raise(this.start,"'return' outside of function")}this.next();if(this.eat(types.semi)||this.insertSemicolon()){node.argument=null}else{node.argument=this.parseExpression();this.semicolon()}return this.finishNode(node,"ReturnStatement")};pp$1.parseSwitchStatement=function(node){this.next();node.discriminant=this.parseParenExpression();node.cases=[];this.expect(types.braceL);this.labels.push(switchLabel);this.enterScope(0);var cur;for(var sawDefault=false;this.type!==types.braceR;){if(this.type===types._case||this.type===types._default){var isCase=this.type===types._case;if(cur){this.finishNode(cur,"SwitchCase")}node.cases.push(cur=this.startNode());cur.consequent=[];this.next();if(isCase){cur.test=this.parseExpression()}else{if(sawDefault){this.raiseRecoverable(this.lastTokStart,"Multiple default clauses")}sawDefault=true;cur.test=null}this.expect(types.colon)}else{if(!cur){this.unexpected()}cur.consequent.push(this.parseStatement(null))}}this.exitScope();if(cur){this.finishNode(cur,"SwitchCase")}this.next();this.labels.pop();return this.finishNode(node,"SwitchStatement")};pp$1.parseThrowStatement=function(node){this.next();if(lineBreak.test(this.input.slice(this.lastTokEnd,this.start))){this.raise(this.lastTokEnd,"Illegal newline after throw")}node.argument=this.parseExpression();this.semicolon();return this.finishNode(node,"ThrowStatement")};var empty=[];pp$1.parseTryStatement=function(node){this.next();node.block=this.parseBlock();node.handler=null;if(this.type===types._catch){var clause=this.startNode();this.next();if(this.eat(types.parenL)){clause.param=this.parseBindingAtom();var simple=clause.param.type==="Identifier";this.enterScope(simple?SCOPE_SIMPLE_CATCH:0);this.checkLVal(clause.param,simple?BIND_SIMPLE_CATCH:BIND_LEXICAL);this.expect(types.parenR)}else{if(this.options.ecmaVersion<10){this.unexpected()}clause.param=null;this.enterScope(0)}clause.body=this.parseBlock(false);this.exitScope();node.handler=this.finishNode(clause,"CatchClause")}node.finalizer=this.eat(types._finally)?this.parseBlock():null;if(!node.handler&&!node.finalizer){this.raise(node.start,"Missing catch or finally clause")}return this.finishNode(node,"TryStatement")};pp$1.parseVarStatement=function(node,kind){this.next();this.parseVar(node,false,kind);this.semicolon();return this.finishNode(node,"VariableDeclaration")};pp$1.parseWhileStatement=function(node){this.next();node.test=this.parseParenExpression();this.labels.push(loopLabel);node.body=this.parseStatement("while");this.labels.pop();return this.finishNode(node,"WhileStatement")};pp$1.parseWithStatement=function(node){if(this.strict){this.raise(this.start,"'with' in strict mode")}this.next();node.object=this.parseParenExpression();node.body=this.parseStatement("with");return this.finishNode(node,"WithStatement")};pp$1.parseEmptyStatement=function(node){this.next();return this.finishNode(node,"EmptyStatement")};pp$1.parseLabeledStatement=function(node,maybeName,expr,context){for(var i$1=0,list=this.labels;i$1=0;i--){var label$1=this.labels[i];if(label$1.statementStart===node.start){label$1.statementStart=this.start;label$1.kind=kind}else{break}}this.labels.push({name:maybeName,kind,statementStart:this.start});node.body=this.parseStatement(context?context.indexOf("label")===-1?context+"label":context:"label");this.labels.pop();node.label=expr;return this.finishNode(node,"LabeledStatement")};pp$1.parseExpressionStatement=function(node,expr){node.expression=expr;this.semicolon();return this.finishNode(node,"ExpressionStatement")};pp$1.parseBlock=function(createNewLexicalScope,node){if(createNewLexicalScope===void 0)createNewLexicalScope=true;if(node===void 0)node=this.startNode();node.body=[];this.expect(types.braceL);if(createNewLexicalScope){this.enterScope(0)}while(!this.eat(types.braceR)){var stmt=this.parseStatement(null);node.body.push(stmt)}if(createNewLexicalScope){this.exitScope()}return this.finishNode(node,"BlockStatement")};pp$1.parseFor=function(node,init){node.init=init;this.expect(types.semi);node.test=this.type===types.semi?null:this.parseExpression();this.expect(types.semi);node.update=this.type===types.parenR?null:this.parseExpression();this.expect(types.parenR);node.body=this.parseStatement("for");this.exitScope();this.labels.pop();return this.finishNode(node,"ForStatement")};pp$1.parseForIn=function(node,init){var isForIn=this.type===types._in;this.next();if(init.type==="VariableDeclaration"&&init.declarations[0].init!=null&&(!isForIn||this.options.ecmaVersion<8||this.strict||init.kind!=="var"||init.declarations[0].id.type!=="Identifier")){this.raise(init.start,(isForIn?"for-in":"for-of")+" loop variable declaration may not have an initializer")}else if(init.type==="AssignmentPattern"){this.raise(init.start,"Invalid left-hand side in for-loop")}node.left=init;node.right=isForIn?this.parseExpression():this.parseMaybeAssign();this.expect(types.parenR);node.body=this.parseStatement("for");this.exitScope();this.labels.pop();return this.finishNode(node,isForIn?"ForInStatement":"ForOfStatement")};pp$1.parseVar=function(node,isFor,kind){node.declarations=[];node.kind=kind;for(;;){var decl=this.startNode();this.parseVarId(decl,kind);if(this.eat(types.eq)){decl.init=this.parseMaybeAssign(isFor)}else if(kind==="const"&&!(this.type===types._in||this.options.ecmaVersion>=6&&this.isContextual("of"))){this.unexpected()}else if(decl.id.type!=="Identifier"&&!(isFor&&(this.type===types._in||this.isContextual("of")))){this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value")}else{decl.init=null}node.declarations.push(this.finishNode(decl,"VariableDeclarator"));if(!this.eat(types.comma)){break}}return node};pp$1.parseVarId=function(decl,kind){decl.id=this.parseBindingAtom();this.checkLVal(decl.id,kind==="var"?BIND_VAR:BIND_LEXICAL,false)};var FUNC_STATEMENT=1,FUNC_HANGING_STATEMENT=2,FUNC_NULLABLE_ID=4;pp$1.parseFunction=function(node,statement,allowExpressionBody,isAsync){this.initFunction(node);if(this.options.ecmaVersion>=9||this.options.ecmaVersion>=6&&!isAsync){if(this.type===types.star&&statement&FUNC_HANGING_STATEMENT){this.unexpected()}node.generator=this.eat(types.star)}if(this.options.ecmaVersion>=8){node.async=!!isAsync}if(statement&FUNC_STATEMENT){node.id=statement&FUNC_NULLABLE_ID&&this.type!==types.name?null:this.parseIdent();if(node.id&&!(statement&FUNC_HANGING_STATEMENT)){this.checkLVal(node.id,this.strict||node.generator||node.async?this.treatFunctionsAsVar?BIND_VAR:BIND_LEXICAL:BIND_FUNCTION)}}var oldYieldPos=this.yieldPos,oldAwaitPos=this.awaitPos,oldAwaitIdentPos=this.awaitIdentPos;this.yieldPos=0;this.awaitPos=0;this.awaitIdentPos=0;this.enterScope(functionFlags(node.async,node.generator));if(!(statement&FUNC_STATEMENT)){node.id=this.type===types.name?this.parseIdent():null}this.parseFunctionParams(node);this.parseFunctionBody(node,allowExpressionBody,false);this.yieldPos=oldYieldPos;this.awaitPos=oldAwaitPos;this.awaitIdentPos=oldAwaitIdentPos;return this.finishNode(node,statement&FUNC_STATEMENT?"FunctionDeclaration":"FunctionExpression")};pp$1.parseFunctionParams=function(node){this.expect(types.parenL);node.params=this.parseBindingList(types.parenR,false,this.options.ecmaVersion>=8);this.checkYieldAwaitInDefaultParams()};pp$1.parseClass=function(node,isStatement){this.next();var oldStrict=this.strict;this.strict=true;this.parseClassId(node,isStatement);this.parseClassSuper(node);var classBody=this.startNode();var hadConstructor=false;classBody.body=[];this.expect(types.braceL);while(!this.eat(types.braceR)){var element=this.parseClassElement(node.superClass!==null);if(element){classBody.body.push(element);if(element.type==="MethodDefinition"&&element.kind==="constructor"){if(hadConstructor){this.raise(element.start,"Duplicate constructor in the same class")}hadConstructor=true}}}node.body=this.finishNode(classBody,"ClassBody");this.strict=oldStrict;return this.finishNode(node,isStatement?"ClassDeclaration":"ClassExpression")};pp$1.parseClassElement=function(constructorAllowsSuper){var this$1=this;if(this.eat(types.semi)){return null}var method=this.startNode();var tryContextual=function(k,noLineBreak){if(noLineBreak===void 0)noLineBreak=false;var start=this$1.start,startLoc=this$1.startLoc;if(!this$1.eatContextual(k)){return false}if(this$1.type!==types.parenL&&(!noLineBreak||!this$1.canInsertSemicolon())){return true}if(method.key){this$1.unexpected()}method.computed=false;method.key=this$1.startNodeAt(start,startLoc);method.key.name=k;this$1.finishNode(method.key,"Identifier");return false};method.kind="method";method.static=tryContextual("static");var isGenerator=this.eat(types.star);var isAsync=false;if(!isGenerator){if(this.options.ecmaVersion>=8&&tryContextual("async",true)){isAsync=true;isGenerator=this.options.ecmaVersion>=9&&this.eat(types.star)}else if(tryContextual("get")){method.kind="get"}else if(tryContextual("set")){method.kind="set"}}if(!method.key){this.parsePropertyName(method)}var key=method.key;var allowsDirectSuper=false;if(!method.computed&&!method.static&&(key.type==="Identifier"&&key.name==="constructor"||key.type==="Literal"&&key.value==="constructor")){if(method.kind!=="method"){this.raise(key.start,"Constructor can't have get/set modifier")}if(isGenerator){this.raise(key.start,"Constructor can't be a generator")}if(isAsync){this.raise(key.start,"Constructor can't be an async method")}method.kind="constructor";allowsDirectSuper=constructorAllowsSuper}else if(method.static&&key.type==="Identifier"&&key.name==="prototype"){this.raise(key.start,"Classes may not have a static property named prototype")}this.parseClassMethod(method,isGenerator,isAsync,allowsDirectSuper);if(method.kind==="get"&&method.value.params.length!==0){this.raiseRecoverable(method.value.start,"getter should have no params")}if(method.kind==="set"&&method.value.params.length!==1){this.raiseRecoverable(method.value.start,"setter should have exactly one param")}if(method.kind==="set"&&method.value.params[0].type==="RestElement"){this.raiseRecoverable(method.value.params[0].start,"Setter cannot use rest params")}return method};pp$1.parseClassMethod=function(method,isGenerator,isAsync,allowsDirectSuper){method.value=this.parseMethod(isGenerator,isAsync,allowsDirectSuper);return this.finishNode(method,"MethodDefinition")};pp$1.parseClassId=function(node,isStatement){if(this.type===types.name){node.id=this.parseIdent();if(isStatement){this.checkLVal(node.id,BIND_LEXICAL,false)}}else{if(isStatement===true){this.unexpected()}node.id=null}};pp$1.parseClassSuper=function(node){node.superClass=this.eat(types._extends)?this.parseExprSubscripts():null};pp$1.parseExport=function(node,exports5){this.next();if(this.eat(types.star)){this.expectContextual("from");if(this.type!==types.string){this.unexpected()}node.source=this.parseExprAtom();this.semicolon();return this.finishNode(node,"ExportAllDeclaration")}if(this.eat(types._default)){this.checkExport(exports5,"default",this.lastTokStart);var isAsync;if(this.type===types._function||(isAsync=this.isAsyncFunction())){var fNode=this.startNode();this.next();if(isAsync){this.next()}node.declaration=this.parseFunction(fNode,FUNC_STATEMENT|FUNC_NULLABLE_ID,false,isAsync)}else if(this.type===types._class){var cNode=this.startNode();node.declaration=this.parseClass(cNode,"nullableID")}else{node.declaration=this.parseMaybeAssign();this.semicolon()}return this.finishNode(node,"ExportDefaultDeclaration")}if(this.shouldParseExportStatement()){node.declaration=this.parseStatement(null);if(node.declaration.type==="VariableDeclaration"){this.checkVariableExport(exports5,node.declaration.declarations)}else{this.checkExport(exports5,node.declaration.id.name,node.declaration.id.start)}node.specifiers=[];node.source=null}else{node.declaration=null;node.specifiers=this.parseExportSpecifiers(exports5);if(this.eatContextual("from")){if(this.type!==types.string){this.unexpected()}node.source=this.parseExprAtom()}else{for(var i=0,list=node.specifiers;i=6&&node){switch(node.type){case"Identifier":if(this.inAsync&&node.name==="await"){this.raise(node.start,"Cannot use 'await' as identifier inside an async function")}break;case"ObjectPattern":case"ArrayPattern":case"RestElement":break;case"ObjectExpression":node.type="ObjectPattern";if(refDestructuringErrors){this.checkPatternErrors(refDestructuringErrors,true)}for(var i=0,list=node.properties;i=8&&!containsEsc&&id.name==="async"&&!this.canInsertSemicolon()&&this.eat(types._function)){return this.parseFunction(this.startNodeAt(startPos,startLoc),0,false,true)}if(canBeArrow&&!this.canInsertSemicolon()){if(this.eat(types.arrow)){return this.parseArrowExpression(this.startNodeAt(startPos,startLoc),[id],false)}if(this.options.ecmaVersion>=8&&id.name==="async"&&this.type===types.name&&!containsEsc){id=this.parseIdent(false);if(this.canInsertSemicolon()||!this.eat(types.arrow)){this.unexpected()}return this.parseArrowExpression(this.startNodeAt(startPos,startLoc),[id],true)}}return id;case types.regexp:var value2=this.value;node=this.parseLiteral(value2.value);node.regex={pattern:value2.pattern,flags:value2.flags};return node;case types.num:case types.string:return this.parseLiteral(this.value);case types._null:case types._true:case types._false:node=this.startNode();node.value=this.type===types._null?null:this.type===types._true;node.raw=this.type.keyword;this.next();return this.finishNode(node,"Literal");case types.parenL:var start=this.start,expr=this.parseParenAndDistinguishExpression(canBeArrow);if(refDestructuringErrors){if(refDestructuringErrors.parenthesizedAssign<0&&!this.isSimpleAssignTarget(expr)){refDestructuringErrors.parenthesizedAssign=start}if(refDestructuringErrors.parenthesizedBind<0){refDestructuringErrors.parenthesizedBind=start}}return expr;case types.bracketL:node=this.startNode();this.next();node.elements=this.parseExprList(types.bracketR,true,true,refDestructuringErrors);return this.finishNode(node,"ArrayExpression");case types.braceL:return this.parseObj(false,refDestructuringErrors);case types._function:node=this.startNode();this.next();return this.parseFunction(node,0);case types._class:return this.parseClass(this.startNode(),false);case types._new:return this.parseNew();case types.backQuote:return this.parseTemplate();case types._import:if(this.options.ecmaVersion>=11){return this.parseExprImport()}else{return this.unexpected()}default:this.unexpected()}};pp$3.parseExprImport=function(){var node=this.startNode();this.next();switch(this.type){case types.parenL:return this.parseDynamicImport(node);default:this.unexpected()}};pp$3.parseDynamicImport=function(node){this.next();node.source=this.parseMaybeAssign();if(!this.eat(types.parenR)){var errorPos=this.start;if(this.eat(types.comma)&&this.eat(types.parenR)){this.raiseRecoverable(errorPos,"Trailing comma is not allowed in import()")}else{this.unexpected(errorPos)}}return this.finishNode(node,"ImportExpression")};pp$3.parseLiteral=function(value2){var node=this.startNode();node.value=value2;node.raw=this.input.slice(this.start,this.end);if(node.raw.charCodeAt(node.raw.length-1)===110){node.bigint=node.raw.slice(0,-1)}this.next();return this.finishNode(node,"Literal")};pp$3.parseParenExpression=function(){this.expect(types.parenL);var val=this.parseExpression();this.expect(types.parenR);return val};pp$3.parseParenAndDistinguishExpression=function(canBeArrow){var startPos=this.start,startLoc=this.startLoc,val,allowTrailingComma=this.options.ecmaVersion>=8;if(this.options.ecmaVersion>=6){this.next();var innerStartPos=this.start,innerStartLoc=this.startLoc;var exprList=[],first=true,lastIsComma=false;var refDestructuringErrors=new DestructuringErrors,oldYieldPos=this.yieldPos,oldAwaitPos=this.awaitPos,spreadStart;this.yieldPos=0;this.awaitPos=0;while(this.type!==types.parenR){first?first=false:this.expect(types.comma);if(allowTrailingComma&&this.afterTrailingComma(types.parenR,true)){lastIsComma=true;break}else if(this.type===types.ellipsis){spreadStart=this.start;exprList.push(this.parseParenItem(this.parseRestBinding()));if(this.type===types.comma){this.raise(this.start,"Comma is not permitted after the rest element")}break}else{exprList.push(this.parseMaybeAssign(false,refDestructuringErrors,this.parseParenItem))}}var innerEndPos=this.start,innerEndLoc=this.startLoc;this.expect(types.parenR);if(canBeArrow&&!this.canInsertSemicolon()&&this.eat(types.arrow)){this.checkPatternErrors(refDestructuringErrors,false);this.checkYieldAwaitInDefaultParams();this.yieldPos=oldYieldPos;this.awaitPos=oldAwaitPos;return this.parseParenArrowList(startPos,startLoc,exprList)}if(!exprList.length||lastIsComma){this.unexpected(this.lastTokStart)}if(spreadStart){this.unexpected(spreadStart)}this.checkExpressionErrors(refDestructuringErrors,true);this.yieldPos=oldYieldPos||this.yieldPos;this.awaitPos=oldAwaitPos||this.awaitPos;if(exprList.length>1){val=this.startNodeAt(innerStartPos,innerStartLoc);val.expressions=exprList;this.finishNodeAt(val,"SequenceExpression",innerEndPos,innerEndLoc)}else{val=exprList[0]}}else{val=this.parseParenExpression()}if(this.options.preserveParens){var par=this.startNodeAt(startPos,startLoc);par.expression=val;return this.finishNode(par,"ParenthesizedExpression")}else{return val}};pp$3.parseParenItem=function(item){return item};pp$3.parseParenArrowList=function(startPos,startLoc,exprList){return this.parseArrowExpression(this.startNodeAt(startPos,startLoc),exprList)};var empty$1=[];pp$3.parseNew=function(){if(this.containsEsc){this.raiseRecoverable(this.start,"Escape sequence in keyword new")}var node=this.startNode();var meta=this.parseIdent(true);if(this.options.ecmaVersion>=6&&this.eat(types.dot)){node.meta=meta;var containsEsc=this.containsEsc;node.property=this.parseIdent(true);if(node.property.name!=="target"||containsEsc){this.raiseRecoverable(node.property.start,"The only valid meta property for new is new.target")}if(!this.inNonArrowFunction()){this.raiseRecoverable(node.start,"new.target can only be used in functions")}return this.finishNode(node,"MetaProperty")}var startPos=this.start,startLoc=this.startLoc,isImport=this.type===types._import;node.callee=this.parseSubscripts(this.parseExprAtom(),startPos,startLoc,true);if(isImport&&node.callee.type==="ImportExpression"){this.raise(startPos,"Cannot use new with import()")}if(this.eat(types.parenL)){node.arguments=this.parseExprList(types.parenR,this.options.ecmaVersion>=8,false)}else{node.arguments=empty$1}return this.finishNode(node,"NewExpression")};pp$3.parseTemplateElement=function(ref2){var isTagged=ref2.isTagged;var elem=this.startNode();if(this.type===types.invalidTemplate){if(!isTagged){this.raiseRecoverable(this.start,"Bad escape sequence in untagged template literal")}elem.value={raw:this.value,cooked:null}}else{elem.value={raw:this.input.slice(this.start,this.end).replace(/\r\n?/g,"\n"),cooked:this.value}}this.next();elem.tail=this.type===types.backQuote;return this.finishNode(elem,"TemplateElement")};pp$3.parseTemplate=function(ref2){if(ref2===void 0)ref2={};var isTagged=ref2.isTagged;if(isTagged===void 0)isTagged=false;var node=this.startNode();this.next();node.expressions=[];var curElt=this.parseTemplateElement({isTagged});node.quasis=[curElt];while(!curElt.tail){if(this.type===types.eof){this.raise(this.pos,"Unterminated template literal")}this.expect(types.dollarBraceL);node.expressions.push(this.parseExpression());this.expect(types.braceR);node.quasis.push(curElt=this.parseTemplateElement({isTagged}))}this.next();return this.finishNode(node,"TemplateLiteral")};pp$3.isAsyncProp=function(prop){return!prop.computed&&prop.key.type==="Identifier"&&prop.key.name==="async"&&(this.type===types.name||this.type===types.num||this.type===types.string||this.type===types.bracketL||this.type.keyword||this.options.ecmaVersion>=9&&this.type===types.star)&&!lineBreak.test(this.input.slice(this.lastTokEnd,this.start))};pp$3.parseObj=function(isPattern,refDestructuringErrors){var node=this.startNode(),first=true,propHash={};node.properties=[];this.next();while(!this.eat(types.braceR)){if(!first){this.expect(types.comma);if(this.options.ecmaVersion>=5&&this.afterTrailingComma(types.braceR)){break}}else{first=false}var prop=this.parseProperty(isPattern,refDestructuringErrors);if(!isPattern){this.checkPropClash(prop,propHash,refDestructuringErrors)}node.properties.push(prop)}return this.finishNode(node,isPattern?"ObjectPattern":"ObjectExpression")};pp$3.parseProperty=function(isPattern,refDestructuringErrors){var prop=this.startNode(),isGenerator,isAsync,startPos,startLoc;if(this.options.ecmaVersion>=9&&this.eat(types.ellipsis)){if(isPattern){prop.argument=this.parseIdent(false);if(this.type===types.comma){this.raise(this.start,"Comma is not permitted after the rest element")}return this.finishNode(prop,"RestElement")}if(this.type===types.parenL&&refDestructuringErrors){if(refDestructuringErrors.parenthesizedAssign<0){refDestructuringErrors.parenthesizedAssign=this.start}if(refDestructuringErrors.parenthesizedBind<0){refDestructuringErrors.parenthesizedBind=this.start}}prop.argument=this.parseMaybeAssign(false,refDestructuringErrors);if(this.type===types.comma&&refDestructuringErrors&&refDestructuringErrors.trailingComma<0){refDestructuringErrors.trailingComma=this.start}return this.finishNode(prop,"SpreadElement")}if(this.options.ecmaVersion>=6){prop.method=false;prop.shorthand=false;if(isPattern||refDestructuringErrors){startPos=this.start;startLoc=this.startLoc}if(!isPattern){isGenerator=this.eat(types.star)}}var containsEsc=this.containsEsc;this.parsePropertyName(prop);if(!isPattern&&!containsEsc&&this.options.ecmaVersion>=8&&!isGenerator&&this.isAsyncProp(prop)){isAsync=true;isGenerator=this.options.ecmaVersion>=9&&this.eat(types.star);this.parsePropertyName(prop,refDestructuringErrors)}else{isAsync=false}this.parsePropertyValue(prop,isPattern,isGenerator,isAsync,startPos,startLoc,refDestructuringErrors,containsEsc);return this.finishNode(prop,"Property")};pp$3.parsePropertyValue=function(prop,isPattern,isGenerator,isAsync,startPos,startLoc,refDestructuringErrors,containsEsc){if((isGenerator||isAsync)&&this.type===types.colon){this.unexpected()}if(this.eat(types.colon)){prop.value=isPattern?this.parseMaybeDefault(this.start,this.startLoc):this.parseMaybeAssign(false,refDestructuringErrors);prop.kind="init"}else if(this.options.ecmaVersion>=6&&this.type===types.parenL){if(isPattern){this.unexpected()}prop.kind="init";prop.method=true;prop.value=this.parseMethod(isGenerator,isAsync)}else if(!isPattern&&!containsEsc&&this.options.ecmaVersion>=5&&!prop.computed&&prop.key.type==="Identifier"&&(prop.key.name==="get"||prop.key.name==="set")&&(this.type!==types.comma&&this.type!==types.braceR)){if(isGenerator||isAsync){this.unexpected()}prop.kind=prop.key.name;this.parsePropertyName(prop);prop.value=this.parseMethod(false);var paramCount=prop.kind==="get"?0:1;if(prop.value.params.length!==paramCount){var start=prop.value.start;if(prop.kind==="get"){this.raiseRecoverable(start,"getter should have no params")}else{this.raiseRecoverable(start,"setter should have exactly one param")}}else{if(prop.kind==="set"&&prop.value.params[0].type==="RestElement"){this.raiseRecoverable(prop.value.params[0].start,"Setter cannot use rest params")}}}else if(this.options.ecmaVersion>=6&&!prop.computed&&prop.key.type==="Identifier"){if(isGenerator||isAsync){this.unexpected()}this.checkUnreserved(prop.key);if(prop.key.name==="await"&&!this.awaitIdentPos){this.awaitIdentPos=startPos}prop.kind="init";if(isPattern){prop.value=this.parseMaybeDefault(startPos,startLoc,prop.key)}else if(this.type===types.eq&&refDestructuringErrors){if(refDestructuringErrors.shorthandAssign<0){refDestructuringErrors.shorthandAssign=this.start}prop.value=this.parseMaybeDefault(startPos,startLoc,prop.key)}else{prop.value=prop.key}prop.shorthand=true}else{this.unexpected()}};pp$3.parsePropertyName=function(prop){if(this.options.ecmaVersion>=6){if(this.eat(types.bracketL)){prop.computed=true;prop.key=this.parseMaybeAssign();this.expect(types.bracketR);return prop.key}else{prop.computed=false}}return prop.key=this.type===types.num||this.type===types.string?this.parseExprAtom():this.parseIdent(this.options.allowReserved!=="never")};pp$3.initFunction=function(node){node.id=null;if(this.options.ecmaVersion>=6){node.generator=node.expression=false}if(this.options.ecmaVersion>=8){node.async=false}};pp$3.parseMethod=function(isGenerator,isAsync,allowDirectSuper){var node=this.startNode(),oldYieldPos=this.yieldPos,oldAwaitPos=this.awaitPos,oldAwaitIdentPos=this.awaitIdentPos;this.initFunction(node);if(this.options.ecmaVersion>=6){node.generator=isGenerator}if(this.options.ecmaVersion>=8){node.async=!!isAsync}this.yieldPos=0;this.awaitPos=0;this.awaitIdentPos=0;this.enterScope(functionFlags(isAsync,node.generator)|SCOPE_SUPER|(allowDirectSuper?SCOPE_DIRECT_SUPER:0));this.expect(types.parenL);node.params=this.parseBindingList(types.parenR,false,this.options.ecmaVersion>=8);this.checkYieldAwaitInDefaultParams();this.parseFunctionBody(node,false,true);this.yieldPos=oldYieldPos;this.awaitPos=oldAwaitPos;this.awaitIdentPos=oldAwaitIdentPos;return this.finishNode(node,"FunctionExpression")};pp$3.parseArrowExpression=function(node,params,isAsync){var oldYieldPos=this.yieldPos,oldAwaitPos=this.awaitPos,oldAwaitIdentPos=this.awaitIdentPos;this.enterScope(functionFlags(isAsync,false)|SCOPE_ARROW);this.initFunction(node);if(this.options.ecmaVersion>=8){node.async=!!isAsync}this.yieldPos=0;this.awaitPos=0;this.awaitIdentPos=0;node.params=this.toAssignableList(params,true);this.parseFunctionBody(node,true,false);this.yieldPos=oldYieldPos;this.awaitPos=oldAwaitPos;this.awaitIdentPos=oldAwaitIdentPos;return this.finishNode(node,"ArrowFunctionExpression")};pp$3.parseFunctionBody=function(node,isArrowFunction,isMethod){var isExpression=isArrowFunction&&this.type!==types.braceL;var oldStrict=this.strict,useStrict=false;if(isExpression){node.body=this.parseMaybeAssign();node.expression=true;this.checkParams(node,false)}else{var nonSimple=this.options.ecmaVersion>=7&&!this.isSimpleParamList(node.params);if(!oldStrict||nonSimple){useStrict=this.strictDirective(this.end);if(useStrict&&nonSimple){this.raiseRecoverable(node.start,"Illegal 'use strict' directive in function with non-simple parameter list")}}var oldLabels=this.labels;this.labels=[];if(useStrict){this.strict=true}this.checkParams(node,!oldStrict&&!useStrict&&!isArrowFunction&&!isMethod&&this.isSimpleParamList(node.params));node.body=this.parseBlock(false);node.expression=false;this.adaptDirectivePrologue(node.body.body);this.labels=oldLabels}this.exitScope();if(this.strict&&node.id){this.checkLVal(node.id,BIND_OUTSIDE)}this.strict=oldStrict};pp$3.isSimpleParamList=function(params){for(var i=0,list=params;i-1||scope.functions.indexOf(name2)>-1||scope.var.indexOf(name2)>-1;scope.lexical.push(name2);if(this.inModule&&scope.flags&SCOPE_TOP){delete this.undefinedExports[name2]}}else if(bindingType===BIND_SIMPLE_CATCH){var scope$1=this.currentScope();scope$1.lexical.push(name2)}else if(bindingType===BIND_FUNCTION){var scope$2=this.currentScope();if(this.treatFunctionsAsVar){redeclared=scope$2.lexical.indexOf(name2)>-1}else{redeclared=scope$2.lexical.indexOf(name2)>-1||scope$2.var.indexOf(name2)>-1}scope$2.functions.push(name2)}else{for(var i=this.scopeStack.length-1;i>=0;--i){var scope$3=this.scopeStack[i];if(scope$3.lexical.indexOf(name2)>-1&&!(scope$3.flags&SCOPE_SIMPLE_CATCH&&scope$3.lexical[0]===name2)||!this.treatFunctionsAsVarInScope(scope$3)&&scope$3.functions.indexOf(name2)>-1){redeclared=true;break}scope$3.var.push(name2);if(this.inModule&&scope$3.flags&SCOPE_TOP){delete this.undefinedExports[name2]}if(scope$3.flags&SCOPE_VAR){break}}}if(redeclared){this.raiseRecoverable(pos,"Identifier '"+name2+"' has already been declared")}};pp$5.checkLocalExport=function(id){if(this.scopeStack[0].lexical.indexOf(id.name)===-1&&this.scopeStack[0].var.indexOf(id.name)===-1){this.undefinedExports[id.name]=id}};pp$5.currentScope=function(){return this.scopeStack[this.scopeStack.length-1]};pp$5.currentVarScope=function(){for(var i=this.scopeStack.length-1;;i--){var scope=this.scopeStack[i];if(scope.flags&SCOPE_VAR){return scope}}};pp$5.currentThisScope=function(){for(var i=this.scopeStack.length-1;;i--){var scope=this.scopeStack[i];if(scope.flags&SCOPE_VAR&&!(scope.flags&SCOPE_ARROW)){return scope}}};var Node=function Node2(parser,pos,loc){this.type="";this.start=pos;this.end=0;if(parser.options.locations){this.loc=new SourceLocation(parser,loc)}if(parser.options.directSourceFile){this.sourceFile=parser.options.directSourceFile}if(parser.options.ranges){this.range=[pos,0]}};var pp$6=Parser.prototype;pp$6.startNode=function(){return new Node(this,this.start,this.startLoc)};pp$6.startNodeAt=function(pos,loc){return new Node(this,pos,loc)};function finishNodeAt(node,type,pos,loc){node.type=type;node.end=pos;if(this.options.locations){node.loc.end=loc}if(this.options.ranges){node.range[1]=pos}return node}pp$6.finishNode=function(node,type){return finishNodeAt.call(this,node,type,this.lastTokEnd,this.lastTokEndLoc)};pp$6.finishNodeAt=function(node,type,pos,loc){return finishNodeAt.call(this,node,type,pos,loc)};var TokContext=function TokContext2(token,isExpr,preserveSpace,override,generator){this.token=token;this.isExpr=!!isExpr;this.preserveSpace=!!preserveSpace;this.override=override;this.generator=!!generator};var types$1={b_stat:new TokContext("{",false),b_expr:new TokContext("{",true),b_tmpl:new TokContext("${",false),p_stat:new TokContext("(",false),p_expr:new TokContext("(",true),q_tmpl:new TokContext("`",true,true,function(p){return p.tryReadTemplateToken()}),f_stat:new TokContext("function",false),f_expr:new TokContext("function",true),f_expr_gen:new TokContext("function",true,false,null,true),f_gen:new TokContext("function",false,false,null,true)};var pp$7=Parser.prototype;pp$7.initialContext=function(){return[types$1.b_stat]};pp$7.braceIsBlock=function(prevType){var parent=this.curContext();if(parent===types$1.f_expr||parent===types$1.f_stat){return true}if(prevType===types.colon&&(parent===types$1.b_stat||parent===types$1.b_expr)){return!parent.isExpr}if(prevType===types._return||prevType===types.name&&this.exprAllowed){return lineBreak.test(this.input.slice(this.lastTokEnd,this.start))}if(prevType===types._else||prevType===types.semi||prevType===types.eof||prevType===types.parenR||prevType===types.arrow){return true}if(prevType===types.braceL){return parent===types$1.b_stat}if(prevType===types._var||prevType===types._const||prevType===types.name){return false}return!this.exprAllowed};pp$7.inGeneratorContext=function(){for(var i=this.context.length-1;i>=1;i--){var context=this.context[i];if(context.token==="function"){return context.generator}}return false};pp$7.updateContext=function(prevType){var update,type=this.type;if(type.keyword&&prevType===types.dot){this.exprAllowed=false}else if(update=type.updateContext){update.call(this,prevType)}else{this.exprAllowed=type.beforeExpr}};types.parenR.updateContext=types.braceR.updateContext=function(){if(this.context.length===1){this.exprAllowed=true;return}var out=this.context.pop();if(out===types$1.b_stat&&this.curContext().token==="function"){out=this.context.pop()}this.exprAllowed=!out.isExpr};types.braceL.updateContext=function(prevType){this.context.push(this.braceIsBlock(prevType)?types$1.b_stat:types$1.b_expr);this.exprAllowed=true};types.dollarBraceL.updateContext=function(){this.context.push(types$1.b_tmpl);this.exprAllowed=true};types.parenL.updateContext=function(prevType){var statementParens=prevType===types._if||prevType===types._for||prevType===types._with||prevType===types._while;this.context.push(statementParens?types$1.p_stat:types$1.p_expr);this.exprAllowed=true};types.incDec.updateContext=function(){};types._function.updateContext=types._class.updateContext=function(prevType){if(prevType.beforeExpr&&prevType!==types.semi&&prevType!==types._else&&!(prevType===types._return&&lineBreak.test(this.input.slice(this.lastTokEnd,this.start)))&&!((prevType===types.colon||prevType===types.braceL)&&this.curContext()===types$1.b_stat)){this.context.push(types$1.f_expr)}else{this.context.push(types$1.f_stat)}this.exprAllowed=false};types.backQuote.updateContext=function(){if(this.curContext()===types$1.q_tmpl){this.context.pop()}else{this.context.push(types$1.q_tmpl)}this.exprAllowed=false};types.star.updateContext=function(prevType){if(prevType===types._function){var index=this.context.length-1;if(this.context[index]===types$1.f_expr){this.context[index]=types$1.f_expr_gen}else{this.context[index]=types$1.f_gen}}this.exprAllowed=true};types.name.updateContext=function(prevType){var allowed=false;if(this.options.ecmaVersion>=6&&prevType!==types.dot){if(this.value==="of"&&!this.exprAllowed||this.value==="yield"&&this.inGeneratorContext()){allowed=true}}this.exprAllowed=allowed};var ecma9BinaryProperties="ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS";var ecma10BinaryProperties=ecma9BinaryProperties+" Extended_Pictographic";var ecma11BinaryProperties=ecma10BinaryProperties;var unicodeBinaryProperties={9:ecma9BinaryProperties,10:ecma10BinaryProperties,11:ecma11BinaryProperties};var unicodeGeneralCategoryValues="Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu";var ecma9ScriptValues="Adlam Adlm Ahom Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb";var ecma10ScriptValues=ecma9ScriptValues+" Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd";var ecma11ScriptValues=ecma10ScriptValues+" Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho";var unicodeScriptValues={9:ecma9ScriptValues,10:ecma10ScriptValues,11:ecma11ScriptValues};var data={};function buildUnicodeData(ecmaVersion){var d=data[ecmaVersion]={binary:wordsRegexp(unicodeBinaryProperties[ecmaVersion]+" "+unicodeGeneralCategoryValues),nonBinary:{General_Category:wordsRegexp(unicodeGeneralCategoryValues),Script:wordsRegexp(unicodeScriptValues[ecmaVersion])}};d.nonBinary.Script_Extensions=d.nonBinary.Script;d.nonBinary.gc=d.nonBinary.General_Category;d.nonBinary.sc=d.nonBinary.Script;d.nonBinary.scx=d.nonBinary.Script_Extensions}buildUnicodeData(9);buildUnicodeData(10);buildUnicodeData(11);var pp$8=Parser.prototype;var RegExpValidationState=function RegExpValidationState2(parser){this.parser=parser;this.validFlags="gim"+(parser.options.ecmaVersion>=6?"uy":"")+(parser.options.ecmaVersion>=9?"s":"");this.unicodeProperties=data[parser.options.ecmaVersion>=11?11:parser.options.ecmaVersion];this.source="";this.flags="";this.start=0;this.switchU=false;this.switchN=false;this.pos=0;this.lastIntValue=0;this.lastStringValue="";this.lastAssertionIsQuantifiable=false;this.numCapturingParens=0;this.maxBackReference=0;this.groupNames=[];this.backReferenceNames=[]};RegExpValidationState.prototype.reset=function reset(start,pattern,flags){var unicode=flags.indexOf("u")!==-1;this.start=start|0;this.source=pattern+"";this.flags=flags;this.switchU=unicode&&this.parser.options.ecmaVersion>=6;this.switchN=unicode&&this.parser.options.ecmaVersion>=9};RegExpValidationState.prototype.raise=function raise(message){this.parser.raiseRecoverable(this.start,"Invalid regular expression: /"+this.source+"/: "+message)};RegExpValidationState.prototype.at=function at(i){var s=this.source;var l=s.length;if(i>=l){return-1}var c=s.charCodeAt(i);if(!this.switchU||c<=55295||c>=57344||i+1>=l){return c}var next=s.charCodeAt(i+1);return next>=56320&&next<=57343?(c<<10)+next-56613888:c};RegExpValidationState.prototype.nextIndex=function nextIndex(i){var s=this.source;var l=s.length;if(i>=l){return l}var c=s.charCodeAt(i),next;if(!this.switchU||c<=55295||c>=57344||i+1>=l||(next=s.charCodeAt(i+1))<56320||next>57343){return i+1}return i+2};RegExpValidationState.prototype.current=function current(){return this.at(this.pos)};RegExpValidationState.prototype.lookahead=function lookahead(){return this.at(this.nextIndex(this.pos))};RegExpValidationState.prototype.advance=function advance(){this.pos=this.nextIndex(this.pos)};RegExpValidationState.prototype.eat=function eat(ch){if(this.current()===ch){this.advance();return true}return false};function codePointToString(ch){if(ch<=65535){return String.fromCharCode(ch)}ch-=65536;return String.fromCharCode((ch>>10)+55296,(ch&1023)+56320)}pp$8.validateRegExpFlags=function(state2){var validFlags=state2.validFlags;var flags=state2.flags;for(var i=0;i-1){this.raise(state2.start,"Duplicate regular expression flag")}}};pp$8.validateRegExpPattern=function(state2){this.regexp_pattern(state2);if(!state2.switchN&&this.options.ecmaVersion>=9&&state2.groupNames.length>0){state2.switchN=true;this.regexp_pattern(state2)}};pp$8.regexp_pattern=function(state2){state2.pos=0;state2.lastIntValue=0;state2.lastStringValue="";state2.lastAssertionIsQuantifiable=false;state2.numCapturingParens=0;state2.maxBackReference=0;state2.groupNames.length=0;state2.backReferenceNames.length=0;this.regexp_disjunction(state2);if(state2.pos!==state2.source.length){if(state2.eat(41)){state2.raise("Unmatched ')'")}if(state2.eat(93)||state2.eat(125)){state2.raise("Lone quantifier brackets")}}if(state2.maxBackReference>state2.numCapturingParens){state2.raise("Invalid escape")}for(var i=0,list=state2.backReferenceNames;i=9){lookbehind=state2.eat(60)}if(state2.eat(61)||state2.eat(33)){this.regexp_disjunction(state2);if(!state2.eat(41)){state2.raise("Unterminated group")}state2.lastAssertionIsQuantifiable=!lookbehind;return true}}state2.pos=start;return false};pp$8.regexp_eatQuantifier=function(state2,noError){if(noError===void 0)noError=false;if(this.regexp_eatQuantifierPrefix(state2,noError)){state2.eat(63);return true}return false};pp$8.regexp_eatQuantifierPrefix=function(state2,noError){return state2.eat(42)||state2.eat(43)||state2.eat(63)||this.regexp_eatBracedQuantifier(state2,noError)};pp$8.regexp_eatBracedQuantifier=function(state2,noError){var start=state2.pos;if(state2.eat(123)){var min=0,max=-1;if(this.regexp_eatDecimalDigits(state2)){min=state2.lastIntValue;if(state2.eat(44)&&this.regexp_eatDecimalDigits(state2)){max=state2.lastIntValue}if(state2.eat(125)){if(max!==-1&&max=9){this.regexp_groupSpecifier(state2)}else if(state2.current()===63){state2.raise("Invalid group")}this.regexp_disjunction(state2);if(state2.eat(41)){state2.numCapturingParens+=1;return true}state2.raise("Unterminated group")}return false};pp$8.regexp_eatExtendedAtom=function(state2){return state2.eat(46)||this.regexp_eatReverseSolidusAtomEscape(state2)||this.regexp_eatCharacterClass(state2)||this.regexp_eatUncapturingGroup(state2)||this.regexp_eatCapturingGroup(state2)||this.regexp_eatInvalidBracedQuantifier(state2)||this.regexp_eatExtendedPatternCharacter(state2)};pp$8.regexp_eatInvalidBracedQuantifier=function(state2){if(this.regexp_eatBracedQuantifier(state2,true)){state2.raise("Nothing to repeat")}return false};pp$8.regexp_eatSyntaxCharacter=function(state2){var ch=state2.current();if(isSyntaxCharacter(ch)){state2.lastIntValue=ch;state2.advance();return true}return false};function isSyntaxCharacter(ch){return ch===36||ch>=40&&ch<=43||ch===46||ch===63||ch>=91&&ch<=94||ch>=123&&ch<=125}pp$8.regexp_eatPatternCharacters=function(state2){var start=state2.pos;var ch=0;while((ch=state2.current())!==-1&&!isSyntaxCharacter(ch)){state2.advance()}return state2.pos!==start};pp$8.regexp_eatExtendedPatternCharacter=function(state2){var ch=state2.current();if(ch!==-1&&ch!==36&&!(ch>=40&&ch<=43)&&ch!==46&&ch!==63&&ch!==91&&ch!==94&&ch!==124){state2.advance();return true}return false};pp$8.regexp_groupSpecifier=function(state2){if(state2.eat(63)){if(this.regexp_eatGroupName(state2)){if(state2.groupNames.indexOf(state2.lastStringValue)!==-1){state2.raise("Duplicate capture group name")}state2.groupNames.push(state2.lastStringValue);return}state2.raise("Invalid group")}};pp$8.regexp_eatGroupName=function(state2){state2.lastStringValue="";if(state2.eat(60)){if(this.regexp_eatRegExpIdentifierName(state2)&&state2.eat(62)){return true}state2.raise("Invalid capture group name")}return false};pp$8.regexp_eatRegExpIdentifierName=function(state2){state2.lastStringValue="";if(this.regexp_eatRegExpIdentifierStart(state2)){state2.lastStringValue+=codePointToString(state2.lastIntValue);while(this.regexp_eatRegExpIdentifierPart(state2)){state2.lastStringValue+=codePointToString(state2.lastIntValue)}return true}return false};pp$8.regexp_eatRegExpIdentifierStart=function(state2){var start=state2.pos;var ch=state2.current();state2.advance();if(ch===92&&this.regexp_eatRegExpUnicodeEscapeSequence(state2)){ch=state2.lastIntValue}if(isRegExpIdentifierStart(ch)){state2.lastIntValue=ch;return true}state2.pos=start;return false};function isRegExpIdentifierStart(ch){return isIdentifierStart(ch,true)||ch===36||ch===95}pp$8.regexp_eatRegExpIdentifierPart=function(state2){var start=state2.pos;var ch=state2.current();state2.advance();if(ch===92&&this.regexp_eatRegExpUnicodeEscapeSequence(state2)){ch=state2.lastIntValue}if(isRegExpIdentifierPart(ch)){state2.lastIntValue=ch;return true}state2.pos=start;return false};function isRegExpIdentifierPart(ch){return isIdentifierChar(ch,true)||ch===36||ch===95||ch===8204||ch===8205}pp$8.regexp_eatAtomEscape=function(state2){if(this.regexp_eatBackReference(state2)||this.regexp_eatCharacterClassEscape(state2)||this.regexp_eatCharacterEscape(state2)||state2.switchN&&this.regexp_eatKGroupName(state2)){return true}if(state2.switchU){if(state2.current()===99){state2.raise("Invalid unicode escape")}state2.raise("Invalid escape")}return false};pp$8.regexp_eatBackReference=function(state2){var start=state2.pos;if(this.regexp_eatDecimalEscape(state2)){var n=state2.lastIntValue;if(state2.switchU){if(n>state2.maxBackReference){state2.maxBackReference=n}return true}if(n<=state2.numCapturingParens){return true}state2.pos=start}return false};pp$8.regexp_eatKGroupName=function(state2){if(state2.eat(107)){if(this.regexp_eatGroupName(state2)){state2.backReferenceNames.push(state2.lastStringValue);return true}state2.raise("Invalid named reference")}return false};pp$8.regexp_eatCharacterEscape=function(state2){return this.regexp_eatControlEscape(state2)||this.regexp_eatCControlLetter(state2)||this.regexp_eatZero(state2)||this.regexp_eatHexEscapeSequence(state2)||this.regexp_eatRegExpUnicodeEscapeSequence(state2)||!state2.switchU&&this.regexp_eatLegacyOctalEscapeSequence(state2)||this.regexp_eatIdentityEscape(state2)};pp$8.regexp_eatCControlLetter=function(state2){var start=state2.pos;if(state2.eat(99)){if(this.regexp_eatControlLetter(state2)){return true}state2.pos=start}return false};pp$8.regexp_eatZero=function(state2){if(state2.current()===48&&!isDecimalDigit(state2.lookahead())){state2.lastIntValue=0;state2.advance();return true}return false};pp$8.regexp_eatControlEscape=function(state2){var ch=state2.current();if(ch===116){state2.lastIntValue=9;state2.advance();return true}if(ch===110){state2.lastIntValue=10;state2.advance();return true}if(ch===118){state2.lastIntValue=11;state2.advance();return true}if(ch===102){state2.lastIntValue=12;state2.advance();return true}if(ch===114){state2.lastIntValue=13;state2.advance();return true}return false};pp$8.regexp_eatControlLetter=function(state2){var ch=state2.current();if(isControlLetter(ch)){state2.lastIntValue=ch%32;state2.advance();return true}return false};function isControlLetter(ch){return ch>=65&&ch<=90||ch>=97&&ch<=122}pp$8.regexp_eatRegExpUnicodeEscapeSequence=function(state2){var start=state2.pos;if(state2.eat(117)){if(this.regexp_eatFixedHexDigits(state2,4)){var lead=state2.lastIntValue;if(state2.switchU&&lead>=55296&&lead<=56319){var leadSurrogateEnd=state2.pos;if(state2.eat(92)&&state2.eat(117)&&this.regexp_eatFixedHexDigits(state2,4)){var trail=state2.lastIntValue;if(trail>=56320&&trail<=57343){state2.lastIntValue=(lead-55296)*1024+(trail-56320)+65536;return true}}state2.pos=leadSurrogateEnd;state2.lastIntValue=lead}return true}if(state2.switchU&&state2.eat(123)&&this.regexp_eatHexDigits(state2)&&state2.eat(125)&&isValidUnicode(state2.lastIntValue)){return true}if(state2.switchU){state2.raise("Invalid unicode escape")}state2.pos=start}return false};function isValidUnicode(ch){return ch>=0&&ch<=1114111}pp$8.regexp_eatIdentityEscape=function(state2){if(state2.switchU){if(this.regexp_eatSyntaxCharacter(state2)){return true}if(state2.eat(47)){state2.lastIntValue=47;return true}return false}var ch=state2.current();if(ch!==99&&(!state2.switchN||ch!==107)){state2.lastIntValue=ch;state2.advance();return true}return false};pp$8.regexp_eatDecimalEscape=function(state2){state2.lastIntValue=0;var ch=state2.current();if(ch>=49&&ch<=57){do{state2.lastIntValue=10*state2.lastIntValue+(ch-48);state2.advance()}while((ch=state2.current())>=48&&ch<=57);return true}return false};pp$8.regexp_eatCharacterClassEscape=function(state2){var ch=state2.current();if(isCharacterClassEscape(ch)){state2.lastIntValue=-1;state2.advance();return true}if(state2.switchU&&this.options.ecmaVersion>=9&&(ch===80||ch===112)){state2.lastIntValue=-1;state2.advance();if(state2.eat(123)&&this.regexp_eatUnicodePropertyValueExpression(state2)&&state2.eat(125)){return true}state2.raise("Invalid property name")}return false};function isCharacterClassEscape(ch){return ch===100||ch===68||ch===115||ch===83||ch===119||ch===87}pp$8.regexp_eatUnicodePropertyValueExpression=function(state2){var start=state2.pos;if(this.regexp_eatUnicodePropertyName(state2)&&state2.eat(61)){var name2=state2.lastStringValue;if(this.regexp_eatUnicodePropertyValue(state2)){var value2=state2.lastStringValue;this.regexp_validateUnicodePropertyNameAndValue(state2,name2,value2);return true}}state2.pos=start;if(this.regexp_eatLoneUnicodePropertyNameOrValue(state2)){var nameOrValue=state2.lastStringValue;this.regexp_validateUnicodePropertyNameOrValue(state2,nameOrValue);return true}return false};pp$8.regexp_validateUnicodePropertyNameAndValue=function(state2,name2,value2){if(!has(state2.unicodeProperties.nonBinary,name2)){state2.raise("Invalid property name")}if(!state2.unicodeProperties.nonBinary[name2].test(value2)){state2.raise("Invalid property value")}};pp$8.regexp_validateUnicodePropertyNameOrValue=function(state2,nameOrValue){if(!state2.unicodeProperties.binary.test(nameOrValue)){state2.raise("Invalid property name")}};pp$8.regexp_eatUnicodePropertyName=function(state2){var ch=0;state2.lastStringValue="";while(isUnicodePropertyNameCharacter(ch=state2.current())){state2.lastStringValue+=codePointToString(ch);state2.advance()}return state2.lastStringValue!==""};function isUnicodePropertyNameCharacter(ch){return isControlLetter(ch)||ch===95}pp$8.regexp_eatUnicodePropertyValue=function(state2){var ch=0;state2.lastStringValue="";while(isUnicodePropertyValueCharacter(ch=state2.current())){state2.lastStringValue+=codePointToString(ch);state2.advance()}return state2.lastStringValue!==""};function isUnicodePropertyValueCharacter(ch){return isUnicodePropertyNameCharacter(ch)||isDecimalDigit(ch)}pp$8.regexp_eatLoneUnicodePropertyNameOrValue=function(state2){return this.regexp_eatUnicodePropertyValue(state2)};pp$8.regexp_eatCharacterClass=function(state2){if(state2.eat(91)){state2.eat(94);this.regexp_classRanges(state2);if(state2.eat(93)){return true}state2.raise("Unterminated character class")}return false};pp$8.regexp_classRanges=function(state2){while(this.regexp_eatClassAtom(state2)){var left=state2.lastIntValue;if(state2.eat(45)&&this.regexp_eatClassAtom(state2)){var right=state2.lastIntValue;if(state2.switchU&&(left===-1||right===-1)){state2.raise("Invalid character class")}if(left!==-1&&right!==-1&&left>right){state2.raise("Range out of order in character class")}}}};pp$8.regexp_eatClassAtom=function(state2){var start=state2.pos;if(state2.eat(92)){if(this.regexp_eatClassEscape(state2)){return true}if(state2.switchU){var ch$1=state2.current();if(ch$1===99||isOctalDigit(ch$1)){state2.raise("Invalid class escape")}state2.raise("Invalid escape")}state2.pos=start}var ch=state2.current();if(ch!==93){state2.lastIntValue=ch;state2.advance();return true}return false};pp$8.regexp_eatClassEscape=function(state2){var start=state2.pos;if(state2.eat(98)){state2.lastIntValue=8;return true}if(state2.switchU&&state2.eat(45)){state2.lastIntValue=45;return true}if(!state2.switchU&&state2.eat(99)){if(this.regexp_eatClassControlLetter(state2)){return true}state2.pos=start}return this.regexp_eatCharacterClassEscape(state2)||this.regexp_eatCharacterEscape(state2)};pp$8.regexp_eatClassControlLetter=function(state2){var ch=state2.current();if(isDecimalDigit(ch)||ch===95){state2.lastIntValue=ch%32;state2.advance();return true}return false};pp$8.regexp_eatHexEscapeSequence=function(state2){var start=state2.pos;if(state2.eat(120)){if(this.regexp_eatFixedHexDigits(state2,2)){return true}if(state2.switchU){state2.raise("Invalid escape")}state2.pos=start}return false};pp$8.regexp_eatDecimalDigits=function(state2){var start=state2.pos;var ch=0;state2.lastIntValue=0;while(isDecimalDigit(ch=state2.current())){state2.lastIntValue=10*state2.lastIntValue+(ch-48);state2.advance()}return state2.pos!==start};function isDecimalDigit(ch){return ch>=48&&ch<=57}pp$8.regexp_eatHexDigits=function(state2){var start=state2.pos;var ch=0;state2.lastIntValue=0;while(isHexDigit(ch=state2.current())){state2.lastIntValue=16*state2.lastIntValue+hexToInt(ch);state2.advance()}return state2.pos!==start};function isHexDigit(ch){return ch>=48&&ch<=57||ch>=65&&ch<=70||ch>=97&&ch<=102}function hexToInt(ch){if(ch>=65&&ch<=70){return 10+(ch-65)}if(ch>=97&&ch<=102){return 10+(ch-97)}return ch-48}pp$8.regexp_eatLegacyOctalEscapeSequence=function(state2){if(this.regexp_eatOctalDigit(state2)){var n1=state2.lastIntValue;if(this.regexp_eatOctalDigit(state2)){var n2=state2.lastIntValue;if(n1<=3&&this.regexp_eatOctalDigit(state2)){state2.lastIntValue=n1*64+n2*8+state2.lastIntValue}else{state2.lastIntValue=n1*8+n2}}else{state2.lastIntValue=n1}return true}return false};pp$8.regexp_eatOctalDigit=function(state2){var ch=state2.current();if(isOctalDigit(ch)){state2.lastIntValue=ch-48;state2.advance();return true}state2.lastIntValue=0;return false};function isOctalDigit(ch){return ch>=48&&ch<=55}pp$8.regexp_eatFixedHexDigits=function(state2,length){var start=state2.pos;state2.lastIntValue=0;for(var i=0;i=this.input.length){return this.finishToken(types.eof)}if(curContext.override){return curContext.override(this)}else{this.readToken(this.fullCharCodeAtPos())}};pp$9.readToken=function(code){if(isIdentifierStart(code,this.options.ecmaVersion>=6)||code===92){return this.readWord()}return this.getTokenFromCode(code)};pp$9.fullCharCodeAtPos=function(){var code=this.input.charCodeAt(this.pos);if(code<=55295||code>=57344){return code}var next=this.input.charCodeAt(this.pos+1);return(code<<10)+next-56613888};pp$9.skipBlockComment=function(){var startLoc=this.options.onComment&&this.curPosition();var start=this.pos,end=this.input.indexOf("*/",this.pos+=2);if(end===-1){this.raise(this.pos-2,"Unterminated comment")}this.pos=end+2;if(this.options.locations){lineBreakG.lastIndex=start;var match;while((match=lineBreakG.exec(this.input))&&match.index8&&ch<14||ch>=5760&&nonASCIIwhitespace.test(String.fromCharCode(ch))){++this.pos}else{break loop}}}};pp$9.finishToken=function(type,val){this.end=this.pos;if(this.options.locations){this.endLoc=this.curPosition()}var prevType=this.type;this.type=type;this.value=val;this.updateContext(prevType)};pp$9.readToken_dot=function(){var next=this.input.charCodeAt(this.pos+1);if(next>=48&&next<=57){return this.readNumber(true)}var next2=this.input.charCodeAt(this.pos+2);if(this.options.ecmaVersion>=6&&next===46&&next2===46){this.pos+=3;return this.finishToken(types.ellipsis)}else{++this.pos;return this.finishToken(types.dot)}};pp$9.readToken_slash=function(){var next=this.input.charCodeAt(this.pos+1);if(this.exprAllowed){++this.pos;return this.readRegexp()}if(next===61){return this.finishOp(types.assign,2)}return this.finishOp(types.slash,1)};pp$9.readToken_mult_modulo_exp=function(code){var next=this.input.charCodeAt(this.pos+1);var size=1;var tokentype=code===42?types.star:types.modulo;if(this.options.ecmaVersion>=7&&code===42&&next===42){++size;tokentype=types.starstar;next=this.input.charCodeAt(this.pos+2)}if(next===61){return this.finishOp(types.assign,size+1)}return this.finishOp(tokentype,size)};pp$9.readToken_pipe_amp=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===code){return this.finishOp(code===124?types.logicalOR:types.logicalAND,2)}if(next===61){return this.finishOp(types.assign,2)}return this.finishOp(code===124?types.bitwiseOR:types.bitwiseAND,1)};pp$9.readToken_caret=function(){var next=this.input.charCodeAt(this.pos+1);if(next===61){return this.finishOp(types.assign,2)}return this.finishOp(types.bitwiseXOR,1)};pp$9.readToken_plus_min=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===code){if(next===45&&!this.inModule&&this.input.charCodeAt(this.pos+2)===62&&(this.lastTokEnd===0||lineBreak.test(this.input.slice(this.lastTokEnd,this.pos)))){this.skipLineComment(3);this.skipSpace();return this.nextToken()}return this.finishOp(types.incDec,2)}if(next===61){return this.finishOp(types.assign,2)}return this.finishOp(types.plusMin,1)};pp$9.readToken_lt_gt=function(code){var next=this.input.charCodeAt(this.pos+1);var size=1;if(next===code){size=code===62&&this.input.charCodeAt(this.pos+2)===62?3:2;if(this.input.charCodeAt(this.pos+size)===61){return this.finishOp(types.assign,size+1)}return this.finishOp(types.bitShift,size)}if(next===33&&code===60&&!this.inModule&&this.input.charCodeAt(this.pos+2)===45&&this.input.charCodeAt(this.pos+3)===45){this.skipLineComment(4);this.skipSpace();return this.nextToken()}if(next===61){size=2}return this.finishOp(types.relational,size)};pp$9.readToken_eq_excl=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===61){return this.finishOp(types.equality,this.input.charCodeAt(this.pos+2)===61?3:2)}if(code===61&&next===62&&this.options.ecmaVersion>=6){this.pos+=2;return this.finishToken(types.arrow)}return this.finishOp(code===61?types.eq:types.prefix,1)};pp$9.getTokenFromCode=function(code){switch(code){case 46:return this.readToken_dot();case 40:++this.pos;return this.finishToken(types.parenL);case 41:++this.pos;return this.finishToken(types.parenR);case 59:++this.pos;return this.finishToken(types.semi);case 44:++this.pos;return this.finishToken(types.comma);case 91:++this.pos;return this.finishToken(types.bracketL);case 93:++this.pos;return this.finishToken(types.bracketR);case 123:++this.pos;return this.finishToken(types.braceL);case 125:++this.pos;return this.finishToken(types.braceR);case 58:++this.pos;return this.finishToken(types.colon);case 63:++this.pos;return this.finishToken(types.question);case 96:if(this.options.ecmaVersion<6){break}++this.pos;return this.finishToken(types.backQuote);case 48:var next=this.input.charCodeAt(this.pos+1);if(next===120||next===88){return this.readRadixNumber(16)}if(this.options.ecmaVersion>=6){if(next===111||next===79){return this.readRadixNumber(8)}if(next===98||next===66){return this.readRadixNumber(2)}}case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return this.readNumber(false);case 34:case 39:return this.readString(code);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo_exp(code);case 124:case 38:return this.readToken_pipe_amp(code);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(code);case 60:case 62:return this.readToken_lt_gt(code);case 61:case 33:return this.readToken_eq_excl(code);case 126:return this.finishOp(types.prefix,1)}this.raise(this.pos,"Unexpected character '"+codePointToString$1(code)+"'")};pp$9.finishOp=function(type,size){var str=this.input.slice(this.pos,this.pos+size);this.pos+=size;return this.finishToken(type,str)};pp$9.readRegexp=function(){var escaped,inClass,start=this.pos;for(;;){if(this.pos>=this.input.length){this.raise(start,"Unterminated regular expression")}var ch=this.input.charAt(this.pos);if(lineBreak.test(ch)){this.raise(start,"Unterminated regular expression")}if(!escaped){if(ch==="["){inClass=true}else if(ch==="]"&&inClass){inClass=false}else if(ch==="/"&&!inClass){break}escaped=ch==="\\"}else{escaped=false}++this.pos}var pattern=this.input.slice(start,this.pos);++this.pos;var flagsStart=this.pos;var flags=this.readWord1();if(this.containsEsc){this.unexpected(flagsStart)}var state2=this.regexpState||(this.regexpState=new RegExpValidationState(this));state2.reset(start,pattern,flags);this.validateRegExpFlags(state2);this.validateRegExpPattern(state2);var value2=null;try{value2=new RegExp(pattern,flags)}catch(e){}return this.finishToken(types.regexp,{pattern,flags,value:value2})};pp$9.readInt=function(radix,len){var start=this.pos,total=0;for(var i=0,e=len==null?Infinity:len;i=97){val=code-97+10}else if(code>=65){val=code-65+10}else if(code>=48&&code<=57){val=code-48}else{val=Infinity}if(val>=radix){break}++this.pos;total=total*radix+val}if(this.pos===start||len!=null&&this.pos-start!==len){return null}return total};pp$9.readRadixNumber=function(radix){var start=this.pos;this.pos+=2;var val=this.readInt(radix);if(val==null){this.raise(this.start+2,"Expected number in radix "+radix)}if(this.options.ecmaVersion>=11&&this.input.charCodeAt(this.pos)===110){val=typeof BigInt!=="undefined"?BigInt(this.input.slice(start,this.pos)):null;++this.pos}else if(isIdentifierStart(this.fullCharCodeAtPos())){this.raise(this.pos,"Identifier directly after number")}return this.finishToken(types.num,val)};pp$9.readNumber=function(startsWithDot){var start=this.pos;if(!startsWithDot&&this.readInt(10)===null){this.raise(start,"Invalid number")}var octal=this.pos-start>=2&&this.input.charCodeAt(start)===48;if(octal&&this.strict){this.raise(start,"Invalid number")}var next=this.input.charCodeAt(this.pos);if(!octal&&!startsWithDot&&this.options.ecmaVersion>=11&&next===110){var str$1=this.input.slice(start,this.pos);var val$1=typeof BigInt!=="undefined"?BigInt(str$1):null;++this.pos;if(isIdentifierStart(this.fullCharCodeAtPos())){this.raise(this.pos,"Identifier directly after number")}return this.finishToken(types.num,val$1)}if(octal&&/[89]/.test(this.input.slice(start,this.pos))){octal=false}if(next===46&&!octal){++this.pos;this.readInt(10);next=this.input.charCodeAt(this.pos)}if((next===69||next===101)&&!octal){next=this.input.charCodeAt(++this.pos);if(next===43||next===45){++this.pos}if(this.readInt(10)===null){this.raise(start,"Invalid number")}}if(isIdentifierStart(this.fullCharCodeAtPos())){this.raise(this.pos,"Identifier directly after number")}var str=this.input.slice(start,this.pos);var val=octal?parseInt(str,8):parseFloat(str);return this.finishToken(types.num,val)};pp$9.readCodePoint=function(){var ch=this.input.charCodeAt(this.pos),code;if(ch===123){if(this.options.ecmaVersion<6){this.unexpected()}var codePos=++this.pos;code=this.readHexChar(this.input.indexOf("}",this.pos)-this.pos);++this.pos;if(code>1114111){this.invalidStringToken(codePos,"Code point out of bounds")}}else{code=this.readHexChar(4)}return code};function codePointToString$1(code){if(code<=65535){return String.fromCharCode(code)}code-=65536;return String.fromCharCode((code>>10)+55296,(code&1023)+56320)}pp$9.readString=function(quote){var out="",chunkStart=++this.pos;for(;;){if(this.pos>=this.input.length){this.raise(this.start,"Unterminated string constant")}var ch=this.input.charCodeAt(this.pos);if(ch===quote){break}if(ch===92){out+=this.input.slice(chunkStart,this.pos);out+=this.readEscapedChar(false);chunkStart=this.pos}else{if(isNewLine(ch,this.options.ecmaVersion>=10)){this.raise(this.start,"Unterminated string constant")}++this.pos}}out+=this.input.slice(chunkStart,this.pos++);return this.finishToken(types.string,out)};var INVALID_TEMPLATE_ESCAPE_ERROR={};pp$9.tryReadTemplateToken=function(){this.inTemplateElement=true;try{this.readTmplToken()}catch(err){if(err===INVALID_TEMPLATE_ESCAPE_ERROR){this.readInvalidTemplateToken()}else{throw err}}this.inTemplateElement=false};pp$9.invalidStringToken=function(position,message){if(this.inTemplateElement&&this.options.ecmaVersion>=9){throw INVALID_TEMPLATE_ESCAPE_ERROR}else{this.raise(position,message)}};pp$9.readTmplToken=function(){var out="",chunkStart=this.pos;for(;;){if(this.pos>=this.input.length){this.raise(this.start,"Unterminated template")}var ch=this.input.charCodeAt(this.pos);if(ch===96||ch===36&&this.input.charCodeAt(this.pos+1)===123){if(this.pos===this.start&&(this.type===types.template||this.type===types.invalidTemplate)){if(ch===36){this.pos+=2;return this.finishToken(types.dollarBraceL)}else{++this.pos;return this.finishToken(types.backQuote)}}out+=this.input.slice(chunkStart,this.pos);return this.finishToken(types.template,out)}if(ch===92){out+=this.input.slice(chunkStart,this.pos);out+=this.readEscapedChar(true);chunkStart=this.pos}else if(isNewLine(ch)){out+=this.input.slice(chunkStart,this.pos);++this.pos;switch(ch){case 13:if(this.input.charCodeAt(this.pos)===10){++this.pos}case 10:out+="\n";break;default:out+=String.fromCharCode(ch);break}if(this.options.locations){++this.curLine;this.lineStart=this.pos}chunkStart=this.pos}else{++this.pos}}};pp$9.readInvalidTemplateToken=function(){for(;this.pos=48&&ch<=55){var octalStr=this.input.substr(this.pos-1,3).match(/^[0-7]+/)[0];var octal=parseInt(octalStr,8);if(octal>255){octalStr=octalStr.slice(0,-1);octal=parseInt(octalStr,8)}this.pos+=octalStr.length-1;ch=this.input.charCodeAt(this.pos);if((octalStr!=="0"||ch===56||ch===57)&&(this.strict||inTemplate)){this.invalidStringToken(this.pos-1-octalStr.length,inTemplate?"Octal literal in template string":"Octal literal in strict mode")}return String.fromCharCode(octal)}if(isNewLine(ch)){return""}return String.fromCharCode(ch)}};pp$9.readHexChar=function(len){var codePos=this.pos;var n=this.readInt(16,len);if(n===null){this.invalidStringToken(codePos,"Bad character escape sequence")}return n};pp$9.readWord1=function(){this.containsEsc=false;var word="",first=true,chunkStart=this.pos;var astral=this.options.ecmaVersion>=6;while(this.pos0){recording.pop()}}function insertVariable(name2,value2){variables[name2]=value2}function getEntity(value2){const name2=entityNames[value2];if(name2){return contextName+"."+name2}return value2}function setIndent(spaces){indent=" ".repeat(spaces)}function addVariable(value2,source){const variableName=`${contextName}Variable${contextVariables.length}`;recording.push(`${indent}const ${variableName} = ${source};`);contextVariables.push(value2);return variableName}function writePPM(width,height){const sourceVariable=`${contextName}Variable${contextVariables.length}`;const imageVariable=`imageDatum${imageCount}`;recording.push(`${indent}let ${imageVariable} = ["P3\\n# ${readPixelsFile}.ppm\\n", ${width}, ' ', ${height}, "\\n255\\n"].join("");`);recording.push(`${indent}for (let i = 0; i < ${imageVariable}.length; i += 4) {`);recording.push(`${indent} ${imageVariable} += ${sourceVariable}[i] + ' ' + ${sourceVariable}[i + 1] + ' ' + ${sourceVariable}[i + 2] + ' ';`);recording.push(`${indent}}`);recording.push(`${indent}if (typeof require !== "undefined") {`);recording.push(`${indent} require('fs').writeFileSync('./${readPixelsFile}.ppm', ${imageVariable});`);recording.push(`${indent}}`);imageCount++}function addComment(value2){recording.push(`${indent}// ${value2}`)}function checkThrowError(){recording.push(`${indent}(() => { - ${indent}const error = ${contextName}.getError(); - ${indent}if (error !== ${contextName}.NONE) { - ${indent} const names = Object.getOwnPropertyNames(gl); - ${indent} for (let i = 0; i < names.length; i++) { - ${indent} const name = names[i]; - ${indent} if (${contextName}[name] === error) { - ${indent} throw new Error('${contextName} threw ' + name); - ${indent} } - ${indent} } - ${indent}} - ${indent}})();`)}function methodCallToString(method,args){return`${contextName}.${method}(${argumentsToString(args,{contextName,contextVariables,getEntity,addVariable,variables,onUnrecognizedArgumentLookup})})`}function getVariableName(value2){if(variables){for(const name2 in variables){if(variables[name2]===value2){return name2}}}return null}function getContextVariableName(value2){const i=contextVariables.indexOf(value2);if(i!==-1){return`${contextName}Variable${i}`}return null}}function glExtensionWiretap(extension,options){const proxy=new Proxy(extension,{get:listen});const extensionEntityNames={};const{contextName,contextVariables,getEntity,useTrackablePrimitives,recording,variables,indent,onUnrecognizedArgumentLookup}=options;return proxy;function listen(obj,property){if(typeof obj[property]==="function"){return function(){switch(property){case"drawBuffersWEBGL":recording.push(`${indent}${contextName}.drawBuffersWEBGL([${argumentsToString(arguments[0],{contextName,contextVariables,getEntity:getExtensionEntity,addVariable,variables,onUnrecognizedArgumentLookup})}]);`);return extension.drawBuffersWEBGL(arguments[0])}let result=extension[property].apply(extension,arguments);switch(typeof result){case"undefined":recording.push(`${indent}${methodCallToString(property,arguments)};`);return;case"number":case"boolean":if(useTrackablePrimitives&&contextVariables.indexOf(trackablePrimitive(result))===-1){recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property,arguments)};`);contextVariables.push(result=trackablePrimitive(result))}else{recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property,arguments)};`);contextVariables.push(result)}break;default:if(result===null){recording.push(`${methodCallToString(property,arguments)};`)}else{recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property,arguments)};`)}contextVariables.push(result)}return result}}extensionEntityNames[extension[property]]=property;return extension[property]}function getExtensionEntity(value2){if(extensionEntityNames.hasOwnProperty(value2)){return`${contextName}.${extensionEntityNames[value2]}`}return getEntity(value2)}function methodCallToString(method,args){return`${contextName}.${method}(${argumentsToString(args,{contextName,contextVariables,getEntity:getExtensionEntity,addVariable,variables,onUnrecognizedArgumentLookup})})`}function addVariable(value2,source){const variableName=`${contextName}Variable${contextVariables.length}`;contextVariables.push(value2);recording.push(`${indent}const ${variableName} = ${source};`);return variableName}}function argumentsToString(args,options){const{variables,onUnrecognizedArgumentLookup}=options;return Array.from(args).map(arg=>{const variableName=getVariableName(arg);if(variableName){return variableName}return argumentToString(arg,options)}).join(", ");function getVariableName(value2){if(variables){for(const name2 in variables){if(!variables.hasOwnProperty(name2))continue;if(variables[name2]===value2){return name2}}}if(onUnrecognizedArgumentLookup){return onUnrecognizedArgumentLookup(value2)}return null}}function argumentToString(arg,options){const{contextName,contextVariables,getEntity,addVariable,onUnrecognizedArgumentLookup}=options;if(typeof arg==="undefined"){return"undefined"}if(arg===null){return"null"}const i=contextVariables.indexOf(arg);if(i>-1){return`${contextName}Variable${i}`}switch(arg.constructor.name){case"String":const hasLines=/\n/.test(arg);const hasSingleQuotes=/'/.test(arg);const hasDoubleQuotes=/"/.test(arg);if(hasLines){return"`"+arg+"`"}else if(hasSingleQuotes&&!hasDoubleQuotes){return'"'+arg+'"'}else if(!hasSingleQuotes&&hasDoubleQuotes){return"'"+arg+"'"}else{return"'"+arg+"'"}case"Number":return getEntity(arg);case"Boolean":return getEntity(arg);case"Array":return addVariable(arg,`new ${arg.constructor.name}([${Array.from(arg).join(",")}])`);case"Float32Array":case"Uint8Array":case"Uint16Array":case"Int32Array":return addVariable(arg,`new ${arg.constructor.name}(${JSON.stringify(Array.from(arg))})`);default:if(onUnrecognizedArgumentLookup){const instantiationString=onUnrecognizedArgumentLookup(arg);if(instantiationString){return instantiationString}}throw new Error(`unrecognized argument type ${arg.constructor.name}`)}}function trackablePrimitive(value2){return new value2.constructor(value2)}if(typeof module3!=="undefined"){module3.exports={glWiretap,glExtensionWiretap}}if(typeof window!=="undefined"){glWiretap.glExtensionWiretap=glExtensionWiretap;window.glWiretap=glWiretap}},{}],4:[function(require2,module3,exports3){function setupArguments(args){const newArguments=new Array(args.length);for(let i=0;i{kernel.output=setupOutput(output);if(kernel.graphical){setupGraphical(kernel)}};kernel.toJSON=()=>{throw new Error("Not usable with gpuMock")};kernel.setConstants=flag=>{kernel.constants=flag;return kernel};kernel.setGraphical=flag=>{kernel.graphical=flag;return kernel};kernel.setCanvas=flag=>{kernel.canvas=flag;return kernel};kernel.setContext=flag=>{kernel.context=flag;return kernel};kernel.destroy=()=>{};kernel.validateSettings=()=>{};if(kernel.graphical&&kernel.output){setupGraphical(kernel)}kernel.exec=function(){return new Promise((resolve,reject)=>{try{resolve(kernel.apply(kernel,arguments))}catch(e){reject(e)}})};kernel.getPixels=flip=>{const{x:x2,y}=kernel.output;return flip?flipPixels(kernel._imageData.data,x2,y):kernel._imageData.data.slice(0)};kernel.color=function(r,g,b,a){if(typeof a==="undefined"){a=1}r=Math.floor(r*255);g=Math.floor(g*255);b=Math.floor(b*255);a=Math.floor(a*255);const width=kernel.output.x;const height=kernel.output.y;const x2=kernel.thread.x;const y=height-kernel.thread.y-1;const index=x2+y*width;kernel._colorData[index*4+0]=r;kernel._colorData[index*4+1]=g;kernel._colorData[index*4+2]=b;kernel._colorData[index*4+3]=a};const mockMethod=()=>kernel;const methods=["setWarnVarUsage","setArgumentTypes","setTactic","setOptimizeFloatMemory","setDebug","setLoopMaxIterations","setConstantTypes","setFunctions","setNativeFunctions","setInjectedNative","setPipeline","setPrecision","setOutputToTexture","setImmutable","setStrictIntegers","setDynamicOutput","setHardcodeConstants","setDynamicArguments","setUseLegacyEncoder","setWarnVarUsage","addSubKernel"];for(let i=0;i0){retArr.push(", ")}retArr.push("user_");retArr.push(argumentName)}retArr.push(") {\n")}for(let i=0;i0){retArr.push(initArr.join(""),";\n")}retArr.push(`for (let ${iVariableName}=0;${iVariableName}0){retArr.push(`if (!${testArr.join("")}) break; -`)}retArr.push(bodyArr.join(""));retArr.push(` -${updateArr.join("")};`);retArr.push("}\n")}return retArr}astWhileStatement(whileNode,retArr){if(whileNode.type!=="WhileStatement"){throw this.astErrorOutput("Invalid while statement",whileNode)}retArr.push("for (let i = 0; i < LOOP_MAX; i++) {");retArr.push("if (");this.astGeneric(whileNode.test,retArr);retArr.push(") {\n");this.astGeneric(whileNode.body,retArr);retArr.push("} else {\n");retArr.push("break;\n");retArr.push("}\n");retArr.push("}\n");return retArr}astDoWhileStatement(doWhileNode,retArr){if(doWhileNode.type!=="DoWhileStatement"){throw this.astErrorOutput("Invalid while statement",doWhileNode)}retArr.push("for (let i = 0; i < LOOP_MAX; i++) {");this.astGeneric(doWhileNode.body,retArr);retArr.push("if (!");this.astGeneric(doWhileNode.test,retArr);retArr.push(") {\n");retArr.push("break;\n");retArr.push("}\n");retArr.push("}\n");return retArr}astAssignmentExpression(assNode,retArr){const declaration=this.getDeclaration(assNode.left);if(declaration&&!declaration.assignable){throw this.astErrorOutput(`Variable ${assNode.left.name} is not assignable here`,assNode)}this.astGeneric(assNode.left,retArr);retArr.push(assNode.operator);this.astGeneric(assNode.right,retArr);return retArr}astBlockStatement(bNode,retArr){if(this.isState("loop-body")){this.pushState("block-body");for(let i=0;i0){retArr.push(",")}const declaration=declarations[i];const info=this.getDeclaration(declaration.id);if(!info.valueType){info.valueType=this.getType(declaration.init)}this.astGeneric(declaration,retArr)}if(!this.isState("in-for-loop-init")){retArr.push(";")}return retArr}astIfStatement(ifNode,retArr){retArr.push("if (");this.astGeneric(ifNode.test,retArr);retArr.push(")");if(ifNode.consequent.type==="BlockStatement"){this.astGeneric(ifNode.consequent,retArr)}else{retArr.push(" {\n");this.astGeneric(ifNode.consequent,retArr);retArr.push("\n}\n")}if(ifNode.alternate){retArr.push("else ");if(ifNode.alternate.type==="BlockStatement"||ifNode.alternate.type==="IfStatement"){this.astGeneric(ifNode.alternate,retArr)}else{retArr.push(" {\n");this.astGeneric(ifNode.alternate,retArr);retArr.push("\n}\n")}}return retArr}astSwitchStatement(ast,retArr){const{discriminant,cases}=ast;retArr.push("switch (");this.astGeneric(discriminant,retArr);retArr.push(") {\n");for(let i=0;i0){retArr.push("break;\n")}continue}retArr.push("case ");this.astGeneric(cases[i].test,retArr);retArr.push(":\n");if(cases[i].consequent&&cases[i].consequent.length>0){this.astGeneric(cases[i].consequent,retArr);retArr.push("break;\n")}}retArr.push("\n}")}astThisExpression(tNode,retArr){retArr.push("_this");return retArr}astMemberExpression(mNode,retArr){const{signature,type,property,xProperty,yProperty,zProperty,name:name2,origin}=this.getMemberExpressionDetails(mNode);switch(signature){case"this.thread.value":retArr.push(`_this.thread.${name2}`);return retArr;case"this.output.value":switch(name2){case"x":retArr.push("outputX");break;case"y":retArr.push("outputY");break;case"z":retArr.push("outputZ");break;default:throw this.astErrorOutput("Unexpected expression",mNode)}return retArr;case"value":throw this.astErrorOutput("Unexpected expression",mNode);case"value[]":case"value[][]":case"value[][][]":case"value.value":if(origin==="Math"){retArr.push(Math[name2]);return retArr}switch(property){case"r":retArr.push(`user_${name2}[0]`);return retArr;case"g":retArr.push(`user_${name2}[1]`);return retArr;case"b":retArr.push(`user_${name2}[2]`);return retArr;case"a":retArr.push(`user_${name2}[3]`);return retArr}break;case"this.constants.value":case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":break;case"fn()[]":this.astGeneric(mNode.object,retArr);retArr.push("[");this.astGeneric(mNode.property,retArr);retArr.push("]");return retArr;case"fn()[][]":this.astGeneric(mNode.object.object,retArr);retArr.push("[");this.astGeneric(mNode.object.property,retArr);retArr.push("]");retArr.push("[");this.astGeneric(mNode.property,retArr);retArr.push("]");return retArr;default:throw this.astErrorOutput("Unexpected expression",mNode)}if(!mNode.computed){switch(type){case"Number":case"Integer":case"Float":case"Boolean":retArr.push(`${origin}_${name2}`);return retArr}}const markupName=`${origin}_${name2}`;switch(type){case"Array(2)":case"Array(3)":case"Array(4)":case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":case"HTMLImageArray":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":case"HTMLImage":default:let size;let isInput;if(origin==="constants"){const constant=this.constants[name2];isInput=this.constantTypes[name2]==="Input";size=isInput?constant.size:null}else{isInput=this.isInput(name2);size=isInput?this.argumentSizes[this.argumentNames.indexOf(name2)]:null}retArr.push(`${markupName}`);if(zProperty&&yProperty){if(isInput){retArr.push("[(");this.astGeneric(zProperty,retArr);retArr.push(`*${this.dynamicArguments?"(outputY * outputX)":size[1]*size[0]})+(`);this.astGeneric(yProperty,retArr);retArr.push(`*${this.dynamicArguments?"outputX":size[0]})+`);this.astGeneric(xProperty,retArr);retArr.push("]")}else{retArr.push("[");this.astGeneric(zProperty,retArr);retArr.push("]");retArr.push("[");this.astGeneric(yProperty,retArr);retArr.push("]");retArr.push("[");this.astGeneric(xProperty,retArr);retArr.push("]")}}else if(yProperty){if(isInput){retArr.push("[(");this.astGeneric(yProperty,retArr);retArr.push(`*${this.dynamicArguments?"outputX":size[0]})+`);this.astGeneric(xProperty,retArr);retArr.push("]")}else{retArr.push("[");this.astGeneric(yProperty,retArr);retArr.push("]");retArr.push("[");this.astGeneric(xProperty,retArr);retArr.push("]")}}else if(typeof xProperty!=="undefined"){retArr.push("[");this.astGeneric(xProperty,retArr);retArr.push("]")}}return retArr}astCallExpression(ast,retArr){if(ast.type!=="CallExpression"){throw this.astErrorOutput("Unknown CallExpression",ast)}let functionName=this.astMemberExpressionUnroll(ast.callee);if(this.calledFunctions.indexOf(functionName)<0){this.calledFunctions.push(functionName)}const isMathFunction=this.isAstMathFunction(ast);if(this.onFunctionCall){this.onFunctionCall(this.name,functionName,ast.arguments)}retArr.push(functionName);retArr.push("(");const targetTypes=this.lookupFunctionArgumentTypes(functionName)||[];for(let i=0;i0){retArr.push(", ")}this.astGeneric(argument,retArr)}retArr.push(")");return retArr}astArrayExpression(arrNode,retArr){const returnType=this.getType(arrNode);const arrLen=arrNode.elements.length;const elements=[];for(let i=0;i{switch(propertyName){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(cpuKernel[propertyName])},findDependency:(object,name3)=>{return null}});const getPixelsFn=utils.flattenFunctionToString((useFunctionKeyword?"function ":"")+cpuKernel.getPixels.toString(),{thisLookup:propertyName=>{switch(propertyName){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(cpuKernel[propertyName])},findDependency:()=>{return null}});thisProperties.push(" _imageData,"," _colorData,",` color: ${colorFn},`);beforeReturn.push(` kernel.getPixels = ${getPixelsFn};`)}const constantTypes=[];const constantKeys=Object.keys(cpuKernel.constantTypes);for(let i=0;i{if(object==="this"){return(useFunctionKeyword?"function ":"")+cpuKernel[name3].toString()}return null},thisLookup:propertyName=>{switch(propertyName){case"canvas":return;case"context":return"context"}}});beforeReturn.push(flattenedImageTo3DArray);thisProperties.push(` _mediaTo2DArray,`);thisProperties.push(` _imageTo3DArray,`)}else if(cpuKernel.argumentTypes.indexOf("HTMLImage")!==-1||constantTypes.indexOf("HTMLImage")!==-1){const flattenedImageTo2DArray=utils.flattenFunctionToString((useFunctionKeyword?"function ":"")+cpuKernel._mediaTo2DArray.toString(),{findDependency:(object,name3)=>{return null},thisLookup:propertyName=>{switch(propertyName){case"canvas":return"settings.canvas";case"context":return"settings.context"}throw new Error("unhandled thisLookup")}});beforeReturn.push(flattenedImageTo2DArray);thisProperties.push(` _mediaTo2DArray,`)}return`function(settings) { - ${header.join("\n")} - for (const p in _constantTypes) { - if (!_constantTypes.hasOwnProperty(p)) continue; - const type = _constantTypes[p]; - switch (type) { - case 'Number': - case 'Integer': - case 'Float': - case 'Boolean': - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - case 'Matrix(2)': - case 'Matrix(3)': - case 'Matrix(4)': - if (incomingConstants.hasOwnProperty(p)) { - console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned'); - } - continue; - } - if (!incomingConstants.hasOwnProperty(p)) { - throw new Error('constant ' + p + ' not found'); - } - _constants[p] = incomingConstants[p]; - } - const kernel = (function() { - ${cpuKernel._kernelString} - }) - .apply({ ${thisProperties.join("\n")} }); - ${beforeReturn.join("\n")} - return kernel; - }`}module3.exports={cpuKernelString}},{"../../utils":114}],8:[function(require2,module3,exports3){const{Kernel}=require2("../kernel");const{FunctionBuilder}=require2("../function-builder");const{CPUFunctionNode}=require2("./function-node");const{utils}=require2("../../utils");const{cpuKernelString}=require2("./kernel-string");class CPUKernel extends Kernel{static getFeatures(){return this.features}static get features(){return Object.freeze({kernelMap:true,isIntegerDivisionAccurate:true})}static get isSupported(){return true}static isContextMatch(context){return false}static get mode(){return"cpu"}static nativeFunctionArguments(){return null}static nativeFunctionReturnType(){throw new Error(`Looking up native function return type not supported on ${this.name}`)}static combineKernels(combinedKernel){return combinedKernel}static getSignature(kernel,argumentTypes){return"cpu"+(argumentTypes.length>0?":"+argumentTypes.join(","):"")}constructor(source,settings){super(source,settings);this.mergeSettings(source.settings||settings);this._imageData=null;this._colorData=null;this._kernelString=null;this._prependedString=[];this.thread={x:0,y:0,z:0};this.translatedSources=null}initCanvas(){if(typeof document!=="undefined"){return document.createElement("canvas")}else if(typeof OffscreenCanvas!=="undefined"){return new OffscreenCanvas(0,0)}}initContext(){if(!this.canvas)return null;return this.canvas.getContext("2d")}initPlugins(settings){return[]}validateSettings(args){if(!this.output||this.output.length===0){if(args.length!==1){throw new Error("Auto output only supported for kernels with only one input")}const argType=utils.getVariableType(args[0],this.strictIntegers);if(argType==="Array"){this.output=utils.getDimensions(argType)}else if(argType==="NumberTexture"||argType==="ArrayTexture(4)"){this.output=args[0].output}else{throw new Error("Auto output not supported for input type: "+argType)}}if(this.graphical){if(this.output.length!==2){throw new Error("Output must have 2 dimensions on graphical mode")}}this.checkOutput()}translateSource(){this.leadingReturnStatement=this.output.length>1?"resultX[x] = ":"result[x] = ";if(this.subKernels){const followingReturnStatement=[];for(let i=0;i1?`resultX_${name2}[x] = subKernelResult_${name2}; -`:`result_${name2}[x] = subKernelResult_${name2}; -`)}this.followingReturnStatement=followingReturnStatement.join("")}const functionBuilder=FunctionBuilder.fromKernel(this,CPUFunctionNode);this.translatedSources=functionBuilder.getPrototypes("kernel");if(!this.graphical&&!this.returnType){this.returnType=functionBuilder.getKernelResultType()}}build(){if(this.built)return;this.setupConstants();this.setupArguments(arguments);this.validateSettings(arguments);this.translateSource();if(this.graphical){const{canvas,output}=this;if(!canvas){throw new Error("no canvas available for using graphical output")}const width=output[0];const height=output[1]||1;canvas.width=width;canvas.height=height;this._imageData=this.context.createImageData(width,height);this._colorData=new Uint8ClampedArray(width*height*4)}const kernelString=this.getKernelString();this.kernelString=kernelString;if(this.debug){console.log("Function output:");console.log(kernelString)}try{this.run=new Function([],kernelString).bind(this)()}catch(e){console.error("An error occurred compiling the javascript: ",e)}this.buildSignature(arguments);this.built=true}color(r,g,b,a){if(typeof a==="undefined"){a=1}r=Math.floor(r*255);g=Math.floor(g*255);b=Math.floor(b*255);a=Math.floor(a*255);const width=this.output[0];const height=this.output[1];const x2=this.thread.x;const y=height-this.thread.y-1;const index=x2+y*width;this._colorData[index*4+0]=r;this._colorData[index*4+1]=g;this._colorData[index*4+2]=b;this._colorData[index*4+3]=a}getKernelString(){if(this._kernelString!==null)return this._kernelString;let kernelThreadString=null;let{translatedSources}=this;if(translatedSources.length>1){translatedSources=translatedSources.filter(fn=>{if(/^function/.test(fn))return fn;kernelThreadString=fn;return false})}else{kernelThreadString=translatedSources.shift()}return this._kernelString=` const LOOP_MAX = ${this._getLoopMaxString()}; - ${this.injectedNative||""} - const _this = this; - ${this._resultKernelHeader()} - ${this._processConstants()} - return (${this.argumentNames.map(argumentName=>"user_"+argumentName).join(", ")}) => { - ${this._prependedString.join("")} - ${this._earlyThrows()} - ${this._processArguments()} - ${this.graphical?this._graphicalKernelBody(kernelThreadString):this._resultKernelBody(kernelThreadString)} - ${translatedSources.length>0?translatedSources.join("\n"):""} - };`}toString(){return cpuKernelString(this)}_getLoopMaxString(){return this.loopMaxIterations?` ${parseInt(this.loopMaxIterations)};`:" 1000;"}_processConstants(){if(!this.constants)return"";const result=[];for(let p in this.constants){const type=this.constantTypes[p];switch(type){case"HTMLCanvas":case"HTMLImage":case"HTMLVideo":result.push(` const constants_${p} = this._mediaTo2DArray(this.constants.${p}); -`);break;case"HTMLImageArray":result.push(` const constants_${p} = this._imageTo3DArray(this.constants.${p}); -`);break;case"Input":result.push(` const constants_${p} = this.constants.${p}.value; -`);break;default:result.push(` const constants_${p} = this.constants.${p}; -`)}}return result.join("")}_earlyThrows(){if(this.graphical)return"";if(this.immutable)return"";if(!this.pipeline)return"";const arrayArguments=[];for(let i=0;i`user_${argumentName} === result_${subKernel.name}`).join(" || ");checks.push(`user_${argumentName} === result${checkSubKernels?` || ${checkSubKernels}`:""}`)}return`if (${checks.join(" || ")}) throw new Error('Source and destination arrays are the same. Use immutable = true');`}_processArguments(){const result=[];for(let i=0;i0?media.width:media.videoWidth;const height=media.height>0?media.height:media.videoHeight;if(canvas.width=0;y--){const row=imageArray[y]=new Array(width);for(let x2=0;x2`const result_${subKernel.name} = new ${constructorString}(outputX); -`).join(" ")} - ${this._mapSubKernels(subKernel=>`let subKernelResult_${subKernel.name}; -`).join(" ")} - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - this.thread.y = 0; - this.thread.z = 0; - ${kernelString} - }`}_mutableKernel1DResults(){const constructorString=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0]; - const result = new ${constructorString}(outputX); - ${this._mapSubKernels(subKernel=>`const result_${subKernel.name} = new ${constructorString}(outputX); -`).join(" ")} - ${this._mapSubKernels(subKernel=>`let subKernelResult_${subKernel.name}; -`).join(" ")}`}_resultMutableKernel1DLoop(kernelString){return` const outputX = _this.output[0]; - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - this.thread.y = 0; - this.thread.z = 0; - ${kernelString} - }`}_resultImmutableKernel2DLoop(kernelString){const constructorString=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0]; - const outputY = _this.output[1]; - const result = new Array(outputY); - ${this._mapSubKernels(subKernel=>`const result_${subKernel.name} = new Array(outputY); -`).join(" ")} - ${this._mapSubKernels(subKernel=>`let subKernelResult_${subKernel.name}; -`).join(" ")} - for (let y = 0; y < outputY; y++) { - this.thread.z = 0; - this.thread.y = y; - const resultX = result[y] = new ${constructorString}(outputX); - ${this._mapSubKernels(subKernel=>`const resultX_${subKernel.name} = result_${subKernel.name}[y] = new ${constructorString}(outputX); -`).join("")} - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${kernelString} - } - }`}_mutableKernel2DResults(){const constructorString=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0]; - const outputY = _this.output[1]; - const result = new Array(outputY); - ${this._mapSubKernels(subKernel=>`const result_${subKernel.name} = new Array(outputY); -`).join(" ")} - ${this._mapSubKernels(subKernel=>`let subKernelResult_${subKernel.name}; -`).join(" ")} - for (let y = 0; y < outputY; y++) { - const resultX = result[y] = new ${constructorString}(outputX); - ${this._mapSubKernels(subKernel=>`const resultX_${subKernel.name} = result_${subKernel.name}[y] = new ${constructorString}(outputX); -`).join("")} - }`}_resultMutableKernel2DLoop(kernelString){const constructorString=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0]; - const outputY = _this.output[1]; - for (let y = 0; y < outputY; y++) { - this.thread.z = 0; - this.thread.y = y; - const resultX = result[y]; - ${this._mapSubKernels(subKernel=>`const resultX_${subKernel.name} = result_${subKernel.name}[y] = new ${constructorString}(outputX); -`).join("")} - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${kernelString} - } - }`}_graphicalKernel2DLoop(kernelString){return` const outputX = _this.output[0]; - const outputY = _this.output[1]; - for (let y = 0; y < outputY; y++) { - this.thread.z = 0; - this.thread.y = y; - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${kernelString} - } - }`}_resultImmutableKernel3DLoop(kernelString){const constructorString=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0]; - const outputY = _this.output[1]; - const outputZ = _this.output[2]; - const result = new Array(outputZ); - ${this._mapSubKernels(subKernel=>`const result_${subKernel.name} = new Array(outputZ); -`).join(" ")} - ${this._mapSubKernels(subKernel=>`let subKernelResult_${subKernel.name}; -`).join(" ")} - for (let z = 0; z < outputZ; z++) { - this.thread.z = z; - const resultY = result[z] = new Array(outputY); - ${this._mapSubKernels(subKernel=>`const resultY_${subKernel.name} = result_${subKernel.name}[z] = new Array(outputY); -`).join(" ")} - for (let y = 0; y < outputY; y++) { - this.thread.y = y; - const resultX = resultY[y] = new ${constructorString}(outputX); - ${this._mapSubKernels(subKernel=>`const resultX_${subKernel.name} = resultY_${subKernel.name}[y] = new ${constructorString}(outputX); -`).join(" ")} - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${kernelString} - } - } - }`}_mutableKernel3DResults(){const constructorString=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0]; - const outputY = _this.output[1]; - const outputZ = _this.output[2]; - const result = new Array(outputZ); - ${this._mapSubKernels(subKernel=>`const result_${subKernel.name} = new Array(outputZ); -`).join(" ")} - ${this._mapSubKernels(subKernel=>`let subKernelResult_${subKernel.name}; -`).join(" ")} - for (let z = 0; z < outputZ; z++) { - const resultY = result[z] = new Array(outputY); - ${this._mapSubKernels(subKernel=>`const resultY_${subKernel.name} = result_${subKernel.name}[z] = new Array(outputY); -`).join(" ")} - for (let y = 0; y < outputY; y++) { - const resultX = resultY[y] = new ${constructorString}(outputX); - ${this._mapSubKernels(subKernel=>`const resultX_${subKernel.name} = resultY_${subKernel.name}[y] = new ${constructorString}(outputX); -`).join(" ")} - } - }`}_resultMutableKernel3DLoop(kernelString){return` const outputX = _this.output[0]; - const outputY = _this.output[1]; - const outputZ = _this.output[2]; - for (let z = 0; z < outputZ; z++) { - this.thread.z = z; - const resultY = result[z]; - for (let y = 0; y < outputY; y++) { - this.thread.y = y; - const resultX = resultY[y]; - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${kernelString} - } - } - }`}_kernelOutput(){if(!this.subKernels){return"\n return result;"}return` - return { - result: result, - ${this.subKernels.map(subKernel=>`${subKernel.property}: result_${subKernel.name}`).join(",\n ")} - };`}_mapSubKernels(fn){return this.subKernels===null?[""]:this.subKernels.map(fn)}destroy(removeCanvasReference){if(removeCanvasReference){delete this.canvas}}static destroyContext(context){}toJSON(){const json=super.toJSON();json.functionNodes=FunctionBuilder.fromKernel(this,CPUFunctionNode).toJSON();return json}setOutput(output){super.setOutput(output);const[width,height]=this.output;if(this.graphical){this._imageData=this.context.createImageData(width,height);this._colorData=new Uint8ClampedArray(width*height*4)}}prependString(value2){if(this._kernelString)throw new Error("Kernel already built");this._prependedString.push(value2)}hasPrependString(value2){return this._prependedString.indexOf(value2)>-1}}module3.exports={CPUKernel}},{"../../utils":114,"../function-builder":9,"../kernel":36,"./function-node":6,"./kernel-string":7}],9:[function(require2,module3,exports3){class FunctionBuilder{static fromKernel(kernel,FunctionNode,extraNodeOptions){const{kernelArguments,kernelConstants,argumentNames,argumentSizes,argumentBitRatios,constants,constantBitRatios,debug,loopMaxIterations,nativeFunctions,output,optimizeFloatMemory,precision,plugins,source,subKernels,functions,leadingReturnStatement,followingReturnStatement,dynamicArguments,dynamicOutput}=kernel;const argumentTypes=new Array(kernelArguments.length);const constantTypes={};for(let i=0;i{return functionBuilder.needsArgumentType(functionName,index)};const assignArgumentType=(functionName,index,type)=>{functionBuilder.assignArgumentType(functionName,index,type)};const lookupReturnType=(functionName,ast,requestingNode)=>{return functionBuilder.lookupReturnType(functionName,ast,requestingNode)};const lookupFunctionArgumentTypes=functionName=>{return functionBuilder.lookupFunctionArgumentTypes(functionName)};const lookupFunctionArgumentName=(functionName,argumentIndex)=>{return functionBuilder.lookupFunctionArgumentName(functionName,argumentIndex)};const lookupFunctionArgumentBitRatio=(functionName,argumentName)=>{return functionBuilder.lookupFunctionArgumentBitRatio(functionName,argumentName)};const triggerImplyArgumentType=(functionName,i,argumentType,requestingNode)=>{functionBuilder.assignArgumentType(functionName,i,argumentType,requestingNode)};const triggerImplyArgumentBitRatio=(functionName,argumentName,calleeFunctionName,argumentIndex)=>{functionBuilder.assignArgumentBitRatio(functionName,argumentName,calleeFunctionName,argumentIndex)};const onFunctionCall=(functionName,calleeFunctionName,args)=>{functionBuilder.trackFunctionCall(functionName,calleeFunctionName,args)};const onNestedFunction=(ast,source2)=>{const argumentNames2=[];for(let i=0;inew FunctionNode(fn.source,{returnType:fn.returnType,argumentTypes:fn.argumentTypes,output,plugins,constants,constantTypes,constantBitRatios,optimizeFloatMemory,precision,lookupReturnType,lookupFunctionArgumentTypes,lookupFunctionArgumentName,lookupFunctionArgumentBitRatio,needsArgumentType,assignArgumentType,triggerImplyArgumentType,triggerImplyArgumentBitRatio,onFunctionCall,onNestedFunction}))}let subKernelNodes=null;if(subKernels){subKernelNodes=subKernels.map(subKernel=>{const{name:name2,source:source2}=subKernel;return new FunctionNode(source2,Object.assign({},nodeOptions,{name:name2,isSubKernel:true,isRootKernel:false}))})}const functionBuilder=new FunctionBuilder({kernel,rootNode,functionNodes,nativeFunctions,subKernelNodes});return functionBuilder}constructor(settings){settings=settings||{};this.kernel=settings.kernel;this.rootNode=settings.rootNode;this.functionNodes=settings.functionNodes||[];this.subKernelNodes=settings.subKernelNodes||[];this.nativeFunctions=settings.nativeFunctions||[];this.functionMap={};this.nativeFunctionNames=[];this.lookupChain=[];this.functionNodeDependencies={};this.functionCalls={};if(this.rootNode){this.functionMap["kernel"]=this.rootNode}if(this.functionNodes){for(let i=0;i-1){const nativeFunctionIndex=retList.indexOf(functionName);if(nativeFunctionIndex===-1){retList.push(functionName)}else{const dependantNativeFunctionName=retList.splice(nativeFunctionIndex,1)[0];retList.push(dependantNativeFunctionName)}return retList}const functionNode=this.functionMap[functionName];if(functionNode){const functionIndex=retList.indexOf(functionName);if(functionIndex===-1){retList.push(functionName);functionNode.toString();for(let i=0;i-1){ret.push(this.nativeFunctions[functionIndex].source);continue}const node=this.functionMap[functionName];if(node){ret.push(node.toString())}}return ret}toJSON(){return this.traceFunctionCalls(this.rootNode.name).reverse().map(name2=>{const nativeIndex=this.nativeFunctions.indexOf(name2);if(nativeIndex>-1){return{name:name2,source:this.nativeFunctions[nativeIndex].source}}else if(this.functionMap[name2]){return this.functionMap[name2].toJSON()}else{throw new Error(`function ${name2} not found`)}})}fromJSON(jsonFunctionNodes,FunctionNode){this.functionMap={};for(let i=0;i0){const args=ast.arguments;for(let j=0;j0&&this.argumentTypes.length!==this.argumentNames.length){throw new Error(`argumentTypes count of ${this.argumentTypes.length} exceeds ${this.argumentNames.length}`)}if(this.output.length<1){throw new Error("this.output is not big enough")}}isIdentifierConstant(name2){if(!this.constants)return false;return this.constants.hasOwnProperty(name2)}isInput(argumentName){return this.argumentTypes[this.argumentNames.indexOf(argumentName)]==="Input"}pushState(state2){this.states.push(state2)}popState(state2){if(this.state!==state2){throw new Error(`Cannot popState ${state2} when in ${this.state}`)}this.states.pop()}isState(state2){return this.state===state2}get state(){return this.states[this.states.length-1]}astMemberExpressionUnroll(ast){if(ast.type==="Identifier"){return ast.name}else if(ast.type==="ThisExpression"){return"this"}if(ast.type==="MemberExpression"){if(ast.object&&ast.property){if(ast.object.hasOwnProperty("name")&&ast.object.name!=="Math"){return this.astMemberExpressionUnroll(ast.property)}return this.astMemberExpressionUnroll(ast.object)+"."+this.astMemberExpressionUnroll(ast.property)}}if(ast.hasOwnProperty("expressions")){const firstExpression=ast.expressions[0];if(firstExpression.type==="Literal"&&firstExpression.value===0&&ast.expressions.length===2){return this.astMemberExpressionUnroll(ast.expressions[1])}}throw this.astErrorOutput("Unknown astMemberExpressionUnroll",ast)}getJsAST(inParser){if(this.ast){return this.ast}if(typeof this.source==="object"){this.traceFunctionAST(this.source);return this.ast=this.source}inParser=inParser||acorn;if(inParser===null){throw new Error("Missing JS to AST parser")}const ast=Object.freeze(inParser.parse(`const parser_${this.name} = ${this.source};`,{locations:true}));const functionAST=ast.body[0].declarations[0].init;this.traceFunctionAST(functionAST);if(!ast){throw new Error("Failed to parse JS code")}return this.ast=functionAST}traceFunctionAST(ast){const{contexts,declarations,functions,identifiers,functionCalls}=new FunctionTracer(ast);this.contexts=contexts;this.identifiers=identifiers;this.functionCalls=functionCalls;this.functions=functions;for(let i=0;i":case"<":return"Boolean";case"&":case"|":case"^":case"<<":case">>":case">>>":return"Integer"}const type=this.getType(ast.left);if(this.isState("skip-literal-correction"))return type;if(type==="LiteralInteger"){const rightType=this.getType(ast.right);if(rightType==="LiteralInteger"){if(ast.left.value%1===0){return"Integer"}else{return"Float"}}return rightType}return typeLookupMap[type]||type;case"UpdateExpression":return this.getType(ast.argument);case"UnaryExpression":if(ast.operator==="~"){return"Integer"}return this.getType(ast.argument);case"VariableDeclaration":{const declarations=ast.declarations;let lastType;for(let i=0;i-1}isAstMathFunction(ast){const mathFunctions=["abs","acos","acosh","asin","asinh","atan","atan2","atanh","cbrt","ceil","clz32","cos","cosh","expm1","exp","floor","fround","imul","log","log2","log10","log1p","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc"];return ast.type==="CallExpression"&&ast.callee&&ast.callee.type==="MemberExpression"&&ast.callee.object&&ast.callee.object.type==="Identifier"&&ast.callee.object.name==="Math"&&ast.callee.property&&ast.callee.property.type==="Identifier"&&mathFunctions.indexOf(ast.callee.property.name)>-1}isAstVariable(ast){return ast.type==="Identifier"||ast.type==="MemberExpression"}isSafe(ast){return this.isSafeDependencies(this.getDependencies(ast))}isSafeDependencies(dependencies){return dependencies&&dependencies.every?dependencies.every(dependency=>dependency.isSafe):true}getDependencies(ast,dependencies,isNotSafe){if(!dependencies){dependencies=[]}if(!ast)return null;if(Array.isArray(ast)){for(let i=0;i-Infinity&&ast.value-1){dependencies.push({name:ast.name,origin:"argument",isSafe:false})}else if(this.strictTypingChecking){throw new Error(`Cannot find identifier origin "${ast.name}"`)}break;case"FunctionDeclaration":return this.getDependencies(ast.body.body[ast.body.body.length-1],dependencies,isNotSafe);case"ReturnStatement":return this.getDependencies(ast.argument,dependencies);case"BinaryExpression":case"LogicalExpression":isNotSafe=ast.operator==="/"||ast.operator==="*";this.getDependencies(ast.left,dependencies,isNotSafe);this.getDependencies(ast.right,dependencies,isNotSafe);return dependencies;case"UnaryExpression":case"UpdateExpression":return this.getDependencies(ast.argument,dependencies,isNotSafe);case"VariableDeclaration":return this.getDependencies(ast.declarations,dependencies,isNotSafe);case"ArrayExpression":dependencies.push({origin:"declaration",isSafe:true});return dependencies;case"CallExpression":dependencies.push({origin:"function",isSafe:true});return dependencies;case"MemberExpression":const details=this.getMemberExpressionDetails(ast);switch(details.signature){case"value[]":this.getDependencies(ast.object,dependencies,isNotSafe);break;case"value[][]":this.getDependencies(ast.object.object,dependencies,isNotSafe);break;case"value[][][]":this.getDependencies(ast.object.object.object,dependencies,isNotSafe);break;case"this.output.value":if(this.dynamicOutput){dependencies.push({name:details.name,origin:"output",isSafe:false})}break}if(details){if(details.property){this.getDependencies(details.property,dependencies,isNotSafe)}if(details.xProperty){this.getDependencies(details.xProperty,dependencies,isNotSafe)}if(details.yProperty){this.getDependencies(details.yProperty,dependencies,isNotSafe)}if(details.zProperty){this.getDependencies(details.zProperty,dependencies,isNotSafe)}return dependencies}case"SequenceExpression":return this.getDependencies(ast.expressions,dependencies,isNotSafe);default:throw this.astErrorOutput(`Unhandled type ${ast.type} in getDependencies`,ast)}return dependencies}getVariableSignature(ast,returnRawValue){if(!this.isAstVariable(ast)){throw new Error(`ast of type "${ast.type}" is not a variable signature`)}if(ast.type==="Identifier"){return"value"}const signature=[];while(true){if(!ast)break;if(ast.computed){signature.push("[]")}else if(ast.type==="ThisExpression"){signature.unshift("this")}else if(ast.property&&ast.property.name){if(ast.property.name==="x"||ast.property.name==="y"||ast.property.name==="z"){signature.unshift(returnRawValue?"."+ast.property.name:".value")}else if(ast.property.name==="constants"||ast.property.name==="thread"||ast.property.name==="output"){signature.unshift("."+ast.property.name)}else{signature.unshift(returnRawValue?"."+ast.property.name:".value")}}else if(ast.name){signature.unshift(returnRawValue?ast.name:"value")}else if(ast.callee&&ast.callee.name){signature.unshift(returnRawValue?ast.callee.name+"()":"fn()")}else if(ast.elements){signature.unshift("[]")}else{signature.unshift("unknown")}ast=ast.object}const signatureString=signature.join("");if(returnRawValue){return signatureString}const allowedExpressions=["value","value[]","value[][]","value[][][]","value[][][][]","value.value","value.thread.value","this.thread.value","this.output.value","this.constants.value","this.constants.value[]","this.constants.value[][]","this.constants.value[][][]","this.constants.value[][][][]","fn()[]","fn()[][]","fn()[][][]","[][]"];if(allowedExpressions.indexOf(signatureString)>-1){return signatureString}return null}build(){return this.toString().length>0}astGeneric(ast,retArr){if(ast===null){throw this.astErrorOutput("NULL ast",ast)}else{if(Array.isArray(ast)){for(let i=0;i0?splitLines[splitLines.length-1]:0;return new Error(`${error} on line ${splitLines.length}, position ${lineBefore.length}: - ${debugString}`)}astDebuggerStatement(arrNode,retArr){return retArr}astConditionalExpression(ast,retArr){if(ast.type!=="ConditionalExpression"){throw this.astErrorOutput("Not a conditional expression",ast)}retArr.push("(");this.astGeneric(ast.test,retArr);retArr.push("?");this.astGeneric(ast.consequent,retArr);retArr.push(":");this.astGeneric(ast.alternate,retArr);retArr.push(")");return retArr}astFunction(ast,retArr){throw new Error(`"astFunction" not defined on ${this.constructor.name}`)}astFunctionDeclaration(ast,retArr){if(this.isChildFunction(ast)){return retArr}return this.astFunction(ast,retArr)}astFunctionExpression(ast,retArr){if(this.isChildFunction(ast)){return retArr}return this.astFunction(ast,retArr)}isChildFunction(ast){for(let i=0;i1){retArr.push("(",sequenceResult.join(","),")")}else{retArr.push(sequenceResult[0])}return retArr}astUnaryExpression(uNode,retArr){const unaryResult=this.checkAndUpconvertBitwiseUnary(uNode,retArr);if(unaryResult){return retArr}if(uNode.prefix){retArr.push(uNode.operator);this.astGeneric(uNode.argument,retArr)}else{this.astGeneric(uNode.argument,retArr);retArr.push(uNode.operator)}return retArr}checkAndUpconvertBitwiseUnary(uNode,retArr){}astUpdateExpression(uNode,retArr){if(uNode.prefix){retArr.push(uNode.operator);this.astGeneric(uNode.argument,retArr)}else{this.astGeneric(uNode.argument,retArr);retArr.push(uNode.operator)}return retArr}astLogicalExpression(logNode,retArr){retArr.push("(");this.astGeneric(logNode.left,retArr);retArr.push(logNode.operator);this.astGeneric(logNode.right,retArr);retArr.push(")");return retArr}astMemberExpression(ast,retArr){return retArr}astCallExpression(ast,retArr){return retArr}astArrayExpression(ast,retArr){return retArr}getMemberExpressionDetails(ast){if(ast.type!=="MemberExpression"){throw this.astErrorOutput(`Expression ${ast.type} not a MemberExpression`,ast)}let name2=null;let type=null;const variableSignature=this.getVariableSignature(ast);switch(variableSignature){case"value":return null;case"value.thread.value":case"this.thread.value":case"this.output.value":return{signature:variableSignature,type:"Integer",name:ast.property.name};case"value[]":if(typeof ast.object.name!=="string"){throw this.astErrorOutput("Unexpected expression",ast)}name2=ast.object.name;return{name:name2,origin:"user",signature:variableSignature,type:this.getVariableType(ast.object),xProperty:ast.property};case"value[][]":if(typeof ast.object.object.name!=="string"){throw this.astErrorOutput("Unexpected expression",ast)}name2=ast.object.object.name;return{name:name2,origin:"user",signature:variableSignature,type:this.getVariableType(ast.object.object),yProperty:ast.object.property,xProperty:ast.property};case"value[][][]":if(typeof ast.object.object.object.name!=="string"){throw this.astErrorOutput("Unexpected expression",ast)}name2=ast.object.object.object.name;return{name:name2,origin:"user",signature:variableSignature,type:this.getVariableType(ast.object.object.object),zProperty:ast.object.object.property,yProperty:ast.object.property,xProperty:ast.property};case"value[][][][]":if(typeof ast.object.object.object.object.name!=="string"){throw this.astErrorOutput("Unexpected expression",ast)}name2=ast.object.object.object.object.name;return{name:name2,origin:"user",signature:variableSignature,type:this.getVariableType(ast.object.object.object.object),zProperty:ast.object.object.property,yProperty:ast.object.property,xProperty:ast.property};case"value.value":if(typeof ast.property.name!=="string"){throw this.astErrorOutput("Unexpected expression",ast)}if(this.isAstMathVariable(ast)){name2=ast.property.name;return{name:name2,origin:"Math",type:"Number",signature:variableSignature}}switch(ast.property.name){case"r":case"g":case"b":case"a":name2=ast.object.name;return{name:name2,property:ast.property.name,origin:"user",signature:variableSignature,type:"Number"};default:throw this.astErrorOutput("Unexpected expression",ast)}case"this.constants.value":if(typeof ast.property.name!=="string"){throw this.astErrorOutput("Unexpected expression",ast)}name2=ast.property.name;type=this.getConstantType(name2);if(!type){throw this.astErrorOutput("Constant has no type",ast)}return{name:name2,type,origin:"constants",signature:variableSignature};case"this.constants.value[]":if(typeof ast.object.property.name!=="string"){throw this.astErrorOutput("Unexpected expression",ast)}name2=ast.object.property.name;type=this.getConstantType(name2);if(!type){throw this.astErrorOutput("Constant has no type",ast)}return{name:name2,type,origin:"constants",signature:variableSignature,xProperty:ast.property};case"this.constants.value[][]":{if(typeof ast.object.object.property.name!=="string"){throw this.astErrorOutput("Unexpected expression",ast)}name2=ast.object.object.property.name;type=this.getConstantType(name2);if(!type){throw this.astErrorOutput("Constant has no type",ast)}return{name:name2,type,origin:"constants",signature:variableSignature,yProperty:ast.object.property,xProperty:ast.property}}case"this.constants.value[][][]":{if(typeof ast.object.object.object.property.name!=="string"){throw this.astErrorOutput("Unexpected expression",ast)}name2=ast.object.object.object.property.name;type=this.getConstantType(name2);if(!type){throw this.astErrorOutput("Constant has no type",ast)}return{name:name2,type,origin:"constants",signature:variableSignature,zProperty:ast.object.object.property,yProperty:ast.object.property,xProperty:ast.property}}case"fn()[]":case"fn()[][]":case"[][]":return{signature:variableSignature,property:ast.property};default:throw this.astErrorOutput("Unexpected expression",ast)}}findIdentifierOrigin(astToFind){const stack=[this.ast];while(stack.length>0){const atNode=stack[0];if(atNode.type==="VariableDeclarator"&&atNode.id&&atNode.id.name&&atNode.id.name===astToFind.name){return atNode}stack.shift();if(atNode.argument){stack.push(atNode.argument)}else if(atNode.body){stack.push(atNode.body)}else if(atNode.declarations){stack.push(atNode.declarations)}else if(Array.isArray(atNode)){for(let i=0;i0){const atNode=stack.pop();if(atNode.type==="ReturnStatement"){return atNode}if(atNode.type==="FunctionDeclaration"){continue}if(atNode.argument){stack.push(atNode.argument)}else if(atNode.body){stack.push(atNode.body)}else if(atNode.declarations){stack.push(atNode.declarations)}else if(Array.isArray(atNode)){for(let i=0;i0?array[array.length-1]:null}const states={trackIdentifiers:"trackIdentifiers",memberExpression:"memberExpression",inForLoopInit:"inForLoopInit"};class FunctionTracer{constructor(ast){this.runningContexts=[];this.functionContexts=[];this.contexts=[];this.functionCalls=[];this.declarations=[];this.identifiers=[];this.functions=[];this.returnStatements=[];this.trackedIdentifiers=null;this.states=[];this.newFunctionContext();this.scan(ast)}isState(state2){return this.states[this.states.length-1]===state2}hasState(state2){return this.states.indexOf(state2)>-1}pushState(state2){this.states.push(state2)}popState(state2){if(this.isState(state2)){this.states.pop()}else{throw new Error(`Cannot pop the non-active state "${state2}"`)}}get currentFunctionContext(){return last(this.functionContexts)}get currentContext(){return last(this.runningContexts)}newFunctionContext(){const newContext={"@contextType":"function"};this.contexts.push(newContext);this.functionContexts.push(newContext)}newContext(run){const newContext=Object.assign({"@contextType":"const/let"},this.currentContext);this.contexts.push(newContext);this.runningContexts.push(newContext);run();const{currentFunctionContext}=this;for(const p in currentFunctionContext){if(!currentFunctionContext.hasOwnProperty(p)||newContext.hasOwnProperty(p))continue;newContext[p]=currentFunctionContext[p]}this.runningContexts.pop();return newContext}useFunctionContext(run){const functionContext=last(this.functionContexts);this.runningContexts.push(functionContext);run();this.runningContexts.pop()}getIdentifiers(run){const trackedIdentifiers=this.trackedIdentifiers=[];this.pushState(states.trackIdentifiers);run();this.trackedIdentifiers=null;this.popState(states.trackIdentifiers);return trackedIdentifiers}getDeclaration(name2){const{currentContext,currentFunctionContext,runningContexts}=this;const declaration=currentContext[name2]||currentFunctionContext[name2]||null;if(!declaration&¤tContext===currentFunctionContext&&runningContexts.length>0){const previousRunningContext=runningContexts[runningContexts.length-2];if(previousRunningContext[name2]){return previousRunningContext[name2]}}return declaration}scan(ast){if(!ast)return;if(Array.isArray(ast)){for(let i=0;i{this.scan(ast.body)});break;case"BlockStatement":this.newContext(()=>{this.scan(ast.body)});break;case"AssignmentExpression":case"LogicalExpression":this.scan(ast.left);this.scan(ast.right);break;case"BinaryExpression":this.scan(ast.left);this.scan(ast.right);break;case"UpdateExpression":if(ast.operator==="++"){const declaration=this.getDeclaration(ast.argument.name);if(declaration){declaration.suggestedType="Integer"}}this.scan(ast.argument);break;case"UnaryExpression":this.scan(ast.argument);break;case"VariableDeclaration":if(ast.kind==="var"){this.useFunctionContext(()=>{ast.declarations=utils.normalizeDeclarations(ast);this.scan(ast.declarations)})}else{ast.declarations=utils.normalizeDeclarations(ast);this.scan(ast.declarations)}break;case"VariableDeclarator":{const{currentContext}=this;const inForLoopInit=this.hasState(states.inForLoopInit);const declaration={ast,context:currentContext,name:ast.id.name,origin:"declaration",inForLoopInit,inForLoopTest:null,assignable:currentContext===this.currentFunctionContext||!inForLoopInit&&!currentContext.hasOwnProperty(ast.id.name),suggestedType:null,valueType:null,dependencies:null,isSafe:null};if(!currentContext[ast.id.name]){currentContext[ast.id.name]=declaration}this.declarations.push(declaration);this.scan(ast.id);this.scan(ast.init);break}case"FunctionExpression":case"FunctionDeclaration":if(this.runningContexts.length===0){this.scan(ast.body)}else{this.functions.push(ast)}break;case"IfStatement":this.scan(ast.test);this.scan(ast.consequent);if(ast.alternate)this.scan(ast.alternate);break;case"ForStatement":{let testIdentifiers;const context=this.newContext(()=>{this.pushState(states.inForLoopInit);this.scan(ast.init);this.popState(states.inForLoopInit);testIdentifiers=this.getIdentifiers(()=>{this.scan(ast.test)});this.scan(ast.update);this.newContext(()=>{this.scan(ast.body)})});if(testIdentifiers){for(const p in context){if(p==="@contextType")continue;if(testIdentifiers.indexOf(p)>-1){context[p].inForLoopTest=true}}}break}case"DoWhileStatement":case"WhileStatement":this.newContext(()=>{this.scan(ast.body);this.scan(ast.test)});break;case"Identifier":{if(this.isState(states.trackIdentifiers)){this.trackedIdentifiers.push(ast.name)}this.identifiers.push({context:this.currentContext,declaration:this.getDeclaration(ast.name),ast});break}case"ReturnStatement":this.returnStatements.push(ast);this.scan(ast.argument);break;case"MemberExpression":this.pushState(states.memberExpression);this.scan(ast.object);this.scan(ast.property);this.popState(states.memberExpression);break;case"ExpressionStatement":this.scan(ast.expression);break;case"SequenceExpression":this.scan(ast.expressions);break;case"CallExpression":this.functionCalls.push({context:this.currentContext,ast});this.scan(ast.arguments);break;case"ArrayExpression":this.scan(ast.elements);break;case"ConditionalExpression":this.scan(ast.test);this.scan(ast.alternate);this.scan(ast.consequent);break;case"SwitchStatement":this.scan(ast.discriminant);this.scan(ast.cases);break;case"SwitchCase":this.scan(ast.test);this.scan(ast.consequent);break;case"ThisExpression":case"Literal":case"DebuggerStatement":case"EmptyStatement":case"BreakStatement":case"ContinueStatement":break;default:throw new Error(`unhandled type "${ast.type}"`)}}}module3.exports={FunctionTracer}},{"../utils":114}],12:[function(require2,module3,exports3){const{glWiretap}=require2("gl-wiretap");const{utils}=require2("../../utils");function toStringWithoutUtils(fn){return fn.toString().replace("=>","").replace(/^function /,"").replace(/utils[.]/g,"/*utils.*/")}function glKernelString(Kernel,args,originKernel,setupContextString,destroyContextString){if(!originKernel.built){originKernel.build.apply(originKernel,args)}args=args?Array.from(args).map(arg=>{switch(typeof arg){case"boolean":return new Boolean(arg);case"number":return new Number(arg);default:return arg}}):null;const uploadedValues=[];const postResult=[];const context=glWiretap(originKernel.context,{useTrackablePrimitives:true,onReadPixels:targetName=>{if(kernel.subKernels){if(!subKernelsResultVariableSetup){postResult.push(` const result = { result: ${getRenderString(targetName,kernel)} };`);subKernelsResultVariableSetup=true}else{const property=kernel.subKernels[subKernelsResultIndex++].property;postResult.push(` result${isNaN(property)?"."+property:`[${property}]`} = ${getRenderString(targetName,kernel)};`)}if(subKernelsResultIndex===kernel.subKernels.length){postResult.push(" return result;")}return}if(targetName){postResult.push(` return ${getRenderString(targetName,kernel)};`)}else{postResult.push(` return null;`)}},onUnrecognizedArgumentLookup:argument=>{const argumentName=findKernelValue(argument,kernel.kernelArguments,[],context,uploadedValues);if(argumentName){return argumentName}const constantName=findKernelValue(argument,kernel.kernelConstants,constants?Object.keys(constants).map(key=>constants[key]):[],context,uploadedValues);if(constantName){return constantName}return null}});let subKernelsResultVariableSetup=false;let subKernelsResultIndex=0;const{source,canvas,output,pipeline,graphical,loopMaxIterations,constants,optimizeFloatMemory,precision,fixIntegerDivisionAccuracy,functions,nativeFunctions,subKernels,immutable,argumentTypes,constantTypes,kernelArguments,kernelConstants,tactic}=originKernel;const kernel=new Kernel(source,{canvas,context,checkContext:false,output,pipeline,graphical,loopMaxIterations,constants,optimizeFloatMemory,precision,fixIntegerDivisionAccuracy,functions,nativeFunctions,subKernels,immutable,argumentTypes,constantTypes,tactic});let result=[];context.setIndent(2);kernel.build.apply(kernel,args);result.push(context.toString());context.reset();kernel.kernelArguments.forEach((kernelArgument,i)=>{switch(kernelArgument.type){case"Integer":case"Boolean":case"Number":case"Float":case"Array":case"Array(2)":case"Array(3)":case"Array(4)":case"HTMLCanvas":case"HTMLImage":case"HTMLVideo":context.insertVariable(`uploadValue_${kernelArgument.name}`,kernelArgument.uploadValue);break;case"HTMLImageArray":for(let imageIndex=0;imageIndexkernelArgument.varName).join(", ")}) {`);context.setIndent(4);kernel.run.apply(kernel,args);if(kernel.renderKernels){kernel.renderKernels()}else if(kernel.renderOutput){kernel.renderOutput()}result.push(" /** start setup uploads for kernel values **/");kernel.kernelArguments.forEach(kernelArgument=>{result.push(" "+kernelArgument.getStringValueHandler().split("\n").join("\n "))});result.push(" /** end setup uploads for kernel values **/");result.push(context.toString());if(kernel.renderOutput===kernel.renderTexture){context.reset();const framebufferName=context.getContextVariableName(kernel.framebuffer);if(kernel.renderKernels){const results=kernel.renderKernels();const textureName=context.getContextVariableName(kernel.texture.texture);result.push(` return { - result: { - texture: ${textureName}, - type: '${results.result.type}', - toArray: ${getToArrayString(results.result,textureName,framebufferName)} - },`);const{subKernels:subKernels2,mappedTextures}=kernel;for(let i=0;i{constantsUpload.push(`${kernelConstant.getStringValueHandler()}`)});return`function kernel(settings) { - const { context, constants } = settings; - ${constantsUpload.join("")} - ${setupContextString?setupContextString:""} - ${result.join("\n")} - }`}function getRenderString(targetName,kernel){const readBackValue=kernel.precision==="single"?targetName:`new Float32Array(${targetName}.buffer)`;if(kernel.output[2]){return`renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]}, ${kernel.output[2]})`}if(kernel.output[1]){return`renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]})`}return`renderOutput(${readBackValue}, ${kernel.output[0]})`}function getGetPixelsString(kernel){const getPixels=kernel.getPixels.toString();const useFunctionKeyword=!/^function/.test(getPixels);return utils.flattenFunctionToString(`${useFunctionKeyword?"function ":""}${getPixels}`,{findDependency:(object,name2)=>{if(object==="utils"){return`const ${name2} = ${utils[name2].toString()};`}return null},thisLookup:property=>{if(property==="context"){return null}if(kernel.hasOwnProperty(property)){return JSON.stringify(kernel[property])}throw new Error(`unhandled thisLookup ${property}`)}})}function getToArrayString(kernelResult,textureName,framebufferName){const toArray=kernelResult.toArray.toString();const useFunctionKeyword=!/^function/.test(toArray);const flattenedFunctions=utils.flattenFunctionToString(`${useFunctionKeyword?"function ":""}${toArray}`,{findDependency:(object,name2)=>{if(object==="utils"){return`const ${name2} = ${utils[name2].toString()};`}else if(object==="this"){if(name2==="framebuffer"){return""}return`${useFunctionKeyword?"function ":""}${kernelResult[name2].toString()}`}else{throw new Error("unhandled fromObject")}},thisLookup:(property,isDeclaration)=>{if(property==="texture"){return textureName}if(property==="context"){if(isDeclaration)return null;return"gl"}if(kernelResult.hasOwnProperty(property)){return JSON.stringify(kernelResult[property])}throw new Error(`unhandled thisLookup ${property}`)}});return`() => { - function framebuffer() { return ${framebufferName}; }; - ${flattenedFunctions} - return toArray(); - }`}function findKernelValue(argument,kernelValues,values,context,uploadedValues){if(argument===null)return null;if(kernelValues===null)return null;switch(typeof argument){case"boolean":case"number":return null}if(typeof HTMLImageElement!=="undefined"&&argument instanceof HTMLImageElement){for(let i=0;i0?":"+argumentTypes.join(","):"")}setFixIntegerDivisionAccuracy(fix){this.fixIntegerDivisionAccuracy=fix;return this}setPrecision(flag){this.precision=flag;return this}setFloatTextures(flag){utils.warnDeprecated("method","setFloatTextures","setOptimizeFloatMemory");this.floatTextures=flag;return this}static nativeFunctionArguments(source){const argumentTypes=[];const argumentNames=[];const states=[];const isStartingVariableName=/^[a-zA-Z_]/;const isVariableChar=/[a-zA-Z_0-9]/;let i=0;let argumentName=null;let argumentType=null;while(i0?states[states.length-1]:null;if(state2==="FUNCTION_ARGUMENTS"&&char==="/"&&nextChar==="*"){states.push("MULTI_LINE_COMMENT");i+=2;continue}else if(state2==="MULTI_LINE_COMMENT"&&char==="*"&&nextChar==="/"){states.pop();i+=2;continue}else if(state2==="FUNCTION_ARGUMENTS"&&char==="/"&&nextChar==="/"){states.push("COMMENT");i+=2;continue}else if(state2==="COMMENT"&&char==="\n"){states.pop();i++;continue}else if(state2===null&&char==="("){states.push("FUNCTION_ARGUMENTS");i++;continue}else if(state2==="FUNCTION_ARGUMENTS"){if(char===")"){states.pop();break}if(char==="f"&&nextChar==="l"&&source[i+2]==="o"&&source[i+3]==="a"&&source[i+4]==="t"&&source[i+5]===" "){states.push("DECLARE_VARIABLE");argumentType="float";argumentName="";i+=6;continue}else if(char==="i"&&nextChar==="n"&&source[i+2]==="t"&&source[i+3]===" "){states.push("DECLARE_VARIABLE");argumentType="int";argumentName="";i+=4;continue}else if(char==="v"&&nextChar==="e"&&source[i+2]==="c"&&source[i+3]==="2"&&source[i+4]===" "){states.push("DECLARE_VARIABLE");argumentType="vec2";argumentName="";i+=5;continue}else if(char==="v"&&nextChar==="e"&&source[i+2]==="c"&&source[i+3]==="3"&&source[i+4]===" "){states.push("DECLARE_VARIABLE");argumentType="vec3";argumentName="";i+=5;continue}else if(char==="v"&&nextChar==="e"&&source[i+2]==="c"&&source[i+3]==="4"&&source[i+4]===" "){states.push("DECLARE_VARIABLE");argumentType="vec4";argumentName="";i+=5;continue}}else if(state2==="DECLARE_VARIABLE"){if(argumentName===""){if(char===" "){i++;continue}if(!isStartingVariableName.test(char)){throw new Error("variable name is not expected string")}}argumentName+=char;if(!isVariableChar.test(nextChar)){states.pop();argumentNames.push(argumentName);argumentTypes.push(typeMap[argumentType])}}i++}if(states.length>0){throw new Error("GLSL function was not parsable")}return{argumentNames,argumentTypes}}static nativeFunctionReturnType(source){return typeMap[source.match(/int|float|vec[2-4]/)[0]]}static combineKernels(combinedKernel,lastKernel){combinedKernel.apply(null,arguments);const{texSize,context,threadDim}=lastKernel.texSize;let result;if(lastKernel.precision==="single"){const w=texSize[0];const h=Math.ceil(texSize[1]/4);result=new Float32Array(w*h*4*4);context.readPixels(0,0,w,h*4,context.RGBA,context.FLOAT,result)}else{const bytes=new Uint8Array(texSize[0]*texSize[1]*4);context.readPixels(0,0,texSize[0],texSize[1],context.RGBA,context.UNSIGNED_BYTE,bytes);result=new Float32Array(bytes.buffer)}result=result.subarray(0,threadDim[0]*threadDim[1]*threadDim[2]);if(lastKernel.output.length===1){return result}else if(lastKernel.output.length===2){return utils.splitArray(result,lastKernel.output[0])}else if(lastKernel.output.length===3){const cube=utils.splitArray(result,lastKernel.output[0]*lastKernel.output[1]);return cube.map(function(x2){return utils.splitArray(x2,lastKernel.output[0])})}}constructor(source,settings){super(source,settings);this.transferValues=null;this.formatValues=null;this.TextureConstructor=null;this.renderOutput=null;this.renderRawOutput=null;this.texSize=null;this.translatedSource=null;this.compiledFragmentShader=null;this.compiledVertexShader=null;this.switchingKernels=null;this._textureSwitched=null;this._mappedTextureSwitched=null}checkTextureSize(){const{features}=this.constructor;if(this.texSize[0]>features.maxTextureSize||this.texSize[1]>features.maxTextureSize){throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${features.maxTextureSize},${features.maxTextureSize}]`)}}translateSource(){throw new Error(`"translateSource" not defined on ${this.constructor.name}`)}pickRenderStrategy(args){if(this.graphical){this.renderRawOutput=this.readPackedPixelsToUint8Array;this.transferValues=pixels=>pixels;this.TextureConstructor=GLTextureGraphical;return null}if(this.precision==="unsigned"){this.renderRawOutput=this.readPackedPixelsToUint8Array;this.transferValues=this.readPackedPixelsToFloat32Array;if(this.pipeline){this.renderOutput=this.renderTexture;if(this.subKernels!==null){this.renderKernels=this.renderKernelsToTextures}switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":if(this.output[2]>0){this.TextureConstructor=GLTextureUnsigned3D;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureUnsigned2D;return null}else{this.TextureConstructor=GLTextureUnsigned;return null}case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(args)}}else{if(this.subKernels!==null){this.renderKernels=this.renderKernelsToArrays}switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":this.renderOutput=this.renderValues;if(this.output[2]>0){this.TextureConstructor=GLTextureUnsigned3D;this.formatValues=utils.erect3DPackedFloat;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureUnsigned2D;this.formatValues=utils.erect2DPackedFloat;return null}else{this.TextureConstructor=GLTextureUnsigned;this.formatValues=utils.erectPackedFloat;return null}case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(args)}}}else if(this.precision==="single"){this.renderRawOutput=this.readFloatPixelsToFloat32Array;this.transferValues=this.readFloatPixelsToFloat32Array;if(this.pipeline){this.renderOutput=this.renderTexture;if(this.subKernels!==null){this.renderKernels=this.renderKernelsToTextures}switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":{if(this.optimizeFloatMemory){if(this.output[2]>0){this.TextureConstructor=GLTextureMemoryOptimized3D;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureMemoryOptimized2D;return null}else{this.TextureConstructor=GLTextureMemoryOptimized;return null}}else{if(this.output[2]>0){this.TextureConstructor=GLTextureFloat3D;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureFloat2D;return null}else{this.TextureConstructor=GLTextureFloat;return null}}}case"Array(2)":{if(this.output[2]>0){this.TextureConstructor=GLTextureArray2Float3D;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureArray2Float2D;return null}else{this.TextureConstructor=GLTextureArray2Float;return null}}case"Array(3)":{if(this.output[2]>0){this.TextureConstructor=GLTextureArray3Float3D;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureArray3Float2D;return null}else{this.TextureConstructor=GLTextureArray3Float;return null}}case"Array(4)":{if(this.output[2]>0){this.TextureConstructor=GLTextureArray4Float3D;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureArray4Float2D;return null}else{this.TextureConstructor=GLTextureArray4Float;return null}}}}this.renderOutput=this.renderValues;if(this.subKernels!==null){this.renderKernels=this.renderKernelsToArrays}if(this.optimizeFloatMemory){switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":{if(this.output[2]>0){this.TextureConstructor=GLTextureMemoryOptimized3D;this.formatValues=utils.erectMemoryOptimized3DFloat;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureMemoryOptimized2D;this.formatValues=utils.erectMemoryOptimized2DFloat;return null}else{this.TextureConstructor=GLTextureMemoryOptimized;this.formatValues=utils.erectMemoryOptimizedFloat;return null}}case"Array(2)":{if(this.output[2]>0){this.TextureConstructor=GLTextureArray2Float3D;this.formatValues=utils.erect3DArray2;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureArray2Float2D;this.formatValues=utils.erect2DArray2;return null}else{this.TextureConstructor=GLTextureArray2Float;this.formatValues=utils.erectArray2;return null}}case"Array(3)":{if(this.output[2]>0){this.TextureConstructor=GLTextureArray3Float3D;this.formatValues=utils.erect3DArray3;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureArray3Float2D;this.formatValues=utils.erect2DArray3;return null}else{this.TextureConstructor=GLTextureArray3Float;this.formatValues=utils.erectArray3;return null}}case"Array(4)":{if(this.output[2]>0){this.TextureConstructor=GLTextureArray4Float3D;this.formatValues=utils.erect3DArray4;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureArray4Float2D;this.formatValues=utils.erect2DArray4;return null}else{this.TextureConstructor=GLTextureArray4Float;this.formatValues=utils.erectArray4;return null}}}}else{switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":{if(this.output[2]>0){this.TextureConstructor=GLTextureFloat3D;this.formatValues=utils.erect3DFloat;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureFloat2D;this.formatValues=utils.erect2DFloat;return null}else{this.TextureConstructor=GLTextureFloat;this.formatValues=utils.erectFloat;return null}}case"Array(2)":{if(this.output[2]>0){this.TextureConstructor=GLTextureArray2Float3D;this.formatValues=utils.erect3DArray2;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureArray2Float2D;this.formatValues=utils.erect2DArray2;return null}else{this.TextureConstructor=GLTextureArray2Float;this.formatValues=utils.erectArray2;return null}}case"Array(3)":{if(this.output[2]>0){this.TextureConstructor=GLTextureArray3Float3D;this.formatValues=utils.erect3DArray3;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureArray3Float2D;this.formatValues=utils.erect2DArray3;return null}else{this.TextureConstructor=GLTextureArray3Float;this.formatValues=utils.erectArray3;return null}}case"Array(4)":{if(this.output[2]>0){this.TextureConstructor=GLTextureArray4Float3D;this.formatValues=utils.erect3DArray4;return null}else if(this.output[1]>0){this.TextureConstructor=GLTextureArray4Float2D;this.formatValues=utils.erect2DArray4;return null}else{this.TextureConstructor=GLTextureArray4Float;this.formatValues=utils.erectArray4;return null}}}}}else{throw new Error(`unhandled precision of "${this.precision}"`)}throw new Error(`unhandled return type "${this.returnType}"`)}getKernelString(){throw new Error(`abstract method call`)}getMainResultTexture(){switch(this.returnType){case"LiteralInteger":case"Float":case"Integer":case"Number":return this.getMainResultNumberTexture();case"Array(2)":return this.getMainResultArray2Texture();case"Array(3)":return this.getMainResultArray3Texture();case"Array(4)":return this.getMainResultArray4Texture();default:throw new Error(`unhandled returnType type ${this.returnType}`)}}getMainResultKernelNumberTexture(){throw new Error(`abstract method call`)}getMainResultSubKernelNumberTexture(){throw new Error(`abstract method call`)}getMainResultKernelArray2Texture(){throw new Error(`abstract method call`)}getMainResultSubKernelArray2Texture(){throw new Error(`abstract method call`)}getMainResultKernelArray3Texture(){throw new Error(`abstract method call`)}getMainResultSubKernelArray3Texture(){throw new Error(`abstract method call`)}getMainResultKernelArray4Texture(){throw new Error(`abstract method call`)}getMainResultSubKernelArray4Texture(){throw new Error(`abstract method call`)}getMainResultGraphical(){throw new Error(`abstract method call`)}getMainResultMemoryOptimizedFloats(){throw new Error(`abstract method call`)}getMainResultPackedPixels(){throw new Error(`abstract method call`)}getMainResultString(){if(this.graphical){return this.getMainResultGraphical()}else if(this.precision==="single"){if(this.optimizeFloatMemory){return this.getMainResultMemoryOptimizedFloats()}return this.getMainResultTexture()}else{return this.getMainResultPackedPixels()}}getMainResultNumberTexture(){return utils.linesToString(this.getMainResultKernelNumberTexture())+utils.linesToString(this.getMainResultSubKernelNumberTexture())}getMainResultArray2Texture(){return utils.linesToString(this.getMainResultKernelArray2Texture())+utils.linesToString(this.getMainResultSubKernelArray2Texture())}getMainResultArray3Texture(){return utils.linesToString(this.getMainResultKernelArray3Texture())+utils.linesToString(this.getMainResultSubKernelArray3Texture())}getMainResultArray4Texture(){return utils.linesToString(this.getMainResultKernelArray4Texture())+utils.linesToString(this.getMainResultSubKernelArray4Texture())}getFloatTacticDeclaration(){const variablePrecision=this.getVariablePrecisionString(this.texSize,this.tactic);return`precision ${variablePrecision} float; -`}getIntTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic,true)} int; -`}getSampler2DTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} sampler2D; -`}getSampler2DArrayTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} sampler2DArray; -`}renderTexture(){return this.immutable?this.texture.clone():this.texture}readPackedPixelsToUint8Array(){if(this.precision!=="unsigned")throw new Error('Requires this.precision to be "unsigned"');const{texSize,context:gl}=this;const result=new Uint8Array(texSize[0]*texSize[1]*4);gl.readPixels(0,0,texSize[0],texSize[1],gl.RGBA,gl.UNSIGNED_BYTE,result);return result}readPackedPixelsToFloat32Array(){return new Float32Array(this.readPackedPixelsToUint8Array().buffer)}readFloatPixelsToFloat32Array(){if(this.precision!=="single")throw new Error('Requires this.precision to be "single"');const{texSize,context:gl}=this;const w=texSize[0];const h=texSize[1];const result=new Float32Array(w*h*4);gl.readPixels(0,0,w,h,gl.RGBA,gl.FLOAT,result);return result}getPixels(flip){const{context:gl,output}=this;const[width,height]=output;const pixels=new Uint8Array(width*height*4);gl.readPixels(0,0,width,height,gl.RGBA,gl.UNSIGNED_BYTE,pixels);return new Uint8ClampedArray((flip?pixels:utils.flipPixels(pixels,width,height)).buffer)}renderKernelsToArrays(){const result={result:this.renderOutput()};for(let i=0;i0){for(let i=0;i0){const{mappedTextures}=this;for(let i=0;i1){this.newTexture();return true}return false}cloneTexture(){this.texture._refs--;const{context:gl,size,texture,kernel}=this;if(kernel.debug){console.warn("cloning internal texture")}gl.bindFramebuffer(gl.FRAMEBUFFER,this.framebuffer());selectTexture(gl,texture);gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D,texture,0);const target=gl.createTexture();selectTexture(gl,target);gl.texImage2D(gl.TEXTURE_2D,0,this.internalFormat,size[0],size[1],0,this.textureFormat,this.textureType,null);gl.copyTexSubImage2D(gl.TEXTURE_2D,0,0,0,0,0,size[0],size[1]);target._refs=1;this.texture=target}newTexture(){this.texture._refs--;const gl=this.context;const size=this.size;const kernel=this.kernel;if(kernel.debug){console.warn("new internal texture")}const target=gl.createTexture();selectTexture(gl,target);gl.texImage2D(gl.TEXTURE_2D,0,this.internalFormat,size[0],size[1],0,this.textureFormat,this.textureType,null);target._refs=1;this.texture=target}clear(){if(this.texture._refs){this.texture._refs--;const gl2=this.context;const target=this.texture=gl2.createTexture();selectTexture(gl2,target);const size=this.size;target._refs=1;gl2.texImage2D(gl2.TEXTURE_2D,0,this.internalFormat,size[0],size[1],0,this.textureFormat,this.textureType,null)}const{context:gl,texture}=this;gl.bindFramebuffer(gl.FRAMEBUFFER,this.framebuffer());gl.bindTexture(gl.TEXTURE_2D,texture);selectTexture(gl,texture);gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D,texture,0);gl.clearColor(0,0,0,0);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT)}delete(){if(this._deleted)return;this._deleted=true;if(this.texture._refs){this.texture._refs--;if(this.texture._refs)return}this.context.deleteTexture(this.texture)}framebuffer(){if(!this._framebuffer){this._framebuffer=this.kernel.getRawValueFramebuffer(this.size[0],this.size[1])}return this._framebuffer}}function selectTexture(gl,texture){gl.activeTexture(gl.TEXTURE15);gl.bindTexture(gl.TEXTURE_2D,texture);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.NEAREST);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.NEAREST)}module3.exports={GLTexture}},{"../../../texture":113}],28:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{GLTextureFloat}=require2("./float");class GLTextureMemoryOptimized2D extends GLTextureFloat{constructor(settings){super(settings);this.type="MemoryOptimizedNumberTexture"}toArray(){return utils.erectMemoryOptimized2DFloat(this.renderValues(),this.output[0],this.output[1])}}module3.exports={GLTextureMemoryOptimized2D}},{"../../../utils":114,"./float":25}],29:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{GLTextureFloat}=require2("./float");class GLTextureMemoryOptimized3D extends GLTextureFloat{constructor(settings){super(settings);this.type="MemoryOptimizedNumberTexture"}toArray(){return utils.erectMemoryOptimized3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}module3.exports={GLTextureMemoryOptimized3D}},{"../../../utils":114,"./float":25}],30:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{GLTextureFloat}=require2("./float");class GLTextureMemoryOptimized extends GLTextureFloat{constructor(settings){super(settings);this.type="MemoryOptimizedNumberTexture"}toArray(){return utils.erectMemoryOptimizedFloat(this.renderValues(),this.output[0])}}module3.exports={GLTextureMemoryOptimized}},{"../../../utils":114,"./float":25}],31:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{GLTextureUnsigned}=require2("./unsigned");class GLTextureUnsigned2D extends GLTextureUnsigned{constructor(settings){super(settings);this.type="NumberTexture"}toArray(){return utils.erect2DPackedFloat(this.renderValues(),this.output[0],this.output[1])}}module3.exports={GLTextureUnsigned2D}},{"../../../utils":114,"./unsigned":33}],32:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{GLTextureUnsigned}=require2("./unsigned");class GLTextureUnsigned3D extends GLTextureUnsigned{constructor(settings){super(settings);this.type="NumberTexture"}toArray(){return utils.erect3DPackedFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}module3.exports={GLTextureUnsigned3D}},{"../../../utils":114,"./unsigned":33}],33:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{GLTexture}=require2("./index");class GLTextureUnsigned extends GLTexture{get textureType(){return this.context.UNSIGNED_BYTE}constructor(settings){super(settings);this.type="NumberTexture"}renderRawOutput(){const{context:gl}=this;gl.bindFramebuffer(gl.FRAMEBUFFER,this.framebuffer());gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D,this.texture,0);const result=new Uint8Array(this.size[0]*this.size[1]*4);gl.readPixels(0,0,this.size[0],this.size[1],gl.RGBA,gl.UNSIGNED_BYTE,result);return result}renderValues(){if(this._deleted)return null;return new Float32Array(this.renderRawOutput().buffer)}toArray(){return utils.erectPackedFloat(this.renderValues(),this.output[0])}}module3.exports={GLTextureUnsigned}},{"../../../utils":114,"./index":27}],34:[function(require2,module3,exports3){const getContext=require2("gl");const{WebGLKernel}=require2("../web-gl/kernel");const{glKernelString}=require2("../gl/kernel-string");let isSupported=null;let testCanvas=null;let testContext=null;let testExtensions=null;let features=null;class HeadlessGLKernel extends WebGLKernel{static get isSupported(){if(isSupported!==null)return isSupported;this.setupFeatureChecks();isSupported=testContext!==null;return isSupported}static setupFeatureChecks(){testCanvas=null;testExtensions=null;if(typeof getContext!=="function")return;try{testContext=getContext(2,2,{preserveDrawingBuffer:true});if(!testContext||!testContext.getExtension)return;testExtensions={STACKGL_resize_drawingbuffer:testContext.getExtension("STACKGL_resize_drawingbuffer"),STACKGL_destroy_context:testContext.getExtension("STACKGL_destroy_context"),OES_texture_float:testContext.getExtension("OES_texture_float"),OES_texture_float_linear:testContext.getExtension("OES_texture_float_linear"),OES_element_index_uint:testContext.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:testContext.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:testContext.getExtension("WEBGL_color_buffer_float")};features=this.getFeatures()}catch(e){console.warn(e)}}static isContextMatch(context){try{return context.getParameter(context.RENDERER)==="ANGLE"}catch(e){return false}}static getIsTextureFloat(){return Boolean(testExtensions.OES_texture_float)}static getIsDrawBuffers(){return Boolean(testExtensions.WEBGL_draw_buffers)}static getChannelCount(){return testExtensions.WEBGL_draw_buffers?testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL):1}static getMaxTextureSize(){return testContext.getParameter(testContext.MAX_TEXTURE_SIZE)}static get testCanvas(){return testCanvas}static get testContext(){return testContext}static get features(){return features}initCanvas(){return{}}initContext(){return getContext(2,2,{preserveDrawingBuffer:true})}initExtensions(){this.extensions={STACKGL_resize_drawingbuffer:this.context.getExtension("STACKGL_resize_drawingbuffer"),STACKGL_destroy_context:this.context.getExtension("STACKGL_destroy_context"),OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers")}}build(){super.build.apply(this,arguments);if(!this.fallbackRequested){this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1])}}destroyExtensions(){this.extensions.STACKGL_resize_drawingbuffer=null;this.extensions.STACKGL_destroy_context=null;this.extensions.OES_texture_float=null;this.extensions.OES_texture_float_linear=null;this.extensions.OES_element_index_uint=null;this.extensions.WEBGL_draw_buffers=null}static destroyContext(context){const extension=context.getExtension("STACKGL_destroy_context");if(extension&&extension.destroy){extension.destroy()}}toString(){const setupContextString=`const gl = context || require('gl')(1, 1); -`;const destroyContextString=` if (!context) { gl.getExtension('STACKGL_destroy_context').destroy(); } -`;return glKernelString(this.constructor,arguments,this,setupContextString,destroyContextString)}setOutput(output){super.setOutput(output);if(this.graphical&&this.extensions.STACKGL_resize_drawingbuffer){this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1])}return this}}module3.exports={HeadlessGLKernel}},{"../gl/kernel-string":12,"../web-gl/kernel":70,"gl":2}],35:[function(require2,module3,exports3){class KernelValue{constructor(value2,settings){const{name:name2,kernel,context,checkContext,onRequestContextHandle,onUpdateValueMismatch,origin,strictIntegers,type,tactic}=settings;if(!name2){throw new Error("name not set")}if(!type){throw new Error("type not set")}if(!origin){throw new Error("origin not set")}if(origin!=="user"&&origin!=="constants"){throw new Error(`origin must be "user" or "constants" value is "${origin}"`)}if(!onRequestContextHandle){throw new Error("onRequestContextHandle is not set")}this.name=name2;this.origin=origin;this.tactic=tactic;this.varName=origin==="constants"?`constants.${name2}`:name2;this.kernel=kernel;this.strictIntegers=strictIntegers;this.type=value2.type||type;this.size=value2.size||null;this.index=null;this.context=context;this.checkContext=checkContext!==null&&checkContext!==void 0?checkContext:true;this.contextHandle=null;this.onRequestContextHandle=onRequestContextHandle;this.onUpdateValueMismatch=onUpdateValueMismatch;this.forceUploadEachRun=null}get id(){return`${this.origin}_${name}`}getSource(){throw new Error(`"getSource" not defined on ${this.constructor.name}`)}updateValue(value2){throw new Error(`"updateValue" not defined on ${this.constructor.name}`)}}module3.exports={KernelValue}},{}],36:[function(require2,module3,exports3){const{utils}=require2("../utils");const{Input}=require2("../input");class Kernel{static get isSupported(){throw new Error(`"isSupported" not implemented on ${this.name}`)}static isContextMatch(context){throw new Error(`"isContextMatch" not implemented on ${this.name}`)}static getFeatures(){throw new Error(`"getFeatures" not implemented on ${this.name}`)}static destroyContext(context){throw new Error(`"destroyContext" called on ${this.name}`)}static nativeFunctionArguments(){throw new Error(`"nativeFunctionArguments" called on ${this.name}`)}static nativeFunctionReturnType(){throw new Error(`"nativeFunctionReturnType" called on ${this.name}`)}static combineKernels(){throw new Error(`"combineKernels" called on ${this.name}`)}constructor(source,settings){if(typeof source!=="object"){if(typeof source!=="string"){throw new Error("source not a string")}if(!utils.isFunctionString(source)){throw new Error("source not a function string")}}this.useLegacyEncoder=false;this.fallbackRequested=false;this.onRequestFallback=null;this.argumentNames=typeof source==="string"?utils.getArgumentNamesFromString(source):null;this.argumentTypes=null;this.argumentSizes=null;this.argumentBitRatios=null;this.kernelArguments=null;this.kernelConstants=null;this.forceUploadKernelConstants=null;this.source=source;this.output=null;this.debug=false;this.graphical=false;this.loopMaxIterations=0;this.constants=null;this.constantTypes=null;this.constantBitRatios=null;this.dynamicArguments=false;this.dynamicOutput=false;this.canvas=null;this.context=null;this.checkContext=null;this.gpu=null;this.functions=null;this.nativeFunctions=null;this.injectedNative=null;this.subKernels=null;this.validate=true;this.immutable=false;this.pipeline=false;this.precision=null;this.tactic=null;this.plugins=null;this.returnType=null;this.leadingReturnStatement=null;this.followingReturnStatement=null;this.optimizeFloatMemory=null;this.strictIntegers=false;this.fixIntegerDivisionAccuracy=null;this.built=false;this.signature=null}mergeSettings(settings){for(let p in settings){if(!settings.hasOwnProperty(p)||!this.hasOwnProperty(p))continue;switch(p){case"output":if(!Array.isArray(settings.output)){this.setOutput(settings.output);continue}break;case"functions":this.functions=[];for(let i=0;iplugin.name):null,returnType:this.returnType}}}buildSignature(args){const Constructor=this.constructor;this.signature=Constructor.getSignature(this,Constructor.getArgumentTypes(this,args))}static getArgumentTypes(kernel,args){const argumentTypes=new Array(args.length);for(let i=0;isettings.argumentTypes[name2])||[]}else{argumentTypes=settings.argumentTypes||[]}return{name:utils.getFunctionNameFromString(sourceString)||null,source:sourceString,argumentTypes,returnType:settings.returnType||null}}onActivate(previousKernel){}}function splitArgumentTypes(argumentTypesObject){const argumentNames=Object.keys(argumentTypesObject);const argumentTypes=[];for(let i=0;i= 0.0) { - return pow(x, 1.0 / 3.0); - } else { - return -pow(x, 1.0 / 3.0); - } - } - - float cosh(float x) { - return (pow(${Math.E}, x) + pow(${Math.E}, -x)) / 2.0; - } - - float expm1(float x) { - return pow(${Math.E}, x) - 1.0; - } - - float fround(highp float x) { - return x; - } - - float imul(float v1, float v2) { - return float(int(v1) * int(v2)); - } - - float log10(float x) { - return log2(x) * (1.0 / log2(10.0)); - } - - float log1p(float x) { - return log(1.0 + x); - } - - float _pow(float v1, float v2) { - if (v2 == 0.0) return 1.0; - return pow(v1, v2); - } - - float tanh(float x) { - float e = exp(2.0 * x); - return (e - 1.0) / (e + 1.0); - } - - float trunc(float x) { - if (x >= 0.0) { - return floor(x); - } else { - return ceil(x); - } - } - - vec4 _round(vec4 x) { - return floor(x + 0.5); - } - - float _round(float x) { - return floor(x + 0.5); - } - - const int BIT_COUNT = 32; - int modi(int x, int y) { - return x - y * (x / y); - } - - int bitwiseOr(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; - } - } - return result; - } - int bitwiseXOR(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; - } - } - return result; - } - int bitwiseAnd(int a, int b) { - int result = 0; - int n = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 && b > 0)) { - break; - } - } - return result; - } - int bitwiseNot(int a) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if (modi(a, 2) == 0) { - result += n; - } - a = a / 2; - n = n * 2; - } - return result; - } - int bitwiseZeroFillLeftShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; - } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; - } - n *= 2; - } - - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; - } - - int bitwiseSignedRightShift(int num, int shifts) { - return int(floor(float(num) / pow(2.0, float(shifts)))); - } - - int bitwiseZeroFillRightShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; - } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; - } - n /= 2; - } - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; - } - - vec2 integerMod(vec2 x, float y) { - vec2 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); - } - - vec3 integerMod(vec3 x, float y) { - vec3 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); - } - - vec4 integerMod(vec4 x, vec4 y) { - vec4 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); - } - - float integerMod(float x, float y) { - float res = floor(mod(x, y)); - return res * (res > floor(y) - 1.0 ? 0.0 : 1.0); - } - - int integerMod(int x, int y) { - return x - (y * int(x / y)); - } - - __DIVIDE_WITH_INTEGER_CHECK__; - - // Here be dragons! - // DO NOT OPTIMIZE THIS CODE - // YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE - // LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME - const vec2 MAGIC_VEC = vec2(1.0, -256.0); - const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0); - const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536 - float decode32(vec4 texel) { - __DECODE32_ENDIANNESS__; - texel *= 255.0; - vec2 gte128; - gte128.x = texel.b >= 128.0 ? 1.0 : 0.0; - gte128.y = texel.a >= 128.0 ? 1.0 : 0.0; - float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC); - float res = exp2(_round(exponent)); - texel.b = texel.b - 128.0 * gte128.x; - res = dot(texel, SCALE_FACTOR) * exp2(_round(exponent-23.0)) + res; - res *= gte128.y * -2.0 + 1.0; - return res; - } - - float decode16(vec4 texel, int index) { - int channel = integerMod(index, 2); - if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0; - if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0; - return 0.0; - } - - float decode8(vec4 texel, int index) { - int channel = integerMod(index, 4); - if (channel == 0) return texel.r * 255.0; - if (channel == 1) return texel.g * 255.0; - if (channel == 2) return texel.b * 255.0; - if (channel == 3) return texel.a * 255.0; - return 0.0; - } - - vec4 legacyEncode32(float f) { - float F = abs(f); - float sign = f < 0.0 ? 1.0 : 0.0; - float exponent = floor(log2(F)); - float mantissa = (exp2(-exponent) * F); - // exponent += floor(log2(mantissa)); - vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV; - texel.rg = integerMod(texel.rg, 256.0); - texel.b = integerMod(texel.b, 128.0); - texel.a = exponent*0.5 + 63.5; - texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0; - texel = floor(texel); - texel *= 0.003921569; // 1/255 - __ENCODE32_ENDIANNESS__; - return texel; - } - - // https://github.com/gpujs/gpu.js/wiki/Encoder-details - vec4 encode32(float value) { - if (value == 0.0) return vec4(0, 0, 0, 0); - - float exponent; - float mantissa; - vec4 result; - float sgn; - - sgn = step(0.0, -value); - value = abs(value); - - exponent = floor(log2(value)); - - mantissa = value*pow(2.0, -exponent)-1.0; - exponent = exponent+127.0; - result = vec4(0,0,0,0); - - result.a = floor(exponent/2.0); - exponent = exponent - result.a*2.0; - result.a = result.a + 128.0*sgn; - - result.b = floor(mantissa * 128.0); - mantissa = mantissa - result.b / 128.0; - result.b = result.b + exponent*128.0; - - result.g = floor(mantissa*32768.0); - mantissa = mantissa - result.g/32768.0; - - result.r = floor(mantissa*8388608.0); - return result/255.0; - } - // Dragons end here - - int index; - ivec3 threadId; - - ivec3 indexTo3D(int idx, ivec3 texDim) { - int z = int(idx / (texDim.x * texDim.y)); - idx -= z * int(texDim.x * texDim.y); - int y = int(idx / texDim.x); - int x = int(integerMod(idx, texDim.x)); - return ivec3(x, y, z); - } - - float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - return decode32(texel); - } - - float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x * 2; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y)); - return decode16(texel, index); - } - - float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x * 4; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y)); - return decode8(texel, index); - } - - float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 4); - index = index / 4; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - if (channel == 0) return texel.r; - if (channel == 1) return texel.g; - if (channel == 2) return texel.b; - if (channel == 3) return texel.a; - return 0.0; - } - - vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - return texture2D(tex, st / vec2(texSize)); - } - - float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return result[0]; - } - - vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec2(result[0], result[1]); - } - - vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int channel = integerMod(index, 2); - index = index / 2; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - if (channel == 0) return vec2(texel.r, texel.g); - if (channel == 1) return vec2(texel.b, texel.a); - return vec2(0.0, 0.0); - } - - vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec3(result[0], result[1], result[2]); - } - - vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z)); - int vectorIndex = fieldIndex / 4; - int vectorOffset = fieldIndex - vectorIndex * 4; - int readY = vectorIndex / texSize.x; - int readX = vectorIndex - readY * texSize.x; - vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize)); - - if (vectorOffset == 0) { - return tex1.xyz; - } else if (vectorOffset == 1) { - return tex1.yzw; - } else { - readX++; - if (readX >= texSize.x) { - readX = 0; - readY++; - } - vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize)); - if (vectorOffset == 2) { - return vec3(tex1.z, tex1.w, tex2.x); - } else { - return vec3(tex1.w, tex2.x, tex2.y); - } - } - } - - vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - return getImage2D(tex, texSize, texDim, z, y, x); - } - - vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 2); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - return vec4(texel.r, texel.g, texel.b, texel.a); - } - - vec4 actualColor; - void color(float r, float g, float b, float a) { - actualColor = vec4(r,g,b,a); - } - - void color(float r, float g, float b) { - color(r,g,b,1.0); - } - - void color(sampler2D image) { - actualColor = texture2D(image, vTexCoord); - } - - float modulo(float number, float divisor) { - if (number < 0.0) { - number = abs(number); - if (divisor < 0.0) { - divisor = abs(divisor); - } - return -mod(number, divisor); - } - if (divisor < 0.0) { - divisor = abs(divisor); - } - return mod(number, divisor); - } - - __INJECTED_NATIVE__; - __MAIN_CONSTANTS__; - __MAIN_ARGUMENTS__; - __KERNEL__; - - void main(void) { - index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x; - __MAIN_RESULT__; - }`;module3.exports={fragmentShader}},{}],38:[function(require2,module3,exports3){const{utils}=require2("../../utils");const{FunctionNode}=require2("../function-node");class WebGLFunctionNode extends FunctionNode{constructor(source,settings){super(source,settings);if(settings&&settings.hasOwnProperty("fixIntegerDivisionAccuracy")){this.fixIntegerDivisionAccuracy=settings.fixIntegerDivisionAccuracy}}astConditionalExpression(ast,retArr){if(ast.type!=="ConditionalExpression"){throw this.astErrorOutput("Not a conditional expression",ast)}const consequentType=this.getType(ast.consequent);const alternateType=this.getType(ast.alternate);if(consequentType===null&&alternateType===null){retArr.push("if (");this.astGeneric(ast.test,retArr);retArr.push(") {");this.astGeneric(ast.consequent,retArr);retArr.push(";");retArr.push("} else {");this.astGeneric(ast.alternate,retArr);retArr.push(";");retArr.push("}");return retArr}retArr.push("(");this.astGeneric(ast.test,retArr);retArr.push("?");this.astGeneric(ast.consequent,retArr);retArr.push(":");this.astGeneric(ast.alternate,retArr);retArr.push(")");return retArr}astFunction(ast,retArr){if(this.isRootKernel){retArr.push("void")}else{if(!this.returnType){const lastReturn=this.findLastReturn();if(lastReturn){this.returnType=this.getType(ast.body);if(this.returnType==="LiteralInteger"){this.returnType="Number"}}}const{returnType}=this;if(!returnType){retArr.push("void")}else{const type=typeMap[returnType];if(!type){throw new Error(`unknown type ${returnType}`)}retArr.push(type)}}retArr.push(" ");retArr.push(this.name);retArr.push("(");if(!this.isRootKernel){for(let i=0;i0){retArr.push(", ")}let argumentType=this.argumentTypes[this.argumentNames.indexOf(argumentName)];if(!argumentType){throw this.astErrorOutput(`Unknown argument ${argumentName} type`,ast)}if(argumentType==="LiteralInteger"){this.argumentTypes[i]=argumentType="Number"}const type=typeMap[argumentType];if(!type){throw this.astErrorOutput("Unexpected expression",ast)}const name2=utils.sanitizeName(argumentName);if(type==="sampler2D"||type==="sampler2DArray"){retArr.push(`${type} user_${name2},ivec2 user_${name2}Size,ivec3 user_${name2}Dim`)}else{retArr.push(`${type} user_${name2}`)}}}retArr.push(") {\n");for(let i=0;i"||ast.operator==="<"&&ast.right.type==="Literal"){if(!Number.isInteger(ast.right.value)){this.pushState("building-float");this.castValueToFloat(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.astGeneric(ast.right,retArr);this.popState("building-float");break}}this.pushState("building-integer");this.astGeneric(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.pushState("casting-to-integer");if(ast.right.type==="Literal"){const literalResult=[];this.astGeneric(ast.right,literalResult);const literalType=this.getType(ast.right);if(literalType==="Integer"){retArr.push(literalResult.join(""))}else{throw this.astErrorOutput(`Unhandled binary expression with literal`,ast)}}else{retArr.push("int(");this.astGeneric(ast.right,retArr);retArr.push(")")}this.popState("casting-to-integer");this.popState("building-integer");break;case"Integer & LiteralInteger":this.pushState("building-integer");this.astGeneric(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.castLiteralToInteger(ast.right,retArr);this.popState("building-integer");break;case"Number & Integer":this.pushState("building-float");this.astGeneric(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.castValueToFloat(ast.right,retArr);this.popState("building-float");break;case"Float & LiteralInteger":case"Number & LiteralInteger":this.pushState("building-float");this.astGeneric(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.castLiteralToFloat(ast.right,retArr);this.popState("building-float");break;case"LiteralInteger & Float":case"LiteralInteger & Number":if(this.isState("casting-to-integer")){this.pushState("building-integer");this.castLiteralToInteger(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.castValueToInteger(ast.right,retArr);this.popState("building-integer")}else{this.pushState("building-float");this.astGeneric(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.pushState("casting-to-float");this.astGeneric(ast.right,retArr);this.popState("casting-to-float");this.popState("building-float")}break;case"LiteralInteger & Integer":this.pushState("building-integer");this.castLiteralToInteger(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.astGeneric(ast.right,retArr);this.popState("building-integer");break;case"Boolean & Boolean":this.pushState("building-boolean");this.astGeneric(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.astGeneric(ast.right,retArr);this.popState("building-boolean");break;case"Float & Integer":this.pushState("building-float");this.astGeneric(ast.left,retArr);retArr.push(operatorMap[ast.operator]||ast.operator);this.castValueToFloat(ast.right,retArr);this.popState("building-float");break;default:throw this.astErrorOutput(`Unhandled binary expression between ${key}`,ast)}retArr.push(")");return retArr}checkAndUpconvertOperator(ast,retArr){const bitwiseResult=this.checkAndUpconvertBitwiseOperators(ast,retArr);if(bitwiseResult){return bitwiseResult}const upconvertableOperators={"%":this.fixIntegerDivisionAccuracy?"integerCorrectionModulo":"modulo","**":"pow"};const foundOperator=upconvertableOperators[ast.operator];if(!foundOperator)return null;retArr.push(foundOperator);retArr.push("(");switch(this.getType(ast.left)){case"Integer":this.castValueToFloat(ast.left,retArr);break;case"LiteralInteger":this.castLiteralToFloat(ast.left,retArr);break;default:this.astGeneric(ast.left,retArr)}retArr.push(",");switch(this.getType(ast.right)){case"Integer":this.castValueToFloat(ast.right,retArr);break;case"LiteralInteger":this.castLiteralToFloat(ast.right,retArr);break;default:this.astGeneric(ast.right,retArr)}retArr.push(")");return retArr}checkAndUpconvertBitwiseOperators(ast,retArr){const upconvertableOperators={"&":"bitwiseAnd","|":"bitwiseOr","^":"bitwiseXOR","<<":"bitwiseZeroFillLeftShift",">>":"bitwiseSignedRightShift",">>>":"bitwiseZeroFillRightShift"};const foundOperator=upconvertableOperators[ast.operator];if(!foundOperator)return null;retArr.push(foundOperator);retArr.push("(");const leftType=this.getType(ast.left);switch(leftType){case"Number":case"Float":this.castValueToInteger(ast.left,retArr);break;case"LiteralInteger":this.castLiteralToInteger(ast.left,retArr);break;default:this.astGeneric(ast.left,retArr)}retArr.push(",");const rightType=this.getType(ast.right);switch(rightType){case"Number":case"Float":this.castValueToInteger(ast.right,retArr);break;case"LiteralInteger":this.castLiteralToInteger(ast.right,retArr);break;default:this.astGeneric(ast.right,retArr)}retArr.push(")");return retArr}checkAndUpconvertBitwiseUnary(ast,retArr){const upconvertableOperators={"~":"bitwiseNot"};const foundOperator=upconvertableOperators[ast.operator];if(!foundOperator)return null;retArr.push(foundOperator);retArr.push("(");switch(this.getType(ast.argument)){case"Number":case"Float":this.castValueToInteger(ast.argument,retArr);break;case"LiteralInteger":this.castLiteralToInteger(ast.argument,retArr);break;default:this.astGeneric(ast.argument,retArr)}retArr.push(")");return retArr}castLiteralToInteger(ast,retArr){this.pushState("casting-to-integer");this.astGeneric(ast,retArr);this.popState("casting-to-integer");return retArr}castLiteralToFloat(ast,retArr){this.pushState("casting-to-float");this.astGeneric(ast,retArr);this.popState("casting-to-float");return retArr}castValueToInteger(ast,retArr){this.pushState("casting-to-integer");retArr.push("int(");this.astGeneric(ast,retArr);retArr.push(")");this.popState("casting-to-integer");return retArr}castValueToFloat(ast,retArr){this.pushState("casting-to-float");retArr.push("float(");this.astGeneric(ast,retArr);retArr.push(")");this.popState("casting-to-float");return retArr}astIdentifierExpression(idtNode,retArr){if(idtNode.type!=="Identifier"){throw this.astErrorOutput("IdentifierExpression - not an Identifier",idtNode)}const type=this.getType(idtNode);const name2=utils.sanitizeName(idtNode.name);if(idtNode.name==="Infinity"){retArr.push("3.402823466e+38")}else if(type==="Boolean"){if(this.argumentNames.indexOf(name2)>-1){retArr.push(`bool(user_${name2})`)}else{retArr.push(`user_${name2}`)}}else{retArr.push(`user_${name2}`)}return retArr}astForStatement(forNode,retArr){if(forNode.type!=="ForStatement"){throw this.astErrorOutput("Invalid for statement",forNode)}const initArr=[];const testArr=[];const updateArr=[];const bodyArr=[];let isSafe=null;if(forNode.init){const{declarations}=forNode.init;if(declarations.length>1){isSafe=false}this.astGeneric(forNode.init,initArr);for(let i=0;i0){retArr.push(initArr.join(""),"\n")}retArr.push(`for (int ${iVariableName}=0;${iVariableName}0){retArr.push(`if (!${testArr.join("")}) break; -`)}retArr.push(bodyArr.join(""));retArr.push(` -${updateArr.join("")};`);retArr.push("}\n")}return retArr}astWhileStatement(whileNode,retArr){if(whileNode.type!=="WhileStatement"){throw this.astErrorOutput("Invalid while statement",whileNode)}const iVariableName=this.getInternalVariableName("safeI");retArr.push(`for (int ${iVariableName}=0;${iVariableName}0){declarationSets.push(declarationSet.join(","))}result.push(declarationSets.join(";"));retArr.push(result.join(""));retArr.push(";");return retArr}astIfStatement(ifNode,retArr){retArr.push("if (");this.astGeneric(ifNode.test,retArr);retArr.push(")");if(ifNode.consequent.type==="BlockStatement"){this.astGeneric(ifNode.consequent,retArr)}else{retArr.push(" {\n");this.astGeneric(ifNode.consequent,retArr);retArr.push("\n}\n")}if(ifNode.alternate){retArr.push("else ");if(ifNode.alternate.type==="BlockStatement"||ifNode.alternate.type==="IfStatement"){this.astGeneric(ifNode.alternate,retArr)}else{retArr.push(" {\n");this.astGeneric(ifNode.alternate,retArr);retArr.push("\n}\n")}}return retArr}astSwitchStatement(ast,retArr){if(ast.type!=="SwitchStatement"){throw this.astErrorOutput("Invalid switch statement",ast)}const{discriminant,cases}=ast;const type=this.getType(discriminant);const varName=`switchDiscriminant${this.astKey(ast,"_")}`;switch(type){case"Float":case"Number":retArr.push(`float ${varName} = `);this.astGeneric(discriminant,retArr);retArr.push(";\n");break;case"Integer":retArr.push(`int ${varName} = `);this.astGeneric(discriminant,retArr);retArr.push(";\n");break}if(cases.length===1&&!cases[0].test){this.astGeneric(cases[0].consequent,retArr);return retArr}let fallingThrough=false;let defaultResult=[];let movingDefaultToEnd=false;let pastFirstIf=false;for(let i=0;ii+1){movingDefaultToEnd=true;this.astGeneric(cases[i].consequent,defaultResult);continue}else{retArr.push(" else {\n")}}else{if(i===0||!pastFirstIf){pastFirstIf=true;retArr.push(`if (${varName} == `)}else{if(fallingThrough){retArr.push(`${varName} == `);fallingThrough=false}else{retArr.push(` else if (${varName} == `)}}if(type==="Integer"){const testType=this.getType(cases[i].test);switch(testType){case"Number":case"Float":this.castValueToInteger(cases[i].test,retArr);break;case"LiteralInteger":this.castLiteralToInteger(cases[i].test,retArr);break}}else if(type==="Float"){const testType=this.getType(cases[i].test);switch(testType){case"LiteralInteger":this.castLiteralToFloat(cases[i].test,retArr);break;case"Integer":this.castValueToFloat(cases[i].test,retArr);break}}else{throw new Error("unhanlded")}if(!cases[i].consequent||cases[i].consequent.length===0){fallingThrough=true;retArr.push(" || ");continue}retArr.push(`) { -`)}this.astGeneric(cases[i].consequent,retArr);retArr.push("\n}")}if(movingDefaultToEnd){retArr.push(" else {");retArr.push(defaultResult.join(""));retArr.push("}")}return retArr}astThisExpression(tNode,retArr){retArr.push("this");return retArr}astMemberExpression(mNode,retArr){const{property,name:name2,signature,origin,type,xProperty,yProperty,zProperty}=this.getMemberExpressionDetails(mNode);switch(signature){case"value.thread.value":case"this.thread.value":if(name2!=="x"&&name2!=="y"&&name2!=="z"){throw this.astErrorOutput("Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`",mNode)}retArr.push(`threadId.${name2}`);return retArr;case"this.output.value":if(this.dynamicOutput){switch(name2){case"x":if(this.isState("casting-to-float")){retArr.push("float(uOutputDim.x)")}else{retArr.push("uOutputDim.x")}break;case"y":if(this.isState("casting-to-float")){retArr.push("float(uOutputDim.y)")}else{retArr.push("uOutputDim.y")}break;case"z":if(this.isState("casting-to-float")){retArr.push("float(uOutputDim.z)")}else{retArr.push("uOutputDim.z")}break;default:throw this.astErrorOutput("Unexpected expression",mNode)}}else{switch(name2){case"x":if(this.isState("casting-to-integer")){retArr.push(this.output[0])}else{retArr.push(this.output[0],".0")}break;case"y":if(this.isState("casting-to-integer")){retArr.push(this.output[1])}else{retArr.push(this.output[1],".0")}break;case"z":if(this.isState("casting-to-integer")){retArr.push(this.output[2])}else{retArr.push(this.output[2],".0")}break;default:throw this.astErrorOutput("Unexpected expression",mNode)}}return retArr;case"value":throw this.astErrorOutput("Unexpected expression",mNode);case"value[]":case"value[][]":case"value[][][]":case"value[][][][]":case"value.value":if(origin==="Math"){retArr.push(Math[name2]);return retArr}const cleanName=utils.sanitizeName(name2);switch(property){case"r":retArr.push(`user_${cleanName}.r`);return retArr;case"g":retArr.push(`user_${cleanName}.g`);return retArr;case"b":retArr.push(`user_${cleanName}.b`);return retArr;case"a":retArr.push(`user_${cleanName}.a`);return retArr}break;case"this.constants.value":if(typeof xProperty==="undefined"){switch(type){case"Array(2)":case"Array(3)":case"Array(4)":retArr.push(`constants_${utils.sanitizeName(name2)}`);return retArr}}case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":case"this.constants.value[][][][]":break;case"fn()[]":this.astCallExpression(mNode.object,retArr);retArr.push("[");retArr.push(this.memberExpressionPropertyMarkup(property));retArr.push("]");return retArr;case"fn()[][]":this.astCallExpression(mNode.object.object,retArr);retArr.push("[");retArr.push(this.memberExpressionPropertyMarkup(mNode.object.property));retArr.push("]");retArr.push("[");retArr.push(this.memberExpressionPropertyMarkup(mNode.property));retArr.push("]");return retArr;case"[][]":this.astArrayExpression(mNode.object,retArr);retArr.push("[");retArr.push(this.memberExpressionPropertyMarkup(property));retArr.push("]");return retArr;default:throw this.astErrorOutput("Unexpected expression",mNode)}if(mNode.computed===false){switch(type){case"Number":case"Integer":case"Float":case"Boolean":retArr.push(`${origin}_${utils.sanitizeName(name2)}`);return retArr}}const markupName=`${origin}_${utils.sanitizeName(name2)}`;switch(type){case"Array(2)":case"Array(3)":case"Array(4)":this.astGeneric(mNode.object,retArr);retArr.push("[");retArr.push(this.memberExpressionPropertyMarkup(xProperty));retArr.push("]");break;case"HTMLImageArray":retArr.push(`getImage3D(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")");break;case"ArrayTexture(1)":retArr.push(`getFloatFromSampler2D(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")");break;case"Array1D(2)":case"Array2D(2)":case"Array3D(2)":retArr.push(`getMemoryOptimizedVec2(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")");break;case"ArrayTexture(2)":retArr.push(`getVec2FromSampler2D(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")");break;case"Array1D(3)":case"Array2D(3)":case"Array3D(3)":retArr.push(`getMemoryOptimizedVec3(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")");break;case"ArrayTexture(3)":retArr.push(`getVec3FromSampler2D(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")");break;case"Array1D(4)":case"Array2D(4)":case"Array3D(4)":retArr.push(`getMemoryOptimizedVec4(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")");break;case"ArrayTexture(4)":case"HTMLCanvas":case"HTMLImage":case"HTMLVideo":retArr.push(`getVec4FromSampler2D(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")");break;case"NumberTexture":case"Array":case"Array2D":case"Array3D":case"Array4D":case"Input":case"Number":case"Float":case"Integer":if(this.precision==="single"){retArr.push(`getMemoryOptimized32(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")")}else{const bitRatio=origin==="user"?this.lookupFunctionArgumentBitRatio(this.name,name2):this.constantBitRatios[name2];switch(bitRatio){case 1:retArr.push(`get8(${markupName}, ${markupName}Size, ${markupName}Dim, `);break;case 2:retArr.push(`get16(${markupName}, ${markupName}Size, ${markupName}Dim, `);break;case 4:case 0:retArr.push(`get32(${markupName}, ${markupName}Size, ${markupName}Dim, `);break;default:throw new Error(`unhandled bit ratio of ${bitRatio}`)}this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")")}break;case"MemoryOptimizedNumberTexture":retArr.push(`getMemoryOptimized32(${markupName}, ${markupName}Size, ${markupName}Dim, `);this.memberExpressionXYZ(xProperty,yProperty,zProperty,retArr);retArr.push(")");break;case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":retArr.push(`${markupName}[${this.memberExpressionPropertyMarkup(yProperty)}]`);if(yProperty){retArr.push(`[${this.memberExpressionPropertyMarkup(xProperty)}]`)}break;default:throw new Error(`unhandled member expression "${type}"`)}return retArr}astCallExpression(ast,retArr){if(!ast.callee){throw this.astErrorOutput("Unknown CallExpression",ast)}let functionName=null;const isMathFunction=this.isAstMathFunction(ast);if(isMathFunction||ast.callee.object&&ast.callee.object.type==="ThisExpression"){functionName=ast.callee.property.name}else if(ast.callee.type==="SequenceExpression"&&ast.callee.expressions[0].type==="Literal"&&!isNaN(ast.callee.expressions[0].raw)){functionName=ast.callee.expressions[1].property.name}else{functionName=ast.callee.name}if(!functionName){throw this.astErrorOutput(`Unhandled function, couldn't find name`,ast)}switch(functionName){case"pow":functionName="_pow";break;case"round":functionName="_round";break}if(this.calledFunctions.indexOf(functionName)<0){this.calledFunctions.push(functionName)}if(functionName==="random"&&this.plugins&&this.plugins.length>0){for(let i=0;i0){retArr.push(", ")}switch(argumentType){case"Integer":this.castValueToFloat(argument,retArr);break;default:this.astGeneric(argument,retArr);break}}}else{const targetTypes=this.lookupFunctionArgumentTypes(functionName)||[];for(let i=0;i0){retArr.push(", ")}const argumentType=this.getType(argument);if(!targetType){this.triggerImplyArgumentType(functionName,i,argumentType,this);targetType=argumentType}switch(argumentType){case"Boolean":this.astGeneric(argument,retArr);continue;case"Number":case"Float":if(targetType==="Integer"){retArr.push("int(");this.astGeneric(argument,retArr);retArr.push(")");continue}else if(targetType==="Number"||targetType==="Float"){this.astGeneric(argument,retArr);continue}else if(targetType==="LiteralInteger"){this.castLiteralToFloat(argument,retArr);continue}break;case"Integer":if(targetType==="Number"||targetType==="Float"){retArr.push("float(");this.astGeneric(argument,retArr);retArr.push(")");continue}else if(targetType==="Integer"){this.astGeneric(argument,retArr);continue}break;case"LiteralInteger":if(targetType==="Integer"){this.castLiteralToInteger(argument,retArr);continue}else if(targetType==="Number"||targetType==="Float"){this.castLiteralToFloat(argument,retArr);continue}else if(targetType==="LiteralInteger"){this.astGeneric(argument,retArr);continue}break;case"Array(2)":case"Array(3)":case"Array(4)":if(targetType===argumentType){if(argument.type==="Identifier"){retArr.push(`user_${utils.sanitizeName(argument.name)}`)}else if(argument.type==="ArrayExpression"||argument.type==="MemberExpression"||argument.type==="CallExpression"){this.astGeneric(argument,retArr)}else{throw this.astErrorOutput(`Unhandled argument type ${argument.type}`,ast)}continue}break;case"HTMLCanvas":case"HTMLImage":case"HTMLImageArray":case"HTMLVideo":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":case"Array":case"Input":if(targetType===argumentType){if(argument.type!=="Identifier")throw this.astErrorOutput(`Unhandled argument type ${argument.type}`,ast);this.triggerImplyArgumentBitRatio(this.name,argument.name,functionName,i);const name2=utils.sanitizeName(argument.name);retArr.push(`user_${name2},user_${name2}Size,user_${name2}Dim`);continue}break}throw this.astErrorOutput(`Unhandled argument combination of ${argumentType} and ${targetType} for argument named "${argument.name}"`,ast)}}retArr.push(")");return retArr}astArrayExpression(arrNode,retArr){const returnType=this.getType(arrNode);const arrLen=arrNode.elements.length;switch(returnType){case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":retArr.push(`mat${arrLen}(`);break;default:retArr.push(`vec${arrLen}(`)}for(let i=0;i0){retArr.push(", ")}const subNode=arrNode.elements[i];this.astGeneric(subNode,retArr)}retArr.push(")");return retArr}memberExpressionXYZ(x2,y,z,retArr){if(z){retArr.push(this.memberExpressionPropertyMarkup(z),", ")}else{retArr.push("0, ")}if(y){retArr.push(this.memberExpressionPropertyMarkup(y),", ")}else{retArr.push("0, ")}retArr.push(this.memberExpressionPropertyMarkup(x2));return retArr}memberExpressionPropertyMarkup(property){if(!property){throw new Error("Property not set")}const type=this.getType(property);const result=[];switch(type){case"Number":case"Float":this.castValueToInteger(property,result);break;case"LiteralInteger":this.castLiteralToInteger(property,result);break;default:this.astGeneric(property,result)}return result.join("")}}const typeMap={"Array":"sampler2D","Array(2)":"vec2","Array(3)":"vec3","Array(4)":"vec4","Matrix(2)":"mat2","Matrix(3)":"mat3","Matrix(4)":"mat4","Array2D":"sampler2D","Array3D":"sampler2D","Boolean":"bool","Float":"float","Input":"sampler2D","Integer":"int","Number":"float","LiteralInteger":"float","NumberTexture":"sampler2D","MemoryOptimizedNumberTexture":"sampler2D","ArrayTexture(1)":"sampler2D","ArrayTexture(2)":"sampler2D","ArrayTexture(3)":"sampler2D","ArrayTexture(4)":"sampler2D","HTMLVideo":"sampler2D","HTMLCanvas":"sampler2D","HTMLImage":"sampler2D","HTMLImageArray":"sampler2DArray"};const operatorMap={"===":"==","!==":"!="};module3.exports={WebGLFunctionNode}},{"../../utils":114,"../function-node":10}],39:[function(require2,module3,exports3){const{WebGLKernelValueBoolean}=require2("./kernel-value/boolean");const{WebGLKernelValueFloat}=require2("./kernel-value/float");const{WebGLKernelValueInteger}=require2("./kernel-value/integer");const{WebGLKernelValueHTMLImage}=require2("./kernel-value/html-image");const{WebGLKernelValueDynamicHTMLImage}=require2("./kernel-value/dynamic-html-image");const{WebGLKernelValueHTMLVideo}=require2("./kernel-value/html-video");const{WebGLKernelValueDynamicHTMLVideo}=require2("./kernel-value/dynamic-html-video");const{WebGLKernelValueSingleInput}=require2("./kernel-value/single-input");const{WebGLKernelValueDynamicSingleInput}=require2("./kernel-value/dynamic-single-input");const{WebGLKernelValueUnsignedInput}=require2("./kernel-value/unsigned-input");const{WebGLKernelValueDynamicUnsignedInput}=require2("./kernel-value/dynamic-unsigned-input");const{WebGLKernelValueMemoryOptimizedNumberTexture}=require2("./kernel-value/memory-optimized-number-texture");const{WebGLKernelValueDynamicMemoryOptimizedNumberTexture}=require2("./kernel-value/dynamic-memory-optimized-number-texture");const{WebGLKernelValueNumberTexture}=require2("./kernel-value/number-texture");const{WebGLKernelValueDynamicNumberTexture}=require2("./kernel-value/dynamic-number-texture");const{WebGLKernelValueSingleArray}=require2("./kernel-value/single-array");const{WebGLKernelValueDynamicSingleArray}=require2("./kernel-value/dynamic-single-array");const{WebGLKernelValueSingleArray1DI}=require2("./kernel-value/single-array1d-i");const{WebGLKernelValueDynamicSingleArray1DI}=require2("./kernel-value/dynamic-single-array1d-i");const{WebGLKernelValueSingleArray2DI}=require2("./kernel-value/single-array2d-i");const{WebGLKernelValueDynamicSingleArray2DI}=require2("./kernel-value/dynamic-single-array2d-i");const{WebGLKernelValueSingleArray3DI}=require2("./kernel-value/single-array3d-i");const{WebGLKernelValueDynamicSingleArray3DI}=require2("./kernel-value/dynamic-single-array3d-i");const{WebGLKernelValueSingleArray2}=require2("./kernel-value/single-array2");const{WebGLKernelValueSingleArray3}=require2("./kernel-value/single-array3");const{WebGLKernelValueSingleArray4}=require2("./kernel-value/single-array4");const{WebGLKernelValueUnsignedArray}=require2("./kernel-value/unsigned-array");const{WebGLKernelValueDynamicUnsignedArray}=require2("./kernel-value/dynamic-unsigned-array");const kernelValueMaps={unsigned:{dynamic:{"Boolean":WebGLKernelValueBoolean,"Integer":WebGLKernelValueInteger,"Float":WebGLKernelValueFloat,"Array":WebGLKernelValueDynamicUnsignedArray,"Array(2)":false,"Array(3)":false,"Array(4)":false,"Array1D(2)":false,"Array1D(3)":false,"Array1D(4)":false,"Array2D(2)":false,"Array2D(3)":false,"Array2D(4)":false,"Array3D(2)":false,"Array3D(3)":false,"Array3D(4)":false,"Input":WebGLKernelValueDynamicUnsignedInput,"NumberTexture":WebGLKernelValueDynamicNumberTexture,"ArrayTexture(1)":WebGLKernelValueDynamicNumberTexture,"ArrayTexture(2)":WebGLKernelValueDynamicNumberTexture,"ArrayTexture(3)":WebGLKernelValueDynamicNumberTexture,"ArrayTexture(4)":WebGLKernelValueDynamicNumberTexture,"MemoryOptimizedNumberTexture":WebGLKernelValueDynamicMemoryOptimizedNumberTexture,"HTMLCanvas":WebGLKernelValueDynamicHTMLImage,"HTMLImage":WebGLKernelValueDynamicHTMLImage,"HTMLImageArray":false,"HTMLVideo":WebGLKernelValueDynamicHTMLVideo},static:{"Boolean":WebGLKernelValueBoolean,"Float":WebGLKernelValueFloat,"Integer":WebGLKernelValueInteger,"Array":WebGLKernelValueUnsignedArray,"Array(2)":false,"Array(3)":false,"Array(4)":false,"Array1D(2)":false,"Array1D(3)":false,"Array1D(4)":false,"Array2D(2)":false,"Array2D(3)":false,"Array2D(4)":false,"Array3D(2)":false,"Array3D(3)":false,"Array3D(4)":false,"Input":WebGLKernelValueUnsignedInput,"NumberTexture":WebGLKernelValueNumberTexture,"ArrayTexture(1)":WebGLKernelValueNumberTexture,"ArrayTexture(2)":WebGLKernelValueNumberTexture,"ArrayTexture(3)":WebGLKernelValueNumberTexture,"ArrayTexture(4)":WebGLKernelValueNumberTexture,"MemoryOptimizedNumberTexture":WebGLKernelValueMemoryOptimizedNumberTexture,"HTMLCanvas":WebGLKernelValueHTMLImage,"HTMLImage":WebGLKernelValueHTMLImage,"HTMLImageArray":false,"HTMLVideo":WebGLKernelValueHTMLVideo}},single:{dynamic:{"Boolean":WebGLKernelValueBoolean,"Integer":WebGLKernelValueInteger,"Float":WebGLKernelValueFloat,"Array":WebGLKernelValueDynamicSingleArray,"Array(2)":WebGLKernelValueSingleArray2,"Array(3)":WebGLKernelValueSingleArray3,"Array(4)":WebGLKernelValueSingleArray4,"Array1D(2)":WebGLKernelValueDynamicSingleArray1DI,"Array1D(3)":WebGLKernelValueDynamicSingleArray1DI,"Array1D(4)":WebGLKernelValueDynamicSingleArray1DI,"Array2D(2)":WebGLKernelValueDynamicSingleArray2DI,"Array2D(3)":WebGLKernelValueDynamicSingleArray2DI,"Array2D(4)":WebGLKernelValueDynamicSingleArray2DI,"Array3D(2)":WebGLKernelValueDynamicSingleArray3DI,"Array3D(3)":WebGLKernelValueDynamicSingleArray3DI,"Array3D(4)":WebGLKernelValueDynamicSingleArray3DI,"Input":WebGLKernelValueDynamicSingleInput,"NumberTexture":WebGLKernelValueDynamicNumberTexture,"ArrayTexture(1)":WebGLKernelValueDynamicNumberTexture,"ArrayTexture(2)":WebGLKernelValueDynamicNumberTexture,"ArrayTexture(3)":WebGLKernelValueDynamicNumberTexture,"ArrayTexture(4)":WebGLKernelValueDynamicNumberTexture,"MemoryOptimizedNumberTexture":WebGLKernelValueDynamicMemoryOptimizedNumberTexture,"HTMLCanvas":WebGLKernelValueDynamicHTMLImage,"HTMLImage":WebGLKernelValueDynamicHTMLImage,"HTMLImageArray":false,"HTMLVideo":WebGLKernelValueDynamicHTMLVideo},static:{"Boolean":WebGLKernelValueBoolean,"Float":WebGLKernelValueFloat,"Integer":WebGLKernelValueInteger,"Array":WebGLKernelValueSingleArray,"Array(2)":WebGLKernelValueSingleArray2,"Array(3)":WebGLKernelValueSingleArray3,"Array(4)":WebGLKernelValueSingleArray4,"Array1D(2)":WebGLKernelValueSingleArray1DI,"Array1D(3)":WebGLKernelValueSingleArray1DI,"Array1D(4)":WebGLKernelValueSingleArray1DI,"Array2D(2)":WebGLKernelValueSingleArray2DI,"Array2D(3)":WebGLKernelValueSingleArray2DI,"Array2D(4)":WebGLKernelValueSingleArray2DI,"Array3D(2)":WebGLKernelValueSingleArray3DI,"Array3D(3)":WebGLKernelValueSingleArray3DI,"Array3D(4)":WebGLKernelValueSingleArray3DI,"Input":WebGLKernelValueSingleInput,"NumberTexture":WebGLKernelValueNumberTexture,"ArrayTexture(1)":WebGLKernelValueNumberTexture,"ArrayTexture(2)":WebGLKernelValueNumberTexture,"ArrayTexture(3)":WebGLKernelValueNumberTexture,"ArrayTexture(4)":WebGLKernelValueNumberTexture,"MemoryOptimizedNumberTexture":WebGLKernelValueMemoryOptimizedNumberTexture,"HTMLCanvas":WebGLKernelValueHTMLImage,"HTMLImage":WebGLKernelValueHTMLImage,"HTMLImageArray":false,"HTMLVideo":WebGLKernelValueHTMLVideo}}};function lookupKernelValueType(type,dynamic,precision,value2){if(!type){throw new Error("type missing")}if(!dynamic){throw new Error("dynamic missing")}if(!precision){throw new Error("precision missing")}if(value2.type){type=value2.type}const types=kernelValueMaps[precision][dynamic];if(types[type]===false){return null}else if(types[type]===void 0){throw new Error(`Could not find a KernelValue for ${type}`)}return types[type]}module3.exports={lookupKernelValueType,kernelValueMaps}},{"./kernel-value/boolean":41,"./kernel-value/dynamic-html-image":42,"./kernel-value/dynamic-html-video":43,"./kernel-value/dynamic-memory-optimized-number-texture":44,"./kernel-value/dynamic-number-texture":45,"./kernel-value/dynamic-single-array":46,"./kernel-value/dynamic-single-array1d-i":47,"./kernel-value/dynamic-single-array2d-i":48,"./kernel-value/dynamic-single-array3d-i":49,"./kernel-value/dynamic-single-input":50,"./kernel-value/dynamic-unsigned-array":51,"./kernel-value/dynamic-unsigned-input":52,"./kernel-value/float":53,"./kernel-value/html-image":54,"./kernel-value/html-video":55,"./kernel-value/integer":57,"./kernel-value/memory-optimized-number-texture":58,"./kernel-value/number-texture":59,"./kernel-value/single-array":60,"./kernel-value/single-array1d-i":61,"./kernel-value/single-array2":62,"./kernel-value/single-array2d-i":63,"./kernel-value/single-array3":64,"./kernel-value/single-array3d-i":65,"./kernel-value/single-array4":66,"./kernel-value/single-input":67,"./kernel-value/unsigned-array":68,"./kernel-value/unsigned-input":69}],40:[function(require2,module3,exports3){const{WebGLKernelValue}=require2("./index");const{Input}=require2("../../../input");class WebGLKernelArray extends WebGLKernelValue{checkSize(width,height){if(!this.kernel.validate)return;const{maxTextureSize}=this.kernel.constructor.features;if(width>maxTextureSize||height>maxTextureSize){if(width>height){throw new Error(`Argument texture width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`)}else if(widthpluginName===plugin.name);if(usePlugin){pluginsToUse.push(plugin)}}}}return pluginsToUse}initExtensions(){this.extensions={OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:this.context.getExtension("WEBGL_color_buffer_float")}}validateSettings(args){if(!this.validate){this.texSize=utils.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output);return}const{features:features2}=this.constructor;if(this.optimizeFloatMemory===true&&!features2.isTextureFloat){throw new Error("Float textures are not supported")}else if(this.precision==="single"&&!features2.isFloatRead){throw new Error("Single precision not supported")}else if(!this.graphical&&this.precision===null&&features2.isTextureFloat){this.precision=features2.isFloatRead?"single":"unsigned"}if(this.subKernels&&this.subKernels.length>0&&!this.extensions.WEBGL_draw_buffers){throw new Error("could not instantiate draw buffers extension")}if(this.fixIntegerDivisionAccuracy===null){this.fixIntegerDivisionAccuracy=!features2.isIntegerDivisionAccurate}else if(this.fixIntegerDivisionAccuracy&&features2.isIntegerDivisionAccurate){this.fixIntegerDivisionAccuracy=false}this.checkOutput();if(!this.output||this.output.length===0){if(args.length!==1){throw new Error("Auto output only supported for kernels with only one input")}const argType=utils.getVariableType(args[0],this.strictIntegers);switch(argType){case"Array":this.output=utils.getDimensions(argType);break;case"NumberTexture":case"MemoryOptimizedNumberTexture":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":this.output=args[0].output;break;default:throw new Error("Auto output not supported for input type: "+argType)}}if(this.graphical){if(this.output.length!==2){throw new Error("Output must have 2 dimensions on graphical mode")}if(this.precision==="precision"){this.precision="unsigned";console.warn("Cannot use graphical mode and single precision at the same time")}this.texSize=utils.clone(this.output);return}else if(this.precision===null&&features2.isTextureFloat){this.precision="single"}this.texSize=utils.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output);this.checkTextureSize()}updateMaxTexSize(){const{texSize,canvas}=this;if(this.maxTexSize===null){let canvasIndex=canvases.indexOf(canvas);if(canvasIndex===-1){canvasIndex=canvases.length;canvases.push(canvas);maxTexSizes[canvasIndex]=[texSize[0],texSize[1]]}this.maxTexSize=maxTexSizes[canvasIndex]}if(this.maxTexSize[0]this.argumentNames.length){throw new Error("too many arguments for kernel")}const{context:gl}=this;let textureIndexes=0;const onRequestTexture=()=>{return this.createTexture()};const onRequestIndex=()=>{return this.constantTextureCount+textureIndexes++};const onUpdateValueMismatch=constructor=>{this.switchKernels({type:"argumentMismatch",needed:constructor})};const onRequestContextHandle=()=>{return gl.TEXTURE0+this.constantTextureCount+this.argumentTextureCount++};for(let index=0;index{return this.createTexture()},onRequestIndex:()=>{return textureIndexes++},onRequestContextHandle:()=>{return gl.TEXTURE0+this.constantTextureCount++}});this.constantBitRatios[name2]=kernelValue.bitRatio;this.kernelConstants.push(kernelValue);kernelValue.setup();if(kernelValue.forceUploadEachRun){this.forceUploadKernelConstants.push(kernelValue)}}}build(){if(this.built)return;this.initExtensions();this.validateSettings(arguments);this.setupConstants(arguments);if(this.fallbackRequested)return;this.setupArguments(arguments);if(this.fallbackRequested)return;this.updateMaxTexSize();this.translateSource();const failureResult=this.pickRenderStrategy(arguments);if(failureResult){return failureResult}const{texSize,context:gl,canvas}=this;gl.enable(gl.SCISSOR_TEST);if(this.pipeline&&this.precision==="single"){gl.viewport(0,0,this.maxTexSize[0],this.maxTexSize[1]);canvas.width=this.maxTexSize[0];canvas.height=this.maxTexSize[1]}else{gl.viewport(0,0,this.maxTexSize[0],this.maxTexSize[1]);canvas.width=this.maxTexSize[0];canvas.height=this.maxTexSize[1]}const threadDim=this.threadDim=Array.from(this.output);while(threadDim.length<3){threadDim.push(1)}const compiledVertexShader=this.getVertexShader(arguments);const vertShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertShader,compiledVertexShader);gl.compileShader(vertShader);this.vertShader=vertShader;const compiledFragmentShader=this.getFragmentShader(arguments);const fragShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragShader,compiledFragmentShader);gl.compileShader(fragShader);this.fragShader=fragShader;if(this.debug){console.log("GLSL Shader Output:");console.log(compiledFragmentShader)}if(!gl.getShaderParameter(vertShader,gl.COMPILE_STATUS)){throw new Error("Error compiling vertex shader: "+gl.getShaderInfoLog(vertShader))}if(!gl.getShaderParameter(fragShader,gl.COMPILE_STATUS)){throw new Error("Error compiling fragment shader: "+gl.getShaderInfoLog(fragShader))}const program=this.program=gl.createProgram();gl.attachShader(program,vertShader);gl.attachShader(program,fragShader);gl.linkProgram(program);this.framebuffer=gl.createFramebuffer();this.framebuffer.width=texSize[0];this.framebuffer.height=texSize[1];this.rawValueFramebuffers={};const vertices=new Float32Array([-1,-1,1,-1,-1,1,1,1]);const texCoords=new Float32Array([0,0,1,0,0,1,1,1]);const texCoordOffset=vertices.byteLength;let buffer=this.buffer;if(!buffer){buffer=this.buffer=gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER,buffer);gl.bufferData(gl.ARRAY_BUFFER,vertices.byteLength+texCoords.byteLength,gl.STATIC_DRAW)}else{gl.bindBuffer(gl.ARRAY_BUFFER,buffer)}gl.bufferSubData(gl.ARRAY_BUFFER,0,vertices);gl.bufferSubData(gl.ARRAY_BUFFER,texCoordOffset,texCoords);const aPosLoc=gl.getAttribLocation(this.program,"aPos");gl.enableVertexAttribArray(aPosLoc);gl.vertexAttribPointer(aPosLoc,2,gl.FLOAT,false,0,0);const aTexCoordLoc=gl.getAttribLocation(this.program,"aTexCoord");gl.enableVertexAttribArray(aTexCoordLoc);gl.vertexAttribPointer(aTexCoordLoc,2,gl.FLOAT,false,0,texCoordOffset);gl.bindFramebuffer(gl.FRAMEBUFFER,this.framebuffer);let i=0;gl.useProgram(this.program);for(let p in this.constants){this.kernelConstants[i++].updateValue(this.constants[p])}this._setupOutputTexture();if(this.subKernels!==null&&this.subKernels.length>0){this._mappedTextureSwitched={};this._setupSubOutputTextures()}this.buildSignature(arguments);this.built=true}translateSource(){const functionBuilder=FunctionBuilder.fromKernel(this,WebGLFunctionNode,{fixIntegerDivisionAccuracy:this.fixIntegerDivisionAccuracy});this.translatedSource=functionBuilder.getPrototypeString("kernel");this.setupReturnTypes(functionBuilder)}setupReturnTypes(functionBuilder){if(!this.graphical&&!this.returnType){this.returnType=functionBuilder.getKernelResultType()}if(this.subKernels&&this.subKernels.length>0){for(let i=0;iplugin.source&&this.source.match(plugin.functionMatch)?plugin.source:"").join("\n")}_getConstantsString(){const result=[];const{threadDim,texSize}=this;if(this.dynamicOutput){result.push("uniform ivec3 uOutputDim","uniform ivec2 uTexSize")}else{result.push(`ivec3 uOutputDim = ivec3(${threadDim[0]}, ${threadDim[1]}, ${threadDim[2]})`,`ivec2 uTexSize = ivec2(${texSize[0]}, ${texSize[1]})`)}return utils.linesToString(result)}_getTextureCoordinate(){const subKernels=this.subKernels;if(subKernels===null||subKernels.length<1){return"varying vec2 vTexCoord;\n"}else{return"out vec2 vTexCoord;\n"}}_getDecode32EndiannessString(){return this.endianness==="LE"?"":" texel.rgba = texel.abgr;\n"}_getEncode32EndiannessString(){return this.endianness==="LE"?"":" texel.rgba = texel.abgr;\n"}_getDivideWithIntegerCheckString(){return this.fixIntegerDivisionAccuracy?`float divWithIntCheck(float x, float y) { - if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) { - return float(int(x) / int(y)); - } - return x / y; - } - - float integerCorrectionModulo(float number, float divisor) { - if (number < 0.0) { - number = abs(number); - if (divisor < 0.0) { - divisor = abs(divisor); - } - return -(number - (divisor * floor(divWithIntCheck(number, divisor)))); - } - if (divisor < 0.0) { - divisor = abs(divisor); - } - return number - (divisor * floor(divWithIntCheck(number, divisor))); - }`:""}_getMainArgumentsString(args){const results=[];const{argumentNames}=this;for(let i=0;i{if(map.hasOwnProperty(artifact)){return map[artifact]}throw`unhandled artifact ${artifact}`})}getFragmentShader(args){if(this.compiledFragmentShader!==null){return this.compiledFragmentShader}return this.compiledFragmentShader=this.replaceArtifacts(this.constructor.fragmentShader,this._getFragShaderArtifactMap(args))}getVertexShader(args){if(this.compiledVertexShader!==null){return this.compiledVertexShader}return this.compiledVertexShader=this.replaceArtifacts(this.constructor.vertexShader,this._getVertShaderArtifactMap(args))}toString(){const setupContextString=utils.linesToString([`const gl = context`]);return glKernelString(this.constructor,arguments,this,setupContextString)}destroy(removeCanvasReferences){if(!this.context)return;if(this.buffer){this.context.deleteBuffer(this.buffer)}if(this.framebuffer){this.context.deleteFramebuffer(this.framebuffer)}for(const width in this.rawValueFramebuffers){for(const height in this.rawValueFramebuffers[width]){this.context.deleteFramebuffer(this.rawValueFramebuffers[width][height]);delete this.rawValueFramebuffers[width][height]}delete this.rawValueFramebuffers[width]}if(this.vertShader){this.context.deleteShader(this.vertShader)}if(this.fragShader){this.context.deleteShader(this.fragShader)}if(this.program){this.context.deleteProgram(this.program)}if(this.texture){this.texture.delete();const textureCacheIndex=this.textureCache.indexOf(this.texture.texture);if(textureCacheIndex>-1){this.textureCache.splice(textureCacheIndex,1)}this.texture=null}if(this.mappedTextures&&this.mappedTextures.length){for(let i2=0;i2-1){this.textureCache.splice(textureCacheIndex,1)}}this.mappedTextures=null}if(this.kernelArguments){for(let i2=0;i20){const texture=this.textureCache.pop();this.context.deleteTexture(texture)}if(removeCanvasReferences){const idx=canvases.indexOf(this.canvas);if(idx>=0){canvases[idx]=null;maxTexSizes[idx]=null}}this.destroyExtensions();delete this.context;delete this.canvas;if(!this.gpu)return;const i=this.gpu.kernels.indexOf(this);if(i===-1)return;this.gpu.kernels.splice(i,1)}destroyExtensions(){this.extensions.OES_texture_float=null;this.extensions.OES_texture_float_linear=null;this.extensions.OES_element_index_uint=null;this.extensions.WEBGL_draw_buffers=null}static destroyContext(context){const extension=context.getExtension("WEBGL_lose_context");if(extension){extension.loseContext()}}toJSON(){const json=super.toJSON();json.functionNodes=FunctionBuilder.fromKernel(this,WebGLFunctionNode).toJSON();json.settings.threadDim=this.threadDim;return json}}module3.exports={WebGLKernel}},{"../../plugins/math-random-uniformly-distributed":112,"../../utils":114,"../function-builder":9,"../gl/kernel":13,"../gl/kernel-string":12,"./fragment-shader":37,"./function-node":38,"./kernel-value-maps":39,"./vertex-shader":71}],71:[function(require2,module3,exports3){const vertexShader=`__FLOAT_TACTIC_DECLARATION__; - __INT_TACTIC_DECLARATION__; - __SAMPLER_2D_TACTIC_DECLARATION__; - - attribute vec2 aPos; - attribute vec2 aTexCoord; - - varying vec2 vTexCoord; - uniform vec2 ratio; - - void main(void) { - gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1); - vTexCoord = aTexCoord; - }`;module3.exports={vertexShader}},{}],72:[function(require2,module3,exports3){const fragmentShader=`#version 300 es - __HEADER__; - __FLOAT_TACTIC_DECLARATION__; - __INT_TACTIC_DECLARATION__; - __SAMPLER_2D_TACTIC_DECLARATION__; - __SAMPLER_2D_ARRAY_TACTIC_DECLARATION__; - - const int LOOP_MAX = __LOOP_MAX__; - - __PLUGINS__; - __CONSTANTS__; - - in vec2 vTexCoord; - - float atan2(float v1, float v2) { - if (v1 == 0.0 || v2 == 0.0) return 0.0; - return atan(v1 / v2); - } - - float cbrt(float x) { - if (x >= 0.0) { - return pow(x, 1.0 / 3.0); - } else { - return -pow(x, 1.0 / 3.0); - } - } - - float expm1(float x) { - return pow(${Math.E}, x) - 1.0; - } - - float fround(highp float x) { - return x; - } - - float imul(float v1, float v2) { - return float(int(v1) * int(v2)); - } - - float log10(float x) { - return log2(x) * (1.0 / log2(10.0)); - } - - float log1p(float x) { - return log(1.0 + x); - } - - float _pow(float v1, float v2) { - if (v2 == 0.0) return 1.0; - return pow(v1, v2); - } - - float _round(float x) { - return floor(x + 0.5); - } - - - const int BIT_COUNT = 32; - int modi(int x, int y) { - return x - y * (x / y); - } - - int bitwiseOr(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; - } - } - return result; - } - int bitwiseXOR(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; - } - } - return result; - } - int bitwiseAnd(int a, int b) { - int result = 0; - int n = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 && b > 0)) { - break; - } - } - return result; - } - int bitwiseNot(int a) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if (modi(a, 2) == 0) { - result += n; - } - a = a / 2; - n = n * 2; - } - return result; - } - int bitwiseZeroFillLeftShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; - } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; - } - n *= 2; - } - - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; - } - - int bitwiseSignedRightShift(int num, int shifts) { - return int(floor(float(num) / pow(2.0, float(shifts)))); - } - - int bitwiseZeroFillRightShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; - } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; - } - n /= 2; - } - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; - } - - vec2 integerMod(vec2 x, float y) { - vec2 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); - } - - vec3 integerMod(vec3 x, float y) { - vec3 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); - } - - vec4 integerMod(vec4 x, vec4 y) { - vec4 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); - } - - float integerMod(float x, float y) { - float res = floor(mod(x, y)); - return res * (res > floor(y) - 1.0 ? 0.0 : 1.0); - } - - int integerMod(int x, int y) { - return x - (y * int(x/y)); - } - - __DIVIDE_WITH_INTEGER_CHECK__; - - // Here be dragons! - // DO NOT OPTIMIZE THIS CODE - // YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE - // LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME - const vec2 MAGIC_VEC = vec2(1.0, -256.0); - const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0); - const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536 - float decode32(vec4 texel) { - __DECODE32_ENDIANNESS__; - texel *= 255.0; - vec2 gte128; - gte128.x = texel.b >= 128.0 ? 1.0 : 0.0; - gte128.y = texel.a >= 128.0 ? 1.0 : 0.0; - float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC); - float res = exp2(round(exponent)); - texel.b = texel.b - 128.0 * gte128.x; - res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res; - res *= gte128.y * -2.0 + 1.0; - return res; - } - - float decode16(vec4 texel, int index) { - int channel = integerMod(index, 2); - return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0; - } - - float decode8(vec4 texel, int index) { - int channel = integerMod(index, 4); - return texel[channel] * 255.0; - } - - vec4 legacyEncode32(float f) { - float F = abs(f); - float sign = f < 0.0 ? 1.0 : 0.0; - float exponent = floor(log2(F)); - float mantissa = (exp2(-exponent) * F); - // exponent += floor(log2(mantissa)); - vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV; - texel.rg = integerMod(texel.rg, 256.0); - texel.b = integerMod(texel.b, 128.0); - texel.a = exponent*0.5 + 63.5; - texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0; - texel = floor(texel); - texel *= 0.003921569; // 1/255 - __ENCODE32_ENDIANNESS__; - return texel; - } - - // https://github.com/gpujs/gpu.js/wiki/Encoder-details - vec4 encode32(float value) { - if (value == 0.0) return vec4(0, 0, 0, 0); - - float exponent; - float mantissa; - vec4 result; - float sgn; - - sgn = step(0.0, -value); - value = abs(value); - - exponent = floor(log2(value)); - - mantissa = value*pow(2.0, -exponent)-1.0; - exponent = exponent+127.0; - result = vec4(0,0,0,0); - - result.a = floor(exponent/2.0); - exponent = exponent - result.a*2.0; - result.a = result.a + 128.0*sgn; - - result.b = floor(mantissa * 128.0); - mantissa = mantissa - result.b / 128.0; - result.b = result.b + exponent*128.0; - - result.g = floor(mantissa*32768.0); - mantissa = mantissa - result.g/32768.0; - - result.r = floor(mantissa*8388608.0); - return result/255.0; - } - // Dragons end here - - int index; - ivec3 threadId; - - ivec3 indexTo3D(int idx, ivec3 texDim) { - int z = int(idx / (texDim.x * texDim.y)); - idx -= z * int(texDim.x * texDim.y); - int y = int(idx / texDim.x); - int x = int(integerMod(idx, texDim.x)); - return ivec3(x, y, z); - } - - float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize)); - return decode32(texel); - } - - float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int w = texSize.x * 2; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y)); - return decode16(texel, index); - } - - float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int w = texSize.x * 4; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y)); - return decode8(texel, index); - } - - float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int channel = integerMod(index, 4); - index = index / 4; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - index = index / 4; - vec4 texel = texture(tex, st / vec2(texSize)); - return texel[channel]; - } - - vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - return texture(tex, st / vec2(texSize)); - } - - vec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - return texture(tex, vec3(st / vec2(texSize), z)); - } - - float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return result[0]; - } - - vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec2(result[0], result[1]); - } - - vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 2); - index = index / 2; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize)); - if (channel == 0) return vec2(texel.r, texel.g); - if (channel == 1) return vec2(texel.b, texel.a); - return vec2(0.0, 0.0); - } - - vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec3(result[0], result[1], result[2]); - } - - vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z)); - int vectorIndex = fieldIndex / 4; - int vectorOffset = fieldIndex - vectorIndex * 4; - int readY = vectorIndex / texSize.x; - int readX = vectorIndex - readY * texSize.x; - vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize)); - - if (vectorOffset == 0) { - return tex1.xyz; - } else if (vectorOffset == 1) { - return tex1.yzw; - } else { - readX++; - if (readX >= texSize.x) { - readX = 0; - readY++; - } - vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize)); - if (vectorOffset == 2) { - return vec3(tex1.z, tex1.w, tex2.x); - } else { - return vec3(tex1.w, tex2.x, tex2.y); - } - } - } - - vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - return getImage2D(tex, texSize, texDim, z, y, x); - } - - vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 2); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize)); - return vec4(texel.r, texel.g, texel.b, texel.a); - } - - vec4 actualColor; - void color(float r, float g, float b, float a) { - actualColor = vec4(r,g,b,a); - } - - void color(float r, float g, float b) { - color(r,g,b,1.0); - } - - float modulo(float number, float divisor) { - if (number < 0.0) { - number = abs(number); - if (divisor < 0.0) { - divisor = abs(divisor); - } - return -mod(number, divisor); - } - if (divisor < 0.0) { - divisor = abs(divisor); - } - return mod(number, divisor); - } - - __INJECTED_NATIVE__; - __MAIN_CONSTANTS__; - __MAIN_ARGUMENTS__; - __KERNEL__; - - void main(void) { - index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x; - __MAIN_RESULT__; - }`;module3.exports={fragmentShader}},{}],73:[function(require2,module3,exports3){const{utils}=require2("../../utils");const{WebGLFunctionNode}=require2("../web-gl/function-node");class WebGL2FunctionNode extends WebGLFunctionNode{astIdentifierExpression(idtNode,retArr){if(idtNode.type!=="Identifier"){throw this.astErrorOutput("IdentifierExpression - not an Identifier",idtNode)}const type=this.getType(idtNode);const name2=utils.sanitizeName(idtNode.name);if(idtNode.name==="Infinity"){retArr.push("intBitsToFloat(2139095039)")}else if(type==="Boolean"){if(this.argumentNames.indexOf(name2)>-1){retArr.push(`bool(user_${name2})`)}else{retArr.push(`user_${name2}`)}}else{retArr.push(`user_${name2}`)}return retArr}}module3.exports={WebGL2FunctionNode}},{"../../utils":114,"../web-gl/function-node":38}],74:[function(require2,module3,exports3){const{WebGL2KernelValueBoolean}=require2("./kernel-value/boolean");const{WebGL2KernelValueFloat}=require2("./kernel-value/float");const{WebGL2KernelValueInteger}=require2("./kernel-value/integer");const{WebGL2KernelValueHTMLImage}=require2("./kernel-value/html-image");const{WebGL2KernelValueDynamicHTMLImage}=require2("./kernel-value/dynamic-html-image");const{WebGL2KernelValueHTMLImageArray}=require2("./kernel-value/html-image-array");const{WebGL2KernelValueDynamicHTMLImageArray}=require2("./kernel-value/dynamic-html-image-array");const{WebGL2KernelValueHTMLVideo}=require2("./kernel-value/html-video");const{WebGL2KernelValueDynamicHTMLVideo}=require2("./kernel-value/dynamic-html-video");const{WebGL2KernelValueSingleInput}=require2("./kernel-value/single-input");const{WebGL2KernelValueDynamicSingleInput}=require2("./kernel-value/dynamic-single-input");const{WebGL2KernelValueUnsignedInput}=require2("./kernel-value/unsigned-input");const{WebGL2KernelValueDynamicUnsignedInput}=require2("./kernel-value/dynamic-unsigned-input");const{WebGL2KernelValueMemoryOptimizedNumberTexture}=require2("./kernel-value/memory-optimized-number-texture");const{WebGL2KernelValueDynamicMemoryOptimizedNumberTexture}=require2("./kernel-value/dynamic-memory-optimized-number-texture");const{WebGL2KernelValueNumberTexture}=require2("./kernel-value/number-texture");const{WebGL2KernelValueDynamicNumberTexture}=require2("./kernel-value/dynamic-number-texture");const{WebGL2KernelValueSingleArray}=require2("./kernel-value/single-array");const{WebGL2KernelValueDynamicSingleArray}=require2("./kernel-value/dynamic-single-array");const{WebGL2KernelValueSingleArray1DI}=require2("./kernel-value/single-array1d-i");const{WebGL2KernelValueDynamicSingleArray1DI}=require2("./kernel-value/dynamic-single-array1d-i");const{WebGL2KernelValueSingleArray2DI}=require2("./kernel-value/single-array2d-i");const{WebGL2KernelValueDynamicSingleArray2DI}=require2("./kernel-value/dynamic-single-array2d-i");const{WebGL2KernelValueSingleArray3DI}=require2("./kernel-value/single-array3d-i");const{WebGL2KernelValueDynamicSingleArray3DI}=require2("./kernel-value/dynamic-single-array3d-i");const{WebGL2KernelValueSingleArray2}=require2("./kernel-value/single-array2");const{WebGL2KernelValueSingleArray3}=require2("./kernel-value/single-array3");const{WebGL2KernelValueSingleArray4}=require2("./kernel-value/single-array4");const{WebGL2KernelValueUnsignedArray}=require2("./kernel-value/unsigned-array");const{WebGL2KernelValueDynamicUnsignedArray}=require2("./kernel-value/dynamic-unsigned-array");const kernelValueMaps={unsigned:{dynamic:{"Boolean":WebGL2KernelValueBoolean,"Integer":WebGL2KernelValueInteger,"Float":WebGL2KernelValueFloat,"Array":WebGL2KernelValueDynamicUnsignedArray,"Array(2)":false,"Array(3)":false,"Array(4)":false,"Array1D(2)":false,"Array1D(3)":false,"Array1D(4)":false,"Array2D(2)":false,"Array2D(3)":false,"Array2D(4)":false,"Array3D(2)":false,"Array3D(3)":false,"Array3D(4)":false,"Input":WebGL2KernelValueDynamicUnsignedInput,"NumberTexture":WebGL2KernelValueDynamicNumberTexture,"ArrayTexture(1)":WebGL2KernelValueDynamicNumberTexture,"ArrayTexture(2)":WebGL2KernelValueDynamicNumberTexture,"ArrayTexture(3)":WebGL2KernelValueDynamicNumberTexture,"ArrayTexture(4)":WebGL2KernelValueDynamicNumberTexture,"MemoryOptimizedNumberTexture":WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,"HTMLCanvas":WebGL2KernelValueDynamicHTMLImage,"HTMLImage":WebGL2KernelValueDynamicHTMLImage,"HTMLImageArray":WebGL2KernelValueDynamicHTMLImageArray,"HTMLVideo":WebGL2KernelValueDynamicHTMLVideo},static:{"Boolean":WebGL2KernelValueBoolean,"Float":WebGL2KernelValueFloat,"Integer":WebGL2KernelValueInteger,"Array":WebGL2KernelValueUnsignedArray,"Array(2)":false,"Array(3)":false,"Array(4)":false,"Array1D(2)":false,"Array1D(3)":false,"Array1D(4)":false,"Array2D(2)":false,"Array2D(3)":false,"Array2D(4)":false,"Array3D(2)":false,"Array3D(3)":false,"Array3D(4)":false,"Input":WebGL2KernelValueUnsignedInput,"NumberTexture":WebGL2KernelValueNumberTexture,"ArrayTexture(1)":WebGL2KernelValueNumberTexture,"ArrayTexture(2)":WebGL2KernelValueNumberTexture,"ArrayTexture(3)":WebGL2KernelValueNumberTexture,"ArrayTexture(4)":WebGL2KernelValueNumberTexture,"MemoryOptimizedNumberTexture":WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,"HTMLCanvas":WebGL2KernelValueHTMLImage,"HTMLImage":WebGL2KernelValueHTMLImage,"HTMLImageArray":WebGL2KernelValueHTMLImageArray,"HTMLVideo":WebGL2KernelValueHTMLVideo}},single:{dynamic:{"Boolean":WebGL2KernelValueBoolean,"Integer":WebGL2KernelValueInteger,"Float":WebGL2KernelValueFloat,"Array":WebGL2KernelValueDynamicSingleArray,"Array(2)":WebGL2KernelValueSingleArray2,"Array(3)":WebGL2KernelValueSingleArray3,"Array(4)":WebGL2KernelValueSingleArray4,"Array1D(2)":WebGL2KernelValueDynamicSingleArray1DI,"Array1D(3)":WebGL2KernelValueDynamicSingleArray1DI,"Array1D(4)":WebGL2KernelValueDynamicSingleArray1DI,"Array2D(2)":WebGL2KernelValueDynamicSingleArray2DI,"Array2D(3)":WebGL2KernelValueDynamicSingleArray2DI,"Array2D(4)":WebGL2KernelValueDynamicSingleArray2DI,"Array3D(2)":WebGL2KernelValueDynamicSingleArray3DI,"Array3D(3)":WebGL2KernelValueDynamicSingleArray3DI,"Array3D(4)":WebGL2KernelValueDynamicSingleArray3DI,"Input":WebGL2KernelValueDynamicSingleInput,"NumberTexture":WebGL2KernelValueDynamicNumberTexture,"ArrayTexture(1)":WebGL2KernelValueDynamicNumberTexture,"ArrayTexture(2)":WebGL2KernelValueDynamicNumberTexture,"ArrayTexture(3)":WebGL2KernelValueDynamicNumberTexture,"ArrayTexture(4)":WebGL2KernelValueDynamicNumberTexture,"MemoryOptimizedNumberTexture":WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,"HTMLCanvas":WebGL2KernelValueDynamicHTMLImage,"HTMLImage":WebGL2KernelValueDynamicHTMLImage,"HTMLImageArray":WebGL2KernelValueDynamicHTMLImageArray,"HTMLVideo":WebGL2KernelValueDynamicHTMLVideo},static:{"Boolean":WebGL2KernelValueBoolean,"Float":WebGL2KernelValueFloat,"Integer":WebGL2KernelValueInteger,"Array":WebGL2KernelValueSingleArray,"Array(2)":WebGL2KernelValueSingleArray2,"Array(3)":WebGL2KernelValueSingleArray3,"Array(4)":WebGL2KernelValueSingleArray4,"Array1D(2)":WebGL2KernelValueSingleArray1DI,"Array1D(3)":WebGL2KernelValueSingleArray1DI,"Array1D(4)":WebGL2KernelValueSingleArray1DI,"Array2D(2)":WebGL2KernelValueSingleArray2DI,"Array2D(3)":WebGL2KernelValueSingleArray2DI,"Array2D(4)":WebGL2KernelValueSingleArray2DI,"Array3D(2)":WebGL2KernelValueSingleArray3DI,"Array3D(3)":WebGL2KernelValueSingleArray3DI,"Array3D(4)":WebGL2KernelValueSingleArray3DI,"Input":WebGL2KernelValueSingleInput,"NumberTexture":WebGL2KernelValueNumberTexture,"ArrayTexture(1)":WebGL2KernelValueNumberTexture,"ArrayTexture(2)":WebGL2KernelValueNumberTexture,"ArrayTexture(3)":WebGL2KernelValueNumberTexture,"ArrayTexture(4)":WebGL2KernelValueNumberTexture,"MemoryOptimizedNumberTexture":WebGL2KernelValueMemoryOptimizedNumberTexture,"HTMLCanvas":WebGL2KernelValueHTMLImage,"HTMLImage":WebGL2KernelValueHTMLImage,"HTMLImageArray":WebGL2KernelValueHTMLImageArray,"HTMLVideo":WebGL2KernelValueHTMLVideo}}};function lookupKernelValueType(type,dynamic,precision,value2){if(!type){throw new Error("type missing")}if(!dynamic){throw new Error("dynamic missing")}if(!precision){throw new Error("precision missing")}if(value2.type){type=value2.type}const types=kernelValueMaps[precision][dynamic];if(types[type]===false){return null}else if(types[type]===void 0){throw new Error(`Could not find a KernelValue for ${type}`)}return types[type]}module3.exports={kernelValueMaps,lookupKernelValueType}},{"./kernel-value/boolean":75,"./kernel-value/dynamic-html-image":77,"./kernel-value/dynamic-html-image-array":76,"./kernel-value/dynamic-html-video":78,"./kernel-value/dynamic-memory-optimized-number-texture":79,"./kernel-value/dynamic-number-texture":80,"./kernel-value/dynamic-single-array":81,"./kernel-value/dynamic-single-array1d-i":82,"./kernel-value/dynamic-single-array2d-i":83,"./kernel-value/dynamic-single-array3d-i":84,"./kernel-value/dynamic-single-input":85,"./kernel-value/dynamic-unsigned-array":86,"./kernel-value/dynamic-unsigned-input":87,"./kernel-value/float":88,"./kernel-value/html-image":90,"./kernel-value/html-image-array":89,"./kernel-value/html-video":91,"./kernel-value/integer":92,"./kernel-value/memory-optimized-number-texture":93,"./kernel-value/number-texture":94,"./kernel-value/single-array":95,"./kernel-value/single-array1d-i":96,"./kernel-value/single-array2":97,"./kernel-value/single-array2d-i":98,"./kernel-value/single-array3":99,"./kernel-value/single-array3d-i":100,"./kernel-value/single-array4":101,"./kernel-value/single-input":102,"./kernel-value/unsigned-array":103,"./kernel-value/unsigned-input":104}],75:[function(require2,module3,exports3){const{WebGLKernelValueBoolean}=require2("../../web-gl/kernel-value/boolean");class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean{}module3.exports={WebGL2KernelValueBoolean}},{"../../web-gl/kernel-value/boolean":41}],76:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGL2KernelValueHTMLImageArray}=require2("./html-image-array");class WebGL2KernelValueDynamicHTMLImageArray extends WebGL2KernelValueHTMLImageArray{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2DArray ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}updateValue(images){const{width,height}=images[0];this.checkSize(width,height);this.dimensions=[width,height,images.length];this.textureSize=[width,height];this.kernel.setUniform3iv(this.dimensionsId,this.dimensions);this.kernel.setUniform2iv(this.sizeId,this.textureSize);super.updateValue(images)}}module3.exports={WebGL2KernelValueDynamicHTMLImageArray}},{"../../../utils":114,"./html-image-array":89}],77:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGLKernelValueDynamicHTMLImage}=require2("../../web-gl/kernel-value/dynamic-html-image");class WebGL2KernelValueDynamicHTMLImage extends WebGLKernelValueDynamicHTMLImage{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2D ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}}module3.exports={WebGL2KernelValueDynamicHTMLImage}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-html-image":42}],78:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGL2KernelValueDynamicHTMLImage}=require2("./dynamic-html-image");class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage{}module3.exports={WebGL2KernelValueDynamicHTMLVideo}},{"../../../utils":114,"./dynamic-html-image":77}],79:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGLKernelValueDynamicMemoryOptimizedNumberTexture}=require2("../../web-gl/kernel-value/dynamic-memory-optimized-number-texture");class WebGL2KernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueDynamicMemoryOptimizedNumberTexture{getSource(){return utils.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}}module3.exports={WebGL2KernelValueDynamicMemoryOptimizedNumberTexture}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-memory-optimized-number-texture":44}],80:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGLKernelValueDynamicNumberTexture}=require2("../../web-gl/kernel-value/dynamic-number-texture");class WebGL2KernelValueDynamicNumberTexture extends WebGLKernelValueDynamicNumberTexture{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2D ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}}module3.exports={WebGL2KernelValueDynamicNumberTexture}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-number-texture":45}],81:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGL2KernelValueSingleArray}=require2("../../web-gl2/kernel-value/single-array");class WebGL2KernelValueDynamicSingleArray extends WebGL2KernelValueSingleArray{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2D ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}updateValue(value2){this.dimensions=utils.getDimensions(value2,true);this.textureSize=utils.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio);this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio;this.checkSize(this.textureSize[0],this.textureSize[1]);this.uploadValue=new Float32Array(this.uploadArrayLength);this.kernel.setUniform3iv(this.dimensionsId,this.dimensions);this.kernel.setUniform2iv(this.sizeId,this.textureSize);super.updateValue(value2)}}module3.exports={WebGL2KernelValueDynamicSingleArray}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array":95}],82:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGL2KernelValueSingleArray1DI}=require2("../../web-gl2/kernel-value/single-array1d-i");class WebGL2KernelValueDynamicSingleArray1DI extends WebGL2KernelValueSingleArray1DI{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2D ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}updateValue(value2){this.setShape(value2);this.kernel.setUniform3iv(this.dimensionsId,this.dimensions);this.kernel.setUniform2iv(this.sizeId,this.textureSize);super.updateValue(value2)}}module3.exports={WebGL2KernelValueDynamicSingleArray1DI}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array1d-i":96}],83:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGL2KernelValueSingleArray2DI}=require2("../../web-gl2/kernel-value/single-array2d-i");class WebGL2KernelValueDynamicSingleArray2DI extends WebGL2KernelValueSingleArray2DI{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2D ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}updateValue(value2){this.setShape(value2);this.kernel.setUniform3iv(this.dimensionsId,this.dimensions);this.kernel.setUniform2iv(this.sizeId,this.textureSize);super.updateValue(value2)}}module3.exports={WebGL2KernelValueDynamicSingleArray2DI}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array2d-i":98}],84:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGL2KernelValueSingleArray3DI}=require2("../../web-gl2/kernel-value/single-array3d-i");class WebGL2KernelValueDynamicSingleArray3DI extends WebGL2KernelValueSingleArray3DI{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2D ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}updateValue(value2){this.setShape(value2);this.kernel.setUniform3iv(this.dimensionsId,this.dimensions);this.kernel.setUniform2iv(this.sizeId,this.textureSize);super.updateValue(value2)}}module3.exports={WebGL2KernelValueDynamicSingleArray3DI}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array3d-i":100}],85:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGL2KernelValueSingleInput}=require2("../../web-gl2/kernel-value/single-input");class WebGL2KernelValueDynamicSingleInput extends WebGL2KernelValueSingleInput{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2D ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}updateValue(value2){let[w,h,d]=value2.size;this.dimensions=new Int32Array([w||1,h||1,d||1]);this.textureSize=utils.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio);this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio;this.checkSize(this.textureSize[0],this.textureSize[1]);this.uploadValue=new Float32Array(this.uploadArrayLength);this.kernel.setUniform3iv(this.dimensionsId,this.dimensions);this.kernel.setUniform2iv(this.sizeId,this.textureSize);super.updateValue(value2)}}module3.exports={WebGL2KernelValueDynamicSingleInput}},{"../../../utils":114,"../../web-gl2/kernel-value/single-input":102}],86:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGLKernelValueDynamicUnsignedArray}=require2("../../web-gl/kernel-value/dynamic-unsigned-array");class WebGL2KernelValueDynamicUnsignedArray extends WebGLKernelValueDynamicUnsignedArray{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2D ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}}module3.exports={WebGL2KernelValueDynamicUnsignedArray}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-unsigned-array":51}],87:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGLKernelValueDynamicUnsignedInput}=require2("../../web-gl/kernel-value/dynamic-unsigned-input");class WebGL2KernelValueDynamicUnsignedInput extends WebGLKernelValueDynamicUnsignedInput{getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2D ${this.id}`,`uniform ${variablePrecision} ivec2 ${this.sizeId}`,`uniform ${variablePrecision} ivec3 ${this.dimensionsId}`])}}module3.exports={WebGL2KernelValueDynamicUnsignedInput}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-unsigned-input":52}],88:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGLKernelValueFloat}=require2("../../web-gl/kernel-value/float");class WebGL2KernelValueFloat extends WebGLKernelValueFloat{}module3.exports={WebGL2KernelValueFloat}},{"../../../utils":114,"../../web-gl/kernel-value/float":53}],89:[function(require2,module3,exports3){const{utils}=require2("../../../utils");const{WebGLKernelArray}=require2("../../web-gl/kernel-value/array");class WebGL2KernelValueHTMLImageArray extends WebGLKernelArray{constructor(value2,settings){super(value2,settings);this.checkSize(value2[0].width,value2[0].height);this.dimensions=[value2[0].width,value2[0].height,value2.length];this.textureSize=[value2[0].width,value2[0].height]}defineTexture(){const{context:gl}=this;gl.activeTexture(this.contextHandle);gl.bindTexture(gl.TEXTURE_2D_ARRAY,this.texture);gl.texParameteri(gl.TEXTURE_2D_ARRAY,gl.TEXTURE_MAG_FILTER,gl.NEAREST);gl.texParameteri(gl.TEXTURE_2D_ARRAY,gl.TEXTURE_MIN_FILTER,gl.NEAREST)}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName}; -`}getSource(){const variablePrecision=this.getVariablePrecisionString();return utils.linesToString([`uniform ${variablePrecision} sampler2DArray ${this.id}`,`${variablePrecision} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${variablePrecision} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(images){const{context:gl}=this;gl.activeTexture(this.contextHandle);gl.bindTexture(gl.TEXTURE_2D_ARRAY,this.texture);gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true);gl.texImage3D(gl.TEXTURE_2D_ARRAY,0,gl.RGBA,images[0].width,images[0].height,images.length,0,gl.RGBA,gl.UNSIGNED_BYTE,null);for(let i=0;iKernel2.isSupported)}static get isKernelMapSupported(){return kernelOrder.some(Kernel2=>Kernel2.isSupported&&Kernel2.features.kernelMap)}static get isOffscreenCanvasSupported(){return typeof Worker!=="undefined"&&typeof OffscreenCanvas!=="undefined"||typeof importScripts!=="undefined"}static get isWebGLSupported(){return WebGLKernel.isSupported}static get isWebGL2Supported(){return WebGL2Kernel.isSupported}static get isHeadlessGLSupported(){return HeadlessGLKernel.isSupported}static get isCanvasSupported(){return typeof HTMLCanvasElement!=="undefined"}static get isGPUHTMLImageArraySupported(){return WebGL2Kernel.isSupported}static get isSinglePrecisionSupported(){return kernelOrder.some(Kernel2=>Kernel2.isSupported&&Kernel2.features.isFloatRead&&Kernel2.features.isTextureFloat)}constructor(settings){settings=settings||{};this.canvas=settings.canvas||null;this.context=settings.context||null;this.mode=settings.mode;this.Kernel=null;this.kernels=[];this.functions=[];this.nativeFunctions=[];this.injectedNative=null;if(this.mode==="dev")return;this.chooseKernel();if(settings.functions){for(let i=0;isettings.argumentTypes[argumentName])}function onRequestFallback(args){console.warn("Falling back to CPU");const fallbackKernel=new CPUKernel(source,{argumentTypes:kernelRun.argumentTypes,constantTypes:kernelRun.constantTypes,graphical:kernelRun.graphical,loopMaxIterations:kernelRun.loopMaxIterations,constants:kernelRun.constants,dynamicOutput:kernelRun.dynamicOutput,dynamicArgument:kernelRun.dynamicArguments,output:kernelRun.output,precision:kernelRun.precision,pipeline:kernelRun.pipeline,immutable:kernelRun.immutable,optimizeFloatMemory:kernelRun.optimizeFloatMemory,fixIntegerDivisionAccuracy:kernelRun.fixIntegerDivisionAccuracy,functions:kernelRun.functions,nativeFunctions:kernelRun.nativeFunctions,injectedNative:kernelRun.injectedNative,subKernels:kernelRun.subKernels,strictIntegers:kernelRun.strictIntegers,debug:kernelRun.debug});fallbackKernel.build.apply(fallbackKernel,args);const result=fallbackKernel.run.apply(fallbackKernel,args);kernelRun.replaceKernel(fallbackKernel);return result}function onRequestSwitchKernel(reasons,args,_kernel){if(_kernel.debug){console.warn("Switching kernels")}let newOutput=null;if(_kernel.signature&&!switchableKernels[_kernel.signature]){switchableKernels[_kernel.signature]=_kernel}if(_kernel.dynamicOutput){for(let i=reasons.length-1;i>=0;i--){const reason=reasons[i];if(reason.type==="outputPrecisionMismatch"){newOutput=reason.needed}}}const Constructor=_kernel.constructor;const argumentTypes=Constructor.getArgumentTypes(_kernel,args);const signature=Constructor.getSignature(_kernel,argumentTypes);const existingKernel=switchableKernels[signature];if(existingKernel){existingKernel.onActivate(_kernel);return existingKernel}const newKernel=switchableKernels[signature]=new Constructor(source,{argumentTypes,constantTypes:_kernel.constantTypes,graphical:_kernel.graphical,loopMaxIterations:_kernel.loopMaxIterations,constants:_kernel.constants,dynamicOutput:_kernel.dynamicOutput,dynamicArgument:_kernel.dynamicArguments,context:_kernel.context,canvas:_kernel.canvas,output:newOutput||_kernel.output,precision:_kernel.precision,pipeline:_kernel.pipeline,immutable:_kernel.immutable,optimizeFloatMemory:_kernel.optimizeFloatMemory,fixIntegerDivisionAccuracy:_kernel.fixIntegerDivisionAccuracy,functions:_kernel.functions,nativeFunctions:_kernel.nativeFunctions,injectedNative:_kernel.injectedNative,subKernels:_kernel.subKernels,strictIntegers:_kernel.strictIntegers,debug:_kernel.debug,gpu:_kernel.gpu,validate,returnType:_kernel.returnType,tactic:_kernel.tactic,onRequestFallback,onRequestSwitchKernel,texture:_kernel.texture,mappedTextures:_kernel.mappedTextures,drawBuffersMap:_kernel.drawBuffersMap});newKernel.build.apply(newKernel,args);kernelRun.replaceKernel(newKernel);kernels.push(newKernel);return newKernel}const mergedSettings=Object.assign({context:this.context,canvas:this.canvas,functions:this.functions,nativeFunctions:this.nativeFunctions,injectedNative:this.injectedNative,gpu:this,validate,onRequestFallback,onRequestSwitchKernel},settingsCopy);const kernel=new this.Kernel(source,mergedSettings);const kernelRun=kernelRunShortcut(kernel);if(!this.canvas){this.canvas=kernel.canvas}if(!this.context){this.context=kernel.context}kernels.push(kernel);return kernelRun}createKernelMap(){let fn;let settings;const argument2Type=typeof arguments[arguments.length-2];if(argument2Type==="function"||argument2Type==="string"){fn=arguments[arguments.length-2];settings=arguments[arguments.length-1]}else{fn=arguments[arguments.length-1]}if(this.mode!=="dev"){if(!this.Kernel.isSupported||!this.Kernel.features.kernelMap){if(this.mode&&kernelTypes.indexOf(this.mode)<0){throw new Error(`kernelMap not supported on ${this.Kernel.name}`)}}}const settingsCopy=upgradeDeprecatedCreateKernelSettings(settings);if(settings&&typeof settings.argumentTypes==="object"){settingsCopy.argumentTypes=Object.keys(settings.argumentTypes).map(argumentName=>settings.argumentTypes[argumentName])}if(Array.isArray(arguments[0])){settingsCopy.subKernels=[];const functions=arguments[0];for(let i=0;i0){throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.')}this.nativeFunctions.push(Object.assign({name:name2,source},settings));return this}injectNative(source){this.injectedNative=source;return this}destroy(){return new Promise((resolve,reject)=>{if(!this.kernels){resolve()}setTimeout(()=>{try{for(let i=0;i{try{accept(run.apply(this,arguments))}catch(e){reject(e)}})};shortcut.replaceKernel=function(replacementKernel){kernel=replacementKernel;bindKernelToShortcut(kernel,shortcut)};bindKernelToShortcut(kernel,shortcut);return shortcut}function bindKernelToShortcut(kernel,shortcut){if(shortcut.kernel){shortcut.kernel=kernel;return}const properties=utils.allPropertiesOf(kernel);for(let i=0;ishortcut.kernel[property]);shortcut.__defineSetter__(property,value2=>{shortcut.kernel[property]=value2})}}shortcut.kernel=kernel}module3.exports={kernelRunShortcut}},{"./utils":114}],112:[function(require2,module3,exports3){const source=`// https://www.shadertoy.com/view/4t2SDh - //note: uniformly distributed, normalized rand, [0,1] - highp float randomSeedShift = 1.0; - highp float slide = 1.0; - uniform highp float randomSeed1; - uniform highp float randomSeed2; - - highp float nrand(highp vec2 n) { - highp float result = fract(sin(dot((n.xy + 1.0) * vec2(randomSeed1 * slide, randomSeed2 * randomSeedShift), vec2(12.9898, 78.233))) * 43758.5453); - randomSeedShift = result; - if (randomSeedShift > 0.5) { - slide += 0.00009; - } else { - slide += 0.0009; - } - return result; - }`;const name2="math-random-uniformly-distributed";const functionMatch=`Math.random()`;const functionReplace=`nrand(vTexCoord)`;const functionReturnType="Number";const onBeforeRun=kernel=>{kernel.setUniform1f("randomSeed1",Math.random());kernel.setUniform1f("randomSeed2",Math.random())};const plugin={name:name2,onBeforeRun,functionMatch,functionReplace,functionReturnType,source};module3.exports=plugin},{}],113:[function(require2,module3,exports3){class Texture{constructor(settings){const{texture,size,dimensions,output,context,type="NumberTexture",kernel,internalFormat,textureFormat}=settings;if(!output)throw new Error('settings property "output" required.');if(!context)throw new Error('settings property "context" required.');if(!texture)throw new Error('settings property "texture" required.');if(!kernel)throw new Error('settings property "kernel" required.');this.texture=texture;if(texture._refs){texture._refs++}else{texture._refs=1}this.size=size;this.dimensions=dimensions;this.output=output;this.context=context;this.kernel=kernel;this.type=type;this._deleted=false;this.internalFormat=internalFormat;this.textureFormat=textureFormat}toArray(){throw new Error(`Not implemented on ${this.constructor.name}`)}clone(){throw new Error(`Not implemented on ${this.constructor.name}`)}delete(){throw new Error(`Not implemented on ${this.constructor.name}`)}clear(){throw new Error(`Not implemented on ${this.constructor.name}`)}}module3.exports={Texture}},{}],114:[function(require2,module3,exports3){const acorn=require2("acorn");const{Input}=require2("./input");const{Texture}=require2("./texture");const FUNCTION_NAME=/function ([^(]*)/;const STRIP_COMMENTS=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;const ARGUMENT_NAMES=/([^\s,]+)/g;const utils={systemEndianness(){return _systemEndianness},getSystemEndianness(){const b=new ArrayBuffer(4);const a=new Uint32Array(b);const c=new Uint8Array(b);a[0]=3735928559;if(c[0]===239)return"LE";if(c[0]===222)return"BE";throw new Error("unknown endianness")},isFunction(funcObj){return typeof funcObj==="function"},isFunctionString(fn){if(typeof fn==="string"){return fn.slice(0,"function".length).toLowerCase()==="function"}return false},getFunctionNameFromString(funcStr){const result=FUNCTION_NAME.exec(funcStr);if(!result||result.length===0)return null;return result[1].trim()},getFunctionBodyFromString(funcStr){return funcStr.substring(funcStr.indexOf("{")+1,funcStr.lastIndexOf("}"))},getArgumentNamesFromString(fn){const fnStr=fn.replace(STRIP_COMMENTS,"");let result=fnStr.slice(fnStr.indexOf("(")+1,fnStr.indexOf(")")).match(ARGUMENT_NAMES);if(result===null){result=[]}return result},clone(obj){if(obj===null||typeof obj!=="object"||obj.hasOwnProperty("isActiveClone"))return obj;const temp=obj.constructor();for(let key in obj){if(Object.prototype.hasOwnProperty.call(obj,key)){obj.isActiveClone=null;temp[key]=utils.clone(obj[key]);delete obj.isActiveClone}}return temp},isArray(array){return!isNaN(array.length)},getVariableType(value2,strictIntegers){if(utils.isArray(value2)){if(value2.length>0&&value2[0].nodeName==="IMG"){return"HTMLImageArray"}return"Array"}switch(value2.constructor){case Boolean:return"Boolean";case Number:if(strictIntegers&&Number.isInteger(value2)){return"Integer"}return"Float";case Texture:return value2.type;case Input:return"Input"}switch(value2.nodeName){case"IMG":return"HTMLImage";case"CANVAS":return"HTMLImage";case"VIDEO":return"HTMLVideo"}if(value2.hasOwnProperty("type")){return value2.type}return"Unknown"},getKernelTextureSize(settings,dimensions){let[w,h,d]=dimensions;let texelCount=(w||1)*(h||1)*(d||1);if(settings.optimizeFloatMemory&&settings.precision==="single"){w=texelCount=Math.ceil(texelCount/4)}if(h>1&&w*h===texelCount){return new Int32Array([w,h])}return utils.closestSquareDimensions(texelCount)},closestSquareDimensions(length){const sqrt=Math.sqrt(length);let high=Math.ceil(sqrt);let low=Math.floor(sqrt);while(high*low0){return lines.join(";\n")+";\n"}else{return"\n"}},warnDeprecated(type,oldName,newName){if(newName){console.warn(`You are using a deprecated ${type} "${oldName}". It has been replaced with "${newName}". Fixing, but please upgrade as it will soon be removed.`)}else{console.warn(`You are using a deprecated ${type} "${oldName}". It has been removed. Fixing, but please upgrade as it will soon be removed.`)}},flipPixels:(pixels,width,height)=>{const halfHeight=height/2|0;const bytesPerRow=width*4;const temp=new Uint8ClampedArray(width*4);const result=pixels.slice(0);for(let y=0;y{return array.subarray(0,width)},erect2DPackedFloat:(array,width,height)=>{const yResults=new Array(height);for(let y=0;y{const zResults=new Array(depth);for(let z=0;z{return array.subarray(0,width)},erectMemoryOptimized2DFloat:(array,width,height)=>{const yResults=new Array(height);for(let y=0;y{const zResults=new Array(depth);for(let z=0;z{const xResults=new Float32Array(width);let i=0;for(let x2=0;x2{const yResults=new Array(height);let i=0;for(let y=0;y{const zResults=new Array(depth);let i=0;for(let z=0;z{const xResults=new Array(width);const xResultsMax=width*4;let i=0;for(let x2=0;x2{const yResults=new Array(height);const XResultsMax=width*4;for(let y=0;y{const xResultsMax=width*4;const zResults=new Array(depth);for(let z=0;z{const xResults=new Array(width);const xResultsMax=width*4;let i=0;for(let x2=0;x2{const xResultsMax=width*4;const yResults=new Array(height);for(let y=0;y{const xResultsMax=width*4;const zResults=new Array(depth);for(let z=0;z{const xResults=new Array(array);const xResultsMax=width*4;let i=0;for(let x2=0;x2{const xResultsMax=width*4;const yResults=new Array(height);for(let y=0;y{const xResultsMax=width*4;const zResults=new Array(depth);for(let z=0;z{const{findDependency,thisLookup,doNotDefine}=settings;let flattened=settings.flattened;if(!flattened){flattened=settings.flattened={}}const ast=acorn.parse(source);const functionDependencies=[];let indent=0;function flatten2(ast2){if(Array.isArray(ast2)){const results=[];for(let i=0;ir!==null);if(declarations.length<1){return""}else{return`${ast2.kind} ${declarations.join(",")}`}case"VariableDeclarator":if(ast2.init.object&&ast2.init.object.type==="ThisExpression"){const lookup=thisLookup(ast2.init.property.name,true);if(lookup){return`${ast2.id.name} = ${flatten2(ast2.init)}`}else{return null}}else{return`${ast2.id.name} = ${flatten2(ast2.init)}`}case"CallExpression":{if(ast2.callee.property.name==="subarray"){return`${flatten2(ast2.callee.object)}.${flatten2(ast2.callee.property)}(${ast2.arguments.map(value2=>flatten2(value2)).join(", ")})`}if(ast2.callee.object.name==="gl"||ast2.callee.object.name==="context"){return`${flatten2(ast2.callee.object)}.${flatten2(ast2.callee.property)}(${ast2.arguments.map(value2=>flatten2(value2)).join(", ")})`}if(ast2.callee.object.type==="ThisExpression"){functionDependencies.push(findDependency("this",ast2.callee.property.name));return`${ast2.callee.property.name}(${ast2.arguments.map(value2=>flatten2(value2)).join(", ")})`}else if(ast2.callee.object.name){const foundSource=findDependency(ast2.callee.object.name,ast2.callee.property.name);if(foundSource===null){return`${ast2.callee.object.name}.${ast2.callee.property.name}(${ast2.arguments.map(value2=>flatten2(value2)).join(", ")})`}else{functionDependencies.push(foundSource);return`${ast2.callee.property.name}(${ast2.arguments.map(value2=>flatten2(value2)).join(", ")})`}}else if(ast2.callee.object.type==="MemberExpression"){return`${flatten2(ast2.callee.object)}.${ast2.callee.property.name}(${ast2.arguments.map(value2=>flatten2(value2)).join(", ")})`}else{throw new Error("unknown ast.callee")}}case"ReturnStatement":return`return ${flatten2(ast2.argument)}`;case"BinaryExpression":return`(${flatten2(ast2.left)}${ast2.operator}${flatten2(ast2.right)})`;case"UnaryExpression":if(ast2.prefix){return`${ast2.operator} ${flatten2(ast2.argument)}`}else{return`${flatten2(ast2.argument)} ${ast2.operator}`}case"ExpressionStatement":return`${flatten2(ast2.expression)}`;case"SequenceExpression":return`(${flatten2(ast2.expressions)})`;case"ArrowFunctionExpression":return`(${ast2.params.map(flatten2).join(", ")}) => ${flatten2(ast2.body)}`;case"Literal":return ast2.raw;case"Identifier":return ast2.name;case"MemberExpression":if(ast2.object.type==="ThisExpression"){return thisLookup(ast2.property.name)}if(ast2.computed){return`${flatten2(ast2.object)}[${flatten2(ast2.property)}]`}return flatten2(ast2.object)+"."+flatten2(ast2.property);case"ThisExpression":return"this";case"NewExpression":return`new ${flatten2(ast2.callee)}(${ast2.arguments.map(value2=>flatten2(value2)).join(", ")})`;case"ForStatement":return`for (${flatten2(ast2.init)};${flatten2(ast2.test)};${flatten2(ast2.update)}) ${flatten2(ast2.body)}`;case"AssignmentExpression":return`${flatten2(ast2.left)}${ast2.operator}${flatten2(ast2.right)}`;case"UpdateExpression":return`${flatten2(ast2.argument)}${ast2.operator}`;case"IfStatement":return`if (${flatten2(ast2.test)}) ${flatten2(ast2.consequent)}`;case"ThrowStatement":return`throw ${flatten2(ast2.argument)}`;case"ObjectPattern":return ast2.properties.map(flatten2).join(", ");case"ArrayPattern":return ast2.elements.map(flatten2).join(", ");case"DebuggerStatement":return"debugger;";case"ConditionalExpression":return`${flatten2(ast2.test)}?${flatten2(ast2.consequent)}:${flatten2(ast2.alternate)}`;case"Property":if(ast2.kind==="init"){return flatten2(ast2.key)}}throw new Error(`unhandled ast.type of ${ast2.type}`)}const result=flatten2(ast);if(functionDependencies.length>0){const flattenedFunctionDependencies=[];for(let i=0;i{if(ast.type!=="VariableDeclaration")throw new Error('Ast is not of type "VariableDeclaration"');const normalizedDeclarations=[];for(let declarationIndex=0;declarationIndex{const rKernel=gpu.createKernel(function(a){const pixel=a[this.thread.y][this.thread.x];return pixel.r*255},{output:[image.width,image.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}});const gKernel=gpu.createKernel(function(a){const pixel=a[this.thread.y][this.thread.x];return pixel.g*255},{output:[image.width,image.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}});const bKernel=gpu.createKernel(function(a){const pixel=a[this.thread.y][this.thread.x];return pixel.b*255},{output:[image.width,image.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}});const aKernel=gpu.createKernel(function(a){const pixel=a[this.thread.y][this.thread.x];return pixel.a*255},{output:[image.width,image.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}});const result=[rKernel(image),gKernel(image),bKernel(image),aKernel(image)];result.rKernel=rKernel;result.gKernel=gKernel;result.bKernel=bKernel;result.aKernel=aKernel;result.gpu=gpu;return result},splitRGBAToCanvases:(gpu,rgba,width,height)=>{const visualKernelR=gpu.createKernel(function(v){const pixel=v[this.thread.y][this.thread.x];this.color(pixel.r/255,0,0,255)},{output:[width,height],graphical:true,argumentTypes:{v:"Array2D(4)"}});visualKernelR(rgba);const visualKernelG=gpu.createKernel(function(v){const pixel=v[this.thread.y][this.thread.x];this.color(0,pixel.g/255,0,255)},{output:[width,height],graphical:true,argumentTypes:{v:"Array2D(4)"}});visualKernelG(rgba);const visualKernelB=gpu.createKernel(function(v){const pixel=v[this.thread.y][this.thread.x];this.color(0,0,pixel.b/255,255)},{output:[width,height],graphical:true,argumentTypes:{v:"Array2D(4)"}});visualKernelB(rgba);const visualKernelA=gpu.createKernel(function(v){const pixel=v[this.thread.y][this.thread.x];this.color(255,255,255,pixel.a/255)},{output:[width,height],graphical:true,argumentTypes:{v:"Array2D(4)"}});visualKernelA(rgba);return[visualKernelR.canvas,visualKernelG.canvas,visualKernelB.canvas,visualKernelA.canvas]},getMinifySafeName:fn=>{try{const ast=acorn.parse(`const value = ${fn.toString()}`);const{init}=ast.body[0].declarations[0];return init.body.name||init.body.body[0].argument.name}catch(e){throw new Error("Unrecognized function type. Please use `() => yourFunctionVariableHere` or function() { return yourFunctionVariableHere; }")}},sanitizeName:function(name2){if(dollarSign.test(name2)){name2=name2.replace(dollarSign,"S_S")}if(doubleUnderscore.test(name2)){name2=name2.replace(doubleUnderscore,"U_U")}else if(singleUnderscore.test(name2)){name2=name2.replace(singleUnderscore,"u_u")}return name2}};const dollarSign=/\$/;const doubleUnderscore=/__/;const singleUnderscore=/_/;const _systemEndianness=utils.getSystemEndianness();module3.exports={utils}},{"./input":110,"./texture":113,"acorn":1}]},{},[107])(107)})}});var import_gpu_browser_min=__toESM(require_gpu_browser_min());function add(a,b){return a+b}function sub(a,b){return a-b}function mul(a,b){return a*b}function div(a,b){return a/b}function cadd(a_real,a_imag,b_real,b_imag){return[a_real+b_real,a_imag+b_imag]}function csub(a_real,a_imag,b_real,b_imag){return[a_real-b_real,a_imag-b_imag]}function cmul(a_real,a_imag,b_real,b_imag){return[a_real*b_real-a_imag*b_imag,a_real*b_imag+a_imag*b_real]}function cexp(a_real,a_imag){const er=Math.exp(a_real);return[er*Math.cos(a_imag),er*Math.sin(a_imag)]}function mag(a,b){return Math.sqrt(a*a+b*b)}function conj(imag){return 0-imag}function lof(n){const sqrt_n=Math.sqrt(n);var factor=3;while(factor<=sqrt_n){if(n%factor===0)return factor;factor+=2}}function mean(arr,len){var mean2=0;for(var i=0;ilen){j=len}var sharedi=shared*j;real=real+signal[j]*Math.cos(sharedi);imag=imag-signal[j]*Math.sin(sharedi);N+=1}return[real/N,imag/N]}function FFTlist(signals,len,freq,n,sr){var real=0;var imag=0;var _len=1/len;var shared=6.28318530718*freq*_len;var skip=1;var N=0;var factor=sr*.25;if(freq<=factor){while(freq<=factor){factor=factor*.5;skip+=1}}for(var i=0;ilen){j=len}var sharedi=shared*j;real=real+signals[j+(len-1)*n]*Math.cos(sharedi);imag=imag-signals[j+(len-1)*n]*Math.sin(sharedi);N+=1}return[real/N,imag/N]}function iDFT(fft,len,freq){var real=0;var imag=0;var _len=1/len;var shared=6.28318530718*freq*_len;for(var i=0;ilen){j=len}var sharedi=shared*j;real=real+fft[j]*Math.cos(sharedi);imag=fft[j]*Math.sin(sharedi)-imag;N+=1}return[real/N,imag/N]}function iFFTlist(signals,len,freq,n,sr){var real=0;var imag=0;var _len=1/len;var shared=6.28318530718*freq*_len;var skip=1;var N=0;var factor=sr*.25;if(freq<=factor){while(freq<=factor){factor=factor*.5;skip+=1}}for(var i=0;ilen){j=len}var sharedi=shared*j;real=real+signals[j+(len-1)*n]*Math.cos(sharedi);imag=signals[j+(len-1)*n]*Math.sin(sharedi)-imag;N+=1}return[real/N,imag/N]}function correlogramsKern(arrays,len){var k=Math.floor(this.thread.x/len)*2;var delay=this.thread.x-Math.floor(this.thread.x/len)*len;var arr1mean=mean(arrays[k],len);var arr2mean=mean(arrays[k+1],len);var arr1Est=est(arrays[k],arr1mean,len);var arr2Est2=est(arrays[k+1],arr2mean,len);var y_x=xcor(arrays[k],arr1mean,arr1Est,arrays[k+1],arr2mean,arr2Est2,len,delay);return y_x}function correlogramsPCKern(arrays,len,means,estimators){var k=Math.floor(this.thread.x/len)*2;var delay=this.thread.x-Math.floor(this.thread.x/len)*len;var arr1mean=means[k];var arr2mean=means[k+1];var arr1Est=estimators[k];var arr2Est2=estimators[k+1];var y_x=xcor(arrays[k],arr1mean,arr1Est,arrays[k+1],arr2mean,arr2Est2,len,delay);return y_x}function dftKern(signal,len,scalar){var result=DFT(signal,len,this.thread.x);return mag(result[0],result[1])*scalar}function idftKern(amplitudes,len,scalar){var result=iDFT(amplitudes,len,this.thread.x);return mag(result[0],result[1])*scalar}function fftKern(signal,len,scalar,sampleRate){var result=FFT(signal,len,this.thread.x,sampleRate);return mag(result[0],result[1])*scalar}function ifftKern(amplitudes,len,scalar,sampleRate){var result=iFFT(amplitudes,len,this.thread.x,sampleRate);return mag(result[0],result[1])*scalar}function listdft2DKern(signals,scalar){var len=this.output.x;var result=DFT(signals[this.thread.y],len,this.thread.x);return mag(result[0],result[1])*scalar}function listdft1DKern(signals,len,scalar){var result=[0,0];if(this.thread.x<=len){result=DFT(signals,len,this.thread.x)}else{var n=Math.floor(this.thread.x/len);result=DFTlist(signals,len,this.thread.x-n*len,n)}return mag(result[0],result[1])*scalar}function listfft1DKern(signals,len,scalar,sps){var result=[0,0];if(this.thread.x<=len){result=FFT(signals,len,this.thread.x,sps)}else{var n=Math.floor(this.thread.x/len);result=FFTlist(signals,len,this.thread.x-n*len,n,sps)}return mag(result[0],result[1])*scalar}function dft_windowedKern(signal,sampleRate,freqStart,freqEnd,scalar){var result=[0,0];var freq=this.thread.x/sampleRate*(freqEnd-freqStart)+freqStart;result=DFT(signal,sampleRate,freq);return mag(result[0],result[1])*scalar}function fft_windowedKern(signal,sampleRate,freqStart,freqEnd,scalar){var result=[0,0];var freq=this.thread.x/sampleRate*(freqEnd-freqStart)+freqStart;result=FFT(signal,sampleRate,freq);return mag(result[0],result[1])*scalar}function idft_windowedKern(amplitudes,sampleRate,freqStart,freqEnd,scalar){var result=[0,0];var freq=this.thread.x/sampleRate*(freqEnd-freqStart)+freqStart;result=iDFT(amplitudes,sampleRate,freq);return mag(result[0],result[1])*scalar}function ifft_windowedKern(amplitudes,sampleRate,freqStart,freqEnd,scalar){var result=[0,0];var freq=this.thread.x/sampleRate*(freqEnd-freqStart)+freqStart;result=iFFT(amplitudes,sampleRate,freq);return mag(result[0],result[1])*scalar}function listdft1D_windowedKern(signals,sampleRate,freqStart,freqEnd,scalar){var result=[0,0];if(this.thread.x=width){i++;continue}let j=-kernelRadius;while(j<=kernelRadius){if(this.thread.y+j<0||this.thread.y+j>=height){j++;continue}kernelOffset=(j+kernelRadius)*kSize+i+kernelRadius;const weights=kernel[kernelOffset];const pixel=img[this.thread.y+i][this.thread.x+j];r+=pixel.r*weights;g+=pixel.g*weights;b+=pixel.b*weights;j++}i++}this.color(r,g,b)}function multiImgConv2DKern(img,width,height,kernels,kernelLengths,nKernels){let r=0,g=0,b=0;for(var i=0;i=width){k++;continue}let j=-kernelRadius;while(j<=kernelRadius){if(this.thread.y+j<0||this.thread.y+j>=height){j++;continue}kernelOffset=(j+kernelRadius)*kSize+k+kernelRadius;const weights=kernels[i][kernelOffset];const pixel=img[this.thread.y+k][this.thread.x+j];r+=pixel.r*weights;g+=pixel.g*weights;b+=pixel.b*weights;j++}k++}}this.color(r,g,b)}function transpose2DKern(mat2){return mat2[this.thread.y][this.thread.x]}var createGpuKernels={correlogramsKern,correlogramsPCKern,dftKern,idftKern,fftKern,ifftKern,dft_windowedKern,idft_windowedKern,fft_windowedKern,ifft_windowedKern,listdft2DKern,listdft1DKern,listfft1DKern,listfft1D_windowedKern,listdft1D_windowedKern,listidft1D_windowedKern,listifft1D_windowedKern,bulkArrayMulKern,multiImgConv2DKern,ImgConv2DKern,transpose2DKern};var addGpuFunctions=[add,sub,mul,div,cadd,csub,cmul,cexp,mag,conj,lof,mean,est,mse,rms,xcor,softmax,DFT,DFTlist,iDFT,iDFTlist,FFT,iFFT,iFFTlist];function makeKrnl(gpu,f,opts={setDynamicOutput:true,setDynamicArguments:true,setPipeline:true,setImmutable:true,setGraphical:false}){const k=gpu.createKernel(f);if(opts.setDynamicOutput)k.setDynamicOutput(true);if(opts.output)k.setOutput(opts.output);if(opts.setDynamicArguments)k.setDynamicArguments(true);if(opts.setPipeline)k.setPipeline(true);if(opts.setImmutable)k.setImmutable(true);if(opts.setGraphical)k.setGraphical(true);return k}function makeCanvasKrnl(gpu,f,opts={output:[300,300],setDynamicArguments:true,setDynamicOutput:true,setPipeline:false,setImmutable:true,setGraphical:true},divId){const k=makeKrnl(gpu,f,opts);const canvas=k.canvas;if(typeof divId==="string")document.getElementById(toAppend).appendChild(canvas);else if(divId)toAppend.appendChild(canvas);else document.body.appendChild(canvas);return k}var gpuUtils=class{constructor(gpu=new GPUjs){this.gpu=gpu;this.kernels=new Map;this.kernel;this.PI=3.141592653589793;this.SQRT1_2=.7071067811865476;this.addFunctions();this.imgkernels={edgeDetection:[-1,-1,-1,-1,8,-1,-1,-1,-1],boxBlur:[1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9],sobelLeft:[1,0,-1,2,0,-2,1,0,-1],sobelRight:[-1,0,1,-2,0,2,-1,0,1],sobelTop:[1,2,1,0,0,0,-1,-2,-1],sobelBottom:[-1,2,1,0,0,0,1,2,1],identity:[0,0,0,0,1,0,0,0,0],gaussian3x3:[1,2,1,2,4,2,1,2,1],guassian7x7:[0,0,0,5,0,0,0,0,5,18,32,18,5,0,0,18,64,100,64,18,0,5,32,100,100,100,32,5,0,18,64,100,64,18,0,0,5,18,32,18,5,0,0,0,0,5,0,0,0],emboss:[-2,-1,0,-1,1,1,0,1,2],sharpen:[0,-1,0,-1,5,-1,0,-1,0]}}addFunction(func=function f(){}){this.gpu.addFunction(func)}addKernel(name2="",krnl=function foo(){},opts){let found=this.kernels.get(name2);if(!found){this.kernels.set(name2,makeKrnl(this.gpu,krnl,opts));return true}else{console.error("Kernel already exists");return false}}addCanvasKernel(name2,f,opts,divId){let found=this.kernels.get(name2);if(!found){let krnl=makeCanvasKrnl(this.gpu,f,opts,divId);this.kernels.set(name2,krnl);return krnl}else{console.error("Kernel already exists");return false}}combineKernels(name2,fs=[],ckrnl=function foo(){}){let found=this.kernels.get(name2);if(!found){fs.forEach((f,i)=>{if(typeof f==="string"){let found2=this.kernels.get(f);if(found2)fs[i]=found2;else return false}else if(typeof f==="function"){if(this.kernels.get(f.name)){}else{this.addKernel(f.name,f)}}});let krnl=this.gpu.combineKernels(...fs,ckrnl);this.kernels.set(name2,krnl);return krnl}else{console.error("Kernel already exists");return false}}callKernel(name2="",args=[]){let result;let krnl=this.kernels.get(name2);if(!krnl){console.error("Kernel not found");return false}result=krnl(...args);return result}callCanvasKernel(name2="",args=[],outputDims=[]){let result;let krnl=this.kernels.get(name2);if(!krnl){console.error("Kernel not found");return false}else{if(outputDims.length===2)krnl.setOutput(outputDims);result=krnl(...args);return result}}hasKernel(name2=""){let found=this.kernels.get(name2);if(!found){return false}else return true}addFunctions(){addGpuFunctions.forEach(f=>this.gpu.addFunction(f));this.correlograms=makeKrnl(this.gpu,createGpuKernels.correlogramsKern);this.correlogramsPC=makeKrnl(this.gpu,createGpuKernels.correlogramsPCKern);this.dft=makeKrnl(this.gpu,createGpuKernels.dftKern);this.idft=makeKrnl(this.gpu,createGpuKernels.idftKern);this.dft_windowed=makeKrnl(this.gpu,createGpuKernels.dft_windowedKern);this.idft_windowed=makeKrnl(this.gpu,createGpuKernels.idft_windowedKern);this.fft=makeKrnl(this.gpu,createGpuKernels.fftKern);this.ifft=makeKrnl(this.gpu,createGpuKernels.ifftKern);this.fft_windowed=makeKrnl(this.gpu,createGpuKernels.fft_windowedKern);this.ifft_windowed=makeKrnl(this.gpu,createGpuKernels.ifft_windowedKern);this.listdft2D=makeKrnl(this.gpu,createGpuKernels.listdft2DKern);this.listdft1D=makeKrnl(this.gpu,createGpuKernels.listdft1DKern);this.listdft1D_windowed=makeKrnl(this.gpu,createGpuKernels.listdft1D_windowedKern);this.listfft1D=makeKrnl(this.gpu,createGpuKernels.listfft1DKern);this.listfft1D_windowed=makeKrnl(this.gpu,createGpuKernels.listfft1D_windowedKern);this.listidft1D_windowed=makeKrnl(this.gpu,createGpuKernels.listidft1D_windowedKern);this.listifft1D_windowed=makeKrnl(this.gpu,createGpuKernels.listifft1D_windowedKern);this.bulkArrayMul=makeKrnl(this.gpu,createGpuKernels.bulkArrayMulKern);let kernels=[{name:"correlograms",krnl:this.correlograms},{name:"correlogramsPC",krnl:this.correlogramsPC},{name:"dft",krnl:this.dft},{name:"idft",krnl:this.idft},{name:"dft_windowed",krnl:this.idft_windowed},{name:"fft",krnl:this.fft},{name:"ifft",krnl:this.ifft},{name:"fft_windowed",krnl:this.fft_windowed},{name:"ifft_windowed",krnl:this.ifft_windowed},{name:"listdft2D",krnl:this.listdft2D},{name:"listdft1D",krnl:this.listdft1D},{name:"listdft1D_windowed",krnl:this.listdft1D_windowed},{name:"listfft1D",krnl:this.listfft1D},{name:"listfft1D_windowed",krnl:this.listfft1D_windowed},{name:"listidft1D_windowed",krnl:this.listidft1D_windowed},{name:"listifft1D_windowed",krnl:this.listifft1D_windowed},{name:"bulkArrayMul",krnl:this.bulkArrayMul}];kernels.forEach(k=>{this.kernels.set(k.name,k)});const signalBandpass=(signal,sampleRate,freqStart,freqEnd,scalar)=>{var dft2=this.fft_windowed(signal,sampleRate,freqStart,freqEnd,scalar,0);var filtered_signal=this.ifft_windowed(dft2,sampleRate,freqStart,freqEnd,scalar);return filtered_signal};const signalBandpassMulti=(signals,sampleRate,freqStart,freqEnd,scalar)=>{var dfts=this.listdft1D_windowed(signals,sampleRate,freqStart,freqEnd,scalar,new Array(Math.ceil(signals/sampleRate)).fill(0));var filtered_signals=this.listifft1D_windowed(dfts,sampleRate,freqStart,freqEnd,scalar);return filtered_signals};this.gpuCoherence=(signals,sampleRate,freqStart,freqEnd,scalar)=>{var xcors=this.correlograms(signals);var dfts=this.listfft1D_windowed(xcors,sampleRate,freqStart,freqEnd,scalar,new Array(Math.ceil(signals/sampleRate)).fill(0));var products=this.bulkArrayMul(dfts,sampleRate,5,1);return products}}gpuXCors(arrays,precompute=false,texOut=false){var outputTex;if(precompute===true){var means=[];var ests=[];arrays.forEach((arr,i2)=>{means.push(arr.reduce((prev,curr)=>curr+=prev)/arr.length);ests.push(Math.sqrt(means[i2].reduce((sum,item)=>sum+=Math.pow(item-mean1,2))))});var meansbuf=[];var estsbuf=[];var buffer=[];for(var i=0;i{signalBufferProcessed.push(...row)});var nSamplesPerChannel=signalBuffer[0].length;var sampleRate=nSamplesPerChannel/nSeconds;this.listdft1D.setOutput([signalBufferProcessed.length]);this.listdft1D.setLoopMaxIterations(nSamplesPerChannel);var outputTex=this.listdft1D(signalBufferProcessed,nSamplesPerChannel,scalar);if(texOut===false){var orderedMagsList=[];var freqDist=this.makeFrequencyDistribution(nSamplesPerChannel,sampleRate);signalBufferProcessed=outputTex.toArray();for(var i=0;i{signalBufferProcessed.push(...row)});var freqEnd_nyquist=freqEnd*2;var nSamplesPerChannel=signalBuffer[0].length;var sampleRate=nSamplesPerChannel/nSeconds;this.listdft1D_windowed.setOutput([signalBufferProcessed.length]);this.listdft1D_windowed.setLoopMaxIterations(nSamplesPerChannel);var outputTex=this.listdft1D_windowed(signalBufferProcessed,sampleRate,freqStart,freqEnd_nyquist,scalar);if(texOut===true){return outputTex}signalBufferProcessed=outputTex.toArray();outputTex.delete();var freqDist=this.bandPassWindow(freqStart,freqEnd,sampleRate);return[freqDist,this.orderBPMagnitudes(signalBufferProcessed,nSeconds,sampleRate,nSamplesPerChannel)]}gpuFFT(signalBuffer,nSeconds,scalar=1,sampleRate,texOut=false){var nSamples=signalBuffer.length;var sampleRate=nSamples/nSeconds;this.fft.setOutput([signalBuffer.length]);this.fft.setLoopMaxIterations(nSamples);var outputTex=this.fft(signalBuffer,nSamples,scalar,sampleRate);var output=null;if(texOut===false){var freqDist=this.makeFrequencyDistribution(nSamples,sampleRate);var signalBufferProcessed=outputTex.toArray();outputTex.delete();return[freqDist,this.orderMagnitudes(signalBufferProcessed)]}else{var tex=outputTex;outputTex.delete();return tex}}MultiChannelFFT(signalBuffer,nSeconds,scalar=1,texOut=false){var signalBufferProcessed=[];signalBuffer.forEach(row=>{signalBufferProcessed.push(...row)});var nSamplesPerChannel=signalBuffer[0].length;var sampleRate=nSamplesPerChannel/nSeconds;this.listfft1D.setOutput([signalBufferProcessed.length]);this.listfft1D.setLoopMaxIterations(nSamplesPerChannel);var outputTex=this.listfft1D(signalBufferProcessed,nSamplesPerChannel,scalar,sampleRate);if(texOut===false){var orderedMagsList=[];var freqDist=this.makeFrequencyDistribution(nSamplesPerChannel,sampleRate);signalBufferProcessed=outputTex.toArray();for(var i=0;i{signalBufferProcessed.push(...row)});var freqEnd_nyquist=freqEnd*2;var nSamplesPerChannel=signalBuffer[0].length;var sampleRate=nSamplesPerChannel/nSeconds;this.listfft1D_windowed.setOutput([signalBufferProcessed.length]);this.listfft1D_windowed.setLoopMaxIterations(nSamplesPerChannel);var outputTex=this.listfft1D_windowed(signalBufferProcessed,sampleRate,freqStart,freqEnd_nyquist,scalar);if(texOut===true){return outputTex}signalBufferProcessed=outputTex.toArray();outputTex.delete();var freqDist=this.bandPassWindow(freqStart,freqEnd,sampleRate);return[freqDist,this.orderBPMagnitudes(signalBufferProcessed,nSeconds,sampleRate,nSamplesPerChannel)]}orderMagnitudes(unorderedMags){return[...unorderedMags.slice(Math.ceil(unorderedMags.length*.5),unorderedMags.length),...unorderedMags.slice(0,Math.ceil(unorderedMags.length*.5))]}makeFrequencyDistribution(FFTlength,sampleRate){var N=FFTlength;var df=sampleRate/N;var freqDist=[];for(var i=-N/2;i1){magList.forEach((row,k)=>{summedMags.push([]);var _max=1/Math.max(...row);for(var i2=0;i2{s/=100;l/=100;let c=(1-Math.abs(2*l-1))*s,x2=c*(1-Math.abs(h/60%2-1)),m=l-c/2,r=0,g=0,b=0;if(0<=h&&h<60){r=c;g=x2;b=0}else if(60<=h&&h<120){r=x2;g=c;b=0}else if(120<=h&&h<180){r=0;g=c;b=x2}else if(180<=h&&h<240){r=0;g=x2;b=c}else if(240<=h&&h<300){r=x2;g=0;b=c}else if(300<=h&&h<360){r=c;g=0;b=x2}r=(r+m)*scalar;g=(g+m)*scalar;b=(b+m)*scalar;return[r,g,b]};static genSineWave=(freq=20,peakAmp=1,nSec=1,fs=512,freq2=0,peakAmp2=1)=>{var sineWave=[];var t=[];var increment=1/fs;for(var ti=0;ti{return Math.sin(this.TWO_PI*frequency*ti+tOffset)*peakAmplitude};static mean=arr=>{var sum=arr.reduce((prev,curr)=>curr+=prev);return sum/arr.length};static median=data=>{const sortedData=data.slice().sort((a,b)=>a-b);const middle=Math.floor(sortedData.length/2);if(sortedData.length%2===0){return(sortedData[middle-1]+sortedData[middle])/2}else{return sortedData[middle]}};static mode=arr=>{return arr.sort((a,b)=>arr.filter(v=>v===a).length-arr.filter(v=>v===b).length).pop()};static range=data=>{return Math.max(...data)-Math.min(...data)};static std=(arr,mean2=void 0)=>{let avg=mean2;if(!mean2)avg=this.mean(arr);let summed=0;for(let i=0;i{if(actual.length!==forecast.length)throw new Error("Input arrays of same length!");let i=actual.length;let d=new Array(actual.length);for(let j=0;j{let len=probabilities.length;let entropy=new Array(len);for(let i=0;i{let mean2=this.mean(arr);let std=this.std(arr,mean2);let z=new Array(arr.length);for(let i=0;ia+(b-mean2)**2,0)/arr.length}static coeffVariation=(arr,populationMean)=>{let mean2=this.mean(arr);let std=this.std(arr,mean2);return populationMean?std/populationMean:std/mean2};static coeffDetermination=(observed,expected)=>{const meanY=this.mean(observed);const ssTotal=observed.reduce((acc,y)=>acc+Math.pow(y-meanY,2),0);const ssResidual=observed.reduce((acc,y,i)=>acc+Math.pow(y-expected[i],2),0);return 1-ssResidual/ssTotal};static percentile=(arr,p)=>{const sortedData=arr.slice().sort((a,b)=>a-b);const index=Math.ceil(p*(sortedData.length-1));return sortedData[index]};static interquartileRange=arr=>{const sortedData=arr.slice().sort((a,b)=>a-b);const index=Math.ceil(.25*(sortedData.length-1));const index2=Math.ceil(.75*(sortedData.length-1));const q1=sortedData[index];const q3=sortedData[index2];return q3-q1};static skewness=arr=>{const n=arr.length;const meanValue=this.mean(arr);const stdDevValue=this.std(arr);const sumCubedDeviation=arr.reduce((acc,value2)=>acc+Math.pow(value2-meanValue,3),0);const skew=sumCubedDeviation/(n*Math.pow(stdDevValue,3));return skew};static kurtosis=arr=>{const n=arr.length;const meanValue=this.mean(arr);const stdDevValue=this.std(arr);const sumFourthDeviation=arr.reduce((acc,value2)=>acc+Math.pow(value2-meanValue,4),0);const kurt=sumFourthDeviation/(n*Math.pow(stdDevValue,4))-3;return kurt};static chiSquareTest=(observed,expected)=>{const chiSquared=observed.reduce((acc,obs,i)=>{const exp=expected[i];return acc+Math.pow(obs-exp,2)/exp},0);return chiSquared};static simpleLinearRegression=(xCoords,yCoords)=>{const n=xCoords.length;const sumX=xCoords.reduce((sum,x2)=>sum+x2,0);const sumY=yCoords.reduce((sum,y)=>sum+y,0);const sumXY=xCoords.reduce((sum,x2,i)=>sum+x2*yCoords[i],0);const sumX2=xCoords.reduce((sum,x2)=>sum+x2*x2,0);const slope=(n*sumXY-sumX*sumY)/(n*sumX2-sumX*sumX);const intercept=(sumY-slope*sumX)/n;return{slope,intercept}};static pad=(arr,pad=1,padValue=0)=>{if(Array.isArray(arr[0]))return pad2D(arr,pad);if(pad>0){let pads=new Array(pad).fill(padValue);arr=[...pads,...arr,...pads]}return arr};static pad2D=(array,pad,padValue=0)=>{let pads=new Array(pad).fill(padValue);const paddedArray=array.map(row=>{return[...pads,...row,...pads]});const paddedRow=new Array(array[0].length+2*pad).fill(padValue);for(let i=0;i{const firstElem=array[0];const lastElem=array[array.length-1];const startPadding=new Array(padSize).fill(firstElem);const endPadding=new Array(padSize).fill(lastElem);return startPadding.concat(array,endPadding)};static edgePad2D=(matrix,padSize)=>{const topRows=Array(padSize).fill(matrix[0]);const bottomRows=Array(padSize).fill(matrix[matrix.length-1]);const paddedMatrix=topRows.concat(matrix,bottomRows);for(let i=0;i{const nVecs=vectors.length;return vectors[0].map((v,i)=>{for(let j=1;j{const nVecs=vectors.length;return vectors[0].map((v,i)=>{for(let j=1;j{return vec.map((v,i)=>v-subvec[i])};static vecdiv=(numvec,denvec)=>{return numvec.map((v,i)=>v/denvec[i])};static vecscale=(vec,scalar)=>{return vec.map((v,i)=>v*scalar)};static vecaddScalar=(vec,scalar)=>{return vec.map((v,i)=>v+scalar)};static vecmulScalar=(vec,scalar)=>{return vec.map((v,i)=>v*scalar)};static vecsubScalar=(vec,scalar)=>{return vec.map((v,i)=>v-scalar)};static vecdivScalar=(vec,scalar)=>{return vec.map((v,i)=>v/scalar)};static dot=(vec1,vec2)=>{var dot=0;for(var i=0;i{return[vec1[1]*vec2[2]-vec1[2]*vec2[1],vec1[2]*vec2[0]-vec1[0]*vec2[2],vec1[0]*vec2[1]-vec1[1]*vec2[0]]};static sphericalToCartesian=(r,theta,phi)=>{return{x:r*Math.sin(phi)*Math.cos(theta),y:r*Math.sin(phi)*Math.sin(theta),z:r*Math.cos(phi)}};static cartesianToSpherical=(x2,y,z)=>{var r=Math.sqrt(x2*x2+y*y+z*z);var theta=Math.atan2(y,x2);var phi=Math.acos(z/r);return{r,theta,phi}};static magnitude=vec=>{var sqrd=0;vec.forEach(c=>{sqrd+=c*c});return Math.sqrt(sqrd)};static distance=(point1,point2)=>{var dsqrd=0;point1.forEach((c,i)=>{dsqrd+=(point2[i]-c)*(point2[i]-c)});return Math.sqrt(dsqrd)};static midpoint=(point1=[1,2,3],point2=[3,4,5])=>{return point1.map((c,i)=>{return(c+point2[i])*.5})};static project=(vec1,vec2)=>{const dot=this.dot(vec1,vec2);const magSqrd=this.magnitude(vec2)**2;return this.vecmulScalar(vec2,dot/magSqrd)};static angleBetween=(vec1,vec2)=>{const dotProduct=this.dot(vec1,vec2);const magProduct=this.magnitude(vec1)*this.magnitude(vec2);return Math.acos(dotProduct/magProduct)};static normalize=vec=>{var norm=0;norm=1/this.magnitude(vec);var vecn=new Array(vec.length);vec.forEach((c,i)=>{vecn[i]=c*norm});return vecn};static normalizeSeries=(arr=[],fromZero=true)=>{let max=Math.max(...arr);let min=Math.min(...arr);if(fromZero==false){max=Math.max(max,Math.abs(min));min=0}if(max-min===0){min=0;if(max===0)max=1e-13}return arr.map(v=>(v-min)/(max-min))};static quadraticFormula=(a,b,c)=>{let bbmac4=Math.sqrt(b*b-4*a*c);if(!isNaN(bbmac4))return["complex","complex"];let _a2=1/(2*a);if(bbmac4===0)return[b*_a2];let nb=-b;return[(nb+bbmac4)*_a2,(nb-bbmac4)*_a2]};static newtonsMethod1D=(foo=x2=>{return Math.pow(x2,5)+x2*x2-x2-.2},start=0,end=1,precision=.01,attempts=10)=>{let roots=[];for(let i=0;iprecision){let step=-guess/slope2;let xn12=xn+step;guess=guess2;guess2=foo(xn12);let slope2=(guess2-guess)/(xn12-xn)}let idx;let f=roots.find((root,i2)=>{if(Math.abs(xn1-root){let y=x2;return y},range=[0,1],stepx=.01)=>{let area=0;for(let i=range[0];i{let z=x2+y;return z},range=[[0,1],[0,1]],stepx=.01,stepy=stepx)=>{let volume=0;for(let i=range[0][0]+stepx;i{let w=x2+y+z;return w},range=[[0,1],[0,1],[0,1]],stepx=.01,stepy=stepx,stepz=stepx)=>{let volume=0;for(let i=range[0][0]+stepx;i{let y=x2;return y},range=[0,1],stepx=.01)=>{let length=0;let y0=func(range[0]);for(let i=range[0]+stepx;i<=range[1];i+=stepx){let yi=func(i);length+=Math.sqrt(stepx**2+(yi-y0)**2);y0=yi}return length};static pathIntegral2D=(xFunc=t=>{let x2=Math.cos(t);return x2},yFunc=t=>{let y=Math.sin(t);return y},range=[[0,1],[0,1]],stept=.01)=>{let length=0;let x0=xFunc(range[0][0]);let y0=yFunc(range[1][0]);let tMaxX=range[0][1];let tMaxY=range[1][1];let tMax=Math.max(tMaxX,tMaxY);for(let t=0;t<=tMax;t+=stept){let xi=xFunc(Math.min(t,tMaxX));let yi=yFunc(Math.min(t,tMaxY));length+=Math.sqrt((xi-x0)**2+(yi-y0)**2);x0=xi;y0=yi}return length};static pathIntegral3D=(xFunc=(u,v)=>u,yFunc=(u,v)=>v,zFunc=(u,v)=>u+v,rangeU=[0,1],rangeV=[0,1],stepU=.01,stepV=.01)=>{let area=0;for(let u=rangeU[0];u{var vec=[];point1.forEach((c,i)=>{vec.push(point2[i]-c)});return vec};static getBufferedValueByCoordinates=(vb=new Array(300).fill(1),dims=[10,10,2],coordinate=[1,2,1],cardinal=void 0)=>{let getIdx=(foundIdx=0,dimIdx=0)=>{if(dimIdx===dims.length)return foundIdx;if(dimIdx==0)foundIdx+=coordinate[dimIdx];else if(dims[dimIdx]==0)dimsAt0++;else{let reMul=(val=coordinate[dimIdx],di=dimIdx-1)=>{val*=dims[di];di--;if(di==0)return val;else return reMul(val,di)};foundIdx+=reMul(coordinate[dimIdx]+1,dimIdx-1)}dimIdx++;return getIdx(foundIdx,dimIdx)};let found=getIdx();if(cardinal){if(coordinate[coordinate.length-1]===0){let lastnonzero=0;let idx=0;while(idx!==coordinate.length-1){if(coordinate[idx]!==0)lastnonzero=idx;idx++}return vb[found-lastnonzero+cardinal]}return vb[found-dims.length+cardinal]}else{if(coordinate[coordinate.length-1]===0){let lastnonzero=0;let idx=0;while(idx!==coordinate.length-1){if(coordinate[idx]!==0)lastnonzero=idx;idx++}return vb.slice(found-lastnonzero,found+1)}return vb.slice(found-dims.length,found+1)}};static forBufferedMat=(vb=new Array(100).fill(1),dims=[10,10],asIndex=(v,i,x2,y)=>{return v+x2+y})=>{let coordinate=[];let idx=0;let recurseFor=(depth=0,nextDepth=depth+1)=>{let result=new Array(vb.length);for(let di=0;di{let result=new Array(vb.length);for(let di=0;di{console.log(`value:${v}, idx:${idx}, x:${i},y:${j}`);return v+i+j})=>{let coordinate=new Array(dimensions.length).fill(0);const iterateCoordinate=(coord,idx=0)=>{if(coord[idx]>=dimensions[idx]){coord[idx]=0;idx++;if(idx===dimensions.length)return;iterateCoordinate(coord,idx)}else coord[idx]++};let result=new Array(buffer.length);let i=0;if(typeof asIndex==="function"){while(i{result[i]=func(buffer[i],i,...coordinate);i++;iterateCoordinate(coordinate)})}}return result};static combinations=(choices=["a","b","c"],vecsize=3)=>{var result=[];if(vecsize<=0){result.push([])}else{_Math2.combinations(choices,vecsize-1).forEach(function(previousComb){choices.forEach(function(element){result.push([element].concat(previousComb))})})}return result};static generateCoordinateSpace=(upperBounds=[10,10,10],lowerBounds=[-10,-10,-10],steps=[1,1,1],mutater=void 0)=>{for(let i=0;iupperBounds[i]){let temp=upperBounds[i];upperBounds[i]=lowerBounds[i];lowerBounds[i]=temp}}let result=[];let copy=[...upperBounds];let lastindex=copy.length-1;result.push([...copy]);while(copy[0]>=lowerBounds[0]){let checkNextIndex=decrIdx2=>{if(copy[decrIdx2]<=lowerBounds[decrIdx2]){if(decrIdx2===0)return;copy[decrIdx2]=upperBounds[decrIdx2];decrIdx2--;if(decrIdx2<0)return;if(typeof steps[decrIdx2]=="function")copy[decrIdx2]-=steps[decrIdx2](copy[decrIdx2]);else copy[decrIdx2]-=steps[decrIdx2];checkNextIndex(decrIdx2)}};let decrIdx=lastindex;if(typeof steps[decrIdx]=="function")copy[decrIdx]-=steps[decrIdx](copy[decrIdx]);else copy[decrIdx]-=steps[decrIdx];result.push([...copy]);checkNextIndex(decrIdx);if(mutater)result[result.length-1]=mutater(result[result.length-1])}return result};static meshgrid=_Math2.generateCoordinateSpace;static calcVectorField=(coordinates=[[0,0],[0,1],[1,0],[1,1]],formula=(x2,y)=>{return[x2*10,y*10]})=>{return coordinates.map(vec=>formula(...vec))};static randomMatrix=(rows,cols)=>{return Array.from({length:rows},()=>Array.from({length:cols},()=>Math.random()))};static identityMatrix=size=>{return Array.from({length:size},(_,i)=>Array.from({length:size},(_2,j)=>i===j?1:0))};static diagonalMatrix=values=>{return values.map((value2,index)=>{const row=Array(values.length).fill(0);row[index]=value2;return row})};static householderMatrix=v=>{const size=v.length;const vvT=v.map(rowVal=>v.map(colVal=>rowVal*colVal));const vTv=this.normalize(v)**2;return Array.from({length:size},(_,i)=>Array.from({length:size},(_2,j)=>(i===j?1:0)-2*vvT[i][j]/vTv))};static transpose=mat=>{return mat[0].map((_,colIndex)=>mat.map(row=>row[colIndex]))};static clone=mat=>{return mat.map(row=>{if(Array.isArray(row[0]))return this.clone(row);else return[...row]})};static getColumn(matrix,col){return matrix.map(row=>row[col])}static matmul=(A,B)=>{return A.map(row=>B[0].map((_,colIndex)=>row.reduce((sum,cell,rowIndex)=>sum+cell*B[rowIndex][colIndex],0)))};static matscale=(mat,scalar)=>{return mat.map(row=>row.map(cell=>cell*scalar))};static matadd=(A,B)=>{return A.map((row,rowIndex)=>row.map((cell,colIndex)=>cell+B[rowIndex][colIndex]))};static matsub=(A,B)=>{return A.map((row,rowIndex)=>row.map((cell,colIndex)=>cell-B[rowIndex][colIndex]))};static inverse=matrix=>{const numRows=matrix.length;const numCols=matrix[0].length;if(numRows!==numCols){throw new Error("Matrix must be square to compute its inverse.")}const augmentedMatrix=matrix.map((row,rowIndex)=>{const identityRow=Array(numRows).fill(0);identityRow[rowIndex]=1;return row.concat(identityRow)});for(let pivotRow=0;pivotRowrow.slice(numCols))};static pseudoInverse=matrix=>{const numRows=matrix.length;const numCols=matrix[0].length;if(numRows>numCols){const ata=this.matmul(this.transpose(matrix),matrix);const ataInv=this.inverse(ata);return this.matmul(ataInv,this.transpose(matrix))}else{const aat=this.matmul(matrix,this.transpose(matrix));const aatInv=this.inverse(aat);return this.matmul(this.transpose(matrix),aatInv)}};static histogram=(arr=[],binSize=1,nBins=void 0)=>{let copy=[...arr];copy.sort(function(a,b){return a-b});let binStart=Math.min(...copy);if(typeof nBins==="number"){let binEnd=Math.max(...copy);binSize=Math.abs((binEnd-binStart)/(nBins-1))}let j=binStart;let binx=[];let biny=[];for(let i=0;ibinStart+binidx){j++;binidx+=binSize;let binmin=binStart+binidx;let binmid=binmin+binidx*.5;binx.push(binmid);biny.push(0)}biny[biny.length-1]++}return[binx,biny]};static normalDistribution=(samples=[],normalize=true,cutoff=1e-4)=>{let m=this.mean(samples);let vari=this.variance(samples);let nSamples=samples.length;let probabilities=[];let denom=1/(this.TWO_PI*vari);let _variance=1/vari;let sum=0;for(let i=0;ix2*_sum)}return probabilities};static expectedValue=(samples=[],probabilities=this.normalDistribution(samples))=>{return samples.reduce((sum,item,idx)=>sum+item*probabilities[idx])};static originMoment=(samples=[],probabilities=this.normalDistribution(samples),order=1)=>{return samples.reduce((sum,item,idx)=>sum+Math.pow(item,order)*probabilities[idx])};static centralMoment=(samples=[],probabilities=this.normalDistribution(samples),order=1)=>{let m=this.mean(samples);return samples.reduce((sum,item,idx)=>sum+Math.pow(item-m,order)*probabilities[idx]/samples.length)};static linearDiscriminantAnalysis=(samples=[],classifier=[])=>{let mean2=this.mean(samples);let meank=this.mean(classifier);let covariance=this.cov1d(samples,classifier);let probs=this.normalDistribution(samples);let dk=[];for(let i=0;i{const padlen=deconstructionLowPass.length;let sg=this.edgePad(signal,padlen);let approxCoeffs=this.conv1D(sg,deconstructionLowPass).slice(1+padlen,-padlen).filter((_,idx)=>idx%2===0);let detailCoeffs=this.conv1D(sg,deconstructionHighPass).slice(1+padlen,-padlen).filter((_,idx)=>idx%2===0);let results=[detailCoeffs];for(let i=0;iidx%2===0));approxCoeffs=this.conv1D(approxCoeffs,deconstructionLowPass).slice(1+padlen,-padlen).filter((_,idx)=>idx%2===0)}return[approxCoeffs].concat(results.reverse())};static idwt=(approxCoeffs=[],detailCoeffs=[],reconstructionHighPass=[],reconstructionLowPass=[])=>{if(approxCoeffs.length!==detailCoeffs.length){approxCoeffs.pop()}const _ca=this.dyadicUpsample(approxCoeffs,true);const _cd=this.dyadicUpsample(detailCoeffs,true);const halfa=this.conv1D(_ca,reconstructionLowPass);const halfb=this.conv1D(_cd,reconstructionHighPass);const sig=halfa.map((val,idx)=>val+halfb[idx]);const padlen=reconstructionLowPass.length;const lo=padlen-1;const hi=sig.length-(padlen-2);return sig.slice(lo,hi)};static dwtMaxLevel=(dataLength,waveletLength)=>{return Math.floor(Math.log2(dataLength/(waveletLength-1)))};static minMaxScaler=data=>{const min=Math.min(...data);const max=Math.max(...data);return data.map(value2=>(value2-min)/(max-min))};static garroteThreshold=(data,value2)=>{return data.map(x2=>{if(Math.abs(x2)<=value2){return 0}else{return x2-value2*value2/x2}})};static conv1D=(s,kernel)=>{const revKernel=[...kernel].reverse();const padsize=kernel.length-1;const paddedS=new Array(padsize).fill(0).concat(s).concat(new Array(padsize).fill(0));const nSteps=paddedS.length-kernel.length+1;const result=new Array(nSteps).fill(0);const nKer=kernel.length;for(let i=0;i{const rows=matrix.length;const cols=matrix[0].length;const kRows=kernel.length;const kCols=kernel[0].length;const halfKRows=Math.floor(kRows/2);const halfKCols=Math.floor(kCols/2);const output=new Array(rows).fill(0).map(()=>new Array(cols).fill(0));for(let i=0;i=0&&xi=0&&yj{if(matrix.length===0||kernel.length===0)return[];function getShape(arr){const shape=[];while(Array.isArray(arr)){shape.push(arr.length);arr=arr[0]}return shape}function convolveRecurse(mat,ker,matrixShape2,kernelShape2,matIndices=[],kerIndices=[]){const depth=matIndices.length;if(depth===matrixShape2.length){let sum=0;for(let i=0;i=0&&matIndex{const mean12=this.mean(arr1);const mean2=this.mean(arr2);return arr1.map((v,i)=>(v-mean12)*(arr2[i]-mean2))};static cov1d=(arr1,arr2)=>{this.mean(this.covVec(arr1,arr2))};static cov2d=mat=>{var mattransposed=this.transpose(mat);var matproducts=[];var rowmeans=[];var colmeans=[];mat.forEach((row,idx)=>{rowmeans.push(this.mean(row))});mattransposed.forEach((col,idx)=>{colmeans.push(this.mean(col))});mat.forEach((row,idx)=>{matproducts.push([]);for(var col=0;col{return[[this.cov1d(x2,x2),this.cov1d(x2,y),this.cov1d(x2,z)],[this.cov1d(y,x2),this.cov1d(y,y),this.cov1d(y,z)],[this.cov1d(z,x2),this.cov1d(z,y),this.cov1d(z,z)]]};static covNd=(dimensionalData=[])=>{let covariance=[];dimensionalData.forEach((arr,i)=>{covariance.push([]);dimensionalData.forEach((arr2,j)=>{covariance[i].push(this.cov1d(arr,arr2))})})};static correlationCoeff=(arr1,arr2)=>{const cov=this.cov1d(arr1,arr2);const stdDev1=this.std(arr1);const stdDev2=this.std(arr2);return cov/(stdDev1*stdDev2)};static pearsonCorrelation=(arr1,arr2)=>{let sumX=0,sumY=0,sumXY=0,sumX2=0,sumY2=0;const n=arr1.length>arr2.length?arr2.length:arr1.length;for(let i=0;i{let det=mat[0][0]*mat[1][1]-mat[0][1]*mat[1][0];let mean2=(mat[0][0]+mat[1][1])*.5;let sqrt=Math.sqrt(mean2*mean2-det);let eig1=mean2+sqrt;let eig2=mean2-sqrt;return[eig1,eig2]};static eigenvectors2x2=(mat=[[1,2],[3,4]],eigens=[1,2])=>{let v1=[-mat[0][1],mat[0][0]-eigens[0]];if(v1[0]===0&&v1[1]===0){v1[0]=mat[1][1]-eigens[0];v1[1]=-mat[1][0]}let v2=[-mat[0][1],mat[0][0]-eigens[1]];if(v2[0]===0&&v2[1]===0){v2[0]=mat[1][1]-eigens[1];v2[1]=-mat[1][0]}return[v1,v2]};static fastpca2d=(xarr,yarr)=>{let covMat=this.cov2d(xarr,yarr);let eigs=this.eigens2x2(covMat);if(eigs[1]>eigs[0])eigs.reverse();let evs=this.eigenvectors2x2(covMat,eigs);return[eigs,evs]};static centerData=data=>{const mean2=data.reduce((sum,val)=>sum+val,0)/data.length;return data.map(v=>v-mean2)};static crosscorrelation=(signalA,signalB,posOnly=false)=>{const N=signalA.length;const M=signalB.length;const result=[];const normFactor=1/Math.sqrt(signalA.reduce((acc,val)=>acc+val*val,0)*signalB.reduce((acc,val)=>acc+val*val,0));if(posOnly){result.length=signalA.length;for(let lag=0;lag=0&&m{const lags=[];const timeResolution=samplingRate?1/samplingRate:0;const center=centered?correlogram.length/2:null;const len=correlogram.length-1;for(let i=1;icorrelogram[i-1]&&correlogram[i]>correlogram[i+1]){let lag={offset:centered?i-center:i,value:correlogram[i]};if(timeResolution)lag.offset*=timeResolution;lags.push(lag)}}if(getMax)return lags.reduce((maxObj,currentObj)=>{return currentObj.value>maxObj.value?currentObj:maxObj},lags[0]);else return lags};static autocorrelation=arr1=>{var delaybuf=[...arr1,...Array(arr1.length).fill(0)];var mean12=this.mean(arr1);var arr1Est=arr1.reduce((sum,item)=>sum+=Math.pow(item-mean12,2));arr1Est=Math.sqrt(Math.abs(arr1Est));let denom=arr1Est*arr2Est;if(denom===0)denom=1e-26;var _arr1estsqrd=1/denom;var correlations=new Array(arr1.length).fill(0);for(var delay=0;delaysum+=(item-mean12)*(delaybuf[delay+i]-mean12));correlations[delay]=r*_arr1estsqrd}return correlations};static autocorrelation2d=mat2d2=>{let result=[];for(let y=0;y{let result=[];for(let y=0;y{let result=[];for(let y=0;y{let result=[];for(let y=0;y{var correlograms=[];dat.forEach((row1,i)=>{dat.forEach((row2,j)=>{if(j>=i){correlograms.push(_Math2.crosscorrelation(row1,row2))}})});return correlograms};static dft=(sineWave=[],sampleRate=250,frequencyResolution=.25)=>{const N=sineWave.length;const NyquistLimit=Math.floor(sampleRate/2);const totalFreqs=Math.floor(NyquistLimit/frequencyResolution);const Npadded=Math.ceil(sampleRate/frequencyResolution);const TWOPI=2*3.141592653589793;const real=new Array(Npadded).fill(0);const imag=new Array(Npadded).fill(0);const amplitudes=new Array(Npadded);const zerosToAdd=Npadded-N;if(zerosToAdd<0){throw new Error("Desired resolution is not achievable with current sample size.")}const paddedSineWave=zerosToAdd?[...sineWave,...Array(zerosToAdd).fill(0)]:sineWave;let orderedFrequencies;if(totalFreqs%2===0){orderedFrequencies=[...new Array(totalFreqs).fill(0).map((x2,i)=>-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs).fill(0).map((x2,i)=>i*frequencyResolution)]}else{orderedFrequencies=[...new Array(totalFreqs).fill(0).map((x2,i)=>-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs+1).fill(0).map((x2,i)=>i*frequencyResolution)]}for(let k=0;k-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs).fill(0).map((x2,i)=>(i+1)*frequencyResolution)]}else{orderedMagnitudes=[...amplitudes.slice(totalFreqs,2*totalFreqs),...amplitudes.slice(0,totalFreqs+1)];orderedFrequencies=[...new Array(totalFreqs).fill(0).map((x2,i)=>-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs+1).fill(0).map((x2,i)=>i*frequencyResolution)]}return{real,imag,freqs:orderedFrequencies,amplitudes:orderedMagnitudes}};static eulerTransform=(dataSeries=[],timeTransform=(j,dataSeries2,real,imag,magnitudes)=>{return dataSeries2[j]},stepTransform=(k,j,length,real,imag,magnitudes)=>{return 2*Math.PI*k*j/length},kN=dataSeries.length)=>{var real=[];var imag=[];var magnitudes=[];for(var k=0;k{var smaArr=[];for(var i=0;icurrent+=previous)/(i+1))}else{var arrslice=arr.slice(i-window2,i);smaArr.push(arrslice.reduce((previous,current)=>current+=previous)/window2)}}return smaArr};static sum=(arr=[])=>{if(arr.length>0){var sum=arr.reduce((prev,curr)=>curr+=prev);return sum}else{return 0}};static reduceArrByFactor=(arr,factor=2)=>{let x2=arr.filter((element,index)=>{return index%factor===0});return x2};static makeArr=(startValue,stopValue,nSteps)=>{var arr=[];var step=(stopValue-startValue)/(nSteps-1);for(var i=0;i{if(array?.length===0)return array;let max=Math.max(...array);let min=Math.min(...array);let _lines=1/stackedLines;let scalar;if(centerZero){let absmax=Math.max(Math.abs(min),Math.abs(max));scalar=_lines/absmax;return array.map(y=>y*scalar+(_lines*(stackPosition+1)*2-1-_lines))}else{scalar=_lines/(max-min);return array.map(y=>2*((y-min)*scalar-1/(2*stackedLines))+(_lines*(stackPosition+1)*2-1-_lines))}};static absmax=array=>{return Math.max(Math.abs(Math.min(...array)),Math.max(...array))};static downsample=(array,fitCount,scalar=1)=>{if(array.length>fitCount){let output=new Array(fitCount);let incr=array.length/fitCount;let lastIdx=array.length-1;let last=0;let counter=0;for(let i=incr;ilastIdx)rounded=lastIdx;for(let j=last;j{var linearInterpolate=function(before2,after2,atPoint2){return(before2+(after2-before2)*atPoint2)*scalar};var newData=new Array;var springFactor=(array.length-1)/(fitCount-1);newData[0]=array[0];for(var i=1;i{const start=even?1:0;const out=new Array(a.length*2).fill(0);for(let i=0;i{if(array.length===fitCount)return array;if(array.length>fitCount){return this.downsample(array,fitCount,scalar)}else{return this.upsample(array,fitCount,scalar)}};static lerp=(v0,v1,t)=>{return(1-t)*v0+t*v1};static linspace=(start,end,num,floor=false)=>{const arr=new Array(num);const step=(end-start)/(num-1);for(let i=0;i{let ref=[...arr];if(ref.length%2===0)ref.pop();if(arr.length>1){let pass=true;for(let i=0;i=ref[Math.floor(ref.length*.5)]){pass=false;break}else if(i>Math.floor(ref.length*.5)&&val>=ref[Math.floor(ref.length*.5)]){pass=false;break}}else if(critical==="valley"){if(iMath.floor(ref.length*.5)&&val<=ref[Math.floor(ref.length*.5)]){pass=false;break}}else{if(iMath.floor(ref.length*.5)&&val<=ref[Math.floor(ref.length*.5)]){pass=false;break}}}if(critical!=="peak"&&critical!=="valley"&&pass===false){pass=true;for(let i=0;i=ref[Math.floor(ref.length*.5)]){pass=false;break}else if(i>Math.floor(ref.length*.5)&&val>=ref[Math.floor(ref.length*.5)]){pass=false;break}}}return pass}else return void 0};static isCriticalPoint=(arr,critical="peak")=>{let ref=[...arr];if(ref.length%2===0)ref.pop();if(arr.length>1){let pass=true;for(let i=0;iref.length*.5&&val>0){pass=false;break}}else if(critical==="valley"){if(i=0){pass=false;break}else if(i>ref.length*.5&&val<0){pass=false;break}}else{if(i=0){pass=false;break}else if(i>ref.length*.5&&val<0){pass=false;break}}}if(critical!=="peak"&&critical!=="valley"&&pass===false){pass=true;for(let i=0;iref.length*.5&&val>0){pass=false;break}}}return pass}else return void 0};static peakDetect=(smoothedArray,type="peak",window2=49)=>{let mid=Math.floor(window2*.5);let peaks=[];for(let i=0;i{let threshold;let filtered=arr.filter((o,i)=>{if(peakIndices.indexOf(i)>-1)return true});if(thresholdVar===0){threshold=this.mean(filtered)}else threshold=(thresholdVar+this.mean(filtered))*.5;return threshold};static column=(mat,x2)=>{let col=new Array(mat.length).fill(0).map(()=>new Array(1).fill(0));for(let i=0;i{let v_new=[];for(let i=0;i{let sum=0;for(let i=0;i{let len=Math.sqrt(this.matmul(this.transpose(eigenvector),eigenvector));let U=this.matscale(eigenvector,1/len);let delta=this.matscale(this.matmul(U,this.transpose(U)),eigenvalue);let M_new=this.matsub(mat,delta);return M_new};static eigenvalue_of_vector=(mat,eigenvector)=>{ev=this.matmul(this.matmul(this.transpose(eigenvector),mat),eigenvector);return ev};static power_iteration=(A,numIter=100)=>{let b=Array(A.length).fill(1);for(let i=0;i{let eigenvalues=[];let eigenvectors=[];for(let i=0;i{if(A[0].length>A.length){A=this.transpose(A)}const m=A.length;const n=A[0].length;const prec=Number.EPSILON;const tolerance=1e-64/prec;const itmax=50;const leftSingularVectors=this.clone(A);const offDiagonalValues=Array(n).fill(0);const singularValues=Array(n).fill(0);const rightSingularVectors=Array.from({length:n},()=>Array(n).fill(0));function pythag(a,b){if(a===0||b===0)return a+b;const absA=Math.abs(a),absB=Math.abs(b);if(absA>absB){const t=absB/absA;return absA*Math.sqrt(1+t*t)}else{const t=absA/absB;return absB*Math.sqrt(1+t*t)}}let scaleFactorF=0;let scaleFactorG=0;let scaleFactorH=0;let maxMagnitude=0;let intermediateY=0;let intermediateZ=0;let sumValue=0;let cosineTheta=0;let limitIndex=0;for(let i=0;i=0)scaleFactorG=-scaleFactorG;scaleFactorH=scaleFactorF*scaleFactorG-sumValue;leftSingularVectors[i][i]=scaleFactorF-scaleFactorG;for(let j=limitIndex;j=0)scaleFactorG=-scaleFactorG;scaleFactorH=scaleFactorF*scaleFactorG-sumValue;leftSingularVectors[i][i+1]=scaleFactorF-scaleFactorG;for(let j=limitIndex;jmaxMagnitude)maxMagnitude=intermediateY}for(let i=n-1;i>=0;i--){if(scaleFactorG!==0){scaleFactorH=scaleFactorG*leftSingularVectors[i][i+1];for(let j=limitIndex;j=0;i--){limitIndex=i+1;scaleFactorG=singularValues[i];for(let j=limitIndex;j=0;k--){for(let iteration=0;iteration=0;limitIndex--){if(Math.abs(offDiagonalValues[limitIndex])<=eps){testConvergence=true;break}if(Math.abs(singularValues[limitIndex-1])<=eps)break}if(!testConvergence){cosineTheta=0;sumValue=1;const l1=limitIndex-1;for(let i=limitIndex;i=itmax-1)throw new Error("No convergence.");maxMagnitude=singularValues[limitIndex];intermediateY=singularValues[k-1];scaleFactorG=offDiagonalValues[k-1];scaleFactorH=offDiagonalValues[k];scaleFactorF=((intermediateY-intermediateZ)*(intermediateY+intermediateZ)+(scaleFactorG-scaleFactorH)*(scaleFactorG+scaleFactorH))/(2*scaleFactorH*intermediateY);scaleFactorG=pythag(scaleFactorF,1);if(scaleFactorF<0)scaleFactorF=((maxMagnitude-intermediateZ)*(maxMagnitude+intermediateZ)+scaleFactorH*(intermediateY/(scaleFactorF-scaleFactorG)-scaleFactorH))/maxMagnitude;else scaleFactorF=((maxMagnitude-intermediateZ)*(maxMagnitude+intermediateZ)+scaleFactorH*(intermediateY/(scaleFactorF+scaleFactorG)-scaleFactorH))/maxMagnitude;cosineTheta=1;sumValue=1;for(let i=limitIndex+1;i=0;j--){if(singularValues[j]row.slice());for(let k=0;k0?-this.normalize(x2):this.normalize(x2);const u=this.vecsub(x2,e);const normU=this.normalize(u);const v=u.map(val=>val/normU);const Qk=this.householderMatrix(v);const QkFull=this.identityMatrix(numRows);for(let row=k;row{const numRowsOriginal=matrixA.length;const numColsOriginal=matrixA[0].length;if(!numComponents){numComponents=Math.min(numRowsOriginal,numColsOriginal)}let matrixACopy=[...matrixA.map(row=>[...row])];if(numRowsOriginal>numColsOriginal){matrixA=this.matmul(this.transpose(matrixA),matrixA)}else if(numRowsOriginalsum+row.reduce((rowSum,val)=>rowSum+val*val,0),0);previousMatrixQ=matrixQ;if(errorMath.sqrt(row[row.indexOf(Math.max(...row))]));let leftVectors,rightVectors;if(numRowsOriginalval*val)}else{rightVectors=this.transpose(matrixQ);leftVectors=this.matmul(this.matmul(matrixACopy,rightVectors),this.inverse(this.diagonalMatrix(singularValues)))}return{U:leftVectors,S:singularValues,V:rightVectors}};static pca=(mat,tolerance=1e-5)=>{let dims=mat.length;let t=new Array(dims);let p=new Array(dims);let mat_t=this.transpose(mat);t[0]=this.column(mat,0);let epsilon=1;let iter=0;while(espilon>tolerance){iter++;p[0]=this.matmul(mat_t,t[0]);let tp=this.matmul(this.transpose(t[0]),t[0]);p[0]=this.matscale(p[0],1/tp);let p_length=Math.sqrt(this.matmul(this.transpose(p[0]),p[0]));p[0]=this.matscale(p[0],1/p_length);let t_new=this.matmul(mat,p[0]);let pp=this.matmul(this.transpose(p[0]),p[0]);t_new=this.matscale(t_new,1/pp);epsilon=this.squared_difference(t[0],t_new);t[0]=JSON.parse(JSON.stringify(t_new))}let components=this.matmul(this.transpose(t[0]),t[0]);return components};static circularBuffer=(arr,newEntries)=>{if(Array.isArray(newEntries)){if(newEntries.lengtharr.length){let len=arr.length;arr.splice(0,len,newEntries.slice(len-newEntries.length))}else{arr.splice(0,arr.length,...newEntries)}}else{arr.push(newEntries);arr.shift()}return arr};static reshape=(arr,shape)=>{const totalSize=shape.reduce((acc,val)=>acc*val,1);const flatArr=this.flatten(arr);if(flatArr.length!==totalSize){throw new Error("The given shape is incompatible with the array size.")}function buildArray(shape2,flatData){const dim=shape2[0];if(shape2.length===1){return flatData.splice(0,dim)}let result=[];for(let i=0;i{if(!Array.isArray(arr)){return[arr]}return arr.reduce((acc,val)=>acc.concat(flatten(val)),[])};static p300=(event_timestamps=[],raw_signal=[],signal_timestamps=[],sps=256)=>{let smoothingstep=Math.floor(sps/10);let smoothed=this.sma(raw_signal,smoothingstep);let peaks=this.peakDetect(smoothed,"peak",smoothingstep);let mean2=this.mean(smoothed);let std=this.std(smoothed,mean2);let p_idx=0;let candidates=[];if(peaks.length>0){event_timestamps.forEach((t,j)=>{while(signal_timestamps[peaks[p_idx]]1){let peakvals=[];tempcandidates.forEach(tc=>{peakvals.push(smoothed[peaks[tc]])});let max=Math.max(...peakvals);let maxi=tempcandidates[peakvals.indexOf(max)];candidates.push({event_timestamp:t,event_index:j,peak_timestamp:signal_timestamps[[peaks[maxi]]],signal_index:[peaks[maxi]],signal_amplitude:raw_signal[[peaks[maxi]]],zscore:(smoothed[peaks[maxi]]-mean2)/std})}else if(tempcandidates.length===1)candidates.push({event_timestamp:t,event_index:j,peak_timestamp:signal_timestamps[peaks[tempcandidates[0]]],signal_index:peaks[tempcandidates[0]],signal_amplitude:raw_signal[[peaks[tempcandidates[0]]]],zscore:(smoothed[peaks[tempcandidates[0]]]-mean2)/std})})}return candidates};static dec_lo=[-.07576571478927333,-.02963552764599851,.49761866763201545,.8037387518059161,.29785779560527736,-.09921954357684722,-.012603967262037833,.0322231006040427];static dec_hi=[-.0322231006040427,-.012603967262037833,.09921954357684722,.29785779560527736,-.8037387518059161,.49761866763201545,.02963552764599851,-.07576571478927333];static rec_lo=[.0322231006040427,-.012603967262037833,-.09921954357684722,.29785779560527736,.8037387518059161,.49761866763201545,-.02963552764599851,-.07576571478927333];static rec_hi=[-.07576571478927333,.02963552764599851,.49761866763201545,-.8037387518059161,.29785779560527736,.09921954357684722,-.012603967262037833,-.0322231006040427];static waveletFiltering=(signal=[],wavelets={dec_hi:this.dec_hi,dec_lo:this.dec_lo,rec_hi:this.rec_hi,rec_lo:this.rec_lo})=>{let maxlevel=this.dwtMaxLevel(signal.length,wavelets.dec_lo.length);let decomposed=this.decompose(signal,maxlevel,wavelets.dec_hi,wavelets.dec_lo);for(let i=2;i{let startindex=methodString.indexOf("=>")+1;if(startindex<=0){startindex=methodString.indexOf("){")}if(startindex<=0){startindex=methodString.indexOf(") {")}return methodString.slice(0,methodString.indexOf("{",startindex)+1)};function parseFunctionFromText(method=""){let getFunctionBody=methodString=>{return methodString.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i,"$2$3$4")};let newFuncHead=getFunctionHead(method);let newFuncBody=getFunctionBody(method);let newFunc;if(newFuncHead.includes("function")){let varName=newFuncHead.substring(newFuncHead.indexOf("(")+1,newFuncHead.lastIndexOf(")"));newFunc=new Function(varName,newFuncBody)}else{if(newFuncHead.substring(0,6)===newFuncBody.substring(0,6)){let varName=newFuncHead.substring(newFuncHead.indexOf("(")+1,newFuncHead.lastIndexOf(")"));newFunc=new Function(varName,newFuncBody.substring(newFuncBody.indexOf("{")+1,newFuncBody.length-1))}else{try{newFunc=(0,eval)(method)}catch{}}}return newFunc}var stringifyWithCircularRefs=function(){const refs=new Map;const parents=[];const path=["this"];function clear(){refs.clear();parents.length=0;path.length=1}function updateParents(key,value2){var idx=parents.length-1;var prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value2||idx===0){path.push(key);parents.push(value2.pushed)}else{while(idx-->=0){prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value2){idx+=2;parents.length=idx;path.length=idx;--idx;parents[idx]=value2;path[idx]=key;break}}idx--}}}}function checkCircular(key,value2){if(value2!=null){if(typeof value2==="object"){if(key){updateParents(key,value2)}let other=refs.get(value2);if(other){return"[Circular Reference]"+other}else{refs.set(value2,path.join("."))}}}return value2}return function stringifyWithCircularRefs2(obj,space){try{parents.push(obj);return JSON.stringify(obj,checkCircular,space)}finally{clear()}}}();if(JSON.stringifyWithCircularRefs===void 0){JSON.stringifyWithCircularRefs=stringifyWithCircularRefs}var stringifyWithFunctionsAndCircularRefs=function(){const refs=new Map;const parents=[];const path=["this"];function clear(){refs.clear();parents.length=0;path.length=1}function updateParents(key,value2){var idx=parents.length-1;var prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value2||idx===0){path.push(key);parents.push(value2.pushed)}else{while(idx-->=0){prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value2){idx+=2;parents.length=idx;path.length=idx;--idx;parents[idx]=value2;path[idx]=key;break}}idx--}}}}function checkCircular(key,value2){if(value2!=null){if(typeof value2==="object"){if(key){updateParents(key,value2)}let other=refs.get(value2);if(other){return"[Circular Reference]"+other}else{refs.set(typeof value2==="function"?value2.toString():value2,path.join("."))}}}return typeof value2==="function"?value2.toString():value2}return function stringifyWithFunctionsAndCircularRefs2(obj,space){try{parents.push(obj);return JSON.stringify(obj,checkCircular,space)}finally{clear()}}}();if(JSON.stringifyWithFunctionsAndCircularRefs===void 0){JSON.stringifyWithFunctionsAndCircularRefs=stringifyWithFunctionsAndCircularRefs}var stringifyFast=function(){const refs=new Map;const parents=[];const path=["this"];function clear(){refs.clear();parents.length=0;path.length=1}function updateParents(key,value2){var idx=parents.length-1;if(parents[idx]){var prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value2||idx===0){path.push(key);parents.push(value2.pushed)}else{while(idx-->=0){prev=parents[idx];if(typeof prev==="object"){if(prev[key]===value2){idx+=2;parents.length=idx;path.length=idx;--idx;parents[idx]=value2;path[idx]=key;break}}idx++}}}}}function checkValues(key,value2){let val;if(value2!=null){if(typeof value2==="object"){let c=value2.constructor.name;if(key&&c==="Object"){updateParents(key,value2)}let other=refs.get(value2);if(other){return"[Circular Reference]"+other}else{refs.set(value2,path.join("."))}if(c==="Array"){if(value2.length>20){val=value2.slice(value2.length-20)}else val=value2}else if(c.includes("Set")){val=Array.from(value2)}else if(c!=="Object"&&c!=="Number"&&c!=="String"&&c!=="Boolean"){val="instanceof_"+c}else if(c==="Object"){let obj={};for(const prop in value2){if(value2[prop]==null){obj[prop]=value2[prop]}else if(Array.isArray(value2[prop])){if(value2[prop].length>20)obj[prop]=value2[prop].slice(value2[prop].length-20);else obj[prop]=value2[prop]}else if(value2[prop].constructor.name==="Object"){obj[prop]={};for(const p in value2[prop]){if(Array.isArray(value2[prop][p])){if(value2[prop][p].length>20)obj[prop][p]=value2[prop][p].slice(value2[prop][p].length-20);else obj[prop][p]=value2[prop][p]}else{if(value2[prop][p]!=null){let con=value2[prop][p].constructor.name;if(con.includes("Set")){obj[prop][p]=Array.from(value2[prop][p])}else if(con!=="Number"&&con!=="String"&&con!=="Boolean"){obj[prop][p]="instanceof_"+con}else{obj[prop][p]=value2[prop][p]}}else{obj[prop][p]=value2[prop][p]}}}}else{let con=value2[prop].constructor.name;if(con.includes("Set")){obj[prop]=Array.from(value2[prop])}else if(con!=="Number"&&con!=="String"&&con!=="Boolean"){obj[prop]="instanceof_"+con}else{obj[prop]=value2[prop]}}}val=obj}else{val=value2}}else{val=value2}}return val}return function stringifyFast2(obj,space){parents.push(obj);let res=JSON.stringify(obj,checkValues,space);clear();return res}}();if(JSON.stringifyFast===void 0){JSON.stringifyFast=stringifyFast}var GPUService=class extends Service{gpu=new gpuUtils;constructor(options){super(options);this.load(this)}addFunc=fn=>{if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function")this.gpu.addFunction(fn)};addKernel=(name2,fn,options)=>{if(typeof fn==="string")fn=parseFunctionFromText(fn);if(typeof fn==="function")this.gpu.addKernel(name2,fn,options)};combineKernels=(name2,fs,ckrnl)=>{for(let i=0;i{this.gpu.callKernel(name2,args)};dft=(signalBuffer,nSeconds,scalar)=>{if(scalar==void 0)scalar=1;return this.gpu.gpuDFT(signalBuffer,nSeconds,scalar)};multidft=(signalBuffer,nSeconds,scalar)=>{if(scalar==void 0)scalar=1;return this.gpu.MultiChannelDFT(signalBuffer,nSeconds,scalar)};multidftbandpass=(buffered,nSeconds,freqStart,freqEnd,scalar)=>{if(scalar==void 0)scalar=1;return this.gpu.MultiChannelDFT_Bandpass(buffered,nSeconds,freqStart,freqEnd,scalar)};coherence=(buffered,nSeconds,freqStart,freqEnd)=>{const correlograms=Math2.correlograms(buffered);const buffer=[...buffered,...correlograms];var dfts;var scalar=1;dfts=this.gpu.MultiChannelDFT_Bandpass(buffer,nSeconds,freqStart,freqEnd,scalar);const cordfts=dfts[1].splice(buffered.length,buffer.length-buffered.length);const coherenceResults=[];const nChannels=buffered.length;var k=0;var l=0;cordfts.forEach((row,i)=>{if(l+k===nChannels){var temp=cordfts.splice(i,1);k++;cordfts.splice(k,0,...temp);l=0}l++});var autoFFTproducts=[];k=0;l=1;cordfts.forEach((dft2,i)=>{var newdft=new Array(dft2.length).fill(0);if(i{newdft[j]=amp});autoFFTproducts.push(newdft)}else{dft2.forEach((amp,j)=>{let denom=autoFFTproducts[k][j]*autoFFTproducts[k+l][j];if(denom!==0)newdft[j]=amp*amp/denom;else newdft[j]=0;if(newdft[j]>1){newdft[j]=1}});l++;if(l+k===nChannels){k++;l=1}coherenceResults.push(newdft)}});return[dfts[0],dfts[1],coherenceResults]}};if(!globalThis.gpu)globalThis.gpu=new GPUService;var dft={sps:250,nSec:1,freqStart:0,freqEnd:125,watch:["0","1","2","3"],blocking:false,__operator:function(arraybuffer){let results=globalThis.gpu.multidftbandpass(arraybuffer,this.nSec,this.freqStart,this.freqEnd,1);let dft2={};this.watch.forEach((tag,i)=>{dft2[tag]=results[1][i]});return{frequencies:results[0],dft:dft2}}};if(!globalThis.gpu)globalThis.gpu=new GPUService;var coherence={sps:250,nSec:1,freqStart:0,freqEnd:125,tags:["0","1","2","3"],coherenceTags:[],__onconnected:function(node){node.tags.forEach((tag,i)=>{if(i!==node.tags.length-1){for(let j=i+1;j{dft2[tag]=results[1][i]});let coherence2={};this.coherenceTags.forEach((tag,i)=>{coherence2[tag]=results[2][i]});return{timestamp:ts,frequencies:results[0],dft:dft2,coherence:coherence2}}};var gpualgorithms={dft,coherence};})(); -/*! Bundled license information: - -gpujsutils/dist/index.esm.js: - (** - * gpu.js - * http://gpu.rocks/ - * - * GPU Accelerated JavaScript - * - * @version 2.11.0 - * @date Tue Jan 05 2021 15:55:59 GMT-0500 (Eastern Standard Time) - * - * @license MIT - * The MIT License - * - * Copyright (c) 2021 gpu.js Team - *) -*/ diff --git a/src/extras/dist/index.services.esm.js b/src/extras/dist/index.services.esm.js deleted file mode 100644 index 46e6014b..00000000 --- a/src/extras/dist/index.services.esm.js +++ /dev/null @@ -1,50 +0,0 @@ -var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf;var __hasOwnProp=Object.prototype.hasOwnProperty;var __require=(x3=>typeof require!=="undefined"?require:typeof Proxy!=="undefined"?new Proxy(x3,{get:(a,b)=>(typeof require!=="undefined"?require:a)[b]}):x3)(function(x3){if(typeof require!=="undefined")return require.apply(this,arguments);throw Error('Dynamic require of "'+x3+'" is not supported')});var __commonJS=(cb,mod)=>function __require2(){return mod||(0,cb[__getOwnPropNames(cb)[0]])((mod={exports:{}}).exports,mod),mod.exports};var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from==="object"||typeof from==="function"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:true}):target,mod));var require_bson=__commonJS({"struct/datastructures/bson.cjs"(exports){"use strict";var BSON_MAJOR_VERSION=5;var BSON_INT32_MAX=2147483647;var BSON_INT32_MIN=-2147483648;var BSON_INT64_MAX=Math.pow(2,63)-1;var BSON_INT64_MIN=-Math.pow(2,63);var JS_INT_MAX=Math.pow(2,53);var JS_INT_MIN=-Math.pow(2,53);var BSON_DATA_NUMBER=1;var BSON_DATA_STRING=2;var BSON_DATA_OBJECT=3;var BSON_DATA_ARRAY=4;var BSON_DATA_BINARY=5;var BSON_DATA_UNDEFINED=6;var BSON_DATA_OID=7;var BSON_DATA_BOOLEAN=8;var BSON_DATA_DATE=9;var BSON_DATA_NULL=10;var BSON_DATA_REGEXP=11;var BSON_DATA_DBPOINTER=12;var BSON_DATA_CODE=13;var BSON_DATA_SYMBOL=14;var BSON_DATA_CODE_W_SCOPE=15;var BSON_DATA_INT=16;var BSON_DATA_TIMESTAMP=17;var BSON_DATA_LONG=18;var BSON_DATA_DECIMAL128=19;var BSON_DATA_MIN_KEY=255;var BSON_DATA_MAX_KEY=127;var BSON_BINARY_SUBTYPE_DEFAULT=0;var BSON_BINARY_SUBTYPE_UUID_NEW=4;var BSONType=Object.freeze({double:1,string:2,object:3,array:4,binData:5,undefined:6,objectId:7,bool:8,date:9,null:10,regex:11,dbPointer:12,javascript:13,symbol:14,javascriptWithScope:15,int:16,timestamp:17,long:18,decimal:19,minKey:-1,maxKey:127});var BSONError=class extends Error{get bsonError(){return true}get name(){return"BSONError"}constructor(message){super(message)}static isBSONError(value){return value!=null&&typeof value==="object"&&"bsonError"in value&&value.bsonError===true&&"name"in value&&"message"in value&&"stack"in value}};var BSONVersionError=class extends BSONError{get name(){return"BSONVersionError"}constructor(){super(`Unsupported BSON version, bson types must be from bson ${BSON_MAJOR_VERSION}.0 or later`)}};var BSONRuntimeError=class extends BSONError{get name(){return"BSONRuntimeError"}constructor(message){super(message)}};function nodejsMathRandomBytes(byteLength){return nodeJsByteUtils.fromNumberArray(Array.from({length:byteLength},()=>Math.floor(Math.random()*256)))}var nodejsRandomBytes=(()=>{try{return __require("crypto").randomBytes}catch{return nodejsMathRandomBytes}})();var nodeJsByteUtils={toLocalBufferType(potentialBuffer){if(Buffer.isBuffer(potentialBuffer)){return potentialBuffer}if(ArrayBuffer.isView(potentialBuffer)){return Buffer.from(potentialBuffer.buffer,potentialBuffer.byteOffset,potentialBuffer.byteLength)}const stringTag=potentialBuffer?.[Symbol.toStringTag]??Object.prototype.toString.call(potentialBuffer);if(stringTag==="ArrayBuffer"||stringTag==="SharedArrayBuffer"||stringTag==="[object ArrayBuffer]"||stringTag==="[object SharedArrayBuffer]"){return Buffer.from(potentialBuffer)}throw new BSONError(`Cannot create Buffer from ${String(potentialBuffer)}`)},allocate(size){return Buffer.alloc(size)},equals(a,b){return nodeJsByteUtils.toLocalBufferType(a).equals(b)},fromNumberArray(array){return Buffer.from(array)},fromBase64(base64){return Buffer.from(base64,"base64")},toBase64(buffer2){return nodeJsByteUtils.toLocalBufferType(buffer2).toString("base64")},fromISO88591(codePoints){return Buffer.from(codePoints,"binary")},toISO88591(buffer2){return nodeJsByteUtils.toLocalBufferType(buffer2).toString("binary")},fromHex(hex){return Buffer.from(hex,"hex")},toHex(buffer2){return nodeJsByteUtils.toLocalBufferType(buffer2).toString("hex")},fromUTF8(text){return Buffer.from(text,"utf8")},toUTF8(buffer2){return nodeJsByteUtils.toLocalBufferType(buffer2).toString("utf8")},utf8ByteLength(input){return Buffer.byteLength(input,"utf8")},encodeUTF8Into(buffer2,source,byteOffset){return nodeJsByteUtils.toLocalBufferType(buffer2).write(source,byteOffset,void 0,"utf8")},randomBytes:nodejsRandomBytes};function isReactNative(){const{navigator}=globalThis;return typeof navigator==="object"&&navigator.product==="ReactNative"}function webMathRandomBytes(byteLength){if(byteLength<0){throw new RangeError(`The argument 'byteLength' is invalid. Received ${byteLength}`)}return webByteUtils.fromNumberArray(Array.from({length:byteLength},()=>Math.floor(Math.random()*256)))}var webRandomBytes=(()=>{const{crypto}=globalThis;if(crypto!=null&&typeof crypto.getRandomValues==="function"){return byteLength=>{return crypto.getRandomValues(webByteUtils.allocate(byteLength))}}else{if(isReactNative()){const{console:console2}=globalThis;console2?.warn?.("BSON: For React Native please polyfill crypto.getRandomValues, e.g. using: https://www.npmjs.com/package/react-native-get-random-values.")}return webMathRandomBytes}})();var HEX_DIGIT=/(\d|[a-f])/i;var webByteUtils={toLocalBufferType(potentialUint8array){const stringTag=potentialUint8array?.[Symbol.toStringTag]??Object.prototype.toString.call(potentialUint8array);if(stringTag==="Uint8Array"){return potentialUint8array}if(ArrayBuffer.isView(potentialUint8array)){return new Uint8Array(potentialUint8array.buffer.slice(potentialUint8array.byteOffset,potentialUint8array.byteOffset+potentialUint8array.byteLength))}if(stringTag==="ArrayBuffer"||stringTag==="SharedArrayBuffer"||stringTag==="[object ArrayBuffer]"||stringTag==="[object SharedArrayBuffer]"){return new Uint8Array(potentialUint8array)}throw new BSONError(`Cannot make a Uint8Array from ${String(potentialUint8array)}`)},allocate(size){if(typeof size!=="number"){throw new TypeError(`The "size" argument must be of type number. Received ${String(size)}`)}return new Uint8Array(size)},equals(a,b){if(a.byteLength!==b.byteLength){return false}for(let i=0;ic.charCodeAt(0))},toBase64(uint8array){return btoa(webByteUtils.toISO88591(uint8array))},fromISO88591(codePoints){return Uint8Array.from(codePoints,c=>c.charCodeAt(0)&255)},toISO88591(uint8array){return Array.from(Uint16Array.from(uint8array),b=>String.fromCharCode(b)).join("")},fromHex(hex){const evenLengthHex=hex.length%2===0?hex:hex.slice(0,hex.length-1);const buffer2=[];for(let i=0;ibyte.toString(16).padStart(2,"0")).join("")},fromUTF8(text){return new TextEncoder().encode(text)},toUTF8(uint8array){return new TextDecoder("utf8",{fatal:false}).decode(uint8array)},utf8ByteLength(input){return webByteUtils.fromUTF8(input).byteLength},encodeUTF8Into(buffer2,source,byteOffset){const bytes=webByteUtils.fromUTF8(source);buffer2.set(bytes,byteOffset);return bytes.byteLength},randomBytes:webRandomBytes};var hasGlobalBuffer=typeof Buffer==="function"&&Buffer.prototype?._isBuffer!==true;var ByteUtils=hasGlobalBuffer?nodeJsByteUtils:webByteUtils;var BSONDataView=class extends DataView{static fromUint8Array(input){return new DataView(input.buffer,input.byteOffset,input.byteLength)}};var VALIDATION_REGEX=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15})$/i;var uuidValidateString=str2=>typeof str2==="string"&&VALIDATION_REGEX.test(str2);var uuidHexStringToBuffer=hexString=>{if(!uuidValidateString(hexString)){throw new BSONError('UUID string representations must be a 32 or 36 character hex string (dashes excluded/included). Format: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" or "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".')}const sanitizedHexString=hexString.replace(/-/g,"");return ByteUtils.fromHex(sanitizedHexString)};function bufferToUuidHexString(buffer2,includeDashes=true){if(includeDashes){return[ByteUtils.toHex(buffer2.subarray(0,4)),ByteUtils.toHex(buffer2.subarray(4,6)),ByteUtils.toHex(buffer2.subarray(6,8)),ByteUtils.toHex(buffer2.subarray(8,10)),ByteUtils.toHex(buffer2.subarray(10,16))].join("-")}return ByteUtils.toHex(buffer2)}function isAnyArrayBuffer(value){return["[object ArrayBuffer]","[object SharedArrayBuffer]"].includes(Object.prototype.toString.call(value))}function isUint8Array(value){return Object.prototype.toString.call(value)==="[object Uint8Array]"}function isRegExp(d2){return Object.prototype.toString.call(d2)==="[object RegExp]"}function isMap(d2){return Object.prototype.toString.call(d2)==="[object Map]"}function isDate(d2){return Object.prototype.toString.call(d2)==="[object Date]"}var BSONValue=class{get[Symbol.for("@@mdb.bson.version")](){return BSON_MAJOR_VERSION}};var Binary=class _Binary extends BSONValue{get _bsontype(){return"Binary"}constructor(buffer2,subType){super();if(!(buffer2==null)&&!(typeof buffer2==="string")&&!ArrayBuffer.isView(buffer2)&&!(buffer2 instanceof ArrayBuffer)&&!Array.isArray(buffer2)){throw new BSONError("Binary can only be constructed from string, Buffer, TypedArray, or Array")}this.sub_type=subType??_Binary.BSON_BINARY_SUBTYPE_DEFAULT;if(buffer2==null){this.buffer=ByteUtils.allocate(_Binary.BUFFER_SIZE);this.position=0}else{if(typeof buffer2==="string"){this.buffer=ByteUtils.fromISO88591(buffer2)}else if(Array.isArray(buffer2)){this.buffer=ByteUtils.fromNumberArray(buffer2)}else{this.buffer=ByteUtils.toLocalBufferType(buffer2)}this.position=this.buffer.byteLength}}put(byteValue){if(typeof byteValue==="string"&&byteValue.length!==1){throw new BSONError("only accepts single character String")}else if(typeof byteValue!=="number"&&byteValue.length!==1)throw new BSONError("only accepts single character Uint8Array or Array");let decodedByte;if(typeof byteValue==="string"){decodedByte=byteValue.charCodeAt(0)}else if(typeof byteValue==="number"){decodedByte=byteValue}else{decodedByte=byteValue[0]}if(decodedByte<0||decodedByte>255){throw new BSONError("only accepts number in a valid unsigned byte range 0-255")}if(this.buffer.byteLength>this.position){this.buffer[this.position++]=decodedByte}else{const newSpace=ByteUtils.allocate(_Binary.BUFFER_SIZE+this.buffer.length);newSpace.set(this.buffer,0);this.buffer=newSpace;this.buffer[this.position++]=decodedByte}}write(sequence,offset){offset=typeof offset==="number"?offset:this.position;if(this.buffer.byteLengththis.position?offset+sequence.length:this.position}else if(typeof sequence==="string"){const bytes=ByteUtils.fromISO88591(sequence);this.buffer.set(bytes,offset);this.position=offset+sequence.length>this.position?offset+sequence.length:this.position}}read(position,length){length=length&&length>0?length:this.position;return this.buffer.slice(position,position+length)}value(asRaw){asRaw=!!asRaw;if(asRaw&&this.buffer.length===this.position){return this.buffer}if(asRaw){return this.buffer.slice(0,this.position)}return ByteUtils.toISO88591(this.buffer.subarray(0,this.position))}length(){return this.position}toJSON(){return ByteUtils.toBase64(this.buffer)}toString(encoding){if(encoding==="hex")return ByteUtils.toHex(this.buffer);if(encoding==="base64")return ByteUtils.toBase64(this.buffer);if(encoding==="utf8"||encoding==="utf-8")return ByteUtils.toUTF8(this.buffer);return ByteUtils.toUTF8(this.buffer)}toExtendedJSON(options){options=options||{};const base64String=ByteUtils.toBase64(this.buffer);const subType=Number(this.sub_type).toString(16);if(options.legacy){return{$binary:base64String,$type:subType.length===1?"0"+subType:subType}}return{$binary:{base64:base64String,subType:subType.length===1?"0"+subType:subType}}}toUUID(){if(this.sub_type===_Binary.SUBTYPE_UUID){return new UUID(this.buffer.slice(0,this.position))}throw new BSONError(`Binary sub_type "${this.sub_type}" is not supported for converting to UUID. Only "${_Binary.SUBTYPE_UUID}" is currently supported.`)}static fromExtendedJSON(doc,options){options=options||{};let data;let type;if("$binary"in doc){if(options.legacy&&typeof doc.$binary==="string"&&"$type"in doc){type=doc.$type?parseInt(doc.$type,16):0;data=ByteUtils.fromBase64(doc.$binary)}else{if(typeof doc.$binary!=="string"){type=doc.$binary.subType?parseInt(doc.$binary.subType,16):0;data=ByteUtils.fromBase64(doc.$binary.base64)}}}else if("$uuid"in doc){type=4;data=uuidHexStringToBuffer(doc.$uuid)}if(!data){throw new BSONError(`Unexpected Binary Extended JSON format ${JSON.stringify(doc)}`)}return type===BSON_BINARY_SUBTYPE_UUID_NEW?new UUID(data):new _Binary(data,type)}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){return`new Binary(Buffer.from("${ByteUtils.toHex(this.buffer)}", "hex"), ${this.sub_type})`}};Binary.BSON_BINARY_SUBTYPE_DEFAULT=0;Binary.BUFFER_SIZE=256;Binary.SUBTYPE_DEFAULT=0;Binary.SUBTYPE_FUNCTION=1;Binary.SUBTYPE_BYTE_ARRAY=2;Binary.SUBTYPE_UUID_OLD=3;Binary.SUBTYPE_UUID=4;Binary.SUBTYPE_MD5=5;Binary.SUBTYPE_ENCRYPTED=6;Binary.SUBTYPE_COLUMN=7;Binary.SUBTYPE_USER_DEFINED=128;var UUID_BYTE_LENGTH=16;var UUID=class _UUID extends Binary{constructor(input){let bytes;let hexStr;if(input==null){bytes=_UUID.generate()}else if(input instanceof _UUID){bytes=ByteUtils.toLocalBufferType(new Uint8Array(input.buffer));hexStr=input.__id}else if(ArrayBuffer.isView(input)&&input.byteLength===UUID_BYTE_LENGTH){bytes=ByteUtils.toLocalBufferType(input)}else if(typeof input==="string"){bytes=uuidHexStringToBuffer(input)}else{throw new BSONError("Argument passed in UUID constructor must be a UUID, a 16 byte Buffer or a 32/36 character hex string (dashes excluded/included, format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).")}super(bytes,BSON_BINARY_SUBTYPE_UUID_NEW);this.__id=hexStr}get id(){return this.buffer}set id(value){this.buffer=value;if(_UUID.cacheHexString){this.__id=bufferToUuidHexString(value)}}toHexString(includeDashes=true){if(_UUID.cacheHexString&&this.__id){return this.__id}const uuidHexString=bufferToUuidHexString(this.id,includeDashes);if(_UUID.cacheHexString){this.__id=uuidHexString}return uuidHexString}toString(encoding){if(encoding==="hex")return ByteUtils.toHex(this.id);if(encoding==="base64")return ByteUtils.toBase64(this.id);return this.toHexString()}toJSON(){return this.toHexString()}equals(otherId){if(!otherId){return false}if(otherId instanceof _UUID){return ByteUtils.equals(otherId.id,this.id)}try{return ByteUtils.equals(new _UUID(otherId).id,this.id)}catch{return false}}toBinary(){return new Binary(this.id,Binary.SUBTYPE_UUID)}static generate(){const bytes=ByteUtils.randomBytes(UUID_BYTE_LENGTH);bytes[6]=bytes[6]&15|64;bytes[8]=bytes[8]&63|128;return bytes}static isValid(input){if(!input){return false}if(input instanceof _UUID){return true}if(typeof input==="string"){return uuidValidateString(input)}if(isUint8Array(input)){if(input.byteLength!==UUID_BYTE_LENGTH){return false}return(input[6]&240)===64&&(input[8]&128)===128}return false}static createFromHexString(hexString){const buffer2=uuidHexStringToBuffer(hexString);return new _UUID(buffer2)}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){return`new UUID("${this.toHexString()}")`}};var Code=class _Code extends BSONValue{get _bsontype(){return"Code"}constructor(code,scope){super();this.code=code.toString();this.scope=scope??null}toJSON(){if(this.scope!=null){return{code:this.code,scope:this.scope}}return{code:this.code}}toExtendedJSON(){if(this.scope){return{$code:this.code,$scope:this.scope}}return{$code:this.code}}static fromExtendedJSON(doc){return new _Code(doc.$code,doc.$scope)}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){const codeJson=this.toJSON();return`new Code("${String(codeJson.code)}"${codeJson.scope!=null?`, ${JSON.stringify(codeJson.scope)}`:""})`}};function isDBRefLike(value){return value!=null&&typeof value==="object"&&"$id"in value&&value.$id!=null&&"$ref"in value&&typeof value.$ref==="string"&&(!("$db"in value)||"$db"in value&&typeof value.$db==="string")}var DBRef=class _DBRef extends BSONValue{get _bsontype(){return"DBRef"}constructor(collection,oid,db,fields){super();const parts=collection.split(".");if(parts.length===2){db=parts.shift();collection=parts.shift()}this.collection=collection;this.oid=oid;this.db=db;this.fields=fields||{}}get namespace(){return this.collection}set namespace(value){this.collection=value}toJSON(){const o=Object.assign({$ref:this.collection,$id:this.oid},this.fields);if(this.db!=null)o.$db=this.db;return o}toExtendedJSON(options){options=options||{};let o={$ref:this.collection,$id:this.oid};if(options.legacy){return o}if(this.db)o.$db=this.db;o=Object.assign(o,this.fields);return o}static fromExtendedJSON(doc){const copy=Object.assign({},doc);delete copy.$ref;delete copy.$id;delete copy.$db;return new _DBRef(doc.$ref,doc.$id,doc.$db,copy)}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){const oid=this.oid===void 0||this.oid.toString===void 0?this.oid:this.oid.toString();return`new DBRef("${this.namespace}", new ObjectId("${String(oid)}")${this.db?`, "${this.db}"`:""})`}};var wasm=void 0;try{wasm=new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0,97,115,109,1,0,0,0,1,13,2,96,0,1,127,96,4,127,127,127,127,1,127,3,7,6,0,1,1,1,1,1,6,6,1,127,1,65,0,11,7,50,6,3,109,117,108,0,1,5,100,105,118,95,115,0,2,5,100,105,118,95,117,0,3,5,114,101,109,95,115,0,4,5,114,101,109,95,117,0,5,8,103,101,116,95,104,105,103,104,0,0,10,191,1,6,4,0,35,0,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,126,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,127,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,128,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,129,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,130,34,4,66,32,135,167,36,0,32,4,167,11])),{}).exports}catch{}var TWO_PWR_16_DBL=1<<16;var TWO_PWR_24_DBL=1<<24;var TWO_PWR_32_DBL=TWO_PWR_16_DBL*TWO_PWR_16_DBL;var TWO_PWR_64_DBL=TWO_PWR_32_DBL*TWO_PWR_32_DBL;var TWO_PWR_63_DBL=TWO_PWR_64_DBL/2;var INT_CACHE={};var UINT_CACHE={};var MAX_INT64_STRING_LENGTH=20;var DECIMAL_REG_EX=/^(\+?0|(\+|-)?[1-9][0-9]*)$/;var Long=class _Long extends BSONValue{get _bsontype(){return"Long"}get __isLong__(){return true}constructor(low=0,high,unsigned){super();if(typeof low==="bigint"){Object.assign(this,_Long.fromBigInt(low,!!high))}else if(typeof low==="string"){Object.assign(this,_Long.fromString(low,!!high))}else{this.low=low|0;this.high=high|0;this.unsigned=!!unsigned}}static fromBits(lowBits,highBits,unsigned){return new _Long(lowBits,highBits,unsigned)}static fromInt(value,unsigned){let obj,cachedObj,cache;if(unsigned){value>>>=0;if(cache=0<=value&&value<256){cachedObj=UINT_CACHE[value];if(cachedObj)return cachedObj}obj=_Long.fromBits(value,(value|0)<0?-1:0,true);if(cache)UINT_CACHE[value]=obj;return obj}else{value|=0;if(cache=-128<=value&&value<128){cachedObj=INT_CACHE[value];if(cachedObj)return cachedObj}obj=_Long.fromBits(value,value<0?-1:0,false);if(cache)INT_CACHE[value]=obj;return obj}}static fromNumber(value,unsigned){if(isNaN(value))return unsigned?_Long.UZERO:_Long.ZERO;if(unsigned){if(value<0)return _Long.UZERO;if(value>=TWO_PWR_64_DBL)return _Long.MAX_UNSIGNED_VALUE}else{if(value<=-TWO_PWR_63_DBL)return _Long.MIN_VALUE;if(value+1>=TWO_PWR_63_DBL)return _Long.MAX_VALUE}if(value<0)return _Long.fromNumber(-value,unsigned).neg();return _Long.fromBits(value%TWO_PWR_32_DBL|0,value/TWO_PWR_32_DBL|0,unsigned)}static fromBigInt(value,unsigned){return _Long.fromString(value.toString(),unsigned)}static fromString(str2,unsigned,radix){if(str2.length===0)throw new BSONError("empty string");if(str2==="NaN"||str2==="Infinity"||str2==="+Infinity"||str2==="-Infinity")return _Long.ZERO;if(typeof unsigned==="number"){radix=unsigned,unsigned=false}else{unsigned=!!unsigned}radix=radix||10;if(radix<2||360)throw new BSONError("interior hyphen");else if(p2===0){return _Long.fromString(str2.substring(1),unsigned,radix).neg()}const radixToPower=_Long.fromNumber(Math.pow(radix,8));let result=_Long.ZERO;for(let i=0;i>>16;const a32=this.high&65535;const a16=this.low>>>16;const a00=this.low&65535;const b48=addend.high>>>16;const b32=addend.high&65535;const b16=addend.low>>>16;const b00=addend.low&65535;let c48=0,c32=0,c16=0,c00=0;c00+=a00+b00;c16+=c00>>>16;c00&=65535;c16+=a16+b16;c32+=c16>>>16;c16&=65535;c32+=a32+b32;c48+=c32>>>16;c32&=65535;c48+=a48+b48;c48&=65535;return _Long.fromBits(c16<<16|c00,c48<<16|c32,this.unsigned)}and(other){if(!_Long.isLong(other))other=_Long.fromValue(other);return _Long.fromBits(this.low&other.low,this.high&other.high,this.unsigned)}compare(other){if(!_Long.isLong(other))other=_Long.fromValue(other);if(this.eq(other))return 0;const thisNeg=this.isNegative(),otherNeg=other.isNegative();if(thisNeg&&!otherNeg)return-1;if(!thisNeg&&otherNeg)return 1;if(!this.unsigned)return this.sub(other).isNegative()?-1:1;return other.high>>>0>this.high>>>0||other.high===this.high&&other.low>>>0>this.low>>>0?-1:1}comp(other){return this.compare(other)}divide(divisor){if(!_Long.isLong(divisor))divisor=_Long.fromValue(divisor);if(divisor.isZero())throw new BSONError("division by zero");if(wasm){if(!this.unsigned&&this.high===-2147483648&&divisor.low===-1&&divisor.high===-1){return this}const low=(this.unsigned?wasm.div_u:wasm.div_s)(this.low,this.high,divisor.low,divisor.high);return _Long.fromBits(low,wasm.get_high(),this.unsigned)}if(this.isZero())return this.unsigned?_Long.UZERO:_Long.ZERO;let approx,rem,res;if(!this.unsigned){if(this.eq(_Long.MIN_VALUE)){if(divisor.eq(_Long.ONE)||divisor.eq(_Long.NEG_ONE))return _Long.MIN_VALUE;else if(divisor.eq(_Long.MIN_VALUE))return _Long.ONE;else{const halfThis=this.shr(1);approx=halfThis.div(divisor).shl(1);if(approx.eq(_Long.ZERO)){return divisor.isNegative()?_Long.ONE:_Long.NEG_ONE}else{rem=this.sub(divisor.mul(approx));res=approx.add(rem.div(divisor));return res}}}else if(divisor.eq(_Long.MIN_VALUE))return this.unsigned?_Long.UZERO:_Long.ZERO;if(this.isNegative()){if(divisor.isNegative())return this.neg().div(divisor.neg());return this.neg().div(divisor).neg()}else if(divisor.isNegative())return this.div(divisor.neg()).neg();res=_Long.ZERO}else{if(!divisor.unsigned)divisor=divisor.toUnsigned();if(divisor.gt(this))return _Long.UZERO;if(divisor.gt(this.shru(1)))return _Long.UONE;res=_Long.UZERO}rem=this;while(rem.gte(divisor)){approx=Math.max(1,Math.floor(rem.toNumber()/divisor.toNumber()));const log2=Math.ceil(Math.log(approx)/Math.LN2);const delta=log2<=48?1:Math.pow(2,log2-48);let approxRes=_Long.fromNumber(approx);let approxRem=approxRes.mul(divisor);while(approxRem.isNegative()||approxRem.gt(rem)){approx-=delta;approxRes=_Long.fromNumber(approx,this.unsigned);approxRem=approxRes.mul(divisor)}if(approxRes.isZero())approxRes=_Long.ONE;res=res.add(approxRes);rem=rem.sub(approxRem)}return res}div(divisor){return this.divide(divisor)}equals(other){if(!_Long.isLong(other))other=_Long.fromValue(other);if(this.unsigned!==other.unsigned&&this.high>>>31===1&&other.high>>>31===1)return false;return this.high===other.high&&this.low===other.low}eq(other){return this.equals(other)}getHighBits(){return this.high}getHighBitsUnsigned(){return this.high>>>0}getLowBits(){return this.low}getLowBitsUnsigned(){return this.low>>>0}getNumBitsAbs(){if(this.isNegative()){return this.eq(_Long.MIN_VALUE)?64:this.neg().getNumBitsAbs()}const val=this.high!==0?this.high:this.low;let bit;for(bit=31;bit>0;bit--)if((val&1<0}gt(other){return this.greaterThan(other)}greaterThanOrEqual(other){return this.comp(other)>=0}gte(other){return this.greaterThanOrEqual(other)}ge(other){return this.greaterThanOrEqual(other)}isEven(){return(this.low&1)===0}isNegative(){return!this.unsigned&&this.high<0}isOdd(){return(this.low&1)===1}isPositive(){return this.unsigned||this.high>=0}isZero(){return this.high===0&&this.low===0}lessThan(other){return this.comp(other)<0}lt(other){return this.lessThan(other)}lessThanOrEqual(other){return this.comp(other)<=0}lte(other){return this.lessThanOrEqual(other)}modulo(divisor){if(!_Long.isLong(divisor))divisor=_Long.fromValue(divisor);if(wasm){const low=(this.unsigned?wasm.rem_u:wasm.rem_s)(this.low,this.high,divisor.low,divisor.high);return _Long.fromBits(low,wasm.get_high(),this.unsigned)}return this.sub(this.div(divisor).mul(divisor))}mod(divisor){return this.modulo(divisor)}rem(divisor){return this.modulo(divisor)}multiply(multiplier){if(this.isZero())return _Long.ZERO;if(!_Long.isLong(multiplier))multiplier=_Long.fromValue(multiplier);if(wasm){const low=wasm.mul(this.low,this.high,multiplier.low,multiplier.high);return _Long.fromBits(low,wasm.get_high(),this.unsigned)}if(multiplier.isZero())return _Long.ZERO;if(this.eq(_Long.MIN_VALUE))return multiplier.isOdd()?_Long.MIN_VALUE:_Long.ZERO;if(multiplier.eq(_Long.MIN_VALUE))return this.isOdd()?_Long.MIN_VALUE:_Long.ZERO;if(this.isNegative()){if(multiplier.isNegative())return this.neg().mul(multiplier.neg());else return this.neg().mul(multiplier).neg()}else if(multiplier.isNegative())return this.mul(multiplier.neg()).neg();if(this.lt(_Long.TWO_PWR_24)&&multiplier.lt(_Long.TWO_PWR_24))return _Long.fromNumber(this.toNumber()*multiplier.toNumber(),this.unsigned);const a48=this.high>>>16;const a32=this.high&65535;const a16=this.low>>>16;const a00=this.low&65535;const b48=multiplier.high>>>16;const b32=multiplier.high&65535;const b16=multiplier.low>>>16;const b00=multiplier.low&65535;let c48=0,c32=0,c16=0,c00=0;c00+=a00*b00;c16+=c00>>>16;c00&=65535;c16+=a16*b00;c32+=c16>>>16;c16&=65535;c16+=a00*b16;c32+=c16>>>16;c16&=65535;c32+=a32*b00;c48+=c32>>>16;c32&=65535;c32+=a16*b16;c48+=c32>>>16;c32&=65535;c32+=a00*b32;c48+=c32>>>16;c32&=65535;c48+=a48*b00+a32*b16+a16*b32+a00*b48;c48&=65535;return _Long.fromBits(c16<<16|c00,c48<<16|c32,this.unsigned)}mul(multiplier){return this.multiply(multiplier)}negate(){if(!this.unsigned&&this.eq(_Long.MIN_VALUE))return _Long.MIN_VALUE;return this.not().add(_Long.ONE)}neg(){return this.negate()}not(){return _Long.fromBits(~this.low,~this.high,this.unsigned)}notEquals(other){return!this.equals(other)}neq(other){return this.notEquals(other)}ne(other){return this.notEquals(other)}or(other){if(!_Long.isLong(other))other=_Long.fromValue(other);return _Long.fromBits(this.low|other.low,this.high|other.high,this.unsigned)}shiftLeft(numBits){if(_Long.isLong(numBits))numBits=numBits.toInt();if((numBits&=63)===0)return this;else if(numBits<32)return _Long.fromBits(this.low<>>32-numBits,this.unsigned);else return _Long.fromBits(0,this.low<>>numBits|this.high<<32-numBits,this.high>>numBits,this.unsigned);else return _Long.fromBits(this.high>>numBits-32,this.high>=0?0:-1,this.unsigned)}shr(numBits){return this.shiftRight(numBits)}shiftRightUnsigned(numBits){if(_Long.isLong(numBits))numBits=numBits.toInt();numBits&=63;if(numBits===0)return this;else{const high=this.high;if(numBits<32){const low=this.low;return _Long.fromBits(low>>>numBits|high<<32-numBits,high>>>numBits,this.unsigned)}else if(numBits===32)return _Long.fromBits(high,0,this.unsigned);else return _Long.fromBits(high>>>numBits-32,0,this.unsigned)}}shr_u(numBits){return this.shiftRightUnsigned(numBits)}shru(numBits){return this.shiftRightUnsigned(numBits)}subtract(subtrahend){if(!_Long.isLong(subtrahend))subtrahend=_Long.fromValue(subtrahend);return this.add(subtrahend.neg())}sub(subtrahend){return this.subtract(subtrahend)}toInt(){return this.unsigned?this.low>>>0:this.low}toNumber(){if(this.unsigned)return(this.high>>>0)*TWO_PWR_32_DBL+(this.low>>>0);return this.high*TWO_PWR_32_DBL+(this.low>>>0)}toBigInt(){return BigInt(this.toString())}toBytes(le){return le?this.toBytesLE():this.toBytesBE()}toBytesLE(){const hi=this.high,lo=this.low;return[lo&255,lo>>>8&255,lo>>>16&255,lo>>>24,hi&255,hi>>>8&255,hi>>>16&255,hi>>>24]}toBytesBE(){const hi=this.high,lo=this.low;return[hi>>>24,hi>>>16&255,hi>>>8&255,hi&255,lo>>>24,lo>>>16&255,lo>>>8&255,lo&255]}toSigned(){if(!this.unsigned)return this;return _Long.fromBits(this.low,this.high,false)}toString(radix){radix=radix||10;if(radix<2||36>>0;let digits=intval.toString(radix);rem=remDiv;if(rem.isZero()){return digits+result}else{while(digits.length<6)digits="0"+digits;result=""+digits+result}}}toUnsigned(){if(this.unsigned)return this;return _Long.fromBits(this.low,this.high,true)}xor(other){if(!_Long.isLong(other))other=_Long.fromValue(other);return _Long.fromBits(this.low^other.low,this.high^other.high,this.unsigned)}eqz(){return this.isZero()}le(other){return this.lessThanOrEqual(other)}toExtendedJSON(options){if(options&&options.relaxed)return this.toNumber();return{$numberLong:this.toString()}}static fromExtendedJSON(doc,options){const{useBigInt64=false,relaxed=true}={...options};if(doc.$numberLong.length>MAX_INT64_STRING_LENGTH){throw new BSONError("$numberLong string is too long")}if(!DECIMAL_REG_EX.test(doc.$numberLong)){throw new BSONError(`$numberLong string "${doc.$numberLong}" is in an invalid format`)}if(useBigInt64){const bigIntResult=BigInt(doc.$numberLong);return BigInt.asIntN(64,bigIntResult)}const longResult=_Long.fromString(doc.$numberLong);if(relaxed){return longResult.toNumber()}return longResult}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){return`new Long("${this.toString()}"${this.unsigned?", true":""})`}};Long.TWO_PWR_24=Long.fromInt(TWO_PWR_24_DBL);Long.MAX_UNSIGNED_VALUE=Long.fromBits(4294967295|0,4294967295|0,true);Long.ZERO=Long.fromInt(0);Long.UZERO=Long.fromInt(0,true);Long.ONE=Long.fromInt(1);Long.UONE=Long.fromInt(1,true);Long.NEG_ONE=Long.fromInt(-1);Long.MAX_VALUE=Long.fromBits(4294967295|0,2147483647|0,false);Long.MIN_VALUE=Long.fromBits(0,2147483648|0,false);var PARSE_STRING_REGEXP=/^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/;var PARSE_INF_REGEXP=/^(\+|-)?(Infinity|inf)$/i;var PARSE_NAN_REGEXP=/^(\+|-)?NaN$/i;var EXPONENT_MAX=6111;var EXPONENT_MIN=-6176;var EXPONENT_BIAS=6176;var MAX_DIGITS=34;var NAN_BUFFER=ByteUtils.fromNumberArray([124,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].reverse());var INF_NEGATIVE_BUFFER=ByteUtils.fromNumberArray([248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].reverse());var INF_POSITIVE_BUFFER=ByteUtils.fromNumberArray([120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].reverse());var EXPONENT_REGEX=/^([-+])?(\d+)?$/;var COMBINATION_MASK=31;var EXPONENT_MASK=16383;var COMBINATION_INFINITY=30;var COMBINATION_NAN=31;function isDigit(value){return!isNaN(parseInt(value,10))}function divideu128(value){const DIVISOR=Long.fromNumber(1e3*1e3*1e3);let _rem=Long.fromNumber(0);if(!value.parts[0]&&!value.parts[1]&&!value.parts[2]&&!value.parts[3]){return{quotient:value,rem:_rem}}for(let i=0;i<=3;i++){_rem=_rem.shiftLeft(32);_rem=_rem.add(new Long(value.parts[i],0));value.parts[i]=_rem.div(DIVISOR).low;_rem=_rem.modulo(DIVISOR)}return{quotient:value,rem:_rem}}function multiply64x2(left,right){if(!left&&!right){return{high:Long.fromNumber(0),low:Long.fromNumber(0)}}const leftHigh=left.shiftRightUnsigned(32);const leftLow=new Long(left.getLowBits(),0);const rightHigh=right.shiftRightUnsigned(32);const rightLow=new Long(right.getLowBits(),0);let productHigh=leftHigh.multiply(rightHigh);let productMid=leftHigh.multiply(rightLow);const productMid2=leftLow.multiply(rightHigh);let productLow=leftLow.multiply(rightLow);productHigh=productHigh.add(productMid.shiftRightUnsigned(32));productMid=new Long(productMid.getLowBits(),0).add(productMid2).add(productLow.shiftRightUnsigned(32));productHigh=productHigh.add(productMid.shiftRightUnsigned(32));productLow=productMid.shiftLeft(32).add(new Long(productLow.getLowBits(),0));return{high:productHigh,low:productLow}}function lessThan(left,right){const uhleft=left.high>>>0;const uhright=right.high>>>0;if(uhleft>>0;const ulright=right.low>>>0;if(ulleft=7e3){throw new BSONError(""+representation+" not a valid Decimal128 string")}const stringMatch=representation.match(PARSE_STRING_REGEXP);const infMatch=representation.match(PARSE_INF_REGEXP);const nanMatch=representation.match(PARSE_NAN_REGEXP);if(!stringMatch&&!infMatch&&!nanMatch||representation.length===0){throw new BSONError(""+representation+" not a valid Decimal128 string")}if(stringMatch){const unsignedNumber=stringMatch[2];const e=stringMatch[4];const expSign=stringMatch[5];const expNumber=stringMatch[6];if(e&&expNumber===void 0)invalidErr(representation,"missing exponent power");if(e&&unsignedNumber===void 0)invalidErr(representation,"missing exponent base");if(e===void 0&&(expSign||expNumber)){invalidErr(representation,"missing e before exponent")}}if(representation[index]==="+"||representation[index]==="-"){isNegative=representation[index++]==="-"}if(!isDigit(representation[index])&&representation[index]!=="."){if(representation[index]==="i"||representation[index]==="I"){return new _Decimal128(isNegative?INF_NEGATIVE_BUFFER:INF_POSITIVE_BUFFER)}else if(representation[index]==="N"){return new _Decimal128(NAN_BUFFER)}}while(isDigit(representation[index])||representation[index]==="."){if(representation[index]==="."){if(sawRadix)invalidErr(representation,"contains multiple periods");sawRadix=true;index=index+1;continue}if(nDigitsStored<34){if(representation[index]!=="0"||foundNonZero){if(!foundNonZero){firstNonZero=nDigitsRead}foundNonZero=true;digits[digitsInsert++]=parseInt(representation[index],10);nDigitsStored=nDigitsStored+1}}if(foundNonZero)nDigits=nDigits+1;if(sawRadix)radixPosition=radixPosition+1;nDigitsRead=nDigitsRead+1;index=index+1}if(sawRadix&&!nDigitsRead)throw new BSONError(""+representation+" not a valid Decimal128 string");if(representation[index]==="e"||representation[index]==="E"){const match=representation.substr(++index).match(EXPONENT_REGEX);if(!match||!match[2])return new _Decimal128(NAN_BUFFER);exponent=parseInt(match[0],10);index=index+match[0].length}if(representation[index])return new _Decimal128(NAN_BUFFER);firstDigit=0;if(!nDigitsStored){firstDigit=0;lastDigit=0;digits[0]=0;nDigits=1;nDigitsStored=1;significantDigits=0}else{lastDigit=nDigitsStored-1;significantDigits=nDigits;if(significantDigits!==1){while(digits[firstNonZero+significantDigits-1]===0){significantDigits=significantDigits-1}}}if(exponent<=radixPosition&&radixPosition-exponent>1<<14){exponent=EXPONENT_MIN}else{exponent=exponent-radixPosition}while(exponent>EXPONENT_MAX){lastDigit=lastDigit+1;if(lastDigit-firstDigit>MAX_DIGITS){const digitsString=digits.join("");if(digitsString.match(/^0+$/)){exponent=EXPONENT_MAX;break}invalidErr(representation,"overflow")}exponent=exponent-1}while(exponent=5){roundBit=1;if(roundDigit===5){roundBit=digits[lastDigit]%2===1?1:0;for(i=firstNonZero+lastDigit+2;i=0;dIdx--){if(++digits[dIdx]>9){digits[dIdx]=0;if(dIdx===0){if(exponent>8&255;buffer2[index++]=dec.low.low>>16&255;buffer2[index++]=dec.low.low>>24&255;buffer2[index++]=dec.low.high&255;buffer2[index++]=dec.low.high>>8&255;buffer2[index++]=dec.low.high>>16&255;buffer2[index++]=dec.low.high>>24&255;buffer2[index++]=dec.high.low&255;buffer2[index++]=dec.high.low>>8&255;buffer2[index++]=dec.high.low>>16&255;buffer2[index++]=dec.high.low>>24&255;buffer2[index++]=dec.high.high&255;buffer2[index++]=dec.high.high>>8&255;buffer2[index++]=dec.high.high>>16&255;buffer2[index++]=dec.high.high>>24&255;return new _Decimal128(buffer2)}toString(){let biased_exponent;let significand_digits=0;const significand=new Array(36);for(let i=0;i>26&COMBINATION_MASK;if(combination>>3===3){if(combination===COMBINATION_INFINITY){return string.join("")+"Infinity"}else if(combination===COMBINATION_NAN){return"NaN"}else{biased_exponent=high>>15&EXPONENT_MASK;significand_msb=8+(high>>14&1)}}else{significand_msb=high>>14&7;biased_exponent=high>>17&EXPONENT_MASK}const exponent=biased_exponent-EXPONENT_BIAS;significand128.parts[0]=(high&16383)+((significand_msb&15)<<14);significand128.parts[1]=midh;significand128.parts[2]=midl;significand128.parts[3]=low;if(significand128.parts[0]===0&&significand128.parts[1]===0&&significand128.parts[2]===0&&significand128.parts[3]===0){is_zero=true}else{for(k=3;k>=0;k--){let least_digits=0;const result=divideu128(significand128);significand128=result.quotient;least_digits=result.rem.low;if(!least_digits)continue;for(j=8;j>=0;j--){significand[k*9+j]=least_digits%10;least_digits=Math.floor(least_digits/10)}}}if(is_zero){significand_digits=1;significand[index]=0}else{significand_digits=36;while(!significand[index]){significand_digits=significand_digits-1;index=index+1}}const scientific_exponent=significand_digits-1+exponent;if(scientific_exponent>=34||scientific_exponent<=-7||exponent>0){if(significand_digits>34){string.push(`${0}`);if(exponent>0)string.push(`E+${exponent}`);else if(exponent<0)string.push(`E${exponent}`);return string.join("")}string.push(`${significand[index++]}`);significand_digits=significand_digits-1;if(significand_digits){string.push(".")}for(let i=0;i0){string.push(`+${scientific_exponent}`)}else{string.push(`${scientific_exponent}`)}}else{if(exponent>=0){for(let i=0;i0){for(let i=0;i>8&255;buffer2[9]=inc>>16&255;return buffer2}toString(encoding){if(encoding==="base64")return ByteUtils.toBase64(this.id);if(encoding==="hex")return this.toHexString();return this.toHexString()}toJSON(){return this.toHexString()}equals(otherId){if(otherId===void 0||otherId===null){return false}if(otherId instanceof _ObjectId){return this[kId][11]===otherId[kId][11]&&ByteUtils.equals(this[kId],otherId[kId])}if(typeof otherId==="string"&&_ObjectId.isValid(otherId)&&otherId.length===12&&isUint8Array(this.id)){return ByteUtils.equals(this.id,ByteUtils.fromISO88591(otherId))}if(typeof otherId==="string"&&_ObjectId.isValid(otherId)&&otherId.length===24){return otherId.toLowerCase()===this.toHexString()}if(typeof otherId==="string"&&_ObjectId.isValid(otherId)&&otherId.length===12){return ByteUtils.equals(ByteUtils.fromUTF8(otherId),this.id)}if(typeof otherId==="object"&&"toHexString"in otherId&&typeof otherId.toHexString==="function"){const otherIdString=otherId.toHexString();const thisIdString=this.toHexString().toLowerCase();return typeof otherIdString==="string"&&otherIdString.toLowerCase()===thisIdString}return false}getTimestamp(){const timestamp=new Date;const time=BSONDataView.fromUint8Array(this.id).getUint32(0,false);timestamp.setTime(Math.floor(time)*1e3);return timestamp}static createPk(){return new _ObjectId}static createFromTime(time){const buffer2=ByteUtils.fromNumberArray([0,0,0,0,0,0,0,0,0,0,0,0]);BSONDataView.fromUint8Array(buffer2).setUint32(0,time,false);return new _ObjectId(buffer2)}static createFromHexString(hexString){if(typeof hexString==="undefined"||hexString!=null&&hexString.length!==24){throw new BSONError("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters")}return new _ObjectId(ByteUtils.fromHex(hexString))}static isValid(id){if(id==null)return false;try{new _ObjectId(id);return true}catch{return false}}toExtendedJSON(){if(this.toHexString)return{$oid:this.toHexString()};return{$oid:this.toString("hex")}}static fromExtendedJSON(doc){return new _ObjectId(doc.$oid)}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){return`new ObjectId("${this.toHexString()}")`}};ObjectId2.index=Math.floor(Math.random()*16777215);function internalCalculateObjectSize(object,serializeFunctions,ignoreUndefined){let totalLength=4+1;if(Array.isArray(object)){for(let i=0;i=JS_INT_MIN&&value<=JS_INT_MAX){if(value>=BSON_INT32_MIN&&value<=BSON_INT32_MAX){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(4+1)}else{return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(8+1)}}else{return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(8+1)}case"undefined":if(isArray||!ignoreUndefined)return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1;return 0;case"boolean":return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(1+1);case"object":if(value!=null&&typeof value._bsontype==="string"&&value[Symbol.for("@@mdb.bson.version")]!==BSON_MAJOR_VERSION){throw new BSONVersionError}else if(value==null||value._bsontype==="MinKey"||value._bsontype==="MaxKey"){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1}else if(value._bsontype==="ObjectId"){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(12+1)}else if(value instanceof Date||isDate(value)){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(8+1)}else if(ArrayBuffer.isView(value)||value instanceof ArrayBuffer||isAnyArrayBuffer(value)){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(1+4+1)+value.byteLength}else if(value._bsontype==="Long"||value._bsontype==="Double"||value._bsontype==="Timestamp"){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(8+1)}else if(value._bsontype==="Decimal128"){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(16+1)}else if(value._bsontype==="Code"){if(value.scope!=null&&Object.keys(value.scope).length>0){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1+4+4+ByteUtils.utf8ByteLength(value.code.toString())+1+internalCalculateObjectSize(value.scope,serializeFunctions,ignoreUndefined)}else{return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1+4+ByteUtils.utf8ByteLength(value.code.toString())+1}}else if(value._bsontype==="Binary"){const binary=value;if(binary.sub_type===Binary.SUBTYPE_BYTE_ARRAY){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(binary.position+1+4+1+4)}else{return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(binary.position+1+4+1)}}else if(value._bsontype==="Symbol"){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+ByteUtils.utf8ByteLength(value.value)+4+1+1}else if(value._bsontype==="DBRef"){const ordered_values=Object.assign({$ref:value.collection,$id:value.oid},value.fields);if(value.db!=null){ordered_values["$db"]=value.db}return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1+internalCalculateObjectSize(ordered_values,serializeFunctions,ignoreUndefined)}else if(value instanceof RegExp||isRegExp(value)){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1+ByteUtils.utf8ByteLength(value.source)+1+(value.global?1:0)+(value.ignoreCase?1:0)+(value.multiline?1:0)+1}else if(value._bsontype==="BSONRegExp"){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1+ByteUtils.utf8ByteLength(value.pattern)+1+ByteUtils.utf8ByteLength(value.options)+1}else{return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+internalCalculateObjectSize(value,serializeFunctions,ignoreUndefined)+1}case"function":if(serializeFunctions){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1+4+ByteUtils.utf8ByteLength(value.toString())+1}}return 0}function alphabetize(str2){return str2.split("").sort().join("")}var BSONRegExp=class _BSONRegExp extends BSONValue{get _bsontype(){return"BSONRegExp"}constructor(pattern,options){super();this.pattern=pattern;this.options=alphabetize(options??"");if(this.pattern.indexOf("\0")!==-1){throw new BSONError(`BSON Regex patterns cannot contain null bytes, found: ${JSON.stringify(this.pattern)}`)}if(this.options.indexOf("\0")!==-1){throw new BSONError(`BSON Regex options cannot contain null bytes, found: ${JSON.stringify(this.options)}`)}for(let i=0;i4294967295){throw new BSONError("Timestamp constructed from { t, i } must provide t equal or less than uint32 max")}if(low.i>4294967295){throw new BSONError("Timestamp constructed from { t, i } must provide i equal or less than uint32 max")}super(low.i.valueOf(),low.t.valueOf(),true)}else{throw new BSONError("A Timestamp can only be constructed with: bigint, Long, or { t: number; i: number }")}}toJSON(){return{$timestamp:this.toString()}}static fromInt(value){return new _Timestamp(Long.fromInt(value,true))}static fromNumber(value){return new _Timestamp(Long.fromNumber(value,true))}static fromBits(lowBits,highBits){return new _Timestamp({i:lowBits,t:highBits})}static fromString(str2,optRadix){return new _Timestamp(Long.fromString(str2,true,optRadix))}toExtendedJSON(){return{$timestamp:{t:this.high>>>0,i:this.low>>>0}}}static fromExtendedJSON(doc){const i=Long.isLong(doc.$timestamp.i)?doc.$timestamp.i.getLowBitsUnsigned():doc.$timestamp.i;const t=Long.isLong(doc.$timestamp.t)?doc.$timestamp.t.getLowBitsUnsigned():doc.$timestamp.t;return new _Timestamp({t,i})}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){return`new Timestamp({ t: ${this.getHighBits()}, i: ${this.getLowBits()} })`}};Timestamp.MAX_VALUE=Long.MAX_UNSIGNED_VALUE;var FIRST_BIT=128;var FIRST_TWO_BITS=192;var FIRST_THREE_BITS=224;var FIRST_FOUR_BITS=240;var FIRST_FIVE_BITS=248;var TWO_BIT_CHAR=192;var THREE_BIT_CHAR=224;var FOUR_BIT_CHAR=240;var CONTINUING_CHAR=128;function validateUtf8(bytes,start,end){let continuation=0;for(let i=start;i= 5, is ${size}`)}if(options.allowObjectSmallerThanBufferSize&&buffer2.length= bson size ${size}`)}if(!options.allowObjectSmallerThanBufferSize&&buffer2.length!==size){throw new BSONError(`buffer length ${buffer2.length} must === bson size ${size}`)}if(size+index>buffer2.byteLength){throw new BSONError(`(bson size ${size} + options.index ${index} must be <= buffer length ${buffer2.byteLength})`)}if(buffer2[index+size-1]!==0){throw new BSONError("One object, sized correctly, with a spot for an EOO, but the EOO isn't 0x00")}return deserializeObject(buffer2,index,options,isArray)}var allowedDBRefKeys=/^\$ref$|^\$id$|^\$db$/;function deserializeObject(buffer2,index,options,isArray=false){const fieldsAsRaw=options["fieldsAsRaw"]==null?null:options["fieldsAsRaw"];const raw=options["raw"]==null?false:options["raw"];const bsonRegExp=typeof options["bsonRegExp"]==="boolean"?options["bsonRegExp"]:false;const promoteBuffers=options.promoteBuffers??false;const promoteLongs=options.promoteLongs??true;const promoteValues=options.promoteValues??true;const useBigInt64=options.useBigInt64??false;if(useBigInt64&&!promoteValues){throw new BSONError("Must either request bigint or Long for int64 deserialization")}if(useBigInt64&&!promoteLongs){throw new BSONError("Must either request bigint or Long for int64 deserialization")}const validation=options.validation==null?{utf8:true}:options.validation;let globalUTFValidation=true;let validationSetting;const utf8KeysSet=new Set;const utf8ValidatedKeys=validation.utf8;if(typeof utf8ValidatedKeys==="boolean"){validationSetting=utf8ValidatedKeys}else{globalUTFValidation=false;const utf8ValidationValues=Object.keys(utf8ValidatedKeys).map(function(key){return utf8ValidatedKeys[key]});if(utf8ValidationValues.length===0){throw new BSONError("UTF-8 validation setting cannot be empty")}if(typeof utf8ValidationValues[0]!=="boolean"){throw new BSONError("Invalid UTF-8 validation option, must specify boolean values")}validationSetting=utf8ValidationValues[0];if(!utf8ValidationValues.every(item=>item===validationSetting)){throw new BSONError("Invalid UTF-8 validation option - keys must be all true or all false")}}if(!globalUTFValidation){for(const key of Object.keys(utf8ValidatedKeys)){utf8KeysSet.add(key)}}const startIndex=index;if(buffer2.length<5)throw new BSONError("corrupt bson message < 5 bytes long");const size=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(size<5||size>buffer2.length)throw new BSONError("corrupt bson message");const object=isArray?[]:{};let arrayIndex=0;const done=false;let isPossibleDBRef=isArray?false:null;const dataview=new DataView(buffer2.buffer,buffer2.byteOffset,buffer2.byteLength);while(!done){const elementType=buffer2[index++];if(elementType===0)break;let i=index;while(buffer2[i]!==0&&i=buffer2.byteLength)throw new BSONError("Bad BSON Document: illegal CString");const name=isArray?arrayIndex++:ByteUtils.toUTF8(buffer2.subarray(index,i));let shouldValidateKey=true;if(globalUTFValidation||utf8KeysSet.has(name)){shouldValidateKey=validationSetting}else{shouldValidateKey=!validationSetting}if(isPossibleDBRef!==false&&name[0]==="$"){isPossibleDBRef=allowedDBRefKeys.test(name)}let value;index=i+1;if(elementType===BSON_DATA_STRING){const stringSize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(stringSize<=0||stringSize>buffer2.length-index||buffer2[index+stringSize-1]!==0){throw new BSONError("bad string length in bson")}value=getValidatedString(buffer2,index,index+stringSize-1,shouldValidateKey);index=index+stringSize}else if(elementType===BSON_DATA_OID){const oid=ByteUtils.allocate(12);oid.set(buffer2.subarray(index,index+12));value=new ObjectId2(oid);index=index+12}else if(elementType===BSON_DATA_INT&&promoteValues===false){value=new Int32(buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24)}else if(elementType===BSON_DATA_INT){value=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24}else if(elementType===BSON_DATA_NUMBER&&promoteValues===false){value=new Double(dataview.getFloat64(index,true));index=index+8}else if(elementType===BSON_DATA_NUMBER){value=dataview.getFloat64(index,true);index=index+8}else if(elementType===BSON_DATA_DATE){const lowBits=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;const highBits=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;value=new Date(new Long(lowBits,highBits).toNumber())}else if(elementType===BSON_DATA_BOOLEAN){if(buffer2[index]!==0&&buffer2[index]!==1)throw new BSONError("illegal boolean type value");value=buffer2[index++]===1}else if(elementType===BSON_DATA_OBJECT){const _index=index;const objectSize=buffer2[index]|buffer2[index+1]<<8|buffer2[index+2]<<16|buffer2[index+3]<<24;if(objectSize<=0||objectSize>buffer2.length-index)throw new BSONError("bad embedded document length in bson");if(raw){value=buffer2.slice(index,index+objectSize)}else{let objectOptions=options;if(!globalUTFValidation){objectOptions={...options,validation:{utf8:shouldValidateKey}}}value=deserializeObject(buffer2,_index,objectOptions,false)}index=index+objectSize}else if(elementType===BSON_DATA_ARRAY){const _index=index;const objectSize=buffer2[index]|buffer2[index+1]<<8|buffer2[index+2]<<16|buffer2[index+3]<<24;let arrayOptions=options;const stopIndex=index+objectSize;if(fieldsAsRaw&&fieldsAsRaw[name]){arrayOptions={...options,raw:true}}if(!globalUTFValidation){arrayOptions={...arrayOptions,validation:{utf8:shouldValidateKey}}}value=deserializeObject(buffer2,_index,arrayOptions,true);index=index+objectSize;if(buffer2[index-1]!==0)throw new BSONError("invalid array terminator byte");if(index!==stopIndex)throw new BSONError("corrupted array bson")}else if(elementType===BSON_DATA_UNDEFINED){value=void 0}else if(elementType===BSON_DATA_NULL){value=null}else if(elementType===BSON_DATA_LONG){const dataview2=BSONDataView.fromUint8Array(buffer2.subarray(index,index+8));const lowBits=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;const highBits=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;const long=new Long(lowBits,highBits);if(useBigInt64){value=dataview2.getBigInt64(0,true)}else if(promoteLongs&&promoteValues===true){value=long.lessThanOrEqual(JS_INT_MAX_LONG)&&long.greaterThanOrEqual(JS_INT_MIN_LONG)?long.toNumber():long}else{value=long}}else if(elementType===BSON_DATA_DECIMAL128){const bytes=ByteUtils.allocate(16);bytes.set(buffer2.subarray(index,index+16),0);index=index+16;value=new Decimal128(bytes)}else if(elementType===BSON_DATA_BINARY){let binarySize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;const totalBinarySize=binarySize;const subType=buffer2[index++];if(binarySize<0)throw new BSONError("Negative binary type element size found");if(binarySize>buffer2.byteLength)throw new BSONError("Binary type size larger than document size");if(buffer2["slice"]!=null){if(subType===Binary.SUBTYPE_BYTE_ARRAY){binarySize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(binarySize<0)throw new BSONError("Negative binary type element size found for subtype 0x02");if(binarySize>totalBinarySize-4)throw new BSONError("Binary type with subtype 0x02 contains too long binary size");if(binarySizetotalBinarySize-4)throw new BSONError("Binary type with subtype 0x02 contains too long binary size");if(binarySize=buffer2.length)throw new BSONError("Bad BSON Document: illegal CString");const source=ByteUtils.toUTF8(buffer2.subarray(index,i));index=i+1;i=index;while(buffer2[i]!==0&&i=buffer2.length)throw new BSONError("Bad BSON Document: illegal CString");const regExpOptions=ByteUtils.toUTF8(buffer2.subarray(index,i));index=i+1;const optionsArray=new Array(regExpOptions.length);for(i=0;i=buffer2.length)throw new BSONError("Bad BSON Document: illegal CString");const source=ByteUtils.toUTF8(buffer2.subarray(index,i));index=i+1;i=index;while(buffer2[i]!==0&&i=buffer2.length)throw new BSONError("Bad BSON Document: illegal CString");const regExpOptions=ByteUtils.toUTF8(buffer2.subarray(index,i));index=i+1;value=new BSONRegExp(source,regExpOptions)}else if(elementType===BSON_DATA_SYMBOL){const stringSize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(stringSize<=0||stringSize>buffer2.length-index||buffer2[index+stringSize-1]!==0){throw new BSONError("bad string length in bson")}const symbol=getValidatedString(buffer2,index,index+stringSize-1,shouldValidateKey);value=promoteValues?symbol:new BSONSymbol(symbol);index=index+stringSize}else if(elementType===BSON_DATA_TIMESTAMP){const i2=buffer2[index++]+buffer2[index++]*(1<<8)+buffer2[index++]*(1<<16)+buffer2[index++]*(1<<24);const t=buffer2[index++]+buffer2[index++]*(1<<8)+buffer2[index++]*(1<<16)+buffer2[index++]*(1<<24);value=new Timestamp({i:i2,t})}else if(elementType===BSON_DATA_MIN_KEY){value=new MinKey}else if(elementType===BSON_DATA_MAX_KEY){value=new MaxKey}else if(elementType===BSON_DATA_CODE){const stringSize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(stringSize<=0||stringSize>buffer2.length-index||buffer2[index+stringSize-1]!==0){throw new BSONError("bad string length in bson")}const functionString=getValidatedString(buffer2,index,index+stringSize-1,shouldValidateKey);value=new Code(functionString);index=index+stringSize}else if(elementType===BSON_DATA_CODE_W_SCOPE){const totalSize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(totalSize<4+4+4+1){throw new BSONError("code_w_scope total size shorter minimum expected length")}const stringSize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(stringSize<=0||stringSize>buffer2.length-index||buffer2[index+stringSize-1]!==0){throw new BSONError("bad string length in bson")}const functionString=getValidatedString(buffer2,index,index+stringSize-1,shouldValidateKey);index=index+stringSize;const _index=index;const objectSize=buffer2[index]|buffer2[index+1]<<8|buffer2[index+2]<<16|buffer2[index+3]<<24;const scopeObject=deserializeObject(buffer2,_index,options,false);index=index+objectSize;if(totalSize<4+4+objectSize+stringSize){throw new BSONError("code_w_scope total size is too short, truncating scope")}if(totalSize>4+4+objectSize+stringSize){throw new BSONError("code_w_scope total size is too long, clips outer document")}value=new Code(functionString,scopeObject)}else if(elementType===BSON_DATA_DBPOINTER){const stringSize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(stringSize<=0||stringSize>buffer2.length-index||buffer2[index+stringSize-1]!==0)throw new BSONError("bad string length in bson");if(validation!=null&&validation.utf8){if(!validateUtf8(buffer2,index,index+stringSize-1)){throw new BSONError("Invalid UTF-8 string in BSON document")}}const namespace=ByteUtils.toUTF8(buffer2.subarray(index,index+stringSize-1));index=index+stringSize;const oidBuffer=ByteUtils.allocate(12);oidBuffer.set(buffer2.subarray(index,index+12),0);const oid=new ObjectId2(oidBuffer);index=index+12;value=new DBRef(namespace,oid)}else{throw new BSONError(`Detected unknown BSON type ${elementType.toString(16)} for fieldname "${name}"`)}if(name==="__proto__"){Object.defineProperty(object,name,{value,writable:true,enumerable:true,configurable:true})}else{object[name]=value}}if(size!==index-startIndex){if(isArray)throw new BSONError("corrupt array bson");throw new BSONError("corrupt object bson")}if(!isPossibleDBRef)return object;if(isDBRefLike(object)){const copy=Object.assign({},object);delete copy.$ref;delete copy.$id;delete copy.$db;return new DBRef(object.$ref,object.$id,object.$db,copy)}return object}function getValidatedString(buffer2,start,end,shouldValidateUtf8){const value=ByteUtils.toUTF8(buffer2.subarray(start,end));if(shouldValidateUtf8){for(let i=0;i>24&255;buffer2[index+2]=size+1>>16&255;buffer2[index+1]=size+1>>8&255;buffer2[index]=size+1&255;index=index+4+size;buffer2[index++]=0;return index}var NUMBER_SPACE=new DataView(new ArrayBuffer(8),0,8);var FOUR_BYTE_VIEW_ON_NUMBER=new Uint8Array(NUMBER_SPACE.buffer,0,4);var EIGHT_BYTE_VIEW_ON_NUMBER=new Uint8Array(NUMBER_SPACE.buffer,0,8);function serializeNumber(buffer2,key,value,index){const isNegativeZero=Object.is(value,-0);const type=!isNegativeZero&&Number.isSafeInteger(value)&&value<=BSON_INT32_MAX&&value>=BSON_INT32_MIN?BSON_DATA_INT:BSON_DATA_NUMBER;if(type===BSON_DATA_INT){NUMBER_SPACE.setInt32(0,value,true)}else{NUMBER_SPACE.setFloat64(0,value,true)}const bytes=type===BSON_DATA_INT?FOUR_BYTE_VIEW_ON_NUMBER:EIGHT_BYTE_VIEW_ON_NUMBER;buffer2[index++]=type;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;buffer2.set(bytes,index);index+=bytes.byteLength;return index}function serializeBigInt(buffer2,key,value,index){buffer2[index++]=BSON_DATA_LONG;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index+=numberOfWrittenBytes;buffer2[index++]=0;NUMBER_SPACE.setBigInt64(0,value,true);buffer2.set(EIGHT_BYTE_VIEW_ON_NUMBER,index);index+=EIGHT_BYTE_VIEW_ON_NUMBER.byteLength;return index}function serializeNull(buffer2,key,_,index){buffer2[index++]=BSON_DATA_NULL;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;return index}function serializeBoolean(buffer2,key,value,index){buffer2[index++]=BSON_DATA_BOOLEAN;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;buffer2[index++]=value?1:0;return index}function serializeDate(buffer2,key,value,index){buffer2[index++]=BSON_DATA_DATE;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const dateInMilis=Long.fromNumber(value.getTime());const lowBits=dateInMilis.getLowBits();const highBits=dateInMilis.getHighBits();buffer2[index++]=lowBits&255;buffer2[index++]=lowBits>>8&255;buffer2[index++]=lowBits>>16&255;buffer2[index++]=lowBits>>24&255;buffer2[index++]=highBits&255;buffer2[index++]=highBits>>8&255;buffer2[index++]=highBits>>16&255;buffer2[index++]=highBits>>24&255;return index}function serializeRegExp(buffer2,key,value,index){buffer2[index++]=BSON_DATA_REGEXP;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;if(value.source&&value.source.match(regexp)!=null){throw new BSONError("value "+value.source+" must not contain null bytes")}index=index+ByteUtils.encodeUTF8Into(buffer2,value.source,index);buffer2[index++]=0;if(value.ignoreCase)buffer2[index++]=105;if(value.global)buffer2[index++]=115;if(value.multiline)buffer2[index++]=109;buffer2[index++]=0;return index}function serializeBSONRegExp(buffer2,key,value,index){buffer2[index++]=BSON_DATA_REGEXP;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;if(value.pattern.match(regexp)!=null){throw new BSONError("pattern "+value.pattern+" must not contain null bytes")}index=index+ByteUtils.encodeUTF8Into(buffer2,value.pattern,index);buffer2[index++]=0;const sortedOptions=value.options.split("").sort().join("");index=index+ByteUtils.encodeUTF8Into(buffer2,sortedOptions,index);buffer2[index++]=0;return index}function serializeMinMax(buffer2,key,value,index){if(value===null){buffer2[index++]=BSON_DATA_NULL}else if(value._bsontype==="MinKey"){buffer2[index++]=BSON_DATA_MIN_KEY}else{buffer2[index++]=BSON_DATA_MAX_KEY}const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;return index}function serializeObjectId(buffer2,key,value,index){buffer2[index++]=BSON_DATA_OID;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;if(isUint8Array(value.id)){buffer2.set(value.id.subarray(0,12),index)}else{throw new BSONError("object ["+JSON.stringify(value)+"] is not a valid ObjectId")}return index+12}function serializeBuffer(buffer2,key,value,index){buffer2[index++]=BSON_DATA_BINARY;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const size=value.length;buffer2[index++]=size&255;buffer2[index++]=size>>8&255;buffer2[index++]=size>>16&255;buffer2[index++]=size>>24&255;buffer2[index++]=BSON_BINARY_SUBTYPE_DEFAULT;buffer2.set(value,index);index=index+size;return index}function serializeObject(buffer2,key,value,index,checkKeys,depth,serializeFunctions,ignoreUndefined,path){if(path.has(value)){throw new BSONError("Cannot convert circular structure to BSON")}path.add(value);buffer2[index++]=Array.isArray(value)?BSON_DATA_ARRAY:BSON_DATA_OBJECT;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const endIndex=serializeInto(buffer2,value,checkKeys,index,depth+1,serializeFunctions,ignoreUndefined,path);path.delete(value);return endIndex}function serializeDecimal128(buffer2,key,value,index){buffer2[index++]=BSON_DATA_DECIMAL128;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;buffer2.set(value.bytes.subarray(0,16),index);return index+16}function serializeLong(buffer2,key,value,index){buffer2[index++]=value._bsontype==="Long"?BSON_DATA_LONG:BSON_DATA_TIMESTAMP;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const lowBits=value.getLowBits();const highBits=value.getHighBits();buffer2[index++]=lowBits&255;buffer2[index++]=lowBits>>8&255;buffer2[index++]=lowBits>>16&255;buffer2[index++]=lowBits>>24&255;buffer2[index++]=highBits&255;buffer2[index++]=highBits>>8&255;buffer2[index++]=highBits>>16&255;buffer2[index++]=highBits>>24&255;return index}function serializeInt32(buffer2,key,value,index){value=value.valueOf();buffer2[index++]=BSON_DATA_INT;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;buffer2[index++]=value&255;buffer2[index++]=value>>8&255;buffer2[index++]=value>>16&255;buffer2[index++]=value>>24&255;return index}function serializeDouble(buffer2,key,value,index){buffer2[index++]=BSON_DATA_NUMBER;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;NUMBER_SPACE.setFloat64(0,value.value,true);buffer2.set(EIGHT_BYTE_VIEW_ON_NUMBER,index);index=index+8;return index}function serializeFunction(buffer2,key,value,index){buffer2[index++]=BSON_DATA_CODE;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const functionString=value.toString();const size=ByteUtils.encodeUTF8Into(buffer2,functionString,index+4)+1;buffer2[index]=size&255;buffer2[index+1]=size>>8&255;buffer2[index+2]=size>>16&255;buffer2[index+3]=size>>24&255;index=index+4+size-1;buffer2[index++]=0;return index}function serializeCode(buffer2,key,value,index,checkKeys=false,depth=0,serializeFunctions=false,ignoreUndefined=true,path){if(value.scope&&typeof value.scope==="object"){buffer2[index++]=BSON_DATA_CODE_W_SCOPE;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;let startIndex=index;const functionString=value.code;index=index+4;const codeSize=ByteUtils.encodeUTF8Into(buffer2,functionString,index+4)+1;buffer2[index]=codeSize&255;buffer2[index+1]=codeSize>>8&255;buffer2[index+2]=codeSize>>16&255;buffer2[index+3]=codeSize>>24&255;buffer2[index+4+codeSize-1]=0;index=index+codeSize+4;const endIndex=serializeInto(buffer2,value.scope,checkKeys,index,depth+1,serializeFunctions,ignoreUndefined,path);index=endIndex-1;const totalSize=endIndex-startIndex;buffer2[startIndex++]=totalSize&255;buffer2[startIndex++]=totalSize>>8&255;buffer2[startIndex++]=totalSize>>16&255;buffer2[startIndex++]=totalSize>>24&255;buffer2[index++]=0}else{buffer2[index++]=BSON_DATA_CODE;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const functionString=value.code.toString();const size=ByteUtils.encodeUTF8Into(buffer2,functionString,index+4)+1;buffer2[index]=size&255;buffer2[index+1]=size>>8&255;buffer2[index+2]=size>>16&255;buffer2[index+3]=size>>24&255;index=index+4+size-1;buffer2[index++]=0}return index}function serializeBinary(buffer2,key,value,index){buffer2[index++]=BSON_DATA_BINARY;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const data=value.buffer;let size=value.position;if(value.sub_type===Binary.SUBTYPE_BYTE_ARRAY)size=size+4;buffer2[index++]=size&255;buffer2[index++]=size>>8&255;buffer2[index++]=size>>16&255;buffer2[index++]=size>>24&255;buffer2[index++]=value.sub_type;if(value.sub_type===Binary.SUBTYPE_BYTE_ARRAY){size=size-4;buffer2[index++]=size&255;buffer2[index++]=size>>8&255;buffer2[index++]=size>>16&255;buffer2[index++]=size>>24&255}buffer2.set(data,index);index=index+value.position;return index}function serializeSymbol(buffer2,key,value,index){buffer2[index++]=BSON_DATA_SYMBOL;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const size=ByteUtils.encodeUTF8Into(buffer2,value.value,index+4)+1;buffer2[index]=size&255;buffer2[index+1]=size>>8&255;buffer2[index+2]=size>>16&255;buffer2[index+3]=size>>24&255;index=index+4+size-1;buffer2[index++]=0;return index}function serializeDBRef(buffer2,key,value,index,depth,serializeFunctions,path){buffer2[index++]=BSON_DATA_OBJECT;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;let startIndex=index;let output={$ref:value.collection||value.namespace,$id:value.oid};if(value.db!=null){output.$db=value.db}output=Object.assign(output,value.fields);const endIndex=serializeInto(buffer2,output,false,index,depth+1,serializeFunctions,true,path);const size=endIndex-startIndex;buffer2[startIndex++]=size&255;buffer2[startIndex++]=size>>8&255;buffer2[startIndex++]=size>>16&255;buffer2[startIndex++]=size>>24&255;return endIndex}function serializeInto(buffer2,object,checkKeys,startingIndex,depth,serializeFunctions,ignoreUndefined,path){if(path==null){if(object==null){buffer2[0]=5;buffer2[1]=0;buffer2[2]=0;buffer2[3]=0;buffer2[4]=0;return 5}if(Array.isArray(object)){throw new BSONError("serialize does not support an array as the root input")}if(typeof object!=="object"){throw new BSONError("serialize does not support non-object as the root input")}else if("_bsontype"in object&&typeof object._bsontype==="string"){throw new BSONError(`BSON types cannot be serialized as a document`)}else if(isDate(object)||isRegExp(object)||isUint8Array(object)||isAnyArrayBuffer(object)){throw new BSONError(`date, regexp, typedarray, and arraybuffer cannot be BSON documents`)}path=new Set}path.add(object);let index=startingIndex+4;if(Array.isArray(object)){for(let i=0;i>8&255;buffer2[startingIndex++]=size>>16&255;buffer2[startingIndex++]=size>>24&255;return index}function isBSONType(value){return value!=null&&typeof value==="object"&&"_bsontype"in value&&typeof value._bsontype==="string"}var keysToCodecs={$oid:ObjectId2,$binary:Binary,$uuid:Binary,$symbol:BSONSymbol,$numberInt:Int32,$numberDecimal:Decimal128,$numberDouble:Double,$numberLong:Long,$minKey:MinKey,$maxKey:MaxKey,$regex:BSONRegExp,$regularExpression:BSONRegExp,$timestamp:Timestamp};function deserializeValue(value,options={}){if(typeof value==="number"){const in32BitRange=value<=BSON_INT32_MAX&&value>=BSON_INT32_MIN;const in64BitRange=value<=BSON_INT64_MAX&&value>=BSON_INT64_MIN;if(options.relaxed||options.legacy){return value}if(Number.isInteger(value)&&!Object.is(value,-0)){if(in32BitRange){return new Int32(value)}if(in64BitRange){if(options.useBigInt64){return BigInt(value)}return Long.fromNumber(value)}}return new Double(value)}if(value==null||typeof value!=="object")return value;if(value.$undefined)return null;const keys=Object.keys(value).filter(k=>k.startsWith("$")&&value[k]!=null);for(let i=0;ik.startsWith("$"));let valid=true;dollarKeys.forEach(k=>{if(["$ref","$id","$db"].indexOf(k)===-1)valid=false});if(valid)return DBRef.fromExtendedJSON(v2)}return value}function serializeArray(array,options){return array.map((v2,index)=>{options.seenObjects.push({propertyName:`index ${index}`,obj:null});try{return serializeValue(v2,options)}finally{options.seenObjects.pop()}})}function getISOString(date){const isoStr=date.toISOString();return date.getUTCMilliseconds()!==0?isoStr:isoStr.slice(0,-5)+"Z"}function serializeValue(value,options){if(value instanceof Map||isMap(value)){const obj=Object.create(null);for(const[k,v2]of value){if(typeof k!=="string"){throw new BSONError("Can only serialize maps with string keys")}obj[k]=v2}return serializeValue(obj,options)}if((typeof value==="object"||typeof value==="function")&&value!==null){const index=options.seenObjects.findIndex(entry=>entry.obj===value);if(index!==-1){const props=options.seenObjects.map(entry=>entry.propertyName);const leadingPart=props.slice(0,index).map(prop=>`${prop} -> `).join("");const alreadySeen=props[index];const circularPart=" -> "+props.slice(index+1,props.length-1).map(prop=>`${prop} -> `).join("");const current=props[props.length-1];const leadingSpace=" ".repeat(leadingPart.length+alreadySeen.length/2);const dashes="-".repeat(circularPart.length+(alreadySeen.length+current.length)/2-1);throw new BSONError(`Converting circular structure to EJSON: - ${leadingPart}${alreadySeen}${circularPart}${current} - ${leadingSpace}\\${dashes}/`)}options.seenObjects[options.seenObjects.length-1].obj=value}if(Array.isArray(value))return serializeArray(value,options);if(value===void 0)return null;if(value instanceof Date||isDate(value)){const dateNum=value.getTime(),inRange=dateNum>-1&&dateNum<2534023188e5;if(options.legacy){return options.relaxed&&inRange?{$date:value.getTime()}:{$date:getISOString(value)}}return options.relaxed&&inRange?{$date:getISOString(value)}:{$date:{$numberLong:value.getTime().toString()}}}if(typeof value==="number"&&(!options.relaxed||!isFinite(value))){if(Number.isInteger(value)&&!Object.is(value,-0)){if(value>=BSON_INT32_MIN&&value<=BSON_INT32_MAX){return{$numberInt:value.toString()}}if(value>=BSON_INT64_MIN&&value<=BSON_INT64_MAX){return{$numberLong:value.toString()}}}return{$numberDouble:Object.is(value,-0)?"-0.0":value.toString()}}if(typeof value==="bigint"){if(!options.relaxed){return{$numberLong:BigInt.asIntN(64,value).toString()}}return Number(BigInt.asIntN(64,value))}if(value instanceof RegExp||isRegExp(value)){let flags=value.flags;if(flags===void 0){const match=value.toString().match(/[gimuy]*$/);if(match){flags=match[0]}}const rx=new BSONRegExp(value.source,flags);return rx.toExtendedJSON(options)}if(value!=null&&typeof value==="object")return serializeDocument(value,options);return value}var BSON_TYPE_MAPPINGS={Binary:o=>new Binary(o.value(),o.sub_type),Code:o=>new Code(o.code,o.scope),DBRef:o=>new DBRef(o.collection||o.namespace,o.oid,o.db,o.fields),Decimal128:o=>new Decimal128(o.bytes),Double:o=>new Double(o.value),Int32:o=>new Int32(o.value),Long:o=>Long.fromBits(o.low!=null?o.low:o.low_,o.low!=null?o.high:o.high_,o.low!=null?o.unsigned:o.unsigned_),MaxKey:()=>new MaxKey,MinKey:()=>new MinKey,ObjectId:o=>new ObjectId2(o),BSONRegExp:o=>new BSONRegExp(o.pattern,o.options),BSONSymbol:o=>new BSONSymbol(o.value),Timestamp:o=>Timestamp.fromBits(o.low,o.high)};function serializeDocument(doc,options){if(doc==null||typeof doc!=="object")throw new BSONError("not an object instance");const bsontype=doc._bsontype;if(typeof bsontype==="undefined"){const _doc={};for(const name of Object.keys(doc)){options.seenObjects.push({propertyName:name,obj:null});try{const value=serializeValue(doc[name],options);if(name==="__proto__"){Object.defineProperty(_doc,name,{value,writable:true,enumerable:true,configurable:true})}else{_doc[name]=value}}finally{options.seenObjects.pop()}}return _doc}else if(doc!=null&&typeof doc==="object"&&typeof doc._bsontype==="string"&&doc[Symbol.for("@@mdb.bson.version")]!==BSON_MAJOR_VERSION){throw new BSONVersionError}else if(isBSONType(doc)){let outDoc=doc;if(typeof outDoc.toExtendedJSON!=="function"){const mapper=BSON_TYPE_MAPPINGS[doc._bsontype];if(!mapper){throw new BSONError("Unrecognized or invalid _bsontype: "+doc._bsontype)}outDoc=mapper(outDoc)}if(bsontype==="Code"&&outDoc.scope){outDoc=new Code(outDoc.code,serializeValue(outDoc.scope,options))}else if(bsontype==="DBRef"&&outDoc.oid){outDoc=new DBRef(serializeValue(outDoc.collection,options),serializeValue(outDoc.oid,options),serializeValue(outDoc.db,options),serializeValue(outDoc.fields,options))}return outDoc.toExtendedJSON(options)}else{throw new BSONError("_bsontype must be a string, but was: "+typeof bsontype)}}function parse(text,options){const ejsonOptions={useBigInt64:options?.useBigInt64??false,relaxed:options?.relaxed??true,legacy:options?.legacy??false};return JSON.parse(text,(key,value)=>{if(key.indexOf("\0")!==-1){throw new BSONError(`BSON Document field names cannot contain null bytes, found: ${JSON.stringify(key)}`)}return deserializeValue(value,ejsonOptions)})}function stringify(value,replacer,space,options){if(space!=null&&typeof space==="object"){options=space;space=0}if(replacer!=null&&typeof replacer==="object"&&!Array.isArray(replacer)){options=replacer;replacer=void 0;space=0}const serializeOptions=Object.assign({relaxed:true,legacy:false},options,{seenObjects:[{propertyName:"(root)",obj:null}]});const doc=serializeValue(value,serializeOptions);return JSON.stringify(doc,replacer,space)}function EJSONserialize(value,options){options=options||{};return JSON.parse(stringify(value,options))}function EJSONdeserialize(ejson,options){options=options||{};return parse(JSON.stringify(ejson),options)}var EJSON=Object.create(null);EJSON.parse=parse;EJSON.stringify=stringify;EJSON.serialize=EJSONserialize;EJSON.deserialize=EJSONdeserialize;Object.freeze(EJSON);var MAXSIZE=1024*1024*17;var buffer=ByteUtils.allocate(MAXSIZE);function setInternalBufferSize(size){if(buffer.lengthAuthorizationStruct,ChatroomStruct:()=>ChatroomStruct,CoherenceMap:()=>CoherenceMap,CoherenceStruct:()=>CoherenceStruct,CommentStruct:()=>CommentStruct,Data:()=>Data,DataStruct:()=>DataStruct,DateStruct:()=>DateStruct,ECGStruct:()=>ECGStruct,EDAStruct:()=>EDAStruct,EEGCoordinates:()=>EEGCoordinates,EEGStruct:()=>EEGStruct,EMGStruct:()=>EMGStruct,EventStruct:()=>EventStruct,EyeTrackerStruct:()=>EyeTrackerStruct,FNIRSStruct:()=>FNIRSStruct,FrequencyBandsStruct:()=>FrequencyBandsStruct,GroupStruct:()=>GroupStruct,HRVStruct:()=>HRVStruct,IMUStruct:()=>IMUStruct,NotificationStruct:()=>NotificationStruct,PPGStruct:()=>PPGStruct,ProfileStruct:()=>ProfileStruct,ScheduleStruct:()=>ScheduleStruct,Struct:()=>Struct,eegCoordinates:()=>eegCoordinates,setCoordinate:()=>setCoordinate,structRegistry:()=>structRegistry});function Struct(structType="struct",assignProps={},parentUser={_id:""},parentStruct={structType:"struct",_id:""}){function randomId3(tag=""){return`${tag+Math.floor(Math.random()+Math.random()*Math.random()*1e16)}`}let struct={_id:randomId3(structType+"defaultId"),structType,ownerId:parentUser?._id,timestamp:Date.now(),parent:{structType:parentStruct?.structType,_id:parentStruct?._id}};if(!struct.ownerId)delete struct.ownerId;if(!struct?.parent?._id)delete struct.parent;if(Object.keys(assignProps).length>0)Object.assign(struct,assignProps);return struct}var eegCoordinates={FP1:[-21.2,66.9,12.1],FPZ:[1.4,65.1,11.3],FP2:[24.3,66.3,12.5],AF7:[-41.7,52.8,11.3],AF3:[-32.7,48.4,32.8],AFZ:[1.8,54.8,37.9],AF4:[35.1,50.1,31.1],AF8:[43.9,52.7,9.3],F5:[-51.4,26.7,24.7],F3:[-39.7,25.3,44.7],F1:[-22.1,26.8,54.9],FZ:[0,26.8,60.6],F2:[23.6,28.2,55.6],F4:[41.9,27.5,43.9],F6:[52.9,28.7,25.2],F7:[-52.1,28.6,3.8],F8:[53.2,28.4,3.1],FC5:[-59.1,3,26.1],FC3:[-45.5,2.4,51.3],FC1:[-24.7,.3,66.4],FCZ:[1,1,72.8],FC2:[26.1,3.2,66],FC4:[47.5,4.6,49.7],FC6:[60.5,4.9,25.5],FT9:[-53.8,-2.1,-29.1],FT7:[-59.2,3.4,-2.1],FT8:[60.2,4.7,-2.8],FT10:[55,-3.6,-31],T7:[-65.8,-17.8,-2.9],T5:[-61.5,-65.3,1.1],T3:[-70.2,-21.3,-10.7],T4:[71.9,-25.2,-8.2],T6:[59.3,-67.6,3.8],T8:[67.4,-18.5,-3.4],C5:[-63.6,-18.9,25.8],C3:[-49.1,-20.7,53.2],C1:[-25.1,-22.5,70.1],CZ:[.8,-21.9,77.4],C2:[26.7,-20.9,69.5],C4:[50.3,-18.8,53],C6:[65.2,-18,26.4],CP5:[-61.8,-46.2,22.5],CP3:[-46.9,-47.7,49.7],CP1:[-24,-49.1,66.1],CPZ:[.7,-47.9,72.6],CP2:[25.8,-47.1,66],CP4:[49.5,-45.5,50.7],CP6:[62.9,-44.6,24.4],TP9:[-73.6,-46.7,-4],TP7:[-63.6,-44.7,-4],TP8:[64.6,-45.4,-3.7],TP10:[74.6,-47.4,-3.7],P9:[-50.8,-51.3,-37.7],P7:[-55.9,-64.8,0],P5:[-52.7,-67.1,19.9],P3:[-41.4,-67.8,42.4],P1:[-21.6,-71.3,52.6],PZ:[.7,-69.3,56.9],P2:[24.4,-69.9,53.5],P4:[44.2,-65.8,42.7],P6:[54.4,-65.3,20.2],P8:[56.4,-64.4,.1],P10:[51,-53.9,-36.5],PO7:[-44,-81.7,1.6],PO3:[-33.3,-84.3,26.5],POZ:[0,-87.9,33.5],PO4:[35.2,-82.6,26.1],PO8:[43.3,-82,.7],O1:[-25.8,-93.3,7.7],OZ:[.3,-97.1,8.7],O2:[25,-95.2,6.2]};function setCoordinate(channelDict,assignTo={}){if(!eegCoordinates[channelDict.tag]&&channelDict.position){eegCoordinates[channelDict.tag]=[channelDict.position.x,channelDict.position.y,channelDict.position.z]}if(eegCoordinates[channelDict.tag]){let props={channel:"",position:{x:eegCoordinates[channelDict.tag][0],y:eegCoordinates[channelDict.tag][1],z:eegCoordinates[channelDict.tag][2]}};return Object.assign(assignTo,props)}else return Object.assign(assignTo,channelDict)}function EEGCoordinates(channelDicts=[],genCoherenceMap=true){let structs=[];for(let channelDict of channelDicts){let struct=EEGStruct(channelDict);structs.push(struct)}if(genCoherenceMap){structs.push(...CoherenceMap({channelDicts}))}return structs}function FrequencyBandsStruct(additionalBands=[],assignTo={}){let bands={scp:[],delta:[],theta:[],alpha1:[],alpha2:[],beta:[],lowgamma:[],highgamma:[]};additionalBands.forEach(band=>bands[band]=[]);return Object.assign(assignTo,bands)}function EEGStruct(tag="",assignProps={},parentUser={_id:""},parentStruct={structType:"struct",_id:""}){let bands=FrequencyBandsStruct();let props={tag,position:{x:0,y:0,z:0},count:0,times:[],raw:[],filtered:[],fftCount:0,fftTimes:[],ffts:[],slices:JSON.parse(JSON.stringify(bands)),means:JSON.parse(JSON.stringify(bands)),startTime:Date.now()};let struct=Struct("eeg",props,parentUser,parentStruct);if(tag)setCoordinate(props,struct);return Object.assign(struct,assignProps)}function CoherenceStruct(coords={0:EEGStruct("FP1"),1:EEGStruct("FP2")},assignProps={},parentUser={_id:""},parentStruct={structType:"struct",_id:""}){let bands=FrequencyBandsStruct();let props={tag:coords[0]?.tag+"::"+coords[1]?.tag,x0:coords[0]?.position?.x,y0:coords[0]?.position?.y,z0:coords[0]?.position?.z,x1:coords[1]?.position?.x,y1:coords[1]?.position?.y,z1:coords[1]?.position?.z,fftCount:0,fftTimes:[],ffts:[],slices:JSON.parse(JSON.stringify(bands)),means:JSON.parse(JSON.stringify(bands)),startTime:Date.now()};let struct=Struct("coherence",props,parentUser,parentStruct);return Object.assign(struct,assignProps)}function CoherenceMap(opts={channelDicts:[{ch:0,tag:"FP1",analyze:false},{ch:1,tag:"FP2",analyze:false}],taggedOnly:true},_={},parentUser={_id:""},parentStruct={structType:"struct",_id:""}){var cmap=[];var l=1,k=0;for(var i=0;i{if(!this.data.events[dataObj.timestamp])this.data.events[dataObj.timestamp]=[dataObj];else this.data.events[dataObj.timestamp].push(dataObj);if(dataObj.event==="sleep"){if(!this.data.sleep[dataObj.timestamp])this.data.sleep[dataObj.timestamp]=[dataObj];else this.data.sleep[dataObj.timestamp].push(dataObj)}return dataObj});this.setSort(["notes","note","link"],dataObj=>{if(!this.data.notes[dataObj.timestamp])this.data.notes[dataObj.timestamp]=[dataObj];else this.data.notes[dataObj.timestamp].push(dataObj);if(!this.data.byTime[dataObj.timestamp])this.data.byTime[dataObj.timestamp]=[dataObj];else this.data.byTime[dataObj.timestamp].push(dataObj);return dataObj});this.id=this.randomId("dataTablet")}randomId(tag=""){return`${tag+Math.floor(Math.random()+Math.random()*Math.random()*1e16)}`}setLocalData(structs){let setInCollection=s=>{let type=s.structType;let collection=this.collections.get(type);if(!collection){collection=new Map;this.collections.set(type,collection)}collection.set(s._id,s);this.onCollectionSet(type,collection)};if(Array.isArray(structs)){structs.forEach(s=>{setInCollection(s)})}else setInCollection(structs)}getLocalData(collection,query){let ownerId="";let key="";let value="";if(typeof query==="object"){ownerId=query.ownerId;const keys=Object.keys(query).filter(k=>k!="ownerId");key=keys[0];value=query[key]}else value=query;if(!collection&&!ownerId&&!key&&!value)return[];let result=[];if(!collection&&(ownerId||key)){this.collections.forEach(c=>{if((key==="_id"||key==="id")&&value){let found=c.get(value);if(found)result.push(found)}else{c.forEach(struct=>{if(key&&value){if(struct[key]===value&&struct.ownerId===ownerId){result.push(struct)}}else if(struct.ownerId===ownerId){result.push(struct)}})}});return result}else{let c=this.collections.get(collection);if(!c)return result;if(!key&&!ownerId){c.forEach(struct=>{result.push(struct)});return result}if((key==="_id"||key==="id")&&value)return c.get(value);else{c.forEach((struct,_)=>{if(key&&value&&!ownerId){if(struct[key]===value)result.push(struct)}else if(ownerId&&!key){if(struct.ownerId===ownerId)result.push(struct)}else if(ownerId&&key&&value){if(struct.ownerId===ownerId&&struct[key]){if(struct[key]===value)result.push(struct)}}})}}return result}onCollectionSet=(type,collection)=>{};runSort(key,dataObj={},newdata=[],tablet=this){let result;let sort=this.getSort(key);if(sort)result=sort(dataObj,newdata,tablet);else return false;return result}setSort(key,response=(data,newdata=[],tablet=this)=>{}){if(Array.isArray(key))key.forEach(k=>{this.dataSorts.set(k,response)});else this.dataSorts.set(key,response)}getSort(key){return this.dataSorts.get(key)}checkWatches(sorted={}){for(const prop in this.watches){let triggered=this.watches[prop].ondata(sorted,this.watches[prop].accum,this.watches[prop].ownerId);if(triggered){this.watches[prop].ontrigger(this.watches[prop].accum);this.watches[prop].triggered=false}}}setWatch(name,ownerId,ondata=(sorted,accum,ownerId2)=>{if(sorted.ownerId===ownerId2)accum.data[sorted._id]=sorted;if(Object.keys(accum.data).length>10){return true}else return false},ontrigger=accum=>{console.log(accum);let alert=Struct("alert",{alert:true,data:accum},{_id:accum[Object.keys(accum)[0]].ownerId});accum={}}){this.watches[name]={accum:{},ownerId,ondata,ontrigger}}getWatch(name){return this.watches[name]}async sortStructsIntoTable(datastructs=[]){let ascending=function(a,b){if(a.timestamp&&b.timestamp)return a.timestamp-b.timestamp};datastructs.sort(ascending);let newdata=[];for(let i=0;i{if(typeof dat==="object"&&!Array.isArray(dat)){let typ=dat.dataType;dat.ownerId=struct.ownerId;if(!dat.timestamp)dat.timestamp=timestamp;if(typ){let sorted=this.runSort(typ,dat,newdata,this);if(!sorted){if(!this.data[typ])this.data[typ]={};dat.timestamp=timestamp;if(!this.data[typ][timestamp])this.data[typ][timestamp]=[dat];else this.data[typ][timestamp].push(dat);if(!this.data.byTime[timestamp])this.data.byTime[timestamp]=[dat];else this.data.byTime[timestamp].push(dat);this.checkWatches(dat);this.onUpdate(timestamp,dat);newdata.push(dat)}else{if(sorted.constructor?.name!=="Promise"){this.checkWatches(sorted);this.onUpdate(timestamp,sorted);newdata.push(sorted)}}}}})}else{let sorted=this.runSort(struct.structType,struct,newdata,this);if(!sorted){let typ=struct.structType;if(!this.data[typ])this.data[typ]={};if(!this.data[typ][timestamp])this.data[typ][timestamp]=[struct];else this.data[typ][timestamp].push(struct);this.checkWatches(struct);this.onUpdate(timestamp,struct);newdata.push(struct)}else{this.checkWatches(sorted);this.onUpdate(timestamp,sorted);newdata.push(sorted)}}}for(const prop in this.data){this.data[prop]=this.sortObjectByPropName(this.data[prop])}this.onSorted(newdata)}onUpdate(_,__,___=this.data){}onSorted(_=[]){}getDataByTimestamp(timestamp,ownerId){let result=this.data.byTime[timestamp];if(ownerId&&result)result=result.filter(o=>{if(!ownerId)return true;else if(ownerId===o.ownerId)return true;else return false});return result}getDataByTimeRange(begin,end,type,ownerId){let result={};if(type){for(const key in this.data[type]){let t=parseInt(key);if(t>begin&&tbegin&&t{if(o.ownerId!==ownerId){popidx.push(i)}});popidx.reverse().forEach(idx=>{result[key].splice(idx,1)});if(result[key].length===0)delete result[key]}}return result}getDataByType(type,timestamp,ownerId){if(!this.data[type])return void 0;let result={...this.data[type]};if(timestamp)result=[...result[timestamp]];if(ownerId&&result){for(const key in result){let popidx=[];result[key]=[...result[key]];result[key].forEach((o,i)=>{if(o.ownerId!==ownerId){popidx.push(i)}});popidx.reverse().forEach(idx=>{result[key].splice(idx,1)});if(result[key].length===0)delete result[key]}}if(type==="sleep"){result=this.filterSleepResults(result)}return result}filterSleepResults(unfiltered={}){let events=[];for(const key in unfiltered){unfiltered[key]=[...unfiltered[key]];events.push(...unfiltered[key].filter(o=>{if(o.structType==="event")return true;else return false}))}events.forEach(ev2=>{let foundidx;for(const key in unfiltered){unfiltered[key].forEach((o,i)=>{if(o.structType==="fitbitsleep"&&ev2.startTime&&ev2.endTime){if(Math.abs(o.startTime-ev2.startTime)<1e3*12*3600&&Math.abs(o.endTime-ev2.endTime)<1e3*12*3600&&ev2.endTime-ev2.startTime>1e3*2*3600){foundidx=i;return true}else return false}else return false});if(foundidx)unfiltered[key].splice(foundidx,1)}});let result=unfiltered;return result}sortObjectByPropName(object){const ordered=Object.keys(object).sort().reduce((obj,key)=>{obj[key]=object[key];return obj},{});return ordered}checkRollover(collection,limit=this.rolloverLimit){if(!collection)return false;let c=this.collections.get(collection);if(!c)return false;c.forEach(struct=>{for(const prop in struct){if(Array.isArray(struct[prop])){if(struct[prop].length>limit){struct[prop].slice(struct[prop].length-limit);if(prop==="ffts"){struct.fftCount=struct[prop].length}else if(prop==="times"){struct.count=struct[prop].length}}}else if(typeof struct[prop]==="object"){this.checkRollover(struct[prop])}}});return true}};var defaultSpecifiers=["now","minute","5 minutes","30 minutes","hour","6 hours","12 hours","day","3 days","week","2 weeks","month","6 months","year","5 years","decade"];function genTimeSpecifiers(specifiers=defaultSpecifiers){let result=["now"];specifiers.forEach(s=>{if(s!=="now")result.push(`last ${s}`);else result.push(s)});return result}function genTimestampFromString(specifier){const now=new Date;if(specifier==="now"){}else if(specifier==="last minute"){now.setMinutes(now.getMinutes()-1)}else if(specifier==="last hour"){now.setHours(now.getHours()-1)}else if(specifier==="last day"){now.setDate(now.getDate()-1)}else if(specifier==="last week"){now.setDate(now.getDate()-7)}else if(specifier==="last month"){now.setMonth(now.getMonth()-1)}else if(specifier==="last year"){now.setFullYear(now.getFullYear()-1)}else if(specifier==="last decade"){now.setFullYear(now.getFullYear()-1*10)}else if(specifier==="last century"){now.setFullYear(now.getFullYear()-1*100)}else if(specifier==="last millennium"){now.setFullYear(now.getFullYear()-1*1e3)}else if(specifier==="last microsecond"){now.setMilliseconds(now.getMilliseconds()-1)}else if(specifier==="last nanosecond"){now.setMilliseconds(now.getMilliseconds()-1*.001)}else if(specifier.startsWith("last")){const[,count,unit]=specifier.match(/last (\d+) (\w+)/)||[];if(count&&unit){const num=parseInt(count,10);if(unit.includes("minute")){now.setMinutes(now.getMinutes()-num)}else if(unit.includes("hour")){now.setHours(now.getHours()-num)}else if(unit.includes("day")){now.setDate(now.getDate()-num)}else if(unit.includes("week")){now.setDate(now.getDate()-num*7)}else if(unit.includes("month")){now.setMonth(now.getMonth()-num)}else if(unit.includes("year")){now.setFullYear(now.getFullYear()-num)}else if(unit.includes("decade")){now.setFullYear(now.getFullYear()-num*10)}else if(unit.includes("century")){now.setFullYear(now.getFullYear()-num*100)}else if(unit.includes("millennium")){now.setFullYear(now.getFullYear()-num*1e3)}else if(unit.includes("microsecond")){now.setMilliseconds(now.getMilliseconds()-num)}else if(unit.includes("nanosecond")){now.setMilliseconds(now.getMilliseconds()-num*.001)}}}return now.getTime()}var EventHandler=class{data={};triggers={};ctr=0;constructor(data){if(typeof data==="object")this.data=data}setState=updateObj=>{Object.assign(this.data,updateObj);let props=Object.getOwnPropertyNames(updateObj);for(const prop of props){this.triggerEvent(prop,this.data[prop])}if(this.triggers[statesubKey]){let run=fn=>{fn(updateObj)};const l=this.triggers[statesubKey].length;for(let i=l-1;i>=0;i--){run(this.triggers[statesubKey][i].onchange)}}return this.data};setValue=(key,value)=>{this.data[key]=value;this.triggerEvent(key,value)};triggerEvent=(key,value)=>{if(this.triggers[key]){let fn=obj=>{obj.onchange(value)};const l=this.triggers[key].length;for(let i=l-1;i>=0;i--){fn(this.triggers[key][i])}}};subscribeState=onchange=>{return this.subscribeEvent(statesubKey,onchange)};unsubscribeState=sub=>{return this.unsubscribeEvent(statesubKey,sub)};subscribeEvent=(key,onchange,refObject,refKey)=>{if(key){if(refObject&&refKey&&!this.triggers[key]){Object.defineProperty(this.data,key,{get:()=>{return refObject[refKey]},set:value=>{refObject[refKey]=value},enumerable:true,configurable:true})}if(!this.triggers[key]){this.triggers[key]=[]}let l=this.ctr;this.ctr++;this.triggers[key].push({sub:l,onchange});return l}else return void 0};unsubscribeEvent=(key,sub)=>{let triggers=this.triggers[key];if(triggers){if(sub===void 0){delete this.triggers[key];delete this.data[key]}else{let idx=void 0;let obj=triggers.find((o,i)=>{if(o.sub===sub){idx=i;return true}});if(obj)triggers.splice(idx,1);if(Object.keys(triggers).length===0){delete this.triggers[key];delete this.data[key]}if(this.onRemoved)this.onRemoved(obj);return true}}};subscribeEventOnce=(key,onchange)=>{let sub;let changed=value=>{onchange(value);this.unsubscribeEvent(key,sub)};sub=this.subscribeEvent(key,changed);return sub};getEvent=(key,sub)=>{if(typeof sub!=="number")return this.triggers[key];for(const s in this.triggers[key]){if(this.triggers[key][s].sub===sub)return this.triggers[key][s]}};getSnapshot=()=>{const snapshot={};for(const key in this.data){snapshot[key]=this.data[key]}};onRemoved};var statesubKey="*s";var state=new EventHandler;var Callable=class extends Function{__bound;__call;constructor(){super("return this.__bound.__call.apply(this.__bound, arguments)");this.__bound=this.bind(this);return this.__bound}};var GraphNode=class _GraphNode{__node={tag:`node${Math.floor(Math.random()*1e15)}`,unique:`${Math.floor(Math.random()*1e15)}`,state};__children;__parent;__operator;__listeners;__props;__args;constructor(properties,parent,graph){this.__setProperties(properties,parent,graph);if(typeof properties==="function"||properties?.__callable){const callableInstance=new Callable;callableInstance.__call=(...args)=>this.__operator(...args);const proxy=new Proxy(callableInstance,{get:(target,prop,receiver)=>{if(Reflect.has(this,prop)){return Reflect.get(this,prop,receiver)}return Reflect.get(target,prop,receiver)},set:(target,prop,value,receiver)=>{if(Reflect.has(this,prop)){return Reflect.set(this,prop,value,receiver)}return Reflect.set(target,prop,value,receiver)}});Object.setPrototypeOf(proxy,this);return proxy}}get __graph(){return this.__node?.graph}set __graph(graph){this.__node.graph=graph}__setProperties=(properties,parent,graph)=>{let enforceProperties=()=>{let orig=properties;if(typeof properties==="function"){if(isNativeClass(properties)){properties=new properties}else properties={__operator:properties,__node:{forward:true,tag:properties.name}}}else if(typeof properties==="string"){if(graph?.get(properties)){properties=graph.get(properties)}}if(!("__node"in properties))properties.__node={};if(!properties.__node.initial)properties.__node.initial=orig};enforceProperties();if(typeof properties==="object"){let assignState=()=>{if(properties.__node?.state)this.__node.state=properties.__node.state;else if(graph){properties.__node.state=graph.__node.state}};let setProps=()=>{if(properties.__props){if(typeof properties.__props==="function")properties.__props=new properties.__props;if(typeof properties.__props==="object"){this.__proxyObject(properties.__props)}}};let setTag=()=>{if(!properties.__node.tag){if(properties.__operator?.name)properties.__node.tag=properties.__operator.name;else properties.__node.tag=`node${Math.floor(Math.random()*1e15)}`}};let setNode=()=>{if(typeof properties.__node==="string"){if(graph?.get(properties.__node.tag)){properties=graph.get(properties.__node.tag)}else properties.__node={}}else if(!properties.__node)properties.__node={};if(graph){properties.__node.graph=graph}if(properties instanceof Graph)properties.__node.source=properties};let setParent=()=>{if(!properties.__parent&&parent)properties.__parent=parent;if(parent?.__node&&!(parent instanceof Graph||properties instanceof Graph))properties.__node.tag=parent.__node.tag+"."+properties.__node.tag;if(parent instanceof Graph&&properties instanceof Graph){if(properties.__node.loaders)Object.assign(parent.__node.loaders?parent.__node.loaders:{},properties.__node.loaders);if(parent.__node.mapGraphs){properties.__node.nodes.forEach(n=>{parent.set(properties.__node.tag+"."+n.__node.tag,n)});let ondelete=()=>{properties.__node.nodes.forEach(n=>{parent.__node.nodes.delete(properties.__node.tag+"."+n.__node.tag)})};this.__addOndisconnected(ondelete)}}};let setOp=()=>{if(typeof properties.default==="function"&&!properties.__operator){properties.__operator=properties.default}if(properties.__operator){if(typeof properties.__operator==="string"){if(graph){let n=graph.get(properties.__operator);if(n)properties.__operator=n.__operator;if(!properties.__node.tag&&properties.__operator.name)properties.__node.tag=properties.__operator.name}}if(typeof properties.__operator==="function")properties.__operator=this.__setOperator(properties.__operator);if(properties.default)properties.default=properties.__operator}};let assignProps=()=>{properties.__node=Object.assign(this.__node,properties.__node);let keys=Object.getOwnPropertyNames(properties).filter(v2=>{if(!objProps[v2])return true});for(const key of keys){if(key in properties&&key!=="name")this[key]=properties[key]}};let bindCallbacks=()=>{if(this.__onconnected){if(typeof this.__onconnected==="function"){this.__onconnected=this.__onconnected.bind(this)}else if(Array.isArray(this.__onconnected)){this.__onconnected=this.__onconnected.map(f=>{return f.bind(this)})}if(typeof this.__ondisconnected==="function"){this.__ondisconnected=this.__ondisconnected.bind(this)}else if(Array.isArray(this.__ondisconnected)){this.__ondisconnected=this.__ondisconnected.map(f=>{return f.bind(this)})}}};assignState();setTag();setProps();setNode();setParent();assignProps();bindCallbacks();setOp()}};__subscribe=(callback,key,subInput,target,tkey,args,callbackStr)=>{const subscribeToFunction=(k,setTarget=(callback2,target2)=>target2?target2:callback2,triggerCallback=callback)=>{let wrappedArgs;if(args){let wrapped=wrapArgs(triggerCallback,args,this.__node.graph);triggerCallback=wrapped.__callback;wrappedArgs=wrapped.__args}let sub=this.__node.state.subscribeEvent(k,triggerCallback,this,key);let trigger=this.__node.state.getEvent(k,sub);if(!this.__listeners)this.__listeners={};this.__listeners[k]=this.__node.state.triggers[k];if(!trigger)return sub;trigger.source=this.__node.tag;if(key)trigger.key=key;trigger.target=setTarget(callback,target);if(tkey)trigger.tkey=tkey;if(subInput)trigger.subInput=subInput;if(args){trigger.arguments=wrappedArgs;trigger.__args=args}if(callbackStr)trigger.__callback=callbackStr;trigger.node=this;trigger.graph=this.__node.graph;return sub};const getCallbackFromGraph=callback2=>{let fn=this.__node.graph.get(callback2);if(!fn&&callback2.includes(".")){target=callback2.substring(0,callback2.lastIndexOf("."));let n=this.__node.graph.get(callback2.substring(0,target));tkey=callback2.lastIndexOf(".")+1;if(n&&typeof n[key]==="function")callback2=(...args2)=>{return n[tkey](...args2)}}else if(fn.__operator){callback2=fn.__operator;tkey="__operator"}return callback2};if(key){if(!this.__node.localState||!this.__node.localState[key]){this.__addLocalState(this,key)}if(typeof callback==="string"){callbackStr=this.__node.tag+"."+callback;tkey=callback;if(target){if(this.__node.graph?.get(target)){let n=this.__node.graph?.get(target);if(typeof n[callback]==="function"){let fn=n[callback];callback=(...inp)=>{fn(...inp)}}else{let k2=callback;let setter=inp=>{n[k2]=inp};callback=setter}}}else if(typeof this[callback]==="function"){let fn=this[callback];callback=(...inp)=>{fn(...inp)}}else if(this.__node.graph?.get(callback))callback=getCallbackFromGraph(callback);if(typeof callback!=="function")return void 0}let sub;let k=subInput?this.__node.unique+"."+key+"input":this.__node.unique+"."+key;if(typeof callback==="function"&&!callback?.__node)sub=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2,callback);else if(callback?.__node)sub=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2.__node.unique,(...inp)=>{if(callback.__operator)callback.__operator(...inp)});return sub}else{if(typeof callback==="string"){callbackStr=callback;if(!target)target=callback;if(this.__node.graph.get(callback))callback=this.__node.graph.get(callback);tkey="__operator";if(typeof callback!=="object")return void 0}let sub;let k=subInput?this.__node.unique+"input":this.__node.unique;if(typeof callback==="function"&&!callback?.__node)sub=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2,callback);else if(callback?.__node){sub=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2.__node.unique,(...inp)=>{if(callback.__operator)callback.__operator(...inp)})}return sub}};__unsubscribe=(sub,key,unsubInput)=>{if(key){return this.__node.state.unsubscribeEvent(unsubInput?this.__node.unique+"."+key+"input":this.__node.unique+"."+key,sub)}else return this.__node.state.unsubscribeEvent(unsubInput?this.__node.unique+"input":this.__node.unique,sub)};__setOperator=fn=>{fn=fn.bind(this);if(this.__args&&this.__node.graph){fn=wrapArgs(fn,this.__args,this.__node.graph).__callback}let inpstr=`${this.__node.unique}input`;this.__operator=(...args)=>{if(this.__node.state.triggers[inpstr])this.__node.state.setValue(inpstr,args);let result=fn(...args);if(this.__node.state.triggers[this.__node.unique]){if(typeof result?.then==="function"){result.then(res=>{if(res!==void 0)this.__node.state.setValue(this.__node.unique,res)}).catch(console.error)}else if(result!==void 0)this.__node.state.setValue(this.__node.unique,result)}return result};if(this.__parent instanceof _GraphNode&&!this.__subscribedToParent){if(this.__parent.__operator){let sub=this.__parent.__subscribe(this);let ondelete=()=>{this.__parent?.__unsubscribe(sub);delete this.__subscribedToParent};this.__addOndisconnected(ondelete);this.__subscribedToParent=true}}return this.__operator};__addLocalState=(props,key)=>{if(!props)return;if(!this.__node.localState){this.__node.localState={}}const localState=this.__node.localState;const initState=(props2,k)=>{let str2=this.__node.unique+"."+k;let inpstr=`${str2}input`;let get,set;let obj,descriptor;if(typeof props2[k]==="function"&&k!=="__operator"){if(this.__props?.[k]){obj=this.__props}else{obj=localState}get=()=>{return obj[k]};set=fn=>{if(!this.__props?.[k])fn=fn.bind(this);obj[k]=(...args)=>{if(this.__node.state.triggers[inpstr])this.__node.state.setValue(inpstr,args);let result=fn(...args);if(this.__node.state.triggers[str2]){if(typeof result?.then==="function"){result.then(res=>{this.__node.state.triggerEvent(str2,res)}).catch(console.error)}else this.__node.state.triggerEvent(str2,result)}return result}};localState[k]=props2[k].bind(this);descriptor={get,set,enumerable:true,configurable:true}}else if(k!=="__graph"){let get2,set2;let obj2;if(this.__props?.[k]){obj2=this.__props}else{obj2=localState}get2=()=>{return obj2[k]};set2=v2=>{obj2[k]=v2;if(this.__node.state.triggers[str2])this.__node.state.triggerEvent(str2,v2)};localState[k]=props2[k];descriptor={get:get2,set:set2,enumerable:true,configurable:true}}Object.defineProperty(props2,k,descriptor);if(typeof this.__node.initial==="object"){let dec=Object.getOwnPropertyDescriptor(this.__node.initial,k);if(dec===void 0||dec?.configurable){Object.defineProperty(this.__node.initial,k,descriptor)}}};if(key)initState(props,key);else{for(let k in props){initState(props,k)}}};__proxyObject=obj=>{const allProps=getAllProperties(obj);for(const k of allProps){const descriptor={get:()=>{return obj[k]},set:value=>{obj[k]=value},enumerable:true,configurable:true};Object.defineProperty(this,k,descriptor);if(typeof this.__node.initial==="object"){let dec=Object.getOwnPropertyDescriptor(this.__node.initial,k);if(dec===void 0||dec?.configurable){Object.defineProperty(this.__node.initial,k,descriptor)}}}};__addOnconnected(callback){callback=callback.bind(this);if(Array.isArray(this.__onconnected)){this.__onconnected.push(callback)}else if(typeof this.__onconnected==="function"){this.__onconnected=[callback,this.__onconnected]}else this.__onconnected=callback}__addOndisconnected(callback){callback=callback.bind(this);if(Array.isArray(this.__ondisconnected)){this.__ondisconnected.push(callback)}else if(typeof this.__ondisconnected==="function"){this.__ondisconnected=[callback,this.__ondisconnected]}else this.__ondisconnected=callback}__callConnected(node=this){if(typeof this.__onconnected==="function"){this.__onconnected(this)}else if(Array.isArray(this.__onconnected)){let fn=o=>{o(this)};this.__onconnected.forEach(fn)}}__callDisconnected(node=this){if(typeof this.__ondisconnected==="function")this.__ondisconnected(this);else if(Array.isArray(this.__ondisconnected)){let fn=o=>{o(this)};this.__ondisconnected.forEach(fn)}}};var Graph=class _Graph{__node={tag:`graph${Math.floor(Math.random()*1e15)}`,unique:`${Math.random()}`,nodes:new Map,state,roots:{}};constructor(options){this.init(options)}init=options=>{if(options){let cpy=Object.assign({},options);delete cpy.roots;recursivelyAssign(this.__node,cpy);if(options.roots)this.load(options.roots)}};load=(roots,overwrite=false)=>{function recursivelyAssignChildren(target,obj,inChildren=true,top=true){if(top){if(!target)target={};for(const key in obj){if(!key.startsWith("__")&&obj[key]&&typeof obj[key]==="object"){target[key]=obj[key];if(obj[key]?.__children){recursivelyAssignChildren({},obj[key].__children,false,false)}}else if(typeof obj[key]==="function")target[key]=obj[key]}recursivelyAssignChildren(target,obj,true,false)}else{if(obj?.__children&&!inChildren){if(obj.__children?.constructor.name==="Object"){if(target.__children?.constructor.name==="Object")target.__children=recursivelyAssignChildren(target.__children,obj.__children,true,false);else target.__children=recursivelyAssignChildren({},obj.__children,true,false)}else{target.__children=obj.__children}}else if(inChildren){for(const key in obj){if(!key.startsWith("__")&&obj[key]&&typeof obj[key]==="object"){target[key]=Object.assign({},obj[key]);if(obj[key]?.__children){target[key].__children=recursivelyAssignChildren({},obj[key].__children,false,false)}}else if(typeof obj[key]==="function")target[key]=obj[key]}}}return target}this.__node.roots=recursivelyAssignChildren(this.__node.roots?this.__node.roots:{},roots);let cpy=Object.assign({},roots);if(cpy.__node)delete cpy.__node;let listeners=this.recursiveSet(cpy,this,void 0,roots,overwrite);if(roots.__node){if(!roots.__node.tag)roots.__node._tag=`roots${Math.floor(Math.random()*1e15)}`;else if(!this.get(roots.__node.tag)){let node=new GraphNode(roots,this,this);this.set(node.__node.tag,node);this.runLoaders(node,this,roots,roots.__node.tag);if(node.__listeners){listeners[node.__node.tag]=node.__listeners}}}else if(roots.__listeners){this.setListeners(roots.__listeners)}this.setListeners(listeners);return cpy};setLoaders=(loaders2,replace)=>{if(replace)this.__node.loaders=loaders2;else Object.assign(this.__node.loaders,loaders2);return this.__node.loaders};runLoaders=(node,parent,properties,key)=>{for(const l in this.__node.loaders){if(typeof this.__node.loaders[l]==="object"){if(this.__node.loaders[l].init)this.__node.loaders[l](node,parent,this,this.__node.roots,properties,key);if(this.__node.loaders[l].connected)node.__addOnconnected(this.__node.loaders[l].connect);if(this.__node.loaders[l].disconnected)node.__addOndisconnected(this.__node.loaders[l].disconnect)}else if(typeof this.__node.loaders[l]==="function")this.__node.loaders[l](node,parent,this,this.__node.roots,properties,key)}};add=(properties,parent,overwrite=true)=>{let listeners={};if(typeof parent==="string")parent=this.get(parent);let instanced;if(typeof properties==="function"){if(isNativeClass(properties)){if(properties.prototype instanceof GraphNode){properties=properties.prototype.constructor(properties,parent,this);instanced=true}else properties=new properties}else properties={__operator:properties,__callable:true}}else if(typeof properties==="string"){properties=this.__node.roots[properties]}if(!properties)return;if(!instanced){let keys=Object.getOwnPropertyNames(properties);let nonArrowFunctions=Object.getOwnPropertyNames(Object.getPrototypeOf(properties));keys.push(...nonArrowFunctions);keys=keys.filter(v2=>!objProps.includes(v2));let cpy={};for(const key of keys){cpy[key]=properties[key]}properties=cpy}if(!properties.__node)properties.__node={};properties.__node.initial=properties;if(typeof properties==="object"&&this.get(properties.__node.tag)){if(overwrite)this.remove(properties.__node.tag,true);else return}else if(properties.__node.tag&&this.get(properties.__node.tag))return this.get(properties.__node.tag);let node;let root=recursivelyAssign({},properties,2);if(instanced)node=properties;else node=new GraphNode(properties,parent,this);this.set(node.__node.tag,node);this.runLoaders(node,parent,properties,node.__node.tag);this.__node.roots[node.__node.tag]=root;if(node.__children){node.__children=Object.assign({},node.__children);this.recursiveSet(node.__children,node,listeners,node.__children)}if(node.__listeners){listeners[node.__node.tag]=Object.assign({},node.__listeners);for(const key in node.__listeners){let listener=node.__listeners[key];if(node[key]){delete listeners[node.__node.tag][key];listeners[node.__node.tag][node.__node.tag+"."+key]=listener}if(typeof listener==="string"){if(node.__children?.[listener]){listeners[node.__node.tag][key]=node.__node.tag+"."+listener}else if(parent instanceof GraphNode&&(parent.__node.tag===listener||parent.__node.tag.includes(".")&&parent.__node.tag.split(".").pop()===listener)){listeners[node.__node.tag][key]=parent.__node.tag}}}}this.setListeners(listeners);node.__callConnected();return node};recursiveSet=(originCpy,parent,listeners={},origin,overwrite=false)=>{let keys=Object.getOwnPropertyNames(origin).filter(v2=>!objProps.includes(v2));let nonArrowFunctions=Object.getOwnPropertyNames(Object.getPrototypeOf(origin)).filter(v2=>!objProps.includes(v2));keys.push(...nonArrowFunctions);for(const key of keys){if(key.includes("__"))continue;let p2=origin[key];if(Array.isArray(p2))continue;let instanced;if(typeof p2==="function"){if(isNativeClass(p2)){p2=new p2;if(p2 instanceof GraphNode){p2=p2.prototype.constructor(p2,parent,this);instanced=true}}else p2={__operator:p2,__callable:true}}else if(typeof p2==="string"){if(this.__node.nodes.get(p2))p2=this.__node.nodes.get(p2);else p2=this.__node.roots[p2]}else if(typeof p2==="boolean"){if(this.__node.nodes.get(key))p2=this.__node.nodes.get(key);else p2=this.__node.roots[key]}if(p2&&typeof p2==="object"){if(!instanced&&!(p2 instanceof GraphNode)){let ks=Object.getOwnPropertyNames(p2).filter(v2=>!objProps.includes(v2));let nonArrowFunctions2=Object.getOwnPropertyNames(Object.getPrototypeOf(p2)).filter(v2=>!objProps.includes(v2));nonArrowFunctions2.splice(nonArrowFunctions2.indexOf("constructor"),1);ks.push(...nonArrowFunctions2);let cpy={};for(const key2 of ks){cpy[key2]=p2[key2]}p2=cpy}if(!p2.__node)p2.__node={};if(!p2.__node.tag)p2.__node.tag=key;if(!p2.__node.initial)p2.__node.initial=originCpy[key];if(overwrite&&this.get(p2.__node.tag)){this.remove(p2.__node.tag,true)}else if(this.get(p2.__node.tag)&&!(!(parent instanceof _Graph)&&parent?.__node)||parent?.__node&&this.get(parent.__node.tag+"."+p2.__node.tag))continue;let node;let newnode=false;let root=recursivelyAssign({},p2,2);if(instanced||p2 instanceof GraphNode){node=p2}else{node=new GraphNode(p2,parent,this);newnode=true}if(!newnode&&p2 instanceof GraphNode&&!instanced&&parent instanceof GraphNode){let sub=this.subscribe(parent.__node.tag,node.__node.tag);let ondelete=node2=>{this.unsubscribe(parent.__node.tag,sub)};node.__addOndisconnected(ondelete)}else if(node){this.set(node.__node.tag,node);this.runLoaders(node,parent,originCpy[key],key);originCpy[key]=node;this.__node.roots[node.__node.tag]=root;if(node.__children){node.__children=Object.assign({},node.__children);this.recursiveSet(node.__children,node,listeners,node.__children)}if(node.__listeners){listeners[node.__node.tag]=Object.assign({},node.__listeners);for(const key2 in node.__listeners){let listener=node.__listeners[key2];let k=key2;if(node[key2]){delete listeners[node.__node.tag][key2];k=node.__node.tag+"."+key2;listeners[node.__node.tag][k]=listener}if(typeof listener==="string"){if(node.__children?.[listener]){listeners[node.__node.tag][k]=node.__node.tag+"."+listener}else if(parent instanceof GraphNode&&(parent.__node.tag===listener||parent.__node.tag.includes(".")&&parent.__node.tag.split(".").pop()===listener)){listeners[node.__node.tag][k]=parent.__node.tag}}}}node.__callConnected()}}}return listeners};remove=(node,clearListeners=true)=>{this.unsubscribe(node);if(typeof node==="string")node=this.get(node);if(node instanceof GraphNode){this.delete(node.__node.tag);delete this.__node.roots[node.__node.tag];if(clearListeners){this.clearListeners(node)}node.__callDisconnected();const recursiveRemove=t=>{for(const key in t){this.unsubscribe(t[key]);this.delete(t[key].__node.tag);delete this.__node.roots[t[key].__node.tag];this.delete(key);delete this.__node.roots[key];t[key].__node.tag=t[key].__node.tag.substring(t[key].__node.tag.lastIndexOf(".")+1);if(clearListeners){this.clearListeners(t[key])}t[key].__callDisconnected();if(t[key].__children){recursiveRemove(t[key].__children)}}};if(node.__children){recursiveRemove(node.__children)}}if(node?.__node.tag&&node?.__parent){delete node?.__parent;node.__node.tag=node.__node.tag.substring(node.__node.tag.indexOf(".")+1)}if(node?.__node.graph)node.__node.graph=void 0;return node};run=(node,...args)=>{if(typeof node==="string"){let nd=this.get(node);if(!nd&&node.includes(".")){nd=this.get(node.substring(0,node.lastIndexOf(".")));if(typeof nd?.[node.substring(node.lastIndexOf(".")+1)]==="function")return nd[node.substring(node.lastIndexOf(".")+1)](...args)}else if(nd?.__operator)return nd.__operator(...args)}if(node?.__operator){return node?.__operator(...args)}};setListeners=listeners=>{for(const key in listeners){let node=this.get(key);if(typeof listeners[key]==="object"){for(const k in listeners[key]){let n=this.get(k);let sub;if(typeof listeners[key][k]!=="object")listeners[key][k]={__callback:listeners[key][k]};else if(!listeners[key][k].__callback){for(const kk in listeners[key][k]){if(typeof listeners[key][k][kk]!=="object"){listeners[key][k][kk]={__callback:listeners[key][k][kk]};if(node.__operator&&(listeners[key][k][kk].__callback===true||typeof listeners[key][k][kk].__callback==="undefined"))listeners[key][k][kk].__callback=node.__operator}let nn=this.get(kk);if(!nn){let tag=k.substring(0,k.lastIndexOf("."));nn=this.get(tag);if(nn){let prop=k.substring(k.lastIndexOf(".")+1);sub=this.subscribe(nn,listeners[key][k][kk].__callback,listeners[key][k][kk].__args,prop,listeners[key][k][kk].subInput,key)}}else{sub=this.subscribe(nn,listeners[key][k][kk].__callback,listeners[key][k][kk].__args,void 0,listeners[key][k][kk].subInput,key)}}}if("__callback"in listeners[key][k]){if(node){if(listeners[key][k].__callback===true||typeof listeners[key][k].__callback==="undefined")listeners[key][k].__callback=node.__operator;if(typeof listeners[key][k].__callback==="function")listeners[key][k].__callback=listeners[key][k].__callback.bind(node)}if(!n){let tag=k.substring(0,k.lastIndexOf("."));n=this.get(tag);if(n){sub=this.subscribe(n,listeners[key][k].__callback,listeners[key][k].__args,k.substring(k.lastIndexOf(".")+1),listeners[key][k].subInput,key)}}else{sub=this.subscribe(n,listeners[key][k].__callback,listeners[key][k].__args,void 0,listeners[key][k].subInput,key)}}}}}};clearListeners=(node,listener)=>{if(typeof node==="string")node=this.get(node);if(node?.__listeners){for(const key in node.__listeners){if(listener&&key!==listener)continue;if(typeof node.__listeners[key]?.sub!=="number")continue;let n=this.get(key);if(!n){n=this.get(key.substring(0,key.lastIndexOf(".")));if(n){if(typeof node.__listeners[key]==="object"&&!node.__listeners[key]?.__callback){for(const k in node.__listeners[key]){if(typeof node.__listeners[key][k]?.sub==="number"){this.unsubscribe(n,node.__listeners[key][k].sub,key.substring(key.lastIndexOf(".")+1),node.__listeners[key][k].subInput);node.__listeners[key][k].sub=void 0}}}else if(typeof node.__listeners[key]?.sub==="number"){this.unsubscribe(n,node.__listeners[key].sub,key.substring(key.lastIndexOf(".")+1),node.__listeners[key].subInput);node.__listeners[key].sub=void 0}}}else{if(typeof!node.__listeners[key]?.__callback==="number"){for(const k in node.__listeners[key]){if(node.__listeners[key][k]?.sub){this.unsubscribe(n,node.__listeners[key][k].sub,void 0,node.__listeners[key][k].subInput);node.__listeners[key][k].sub=void 0}}}else if(typeof node.__listeners[key]?.sub==="number"){this.unsubscribe(n,node.__listeners[key].sub,void 0,node.__listeners[key].subInput);node.__listeners[key].sub=void 0}}}}};get=tag=>{return this.__node.nodes.get(tag)};getByUnique=unique=>{return Array.from(this.__node.nodes.values()).find(node=>{if(node.__node.unique===unique)return true})};set=(tag,node)=>{return this.__node.nodes.set(tag,node)};delete=tag=>{return this.__node.nodes.delete(tag)};list=()=>{return Array.from(this.__node.nodes.keys())};getListener=(nodeTag,key,sub)=>{let node=this.get(nodeTag);if(node){let k=node.__node.unique;if(key){k+="."+key}return this.__node.state.getEvent(k,sub)}};getProps=(node,getInitial)=>{if(typeof node==="string")node=this.get(node);if(node instanceof GraphNode){let cpy;if(getInitial)cpy=Object.assign({},this.__node.roots[node.__node.tag]);else{cpy=Object.assign({},node);for(const key in cpy){if(key.includes("__"))delete cpy[key]}}}};subscribe=(nodeEvent,onEvent,args,key,subInput,target,tkey)=>{let nd=nodeEvent;if(typeof nodeEvent==="string"){nd=this.get(nodeEvent);if(!nd&&nodeEvent.includes(".")){nd=this.get(nodeEvent.substring(0,nodeEvent.lastIndexOf(".")));key=nodeEvent.substring(nodeEvent.lastIndexOf(".")+1)}}if(target instanceof GraphNode)target=target.__node.tag;let callbackStr;if(typeof onEvent==="string"){callbackStr=onEvent;let setOnEventFromString=onEvent2=>{if(this.get(onEvent2)?.__operator){let node=this.get(onEvent2);target=onEvent2;onEvent2=function(...inp){return node.__operator(...inp)}}else if(onEvent2.includes(".")){target=onEvent2.substring(0,onEvent2.lastIndexOf("."));let n=this.get(target);let k=onEvent2.substring(onEvent2.lastIndexOf(".")+1);tkey=k;if(typeof n[k]==="function"){if(n[k]instanceof GraphNode)onEvent2=n[k];else onEvent2=function(...inp){return n[k](...inp)}}else{onEvent2=function(inp){n[k]=inp;return n[k]}}}return onEvent2};if(target){let node=this.get(target);if(typeof node?.[onEvent]==="function"){tkey=onEvent;onEvent=function(...inp){return node[key](...inp)}}else if(node?.[key]){tkey=key;if(node[key]instanceof GraphNode)onEvent=node[key];else onEvent=function(inp){node[key]=inp;return node[key]}}else{onEvent=setOnEventFromString(onEvent)}}else{onEvent=setOnEventFromString(onEvent)}}let sub;if(nd instanceof GraphNode){const doSub=()=>{sub=nd.__subscribe(onEvent,key,subInput,target,tkey,args,callbackStr);let ondelete=()=>{if(sub!==void 0)nd.__unsubscribe(sub,key,subInput);sub=void 0};nd.__addOndisconnected(()=>{ondelete();nd.__addOnconnected(()=>{if(sub===void 0&&nd.__node.graph.__node.tag===this.__node.tag)doSub()})});if(typeof onEvent==="string"&&this.get(onEvent))onEvent=this.get(onEvent);if(onEvent instanceof GraphNode){onEvent.__addOndisconnected(()=>{ondelete()})}};doSub()}else if(typeof nodeEvent==="string"){let node=this.get(nodeEvent);if(node){if(onEvent instanceof GraphNode&&onEvent.__operator){const doSub=()=>{sub=node.__subscribe(onEvent.__operator,key,subInput,target,tkey,args,callbackStr);let ondelete=()=>{if(sub!==void 0)node.__unsubscribe(sub,key,subInput)};node.__addOndisconnected(()=>{ondelete();node.__addOnconnected(()=>{if(sub===void 0&&node.__node.graph.__node.tag===this.__node.tag)doSub()})});onEvent.__addOndisconnected(ondelete)};doSub()}else if(typeof onEvent==="function"||typeof onEvent==="string"){const doSub=()=>{sub=node.__subscribe(onEvent,key,subInput,target,tkey,args,callbackStr);let ondelete=()=>{if(sub!==void 0)node.__unsubscribe(sub,key,subInput);sub=void 0};node.__addOndisconnected(()=>{ondelete();node.__addOnconnected(()=>{if(sub===void 0&&node.__node.graph.__node.tag===this.__node.tag)doSub()})});if(typeof onEvent==="string"&&this.get(onEvent))this.get(onEvent).__addOndisconnected(ondelete)};doSub()}}else{if(typeof onEvent==="string")onEvent=this.__node.nodes.get(onEvent).__operator;if(typeof onEvent==="function"&&!onEvent?.__node)sub=this.__node.state.subscribeEvent(nodeEvent,onEvent)}}return sub};unsubscribe=(node,sub,key,subInput)=>{if(node instanceof GraphNode){return node.__unsubscribe(sub,key,subInput)}else return this.get(node)?.__unsubscribe(sub,key,subInput)};setState=update=>{this.__node.state.setState(update)}};function recursivelyAssign(target,obj,maxDepth=Infinity,curDepth=0){for(const key in obj){if(obj[key]?.constructor.name==="Object"&&curDepth{if(graph.get(a)?.__operator){let node=graph.get(a);return(...inp)=>{node.__operator(...inp)}}else if(a.includes(".")){let split=a.split(".");let popped=split.pop();let joined=split.join(".");let node=graph.get(joined);if(typeof graph.get(joined)?.[popped]==="function"){return(...inp)=>{return node[popped](...inp)}}else return()=>{return node[popped]}}else if(graph.get(a)){let node=graph.get(a);return()=>{return node}}else{let arg=a;return()=>{return arg}}};var wrapArgs=(callback,argOrder,graph)=>{let args=[];let forArg=(a,i)=>{if(a==="__output"||a==="__input"||a==="__callback"){args[i]={__callback:inp=>{return inp},__args:void 0,idx:i}}else if(typeof a==="string"){args[i]={__callback:getCallbackFromString(a,graph),__args:void 0,idx:i}}else if(typeof a==="function"){let fn2=a;args[i]={__callback:(...inp)=>{return fn2(...inp)},__args:void 0,idx:i}}else if(typeof a==="object"&&(a.__input||a.__callback)){let recursivelyCreateCallback=function(c){let input=c.__input?c.__input:c.__callback;if(typeof c.__input==="string"){input={__callback:getCallbackFromString(c.__input,graph),__args:void 0,idx:i}}if(c.__args){let wrapped=wrapArgs(input,c.__args,graph);input={__callback:wrapped.__callback,__args:wrapped.__args,idx:i}}else{input={__callback:input,__args:void 0,idx:i}}if(c.__output){let output=c.__output;if(typeof c.__output==="string"){output={__callback:getCallbackFromString(output,graph),__args:void 0,idx:i}}else if(typeof a.__output==="object"){output=recursivelyCreateCallback(output)}if(typeof output?.__callback==="function"){let fn2=input.__callback;let callback2=output.__callback;input={__callback:(...inp)=>{return callback2(fn2(...inp))},__args:output.__args,idx:i}}}return input};args[i]=recursivelyCreateCallback(a)}else{let arg=a;args[i]={__callback:()=>{return arg},__args:void 0,idx:i}}};argOrder.forEach(forArg);if(typeof callback==="string")callback={__callback:getCallbackFromString(callback,graph),__args:void 0};let fn=typeof callback==="function"?callback:callback.__callback;callback=function(...inp){let mapArg=arg=>{return arg.__callback(...inp)};const result=fn(...args.map(mapArg));return result};return{__callback:callback,__args:args}};var objProps=Object.getOwnPropertyNames(Object.getPrototypeOf({}));var backprop=(node,parent,graph)=>{if(node.__node.backward&&parent instanceof GraphNode){graph.setListeners({[parent.__node.tag]:{[node.__node.tag]:parent}})}};var loop=(node,parent,graph)=>{if(node.__operator){let loopId=Math.random();if(!node.__node.loops)node.__node.loops={};if(typeof node.__node.delay==="number"){let fn=node.__operator;node.__setOperator((...args)=>{return new Promise((res,rej)=>{node.__node.loops[loopId]=setTimeout(async()=>{res(await fn(...args))},node.__node.delay)})})}else if(node.__node.frame===true){let fn=node.__operator;node.__setOperator((...args)=>{return new Promise((res,rej)=>{node.__node.loops[loopId]=requestAnimationFrame(async()=>{res(await fn(...args))})})})}if(typeof node.__node.repeat==="number"||typeof node.__node.recursive==="number"){let fn=node.__operator;node.__setOperator(async(...args)=>{let i=node.__node.repeat?node.__node.repeat:node.__node.recursive;let result;let repeater=async(tick,...inp)=>{while(tick>0){if(node.__node.delay||node.__node.frame){fn(...inp).then(async res=>{if(node.__node.recursive){await repeater(tick,res)}else await repeater(tick,...inp)});break}else result=await fn(...args);tick--}};await repeater(i,...args);return result})}if(node.__node.loop&&typeof node.__node.loop==="number"){let fn=node.__operator;let time=node.__node.loop;node.__setOperator((...args)=>{if(!("looping"in node.__node))node.__node.looping=true;if(node.__node.looping){let last=performance.now();fn(...args);node.__node.loops[loopId]=setTimeout(()=>{let now=performance.now();let overshoot=now-last-node.__node.loop;if(overshoot>0)time=node.__node.loop-overshoot;else time=node.__node.loop;if(time<=0)time=node.__node.loop;node.__operator(...args)},time)}});if(node.__node.looping)node.__operator();let ondelete=node2=>{if(node2.__node.looping)node2.__node.looping=false;if(node2.__node.loops[loopId]){clearTimeout(node2.__node.loops[loopId]);cancelAnimationFrame(node2.__node.loops[loopId])}};node.__addOndisconnected(ondelete)}}};var animate=(node,parent,graph)=>{if(node.__node.animate===true||node.__animation){let fn=node.__operator;node.__setOperator((...args)=>{if(!("animating"in node.__node))node.__node.animating=true;if(node.__node.animating){if(typeof node.__animation==="function")node.__animation(...args);else fn(...args);node.__node.animationFrame=requestAnimationFrame(()=>{node.__operator(...args)})}});if(node.__node.animating||(!("animating"in node.__node)||node.__node.animating)&&node.__animation)setTimeout(()=>{node.__node.animationFrame=requestAnimationFrame(node.__operator)},10);let ondelete=node2=>{if(node2.__node.animating)node2.__node.animating=false;if(node2.__node.animationFrame)cancelAnimationFrame(node2.__node.animationFrame)};node.__addOndisconnected(ondelete)}};var branching=(node,parent,graph)=>{if(typeof node.__branch==="object"&&node.__operator&&!node.__branchApplied){let fn=node.__operator;node.__branchApplied=true;node.__operator=(...args)=>{let result=fn(...args);for(const key in node.__branch){let triggered=()=>{if(typeof node.__branch[key].then==="function"){node.__branch[key].then(result)}else if(node.__branch[key].then instanceof GraphNode&&node.__branch[key].then.__operator){node.__branch[key].then.__operator(result)}else result=node.__branch[key].then};if(typeof node.__branch[key].if==="function"){if(node.__branch[key].if(result)==true){triggered()}}else if(node.__branch[key].if===result){triggered()}}return result}}if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(node.__listeners[key].branch&&!node.__listeners[key].branchApplied){let fn=node.__listeners[key].callback;node.__listeners[key].branchApplied=true;node.__listeners.callback=ret=>{let triggered=()=>{if(typeof node.__listeners[key].branch.then==="function"){ret=node.__listeners[key].branch.then(ret)}else if(node.__listeners[key].branch.then instanceof GraphNode&&node.__listeners[key].branch.then.__operator){ret=node.__listeners[key].branch.then.__operator(ret)}else ret=node.__listeners[key].branch.then};if(typeof node.__listeners[key].branch.if==="function"){if(node.__listeners[key].branch.if(ret)){triggered()}}else if(node.__listeners[key].branch.if===ret){triggered()}return fn(ret)}}}}}};var triggerListenerOncreate=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(node.__listeners[key].oncreate){node.__listeners[key].callback(node.__listeners[key].oncreate)}}}}};var bindListener=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(typeof node.__listeners[key].binding==="object"){node.__listeners.callback=node.__listeners.callback.bind(node.__listeners[key].binding)}}}}};var transformListenerResult=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(typeof node.__listeners[key].transform==="function"&&!node.__listeners[key].transformApplied){let fn=node.__listeners[key].callback;node.__listeners[key].transformApplied=true;node.__listeners.callback=ret=>{ret=node.__listeners[key].transform(ret);return fn(ret)}}}}}};var substitute__operator=(node,parent,graph)=>{if(node.post&&!node.__operator){node.__setOperator(node.post)}else if(!node.__operator&&typeof node.get=="function"){node.__setOperator(node.get)}if(!node.get&&node.__operator){}if(node.aliases){node.aliases.forEach(a=>{graph.set(a,node);let ondelete=node2=>{graph.__node.nodes.delete(a)};node.__addOndisconnected(ondelete)})}if(typeof graph.__node.roots?.[node.__node.tag]==="object"&&node.get)graph.__node.roots[node.__node.tag].get=node.get};var loaders={backprop,loop,animate,branching,triggerListenerOncreate,bindListener,transformListenerResult,substitute__operator};var Service=class extends Graph{name=`service${Math.floor(Math.random()*1e15)}`;restrict;constructor(options){super({...options,loaders:options?.loaders?Object.assign({...loaders},options.loaders):{...loaders}});if(options?.services)this.addServices(options.services);if(options?.restrict)this.restrict=options.restrict;this.load(this)}addServices=services=>{for(const s in services){if(typeof services[s]==="function")services[s]=new services[s];if(services[s]?.__node?.loaders)Object.assign(this.__node.loaders,services[s].__node.loaders);if(services[s]?.__node?.nodes){services[s].__node.nodes.forEach((n,tag)=>{if(!this.get(tag)){this.set(tag,n)}else this.set(s+"."+tag,n)});this.__node.nodes.forEach((n,k)=>{if(!services[s].__node.nodes.get(k))services[s].__node.nodes.set(k,n)});let set=this.set;this.set=(tag,node)=>{services[s].set(tag,node);return set(tag,node)};let del=this.delete;this.delete=tag=>{services[s].delete(tag);return del(tag)}}else if(typeof services[s]==="object"){this.load(services[s])}}};handleMethod=(route,method,args)=>{let m=method.toLowerCase();let src=this.__node.nodes.get(route);if(!src){src=this.__node.roots[route]}if(src?.[m]){if(typeof src[m]!=="function"){if(args){if(Array.isArray(args)&&args.length===1)src[m]=args[0];else src[m]=args;return}return src[m]}else{if(Array.isArray(args))return src[m](...args);else return src[m](args)}}else return this.handleServiceMessage({route,args,method})};handleServiceMessage(message){let call;if(typeof message==="object"){if(message.route)call=message.route;else if(message.node)call=message.node}if(call){if(Array.isArray(message.args))return this.run(call,...message.args);else return this.run(call,message.args)}else return message}handleGraphNodeCall(route,args){if(!route)return args;if(args?.args){this.handleServiceMessage(args)}else if(Array.isArray(args))return this.run(route,...args);else return this.run(route,args)}transmit=(...args)=>{if(typeof args[0]==="object"){const message=args[0];if(message.method){return this.handleMethod(message.route,message.method,message.args)}else if(message.route){return this.handleServiceMessage(message)}else if(message.node){return this.handleGraphNodeCall(message.node,message.args)}else if(this.__node.keepState){if(message.route)this.setState({[message.route]:message.args});if(message.node)this.setState({[message.node]:message.args})}return void 0}else return void 0};receive=(...args)=>{if(args[0]){let message=args[0];if(typeof message==="string"){let substr=message.substring(0,8);if(substr.includes("{")||substr.includes("[")){if(substr.includes("\\"))message=message.replace(/\\/g,"");if(message[0]==='"'){message=message.substring(1,message.length-1)};message=JSON.parse(message)}}if(typeof message==="object"){if(message.method){if(this.restrict?.[message.route])return void 0;return this.handleMethod(message.route,message.method,message.args)}else if(message.route){if(this.restrict?.[message.route])return void 0;return this.handleServiceMessage(message)}else if(message.node){if(typeof message.node==="string"&&this.restrict?.[message.node])return void 0;return this.handleGraphNodeCall(message.node,message.args)}else if(this.__node.keepState){if(message.route)this.setState({[message.route]:message.args});if(message.node)this.setState({[message.node]:message.args})}return void 0}}return void 0};pipe=(source,destination,endpoint,method,callback)=>{if(source instanceof GraphNode){if(callback)return this.subscribe(source,res=>{let mod=callback(res);if(mod!==void 0)this.transmit({route:destination,args:mod,method});else this.transmit({route:destination,args:res,method},endpoint)});else return this.subscribe(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})}else if(typeof source==="string")return this.subscribe(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})};pipeOnce=(source,destination,endpoint,method,callback)=>{if(source instanceof GraphNode){if(callback)return source.__node.state.subscribeEventOnce(source.__node.unique,res=>{let mod=callback(res);if(mod!==void 0)this.transmit({route:destination,args:mod,method});else this.transmit({route:destination,args:res,method},endpoint)});else return this.__node.state.subscribeEventOnce(source.__node.unique,res=>{this.transmit({route:destination,args:res,method},endpoint)})}else if(typeof source==="string")return this.__node.state.subscribeEventOnce(this.__node.nodes.get(source).__node.unique,res=>{this.transmit({route:destination,args:res,method},endpoint)})};terminate=(...args)=>{};isTypedArray=isTypedArray;recursivelyAssign=recursivelyAssign2;spliceTypedArray=spliceTypedArray;ping=()=>{console.log("pinged!");return"pong"};echo=(...args)=>{this.transmit(...args);return args};log=(...args)=>{console.log(...args);return true};error=(...args)=>{console.error(...args);return true}};function isTypedArray(x3){return ArrayBuffer.isView(x3)&&Object.prototype.toString.call(x3)!=="[object DataView]"}var recursivelyAssign2=(target,obj)=>{for(const key in obj){if(obj[key]?.constructor.name==="Object"&&!Array.isArray(obj[key])){if(target[key]?.constructor.name==="Object"&&!Array.isArray(target[key]))recursivelyAssign2(target[key],obj[key]);else target[key]=recursivelyAssign2({},obj[key])}else target[key]=obj[key]}return target};function spliceTypedArray(arr,start,end){let s=arr.subarray(0,start);let e;if(end){e=arr.subarray(end+1)}let ta;if(s.length>0||e?.length>0)ta=new arr.constructor(s.length+e.length);if(ta){if(s.length>0)ta.set(s);if(e&&e.length>0)ta.set(e,s.length)}return ta}var randomId=prefix=>(prefix?`${prefix}`:"")+Math.floor(1e15*Math.random());var pseudoObjectId=(m=Math,d2=Date,h=16,s=s2=>m.floor(s2).toString(h))=>s(d2.now()/1e3)+" ".repeat(h).replace(/./g,()=>s(m.random()*h));var StructFrontend=class extends Service{name="structs";currentUser;tablet=new DataTablet;collections=this.tablet.collections;id=randomId();useAccessTokens=false;useRefreshTokens=false;constructor(options,user){super(options);this.load(this);if(options.useAccessTokens)this.useAccessTokens=options.useAccessTokens;if(options.useRefreshTokens)this.useRefreshTokens=options.useRefreshTokens;if(user instanceof Object&&Object.keys(user).length>0)this.setupUser(user)}getToken(user){if(this.useAccessTokens)return user.accessToken;else if(this.useRefreshTokens)return user.refreshToken}setupUser=async(userinfo,callback=currentUser=>{})=>{if(!userinfo){console.error('must provide a minimum info object! e.g. {_id:"abc123"}');callback(void 0);return void 0}let changed=false;if(userinfo.id&&!userinfo._id)userinfo._id=userinfo.id;else if(userinfo._id)userinfo.id=userinfo._id;let res=await this.getUser(userinfo._id);let user=res?.user;let u2;let newu=false;if(!user||!user._id){u2=this.userStruct(userinfo,false);newu=true;let wasSet=await this.setUser(u2);let structs=this.getLocalData(void 0,{"ownerId":u2._id});if(structs?.length>0)this.updateServerData(structs);this.setAuthorizationsByGroup(u2)}else{u2=user;let toUpdate={_id:userinfo._id,ownerId:userinfo._id};let struct=this.userStruct(userinfo,false);for(const key in struct){if(userinfo[key]&&user[key]!==userinfo[key]){toUpdate[key]=userinfo[key];user[key]=userinfo[key]}else if(struct[key]&&!user[key]){toUpdate[key]=struct[key];user[key]=struct[key]}}if(Object.keys(toUpdate).length>2)await this.setUser(toUpdate);if(res?.authorizations){if(Array.isArray(res.authorizations)){this.setLocalData(res.authorizations)}}if(res?.groups){if(Array.isArray(res.groups)){this.setLocalData(res.groups)}}}if(newu){this.setLocalData(u2)}else{let data=await this.getAllUserData(u2._id,void 0,[genTimestampFromString("last day"),Date.now()]);if(!data||data.length===0){}else{this.setLocalData(data);let notes=data.filter(s=>{if(s.structType==="notification"){if(this.getLocalData("authorization",s.parent._id)){return true}if(s.parent.structType==="user"||s.parent.structType==="authorization"){return true}if(!this.getLocalData(s.parent.structType,s.parent._id))return true}});let comments=data.filter(s=>{if(s.structType==="comment"){return true}});let toDelete=[];comments.forEach(comment=>{if(!this.getLocalData("comment",{"_id":comment._id}))toDelete.push(comment._id)});if(toDelete.length>0)this.deleteData(toDelete);if(notes.length>0){this.resolveNotifications(notes,false,void 0);changed=true}let filtered=data.filter(o=>{if(o.structType!=="notification")return true});if(this.tablet)this.tablet.sortStructsIntoTable(filtered)}this.setLocalData(u2)}if(u2){if(this.currentUser)Object.assign(this.currentUser,u2);else this.currentUser=u2;callback(this.currentUser);return this.currentUser}else{callback(u2);return u2}};baseServerCallback=data=>{let structs=data;if(typeof data==="object"&&data?.structType)structs=[data];if(Array.isArray(structs)){let filtered=structs.filter(o=>{if(o.structType!=="notification")return true});if(this.tablet)this.tablet.sortStructsIntoTable(filtered);structs.forEach(struct=>{if(typeof struct==="object"){if(!struct.structType||struct.structType==="USER"){if(struct.email)struct.structType="user";else struct.structType="uncategorized"}if(struct.structType==="user"||struct.structType==="authorization"||struct.structType==="group"){if(struct.structType==="user"){struct._id=struct.id}else if(struct.structType==="group"){if(this.currentUser){let uset=false;if(struct.admins[this.currentUser?._id]&&!this.currentUser.userRoles?.[struct.name+"_admin"]){this.currentUser.userRoles[struct.name+"_admin"]=true;uset=true}else if(!struct.admins[this.currentUser?._id]&&this.currentUser.userRoles?.[struct.name+"_admin"]){delete this.currentUser.userRoles[struct.name+"_admin"];uset=true}if(struct.admins[this.currentUser?._id]&&!this.currentUser.userRoles?.[struct.name+"_peer"]){this.currentUser.userRoles[struct.name+"_peer"]=true;uset=true}else if(!struct.admins[this.currentUser?._id]&&this.currentUser.userRoles?.[struct.name+"_peer"]){delete this.currentUser.userRoles[struct.name+"_peer"];uset=true}if(struct.admins[this.currentUser?._id]&&!this.currentUser.userRoles?.[struct.name+"_client"]){this.currentUser.userRoles[struct.name+"_client"]=true;uset=true}else if(!struct.admins[this.currentUser?._id]&&this.currentUser.userRoles?.[struct.name+"_client"]){delete this.currentUser.userRoles[struct.name+"_client"];uset=true}if(uset)this.setUser(this.currentUser)}}this.setLocalData(struct)}else{if(struct.structType==="notification"){let found=this.getLocalData("notification",{"ownerId":struct.ownerId,"_id":struct.parent._id});if(found){this.setLocalData(struct)}else{if(this.getLocalData(struct.structType,{"_id":struct.parent._id})){}else{this.overwriteLocalData(struct)}}if(struct.ownerId===this.currentUser?._id&&(struct.parent.structType==="user"||struct.parent.structType==="dataInstance"||struct.parent.structType==="schedule"||struct.parent.structType==="authorization")){this.resolveNotifications([struct],true)}}else{this.overwriteLocalData(struct)}}}})}this.onResult(data)};structNotification=()=>{this.checkForNotifications()};structDeleted=struct=>{this.deleteLocalData([struct])};onResult=data=>{};randomId(tag=""){return`${tag+Math.floor(Math.random()+Math.random()*Math.random()*1e16)}`}addStruct=async(structType="struct",props={},parentUser,parentStruct,updateServer=true)=>{let newStruct=DataStructures_exports.Struct(structType,props,parentUser,parentStruct);if(updateServer)newStruct=await this.updateServerData([newStruct])[0];return newStruct};getUser=async(info="",basicInfo,callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"getUser",args:[this.currentUser._id,info,basicInfo,this.getToken(this.currentUser)]});callback(res);return res}};queryUsers=async(info,skip,limit,callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"queryUsers",args:[this.currentUser._id,info,skip,limit,void 0,this.getToken(this.currentUser)]});callback(res);return res}};getUsers=async(ids=[],basicInfo,callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"getUsersByIds",args:[this.currentUser._id,ids,basicInfo]});callback(res);return res}};getUsersByRole=async(userRole,callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"getUsersByRole",args:[this.currentUser._id,userRole]});callback(res);return res}};getAllUserData=async(ownerId,excluded=[],timeRange,callback=this.baseServerCallback)=>{if(timeRange){if(typeof timeRange[0]==="string")timeRange[0]=genTimestampFromString(timeRange[0]);if(typeof timeRange[1]==="string")timeRange[1]=genTimestampFromString(timeRange[1])}if(this.currentUser?.request){let res=await this.currentUser.request({route:"getAllData",args:[this.currentUser._id,ownerId,excluded,timeRange,this.getToken(this.currentUser)]});callback(res);return res}};query=async(collection,mongoQuery={},findOne=false,skip=0,callback=this.baseServerCallback)=>{if(this.currentUser?.request){if(!collection||!mongoQuery)return void 0;let res=await this.currentUser.request({route:"query",args:[this.currentUser._id,collection,mongoQuery,findOne,skip,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};getDataByTimeRange(collection,timeRange,ownerId,limit=0,skip=0,key){let query={};if(timeRange){if(typeof timeRange[0]==="string")timeRange[0]=genTimestampFromString(timeRange[0]);if(typeof timeRange[1]==="string")timeRange[1]=genTimestampFromString(timeRange[1])}let range={$gt:timeRange[0],$lt:timeRange[1]};if(key)query[key]=range;else query.timestamp=range;return this.getData(collection,ownerId,query,limit,skip)}getData=async(collection,ownerId,searchDict,limit=0,skip=0,callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"getData",args:[this.currentUser._id,collection,ownerId,searchDict,limit,skip,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};getDataByIds=async(structIds=[],ownerId,collection,callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"getDataByIds",args:[this.currentUser._id,structIds,ownerId,collection,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};getStructParentData=async(struct,callback=this.baseServerCallback)=>{if(!struct?.parent)return;if(this.currentUser?.request){let args=[this.currentUser._id,struct.parent?.structType,"_id",struct.parent?._id,this.getToken(this.currentUser)];let res=(await this.currentUser.request({route:"getData",args}))?.[0];if(typeof callback==="function")callback(res);return res}};setUser=async(userStruct,callback=this.baseServerCallback)=>{if(userStruct&&this.currentUser?.request){let res=await this.currentUser.request({route:"setUser",args:[this.currentUser._id,this.stripStruct(userStruct),this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};checkUserToken=async(usertoken,user=this.currentUser,callback=this.baseServerCallback)=>{if(!usertoken)return false;let changed=false;for(const prop in usertoken){let dummystruct=this.userStruct();if(user[prop]&&prop!=="_id"){if(Array.isArray(usertoken[prop])){for(let i=0;i{if(this.currentUser?.request){const copies=new Array;if(!Array.isArray(structs)&&typeof structs==="object")structs=[structs];structs.forEach(struct=>{copies.push(this.stripStruct(struct))});let res=await this.currentUser.request({route:"setData",args:[this.currentUser._id,copies,notify,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};updateServerData=this.setData;deleteData=async(structs=[],callback=this.baseServerCallback)=>{if(this.currentUser?.request){let toDelete=[];structs.forEach(struct=>{if(typeof struct==="object"){if(struct?.structType&&struct?._id){toDelete.push({structType:struct.structType,_id:struct._id});this.deleteLocalData(struct)}}else if(typeof struct==="string"){let localstruct=this.getLocalData(void 0,{_id:struct});if(localstruct&&!Array.isArray(localstruct)){toDelete.push({structType:localstruct.structType,_id:localstruct._id})}else{toDelete.push({_id:struct})}}});let res=await this.currentUser.request({route:"deleteData",args:[this.currentUser._id,toDelete,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};deleteUser=async(userId=this.currentUser._id,deleteData,callback=this.baseServerCallback)=>{if(this.currentUser?.request){if(!userId)return;let res=await this.currentUser.request({route:"deleteUser",args:[this.currentUser._id,userId,deleteData,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};setGroup=async(groupStruct,callback=this.baseServerCallback)=>{if(groupStruct&&this.currentUser?.request){let res=await this.currentUser.request({route:"setGroup",args:[this.currentUser._id,this.stripStruct(groupStruct),this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};getUserGroups=async(userId=this.currentUser._id,groupId="",callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"getUserGroups",args:[this.currentUser._id,userId,groupId,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};deleteGroup=async(groupId,callback=this.baseServerCallback)=>{if(this.currentUser?.request){if(!groupId)return;this.deleteLocalData(groupId);let res=await this.currentUser.request({route:"deleteGroup",args:[this.currentUser._id,groupId,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};setAuthorization=async(authorizationStruct,callback=this.baseServerCallback)=>{if(authorizationStruct&&this.currentUser?.request){let res=await this.currentUser.request({route:"setAuthorization",args:[this.currentUser._id,this.stripStruct(authorizationStruct),this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};getAuthorizations=async(userId=this.currentUser?._id,authorizationId="",callback=this.baseServerCallback)=>{if(this.currentUser?.request){if(userId===void 0)return;let res=await this.currentUser.request({route:"getAuthorizations",args:[this.currentUser._id,userId,authorizationId,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};deleteAuthorization=async(authorizationId,callback=this.baseServerCallback)=>{if(this.currentUser?.request){if(!authorizationId)return;this.deleteLocalData(authorizationId);let res=await this.currentUser.request({route:"deleteAuthorization",args:[this.currentUser._id,authorizationId,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};checkForNotifications=async(userId=this.currentUser?._id)=>{return await this.getData("notification",userId)};resolveNotifications=async(notifications=[],pull=true,user=this.currentUser)=>{if(!user||notifications.length===0)return;let structIds=[];let notificationIds=[];let nTypes=[];let unote=false;if(notifications.length===0)notifications=this.getLocalData("notification",{"ownerId":user._id});notifications.forEach(struct=>{if(struct.parent.structType==="user")unote=true;nTypes.push(struct.parent.structType);structIds.push(struct.parent._id);notificationIds.push(struct._id);this.deleteLocalData(struct)});this.deleteData(notifications);if(pull){nTypes.reverse().forEach((note,i)=>{if(note==="user"){this.getUser(structIds[i]);structIds.splice(structIds.length-i-1,1)}});if(structIds.length===1)return await this.getDataByIds(structIds,void 0,notifications[0].parent.structType);if(structIds.length>0)return await this.getDataByIds(structIds)}return true};setAuthorizationsByGroup=async(user=this.currentUser)=>{let auths=this.getLocalData("authorization",{"ownerId":user._id});let newauths=[];if(user.userRoles)await Promise.all(Object.keys(user.userRoles).map(async role=>{let split=role.split("_");let team=split[0];let otherrole;if(role.includes("client")){otherrole=team+"_peer"}else if(role.includes("peer")){otherrole=team+"_client"}else if(role.includes("admin")){otherrole=team+"_owner"}if(otherrole){let users=await this.getUsersByRole(otherrole);if(users)await Promise.all(users.map(async groupie=>{let theirname=groupie.username;if(!theirname)theirname=groupie.email;if(!theirname)theirname=groupie._id;let myname=user.username;if(!myname)myname=user.email;if(!myname)myname=user._id;if(theirname!==myname){if(role.includes("client")){let found=auths.find(a=>{if(a.authorizerId===groupie._id&&a.authorizedId===user._id)return true});if(!found){let auth=await this.authorizeUser(DataStructures_exports.ProfileStruct("user",user,user),groupie._id,theirname,user._id,myname,{"peer":true},void 0,{group:team});newauths.push(auth)}}else if(role.includes("peer")){let found=auths.find(a=>{if(a.authorizedId===groupie._id&&a.authorizerId===user._id)return true});if(!found){let auth=await this.authorizeUser(DataStructures_exports.ProfileStruct("user",user,user),user._id,myname,groupie._id,theirname,{"peer":true},void 0,{group:team});newauths.push(auth)}}}}))}}));if(newauths.length>0)return newauths;return void 0};deleteRoom=async roomStruct=>{if(!roomStruct)return false;let toDelete=[roomStruct];roomStruct.comments?.forEach(id=>{let struct=this.getLocalData("comment",{"_id":id});toDelete.push(struct)});if(roomStruct)return await this.deleteData(toDelete);else return false};deleteComment=async commentStruct=>{let allReplies=[commentStruct];let getRepliesRecursive=(head=commentStruct)=>{if(head?.replies){head.replies.forEach(replyId=>{let reply=this.getLocalData("comment",{"_id":replyId});if(reply){if(reply.replies.length>0){reply.replies.forEach(replyId2=>{getRepliesRecursive(replyId2)})}allReplies.push(reply)}})}};getRepliesRecursive(commentStruct);let parent=this.getLocalData(commentStruct.parent?.structType,{"_id":commentStruct.parent?._id});let toUpdate=[];if(parent){toUpdate=[parent];allReplies.forEach(r=>{let idx=parent.replies?.indexOf(r._id);if(idx>-1)parent.replies.splice(idx,1);let idx2=parent.comments?.indexOf(r._id);if(idx2>-1)parent.comments.splice(idx2,1)})}let replyTo=this.getLocalData("comment",{"_id":commentStruct.replyTo});if(replyTo?._id!==parent?._id){let idx=replyTo.replies?.indexOf(parent._id);if(idx>-1)replyTo.replies.splice(idx,1);toUpdate.push(replyTo)}if(toUpdate.length>0)await this.updateServerData(toUpdate);return await this.deleteData(allReplies)};getUserDataByAuthorization=async(authorizationStruct,collection,searchDict,limit=0,skip=0,callback=this.baseServerCallback)=>{let u2=authorizationStruct.authorizerId;if(u2){return new Promise(async resolve=>{this.getUser(u2,true,async data=>{let res;if(!collection)res=await this.getAllUserData(u2,["notification"],void 0,callback);else res=await this.getData(collection,u2,searchDict,limit,skip,callback);resolve(res);callback(res)})})}else return void 0};getUserDataByAuthorizationGroup=async(groupId="",collection,searchDict,limit=0,skip=0,callback=this.baseServerCallback)=>{let auths=this.getLocalData("authorization");let results=[];await Promise.all(auths.map(async o=>{if(o.groups?.includes(groupId)){let u2=o.authorizerId;if(u2){let data;let user=await this.getUser(u2,true,callback);if(user)results.push(user);if(!collection)data=await this.getAllUserData(u2,["notification"],void 0,callback);else data=await this.getData(collection,u2,searchDict,limit,skip,callback);if(data)results.push(data)}return true}}));return results};overwriteLocalData(structs){if(Array.isArray(structs)){structs.forEach(struct=>{let localdat=this.getLocalData(struct.structType,{"ownerId":struct.ownerId,"_id":struct._id});if(!localdat||localdat?.length===0){this.setLocalData(struct)}else Object.assign(localdat,struct)})}else{let localdat=this.getLocalData(structs.structType,{"ownerId":structs.ownerId,"_id":structs._id});if(!localdat||localdat?.length===0){this.setLocalData(structs)}else Object.assign(localdat,structs)}}setLocalData(structs){this.tablet.setLocalData(structs)}getLocalData(collection,query){return this.tablet.getLocalData(collection,query)}getLocalUserPeerIds=(user=this.currentUser)=>{if(!user)return{};let result={};let authorizations=this.getLocalData("authorization",user._id);authorizations.forEach(a=>{if(a.authorizations["peer"]&&a.authorizerId===user._id)result[a.authorizedId]=true});return result};getLocalReplies(struct){let replies=[];if(!struct.replies)return replies;else if(struct.replies.reduce((a,b)=>a*(typeof b==="object"?1:0),1))return struct.replies;replies=this.getLocalData("comment",{"replyTo":struct._id});return replies}hasLocalAuthorization(otherUserId,ownerId=this.currentUser._id){let auths=this.getLocalData("authorization",{ownerId});let found=auths.find(a=>{if(a.authorizedId===ownerId&&a.authorizerId===otherUserId)return true;if(a.authorizerId===ownerId&&a.authorizedId===otherUserId)return true});if(found){return found}else return false}deleteLocalData(structs){if(Array.isArray(structs))structs.forEach(s=>this.deleteStruct(s));else this.deleteStruct(structs);return true}deleteStruct(struct){if(typeof struct==="string")struct=this.getLocalData(void 0,{_id:struct});if(!struct)throw new Error("Struct not supplied");if(!struct.structType||!struct._id)return false;this.tablet.collections.get(struct.structType).delete(struct._id);return true}stripStruct(struct){const copy=Object.assign({},struct);for(const prop in copy){if(copy[prop]===void 0||copy[prop]===""||copy[prop].constructor.name==="Map"||copy[prop].constructor.name==="Set"||typeof copy[prop]==="function")delete copy[prop];else if(Array.isArray(copy[prop])&©[prop].length===0)delete copy[prop];else if(typeof copy[prop]==="object"&&Object.keys(copy[prop]).length===0)delete copy[prop]}return copy}createStruct(structType,props,parentUser=this.currentUser,parentStruct){let struct=DataStructures_exports.Struct(structType,props,parentUser,parentStruct);return struct}userStruct(props={},currentUser=false){let user=DataStructures_exports.ProfileStruct(void 0,props,props);if(!user.name&&user.firstName)user.name=user.firstName+" "+user.lastName;else if(user.name&&!user.firstName){let split=user.name.split(" ");user.firstName=split[0];user.lastName=split[split.length-1]}if(props._id)user.id=props._id;else if(props.id)user.id=props.id;else user.id="user"+Math.floor(Math.random()*1e15);user._id=user.id;user.ownerId=user.id;let dummy=DataStructures_exports.ProfileStruct();for(const prop in props){if(Object.keys(dummy).indexOf(prop)<0){delete user[prop]}}if(currentUser)this.currentUser=user;return user}authorizeUser=async(parentUser,authorizerUserId="",authorizerUserName="",authorizedUserId="",authorizedUserName="",authorizations={},structs={},excluded={},groups={},expires=false)=>{if(!parentUser)return void 0;let newAuthorization=this.createStruct("authorization",void 0,parentUser,void 0);newAuthorization.authorizedId=authorizedUserId;newAuthorization.authorizedName=authorizedUserName;newAuthorization.authorizerId=authorizerUserId;newAuthorization.authorizerName=authorizerUserName;newAuthorization.authorizations=authorizations;newAuthorization.structs=structs;newAuthorization.excluded=excluded;newAuthorization.groups=groups;newAuthorization.expires=expires;newAuthorization.status="PENDING";newAuthorization.associatedAuthId="";newAuthorization=await this.setAuthorization(newAuthorization);return newAuthorization};addGroup=async(parentUser,name="",details="",admins={},peers={},clients={},updateServer=true)=>{if(!parentUser)return void 0;let newGroup=this.createStruct("group",void 0,parentUser);newGroup.name=name;newGroup.details=details;newGroup.admins=admins;newGroup.peers=peers;newGroup.clients=clients;newGroup.users={};Object.assign(newGroup.users,newGroup.admins);Object.assign(newGroup.users,newGroup.peers);Object.assign(newGroup.users,newGroup.clients);if(updateServer){newGroup=await this.setGroup(newGroup)}return newGroup};dataObject(data=void 0,type="any",timestamp=Date.now()){return{type,data,timestamp}}addData=async(parentUser,author="",title="",type="",data=[],expires=false,updateServer=true)=>{if(!parentUser)return void 0;let newDataInstance=this.createStruct("dataInstance",void 0,parentUser);newDataInstance.author=author;newDataInstance.title=title;newDataInstance.type=type;newDataInstance.data=data;newDataInstance.expires=expires;if(updateServer)newDataInstance=await this.updateServerData([newDataInstance])[0];return newDataInstance};addEvent=async(parentUser,author="",event="",notes="",startTime=void 0,endTime=void 0,grade=void 0,value=void 0,units=void 0,location=void 0,attachments=void 0,users=void 0,updateServer=true)=>{if(!parentUser)return void 0;if(users&&Object.keys(users).length===0)users=this.getLocalUserPeerIds(parentUser);let newEvent=this.createStruct("event",void 0,parentUser);newEvent.author=author;newEvent.event=event;newEvent.notes=notes;newEvent.startTime=startTime;newEvent.endTime=endTime;newEvent.grade=grade;newEvent.attachments=attachments;newEvent.value=value;newEvent.units=units;newEvent.users=users;newEvent.location=location;if(updateServer)newEvent=await this.updateServerData([newEvent])[0];return newEvent};addChatroom=async(parentUser,authorId="",message="",attachments=void 0,users=void 0,updateServer=true)=>{if(!parentUser)return void 0;if(users&&Object.keys(users).length===0)users=this.getLocalUserPeerIds(parentUser);let newChatroom=this.createStruct("chatroom",void 0,parentUser);newChatroom.message=message;newChatroom.attachments=attachments;newChatroom.authorId=authorId;newChatroom.users=users;newChatroom.replies=[];newChatroom.comments=[];let update=[newChatroom];if(updateServer)newChatroom=await this.updateServerData(update)[0];return newChatroom};addComment=async(parentUser,roomStruct,replyTo,authorId="",message="",attachments=void 0,updateServer=true)=>{if(!roomStruct)return void 0;if(!replyTo)replyTo=roomStruct;if(!parentUser)return void 0;let newComment=this.createStruct("comment",void 0,parentUser,roomStruct);newComment.authorId=authorId;newComment.replyTo=replyTo?._id;newComment.message=message;newComment.attachments=attachments;newComment.users=roomStruct?.users;newComment.replies=[];if(!updateServer)replyTo?.replies.push(newComment._id);if(!updateServer)roomStruct?.comments.push(newComment._id);let update=[newComment,roomStruct];if(replyTo?._id!==roomStruct._id)update.push(replyTo);let res;if(updateServer)res=await this.updateServerData(update);let updatedComment;if(typeof res==="object"){updatedComment=res.find(s=>{if(newComment.ownerId===s.ownerId&&newComment.timestamp===s.timestamp&&newComment.message===s.message){return true}})}if(updatedComment)return updatedComment;return res}};var import_bson=__toESM(require_bson());var randomId2=prefix=>(prefix?`${prefix}_`:"")+Math.floor(1e15*Math.random());var toObjectId=str2=>{return typeof str2==="string"&&str2.length===24?new import_bson.ObjectId(str2):str2};var getStringId=mongoid=>{if(typeof mongoid==="object")return mongoid.toString();else return mongoid};var defaultCollections=["profile","group","authorization","discussion","chatroom","comment","dataInstance","event","notification","schedule","date"];var StructBackend=class extends Service{name="structs";debug=false;db;users={};collections={};mode="local";useAuths=true;useAccessTokens=false;useRefreshTokens=false;accessTokens=new Map;refreshTokens=new Map;constructor(options,dboptions){super(options);this.load(this);if(dboptions){this.initDB(dboptions)}}initDB=dboptions=>{this.db=dboptions.db;if(dboptions?.users)this.users=dboptions.users;if(dboptions.mode)this.mode=dboptions.mode;if(dboptions?.collections)this.collections=dboptions.collections;if(dboptions.debug)this.debug=dboptions.debug;if(dboptions.useAccessTokens)this.useAccessTokens=dboptions.useAccessTokens;if(dboptions.useRefreshTokens)this.useRefreshTokens=dboptions.useRefreshTokens;if("useAuths"in dboptions)this.useAuths=dboptions.useAuths;defaultCollections.forEach(k=>{if(!this.collections[k]){this.collections[k]=this.db?{instance:this.db.collection(k)}:{};this.collections[k].reference={}}})};query=async(requestingUserId,collection,queryObj,findOne,skip,token)=>{let user=this.users[requestingUserId];if(!user)return false;if(this.mode.indexOf("mongo")>-1){return await this.queryMongo(user,collection,queryObj,findOne,skip,token)}else{let res=this.getLocalData(user,collection);if(res&&!Array.isArray(res)){let passed=!this.useAuths;if(!res?.ownerId)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,res,"READ",token);if(passed)return res}if(typeof skip==="number"&&Array.isArray(res)){if(res.length>skip)res.splice(0,skip)}let data=[];if(res)await Promise.all(res.map(async s=>{let struct=this.getLocalData(getStringId(s._id));let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);if(passed)data.push(struct)}));return data}};getUser=async(requestingUserId,lookupId,basicInfo,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.indexOf("mongo")>-1){data=await this.getMongoUser(user,lookupId,void 0,basicInfo,token)}else{let struct=this.getLocalData("profile",{_id:lookupId});if(!struct)data={user:void 0};else{let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);if(passed){let groups=this.getLocalData("group",{ownerId:lookupId});let auths=this.getLocalData("authorization",{ownerId:lookupId});data={user:struct,groups,authorizations:auths}}else data={user:{}}}}if(this.debug)console.log("getUser: user:",user,"input:",lookupId,"output",data);return data};setUser=async(requestingUserId,struct,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(struct.accessToken){this.accessTokens.set(requestingUserId,token)}if(struct.refreshToken){this.refreshTokens.set(requestingUserId,struct.refreshToken)}delete struct.accessToken;delete struct.refreshToken;delete user.accessToken;delete user.refreshToken;if(this.mode.indexOf("mongo")>-1){data=await this.setMongoUser(user,struct,token)}else{let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(passed)this.setLocalData(struct);return true}if(this.debug)console.log("setUser user:",user,"input:",struct,"output",data);return data};getUsersByIds=async(requestingUserId,userIds,basicInfo)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getMongoUsersByIds(user,userIds,basicInfo)}else{data=[];if(Array.isArray(userIds)){let struct=this.getLocalData("profile",{_id:userIds});if(struct){if(basicInfo)data.push({_id:struct._id,username:struct.username,firstName:struct.firstName,lastName:struct.lastName,fullName:struct.fullName,pictureUrl:struct.pictureUrl});else data.push(struct)}}}if(this.debug)console.log("getUserByIds: user:",user,"input:",userIds,"output",data);return data};getUsersByRole=async(requestingUserId,role)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getMongoUsersByRole(user,role)}else{let profiles=this.getLocalData("profile");data=[];profiles.forEach(struct=>{if(struct.userRoles[role]){data.push(struct)}})}if(this.debug)console.log("getUserByRoles: user:",user,"input:",role,"output",data);return data};deleteUser=async(requestingUserId,userId,deleteData,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.deleteMongoUser(user,userId,deleteData,token)}else{data=false;let struct=this.getLocalData(userId);if(struct){let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(passed)data=this.deleteLocalData(struct)}}if(this.debug)console.log("deleteUser: user:",user,"input:",userId,"output",data);return data};setData=async(requestingUserId,structs,notify,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.setMongoData(user,structs,notify,token)}else{let non_notes=[];data=[];await Promise.all(structs.map(async structId=>{let struct=this.getLocalData(structId);let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(passed){if(!this.collections[struct.structType]){this.collections[struct.structType]={};this.collections[struct.structType].reference={}}this.setLocalData(struct);data.push(struct);if(struct.structType!=="notification")non_notes.push(struct)}}));if(non_notes.length>0&&(notify===true||typeof notify==="undefined"))this.checkToNotify(user,non_notes,this.mode);if(this.debug)console.log("setData:",user,structs,data);return true}if(this.debug)console.log("setData: user:",user,"input:",structs,notify,"output",data);return data};getData=async(requestingUserId,collection,ownerId,dict,limit,skip,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getMongoData(user,collection,ownerId,dict,limit,skip,token)}else{data=[];let structs;if(collection)structs=this.getLocalData(collection);if(structs&&ownerId)structs=structs.filter(o=>{if(o.ownerId===ownerId)return true});if(structs)await Promise.all(structs.map(async s=>{let struct=this.getLocalData(getStringId(s._id));let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);if(passed)data.push(struct)}))}if(this.debug)console.log("getData: user:",user,"input:",collection,ownerId,dict,limit,skip,"output",data);return data};getDataByIds=async(requestingUserId,structIds,ownerId,collection,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getMongoDataByIds(user,structIds,ownerId,collection,token)}else{data=[];let structs;if(collection)structs=this.getLocalData(collection);if(structs&&ownerId)structs=structs.filter(o=>{if(o.ownerId===ownerId)return true});if(structs)await Promise.all(structs.map(async s=>{let struct=this.getLocalData(getStringId(s._id));let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);if(passed)data.push(struct)}))}if(this.debug)console.log("getDataByIds: user:",user,"input:",structIds,ownerId,collection,"output",data);return data};getAllData=async(requestingUserId,ownerId,excludedCollections,timeRange,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getAllUserMongoData(user,ownerId,excludedCollections,timeRange,token)}else{let result=this.getLocalData(void 0,{ownerId});data=[];await Promise.all(result.map(async struct=>{if(excludedCollections){if(excludedCollections.indexOf(struct.structType)<0){let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);if(passed)data.push(struct)}}else{let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);if(passed)data.push(struct)}}))}if(this.debug)console.log("getAllData: user:",user,"input:",ownerId,excludedCollections,"output",data);return data};deleteData=async(requestingUserId,structIds,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.deleteMongoData(user,structIds,token)}else{data=false;await Promise.all(structIds.map(async structId=>{let struct=this.getLocalData(structId);let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(passed)this.deleteLocalData(struct);data=true}))}if(this.debug)console.log("deleteData: user:",user,"input:",structIds,"output",data);return data};getUserGroups=async(requestingUserId,userId,groupId)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getMongoGroups(user,userId,groupId)}else{if(typeof groupId==="string"){data=this.getLocalData("group",{_id:groupId})}else{data=[];let result=this.getLocalData("group");if(userId){result.forEach(struct=>{if(Object.keys(struct.users).includes(userId))data.push(struct)})}else{result.forEach(struct=>{if(Object.keys(struct.users).includes(getStringId(user._id)))data.push(struct)})}}}if(this.debug)console.log("getGroups: user:",user,"input:",userId,groupId,"output",data);return data};deleteGroup=async(requestingUserId,groupId,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.deleteMongoGroup(user,groupId,token)}else{let struct=this.getLocalData("group",groupId);let passed=!this.useAuths;if(struct){if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token)}if(passed){data=true}}if(this.debug)console.log("deleteGroup: user:",user,"input:",groupId,"output",data);return data};getAuthorizations=async(requestingUserId,ownerId,authId,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getMongoAuthorizations(user,ownerId,authId,token)}else{if(authId){let result=this.getLocalData("authorization",{_id:authId});if(result)data=[result]}else{data=this.getLocalData("authorization",{ownerId})}}if(this.debug)console.log("getAuthorizations: user:",user,"input:",ownerId,authId,"output",data);return data};deleteAuthorization=async(requestingUserId,authId,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.deleteMongoAuthorization(user,authId,token)}else{data=true;let struct=this.getLocalData("authorization",{_id:authId});if(struct){let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(passed)data=this.deleteLocalData(struct)}}if(this.debug)console.log("deleteAuthorization: user:",user,"input:",authId,"output",data);return data};getToken=user=>{return this.useAccessTokens?this.accessTokens.get(user._id):this.useRefreshTokens?this.refreshTokens.get(user._id):void 0};notificationStruct=(parentStruct={})=>{let structType="notification";let struct={structType,timestamp:Date.now(),_id:randomId2(structType),note:"",alert:false,ownerId:"",parentUserId:"",parent:{structType:parentStruct?.structType,_id:getStringId(parentStruct?._id)}};return struct};checkToNotify=async(user,structs=[],mode=this.mode)=>{if(structs.length===0)return false;if(typeof user==="string"){for(let key in this.users){const obj=this.users[key];if(getStringId(obj._id)===user)user=obj}}if(typeof user==="string"||user==null)return false;let usersToNotify={};let newNotifications=[];structs.forEach(async struct=>{if(struct?._id){if(struct.ownerId&&user?._id!==struct.ownerId){let newNotification=this.notificationStruct(struct);newNotification._id="notification_"+getStringId(struct._id)+"_"+struct.ownerId;newNotification.ownerId=struct.ownerId;newNotification.note=struct.structType;newNotification.parentUserId=struct.ownerId;if(struct.alert)newNotification.alert=struct.alert;newNotifications.push(newNotification);usersToNotify[struct.ownerId]=struct.ownerId}if(struct.users){Object.keys(struct.users).forEach(usr=>{if(usr!==user._id){let newNotification=this.notificationStruct(struct);newNotification._id="notification_"+getStringId(struct._id)+"_"+usr;newNotification.ownerId=usr;newNotification.note=struct.structType;if(struct.alert)newNotification.alert=struct.alert;newNotification.parentUserId=struct.ownerId;newNotifications.push(newNotification);usersToNotify[usr]=usr}})}else{let auths=[];if(mode.includes("mongo")){let s=this.collections.authorization.instance.find({$or:[{authorizedId:user._id},{authorizerId:user._id}]});let arr=await s.toArray();if(arr.length>0){arr.forEach(d2=>auths.push(d2))}}else{auths=this.getLocalData("authorization",{authorizedId:user._id});auths.push(...this.getLocalData("authorization",{authorizerId:user._id}))}if(auths.length>0){auths.forEach(auth=>{if(struct.authorizerId===struct.ownerId&&!usersToNotify[struct.authorizedId]){if(auth.status==="OKAY"&&auth.authorizations["peer"]){let newNotification=this.notificationStruct(struct);newNotification.ownerId=auth.authorizedId;newNotification._id="notification_"+getStringId(struct._id)+"_"+auth.authorizedId;newNotification.note=struct.structType;newNotification.parentUserId=struct.ownerId;if(struct.alert)newNotification.alert=struct.alert;newNotifications.push(newNotification);usersToNotify[newNotification.ownerId]=newNotification.ownerId}}})}}}});if(newNotifications.length>0){if(mode.includes("mongo")){await this.setMongoData(user,newNotifications,true,this.getToken(user))}else{this.setLocalData(newNotifications)}for(const uid in usersToNotify){this.users[uid]?.sendAll({route:"structNotification",args:true})}return true}else return false};queryMongo=async(user,collection,queryObj={},findOne=false,skip=0,token)=>{if(!collection&&!queryObj)return void 0;else if(findOne){let res=await this.db.collection(collection).findOne(queryObj);if(!res)return void 0;let passed=!this.useAuths;if(!res?.ownerId){passed=true}else if(getStringId(user._id)!==res.ownerId||getStringId(user._id)===res.ownerId&&user.userRoles?.admincontrol){if(this.useAuths)passed=await this.checkAuthorization(user,res,"READ",token)}if(passed)return res;else return void 0}else{let res=this.db.collection(collection).find(queryObj).sort({$natural:-1}).skip(skip);let structs=[];let arr=await res.toArray();if(arr.length>0){let passed=!this.useAuths;let checkedAuth="";for(const s of arr){if(!s?.ownerId){passed=true}else if((getStringId(user._id)!==s.ownerId||getStringId(user._id)===s.ownerId&&user.userRoles?.admincontrol)&&checkedAuth!==s.ownerId){if(this.useAuths)passed=await this.checkAuthorization(user,s,"READ",token);checkedAuth=s.ownerId}if(passed)structs.push(s)}}return structs}};setMongoData=async(user,structs=[],notify=true,token)=>{let firstwrite=false;if(structs.length>0){let passed=!this.useAuths;let checkedAuth="";await Promise.all(structs.map(async struct=>{let secondary={};if(Array.isArray(struct)){secondary=struct[1];struct=struct[0]}if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if((getStringId(user._id)!==struct.ownerId||getStringId(user._id)===struct.ownerId&&user.userRoles?.admincontrol)&&checkedAuth!==struct.ownerId){if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);checkedAuth=struct.ownerId}if(passed){if(struct.structType){if(!this.collections[struct.structType]){this.collections[struct.structType]={};this.collections[struct.structType].reference={}}let copy=JSON.parse(JSON.stringify(struct));if(copy._id)delete copy._id;if(struct._id){if(getStringId(struct._id).includes("defaultId")){await this.db.collection(struct.structType?struct.structType:"data").insertOne(copy);firstwrite=true}else if(struct.structType==="notification")await this.db.collection(struct.structType?struct.structType:"data").updateOne({_id:struct._id},{$set:copy,...secondary},{upsert:true,unique:false});else await this.db.collection(struct.structType?struct.structType:"data").updateOne({_id:toObjectId(struct._id)},{$set:copy,...secondary},{upsert:true})}else if(struct.structType){this.db.collection(struct.structType?struct.structType:"data").insertOne(copy)}}}}));if(firstwrite===true){let toReturn=[];await Promise.all(structs.map(async(struct,j)=>{let copy=JSON.parse(JSON.stringify(struct));if(copy._id&©.structType!=="profile")delete copy._id;if(struct.structType!=="comment"){let pulled;if(struct.structType!=="notification")pulled=await this.db.collection(copy.structType).findOne(copy);if(pulled){pulled._id=getStringId(pulled._id);toReturn.push(pulled)}}else if(struct.structType==="comment"){let comment=struct;let copy2=JSON.parse(JSON.stringify(comment));if(copy2._id)delete copy2._id;let pulledComment=await this.db.collection("comment").findOne(copy2);let replyToId=pulledComment?.replyTo;let replyTo=structs.find(s=>{if(getStringId(s._id)===replyToId)return true});if(replyTo){let copy3=JSON.parse(JSON.stringify(replyTo));if(copy3._id)delete copy3._id;let pulledReply;await Promise.all(["discussion","chatroom","comment"].map(async name=>{let found=await this.db.collection(name).findOne({_id:toObjectId(replyToId)});if(found)pulledReply=found}));if(pulledReply){let roomId=getStringId(pulledComment.parent._id);let room,pulledRoom;if(roomId!==replyToId){room=structs.find(s=>{if(getStringId(s._id)===roomId)return true});if(room){delete room._id;await Promise.all(["discussion","chatroom"].map(async name=>{let found=await this.db.collection(name).findOne(room);if(found)pulledRoom=found}))}}else pulledRoom=pulledReply;let toUpdate=[pulledComment];if(pulledReply){let i=pulledReply.replies.indexOf(getStringId(pulledComment._id));if(i<0){pulledReply.replies.push(getStringId(pulledComment._id));pulledComment.replyTo=getStringId(pulledReply._id)}toUpdate.push(pulledReply)}if(pulledRoom){let i=pulledRoom.comments.indexOf(pulledComment._id);if(i<0){pulledRoom.comments.push(getStringId(pulledComment._id));pulledComment.parent._id=getStringId(pulledRoom._id)}}await Promise.all(toUpdate.map(async s=>{let copy4=JSON.parse(JSON.stringify(s));delete copy4._id;await this.db.collection(s.structType).updateOne({_id:toObjectId(s._id)},{$set:copy4},{upsert:false})}));[...toReturn].reverse().forEach((s,j2)=>{if(toUpdate.find(o=>{if(getStringId(s._id)===getStringId(o._id))return true})){toReturn.splice(toReturn.length-j2-1,1)}});toReturn.push(...toUpdate)}}else if(pulledComment){toReturn.push(pulledComment)}}}));if(notify)this.checkToNotify(user,toReturn);return toReturn}else{let non_notes=[];structs.forEach(s=>{if(s.structType!=="notification")non_notes.push(s)});if(notify)this.checkToNotify(user,non_notes);return true}}else return false};setMongoUser=async(user,struct,token)=>{if(struct._id){const _id=toObjectId(struct._id);let usersearch={_id};let userexists=await this.collections.profile.instance.findOne(usersearch);if(userexists){if(getStringId(user._id)!==struct.ownerId||getStringId(user._id)===struct.ownerId&&user.userRoles?.admincontrol){let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(!passed)return false}}let copy=JSON.parse(JSON.stringify(struct));copy._id=_id;if(this.debug)console.log("RETURNS PROFILE",struct);await this.collections.profile.instance.updateOne(usersearch,{$set:copy},{upsert:true});user=await this.collections.profile.instance.findOne(usersearch);this.checkToNotify(user,[struct]);return user}else return false};setGroup=async(user,struct,mode=this.mode,token)=>{if(struct?._id){let uid=getStringId(user._id);let exists=void 0;if(mode.includes("mongo")){exists=await this.collections.group.instance.findOne({name:struct.name})}else{exists=this.getLocalData("group",{_id:getStringId(struct._id)})}if(exists&&(exists.ownerId!==struct.ownerId||struct.admins.indexOf(uid)<0))return false;if(uid!==struct.ownerId){let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(!passed)return false}let allusers=[];Object.keys(struct.users).forEach(u2=>{allusers.push({email:u2},{id:u2},{username:u2})});let users={};let ids={};if(mode.includes("mongo")){let cursor=this.collections.profile.instance.find({$or:allusers});let arr=cursor.toArray();if(arr.length>0){arr.forEach(user2=>{users[uid]=user2;ids[uid]=true})}}else{allusers.forEach(search=>{let result=this.getLocalData("profile",search);if(result.length>0){users[getStringId(result[0]._id)]=result[0];ids[getStringId(result[0]._id)]=true}})}struct.users=ids;let admins={};let peers={};let clients={};Object.keys(users).forEach(id=>{let u2=users[id];if(struct.admins[getStringId(u2._id)]||struct.admins[u2.email]||struct.admins[u2.username]||struct.admins[struct.ownerId]){if(!admins[getStringId(u2._id)])admins[getStringId(u2._id)]=true}if(struct.peers[getStringId(u2._id)]||struct.peers[u2.email]||struct.peers[u2.username]||struct.peers[struct.ownerId]){if(!peers[getStringId(u2._id)])peers[getStringId(u2._id)]=true}if(struct.clients[getStringId(u2._id)]||struct.clients[u2.email]||struct.clients[u2.username]||struct.clients[struct.ownerId]){if(!clients[getStringId(u2._id)])clients[getStringId(u2._id)]=true}});struct.admins=admins;struct.peers=peers;struct.clients=clients;let copy=JSON.parse(JSON.stringify(struct));if(copy._id)delete copy._id;if(mode.includes("mongo")){if(getStringId(struct._id).includes("defaultId")){await this.db.collection(struct.structType?struct.structType:"data").insertOne(copy);delete struct._id;struct=await this.db.collection(struct.structType?struct.structType:"data").findOne(struct);struct._id=getStringId(struct._id)}else await this.collections.group.instance.updateOne({_id:toObjectId(struct._id)},{$set:copy},{upsert:true})}else{this.setLocalData(struct)}this.checkToNotify(user,[struct],this.mode);if(this.debug)console.log("setGroup: user:",user,"output",struct);return struct}else return false};getMongoUser=(user,info="",requireAuth=true,basicInfo=false,token)=>{return new Promise(async resolve=>{const query=[{email:info},{id:info},{username:info}];try{query.push({_id:toObjectId(info)})}catch(e){console.log("error creating ObjectId with ",info)}let u2=await this.collections.profile.instance.findOne({$or:query});if(!u2||u2==null)resolve(void 0);else{u2._id=getStringId(u2._id);if(!u2.ownerId)u2.ownerId=u2._id;if(basicInfo){if(this.useAccessTokens||this.useRefreshTokens){if(this.getToken(user)!==token)resolve(void 0)}let stripped={username:u2.username,firstName:u2.firstName,lastName:u2.lastName,fullName:u2.fullName,pictureUrl:u2.pictureUrl,_id:u2._id};u2=stripped;resolve({user:u2})}else if(requireAuth){if(getStringId(user._id)!==u2._id||getStringId(user._id)===u2._id&&user.userRoles?.admincontrol){let passed=!this.useAuths;if(this.useAuths)passed=await this.checkAuthorization(user,u2,"READ",token);if(!passed)resolve(void 0)}let authorizations=[];let auths=this.collections.authorization.instance.find({ownerId:u2._id});let aarr=await auths.toArray();if(auths.toArray().length>0){aarr.forEach(d2=>authorizations.push(d2))}let gs=this.collections.group.instance.find({users:{$all:[u2._id]}});let arr=await gs.toArray();let groups=[];if(arr.length>0){arr.forEach(d2=>groups.push(d2))}resolve({user:u2,authorizations,groups})}else{if(this.useAccessTokens||this.useRefreshTokens){if(this.getToken(user)!==token)resolve(void 0)}resolve({user:u2})}}})};queryUsers=(user,info="",limit=0,skip=0,requireAuth=false,token)=>{if(typeof user==="string")user=this.users[user];if(!user)return;return new Promise(async resolve=>{let q={$regex:`^${info}`,$options:"i"};const query=[{email:q},{username:q},{firstName:q},{lastName:q},{name:q}];let arr;if(this.mode.includes("mongo")){let users=this.collections.profile.instance.find({$or:query},{projection:shallowqueryDummy}).skip(skip);if(limit>0)users.limit(limit);await users;arr=await users.toArray()}else{arr=[];for(let i=0;i{arr.push({firstName:u2.firstName,lastName:u2.lastName,fullName:u2.fullName,username:u2.username,pictureUrl:u2.pictureUrl})})}else if(dat)arr.push({firstName:dat.firstName,lastName:dat.lastName,fullName:dat.fullName,username:dat.username,pictureUrl:dat.pictureUrl})}}if(requireAuth){let result=[];let strid=getStringId(user._id);for(let i=0;i{let usrs=[];userIds.forEach(u2=>{try{usrs.push({_id:toObjectId(u2)})}catch{}});let found=[];if(usrs.length>0){let users=this.collections.profile.instance.find({$or:usrs});let arr=await users.toArray();if(arr.length>0){arr.forEach(u2=>{if(basicInfo){found.push({username:u2.username,firstName:u2.firstName,lastName:u2.lastName,fullName:u2.fullName,pictureUrl:u2.pictureUrl,_id:u2._id})}else found.push(u2)})}}return found};getMongoUsersByRole=async(user,role)=>{let users=this.collections.profile.instance.find({userRoles:{$all:{[role]:true}}});let found=[];let arr=await users.toArray();if(arr.length>0){arr.forEach(u2=>{found.push(u2)})}return found};getMongoDataByIds=async(user,structIds,ownerId,collection,token)=>{let uid=getStringId(user._id);if(structIds.length>0){let query=[];structIds.forEach(_id=>{let q={_id:toObjectId(_id)};if(ownerId)q.ownerId=ownerId;query.push(q)});let found=[];if(!collection){await Promise.all(Object.keys(this.collections).map(async name=>{let cursor=await this.db.collection(name).find({$or:query});let arr=await cursor.toArray();if(arr.length>0){let passed=true;let checkedAuth="";for(let i=0;i0){let passed=true;let checkedAuth="";arr.forEach(async s=>{if(!s?.ownerId)passed=true;else if((uid!==s.ownerId||uid===s.ownerId&&user.userRoles?.admincontrol)&&checkedAuth!==s.ownerId){if(this.useAuths)passed=await this.checkAuthorization(user,s,"READ",token);checkedAuth=s.ownerId}if(passed)found.push(s)})}}return found}};getMongoData=async(user,collection,ownerId,dict={},limit=0,skip=0,token)=>{if(!ownerId)ownerId=dict?.ownerId;if(!dict)dict={};if(dict._id)dict._id=toObjectId(dict._id);let uid=getStringId(user._id);let structs=[];let passed=true;let checkedAuth="";let cursor;if(!collection&&!ownerId&&!dict)return[];else if(!collection&&ownerId&&Object.keys(dict).length===0)return await this.getAllUserMongoData(user,ownerId);else if((!dict||Object.keys(dict).length===0)&&ownerId&&collection){cursor=this.db.collection(collection).find({ownerId}).sort({$natural:-1}).skip(skip)}else if(collection&&Object.keys(dict).length>0){if(ownerId)dict.ownerId=ownerId;cursor=await this.db.collection(collection).find(dict).sort({$natural:-1}).skip(skip)}if(cursor){if(limit>0)cursor.limit(limit);let arr=await cursor.toArray();if(arr.length>0){for(let i=0;i0&&!ownerId){await Promise.all(Object.keys(this.collections).map(async name=>{cursor=await this.db.collection(name).find(dict).sort({$natural:-1}).skip(skip);;if(cursor){if(limit>0)cursor.limit(limit);let arr=await cursor.toArray();if(arr.length>0){for(let i=0;i{let structs=[];let passed=true;let checkedId="";await Promise.all(Object.keys(this.collections).map(async(name,j)=>{if(passed&&excluded.indexOf(name)<0){let query={ownerId};if(timeRange){if(typeof timeRange[0]==="string")timeRange[0]=genTimestampFromString(timeRange[0]);if(typeof timeRange[1]==="string")timeRange[1]=genTimestampFromString(timeRange[1]);query.timestamp={$gt:timeRange[0],$lt:timeRange[1]}}let cursor=this.db.collection(name).find(query);let arr=await cursor.toArray();let count=arr.length;for(let k=0;k{let structs=[];if(structs.length>0){let checkedAuth="";structRefs.forEach(async ref=>{if(ref.structType&&getStringId(ref._id)){let struct=await this.db.collection(ref.structType).findOne({_id:toObjectId(ref._id)});if(struct){let passed=true;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if((getStringId(user._id)!==struct.ownerId||getStringId(user._id)===struct.ownerId&&user.userRoles?.admincontrol)&&checkedAuth!==struct.ownerId){if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);checkedAuth=struct.ownerId}if(passed===true){structs.push(struct)}}}})}return structs};getMongoAuthorizations=async(user,ownerId=getStringId(user._id),authId="",token)=>{let auths=[];if(authId.length===0){let cursor=this.collections.authorization.instance.find({ownerId});let arr=await cursor.toArray();if(arr.length>0){arr.forEach(a=>{auths.push(a)})}}else auths.push(await this.collections.authorization.instance.findOne({_id:toObjectId(authId),ownerId}));if(!auths[0]?.ownerId)true;else if(getStringId(user._id)!==auths[0]?.ownerId){let passed=!this.useAuths;if(this.useAuths)passed=await this.checkAuthorization(user,auths[0],"READ",token);if(!passed)return void 0}return auths};getMongoGroups=async(user,userId=getStringId(user._id),groupId="")=>{let groups=[];if(groupId.length===0){let cursor=this.collections.group.instance.find({users:{$all:[userId]}});let arr=await cursor.toArray();if(arr.length>0){arr.forEach(a=>{groups.push(a)})}}else{try{groups.push(await this.collections.group.instance.findOne({_id:toObjectId(groupId),users:{$all:[userId]}}))}catch{}}return groups};deleteMongoData=async(user,structRefs=[],token)=>{let structs=[];await Promise.all(structRefs.map(async ref=>{try{let _id=toObjectId(ref._id);let struct=await this.db.collection(ref.structType).findOne({_id});if(struct){structs.push(struct);let notifications=await this.collections.notifications.instance.find({parent:{structType:ref.structType,_id:getStringId(ref._id)}});let count=notifications.toArray().length;for(let i=0;i{let passed=true;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if((struct.ownerId!==getStringId(user._id)||getStringId(user._id)===struct.ownerId&&user.userRoles?.admincontrol)&&struct.ownerId!==checkedOwner){checkedOwner=struct.ownerId;if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token)}if(passed){await this.db.collection(struct.structType?struct.structType:"data").deleteOne({_id:toObjectId(struct._id)});if(struct.users){Object.keys(struct.users).forEach(uid=>{if(uid!==getStringId(user._id)&&uid!==struct.ownerId&&this.users[uid])this.users[uid]?.sendAll({route:"structDeleted",args:{_id:getStringId(struct._id),structType:struct.structType}})})}if(struct.ownerId!==user._id&&this.users[struct.ownerId]){this.users[struct.ownerId]?.sendAll({route:"structDeleted",args:{_id:getStringId(struct._id),structType:struct.structType}})}}}));return true};deleteMongoUser=async(user,userId,deleteData,token)=>{if(getStringId(user._id)!==userId||getStringId(user._id)===userId&&user.userRoles?.admincontrol){let u2=await this.collections.profile.instance.findOne({id:userId});let passed=!this.useAuths;if(!u2?.ownerId)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,u2,"WRITE",token);if(!passed)return false}await this.collections.profile.instance.deleteOne({id:userId});if(deleteData){for(const key in this.collections){this.collections[key].instance.deleteMany({ownerId:userId});this.collections[key].instance.updateMany({users:{[userId]:true}},{$unset:{[`users.${userId}`]:""}})}}if(getStringId(user._id)!==userId&&this.users[userId])this.users[userId]?.sendAll({route:"structDeleted",args:{_id:userId,structType:"profile"}});return true};deleteMongoGroup=async(user,groupId,token)=>{let s=await this.collections.group.instance.findOne({_id:toObjectId(groupId)});if(s){if(!s?.ownerId)true;else if(getStringId(user._id)!==s.ownerId||getStringId(user._id)===s.ownerId&&user.userRoles?.admincontrol){let passed=!this.useAuths;if(this.useAuths)passed=await this.checkAuthorization(user,s,"WRITE",token);if(!passed)return false}if(s.users){Object.keys(s.users).forEach(u2=>{this.users[u2]?.sendAll({route:"structDeleted",args:{_id:getStringId(s._id),structType:s.structType}})})}await this.collections.group.instance.deleteOne({_id:toObjectId(groupId)});return true}else return false};deleteMongoAuthorization=async(user,authId,token)=>{let s=await this.collections.authorization.instance.findOne({_id:toObjectId(authId)});let uid=getStringId(user._id);if(s){if(uid!==s.ownerId||uid===s.ownerId&&user.userRoles?.admincontrol){let passed=!this.useAuths;if(!s?.ownerId)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,s,"WRITE",token);if(!passed)return false}if(s.associatedAuthId){if(this.debug)console.log(s);await this.collections.authorization.instance.deleteOne({_id:toObjectId(s.associatedAuthId)});if(s.authorizerId!==uid)this.users[s.authorizerId]?.sendAll({route:"structDeleted",args:{_id:getStringId(s.associatedAuthId),structType:s.structType}});else if(s.authorizedId!==uid)this.users[s.authorizedId]?.sendAll({route:"structDeleted",args:{_id:getStringId(s.associatedAuthId),structType:s.structType}})}await this.collections.authorization.instance.deleteOne({_id:toObjectId(authId)});if(s.authorizerId===uid)this.users[s.authorizerId]?.sendAll({route:"structDeleted",args:{_id:getStringId(s._id),structType:s.structType}});else if(s.authorizedId===uid)this.users[s.authorizedId]?.sendAll({route:"structDeleted",args:{_id:getStringId(s._id),structType:s.structType}});return true}else return false};setAuthorization=async(user,authStruct,token)=>{let u1,u2;let mmode=this.mode.includes("mongo");if(mmode){u1=(await this.getMongoUser(user,authStruct.authorizedId,false)).user;u2=(await this.getMongoUser(user,authStruct.authorizerId,false)).user}else{u1=this.getLocalData("profile",{"_id":authStruct.authorizedId})?.[0];u2=this.getLocalData("profile",{"_id":authStruct.authorizerId})?.[0]}if(!u1||!u2)return false;if(authStruct.authorizedId!==getStringId(u1._id))authStruct.authorizedId=getStringId(u1._id);if(authStruct.authorizerId!==getStringId(u2._id))authStruct.authorizerId=getStringId(u2._id);if(!authStruct.authorizedName){if(u1.name)authStruct.authorizedName=u1.name;else if(u1.username)authStruct.authorizedName=u1.username;else if(u1.email)authStruct.authorizedName=u1.email}if(!authStruct.authorizerName){if(u1.name)authStruct.authorizedName=u1.name;else if(u2.username)authStruct.authorizerName=u2.username;else if(u2.email)authStruct.authorizerName=u2.email}if(!authStruct?.ownerId)true;else if((getStringId(user._id)!==authStruct.ownerId||getStringId(user._id)===authStruct.ownerId&&user.userRoles?.admincontrol)&&(getStringId(user._id)!==authStruct.authorizedId&&getStringId(user._id)!==authStruct.authorizerId)){let passed=!this.useAuths;if(this.useAuths)passed=await this.checkAuthorization(user,authStruct,"WRITE",token);if(!passed)return false}let auths=[];if(mmode){let s=await this.collections.authorization.instance.find({$and:[{authorizedId:authStruct.authorizedId},{authorizerId:authStruct.authorizerId}]});let arr=await s.toArray();if(arr.length>0){arr.forEach(d2=>auths.push(d2))}}else{let s=this.getLocalData("authorization",{authorizedId:authStruct.authorizedId});if(Array.isArray(s)){s.forEach(d2=>{if(d2.authorizerId===authStruct.authorizerId)auths.push(d2)})}}let otherAuthset;if(Array.isArray(auths)){for(let i=0;i{if(typeof user==="string"){if(this.users[user])user=this.users[user];else user={_id:user}}if(!user||!struct)return false;if(!struct.ownerId)return true;if(typeof user==="object"){if(struct.ownerId===getStringId(user._id)){if(user.userRoles?.["admincontrol"]){}return true}}if(this.useAccessTokens){if(!this.accessTokens.get(user._id)||this.accessTokens.get(user._id)!==token){return false}}else if(this.useRefreshTokens){if(!this.refreshTokens.get(user._id)||this.refreshTokens.get(user._id)!==token){return false}}let auth1,auth2;if(this.mode.includes("mongo")){auth1=await this.collections.authorization.instance.findOne({$or:[{authorizedId:getStringId(user._id),authorizerId:struct.ownerId,ownerId:getStringId(user._id)},{authorizedId:struct.ownerId,authorizerId:getStringId(user._id),ownerId:getStringId(user._id)}]});if(!auth1)return false;auth2=await this.collections.authorization.instance.findOne({$or:[{authorizedId:getStringId(user._id),authorizerId:struct.ownerId,ownerId:getStringId(struct.ownerId)},{authorizedId:struct.ownerId,authorizerId:getStringId(user._id),ownerId:getStringId(struct.ownerId)}]})}else{auth1=this.getLocalData("authorization",{ownerId:getStringId(user._id)}).find(o=>{if(o.authorizedId===getStringId(user._id)&&o.authorizerId===struct.ownerId)return true});auth2=this.getLocalData("authorization",{ownerId:struct.ownerId}).find(o=>{if(o.authorizedId===getStringId(user._id)&&o.authorizerId===struct.ownerId)return true})}if(!auth1||!auth2){return false}let passed=false;if(auth1.status==="OKAY"&&auth2.status==="OKAY"){if(struct.structType==="group"){if(auth1.authorizations[struct.name+"_admin"]&&auth2.authorizations[struct.name+"_admin"])passed=true}else if(auth1.authorizations["peer"]&&auth2.authorizations["peer"])passed=true;else if(auth1.authorizations["admincontrol"]&&auth2.authorizations["admincontrol"])passed=true;else if(auth1.structIds[getStringId(struct._id)]&&auth2.structIds[getStringId(struct._id)])passed=true;else if(auth1.excluded[struct.structType]&&struct.ownerId===getStringId(user._id)&&request==="WRITE")passed=false}return passed};wipeDB=async()=>{await Promise.all(Object.values(this.collections).map(c=>{try{c.instance.remove({})}catch(err){}}));return true};overwriteLocalData=structs=>{if(Array.isArray(structs)){structs.forEach(struct=>{let localdat=this.getLocalData(struct.structType,{"ownerId":struct.ownerId,"_id":getStringId(struct._id)});if(!localdat||localdat?.length===0){this.setLocalData(struct)}else Object.assign(localdat,struct)})}else{let localdat=this.getLocalData(structs.structType,{"ownerId":structs.ownerId,"_id":getStringId(structs._id)});if(!localdat||localdat?.length===0){this.setLocalData(structs)}else Object.assign(localdat,structs)}};setLocalData=structs=>{let setInCollection=s=>{let type=s.structType;let collection=this.collections[type]?.reference;if(!collection){collection={};if(!this.collections[type])this.collections[type]={};this.collections[type].reference=collection}collection[getStringId(s._id)]=s};if(Array.isArray(structs)){structs.forEach(s=>{setInCollection(s)})}else setInCollection(structs)};getLocalData=(collection,query)=>{let ownerId,key,value;if(typeof query==="object"){ownerId=query.ownerId;const keys=Object.keys(query).filter(k=>k!="ownerId");key=keys[0];value=query[key]}else value=query;if(!collection&&!ownerId&&!key&&!value)return[];let result=[];if(!collection&&(ownerId||key)){Object.values(this.collections).forEach(c=>{c=c.reference;if((key==="_id"||key==="id")&&value){let found=c[value];if(found)result.push(found)}else{Object.values(c).forEach(struct=>{if(key&&value){if(struct[key]===value&&struct.ownerId===ownerId){result.push(struct)}}else if(struct.ownerId===ownerId){result.push(struct)}})}});return result}else{let c=this.collections[collection]?.reference;if(!c)return result;if(!key&&!ownerId){Object.values(c).forEach(struct=>{result.push(struct)});return result}if((key==="_id"||key==="id")&&value)return getStringId(c[value]);else{Object.keys(c).forEach(k=>{const struct=c[k];if(key&&value&&!ownerId){if(struct[key]===value)result.push(struct)}else if(ownerId&&!key){if(struct.ownerId===ownerId)result.push(struct)}else if(ownerId&&key&&value){if(struct.ownerId===ownerId&&struct[key]){if(struct[key]===value)result.push(struct)}}})}}return result};deleteLocalData=struct=>{if(!struct)throw new Error("Struct not supplied");if(!struct.structType||!struct._id)return false;if(this.collections[struct.structType])delete this.collections[struct.structType].reference[struct._id];return true}};var shallowqueryDummy=DataStructures_exports.ProfileStruct();for(const key in shallowqueryDummy){if(key==="username"||key==="lastName"||key==="firstName"||key==="name"||key==="_id"||key==="pictureUrl")shallowqueryDummy[key]=1;else delete shallowqueryDummy[key]}var Systems={collision:{setupEntities:function(entities){for(const key in entities){const entity=entities[key];if(entity.components){if(!entity.components[this.__node.tag])continue}this.setupEntity(entity)}return entities},setupEntity:function(entity){if(!("collisionEnabled"in entity))entity.collisionEnabled=true;if(!entity.collisionType)entity.collisionType="sphere";if(!entity.collisionRadius)entity.collisionRadius=1;if(!entity.collisionBoundsScale)entity.collisionBoundsScale={x:1,y:1,z:1};if(!entity.colliding)entity.colliding={};if(!entity.position)entity.position={x:0,y:0,z:0};return entity},__node:{tag:"collision"},__operator:function(entities){let keys=this.entityKeys;for(let i=0;i{if(body1.collisionEnabled===false||body2.collisionEnabled===false)return false;const dist=Systems.collision.distance(body1.position,body2.position);if(dist{if(dist===void 0)dist=Systems.collision.distance(body1.position,body2.position);return dist{let body1minX=(body1.position.x-body1.collisionRadius)*body1.collisionBoundsScale.x;let body1maxX=(body1.position.x+body1.collisionRadius)*body1.collisionBoundsScale.x;let body1minY=(body1.position.y-body1.collisionRadius)*body1.collisionBoundsScale.y;let body1maxY=(body1.position.y+body1.collisionRadius)*body1.collisionBoundsScale.y;let body1minZ=(body1.position.z-body1.collisionRadius)*body1.collisionBoundsScale.z;let body1maxZ=(body1.position.z+body1.collisionRadius)*body1.collisionBoundsScale.z;let body2minX=(body2.position.x-body2.collisionRadius)*body1.collisionBoundsScale.x;let body2maxX=(body2.position.x+body2.collisionRadius)*body1.collisionBoundsScale.x;let body2minY=(body2.position.y-body2.collisionRadius)*body1.collisionBoundsScale.y;let body2maxY=(body2.position.y+body2.collisionRadius)*body1.collisionBoundsScale.y;let body2minZ=(body2.position.z-body2.collisionRadius)*body1.collisionBoundsScale.z;let body2maxZ=(body2.position.z+body2.collisionRadius)*body1.collisionBoundsScale.z;return(body1maxX<=body2maxX&&body1maxX>=body2minX||body1minX<=body2maxX&&body1minX>=body2minX)&&(body1maxY<=body2maxY&&body1maxY>=body2minY||body1minY<=body2maxY&&body1minY>=body2minY)&&(body1maxZ<=body2maxZ&&body1maxZ>=body2minZ||body1minZ<=body2maxZ&&body1minZ>=body2minZ)},sphereBoxCollisionCheck:(sphere,box,dist)=>{let boxMinX=(box.position.x-box.collisionRadius)*box.collisionBoundsScale.x;let boxMaxX=(box.position.x+box.collisionRadius)*box.collisionBoundsScale.x;let boxMinY=(box.position.y-box.collisionRadius)*box.collisionBoundsScale.y;let boxMaxY=(box.position.y+box.collisionRadius)*box.collisionBoundsScale.y;let boxMinZ=(box.position.z-box.collisionRadius)*box.collisionBoundsScale.z;let boxMaxZ=(box.position.z+box.collisionRadius)*box.collisionBoundsScale.z;let clamp={x:Math.max(boxMinX,Math.min(sphere.position.x,boxMaxX)),y:Math.max(boxMinY,Math.min(sphere.position.y,boxMaxY)),z:Math.max(boxMinZ,Math.min(sphere.position.z,boxMaxZ))};if(dist===void 0)dist=Systems.collision.distance(sphere.position,clamp);return dist>sphere.collisionRadius},isPointInsideSphere:(point,sphere,dist)=>{if(dist===void 0)dist=Systems.collision.distance(point,sphere.position);return dist{let boxminX=(box.position.x-box.collisionRadius)*box.collisionBoundsScale.x;let boxmaxX=(box.position.x+box.collisionRadius)*box.collisionBoundsScale.x;let boxminY=(box.position.y-box.collisionRadius)*box.collisionBoundsScale.x;let boxmaxY=(box.position.y+box.collisionRadius)*box.collisionBoundsScale.x;let boxminZ=(box.position.z-box.collisionRadius)*box.collisionBoundsScale.x;let boxmaxZ=(box.position.z+box.collisionRadius)*box.collisionBoundsScale.x;return point.x>=boxminX&&point.x<=boxmaxX&&(point.y>=boxminY&&point.y<=boxmaxY)&&(point.z>=boxminZ&&point.z<=boxmaxZ)},closestPointOnLine:(point,lineStart,lineEnd)=>{let a={x:lineEnd.x-lineStart.x,y:lineEnd.y-lineStart.y,z:lineEnd.z-lineStart.z};let b={x:lineStart.x-point.x,y:lineStart.y-point.y,z:lineStart.z-point.z};let c={x:lineEnd.x-point.x,y:lineEnd.y-point.y,z:lineEnd.z-point.z};let bdota=Systems.collision.dot(b,a);if(bdota<=0)return lineStart;let cdota=Systems.collision.dot(c,a);if(cdota<=0)return lineEnd;let _bdotapluscdota=1/(bdota+cdota);return{x:lineStart.x+(lineEnd.x-lineStart.x)*bdota*_bdotapluscdota,y:lineStart.y+(lineEnd.y-lineStart.y)*bdota*_bdotapluscdota,z:lineStart.z+(lineEnd.z-lineStart.z)*bdota*_bdotapluscdota}},closestPointOnPolygon:(point,t0,t1,t2)=>{let n=Systems.collision.calcNormal(t0,t1,t2);let dist=Systems.collision.dot(point,n)-Systems.collision.dot(t0,n);let projection=Systems.collision.vecadd(point,Systems.collision.vecscale(n,-dist));let v0x=t2[0]-t0[0];let v0y=t2[1]-t0[1];let v0z=t2[2]-t0[2];let v1x=t1[0]-t0[0];let v1y=t1[1]-t0[1];let v1z=t1[2]-t0[2];let v2x=projection[0]-t0[0];let v2y=projection[1]-t0[1];let v2z=projection[2]-t0[2];let dot00=v0x*v0x+v0y*v0y+v0z*v0z;let dot01=v0x*v1x+v0y*v1y+v0z*v1z;let dot02=v0x*v2x+v0y*v2y+v0z*v2z;let dot11=v1x*v1x+v1y*v1y+v1z*v1z;let dot12=v1x*v2x+v1y*v2y+v1z*v2z;let denom=dot00*dot11-dot01*dot01;if(Math.abs(denom)<1e-30){return void 0}let _denom=1/denom;let u2=(dot11*dot02-dot01*dot12)*_denom;let v2=(dot00*dot12-dot01*dot02)*_denom;if(u2>=0&&v2>=0&&u2+v2<1){return projection}else return void 0},calcNormal:(t0,t1,t2,positive=true)=>{var QR=Systems.collision.makeVec(t0,t1);var QS=Systems.collision.makeVec(t0,t2);if(positive===true){return Systems.collision.normalize(Systems.collision.cross3D(QR,QS))}else{return Systems.collision.normalize(Systems.collision.cross3D(QS,QR))}},dot:(v1,v2)=>{let dot=0;for(const key in v1){dot+=v1[key]*v2[key]}return dot},makeVec(p1,p2){return{x:p2.x-p1.x,y:p2.y-p1.y,z:p2.z-p1.z}},vecadd:(v1,v2)=>{let result=Object.assign({},v1);for(const key in result){result[key]+=v2[key]}return result},vecsub:(v1,v2)=>{let result=Object.assign({},v1);for(const key in result){result[key]-=v2[key]}return result},vecmul:(v1,v2)=>{let result=Object.assign({},v1);for(const key in result){result[key]*=v2[key]}return result},vecdiv:(v1,v2)=>{let result=Object.assign({},v1);for(const key in result){result[key]/=v2[key]}return result},vecscale:(v1,scalar)=>{let result=Object.assign({},v1);for(const key in result){result[key]*=scalar}return result},distance:(v1,v2)=>{let distance=0;for(const key in v1){distance+=Math.pow(v1[key]-v2[key],2)}return Math.sqrt(distance)},magnitude:v2=>{let magnitude=0;for(const key in v2){magnitude+=v2[key]*v2[key]}return Math.sqrt(magnitude)},normalize:v2=>{let magnitude=Systems.collision.magnitude(v2);let _mag=magnitude?1/magnitude:0;let vn={};for(const key in v2){vn[key]=v2[key]*_mag}return vn},distance3D(v1,v2){return Math.sqrt((v1.x-v2.x)*(v1.x-v2.x)+(v1.y-v2.y)*(v1.y-v2.y)+(v1.z-v2.z)*(v1.z-v2.z))},cross3D(v1,v2){return{x:v1.y*v2.z-v1.z*v2.y,y:v1.z*v2.x-v1.x*v2.z,z:v1.x*v2.y-v1.y*v2.x}},nearestNeighborSearch(entities,isWithinRadius=1e15){var tree={};;for(const key in entities){let newnode={tag:key,position:void 0,neighbors:[]};newnode.position=entities[key].position;tree[key]=newnode}for(const i in tree){for(const j in tree){var dist=Systems.collision.distance3D(tree[i].position,tree[j].position);if(distxx)minX=xx;if(maxYyy)minY=yy;if(maxZzz)minZ=zz;if(minRadius>body.collisionRadius)minRadius=body.collisionRadius;positions[key]=body.position};let head=JSON.parse(JSON.stringify(dynamicBoundingVolumeTree.proto));let boxpos={x:(maxX+minX)*.5,y:(maxY+minY)*.5,z:(maxZ+minZ)*.5};let boxbounds={x:maxX-boxpos.x,y:maxY-boxpos.y,z:maxZ-boxpos.z};head.position=boxpos;head.collisionBoundsScale=boxbounds;head.entities=entities;dynamicBoundingVolumeTree.tree=head;minRadius*=2;if(mode==="octree"){let genOct=function(parentPos,halfbounds){let oct1={x:parentPos.x+halfbounds.x,y:parentPos.y+halfbounds.y,z:parentPos.z+halfbounds.z};let oct2={x:parentPos.x-halfbounds.x,y:parentPos.y+halfbounds.y,z:parentPos.z+halfbounds.z};let oct3={x:parentPos.x+halfbounds.x,y:parentPos.y-halfbounds.y,z:parentPos.z+halfbounds.z};let oct4={x:parentPos.x+halfbounds.x,y:parentPos.y+halfbounds.y,z:parentPos.z-halfbounds.z};let oct5={x:parentPos.x-halfbounds.x,y:parentPos.y-halfbounds.y,z:parentPos.z+halfbounds.z};let oct6={x:parentPos.x-halfbounds.x,y:parentPos.y+halfbounds.y,z:parentPos.z-halfbounds.z};let oct7={x:parentPos.x+halfbounds.x,y:parentPos.y-halfbounds.y,z:parentPos.z-halfbounds.z};let oct8={x:parentPos.x-halfbounds.x,y:parentPos.y-halfbounds.y,z:parentPos.z-halfbounds.z};return[oct1,oct2,oct3,oct4,oct5,oct6,oct7,oct8]},genOctTree=function(head2){let halfbounds={x:head2.collisionBoundsScale.x*.5,y:head2.collisionBoundsScale.y*.5,z:head2.collisionBoundsScale.z*.5};let octPos=genOct(head2.position,halfbounds);let check=Object.assign({},head2.bodies);for(let i=0;i<8;i++){let octquadrant=Object.assign(JSON.parse(JSON.stringify(dynamicBoundingVolumeTree.proto)),{position:octPos[i],collisionBoundsScale:halfbounds});octquadrant.parent=head2;for(const j in check){let collided=Systems.collision.collisionCheck(check[j],octquadrant);if(collided){octquadrant.entities[j]=check[j];delete check[j]}}if(Object.keys(octquadrant.entities).length>minEntities-1){head2.children[i]=octquadrant;octquadrant.parent=head2;if(Object.keys(octquadrant.entities).length>minEntities&&octquadrant.collisionRadius*.5>minRadius){genOctTree(octquadrant)}}}};genOctTree(head);return head}else{let tree=Systems.collision.nearestNeighborSearch(positions,withinRadius);let keys=Object.keys(tree);let tag=keys[Math.floor(Math.random()*keys.length)];let searching=true;let count=0;let genBoundingBoxLevel=(tree2,volumes)=>{let newVolumes={};let foundidxs={};let treekeys=Object.keys(tree2);while(searching&&countuxn)ux=uxn;if(mxuyn)uy=uyn;if(myuzn)uz=uzn;if(mz2){let nextTree=Systems.collision.nearestNeighborSearch(result,withinRadius);result=genBoundingBoxLevel(nextTree,result)}head.children=result;head.children.forEach(n=>{n.parent=head});return head}}},collider:{lastTime:performance.now(),setupEntities:function(entities){for(const key in entities){const entity=entities[key];if(entity.components){if(!entity.components[this.__node.tag])continue}this.setupEntity(entity)}return entities},setupEntity:function(entity){if(!("collisionEnabled"in entity))Systems.collision.setupEntity(entity);if(!("boundingBox"in entity))entity.boundingBox={bot:0,top:100,left:0,right:100,front:0,back:100};if(!("position"in entity)){Systems.movement.setupEntity(entity)}if(!("restitution"in entity))entity.restitution=1;if(!("useBoundingBox"in entity))entity.useBoundingBox=true;if(!entity.position.x&&!entity.position.y&&!entity.position.z){entity.position.x=Math.random()*entity.boundingBox.right;entity.position.y=Math.random()*entity.boundingBox.back;entity.position.z=Math.random()*entity.boundingBox.top}return entity},__operator:function(entities){let keys=this.entityKeys;for(let i=0;i{const xsize=entity.collisionRadius*entity.collisionBoundsScale.x;const ysize=entity.collisionRadius*entity.collisionBoundsScale.y;const zsize=entity.collisionRadius*entity.collisionBoundsScale.z;if(entity.position.y-ysize<=entity.boundingBox.front){entity.velocity.y*=-entity.restitution;entity.position.y=entity.boundingBox.front+ysize}if(entity.position.y+ysize>=entity.boundingBox.back){entity.velocity.y*=-entity.restitution;entity.position.y=entity.boundingBox.back-ysize}if(entity.position.x-xsize<=entity.boundingBox.left){entity.velocity.x*=-entity.restitution;entity.position.x=entity.boundingBox.left+xsize}if(entity.position.x+xsize>=entity.boundingBox.right){entity.velocity.x*=-entity.restitution;entity.position.x=entity.boundingBox.right-xsize}if(entity.position.z-zsize<=entity.boundingBox.bot){entity.velocity.z*=-entity.restitution;entity.position.z=entity.boundingBox.bot+zsize}if(entity.position.z+zsize>=entity.boundingBox.top){entity.velocity.z*=-entity.restitution;entity.position.z=entity.boundingBox.top-zsize}},resolveBoxCollision:(body1,box,negate)=>{let positionVec=Systems.collision.makeVec(body1.position,box.position);var directionVec=Object.values(positionVec);let closestSide;let closestDist=Infinity;let mul=-1;if(directionVec[idx]<0)mul=1;if(negate)mul=-mul;for(const key in body1.position){let dist=Math.abs(box.position[key]-body1.position[key]);if(dist{if(dist===void 0)dist=Systems.collision.distance(entity1.position,entity2.position);let vecn=Systems.collision.normalize(Systems.collision.makeVec(entity1.position,entity2.position));let sumMass=entity1.mass+entity2.mass;let ratio=entity1.mass/sumMass;let rmin=1-ratio;if(entity1.fixed===false){entity1.position.x+=vecn.x*rmin*1.01;entity1.position.y+=vecn.y*rmin*1.01;entity1.position.z+=vecn.z*rmin*1.001}else{entity2.position.x-=vecn.x*1.01;entity2.position.y-=vecn.y*1.01;entity2.position.z-=vecn.z*1.01}if(entity2.fixed===false){entity2.position.x+=vecn.x*ratio*1.01;entity2.position.y+=vecn.y*ratio*1.01;entity2.position.z+=vecn.z*ratio*1.01}else{entity1.position.x+=vecn.x*1.01;entity1.position.y+=vecn.y*1.01;entity1.position.z+=vecn.z*1.01}dist=Systems.collision.distance(entity1.position,entity2.position);let vrel={x:entity1.velocity.x-entity2.velocity.x,y:entity1.velocity.y-entity2.velocity.y,z:entity1.velocity.z-entity2.velocity.z};let speed=vrel.x*vecn.x+vrel.y*vecn.y+vrel.z*vecn.z;if(speed>0){let impulse=2*speed/sumMass;if(entity1.fixed===false){entity1.velocity.x-=impulse*vecn.x*entity2.mass*entity1.restitution;entity1.velocity.y-=impulse*vecn.y*entity2.mass*entity1.restitution;entity1.velocity.z-=impulse*vecn.z*entity2.mass*entity1.restitution}if(entity2.fixed===false){entity2.velocity.x+=impulse*vecn.x*entity2.mass*entity2.restitution/entity2.mass;entity2.velocity.y+=impulse*vecn.y*entity2.mass*entity2.restitution/entity2.mass;entity2.velocity.z+=impulse*vecn.z*entity2.mass*entity2.restitution/entity2.mass}}}},nbody:{lastTime:performance.now(),G:6674e-14,setupEntities:function(entities){for(const key in entities){const entity=entities[key];if(entity.components){if(!entity.components[this.__node.tag])continue}this.setupEntity(entity)}return entities},setupEntity:function(entity){if(!("collisionEnabled"in entity))Systems.collider.setupEntity(entity);entity.isAttractor=true;if(!("attractorGroup"in entity))entity.attractorGroup=0;if(!("attractorFrameSearchMax"in entity))entity.attractorFrameSearchMax=10;if(!("attractorGroupRules"in entity))entity.attractorGroupRules={0:{G:this.G,maxDist:void 0}};return entity},__operator:function(entities){let keys=this.entityKeys;for(let i=0;ientity.attractorFrameSearchMax)break nested}}return entities},__node:{tag:"nbody"},attract:function(body1,body2,dist,G=this.G,vecn){if(dist===void 0)dist=Systems.collision.distance3D(body1.position,body2.position);if(vecn===void 0)vecn=Systems.collision.normalize(Systems.collision.makeVec(body1.position,body2.position));let Fg=0;if(dist<.01)dist=.01;if(body1.attractorGroupRules[body2.attractorGroup]){if(typeof body1.attractorGroupRules[body2.attractorGroup]==="object"){if(body1.attractorGroupRules[body2.attractorGroup].maxDist&&body1.attractorGroupRules[body2.attractorGroup].maxDist1e3){entity.boid.groupSize=1;entity.boid.searchLimit=1}return entity},__operator:function(entities){let now=performance.now();let timeStep=now-this.lastTime;this.lastTime=now;let keys=this.entityKeys;let length=keys.length;let _timeStep=1/timeStep;let w2=-1;outer:for(let i=0;ip0.boid.groupSize||k>p0.boid.searchLimit){break nested}let randj=keys[Math.floor(Math.random()*length)];if(k===w2||randj===keys[i]||inRange.indexOf(randj)>-1){continue nested}else{let pr=entities[randj];let disttemp=Math.sqrt((p0.position.x-pr.position.x)*(p0.position.x-pr.position.x)+(p0.position.y-pr.position.y)*(p0.position.y-pr.position.y)+(p0.position.z-pr.position.z)*(p0.position.z-pr.position.z));if(disttemp>p0.boid.groupRadius){continue nested}else{distances.push(disttemp);inRange.push(randj);let distInv;if(p0.boid.useSeparation||p0.boid.useAlignment){distInv=p0.boid.groupRadius/(disttemp*disttemp);if(distInv>p0.maxSpeed)distInv=p0.maxSpeed;else if(distInv<-p0.maxSpeed)distInv=-p0.maxSpeed}if(p0.boid.useCohesion){boidVelocities[0]+=(pr.position.x-p0.position.x)*.5*disttemp*_timeStep;boidVelocities[1]+=(pr.position.y-p0.position.y)*.5*disttemp*_timeStep;boidVelocities[2]+=(pr.position.z-p0.position.z)*.5*disttemp*_timeStep}if(isNaN(disttemp)||isNaN(boidVelocities[0])||isNaN(pr.position.x)){console.log(disttemp,i,randj,p0.position,pr.position,boidVelocities);p0.position.x=NaN;return}if(p0.boid.useSeparation){boidVelocities[3]=boidVelocities[3]+(p0.position.x-pr.position.x)*distInv;boidVelocities[4]=boidVelocities[4]+(p0.position.y-pr.position.y)*distInv;boidVelocities[5]=boidVelocities[5]+(p0.position.z-pr.position.z)*distInv}if(p0.boid.useAttraction&&pr.boid.useAttraction){Systems.nbody.attract(p0,pr,disttemp)}if(p0.boid.useAlignment){boidVelocities[6]=boidVelocities[6]+pr.velocity.x*distInv;boidVelocities[7]=boidVelocities[7]+pr.velocity.y*distInv;boidVelocities[8]=boidVelocities[8]+pr.velocity.z*distInv}groupCount++}}}let _groupCount=1/groupCount;if(p0.boid.useCohesion){boidVelocities[0]=p0.boid.cohesion*(boidVelocities[0]*_groupCount);boidVelocities[1]=p0.boid.cohesion*(boidVelocities[1]*_groupCount);boidVelocities[2]=p0.boid.cohesion*(boidVelocities[2]*_groupCount)}else{boidVelocities[0]=0;boidVelocities[1]=0;boidVelocities[2]=0}if(p0.boid.useSeparation){boidVelocities[3]=p0.boid.separation*boidVelocities[3];boidVelocities[4]=p0.boid.separation*boidVelocities[4];boidVelocities[5]=p0.boid.separation*boidVelocities[5]}else{boidVelocities[3]=0;boidVelocities[4]=0;boidVelocities[5]=0}if(p0.boid.useAlignment){boidVelocities[6]=-(p0.boid.alignment*boidVelocities[6]*_groupCount);boidVelocities[7]=p0.boid.alignment*boidVelocities[7]*_groupCount;boidVelocities[8]=p0.boid.alignment*boidVelocities[8]*_groupCount}else{boidVelocities[6]=0;boidVelocities[7]=0;boidVelocities[8]=0}const swirlVec=[0,0,0];if(p0.boid.useSwirl==true){boidVelocities[9]=-(p0.position.y-p0.boid.swirl.y)*p0.boid.swirl.mul;boidVelocities[10]=(p0.position.z-p0.boid.swirl.z)*p0.boid.swirl.mul;boidVelocities[11]=(p0.position.x-p0.boid.swirl.x)*p0.boid.swirl.mul}const attractorVec=[0,0,0];if(p0.boid.useAttractor==true){boidVelocities[12]=(p0.boid.attractor.x-p0.position.x)*p0.boid.attractor.mul;if(p0.position.x>p0.boundingBox.left||p0.position.xp0.boundingBox.top||p0.position.yp0.boundingBox.front||p0.position.z0){let magnitude=Systems.collision.magnitude(entity.velocity);if(magnitude>entity.maxSpeed){let scalar=entity.maxSpeed/magnitude;entity.velocity.x*=scalar;entity.velocity.y*=scalar;entity.velocity.z*=scalar}}if(entity.velocity.x)entity.position.x+=entity.velocity.x*timeStep;if(entity.velocity.y)entity.position.y+=entity.velocity.y*timeStep;if(entity.velocity.z)entity.position.z+=entity.velocity.z*timeStep}return entities}}};var y=class{r;g;b;a;constructor(e,t,l,o){this.r=e,this.g=t,this.b=l,this.a=o}};var w=class{intensity;visible;numPoints;xy;color;scaleX;scaleY;offsetX;offsetY;loop;webglNumPoints;_vbuffer;_coord;constructor(){this.scaleX=1,this.scaleY=1,this.offsetX=0,this.offsetY=0,this.loop=false,this._vbuffer=0,this._coord=0,this.visible=true,this.intensity=1,this.xy=new Float32Array([]),this.numPoints=0,this.color=new y(0,0,0,1),this.webglNumPoints=0}};var v=class extends w{currentIndex=0;constructor(e,t){super(),this.webglNumPoints=t,this.numPoints=t,this.color=e,this.xy=new Float32Array(2*this.webglNumPoints)}setX(e,t){this.xy[e*2]=t}setY(e,t){this.xy[e*2+1]=t}getX(e){return this.xy[e*2]}getY(e){return this.xy[e*2+1]}lineSpaceX(e,t){for(let l=0;l{let l={x:0,y:0};return l.x=u2.x+e.x*t,l.y=u2.y+e.y*t,l};var A=u2=>P(-u2.y,u2.x);var p=(u2,e)=>{let t=R(u2,e);return t=M(t),t};var T=(u2,e)=>{let t={x:0,y:0};return t.x=u2.x+e.x,t.y=u2.y+e.y,t};var C=(u2,e)=>u2.x*e.x+u2.y*e.y;var M=u2=>{let e={x:0,y:0},t=u2.x*u2.x+u2.y*u2.y;return t>0&&(t=1/Math.sqrt(t),e.x=u2.x*t,e.y=u2.y*t),e};var P=(u2,e)=>{let t={x:0,y:0};return t.x=u2,t.y=e,t};var R=(u2,e)=>{let t={x:0,y:0};return t.x=u2.x-e.x,t.y=u2.y-e.y,t};var X=u2=>{let e,t={x:0,y:0},l={x:0,y:0},o=[],a=(s,r)=>{o.push({vec2:s,miterLength:r})},h=s=>({x:u2[s*2],y:u2[s*2+1]});t=p(h(1),h(0)),e=A(t),a(e,1);let n=u2.length/2;for(let s=1;s{let t=T(u2,e);return t=M(t),P(-t.y,t.x)};var N=(u2,e,t)=>{let l=P(-u2.y,u2.x);return t/C(e,l)};var d=class extends w{currentIndex=0;_linePoints;_thicknessRequested=0;_actualThickness=0;constructor(e,t,l){super(),this.webglNumPoints=t*2,this.numPoints=t,this.color=e,this._thicknessRequested=l,this._linePoints=new Float32Array(t*2),this.xy=new Float32Array(2*this.webglNumPoints)}convertToTriPoints(){let e=this._actualThickness/2,t=X(this._linePoints);for(let l=0;l{if(l.visible){t.useProgram(this._progLine);let o=t.getUniformLocation(this._progLine,"uscale");t.uniformMatrix2fv(o,false,new Float32Array([l.scaleX*this.gScaleX*(this.gLog10X?1/Math.log(10):1),0,0,l.scaleY*this.gScaleY*this.gXYratio*(this.gLog10Y?1/Math.log(10):1)]));let a=t.getUniformLocation(this._progLine,"uoffset");t.uniform2fv(a,new Float32Array([l.offsetX+this.gOffsetX,l.offsetY+this.gOffsetY]));let h=t.getUniformLocation(this._progLine,"is_log");t.uniform2iv(h,new Int32Array([this.gLog10X?1:0,this.gLog10Y?1:0]));let n=t.getUniformLocation(this._progLine,"uColor");t.uniform4fv(n,[l.color.r,l.color.g,l.color.b,l.color.a]),t.bufferData(t.ARRAY_BUFFER,l.xy,t.STREAM_DRAW),t.drawArrays(l.loop?t.LINE_LOOP:t.LINE_STRIP,0,l.webglNumPoints)}})}_drawSurfaces(e){let t=this.webgl;e.forEach(l=>{if(l.visible){t.useProgram(this._progLine);let o=t.getUniformLocation(this._progLine,"uscale");t.uniformMatrix2fv(o,false,new Float32Array([l.scaleX*this.gScaleX*(this.gLog10X?1/Math.log(10):1),0,0,l.scaleY*this.gScaleY*this.gXYratio*(this.gLog10Y?1/Math.log(10):1)]));let a=t.getUniformLocation(this._progLine,"uoffset");t.uniform2fv(a,new Float32Array([l.offsetX+this.gOffsetX,l.offsetY+this.gOffsetY]));let h=t.getUniformLocation(this._progLine,"is_log");t.uniform2iv(h,new Int32Array([this.gLog10X?1:0,this.gLog10Y?1:0]));let n=t.getUniformLocation(this._progLine,"uColor");t.uniform4fv(n,[l.color.r,l.color.g,l.color.b,l.color.a]),t.bufferData(t.ARRAY_BUFFER,l.xy,t.STREAM_DRAW),t.drawArrays(t.TRIANGLE_STRIP,0,l.webglNumPoints)}})}_drawTriangles(e){let t=this.webgl;t.bufferData(t.ARRAY_BUFFER,e.xy,t.STREAM_DRAW),t.useProgram(this._progLine);let l=t.getUniformLocation(this._progLine,"uscale");t.uniformMatrix2fv(l,false,new Float32Array([e.scaleX*this.gScaleX*(this.gLog10X?1/Math.log(10):1),0,0,e.scaleY*this.gScaleY*this.gXYratio*(this.gLog10Y?1/Math.log(10):1)]));let o=t.getUniformLocation(this._progLine,"uoffset");t.uniform2fv(o,new Float32Array([e.offsetX+this.gOffsetX,e.offsetY+this.gOffsetY]));let a=t.getUniformLocation(this._progLine,"is_log");t.uniform2iv(a,new Int32Array([0,0]));let h=t.getUniformLocation(this._progLine,"uColor");t.uniform4fv(h,[e.color.r,e.color.g,e.color.b,e.color.a]),t.drawArrays(t.TRIANGLE_STRIP,0,e.xy.length/2)}_drawThickLines(){this._thickLines.forEach(e=>{if(e.visible){let t=Math.min(this.gScaleX,this.gScaleY);e.setActualThickness(e.getThickness()/t),e.convertToTriPoints(),this._drawTriangles(e)}})}update(){this.clear(),this.draw()}draw(){this._drawLines(this.linesData),this._drawLines(this.linesAux),this._drawThickLines(),this._drawSurfaces(this.surfaces)}clear(){this.webgl.clear(this.webgl.COLOR_BUFFER_BIT)}_addLine(e){e._vbuffer=this.webgl.createBuffer(),this.webgl.bindBuffer(this.webgl.ARRAY_BUFFER,e._vbuffer),this.webgl.bufferData(this.webgl.ARRAY_BUFFER,e.xy,this.webgl.STREAM_DRAW),e._coord=this.webgl.getAttribLocation(this._progLine,"coordinates"),this.webgl.vertexAttribPointer(e._coord,2,this.webgl.FLOAT,false,0,0),this.webgl.enableVertexAttribArray(e._coord)}addDataLine(e){this._addLine(e),this.linesData.push(e)}addLine=this.addDataLine;addAuxLine(e){this._addLine(e),this.linesAux.push(e)}addThickLine(e){this._addLine(e),this._thickLines.push(e)}addSurface(e){this._addLine(e),this.surfaces.push(e)}initThinLineProgram(){let e=` - attribute vec2 coordinates; - uniform mat2 uscale; - uniform vec2 uoffset; - uniform ivec2 is_log; - - void main(void) { - float x = (is_log[0]==1) ? log(coordinates.x) : coordinates.x; - float y = (is_log[1]==1) ? log(coordinates.y) : coordinates.y; - vec2 line = vec2(x, y); - gl_Position = vec4(uscale*line + uoffset, 0.0, 1.0); - }`,t=this.webgl.createShader(this.webgl.VERTEX_SHADER);this.webgl.shaderSource(t,e),this.webgl.compileShader(t);let l=` - precision mediump float; - uniform highp vec4 uColor; - void main(void) { - gl_FragColor = uColor; - }`,o=this.webgl.createShader(this.webgl.FRAGMENT_SHADER);this.webgl.shaderSource(o,l),this.webgl.compileShader(o),this._progLine=this.webgl.createProgram(),this.webgl.attachShader(this._progLine,t),this.webgl.attachShader(this._progLine,o),this.webgl.linkProgram(this._progLine)}popDataLine(){this.linesData.pop()}removeAllLines(){this._linesData=[],this._linesAux=[],this._thickLines=[],this._surfaces=[]}removeDataLines(){this._linesData=[]}removeAuxLines(){this._linesAux=[]}viewport(e,t,l,o){this.webgl.viewport(e,t,l,o)}log(e){this.debug&&console.log("[webgl-plot]:"+e)}};var S=class u{constructor(){this.plots={};this.renderOverlay=(e,t,l,o,a,h=1,n=0)=>{if(typeof l.settings.overlay=="object"&&(o.useOverlay||!("useOverlay"in o))){let s=l.settings.nLines-o.position-1,r=e.height*s/l.settings.nLines,i=e.height*(s+1)/l.settings.nLines;if(t.clearRect(0,r,e.width,i),l.settings.mode==="sweep"){t.strokeStyle=l.settings.sweepColor?l.settings.sweepColor:"rgba(0,255,0,0.8)",t.beginPath();let f=e.width*o.ct/o.values.length;t.moveTo(f,r),t.lineTo(f,i),t.stroke()}if(t.fillStyle=l.settings.overlayColor?l.settings.overlayColor:"white",a&&t.fillText(a,20,e.height*(s+.2)/l.settings.nLines),o.nSec){let f=this.formatTime(o.nSec);t.fillText(`${f}`,l.settings.mode==="sweep"?e.width-35:20,e.height*(s+.9)/l.settings.nLines),t.fillText("0:00",l.settings.mode==="sweep"?20:e.width-35,e.height*(s+.9)/l.settings.nLines)}typeof h=="number"&&t.fillText(`${Math.floor(h)===h?h:h?.toFixed(5)} ${o.units?o.units:""}`,e.width-100,e.height*(s+.2)/l.settings.nLines),typeof n=="number"&&t.fillText(`${Math.floor(n)===n?n:n?.toFixed(5)} ${o.units?o.units:""}`,e.width-100,e.height*(s+.8)/l.settings.nLines)}}}initPlot(e,t){if(t||(t=new x2(e.canvas,e.webglOptions)),!e._id)e._id=`plot${Math.floor(Math.random()*1e15)}`;else if(this.plots[e._id]){let r=this.plots[e._id].initial;if(e.lines){for(let i in e.lines)if(r.lines[i]&&Array.isArray(e.lines[i])){let f=e.lines[i];e.lines[i]=r.lines[i]}}e=Object.assign(r,e)}e.overlay&&(typeof e.overlay!="object"&&(e.overlay=document.createElement("canvas"),e.overlay.style.position="absolute",e.overlay.width=e.canvas.width,e.overlay.height=e.canvas.height,e.canvas.appendChild(e.overlay)),e.overlayCtx||(e.overlayCtx=e.overlay.getContext("2d"))),e.width&&(e.canvas.width=e.width,e.canvas.style&&(e.canvas.style.width=e.width+"px"),typeof e.overlay=="object"&&(e.overlay.width=e.width,e.overlay.style&&(e.overlay.style.width=e.width+"px"))),e.height&&(e.canvas.height=e.height,e.canvas.style&&(e.canvas.style.height=e.height+"px"),typeof e.overlay=="object"&&(e.overlay.height=e.height,e.overlay.style&&(e.overlay.style.height=e.height+"px"))),e.lines?.timestamp&&delete e.lines.timestamp,e.lines||(e.lines={});let l={};for(let r in e.lines)l[r]=Object.assign({},l[r]),"viewing"in e.lines[r]||(e.lines[r].viewing=true),l[r].viewing=e.lines[r].viewing,l[r].sps=e.lines[r].sps,l[r].nSec=e.lines[r].nSec,l[r].nPoints=e.lines[r].nPoints,l[r].ymin=e.lines[r].ymin,l[r].ymax=e.lines[r].ymax,l[r].units=e.lines[r].units;let o={plot:t,settings:e,initial:Object.assign(Object.assign({},e),{lines:l}),anim:()=>{t.update()}};this.plots[e._id]=o;let a=0,h=0;Object.keys(e.lines).forEach(r=>{e.lines[r]?.viewing!==false&&h++}),e.nLines=h;let n,s;typeof e.overlay=="object"&&(n=e.overlay,s=e.overlayCtx,s.clearRect(0,0,e.overlay.width,e.overlay.height),s.font=e.overlayFont?e.overlayFont:"1em Courier",s.fillStyle=e.overlayColor?e.overlayColor:"white");for(let r in e.lines){let i=e.lines[r];if(Array.isArray(i)&&(i={values:i},e.lines[r]=i),"viewing"in i||(i.viewing=true),i.color)Array.isArray(i.color)&&(i.color=new y(...i.color));else{let m=u.HSLToRGB(360*(a/h)%360,100,50,1);o.initial.lines[r].color=[...m,1],i.color=new y(...m,1)}let f;if(i.nSec&&i.sps?f=Math.ceil(i.nSec*i.sps):i.nPoints?f=i.nPoints:i.points?f=i.points:e.linePoints?f=e.linePoints:i.values?f=i.values.length:f=1e3,i.points=f,e.lines[r].viewing===false)continue;if((i.width||e.lineWidth)&&i.width!==0){let m=e.lineWidth;m||(m=i.width),i.width?i.line=new d(i.color,f,i.width):e.lineWidth&&(i.line=new d(i.color,f,e.lineWidth)),i.line.lineSpaceX(-1,2/i.line.numPoints)}else i.line=new v(i.color,f),i.line.arrangeX();i.values?.length===i.points?i.values.length!==f&&(i.interpolate?i.values.length>f?i.values=u.downsample(i.values,f):i.values.lengthi.points?i.values=i.values.slice(i.values.length-i.points):i.values=[...new Array(i.points-i.values.length).fill(0),...i.values]):Array.isArray(i.values)?i.values.length>f?i.values=i.values.slice(i.values.length-f):i.values.lengthg){let m=c;g=c,c=m}let _=Math.abs(c);if(i.absmax=_>g?_:g,"autoscale"in i||(i.autoscale=true),i.position||(i.position=e.nLines-a-1),i.autoscale?i.autoscale===2?("clamp"in i||(i.clamp=true),i.scaled=u.autoscale(i.values,i.position,h,i.centerZero,c,g,i.clamp)):(i.scaled=i.values,i.line.scaleY=u.getYScalar(i.values,h,i.centerZero,c,g),i.line.offsetY=u.getYOffset(i.position,h,c,i.line.scaleY)):i.scaled=i.values,i.scaled.forEach((m,L)=>i.line.setY(L,m)),i.line instanceof d?t.addThickLine(i.line):i.line instanceof v&&t.addDataLine(i.line),"xAxis"in i||(i.xAxis=true),i.xAxis){i.xColor?Array.isArray(i.xColor)&&(i.xColor=new y(...i.xColor)):i.xColor=new y(1,1,1,.3);let m=new v(i.xColor,2),L=i.autoscale?(a+1)*2/h-1-1/h:0;m.constY(L),m.arrangeX(),m.xy[2]=1,i.x=m,t.addAuxLine(m)}if(h>1&&i.autoscale&&a!==h-1){e.dividerColor?Array.isArray(e.dividerColor)&&(e.dividerColor=new y(...e.dividerColor)):e.dividerColor=new y(1,1,1,1);let m=new v(e.dividerColor,2);m.constY(i.autoscale?(a+1)*2/h-1:1),m.arrangeX(),m.xy[2]=1,i.divider=m,t.addAuxLine(m)}if(typeof e.overlay=="object"&&(i.useOverlay||!("useOverlay"in i))){let m=e.nLines-i.position-1;s.fillText(r,20,n.height*(m+.2)/e.nLines),s.fillText(`${Math.floor(g)===g?g:g?.toFixed(5)} ${i.units?i.units:""}`,n.width-100,n.height*(m+.2)/e.nLines),s.fillText(`${Math.floor(c)===c?c:c?.toFixed(5)} ${i.units?i.units:""}`,n.width-100,n.height*(m+.9)/e.nLines)}a++}return requestAnimationFrame(o.anim),this.plots[e._id]}deinitPlot(e){return typeof e=="string"&&(e=this.plots[e]),e.plot.clear(),e.plot.removeAllLines(),true}reinitPlot(e,t){if(typeof e=="string"){let l=e;e=this.plots[e],t._id||(t._id=l)}if(e.plot)return e.plot.clear(),e.plot.removeAllLines(),e.settings.overlayCtx&&e.settings.overlayCtx.clearRect(0,0,e.settings.overlay?.width,e.settings.overlay?.height),this.initPlot(t,e.plot)}getChartSettings(e,t){let l=this.plots[e];if(l){let o=Object.assign({},l.initial);for(let a in l.initial.lines)typeof l.initial.lines[a]?.ymax!="number"&&(o.lines[a].ymax=l.settings.lines[a]?.ymax),typeof l.initial.lines[a]?.ymin!="number"&&(o.lines[a].ymin=l.settings.lines[a]?.ymin),t&&(o.lines[a].values=l.settings.lines[a].values);return delete o.canvas,delete o.overlay,delete o.overlayCtx,o}}update(e,t,l=true){if(typeof e=="string"&&(e=this.plots[e]),!e)return false;let o,a;if(typeof e.settings.overlay=="object"&&(o=e.settings.overlay,a=e.settings.overlayCtx,a.font=e.settings.overlayFont?e.settings.overlayFont:"1em Courier",a.fillStyle=e.settings.overlayColor?e.settings.overlayColor:"white"),t){let h=false;for(let n in t)if(e.settings.lines[n]&&e.settings.lines[n].line){if(e.settings.lines[n]?.viewing===false)continue;let s=e.settings.lines[n];if(s.values){if(e.settings.mode&&e.settings.mode==="sweep"){"ct"in s||(s.ct=0);let g=b=>{s.ct>s.values.length&&(s.ct=0),s.values[s.ct]=b,s.ct++};Array.isArray(t[n])?(s.ct===0&&(s.values=new Array(s.values.length).fill(t[n][t[n].length-1])),t[n].forEach(g)):typeof t[n]=="number"?(s.ct===0&&(s.values=new Array(s.values.length).fill(t[n])),g(t[n])):t[n].values&&(s.ct===0&&(s.values=new Array(s.values.length).fill(t[n].values[t[n].values.length-1])),t[n].values.forEach(g))}else Array.isArray(t[n])&&s.values?.length<1e5?(s.values.length===0?(s.values.length=s.points?s.points:1e3,s.values.fill(t[n][t[n].length-1]),s.firstWrite=true):s.firstWrite||(s.values.fill(t[n][t[n].length-1]),s.firstWrite=true),t[n].length===s.values.length?s.values=t[n]:u.circularBuffer(s.values,t[n])):typeof t[n]=="number"?(s.firstWrite||(s.values.fill(t[n]),s.firstWrite=true),s.values.push(t[n]),s.values.shift()):t[n]?.values&&(s.values.length===0?(s.values.length=s.points?s.points:1e3,s.values.fill(t[n].values[t[n].values.length-1]),s.firstWrite=true):s.firstWrite||(s.values.fill(t[n].values[t[n].values.length-1]),s.firstWrite=true),t[n].values.length===s.values.length?s.values=t[n].values:u.circularBuffer(s.values,t[n].values));s.values.length!==s.points&&(s.interpolate?s.values.length>s.points?s.values=u.downsample(s.values,s.points):s.scaled.lengths.points?s.values.splice(0,s.values.length-s.points):s.values=new Array(s.points).fill(0).splice(s.points-s.values.length,0,s.values));let r=s.ymin,i=s.ymax,f=s.values.length<=1e5;if(r===i?(i=f?Math.max(...s.values):1,r=f?Math.min(...s.values):0):isNaN(i)&&(i=f?Math.max(...s.values):1),isNaN(r)&&(r=f?Math.min(...s.values):0),r>i){let g=r;i=r,r=g}let c=Math.abs(r);s.absmax=c>i?c:i,s.autoscale?s.autoscale===2?s.scaled=u.autoscale(s.values,s.position,e.settings.nLines,s.centerZero,r,i,s.clamp):(s.scaled=s.values,s.line.scaleY=u.getYScalar(s.values,e.settings.nLines,s.centerZero,r,i),s.line.offsetY=u.getYOffset(s.position,e.settings.nLines,r,s.line.scaleY)):s.scaled=s.values,s.scaled.forEach((g,b)=>{!s.autoscale&&s.absmax>1?s.line.setY(b,g/s.absmax):s.line.setY(b,g)}),this.renderOverlay(o,a,e,s,n,i,r)}}else e.settings.generateNewLines&&!n.includes("timestamp")&&(Array.isArray(t[n])&&(t[n]={values:t[n]}),!t[n].nSec&&!t[n].nPoints&&!e.settings.linePoints&&(t[n].nPoints=1e3),h=true);if(h)return e.settings.cleanGeneration||Object.keys(e.initial.lines).forEach(n=>{t[n]?t[n]=Object.assign(e.initial.lines[n],t[n]):t[n]=e.initial.lines[n]}),this.reinitPlot(e,{_id:e.settings._id,lines:t}),true}else for(let h in e.settings.lines){let n=e.settings.lines[h];this.renderOverlay(o,a,e,n,h,n.ymax,n.ymin)}return l&&requestAnimationFrame(e.anim),true}updateLine(e,t,l,o,a,h,n){return e.numPoints!==t.length&&(l?e.numPoints>t.length?t=u.downsample(t,e.numPoints):e.numPointse.numPoints?t=t.slice(t.length-e.numPoints):t=[...new Array(t.length).fill(0),...t]),o&&(t=u.autoscale(t,a,h,n)),t.forEach((s,r)=>e.setY(r,s)),true}formatTime(e){let t=Math.floor(e/60),l=Math.floor(t/60);t=t%60,e=e%60;let o="";return l>0&&(o+=l+":",t<10&&(o+="0")),o+=t+":",e>0&&(e<10&&(o+="0"),o+=e),o}static autoscale(e,t=0,l=1,o=false,a,h,n){if(e?.length===0)return e;let s=typeof h=="number"?h:e.length<=1e5?Math.max(...e):1,r=typeof a=="number"?a:e.length<=1e5?Math.min(...e):0,i=1/l,f=1;if(o){let c=Math.max(Math.abs(r),Math.abs(s));return c!==0&&(f=i/c),e.map(g=>(n&&(gs&&(g=s)),g*f+(i*(t+1)*2-1-i)))}else return s===r?s!==0?f=i/s:r!==0&&(f=i/Math.abs(r)):f=i/(s-r),e.map(c=>(n&&(cs&&(c=s)),2*((c-r)*f-1/(2*l))+(i*(t+1)*2-1-i)))}static getYScalar(e,t=1,l=false,o,a){if(e?.length===0)return e;let h=typeof a=="number"?a:e.length<=1e5?Math.max(...e):1,n=typeof o=="number"?o:e.length<=1e5?Math.min(...e):0,s=1/t,r=1;if(l){let i=Math.max(Math.abs(n),Math.abs(h));return i!==0&&(r=s/i),2*r}else return h===n?h!==0?r=s/h:n!==0&&(r=s/Math.abs(n)):r=s/(h-n),2*r}static getYOffset(e=0,t=1,l=0,o=1){let a=1/t,h=a*(e+1)*2-1-a;return l!==0?h-=l*o+1/t:h-=o+1/t,h}static absmax(e){return Math.max(Math.abs(Math.min(...e)),Math.max(...e))}static downsample(e,t,l=1){if(e.length>t){let o=new Array(t),a=e.length/t,h=e.length-1,n=0,s=0;for(let r=a;rh&&(i=h);for(let f=n;ft?u.downsample(e,t,l):e.lengthe.length){let l=e.length;e.splice(0,l,...t.slice(t.length-l))}else e.splice(0,e.length,...t);return e}static formatDataForCharts(e,t){if(Array.isArray(e)){if(Array.isArray(e[0])){let l={};if(e.forEach((o,a)=>{l[a]=o}),e=l,isNaN(e[0][0]))return}else if(t){if(e={[t]:e},isNaN(e[t][0]))return}else if(e={0:e},isNaN(e[0][0]))return}else if(typeof e=="object"){for(let l in e)if(typeof e[l]=="number"?e[l]=[e[l]]:e[l]?.values&&typeof e[l].values=="number"&&(e[l].values=[e[l].values]),isNaN(e[l][0]))return}else if(typeof e=="string"){let l;if(e.includes(`\r -`)){let o=e.split(`\r -`);e={},o.forEach((a,h)=>{a.includes(" ")?l=a.split(" "):a.includes(",")?l=a.split(","):a.includes("|")&&(l=a.split("|")),l&&l.forEach((n,s)=>{if(n.includes(":")){let[r,i]=n.split(":"),f=parseFloat(i);isNaN(f)||(e[r]=[f])}else{let r=parseFloat(n);isNaN(r)||(e[s]=[r])}})})}else e.includes(" ")?l=e.split(" "):e.includes(",")?l=e.split(","):e.includes("|")&&(l=e.split("|"));e={},l&&l.forEach((o,a)=>{if(o.includes(":")){let[h,n]=o.split(":"),s=parseFloat(n);isNaN(s)||(e[h]=[s])}else{let h=parseFloat(o);isNaN(h)||(e[a]=[h])}})}else typeof e=="number"&&(t?e={[t]:[e]}:e={0:[e]});return e}static padTime(e,t,l,o){let a=(e[0]-t)/l/o;return[...new Array(o-e.length).map((n,s)=>t+a*(s+1)),...e]}static interpolateForTime(e,t,l){return u.interpolate(e,Math.ceil(l*t))}};var webglPlotRoutes={setupChart:function setupChart(settings){console.log("initializing chart",settings);if(!this?.__node?.graph?.plotter){this.__node.graph.plotter=new S;return this.__node.graph.plotter.initPlot(settings).settings._id}else{globalThis.plotter=new S;return globalThis.plotter.initPlot(settings).settings._id}},updateChartData:function updateChartData(plot,lines,draw=true){if(typeof lines==="object"){if(globalThis.plotter)globalThis.plotter.update(plot,lines,draw);else if(this?.__node?.graph?.plotter)this.__node.graph.plotter.update(plot,lines,draw);return true}return false},clearChart:function clearChart(plot){if(globalThis.plotter)globalThis.plotter.deinitPlot(plot);else if(this?.__node?.graph?.plotter)this.__node.graph.plotter.deinitPlot(plot);return true},resetChart:function resetChart(plot,settings){if(globalThis.plotter)globalThis.plotter.reinitPlot(plot,settings);else if(this?.__node?.graph?.plotter)this.__node.graph.plotter.reinitPlot(plot,settings);return settings._id},getChartSettings:function getChartSettings(plotId){let settings;if(globalThis.plotter)settings=globalThis.plotter.getChartSettings(plotId);else if(this?.__node?.graph?.plotter)settings=this.__node.graph.plotter.getChartSettings(plotId);return settings}};async function setSignalControls(controlsDiv,plotId,streamworker,chartworker,chartSettings,filterSettings){let controls=controlsDiv;if(!controls)return false;if(!chartSettings&&chartworker)chartSettings=await chartworker.run("getChartSettings",plotId);if(!filterSettings&&streamworker)filterSettings=await streamworker.run("getFilterSettings");if(chartSettings?.lines){let body=``;let viewingall=true;let scalingall=true;let n50all=true;let n60all=true;let dcall=true;let lpall=true;let bpall=true;for(const prop in chartSettings.lines){let line=chartSettings.lines[prop];body+=` - - ${prop} - - - - - - - - - - Hz - Hz to Hz - `;if(!line.viewing)viewingall=false;if(!filterSettings[prop]?.useScaling)scalingall=false;if(!filterSettings[prop]?.useNotch50)n50all=false;if(!filterSettings[prop]?.useNotch60)n60all=false;if(!filterSettings[prop]?.useDCBlock)dcall=false;if(!filterSettings[prop]?.useLowpass)lpall=false;if(!filterSettings[prop]?.useBandpass)bpall=false}let head=` - - Name - SPS - Plot nSec - Scalar - Units - Lower Bound - Upper Bound - 50Hz Notch - 60Hz Notch - DC Block - Lowpass - Bandpass - - `;controls.innerHTML=head+body;let viewall=document.getElementById(plotId+"viewing");let usescalar=document.getElementById(plotId+"useScaling");let usen50=document.getElementById(plotId+"useNotch50");let usen60=document.getElementById(plotId+"useNotch60");let usedcb=document.getElementById(plotId+"useDCBlock");let uselp=document.getElementById(plotId+"useLowpass");let usebp=document.getElementById(plotId+"useBandpass");let headeronchange=(checked,idsuffix)=>{for(const prop in chartSettings.lines){let elm=document.getElementById(plotId+prop+idsuffix);if(elm?.checked!==checked)elm.click()}};viewall.onchange=ev2=>{headeronchange(ev2.target.checked,"viewing")};usescalar.onchange=ev2=>{headeronchange(ev2.target.checked,"useScaling")};usen50.onchange=ev2=>{headeronchange(ev2.target.checked,"useNotch50")};usen60.onchange=ev2=>{headeronchange(ev2.target.checked,"useNotch60")};usedcb.onchange=ev2=>{headeronchange(ev2.target.checked,"useDCBlock")};uselp.onchange=ev2=>{headeronchange(ev2.target.checked,"useLowpass")};usebp.onchange=ev2=>{headeronchange(ev2.target.checked,"useBandpass")};for(const prop in chartSettings.lines){let viewing=document.getElementById(plotId+prop+"viewing");let sps=document.getElementById(plotId+prop+"sps");let nSec=document.getElementById(plotId+prop+"nSec");let useScaling=document.getElementById(plotId+prop+"useScaling");let scalar=document.getElementById(plotId+prop+"scalar");let units=document.getElementById(plotId+prop+"units");let ymin=document.getElementById(plotId+prop+"ymin");let ymax=document.getElementById(plotId+prop+"ymax");let useNotch50=document.getElementById(plotId+prop+"useNotch50");let useNotch60=document.getElementById(plotId+prop+"useNotch60");let useDCBlock=document.getElementById(plotId+prop+"useDCBlock");let useLowpass=document.getElementById(plotId+prop+"useLowpass");let lowpassHz=document.getElementById(plotId+prop+"lowpassHz");let useBandpass=document.getElementById(plotId+prop+"useBandpass");let bandpassLower=document.getElementById(plotId+prop+"bandpassLower");let bandpassUpper=document.getElementById(plotId+prop+"bandpassUpper");viewing.onchange=()=>{if(!Array.isArray(chartSettings.lines?.[prop])){(chartSettings.lines?.[prop]).viewing=viewing.checked;chartSettings.generateNewLines=false;chartworker.run("resetChart",[plotId,chartSettings])}};let filteronchange=()=>{let setting={[prop]:{sps:sps.value?parseFloat(sps.value):100,useScaling:useScaling.checked,scalar:scalar.value?parseFloat(scalar.value):1,useNotch50:useNotch50.checked,useNotch60:useNotch60.checked,useDCBlock:useDCBlock.checked,useLowpass:useLowpass.checked,lowpassHz:lowpassHz.value?parseFloat(lowpassHz.value):100,useBandpass:useBandpass.checked,bandpassLower:bandpassLower.value?parseFloat(bandpassLower.value):3,bandpassUpper:bandpassUpper.value?parseFloat(bandpassUpper.value):45,trimOutliers:filterSettings[prop]?.trimOutliers,outlierTolerance:filterSettings[prop]?.outlierTolerance}};streamworker.post("setFilters",setting)};sps.onchange=()=>{filteronchange();(chartSettings.lines?.[prop]).sps=parseFloat(sps.value);(chartSettings.lines?.[prop]).nSec=parseFloat(nSec.value);delete(chartSettings.lines?.[prop]).points;delete(chartSettings.lines?.[prop]).nPoints;chartworker.run("resetChart",[plotId,chartSettings])};units.onchange=()=>{if(!Array.isArray(chartSettings.lines?.[prop])){(chartSettings.lines?.[prop]).units=units.value;chartworker.run("resetChart",[plotId,chartSettings])}};ymax.onchange=()=>{if(!Array.isArray(chartSettings.lines?.[prop])){(chartSettings.lines?.[prop]).ymax=ymax.value?parseFloat(ymax.value):1;(chartSettings.lines?.[prop]).ymin=ymin.value?parseFloat(ymin.value):0;chartworker.run("resetChart",[plotId,chartSettings])}};ymin.onchange=()=>{if(!Array.isArray(chartSettings.lines?.[prop])){(chartSettings.lines?.[prop]).ymax=ymax.value?parseFloat(ymax.value):1;(chartSettings.lines?.[prop]).ymin=ymin.value?parseFloat(ymin.value):0;chartworker.run("resetChart",[plotId,chartSettings])}};nSec.onchange=()=>{if(!Array.isArray(chartSettings.lines?.[prop])){(chartSettings.lines?.[prop]).sps=parseFloat(sps.value);(chartSettings.lines?.[prop]).nSec=parseFloat(nSec.value);delete(chartSettings.lines?.[prop]).points;delete(chartSettings.lines?.[prop]).nPoints;chartworker.run("resetChart",[plotId,chartSettings])}};useScaling.onchange=filteronchange;useNotch50.onchange=filteronchange;useNotch60.onchange=filteronchange;useDCBlock.onchange=filteronchange;useLowpass.onchange=filteronchange;useBandpass.onchange=filteronchange;lowpassHz.onchange=filteronchange;scalar.onchange=filteronchange;bandpassLower.onchange=filteronchange;bandpassUpper.onchange=filteronchange}}}var Math2=class _Math2{constructor(){}static TWO_PI=Math.PI*2;static C=299792458;static G=66743e-15;static h=662607015e-42;static R=8314.32;static Ra=287;static H=69.3;static kbar=1054571817e-43;static kB=1380649e-29;static ke=89875517923e-1;static me=91093837015e-41;static mp=167262192369e-38;static mn=167492749804e-38;static P0=101325;static T0=288.15;static p0=1.225;static Na=60220978e16;static y=1.405;static M0=28.96643;static g0=9.80665;static Re=6378100;static B=1458e-9;static S=110.4;static Sigma=365e-12;static imgkernels={edgeDetection:[[-1,-1,-1],[-1,8,-1],[-1,-1,-1]],boxBlur:[[1/9,1/9,1/9],[1/9,1/9,1/9],[1/9,1/9,1/9]],sobelLeft:[[1,0,-1],[2,0,-2],[1,0,-1]],sobelRight:[[-1,0,1],[-2,0,2],[-1,0,1]],sobelTop:[[1,2,1],[0,0,0],[-1,-2,-1]],sobelBottom:[[-1,2,1],[0,0,0],[1,2,1]],identity:[[0,0,0],[0,1,0],[0,0,0]],gaussian3x3:[[1,2,1],[2,4,2],[1,2,1]],guassian7x7:[[0,0,0,5,0,0,0],[0,5,18,32,18,5,0],[0,18,64,100,64,18,0],[5,32,100,100,100,32,5],[0,18,64,100,64,18,0],[0,5,18,32,18,5,0],[0,0,0,5,0,0,0]],emboss:[[-2,-1,0],[-1,1,1],[0,1,2]],sharpen:[[0,-1,0],[-1,5,-1],[0,-1,0]]};static HSLToRGB=(h,s,l,scalar=255)=>{s/=100;l/=100;let c=(1-Math.abs(2*l-1))*s,x22=c*(1-Math.abs(h/60%2-1)),m=l-c/2,r=0,g=0,b=0;if(0<=h&&h<60){r=c;g=x22;b=0}else if(60<=h&&h<120){r=x22;g=c;b=0}else if(120<=h&&h<180){r=0;g=c;b=x22}else if(180<=h&&h<240){r=0;g=x22;b=c}else if(240<=h&&h<300){r=x22;g=0;b=c}else if(300<=h&&h<360){r=c;g=0;b=x22}r=(r+m)*scalar;g=(g+m)*scalar;b=(b+m)*scalar;return[r,g,b]};static genSineWave=(freq=20,peakAmp=1,nSec=1,fs=512,freq2=0,peakAmp2=1)=>{var sineWave=[];var t=[];var increment=1/fs;for(var ti=0;ti{return Math.sin(this.TWO_PI*frequency*ti+tOffset)*peakAmplitude};static mean=arr=>{var sum=arr.reduce((prev,curr)=>curr+=prev);return sum/arr.length};static median=data=>{const sortedData=data.slice().sort((a,b)=>a-b);const middle=Math.floor(sortedData.length/2);if(sortedData.length%2===0){return(sortedData[middle-1]+sortedData[middle])/2}else{return sortedData[middle]}};static mode=arr=>{return arr.sort((a,b)=>arr.filter(v2=>v2===a).length-arr.filter(v2=>v2===b).length).pop()};static range=data=>{return Math.max(...data)-Math.min(...data)};static std=(arr,mean=void 0)=>{let avg=mean;if(!mean)avg=this.mean(arr);let summed=0;for(let i=0;i{if(actual.length!==forecast.length)throw new Error("Input arrays of same length!");let i=actual.length;let d2=new Array(actual.length);for(let j=0;j{let len=probabilities.length;let entropy=new Array(len);for(let i=0;i{let mean=this.mean(arr);let std=this.std(arr,mean);let z=new Array(arr.length);for(let i=0;ia+(b-mean)**2,0)/arr.length}static coeffVariation=(arr,populationMean)=>{let mean=this.mean(arr);let std=this.std(arr,mean);return populationMean?std/populationMean:std/mean};static coeffDetermination=(observed,expected)=>{const meanY=this.mean(observed);const ssTotal=observed.reduce((acc,y2)=>acc+Math.pow(y2-meanY,2),0);const ssResidual=observed.reduce((acc,y2,i)=>acc+Math.pow(y2-expected[i],2),0);return 1-ssResidual/ssTotal};static percentile=(arr,p2)=>{const sortedData=arr.slice().sort((a,b)=>a-b);const index=Math.ceil(p2*(sortedData.length-1));return sortedData[index]};static interquartileRange=arr=>{const sortedData=arr.slice().sort((a,b)=>a-b);const index=Math.ceil(.25*(sortedData.length-1));const index2=Math.ceil(.75*(sortedData.length-1));const q1=sortedData[index];const q3=sortedData[index2];return q3-q1};static skewness=arr=>{const n=arr.length;const meanValue=this.mean(arr);const stdDevValue=this.std(arr);const sumCubedDeviation=arr.reduce((acc,value)=>acc+Math.pow(value-meanValue,3),0);const skew=sumCubedDeviation/(n*Math.pow(stdDevValue,3));return skew};static kurtosis=arr=>{const n=arr.length;const meanValue=this.mean(arr);const stdDevValue=this.std(arr);const sumFourthDeviation=arr.reduce((acc,value)=>acc+Math.pow(value-meanValue,4),0);const kurt=sumFourthDeviation/(n*Math.pow(stdDevValue,4))-3;return kurt};static chiSquareTest=(observed,expected)=>{const chiSquared=observed.reduce((acc,obs,i)=>{const exp=expected[i];return acc+Math.pow(obs-exp,2)/exp},0);return chiSquared};static simpleLinearRegression=(xCoords,yCoords)=>{const n=xCoords.length;const sumX=xCoords.reduce((sum,x22)=>sum+x22,0);const sumY=yCoords.reduce((sum,y2)=>sum+y2,0);const sumXY=xCoords.reduce((sum,x22,i)=>sum+x22*yCoords[i],0);const sumX2=xCoords.reduce((sum,x22)=>sum+x22*x22,0);const slope=(n*sumXY-sumX*sumY)/(n*sumX2-sumX*sumX);const intercept=(sumY-slope*sumX)/n;return{slope,intercept}};static pad=(arr,pad=1,padValue=0)=>{if(Array.isArray(arr[0]))return pad2D(arr,pad);if(pad>0){let pads=new Array(pad).fill(padValue);arr=[...pads,...arr,...pads]}return arr};static pad2D=(array,pad,padValue=0)=>{let pads=new Array(pad).fill(padValue);const paddedArray=array.map(row=>{return[...pads,...row,...pads]});const paddedRow=new Array(array[0].length+2*pad).fill(padValue);for(let i=0;i{const firstElem=array[0];const lastElem=array[array.length-1];const startPadding=new Array(padSize).fill(firstElem);const endPadding=new Array(padSize).fill(lastElem);return startPadding.concat(array,endPadding)};static edgePad2D=(matrix,padSize)=>{const topRows=Array(padSize).fill(matrix[0]);const bottomRows=Array(padSize).fill(matrix[matrix.length-1]);const paddedMatrix=topRows.concat(matrix,bottomRows);for(let i=0;i{const nVecs=vectors.length;return vectors[0].map((v2,i)=>{for(let j=1;j{const nVecs=vectors.length;return vectors[0].map((v2,i)=>{for(let j=1;j{return vec.map((v2,i)=>v2-subvec[i])};static vecdiv=(numvec,denvec)=>{return numvec.map((v2,i)=>v2/denvec[i])};static vecscale=(vec,scalar)=>{return vec.map((v2,i)=>v2*scalar)};static vecaddScalar=(vec,scalar)=>{return vec.map((v2,i)=>v2+scalar)};static vecmulScalar=(vec,scalar)=>{return vec.map((v2,i)=>v2*scalar)};static vecsubScalar=(vec,scalar)=>{return vec.map((v2,i)=>v2-scalar)};static vecdivScalar=(vec,scalar)=>{return vec.map((v2,i)=>v2/scalar)};static dot=(vec1,vec2)=>{var dot=0;for(var i=0;i{return[vec1[1]*vec2[2]-vec1[2]*vec2[1],vec1[2]*vec2[0]-vec1[0]*vec2[2],vec1[0]*vec2[1]-vec1[1]*vec2[0]]};static sphericalToCartesian=(r,theta,phi)=>{return{x:r*Math.sin(phi)*Math.cos(theta),y:r*Math.sin(phi)*Math.sin(theta),z:r*Math.cos(phi)}};static cartesianToSpherical=(x22,y2,z)=>{var r=Math.sqrt(x22*x22+y2*y2+z*z);var theta=Math.atan2(y2,x22);var phi=Math.acos(z/r);return{r,theta,phi}};static magnitude=vec=>{var sqrd=0;vec.forEach(c=>{sqrd+=c*c});return Math.sqrt(sqrd)};static distance=(point1,point2)=>{var dsqrd=0;point1.forEach((c,i)=>{dsqrd+=(point2[i]-c)*(point2[i]-c)});return Math.sqrt(dsqrd)};static midpoint=(point1=[1,2,3],point2=[3,4,5])=>{return point1.map((c,i)=>{return(c+point2[i])*.5})};static project=(vec1,vec2)=>{const dot=this.dot(vec1,vec2);const magSqrd=this.magnitude(vec2)**2;return this.vecmulScalar(vec2,dot/magSqrd)};static angleBetween=(vec1,vec2)=>{const dotProduct=this.dot(vec1,vec2);const magProduct=this.magnitude(vec1)*this.magnitude(vec2);return Math.acos(dotProduct/magProduct)};static normalize=vec=>{var norm=0;norm=1/this.magnitude(vec);var vecn=new Array(vec.length);vec.forEach((c,i)=>{vecn[i]=c*norm});return vecn};static normalizeSeries=(arr=[],fromZero=true)=>{let max=Math.max(...arr);let min=Math.min(...arr);if(fromZero==false){max=Math.max(max,Math.abs(min));min=0}if(max-min===0){min=0;if(max===0)max=1e-13}return arr.map(v2=>(v2-min)/(max-min))};static quadraticFormula=(a,b,c)=>{let bbmac4=Math.sqrt(b*b-4*a*c);if(!isNaN(bbmac4))return["complex","complex"];let _a2=1/(2*a);if(bbmac4===0)return[b*_a2];let nb=-b;return[(nb+bbmac4)*_a2,(nb-bbmac4)*_a2]};static newtonsMethod1D=(foo=x22=>{return Math.pow(x22,5)+x22*x22-x22-.2},start=0,end=1,precision=.01,attempts=10)=>{let roots=[];for(let i=0;iprecision){let step=-guess/slope2;let xn12=xn+step;guess=guess2;guess2=foo(xn12);let slope2=(guess2-guess)/(xn12-xn)}let idx;let f=roots.find((root,i2)=>{if(Math.abs(xn1-root){let y2=x22;return y2},range=[0,1],stepx=.01)=>{let area=0;for(let i=range[0];i{let z=x22+y2;return z},range=[[0,1],[0,1]],stepx=.01,stepy=stepx)=>{let volume=0;for(let i=range[0][0]+stepx;i{let w2=x22+y2+z;return w2},range=[[0,1],[0,1],[0,1]],stepx=.01,stepy=stepx,stepz=stepx)=>{let volume=0;for(let i=range[0][0]+stepx;i{let y2=x22;return y2},range=[0,1],stepx=.01)=>{let length=0;let y0=func(range[0]);for(let i=range[0]+stepx;i<=range[1];i+=stepx){let yi=func(i);length+=Math.sqrt(stepx**2+(yi-y0)**2);y0=yi}return length};static pathIntegral2D=(xFunc=t=>{let x22=Math.cos(t);return x22},yFunc=t=>{let y2=Math.sin(t);return y2},range=[[0,1],[0,1]],stept=.01)=>{let length=0;let x0=xFunc(range[0][0]);let y0=yFunc(range[1][0]);let tMaxX=range[0][1];let tMaxY=range[1][1];let tMax=Math.max(tMaxX,tMaxY);for(let t=0;t<=tMax;t+=stept){let xi=xFunc(Math.min(t,tMaxX));let yi=yFunc(Math.min(t,tMaxY));length+=Math.sqrt((xi-x0)**2+(yi-y0)**2);x0=xi;y0=yi}return length};static pathIntegral3D=(xFunc=(u2,v2)=>u2,yFunc=(u2,v2)=>v2,zFunc=(u2,v2)=>u2+v2,rangeU=[0,1],rangeV=[0,1],stepU=.01,stepV=.01)=>{let area=0;for(let u2=rangeU[0];u2{var vec=[];point1.forEach((c,i)=>{vec.push(point2[i]-c)});return vec};static getBufferedValueByCoordinates=(vb=new Array(300).fill(1),dims=[10,10,2],coordinate=[1,2,1],cardinal=void 0)=>{let getIdx=(foundIdx=0,dimIdx=0)=>{if(dimIdx===dims.length)return foundIdx;if(dimIdx==0)foundIdx+=coordinate[dimIdx];else if(dims[dimIdx]==0)dimsAt0++;else{let reMul=(val=coordinate[dimIdx],di=dimIdx-1)=>{val*=dims[di];di--;if(di==0)return val;else return reMul(val,di)};foundIdx+=reMul(coordinate[dimIdx]+1,dimIdx-1)}dimIdx++;return getIdx(foundIdx,dimIdx)};let found=getIdx();if(cardinal){if(coordinate[coordinate.length-1]===0){let lastnonzero=0;let idx=0;while(idx!==coordinate.length-1){if(coordinate[idx]!==0)lastnonzero=idx;idx++}return vb[found-lastnonzero+cardinal]}return vb[found-dims.length+cardinal]}else{if(coordinate[coordinate.length-1]===0){let lastnonzero=0;let idx=0;while(idx!==coordinate.length-1){if(coordinate[idx]!==0)lastnonzero=idx;idx++}return vb.slice(found-lastnonzero,found+1)}return vb.slice(found-dims.length,found+1)}};static forBufferedMat=(vb=new Array(100).fill(1),dims=[10,10],asIndex=(v2,i,x22,y2)=>{return v2+x22+y2})=>{let coordinate=[];let idx=0;let recurseFor=(depth=0,nextDepth=depth+1)=>{let result=new Array(vb.length);for(let di=0;di{let result=new Array(vb.length);for(let di=0;di{console.log(`value:${v2}, idx:${idx}, x:${i},y:${j}`);return v2+i+j})=>{let coordinate=new Array(dimensions.length).fill(0);const iterateCoordinate=(coord,idx=0)=>{if(coord[idx]>=dimensions[idx]){coord[idx]=0;idx++;if(idx===dimensions.length)return;iterateCoordinate(coord,idx)}else coord[idx]++};let result=new Array(buffer.length);let i=0;if(typeof asIndex==="function"){while(i{result[i]=func(buffer[i],i,...coordinate);i++;iterateCoordinate(coordinate)})}}return result};static combinations=(choices=["a","b","c"],vecsize=3)=>{var result=[];if(vecsize<=0){result.push([])}else{_Math2.combinations(choices,vecsize-1).forEach(function(previousComb){choices.forEach(function(element){result.push([element].concat(previousComb))})})}return result};static generateCoordinateSpace=(upperBounds=[10,10,10],lowerBounds=[-10,-10,-10],steps=[1,1,1],mutater=void 0)=>{for(let i=0;iupperBounds[i]){let temp=upperBounds[i];upperBounds[i]=lowerBounds[i];lowerBounds[i]=temp}}let result=[];let copy=[...upperBounds];let lastindex=copy.length-1;result.push([...copy]);while(copy[0]>=lowerBounds[0]){let checkNextIndex=decrIdx2=>{if(copy[decrIdx2]<=lowerBounds[decrIdx2]){if(decrIdx2===0)return;copy[decrIdx2]=upperBounds[decrIdx2];decrIdx2--;if(decrIdx2<0)return;if(typeof steps[decrIdx2]=="function")copy[decrIdx2]-=steps[decrIdx2](copy[decrIdx2]);else copy[decrIdx2]-=steps[decrIdx2];checkNextIndex(decrIdx2)}};let decrIdx=lastindex;if(typeof steps[decrIdx]=="function")copy[decrIdx]-=steps[decrIdx](copy[decrIdx]);else copy[decrIdx]-=steps[decrIdx];result.push([...copy]);checkNextIndex(decrIdx);if(mutater)result[result.length-1]=mutater(result[result.length-1])}return result};static meshgrid=_Math2.generateCoordinateSpace;static calcVectorField=(coordinates=[[0,0],[0,1],[1,0],[1,1]],formula=(x22,y2)=>{return[x22*10,y2*10]})=>{return coordinates.map(vec=>formula(...vec))};static randomMatrix=(rows,cols)=>{return Array.from({length:rows},()=>Array.from({length:cols},()=>Math.random()))};static identityMatrix=size=>{return Array.from({length:size},(_,i)=>Array.from({length:size},(_2,j)=>i===j?1:0))};static diagonalMatrix=values=>{return values.map((value,index)=>{const row=Array(values.length).fill(0);row[index]=value;return row})};static householderMatrix=v2=>{const size=v2.length;const vvT=v2.map(rowVal=>v2.map(colVal=>rowVal*colVal));const vTv=this.normalize(v2)**2;return Array.from({length:size},(_,i)=>Array.from({length:size},(_2,j)=>(i===j?1:0)-2*vvT[i][j]/vTv))};static transpose=mat=>{return mat[0].map((_,colIndex)=>mat.map(row=>row[colIndex]))};static clone=mat=>{return mat.map(row=>{if(Array.isArray(row[0]))return this.clone(row);else return[...row]})};static getColumn(matrix,col){return matrix.map(row=>row[col])}static matmul=(A2,B)=>{return A2.map(row=>B[0].map((_,colIndex)=>row.reduce((sum,cell,rowIndex)=>sum+cell*B[rowIndex][colIndex],0)))};static matscale=(mat,scalar)=>{return mat.map(row=>row.map(cell=>cell*scalar))};static matadd=(A2,B)=>{return A2.map((row,rowIndex)=>row.map((cell,colIndex)=>cell+B[rowIndex][colIndex]))};static matsub=(A2,B)=>{return A2.map((row,rowIndex)=>row.map((cell,colIndex)=>cell-B[rowIndex][colIndex]))};static inverse=matrix=>{const numRows=matrix.length;const numCols=matrix[0].length;if(numRows!==numCols){throw new Error("Matrix must be square to compute its inverse.")}const augmentedMatrix=matrix.map((row,rowIndex)=>{const identityRow=Array(numRows).fill(0);identityRow[rowIndex]=1;return row.concat(identityRow)});for(let pivotRow=0;pivotRowrow.slice(numCols))};static pseudoInverse=matrix=>{const numRows=matrix.length;const numCols=matrix[0].length;if(numRows>numCols){const ata=this.matmul(this.transpose(matrix),matrix);const ataInv=this.inverse(ata);return this.matmul(ataInv,this.transpose(matrix))}else{const aat=this.matmul(matrix,this.transpose(matrix));const aatInv=this.inverse(aat);return this.matmul(this.transpose(matrix),aatInv)}};static histogram=(arr=[],binSize=1,nBins=void 0)=>{let copy=[...arr];copy.sort(function(a,b){return a-b});let binStart=Math.min(...copy);if(typeof nBins==="number"){let binEnd=Math.max(...copy);binSize=Math.abs((binEnd-binStart)/(nBins-1))}let j=binStart;let binx=[];let biny=[];for(let i=0;ibinStart+binidx){j++;binidx+=binSize;let binmin=binStart+binidx;let binmid=binmin+binidx*.5;binx.push(binmid);biny.push(0)}biny[biny.length-1]++}return[binx,biny]};static normalDistribution=(samples=[],normalize=true,cutoff=1e-4)=>{let m=this.mean(samples);let vari=this.variance(samples);let nSamples=samples.length;let probabilities=[];let denom=1/(this.TWO_PI*vari);let _variance=1/vari;let sum=0;for(let i=0;ix22*_sum)}return probabilities};static expectedValue=(samples=[],probabilities=this.normalDistribution(samples))=>{return samples.reduce((sum,item,idx)=>sum+item*probabilities[idx])};static originMoment=(samples=[],probabilities=this.normalDistribution(samples),order=1)=>{return samples.reduce((sum,item,idx)=>sum+Math.pow(item,order)*probabilities[idx])};static centralMoment=(samples=[],probabilities=this.normalDistribution(samples),order=1)=>{let m=this.mean(samples);return samples.reduce((sum,item,idx)=>sum+Math.pow(item-m,order)*probabilities[idx]/samples.length)};static linearDiscriminantAnalysis=(samples=[],classifier=[])=>{let mean=this.mean(samples);let meank=this.mean(classifier);let covariance=this.cov1d(samples,classifier);let probs=this.normalDistribution(samples);let dk=[];for(let i=0;i{const padlen=deconstructionLowPass.length;let sg=this.edgePad(signal,padlen);let approxCoeffs=this.conv1D(sg,deconstructionLowPass).slice(1+padlen,-padlen).filter((_,idx)=>idx%2===0);let detailCoeffs=this.conv1D(sg,deconstructionHighPass).slice(1+padlen,-padlen).filter((_,idx)=>idx%2===0);let results=[detailCoeffs];for(let i=0;iidx%2===0));approxCoeffs=this.conv1D(approxCoeffs,deconstructionLowPass).slice(1+padlen,-padlen).filter((_,idx)=>idx%2===0)}return[approxCoeffs].concat(results.reverse())};static idwt=(approxCoeffs=[],detailCoeffs=[],reconstructionHighPass=[],reconstructionLowPass=[])=>{if(approxCoeffs.length!==detailCoeffs.length){approxCoeffs.pop()}const _ca=this.dyadicUpsample(approxCoeffs,true);const _cd=this.dyadicUpsample(detailCoeffs,true);const halfa=this.conv1D(_ca,reconstructionLowPass);const halfb=this.conv1D(_cd,reconstructionHighPass);const sig=halfa.map((val,idx)=>val+halfb[idx]);const padlen=reconstructionLowPass.length;const lo=padlen-1;const hi=sig.length-(padlen-2);return sig.slice(lo,hi)};static dwtMaxLevel=(dataLength,waveletLength)=>{return Math.floor(Math.log2(dataLength/(waveletLength-1)))};static minMaxScaler=data=>{const min=Math.min(...data);const max=Math.max(...data);return data.map(value=>(value-min)/(max-min))};static garroteThreshold=(data,value)=>{return data.map(x22=>{if(Math.abs(x22)<=value){return 0}else{return x22-value*value/x22}})};static conv1D=(s,kernel)=>{const revKernel=[...kernel].reverse();const padsize=kernel.length-1;const paddedS=new Array(padsize).fill(0).concat(s).concat(new Array(padsize).fill(0));const nSteps=paddedS.length-kernel.length+1;const result=new Array(nSteps).fill(0);const nKer=kernel.length;for(let i=0;i{const rows=matrix.length;const cols=matrix[0].length;const kRows=kernel.length;const kCols=kernel[0].length;const halfKRows=Math.floor(kRows/2);const halfKCols=Math.floor(kCols/2);const output=new Array(rows).fill(0).map(()=>new Array(cols).fill(0));for(let i=0;i=0&&xi=0&&yj{if(matrix.length===0||kernel.length===0)return[];function getShape(arr){const shape=[];while(Array.isArray(arr)){shape.push(arr.length);arr=arr[0]}return shape}function convolveRecurse(mat,ker,matrixShape2,kernelShape2,matIndices=[],kerIndices=[]){const depth=matIndices.length;if(depth===matrixShape2.length){let sum=0;for(let i=0;i=0&&matIndex{const mean1=this.mean(arr1);const mean2=this.mean(arr2);return arr1.map((v2,i)=>(v2-mean1)*(arr2[i]-mean2))};static cov1d=(arr1,arr2)=>{this.mean(this.covVec(arr1,arr2))};static cov2d=mat=>{var mattransposed=this.transpose(mat);var matproducts=[];var rowmeans=[];var colmeans=[];mat.forEach((row,idx)=>{rowmeans.push(this.mean(row))});mattransposed.forEach((col,idx)=>{colmeans.push(this.mean(col))});mat.forEach((row,idx)=>{matproducts.push([]);for(var col=0;col{return[[this.cov1d(x22,x22),this.cov1d(x22,y2),this.cov1d(x22,z)],[this.cov1d(y2,x22),this.cov1d(y2,y2),this.cov1d(y2,z)],[this.cov1d(z,x22),this.cov1d(z,y2),this.cov1d(z,z)]]};static covNd=(dimensionalData=[])=>{let covariance=[];dimensionalData.forEach((arr,i)=>{covariance.push([]);dimensionalData.forEach((arr2,j)=>{covariance[i].push(this.cov1d(arr,arr2))})})};static correlationCoeff=(arr1,arr2)=>{const cov=this.cov1d(arr1,arr2);const stdDev1=this.std(arr1);const stdDev2=this.std(arr2);return cov/(stdDev1*stdDev2)};static pearsonCorrelation=(arr1,arr2)=>{let sumX=0,sumY=0,sumXY=0,sumX2=0,sumY2=0;const n=arr1.length>arr2.length?arr2.length:arr1.length;for(let i=0;i{let det=mat[0][0]*mat[1][1]-mat[0][1]*mat[1][0];let mean=(mat[0][0]+mat[1][1])*.5;let sqrt=Math.sqrt(mean*mean-det);let eig1=mean+sqrt;let eig2=mean-sqrt;return[eig1,eig2]};static eigenvectors2x2=(mat=[[1,2],[3,4]],eigens=[1,2])=>{let v1=[-mat[0][1],mat[0][0]-eigens[0]];if(v1[0]===0&&v1[1]===0){v1[0]=mat[1][1]-eigens[0];v1[1]=-mat[1][0]}let v2=[-mat[0][1],mat[0][0]-eigens[1]];if(v2[0]===0&&v2[1]===0){v2[0]=mat[1][1]-eigens[1];v2[1]=-mat[1][0]}return[v1,v2]};static fastpca2d=(xarr,yarr)=>{let covMat=this.cov2d(xarr,yarr);let eigs=this.eigens2x2(covMat);if(eigs[1]>eigs[0])eigs.reverse();let evs=this.eigenvectors2x2(covMat,eigs);return[eigs,evs]};static centerData=data=>{const mean=data.reduce((sum,val)=>sum+val,0)/data.length;return data.map(v2=>v2-mean)};static crosscorrelation=(signalA,signalB,posOnly=false)=>{const N2=signalA.length;const M2=signalB.length;const result=[];const normFactor=1/Math.sqrt(signalA.reduce((acc,val)=>acc+val*val,0)*signalB.reduce((acc,val)=>acc+val*val,0));if(posOnly){result.length=signalA.length;for(let lag=0;lag=0&&m{const lags=[];const timeResolution=samplingRate?1/samplingRate:0;const center=centered?correlogram.length/2:null;const len=correlogram.length-1;for(let i=1;icorrelogram[i-1]&&correlogram[i]>correlogram[i+1]){let lag={offset:centered?i-center:i,value:correlogram[i]};if(timeResolution)lag.offset*=timeResolution;lags.push(lag)}}if(getMax)return lags.reduce((maxObj,currentObj)=>{return currentObj.value>maxObj.value?currentObj:maxObj},lags[0]);else return lags};static autocorrelation=arr1=>{var delaybuf=[...arr1,...Array(arr1.length).fill(0)];var mean1=this.mean(arr1);var arr1Est=arr1.reduce((sum,item)=>sum+=Math.pow(item-mean1,2));arr1Est=Math.sqrt(Math.abs(arr1Est));let denom=arr1Est*arr2Est;if(denom===0)denom=1e-26;var _arr1estsqrd=1/denom;var correlations=new Array(arr1.length).fill(0);for(var delay=0;delaysum+=(item-mean1)*(delaybuf[delay+i]-mean1));correlations[delay]=r*_arr1estsqrd}return correlations};static autocorrelation2d=mat2d2=>{let result=[];for(let y2=0;y2{let result=[];for(let y2=0;y2{let result=[];for(let y2=0;y2{let result=[];for(let y2=0;y2{var correlograms=[];dat.forEach((row1,i)=>{dat.forEach((row2,j)=>{if(j>=i){correlograms.push(_Math2.crosscorrelation(row1,row2))}})});return correlograms};static dft=(sineWave=[],sampleRate=250,frequencyResolution=.25)=>{const N2=sineWave.length;const NyquistLimit=Math.floor(sampleRate/2);const totalFreqs=Math.floor(NyquistLimit/frequencyResolution);const Npadded=Math.ceil(sampleRate/frequencyResolution);const TWOPI=2*3.141592653589793;const real=new Array(Npadded).fill(0);const imag=new Array(Npadded).fill(0);const amplitudes=new Array(Npadded);const zerosToAdd=Npadded-N2;if(zerosToAdd<0){throw new Error("Desired resolution is not achievable with current sample size.")}const paddedSineWave=zerosToAdd?[...sineWave,...Array(zerosToAdd).fill(0)]:sineWave;let orderedFrequencies;if(totalFreqs%2===0){orderedFrequencies=[...new Array(totalFreqs).fill(0).map((x22,i)=>-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs).fill(0).map((x22,i)=>i*frequencyResolution)]}else{orderedFrequencies=[...new Array(totalFreqs).fill(0).map((x22,i)=>-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs+1).fill(0).map((x22,i)=>i*frequencyResolution)]}for(let k=0;k-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs).fill(0).map((x22,i)=>(i+1)*frequencyResolution)]}else{orderedMagnitudes=[...amplitudes.slice(totalFreqs,2*totalFreqs),...amplitudes.slice(0,totalFreqs+1)];orderedFrequencies=[...new Array(totalFreqs).fill(0).map((x22,i)=>-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs+1).fill(0).map((x22,i)=>i*frequencyResolution)]}return{real,imag,freqs:orderedFrequencies,amplitudes:orderedMagnitudes}};static eulerTransform=(dataSeries=[],timeTransform=(j,dataSeries2,real,imag,magnitudes)=>{return dataSeries2[j]},stepTransform=(k,j,length,real,imag,magnitudes)=>{return 2*Math.PI*k*j/length},kN=dataSeries.length)=>{var real=[];var imag=[];var magnitudes=[];for(var k=0;k{var smaArr=[];for(var i=0;icurrent+=previous)/(i+1))}else{var arrslice=arr.slice(i-window,i);smaArr.push(arrslice.reduce((previous,current)=>current+=previous)/window)}}return smaArr};static sum=(arr=[])=>{if(arr.length>0){var sum=arr.reduce((prev,curr)=>curr+=prev);return sum}else{return 0}};static reduceArrByFactor=(arr,factor=2)=>{let x22=arr.filter((element,index)=>{return index%factor===0});return x22};static makeArr=(startValue,stopValue,nSteps)=>{var arr=[];var step=(stopValue-startValue)/(nSteps-1);for(var i=0;i{if(array?.length===0)return array;let max=Math.max(...array);let min=Math.min(...array);let _lines=1/stackedLines;let scalar;if(centerZero){let absmax=Math.max(Math.abs(min),Math.abs(max));scalar=_lines/absmax;return array.map(y2=>y2*scalar+(_lines*(stackPosition+1)*2-1-_lines))}else{scalar=_lines/(max-min);return array.map(y2=>2*((y2-min)*scalar-1/(2*stackedLines))+(_lines*(stackPosition+1)*2-1-_lines))}};static absmax=array=>{return Math.max(Math.abs(Math.min(...array)),Math.max(...array))};static downsample=(array,fitCount,scalar=1)=>{if(array.length>fitCount){let output=new Array(fitCount);let incr=array.length/fitCount;let lastIdx=array.length-1;let last=0;let counter=0;for(let i=incr;ilastIdx)rounded=lastIdx;for(let j=last;j{var linearInterpolate=function(before2,after2,atPoint2){return(before2+(after2-before2)*atPoint2)*scalar};var newData=new Array;var springFactor=(array.length-1)/(fitCount-1);newData[0]=array[0];for(var i=1;i{const start=even?1:0;const out=new Array(a.length*2).fill(0);for(let i=0;i{if(array.length===fitCount)return array;if(array.length>fitCount){return this.downsample(array,fitCount,scalar)}else{return this.upsample(array,fitCount,scalar)}};static lerp=(v0,v1,t)=>{return(1-t)*v0+t*v1};static linspace=(start,end,num,floor=false)=>{const arr=new Array(num);const step=(end-start)/(num-1);for(let i=0;i{let ref=[...arr];if(ref.length%2===0)ref.pop();if(arr.length>1){let pass=true;for(let i=0;i=ref[Math.floor(ref.length*.5)]){pass=false;break}else if(i>Math.floor(ref.length*.5)&&val>=ref[Math.floor(ref.length*.5)]){pass=false;break}}else if(critical==="valley"){if(iMath.floor(ref.length*.5)&&val<=ref[Math.floor(ref.length*.5)]){pass=false;break}}else{if(iMath.floor(ref.length*.5)&&val<=ref[Math.floor(ref.length*.5)]){pass=false;break}}}if(critical!=="peak"&&critical!=="valley"&&pass===false){pass=true;for(let i=0;i=ref[Math.floor(ref.length*.5)]){pass=false;break}else if(i>Math.floor(ref.length*.5)&&val>=ref[Math.floor(ref.length*.5)]){pass=false;break}}}return pass}else return void 0};static isCriticalPoint=(arr,critical="peak")=>{let ref=[...arr];if(ref.length%2===0)ref.pop();if(arr.length>1){let pass=true;for(let i=0;iref.length*.5&&val>0){pass=false;break}}else if(critical==="valley"){if(i=0){pass=false;break}else if(i>ref.length*.5&&val<0){pass=false;break}}else{if(i=0){pass=false;break}else if(i>ref.length*.5&&val<0){pass=false;break}}}if(critical!=="peak"&&critical!=="valley"&&pass===false){pass=true;for(let i=0;iref.length*.5&&val>0){pass=false;break}}}return pass}else return void 0};static peakDetect=(smoothedArray,type="peak",window=49)=>{let mid=Math.floor(window*.5);let peaks=[];for(let i=0;i{let threshold;let filtered=arr.filter((o,i)=>{if(peakIndices.indexOf(i)>-1)return true});if(thresholdVar===0){threshold=this.mean(filtered)}else threshold=(thresholdVar+this.mean(filtered))*.5;return threshold};static column=(mat,x22)=>{let col=new Array(mat.length).fill(0).map(()=>new Array(1).fill(0));for(let i=0;i{let v_new=[];for(let i=0;i{let sum=0;for(let i=0;i{let len=Math.sqrt(this.matmul(this.transpose(eigenvector),eigenvector));let U=this.matscale(eigenvector,1/len);let delta=this.matscale(this.matmul(U,this.transpose(U)),eigenvalue);let M_new=this.matsub(mat,delta);return M_new};static eigenvalue_of_vector=(mat,eigenvector)=>{ev=this.matmul(this.matmul(this.transpose(eigenvector),mat),eigenvector);return ev};static power_iteration=(A2,numIter=100)=>{let b=Array(A2.length).fill(1);for(let i=0;i{let eigenvalues=[];let eigenvectors=[];for(let i=0;i{if(A2[0].length>A2.length){A2=this.transpose(A2)}const m=A2.length;const n=A2[0].length;const prec=Number.EPSILON;const tolerance=1e-64/prec;const itmax=50;const leftSingularVectors=this.clone(A2);const offDiagonalValues=Array(n).fill(0);const singularValues=Array(n).fill(0);const rightSingularVectors=Array.from({length:n},()=>Array(n).fill(0));function pythag(a,b){if(a===0||b===0)return a+b;const absA=Math.abs(a),absB=Math.abs(b);if(absA>absB){const t=absB/absA;return absA*Math.sqrt(1+t*t)}else{const t=absA/absB;return absB*Math.sqrt(1+t*t)}}let scaleFactorF=0;let scaleFactorG=0;let scaleFactorH=0;let maxMagnitude=0;let intermediateY=0;let intermediateZ=0;let sumValue=0;let cosineTheta=0;let limitIndex=0;for(let i=0;i=0)scaleFactorG=-scaleFactorG;scaleFactorH=scaleFactorF*scaleFactorG-sumValue;leftSingularVectors[i][i]=scaleFactorF-scaleFactorG;for(let j=limitIndex;j=0)scaleFactorG=-scaleFactorG;scaleFactorH=scaleFactorF*scaleFactorG-sumValue;leftSingularVectors[i][i+1]=scaleFactorF-scaleFactorG;for(let j=limitIndex;jmaxMagnitude)maxMagnitude=intermediateY}for(let i=n-1;i>=0;i--){if(scaleFactorG!==0){scaleFactorH=scaleFactorG*leftSingularVectors[i][i+1];for(let j=limitIndex;j=0;i--){limitIndex=i+1;scaleFactorG=singularValues[i];for(let j=limitIndex;j=0;k--){for(let iteration=0;iteration=0;limitIndex--){if(Math.abs(offDiagonalValues[limitIndex])<=eps){testConvergence=true;break}if(Math.abs(singularValues[limitIndex-1])<=eps)break}if(!testConvergence){cosineTheta=0;sumValue=1;const l1=limitIndex-1;for(let i=limitIndex;i=itmax-1)throw new Error("No convergence.");maxMagnitude=singularValues[limitIndex];intermediateY=singularValues[k-1];scaleFactorG=offDiagonalValues[k-1];scaleFactorH=offDiagonalValues[k];scaleFactorF=((intermediateY-intermediateZ)*(intermediateY+intermediateZ)+(scaleFactorG-scaleFactorH)*(scaleFactorG+scaleFactorH))/(2*scaleFactorH*intermediateY);scaleFactorG=pythag(scaleFactorF,1);if(scaleFactorF<0)scaleFactorF=((maxMagnitude-intermediateZ)*(maxMagnitude+intermediateZ)+scaleFactorH*(intermediateY/(scaleFactorF-scaleFactorG)-scaleFactorH))/maxMagnitude;else scaleFactorF=((maxMagnitude-intermediateZ)*(maxMagnitude+intermediateZ)+scaleFactorH*(intermediateY/(scaleFactorF+scaleFactorG)-scaleFactorH))/maxMagnitude;cosineTheta=1;sumValue=1;for(let i=limitIndex+1;i=0;j--){if(singularValues[j]row.slice());for(let k=0;k0?-this.normalize(x22):this.normalize(x22);const u2=this.vecsub(x22,e);const normU=this.normalize(u2);const v2=u2.map(val=>val/normU);const Qk=this.householderMatrix(v2);const QkFull=this.identityMatrix(numRows);for(let row=k;row{const numRowsOriginal=matrixA.length;const numColsOriginal=matrixA[0].length;if(!numComponents){numComponents=Math.min(numRowsOriginal,numColsOriginal)}let matrixACopy=[...matrixA.map(row=>[...row])];if(numRowsOriginal>numColsOriginal){matrixA=this.matmul(this.transpose(matrixA),matrixA)}else if(numRowsOriginalsum+row.reduce((rowSum,val)=>rowSum+val*val,0),0);previousMatrixQ=matrixQ;if(errorMath.sqrt(row[row.indexOf(Math.max(...row))]));let leftVectors,rightVectors;if(numRowsOriginalval*val)}else{rightVectors=this.transpose(matrixQ);leftVectors=this.matmul(this.matmul(matrixACopy,rightVectors),this.inverse(this.diagonalMatrix(singularValues)))}return{U:leftVectors,S:singularValues,V:rightVectors}};static pca=(mat,tolerance=1e-5)=>{let dims=mat.length;let t=new Array(dims);let p2=new Array(dims);let mat_t=this.transpose(mat);t[0]=this.column(mat,0);let epsilon=1;let iter=0;while(espilon>tolerance){iter++;p2[0]=this.matmul(mat_t,t[0]);let tp=this.matmul(this.transpose(t[0]),t[0]);p2[0]=this.matscale(p2[0],1/tp);let p_length=Math.sqrt(this.matmul(this.transpose(p2[0]),p2[0]));p2[0]=this.matscale(p2[0],1/p_length);let t_new=this.matmul(mat,p2[0]);let pp=this.matmul(this.transpose(p2[0]),p2[0]);t_new=this.matscale(t_new,1/pp);epsilon=this.squared_difference(t[0],t_new);t[0]=JSON.parse(JSON.stringify(t_new))}let components=this.matmul(this.transpose(t[0]),t[0]);return components};static circularBuffer=(arr,newEntries)=>{if(Array.isArray(newEntries)){if(newEntries.lengtharr.length){let len=arr.length;arr.splice(0,len,newEntries.slice(len-newEntries.length))}else{arr.splice(0,arr.length,...newEntries)}}else{arr.push(newEntries);arr.shift()}return arr};static reshape=(arr,shape)=>{const totalSize=shape.reduce((acc,val)=>acc*val,1);const flatArr=this.flatten(arr);if(flatArr.length!==totalSize){throw new Error("The given shape is incompatible with the array size.")}function buildArray(shape2,flatData){const dim=shape2[0];if(shape2.length===1){return flatData.splice(0,dim)}let result=[];for(let i=0;i{if(!Array.isArray(arr)){return[arr]}return arr.reduce((acc,val)=>acc.concat(flatten(val)),[])};static p300=(event_timestamps=[],raw_signal=[],signal_timestamps=[],sps=256)=>{let smoothingstep=Math.floor(sps/10);let smoothed=this.sma(raw_signal,smoothingstep);let peaks=this.peakDetect(smoothed,"peak",smoothingstep);let mean=this.mean(smoothed);let std=this.std(smoothed,mean);let p_idx=0;let candidates=[];if(peaks.length>0){event_timestamps.forEach((t,j)=>{while(signal_timestamps[peaks[p_idx]]1){let peakvals=[];tempcandidates.forEach(tc=>{peakvals.push(smoothed[peaks[tc]])});let max=Math.max(...peakvals);let maxi=tempcandidates[peakvals.indexOf(max)];candidates.push({event_timestamp:t,event_index:j,peak_timestamp:signal_timestamps[[peaks[maxi]]],signal_index:[peaks[maxi]],signal_amplitude:raw_signal[[peaks[maxi]]],zscore:(smoothed[peaks[maxi]]-mean)/std})}else if(tempcandidates.length===1)candidates.push({event_timestamp:t,event_index:j,peak_timestamp:signal_timestamps[peaks[tempcandidates[0]]],signal_index:peaks[tempcandidates[0]],signal_amplitude:raw_signal[[peaks[tempcandidates[0]]]],zscore:(smoothed[peaks[tempcandidates[0]]]-mean)/std})})}return candidates};static dec_lo=[-.07576571478927333,-.02963552764599851,.49761866763201545,.8037387518059161,.29785779560527736,-.09921954357684722,-.012603967262037833,.0322231006040427];static dec_hi=[-.0322231006040427,-.012603967262037833,.09921954357684722,.29785779560527736,-.8037387518059161,.49761866763201545,.02963552764599851,-.07576571478927333];static rec_lo=[.0322231006040427,-.012603967262037833,-.09921954357684722,.29785779560527736,.8037387518059161,.49761866763201545,-.02963552764599851,-.07576571478927333];static rec_hi=[-.07576571478927333,.02963552764599851,.49761866763201545,-.8037387518059161,.29785779560527736,.09921954357684722,-.012603967262037833,-.0322231006040427];static waveletFiltering=(signal=[],wavelets={dec_hi:this.dec_hi,dec_lo:this.dec_lo,rec_hi:this.rec_hi,rec_lo:this.rec_lo})=>{let maxlevel=this.dwtMaxLevel(signal.length,wavelets.dec_lo.length);let decomposed=this.decompose(signal,maxlevel,wavelets.dec_hi,wavelets.dec_lo);for(let i=2;i{ax=ax*this.accelConstant;ay=ay*this.accelConstant;az=az*this.accelConstant;const accelXAngle=Math.atan(ay/Math.sqrt(ax*ax)+az*az*180/Math.PI)+this.accelXError;const accelYAngle=Math.atan(-ax/Math.sqrt(ay*ay)+az*az*180/Math.PI)+this.accelYError;return{ax,ay,az,roll:accelXAngle,pitch:accelYAngle}};if(Array.isArray(data.timestamp)){result=data.timestamp.map((v2,i)=>{return apass(v2,data.ax[i],data.ay[i],data.az[i])})}else result=apass(data.timestamp,data.ax,data.ay,data.az)}if(data.gx){let gpass=(timestamp,gx,gy,gz)=>{const elapsed=timestamp-this.lastGyroTime;this.lastGyroTime=timestamp;gx=gx*this.gyroConstant+this.gyroXError;gy=gy*this.gyroConstant+this.gyroYError;gz=gz*this.gyroConstant+this.gyroZError;this.gyroXAngle+=gx*elapsed;this.gyroYAngle+=gy*elapsed;this.gyroZAngle+=gz*elapsed;return{gx,gy,gz,roll:this.gyroXAngle,pitch:this.gyroYAngle,yaw:this.gyroZAngle}};let res;if(Array.isArray(data.timestamp)){res=data.timestamp.map((v2,i)=>{if(result){let r=gpass(v2,data.gx[i],data.gy[i],data.gz[i]);result.roll=result.roll*.04+r.roll*.96;result.pitch=result.pitch*.04+r.pitch*.96;result.yaw=res.yaw}else return gpass(v2,data.gx[i],data.gy[i],data.gz[i])});if(!result)result=res}else{res=gpass(data.timestamp,data.gx,data.gy,data.gz);if(result){result.roll=result.roll*.04+res.roll*.96;result.pitch=result.pitch*.04+res.pitch*.96;result.yaw=res.yaw}else result=res}}else if(this.gyroXAngle||this.gyroYAngle||this.gyroZAngle){result.roll=result.roll*.04+this.gyroXAngle*.96;result.pitch=result.pitch*.04+this.gyroYAngle*.96;result.yaw=this.gyroXAngle}if(result.ax){const setPositionOffset=(timestamp,result2)=>{const elapsed=timestamp-this.lastAccelTime;this.lastAccelTime=timestamp;this.px+=result2.ax*elapsed*elapsed*Math.cos(this.pitch*Math.PI*.005555555555);this.py+=result2.ay*elapsed*elapsed*Math.cos(this.roll*Math.PI*.005555555555);this.pz+=result2.az*elapsed*elapsed*Math.sin(this.pitch*Math.PI*.005555555555);result2.px=this.px;result2.py=this.py;result2.pz=this.pz;return result2};if(Array.isArray(data.timestamp)){data.timestamp.map((timestamp,i)=>{setPositionOffset(timestamp,result)})}else{setPositionOffset(data.timestamp,result)}}return result}};var Biquad=class{type;freq;sps;Q;dbGain;a0=0;a1=0;a2=0;b0=0;b1=0;b2=0;x1=0;x2=0;y1=0;y2=0;constructor(type,freq,sps,Q=1/Math.sqrt(2),dbGain=0){let types=["lowpass","highpass","bandpass","notch","peak","lowshelf","highshelf"];if(types.indexOf(type)<0){console.error("Valid types: 'lowpass','highpass','bandpass','notch','peak','lowshelf','highshelf'");return}this.type=type;this.freq=freq;this.sps=sps;this.Q=Q;this.dbGain=dbGain;let A2=Math.pow(10,dbGain/40);let omega=2*Math.PI*freq/sps;let sn=Math.sin(omega);let cs=Math.cos(omega);let alpha=sn/(2*Q);let beta=Math.sqrt(A2+A2);this[type](A2,sn,cs,alpha,beta);this.b0/=this.a0;this.b1/=this.a0;this.b2/=this.a0;this.a1/=this.a0;this.a2/=this.a0}lowpass(A2,sn,cs,alpha,beta){this.b0=(1-cs)*.5;this.b1=1-cs;this.b2=(1-cs)*.5;this.a0=1+alpha;this.a1=-2*cs;this.a2=1-alpha}highpass(A2,sn,cs,alpha,beta){this.b0=(1+cs)*.5;this.b1=-(1+cs);this.b2=(1+cs)*.5;this.a0=1+alpha;this.a1=-2*cs;this.a2=1-alpha}bandpass(A2,sn,cs,alpha,beta){this.b0=alpha;this.b1=0;this.b2=-alpha;this.a0=1+alpha;this.a1=-2*cs;this.a2=1-alpha}notch(A2,sn,cs,alpha,beta){this.b0=1;this.b1=-2*cs;this.b2=1;this.a0=1+alpha;this.a1=-2*cs;this.a2=1-alpha}peak(A2,sn,cs,alpha,beta){this.b0=1+alpha*A2;this.b1=-2*cs;this.b2=1-alpha*A2;this.a0=1+alpha/A2;this.a1=-2*cs;this.a2=1-alpha/A2}lowshelf(A2,sn,cs,alpha,beta){this.b0=A2*(A2+1-(A2-1)*cs+beta*sn);this.b1=2*A2*(A2-1-(A2+1)*cs);this.b2=A2*(A2+1-(A2-1)*cs-beta*sn);this.a0=A2+1+(A2+1)*cs+beta*sn;this.a1=2*(A2-1+(A2+1)*cs);this.a2=A2+1+(A2-1)*cs-beta*sn}highshelf(A2,sn,cs,alpha,beta){this.b0=A2*(A2+1+(A2-1)*cs+beta*sn);this.b1=2*A2*(A2-1+(A2+1)*cs);this.b2=A2*(A2+1-(A2-1)*cs-beta*sn);this.a0=A2+1-(A2+1)*cs-beta*sn;this.a1=2*(A2-1-(A2+1)*cs);this.a2=A2+1-(A2-1)*cs-beta*sn}applyFilter(signal_step){let y2=this.b0*signal_step+this.b1*this.x1+this.b2*this.x2-this.a1*this.y1-this.a2*this.y2;this.x2=this.x1;this.x1=signal_step;this.y2=this.y1;this.y1=y2;return y2}zResult(freq){try{let phi=Math.pow(Math.sin(Math.PI*freq*2/(2*this.sps)),2);let result=(Math.pow(this.b0+this.b1+this.b2,2)-4*(this.b0*this.b1+4*this.b0*this.b2+this.b1*this.b2)*phi+16*this.b0*this.b2*phi*phi)/(Math.pow(1+this.a1+this.a2,2)-4*(this.a1+4*this.a2+this.a1*this.a2)*phi+16*this.a2*phi*phi);return result}catch(err){return-200}}static calcCenterFrequency(freqStart,freqEnd){return(freqStart+freqEnd)/2}static calcBandwidth(freqStart,freqEnd){return freqEnd-this.calcCenterFrequency(freqStart,freqEnd)}static calcBandpassQ(frequency,bandwidth,resonance=Math.pow(10,Math.floor(Math.log10(frequency)))){let Q=resonance*Math.sqrt((frequency-bandwidth)*(frequency+bandwidth))/(2*bandwidth);return Q}static calcNotchQ(frequency,bandwidth,resonance=Math.pow(10,Math.floor(Math.log10(frequency)))){let Q=resonance*frequency*bandwidth/Math.sqrt((frequency-bandwidth)*(frequency+bandwidth));return Q}};var beat_detect={refdata:[],lowpass:void 0,smoothed:[],timestamp:[],peaks:[],valleys:[],peak_distances:[],valley_distances:[],beats:[],lastPeak:0,lastValley:0,sps:100,maxFreq:4,limit:10,__onconnected:function(){if(!this.lowpass){let freq=this.maxFreq;if(!freq)freq=1;if(freq>1)freq*=.5;this.lowpass=new Biquad("lowpass",this.maxFreq,this.sps);this.peakFinderWindow=Math.floor(this.sps/this.maxFreq);if(this.peakFinderWindow%2===0)this.peakFinderWindow+=1;if(this.peakFinderWindow<5)this.peakFinderWindow=5;this.midpoint=Math.round(this.peakFinderWindow*.5)}},__operator:function(data){if(!("red"in data)&&!("heg"in data)&&!("raw"in data))return void 0;let refdata=data.red?data.red:data.heg?data.heg:data.raw;if(!("timestamp"in data)){if(Array.isArray(refdata)){let now=Date.now();let len;if(refdata)len=refdata.length;let toInterp=[now-refdata.length*this.sps*1e3,now];data.timestamp=Math2.upsample(toInterp,refdata.length)}else{data.timestamp=Date.now()}}let pass=(amplitude,timestamp)=>{if(amplitude){this.refdata.push(amplitude)}this.timestamp.push(timestamp);let beat;if(this.refdata.length>this.peakFinderWindow){this.refdata.shift();this.timestamp.shift()}this.smoothed.push(this.lowpass.applyFilter(this.refdata[this.refdata.length-1]));if(this.smoothed.length>this.peakFinderWindow){this.smoothed.shift()}if(this.smoothed.length===this.peakFinderWindow){if(Math2.isExtrema(this.smoothed,"valley")){this.valleys.push({value:this.smoothed[this.smoothed.length-this.midpoint?this.midpoint:1],timestamp:this.timestamp[this.timestamp.length-this.midpoint?this.midpoint:1]})}else if(Math2.isExtrema(this.smoothed,"peak")){this.peaks.push({value:this.smoothed[this.smoothed.length-this.midpoint?this.midpoint:1],timestamp:this.timestamp[this.timestamp.length-this.midpoint?this.midpoint:1]})}if(this.valleys.length>2&&this.peaks.length>2){if(this.valleys[this.valleys.length-1].timestamp1&&this.valley_distances.length>1){if(this.lastPeakthis.peak_distances[this.peak_distances.length-1].timestamp){let bpm,change=0;if(this.beats.length<1){bpm=60/(5e-4*(this.peak_distances[this.peak_distances.length-1].distance+this.valley_distances[this.valley_distances.length-1].distance))}else if(this.beats[this.beats.length-1].timestamp!==this.peak_distances[this.peak_distances.length-1].timestamp){bpm=60/(5e-4*(this.peak_distances[this.peak_distances.length-1].dt+this.valley_distances[this.valley_distances.length-1].dt));change=Math.abs(bpm-this.beats[this.beats.length-1].bpm)}beat={timestamp:this.peak_distances[this.peak_distances.length-1].timestamp,change,bpm,height0:this.peak_distances[this.peak_distances.length-1].peak0-this.valley_distances[this.valley_distances.length-1].peak0,height1:this.peak_distances[this.peak_distances.length-1].peak1-this.valley_distances[this.valley_distances.length-1].peak1};this.beats.push(beat);this.lastPeak=this.peaks[this.peaks.length-1].timestamp;this.lastValley=this.peaks[this.peaks.length-1].timestamp}else{let bpm,change=0;if(this.beats.length<2){bpm=60/(5e-4*(this.peak_distances[this.peak_distances.length-2].distance+this.valley_distances[this.valley_distances.length-2].distance))}else if(this.beats[this.beats.length-1].timestamp!==this.peak_distances[this.peak_distances.length-2].timestamp){bpm=60/(5e-4*(this.peak_distances[this.peak_distances.length-2].distance+this.valley_distances[this.valley_distances.length-2].distance));change=Math.abs(bpm-this.beats[this.beats.length-2].bpm)}beat={timestamp:this.peak_distances[this.peak_distances.length-2].timestamp,change,bpm,height0:this.peak_distances[this.peak_distances.length-2].peak0-this.valley_distances[this.valley_distances.length-2].peak0,height1:this.peak_distances[this.peak_distances.length-2].peak1-this.valley_distances[this.valley_distances.length-2].peak1};if(Array.isArray(beat.timestamp))beat.timestamp=beat.timestamp[0];this.beats.push(beat);this.lastPeak=this.peaks[this.peaks.length-1].timestamp;this.lastValley=this.peaks[this.peaks.length-1].timestamp}}}if(this.peaks.length>this.limit){this.peaks.shift()}if(this.valleys.length>this.limit){this.valleys.shift()}if(this.peak_distances.length>this.limit){this.peak_distances.shift()}if(this.valley_distances.length>this.limit){this.valley_distances.shift()}if(this.beats.length>this.limit){this.beats.shift()}}}return beat};if(data.red){if("ir"in data&&!Array.isArray(data.red))return pass(data.red+data.ir,data.timestamp);let result;if(data.ir)result=data.red.map((v2,i)=>{return pass(v2+data.ir[i],data.timestamp[i])}).filter(v2=>{if(v2)return true});else result=data.red.map((v2,i)=>{return pass(v2,data.timestamp[i])}).filter(v2=>{if(v2)return true});return result}else if(data.raw){if(!Array.isArray(data.raw))return pass(data.raw,data.timestamp);let result=data.raw.map((v2,i)=>{return pass(v2,data.timestamp[i])}).filter(v2=>{if(v2)return true});return result}else if(Array.isArray(data.heg)){if(!Array.isArray(data.heg))return pass(data.heg,data.timestamp);let result=data.heg.map((v2,i)=>{return pass(v2,data.timestamp[i])}).filter(v2=>{if(v2)return true});return result}}};var blink_detect={sps:250,intervals:{},watch:["0"],tolerance:.2,__onconnected:node=>{node.watch.forEach(ch=>node.intervals[ch]={lowpass:new Biquad("lowpass",20,node.sps),filtered:[],averaged:[]})},__operator:function(data){let checkCt=5;let averageCt=50;let found={};let passed=false;let pass=(key,n)=>{let next=this.intervals[key].lowpass.applyFilter(n);this.intervals[key].filtered.push(next);this.intervals[key].averaged.push(next);if(this.intervals[key].filtered.length>checkCt){if(this.intervals[key].averaged.length>averageCt){this.intervals[key].averaged.splice(0,checkCt);let mean=Math2.mean(this.intervals[key].averaged);if(Math.abs(Math.min(...this.intervals[key].filtered))>Math.abs(mean)+this.tolerance){this.intervals[key].filtered.length=0;passed=true;found[key]=true}}else this.intervals[key].filtered.shift()}};for(const key in this.intervals){if(data[key]){if(Array.isArray(data[key])){data[key].forEach(n=>{pass(key,n)})}else if(typeof data[key]==="number")pass(key,data[key])}}if(passed)return found}};var ArrayManip=class _ArrayManip{static autoscale(array,lineIdx=0,nLines=1,centerZero=false,ymin,ymax,clamp){if(array?.length===0)return array;let max=ymax?ymax:Math.max(...array);let min=ymin?ymin:Math.min(...array);let _lines=1/nLines;let scalar=1;if(centerZero){let absmax=Math.max(Math.abs(min),Math.abs(max));if(absmax!==0)scalar=_lines/absmax;return array.map(y2=>{if(clamp){if(y2max)y2=max}return y2*scalar+(_lines*(lineIdx+1)*2-1-_lines)})}else{if(max===min){if(max!==0){scalar=_lines/max}else if(min!==0){scalar=_lines/Math.abs(min)}}else scalar=_lines/(max-min);return array.map(y2=>{if(clamp){if(y2max)y2=max}return 2*((y2-min)*scalar-1/(2*nLines))+(_lines*(lineIdx+1)*2-1-_lines)})}}static genTimestamps(ct,sps){let now=Date.now();let toInterp=[now-ct*1e3/sps,now];return _ArrayManip.upsample(toInterp,ct)}static absmax(array){return Math.max(Math.abs(Math.min(...array)),Math.max(...array))}static downsample(array,fitCount,scalar=1){if(array.length>fitCount){let output=new Array(fitCount);let incr=array.length/fitCount;let lastIdx=array.length-1;let last=0;let counter=0;for(let i=incr;ilastIdx)rounded=lastIdx;for(let j=last;jfitCount){return _ArrayManip.downsample(array,fitCount,scalar)}else if(array.lengtharr.length){let len=arr.length;arr.splice(0,len,...newEntries.slice(newEntries.length-len))}else{arr.splice(0,arr.length,...newEntries)}return arr}static reformatData(data,key){if(Array.isArray(data)){if(Array.isArray(data[0])){let d2={};data.forEach((arr,i)=>{d2[i]=arr});data=d2;if(isNaN(data[0][0]))return void 0}else if(key){data={[key]:data};if(isNaN(data[key][0]))return void 0}else{data={0:data};if(isNaN(data[0][0]))return void 0}}else if(typeof data==="object"){for(const key2 in data){if(typeof data[key2]==="number")data[key2]=[data[key2]];else if(data[key2]?.values){if(typeof data[key2].values==="number")data[key2].values=[data[key2].values]}if(isNaN(data[key2][0]))return void 0}}else if(typeof data==="string"){let split;if(data.includes("\r\n")){let lines=data.split("\r\n");data={};lines.forEach((l,j)=>{if(l.includes(" ")){split=l.split(" ")}else if(l.includes(",")){split=l.split(",")}else if(l.includes("|")){split=l.split("|")}if(Array.isArray(split)){split.forEach((val,i)=>{if(val.includes(":")){let[key2,v2]=val.split(":");let fl=parseFloat(v2);if(fl)data[key2]=[fl];else return void 0}else{let fl=parseFloat(val);if(fl)data[i]=[fl];else return void 0}})}})}else if(data.includes(" ")){split=data.split(" ")}else if(data.includes(",")){split=data.split(",")}else if(data.includes("|")){split=data.split("|")}data={};if(Array.isArray(split)){split.forEach((val,i)=>{if(val.includes(":")){let[key2,v2]=val.split(":");let fl=parseFloat(v2);if(fl)data[key2]=[fl];else return void 0}else{let fl=parseFloat(val);if(fl)data[i]=[fl];else return void 0}})}}else if(typeof data==="number"){if(key)data={[key]:[data]};else data={0:[data]}}return data}static padTime(data,lastValue,time,targetFit){let slopeIncr=(data[0]-lastValue)/time/targetFit;let padded=[...new Array(targetFit-data.length).map((_,i)=>lastValue+slopeIncr*(i+1)),...data];return padded}static interpolateForTime(data,time,targetSPS){return _ArrayManip.interpolate(data,Math.ceil(targetSPS*time))}static bufferValues=(objects,property,keys,buffer)=>{if(!Array.isArray(keys)&&typeof keys==="object")keys=Object.keys(keys);if(!buffer){let object_keys=Object.keys(objects);if(keys)buffer=new Float32Array(object_keys.length*keys.length);else{if(typeof objects[object_keys[0]][property]==="object"){keys=Object.keys(objects[object_keys[0]][property]);buffer=new Float32Array(object_keys.length*keys.length)}else buffer=new Float32Array(object_keys.length)}}let i=0;for(const key in objects){if(objects[key][property]){if(keys){for(let j=0;j{for(const key in obj){if(typeof obj[key]==="object"){if(typeof target[key]==="object")this.recursivelyAssign(target[key],obj[key]);else target[key]=this.recursivelyAssign({},obj[key])}else target[key]=obj[key]}return target};spliceTypedArray(arr,start,end){let s=arr.subarray(0,start);let e;if(end){e=arr.subarray(end+1)}let n;if(s.length>0||e?.length>0)n=new arr.constructor(s.length+e.length);if(s.length>0)n.set(s);if(e&&e.length>0)n.set(e,s.length);return n}};var rechk=/^([<>])?(([1-9]\d*)?([xcbB?hHiIfdsp]))*$/;var refmt=/([1-9]\d*)?([xcbB?hHiIfdsp])/g;var str=(v2,o,c)=>String.fromCharCode(...new Uint8Array(v2.buffer,v2.byteOffset+o,c));var rts=(v2,o,c,s)=>new Uint8Array(v2.buffer,v2.byteOffset+o,c).set(s.split("").map(str2=>str2.charCodeAt(0)));var pst=(v2,o,c)=>str(v2,o+1,Math.min(v2.getUint8(o),c-1));var tsp=(v2,o,c,s)=>{v2.setUint8(o,s.length);rts(v2,o+1,c-1,s)};var lut=le=>({x:c=>[1,c,0],c:c=>[c,1,o=>({u:v2=>str(v2,o,1),p:(v2,c2)=>rts(v2,o,1,c2)})],"?":c=>[c,1,o=>({u:v2=>Boolean(v2.getUint8(o)),p:(v2,B)=>v2.setUint8(o,B)})],b:c=>[c,1,o=>({u:v2=>v2.getInt8(o),p:(v2,b)=>v2.setInt8(o,b)})],B:c=>[c,1,o=>({u:v2=>v2.getUint8(o),p:(v2,B)=>v2.setUint8(o,B)})],h:c=>[c,2,o=>({u:v2=>v2.getInt16(o,le),p:(v2,h)=>v2.setInt16(o,h,le)})],H:c=>[c,2,o=>({u:v2=>v2.getUint16(o,le),p:(v2,H)=>v2.setUint16(o,H,le)})],i:c=>[c,4,o=>({u:v2=>v2.getInt32(o,le),p:(v2,i)=>v2.setInt32(o,i,le)})],I:c=>[c,4,o=>({u:v2=>v2.getUint32(o,le),p:(v2,I)=>v2.setUint32(o,I,le)})],f:c=>[c,4,o=>({u:v2=>v2.getFloat32(o,le),p:(v2,f)=>v2.setFloat32(o,f,le)})],d:c=>[c,8,o=>({u:v2=>v2.getFloat64(o,le),p:(v2,d2)=>v2.setFloat64(o,d2,le)})],s:c=>[1,c,o=>({u:v2=>str(v2,o,c),p:(v2,s)=>rts(v2,o,c,s.slice(0,c))})],p:c=>[1,c,o=>({u:v2=>pst(v2,o,c),p:(v2,s)=>tsp(v2,o,c,s.slice(0,c-1))})]});var errbuf=new RangeError("Structure larger than remaining buffer");var errval=new RangeError("Not enough values for structure");var ByteParser=class _ByteParser extends ArrayManip{static codes={"\\n":10,"\\r":13,"\\t":9,"\\s":32,"\\b":8,"\\f":12,"\\":92};static toDataView(value){if(!(value instanceof DataView)){if(typeof value==="string"&&parseInt(value))value=parseInt(value);if(typeof value==="string"){let enc=new TextEncoder;let hascodes={};for(const code in _ByteParser.codes){while(value.indexOf(code)>-1){let idx=value.indexOf(code);value=value.replace(code,"");hascodes[idx]=code}}let encoded=Array.from(enc.encode(value));for(const key in hascodes){encoded.splice(parseInt(key),0,_ByteParser.codes[hascodes[key]])}value=new DataView(new Uint8Array(encoded).buffer)}else if(typeof value==="number"){let tmp=value;if(value<256){value=new DataView(new ArrayBuffer(1));value.setUint8(0,tmp)}else if(value<65536){value=new DataView(new ArrayBuffer(2));value.setInt16(0,tmp)}else{value=new DataView(new ArrayBuffer(4));value.setUint32(0,tmp)}}else if(value instanceof ArrayBuffer||typeof SharedArrayBuffer!=="undefined"&&value instanceof SharedArrayBuffer){value=new DataView(value)}else if(Array.isArray(value)){value=new DataView(Uint8Array.from(value).buffer)}else if(typeof value==="object"){value=new TextEncoder().encode(JSON.stringify(value))}}return value}static searchBuffer(buffer,searchString,limit){var needle=searchString;var haystack=buffer;var search=_ByteParser.boyerMoore(needle);var skip=search.byteLength;var indices=[];for(var i=search(haystack);i!==-1;i=search(haystack,i+skip)){indices.push(i);if(limit){if(indices.length>=limit)break}}return indices}static bytesToInt16(x0,x1){let int16=(255&x0)<<8|255&x1;if((int16&32768)>0){int16|=4294901760}else{int16&=65535}return int16}static bytesToUInt16(x0,x1){return x0*256+x1}static Uint16ToBytes(y2){return[y2&255,y2>>8&255]}static bytesToInt24(x0,x1,x22){let int24=(255&x0)<<16|(255&x1)<<8|255&x22;if((int24&8388608)>0){int24|=4278190080}else{int24&=16777215}return int24}static bytesToUInt24(x0,x1,x22){return x0*65536+x1*256+x22}static Uint24ToBytes(y2){return[y2&255,y2>>8&255,y2>>16&255]}static bytesToInt32(x0,x1,x22,x3){let int32=(255&x0)<<24|(255&x1)<<16|(255&x22)<<8|255&x3;if((int32&2147483648)>0){int32|=0}else{int32&=4294967295}return int32}static bytesToUInt32(x0,x1,x22,x3){return x0*16777216+x1*65536+x22*256+x3}static Uint32ToBytes(y2){return[y2&255,y2>>8&255,y2>>16&255,y2>>24&255]}static get2sCompliment(val,nbits){if(val>4294967296)return null;return val<<32-nbits>>32-nbits}static getSignedInt(...args){let pos=0;function getInt(size){var value=0;var first=true;while(size--){if(first){let byte=args[pos++];value+=byte&127;if(byte&128){value-=128}first=false}else{value*=256;value+=args[pos++]}}return value}return getInt(args.length)}static asUint8Array(input){if(input instanceof Uint8Array){return input}else if(typeof input==="string"){var arr=new Uint8Array(input.length);for(var i=0;i127){throw new TypeError("Only ASCII patterns are supported")}arr[i]=c}return arr}else{return new Uint8Array(input)}}static boyerMoore(patternBuffer){var pattern=_ByteParser.asUint8Array(patternBuffer);var M2=pattern.length;if(M2===0){throw new TypeError("patternBuffer must be at least 1 byte long")}var R2=256;var rightmost_positions=new Int32Array(R2);for(var c=0;c{var txt=_ByteParser.asUint8Array(txtBuffer);if(start===void 0)start=0;if(end===void 0)end=txt.length;var pat=pattern;var right=rightmost_positions;var lastIndex=end-pat.length;var lastPatIndex=pat.length-1;var skip;for(var i=start;i<=lastIndex;i+=skip){skip=0;for(var j2=lastPatIndex;j2>=0;j2--){var c2=txt[i+j2];if(pat[j2]!==c2){skip=Math.max(1,j2-right[c2]);break}}if(skip===0){return i}}return-1};boyerMooreSearch.byteLength=pattern.byteLength;return boyerMooreSearch}static struct(format){let fns=[],size=0,m=rechk.exec(format);if(!m){throw new RangeError("Invalid format string")}const t=lut("<"===m[1]),lu=(n,c)=>t[c](n?parseInt(n,10):1);while(m=refmt.exec(format)){((r,s,f)=>{for(let i=0;i{if(arrb.byteLength<(offs|0)+size){throw errbuf}let v2=new DataView(arrb,offs|0);return fns.map(f=>f.u(v2))};const pack_into=(arrb,offs,...values)=>{if(values.lengthf.p(v2,values[i]))};const pack=(...values)=>{let b=new ArrayBuffer(size);pack_into(b,0,...values);return b};const unpack=arrb=>unpack_from(arrb,0);function*iter_unpack(arrb){for(let offs=0;offs+size<=arrb.byteLength;offs+=size){yield unpack_from(arrb,offs)}}return Object.freeze({unpack,pack,unpack_from,pack_into,iter_unpack,format,size})}};var rms={sps:250,nSec:1,watch:["0","1","2","3"],data:{},rms:{},__operator:function(data){this.watch.forEach(key=>{if(data[key]){if(!this.data[key]){if(Array.isArray(data[key])){this.data[key]=new Array(Math.floor(this.sps*this.nSec)).fill(data[key][0])}else this.data[key]=new Array(Math.floor(this.sps*this.nSec)).fill(data[key])}ByteParser.circularBuffer(this.data[key],data[key])}});if(data.timestamp){if(Array.isArray(data.timestamp)){this.rms.timestamp=data.timestamp[data.timestamp.length-1]}else this.rms.timestamp=data.timestamp}else this.rms.timestamp=Date.now();return new Promise(async res=>{await Promise.all(this.watch.map(async key=>{if(this.data[key])this.rms[key]=Math.sqrt(Math.abs(this.data[key].reduce((p2,v2,i)=>p2+v2*v2)/this.data[key].length));else delete this.rms[key]}));res(this.rms)})}};var circularBuffer2d={bufferSize:250,watch:["0","1","2","3"],data:{},blocking:false,__onconnected:function(node){for(const key in node.watch){node.data[key]=new Array(node.bufferSize).fill(0)}},__operator:function(data){let buffer2d=[];this.watch.forEach(key=>{if(data[key]){ByteParser.circularBuffer(this.data[key],data[key]);buffer2d.push(this.data[key])}});return buffer2d}};var algorithms={beat_detect,accel_gyro,heartrate:beat_detect,breath:Object.assign({},beat_detect),blink_detect,rms,circularBuffer2d};algorithms["breath"].maxFreq=.2;export{StructBackend,StructFrontend,Systems,S as WebglLinePlotUtil,algorithms,defaultSpecifiers,genTimeSpecifiers,genTimestampFromString,getStringId,pseudoObjectId,randomId,setSignalControls,toObjectId,webglPlotRoutes}; diff --git a/src/extras/dist/index.services.js b/src/extras/dist/index.services.js deleted file mode 100644 index 1f46d0eb..00000000 --- a/src/extras/dist/index.services.js +++ /dev/null @@ -1,50 +0,0 @@ -(()=>{var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf;var __hasOwnProp=Object.prototype.hasOwnProperty;var __require=(x3=>typeof require!=="undefined"?require:typeof Proxy!=="undefined"?new Proxy(x3,{get:(a,b)=>(typeof require!=="undefined"?require:a)[b]}):x3)(function(x3){if(typeof require!=="undefined")return require.apply(this,arguments);throw Error('Dynamic require of "'+x3+'" is not supported')});var __commonJS=(cb,mod)=>function __require2(){return mod||(0,cb[__getOwnPropNames(cb)[0]])((mod={exports:{}}).exports,mod),mod.exports};var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from==="object"||typeof from==="function"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:true}):target,mod));var require_bson=__commonJS({"struct/datastructures/bson.cjs"(exports){"use strict";var BSON_MAJOR_VERSION=5;var BSON_INT32_MAX=2147483647;var BSON_INT32_MIN=-2147483648;var BSON_INT64_MAX=Math.pow(2,63)-1;var BSON_INT64_MIN=-Math.pow(2,63);var JS_INT_MAX=Math.pow(2,53);var JS_INT_MIN=-Math.pow(2,53);var BSON_DATA_NUMBER=1;var BSON_DATA_STRING=2;var BSON_DATA_OBJECT=3;var BSON_DATA_ARRAY=4;var BSON_DATA_BINARY=5;var BSON_DATA_UNDEFINED=6;var BSON_DATA_OID=7;var BSON_DATA_BOOLEAN=8;var BSON_DATA_DATE=9;var BSON_DATA_NULL=10;var BSON_DATA_REGEXP=11;var BSON_DATA_DBPOINTER=12;var BSON_DATA_CODE=13;var BSON_DATA_SYMBOL=14;var BSON_DATA_CODE_W_SCOPE=15;var BSON_DATA_INT=16;var BSON_DATA_TIMESTAMP=17;var BSON_DATA_LONG=18;var BSON_DATA_DECIMAL128=19;var BSON_DATA_MIN_KEY=255;var BSON_DATA_MAX_KEY=127;var BSON_BINARY_SUBTYPE_DEFAULT=0;var BSON_BINARY_SUBTYPE_UUID_NEW=4;var BSONType=Object.freeze({double:1,string:2,object:3,array:4,binData:5,undefined:6,objectId:7,bool:8,date:9,null:10,regex:11,dbPointer:12,javascript:13,symbol:14,javascriptWithScope:15,int:16,timestamp:17,long:18,decimal:19,minKey:-1,maxKey:127});var BSONError=class extends Error{get bsonError(){return true}get name(){return"BSONError"}constructor(message){super(message)}static isBSONError(value){return value!=null&&typeof value==="object"&&"bsonError"in value&&value.bsonError===true&&"name"in value&&"message"in value&&"stack"in value}};var BSONVersionError=class extends BSONError{get name(){return"BSONVersionError"}constructor(){super(`Unsupported BSON version, bson types must be from bson ${BSON_MAJOR_VERSION}.0 or later`)}};var BSONRuntimeError=class extends BSONError{get name(){return"BSONRuntimeError"}constructor(message){super(message)}};function nodejsMathRandomBytes(byteLength){return nodeJsByteUtils.fromNumberArray(Array.from({length:byteLength},()=>Math.floor(Math.random()*256)))}var nodejsRandomBytes=(()=>{try{return __require("crypto").randomBytes}catch{return nodejsMathRandomBytes}})();var nodeJsByteUtils={toLocalBufferType(potentialBuffer){if(Buffer.isBuffer(potentialBuffer)){return potentialBuffer}if(ArrayBuffer.isView(potentialBuffer)){return Buffer.from(potentialBuffer.buffer,potentialBuffer.byteOffset,potentialBuffer.byteLength)}const stringTag=potentialBuffer?.[Symbol.toStringTag]??Object.prototype.toString.call(potentialBuffer);if(stringTag==="ArrayBuffer"||stringTag==="SharedArrayBuffer"||stringTag==="[object ArrayBuffer]"||stringTag==="[object SharedArrayBuffer]"){return Buffer.from(potentialBuffer)}throw new BSONError(`Cannot create Buffer from ${String(potentialBuffer)}`)},allocate(size){return Buffer.alloc(size)},equals(a,b){return nodeJsByteUtils.toLocalBufferType(a).equals(b)},fromNumberArray(array){return Buffer.from(array)},fromBase64(base64){return Buffer.from(base64,"base64")},toBase64(buffer2){return nodeJsByteUtils.toLocalBufferType(buffer2).toString("base64")},fromISO88591(codePoints){return Buffer.from(codePoints,"binary")},toISO88591(buffer2){return nodeJsByteUtils.toLocalBufferType(buffer2).toString("binary")},fromHex(hex){return Buffer.from(hex,"hex")},toHex(buffer2){return nodeJsByteUtils.toLocalBufferType(buffer2).toString("hex")},fromUTF8(text){return Buffer.from(text,"utf8")},toUTF8(buffer2){return nodeJsByteUtils.toLocalBufferType(buffer2).toString("utf8")},utf8ByteLength(input){return Buffer.byteLength(input,"utf8")},encodeUTF8Into(buffer2,source,byteOffset){return nodeJsByteUtils.toLocalBufferType(buffer2).write(source,byteOffset,void 0,"utf8")},randomBytes:nodejsRandomBytes};function isReactNative(){const{navigator}=globalThis;return typeof navigator==="object"&&navigator.product==="ReactNative"}function webMathRandomBytes(byteLength){if(byteLength<0){throw new RangeError(`The argument 'byteLength' is invalid. Received ${byteLength}`)}return webByteUtils.fromNumberArray(Array.from({length:byteLength},()=>Math.floor(Math.random()*256)))}var webRandomBytes=(()=>{const{crypto}=globalThis;if(crypto!=null&&typeof crypto.getRandomValues==="function"){return byteLength=>{return crypto.getRandomValues(webByteUtils.allocate(byteLength))}}else{if(isReactNative()){const{console:console2}=globalThis;console2?.warn?.("BSON: For React Native please polyfill crypto.getRandomValues, e.g. using: https://www.npmjs.com/package/react-native-get-random-values.")}return webMathRandomBytes}})();var HEX_DIGIT=/(\d|[a-f])/i;var webByteUtils={toLocalBufferType(potentialUint8array){const stringTag=potentialUint8array?.[Symbol.toStringTag]??Object.prototype.toString.call(potentialUint8array);if(stringTag==="Uint8Array"){return potentialUint8array}if(ArrayBuffer.isView(potentialUint8array)){return new Uint8Array(potentialUint8array.buffer.slice(potentialUint8array.byteOffset,potentialUint8array.byteOffset+potentialUint8array.byteLength))}if(stringTag==="ArrayBuffer"||stringTag==="SharedArrayBuffer"||stringTag==="[object ArrayBuffer]"||stringTag==="[object SharedArrayBuffer]"){return new Uint8Array(potentialUint8array)}throw new BSONError(`Cannot make a Uint8Array from ${String(potentialUint8array)}`)},allocate(size){if(typeof size!=="number"){throw new TypeError(`The "size" argument must be of type number. Received ${String(size)}`)}return new Uint8Array(size)},equals(a,b){if(a.byteLength!==b.byteLength){return false}for(let i=0;ic.charCodeAt(0))},toBase64(uint8array){return btoa(webByteUtils.toISO88591(uint8array))},fromISO88591(codePoints){return Uint8Array.from(codePoints,c=>c.charCodeAt(0)&255)},toISO88591(uint8array){return Array.from(Uint16Array.from(uint8array),b=>String.fromCharCode(b)).join("")},fromHex(hex){const evenLengthHex=hex.length%2===0?hex:hex.slice(0,hex.length-1);const buffer2=[];for(let i=0;ibyte.toString(16).padStart(2,"0")).join("")},fromUTF8(text){return new TextEncoder().encode(text)},toUTF8(uint8array){return new TextDecoder("utf8",{fatal:false}).decode(uint8array)},utf8ByteLength(input){return webByteUtils.fromUTF8(input).byteLength},encodeUTF8Into(buffer2,source,byteOffset){const bytes=webByteUtils.fromUTF8(source);buffer2.set(bytes,byteOffset);return bytes.byteLength},randomBytes:webRandomBytes};var hasGlobalBuffer=typeof Buffer==="function"&&Buffer.prototype?._isBuffer!==true;var ByteUtils=hasGlobalBuffer?nodeJsByteUtils:webByteUtils;var BSONDataView=class extends DataView{static fromUint8Array(input){return new DataView(input.buffer,input.byteOffset,input.byteLength)}};var VALIDATION_REGEX=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15})$/i;var uuidValidateString=str2=>typeof str2==="string"&&VALIDATION_REGEX.test(str2);var uuidHexStringToBuffer=hexString=>{if(!uuidValidateString(hexString)){throw new BSONError('UUID string representations must be a 32 or 36 character hex string (dashes excluded/included). Format: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" or "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".')}const sanitizedHexString=hexString.replace(/-/g,"");return ByteUtils.fromHex(sanitizedHexString)};function bufferToUuidHexString(buffer2,includeDashes=true){if(includeDashes){return[ByteUtils.toHex(buffer2.subarray(0,4)),ByteUtils.toHex(buffer2.subarray(4,6)),ByteUtils.toHex(buffer2.subarray(6,8)),ByteUtils.toHex(buffer2.subarray(8,10)),ByteUtils.toHex(buffer2.subarray(10,16))].join("-")}return ByteUtils.toHex(buffer2)}function isAnyArrayBuffer(value){return["[object ArrayBuffer]","[object SharedArrayBuffer]"].includes(Object.prototype.toString.call(value))}function isUint8Array(value){return Object.prototype.toString.call(value)==="[object Uint8Array]"}function isRegExp(d2){return Object.prototype.toString.call(d2)==="[object RegExp]"}function isMap(d2){return Object.prototype.toString.call(d2)==="[object Map]"}function isDate(d2){return Object.prototype.toString.call(d2)==="[object Date]"}var BSONValue=class{get[Symbol.for("@@mdb.bson.version")](){return BSON_MAJOR_VERSION}};var Binary=class _Binary extends BSONValue{get _bsontype(){return"Binary"}constructor(buffer2,subType){super();if(!(buffer2==null)&&!(typeof buffer2==="string")&&!ArrayBuffer.isView(buffer2)&&!(buffer2 instanceof ArrayBuffer)&&!Array.isArray(buffer2)){throw new BSONError("Binary can only be constructed from string, Buffer, TypedArray, or Array")}this.sub_type=subType??_Binary.BSON_BINARY_SUBTYPE_DEFAULT;if(buffer2==null){this.buffer=ByteUtils.allocate(_Binary.BUFFER_SIZE);this.position=0}else{if(typeof buffer2==="string"){this.buffer=ByteUtils.fromISO88591(buffer2)}else if(Array.isArray(buffer2)){this.buffer=ByteUtils.fromNumberArray(buffer2)}else{this.buffer=ByteUtils.toLocalBufferType(buffer2)}this.position=this.buffer.byteLength}}put(byteValue){if(typeof byteValue==="string"&&byteValue.length!==1){throw new BSONError("only accepts single character String")}else if(typeof byteValue!=="number"&&byteValue.length!==1)throw new BSONError("only accepts single character Uint8Array or Array");let decodedByte;if(typeof byteValue==="string"){decodedByte=byteValue.charCodeAt(0)}else if(typeof byteValue==="number"){decodedByte=byteValue}else{decodedByte=byteValue[0]}if(decodedByte<0||decodedByte>255){throw new BSONError("only accepts number in a valid unsigned byte range 0-255")}if(this.buffer.byteLength>this.position){this.buffer[this.position++]=decodedByte}else{const newSpace=ByteUtils.allocate(_Binary.BUFFER_SIZE+this.buffer.length);newSpace.set(this.buffer,0);this.buffer=newSpace;this.buffer[this.position++]=decodedByte}}write(sequence,offset){offset=typeof offset==="number"?offset:this.position;if(this.buffer.byteLengththis.position?offset+sequence.length:this.position}else if(typeof sequence==="string"){const bytes=ByteUtils.fromISO88591(sequence);this.buffer.set(bytes,offset);this.position=offset+sequence.length>this.position?offset+sequence.length:this.position}}read(position,length){length=length&&length>0?length:this.position;return this.buffer.slice(position,position+length)}value(asRaw){asRaw=!!asRaw;if(asRaw&&this.buffer.length===this.position){return this.buffer}if(asRaw){return this.buffer.slice(0,this.position)}return ByteUtils.toISO88591(this.buffer.subarray(0,this.position))}length(){return this.position}toJSON(){return ByteUtils.toBase64(this.buffer)}toString(encoding){if(encoding==="hex")return ByteUtils.toHex(this.buffer);if(encoding==="base64")return ByteUtils.toBase64(this.buffer);if(encoding==="utf8"||encoding==="utf-8")return ByteUtils.toUTF8(this.buffer);return ByteUtils.toUTF8(this.buffer)}toExtendedJSON(options){options=options||{};const base64String=ByteUtils.toBase64(this.buffer);const subType=Number(this.sub_type).toString(16);if(options.legacy){return{$binary:base64String,$type:subType.length===1?"0"+subType:subType}}return{$binary:{base64:base64String,subType:subType.length===1?"0"+subType:subType}}}toUUID(){if(this.sub_type===_Binary.SUBTYPE_UUID){return new UUID(this.buffer.slice(0,this.position))}throw new BSONError(`Binary sub_type "${this.sub_type}" is not supported for converting to UUID. Only "${_Binary.SUBTYPE_UUID}" is currently supported.`)}static fromExtendedJSON(doc,options){options=options||{};let data;let type;if("$binary"in doc){if(options.legacy&&typeof doc.$binary==="string"&&"$type"in doc){type=doc.$type?parseInt(doc.$type,16):0;data=ByteUtils.fromBase64(doc.$binary)}else{if(typeof doc.$binary!=="string"){type=doc.$binary.subType?parseInt(doc.$binary.subType,16):0;data=ByteUtils.fromBase64(doc.$binary.base64)}}}else if("$uuid"in doc){type=4;data=uuidHexStringToBuffer(doc.$uuid)}if(!data){throw new BSONError(`Unexpected Binary Extended JSON format ${JSON.stringify(doc)}`)}return type===BSON_BINARY_SUBTYPE_UUID_NEW?new UUID(data):new _Binary(data,type)}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){return`new Binary(Buffer.from("${ByteUtils.toHex(this.buffer)}", "hex"), ${this.sub_type})`}};Binary.BSON_BINARY_SUBTYPE_DEFAULT=0;Binary.BUFFER_SIZE=256;Binary.SUBTYPE_DEFAULT=0;Binary.SUBTYPE_FUNCTION=1;Binary.SUBTYPE_BYTE_ARRAY=2;Binary.SUBTYPE_UUID_OLD=3;Binary.SUBTYPE_UUID=4;Binary.SUBTYPE_MD5=5;Binary.SUBTYPE_ENCRYPTED=6;Binary.SUBTYPE_COLUMN=7;Binary.SUBTYPE_USER_DEFINED=128;var UUID_BYTE_LENGTH=16;var UUID=class _UUID extends Binary{constructor(input){let bytes;let hexStr;if(input==null){bytes=_UUID.generate()}else if(input instanceof _UUID){bytes=ByteUtils.toLocalBufferType(new Uint8Array(input.buffer));hexStr=input.__id}else if(ArrayBuffer.isView(input)&&input.byteLength===UUID_BYTE_LENGTH){bytes=ByteUtils.toLocalBufferType(input)}else if(typeof input==="string"){bytes=uuidHexStringToBuffer(input)}else{throw new BSONError("Argument passed in UUID constructor must be a UUID, a 16 byte Buffer or a 32/36 character hex string (dashes excluded/included, format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).")}super(bytes,BSON_BINARY_SUBTYPE_UUID_NEW);this.__id=hexStr}get id(){return this.buffer}set id(value){this.buffer=value;if(_UUID.cacheHexString){this.__id=bufferToUuidHexString(value)}}toHexString(includeDashes=true){if(_UUID.cacheHexString&&this.__id){return this.__id}const uuidHexString=bufferToUuidHexString(this.id,includeDashes);if(_UUID.cacheHexString){this.__id=uuidHexString}return uuidHexString}toString(encoding){if(encoding==="hex")return ByteUtils.toHex(this.id);if(encoding==="base64")return ByteUtils.toBase64(this.id);return this.toHexString()}toJSON(){return this.toHexString()}equals(otherId){if(!otherId){return false}if(otherId instanceof _UUID){return ByteUtils.equals(otherId.id,this.id)}try{return ByteUtils.equals(new _UUID(otherId).id,this.id)}catch{return false}}toBinary(){return new Binary(this.id,Binary.SUBTYPE_UUID)}static generate(){const bytes=ByteUtils.randomBytes(UUID_BYTE_LENGTH);bytes[6]=bytes[6]&15|64;bytes[8]=bytes[8]&63|128;return bytes}static isValid(input){if(!input){return false}if(input instanceof _UUID){return true}if(typeof input==="string"){return uuidValidateString(input)}if(isUint8Array(input)){if(input.byteLength!==UUID_BYTE_LENGTH){return false}return(input[6]&240)===64&&(input[8]&128)===128}return false}static createFromHexString(hexString){const buffer2=uuidHexStringToBuffer(hexString);return new _UUID(buffer2)}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){return`new UUID("${this.toHexString()}")`}};var Code=class _Code extends BSONValue{get _bsontype(){return"Code"}constructor(code,scope){super();this.code=code.toString();this.scope=scope??null}toJSON(){if(this.scope!=null){return{code:this.code,scope:this.scope}}return{code:this.code}}toExtendedJSON(){if(this.scope){return{$code:this.code,$scope:this.scope}}return{$code:this.code}}static fromExtendedJSON(doc){return new _Code(doc.$code,doc.$scope)}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){const codeJson=this.toJSON();return`new Code("${String(codeJson.code)}"${codeJson.scope!=null?`, ${JSON.stringify(codeJson.scope)}`:""})`}};function isDBRefLike(value){return value!=null&&typeof value==="object"&&"$id"in value&&value.$id!=null&&"$ref"in value&&typeof value.$ref==="string"&&(!("$db"in value)||"$db"in value&&typeof value.$db==="string")}var DBRef=class _DBRef extends BSONValue{get _bsontype(){return"DBRef"}constructor(collection,oid,db,fields){super();const parts=collection.split(".");if(parts.length===2){db=parts.shift();collection=parts.shift()}this.collection=collection;this.oid=oid;this.db=db;this.fields=fields||{}}get namespace(){return this.collection}set namespace(value){this.collection=value}toJSON(){const o=Object.assign({$ref:this.collection,$id:this.oid},this.fields);if(this.db!=null)o.$db=this.db;return o}toExtendedJSON(options){options=options||{};let o={$ref:this.collection,$id:this.oid};if(options.legacy){return o}if(this.db)o.$db=this.db;o=Object.assign(o,this.fields);return o}static fromExtendedJSON(doc){const copy=Object.assign({},doc);delete copy.$ref;delete copy.$id;delete copy.$db;return new _DBRef(doc.$ref,doc.$id,doc.$db,copy)}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){const oid=this.oid===void 0||this.oid.toString===void 0?this.oid:this.oid.toString();return`new DBRef("${this.namespace}", new ObjectId("${String(oid)}")${this.db?`, "${this.db}"`:""})`}};var wasm=void 0;try{wasm=new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0,97,115,109,1,0,0,0,1,13,2,96,0,1,127,96,4,127,127,127,127,1,127,3,7,6,0,1,1,1,1,1,6,6,1,127,1,65,0,11,7,50,6,3,109,117,108,0,1,5,100,105,118,95,115,0,2,5,100,105,118,95,117,0,3,5,114,101,109,95,115,0,4,5,114,101,109,95,117,0,5,8,103,101,116,95,104,105,103,104,0,0,10,191,1,6,4,0,35,0,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,126,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,127,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,128,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,129,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,130,34,4,66,32,135,167,36,0,32,4,167,11])),{}).exports}catch{}var TWO_PWR_16_DBL=1<<16;var TWO_PWR_24_DBL=1<<24;var TWO_PWR_32_DBL=TWO_PWR_16_DBL*TWO_PWR_16_DBL;var TWO_PWR_64_DBL=TWO_PWR_32_DBL*TWO_PWR_32_DBL;var TWO_PWR_63_DBL=TWO_PWR_64_DBL/2;var INT_CACHE={};var UINT_CACHE={};var MAX_INT64_STRING_LENGTH=20;var DECIMAL_REG_EX=/^(\+?0|(\+|-)?[1-9][0-9]*)$/;var Long=class _Long extends BSONValue{get _bsontype(){return"Long"}get __isLong__(){return true}constructor(low=0,high,unsigned){super();if(typeof low==="bigint"){Object.assign(this,_Long.fromBigInt(low,!!high))}else if(typeof low==="string"){Object.assign(this,_Long.fromString(low,!!high))}else{this.low=low|0;this.high=high|0;this.unsigned=!!unsigned}}static fromBits(lowBits,highBits,unsigned){return new _Long(lowBits,highBits,unsigned)}static fromInt(value,unsigned){let obj,cachedObj,cache;if(unsigned){value>>>=0;if(cache=0<=value&&value<256){cachedObj=UINT_CACHE[value];if(cachedObj)return cachedObj}obj=_Long.fromBits(value,(value|0)<0?-1:0,true);if(cache)UINT_CACHE[value]=obj;return obj}else{value|=0;if(cache=-128<=value&&value<128){cachedObj=INT_CACHE[value];if(cachedObj)return cachedObj}obj=_Long.fromBits(value,value<0?-1:0,false);if(cache)INT_CACHE[value]=obj;return obj}}static fromNumber(value,unsigned){if(isNaN(value))return unsigned?_Long.UZERO:_Long.ZERO;if(unsigned){if(value<0)return _Long.UZERO;if(value>=TWO_PWR_64_DBL)return _Long.MAX_UNSIGNED_VALUE}else{if(value<=-TWO_PWR_63_DBL)return _Long.MIN_VALUE;if(value+1>=TWO_PWR_63_DBL)return _Long.MAX_VALUE}if(value<0)return _Long.fromNumber(-value,unsigned).neg();return _Long.fromBits(value%TWO_PWR_32_DBL|0,value/TWO_PWR_32_DBL|0,unsigned)}static fromBigInt(value,unsigned){return _Long.fromString(value.toString(),unsigned)}static fromString(str2,unsigned,radix){if(str2.length===0)throw new BSONError("empty string");if(str2==="NaN"||str2==="Infinity"||str2==="+Infinity"||str2==="-Infinity")return _Long.ZERO;if(typeof unsigned==="number"){radix=unsigned,unsigned=false}else{unsigned=!!unsigned}radix=radix||10;if(radix<2||360)throw new BSONError("interior hyphen");else if(p2===0){return _Long.fromString(str2.substring(1),unsigned,radix).neg()}const radixToPower=_Long.fromNumber(Math.pow(radix,8));let result=_Long.ZERO;for(let i=0;i>>16;const a32=this.high&65535;const a16=this.low>>>16;const a00=this.low&65535;const b48=addend.high>>>16;const b32=addend.high&65535;const b16=addend.low>>>16;const b00=addend.low&65535;let c48=0,c32=0,c16=0,c00=0;c00+=a00+b00;c16+=c00>>>16;c00&=65535;c16+=a16+b16;c32+=c16>>>16;c16&=65535;c32+=a32+b32;c48+=c32>>>16;c32&=65535;c48+=a48+b48;c48&=65535;return _Long.fromBits(c16<<16|c00,c48<<16|c32,this.unsigned)}and(other){if(!_Long.isLong(other))other=_Long.fromValue(other);return _Long.fromBits(this.low&other.low,this.high&other.high,this.unsigned)}compare(other){if(!_Long.isLong(other))other=_Long.fromValue(other);if(this.eq(other))return 0;const thisNeg=this.isNegative(),otherNeg=other.isNegative();if(thisNeg&&!otherNeg)return-1;if(!thisNeg&&otherNeg)return 1;if(!this.unsigned)return this.sub(other).isNegative()?-1:1;return other.high>>>0>this.high>>>0||other.high===this.high&&other.low>>>0>this.low>>>0?-1:1}comp(other){return this.compare(other)}divide(divisor){if(!_Long.isLong(divisor))divisor=_Long.fromValue(divisor);if(divisor.isZero())throw new BSONError("division by zero");if(wasm){if(!this.unsigned&&this.high===-2147483648&&divisor.low===-1&&divisor.high===-1){return this}const low=(this.unsigned?wasm.div_u:wasm.div_s)(this.low,this.high,divisor.low,divisor.high);return _Long.fromBits(low,wasm.get_high(),this.unsigned)}if(this.isZero())return this.unsigned?_Long.UZERO:_Long.ZERO;let approx,rem,res;if(!this.unsigned){if(this.eq(_Long.MIN_VALUE)){if(divisor.eq(_Long.ONE)||divisor.eq(_Long.NEG_ONE))return _Long.MIN_VALUE;else if(divisor.eq(_Long.MIN_VALUE))return _Long.ONE;else{const halfThis=this.shr(1);approx=halfThis.div(divisor).shl(1);if(approx.eq(_Long.ZERO)){return divisor.isNegative()?_Long.ONE:_Long.NEG_ONE}else{rem=this.sub(divisor.mul(approx));res=approx.add(rem.div(divisor));return res}}}else if(divisor.eq(_Long.MIN_VALUE))return this.unsigned?_Long.UZERO:_Long.ZERO;if(this.isNegative()){if(divisor.isNegative())return this.neg().div(divisor.neg());return this.neg().div(divisor).neg()}else if(divisor.isNegative())return this.div(divisor.neg()).neg();res=_Long.ZERO}else{if(!divisor.unsigned)divisor=divisor.toUnsigned();if(divisor.gt(this))return _Long.UZERO;if(divisor.gt(this.shru(1)))return _Long.UONE;res=_Long.UZERO}rem=this;while(rem.gte(divisor)){approx=Math.max(1,Math.floor(rem.toNumber()/divisor.toNumber()));const log2=Math.ceil(Math.log(approx)/Math.LN2);const delta=log2<=48?1:Math.pow(2,log2-48);let approxRes=_Long.fromNumber(approx);let approxRem=approxRes.mul(divisor);while(approxRem.isNegative()||approxRem.gt(rem)){approx-=delta;approxRes=_Long.fromNumber(approx,this.unsigned);approxRem=approxRes.mul(divisor)}if(approxRes.isZero())approxRes=_Long.ONE;res=res.add(approxRes);rem=rem.sub(approxRem)}return res}div(divisor){return this.divide(divisor)}equals(other){if(!_Long.isLong(other))other=_Long.fromValue(other);if(this.unsigned!==other.unsigned&&this.high>>>31===1&&other.high>>>31===1)return false;return this.high===other.high&&this.low===other.low}eq(other){return this.equals(other)}getHighBits(){return this.high}getHighBitsUnsigned(){return this.high>>>0}getLowBits(){return this.low}getLowBitsUnsigned(){return this.low>>>0}getNumBitsAbs(){if(this.isNegative()){return this.eq(_Long.MIN_VALUE)?64:this.neg().getNumBitsAbs()}const val=this.high!==0?this.high:this.low;let bit;for(bit=31;bit>0;bit--)if((val&1<0}gt(other){return this.greaterThan(other)}greaterThanOrEqual(other){return this.comp(other)>=0}gte(other){return this.greaterThanOrEqual(other)}ge(other){return this.greaterThanOrEqual(other)}isEven(){return(this.low&1)===0}isNegative(){return!this.unsigned&&this.high<0}isOdd(){return(this.low&1)===1}isPositive(){return this.unsigned||this.high>=0}isZero(){return this.high===0&&this.low===0}lessThan(other){return this.comp(other)<0}lt(other){return this.lessThan(other)}lessThanOrEqual(other){return this.comp(other)<=0}lte(other){return this.lessThanOrEqual(other)}modulo(divisor){if(!_Long.isLong(divisor))divisor=_Long.fromValue(divisor);if(wasm){const low=(this.unsigned?wasm.rem_u:wasm.rem_s)(this.low,this.high,divisor.low,divisor.high);return _Long.fromBits(low,wasm.get_high(),this.unsigned)}return this.sub(this.div(divisor).mul(divisor))}mod(divisor){return this.modulo(divisor)}rem(divisor){return this.modulo(divisor)}multiply(multiplier){if(this.isZero())return _Long.ZERO;if(!_Long.isLong(multiplier))multiplier=_Long.fromValue(multiplier);if(wasm){const low=wasm.mul(this.low,this.high,multiplier.low,multiplier.high);return _Long.fromBits(low,wasm.get_high(),this.unsigned)}if(multiplier.isZero())return _Long.ZERO;if(this.eq(_Long.MIN_VALUE))return multiplier.isOdd()?_Long.MIN_VALUE:_Long.ZERO;if(multiplier.eq(_Long.MIN_VALUE))return this.isOdd()?_Long.MIN_VALUE:_Long.ZERO;if(this.isNegative()){if(multiplier.isNegative())return this.neg().mul(multiplier.neg());else return this.neg().mul(multiplier).neg()}else if(multiplier.isNegative())return this.mul(multiplier.neg()).neg();if(this.lt(_Long.TWO_PWR_24)&&multiplier.lt(_Long.TWO_PWR_24))return _Long.fromNumber(this.toNumber()*multiplier.toNumber(),this.unsigned);const a48=this.high>>>16;const a32=this.high&65535;const a16=this.low>>>16;const a00=this.low&65535;const b48=multiplier.high>>>16;const b32=multiplier.high&65535;const b16=multiplier.low>>>16;const b00=multiplier.low&65535;let c48=0,c32=0,c16=0,c00=0;c00+=a00*b00;c16+=c00>>>16;c00&=65535;c16+=a16*b00;c32+=c16>>>16;c16&=65535;c16+=a00*b16;c32+=c16>>>16;c16&=65535;c32+=a32*b00;c48+=c32>>>16;c32&=65535;c32+=a16*b16;c48+=c32>>>16;c32&=65535;c32+=a00*b32;c48+=c32>>>16;c32&=65535;c48+=a48*b00+a32*b16+a16*b32+a00*b48;c48&=65535;return _Long.fromBits(c16<<16|c00,c48<<16|c32,this.unsigned)}mul(multiplier){return this.multiply(multiplier)}negate(){if(!this.unsigned&&this.eq(_Long.MIN_VALUE))return _Long.MIN_VALUE;return this.not().add(_Long.ONE)}neg(){return this.negate()}not(){return _Long.fromBits(~this.low,~this.high,this.unsigned)}notEquals(other){return!this.equals(other)}neq(other){return this.notEquals(other)}ne(other){return this.notEquals(other)}or(other){if(!_Long.isLong(other))other=_Long.fromValue(other);return _Long.fromBits(this.low|other.low,this.high|other.high,this.unsigned)}shiftLeft(numBits){if(_Long.isLong(numBits))numBits=numBits.toInt();if((numBits&=63)===0)return this;else if(numBits<32)return _Long.fromBits(this.low<>>32-numBits,this.unsigned);else return _Long.fromBits(0,this.low<>>numBits|this.high<<32-numBits,this.high>>numBits,this.unsigned);else return _Long.fromBits(this.high>>numBits-32,this.high>=0?0:-1,this.unsigned)}shr(numBits){return this.shiftRight(numBits)}shiftRightUnsigned(numBits){if(_Long.isLong(numBits))numBits=numBits.toInt();numBits&=63;if(numBits===0)return this;else{const high=this.high;if(numBits<32){const low=this.low;return _Long.fromBits(low>>>numBits|high<<32-numBits,high>>>numBits,this.unsigned)}else if(numBits===32)return _Long.fromBits(high,0,this.unsigned);else return _Long.fromBits(high>>>numBits-32,0,this.unsigned)}}shr_u(numBits){return this.shiftRightUnsigned(numBits)}shru(numBits){return this.shiftRightUnsigned(numBits)}subtract(subtrahend){if(!_Long.isLong(subtrahend))subtrahend=_Long.fromValue(subtrahend);return this.add(subtrahend.neg())}sub(subtrahend){return this.subtract(subtrahend)}toInt(){return this.unsigned?this.low>>>0:this.low}toNumber(){if(this.unsigned)return(this.high>>>0)*TWO_PWR_32_DBL+(this.low>>>0);return this.high*TWO_PWR_32_DBL+(this.low>>>0)}toBigInt(){return BigInt(this.toString())}toBytes(le){return le?this.toBytesLE():this.toBytesBE()}toBytesLE(){const hi=this.high,lo=this.low;return[lo&255,lo>>>8&255,lo>>>16&255,lo>>>24,hi&255,hi>>>8&255,hi>>>16&255,hi>>>24]}toBytesBE(){const hi=this.high,lo=this.low;return[hi>>>24,hi>>>16&255,hi>>>8&255,hi&255,lo>>>24,lo>>>16&255,lo>>>8&255,lo&255]}toSigned(){if(!this.unsigned)return this;return _Long.fromBits(this.low,this.high,false)}toString(radix){radix=radix||10;if(radix<2||36>>0;let digits=intval.toString(radix);rem=remDiv;if(rem.isZero()){return digits+result}else{while(digits.length<6)digits="0"+digits;result=""+digits+result}}}toUnsigned(){if(this.unsigned)return this;return _Long.fromBits(this.low,this.high,true)}xor(other){if(!_Long.isLong(other))other=_Long.fromValue(other);return _Long.fromBits(this.low^other.low,this.high^other.high,this.unsigned)}eqz(){return this.isZero()}le(other){return this.lessThanOrEqual(other)}toExtendedJSON(options){if(options&&options.relaxed)return this.toNumber();return{$numberLong:this.toString()}}static fromExtendedJSON(doc,options){const{useBigInt64=false,relaxed=true}={...options};if(doc.$numberLong.length>MAX_INT64_STRING_LENGTH){throw new BSONError("$numberLong string is too long")}if(!DECIMAL_REG_EX.test(doc.$numberLong)){throw new BSONError(`$numberLong string "${doc.$numberLong}" is in an invalid format`)}if(useBigInt64){const bigIntResult=BigInt(doc.$numberLong);return BigInt.asIntN(64,bigIntResult)}const longResult=_Long.fromString(doc.$numberLong);if(relaxed){return longResult.toNumber()}return longResult}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){return`new Long("${this.toString()}"${this.unsigned?", true":""})`}};Long.TWO_PWR_24=Long.fromInt(TWO_PWR_24_DBL);Long.MAX_UNSIGNED_VALUE=Long.fromBits(4294967295|0,4294967295|0,true);Long.ZERO=Long.fromInt(0);Long.UZERO=Long.fromInt(0,true);Long.ONE=Long.fromInt(1);Long.UONE=Long.fromInt(1,true);Long.NEG_ONE=Long.fromInt(-1);Long.MAX_VALUE=Long.fromBits(4294967295|0,2147483647|0,false);Long.MIN_VALUE=Long.fromBits(0,2147483648|0,false);var PARSE_STRING_REGEXP=/^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/;var PARSE_INF_REGEXP=/^(\+|-)?(Infinity|inf)$/i;var PARSE_NAN_REGEXP=/^(\+|-)?NaN$/i;var EXPONENT_MAX=6111;var EXPONENT_MIN=-6176;var EXPONENT_BIAS=6176;var MAX_DIGITS=34;var NAN_BUFFER=ByteUtils.fromNumberArray([124,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].reverse());var INF_NEGATIVE_BUFFER=ByteUtils.fromNumberArray([248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].reverse());var INF_POSITIVE_BUFFER=ByteUtils.fromNumberArray([120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].reverse());var EXPONENT_REGEX=/^([-+])?(\d+)?$/;var COMBINATION_MASK=31;var EXPONENT_MASK=16383;var COMBINATION_INFINITY=30;var COMBINATION_NAN=31;function isDigit(value){return!isNaN(parseInt(value,10))}function divideu128(value){const DIVISOR=Long.fromNumber(1e3*1e3*1e3);let _rem=Long.fromNumber(0);if(!value.parts[0]&&!value.parts[1]&&!value.parts[2]&&!value.parts[3]){return{quotient:value,rem:_rem}}for(let i=0;i<=3;i++){_rem=_rem.shiftLeft(32);_rem=_rem.add(new Long(value.parts[i],0));value.parts[i]=_rem.div(DIVISOR).low;_rem=_rem.modulo(DIVISOR)}return{quotient:value,rem:_rem}}function multiply64x2(left,right){if(!left&&!right){return{high:Long.fromNumber(0),low:Long.fromNumber(0)}}const leftHigh=left.shiftRightUnsigned(32);const leftLow=new Long(left.getLowBits(),0);const rightHigh=right.shiftRightUnsigned(32);const rightLow=new Long(right.getLowBits(),0);let productHigh=leftHigh.multiply(rightHigh);let productMid=leftHigh.multiply(rightLow);const productMid2=leftLow.multiply(rightHigh);let productLow=leftLow.multiply(rightLow);productHigh=productHigh.add(productMid.shiftRightUnsigned(32));productMid=new Long(productMid.getLowBits(),0).add(productMid2).add(productLow.shiftRightUnsigned(32));productHigh=productHigh.add(productMid.shiftRightUnsigned(32));productLow=productMid.shiftLeft(32).add(new Long(productLow.getLowBits(),0));return{high:productHigh,low:productLow}}function lessThan(left,right){const uhleft=left.high>>>0;const uhright=right.high>>>0;if(uhleft>>0;const ulright=right.low>>>0;if(ulleft=7e3){throw new BSONError(""+representation+" not a valid Decimal128 string")}const stringMatch=representation.match(PARSE_STRING_REGEXP);const infMatch=representation.match(PARSE_INF_REGEXP);const nanMatch=representation.match(PARSE_NAN_REGEXP);if(!stringMatch&&!infMatch&&!nanMatch||representation.length===0){throw new BSONError(""+representation+" not a valid Decimal128 string")}if(stringMatch){const unsignedNumber=stringMatch[2];const e=stringMatch[4];const expSign=stringMatch[5];const expNumber=stringMatch[6];if(e&&expNumber===void 0)invalidErr(representation,"missing exponent power");if(e&&unsignedNumber===void 0)invalidErr(representation,"missing exponent base");if(e===void 0&&(expSign||expNumber)){invalidErr(representation,"missing e before exponent")}}if(representation[index]==="+"||representation[index]==="-"){isNegative=representation[index++]==="-"}if(!isDigit(representation[index])&&representation[index]!=="."){if(representation[index]==="i"||representation[index]==="I"){return new _Decimal128(isNegative?INF_NEGATIVE_BUFFER:INF_POSITIVE_BUFFER)}else if(representation[index]==="N"){return new _Decimal128(NAN_BUFFER)}}while(isDigit(representation[index])||representation[index]==="."){if(representation[index]==="."){if(sawRadix)invalidErr(representation,"contains multiple periods");sawRadix=true;index=index+1;continue}if(nDigitsStored<34){if(representation[index]!=="0"||foundNonZero){if(!foundNonZero){firstNonZero=nDigitsRead}foundNonZero=true;digits[digitsInsert++]=parseInt(representation[index],10);nDigitsStored=nDigitsStored+1}}if(foundNonZero)nDigits=nDigits+1;if(sawRadix)radixPosition=radixPosition+1;nDigitsRead=nDigitsRead+1;index=index+1}if(sawRadix&&!nDigitsRead)throw new BSONError(""+representation+" not a valid Decimal128 string");if(representation[index]==="e"||representation[index]==="E"){const match=representation.substr(++index).match(EXPONENT_REGEX);if(!match||!match[2])return new _Decimal128(NAN_BUFFER);exponent=parseInt(match[0],10);index=index+match[0].length}if(representation[index])return new _Decimal128(NAN_BUFFER);firstDigit=0;if(!nDigitsStored){firstDigit=0;lastDigit=0;digits[0]=0;nDigits=1;nDigitsStored=1;significantDigits=0}else{lastDigit=nDigitsStored-1;significantDigits=nDigits;if(significantDigits!==1){while(digits[firstNonZero+significantDigits-1]===0){significantDigits=significantDigits-1}}}if(exponent<=radixPosition&&radixPosition-exponent>1<<14){exponent=EXPONENT_MIN}else{exponent=exponent-radixPosition}while(exponent>EXPONENT_MAX){lastDigit=lastDigit+1;if(lastDigit-firstDigit>MAX_DIGITS){const digitsString=digits.join("");if(digitsString.match(/^0+$/)){exponent=EXPONENT_MAX;break}invalidErr(representation,"overflow")}exponent=exponent-1}while(exponent=5){roundBit=1;if(roundDigit===5){roundBit=digits[lastDigit]%2===1?1:0;for(i=firstNonZero+lastDigit+2;i=0;dIdx--){if(++digits[dIdx]>9){digits[dIdx]=0;if(dIdx===0){if(exponent>8&255;buffer2[index++]=dec.low.low>>16&255;buffer2[index++]=dec.low.low>>24&255;buffer2[index++]=dec.low.high&255;buffer2[index++]=dec.low.high>>8&255;buffer2[index++]=dec.low.high>>16&255;buffer2[index++]=dec.low.high>>24&255;buffer2[index++]=dec.high.low&255;buffer2[index++]=dec.high.low>>8&255;buffer2[index++]=dec.high.low>>16&255;buffer2[index++]=dec.high.low>>24&255;buffer2[index++]=dec.high.high&255;buffer2[index++]=dec.high.high>>8&255;buffer2[index++]=dec.high.high>>16&255;buffer2[index++]=dec.high.high>>24&255;return new _Decimal128(buffer2)}toString(){let biased_exponent;let significand_digits=0;const significand=new Array(36);for(let i=0;i>26&COMBINATION_MASK;if(combination>>3===3){if(combination===COMBINATION_INFINITY){return string.join("")+"Infinity"}else if(combination===COMBINATION_NAN){return"NaN"}else{biased_exponent=high>>15&EXPONENT_MASK;significand_msb=8+(high>>14&1)}}else{significand_msb=high>>14&7;biased_exponent=high>>17&EXPONENT_MASK}const exponent=biased_exponent-EXPONENT_BIAS;significand128.parts[0]=(high&16383)+((significand_msb&15)<<14);significand128.parts[1]=midh;significand128.parts[2]=midl;significand128.parts[3]=low;if(significand128.parts[0]===0&&significand128.parts[1]===0&&significand128.parts[2]===0&&significand128.parts[3]===0){is_zero=true}else{for(k=3;k>=0;k--){let least_digits=0;const result=divideu128(significand128);significand128=result.quotient;least_digits=result.rem.low;if(!least_digits)continue;for(j=8;j>=0;j--){significand[k*9+j]=least_digits%10;least_digits=Math.floor(least_digits/10)}}}if(is_zero){significand_digits=1;significand[index]=0}else{significand_digits=36;while(!significand[index]){significand_digits=significand_digits-1;index=index+1}}const scientific_exponent=significand_digits-1+exponent;if(scientific_exponent>=34||scientific_exponent<=-7||exponent>0){if(significand_digits>34){string.push(`${0}`);if(exponent>0)string.push(`E+${exponent}`);else if(exponent<0)string.push(`E${exponent}`);return string.join("")}string.push(`${significand[index++]}`);significand_digits=significand_digits-1;if(significand_digits){string.push(".")}for(let i=0;i0){string.push(`+${scientific_exponent}`)}else{string.push(`${scientific_exponent}`)}}else{if(exponent>=0){for(let i=0;i0){for(let i=0;i>8&255;buffer2[9]=inc>>16&255;return buffer2}toString(encoding){if(encoding==="base64")return ByteUtils.toBase64(this.id);if(encoding==="hex")return this.toHexString();return this.toHexString()}toJSON(){return this.toHexString()}equals(otherId){if(otherId===void 0||otherId===null){return false}if(otherId instanceof _ObjectId){return this[kId][11]===otherId[kId][11]&&ByteUtils.equals(this[kId],otherId[kId])}if(typeof otherId==="string"&&_ObjectId.isValid(otherId)&&otherId.length===12&&isUint8Array(this.id)){return ByteUtils.equals(this.id,ByteUtils.fromISO88591(otherId))}if(typeof otherId==="string"&&_ObjectId.isValid(otherId)&&otherId.length===24){return otherId.toLowerCase()===this.toHexString()}if(typeof otherId==="string"&&_ObjectId.isValid(otherId)&&otherId.length===12){return ByteUtils.equals(ByteUtils.fromUTF8(otherId),this.id)}if(typeof otherId==="object"&&"toHexString"in otherId&&typeof otherId.toHexString==="function"){const otherIdString=otherId.toHexString();const thisIdString=this.toHexString().toLowerCase();return typeof otherIdString==="string"&&otherIdString.toLowerCase()===thisIdString}return false}getTimestamp(){const timestamp=new Date;const time=BSONDataView.fromUint8Array(this.id).getUint32(0,false);timestamp.setTime(Math.floor(time)*1e3);return timestamp}static createPk(){return new _ObjectId}static createFromTime(time){const buffer2=ByteUtils.fromNumberArray([0,0,0,0,0,0,0,0,0,0,0,0]);BSONDataView.fromUint8Array(buffer2).setUint32(0,time,false);return new _ObjectId(buffer2)}static createFromHexString(hexString){if(typeof hexString==="undefined"||hexString!=null&&hexString.length!==24){throw new BSONError("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters")}return new _ObjectId(ByteUtils.fromHex(hexString))}static isValid(id){if(id==null)return false;try{new _ObjectId(id);return true}catch{return false}}toExtendedJSON(){if(this.toHexString)return{$oid:this.toHexString()};return{$oid:this.toString("hex")}}static fromExtendedJSON(doc){return new _ObjectId(doc.$oid)}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){return`new ObjectId("${this.toHexString()}")`}};ObjectId2.index=Math.floor(Math.random()*16777215);function internalCalculateObjectSize(object,serializeFunctions,ignoreUndefined){let totalLength=4+1;if(Array.isArray(object)){for(let i=0;i=JS_INT_MIN&&value<=JS_INT_MAX){if(value>=BSON_INT32_MIN&&value<=BSON_INT32_MAX){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(4+1)}else{return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(8+1)}}else{return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(8+1)}case"undefined":if(isArray||!ignoreUndefined)return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1;return 0;case"boolean":return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(1+1);case"object":if(value!=null&&typeof value._bsontype==="string"&&value[Symbol.for("@@mdb.bson.version")]!==BSON_MAJOR_VERSION){throw new BSONVersionError}else if(value==null||value._bsontype==="MinKey"||value._bsontype==="MaxKey"){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1}else if(value._bsontype==="ObjectId"){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(12+1)}else if(value instanceof Date||isDate(value)){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(8+1)}else if(ArrayBuffer.isView(value)||value instanceof ArrayBuffer||isAnyArrayBuffer(value)){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(1+4+1)+value.byteLength}else if(value._bsontype==="Long"||value._bsontype==="Double"||value._bsontype==="Timestamp"){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(8+1)}else if(value._bsontype==="Decimal128"){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(16+1)}else if(value._bsontype==="Code"){if(value.scope!=null&&Object.keys(value.scope).length>0){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1+4+4+ByteUtils.utf8ByteLength(value.code.toString())+1+internalCalculateObjectSize(value.scope,serializeFunctions,ignoreUndefined)}else{return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1+4+ByteUtils.utf8ByteLength(value.code.toString())+1}}else if(value._bsontype==="Binary"){const binary=value;if(binary.sub_type===Binary.SUBTYPE_BYTE_ARRAY){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(binary.position+1+4+1+4)}else{return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(binary.position+1+4+1)}}else if(value._bsontype==="Symbol"){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+ByteUtils.utf8ByteLength(value.value)+4+1+1}else if(value._bsontype==="DBRef"){const ordered_values=Object.assign({$ref:value.collection,$id:value.oid},value.fields);if(value.db!=null){ordered_values["$db"]=value.db}return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1+internalCalculateObjectSize(ordered_values,serializeFunctions,ignoreUndefined)}else if(value instanceof RegExp||isRegExp(value)){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1+ByteUtils.utf8ByteLength(value.source)+1+(value.global?1:0)+(value.ignoreCase?1:0)+(value.multiline?1:0)+1}else if(value._bsontype==="BSONRegExp"){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1+ByteUtils.utf8ByteLength(value.pattern)+1+ByteUtils.utf8ByteLength(value.options)+1}else{return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+internalCalculateObjectSize(value,serializeFunctions,ignoreUndefined)+1}case"function":if(serializeFunctions){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1+4+ByteUtils.utf8ByteLength(value.toString())+1}}return 0}function alphabetize(str2){return str2.split("").sort().join("")}var BSONRegExp=class _BSONRegExp extends BSONValue{get _bsontype(){return"BSONRegExp"}constructor(pattern,options){super();this.pattern=pattern;this.options=alphabetize(options??"");if(this.pattern.indexOf("\0")!==-1){throw new BSONError(`BSON Regex patterns cannot contain null bytes, found: ${JSON.stringify(this.pattern)}`)}if(this.options.indexOf("\0")!==-1){throw new BSONError(`BSON Regex options cannot contain null bytes, found: ${JSON.stringify(this.options)}`)}for(let i=0;i4294967295){throw new BSONError("Timestamp constructed from { t, i } must provide t equal or less than uint32 max")}if(low.i>4294967295){throw new BSONError("Timestamp constructed from { t, i } must provide i equal or less than uint32 max")}super(low.i.valueOf(),low.t.valueOf(),true)}else{throw new BSONError("A Timestamp can only be constructed with: bigint, Long, or { t: number; i: number }")}}toJSON(){return{$timestamp:this.toString()}}static fromInt(value){return new _Timestamp(Long.fromInt(value,true))}static fromNumber(value){return new _Timestamp(Long.fromNumber(value,true))}static fromBits(lowBits,highBits){return new _Timestamp({i:lowBits,t:highBits})}static fromString(str2,optRadix){return new _Timestamp(Long.fromString(str2,true,optRadix))}toExtendedJSON(){return{$timestamp:{t:this.high>>>0,i:this.low>>>0}}}static fromExtendedJSON(doc){const i=Long.isLong(doc.$timestamp.i)?doc.$timestamp.i.getLowBitsUnsigned():doc.$timestamp.i;const t=Long.isLong(doc.$timestamp.t)?doc.$timestamp.t.getLowBitsUnsigned():doc.$timestamp.t;return new _Timestamp({t,i})}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){return`new Timestamp({ t: ${this.getHighBits()}, i: ${this.getLowBits()} })`}};Timestamp.MAX_VALUE=Long.MAX_UNSIGNED_VALUE;var FIRST_BIT=128;var FIRST_TWO_BITS=192;var FIRST_THREE_BITS=224;var FIRST_FOUR_BITS=240;var FIRST_FIVE_BITS=248;var TWO_BIT_CHAR=192;var THREE_BIT_CHAR=224;var FOUR_BIT_CHAR=240;var CONTINUING_CHAR=128;function validateUtf8(bytes,start,end){let continuation=0;for(let i=start;i= 5, is ${size}`)}if(options.allowObjectSmallerThanBufferSize&&buffer2.length= bson size ${size}`)}if(!options.allowObjectSmallerThanBufferSize&&buffer2.length!==size){throw new BSONError(`buffer length ${buffer2.length} must === bson size ${size}`)}if(size+index>buffer2.byteLength){throw new BSONError(`(bson size ${size} + options.index ${index} must be <= buffer length ${buffer2.byteLength})`)}if(buffer2[index+size-1]!==0){throw new BSONError("One object, sized correctly, with a spot for an EOO, but the EOO isn't 0x00")}return deserializeObject(buffer2,index,options,isArray)}var allowedDBRefKeys=/^\$ref$|^\$id$|^\$db$/;function deserializeObject(buffer2,index,options,isArray=false){const fieldsAsRaw=options["fieldsAsRaw"]==null?null:options["fieldsAsRaw"];const raw=options["raw"]==null?false:options["raw"];const bsonRegExp=typeof options["bsonRegExp"]==="boolean"?options["bsonRegExp"]:false;const promoteBuffers=options.promoteBuffers??false;const promoteLongs=options.promoteLongs??true;const promoteValues=options.promoteValues??true;const useBigInt64=options.useBigInt64??false;if(useBigInt64&&!promoteValues){throw new BSONError("Must either request bigint or Long for int64 deserialization")}if(useBigInt64&&!promoteLongs){throw new BSONError("Must either request bigint or Long for int64 deserialization")}const validation=options.validation==null?{utf8:true}:options.validation;let globalUTFValidation=true;let validationSetting;const utf8KeysSet=new Set;const utf8ValidatedKeys=validation.utf8;if(typeof utf8ValidatedKeys==="boolean"){validationSetting=utf8ValidatedKeys}else{globalUTFValidation=false;const utf8ValidationValues=Object.keys(utf8ValidatedKeys).map(function(key){return utf8ValidatedKeys[key]});if(utf8ValidationValues.length===0){throw new BSONError("UTF-8 validation setting cannot be empty")}if(typeof utf8ValidationValues[0]!=="boolean"){throw new BSONError("Invalid UTF-8 validation option, must specify boolean values")}validationSetting=utf8ValidationValues[0];if(!utf8ValidationValues.every(item=>item===validationSetting)){throw new BSONError("Invalid UTF-8 validation option - keys must be all true or all false")}}if(!globalUTFValidation){for(const key of Object.keys(utf8ValidatedKeys)){utf8KeysSet.add(key)}}const startIndex=index;if(buffer2.length<5)throw new BSONError("corrupt bson message < 5 bytes long");const size=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(size<5||size>buffer2.length)throw new BSONError("corrupt bson message");const object=isArray?[]:{};let arrayIndex=0;const done=false;let isPossibleDBRef=isArray?false:null;const dataview=new DataView(buffer2.buffer,buffer2.byteOffset,buffer2.byteLength);while(!done){const elementType=buffer2[index++];if(elementType===0)break;let i=index;while(buffer2[i]!==0&&i=buffer2.byteLength)throw new BSONError("Bad BSON Document: illegal CString");const name=isArray?arrayIndex++:ByteUtils.toUTF8(buffer2.subarray(index,i));let shouldValidateKey=true;if(globalUTFValidation||utf8KeysSet.has(name)){shouldValidateKey=validationSetting}else{shouldValidateKey=!validationSetting}if(isPossibleDBRef!==false&&name[0]==="$"){isPossibleDBRef=allowedDBRefKeys.test(name)}let value;index=i+1;if(elementType===BSON_DATA_STRING){const stringSize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(stringSize<=0||stringSize>buffer2.length-index||buffer2[index+stringSize-1]!==0){throw new BSONError("bad string length in bson")}value=getValidatedString(buffer2,index,index+stringSize-1,shouldValidateKey);index=index+stringSize}else if(elementType===BSON_DATA_OID){const oid=ByteUtils.allocate(12);oid.set(buffer2.subarray(index,index+12));value=new ObjectId2(oid);index=index+12}else if(elementType===BSON_DATA_INT&&promoteValues===false){value=new Int32(buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24)}else if(elementType===BSON_DATA_INT){value=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24}else if(elementType===BSON_DATA_NUMBER&&promoteValues===false){value=new Double(dataview.getFloat64(index,true));index=index+8}else if(elementType===BSON_DATA_NUMBER){value=dataview.getFloat64(index,true);index=index+8}else if(elementType===BSON_DATA_DATE){const lowBits=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;const highBits=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;value=new Date(new Long(lowBits,highBits).toNumber())}else if(elementType===BSON_DATA_BOOLEAN){if(buffer2[index]!==0&&buffer2[index]!==1)throw new BSONError("illegal boolean type value");value=buffer2[index++]===1}else if(elementType===BSON_DATA_OBJECT){const _index=index;const objectSize=buffer2[index]|buffer2[index+1]<<8|buffer2[index+2]<<16|buffer2[index+3]<<24;if(objectSize<=0||objectSize>buffer2.length-index)throw new BSONError("bad embedded document length in bson");if(raw){value=buffer2.slice(index,index+objectSize)}else{let objectOptions=options;if(!globalUTFValidation){objectOptions={...options,validation:{utf8:shouldValidateKey}}}value=deserializeObject(buffer2,_index,objectOptions,false)}index=index+objectSize}else if(elementType===BSON_DATA_ARRAY){const _index=index;const objectSize=buffer2[index]|buffer2[index+1]<<8|buffer2[index+2]<<16|buffer2[index+3]<<24;let arrayOptions=options;const stopIndex=index+objectSize;if(fieldsAsRaw&&fieldsAsRaw[name]){arrayOptions={...options,raw:true}}if(!globalUTFValidation){arrayOptions={...arrayOptions,validation:{utf8:shouldValidateKey}}}value=deserializeObject(buffer2,_index,arrayOptions,true);index=index+objectSize;if(buffer2[index-1]!==0)throw new BSONError("invalid array terminator byte");if(index!==stopIndex)throw new BSONError("corrupted array bson")}else if(elementType===BSON_DATA_UNDEFINED){value=void 0}else if(elementType===BSON_DATA_NULL){value=null}else if(elementType===BSON_DATA_LONG){const dataview2=BSONDataView.fromUint8Array(buffer2.subarray(index,index+8));const lowBits=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;const highBits=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;const long=new Long(lowBits,highBits);if(useBigInt64){value=dataview2.getBigInt64(0,true)}else if(promoteLongs&&promoteValues===true){value=long.lessThanOrEqual(JS_INT_MAX_LONG)&&long.greaterThanOrEqual(JS_INT_MIN_LONG)?long.toNumber():long}else{value=long}}else if(elementType===BSON_DATA_DECIMAL128){const bytes=ByteUtils.allocate(16);bytes.set(buffer2.subarray(index,index+16),0);index=index+16;value=new Decimal128(bytes)}else if(elementType===BSON_DATA_BINARY){let binarySize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;const totalBinarySize=binarySize;const subType=buffer2[index++];if(binarySize<0)throw new BSONError("Negative binary type element size found");if(binarySize>buffer2.byteLength)throw new BSONError("Binary type size larger than document size");if(buffer2["slice"]!=null){if(subType===Binary.SUBTYPE_BYTE_ARRAY){binarySize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(binarySize<0)throw new BSONError("Negative binary type element size found for subtype 0x02");if(binarySize>totalBinarySize-4)throw new BSONError("Binary type with subtype 0x02 contains too long binary size");if(binarySizetotalBinarySize-4)throw new BSONError("Binary type with subtype 0x02 contains too long binary size");if(binarySize=buffer2.length)throw new BSONError("Bad BSON Document: illegal CString");const source=ByteUtils.toUTF8(buffer2.subarray(index,i));index=i+1;i=index;while(buffer2[i]!==0&&i=buffer2.length)throw new BSONError("Bad BSON Document: illegal CString");const regExpOptions=ByteUtils.toUTF8(buffer2.subarray(index,i));index=i+1;const optionsArray=new Array(regExpOptions.length);for(i=0;i=buffer2.length)throw new BSONError("Bad BSON Document: illegal CString");const source=ByteUtils.toUTF8(buffer2.subarray(index,i));index=i+1;i=index;while(buffer2[i]!==0&&i=buffer2.length)throw new BSONError("Bad BSON Document: illegal CString");const regExpOptions=ByteUtils.toUTF8(buffer2.subarray(index,i));index=i+1;value=new BSONRegExp(source,regExpOptions)}else if(elementType===BSON_DATA_SYMBOL){const stringSize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(stringSize<=0||stringSize>buffer2.length-index||buffer2[index+stringSize-1]!==0){throw new BSONError("bad string length in bson")}const symbol=getValidatedString(buffer2,index,index+stringSize-1,shouldValidateKey);value=promoteValues?symbol:new BSONSymbol(symbol);index=index+stringSize}else if(elementType===BSON_DATA_TIMESTAMP){const i2=buffer2[index++]+buffer2[index++]*(1<<8)+buffer2[index++]*(1<<16)+buffer2[index++]*(1<<24);const t=buffer2[index++]+buffer2[index++]*(1<<8)+buffer2[index++]*(1<<16)+buffer2[index++]*(1<<24);value=new Timestamp({i:i2,t})}else if(elementType===BSON_DATA_MIN_KEY){value=new MinKey}else if(elementType===BSON_DATA_MAX_KEY){value=new MaxKey}else if(elementType===BSON_DATA_CODE){const stringSize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(stringSize<=0||stringSize>buffer2.length-index||buffer2[index+stringSize-1]!==0){throw new BSONError("bad string length in bson")}const functionString=getValidatedString(buffer2,index,index+stringSize-1,shouldValidateKey);value=new Code(functionString);index=index+stringSize}else if(elementType===BSON_DATA_CODE_W_SCOPE){const totalSize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(totalSize<4+4+4+1){throw new BSONError("code_w_scope total size shorter minimum expected length")}const stringSize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(stringSize<=0||stringSize>buffer2.length-index||buffer2[index+stringSize-1]!==0){throw new BSONError("bad string length in bson")}const functionString=getValidatedString(buffer2,index,index+stringSize-1,shouldValidateKey);index=index+stringSize;const _index=index;const objectSize=buffer2[index]|buffer2[index+1]<<8|buffer2[index+2]<<16|buffer2[index+3]<<24;const scopeObject=deserializeObject(buffer2,_index,options,false);index=index+objectSize;if(totalSize<4+4+objectSize+stringSize){throw new BSONError("code_w_scope total size is too short, truncating scope")}if(totalSize>4+4+objectSize+stringSize){throw new BSONError("code_w_scope total size is too long, clips outer document")}value=new Code(functionString,scopeObject)}else if(elementType===BSON_DATA_DBPOINTER){const stringSize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(stringSize<=0||stringSize>buffer2.length-index||buffer2[index+stringSize-1]!==0)throw new BSONError("bad string length in bson");if(validation!=null&&validation.utf8){if(!validateUtf8(buffer2,index,index+stringSize-1)){throw new BSONError("Invalid UTF-8 string in BSON document")}}const namespace=ByteUtils.toUTF8(buffer2.subarray(index,index+stringSize-1));index=index+stringSize;const oidBuffer=ByteUtils.allocate(12);oidBuffer.set(buffer2.subarray(index,index+12),0);const oid=new ObjectId2(oidBuffer);index=index+12;value=new DBRef(namespace,oid)}else{throw new BSONError(`Detected unknown BSON type ${elementType.toString(16)} for fieldname "${name}"`)}if(name==="__proto__"){Object.defineProperty(object,name,{value,writable:true,enumerable:true,configurable:true})}else{object[name]=value}}if(size!==index-startIndex){if(isArray)throw new BSONError("corrupt array bson");throw new BSONError("corrupt object bson")}if(!isPossibleDBRef)return object;if(isDBRefLike(object)){const copy=Object.assign({},object);delete copy.$ref;delete copy.$id;delete copy.$db;return new DBRef(object.$ref,object.$id,object.$db,copy)}return object}function getValidatedString(buffer2,start,end,shouldValidateUtf8){const value=ByteUtils.toUTF8(buffer2.subarray(start,end));if(shouldValidateUtf8){for(let i=0;i>24&255;buffer2[index+2]=size+1>>16&255;buffer2[index+1]=size+1>>8&255;buffer2[index]=size+1&255;index=index+4+size;buffer2[index++]=0;return index}var NUMBER_SPACE=new DataView(new ArrayBuffer(8),0,8);var FOUR_BYTE_VIEW_ON_NUMBER=new Uint8Array(NUMBER_SPACE.buffer,0,4);var EIGHT_BYTE_VIEW_ON_NUMBER=new Uint8Array(NUMBER_SPACE.buffer,0,8);function serializeNumber(buffer2,key,value,index){const isNegativeZero=Object.is(value,-0);const type=!isNegativeZero&&Number.isSafeInteger(value)&&value<=BSON_INT32_MAX&&value>=BSON_INT32_MIN?BSON_DATA_INT:BSON_DATA_NUMBER;if(type===BSON_DATA_INT){NUMBER_SPACE.setInt32(0,value,true)}else{NUMBER_SPACE.setFloat64(0,value,true)}const bytes=type===BSON_DATA_INT?FOUR_BYTE_VIEW_ON_NUMBER:EIGHT_BYTE_VIEW_ON_NUMBER;buffer2[index++]=type;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;buffer2.set(bytes,index);index+=bytes.byteLength;return index}function serializeBigInt(buffer2,key,value,index){buffer2[index++]=BSON_DATA_LONG;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index+=numberOfWrittenBytes;buffer2[index++]=0;NUMBER_SPACE.setBigInt64(0,value,true);buffer2.set(EIGHT_BYTE_VIEW_ON_NUMBER,index);index+=EIGHT_BYTE_VIEW_ON_NUMBER.byteLength;return index}function serializeNull(buffer2,key,_,index){buffer2[index++]=BSON_DATA_NULL;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;return index}function serializeBoolean(buffer2,key,value,index){buffer2[index++]=BSON_DATA_BOOLEAN;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;buffer2[index++]=value?1:0;return index}function serializeDate(buffer2,key,value,index){buffer2[index++]=BSON_DATA_DATE;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const dateInMilis=Long.fromNumber(value.getTime());const lowBits=dateInMilis.getLowBits();const highBits=dateInMilis.getHighBits();buffer2[index++]=lowBits&255;buffer2[index++]=lowBits>>8&255;buffer2[index++]=lowBits>>16&255;buffer2[index++]=lowBits>>24&255;buffer2[index++]=highBits&255;buffer2[index++]=highBits>>8&255;buffer2[index++]=highBits>>16&255;buffer2[index++]=highBits>>24&255;return index}function serializeRegExp(buffer2,key,value,index){buffer2[index++]=BSON_DATA_REGEXP;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;if(value.source&&value.source.match(regexp)!=null){throw new BSONError("value "+value.source+" must not contain null bytes")}index=index+ByteUtils.encodeUTF8Into(buffer2,value.source,index);buffer2[index++]=0;if(value.ignoreCase)buffer2[index++]=105;if(value.global)buffer2[index++]=115;if(value.multiline)buffer2[index++]=109;buffer2[index++]=0;return index}function serializeBSONRegExp(buffer2,key,value,index){buffer2[index++]=BSON_DATA_REGEXP;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;if(value.pattern.match(regexp)!=null){throw new BSONError("pattern "+value.pattern+" must not contain null bytes")}index=index+ByteUtils.encodeUTF8Into(buffer2,value.pattern,index);buffer2[index++]=0;const sortedOptions=value.options.split("").sort().join("");index=index+ByteUtils.encodeUTF8Into(buffer2,sortedOptions,index);buffer2[index++]=0;return index}function serializeMinMax(buffer2,key,value,index){if(value===null){buffer2[index++]=BSON_DATA_NULL}else if(value._bsontype==="MinKey"){buffer2[index++]=BSON_DATA_MIN_KEY}else{buffer2[index++]=BSON_DATA_MAX_KEY}const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;return index}function serializeObjectId(buffer2,key,value,index){buffer2[index++]=BSON_DATA_OID;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;if(isUint8Array(value.id)){buffer2.set(value.id.subarray(0,12),index)}else{throw new BSONError("object ["+JSON.stringify(value)+"] is not a valid ObjectId")}return index+12}function serializeBuffer(buffer2,key,value,index){buffer2[index++]=BSON_DATA_BINARY;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const size=value.length;buffer2[index++]=size&255;buffer2[index++]=size>>8&255;buffer2[index++]=size>>16&255;buffer2[index++]=size>>24&255;buffer2[index++]=BSON_BINARY_SUBTYPE_DEFAULT;buffer2.set(value,index);index=index+size;return index}function serializeObject(buffer2,key,value,index,checkKeys,depth,serializeFunctions,ignoreUndefined,path){if(path.has(value)){throw new BSONError("Cannot convert circular structure to BSON")}path.add(value);buffer2[index++]=Array.isArray(value)?BSON_DATA_ARRAY:BSON_DATA_OBJECT;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const endIndex=serializeInto(buffer2,value,checkKeys,index,depth+1,serializeFunctions,ignoreUndefined,path);path.delete(value);return endIndex}function serializeDecimal128(buffer2,key,value,index){buffer2[index++]=BSON_DATA_DECIMAL128;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;buffer2.set(value.bytes.subarray(0,16),index);return index+16}function serializeLong(buffer2,key,value,index){buffer2[index++]=value._bsontype==="Long"?BSON_DATA_LONG:BSON_DATA_TIMESTAMP;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const lowBits=value.getLowBits();const highBits=value.getHighBits();buffer2[index++]=lowBits&255;buffer2[index++]=lowBits>>8&255;buffer2[index++]=lowBits>>16&255;buffer2[index++]=lowBits>>24&255;buffer2[index++]=highBits&255;buffer2[index++]=highBits>>8&255;buffer2[index++]=highBits>>16&255;buffer2[index++]=highBits>>24&255;return index}function serializeInt32(buffer2,key,value,index){value=value.valueOf();buffer2[index++]=BSON_DATA_INT;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;buffer2[index++]=value&255;buffer2[index++]=value>>8&255;buffer2[index++]=value>>16&255;buffer2[index++]=value>>24&255;return index}function serializeDouble(buffer2,key,value,index){buffer2[index++]=BSON_DATA_NUMBER;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;NUMBER_SPACE.setFloat64(0,value.value,true);buffer2.set(EIGHT_BYTE_VIEW_ON_NUMBER,index);index=index+8;return index}function serializeFunction(buffer2,key,value,index){buffer2[index++]=BSON_DATA_CODE;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const functionString=value.toString();const size=ByteUtils.encodeUTF8Into(buffer2,functionString,index+4)+1;buffer2[index]=size&255;buffer2[index+1]=size>>8&255;buffer2[index+2]=size>>16&255;buffer2[index+3]=size>>24&255;index=index+4+size-1;buffer2[index++]=0;return index}function serializeCode(buffer2,key,value,index,checkKeys=false,depth=0,serializeFunctions=false,ignoreUndefined=true,path){if(value.scope&&typeof value.scope==="object"){buffer2[index++]=BSON_DATA_CODE_W_SCOPE;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;let startIndex=index;const functionString=value.code;index=index+4;const codeSize=ByteUtils.encodeUTF8Into(buffer2,functionString,index+4)+1;buffer2[index]=codeSize&255;buffer2[index+1]=codeSize>>8&255;buffer2[index+2]=codeSize>>16&255;buffer2[index+3]=codeSize>>24&255;buffer2[index+4+codeSize-1]=0;index=index+codeSize+4;const endIndex=serializeInto(buffer2,value.scope,checkKeys,index,depth+1,serializeFunctions,ignoreUndefined,path);index=endIndex-1;const totalSize=endIndex-startIndex;buffer2[startIndex++]=totalSize&255;buffer2[startIndex++]=totalSize>>8&255;buffer2[startIndex++]=totalSize>>16&255;buffer2[startIndex++]=totalSize>>24&255;buffer2[index++]=0}else{buffer2[index++]=BSON_DATA_CODE;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const functionString=value.code.toString();const size=ByteUtils.encodeUTF8Into(buffer2,functionString,index+4)+1;buffer2[index]=size&255;buffer2[index+1]=size>>8&255;buffer2[index+2]=size>>16&255;buffer2[index+3]=size>>24&255;index=index+4+size-1;buffer2[index++]=0}return index}function serializeBinary(buffer2,key,value,index){buffer2[index++]=BSON_DATA_BINARY;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const data=value.buffer;let size=value.position;if(value.sub_type===Binary.SUBTYPE_BYTE_ARRAY)size=size+4;buffer2[index++]=size&255;buffer2[index++]=size>>8&255;buffer2[index++]=size>>16&255;buffer2[index++]=size>>24&255;buffer2[index++]=value.sub_type;if(value.sub_type===Binary.SUBTYPE_BYTE_ARRAY){size=size-4;buffer2[index++]=size&255;buffer2[index++]=size>>8&255;buffer2[index++]=size>>16&255;buffer2[index++]=size>>24&255}buffer2.set(data,index);index=index+value.position;return index}function serializeSymbol(buffer2,key,value,index){buffer2[index++]=BSON_DATA_SYMBOL;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const size=ByteUtils.encodeUTF8Into(buffer2,value.value,index+4)+1;buffer2[index]=size&255;buffer2[index+1]=size>>8&255;buffer2[index+2]=size>>16&255;buffer2[index+3]=size>>24&255;index=index+4+size-1;buffer2[index++]=0;return index}function serializeDBRef(buffer2,key,value,index,depth,serializeFunctions,path){buffer2[index++]=BSON_DATA_OBJECT;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;let startIndex=index;let output={$ref:value.collection||value.namespace,$id:value.oid};if(value.db!=null){output.$db=value.db}output=Object.assign(output,value.fields);const endIndex=serializeInto(buffer2,output,false,index,depth+1,serializeFunctions,true,path);const size=endIndex-startIndex;buffer2[startIndex++]=size&255;buffer2[startIndex++]=size>>8&255;buffer2[startIndex++]=size>>16&255;buffer2[startIndex++]=size>>24&255;return endIndex}function serializeInto(buffer2,object,checkKeys,startingIndex,depth,serializeFunctions,ignoreUndefined,path){if(path==null){if(object==null){buffer2[0]=5;buffer2[1]=0;buffer2[2]=0;buffer2[3]=0;buffer2[4]=0;return 5}if(Array.isArray(object)){throw new BSONError("serialize does not support an array as the root input")}if(typeof object!=="object"){throw new BSONError("serialize does not support non-object as the root input")}else if("_bsontype"in object&&typeof object._bsontype==="string"){throw new BSONError(`BSON types cannot be serialized as a document`)}else if(isDate(object)||isRegExp(object)||isUint8Array(object)||isAnyArrayBuffer(object)){throw new BSONError(`date, regexp, typedarray, and arraybuffer cannot be BSON documents`)}path=new Set}path.add(object);let index=startingIndex+4;if(Array.isArray(object)){for(let i=0;i>8&255;buffer2[startingIndex++]=size>>16&255;buffer2[startingIndex++]=size>>24&255;return index}function isBSONType(value){return value!=null&&typeof value==="object"&&"_bsontype"in value&&typeof value._bsontype==="string"}var keysToCodecs={$oid:ObjectId2,$binary:Binary,$uuid:Binary,$symbol:BSONSymbol,$numberInt:Int32,$numberDecimal:Decimal128,$numberDouble:Double,$numberLong:Long,$minKey:MinKey,$maxKey:MaxKey,$regex:BSONRegExp,$regularExpression:BSONRegExp,$timestamp:Timestamp};function deserializeValue(value,options={}){if(typeof value==="number"){const in32BitRange=value<=BSON_INT32_MAX&&value>=BSON_INT32_MIN;const in64BitRange=value<=BSON_INT64_MAX&&value>=BSON_INT64_MIN;if(options.relaxed||options.legacy){return value}if(Number.isInteger(value)&&!Object.is(value,-0)){if(in32BitRange){return new Int32(value)}if(in64BitRange){if(options.useBigInt64){return BigInt(value)}return Long.fromNumber(value)}}return new Double(value)}if(value==null||typeof value!=="object")return value;if(value.$undefined)return null;const keys=Object.keys(value).filter(k=>k.startsWith("$")&&value[k]!=null);for(let i=0;ik.startsWith("$"));let valid=true;dollarKeys.forEach(k=>{if(["$ref","$id","$db"].indexOf(k)===-1)valid=false});if(valid)return DBRef.fromExtendedJSON(v2)}return value}function serializeArray(array,options){return array.map((v2,index)=>{options.seenObjects.push({propertyName:`index ${index}`,obj:null});try{return serializeValue(v2,options)}finally{options.seenObjects.pop()}})}function getISOString(date){const isoStr=date.toISOString();return date.getUTCMilliseconds()!==0?isoStr:isoStr.slice(0,-5)+"Z"}function serializeValue(value,options){if(value instanceof Map||isMap(value)){const obj=Object.create(null);for(const[k,v2]of value){if(typeof k!=="string"){throw new BSONError("Can only serialize maps with string keys")}obj[k]=v2}return serializeValue(obj,options)}if((typeof value==="object"||typeof value==="function")&&value!==null){const index=options.seenObjects.findIndex(entry=>entry.obj===value);if(index!==-1){const props=options.seenObjects.map(entry=>entry.propertyName);const leadingPart=props.slice(0,index).map(prop=>`${prop} -> `).join("");const alreadySeen=props[index];const circularPart=" -> "+props.slice(index+1,props.length-1).map(prop=>`${prop} -> `).join("");const current=props[props.length-1];const leadingSpace=" ".repeat(leadingPart.length+alreadySeen.length/2);const dashes="-".repeat(circularPart.length+(alreadySeen.length+current.length)/2-1);throw new BSONError(`Converting circular structure to EJSON: - ${leadingPart}${alreadySeen}${circularPart}${current} - ${leadingSpace}\\${dashes}/`)}options.seenObjects[options.seenObjects.length-1].obj=value}if(Array.isArray(value))return serializeArray(value,options);if(value===void 0)return null;if(value instanceof Date||isDate(value)){const dateNum=value.getTime(),inRange=dateNum>-1&&dateNum<2534023188e5;if(options.legacy){return options.relaxed&&inRange?{$date:value.getTime()}:{$date:getISOString(value)}}return options.relaxed&&inRange?{$date:getISOString(value)}:{$date:{$numberLong:value.getTime().toString()}}}if(typeof value==="number"&&(!options.relaxed||!isFinite(value))){if(Number.isInteger(value)&&!Object.is(value,-0)){if(value>=BSON_INT32_MIN&&value<=BSON_INT32_MAX){return{$numberInt:value.toString()}}if(value>=BSON_INT64_MIN&&value<=BSON_INT64_MAX){return{$numberLong:value.toString()}}}return{$numberDouble:Object.is(value,-0)?"-0.0":value.toString()}}if(typeof value==="bigint"){if(!options.relaxed){return{$numberLong:BigInt.asIntN(64,value).toString()}}return Number(BigInt.asIntN(64,value))}if(value instanceof RegExp||isRegExp(value)){let flags=value.flags;if(flags===void 0){const match=value.toString().match(/[gimuy]*$/);if(match){flags=match[0]}}const rx=new BSONRegExp(value.source,flags);return rx.toExtendedJSON(options)}if(value!=null&&typeof value==="object")return serializeDocument(value,options);return value}var BSON_TYPE_MAPPINGS={Binary:o=>new Binary(o.value(),o.sub_type),Code:o=>new Code(o.code,o.scope),DBRef:o=>new DBRef(o.collection||o.namespace,o.oid,o.db,o.fields),Decimal128:o=>new Decimal128(o.bytes),Double:o=>new Double(o.value),Int32:o=>new Int32(o.value),Long:o=>Long.fromBits(o.low!=null?o.low:o.low_,o.low!=null?o.high:o.high_,o.low!=null?o.unsigned:o.unsigned_),MaxKey:()=>new MaxKey,MinKey:()=>new MinKey,ObjectId:o=>new ObjectId2(o),BSONRegExp:o=>new BSONRegExp(o.pattern,o.options),BSONSymbol:o=>new BSONSymbol(o.value),Timestamp:o=>Timestamp.fromBits(o.low,o.high)};function serializeDocument(doc,options){if(doc==null||typeof doc!=="object")throw new BSONError("not an object instance");const bsontype=doc._bsontype;if(typeof bsontype==="undefined"){const _doc={};for(const name of Object.keys(doc)){options.seenObjects.push({propertyName:name,obj:null});try{const value=serializeValue(doc[name],options);if(name==="__proto__"){Object.defineProperty(_doc,name,{value,writable:true,enumerable:true,configurable:true})}else{_doc[name]=value}}finally{options.seenObjects.pop()}}return _doc}else if(doc!=null&&typeof doc==="object"&&typeof doc._bsontype==="string"&&doc[Symbol.for("@@mdb.bson.version")]!==BSON_MAJOR_VERSION){throw new BSONVersionError}else if(isBSONType(doc)){let outDoc=doc;if(typeof outDoc.toExtendedJSON!=="function"){const mapper=BSON_TYPE_MAPPINGS[doc._bsontype];if(!mapper){throw new BSONError("Unrecognized or invalid _bsontype: "+doc._bsontype)}outDoc=mapper(outDoc)}if(bsontype==="Code"&&outDoc.scope){outDoc=new Code(outDoc.code,serializeValue(outDoc.scope,options))}else if(bsontype==="DBRef"&&outDoc.oid){outDoc=new DBRef(serializeValue(outDoc.collection,options),serializeValue(outDoc.oid,options),serializeValue(outDoc.db,options),serializeValue(outDoc.fields,options))}return outDoc.toExtendedJSON(options)}else{throw new BSONError("_bsontype must be a string, but was: "+typeof bsontype)}}function parse(text,options){const ejsonOptions={useBigInt64:options?.useBigInt64??false,relaxed:options?.relaxed??true,legacy:options?.legacy??false};return JSON.parse(text,(key,value)=>{if(key.indexOf("\0")!==-1){throw new BSONError(`BSON Document field names cannot contain null bytes, found: ${JSON.stringify(key)}`)}return deserializeValue(value,ejsonOptions)})}function stringify(value,replacer,space,options){if(space!=null&&typeof space==="object"){options=space;space=0}if(replacer!=null&&typeof replacer==="object"&&!Array.isArray(replacer)){options=replacer;replacer=void 0;space=0}const serializeOptions=Object.assign({relaxed:true,legacy:false},options,{seenObjects:[{propertyName:"(root)",obj:null}]});const doc=serializeValue(value,serializeOptions);return JSON.stringify(doc,replacer,space)}function EJSONserialize(value,options){options=options||{};return JSON.parse(stringify(value,options))}function EJSONdeserialize(ejson,options){options=options||{};return parse(JSON.stringify(ejson),options)}var EJSON=Object.create(null);EJSON.parse=parse;EJSON.stringify=stringify;EJSON.serialize=EJSONserialize;EJSON.deserialize=EJSONdeserialize;Object.freeze(EJSON);var MAXSIZE=1024*1024*17;var buffer=ByteUtils.allocate(MAXSIZE);function setInternalBufferSize(size){if(buffer.lengthAuthorizationStruct,ChatroomStruct:()=>ChatroomStruct,CoherenceMap:()=>CoherenceMap,CoherenceStruct:()=>CoherenceStruct,CommentStruct:()=>CommentStruct,Data:()=>Data,DataStruct:()=>DataStruct,DateStruct:()=>DateStruct,ECGStruct:()=>ECGStruct,EDAStruct:()=>EDAStruct,EEGCoordinates:()=>EEGCoordinates,EEGStruct:()=>EEGStruct,EMGStruct:()=>EMGStruct,EventStruct:()=>EventStruct,EyeTrackerStruct:()=>EyeTrackerStruct,FNIRSStruct:()=>FNIRSStruct,FrequencyBandsStruct:()=>FrequencyBandsStruct,GroupStruct:()=>GroupStruct,HRVStruct:()=>HRVStruct,IMUStruct:()=>IMUStruct,NotificationStruct:()=>NotificationStruct,PPGStruct:()=>PPGStruct,ProfileStruct:()=>ProfileStruct,ScheduleStruct:()=>ScheduleStruct,Struct:()=>Struct,eegCoordinates:()=>eegCoordinates,setCoordinate:()=>setCoordinate,structRegistry:()=>structRegistry});function Struct(structType="struct",assignProps={},parentUser={_id:""},parentStruct={structType:"struct",_id:""}){function randomId3(tag=""){return`${tag+Math.floor(Math.random()+Math.random()*Math.random()*1e16)}`}let struct={_id:randomId3(structType+"defaultId"),structType,ownerId:parentUser?._id,timestamp:Date.now(),parent:{structType:parentStruct?.structType,_id:parentStruct?._id}};if(!struct.ownerId)delete struct.ownerId;if(!struct?.parent?._id)delete struct.parent;if(Object.keys(assignProps).length>0)Object.assign(struct,assignProps);return struct}var eegCoordinates={FP1:[-21.2,66.9,12.1],FPZ:[1.4,65.1,11.3],FP2:[24.3,66.3,12.5],AF7:[-41.7,52.8,11.3],AF3:[-32.7,48.4,32.8],AFZ:[1.8,54.8,37.9],AF4:[35.1,50.1,31.1],AF8:[43.9,52.7,9.3],F5:[-51.4,26.7,24.7],F3:[-39.7,25.3,44.7],F1:[-22.1,26.8,54.9],FZ:[0,26.8,60.6],F2:[23.6,28.2,55.6],F4:[41.9,27.5,43.9],F6:[52.9,28.7,25.2],F7:[-52.1,28.6,3.8],F8:[53.2,28.4,3.1],FC5:[-59.1,3,26.1],FC3:[-45.5,2.4,51.3],FC1:[-24.7,.3,66.4],FCZ:[1,1,72.8],FC2:[26.1,3.2,66],FC4:[47.5,4.6,49.7],FC6:[60.5,4.9,25.5],FT9:[-53.8,-2.1,-29.1],FT7:[-59.2,3.4,-2.1],FT8:[60.2,4.7,-2.8],FT10:[55,-3.6,-31],T7:[-65.8,-17.8,-2.9],T5:[-61.5,-65.3,1.1],T3:[-70.2,-21.3,-10.7],T4:[71.9,-25.2,-8.2],T6:[59.3,-67.6,3.8],T8:[67.4,-18.5,-3.4],C5:[-63.6,-18.9,25.8],C3:[-49.1,-20.7,53.2],C1:[-25.1,-22.5,70.1],CZ:[.8,-21.9,77.4],C2:[26.7,-20.9,69.5],C4:[50.3,-18.8,53],C6:[65.2,-18,26.4],CP5:[-61.8,-46.2,22.5],CP3:[-46.9,-47.7,49.7],CP1:[-24,-49.1,66.1],CPZ:[.7,-47.9,72.6],CP2:[25.8,-47.1,66],CP4:[49.5,-45.5,50.7],CP6:[62.9,-44.6,24.4],TP9:[-73.6,-46.7,-4],TP7:[-63.6,-44.7,-4],TP8:[64.6,-45.4,-3.7],TP10:[74.6,-47.4,-3.7],P9:[-50.8,-51.3,-37.7],P7:[-55.9,-64.8,0],P5:[-52.7,-67.1,19.9],P3:[-41.4,-67.8,42.4],P1:[-21.6,-71.3,52.6],PZ:[.7,-69.3,56.9],P2:[24.4,-69.9,53.5],P4:[44.2,-65.8,42.7],P6:[54.4,-65.3,20.2],P8:[56.4,-64.4,.1],P10:[51,-53.9,-36.5],PO7:[-44,-81.7,1.6],PO3:[-33.3,-84.3,26.5],POZ:[0,-87.9,33.5],PO4:[35.2,-82.6,26.1],PO8:[43.3,-82,.7],O1:[-25.8,-93.3,7.7],OZ:[.3,-97.1,8.7],O2:[25,-95.2,6.2]};function setCoordinate(channelDict,assignTo={}){if(!eegCoordinates[channelDict.tag]&&channelDict.position){eegCoordinates[channelDict.tag]=[channelDict.position.x,channelDict.position.y,channelDict.position.z]}if(eegCoordinates[channelDict.tag]){let props={channel:"",position:{x:eegCoordinates[channelDict.tag][0],y:eegCoordinates[channelDict.tag][1],z:eegCoordinates[channelDict.tag][2]}};return Object.assign(assignTo,props)}else return Object.assign(assignTo,channelDict)}function EEGCoordinates(channelDicts=[],genCoherenceMap=true){let structs=[];for(let channelDict of channelDicts){let struct=EEGStruct(channelDict);structs.push(struct)}if(genCoherenceMap){structs.push(...CoherenceMap({channelDicts}))}return structs}function FrequencyBandsStruct(additionalBands=[],assignTo={}){let bands={scp:[],delta:[],theta:[],alpha1:[],alpha2:[],beta:[],lowgamma:[],highgamma:[]};additionalBands.forEach(band=>bands[band]=[]);return Object.assign(assignTo,bands)}function EEGStruct(tag="",assignProps={},parentUser={_id:""},parentStruct={structType:"struct",_id:""}){let bands=FrequencyBandsStruct();let props={tag,position:{x:0,y:0,z:0},count:0,times:[],raw:[],filtered:[],fftCount:0,fftTimes:[],ffts:[],slices:JSON.parse(JSON.stringify(bands)),means:JSON.parse(JSON.stringify(bands)),startTime:Date.now()};let struct=Struct("eeg",props,parentUser,parentStruct);if(tag)setCoordinate(props,struct);return Object.assign(struct,assignProps)}function CoherenceStruct(coords={0:EEGStruct("FP1"),1:EEGStruct("FP2")},assignProps={},parentUser={_id:""},parentStruct={structType:"struct",_id:""}){let bands=FrequencyBandsStruct();let props={tag:coords[0]?.tag+"::"+coords[1]?.tag,x0:coords[0]?.position?.x,y0:coords[0]?.position?.y,z0:coords[0]?.position?.z,x1:coords[1]?.position?.x,y1:coords[1]?.position?.y,z1:coords[1]?.position?.z,fftCount:0,fftTimes:[],ffts:[],slices:JSON.parse(JSON.stringify(bands)),means:JSON.parse(JSON.stringify(bands)),startTime:Date.now()};let struct=Struct("coherence",props,parentUser,parentStruct);return Object.assign(struct,assignProps)}function CoherenceMap(opts={channelDicts:[{ch:0,tag:"FP1",analyze:false},{ch:1,tag:"FP2",analyze:false}],taggedOnly:true},_={},parentUser={_id:""},parentStruct={structType:"struct",_id:""}){var cmap=[];var l=1,k=0;for(var i=0;i{if(!this.data.events[dataObj.timestamp])this.data.events[dataObj.timestamp]=[dataObj];else this.data.events[dataObj.timestamp].push(dataObj);if(dataObj.event==="sleep"){if(!this.data.sleep[dataObj.timestamp])this.data.sleep[dataObj.timestamp]=[dataObj];else this.data.sleep[dataObj.timestamp].push(dataObj)}return dataObj});this.setSort(["notes","note","link"],dataObj=>{if(!this.data.notes[dataObj.timestamp])this.data.notes[dataObj.timestamp]=[dataObj];else this.data.notes[dataObj.timestamp].push(dataObj);if(!this.data.byTime[dataObj.timestamp])this.data.byTime[dataObj.timestamp]=[dataObj];else this.data.byTime[dataObj.timestamp].push(dataObj);return dataObj});this.id=this.randomId("dataTablet")}randomId(tag=""){return`${tag+Math.floor(Math.random()+Math.random()*Math.random()*1e16)}`}setLocalData(structs){let setInCollection=s=>{let type=s.structType;let collection=this.collections.get(type);if(!collection){collection=new Map;this.collections.set(type,collection)}collection.set(s._id,s);this.onCollectionSet(type,collection)};if(Array.isArray(structs)){structs.forEach(s=>{setInCollection(s)})}else setInCollection(structs)}getLocalData(collection,query){let ownerId="";let key="";let value="";if(typeof query==="object"){ownerId=query.ownerId;const keys=Object.keys(query).filter(k=>k!="ownerId");key=keys[0];value=query[key]}else value=query;if(!collection&&!ownerId&&!key&&!value)return[];let result=[];if(!collection&&(ownerId||key)){this.collections.forEach(c=>{if((key==="_id"||key==="id")&&value){let found=c.get(value);if(found)result.push(found)}else{c.forEach(struct=>{if(key&&value){if(struct[key]===value&&struct.ownerId===ownerId){result.push(struct)}}else if(struct.ownerId===ownerId){result.push(struct)}})}});return result}else{let c=this.collections.get(collection);if(!c)return result;if(!key&&!ownerId){c.forEach(struct=>{result.push(struct)});return result}if((key==="_id"||key==="id")&&value)return c.get(value);else{c.forEach((struct,_)=>{if(key&&value&&!ownerId){if(struct[key]===value)result.push(struct)}else if(ownerId&&!key){if(struct.ownerId===ownerId)result.push(struct)}else if(ownerId&&key&&value){if(struct.ownerId===ownerId&&struct[key]){if(struct[key]===value)result.push(struct)}}})}}return result}onCollectionSet=(type,collection)=>{};runSort(key,dataObj={},newdata=[],tablet=this){let result;let sort=this.getSort(key);if(sort)result=sort(dataObj,newdata,tablet);else return false;return result}setSort(key,response=(data,newdata=[],tablet=this)=>{}){if(Array.isArray(key))key.forEach(k=>{this.dataSorts.set(k,response)});else this.dataSorts.set(key,response)}getSort(key){return this.dataSorts.get(key)}checkWatches(sorted={}){for(const prop in this.watches){let triggered=this.watches[prop].ondata(sorted,this.watches[prop].accum,this.watches[prop].ownerId);if(triggered){this.watches[prop].ontrigger(this.watches[prop].accum);this.watches[prop].triggered=false}}}setWatch(name,ownerId,ondata=(sorted,accum,ownerId2)=>{if(sorted.ownerId===ownerId2)accum.data[sorted._id]=sorted;if(Object.keys(accum.data).length>10){return true}else return false},ontrigger=accum=>{console.log(accum);let alert=Struct("alert",{alert:true,data:accum},{_id:accum[Object.keys(accum)[0]].ownerId});accum={}}){this.watches[name]={accum:{},ownerId,ondata,ontrigger}}getWatch(name){return this.watches[name]}async sortStructsIntoTable(datastructs=[]){let ascending=function(a,b){if(a.timestamp&&b.timestamp)return a.timestamp-b.timestamp};datastructs.sort(ascending);let newdata=[];for(let i=0;i{if(typeof dat==="object"&&!Array.isArray(dat)){let typ=dat.dataType;dat.ownerId=struct.ownerId;if(!dat.timestamp)dat.timestamp=timestamp;if(typ){let sorted=this.runSort(typ,dat,newdata,this);if(!sorted){if(!this.data[typ])this.data[typ]={};dat.timestamp=timestamp;if(!this.data[typ][timestamp])this.data[typ][timestamp]=[dat];else this.data[typ][timestamp].push(dat);if(!this.data.byTime[timestamp])this.data.byTime[timestamp]=[dat];else this.data.byTime[timestamp].push(dat);this.checkWatches(dat);this.onUpdate(timestamp,dat);newdata.push(dat)}else{if(sorted.constructor?.name!=="Promise"){this.checkWatches(sorted);this.onUpdate(timestamp,sorted);newdata.push(sorted)}}}}})}else{let sorted=this.runSort(struct.structType,struct,newdata,this);if(!sorted){let typ=struct.structType;if(!this.data[typ])this.data[typ]={};if(!this.data[typ][timestamp])this.data[typ][timestamp]=[struct];else this.data[typ][timestamp].push(struct);this.checkWatches(struct);this.onUpdate(timestamp,struct);newdata.push(struct)}else{this.checkWatches(sorted);this.onUpdate(timestamp,sorted);newdata.push(sorted)}}}for(const prop in this.data){this.data[prop]=this.sortObjectByPropName(this.data[prop])}this.onSorted(newdata)}onUpdate(_,__,___=this.data){}onSorted(_=[]){}getDataByTimestamp(timestamp,ownerId){let result=this.data.byTime[timestamp];if(ownerId&&result)result=result.filter(o=>{if(!ownerId)return true;else if(ownerId===o.ownerId)return true;else return false});return result}getDataByTimeRange(begin,end,type,ownerId){let result={};if(type){for(const key in this.data[type]){let t=parseInt(key);if(t>begin&&tbegin&&t{if(o.ownerId!==ownerId){popidx.push(i)}});popidx.reverse().forEach(idx=>{result[key].splice(idx,1)});if(result[key].length===0)delete result[key]}}return result}getDataByType(type,timestamp,ownerId){if(!this.data[type])return void 0;let result={...this.data[type]};if(timestamp)result=[...result[timestamp]];if(ownerId&&result){for(const key in result){let popidx=[];result[key]=[...result[key]];result[key].forEach((o,i)=>{if(o.ownerId!==ownerId){popidx.push(i)}});popidx.reverse().forEach(idx=>{result[key].splice(idx,1)});if(result[key].length===0)delete result[key]}}if(type==="sleep"){result=this.filterSleepResults(result)}return result}filterSleepResults(unfiltered={}){let events=[];for(const key in unfiltered){unfiltered[key]=[...unfiltered[key]];events.push(...unfiltered[key].filter(o=>{if(o.structType==="event")return true;else return false}))}events.forEach(ev2=>{let foundidx;for(const key in unfiltered){unfiltered[key].forEach((o,i)=>{if(o.structType==="fitbitsleep"&&ev2.startTime&&ev2.endTime){if(Math.abs(o.startTime-ev2.startTime)<1e3*12*3600&&Math.abs(o.endTime-ev2.endTime)<1e3*12*3600&&ev2.endTime-ev2.startTime>1e3*2*3600){foundidx=i;return true}else return false}else return false});if(foundidx)unfiltered[key].splice(foundidx,1)}});let result=unfiltered;return result}sortObjectByPropName(object){const ordered=Object.keys(object).sort().reduce((obj,key)=>{obj[key]=object[key];return obj},{});return ordered}checkRollover(collection,limit=this.rolloverLimit){if(!collection)return false;let c=this.collections.get(collection);if(!c)return false;c.forEach(struct=>{for(const prop in struct){if(Array.isArray(struct[prop])){if(struct[prop].length>limit){struct[prop].slice(struct[prop].length-limit);if(prop==="ffts"){struct.fftCount=struct[prop].length}else if(prop==="times"){struct.count=struct[prop].length}}}else if(typeof struct[prop]==="object"){this.checkRollover(struct[prop])}}});return true}};var defaultSpecifiers=["now","minute","5 minutes","30 minutes","hour","6 hours","12 hours","day","3 days","week","2 weeks","month","6 months","year","5 years","decade"];function genTimeSpecifiers(specifiers=defaultSpecifiers){let result=["now"];specifiers.forEach(s=>{if(s!=="now")result.push(`last ${s}`);else result.push(s)});return result}function genTimestampFromString(specifier){const now=new Date;if(specifier==="now"){}else if(specifier==="last minute"){now.setMinutes(now.getMinutes()-1)}else if(specifier==="last hour"){now.setHours(now.getHours()-1)}else if(specifier==="last day"){now.setDate(now.getDate()-1)}else if(specifier==="last week"){now.setDate(now.getDate()-7)}else if(specifier==="last month"){now.setMonth(now.getMonth()-1)}else if(specifier==="last year"){now.setFullYear(now.getFullYear()-1)}else if(specifier==="last decade"){now.setFullYear(now.getFullYear()-1*10)}else if(specifier==="last century"){now.setFullYear(now.getFullYear()-1*100)}else if(specifier==="last millennium"){now.setFullYear(now.getFullYear()-1*1e3)}else if(specifier==="last microsecond"){now.setMilliseconds(now.getMilliseconds()-1)}else if(specifier==="last nanosecond"){now.setMilliseconds(now.getMilliseconds()-1*.001)}else if(specifier.startsWith("last")){const[,count,unit]=specifier.match(/last (\d+) (\w+)/)||[];if(count&&unit){const num=parseInt(count,10);if(unit.includes("minute")){now.setMinutes(now.getMinutes()-num)}else if(unit.includes("hour")){now.setHours(now.getHours()-num)}else if(unit.includes("day")){now.setDate(now.getDate()-num)}else if(unit.includes("week")){now.setDate(now.getDate()-num*7)}else if(unit.includes("month")){now.setMonth(now.getMonth()-num)}else if(unit.includes("year")){now.setFullYear(now.getFullYear()-num)}else if(unit.includes("decade")){now.setFullYear(now.getFullYear()-num*10)}else if(unit.includes("century")){now.setFullYear(now.getFullYear()-num*100)}else if(unit.includes("millennium")){now.setFullYear(now.getFullYear()-num*1e3)}else if(unit.includes("microsecond")){now.setMilliseconds(now.getMilliseconds()-num)}else if(unit.includes("nanosecond")){now.setMilliseconds(now.getMilliseconds()-num*.001)}}}return now.getTime()}var EventHandler=class{data={};triggers={};ctr=0;constructor(data){if(typeof data==="object")this.data=data}setState=updateObj=>{Object.assign(this.data,updateObj);let props=Object.getOwnPropertyNames(updateObj);for(const prop of props){this.triggerEvent(prop,this.data[prop])}if(this.triggers[statesubKey]){let run=fn=>{fn(updateObj)};const l=this.triggers[statesubKey].length;for(let i=l-1;i>=0;i--){run(this.triggers[statesubKey][i].onchange)}}return this.data};setValue=(key,value)=>{this.data[key]=value;this.triggerEvent(key,value)};triggerEvent=(key,value)=>{if(this.triggers[key]){let fn=obj=>{obj.onchange(value)};const l=this.triggers[key].length;for(let i=l-1;i>=0;i--){fn(this.triggers[key][i])}}};subscribeState=onchange=>{return this.subscribeEvent(statesubKey,onchange)};unsubscribeState=sub=>{return this.unsubscribeEvent(statesubKey,sub)};subscribeEvent=(key,onchange,refObject,refKey)=>{if(key){if(refObject&&refKey&&!this.triggers[key]){Object.defineProperty(this.data,key,{get:()=>{return refObject[refKey]},set:value=>{refObject[refKey]=value},enumerable:true,configurable:true})}if(!this.triggers[key]){this.triggers[key]=[]}let l=this.ctr;this.ctr++;this.triggers[key].push({sub:l,onchange});return l}else return void 0};unsubscribeEvent=(key,sub)=>{let triggers=this.triggers[key];if(triggers){if(sub===void 0){delete this.triggers[key];delete this.data[key]}else{let idx=void 0;let obj=triggers.find((o,i)=>{if(o.sub===sub){idx=i;return true}});if(obj)triggers.splice(idx,1);if(Object.keys(triggers).length===0){delete this.triggers[key];delete this.data[key]}if(this.onRemoved)this.onRemoved(obj);return true}}};subscribeEventOnce=(key,onchange)=>{let sub;let changed=value=>{onchange(value);this.unsubscribeEvent(key,sub)};sub=this.subscribeEvent(key,changed);return sub};getEvent=(key,sub)=>{if(typeof sub!=="number")return this.triggers[key];for(const s in this.triggers[key]){if(this.triggers[key][s].sub===sub)return this.triggers[key][s]}};getSnapshot=()=>{const snapshot={};for(const key in this.data){snapshot[key]=this.data[key]}};onRemoved};var statesubKey="*s";var state=new EventHandler;var Callable=class extends Function{__bound;__call;constructor(){super("return this.__bound.__call.apply(this.__bound, arguments)");this.__bound=this.bind(this);return this.__bound}};var GraphNode=class _GraphNode{__node={tag:`node${Math.floor(Math.random()*1e15)}`,unique:`${Math.floor(Math.random()*1e15)}`,state};__children;__parent;__operator;__listeners;__props;__args;constructor(properties,parent,graph){this.__setProperties(properties,parent,graph);if(typeof properties==="function"||properties?.__callable){const callableInstance=new Callable;callableInstance.__call=(...args)=>this.__operator(...args);const proxy=new Proxy(callableInstance,{get:(target,prop,receiver)=>{if(Reflect.has(this,prop)){return Reflect.get(this,prop,receiver)}return Reflect.get(target,prop,receiver)},set:(target,prop,value,receiver)=>{if(Reflect.has(this,prop)){return Reflect.set(this,prop,value,receiver)}return Reflect.set(target,prop,value,receiver)}});Object.setPrototypeOf(proxy,this);return proxy}}get __graph(){return this.__node?.graph}set __graph(graph){this.__node.graph=graph}__setProperties=(properties,parent,graph)=>{let enforceProperties=()=>{let orig=properties;if(typeof properties==="function"){if(isNativeClass(properties)){properties=new properties}else properties={__operator:properties,__node:{forward:true,tag:properties.name}}}else if(typeof properties==="string"){if(graph?.get(properties)){properties=graph.get(properties)}}if(!("__node"in properties))properties.__node={};if(!properties.__node.initial)properties.__node.initial=orig};enforceProperties();if(typeof properties==="object"){let assignState=()=>{if(properties.__node?.state)this.__node.state=properties.__node.state;else if(graph){properties.__node.state=graph.__node.state}};let setProps=()=>{if(properties.__props){if(typeof properties.__props==="function")properties.__props=new properties.__props;if(typeof properties.__props==="object"){this.__proxyObject(properties.__props)}}};let setTag=()=>{if(!properties.__node.tag){if(properties.__operator?.name)properties.__node.tag=properties.__operator.name;else properties.__node.tag=`node${Math.floor(Math.random()*1e15)}`}};let setNode=()=>{if(typeof properties.__node==="string"){if(graph?.get(properties.__node.tag)){properties=graph.get(properties.__node.tag)}else properties.__node={}}else if(!properties.__node)properties.__node={};if(graph){properties.__node.graph=graph}if(properties instanceof Graph)properties.__node.source=properties};let setParent=()=>{if(!properties.__parent&&parent)properties.__parent=parent;if(parent?.__node&&!(parent instanceof Graph||properties instanceof Graph))properties.__node.tag=parent.__node.tag+"."+properties.__node.tag;if(parent instanceof Graph&&properties instanceof Graph){if(properties.__node.loaders)Object.assign(parent.__node.loaders?parent.__node.loaders:{},properties.__node.loaders);if(parent.__node.mapGraphs){properties.__node.nodes.forEach(n=>{parent.set(properties.__node.tag+"."+n.__node.tag,n)});let ondelete=()=>{properties.__node.nodes.forEach(n=>{parent.__node.nodes.delete(properties.__node.tag+"."+n.__node.tag)})};this.__addOndisconnected(ondelete)}}};let setOp=()=>{if(typeof properties.default==="function"&&!properties.__operator){properties.__operator=properties.default}if(properties.__operator){if(typeof properties.__operator==="string"){if(graph){let n=graph.get(properties.__operator);if(n)properties.__operator=n.__operator;if(!properties.__node.tag&&properties.__operator.name)properties.__node.tag=properties.__operator.name}}if(typeof properties.__operator==="function")properties.__operator=this.__setOperator(properties.__operator);if(properties.default)properties.default=properties.__operator}};let assignProps=()=>{properties.__node=Object.assign(this.__node,properties.__node);let keys=Object.getOwnPropertyNames(properties).filter(v2=>{if(!objProps[v2])return true});for(const key of keys){if(key in properties&&key!=="name")this[key]=properties[key]}};let bindCallbacks=()=>{if(this.__onconnected){if(typeof this.__onconnected==="function"){this.__onconnected=this.__onconnected.bind(this)}else if(Array.isArray(this.__onconnected)){this.__onconnected=this.__onconnected.map(f=>{return f.bind(this)})}if(typeof this.__ondisconnected==="function"){this.__ondisconnected=this.__ondisconnected.bind(this)}else if(Array.isArray(this.__ondisconnected)){this.__ondisconnected=this.__ondisconnected.map(f=>{return f.bind(this)})}}};assignState();setTag();setProps();setNode();setParent();assignProps();bindCallbacks();setOp()}};__subscribe=(callback,key,subInput,target,tkey,args,callbackStr)=>{const subscribeToFunction=(k,setTarget=(callback2,target2)=>target2?target2:callback2,triggerCallback=callback)=>{let wrappedArgs;if(args){let wrapped=wrapArgs(triggerCallback,args,this.__node.graph);triggerCallback=wrapped.__callback;wrappedArgs=wrapped.__args}let sub=this.__node.state.subscribeEvent(k,triggerCallback,this,key);let trigger=this.__node.state.getEvent(k,sub);if(!this.__listeners)this.__listeners={};this.__listeners[k]=this.__node.state.triggers[k];if(!trigger)return sub;trigger.source=this.__node.tag;if(key)trigger.key=key;trigger.target=setTarget(callback,target);if(tkey)trigger.tkey=tkey;if(subInput)trigger.subInput=subInput;if(args){trigger.arguments=wrappedArgs;trigger.__args=args}if(callbackStr)trigger.__callback=callbackStr;trigger.node=this;trigger.graph=this.__node.graph;return sub};const getCallbackFromGraph=callback2=>{let fn=this.__node.graph.get(callback2);if(!fn&&callback2.includes(".")){target=callback2.substring(0,callback2.lastIndexOf("."));let n=this.__node.graph.get(callback2.substring(0,target));tkey=callback2.lastIndexOf(".")+1;if(n&&typeof n[key]==="function")callback2=(...args2)=>{return n[tkey](...args2)}}else if(fn.__operator){callback2=fn.__operator;tkey="__operator"}return callback2};if(key){if(!this.__node.localState||!this.__node.localState[key]){this.__addLocalState(this,key)}if(typeof callback==="string"){callbackStr=this.__node.tag+"."+callback;tkey=callback;if(target){if(this.__node.graph?.get(target)){let n=this.__node.graph?.get(target);if(typeof n[callback]==="function"){let fn=n[callback];callback=(...inp)=>{fn(...inp)}}else{let k2=callback;let setter=inp=>{n[k2]=inp};callback=setter}}}else if(typeof this[callback]==="function"){let fn=this[callback];callback=(...inp)=>{fn(...inp)}}else if(this.__node.graph?.get(callback))callback=getCallbackFromGraph(callback);if(typeof callback!=="function")return void 0}let sub;let k=subInput?this.__node.unique+"."+key+"input":this.__node.unique+"."+key;if(typeof callback==="function"&&!callback?.__node)sub=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2,callback);else if(callback?.__node)sub=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2.__node.unique,(...inp)=>{if(callback.__operator)callback.__operator(...inp)});return sub}else{if(typeof callback==="string"){callbackStr=callback;if(!target)target=callback;if(this.__node.graph.get(callback))callback=this.__node.graph.get(callback);tkey="__operator";if(typeof callback!=="object")return void 0}let sub;let k=subInput?this.__node.unique+"input":this.__node.unique;if(typeof callback==="function"&&!callback?.__node)sub=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2,callback);else if(callback?.__node){sub=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2.__node.unique,(...inp)=>{if(callback.__operator)callback.__operator(...inp)})}return sub}};__unsubscribe=(sub,key,unsubInput)=>{if(key){return this.__node.state.unsubscribeEvent(unsubInput?this.__node.unique+"."+key+"input":this.__node.unique+"."+key,sub)}else return this.__node.state.unsubscribeEvent(unsubInput?this.__node.unique+"input":this.__node.unique,sub)};__setOperator=fn=>{fn=fn.bind(this);if(this.__args&&this.__node.graph){fn=wrapArgs(fn,this.__args,this.__node.graph).__callback}let inpstr=`${this.__node.unique}input`;this.__operator=(...args)=>{if(this.__node.state.triggers[inpstr])this.__node.state.setValue(inpstr,args);let result=fn(...args);if(this.__node.state.triggers[this.__node.unique]){if(typeof result?.then==="function"){result.then(res=>{if(res!==void 0)this.__node.state.setValue(this.__node.unique,res)}).catch(console.error)}else if(result!==void 0)this.__node.state.setValue(this.__node.unique,result)}return result};if(this.__parent instanceof _GraphNode&&!this.__subscribedToParent){if(this.__parent.__operator){let sub=this.__parent.__subscribe(this);let ondelete=()=>{this.__parent?.__unsubscribe(sub);delete this.__subscribedToParent};this.__addOndisconnected(ondelete);this.__subscribedToParent=true}}return this.__operator};__addLocalState=(props,key)=>{if(!props)return;if(!this.__node.localState){this.__node.localState={}}const localState=this.__node.localState;const initState=(props2,k)=>{let str2=this.__node.unique+"."+k;let inpstr=`${str2}input`;let get,set;let obj,descriptor;if(typeof props2[k]==="function"&&k!=="__operator"){if(this.__props?.[k]){obj=this.__props}else{obj=localState}get=()=>{return obj[k]};set=fn=>{if(!this.__props?.[k])fn=fn.bind(this);obj[k]=(...args)=>{if(this.__node.state.triggers[inpstr])this.__node.state.setValue(inpstr,args);let result=fn(...args);if(this.__node.state.triggers[str2]){if(typeof result?.then==="function"){result.then(res=>{this.__node.state.triggerEvent(str2,res)}).catch(console.error)}else this.__node.state.triggerEvent(str2,result)}return result}};localState[k]=props2[k].bind(this);descriptor={get,set,enumerable:true,configurable:true}}else if(k!=="__graph"){let get2,set2;let obj2;if(this.__props?.[k]){obj2=this.__props}else{obj2=localState}get2=()=>{return obj2[k]};set2=v2=>{obj2[k]=v2;if(this.__node.state.triggers[str2])this.__node.state.triggerEvent(str2,v2)};localState[k]=props2[k];descriptor={get:get2,set:set2,enumerable:true,configurable:true}}Object.defineProperty(props2,k,descriptor);if(typeof this.__node.initial==="object"){let dec=Object.getOwnPropertyDescriptor(this.__node.initial,k);if(dec===void 0||dec?.configurable){Object.defineProperty(this.__node.initial,k,descriptor)}}};if(key)initState(props,key);else{for(let k in props){initState(props,k)}}};__proxyObject=obj=>{const allProps=getAllProperties(obj);for(const k of allProps){const descriptor={get:()=>{return obj[k]},set:value=>{obj[k]=value},enumerable:true,configurable:true};Object.defineProperty(this,k,descriptor);if(typeof this.__node.initial==="object"){let dec=Object.getOwnPropertyDescriptor(this.__node.initial,k);if(dec===void 0||dec?.configurable){Object.defineProperty(this.__node.initial,k,descriptor)}}}};__addOnconnected(callback){callback=callback.bind(this);if(Array.isArray(this.__onconnected)){this.__onconnected.push(callback)}else if(typeof this.__onconnected==="function"){this.__onconnected=[callback,this.__onconnected]}else this.__onconnected=callback}__addOndisconnected(callback){callback=callback.bind(this);if(Array.isArray(this.__ondisconnected)){this.__ondisconnected.push(callback)}else if(typeof this.__ondisconnected==="function"){this.__ondisconnected=[callback,this.__ondisconnected]}else this.__ondisconnected=callback}__callConnected(node=this){if(typeof this.__onconnected==="function"){this.__onconnected(this)}else if(Array.isArray(this.__onconnected)){let fn=o=>{o(this)};this.__onconnected.forEach(fn)}}__callDisconnected(node=this){if(typeof this.__ondisconnected==="function")this.__ondisconnected(this);else if(Array.isArray(this.__ondisconnected)){let fn=o=>{o(this)};this.__ondisconnected.forEach(fn)}}};var Graph=class _Graph{__node={tag:`graph${Math.floor(Math.random()*1e15)}`,unique:`${Math.random()}`,nodes:new Map,state,roots:{}};constructor(options){this.init(options)}init=options=>{if(options){let cpy=Object.assign({},options);delete cpy.roots;recursivelyAssign(this.__node,cpy);if(options.roots)this.load(options.roots)}};load=(roots,overwrite=false)=>{function recursivelyAssignChildren(target,obj,inChildren=true,top=true){if(top){if(!target)target={};for(const key in obj){if(!key.startsWith("__")&&obj[key]&&typeof obj[key]==="object"){target[key]=obj[key];if(obj[key]?.__children){recursivelyAssignChildren({},obj[key].__children,false,false)}}else if(typeof obj[key]==="function")target[key]=obj[key]}recursivelyAssignChildren(target,obj,true,false)}else{if(obj?.__children&&!inChildren){if(obj.__children?.constructor.name==="Object"){if(target.__children?.constructor.name==="Object")target.__children=recursivelyAssignChildren(target.__children,obj.__children,true,false);else target.__children=recursivelyAssignChildren({},obj.__children,true,false)}else{target.__children=obj.__children}}else if(inChildren){for(const key in obj){if(!key.startsWith("__")&&obj[key]&&typeof obj[key]==="object"){target[key]=Object.assign({},obj[key]);if(obj[key]?.__children){target[key].__children=recursivelyAssignChildren({},obj[key].__children,false,false)}}else if(typeof obj[key]==="function")target[key]=obj[key]}}}return target}this.__node.roots=recursivelyAssignChildren(this.__node.roots?this.__node.roots:{},roots);let cpy=Object.assign({},roots);if(cpy.__node)delete cpy.__node;let listeners=this.recursiveSet(cpy,this,void 0,roots,overwrite);if(roots.__node){if(!roots.__node.tag)roots.__node._tag=`roots${Math.floor(Math.random()*1e15)}`;else if(!this.get(roots.__node.tag)){let node=new GraphNode(roots,this,this);this.set(node.__node.tag,node);this.runLoaders(node,this,roots,roots.__node.tag);if(node.__listeners){listeners[node.__node.tag]=node.__listeners}}}else if(roots.__listeners){this.setListeners(roots.__listeners)}this.setListeners(listeners);return cpy};setLoaders=(loaders2,replace)=>{if(replace)this.__node.loaders=loaders2;else Object.assign(this.__node.loaders,loaders2);return this.__node.loaders};runLoaders=(node,parent,properties,key)=>{for(const l in this.__node.loaders){if(typeof this.__node.loaders[l]==="object"){if(this.__node.loaders[l].init)this.__node.loaders[l](node,parent,this,this.__node.roots,properties,key);if(this.__node.loaders[l].connected)node.__addOnconnected(this.__node.loaders[l].connect);if(this.__node.loaders[l].disconnected)node.__addOndisconnected(this.__node.loaders[l].disconnect)}else if(typeof this.__node.loaders[l]==="function")this.__node.loaders[l](node,parent,this,this.__node.roots,properties,key)}};add=(properties,parent,overwrite=true)=>{let listeners={};if(typeof parent==="string")parent=this.get(parent);let instanced;if(typeof properties==="function"){if(isNativeClass(properties)){if(properties.prototype instanceof GraphNode){properties=properties.prototype.constructor(properties,parent,this);instanced=true}else properties=new properties}else properties={__operator:properties,__callable:true}}else if(typeof properties==="string"){properties=this.__node.roots[properties]}if(!properties)return;if(!instanced){let keys=Object.getOwnPropertyNames(properties);let nonArrowFunctions=Object.getOwnPropertyNames(Object.getPrototypeOf(properties));keys.push(...nonArrowFunctions);keys=keys.filter(v2=>!objProps.includes(v2));let cpy={};for(const key of keys){cpy[key]=properties[key]}properties=cpy}if(!properties.__node)properties.__node={};properties.__node.initial=properties;if(typeof properties==="object"&&this.get(properties.__node.tag)){if(overwrite)this.remove(properties.__node.tag,true);else return}else if(properties.__node.tag&&this.get(properties.__node.tag))return this.get(properties.__node.tag);let node;let root=recursivelyAssign({},properties,2);if(instanced)node=properties;else node=new GraphNode(properties,parent,this);this.set(node.__node.tag,node);this.runLoaders(node,parent,properties,node.__node.tag);this.__node.roots[node.__node.tag]=root;if(node.__children){node.__children=Object.assign({},node.__children);this.recursiveSet(node.__children,node,listeners,node.__children)}if(node.__listeners){listeners[node.__node.tag]=Object.assign({},node.__listeners);for(const key in node.__listeners){let listener=node.__listeners[key];if(node[key]){delete listeners[node.__node.tag][key];listeners[node.__node.tag][node.__node.tag+"."+key]=listener}if(typeof listener==="string"){if(node.__children?.[listener]){listeners[node.__node.tag][key]=node.__node.tag+"."+listener}else if(parent instanceof GraphNode&&(parent.__node.tag===listener||parent.__node.tag.includes(".")&&parent.__node.tag.split(".").pop()===listener)){listeners[node.__node.tag][key]=parent.__node.tag}}}}this.setListeners(listeners);node.__callConnected();return node};recursiveSet=(originCpy,parent,listeners={},origin,overwrite=false)=>{let keys=Object.getOwnPropertyNames(origin).filter(v2=>!objProps.includes(v2));let nonArrowFunctions=Object.getOwnPropertyNames(Object.getPrototypeOf(origin)).filter(v2=>!objProps.includes(v2));keys.push(...nonArrowFunctions);for(const key of keys){if(key.includes("__"))continue;let p2=origin[key];if(Array.isArray(p2))continue;let instanced;if(typeof p2==="function"){if(isNativeClass(p2)){p2=new p2;if(p2 instanceof GraphNode){p2=p2.prototype.constructor(p2,parent,this);instanced=true}}else p2={__operator:p2,__callable:true}}else if(typeof p2==="string"){if(this.__node.nodes.get(p2))p2=this.__node.nodes.get(p2);else p2=this.__node.roots[p2]}else if(typeof p2==="boolean"){if(this.__node.nodes.get(key))p2=this.__node.nodes.get(key);else p2=this.__node.roots[key]}if(p2&&typeof p2==="object"){if(!instanced&&!(p2 instanceof GraphNode)){let ks=Object.getOwnPropertyNames(p2).filter(v2=>!objProps.includes(v2));let nonArrowFunctions2=Object.getOwnPropertyNames(Object.getPrototypeOf(p2)).filter(v2=>!objProps.includes(v2));nonArrowFunctions2.splice(nonArrowFunctions2.indexOf("constructor"),1);ks.push(...nonArrowFunctions2);let cpy={};for(const key2 of ks){cpy[key2]=p2[key2]}p2=cpy}if(!p2.__node)p2.__node={};if(!p2.__node.tag)p2.__node.tag=key;if(!p2.__node.initial)p2.__node.initial=originCpy[key];if(overwrite&&this.get(p2.__node.tag)){this.remove(p2.__node.tag,true)}else if(this.get(p2.__node.tag)&&!(!(parent instanceof _Graph)&&parent?.__node)||parent?.__node&&this.get(parent.__node.tag+"."+p2.__node.tag))continue;let node;let newnode=false;let root=recursivelyAssign({},p2,2);if(instanced||p2 instanceof GraphNode){node=p2}else{node=new GraphNode(p2,parent,this);newnode=true}if(!newnode&&p2 instanceof GraphNode&&!instanced&&parent instanceof GraphNode){let sub=this.subscribe(parent.__node.tag,node.__node.tag);let ondelete=node2=>{this.unsubscribe(parent.__node.tag,sub)};node.__addOndisconnected(ondelete)}else if(node){this.set(node.__node.tag,node);this.runLoaders(node,parent,originCpy[key],key);originCpy[key]=node;this.__node.roots[node.__node.tag]=root;if(node.__children){node.__children=Object.assign({},node.__children);this.recursiveSet(node.__children,node,listeners,node.__children)}if(node.__listeners){listeners[node.__node.tag]=Object.assign({},node.__listeners);for(const key2 in node.__listeners){let listener=node.__listeners[key2];let k=key2;if(node[key2]){delete listeners[node.__node.tag][key2];k=node.__node.tag+"."+key2;listeners[node.__node.tag][k]=listener}if(typeof listener==="string"){if(node.__children?.[listener]){listeners[node.__node.tag][k]=node.__node.tag+"."+listener}else if(parent instanceof GraphNode&&(parent.__node.tag===listener||parent.__node.tag.includes(".")&&parent.__node.tag.split(".").pop()===listener)){listeners[node.__node.tag][k]=parent.__node.tag}}}}node.__callConnected()}}}return listeners};remove=(node,clearListeners=true)=>{this.unsubscribe(node);if(typeof node==="string")node=this.get(node);if(node instanceof GraphNode){this.delete(node.__node.tag);delete this.__node.roots[node.__node.tag];if(clearListeners){this.clearListeners(node)}node.__callDisconnected();const recursiveRemove=t=>{for(const key in t){this.unsubscribe(t[key]);this.delete(t[key].__node.tag);delete this.__node.roots[t[key].__node.tag];this.delete(key);delete this.__node.roots[key];t[key].__node.tag=t[key].__node.tag.substring(t[key].__node.tag.lastIndexOf(".")+1);if(clearListeners){this.clearListeners(t[key])}t[key].__callDisconnected();if(t[key].__children){recursiveRemove(t[key].__children)}}};if(node.__children){recursiveRemove(node.__children)}}if(node?.__node.tag&&node?.__parent){delete node?.__parent;node.__node.tag=node.__node.tag.substring(node.__node.tag.indexOf(".")+1)}if(node?.__node.graph)node.__node.graph=void 0;return node};run=(node,...args)=>{if(typeof node==="string"){let nd=this.get(node);if(!nd&&node.includes(".")){nd=this.get(node.substring(0,node.lastIndexOf(".")));if(typeof nd?.[node.substring(node.lastIndexOf(".")+1)]==="function")return nd[node.substring(node.lastIndexOf(".")+1)](...args)}else if(nd?.__operator)return nd.__operator(...args)}if(node?.__operator){return node?.__operator(...args)}};setListeners=listeners=>{for(const key in listeners){let node=this.get(key);if(typeof listeners[key]==="object"){for(const k in listeners[key]){let n=this.get(k);let sub;if(typeof listeners[key][k]!=="object")listeners[key][k]={__callback:listeners[key][k]};else if(!listeners[key][k].__callback){for(const kk in listeners[key][k]){if(typeof listeners[key][k][kk]!=="object"){listeners[key][k][kk]={__callback:listeners[key][k][kk]};if(node.__operator&&(listeners[key][k][kk].__callback===true||typeof listeners[key][k][kk].__callback==="undefined"))listeners[key][k][kk].__callback=node.__operator}let nn=this.get(kk);if(!nn){let tag=k.substring(0,k.lastIndexOf("."));nn=this.get(tag);if(nn){let prop=k.substring(k.lastIndexOf(".")+1);sub=this.subscribe(nn,listeners[key][k][kk].__callback,listeners[key][k][kk].__args,prop,listeners[key][k][kk].subInput,key)}}else{sub=this.subscribe(nn,listeners[key][k][kk].__callback,listeners[key][k][kk].__args,void 0,listeners[key][k][kk].subInput,key)}}}if("__callback"in listeners[key][k]){if(node){if(listeners[key][k].__callback===true||typeof listeners[key][k].__callback==="undefined")listeners[key][k].__callback=node.__operator;if(typeof listeners[key][k].__callback==="function")listeners[key][k].__callback=listeners[key][k].__callback.bind(node)}if(!n){let tag=k.substring(0,k.lastIndexOf("."));n=this.get(tag);if(n){sub=this.subscribe(n,listeners[key][k].__callback,listeners[key][k].__args,k.substring(k.lastIndexOf(".")+1),listeners[key][k].subInput,key)}}else{sub=this.subscribe(n,listeners[key][k].__callback,listeners[key][k].__args,void 0,listeners[key][k].subInput,key)}}}}}};clearListeners=(node,listener)=>{if(typeof node==="string")node=this.get(node);if(node?.__listeners){for(const key in node.__listeners){if(listener&&key!==listener)continue;if(typeof node.__listeners[key]?.sub!=="number")continue;let n=this.get(key);if(!n){n=this.get(key.substring(0,key.lastIndexOf(".")));if(n){if(typeof node.__listeners[key]==="object"&&!node.__listeners[key]?.__callback){for(const k in node.__listeners[key]){if(typeof node.__listeners[key][k]?.sub==="number"){this.unsubscribe(n,node.__listeners[key][k].sub,key.substring(key.lastIndexOf(".")+1),node.__listeners[key][k].subInput);node.__listeners[key][k].sub=void 0}}}else if(typeof node.__listeners[key]?.sub==="number"){this.unsubscribe(n,node.__listeners[key].sub,key.substring(key.lastIndexOf(".")+1),node.__listeners[key].subInput);node.__listeners[key].sub=void 0}}}else{if(typeof!node.__listeners[key]?.__callback==="number"){for(const k in node.__listeners[key]){if(node.__listeners[key][k]?.sub){this.unsubscribe(n,node.__listeners[key][k].sub,void 0,node.__listeners[key][k].subInput);node.__listeners[key][k].sub=void 0}}}else if(typeof node.__listeners[key]?.sub==="number"){this.unsubscribe(n,node.__listeners[key].sub,void 0,node.__listeners[key].subInput);node.__listeners[key].sub=void 0}}}}};get=tag=>{return this.__node.nodes.get(tag)};getByUnique=unique=>{return Array.from(this.__node.nodes.values()).find(node=>{if(node.__node.unique===unique)return true})};set=(tag,node)=>{return this.__node.nodes.set(tag,node)};delete=tag=>{return this.__node.nodes.delete(tag)};list=()=>{return Array.from(this.__node.nodes.keys())};getListener=(nodeTag,key,sub)=>{let node=this.get(nodeTag);if(node){let k=node.__node.unique;if(key){k+="."+key}return this.__node.state.getEvent(k,sub)}};getProps=(node,getInitial)=>{if(typeof node==="string")node=this.get(node);if(node instanceof GraphNode){let cpy;if(getInitial)cpy=Object.assign({},this.__node.roots[node.__node.tag]);else{cpy=Object.assign({},node);for(const key in cpy){if(key.includes("__"))delete cpy[key]}}}};subscribe=(nodeEvent,onEvent,args,key,subInput,target,tkey)=>{let nd=nodeEvent;if(typeof nodeEvent==="string"){nd=this.get(nodeEvent);if(!nd&&nodeEvent.includes(".")){nd=this.get(nodeEvent.substring(0,nodeEvent.lastIndexOf(".")));key=nodeEvent.substring(nodeEvent.lastIndexOf(".")+1)}}if(target instanceof GraphNode)target=target.__node.tag;let callbackStr;if(typeof onEvent==="string"){callbackStr=onEvent;let setOnEventFromString=onEvent2=>{if(this.get(onEvent2)?.__operator){let node=this.get(onEvent2);target=onEvent2;onEvent2=function(...inp){return node.__operator(...inp)}}else if(onEvent2.includes(".")){target=onEvent2.substring(0,onEvent2.lastIndexOf("."));let n=this.get(target);let k=onEvent2.substring(onEvent2.lastIndexOf(".")+1);tkey=k;if(typeof n[k]==="function"){if(n[k]instanceof GraphNode)onEvent2=n[k];else onEvent2=function(...inp){return n[k](...inp)}}else{onEvent2=function(inp){n[k]=inp;return n[k]}}}return onEvent2};if(target){let node=this.get(target);if(typeof node?.[onEvent]==="function"){tkey=onEvent;onEvent=function(...inp){return node[key](...inp)}}else if(node?.[key]){tkey=key;if(node[key]instanceof GraphNode)onEvent=node[key];else onEvent=function(inp){node[key]=inp;return node[key]}}else{onEvent=setOnEventFromString(onEvent)}}else{onEvent=setOnEventFromString(onEvent)}}let sub;if(nd instanceof GraphNode){const doSub=()=>{sub=nd.__subscribe(onEvent,key,subInput,target,tkey,args,callbackStr);let ondelete=()=>{if(sub!==void 0)nd.__unsubscribe(sub,key,subInput);sub=void 0};nd.__addOndisconnected(()=>{ondelete();nd.__addOnconnected(()=>{if(sub===void 0&&nd.__node.graph.__node.tag===this.__node.tag)doSub()})});if(typeof onEvent==="string"&&this.get(onEvent))onEvent=this.get(onEvent);if(onEvent instanceof GraphNode){onEvent.__addOndisconnected(()=>{ondelete()})}};doSub()}else if(typeof nodeEvent==="string"){let node=this.get(nodeEvent);if(node){if(onEvent instanceof GraphNode&&onEvent.__operator){const doSub=()=>{sub=node.__subscribe(onEvent.__operator,key,subInput,target,tkey,args,callbackStr);let ondelete=()=>{if(sub!==void 0)node.__unsubscribe(sub,key,subInput)};node.__addOndisconnected(()=>{ondelete();node.__addOnconnected(()=>{if(sub===void 0&&node.__node.graph.__node.tag===this.__node.tag)doSub()})});onEvent.__addOndisconnected(ondelete)};doSub()}else if(typeof onEvent==="function"||typeof onEvent==="string"){const doSub=()=>{sub=node.__subscribe(onEvent,key,subInput,target,tkey,args,callbackStr);let ondelete=()=>{if(sub!==void 0)node.__unsubscribe(sub,key,subInput);sub=void 0};node.__addOndisconnected(()=>{ondelete();node.__addOnconnected(()=>{if(sub===void 0&&node.__node.graph.__node.tag===this.__node.tag)doSub()})});if(typeof onEvent==="string"&&this.get(onEvent))this.get(onEvent).__addOndisconnected(ondelete)};doSub()}}else{if(typeof onEvent==="string")onEvent=this.__node.nodes.get(onEvent).__operator;if(typeof onEvent==="function"&&!onEvent?.__node)sub=this.__node.state.subscribeEvent(nodeEvent,onEvent)}}return sub};unsubscribe=(node,sub,key,subInput)=>{if(node instanceof GraphNode){return node.__unsubscribe(sub,key,subInput)}else return this.get(node)?.__unsubscribe(sub,key,subInput)};setState=update=>{this.__node.state.setState(update)}};function recursivelyAssign(target,obj,maxDepth=Infinity,curDepth=0){for(const key in obj){if(obj[key]?.constructor.name==="Object"&&curDepth{if(graph.get(a)?.__operator){let node=graph.get(a);return(...inp)=>{node.__operator(...inp)}}else if(a.includes(".")){let split=a.split(".");let popped=split.pop();let joined=split.join(".");let node=graph.get(joined);if(typeof graph.get(joined)?.[popped]==="function"){return(...inp)=>{return node[popped](...inp)}}else return()=>{return node[popped]}}else if(graph.get(a)){let node=graph.get(a);return()=>{return node}}else{let arg=a;return()=>{return arg}}};var wrapArgs=(callback,argOrder,graph)=>{let args=[];let forArg=(a,i)=>{if(a==="__output"||a==="__input"||a==="__callback"){args[i]={__callback:inp=>{return inp},__args:void 0,idx:i}}else if(typeof a==="string"){args[i]={__callback:getCallbackFromString(a,graph),__args:void 0,idx:i}}else if(typeof a==="function"){let fn2=a;args[i]={__callback:(...inp)=>{return fn2(...inp)},__args:void 0,idx:i}}else if(typeof a==="object"&&(a.__input||a.__callback)){let recursivelyCreateCallback=function(c){let input=c.__input?c.__input:c.__callback;if(typeof c.__input==="string"){input={__callback:getCallbackFromString(c.__input,graph),__args:void 0,idx:i}}if(c.__args){let wrapped=wrapArgs(input,c.__args,graph);input={__callback:wrapped.__callback,__args:wrapped.__args,idx:i}}else{input={__callback:input,__args:void 0,idx:i}}if(c.__output){let output=c.__output;if(typeof c.__output==="string"){output={__callback:getCallbackFromString(output,graph),__args:void 0,idx:i}}else if(typeof a.__output==="object"){output=recursivelyCreateCallback(output)}if(typeof output?.__callback==="function"){let fn2=input.__callback;let callback2=output.__callback;input={__callback:(...inp)=>{return callback2(fn2(...inp))},__args:output.__args,idx:i}}}return input};args[i]=recursivelyCreateCallback(a)}else{let arg=a;args[i]={__callback:()=>{return arg},__args:void 0,idx:i}}};argOrder.forEach(forArg);if(typeof callback==="string")callback={__callback:getCallbackFromString(callback,graph),__args:void 0};let fn=typeof callback==="function"?callback:callback.__callback;callback=function(...inp){let mapArg=arg=>{return arg.__callback(...inp)};const result=fn(...args.map(mapArg));return result};return{__callback:callback,__args:args}};var objProps=Object.getOwnPropertyNames(Object.getPrototypeOf({}));var backprop=(node,parent,graph)=>{if(node.__node.backward&&parent instanceof GraphNode){graph.setListeners({[parent.__node.tag]:{[node.__node.tag]:parent}})}};var loop=(node,parent,graph)=>{if(node.__operator){let loopId=Math.random();if(!node.__node.loops)node.__node.loops={};if(typeof node.__node.delay==="number"){let fn=node.__operator;node.__setOperator((...args)=>{return new Promise((res,rej)=>{node.__node.loops[loopId]=setTimeout(async()=>{res(await fn(...args))},node.__node.delay)})})}else if(node.__node.frame===true){let fn=node.__operator;node.__setOperator((...args)=>{return new Promise((res,rej)=>{node.__node.loops[loopId]=requestAnimationFrame(async()=>{res(await fn(...args))})})})}if(typeof node.__node.repeat==="number"||typeof node.__node.recursive==="number"){let fn=node.__operator;node.__setOperator(async(...args)=>{let i=node.__node.repeat?node.__node.repeat:node.__node.recursive;let result;let repeater=async(tick,...inp)=>{while(tick>0){if(node.__node.delay||node.__node.frame){fn(...inp).then(async res=>{if(node.__node.recursive){await repeater(tick,res)}else await repeater(tick,...inp)});break}else result=await fn(...args);tick--}};await repeater(i,...args);return result})}if(node.__node.loop&&typeof node.__node.loop==="number"){let fn=node.__operator;let time=node.__node.loop;node.__setOperator((...args)=>{if(!("looping"in node.__node))node.__node.looping=true;if(node.__node.looping){let last=performance.now();fn(...args);node.__node.loops[loopId]=setTimeout(()=>{let now=performance.now();let overshoot=now-last-node.__node.loop;if(overshoot>0)time=node.__node.loop-overshoot;else time=node.__node.loop;if(time<=0)time=node.__node.loop;node.__operator(...args)},time)}});if(node.__node.looping)node.__operator();let ondelete=node2=>{if(node2.__node.looping)node2.__node.looping=false;if(node2.__node.loops[loopId]){clearTimeout(node2.__node.loops[loopId]);cancelAnimationFrame(node2.__node.loops[loopId])}};node.__addOndisconnected(ondelete)}}};var animate=(node,parent,graph)=>{if(node.__node.animate===true||node.__animation){let fn=node.__operator;node.__setOperator((...args)=>{if(!("animating"in node.__node))node.__node.animating=true;if(node.__node.animating){if(typeof node.__animation==="function")node.__animation(...args);else fn(...args);node.__node.animationFrame=requestAnimationFrame(()=>{node.__operator(...args)})}});if(node.__node.animating||(!("animating"in node.__node)||node.__node.animating)&&node.__animation)setTimeout(()=>{node.__node.animationFrame=requestAnimationFrame(node.__operator)},10);let ondelete=node2=>{if(node2.__node.animating)node2.__node.animating=false;if(node2.__node.animationFrame)cancelAnimationFrame(node2.__node.animationFrame)};node.__addOndisconnected(ondelete)}};var branching=(node,parent,graph)=>{if(typeof node.__branch==="object"&&node.__operator&&!node.__branchApplied){let fn=node.__operator;node.__branchApplied=true;node.__operator=(...args)=>{let result=fn(...args);for(const key in node.__branch){let triggered=()=>{if(typeof node.__branch[key].then==="function"){node.__branch[key].then(result)}else if(node.__branch[key].then instanceof GraphNode&&node.__branch[key].then.__operator){node.__branch[key].then.__operator(result)}else result=node.__branch[key].then};if(typeof node.__branch[key].if==="function"){if(node.__branch[key].if(result)==true){triggered()}}else if(node.__branch[key].if===result){triggered()}}return result}}if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(node.__listeners[key].branch&&!node.__listeners[key].branchApplied){let fn=node.__listeners[key].callback;node.__listeners[key].branchApplied=true;node.__listeners.callback=ret=>{let triggered=()=>{if(typeof node.__listeners[key].branch.then==="function"){ret=node.__listeners[key].branch.then(ret)}else if(node.__listeners[key].branch.then instanceof GraphNode&&node.__listeners[key].branch.then.__operator){ret=node.__listeners[key].branch.then.__operator(ret)}else ret=node.__listeners[key].branch.then};if(typeof node.__listeners[key].branch.if==="function"){if(node.__listeners[key].branch.if(ret)){triggered()}}else if(node.__listeners[key].branch.if===ret){triggered()}return fn(ret)}}}}}};var triggerListenerOncreate=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(node.__listeners[key].oncreate){node.__listeners[key].callback(node.__listeners[key].oncreate)}}}}};var bindListener=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(typeof node.__listeners[key].binding==="object"){node.__listeners.callback=node.__listeners.callback.bind(node.__listeners[key].binding)}}}}};var transformListenerResult=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(typeof node.__listeners[key].transform==="function"&&!node.__listeners[key].transformApplied){let fn=node.__listeners[key].callback;node.__listeners[key].transformApplied=true;node.__listeners.callback=ret=>{ret=node.__listeners[key].transform(ret);return fn(ret)}}}}}};var substitute__operator=(node,parent,graph)=>{if(node.post&&!node.__operator){node.__setOperator(node.post)}else if(!node.__operator&&typeof node.get=="function"){node.__setOperator(node.get)}if(!node.get&&node.__operator){}if(node.aliases){node.aliases.forEach(a=>{graph.set(a,node);let ondelete=node2=>{graph.__node.nodes.delete(a)};node.__addOndisconnected(ondelete)})}if(typeof graph.__node.roots?.[node.__node.tag]==="object"&&node.get)graph.__node.roots[node.__node.tag].get=node.get};var loaders={backprop,loop,animate,branching,triggerListenerOncreate,bindListener,transformListenerResult,substitute__operator};var Service=class extends Graph{name=`service${Math.floor(Math.random()*1e15)}`;restrict;constructor(options){super({...options,loaders:options?.loaders?Object.assign({...loaders},options.loaders):{...loaders}});if(options?.services)this.addServices(options.services);if(options?.restrict)this.restrict=options.restrict;this.load(this)}addServices=services=>{for(const s in services){if(typeof services[s]==="function")services[s]=new services[s];if(services[s]?.__node?.loaders)Object.assign(this.__node.loaders,services[s].__node.loaders);if(services[s]?.__node?.nodes){services[s].__node.nodes.forEach((n,tag)=>{if(!this.get(tag)){this.set(tag,n)}else this.set(s+"."+tag,n)});this.__node.nodes.forEach((n,k)=>{if(!services[s].__node.nodes.get(k))services[s].__node.nodes.set(k,n)});let set=this.set;this.set=(tag,node)=>{services[s].set(tag,node);return set(tag,node)};let del=this.delete;this.delete=tag=>{services[s].delete(tag);return del(tag)}}else if(typeof services[s]==="object"){this.load(services[s])}}};handleMethod=(route,method,args)=>{let m=method.toLowerCase();let src=this.__node.nodes.get(route);if(!src){src=this.__node.roots[route]}if(src?.[m]){if(typeof src[m]!=="function"){if(args){if(Array.isArray(args)&&args.length===1)src[m]=args[0];else src[m]=args;return}return src[m]}else{if(Array.isArray(args))return src[m](...args);else return src[m](args)}}else return this.handleServiceMessage({route,args,method})};handleServiceMessage(message){let call;if(typeof message==="object"){if(message.route)call=message.route;else if(message.node)call=message.node}if(call){if(Array.isArray(message.args))return this.run(call,...message.args);else return this.run(call,message.args)}else return message}handleGraphNodeCall(route,args){if(!route)return args;if(args?.args){this.handleServiceMessage(args)}else if(Array.isArray(args))return this.run(route,...args);else return this.run(route,args)}transmit=(...args)=>{if(typeof args[0]==="object"){const message=args[0];if(message.method){return this.handleMethod(message.route,message.method,message.args)}else if(message.route){return this.handleServiceMessage(message)}else if(message.node){return this.handleGraphNodeCall(message.node,message.args)}else if(this.__node.keepState){if(message.route)this.setState({[message.route]:message.args});if(message.node)this.setState({[message.node]:message.args})}return void 0}else return void 0};receive=(...args)=>{if(args[0]){let message=args[0];if(typeof message==="string"){let substr=message.substring(0,8);if(substr.includes("{")||substr.includes("[")){if(substr.includes("\\"))message=message.replace(/\\/g,"");if(message[0]==='"'){message=message.substring(1,message.length-1)};message=JSON.parse(message)}}if(typeof message==="object"){if(message.method){if(this.restrict?.[message.route])return void 0;return this.handleMethod(message.route,message.method,message.args)}else if(message.route){if(this.restrict?.[message.route])return void 0;return this.handleServiceMessage(message)}else if(message.node){if(typeof message.node==="string"&&this.restrict?.[message.node])return void 0;return this.handleGraphNodeCall(message.node,message.args)}else if(this.__node.keepState){if(message.route)this.setState({[message.route]:message.args});if(message.node)this.setState({[message.node]:message.args})}return void 0}}return void 0};pipe=(source,destination,endpoint,method,callback)=>{if(source instanceof GraphNode){if(callback)return this.subscribe(source,res=>{let mod=callback(res);if(mod!==void 0)this.transmit({route:destination,args:mod,method});else this.transmit({route:destination,args:res,method},endpoint)});else return this.subscribe(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})}else if(typeof source==="string")return this.subscribe(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})};pipeOnce=(source,destination,endpoint,method,callback)=>{if(source instanceof GraphNode){if(callback)return source.__node.state.subscribeEventOnce(source.__node.unique,res=>{let mod=callback(res);if(mod!==void 0)this.transmit({route:destination,args:mod,method});else this.transmit({route:destination,args:res,method},endpoint)});else return this.__node.state.subscribeEventOnce(source.__node.unique,res=>{this.transmit({route:destination,args:res,method},endpoint)})}else if(typeof source==="string")return this.__node.state.subscribeEventOnce(this.__node.nodes.get(source).__node.unique,res=>{this.transmit({route:destination,args:res,method},endpoint)})};terminate=(...args)=>{};isTypedArray=isTypedArray;recursivelyAssign=recursivelyAssign2;spliceTypedArray=spliceTypedArray;ping=()=>{console.log("pinged!");return"pong"};echo=(...args)=>{this.transmit(...args);return args};log=(...args)=>{console.log(...args);return true};error=(...args)=>{console.error(...args);return true}};function isTypedArray(x3){return ArrayBuffer.isView(x3)&&Object.prototype.toString.call(x3)!=="[object DataView]"}var recursivelyAssign2=(target,obj)=>{for(const key in obj){if(obj[key]?.constructor.name==="Object"&&!Array.isArray(obj[key])){if(target[key]?.constructor.name==="Object"&&!Array.isArray(target[key]))recursivelyAssign2(target[key],obj[key]);else target[key]=recursivelyAssign2({},obj[key])}else target[key]=obj[key]}return target};function spliceTypedArray(arr,start,end){let s=arr.subarray(0,start);let e;if(end){e=arr.subarray(end+1)}let ta;if(s.length>0||e?.length>0)ta=new arr.constructor(s.length+e.length);if(ta){if(s.length>0)ta.set(s);if(e&&e.length>0)ta.set(e,s.length)}return ta}var randomId=prefix=>(prefix?`${prefix}`:"")+Math.floor(1e15*Math.random());var pseudoObjectId=(m=Math,d2=Date,h=16,s=s2=>m.floor(s2).toString(h))=>s(d2.now()/1e3)+" ".repeat(h).replace(/./g,()=>s(m.random()*h));var StructFrontend=class extends Service{name="structs";currentUser;tablet=new DataTablet;collections=this.tablet.collections;id=randomId();useAccessTokens=false;useRefreshTokens=false;constructor(options,user){super(options);this.load(this);if(options.useAccessTokens)this.useAccessTokens=options.useAccessTokens;if(options.useRefreshTokens)this.useRefreshTokens=options.useRefreshTokens;if(user instanceof Object&&Object.keys(user).length>0)this.setupUser(user)}getToken(user){if(this.useAccessTokens)return user.accessToken;else if(this.useRefreshTokens)return user.refreshToken}setupUser=async(userinfo,callback=currentUser=>{})=>{if(!userinfo){console.error('must provide a minimum info object! e.g. {_id:"abc123"}');callback(void 0);return void 0}let changed=false;if(userinfo.id&&!userinfo._id)userinfo._id=userinfo.id;else if(userinfo._id)userinfo.id=userinfo._id;let res=await this.getUser(userinfo._id);let user=res?.user;let u2;let newu=false;if(!user||!user._id){u2=this.userStruct(userinfo,false);newu=true;let wasSet=await this.setUser(u2);let structs=this.getLocalData(void 0,{"ownerId":u2._id});if(structs?.length>0)this.updateServerData(structs);this.setAuthorizationsByGroup(u2)}else{u2=user;let toUpdate={_id:userinfo._id,ownerId:userinfo._id};let struct=this.userStruct(userinfo,false);for(const key in struct){if(userinfo[key]&&user[key]!==userinfo[key]){toUpdate[key]=userinfo[key];user[key]=userinfo[key]}else if(struct[key]&&!user[key]){toUpdate[key]=struct[key];user[key]=struct[key]}}if(Object.keys(toUpdate).length>2)await this.setUser(toUpdate);if(res?.authorizations){if(Array.isArray(res.authorizations)){this.setLocalData(res.authorizations)}}if(res?.groups){if(Array.isArray(res.groups)){this.setLocalData(res.groups)}}}if(newu){this.setLocalData(u2)}else{let data=await this.getAllUserData(u2._id,void 0,[genTimestampFromString("last day"),Date.now()]);if(!data||data.length===0){}else{this.setLocalData(data);let notes=data.filter(s=>{if(s.structType==="notification"){if(this.getLocalData("authorization",s.parent._id)){return true}if(s.parent.structType==="user"||s.parent.structType==="authorization"){return true}if(!this.getLocalData(s.parent.structType,s.parent._id))return true}});let comments=data.filter(s=>{if(s.structType==="comment"){return true}});let toDelete=[];comments.forEach(comment=>{if(!this.getLocalData("comment",{"_id":comment._id}))toDelete.push(comment._id)});if(toDelete.length>0)this.deleteData(toDelete);if(notes.length>0){this.resolveNotifications(notes,false,void 0);changed=true}let filtered=data.filter(o=>{if(o.structType!=="notification")return true});if(this.tablet)this.tablet.sortStructsIntoTable(filtered)}this.setLocalData(u2)}if(u2){if(this.currentUser)Object.assign(this.currentUser,u2);else this.currentUser=u2;callback(this.currentUser);return this.currentUser}else{callback(u2);return u2}};baseServerCallback=data=>{let structs=data;if(typeof data==="object"&&data?.structType)structs=[data];if(Array.isArray(structs)){let filtered=structs.filter(o=>{if(o.structType!=="notification")return true});if(this.tablet)this.tablet.sortStructsIntoTable(filtered);structs.forEach(struct=>{if(typeof struct==="object"){if(!struct.structType||struct.structType==="USER"){if(struct.email)struct.structType="user";else struct.structType="uncategorized"}if(struct.structType==="user"||struct.structType==="authorization"||struct.structType==="group"){if(struct.structType==="user"){struct._id=struct.id}else if(struct.structType==="group"){if(this.currentUser){let uset=false;if(struct.admins[this.currentUser?._id]&&!this.currentUser.userRoles?.[struct.name+"_admin"]){this.currentUser.userRoles[struct.name+"_admin"]=true;uset=true}else if(!struct.admins[this.currentUser?._id]&&this.currentUser.userRoles?.[struct.name+"_admin"]){delete this.currentUser.userRoles[struct.name+"_admin"];uset=true}if(struct.admins[this.currentUser?._id]&&!this.currentUser.userRoles?.[struct.name+"_peer"]){this.currentUser.userRoles[struct.name+"_peer"]=true;uset=true}else if(!struct.admins[this.currentUser?._id]&&this.currentUser.userRoles?.[struct.name+"_peer"]){delete this.currentUser.userRoles[struct.name+"_peer"];uset=true}if(struct.admins[this.currentUser?._id]&&!this.currentUser.userRoles?.[struct.name+"_client"]){this.currentUser.userRoles[struct.name+"_client"]=true;uset=true}else if(!struct.admins[this.currentUser?._id]&&this.currentUser.userRoles?.[struct.name+"_client"]){delete this.currentUser.userRoles[struct.name+"_client"];uset=true}if(uset)this.setUser(this.currentUser)}}this.setLocalData(struct)}else{if(struct.structType==="notification"){let found=this.getLocalData("notification",{"ownerId":struct.ownerId,"_id":struct.parent._id});if(found){this.setLocalData(struct)}else{if(this.getLocalData(struct.structType,{"_id":struct.parent._id})){}else{this.overwriteLocalData(struct)}}if(struct.ownerId===this.currentUser?._id&&(struct.parent.structType==="user"||struct.parent.structType==="dataInstance"||struct.parent.structType==="schedule"||struct.parent.structType==="authorization")){this.resolveNotifications([struct],true)}}else{this.overwriteLocalData(struct)}}}})}this.onResult(data)};structNotification=()=>{this.checkForNotifications()};structDeleted=struct=>{this.deleteLocalData([struct])};onResult=data=>{};randomId(tag=""){return`${tag+Math.floor(Math.random()+Math.random()*Math.random()*1e16)}`}addStruct=async(structType="struct",props={},parentUser,parentStruct,updateServer=true)=>{let newStruct=DataStructures_exports.Struct(structType,props,parentUser,parentStruct);if(updateServer)newStruct=await this.updateServerData([newStruct])[0];return newStruct};getUser=async(info="",basicInfo,callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"getUser",args:[this.currentUser._id,info,basicInfo,this.getToken(this.currentUser)]});callback(res);return res}};queryUsers=async(info,skip,limit,callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"queryUsers",args:[this.currentUser._id,info,skip,limit,void 0,this.getToken(this.currentUser)]});callback(res);return res}};getUsers=async(ids=[],basicInfo,callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"getUsersByIds",args:[this.currentUser._id,ids,basicInfo]});callback(res);return res}};getUsersByRole=async(userRole,callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"getUsersByRole",args:[this.currentUser._id,userRole]});callback(res);return res}};getAllUserData=async(ownerId,excluded=[],timeRange,callback=this.baseServerCallback)=>{if(timeRange){if(typeof timeRange[0]==="string")timeRange[0]=genTimestampFromString(timeRange[0]);if(typeof timeRange[1]==="string")timeRange[1]=genTimestampFromString(timeRange[1])}if(this.currentUser?.request){let res=await this.currentUser.request({route:"getAllData",args:[this.currentUser._id,ownerId,excluded,timeRange,this.getToken(this.currentUser)]});callback(res);return res}};query=async(collection,mongoQuery={},findOne=false,skip=0,callback=this.baseServerCallback)=>{if(this.currentUser?.request){if(!collection||!mongoQuery)return void 0;let res=await this.currentUser.request({route:"query",args:[this.currentUser._id,collection,mongoQuery,findOne,skip,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};getDataByTimeRange(collection,timeRange,ownerId,limit=0,skip=0,key){let query={};if(timeRange){if(typeof timeRange[0]==="string")timeRange[0]=genTimestampFromString(timeRange[0]);if(typeof timeRange[1]==="string")timeRange[1]=genTimestampFromString(timeRange[1])}let range={$gt:timeRange[0],$lt:timeRange[1]};if(key)query[key]=range;else query.timestamp=range;return this.getData(collection,ownerId,query,limit,skip)}getData=async(collection,ownerId,searchDict,limit=0,skip=0,callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"getData",args:[this.currentUser._id,collection,ownerId,searchDict,limit,skip,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};getDataByIds=async(structIds=[],ownerId,collection,callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"getDataByIds",args:[this.currentUser._id,structIds,ownerId,collection,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};getStructParentData=async(struct,callback=this.baseServerCallback)=>{if(!struct?.parent)return;if(this.currentUser?.request){let args=[this.currentUser._id,struct.parent?.structType,"_id",struct.parent?._id,this.getToken(this.currentUser)];let res=(await this.currentUser.request({route:"getData",args}))?.[0];if(typeof callback==="function")callback(res);return res}};setUser=async(userStruct,callback=this.baseServerCallback)=>{if(userStruct&&this.currentUser?.request){let res=await this.currentUser.request({route:"setUser",args:[this.currentUser._id,this.stripStruct(userStruct),this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};checkUserToken=async(usertoken,user=this.currentUser,callback=this.baseServerCallback)=>{if(!usertoken)return false;let changed=false;for(const prop in usertoken){let dummystruct=this.userStruct();if(user[prop]&&prop!=="_id"){if(Array.isArray(usertoken[prop])){for(let i=0;i{if(this.currentUser?.request){const copies=new Array;if(!Array.isArray(structs)&&typeof structs==="object")structs=[structs];structs.forEach(struct=>{copies.push(this.stripStruct(struct))});let res=await this.currentUser.request({route:"setData",args:[this.currentUser._id,copies,notify,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};updateServerData=this.setData;deleteData=async(structs=[],callback=this.baseServerCallback)=>{if(this.currentUser?.request){let toDelete=[];structs.forEach(struct=>{if(typeof struct==="object"){if(struct?.structType&&struct?._id){toDelete.push({structType:struct.structType,_id:struct._id});this.deleteLocalData(struct)}}else if(typeof struct==="string"){let localstruct=this.getLocalData(void 0,{_id:struct});if(localstruct&&!Array.isArray(localstruct)){toDelete.push({structType:localstruct.structType,_id:localstruct._id})}else{toDelete.push({_id:struct})}}});let res=await this.currentUser.request({route:"deleteData",args:[this.currentUser._id,toDelete,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};deleteUser=async(userId=this.currentUser._id,deleteData,callback=this.baseServerCallback)=>{if(this.currentUser?.request){if(!userId)return;let res=await this.currentUser.request({route:"deleteUser",args:[this.currentUser._id,userId,deleteData,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};setGroup=async(groupStruct,callback=this.baseServerCallback)=>{if(groupStruct&&this.currentUser?.request){let res=await this.currentUser.request({route:"setGroup",args:[this.currentUser._id,this.stripStruct(groupStruct),this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};getUserGroups=async(userId=this.currentUser._id,groupId="",callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"getUserGroups",args:[this.currentUser._id,userId,groupId,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};deleteGroup=async(groupId,callback=this.baseServerCallback)=>{if(this.currentUser?.request){if(!groupId)return;this.deleteLocalData(groupId);let res=await this.currentUser.request({route:"deleteGroup",args:[this.currentUser._id,groupId,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};setAuthorization=async(authorizationStruct,callback=this.baseServerCallback)=>{if(authorizationStruct&&this.currentUser?.request){let res=await this.currentUser.request({route:"setAuthorization",args:[this.currentUser._id,this.stripStruct(authorizationStruct),this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};getAuthorizations=async(userId=this.currentUser?._id,authorizationId="",callback=this.baseServerCallback)=>{if(this.currentUser?.request){if(userId===void 0)return;let res=await this.currentUser.request({route:"getAuthorizations",args:[this.currentUser._id,userId,authorizationId,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};deleteAuthorization=async(authorizationId,callback=this.baseServerCallback)=>{if(this.currentUser?.request){if(!authorizationId)return;this.deleteLocalData(authorizationId);let res=await this.currentUser.request({route:"deleteAuthorization",args:[this.currentUser._id,authorizationId,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};checkForNotifications=async(userId=this.currentUser?._id)=>{return await this.getData("notification",userId)};resolveNotifications=async(notifications=[],pull=true,user=this.currentUser)=>{if(!user||notifications.length===0)return;let structIds=[];let notificationIds=[];let nTypes=[];let unote=false;if(notifications.length===0)notifications=this.getLocalData("notification",{"ownerId":user._id});notifications.forEach(struct=>{if(struct.parent.structType==="user")unote=true;nTypes.push(struct.parent.structType);structIds.push(struct.parent._id);notificationIds.push(struct._id);this.deleteLocalData(struct)});this.deleteData(notifications);if(pull){nTypes.reverse().forEach((note,i)=>{if(note==="user"){this.getUser(structIds[i]);structIds.splice(structIds.length-i-1,1)}});if(structIds.length===1)return await this.getDataByIds(structIds,void 0,notifications[0].parent.structType);if(structIds.length>0)return await this.getDataByIds(structIds)}return true};setAuthorizationsByGroup=async(user=this.currentUser)=>{let auths=this.getLocalData("authorization",{"ownerId":user._id});let newauths=[];if(user.userRoles)await Promise.all(Object.keys(user.userRoles).map(async role=>{let split=role.split("_");let team=split[0];let otherrole;if(role.includes("client")){otherrole=team+"_peer"}else if(role.includes("peer")){otherrole=team+"_client"}else if(role.includes("admin")){otherrole=team+"_owner"}if(otherrole){let users=await this.getUsersByRole(otherrole);if(users)await Promise.all(users.map(async groupie=>{let theirname=groupie.username;if(!theirname)theirname=groupie.email;if(!theirname)theirname=groupie._id;let myname=user.username;if(!myname)myname=user.email;if(!myname)myname=user._id;if(theirname!==myname){if(role.includes("client")){let found=auths.find(a=>{if(a.authorizerId===groupie._id&&a.authorizedId===user._id)return true});if(!found){let auth=await this.authorizeUser(DataStructures_exports.ProfileStruct("user",user,user),groupie._id,theirname,user._id,myname,{"peer":true},void 0,{group:team});newauths.push(auth)}}else if(role.includes("peer")){let found=auths.find(a=>{if(a.authorizedId===groupie._id&&a.authorizerId===user._id)return true});if(!found){let auth=await this.authorizeUser(DataStructures_exports.ProfileStruct("user",user,user),user._id,myname,groupie._id,theirname,{"peer":true},void 0,{group:team});newauths.push(auth)}}}}))}}));if(newauths.length>0)return newauths;return void 0};deleteRoom=async roomStruct=>{if(!roomStruct)return false;let toDelete=[roomStruct];roomStruct.comments?.forEach(id=>{let struct=this.getLocalData("comment",{"_id":id});toDelete.push(struct)});if(roomStruct)return await this.deleteData(toDelete);else return false};deleteComment=async commentStruct=>{let allReplies=[commentStruct];let getRepliesRecursive=(head=commentStruct)=>{if(head?.replies){head.replies.forEach(replyId=>{let reply=this.getLocalData("comment",{"_id":replyId});if(reply){if(reply.replies.length>0){reply.replies.forEach(replyId2=>{getRepliesRecursive(replyId2)})}allReplies.push(reply)}})}};getRepliesRecursive(commentStruct);let parent=this.getLocalData(commentStruct.parent?.structType,{"_id":commentStruct.parent?._id});let toUpdate=[];if(parent){toUpdate=[parent];allReplies.forEach(r=>{let idx=parent.replies?.indexOf(r._id);if(idx>-1)parent.replies.splice(idx,1);let idx2=parent.comments?.indexOf(r._id);if(idx2>-1)parent.comments.splice(idx2,1)})}let replyTo=this.getLocalData("comment",{"_id":commentStruct.replyTo});if(replyTo?._id!==parent?._id){let idx=replyTo.replies?.indexOf(parent._id);if(idx>-1)replyTo.replies.splice(idx,1);toUpdate.push(replyTo)}if(toUpdate.length>0)await this.updateServerData(toUpdate);return await this.deleteData(allReplies)};getUserDataByAuthorization=async(authorizationStruct,collection,searchDict,limit=0,skip=0,callback=this.baseServerCallback)=>{let u2=authorizationStruct.authorizerId;if(u2){return new Promise(async resolve=>{this.getUser(u2,true,async data=>{let res;if(!collection)res=await this.getAllUserData(u2,["notification"],void 0,callback);else res=await this.getData(collection,u2,searchDict,limit,skip,callback);resolve(res);callback(res)})})}else return void 0};getUserDataByAuthorizationGroup=async(groupId="",collection,searchDict,limit=0,skip=0,callback=this.baseServerCallback)=>{let auths=this.getLocalData("authorization");let results=[];await Promise.all(auths.map(async o=>{if(o.groups?.includes(groupId)){let u2=o.authorizerId;if(u2){let data;let user=await this.getUser(u2,true,callback);if(user)results.push(user);if(!collection)data=await this.getAllUserData(u2,["notification"],void 0,callback);else data=await this.getData(collection,u2,searchDict,limit,skip,callback);if(data)results.push(data)}return true}}));return results};overwriteLocalData(structs){if(Array.isArray(structs)){structs.forEach(struct=>{let localdat=this.getLocalData(struct.structType,{"ownerId":struct.ownerId,"_id":struct._id});if(!localdat||localdat?.length===0){this.setLocalData(struct)}else Object.assign(localdat,struct)})}else{let localdat=this.getLocalData(structs.structType,{"ownerId":structs.ownerId,"_id":structs._id});if(!localdat||localdat?.length===0){this.setLocalData(structs)}else Object.assign(localdat,structs)}}setLocalData(structs){this.tablet.setLocalData(structs)}getLocalData(collection,query){return this.tablet.getLocalData(collection,query)}getLocalUserPeerIds=(user=this.currentUser)=>{if(!user)return{};let result={};let authorizations=this.getLocalData("authorization",user._id);authorizations.forEach(a=>{if(a.authorizations["peer"]&&a.authorizerId===user._id)result[a.authorizedId]=true});return result};getLocalReplies(struct){let replies=[];if(!struct.replies)return replies;else if(struct.replies.reduce((a,b)=>a*(typeof b==="object"?1:0),1))return struct.replies;replies=this.getLocalData("comment",{"replyTo":struct._id});return replies}hasLocalAuthorization(otherUserId,ownerId=this.currentUser._id){let auths=this.getLocalData("authorization",{ownerId});let found=auths.find(a=>{if(a.authorizedId===ownerId&&a.authorizerId===otherUserId)return true;if(a.authorizerId===ownerId&&a.authorizedId===otherUserId)return true});if(found){return found}else return false}deleteLocalData(structs){if(Array.isArray(structs))structs.forEach(s=>this.deleteStruct(s));else this.deleteStruct(structs);return true}deleteStruct(struct){if(typeof struct==="string")struct=this.getLocalData(void 0,{_id:struct});if(!struct)throw new Error("Struct not supplied");if(!struct.structType||!struct._id)return false;this.tablet.collections.get(struct.structType).delete(struct._id);return true}stripStruct(struct){const copy=Object.assign({},struct);for(const prop in copy){if(copy[prop]===void 0||copy[prop]===""||copy[prop].constructor.name==="Map"||copy[prop].constructor.name==="Set"||typeof copy[prop]==="function")delete copy[prop];else if(Array.isArray(copy[prop])&©[prop].length===0)delete copy[prop];else if(typeof copy[prop]==="object"&&Object.keys(copy[prop]).length===0)delete copy[prop]}return copy}createStruct(structType,props,parentUser=this.currentUser,parentStruct){let struct=DataStructures_exports.Struct(structType,props,parentUser,parentStruct);return struct}userStruct(props={},currentUser=false){let user=DataStructures_exports.ProfileStruct(void 0,props,props);if(!user.name&&user.firstName)user.name=user.firstName+" "+user.lastName;else if(user.name&&!user.firstName){let split=user.name.split(" ");user.firstName=split[0];user.lastName=split[split.length-1]}if(props._id)user.id=props._id;else if(props.id)user.id=props.id;else user.id="user"+Math.floor(Math.random()*1e15);user._id=user.id;user.ownerId=user.id;let dummy=DataStructures_exports.ProfileStruct();for(const prop in props){if(Object.keys(dummy).indexOf(prop)<0){delete user[prop]}}if(currentUser)this.currentUser=user;return user}authorizeUser=async(parentUser,authorizerUserId="",authorizerUserName="",authorizedUserId="",authorizedUserName="",authorizations={},structs={},excluded={},groups={},expires=false)=>{if(!parentUser)return void 0;let newAuthorization=this.createStruct("authorization",void 0,parentUser,void 0);newAuthorization.authorizedId=authorizedUserId;newAuthorization.authorizedName=authorizedUserName;newAuthorization.authorizerId=authorizerUserId;newAuthorization.authorizerName=authorizerUserName;newAuthorization.authorizations=authorizations;newAuthorization.structs=structs;newAuthorization.excluded=excluded;newAuthorization.groups=groups;newAuthorization.expires=expires;newAuthorization.status="PENDING";newAuthorization.associatedAuthId="";newAuthorization=await this.setAuthorization(newAuthorization);return newAuthorization};addGroup=async(parentUser,name="",details="",admins={},peers={},clients={},updateServer=true)=>{if(!parentUser)return void 0;let newGroup=this.createStruct("group",void 0,parentUser);newGroup.name=name;newGroup.details=details;newGroup.admins=admins;newGroup.peers=peers;newGroup.clients=clients;newGroup.users={};Object.assign(newGroup.users,newGroup.admins);Object.assign(newGroup.users,newGroup.peers);Object.assign(newGroup.users,newGroup.clients);if(updateServer){newGroup=await this.setGroup(newGroup)}return newGroup};dataObject(data=void 0,type="any",timestamp=Date.now()){return{type,data,timestamp}}addData=async(parentUser,author="",title="",type="",data=[],expires=false,updateServer=true)=>{if(!parentUser)return void 0;let newDataInstance=this.createStruct("dataInstance",void 0,parentUser);newDataInstance.author=author;newDataInstance.title=title;newDataInstance.type=type;newDataInstance.data=data;newDataInstance.expires=expires;if(updateServer)newDataInstance=await this.updateServerData([newDataInstance])[0];return newDataInstance};addEvent=async(parentUser,author="",event="",notes="",startTime=void 0,endTime=void 0,grade=void 0,value=void 0,units=void 0,location=void 0,attachments=void 0,users=void 0,updateServer=true)=>{if(!parentUser)return void 0;if(users&&Object.keys(users).length===0)users=this.getLocalUserPeerIds(parentUser);let newEvent=this.createStruct("event",void 0,parentUser);newEvent.author=author;newEvent.event=event;newEvent.notes=notes;newEvent.startTime=startTime;newEvent.endTime=endTime;newEvent.grade=grade;newEvent.attachments=attachments;newEvent.value=value;newEvent.units=units;newEvent.users=users;newEvent.location=location;if(updateServer)newEvent=await this.updateServerData([newEvent])[0];return newEvent};addChatroom=async(parentUser,authorId="",message="",attachments=void 0,users=void 0,updateServer=true)=>{if(!parentUser)return void 0;if(users&&Object.keys(users).length===0)users=this.getLocalUserPeerIds(parentUser);let newChatroom=this.createStruct("chatroom",void 0,parentUser);newChatroom.message=message;newChatroom.attachments=attachments;newChatroom.authorId=authorId;newChatroom.users=users;newChatroom.replies=[];newChatroom.comments=[];let update=[newChatroom];if(updateServer)newChatroom=await this.updateServerData(update)[0];return newChatroom};addComment=async(parentUser,roomStruct,replyTo,authorId="",message="",attachments=void 0,updateServer=true)=>{if(!roomStruct)return void 0;if(!replyTo)replyTo=roomStruct;if(!parentUser)return void 0;let newComment=this.createStruct("comment",void 0,parentUser,roomStruct);newComment.authorId=authorId;newComment.replyTo=replyTo?._id;newComment.message=message;newComment.attachments=attachments;newComment.users=roomStruct?.users;newComment.replies=[];if(!updateServer)replyTo?.replies.push(newComment._id);if(!updateServer)roomStruct?.comments.push(newComment._id);let update=[newComment,roomStruct];if(replyTo?._id!==roomStruct._id)update.push(replyTo);let res;if(updateServer)res=await this.updateServerData(update);let updatedComment;if(typeof res==="object"){updatedComment=res.find(s=>{if(newComment.ownerId===s.ownerId&&newComment.timestamp===s.timestamp&&newComment.message===s.message){return true}})}if(updatedComment)return updatedComment;return res}};var import_bson=__toESM(require_bson());var randomId2=prefix=>(prefix?`${prefix}_`:"")+Math.floor(1e15*Math.random());var toObjectId=str2=>{return typeof str2==="string"&&str2.length===24?new import_bson.ObjectId(str2):str2};var getStringId=mongoid=>{if(typeof mongoid==="object")return mongoid.toString();else return mongoid};var defaultCollections=["profile","group","authorization","discussion","chatroom","comment","dataInstance","event","notification","schedule","date"];var StructBackend=class extends Service{name="structs";debug=false;db;users={};collections={};mode="local";useAuths=true;useAccessTokens=false;useRefreshTokens=false;accessTokens=new Map;refreshTokens=new Map;constructor(options,dboptions){super(options);this.load(this);if(dboptions){this.initDB(dboptions)}}initDB=dboptions=>{this.db=dboptions.db;if(dboptions?.users)this.users=dboptions.users;if(dboptions.mode)this.mode=dboptions.mode;if(dboptions?.collections)this.collections=dboptions.collections;if(dboptions.debug)this.debug=dboptions.debug;if(dboptions.useAccessTokens)this.useAccessTokens=dboptions.useAccessTokens;if(dboptions.useRefreshTokens)this.useRefreshTokens=dboptions.useRefreshTokens;if("useAuths"in dboptions)this.useAuths=dboptions.useAuths;defaultCollections.forEach(k=>{if(!this.collections[k]){this.collections[k]=this.db?{instance:this.db.collection(k)}:{};this.collections[k].reference={}}})};query=async(requestingUserId,collection,queryObj,findOne,skip,token)=>{let user=this.users[requestingUserId];if(!user)return false;if(this.mode.indexOf("mongo")>-1){return await this.queryMongo(user,collection,queryObj,findOne,skip,token)}else{let res=this.getLocalData(user,collection);if(res&&!Array.isArray(res)){let passed=!this.useAuths;if(!res?.ownerId)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,res,"READ",token);if(passed)return res}if(typeof skip==="number"&&Array.isArray(res)){if(res.length>skip)res.splice(0,skip)}let data=[];if(res)await Promise.all(res.map(async s=>{let struct=this.getLocalData(getStringId(s._id));let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);if(passed)data.push(struct)}));return data}};getUser=async(requestingUserId,lookupId,basicInfo,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.indexOf("mongo")>-1){data=await this.getMongoUser(user,lookupId,void 0,basicInfo,token)}else{let struct=this.getLocalData("profile",{_id:lookupId});if(!struct)data={user:void 0};else{let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);if(passed){let groups=this.getLocalData("group",{ownerId:lookupId});let auths=this.getLocalData("authorization",{ownerId:lookupId});data={user:struct,groups,authorizations:auths}}else data={user:{}}}}if(this.debug)console.log("getUser: user:",user,"input:",lookupId,"output",data);return data};setUser=async(requestingUserId,struct,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(struct.accessToken){this.accessTokens.set(requestingUserId,token)}if(struct.refreshToken){this.refreshTokens.set(requestingUserId,struct.refreshToken)}delete struct.accessToken;delete struct.refreshToken;delete user.accessToken;delete user.refreshToken;if(this.mode.indexOf("mongo")>-1){data=await this.setMongoUser(user,struct,token)}else{let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(passed)this.setLocalData(struct);return true}if(this.debug)console.log("setUser user:",user,"input:",struct,"output",data);return data};getUsersByIds=async(requestingUserId,userIds,basicInfo)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getMongoUsersByIds(user,userIds,basicInfo)}else{data=[];if(Array.isArray(userIds)){let struct=this.getLocalData("profile",{_id:userIds});if(struct){if(basicInfo)data.push({_id:struct._id,username:struct.username,firstName:struct.firstName,lastName:struct.lastName,fullName:struct.fullName,pictureUrl:struct.pictureUrl});else data.push(struct)}}}if(this.debug)console.log("getUserByIds: user:",user,"input:",userIds,"output",data);return data};getUsersByRole=async(requestingUserId,role)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getMongoUsersByRole(user,role)}else{let profiles=this.getLocalData("profile");data=[];profiles.forEach(struct=>{if(struct.userRoles[role]){data.push(struct)}})}if(this.debug)console.log("getUserByRoles: user:",user,"input:",role,"output",data);return data};deleteUser=async(requestingUserId,userId,deleteData,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.deleteMongoUser(user,userId,deleteData,token)}else{data=false;let struct=this.getLocalData(userId);if(struct){let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(passed)data=this.deleteLocalData(struct)}}if(this.debug)console.log("deleteUser: user:",user,"input:",userId,"output",data);return data};setData=async(requestingUserId,structs,notify,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.setMongoData(user,structs,notify,token)}else{let non_notes=[];data=[];await Promise.all(structs.map(async structId=>{let struct=this.getLocalData(structId);let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(passed){if(!this.collections[struct.structType]){this.collections[struct.structType]={};this.collections[struct.structType].reference={}}this.setLocalData(struct);data.push(struct);if(struct.structType!=="notification")non_notes.push(struct)}}));if(non_notes.length>0&&(notify===true||typeof notify==="undefined"))this.checkToNotify(user,non_notes,this.mode);if(this.debug)console.log("setData:",user,structs,data);return true}if(this.debug)console.log("setData: user:",user,"input:",structs,notify,"output",data);return data};getData=async(requestingUserId,collection,ownerId,dict,limit,skip,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getMongoData(user,collection,ownerId,dict,limit,skip,token)}else{data=[];let structs;if(collection)structs=this.getLocalData(collection);if(structs&&ownerId)structs=structs.filter(o=>{if(o.ownerId===ownerId)return true});if(structs)await Promise.all(structs.map(async s=>{let struct=this.getLocalData(getStringId(s._id));let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);if(passed)data.push(struct)}))}if(this.debug)console.log("getData: user:",user,"input:",collection,ownerId,dict,limit,skip,"output",data);return data};getDataByIds=async(requestingUserId,structIds,ownerId,collection,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getMongoDataByIds(user,structIds,ownerId,collection,token)}else{data=[];let structs;if(collection)structs=this.getLocalData(collection);if(structs&&ownerId)structs=structs.filter(o=>{if(o.ownerId===ownerId)return true});if(structs)await Promise.all(structs.map(async s=>{let struct=this.getLocalData(getStringId(s._id));let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);if(passed)data.push(struct)}))}if(this.debug)console.log("getDataByIds: user:",user,"input:",structIds,ownerId,collection,"output",data);return data};getAllData=async(requestingUserId,ownerId,excludedCollections,timeRange,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getAllUserMongoData(user,ownerId,excludedCollections,timeRange,token)}else{let result=this.getLocalData(void 0,{ownerId});data=[];await Promise.all(result.map(async struct=>{if(excludedCollections){if(excludedCollections.indexOf(struct.structType)<0){let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);if(passed)data.push(struct)}}else{let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);if(passed)data.push(struct)}}))}if(this.debug)console.log("getAllData: user:",user,"input:",ownerId,excludedCollections,"output",data);return data};deleteData=async(requestingUserId,structIds,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.deleteMongoData(user,structIds,token)}else{data=false;await Promise.all(structIds.map(async structId=>{let struct=this.getLocalData(structId);let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(passed)this.deleteLocalData(struct);data=true}))}if(this.debug)console.log("deleteData: user:",user,"input:",structIds,"output",data);return data};getUserGroups=async(requestingUserId,userId,groupId)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getMongoGroups(user,userId,groupId)}else{if(typeof groupId==="string"){data=this.getLocalData("group",{_id:groupId})}else{data=[];let result=this.getLocalData("group");if(userId){result.forEach(struct=>{if(Object.keys(struct.users).includes(userId))data.push(struct)})}else{result.forEach(struct=>{if(Object.keys(struct.users).includes(getStringId(user._id)))data.push(struct)})}}}if(this.debug)console.log("getGroups: user:",user,"input:",userId,groupId,"output",data);return data};deleteGroup=async(requestingUserId,groupId,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.deleteMongoGroup(user,groupId,token)}else{let struct=this.getLocalData("group",groupId);let passed=!this.useAuths;if(struct){if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token)}if(passed){data=true}}if(this.debug)console.log("deleteGroup: user:",user,"input:",groupId,"output",data);return data};getAuthorizations=async(requestingUserId,ownerId,authId,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getMongoAuthorizations(user,ownerId,authId,token)}else{if(authId){let result=this.getLocalData("authorization",{_id:authId});if(result)data=[result]}else{data=this.getLocalData("authorization",{ownerId})}}if(this.debug)console.log("getAuthorizations: user:",user,"input:",ownerId,authId,"output",data);return data};deleteAuthorization=async(requestingUserId,authId,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.deleteMongoAuthorization(user,authId,token)}else{data=true;let struct=this.getLocalData("authorization",{_id:authId});if(struct){let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(passed)data=this.deleteLocalData(struct)}}if(this.debug)console.log("deleteAuthorization: user:",user,"input:",authId,"output",data);return data};getToken=user=>{return this.useAccessTokens?this.accessTokens.get(user._id):this.useRefreshTokens?this.refreshTokens.get(user._id):void 0};notificationStruct=(parentStruct={})=>{let structType="notification";let struct={structType,timestamp:Date.now(),_id:randomId2(structType),note:"",alert:false,ownerId:"",parentUserId:"",parent:{structType:parentStruct?.structType,_id:getStringId(parentStruct?._id)}};return struct};checkToNotify=async(user,structs=[],mode=this.mode)=>{if(structs.length===0)return false;if(typeof user==="string"){for(let key in this.users){const obj=this.users[key];if(getStringId(obj._id)===user)user=obj}}if(typeof user==="string"||user==null)return false;let usersToNotify={};let newNotifications=[];structs.forEach(async struct=>{if(struct?._id){if(struct.ownerId&&user?._id!==struct.ownerId){let newNotification=this.notificationStruct(struct);newNotification._id="notification_"+getStringId(struct._id)+"_"+struct.ownerId;newNotification.ownerId=struct.ownerId;newNotification.note=struct.structType;newNotification.parentUserId=struct.ownerId;if(struct.alert)newNotification.alert=struct.alert;newNotifications.push(newNotification);usersToNotify[struct.ownerId]=struct.ownerId}if(struct.users){Object.keys(struct.users).forEach(usr=>{if(usr!==user._id){let newNotification=this.notificationStruct(struct);newNotification._id="notification_"+getStringId(struct._id)+"_"+usr;newNotification.ownerId=usr;newNotification.note=struct.structType;if(struct.alert)newNotification.alert=struct.alert;newNotification.parentUserId=struct.ownerId;newNotifications.push(newNotification);usersToNotify[usr]=usr}})}else{let auths=[];if(mode.includes("mongo")){let s=this.collections.authorization.instance.find({$or:[{authorizedId:user._id},{authorizerId:user._id}]});let arr=await s.toArray();if(arr.length>0){arr.forEach(d2=>auths.push(d2))}}else{auths=this.getLocalData("authorization",{authorizedId:user._id});auths.push(...this.getLocalData("authorization",{authorizerId:user._id}))}if(auths.length>0){auths.forEach(auth=>{if(struct.authorizerId===struct.ownerId&&!usersToNotify[struct.authorizedId]){if(auth.status==="OKAY"&&auth.authorizations["peer"]){let newNotification=this.notificationStruct(struct);newNotification.ownerId=auth.authorizedId;newNotification._id="notification_"+getStringId(struct._id)+"_"+auth.authorizedId;newNotification.note=struct.structType;newNotification.parentUserId=struct.ownerId;if(struct.alert)newNotification.alert=struct.alert;newNotifications.push(newNotification);usersToNotify[newNotification.ownerId]=newNotification.ownerId}}})}}}});if(newNotifications.length>0){if(mode.includes("mongo")){await this.setMongoData(user,newNotifications,true,this.getToken(user))}else{this.setLocalData(newNotifications)}for(const uid in usersToNotify){this.users[uid]?.sendAll({route:"structNotification",args:true})}return true}else return false};queryMongo=async(user,collection,queryObj={},findOne=false,skip=0,token)=>{if(!collection&&!queryObj)return void 0;else if(findOne){let res=await this.db.collection(collection).findOne(queryObj);if(!res)return void 0;let passed=!this.useAuths;if(!res?.ownerId){passed=true}else if(getStringId(user._id)!==res.ownerId||getStringId(user._id)===res.ownerId&&user.userRoles?.admincontrol){if(this.useAuths)passed=await this.checkAuthorization(user,res,"READ",token)}if(passed)return res;else return void 0}else{let res=this.db.collection(collection).find(queryObj).sort({$natural:-1}).skip(skip);let structs=[];let arr=await res.toArray();if(arr.length>0){let passed=!this.useAuths;let checkedAuth="";for(const s of arr){if(!s?.ownerId){passed=true}else if((getStringId(user._id)!==s.ownerId||getStringId(user._id)===s.ownerId&&user.userRoles?.admincontrol)&&checkedAuth!==s.ownerId){if(this.useAuths)passed=await this.checkAuthorization(user,s,"READ",token);checkedAuth=s.ownerId}if(passed)structs.push(s)}}return structs}};setMongoData=async(user,structs=[],notify=true,token)=>{let firstwrite=false;if(structs.length>0){let passed=!this.useAuths;let checkedAuth="";await Promise.all(structs.map(async struct=>{let secondary={};if(Array.isArray(struct)){secondary=struct[1];struct=struct[0]}if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if((getStringId(user._id)!==struct.ownerId||getStringId(user._id)===struct.ownerId&&user.userRoles?.admincontrol)&&checkedAuth!==struct.ownerId){if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);checkedAuth=struct.ownerId}if(passed){if(struct.structType){if(!this.collections[struct.structType]){this.collections[struct.structType]={};this.collections[struct.structType].reference={}}let copy=JSON.parse(JSON.stringify(struct));if(copy._id)delete copy._id;if(struct._id){if(getStringId(struct._id).includes("defaultId")){await this.db.collection(struct.structType?struct.structType:"data").insertOne(copy);firstwrite=true}else if(struct.structType==="notification")await this.db.collection(struct.structType?struct.structType:"data").updateOne({_id:struct._id},{$set:copy,...secondary},{upsert:true,unique:false});else await this.db.collection(struct.structType?struct.structType:"data").updateOne({_id:toObjectId(struct._id)},{$set:copy,...secondary},{upsert:true})}else if(struct.structType){this.db.collection(struct.structType?struct.structType:"data").insertOne(copy)}}}}));if(firstwrite===true){let toReturn=[];await Promise.all(structs.map(async(struct,j)=>{let copy=JSON.parse(JSON.stringify(struct));if(copy._id&©.structType!=="profile")delete copy._id;if(struct.structType!=="comment"){let pulled;if(struct.structType!=="notification")pulled=await this.db.collection(copy.structType).findOne(copy);if(pulled){pulled._id=getStringId(pulled._id);toReturn.push(pulled)}}else if(struct.structType==="comment"){let comment=struct;let copy2=JSON.parse(JSON.stringify(comment));if(copy2._id)delete copy2._id;let pulledComment=await this.db.collection("comment").findOne(copy2);let replyToId=pulledComment?.replyTo;let replyTo=structs.find(s=>{if(getStringId(s._id)===replyToId)return true});if(replyTo){let copy3=JSON.parse(JSON.stringify(replyTo));if(copy3._id)delete copy3._id;let pulledReply;await Promise.all(["discussion","chatroom","comment"].map(async name=>{let found=await this.db.collection(name).findOne({_id:toObjectId(replyToId)});if(found)pulledReply=found}));if(pulledReply){let roomId=getStringId(pulledComment.parent._id);let room,pulledRoom;if(roomId!==replyToId){room=structs.find(s=>{if(getStringId(s._id)===roomId)return true});if(room){delete room._id;await Promise.all(["discussion","chatroom"].map(async name=>{let found=await this.db.collection(name).findOne(room);if(found)pulledRoom=found}))}}else pulledRoom=pulledReply;let toUpdate=[pulledComment];if(pulledReply){let i=pulledReply.replies.indexOf(getStringId(pulledComment._id));if(i<0){pulledReply.replies.push(getStringId(pulledComment._id));pulledComment.replyTo=getStringId(pulledReply._id)}toUpdate.push(pulledReply)}if(pulledRoom){let i=pulledRoom.comments.indexOf(pulledComment._id);if(i<0){pulledRoom.comments.push(getStringId(pulledComment._id));pulledComment.parent._id=getStringId(pulledRoom._id)}}await Promise.all(toUpdate.map(async s=>{let copy4=JSON.parse(JSON.stringify(s));delete copy4._id;await this.db.collection(s.structType).updateOne({_id:toObjectId(s._id)},{$set:copy4},{upsert:false})}));[...toReturn].reverse().forEach((s,j2)=>{if(toUpdate.find(o=>{if(getStringId(s._id)===getStringId(o._id))return true})){toReturn.splice(toReturn.length-j2-1,1)}});toReturn.push(...toUpdate)}}else if(pulledComment){toReturn.push(pulledComment)}}}));if(notify)this.checkToNotify(user,toReturn);return toReturn}else{let non_notes=[];structs.forEach(s=>{if(s.structType!=="notification")non_notes.push(s)});if(notify)this.checkToNotify(user,non_notes);return true}}else return false};setMongoUser=async(user,struct,token)=>{if(struct._id){const _id=toObjectId(struct._id);let usersearch={_id};let userexists=await this.collections.profile.instance.findOne(usersearch);if(userexists){if(getStringId(user._id)!==struct.ownerId||getStringId(user._id)===struct.ownerId&&user.userRoles?.admincontrol){let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(!passed)return false}}let copy=JSON.parse(JSON.stringify(struct));copy._id=_id;if(this.debug)console.log("RETURNS PROFILE",struct);await this.collections.profile.instance.updateOne(usersearch,{$set:copy},{upsert:true});user=await this.collections.profile.instance.findOne(usersearch);this.checkToNotify(user,[struct]);return user}else return false};setGroup=async(user,struct,mode=this.mode,token)=>{if(struct?._id){let uid=getStringId(user._id);let exists=void 0;if(mode.includes("mongo")){exists=await this.collections.group.instance.findOne({name:struct.name})}else{exists=this.getLocalData("group",{_id:getStringId(struct._id)})}if(exists&&(exists.ownerId!==struct.ownerId||struct.admins.indexOf(uid)<0))return false;if(uid!==struct.ownerId){let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(!passed)return false}let allusers=[];Object.keys(struct.users).forEach(u2=>{allusers.push({email:u2},{id:u2},{username:u2})});let users={};let ids={};if(mode.includes("mongo")){let cursor=this.collections.profile.instance.find({$or:allusers});let arr=cursor.toArray();if(arr.length>0){arr.forEach(user2=>{users[uid]=user2;ids[uid]=true})}}else{allusers.forEach(search=>{let result=this.getLocalData("profile",search);if(result.length>0){users[getStringId(result[0]._id)]=result[0];ids[getStringId(result[0]._id)]=true}})}struct.users=ids;let admins={};let peers={};let clients={};Object.keys(users).forEach(id=>{let u2=users[id];if(struct.admins[getStringId(u2._id)]||struct.admins[u2.email]||struct.admins[u2.username]||struct.admins[struct.ownerId]){if(!admins[getStringId(u2._id)])admins[getStringId(u2._id)]=true}if(struct.peers[getStringId(u2._id)]||struct.peers[u2.email]||struct.peers[u2.username]||struct.peers[struct.ownerId]){if(!peers[getStringId(u2._id)])peers[getStringId(u2._id)]=true}if(struct.clients[getStringId(u2._id)]||struct.clients[u2.email]||struct.clients[u2.username]||struct.clients[struct.ownerId]){if(!clients[getStringId(u2._id)])clients[getStringId(u2._id)]=true}});struct.admins=admins;struct.peers=peers;struct.clients=clients;let copy=JSON.parse(JSON.stringify(struct));if(copy._id)delete copy._id;if(mode.includes("mongo")){if(getStringId(struct._id).includes("defaultId")){await this.db.collection(struct.structType?struct.structType:"data").insertOne(copy);delete struct._id;struct=await this.db.collection(struct.structType?struct.structType:"data").findOne(struct);struct._id=getStringId(struct._id)}else await this.collections.group.instance.updateOne({_id:toObjectId(struct._id)},{$set:copy},{upsert:true})}else{this.setLocalData(struct)}this.checkToNotify(user,[struct],this.mode);if(this.debug)console.log("setGroup: user:",user,"output",struct);return struct}else return false};getMongoUser=(user,info="",requireAuth=true,basicInfo=false,token)=>{return new Promise(async resolve=>{const query=[{email:info},{id:info},{username:info}];try{query.push({_id:toObjectId(info)})}catch(e){console.log("error creating ObjectId with ",info)}let u2=await this.collections.profile.instance.findOne({$or:query});if(!u2||u2==null)resolve(void 0);else{u2._id=getStringId(u2._id);if(!u2.ownerId)u2.ownerId=u2._id;if(basicInfo){if(this.useAccessTokens||this.useRefreshTokens){if(this.getToken(user)!==token)resolve(void 0)}let stripped={username:u2.username,firstName:u2.firstName,lastName:u2.lastName,fullName:u2.fullName,pictureUrl:u2.pictureUrl,_id:u2._id};u2=stripped;resolve({user:u2})}else if(requireAuth){if(getStringId(user._id)!==u2._id||getStringId(user._id)===u2._id&&user.userRoles?.admincontrol){let passed=!this.useAuths;if(this.useAuths)passed=await this.checkAuthorization(user,u2,"READ",token);if(!passed)resolve(void 0)}let authorizations=[];let auths=this.collections.authorization.instance.find({ownerId:u2._id});let aarr=await auths.toArray();if(auths.toArray().length>0){aarr.forEach(d2=>authorizations.push(d2))}let gs=this.collections.group.instance.find({users:{$all:[u2._id]}});let arr=await gs.toArray();let groups=[];if(arr.length>0){arr.forEach(d2=>groups.push(d2))}resolve({user:u2,authorizations,groups})}else{if(this.useAccessTokens||this.useRefreshTokens){if(this.getToken(user)!==token)resolve(void 0)}resolve({user:u2})}}})};queryUsers=(user,info="",limit=0,skip=0,requireAuth=false,token)=>{if(typeof user==="string")user=this.users[user];if(!user)return;return new Promise(async resolve=>{let q={$regex:`^${info}`,$options:"i"};const query=[{email:q},{username:q},{firstName:q},{lastName:q},{name:q}];let arr;if(this.mode.includes("mongo")){let users=this.collections.profile.instance.find({$or:query},{projection:shallowqueryDummy}).skip(skip);if(limit>0)users.limit(limit);await users;arr=await users.toArray()}else{arr=[];for(let i=0;i{arr.push({firstName:u2.firstName,lastName:u2.lastName,fullName:u2.fullName,username:u2.username,pictureUrl:u2.pictureUrl})})}else if(dat)arr.push({firstName:dat.firstName,lastName:dat.lastName,fullName:dat.fullName,username:dat.username,pictureUrl:dat.pictureUrl})}}if(requireAuth){let result=[];let strid=getStringId(user._id);for(let i=0;i{let usrs=[];userIds.forEach(u2=>{try{usrs.push({_id:toObjectId(u2)})}catch{}});let found=[];if(usrs.length>0){let users=this.collections.profile.instance.find({$or:usrs});let arr=await users.toArray();if(arr.length>0){arr.forEach(u2=>{if(basicInfo){found.push({username:u2.username,firstName:u2.firstName,lastName:u2.lastName,fullName:u2.fullName,pictureUrl:u2.pictureUrl,_id:u2._id})}else found.push(u2)})}}return found};getMongoUsersByRole=async(user,role)=>{let users=this.collections.profile.instance.find({userRoles:{$all:{[role]:true}}});let found=[];let arr=await users.toArray();if(arr.length>0){arr.forEach(u2=>{found.push(u2)})}return found};getMongoDataByIds=async(user,structIds,ownerId,collection,token)=>{let uid=getStringId(user._id);if(structIds.length>0){let query=[];structIds.forEach(_id=>{let q={_id:toObjectId(_id)};if(ownerId)q.ownerId=ownerId;query.push(q)});let found=[];if(!collection){await Promise.all(Object.keys(this.collections).map(async name=>{let cursor=await this.db.collection(name).find({$or:query});let arr=await cursor.toArray();if(arr.length>0){let passed=true;let checkedAuth="";for(let i=0;i0){let passed=true;let checkedAuth="";arr.forEach(async s=>{if(!s?.ownerId)passed=true;else if((uid!==s.ownerId||uid===s.ownerId&&user.userRoles?.admincontrol)&&checkedAuth!==s.ownerId){if(this.useAuths)passed=await this.checkAuthorization(user,s,"READ",token);checkedAuth=s.ownerId}if(passed)found.push(s)})}}return found}};getMongoData=async(user,collection,ownerId,dict={},limit=0,skip=0,token)=>{if(!ownerId)ownerId=dict?.ownerId;if(!dict)dict={};if(dict._id)dict._id=toObjectId(dict._id);let uid=getStringId(user._id);let structs=[];let passed=true;let checkedAuth="";let cursor;if(!collection&&!ownerId&&!dict)return[];else if(!collection&&ownerId&&Object.keys(dict).length===0)return await this.getAllUserMongoData(user,ownerId);else if((!dict||Object.keys(dict).length===0)&&ownerId&&collection){cursor=this.db.collection(collection).find({ownerId}).sort({$natural:-1}).skip(skip)}else if(collection&&Object.keys(dict).length>0){if(ownerId)dict.ownerId=ownerId;cursor=await this.db.collection(collection).find(dict).sort({$natural:-1}).skip(skip)}if(cursor){if(limit>0)cursor.limit(limit);let arr=await cursor.toArray();if(arr.length>0){for(let i=0;i0&&!ownerId){await Promise.all(Object.keys(this.collections).map(async name=>{cursor=await this.db.collection(name).find(dict).sort({$natural:-1}).skip(skip);;if(cursor){if(limit>0)cursor.limit(limit);let arr=await cursor.toArray();if(arr.length>0){for(let i=0;i{let structs=[];let passed=true;let checkedId="";await Promise.all(Object.keys(this.collections).map(async(name,j)=>{if(passed&&excluded.indexOf(name)<0){let query={ownerId};if(timeRange){if(typeof timeRange[0]==="string")timeRange[0]=genTimestampFromString(timeRange[0]);if(typeof timeRange[1]==="string")timeRange[1]=genTimestampFromString(timeRange[1]);query.timestamp={$gt:timeRange[0],$lt:timeRange[1]}}let cursor=this.db.collection(name).find(query);let arr=await cursor.toArray();let count=arr.length;for(let k=0;k{let structs=[];if(structs.length>0){let checkedAuth="";structRefs.forEach(async ref=>{if(ref.structType&&getStringId(ref._id)){let struct=await this.db.collection(ref.structType).findOne({_id:toObjectId(ref._id)});if(struct){let passed=true;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if((getStringId(user._id)!==struct.ownerId||getStringId(user._id)===struct.ownerId&&user.userRoles?.admincontrol)&&checkedAuth!==struct.ownerId){if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);checkedAuth=struct.ownerId}if(passed===true){structs.push(struct)}}}})}return structs};getMongoAuthorizations=async(user,ownerId=getStringId(user._id),authId="",token)=>{let auths=[];if(authId.length===0){let cursor=this.collections.authorization.instance.find({ownerId});let arr=await cursor.toArray();if(arr.length>0){arr.forEach(a=>{auths.push(a)})}}else auths.push(await this.collections.authorization.instance.findOne({_id:toObjectId(authId),ownerId}));if(!auths[0]?.ownerId)true;else if(getStringId(user._id)!==auths[0]?.ownerId){let passed=!this.useAuths;if(this.useAuths)passed=await this.checkAuthorization(user,auths[0],"READ",token);if(!passed)return void 0}return auths};getMongoGroups=async(user,userId=getStringId(user._id),groupId="")=>{let groups=[];if(groupId.length===0){let cursor=this.collections.group.instance.find({users:{$all:[userId]}});let arr=await cursor.toArray();if(arr.length>0){arr.forEach(a=>{groups.push(a)})}}else{try{groups.push(await this.collections.group.instance.findOne({_id:toObjectId(groupId),users:{$all:[userId]}}))}catch{}}return groups};deleteMongoData=async(user,structRefs=[],token)=>{let structs=[];await Promise.all(structRefs.map(async ref=>{try{let _id=toObjectId(ref._id);let struct=await this.db.collection(ref.structType).findOne({_id});if(struct){structs.push(struct);let notifications=await this.collections.notifications.instance.find({parent:{structType:ref.structType,_id:getStringId(ref._id)}});let count=notifications.toArray().length;for(let i=0;i{let passed=true;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if((struct.ownerId!==getStringId(user._id)||getStringId(user._id)===struct.ownerId&&user.userRoles?.admincontrol)&&struct.ownerId!==checkedOwner){checkedOwner=struct.ownerId;if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token)}if(passed){await this.db.collection(struct.structType?struct.structType:"data").deleteOne({_id:toObjectId(struct._id)});if(struct.users){Object.keys(struct.users).forEach(uid=>{if(uid!==getStringId(user._id)&&uid!==struct.ownerId&&this.users[uid])this.users[uid]?.sendAll({route:"structDeleted",args:{_id:getStringId(struct._id),structType:struct.structType}})})}if(struct.ownerId!==user._id&&this.users[struct.ownerId]){this.users[struct.ownerId]?.sendAll({route:"structDeleted",args:{_id:getStringId(struct._id),structType:struct.structType}})}}}));return true};deleteMongoUser=async(user,userId,deleteData,token)=>{if(getStringId(user._id)!==userId||getStringId(user._id)===userId&&user.userRoles?.admincontrol){let u2=await this.collections.profile.instance.findOne({id:userId});let passed=!this.useAuths;if(!u2?.ownerId)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,u2,"WRITE",token);if(!passed)return false}await this.collections.profile.instance.deleteOne({id:userId});if(deleteData){for(const key in this.collections){this.collections[key].instance.deleteMany({ownerId:userId});this.collections[key].instance.updateMany({users:{[userId]:true}},{$unset:{[`users.${userId}`]:""}})}}if(getStringId(user._id)!==userId&&this.users[userId])this.users[userId]?.sendAll({route:"structDeleted",args:{_id:userId,structType:"profile"}});return true};deleteMongoGroup=async(user,groupId,token)=>{let s=await this.collections.group.instance.findOne({_id:toObjectId(groupId)});if(s){if(!s?.ownerId)true;else if(getStringId(user._id)!==s.ownerId||getStringId(user._id)===s.ownerId&&user.userRoles?.admincontrol){let passed=!this.useAuths;if(this.useAuths)passed=await this.checkAuthorization(user,s,"WRITE",token);if(!passed)return false}if(s.users){Object.keys(s.users).forEach(u2=>{this.users[u2]?.sendAll({route:"structDeleted",args:{_id:getStringId(s._id),structType:s.structType}})})}await this.collections.group.instance.deleteOne({_id:toObjectId(groupId)});return true}else return false};deleteMongoAuthorization=async(user,authId,token)=>{let s=await this.collections.authorization.instance.findOne({_id:toObjectId(authId)});let uid=getStringId(user._id);if(s){if(uid!==s.ownerId||uid===s.ownerId&&user.userRoles?.admincontrol){let passed=!this.useAuths;if(!s?.ownerId)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,s,"WRITE",token);if(!passed)return false}if(s.associatedAuthId){if(this.debug)console.log(s);await this.collections.authorization.instance.deleteOne({_id:toObjectId(s.associatedAuthId)});if(s.authorizerId!==uid)this.users[s.authorizerId]?.sendAll({route:"structDeleted",args:{_id:getStringId(s.associatedAuthId),structType:s.structType}});else if(s.authorizedId!==uid)this.users[s.authorizedId]?.sendAll({route:"structDeleted",args:{_id:getStringId(s.associatedAuthId),structType:s.structType}})}await this.collections.authorization.instance.deleteOne({_id:toObjectId(authId)});if(s.authorizerId===uid)this.users[s.authorizerId]?.sendAll({route:"structDeleted",args:{_id:getStringId(s._id),structType:s.structType}});else if(s.authorizedId===uid)this.users[s.authorizedId]?.sendAll({route:"structDeleted",args:{_id:getStringId(s._id),structType:s.structType}});return true}else return false};setAuthorization=async(user,authStruct,token)=>{let u1,u2;let mmode=this.mode.includes("mongo");if(mmode){u1=(await this.getMongoUser(user,authStruct.authorizedId,false)).user;u2=(await this.getMongoUser(user,authStruct.authorizerId,false)).user}else{u1=this.getLocalData("profile",{"_id":authStruct.authorizedId})?.[0];u2=this.getLocalData("profile",{"_id":authStruct.authorizerId})?.[0]}if(!u1||!u2)return false;if(authStruct.authorizedId!==getStringId(u1._id))authStruct.authorizedId=getStringId(u1._id);if(authStruct.authorizerId!==getStringId(u2._id))authStruct.authorizerId=getStringId(u2._id);if(!authStruct.authorizedName){if(u1.name)authStruct.authorizedName=u1.name;else if(u1.username)authStruct.authorizedName=u1.username;else if(u1.email)authStruct.authorizedName=u1.email}if(!authStruct.authorizerName){if(u1.name)authStruct.authorizedName=u1.name;else if(u2.username)authStruct.authorizerName=u2.username;else if(u2.email)authStruct.authorizerName=u2.email}if(!authStruct?.ownerId)true;else if((getStringId(user._id)!==authStruct.ownerId||getStringId(user._id)===authStruct.ownerId&&user.userRoles?.admincontrol)&&(getStringId(user._id)!==authStruct.authorizedId&&getStringId(user._id)!==authStruct.authorizerId)){let passed=!this.useAuths;if(this.useAuths)passed=await this.checkAuthorization(user,authStruct,"WRITE",token);if(!passed)return false}let auths=[];if(mmode){let s=await this.collections.authorization.instance.find({$and:[{authorizedId:authStruct.authorizedId},{authorizerId:authStruct.authorizerId}]});let arr=await s.toArray();if(arr.length>0){arr.forEach(d2=>auths.push(d2))}}else{let s=this.getLocalData("authorization",{authorizedId:authStruct.authorizedId});if(Array.isArray(s)){s.forEach(d2=>{if(d2.authorizerId===authStruct.authorizerId)auths.push(d2)})}}let otherAuthset;if(Array.isArray(auths)){for(let i=0;i{if(typeof user==="string"){if(this.users[user])user=this.users[user];else user={_id:user}}if(!user||!struct)return false;if(!struct.ownerId)return true;if(typeof user==="object"){if(struct.ownerId===getStringId(user._id)){if(user.userRoles?.["admincontrol"]){}return true}}if(this.useAccessTokens){if(!this.accessTokens.get(user._id)||this.accessTokens.get(user._id)!==token){return false}}else if(this.useRefreshTokens){if(!this.refreshTokens.get(user._id)||this.refreshTokens.get(user._id)!==token){return false}}let auth1,auth2;if(this.mode.includes("mongo")){auth1=await this.collections.authorization.instance.findOne({$or:[{authorizedId:getStringId(user._id),authorizerId:struct.ownerId,ownerId:getStringId(user._id)},{authorizedId:struct.ownerId,authorizerId:getStringId(user._id),ownerId:getStringId(user._id)}]});if(!auth1)return false;auth2=await this.collections.authorization.instance.findOne({$or:[{authorizedId:getStringId(user._id),authorizerId:struct.ownerId,ownerId:getStringId(struct.ownerId)},{authorizedId:struct.ownerId,authorizerId:getStringId(user._id),ownerId:getStringId(struct.ownerId)}]})}else{auth1=this.getLocalData("authorization",{ownerId:getStringId(user._id)}).find(o=>{if(o.authorizedId===getStringId(user._id)&&o.authorizerId===struct.ownerId)return true});auth2=this.getLocalData("authorization",{ownerId:struct.ownerId}).find(o=>{if(o.authorizedId===getStringId(user._id)&&o.authorizerId===struct.ownerId)return true})}if(!auth1||!auth2){return false}let passed=false;if(auth1.status==="OKAY"&&auth2.status==="OKAY"){if(struct.structType==="group"){if(auth1.authorizations[struct.name+"_admin"]&&auth2.authorizations[struct.name+"_admin"])passed=true}else if(auth1.authorizations["peer"]&&auth2.authorizations["peer"])passed=true;else if(auth1.authorizations["admincontrol"]&&auth2.authorizations["admincontrol"])passed=true;else if(auth1.structIds[getStringId(struct._id)]&&auth2.structIds[getStringId(struct._id)])passed=true;else if(auth1.excluded[struct.structType]&&struct.ownerId===getStringId(user._id)&&request==="WRITE")passed=false}return passed};wipeDB=async()=>{await Promise.all(Object.values(this.collections).map(c=>{try{c.instance.remove({})}catch(err){}}));return true};overwriteLocalData=structs=>{if(Array.isArray(structs)){structs.forEach(struct=>{let localdat=this.getLocalData(struct.structType,{"ownerId":struct.ownerId,"_id":getStringId(struct._id)});if(!localdat||localdat?.length===0){this.setLocalData(struct)}else Object.assign(localdat,struct)})}else{let localdat=this.getLocalData(structs.structType,{"ownerId":structs.ownerId,"_id":getStringId(structs._id)});if(!localdat||localdat?.length===0){this.setLocalData(structs)}else Object.assign(localdat,structs)}};setLocalData=structs=>{let setInCollection=s=>{let type=s.structType;let collection=this.collections[type]?.reference;if(!collection){collection={};if(!this.collections[type])this.collections[type]={};this.collections[type].reference=collection}collection[getStringId(s._id)]=s};if(Array.isArray(structs)){structs.forEach(s=>{setInCollection(s)})}else setInCollection(structs)};getLocalData=(collection,query)=>{let ownerId,key,value;if(typeof query==="object"){ownerId=query.ownerId;const keys=Object.keys(query).filter(k=>k!="ownerId");key=keys[0];value=query[key]}else value=query;if(!collection&&!ownerId&&!key&&!value)return[];let result=[];if(!collection&&(ownerId||key)){Object.values(this.collections).forEach(c=>{c=c.reference;if((key==="_id"||key==="id")&&value){let found=c[value];if(found)result.push(found)}else{Object.values(c).forEach(struct=>{if(key&&value){if(struct[key]===value&&struct.ownerId===ownerId){result.push(struct)}}else if(struct.ownerId===ownerId){result.push(struct)}})}});return result}else{let c=this.collections[collection]?.reference;if(!c)return result;if(!key&&!ownerId){Object.values(c).forEach(struct=>{result.push(struct)});return result}if((key==="_id"||key==="id")&&value)return getStringId(c[value]);else{Object.keys(c).forEach(k=>{const struct=c[k];if(key&&value&&!ownerId){if(struct[key]===value)result.push(struct)}else if(ownerId&&!key){if(struct.ownerId===ownerId)result.push(struct)}else if(ownerId&&key&&value){if(struct.ownerId===ownerId&&struct[key]){if(struct[key]===value)result.push(struct)}}})}}return result};deleteLocalData=struct=>{if(!struct)throw new Error("Struct not supplied");if(!struct.structType||!struct._id)return false;if(this.collections[struct.structType])delete this.collections[struct.structType].reference[struct._id];return true}};var shallowqueryDummy=DataStructures_exports.ProfileStruct();for(const key in shallowqueryDummy){if(key==="username"||key==="lastName"||key==="firstName"||key==="name"||key==="_id"||key==="pictureUrl")shallowqueryDummy[key]=1;else delete shallowqueryDummy[key]}var Systems={collision:{setupEntities:function(entities){for(const key in entities){const entity=entities[key];if(entity.components){if(!entity.components[this.__node.tag])continue}this.setupEntity(entity)}return entities},setupEntity:function(entity){if(!("collisionEnabled"in entity))entity.collisionEnabled=true;if(!entity.collisionType)entity.collisionType="sphere";if(!entity.collisionRadius)entity.collisionRadius=1;if(!entity.collisionBoundsScale)entity.collisionBoundsScale={x:1,y:1,z:1};if(!entity.colliding)entity.colliding={};if(!entity.position)entity.position={x:0,y:0,z:0};return entity},__node:{tag:"collision"},__operator:function(entities){let keys=this.entityKeys;for(let i=0;i{if(body1.collisionEnabled===false||body2.collisionEnabled===false)return false;const dist=Systems.collision.distance(body1.position,body2.position);if(dist{if(dist===void 0)dist=Systems.collision.distance(body1.position,body2.position);return dist{let body1minX=(body1.position.x-body1.collisionRadius)*body1.collisionBoundsScale.x;let body1maxX=(body1.position.x+body1.collisionRadius)*body1.collisionBoundsScale.x;let body1minY=(body1.position.y-body1.collisionRadius)*body1.collisionBoundsScale.y;let body1maxY=(body1.position.y+body1.collisionRadius)*body1.collisionBoundsScale.y;let body1minZ=(body1.position.z-body1.collisionRadius)*body1.collisionBoundsScale.z;let body1maxZ=(body1.position.z+body1.collisionRadius)*body1.collisionBoundsScale.z;let body2minX=(body2.position.x-body2.collisionRadius)*body1.collisionBoundsScale.x;let body2maxX=(body2.position.x+body2.collisionRadius)*body1.collisionBoundsScale.x;let body2minY=(body2.position.y-body2.collisionRadius)*body1.collisionBoundsScale.y;let body2maxY=(body2.position.y+body2.collisionRadius)*body1.collisionBoundsScale.y;let body2minZ=(body2.position.z-body2.collisionRadius)*body1.collisionBoundsScale.z;let body2maxZ=(body2.position.z+body2.collisionRadius)*body1.collisionBoundsScale.z;return(body1maxX<=body2maxX&&body1maxX>=body2minX||body1minX<=body2maxX&&body1minX>=body2minX)&&(body1maxY<=body2maxY&&body1maxY>=body2minY||body1minY<=body2maxY&&body1minY>=body2minY)&&(body1maxZ<=body2maxZ&&body1maxZ>=body2minZ||body1minZ<=body2maxZ&&body1minZ>=body2minZ)},sphereBoxCollisionCheck:(sphere,box,dist)=>{let boxMinX=(box.position.x-box.collisionRadius)*box.collisionBoundsScale.x;let boxMaxX=(box.position.x+box.collisionRadius)*box.collisionBoundsScale.x;let boxMinY=(box.position.y-box.collisionRadius)*box.collisionBoundsScale.y;let boxMaxY=(box.position.y+box.collisionRadius)*box.collisionBoundsScale.y;let boxMinZ=(box.position.z-box.collisionRadius)*box.collisionBoundsScale.z;let boxMaxZ=(box.position.z+box.collisionRadius)*box.collisionBoundsScale.z;let clamp={x:Math.max(boxMinX,Math.min(sphere.position.x,boxMaxX)),y:Math.max(boxMinY,Math.min(sphere.position.y,boxMaxY)),z:Math.max(boxMinZ,Math.min(sphere.position.z,boxMaxZ))};if(dist===void 0)dist=Systems.collision.distance(sphere.position,clamp);return dist>sphere.collisionRadius},isPointInsideSphere:(point,sphere,dist)=>{if(dist===void 0)dist=Systems.collision.distance(point,sphere.position);return dist{let boxminX=(box.position.x-box.collisionRadius)*box.collisionBoundsScale.x;let boxmaxX=(box.position.x+box.collisionRadius)*box.collisionBoundsScale.x;let boxminY=(box.position.y-box.collisionRadius)*box.collisionBoundsScale.x;let boxmaxY=(box.position.y+box.collisionRadius)*box.collisionBoundsScale.x;let boxminZ=(box.position.z-box.collisionRadius)*box.collisionBoundsScale.x;let boxmaxZ=(box.position.z+box.collisionRadius)*box.collisionBoundsScale.x;return point.x>=boxminX&&point.x<=boxmaxX&&(point.y>=boxminY&&point.y<=boxmaxY)&&(point.z>=boxminZ&&point.z<=boxmaxZ)},closestPointOnLine:(point,lineStart,lineEnd)=>{let a={x:lineEnd.x-lineStart.x,y:lineEnd.y-lineStart.y,z:lineEnd.z-lineStart.z};let b={x:lineStart.x-point.x,y:lineStart.y-point.y,z:lineStart.z-point.z};let c={x:lineEnd.x-point.x,y:lineEnd.y-point.y,z:lineEnd.z-point.z};let bdota=Systems.collision.dot(b,a);if(bdota<=0)return lineStart;let cdota=Systems.collision.dot(c,a);if(cdota<=0)return lineEnd;let _bdotapluscdota=1/(bdota+cdota);return{x:lineStart.x+(lineEnd.x-lineStart.x)*bdota*_bdotapluscdota,y:lineStart.y+(lineEnd.y-lineStart.y)*bdota*_bdotapluscdota,z:lineStart.z+(lineEnd.z-lineStart.z)*bdota*_bdotapluscdota}},closestPointOnPolygon:(point,t0,t1,t2)=>{let n=Systems.collision.calcNormal(t0,t1,t2);let dist=Systems.collision.dot(point,n)-Systems.collision.dot(t0,n);let projection=Systems.collision.vecadd(point,Systems.collision.vecscale(n,-dist));let v0x=t2[0]-t0[0];let v0y=t2[1]-t0[1];let v0z=t2[2]-t0[2];let v1x=t1[0]-t0[0];let v1y=t1[1]-t0[1];let v1z=t1[2]-t0[2];let v2x=projection[0]-t0[0];let v2y=projection[1]-t0[1];let v2z=projection[2]-t0[2];let dot00=v0x*v0x+v0y*v0y+v0z*v0z;let dot01=v0x*v1x+v0y*v1y+v0z*v1z;let dot02=v0x*v2x+v0y*v2y+v0z*v2z;let dot11=v1x*v1x+v1y*v1y+v1z*v1z;let dot12=v1x*v2x+v1y*v2y+v1z*v2z;let denom=dot00*dot11-dot01*dot01;if(Math.abs(denom)<1e-30){return void 0}let _denom=1/denom;let u2=(dot11*dot02-dot01*dot12)*_denom;let v2=(dot00*dot12-dot01*dot02)*_denom;if(u2>=0&&v2>=0&&u2+v2<1){return projection}else return void 0},calcNormal:(t0,t1,t2,positive=true)=>{var QR=Systems.collision.makeVec(t0,t1);var QS=Systems.collision.makeVec(t0,t2);if(positive===true){return Systems.collision.normalize(Systems.collision.cross3D(QR,QS))}else{return Systems.collision.normalize(Systems.collision.cross3D(QS,QR))}},dot:(v1,v2)=>{let dot=0;for(const key in v1){dot+=v1[key]*v2[key]}return dot},makeVec(p1,p2){return{x:p2.x-p1.x,y:p2.y-p1.y,z:p2.z-p1.z}},vecadd:(v1,v2)=>{let result=Object.assign({},v1);for(const key in result){result[key]+=v2[key]}return result},vecsub:(v1,v2)=>{let result=Object.assign({},v1);for(const key in result){result[key]-=v2[key]}return result},vecmul:(v1,v2)=>{let result=Object.assign({},v1);for(const key in result){result[key]*=v2[key]}return result},vecdiv:(v1,v2)=>{let result=Object.assign({},v1);for(const key in result){result[key]/=v2[key]}return result},vecscale:(v1,scalar)=>{let result=Object.assign({},v1);for(const key in result){result[key]*=scalar}return result},distance:(v1,v2)=>{let distance=0;for(const key in v1){distance+=Math.pow(v1[key]-v2[key],2)}return Math.sqrt(distance)},magnitude:v2=>{let magnitude=0;for(const key in v2){magnitude+=v2[key]*v2[key]}return Math.sqrt(magnitude)},normalize:v2=>{let magnitude=Systems.collision.magnitude(v2);let _mag=magnitude?1/magnitude:0;let vn={};for(const key in v2){vn[key]=v2[key]*_mag}return vn},distance3D(v1,v2){return Math.sqrt((v1.x-v2.x)*(v1.x-v2.x)+(v1.y-v2.y)*(v1.y-v2.y)+(v1.z-v2.z)*(v1.z-v2.z))},cross3D(v1,v2){return{x:v1.y*v2.z-v1.z*v2.y,y:v1.z*v2.x-v1.x*v2.z,z:v1.x*v2.y-v1.y*v2.x}},nearestNeighborSearch(entities,isWithinRadius=1e15){var tree={};;for(const key in entities){let newnode={tag:key,position:void 0,neighbors:[]};newnode.position=entities[key].position;tree[key]=newnode}for(const i in tree){for(const j in tree){var dist=Systems.collision.distance3D(tree[i].position,tree[j].position);if(distxx)minX=xx;if(maxYyy)minY=yy;if(maxZzz)minZ=zz;if(minRadius>body.collisionRadius)minRadius=body.collisionRadius;positions[key]=body.position};let head=JSON.parse(JSON.stringify(dynamicBoundingVolumeTree.proto));let boxpos={x:(maxX+minX)*.5,y:(maxY+minY)*.5,z:(maxZ+minZ)*.5};let boxbounds={x:maxX-boxpos.x,y:maxY-boxpos.y,z:maxZ-boxpos.z};head.position=boxpos;head.collisionBoundsScale=boxbounds;head.entities=entities;dynamicBoundingVolumeTree.tree=head;minRadius*=2;if(mode==="octree"){let genOct=function(parentPos,halfbounds){let oct1={x:parentPos.x+halfbounds.x,y:parentPos.y+halfbounds.y,z:parentPos.z+halfbounds.z};let oct2={x:parentPos.x-halfbounds.x,y:parentPos.y+halfbounds.y,z:parentPos.z+halfbounds.z};let oct3={x:parentPos.x+halfbounds.x,y:parentPos.y-halfbounds.y,z:parentPos.z+halfbounds.z};let oct4={x:parentPos.x+halfbounds.x,y:parentPos.y+halfbounds.y,z:parentPos.z-halfbounds.z};let oct5={x:parentPos.x-halfbounds.x,y:parentPos.y-halfbounds.y,z:parentPos.z+halfbounds.z};let oct6={x:parentPos.x-halfbounds.x,y:parentPos.y+halfbounds.y,z:parentPos.z-halfbounds.z};let oct7={x:parentPos.x+halfbounds.x,y:parentPos.y-halfbounds.y,z:parentPos.z-halfbounds.z};let oct8={x:parentPos.x-halfbounds.x,y:parentPos.y-halfbounds.y,z:parentPos.z-halfbounds.z};return[oct1,oct2,oct3,oct4,oct5,oct6,oct7,oct8]},genOctTree=function(head2){let halfbounds={x:head2.collisionBoundsScale.x*.5,y:head2.collisionBoundsScale.y*.5,z:head2.collisionBoundsScale.z*.5};let octPos=genOct(head2.position,halfbounds);let check=Object.assign({},head2.bodies);for(let i=0;i<8;i++){let octquadrant=Object.assign(JSON.parse(JSON.stringify(dynamicBoundingVolumeTree.proto)),{position:octPos[i],collisionBoundsScale:halfbounds});octquadrant.parent=head2;for(const j in check){let collided=Systems.collision.collisionCheck(check[j],octquadrant);if(collided){octquadrant.entities[j]=check[j];delete check[j]}}if(Object.keys(octquadrant.entities).length>minEntities-1){head2.children[i]=octquadrant;octquadrant.parent=head2;if(Object.keys(octquadrant.entities).length>minEntities&&octquadrant.collisionRadius*.5>minRadius){genOctTree(octquadrant)}}}};genOctTree(head);return head}else{let tree=Systems.collision.nearestNeighborSearch(positions,withinRadius);let keys=Object.keys(tree);let tag=keys[Math.floor(Math.random()*keys.length)];let searching=true;let count=0;let genBoundingBoxLevel=(tree2,volumes)=>{let newVolumes={};let foundidxs={};let treekeys=Object.keys(tree2);while(searching&&countuxn)ux=uxn;if(mxuyn)uy=uyn;if(myuzn)uz=uzn;if(mz2){let nextTree=Systems.collision.nearestNeighborSearch(result,withinRadius);result=genBoundingBoxLevel(nextTree,result)}head.children=result;head.children.forEach(n=>{n.parent=head});return head}}},collider:{lastTime:performance.now(),setupEntities:function(entities){for(const key in entities){const entity=entities[key];if(entity.components){if(!entity.components[this.__node.tag])continue}this.setupEntity(entity)}return entities},setupEntity:function(entity){if(!("collisionEnabled"in entity))Systems.collision.setupEntity(entity);if(!("boundingBox"in entity))entity.boundingBox={bot:0,top:100,left:0,right:100,front:0,back:100};if(!("position"in entity)){Systems.movement.setupEntity(entity)}if(!("restitution"in entity))entity.restitution=1;if(!("useBoundingBox"in entity))entity.useBoundingBox=true;if(!entity.position.x&&!entity.position.y&&!entity.position.z){entity.position.x=Math.random()*entity.boundingBox.right;entity.position.y=Math.random()*entity.boundingBox.back;entity.position.z=Math.random()*entity.boundingBox.top}return entity},__operator:function(entities){let keys=this.entityKeys;for(let i=0;i{const xsize=entity.collisionRadius*entity.collisionBoundsScale.x;const ysize=entity.collisionRadius*entity.collisionBoundsScale.y;const zsize=entity.collisionRadius*entity.collisionBoundsScale.z;if(entity.position.y-ysize<=entity.boundingBox.front){entity.velocity.y*=-entity.restitution;entity.position.y=entity.boundingBox.front+ysize}if(entity.position.y+ysize>=entity.boundingBox.back){entity.velocity.y*=-entity.restitution;entity.position.y=entity.boundingBox.back-ysize}if(entity.position.x-xsize<=entity.boundingBox.left){entity.velocity.x*=-entity.restitution;entity.position.x=entity.boundingBox.left+xsize}if(entity.position.x+xsize>=entity.boundingBox.right){entity.velocity.x*=-entity.restitution;entity.position.x=entity.boundingBox.right-xsize}if(entity.position.z-zsize<=entity.boundingBox.bot){entity.velocity.z*=-entity.restitution;entity.position.z=entity.boundingBox.bot+zsize}if(entity.position.z+zsize>=entity.boundingBox.top){entity.velocity.z*=-entity.restitution;entity.position.z=entity.boundingBox.top-zsize}},resolveBoxCollision:(body1,box,negate)=>{let positionVec=Systems.collision.makeVec(body1.position,box.position);var directionVec=Object.values(positionVec);let closestSide;let closestDist=Infinity;let mul=-1;if(directionVec[idx]<0)mul=1;if(negate)mul=-mul;for(const key in body1.position){let dist=Math.abs(box.position[key]-body1.position[key]);if(dist{if(dist===void 0)dist=Systems.collision.distance(entity1.position,entity2.position);let vecn=Systems.collision.normalize(Systems.collision.makeVec(entity1.position,entity2.position));let sumMass=entity1.mass+entity2.mass;let ratio=entity1.mass/sumMass;let rmin=1-ratio;if(entity1.fixed===false){entity1.position.x+=vecn.x*rmin*1.01;entity1.position.y+=vecn.y*rmin*1.01;entity1.position.z+=vecn.z*rmin*1.001}else{entity2.position.x-=vecn.x*1.01;entity2.position.y-=vecn.y*1.01;entity2.position.z-=vecn.z*1.01}if(entity2.fixed===false){entity2.position.x+=vecn.x*ratio*1.01;entity2.position.y+=vecn.y*ratio*1.01;entity2.position.z+=vecn.z*ratio*1.01}else{entity1.position.x+=vecn.x*1.01;entity1.position.y+=vecn.y*1.01;entity1.position.z+=vecn.z*1.01}dist=Systems.collision.distance(entity1.position,entity2.position);let vrel={x:entity1.velocity.x-entity2.velocity.x,y:entity1.velocity.y-entity2.velocity.y,z:entity1.velocity.z-entity2.velocity.z};let speed=vrel.x*vecn.x+vrel.y*vecn.y+vrel.z*vecn.z;if(speed>0){let impulse=2*speed/sumMass;if(entity1.fixed===false){entity1.velocity.x-=impulse*vecn.x*entity2.mass*entity1.restitution;entity1.velocity.y-=impulse*vecn.y*entity2.mass*entity1.restitution;entity1.velocity.z-=impulse*vecn.z*entity2.mass*entity1.restitution}if(entity2.fixed===false){entity2.velocity.x+=impulse*vecn.x*entity2.mass*entity2.restitution/entity2.mass;entity2.velocity.y+=impulse*vecn.y*entity2.mass*entity2.restitution/entity2.mass;entity2.velocity.z+=impulse*vecn.z*entity2.mass*entity2.restitution/entity2.mass}}}},nbody:{lastTime:performance.now(),G:6674e-14,setupEntities:function(entities){for(const key in entities){const entity=entities[key];if(entity.components){if(!entity.components[this.__node.tag])continue}this.setupEntity(entity)}return entities},setupEntity:function(entity){if(!("collisionEnabled"in entity))Systems.collider.setupEntity(entity);entity.isAttractor=true;if(!("attractorGroup"in entity))entity.attractorGroup=0;if(!("attractorFrameSearchMax"in entity))entity.attractorFrameSearchMax=10;if(!("attractorGroupRules"in entity))entity.attractorGroupRules={0:{G:this.G,maxDist:void 0}};return entity},__operator:function(entities){let keys=this.entityKeys;for(let i=0;ientity.attractorFrameSearchMax)break nested}}return entities},__node:{tag:"nbody"},attract:function(body1,body2,dist,G=this.G,vecn){if(dist===void 0)dist=Systems.collision.distance3D(body1.position,body2.position);if(vecn===void 0)vecn=Systems.collision.normalize(Systems.collision.makeVec(body1.position,body2.position));let Fg=0;if(dist<.01)dist=.01;if(body1.attractorGroupRules[body2.attractorGroup]){if(typeof body1.attractorGroupRules[body2.attractorGroup]==="object"){if(body1.attractorGroupRules[body2.attractorGroup].maxDist&&body1.attractorGroupRules[body2.attractorGroup].maxDist1e3){entity.boid.groupSize=1;entity.boid.searchLimit=1}return entity},__operator:function(entities){let now=performance.now();let timeStep=now-this.lastTime;this.lastTime=now;let keys=this.entityKeys;let length=keys.length;let _timeStep=1/timeStep;let w2=-1;outer:for(let i=0;ip0.boid.groupSize||k>p0.boid.searchLimit){break nested}let randj=keys[Math.floor(Math.random()*length)];if(k===w2||randj===keys[i]||inRange.indexOf(randj)>-1){continue nested}else{let pr=entities[randj];let disttemp=Math.sqrt((p0.position.x-pr.position.x)*(p0.position.x-pr.position.x)+(p0.position.y-pr.position.y)*(p0.position.y-pr.position.y)+(p0.position.z-pr.position.z)*(p0.position.z-pr.position.z));if(disttemp>p0.boid.groupRadius){continue nested}else{distances.push(disttemp);inRange.push(randj);let distInv;if(p0.boid.useSeparation||p0.boid.useAlignment){distInv=p0.boid.groupRadius/(disttemp*disttemp);if(distInv>p0.maxSpeed)distInv=p0.maxSpeed;else if(distInv<-p0.maxSpeed)distInv=-p0.maxSpeed}if(p0.boid.useCohesion){boidVelocities[0]+=(pr.position.x-p0.position.x)*.5*disttemp*_timeStep;boidVelocities[1]+=(pr.position.y-p0.position.y)*.5*disttemp*_timeStep;boidVelocities[2]+=(pr.position.z-p0.position.z)*.5*disttemp*_timeStep}if(isNaN(disttemp)||isNaN(boidVelocities[0])||isNaN(pr.position.x)){console.log(disttemp,i,randj,p0.position,pr.position,boidVelocities);p0.position.x=NaN;return}if(p0.boid.useSeparation){boidVelocities[3]=boidVelocities[3]+(p0.position.x-pr.position.x)*distInv;boidVelocities[4]=boidVelocities[4]+(p0.position.y-pr.position.y)*distInv;boidVelocities[5]=boidVelocities[5]+(p0.position.z-pr.position.z)*distInv}if(p0.boid.useAttraction&&pr.boid.useAttraction){Systems.nbody.attract(p0,pr,disttemp)}if(p0.boid.useAlignment){boidVelocities[6]=boidVelocities[6]+pr.velocity.x*distInv;boidVelocities[7]=boidVelocities[7]+pr.velocity.y*distInv;boidVelocities[8]=boidVelocities[8]+pr.velocity.z*distInv}groupCount++}}}let _groupCount=1/groupCount;if(p0.boid.useCohesion){boidVelocities[0]=p0.boid.cohesion*(boidVelocities[0]*_groupCount);boidVelocities[1]=p0.boid.cohesion*(boidVelocities[1]*_groupCount);boidVelocities[2]=p0.boid.cohesion*(boidVelocities[2]*_groupCount)}else{boidVelocities[0]=0;boidVelocities[1]=0;boidVelocities[2]=0}if(p0.boid.useSeparation){boidVelocities[3]=p0.boid.separation*boidVelocities[3];boidVelocities[4]=p0.boid.separation*boidVelocities[4];boidVelocities[5]=p0.boid.separation*boidVelocities[5]}else{boidVelocities[3]=0;boidVelocities[4]=0;boidVelocities[5]=0}if(p0.boid.useAlignment){boidVelocities[6]=-(p0.boid.alignment*boidVelocities[6]*_groupCount);boidVelocities[7]=p0.boid.alignment*boidVelocities[7]*_groupCount;boidVelocities[8]=p0.boid.alignment*boidVelocities[8]*_groupCount}else{boidVelocities[6]=0;boidVelocities[7]=0;boidVelocities[8]=0}const swirlVec=[0,0,0];if(p0.boid.useSwirl==true){boidVelocities[9]=-(p0.position.y-p0.boid.swirl.y)*p0.boid.swirl.mul;boidVelocities[10]=(p0.position.z-p0.boid.swirl.z)*p0.boid.swirl.mul;boidVelocities[11]=(p0.position.x-p0.boid.swirl.x)*p0.boid.swirl.mul}const attractorVec=[0,0,0];if(p0.boid.useAttractor==true){boidVelocities[12]=(p0.boid.attractor.x-p0.position.x)*p0.boid.attractor.mul;if(p0.position.x>p0.boundingBox.left||p0.position.xp0.boundingBox.top||p0.position.yp0.boundingBox.front||p0.position.z0){let magnitude=Systems.collision.magnitude(entity.velocity);if(magnitude>entity.maxSpeed){let scalar=entity.maxSpeed/magnitude;entity.velocity.x*=scalar;entity.velocity.y*=scalar;entity.velocity.z*=scalar}}if(entity.velocity.x)entity.position.x+=entity.velocity.x*timeStep;if(entity.velocity.y)entity.position.y+=entity.velocity.y*timeStep;if(entity.velocity.z)entity.position.z+=entity.velocity.z*timeStep}return entities}}};var y=class{r;g;b;a;constructor(e,t,l,o){this.r=e,this.g=t,this.b=l,this.a=o}};var w=class{intensity;visible;numPoints;xy;color;scaleX;scaleY;offsetX;offsetY;loop;webglNumPoints;_vbuffer;_coord;constructor(){this.scaleX=1,this.scaleY=1,this.offsetX=0,this.offsetY=0,this.loop=false,this._vbuffer=0,this._coord=0,this.visible=true,this.intensity=1,this.xy=new Float32Array([]),this.numPoints=0,this.color=new y(0,0,0,1),this.webglNumPoints=0}};var v=class extends w{currentIndex=0;constructor(e,t){super(),this.webglNumPoints=t,this.numPoints=t,this.color=e,this.xy=new Float32Array(2*this.webglNumPoints)}setX(e,t){this.xy[e*2]=t}setY(e,t){this.xy[e*2+1]=t}getX(e){return this.xy[e*2]}getY(e){return this.xy[e*2+1]}lineSpaceX(e,t){for(let l=0;l{let l={x:0,y:0};return l.x=u2.x+e.x*t,l.y=u2.y+e.y*t,l};var A=u2=>P(-u2.y,u2.x);var p=(u2,e)=>{let t=R(u2,e);return t=M(t),t};var T=(u2,e)=>{let t={x:0,y:0};return t.x=u2.x+e.x,t.y=u2.y+e.y,t};var C=(u2,e)=>u2.x*e.x+u2.y*e.y;var M=u2=>{let e={x:0,y:0},t=u2.x*u2.x+u2.y*u2.y;return t>0&&(t=1/Math.sqrt(t),e.x=u2.x*t,e.y=u2.y*t),e};var P=(u2,e)=>{let t={x:0,y:0};return t.x=u2,t.y=e,t};var R=(u2,e)=>{let t={x:0,y:0};return t.x=u2.x-e.x,t.y=u2.y-e.y,t};var X=u2=>{let e,t={x:0,y:0},l={x:0,y:0},o=[],a=(s,r)=>{o.push({vec2:s,miterLength:r})},h=s=>({x:u2[s*2],y:u2[s*2+1]});t=p(h(1),h(0)),e=A(t),a(e,1);let n=u2.length/2;for(let s=1;s{let t=T(u2,e);return t=M(t),P(-t.y,t.x)};var N=(u2,e,t)=>{let l=P(-u2.y,u2.x);return t/C(e,l)};var d=class extends w{currentIndex=0;_linePoints;_thicknessRequested=0;_actualThickness=0;constructor(e,t,l){super(),this.webglNumPoints=t*2,this.numPoints=t,this.color=e,this._thicknessRequested=l,this._linePoints=new Float32Array(t*2),this.xy=new Float32Array(2*this.webglNumPoints)}convertToTriPoints(){let e=this._actualThickness/2,t=X(this._linePoints);for(let l=0;l{if(l.visible){t.useProgram(this._progLine);let o=t.getUniformLocation(this._progLine,"uscale");t.uniformMatrix2fv(o,false,new Float32Array([l.scaleX*this.gScaleX*(this.gLog10X?1/Math.log(10):1),0,0,l.scaleY*this.gScaleY*this.gXYratio*(this.gLog10Y?1/Math.log(10):1)]));let a=t.getUniformLocation(this._progLine,"uoffset");t.uniform2fv(a,new Float32Array([l.offsetX+this.gOffsetX,l.offsetY+this.gOffsetY]));let h=t.getUniformLocation(this._progLine,"is_log");t.uniform2iv(h,new Int32Array([this.gLog10X?1:0,this.gLog10Y?1:0]));let n=t.getUniformLocation(this._progLine,"uColor");t.uniform4fv(n,[l.color.r,l.color.g,l.color.b,l.color.a]),t.bufferData(t.ARRAY_BUFFER,l.xy,t.STREAM_DRAW),t.drawArrays(l.loop?t.LINE_LOOP:t.LINE_STRIP,0,l.webglNumPoints)}})}_drawSurfaces(e){let t=this.webgl;e.forEach(l=>{if(l.visible){t.useProgram(this._progLine);let o=t.getUniformLocation(this._progLine,"uscale");t.uniformMatrix2fv(o,false,new Float32Array([l.scaleX*this.gScaleX*(this.gLog10X?1/Math.log(10):1),0,0,l.scaleY*this.gScaleY*this.gXYratio*(this.gLog10Y?1/Math.log(10):1)]));let a=t.getUniformLocation(this._progLine,"uoffset");t.uniform2fv(a,new Float32Array([l.offsetX+this.gOffsetX,l.offsetY+this.gOffsetY]));let h=t.getUniformLocation(this._progLine,"is_log");t.uniform2iv(h,new Int32Array([this.gLog10X?1:0,this.gLog10Y?1:0]));let n=t.getUniformLocation(this._progLine,"uColor");t.uniform4fv(n,[l.color.r,l.color.g,l.color.b,l.color.a]),t.bufferData(t.ARRAY_BUFFER,l.xy,t.STREAM_DRAW),t.drawArrays(t.TRIANGLE_STRIP,0,l.webglNumPoints)}})}_drawTriangles(e){let t=this.webgl;t.bufferData(t.ARRAY_BUFFER,e.xy,t.STREAM_DRAW),t.useProgram(this._progLine);let l=t.getUniformLocation(this._progLine,"uscale");t.uniformMatrix2fv(l,false,new Float32Array([e.scaleX*this.gScaleX*(this.gLog10X?1/Math.log(10):1),0,0,e.scaleY*this.gScaleY*this.gXYratio*(this.gLog10Y?1/Math.log(10):1)]));let o=t.getUniformLocation(this._progLine,"uoffset");t.uniform2fv(o,new Float32Array([e.offsetX+this.gOffsetX,e.offsetY+this.gOffsetY]));let a=t.getUniformLocation(this._progLine,"is_log");t.uniform2iv(a,new Int32Array([0,0]));let h=t.getUniformLocation(this._progLine,"uColor");t.uniform4fv(h,[e.color.r,e.color.g,e.color.b,e.color.a]),t.drawArrays(t.TRIANGLE_STRIP,0,e.xy.length/2)}_drawThickLines(){this._thickLines.forEach(e=>{if(e.visible){let t=Math.min(this.gScaleX,this.gScaleY);e.setActualThickness(e.getThickness()/t),e.convertToTriPoints(),this._drawTriangles(e)}})}update(){this.clear(),this.draw()}draw(){this._drawLines(this.linesData),this._drawLines(this.linesAux),this._drawThickLines(),this._drawSurfaces(this.surfaces)}clear(){this.webgl.clear(this.webgl.COLOR_BUFFER_BIT)}_addLine(e){e._vbuffer=this.webgl.createBuffer(),this.webgl.bindBuffer(this.webgl.ARRAY_BUFFER,e._vbuffer),this.webgl.bufferData(this.webgl.ARRAY_BUFFER,e.xy,this.webgl.STREAM_DRAW),e._coord=this.webgl.getAttribLocation(this._progLine,"coordinates"),this.webgl.vertexAttribPointer(e._coord,2,this.webgl.FLOAT,false,0,0),this.webgl.enableVertexAttribArray(e._coord)}addDataLine(e){this._addLine(e),this.linesData.push(e)}addLine=this.addDataLine;addAuxLine(e){this._addLine(e),this.linesAux.push(e)}addThickLine(e){this._addLine(e),this._thickLines.push(e)}addSurface(e){this._addLine(e),this.surfaces.push(e)}initThinLineProgram(){let e=` - attribute vec2 coordinates; - uniform mat2 uscale; - uniform vec2 uoffset; - uniform ivec2 is_log; - - void main(void) { - float x = (is_log[0]==1) ? log(coordinates.x) : coordinates.x; - float y = (is_log[1]==1) ? log(coordinates.y) : coordinates.y; - vec2 line = vec2(x, y); - gl_Position = vec4(uscale*line + uoffset, 0.0, 1.0); - }`,t=this.webgl.createShader(this.webgl.VERTEX_SHADER);this.webgl.shaderSource(t,e),this.webgl.compileShader(t);let l=` - precision mediump float; - uniform highp vec4 uColor; - void main(void) { - gl_FragColor = uColor; - }`,o=this.webgl.createShader(this.webgl.FRAGMENT_SHADER);this.webgl.shaderSource(o,l),this.webgl.compileShader(o),this._progLine=this.webgl.createProgram(),this.webgl.attachShader(this._progLine,t),this.webgl.attachShader(this._progLine,o),this.webgl.linkProgram(this._progLine)}popDataLine(){this.linesData.pop()}removeAllLines(){this._linesData=[],this._linesAux=[],this._thickLines=[],this._surfaces=[]}removeDataLines(){this._linesData=[]}removeAuxLines(){this._linesAux=[]}viewport(e,t,l,o){this.webgl.viewport(e,t,l,o)}log(e){this.debug&&console.log("[webgl-plot]:"+e)}};var S=class u{constructor(){this.plots={};this.renderOverlay=(e,t,l,o,a,h=1,n=0)=>{if(typeof l.settings.overlay=="object"&&(o.useOverlay||!("useOverlay"in o))){let s=l.settings.nLines-o.position-1,r=e.height*s/l.settings.nLines,i=e.height*(s+1)/l.settings.nLines;if(t.clearRect(0,r,e.width,i),l.settings.mode==="sweep"){t.strokeStyle=l.settings.sweepColor?l.settings.sweepColor:"rgba(0,255,0,0.8)",t.beginPath();let f=e.width*o.ct/o.values.length;t.moveTo(f,r),t.lineTo(f,i),t.stroke()}if(t.fillStyle=l.settings.overlayColor?l.settings.overlayColor:"white",a&&t.fillText(a,20,e.height*(s+.2)/l.settings.nLines),o.nSec){let f=this.formatTime(o.nSec);t.fillText(`${f}`,l.settings.mode==="sweep"?e.width-35:20,e.height*(s+.9)/l.settings.nLines),t.fillText("0:00",l.settings.mode==="sweep"?20:e.width-35,e.height*(s+.9)/l.settings.nLines)}typeof h=="number"&&t.fillText(`${Math.floor(h)===h?h:h?.toFixed(5)} ${o.units?o.units:""}`,e.width-100,e.height*(s+.2)/l.settings.nLines),typeof n=="number"&&t.fillText(`${Math.floor(n)===n?n:n?.toFixed(5)} ${o.units?o.units:""}`,e.width-100,e.height*(s+.8)/l.settings.nLines)}}}initPlot(e,t){if(t||(t=new x2(e.canvas,e.webglOptions)),!e._id)e._id=`plot${Math.floor(Math.random()*1e15)}`;else if(this.plots[e._id]){let r=this.plots[e._id].initial;if(e.lines){for(let i in e.lines)if(r.lines[i]&&Array.isArray(e.lines[i])){let f=e.lines[i];e.lines[i]=r.lines[i]}}e=Object.assign(r,e)}e.overlay&&(typeof e.overlay!="object"&&(e.overlay=document.createElement("canvas"),e.overlay.style.position="absolute",e.overlay.width=e.canvas.width,e.overlay.height=e.canvas.height,e.canvas.appendChild(e.overlay)),e.overlayCtx||(e.overlayCtx=e.overlay.getContext("2d"))),e.width&&(e.canvas.width=e.width,e.canvas.style&&(e.canvas.style.width=e.width+"px"),typeof e.overlay=="object"&&(e.overlay.width=e.width,e.overlay.style&&(e.overlay.style.width=e.width+"px"))),e.height&&(e.canvas.height=e.height,e.canvas.style&&(e.canvas.style.height=e.height+"px"),typeof e.overlay=="object"&&(e.overlay.height=e.height,e.overlay.style&&(e.overlay.style.height=e.height+"px"))),e.lines?.timestamp&&delete e.lines.timestamp,e.lines||(e.lines={});let l={};for(let r in e.lines)l[r]=Object.assign({},l[r]),"viewing"in e.lines[r]||(e.lines[r].viewing=true),l[r].viewing=e.lines[r].viewing,l[r].sps=e.lines[r].sps,l[r].nSec=e.lines[r].nSec,l[r].nPoints=e.lines[r].nPoints,l[r].ymin=e.lines[r].ymin,l[r].ymax=e.lines[r].ymax,l[r].units=e.lines[r].units;let o={plot:t,settings:e,initial:Object.assign(Object.assign({},e),{lines:l}),anim:()=>{t.update()}};this.plots[e._id]=o;let a=0,h=0;Object.keys(e.lines).forEach(r=>{e.lines[r]?.viewing!==false&&h++}),e.nLines=h;let n,s;typeof e.overlay=="object"&&(n=e.overlay,s=e.overlayCtx,s.clearRect(0,0,e.overlay.width,e.overlay.height),s.font=e.overlayFont?e.overlayFont:"1em Courier",s.fillStyle=e.overlayColor?e.overlayColor:"white");for(let r in e.lines){let i=e.lines[r];if(Array.isArray(i)&&(i={values:i},e.lines[r]=i),"viewing"in i||(i.viewing=true),i.color)Array.isArray(i.color)&&(i.color=new y(...i.color));else{let m=u.HSLToRGB(360*(a/h)%360,100,50,1);o.initial.lines[r].color=[...m,1],i.color=new y(...m,1)}let f;if(i.nSec&&i.sps?f=Math.ceil(i.nSec*i.sps):i.nPoints?f=i.nPoints:i.points?f=i.points:e.linePoints?f=e.linePoints:i.values?f=i.values.length:f=1e3,i.points=f,e.lines[r].viewing===false)continue;if((i.width||e.lineWidth)&&i.width!==0){let m=e.lineWidth;m||(m=i.width),i.width?i.line=new d(i.color,f,i.width):e.lineWidth&&(i.line=new d(i.color,f,e.lineWidth)),i.line.lineSpaceX(-1,2/i.line.numPoints)}else i.line=new v(i.color,f),i.line.arrangeX();i.values?.length===i.points?i.values.length!==f&&(i.interpolate?i.values.length>f?i.values=u.downsample(i.values,f):i.values.lengthi.points?i.values=i.values.slice(i.values.length-i.points):i.values=[...new Array(i.points-i.values.length).fill(0),...i.values]):Array.isArray(i.values)?i.values.length>f?i.values=i.values.slice(i.values.length-f):i.values.lengthg){let m=c;g=c,c=m}let _=Math.abs(c);if(i.absmax=_>g?_:g,"autoscale"in i||(i.autoscale=true),i.position||(i.position=e.nLines-a-1),i.autoscale?i.autoscale===2?("clamp"in i||(i.clamp=true),i.scaled=u.autoscale(i.values,i.position,h,i.centerZero,c,g,i.clamp)):(i.scaled=i.values,i.line.scaleY=u.getYScalar(i.values,h,i.centerZero,c,g),i.line.offsetY=u.getYOffset(i.position,h,c,i.line.scaleY)):i.scaled=i.values,i.scaled.forEach((m,L)=>i.line.setY(L,m)),i.line instanceof d?t.addThickLine(i.line):i.line instanceof v&&t.addDataLine(i.line),"xAxis"in i||(i.xAxis=true),i.xAxis){i.xColor?Array.isArray(i.xColor)&&(i.xColor=new y(...i.xColor)):i.xColor=new y(1,1,1,.3);let m=new v(i.xColor,2),L=i.autoscale?(a+1)*2/h-1-1/h:0;m.constY(L),m.arrangeX(),m.xy[2]=1,i.x=m,t.addAuxLine(m)}if(h>1&&i.autoscale&&a!==h-1){e.dividerColor?Array.isArray(e.dividerColor)&&(e.dividerColor=new y(...e.dividerColor)):e.dividerColor=new y(1,1,1,1);let m=new v(e.dividerColor,2);m.constY(i.autoscale?(a+1)*2/h-1:1),m.arrangeX(),m.xy[2]=1,i.divider=m,t.addAuxLine(m)}if(typeof e.overlay=="object"&&(i.useOverlay||!("useOverlay"in i))){let m=e.nLines-i.position-1;s.fillText(r,20,n.height*(m+.2)/e.nLines),s.fillText(`${Math.floor(g)===g?g:g?.toFixed(5)} ${i.units?i.units:""}`,n.width-100,n.height*(m+.2)/e.nLines),s.fillText(`${Math.floor(c)===c?c:c?.toFixed(5)} ${i.units?i.units:""}`,n.width-100,n.height*(m+.9)/e.nLines)}a++}return requestAnimationFrame(o.anim),this.plots[e._id]}deinitPlot(e){return typeof e=="string"&&(e=this.plots[e]),e.plot.clear(),e.plot.removeAllLines(),true}reinitPlot(e,t){if(typeof e=="string"){let l=e;e=this.plots[e],t._id||(t._id=l)}if(e.plot)return e.plot.clear(),e.plot.removeAllLines(),e.settings.overlayCtx&&e.settings.overlayCtx.clearRect(0,0,e.settings.overlay?.width,e.settings.overlay?.height),this.initPlot(t,e.plot)}getChartSettings(e,t){let l=this.plots[e];if(l){let o=Object.assign({},l.initial);for(let a in l.initial.lines)typeof l.initial.lines[a]?.ymax!="number"&&(o.lines[a].ymax=l.settings.lines[a]?.ymax),typeof l.initial.lines[a]?.ymin!="number"&&(o.lines[a].ymin=l.settings.lines[a]?.ymin),t&&(o.lines[a].values=l.settings.lines[a].values);return delete o.canvas,delete o.overlay,delete o.overlayCtx,o}}update(e,t,l=true){if(typeof e=="string"&&(e=this.plots[e]),!e)return false;let o,a;if(typeof e.settings.overlay=="object"&&(o=e.settings.overlay,a=e.settings.overlayCtx,a.font=e.settings.overlayFont?e.settings.overlayFont:"1em Courier",a.fillStyle=e.settings.overlayColor?e.settings.overlayColor:"white"),t){let h=false;for(let n in t)if(e.settings.lines[n]&&e.settings.lines[n].line){if(e.settings.lines[n]?.viewing===false)continue;let s=e.settings.lines[n];if(s.values){if(e.settings.mode&&e.settings.mode==="sweep"){"ct"in s||(s.ct=0);let g=b=>{s.ct>s.values.length&&(s.ct=0),s.values[s.ct]=b,s.ct++};Array.isArray(t[n])?(s.ct===0&&(s.values=new Array(s.values.length).fill(t[n][t[n].length-1])),t[n].forEach(g)):typeof t[n]=="number"?(s.ct===0&&(s.values=new Array(s.values.length).fill(t[n])),g(t[n])):t[n].values&&(s.ct===0&&(s.values=new Array(s.values.length).fill(t[n].values[t[n].values.length-1])),t[n].values.forEach(g))}else Array.isArray(t[n])&&s.values?.length<1e5?(s.values.length===0?(s.values.length=s.points?s.points:1e3,s.values.fill(t[n][t[n].length-1]),s.firstWrite=true):s.firstWrite||(s.values.fill(t[n][t[n].length-1]),s.firstWrite=true),t[n].length===s.values.length?s.values=t[n]:u.circularBuffer(s.values,t[n])):typeof t[n]=="number"?(s.firstWrite||(s.values.fill(t[n]),s.firstWrite=true),s.values.push(t[n]),s.values.shift()):t[n]?.values&&(s.values.length===0?(s.values.length=s.points?s.points:1e3,s.values.fill(t[n].values[t[n].values.length-1]),s.firstWrite=true):s.firstWrite||(s.values.fill(t[n].values[t[n].values.length-1]),s.firstWrite=true),t[n].values.length===s.values.length?s.values=t[n].values:u.circularBuffer(s.values,t[n].values));s.values.length!==s.points&&(s.interpolate?s.values.length>s.points?s.values=u.downsample(s.values,s.points):s.scaled.lengths.points?s.values.splice(0,s.values.length-s.points):s.values=new Array(s.points).fill(0).splice(s.points-s.values.length,0,s.values));let r=s.ymin,i=s.ymax,f=s.values.length<=1e5;if(r===i?(i=f?Math.max(...s.values):1,r=f?Math.min(...s.values):0):isNaN(i)&&(i=f?Math.max(...s.values):1),isNaN(r)&&(r=f?Math.min(...s.values):0),r>i){let g=r;i=r,r=g}let c=Math.abs(r);s.absmax=c>i?c:i,s.autoscale?s.autoscale===2?s.scaled=u.autoscale(s.values,s.position,e.settings.nLines,s.centerZero,r,i,s.clamp):(s.scaled=s.values,s.line.scaleY=u.getYScalar(s.values,e.settings.nLines,s.centerZero,r,i),s.line.offsetY=u.getYOffset(s.position,e.settings.nLines,r,s.line.scaleY)):s.scaled=s.values,s.scaled.forEach((g,b)=>{!s.autoscale&&s.absmax>1?s.line.setY(b,g/s.absmax):s.line.setY(b,g)}),this.renderOverlay(o,a,e,s,n,i,r)}}else e.settings.generateNewLines&&!n.includes("timestamp")&&(Array.isArray(t[n])&&(t[n]={values:t[n]}),!t[n].nSec&&!t[n].nPoints&&!e.settings.linePoints&&(t[n].nPoints=1e3),h=true);if(h)return e.settings.cleanGeneration||Object.keys(e.initial.lines).forEach(n=>{t[n]?t[n]=Object.assign(e.initial.lines[n],t[n]):t[n]=e.initial.lines[n]}),this.reinitPlot(e,{_id:e.settings._id,lines:t}),true}else for(let h in e.settings.lines){let n=e.settings.lines[h];this.renderOverlay(o,a,e,n,h,n.ymax,n.ymin)}return l&&requestAnimationFrame(e.anim),true}updateLine(e,t,l,o,a,h,n){return e.numPoints!==t.length&&(l?e.numPoints>t.length?t=u.downsample(t,e.numPoints):e.numPointse.numPoints?t=t.slice(t.length-e.numPoints):t=[...new Array(t.length).fill(0),...t]),o&&(t=u.autoscale(t,a,h,n)),t.forEach((s,r)=>e.setY(r,s)),true}formatTime(e){let t=Math.floor(e/60),l=Math.floor(t/60);t=t%60,e=e%60;let o="";return l>0&&(o+=l+":",t<10&&(o+="0")),o+=t+":",e>0&&(e<10&&(o+="0"),o+=e),o}static autoscale(e,t=0,l=1,o=false,a,h,n){if(e?.length===0)return e;let s=typeof h=="number"?h:e.length<=1e5?Math.max(...e):1,r=typeof a=="number"?a:e.length<=1e5?Math.min(...e):0,i=1/l,f=1;if(o){let c=Math.max(Math.abs(r),Math.abs(s));return c!==0&&(f=i/c),e.map(g=>(n&&(gs&&(g=s)),g*f+(i*(t+1)*2-1-i)))}else return s===r?s!==0?f=i/s:r!==0&&(f=i/Math.abs(r)):f=i/(s-r),e.map(c=>(n&&(cs&&(c=s)),2*((c-r)*f-1/(2*l))+(i*(t+1)*2-1-i)))}static getYScalar(e,t=1,l=false,o,a){if(e?.length===0)return e;let h=typeof a=="number"?a:e.length<=1e5?Math.max(...e):1,n=typeof o=="number"?o:e.length<=1e5?Math.min(...e):0,s=1/t,r=1;if(l){let i=Math.max(Math.abs(n),Math.abs(h));return i!==0&&(r=s/i),2*r}else return h===n?h!==0?r=s/h:n!==0&&(r=s/Math.abs(n)):r=s/(h-n),2*r}static getYOffset(e=0,t=1,l=0,o=1){let a=1/t,h=a*(e+1)*2-1-a;return l!==0?h-=l*o+1/t:h-=o+1/t,h}static absmax(e){return Math.max(Math.abs(Math.min(...e)),Math.max(...e))}static downsample(e,t,l=1){if(e.length>t){let o=new Array(t),a=e.length/t,h=e.length-1,n=0,s=0;for(let r=a;rh&&(i=h);for(let f=n;ft?u.downsample(e,t,l):e.lengthe.length){let l=e.length;e.splice(0,l,...t.slice(t.length-l))}else e.splice(0,e.length,...t);return e}static formatDataForCharts(e,t){if(Array.isArray(e)){if(Array.isArray(e[0])){let l={};if(e.forEach((o,a)=>{l[a]=o}),e=l,isNaN(e[0][0]))return}else if(t){if(e={[t]:e},isNaN(e[t][0]))return}else if(e={0:e},isNaN(e[0][0]))return}else if(typeof e=="object"){for(let l in e)if(typeof e[l]=="number"?e[l]=[e[l]]:e[l]?.values&&typeof e[l].values=="number"&&(e[l].values=[e[l].values]),isNaN(e[l][0]))return}else if(typeof e=="string"){let l;if(e.includes(`\r -`)){let o=e.split(`\r -`);e={},o.forEach((a,h)=>{a.includes(" ")?l=a.split(" "):a.includes(",")?l=a.split(","):a.includes("|")&&(l=a.split("|")),l&&l.forEach((n,s)=>{if(n.includes(":")){let[r,i]=n.split(":"),f=parseFloat(i);isNaN(f)||(e[r]=[f])}else{let r=parseFloat(n);isNaN(r)||(e[s]=[r])}})})}else e.includes(" ")?l=e.split(" "):e.includes(",")?l=e.split(","):e.includes("|")&&(l=e.split("|"));e={},l&&l.forEach((o,a)=>{if(o.includes(":")){let[h,n]=o.split(":"),s=parseFloat(n);isNaN(s)||(e[h]=[s])}else{let h=parseFloat(o);isNaN(h)||(e[a]=[h])}})}else typeof e=="number"&&(t?e={[t]:[e]}:e={0:[e]});return e}static padTime(e,t,l,o){let a=(e[0]-t)/l/o;return[...new Array(o-e.length).map((n,s)=>t+a*(s+1)),...e]}static interpolateForTime(e,t,l){return u.interpolate(e,Math.ceil(l*t))}};var webglPlotRoutes={setupChart:function setupChart(settings){console.log("initializing chart",settings);if(!this?.__node?.graph?.plotter){this.__node.graph.plotter=new S;return this.__node.graph.plotter.initPlot(settings).settings._id}else{globalThis.plotter=new S;return globalThis.plotter.initPlot(settings).settings._id}},updateChartData:function updateChartData(plot,lines,draw=true){if(typeof lines==="object"){if(globalThis.plotter)globalThis.plotter.update(plot,lines,draw);else if(this?.__node?.graph?.plotter)this.__node.graph.plotter.update(plot,lines,draw);return true}return false},clearChart:function clearChart(plot){if(globalThis.plotter)globalThis.plotter.deinitPlot(plot);else if(this?.__node?.graph?.plotter)this.__node.graph.plotter.deinitPlot(plot);return true},resetChart:function resetChart(plot,settings){if(globalThis.plotter)globalThis.plotter.reinitPlot(plot,settings);else if(this?.__node?.graph?.plotter)this.__node.graph.plotter.reinitPlot(plot,settings);return settings._id},getChartSettings:function getChartSettings(plotId){let settings;if(globalThis.plotter)settings=globalThis.plotter.getChartSettings(plotId);else if(this?.__node?.graph?.plotter)settings=this.__node.graph.plotter.getChartSettings(plotId);return settings}};async function setSignalControls(controlsDiv,plotId,streamworker,chartworker,chartSettings,filterSettings){let controls=controlsDiv;if(!controls)return false;if(!chartSettings&&chartworker)chartSettings=await chartworker.run("getChartSettings",plotId);if(!filterSettings&&streamworker)filterSettings=await streamworker.run("getFilterSettings");if(chartSettings?.lines){let body=``;let viewingall=true;let scalingall=true;let n50all=true;let n60all=true;let dcall=true;let lpall=true;let bpall=true;for(const prop in chartSettings.lines){let line=chartSettings.lines[prop];body+=` - - ${prop} - - - - - - - - - - Hz - Hz to Hz - `;if(!line.viewing)viewingall=false;if(!filterSettings[prop]?.useScaling)scalingall=false;if(!filterSettings[prop]?.useNotch50)n50all=false;if(!filterSettings[prop]?.useNotch60)n60all=false;if(!filterSettings[prop]?.useDCBlock)dcall=false;if(!filterSettings[prop]?.useLowpass)lpall=false;if(!filterSettings[prop]?.useBandpass)bpall=false}let head=` - - Name - SPS - Plot nSec - Scalar - Units - Lower Bound - Upper Bound - 50Hz Notch - 60Hz Notch - DC Block - Lowpass - Bandpass - - `;controls.innerHTML=head+body;let viewall=document.getElementById(plotId+"viewing");let usescalar=document.getElementById(plotId+"useScaling");let usen50=document.getElementById(plotId+"useNotch50");let usen60=document.getElementById(plotId+"useNotch60");let usedcb=document.getElementById(plotId+"useDCBlock");let uselp=document.getElementById(plotId+"useLowpass");let usebp=document.getElementById(plotId+"useBandpass");let headeronchange=(checked,idsuffix)=>{for(const prop in chartSettings.lines){let elm=document.getElementById(plotId+prop+idsuffix);if(elm?.checked!==checked)elm.click()}};viewall.onchange=ev2=>{headeronchange(ev2.target.checked,"viewing")};usescalar.onchange=ev2=>{headeronchange(ev2.target.checked,"useScaling")};usen50.onchange=ev2=>{headeronchange(ev2.target.checked,"useNotch50")};usen60.onchange=ev2=>{headeronchange(ev2.target.checked,"useNotch60")};usedcb.onchange=ev2=>{headeronchange(ev2.target.checked,"useDCBlock")};uselp.onchange=ev2=>{headeronchange(ev2.target.checked,"useLowpass")};usebp.onchange=ev2=>{headeronchange(ev2.target.checked,"useBandpass")};for(const prop in chartSettings.lines){let viewing=document.getElementById(plotId+prop+"viewing");let sps=document.getElementById(plotId+prop+"sps");let nSec=document.getElementById(plotId+prop+"nSec");let useScaling=document.getElementById(plotId+prop+"useScaling");let scalar=document.getElementById(plotId+prop+"scalar");let units=document.getElementById(plotId+prop+"units");let ymin=document.getElementById(plotId+prop+"ymin");let ymax=document.getElementById(plotId+prop+"ymax");let useNotch50=document.getElementById(plotId+prop+"useNotch50");let useNotch60=document.getElementById(plotId+prop+"useNotch60");let useDCBlock=document.getElementById(plotId+prop+"useDCBlock");let useLowpass=document.getElementById(plotId+prop+"useLowpass");let lowpassHz=document.getElementById(plotId+prop+"lowpassHz");let useBandpass=document.getElementById(plotId+prop+"useBandpass");let bandpassLower=document.getElementById(plotId+prop+"bandpassLower");let bandpassUpper=document.getElementById(plotId+prop+"bandpassUpper");viewing.onchange=()=>{if(!Array.isArray(chartSettings.lines?.[prop])){(chartSettings.lines?.[prop]).viewing=viewing.checked;chartSettings.generateNewLines=false;chartworker.run("resetChart",[plotId,chartSettings])}};let filteronchange=()=>{let setting={[prop]:{sps:sps.value?parseFloat(sps.value):100,useScaling:useScaling.checked,scalar:scalar.value?parseFloat(scalar.value):1,useNotch50:useNotch50.checked,useNotch60:useNotch60.checked,useDCBlock:useDCBlock.checked,useLowpass:useLowpass.checked,lowpassHz:lowpassHz.value?parseFloat(lowpassHz.value):100,useBandpass:useBandpass.checked,bandpassLower:bandpassLower.value?parseFloat(bandpassLower.value):3,bandpassUpper:bandpassUpper.value?parseFloat(bandpassUpper.value):45,trimOutliers:filterSettings[prop]?.trimOutliers,outlierTolerance:filterSettings[prop]?.outlierTolerance}};streamworker.post("setFilters",setting)};sps.onchange=()=>{filteronchange();(chartSettings.lines?.[prop]).sps=parseFloat(sps.value);(chartSettings.lines?.[prop]).nSec=parseFloat(nSec.value);delete(chartSettings.lines?.[prop]).points;delete(chartSettings.lines?.[prop]).nPoints;chartworker.run("resetChart",[plotId,chartSettings])};units.onchange=()=>{if(!Array.isArray(chartSettings.lines?.[prop])){(chartSettings.lines?.[prop]).units=units.value;chartworker.run("resetChart",[plotId,chartSettings])}};ymax.onchange=()=>{if(!Array.isArray(chartSettings.lines?.[prop])){(chartSettings.lines?.[prop]).ymax=ymax.value?parseFloat(ymax.value):1;(chartSettings.lines?.[prop]).ymin=ymin.value?parseFloat(ymin.value):0;chartworker.run("resetChart",[plotId,chartSettings])}};ymin.onchange=()=>{if(!Array.isArray(chartSettings.lines?.[prop])){(chartSettings.lines?.[prop]).ymax=ymax.value?parseFloat(ymax.value):1;(chartSettings.lines?.[prop]).ymin=ymin.value?parseFloat(ymin.value):0;chartworker.run("resetChart",[plotId,chartSettings])}};nSec.onchange=()=>{if(!Array.isArray(chartSettings.lines?.[prop])){(chartSettings.lines?.[prop]).sps=parseFloat(sps.value);(chartSettings.lines?.[prop]).nSec=parseFloat(nSec.value);delete(chartSettings.lines?.[prop]).points;delete(chartSettings.lines?.[prop]).nPoints;chartworker.run("resetChart",[plotId,chartSettings])}};useScaling.onchange=filteronchange;useNotch50.onchange=filteronchange;useNotch60.onchange=filteronchange;useDCBlock.onchange=filteronchange;useLowpass.onchange=filteronchange;useBandpass.onchange=filteronchange;lowpassHz.onchange=filteronchange;scalar.onchange=filteronchange;bandpassLower.onchange=filteronchange;bandpassUpper.onchange=filteronchange}}}var Math2=class _Math2{constructor(){}static TWO_PI=Math.PI*2;static C=299792458;static G=66743e-15;static h=662607015e-42;static R=8314.32;static Ra=287;static H=69.3;static kbar=1054571817e-43;static kB=1380649e-29;static ke=89875517923e-1;static me=91093837015e-41;static mp=167262192369e-38;static mn=167492749804e-38;static P0=101325;static T0=288.15;static p0=1.225;static Na=60220978e16;static y=1.405;static M0=28.96643;static g0=9.80665;static Re=6378100;static B=1458e-9;static S=110.4;static Sigma=365e-12;static imgkernels={edgeDetection:[[-1,-1,-1],[-1,8,-1],[-1,-1,-1]],boxBlur:[[1/9,1/9,1/9],[1/9,1/9,1/9],[1/9,1/9,1/9]],sobelLeft:[[1,0,-1],[2,0,-2],[1,0,-1]],sobelRight:[[-1,0,1],[-2,0,2],[-1,0,1]],sobelTop:[[1,2,1],[0,0,0],[-1,-2,-1]],sobelBottom:[[-1,2,1],[0,0,0],[1,2,1]],identity:[[0,0,0],[0,1,0],[0,0,0]],gaussian3x3:[[1,2,1],[2,4,2],[1,2,1]],guassian7x7:[[0,0,0,5,0,0,0],[0,5,18,32,18,5,0],[0,18,64,100,64,18,0],[5,32,100,100,100,32,5],[0,18,64,100,64,18,0],[0,5,18,32,18,5,0],[0,0,0,5,0,0,0]],emboss:[[-2,-1,0],[-1,1,1],[0,1,2]],sharpen:[[0,-1,0],[-1,5,-1],[0,-1,0]]};static HSLToRGB=(h,s,l,scalar=255)=>{s/=100;l/=100;let c=(1-Math.abs(2*l-1))*s,x22=c*(1-Math.abs(h/60%2-1)),m=l-c/2,r=0,g=0,b=0;if(0<=h&&h<60){r=c;g=x22;b=0}else if(60<=h&&h<120){r=x22;g=c;b=0}else if(120<=h&&h<180){r=0;g=c;b=x22}else if(180<=h&&h<240){r=0;g=x22;b=c}else if(240<=h&&h<300){r=x22;g=0;b=c}else if(300<=h&&h<360){r=c;g=0;b=x22}r=(r+m)*scalar;g=(g+m)*scalar;b=(b+m)*scalar;return[r,g,b]};static genSineWave=(freq=20,peakAmp=1,nSec=1,fs=512,freq2=0,peakAmp2=1)=>{var sineWave=[];var t=[];var increment=1/fs;for(var ti=0;ti{return Math.sin(this.TWO_PI*frequency*ti+tOffset)*peakAmplitude};static mean=arr=>{var sum=arr.reduce((prev,curr)=>curr+=prev);return sum/arr.length};static median=data=>{const sortedData=data.slice().sort((a,b)=>a-b);const middle=Math.floor(sortedData.length/2);if(sortedData.length%2===0){return(sortedData[middle-1]+sortedData[middle])/2}else{return sortedData[middle]}};static mode=arr=>{return arr.sort((a,b)=>arr.filter(v2=>v2===a).length-arr.filter(v2=>v2===b).length).pop()};static range=data=>{return Math.max(...data)-Math.min(...data)};static std=(arr,mean=void 0)=>{let avg=mean;if(!mean)avg=this.mean(arr);let summed=0;for(let i=0;i{if(actual.length!==forecast.length)throw new Error("Input arrays of same length!");let i=actual.length;let d2=new Array(actual.length);for(let j=0;j{let len=probabilities.length;let entropy=new Array(len);for(let i=0;i{let mean=this.mean(arr);let std=this.std(arr,mean);let z=new Array(arr.length);for(let i=0;ia+(b-mean)**2,0)/arr.length}static coeffVariation=(arr,populationMean)=>{let mean=this.mean(arr);let std=this.std(arr,mean);return populationMean?std/populationMean:std/mean};static coeffDetermination=(observed,expected)=>{const meanY=this.mean(observed);const ssTotal=observed.reduce((acc,y2)=>acc+Math.pow(y2-meanY,2),0);const ssResidual=observed.reduce((acc,y2,i)=>acc+Math.pow(y2-expected[i],2),0);return 1-ssResidual/ssTotal};static percentile=(arr,p2)=>{const sortedData=arr.slice().sort((a,b)=>a-b);const index=Math.ceil(p2*(sortedData.length-1));return sortedData[index]};static interquartileRange=arr=>{const sortedData=arr.slice().sort((a,b)=>a-b);const index=Math.ceil(.25*(sortedData.length-1));const index2=Math.ceil(.75*(sortedData.length-1));const q1=sortedData[index];const q3=sortedData[index2];return q3-q1};static skewness=arr=>{const n=arr.length;const meanValue=this.mean(arr);const stdDevValue=this.std(arr);const sumCubedDeviation=arr.reduce((acc,value)=>acc+Math.pow(value-meanValue,3),0);const skew=sumCubedDeviation/(n*Math.pow(stdDevValue,3));return skew};static kurtosis=arr=>{const n=arr.length;const meanValue=this.mean(arr);const stdDevValue=this.std(arr);const sumFourthDeviation=arr.reduce((acc,value)=>acc+Math.pow(value-meanValue,4),0);const kurt=sumFourthDeviation/(n*Math.pow(stdDevValue,4))-3;return kurt};static chiSquareTest=(observed,expected)=>{const chiSquared=observed.reduce((acc,obs,i)=>{const exp=expected[i];return acc+Math.pow(obs-exp,2)/exp},0);return chiSquared};static simpleLinearRegression=(xCoords,yCoords)=>{const n=xCoords.length;const sumX=xCoords.reduce((sum,x22)=>sum+x22,0);const sumY=yCoords.reduce((sum,y2)=>sum+y2,0);const sumXY=xCoords.reduce((sum,x22,i)=>sum+x22*yCoords[i],0);const sumX2=xCoords.reduce((sum,x22)=>sum+x22*x22,0);const slope=(n*sumXY-sumX*sumY)/(n*sumX2-sumX*sumX);const intercept=(sumY-slope*sumX)/n;return{slope,intercept}};static pad=(arr,pad=1,padValue=0)=>{if(Array.isArray(arr[0]))return pad2D(arr,pad);if(pad>0){let pads=new Array(pad).fill(padValue);arr=[...pads,...arr,...pads]}return arr};static pad2D=(array,pad,padValue=0)=>{let pads=new Array(pad).fill(padValue);const paddedArray=array.map(row=>{return[...pads,...row,...pads]});const paddedRow=new Array(array[0].length+2*pad).fill(padValue);for(let i=0;i{const firstElem=array[0];const lastElem=array[array.length-1];const startPadding=new Array(padSize).fill(firstElem);const endPadding=new Array(padSize).fill(lastElem);return startPadding.concat(array,endPadding)};static edgePad2D=(matrix,padSize)=>{const topRows=Array(padSize).fill(matrix[0]);const bottomRows=Array(padSize).fill(matrix[matrix.length-1]);const paddedMatrix=topRows.concat(matrix,bottomRows);for(let i=0;i{const nVecs=vectors.length;return vectors[0].map((v2,i)=>{for(let j=1;j{const nVecs=vectors.length;return vectors[0].map((v2,i)=>{for(let j=1;j{return vec.map((v2,i)=>v2-subvec[i])};static vecdiv=(numvec,denvec)=>{return numvec.map((v2,i)=>v2/denvec[i])};static vecscale=(vec,scalar)=>{return vec.map((v2,i)=>v2*scalar)};static vecaddScalar=(vec,scalar)=>{return vec.map((v2,i)=>v2+scalar)};static vecmulScalar=(vec,scalar)=>{return vec.map((v2,i)=>v2*scalar)};static vecsubScalar=(vec,scalar)=>{return vec.map((v2,i)=>v2-scalar)};static vecdivScalar=(vec,scalar)=>{return vec.map((v2,i)=>v2/scalar)};static dot=(vec1,vec2)=>{var dot=0;for(var i=0;i{return[vec1[1]*vec2[2]-vec1[2]*vec2[1],vec1[2]*vec2[0]-vec1[0]*vec2[2],vec1[0]*vec2[1]-vec1[1]*vec2[0]]};static sphericalToCartesian=(r,theta,phi)=>{return{x:r*Math.sin(phi)*Math.cos(theta),y:r*Math.sin(phi)*Math.sin(theta),z:r*Math.cos(phi)}};static cartesianToSpherical=(x22,y2,z)=>{var r=Math.sqrt(x22*x22+y2*y2+z*z);var theta=Math.atan2(y2,x22);var phi=Math.acos(z/r);return{r,theta,phi}};static magnitude=vec=>{var sqrd=0;vec.forEach(c=>{sqrd+=c*c});return Math.sqrt(sqrd)};static distance=(point1,point2)=>{var dsqrd=0;point1.forEach((c,i)=>{dsqrd+=(point2[i]-c)*(point2[i]-c)});return Math.sqrt(dsqrd)};static midpoint=(point1=[1,2,3],point2=[3,4,5])=>{return point1.map((c,i)=>{return(c+point2[i])*.5})};static project=(vec1,vec2)=>{const dot=this.dot(vec1,vec2);const magSqrd=this.magnitude(vec2)**2;return this.vecmulScalar(vec2,dot/magSqrd)};static angleBetween=(vec1,vec2)=>{const dotProduct=this.dot(vec1,vec2);const magProduct=this.magnitude(vec1)*this.magnitude(vec2);return Math.acos(dotProduct/magProduct)};static normalize=vec=>{var norm=0;norm=1/this.magnitude(vec);var vecn=new Array(vec.length);vec.forEach((c,i)=>{vecn[i]=c*norm});return vecn};static normalizeSeries=(arr=[],fromZero=true)=>{let max=Math.max(...arr);let min=Math.min(...arr);if(fromZero==false){max=Math.max(max,Math.abs(min));min=0}if(max-min===0){min=0;if(max===0)max=1e-13}return arr.map(v2=>(v2-min)/(max-min))};static quadraticFormula=(a,b,c)=>{let bbmac4=Math.sqrt(b*b-4*a*c);if(!isNaN(bbmac4))return["complex","complex"];let _a2=1/(2*a);if(bbmac4===0)return[b*_a2];let nb=-b;return[(nb+bbmac4)*_a2,(nb-bbmac4)*_a2]};static newtonsMethod1D=(foo=x22=>{return Math.pow(x22,5)+x22*x22-x22-.2},start=0,end=1,precision=.01,attempts=10)=>{let roots=[];for(let i=0;iprecision){let step=-guess/slope2;let xn12=xn+step;guess=guess2;guess2=foo(xn12);let slope2=(guess2-guess)/(xn12-xn)}let idx;let f=roots.find((root,i2)=>{if(Math.abs(xn1-root){let y2=x22;return y2},range=[0,1],stepx=.01)=>{let area=0;for(let i=range[0];i{let z=x22+y2;return z},range=[[0,1],[0,1]],stepx=.01,stepy=stepx)=>{let volume=0;for(let i=range[0][0]+stepx;i{let w2=x22+y2+z;return w2},range=[[0,1],[0,1],[0,1]],stepx=.01,stepy=stepx,stepz=stepx)=>{let volume=0;for(let i=range[0][0]+stepx;i{let y2=x22;return y2},range=[0,1],stepx=.01)=>{let length=0;let y0=func(range[0]);for(let i=range[0]+stepx;i<=range[1];i+=stepx){let yi=func(i);length+=Math.sqrt(stepx**2+(yi-y0)**2);y0=yi}return length};static pathIntegral2D=(xFunc=t=>{let x22=Math.cos(t);return x22},yFunc=t=>{let y2=Math.sin(t);return y2},range=[[0,1],[0,1]],stept=.01)=>{let length=0;let x0=xFunc(range[0][0]);let y0=yFunc(range[1][0]);let tMaxX=range[0][1];let tMaxY=range[1][1];let tMax=Math.max(tMaxX,tMaxY);for(let t=0;t<=tMax;t+=stept){let xi=xFunc(Math.min(t,tMaxX));let yi=yFunc(Math.min(t,tMaxY));length+=Math.sqrt((xi-x0)**2+(yi-y0)**2);x0=xi;y0=yi}return length};static pathIntegral3D=(xFunc=(u2,v2)=>u2,yFunc=(u2,v2)=>v2,zFunc=(u2,v2)=>u2+v2,rangeU=[0,1],rangeV=[0,1],stepU=.01,stepV=.01)=>{let area=0;for(let u2=rangeU[0];u2{var vec=[];point1.forEach((c,i)=>{vec.push(point2[i]-c)});return vec};static getBufferedValueByCoordinates=(vb=new Array(300).fill(1),dims=[10,10,2],coordinate=[1,2,1],cardinal=void 0)=>{let getIdx=(foundIdx=0,dimIdx=0)=>{if(dimIdx===dims.length)return foundIdx;if(dimIdx==0)foundIdx+=coordinate[dimIdx];else if(dims[dimIdx]==0)dimsAt0++;else{let reMul=(val=coordinate[dimIdx],di=dimIdx-1)=>{val*=dims[di];di--;if(di==0)return val;else return reMul(val,di)};foundIdx+=reMul(coordinate[dimIdx]+1,dimIdx-1)}dimIdx++;return getIdx(foundIdx,dimIdx)};let found=getIdx();if(cardinal){if(coordinate[coordinate.length-1]===0){let lastnonzero=0;let idx=0;while(idx!==coordinate.length-1){if(coordinate[idx]!==0)lastnonzero=idx;idx++}return vb[found-lastnonzero+cardinal]}return vb[found-dims.length+cardinal]}else{if(coordinate[coordinate.length-1]===0){let lastnonzero=0;let idx=0;while(idx!==coordinate.length-1){if(coordinate[idx]!==0)lastnonzero=idx;idx++}return vb.slice(found-lastnonzero,found+1)}return vb.slice(found-dims.length,found+1)}};static forBufferedMat=(vb=new Array(100).fill(1),dims=[10,10],asIndex=(v2,i,x22,y2)=>{return v2+x22+y2})=>{let coordinate=[];let idx=0;let recurseFor=(depth=0,nextDepth=depth+1)=>{let result=new Array(vb.length);for(let di=0;di{let result=new Array(vb.length);for(let di=0;di{console.log(`value:${v2}, idx:${idx}, x:${i},y:${j}`);return v2+i+j})=>{let coordinate=new Array(dimensions.length).fill(0);const iterateCoordinate=(coord,idx=0)=>{if(coord[idx]>=dimensions[idx]){coord[idx]=0;idx++;if(idx===dimensions.length)return;iterateCoordinate(coord,idx)}else coord[idx]++};let result=new Array(buffer.length);let i=0;if(typeof asIndex==="function"){while(i{result[i]=func(buffer[i],i,...coordinate);i++;iterateCoordinate(coordinate)})}}return result};static combinations=(choices=["a","b","c"],vecsize=3)=>{var result=[];if(vecsize<=0){result.push([])}else{_Math2.combinations(choices,vecsize-1).forEach(function(previousComb){choices.forEach(function(element){result.push([element].concat(previousComb))})})}return result};static generateCoordinateSpace=(upperBounds=[10,10,10],lowerBounds=[-10,-10,-10],steps=[1,1,1],mutater=void 0)=>{for(let i=0;iupperBounds[i]){let temp=upperBounds[i];upperBounds[i]=lowerBounds[i];lowerBounds[i]=temp}}let result=[];let copy=[...upperBounds];let lastindex=copy.length-1;result.push([...copy]);while(copy[0]>=lowerBounds[0]){let checkNextIndex=decrIdx2=>{if(copy[decrIdx2]<=lowerBounds[decrIdx2]){if(decrIdx2===0)return;copy[decrIdx2]=upperBounds[decrIdx2];decrIdx2--;if(decrIdx2<0)return;if(typeof steps[decrIdx2]=="function")copy[decrIdx2]-=steps[decrIdx2](copy[decrIdx2]);else copy[decrIdx2]-=steps[decrIdx2];checkNextIndex(decrIdx2)}};let decrIdx=lastindex;if(typeof steps[decrIdx]=="function")copy[decrIdx]-=steps[decrIdx](copy[decrIdx]);else copy[decrIdx]-=steps[decrIdx];result.push([...copy]);checkNextIndex(decrIdx);if(mutater)result[result.length-1]=mutater(result[result.length-1])}return result};static meshgrid=_Math2.generateCoordinateSpace;static calcVectorField=(coordinates=[[0,0],[0,1],[1,0],[1,1]],formula=(x22,y2)=>{return[x22*10,y2*10]})=>{return coordinates.map(vec=>formula(...vec))};static randomMatrix=(rows,cols)=>{return Array.from({length:rows},()=>Array.from({length:cols},()=>Math.random()))};static identityMatrix=size=>{return Array.from({length:size},(_,i)=>Array.from({length:size},(_2,j)=>i===j?1:0))};static diagonalMatrix=values=>{return values.map((value,index)=>{const row=Array(values.length).fill(0);row[index]=value;return row})};static householderMatrix=v2=>{const size=v2.length;const vvT=v2.map(rowVal=>v2.map(colVal=>rowVal*colVal));const vTv=this.normalize(v2)**2;return Array.from({length:size},(_,i)=>Array.from({length:size},(_2,j)=>(i===j?1:0)-2*vvT[i][j]/vTv))};static transpose=mat=>{return mat[0].map((_,colIndex)=>mat.map(row=>row[colIndex]))};static clone=mat=>{return mat.map(row=>{if(Array.isArray(row[0]))return this.clone(row);else return[...row]})};static getColumn(matrix,col){return matrix.map(row=>row[col])}static matmul=(A2,B)=>{return A2.map(row=>B[0].map((_,colIndex)=>row.reduce((sum,cell,rowIndex)=>sum+cell*B[rowIndex][colIndex],0)))};static matscale=(mat,scalar)=>{return mat.map(row=>row.map(cell=>cell*scalar))};static matadd=(A2,B)=>{return A2.map((row,rowIndex)=>row.map((cell,colIndex)=>cell+B[rowIndex][colIndex]))};static matsub=(A2,B)=>{return A2.map((row,rowIndex)=>row.map((cell,colIndex)=>cell-B[rowIndex][colIndex]))};static inverse=matrix=>{const numRows=matrix.length;const numCols=matrix[0].length;if(numRows!==numCols){throw new Error("Matrix must be square to compute its inverse.")}const augmentedMatrix=matrix.map((row,rowIndex)=>{const identityRow=Array(numRows).fill(0);identityRow[rowIndex]=1;return row.concat(identityRow)});for(let pivotRow=0;pivotRowrow.slice(numCols))};static pseudoInverse=matrix=>{const numRows=matrix.length;const numCols=matrix[0].length;if(numRows>numCols){const ata=this.matmul(this.transpose(matrix),matrix);const ataInv=this.inverse(ata);return this.matmul(ataInv,this.transpose(matrix))}else{const aat=this.matmul(matrix,this.transpose(matrix));const aatInv=this.inverse(aat);return this.matmul(this.transpose(matrix),aatInv)}};static histogram=(arr=[],binSize=1,nBins=void 0)=>{let copy=[...arr];copy.sort(function(a,b){return a-b});let binStart=Math.min(...copy);if(typeof nBins==="number"){let binEnd=Math.max(...copy);binSize=Math.abs((binEnd-binStart)/(nBins-1))}let j=binStart;let binx=[];let biny=[];for(let i=0;ibinStart+binidx){j++;binidx+=binSize;let binmin=binStart+binidx;let binmid=binmin+binidx*.5;binx.push(binmid);biny.push(0)}biny[biny.length-1]++}return[binx,biny]};static normalDistribution=(samples=[],normalize=true,cutoff=1e-4)=>{let m=this.mean(samples);let vari=this.variance(samples);let nSamples=samples.length;let probabilities=[];let denom=1/(this.TWO_PI*vari);let _variance=1/vari;let sum=0;for(let i=0;ix22*_sum)}return probabilities};static expectedValue=(samples=[],probabilities=this.normalDistribution(samples))=>{return samples.reduce((sum,item,idx)=>sum+item*probabilities[idx])};static originMoment=(samples=[],probabilities=this.normalDistribution(samples),order=1)=>{return samples.reduce((sum,item,idx)=>sum+Math.pow(item,order)*probabilities[idx])};static centralMoment=(samples=[],probabilities=this.normalDistribution(samples),order=1)=>{let m=this.mean(samples);return samples.reduce((sum,item,idx)=>sum+Math.pow(item-m,order)*probabilities[idx]/samples.length)};static linearDiscriminantAnalysis=(samples=[],classifier=[])=>{let mean=this.mean(samples);let meank=this.mean(classifier);let covariance=this.cov1d(samples,classifier);let probs=this.normalDistribution(samples);let dk=[];for(let i=0;i{const padlen=deconstructionLowPass.length;let sg=this.edgePad(signal,padlen);let approxCoeffs=this.conv1D(sg,deconstructionLowPass).slice(1+padlen,-padlen).filter((_,idx)=>idx%2===0);let detailCoeffs=this.conv1D(sg,deconstructionHighPass).slice(1+padlen,-padlen).filter((_,idx)=>idx%2===0);let results=[detailCoeffs];for(let i=0;iidx%2===0));approxCoeffs=this.conv1D(approxCoeffs,deconstructionLowPass).slice(1+padlen,-padlen).filter((_,idx)=>idx%2===0)}return[approxCoeffs].concat(results.reverse())};static idwt=(approxCoeffs=[],detailCoeffs=[],reconstructionHighPass=[],reconstructionLowPass=[])=>{if(approxCoeffs.length!==detailCoeffs.length){approxCoeffs.pop()}const _ca=this.dyadicUpsample(approxCoeffs,true);const _cd=this.dyadicUpsample(detailCoeffs,true);const halfa=this.conv1D(_ca,reconstructionLowPass);const halfb=this.conv1D(_cd,reconstructionHighPass);const sig=halfa.map((val,idx)=>val+halfb[idx]);const padlen=reconstructionLowPass.length;const lo=padlen-1;const hi=sig.length-(padlen-2);return sig.slice(lo,hi)};static dwtMaxLevel=(dataLength,waveletLength)=>{return Math.floor(Math.log2(dataLength/(waveletLength-1)))};static minMaxScaler=data=>{const min=Math.min(...data);const max=Math.max(...data);return data.map(value=>(value-min)/(max-min))};static garroteThreshold=(data,value)=>{return data.map(x22=>{if(Math.abs(x22)<=value){return 0}else{return x22-value*value/x22}})};static conv1D=(s,kernel)=>{const revKernel=[...kernel].reverse();const padsize=kernel.length-1;const paddedS=new Array(padsize).fill(0).concat(s).concat(new Array(padsize).fill(0));const nSteps=paddedS.length-kernel.length+1;const result=new Array(nSteps).fill(0);const nKer=kernel.length;for(let i=0;i{const rows=matrix.length;const cols=matrix[0].length;const kRows=kernel.length;const kCols=kernel[0].length;const halfKRows=Math.floor(kRows/2);const halfKCols=Math.floor(kCols/2);const output=new Array(rows).fill(0).map(()=>new Array(cols).fill(0));for(let i=0;i=0&&xi=0&&yj{if(matrix.length===0||kernel.length===0)return[];function getShape(arr){const shape=[];while(Array.isArray(arr)){shape.push(arr.length);arr=arr[0]}return shape}function convolveRecurse(mat,ker,matrixShape2,kernelShape2,matIndices=[],kerIndices=[]){const depth=matIndices.length;if(depth===matrixShape2.length){let sum=0;for(let i=0;i=0&&matIndex{const mean1=this.mean(arr1);const mean2=this.mean(arr2);return arr1.map((v2,i)=>(v2-mean1)*(arr2[i]-mean2))};static cov1d=(arr1,arr2)=>{this.mean(this.covVec(arr1,arr2))};static cov2d=mat=>{var mattransposed=this.transpose(mat);var matproducts=[];var rowmeans=[];var colmeans=[];mat.forEach((row,idx)=>{rowmeans.push(this.mean(row))});mattransposed.forEach((col,idx)=>{colmeans.push(this.mean(col))});mat.forEach((row,idx)=>{matproducts.push([]);for(var col=0;col{return[[this.cov1d(x22,x22),this.cov1d(x22,y2),this.cov1d(x22,z)],[this.cov1d(y2,x22),this.cov1d(y2,y2),this.cov1d(y2,z)],[this.cov1d(z,x22),this.cov1d(z,y2),this.cov1d(z,z)]]};static covNd=(dimensionalData=[])=>{let covariance=[];dimensionalData.forEach((arr,i)=>{covariance.push([]);dimensionalData.forEach((arr2,j)=>{covariance[i].push(this.cov1d(arr,arr2))})})};static correlationCoeff=(arr1,arr2)=>{const cov=this.cov1d(arr1,arr2);const stdDev1=this.std(arr1);const stdDev2=this.std(arr2);return cov/(stdDev1*stdDev2)};static pearsonCorrelation=(arr1,arr2)=>{let sumX=0,sumY=0,sumXY=0,sumX2=0,sumY2=0;const n=arr1.length>arr2.length?arr2.length:arr1.length;for(let i=0;i{let det=mat[0][0]*mat[1][1]-mat[0][1]*mat[1][0];let mean=(mat[0][0]+mat[1][1])*.5;let sqrt=Math.sqrt(mean*mean-det);let eig1=mean+sqrt;let eig2=mean-sqrt;return[eig1,eig2]};static eigenvectors2x2=(mat=[[1,2],[3,4]],eigens=[1,2])=>{let v1=[-mat[0][1],mat[0][0]-eigens[0]];if(v1[0]===0&&v1[1]===0){v1[0]=mat[1][1]-eigens[0];v1[1]=-mat[1][0]}let v2=[-mat[0][1],mat[0][0]-eigens[1]];if(v2[0]===0&&v2[1]===0){v2[0]=mat[1][1]-eigens[1];v2[1]=-mat[1][0]}return[v1,v2]};static fastpca2d=(xarr,yarr)=>{let covMat=this.cov2d(xarr,yarr);let eigs=this.eigens2x2(covMat);if(eigs[1]>eigs[0])eigs.reverse();let evs=this.eigenvectors2x2(covMat,eigs);return[eigs,evs]};static centerData=data=>{const mean=data.reduce((sum,val)=>sum+val,0)/data.length;return data.map(v2=>v2-mean)};static crosscorrelation=(signalA,signalB,posOnly=false)=>{const N2=signalA.length;const M2=signalB.length;const result=[];const normFactor=1/Math.sqrt(signalA.reduce((acc,val)=>acc+val*val,0)*signalB.reduce((acc,val)=>acc+val*val,0));if(posOnly){result.length=signalA.length;for(let lag=0;lag=0&&m{const lags=[];const timeResolution=samplingRate?1/samplingRate:0;const center=centered?correlogram.length/2:null;const len=correlogram.length-1;for(let i=1;icorrelogram[i-1]&&correlogram[i]>correlogram[i+1]){let lag={offset:centered?i-center:i,value:correlogram[i]};if(timeResolution)lag.offset*=timeResolution;lags.push(lag)}}if(getMax)return lags.reduce((maxObj,currentObj)=>{return currentObj.value>maxObj.value?currentObj:maxObj},lags[0]);else return lags};static autocorrelation=arr1=>{var delaybuf=[...arr1,...Array(arr1.length).fill(0)];var mean1=this.mean(arr1);var arr1Est=arr1.reduce((sum,item)=>sum+=Math.pow(item-mean1,2));arr1Est=Math.sqrt(Math.abs(arr1Est));let denom=arr1Est*arr2Est;if(denom===0)denom=1e-26;var _arr1estsqrd=1/denom;var correlations=new Array(arr1.length).fill(0);for(var delay=0;delaysum+=(item-mean1)*(delaybuf[delay+i]-mean1));correlations[delay]=r*_arr1estsqrd}return correlations};static autocorrelation2d=mat2d2=>{let result=[];for(let y2=0;y2{let result=[];for(let y2=0;y2{let result=[];for(let y2=0;y2{let result=[];for(let y2=0;y2{var correlograms=[];dat.forEach((row1,i)=>{dat.forEach((row2,j)=>{if(j>=i){correlograms.push(_Math2.crosscorrelation(row1,row2))}})});return correlograms};static dft=(sineWave=[],sampleRate=250,frequencyResolution=.25)=>{const N2=sineWave.length;const NyquistLimit=Math.floor(sampleRate/2);const totalFreqs=Math.floor(NyquistLimit/frequencyResolution);const Npadded=Math.ceil(sampleRate/frequencyResolution);const TWOPI=2*3.141592653589793;const real=new Array(Npadded).fill(0);const imag=new Array(Npadded).fill(0);const amplitudes=new Array(Npadded);const zerosToAdd=Npadded-N2;if(zerosToAdd<0){throw new Error("Desired resolution is not achievable with current sample size.")}const paddedSineWave=zerosToAdd?[...sineWave,...Array(zerosToAdd).fill(0)]:sineWave;let orderedFrequencies;if(totalFreqs%2===0){orderedFrequencies=[...new Array(totalFreqs).fill(0).map((x22,i)=>-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs).fill(0).map((x22,i)=>i*frequencyResolution)]}else{orderedFrequencies=[...new Array(totalFreqs).fill(0).map((x22,i)=>-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs+1).fill(0).map((x22,i)=>i*frequencyResolution)]}for(let k=0;k-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs).fill(0).map((x22,i)=>(i+1)*frequencyResolution)]}else{orderedMagnitudes=[...amplitudes.slice(totalFreqs,2*totalFreqs),...amplitudes.slice(0,totalFreqs+1)];orderedFrequencies=[...new Array(totalFreqs).fill(0).map((x22,i)=>-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs+1).fill(0).map((x22,i)=>i*frequencyResolution)]}return{real,imag,freqs:orderedFrequencies,amplitudes:orderedMagnitudes}};static eulerTransform=(dataSeries=[],timeTransform=(j,dataSeries2,real,imag,magnitudes)=>{return dataSeries2[j]},stepTransform=(k,j,length,real,imag,magnitudes)=>{return 2*Math.PI*k*j/length},kN=dataSeries.length)=>{var real=[];var imag=[];var magnitudes=[];for(var k=0;k{var smaArr=[];for(var i=0;icurrent+=previous)/(i+1))}else{var arrslice=arr.slice(i-window,i);smaArr.push(arrslice.reduce((previous,current)=>current+=previous)/window)}}return smaArr};static sum=(arr=[])=>{if(arr.length>0){var sum=arr.reduce((prev,curr)=>curr+=prev);return sum}else{return 0}};static reduceArrByFactor=(arr,factor=2)=>{let x22=arr.filter((element,index)=>{return index%factor===0});return x22};static makeArr=(startValue,stopValue,nSteps)=>{var arr=[];var step=(stopValue-startValue)/(nSteps-1);for(var i=0;i{if(array?.length===0)return array;let max=Math.max(...array);let min=Math.min(...array);let _lines=1/stackedLines;let scalar;if(centerZero){let absmax=Math.max(Math.abs(min),Math.abs(max));scalar=_lines/absmax;return array.map(y2=>y2*scalar+(_lines*(stackPosition+1)*2-1-_lines))}else{scalar=_lines/(max-min);return array.map(y2=>2*((y2-min)*scalar-1/(2*stackedLines))+(_lines*(stackPosition+1)*2-1-_lines))}};static absmax=array=>{return Math.max(Math.abs(Math.min(...array)),Math.max(...array))};static downsample=(array,fitCount,scalar=1)=>{if(array.length>fitCount){let output=new Array(fitCount);let incr=array.length/fitCount;let lastIdx=array.length-1;let last=0;let counter=0;for(let i=incr;ilastIdx)rounded=lastIdx;for(let j=last;j{var linearInterpolate=function(before2,after2,atPoint2){return(before2+(after2-before2)*atPoint2)*scalar};var newData=new Array;var springFactor=(array.length-1)/(fitCount-1);newData[0]=array[0];for(var i=1;i{const start=even?1:0;const out=new Array(a.length*2).fill(0);for(let i=0;i{if(array.length===fitCount)return array;if(array.length>fitCount){return this.downsample(array,fitCount,scalar)}else{return this.upsample(array,fitCount,scalar)}};static lerp=(v0,v1,t)=>{return(1-t)*v0+t*v1};static linspace=(start,end,num,floor=false)=>{const arr=new Array(num);const step=(end-start)/(num-1);for(let i=0;i{let ref=[...arr];if(ref.length%2===0)ref.pop();if(arr.length>1){let pass=true;for(let i=0;i=ref[Math.floor(ref.length*.5)]){pass=false;break}else if(i>Math.floor(ref.length*.5)&&val>=ref[Math.floor(ref.length*.5)]){pass=false;break}}else if(critical==="valley"){if(iMath.floor(ref.length*.5)&&val<=ref[Math.floor(ref.length*.5)]){pass=false;break}}else{if(iMath.floor(ref.length*.5)&&val<=ref[Math.floor(ref.length*.5)]){pass=false;break}}}if(critical!=="peak"&&critical!=="valley"&&pass===false){pass=true;for(let i=0;i=ref[Math.floor(ref.length*.5)]){pass=false;break}else if(i>Math.floor(ref.length*.5)&&val>=ref[Math.floor(ref.length*.5)]){pass=false;break}}}return pass}else return void 0};static isCriticalPoint=(arr,critical="peak")=>{let ref=[...arr];if(ref.length%2===0)ref.pop();if(arr.length>1){let pass=true;for(let i=0;iref.length*.5&&val>0){pass=false;break}}else if(critical==="valley"){if(i=0){pass=false;break}else if(i>ref.length*.5&&val<0){pass=false;break}}else{if(i=0){pass=false;break}else if(i>ref.length*.5&&val<0){pass=false;break}}}if(critical!=="peak"&&critical!=="valley"&&pass===false){pass=true;for(let i=0;iref.length*.5&&val>0){pass=false;break}}}return pass}else return void 0};static peakDetect=(smoothedArray,type="peak",window=49)=>{let mid=Math.floor(window*.5);let peaks=[];for(let i=0;i{let threshold;let filtered=arr.filter((o,i)=>{if(peakIndices.indexOf(i)>-1)return true});if(thresholdVar===0){threshold=this.mean(filtered)}else threshold=(thresholdVar+this.mean(filtered))*.5;return threshold};static column=(mat,x22)=>{let col=new Array(mat.length).fill(0).map(()=>new Array(1).fill(0));for(let i=0;i{let v_new=[];for(let i=0;i{let sum=0;for(let i=0;i{let len=Math.sqrt(this.matmul(this.transpose(eigenvector),eigenvector));let U=this.matscale(eigenvector,1/len);let delta=this.matscale(this.matmul(U,this.transpose(U)),eigenvalue);let M_new=this.matsub(mat,delta);return M_new};static eigenvalue_of_vector=(mat,eigenvector)=>{ev=this.matmul(this.matmul(this.transpose(eigenvector),mat),eigenvector);return ev};static power_iteration=(A2,numIter=100)=>{let b=Array(A2.length).fill(1);for(let i=0;i{let eigenvalues=[];let eigenvectors=[];for(let i=0;i{if(A2[0].length>A2.length){A2=this.transpose(A2)}const m=A2.length;const n=A2[0].length;const prec=Number.EPSILON;const tolerance=1e-64/prec;const itmax=50;const leftSingularVectors=this.clone(A2);const offDiagonalValues=Array(n).fill(0);const singularValues=Array(n).fill(0);const rightSingularVectors=Array.from({length:n},()=>Array(n).fill(0));function pythag(a,b){if(a===0||b===0)return a+b;const absA=Math.abs(a),absB=Math.abs(b);if(absA>absB){const t=absB/absA;return absA*Math.sqrt(1+t*t)}else{const t=absA/absB;return absB*Math.sqrt(1+t*t)}}let scaleFactorF=0;let scaleFactorG=0;let scaleFactorH=0;let maxMagnitude=0;let intermediateY=0;let intermediateZ=0;let sumValue=0;let cosineTheta=0;let limitIndex=0;for(let i=0;i=0)scaleFactorG=-scaleFactorG;scaleFactorH=scaleFactorF*scaleFactorG-sumValue;leftSingularVectors[i][i]=scaleFactorF-scaleFactorG;for(let j=limitIndex;j=0)scaleFactorG=-scaleFactorG;scaleFactorH=scaleFactorF*scaleFactorG-sumValue;leftSingularVectors[i][i+1]=scaleFactorF-scaleFactorG;for(let j=limitIndex;jmaxMagnitude)maxMagnitude=intermediateY}for(let i=n-1;i>=0;i--){if(scaleFactorG!==0){scaleFactorH=scaleFactorG*leftSingularVectors[i][i+1];for(let j=limitIndex;j=0;i--){limitIndex=i+1;scaleFactorG=singularValues[i];for(let j=limitIndex;j=0;k--){for(let iteration=0;iteration=0;limitIndex--){if(Math.abs(offDiagonalValues[limitIndex])<=eps){testConvergence=true;break}if(Math.abs(singularValues[limitIndex-1])<=eps)break}if(!testConvergence){cosineTheta=0;sumValue=1;const l1=limitIndex-1;for(let i=limitIndex;i=itmax-1)throw new Error("No convergence.");maxMagnitude=singularValues[limitIndex];intermediateY=singularValues[k-1];scaleFactorG=offDiagonalValues[k-1];scaleFactorH=offDiagonalValues[k];scaleFactorF=((intermediateY-intermediateZ)*(intermediateY+intermediateZ)+(scaleFactorG-scaleFactorH)*(scaleFactorG+scaleFactorH))/(2*scaleFactorH*intermediateY);scaleFactorG=pythag(scaleFactorF,1);if(scaleFactorF<0)scaleFactorF=((maxMagnitude-intermediateZ)*(maxMagnitude+intermediateZ)+scaleFactorH*(intermediateY/(scaleFactorF-scaleFactorG)-scaleFactorH))/maxMagnitude;else scaleFactorF=((maxMagnitude-intermediateZ)*(maxMagnitude+intermediateZ)+scaleFactorH*(intermediateY/(scaleFactorF+scaleFactorG)-scaleFactorH))/maxMagnitude;cosineTheta=1;sumValue=1;for(let i=limitIndex+1;i=0;j--){if(singularValues[j]row.slice());for(let k=0;k0?-this.normalize(x22):this.normalize(x22);const u2=this.vecsub(x22,e);const normU=this.normalize(u2);const v2=u2.map(val=>val/normU);const Qk=this.householderMatrix(v2);const QkFull=this.identityMatrix(numRows);for(let row=k;row{const numRowsOriginal=matrixA.length;const numColsOriginal=matrixA[0].length;if(!numComponents){numComponents=Math.min(numRowsOriginal,numColsOriginal)}let matrixACopy=[...matrixA.map(row=>[...row])];if(numRowsOriginal>numColsOriginal){matrixA=this.matmul(this.transpose(matrixA),matrixA)}else if(numRowsOriginalsum+row.reduce((rowSum,val)=>rowSum+val*val,0),0);previousMatrixQ=matrixQ;if(errorMath.sqrt(row[row.indexOf(Math.max(...row))]));let leftVectors,rightVectors;if(numRowsOriginalval*val)}else{rightVectors=this.transpose(matrixQ);leftVectors=this.matmul(this.matmul(matrixACopy,rightVectors),this.inverse(this.diagonalMatrix(singularValues)))}return{U:leftVectors,S:singularValues,V:rightVectors}};static pca=(mat,tolerance=1e-5)=>{let dims=mat.length;let t=new Array(dims);let p2=new Array(dims);let mat_t=this.transpose(mat);t[0]=this.column(mat,0);let epsilon=1;let iter=0;while(espilon>tolerance){iter++;p2[0]=this.matmul(mat_t,t[0]);let tp=this.matmul(this.transpose(t[0]),t[0]);p2[0]=this.matscale(p2[0],1/tp);let p_length=Math.sqrt(this.matmul(this.transpose(p2[0]),p2[0]));p2[0]=this.matscale(p2[0],1/p_length);let t_new=this.matmul(mat,p2[0]);let pp=this.matmul(this.transpose(p2[0]),p2[0]);t_new=this.matscale(t_new,1/pp);epsilon=this.squared_difference(t[0],t_new);t[0]=JSON.parse(JSON.stringify(t_new))}let components=this.matmul(this.transpose(t[0]),t[0]);return components};static circularBuffer=(arr,newEntries)=>{if(Array.isArray(newEntries)){if(newEntries.lengtharr.length){let len=arr.length;arr.splice(0,len,newEntries.slice(len-newEntries.length))}else{arr.splice(0,arr.length,...newEntries)}}else{arr.push(newEntries);arr.shift()}return arr};static reshape=(arr,shape)=>{const totalSize=shape.reduce((acc,val)=>acc*val,1);const flatArr=this.flatten(arr);if(flatArr.length!==totalSize){throw new Error("The given shape is incompatible with the array size.")}function buildArray(shape2,flatData){const dim=shape2[0];if(shape2.length===1){return flatData.splice(0,dim)}let result=[];for(let i=0;i{if(!Array.isArray(arr)){return[arr]}return arr.reduce((acc,val)=>acc.concat(flatten(val)),[])};static p300=(event_timestamps=[],raw_signal=[],signal_timestamps=[],sps=256)=>{let smoothingstep=Math.floor(sps/10);let smoothed=this.sma(raw_signal,smoothingstep);let peaks=this.peakDetect(smoothed,"peak",smoothingstep);let mean=this.mean(smoothed);let std=this.std(smoothed,mean);let p_idx=0;let candidates=[];if(peaks.length>0){event_timestamps.forEach((t,j)=>{while(signal_timestamps[peaks[p_idx]]1){let peakvals=[];tempcandidates.forEach(tc=>{peakvals.push(smoothed[peaks[tc]])});let max=Math.max(...peakvals);let maxi=tempcandidates[peakvals.indexOf(max)];candidates.push({event_timestamp:t,event_index:j,peak_timestamp:signal_timestamps[[peaks[maxi]]],signal_index:[peaks[maxi]],signal_amplitude:raw_signal[[peaks[maxi]]],zscore:(smoothed[peaks[maxi]]-mean)/std})}else if(tempcandidates.length===1)candidates.push({event_timestamp:t,event_index:j,peak_timestamp:signal_timestamps[peaks[tempcandidates[0]]],signal_index:peaks[tempcandidates[0]],signal_amplitude:raw_signal[[peaks[tempcandidates[0]]]],zscore:(smoothed[peaks[tempcandidates[0]]]-mean)/std})})}return candidates};static dec_lo=[-.07576571478927333,-.02963552764599851,.49761866763201545,.8037387518059161,.29785779560527736,-.09921954357684722,-.012603967262037833,.0322231006040427];static dec_hi=[-.0322231006040427,-.012603967262037833,.09921954357684722,.29785779560527736,-.8037387518059161,.49761866763201545,.02963552764599851,-.07576571478927333];static rec_lo=[.0322231006040427,-.012603967262037833,-.09921954357684722,.29785779560527736,.8037387518059161,.49761866763201545,-.02963552764599851,-.07576571478927333];static rec_hi=[-.07576571478927333,.02963552764599851,.49761866763201545,-.8037387518059161,.29785779560527736,.09921954357684722,-.012603967262037833,-.0322231006040427];static waveletFiltering=(signal=[],wavelets={dec_hi:this.dec_hi,dec_lo:this.dec_lo,rec_hi:this.rec_hi,rec_lo:this.rec_lo})=>{let maxlevel=this.dwtMaxLevel(signal.length,wavelets.dec_lo.length);let decomposed=this.decompose(signal,maxlevel,wavelets.dec_hi,wavelets.dec_lo);for(let i=2;i{ax=ax*this.accelConstant;ay=ay*this.accelConstant;az=az*this.accelConstant;const accelXAngle=Math.atan(ay/Math.sqrt(ax*ax)+az*az*180/Math.PI)+this.accelXError;const accelYAngle=Math.atan(-ax/Math.sqrt(ay*ay)+az*az*180/Math.PI)+this.accelYError;return{ax,ay,az,roll:accelXAngle,pitch:accelYAngle}};if(Array.isArray(data.timestamp)){result=data.timestamp.map((v2,i)=>{return apass(v2,data.ax[i],data.ay[i],data.az[i])})}else result=apass(data.timestamp,data.ax,data.ay,data.az)}if(data.gx){let gpass=(timestamp,gx,gy,gz)=>{const elapsed=timestamp-this.lastGyroTime;this.lastGyroTime=timestamp;gx=gx*this.gyroConstant+this.gyroXError;gy=gy*this.gyroConstant+this.gyroYError;gz=gz*this.gyroConstant+this.gyroZError;this.gyroXAngle+=gx*elapsed;this.gyroYAngle+=gy*elapsed;this.gyroZAngle+=gz*elapsed;return{gx,gy,gz,roll:this.gyroXAngle,pitch:this.gyroYAngle,yaw:this.gyroZAngle}};let res;if(Array.isArray(data.timestamp)){res=data.timestamp.map((v2,i)=>{if(result){let r=gpass(v2,data.gx[i],data.gy[i],data.gz[i]);result.roll=result.roll*.04+r.roll*.96;result.pitch=result.pitch*.04+r.pitch*.96;result.yaw=res.yaw}else return gpass(v2,data.gx[i],data.gy[i],data.gz[i])});if(!result)result=res}else{res=gpass(data.timestamp,data.gx,data.gy,data.gz);if(result){result.roll=result.roll*.04+res.roll*.96;result.pitch=result.pitch*.04+res.pitch*.96;result.yaw=res.yaw}else result=res}}else if(this.gyroXAngle||this.gyroYAngle||this.gyroZAngle){result.roll=result.roll*.04+this.gyroXAngle*.96;result.pitch=result.pitch*.04+this.gyroYAngle*.96;result.yaw=this.gyroXAngle}if(result.ax){const setPositionOffset=(timestamp,result2)=>{const elapsed=timestamp-this.lastAccelTime;this.lastAccelTime=timestamp;this.px+=result2.ax*elapsed*elapsed*Math.cos(this.pitch*Math.PI*.005555555555);this.py+=result2.ay*elapsed*elapsed*Math.cos(this.roll*Math.PI*.005555555555);this.pz+=result2.az*elapsed*elapsed*Math.sin(this.pitch*Math.PI*.005555555555);result2.px=this.px;result2.py=this.py;result2.pz=this.pz;return result2};if(Array.isArray(data.timestamp)){data.timestamp.map((timestamp,i)=>{setPositionOffset(timestamp,result)})}else{setPositionOffset(data.timestamp,result)}}return result}};var Biquad=class{type;freq;sps;Q;dbGain;a0=0;a1=0;a2=0;b0=0;b1=0;b2=0;x1=0;x2=0;y1=0;y2=0;constructor(type,freq,sps,Q=1/Math.sqrt(2),dbGain=0){let types=["lowpass","highpass","bandpass","notch","peak","lowshelf","highshelf"];if(types.indexOf(type)<0){console.error("Valid types: 'lowpass','highpass','bandpass','notch','peak','lowshelf','highshelf'");return}this.type=type;this.freq=freq;this.sps=sps;this.Q=Q;this.dbGain=dbGain;let A2=Math.pow(10,dbGain/40);let omega=2*Math.PI*freq/sps;let sn=Math.sin(omega);let cs=Math.cos(omega);let alpha=sn/(2*Q);let beta=Math.sqrt(A2+A2);this[type](A2,sn,cs,alpha,beta);this.b0/=this.a0;this.b1/=this.a0;this.b2/=this.a0;this.a1/=this.a0;this.a2/=this.a0}lowpass(A2,sn,cs,alpha,beta){this.b0=(1-cs)*.5;this.b1=1-cs;this.b2=(1-cs)*.5;this.a0=1+alpha;this.a1=-2*cs;this.a2=1-alpha}highpass(A2,sn,cs,alpha,beta){this.b0=(1+cs)*.5;this.b1=-(1+cs);this.b2=(1+cs)*.5;this.a0=1+alpha;this.a1=-2*cs;this.a2=1-alpha}bandpass(A2,sn,cs,alpha,beta){this.b0=alpha;this.b1=0;this.b2=-alpha;this.a0=1+alpha;this.a1=-2*cs;this.a2=1-alpha}notch(A2,sn,cs,alpha,beta){this.b0=1;this.b1=-2*cs;this.b2=1;this.a0=1+alpha;this.a1=-2*cs;this.a2=1-alpha}peak(A2,sn,cs,alpha,beta){this.b0=1+alpha*A2;this.b1=-2*cs;this.b2=1-alpha*A2;this.a0=1+alpha/A2;this.a1=-2*cs;this.a2=1-alpha/A2}lowshelf(A2,sn,cs,alpha,beta){this.b0=A2*(A2+1-(A2-1)*cs+beta*sn);this.b1=2*A2*(A2-1-(A2+1)*cs);this.b2=A2*(A2+1-(A2-1)*cs-beta*sn);this.a0=A2+1+(A2+1)*cs+beta*sn;this.a1=2*(A2-1+(A2+1)*cs);this.a2=A2+1+(A2-1)*cs-beta*sn}highshelf(A2,sn,cs,alpha,beta){this.b0=A2*(A2+1+(A2-1)*cs+beta*sn);this.b1=2*A2*(A2-1+(A2+1)*cs);this.b2=A2*(A2+1-(A2-1)*cs-beta*sn);this.a0=A2+1-(A2+1)*cs-beta*sn;this.a1=2*(A2-1-(A2+1)*cs);this.a2=A2+1-(A2-1)*cs-beta*sn}applyFilter(signal_step){let y2=this.b0*signal_step+this.b1*this.x1+this.b2*this.x2-this.a1*this.y1-this.a2*this.y2;this.x2=this.x1;this.x1=signal_step;this.y2=this.y1;this.y1=y2;return y2}zResult(freq){try{let phi=Math.pow(Math.sin(Math.PI*freq*2/(2*this.sps)),2);let result=(Math.pow(this.b0+this.b1+this.b2,2)-4*(this.b0*this.b1+4*this.b0*this.b2+this.b1*this.b2)*phi+16*this.b0*this.b2*phi*phi)/(Math.pow(1+this.a1+this.a2,2)-4*(this.a1+4*this.a2+this.a1*this.a2)*phi+16*this.a2*phi*phi);return result}catch(err){return-200}}static calcCenterFrequency(freqStart,freqEnd){return(freqStart+freqEnd)/2}static calcBandwidth(freqStart,freqEnd){return freqEnd-this.calcCenterFrequency(freqStart,freqEnd)}static calcBandpassQ(frequency,bandwidth,resonance=Math.pow(10,Math.floor(Math.log10(frequency)))){let Q=resonance*Math.sqrt((frequency-bandwidth)*(frequency+bandwidth))/(2*bandwidth);return Q}static calcNotchQ(frequency,bandwidth,resonance=Math.pow(10,Math.floor(Math.log10(frequency)))){let Q=resonance*frequency*bandwidth/Math.sqrt((frequency-bandwidth)*(frequency+bandwidth));return Q}};var beat_detect={refdata:[],lowpass:void 0,smoothed:[],timestamp:[],peaks:[],valleys:[],peak_distances:[],valley_distances:[],beats:[],lastPeak:0,lastValley:0,sps:100,maxFreq:4,limit:10,__onconnected:function(){if(!this.lowpass){let freq=this.maxFreq;if(!freq)freq=1;if(freq>1)freq*=.5;this.lowpass=new Biquad("lowpass",this.maxFreq,this.sps);this.peakFinderWindow=Math.floor(this.sps/this.maxFreq);if(this.peakFinderWindow%2===0)this.peakFinderWindow+=1;if(this.peakFinderWindow<5)this.peakFinderWindow=5;this.midpoint=Math.round(this.peakFinderWindow*.5)}},__operator:function(data){if(!("red"in data)&&!("heg"in data)&&!("raw"in data))return void 0;let refdata=data.red?data.red:data.heg?data.heg:data.raw;if(!("timestamp"in data)){if(Array.isArray(refdata)){let now=Date.now();let len;if(refdata)len=refdata.length;let toInterp=[now-refdata.length*this.sps*1e3,now];data.timestamp=Math2.upsample(toInterp,refdata.length)}else{data.timestamp=Date.now()}}let pass=(amplitude,timestamp)=>{if(amplitude){this.refdata.push(amplitude)}this.timestamp.push(timestamp);let beat;if(this.refdata.length>this.peakFinderWindow){this.refdata.shift();this.timestamp.shift()}this.smoothed.push(this.lowpass.applyFilter(this.refdata[this.refdata.length-1]));if(this.smoothed.length>this.peakFinderWindow){this.smoothed.shift()}if(this.smoothed.length===this.peakFinderWindow){if(Math2.isExtrema(this.smoothed,"valley")){this.valleys.push({value:this.smoothed[this.smoothed.length-this.midpoint?this.midpoint:1],timestamp:this.timestamp[this.timestamp.length-this.midpoint?this.midpoint:1]})}else if(Math2.isExtrema(this.smoothed,"peak")){this.peaks.push({value:this.smoothed[this.smoothed.length-this.midpoint?this.midpoint:1],timestamp:this.timestamp[this.timestamp.length-this.midpoint?this.midpoint:1]})}if(this.valleys.length>2&&this.peaks.length>2){if(this.valleys[this.valleys.length-1].timestamp1&&this.valley_distances.length>1){if(this.lastPeakthis.peak_distances[this.peak_distances.length-1].timestamp){let bpm,change=0;if(this.beats.length<1){bpm=60/(5e-4*(this.peak_distances[this.peak_distances.length-1].distance+this.valley_distances[this.valley_distances.length-1].distance))}else if(this.beats[this.beats.length-1].timestamp!==this.peak_distances[this.peak_distances.length-1].timestamp){bpm=60/(5e-4*(this.peak_distances[this.peak_distances.length-1].dt+this.valley_distances[this.valley_distances.length-1].dt));change=Math.abs(bpm-this.beats[this.beats.length-1].bpm)}beat={timestamp:this.peak_distances[this.peak_distances.length-1].timestamp,change,bpm,height0:this.peak_distances[this.peak_distances.length-1].peak0-this.valley_distances[this.valley_distances.length-1].peak0,height1:this.peak_distances[this.peak_distances.length-1].peak1-this.valley_distances[this.valley_distances.length-1].peak1};this.beats.push(beat);this.lastPeak=this.peaks[this.peaks.length-1].timestamp;this.lastValley=this.peaks[this.peaks.length-1].timestamp}else{let bpm,change=0;if(this.beats.length<2){bpm=60/(5e-4*(this.peak_distances[this.peak_distances.length-2].distance+this.valley_distances[this.valley_distances.length-2].distance))}else if(this.beats[this.beats.length-1].timestamp!==this.peak_distances[this.peak_distances.length-2].timestamp){bpm=60/(5e-4*(this.peak_distances[this.peak_distances.length-2].distance+this.valley_distances[this.valley_distances.length-2].distance));change=Math.abs(bpm-this.beats[this.beats.length-2].bpm)}beat={timestamp:this.peak_distances[this.peak_distances.length-2].timestamp,change,bpm,height0:this.peak_distances[this.peak_distances.length-2].peak0-this.valley_distances[this.valley_distances.length-2].peak0,height1:this.peak_distances[this.peak_distances.length-2].peak1-this.valley_distances[this.valley_distances.length-2].peak1};if(Array.isArray(beat.timestamp))beat.timestamp=beat.timestamp[0];this.beats.push(beat);this.lastPeak=this.peaks[this.peaks.length-1].timestamp;this.lastValley=this.peaks[this.peaks.length-1].timestamp}}}if(this.peaks.length>this.limit){this.peaks.shift()}if(this.valleys.length>this.limit){this.valleys.shift()}if(this.peak_distances.length>this.limit){this.peak_distances.shift()}if(this.valley_distances.length>this.limit){this.valley_distances.shift()}if(this.beats.length>this.limit){this.beats.shift()}}}return beat};if(data.red){if("ir"in data&&!Array.isArray(data.red))return pass(data.red+data.ir,data.timestamp);let result;if(data.ir)result=data.red.map((v2,i)=>{return pass(v2+data.ir[i],data.timestamp[i])}).filter(v2=>{if(v2)return true});else result=data.red.map((v2,i)=>{return pass(v2,data.timestamp[i])}).filter(v2=>{if(v2)return true});return result}else if(data.raw){if(!Array.isArray(data.raw))return pass(data.raw,data.timestamp);let result=data.raw.map((v2,i)=>{return pass(v2,data.timestamp[i])}).filter(v2=>{if(v2)return true});return result}else if(Array.isArray(data.heg)){if(!Array.isArray(data.heg))return pass(data.heg,data.timestamp);let result=data.heg.map((v2,i)=>{return pass(v2,data.timestamp[i])}).filter(v2=>{if(v2)return true});return result}}};var blink_detect={sps:250,intervals:{},watch:["0"],tolerance:.2,__onconnected:node=>{node.watch.forEach(ch=>node.intervals[ch]={lowpass:new Biquad("lowpass",20,node.sps),filtered:[],averaged:[]})},__operator:function(data){let checkCt=5;let averageCt=50;let found={};let passed=false;let pass=(key,n)=>{let next=this.intervals[key].lowpass.applyFilter(n);this.intervals[key].filtered.push(next);this.intervals[key].averaged.push(next);if(this.intervals[key].filtered.length>checkCt){if(this.intervals[key].averaged.length>averageCt){this.intervals[key].averaged.splice(0,checkCt);let mean=Math2.mean(this.intervals[key].averaged);if(Math.abs(Math.min(...this.intervals[key].filtered))>Math.abs(mean)+this.tolerance){this.intervals[key].filtered.length=0;passed=true;found[key]=true}}else this.intervals[key].filtered.shift()}};for(const key in this.intervals){if(data[key]){if(Array.isArray(data[key])){data[key].forEach(n=>{pass(key,n)})}else if(typeof data[key]==="number")pass(key,data[key])}}if(passed)return found}};var ArrayManip=class _ArrayManip{static autoscale(array,lineIdx=0,nLines=1,centerZero=false,ymin,ymax,clamp){if(array?.length===0)return array;let max=ymax?ymax:Math.max(...array);let min=ymin?ymin:Math.min(...array);let _lines=1/nLines;let scalar=1;if(centerZero){let absmax=Math.max(Math.abs(min),Math.abs(max));if(absmax!==0)scalar=_lines/absmax;return array.map(y2=>{if(clamp){if(y2max)y2=max}return y2*scalar+(_lines*(lineIdx+1)*2-1-_lines)})}else{if(max===min){if(max!==0){scalar=_lines/max}else if(min!==0){scalar=_lines/Math.abs(min)}}else scalar=_lines/(max-min);return array.map(y2=>{if(clamp){if(y2max)y2=max}return 2*((y2-min)*scalar-1/(2*nLines))+(_lines*(lineIdx+1)*2-1-_lines)})}}static genTimestamps(ct,sps){let now=Date.now();let toInterp=[now-ct*1e3/sps,now];return _ArrayManip.upsample(toInterp,ct)}static absmax(array){return Math.max(Math.abs(Math.min(...array)),Math.max(...array))}static downsample(array,fitCount,scalar=1){if(array.length>fitCount){let output=new Array(fitCount);let incr=array.length/fitCount;let lastIdx=array.length-1;let last=0;let counter=0;for(let i=incr;ilastIdx)rounded=lastIdx;for(let j=last;jfitCount){return _ArrayManip.downsample(array,fitCount,scalar)}else if(array.lengtharr.length){let len=arr.length;arr.splice(0,len,...newEntries.slice(newEntries.length-len))}else{arr.splice(0,arr.length,...newEntries)}return arr}static reformatData(data,key){if(Array.isArray(data)){if(Array.isArray(data[0])){let d2={};data.forEach((arr,i)=>{d2[i]=arr});data=d2;if(isNaN(data[0][0]))return void 0}else if(key){data={[key]:data};if(isNaN(data[key][0]))return void 0}else{data={0:data};if(isNaN(data[0][0]))return void 0}}else if(typeof data==="object"){for(const key2 in data){if(typeof data[key2]==="number")data[key2]=[data[key2]];else if(data[key2]?.values){if(typeof data[key2].values==="number")data[key2].values=[data[key2].values]}if(isNaN(data[key2][0]))return void 0}}else if(typeof data==="string"){let split;if(data.includes("\r\n")){let lines=data.split("\r\n");data={};lines.forEach((l,j)=>{if(l.includes(" ")){split=l.split(" ")}else if(l.includes(",")){split=l.split(",")}else if(l.includes("|")){split=l.split("|")}if(Array.isArray(split)){split.forEach((val,i)=>{if(val.includes(":")){let[key2,v2]=val.split(":");let fl=parseFloat(v2);if(fl)data[key2]=[fl];else return void 0}else{let fl=parseFloat(val);if(fl)data[i]=[fl];else return void 0}})}})}else if(data.includes(" ")){split=data.split(" ")}else if(data.includes(",")){split=data.split(",")}else if(data.includes("|")){split=data.split("|")}data={};if(Array.isArray(split)){split.forEach((val,i)=>{if(val.includes(":")){let[key2,v2]=val.split(":");let fl=parseFloat(v2);if(fl)data[key2]=[fl];else return void 0}else{let fl=parseFloat(val);if(fl)data[i]=[fl];else return void 0}})}}else if(typeof data==="number"){if(key)data={[key]:[data]};else data={0:[data]}}return data}static padTime(data,lastValue,time,targetFit){let slopeIncr=(data[0]-lastValue)/time/targetFit;let padded=[...new Array(targetFit-data.length).map((_,i)=>lastValue+slopeIncr*(i+1)),...data];return padded}static interpolateForTime(data,time,targetSPS){return _ArrayManip.interpolate(data,Math.ceil(targetSPS*time))}static bufferValues=(objects,property,keys,buffer)=>{if(!Array.isArray(keys)&&typeof keys==="object")keys=Object.keys(keys);if(!buffer){let object_keys=Object.keys(objects);if(keys)buffer=new Float32Array(object_keys.length*keys.length);else{if(typeof objects[object_keys[0]][property]==="object"){keys=Object.keys(objects[object_keys[0]][property]);buffer=new Float32Array(object_keys.length*keys.length)}else buffer=new Float32Array(object_keys.length)}}let i=0;for(const key in objects){if(objects[key][property]){if(keys){for(let j=0;j{for(const key in obj){if(typeof obj[key]==="object"){if(typeof target[key]==="object")this.recursivelyAssign(target[key],obj[key]);else target[key]=this.recursivelyAssign({},obj[key])}else target[key]=obj[key]}return target};spliceTypedArray(arr,start,end){let s=arr.subarray(0,start);let e;if(end){e=arr.subarray(end+1)}let n;if(s.length>0||e?.length>0)n=new arr.constructor(s.length+e.length);if(s.length>0)n.set(s);if(e&&e.length>0)n.set(e,s.length);return n}};var rechk=/^([<>])?(([1-9]\d*)?([xcbB?hHiIfdsp]))*$/;var refmt=/([1-9]\d*)?([xcbB?hHiIfdsp])/g;var str=(v2,o,c)=>String.fromCharCode(...new Uint8Array(v2.buffer,v2.byteOffset+o,c));var rts=(v2,o,c,s)=>new Uint8Array(v2.buffer,v2.byteOffset+o,c).set(s.split("").map(str2=>str2.charCodeAt(0)));var pst=(v2,o,c)=>str(v2,o+1,Math.min(v2.getUint8(o),c-1));var tsp=(v2,o,c,s)=>{v2.setUint8(o,s.length);rts(v2,o+1,c-1,s)};var lut=le=>({x:c=>[1,c,0],c:c=>[c,1,o=>({u:v2=>str(v2,o,1),p:(v2,c2)=>rts(v2,o,1,c2)})],"?":c=>[c,1,o=>({u:v2=>Boolean(v2.getUint8(o)),p:(v2,B)=>v2.setUint8(o,B)})],b:c=>[c,1,o=>({u:v2=>v2.getInt8(o),p:(v2,b)=>v2.setInt8(o,b)})],B:c=>[c,1,o=>({u:v2=>v2.getUint8(o),p:(v2,B)=>v2.setUint8(o,B)})],h:c=>[c,2,o=>({u:v2=>v2.getInt16(o,le),p:(v2,h)=>v2.setInt16(o,h,le)})],H:c=>[c,2,o=>({u:v2=>v2.getUint16(o,le),p:(v2,H)=>v2.setUint16(o,H,le)})],i:c=>[c,4,o=>({u:v2=>v2.getInt32(o,le),p:(v2,i)=>v2.setInt32(o,i,le)})],I:c=>[c,4,o=>({u:v2=>v2.getUint32(o,le),p:(v2,I)=>v2.setUint32(o,I,le)})],f:c=>[c,4,o=>({u:v2=>v2.getFloat32(o,le),p:(v2,f)=>v2.setFloat32(o,f,le)})],d:c=>[c,8,o=>({u:v2=>v2.getFloat64(o,le),p:(v2,d2)=>v2.setFloat64(o,d2,le)})],s:c=>[1,c,o=>({u:v2=>str(v2,o,c),p:(v2,s)=>rts(v2,o,c,s.slice(0,c))})],p:c=>[1,c,o=>({u:v2=>pst(v2,o,c),p:(v2,s)=>tsp(v2,o,c,s.slice(0,c-1))})]});var errbuf=new RangeError("Structure larger than remaining buffer");var errval=new RangeError("Not enough values for structure");var ByteParser=class _ByteParser extends ArrayManip{static codes={"\\n":10,"\\r":13,"\\t":9,"\\s":32,"\\b":8,"\\f":12,"\\":92};static toDataView(value){if(!(value instanceof DataView)){if(typeof value==="string"&&parseInt(value))value=parseInt(value);if(typeof value==="string"){let enc=new TextEncoder;let hascodes={};for(const code in _ByteParser.codes){while(value.indexOf(code)>-1){let idx=value.indexOf(code);value=value.replace(code,"");hascodes[idx]=code}}let encoded=Array.from(enc.encode(value));for(const key in hascodes){encoded.splice(parseInt(key),0,_ByteParser.codes[hascodes[key]])}value=new DataView(new Uint8Array(encoded).buffer)}else if(typeof value==="number"){let tmp=value;if(value<256){value=new DataView(new ArrayBuffer(1));value.setUint8(0,tmp)}else if(value<65536){value=new DataView(new ArrayBuffer(2));value.setInt16(0,tmp)}else{value=new DataView(new ArrayBuffer(4));value.setUint32(0,tmp)}}else if(value instanceof ArrayBuffer||typeof SharedArrayBuffer!=="undefined"&&value instanceof SharedArrayBuffer){value=new DataView(value)}else if(Array.isArray(value)){value=new DataView(Uint8Array.from(value).buffer)}else if(typeof value==="object"){value=new TextEncoder().encode(JSON.stringify(value))}}return value}static searchBuffer(buffer,searchString,limit){var needle=searchString;var haystack=buffer;var search=_ByteParser.boyerMoore(needle);var skip=search.byteLength;var indices=[];for(var i=search(haystack);i!==-1;i=search(haystack,i+skip)){indices.push(i);if(limit){if(indices.length>=limit)break}}return indices}static bytesToInt16(x0,x1){let int16=(255&x0)<<8|255&x1;if((int16&32768)>0){int16|=4294901760}else{int16&=65535}return int16}static bytesToUInt16(x0,x1){return x0*256+x1}static Uint16ToBytes(y2){return[y2&255,y2>>8&255]}static bytesToInt24(x0,x1,x22){let int24=(255&x0)<<16|(255&x1)<<8|255&x22;if((int24&8388608)>0){int24|=4278190080}else{int24&=16777215}return int24}static bytesToUInt24(x0,x1,x22){return x0*65536+x1*256+x22}static Uint24ToBytes(y2){return[y2&255,y2>>8&255,y2>>16&255]}static bytesToInt32(x0,x1,x22,x3){let int32=(255&x0)<<24|(255&x1)<<16|(255&x22)<<8|255&x3;if((int32&2147483648)>0){int32|=0}else{int32&=4294967295}return int32}static bytesToUInt32(x0,x1,x22,x3){return x0*16777216+x1*65536+x22*256+x3}static Uint32ToBytes(y2){return[y2&255,y2>>8&255,y2>>16&255,y2>>24&255]}static get2sCompliment(val,nbits){if(val>4294967296)return null;return val<<32-nbits>>32-nbits}static getSignedInt(...args){let pos=0;function getInt(size){var value=0;var first=true;while(size--){if(first){let byte=args[pos++];value+=byte&127;if(byte&128){value-=128}first=false}else{value*=256;value+=args[pos++]}}return value}return getInt(args.length)}static asUint8Array(input){if(input instanceof Uint8Array){return input}else if(typeof input==="string"){var arr=new Uint8Array(input.length);for(var i=0;i127){throw new TypeError("Only ASCII patterns are supported")}arr[i]=c}return arr}else{return new Uint8Array(input)}}static boyerMoore(patternBuffer){var pattern=_ByteParser.asUint8Array(patternBuffer);var M2=pattern.length;if(M2===0){throw new TypeError("patternBuffer must be at least 1 byte long")}var R2=256;var rightmost_positions=new Int32Array(R2);for(var c=0;c{var txt=_ByteParser.asUint8Array(txtBuffer);if(start===void 0)start=0;if(end===void 0)end=txt.length;var pat=pattern;var right=rightmost_positions;var lastIndex=end-pat.length;var lastPatIndex=pat.length-1;var skip;for(var i=start;i<=lastIndex;i+=skip){skip=0;for(var j2=lastPatIndex;j2>=0;j2--){var c2=txt[i+j2];if(pat[j2]!==c2){skip=Math.max(1,j2-right[c2]);break}}if(skip===0){return i}}return-1};boyerMooreSearch.byteLength=pattern.byteLength;return boyerMooreSearch}static struct(format){let fns=[],size=0,m=rechk.exec(format);if(!m){throw new RangeError("Invalid format string")}const t=lut("<"===m[1]),lu=(n,c)=>t[c](n?parseInt(n,10):1);while(m=refmt.exec(format)){((r,s,f)=>{for(let i=0;i{if(arrb.byteLength<(offs|0)+size){throw errbuf}let v2=new DataView(arrb,offs|0);return fns.map(f=>f.u(v2))};const pack_into=(arrb,offs,...values)=>{if(values.lengthf.p(v2,values[i]))};const pack=(...values)=>{let b=new ArrayBuffer(size);pack_into(b,0,...values);return b};const unpack=arrb=>unpack_from(arrb,0);function*iter_unpack(arrb){for(let offs=0;offs+size<=arrb.byteLength;offs+=size){yield unpack_from(arrb,offs)}}return Object.freeze({unpack,pack,unpack_from,pack_into,iter_unpack,format,size})}};var rms={sps:250,nSec:1,watch:["0","1","2","3"],data:{},rms:{},__operator:function(data){this.watch.forEach(key=>{if(data[key]){if(!this.data[key]){if(Array.isArray(data[key])){this.data[key]=new Array(Math.floor(this.sps*this.nSec)).fill(data[key][0])}else this.data[key]=new Array(Math.floor(this.sps*this.nSec)).fill(data[key])}ByteParser.circularBuffer(this.data[key],data[key])}});if(data.timestamp){if(Array.isArray(data.timestamp)){this.rms.timestamp=data.timestamp[data.timestamp.length-1]}else this.rms.timestamp=data.timestamp}else this.rms.timestamp=Date.now();return new Promise(async res=>{await Promise.all(this.watch.map(async key=>{if(this.data[key])this.rms[key]=Math.sqrt(Math.abs(this.data[key].reduce((p2,v2,i)=>p2+v2*v2)/this.data[key].length));else delete this.rms[key]}));res(this.rms)})}};var circularBuffer2d={bufferSize:250,watch:["0","1","2","3"],data:{},blocking:false,__onconnected:function(node){for(const key in node.watch){node.data[key]=new Array(node.bufferSize).fill(0)}},__operator:function(data){let buffer2d=[];this.watch.forEach(key=>{if(data[key]){ByteParser.circularBuffer(this.data[key],data[key]);buffer2d.push(this.data[key])}});return buffer2d}};var algorithms={beat_detect,accel_gyro,heartrate:beat_detect,breath:Object.assign({},beat_detect),blink_detect,rms,circularBuffer2d};algorithms["breath"].maxFreq=.2;})(); diff --git a/src/extras/dist/index.services.node.js b/src/extras/dist/index.services.node.js deleted file mode 100644 index fd7961ad..00000000 --- a/src/extras/dist/index.services.node.js +++ /dev/null @@ -1,32 +0,0 @@ -var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf;var __hasOwnProp=Object.prototype.hasOwnProperty;var __commonJS=(cb,mod)=>function __require(){return mod||(0,cb[__getOwnPropNames(cb)[0]])((mod={exports:{}}).exports,mod),mod.exports};var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from==="object"||typeof from==="function"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:true}):target,mod));var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:true}),mod);var require_bson=__commonJS({"struct/datastructures/bson.cjs"(exports2){"use strict";var BSON_MAJOR_VERSION=5;var BSON_INT32_MAX=2147483647;var BSON_INT32_MIN=-2147483648;var BSON_INT64_MAX=Math.pow(2,63)-1;var BSON_INT64_MIN=-Math.pow(2,63);var JS_INT_MAX=Math.pow(2,53);var JS_INT_MIN=-Math.pow(2,53);var BSON_DATA_NUMBER=1;var BSON_DATA_STRING=2;var BSON_DATA_OBJECT=3;var BSON_DATA_ARRAY=4;var BSON_DATA_BINARY=5;var BSON_DATA_UNDEFINED=6;var BSON_DATA_OID=7;var BSON_DATA_BOOLEAN=8;var BSON_DATA_DATE=9;var BSON_DATA_NULL=10;var BSON_DATA_REGEXP=11;var BSON_DATA_DBPOINTER=12;var BSON_DATA_CODE=13;var BSON_DATA_SYMBOL=14;var BSON_DATA_CODE_W_SCOPE=15;var BSON_DATA_INT=16;var BSON_DATA_TIMESTAMP=17;var BSON_DATA_LONG=18;var BSON_DATA_DECIMAL128=19;var BSON_DATA_MIN_KEY=255;var BSON_DATA_MAX_KEY=127;var BSON_BINARY_SUBTYPE_DEFAULT=0;var BSON_BINARY_SUBTYPE_UUID_NEW=4;var BSONType=Object.freeze({double:1,string:2,object:3,array:4,binData:5,undefined:6,objectId:7,bool:8,date:9,null:10,regex:11,dbPointer:12,javascript:13,symbol:14,javascriptWithScope:15,int:16,timestamp:17,long:18,decimal:19,minKey:-1,maxKey:127});var BSONError=class extends Error{get bsonError(){return true}get name(){return"BSONError"}constructor(message){super(message)}static isBSONError(value){return value!=null&&typeof value==="object"&&"bsonError"in value&&value.bsonError===true&&"name"in value&&"message"in value&&"stack"in value}};var BSONVersionError=class extends BSONError{get name(){return"BSONVersionError"}constructor(){super(`Unsupported BSON version, bson types must be from bson ${BSON_MAJOR_VERSION}.0 or later`)}};var BSONRuntimeError=class extends BSONError{get name(){return"BSONRuntimeError"}constructor(message){super(message)}};function nodejsMathRandomBytes(byteLength){return nodeJsByteUtils.fromNumberArray(Array.from({length:byteLength},()=>Math.floor(Math.random()*256)))}var nodejsRandomBytes=(()=>{try{return require("crypto").randomBytes}catch{return nodejsMathRandomBytes}})();var nodeJsByteUtils={toLocalBufferType(potentialBuffer){if(Buffer.isBuffer(potentialBuffer)){return potentialBuffer}if(ArrayBuffer.isView(potentialBuffer)){return Buffer.from(potentialBuffer.buffer,potentialBuffer.byteOffset,potentialBuffer.byteLength)}const stringTag=potentialBuffer?.[Symbol.toStringTag]??Object.prototype.toString.call(potentialBuffer);if(stringTag==="ArrayBuffer"||stringTag==="SharedArrayBuffer"||stringTag==="[object ArrayBuffer]"||stringTag==="[object SharedArrayBuffer]"){return Buffer.from(potentialBuffer)}throw new BSONError(`Cannot create Buffer from ${String(potentialBuffer)}`)},allocate(size){return Buffer.alloc(size)},equals(a,b){return nodeJsByteUtils.toLocalBufferType(a).equals(b)},fromNumberArray(array){return Buffer.from(array)},fromBase64(base64){return Buffer.from(base64,"base64")},toBase64(buffer2){return nodeJsByteUtils.toLocalBufferType(buffer2).toString("base64")},fromISO88591(codePoints){return Buffer.from(codePoints,"binary")},toISO88591(buffer2){return nodeJsByteUtils.toLocalBufferType(buffer2).toString("binary")},fromHex(hex){return Buffer.from(hex,"hex")},toHex(buffer2){return nodeJsByteUtils.toLocalBufferType(buffer2).toString("hex")},fromUTF8(text){return Buffer.from(text,"utf8")},toUTF8(buffer2){return nodeJsByteUtils.toLocalBufferType(buffer2).toString("utf8")},utf8ByteLength(input){return Buffer.byteLength(input,"utf8")},encodeUTF8Into(buffer2,source,byteOffset){return nodeJsByteUtils.toLocalBufferType(buffer2).write(source,byteOffset,void 0,"utf8")},randomBytes:nodejsRandomBytes};function isReactNative(){const{navigator}=globalThis;return typeof navigator==="object"&&navigator.product==="ReactNative"}function webMathRandomBytes(byteLength){if(byteLength<0){throw new RangeError(`The argument 'byteLength' is invalid. Received ${byteLength}`)}return webByteUtils.fromNumberArray(Array.from({length:byteLength},()=>Math.floor(Math.random()*256)))}var webRandomBytes=(()=>{const{crypto}=globalThis;if(crypto!=null&&typeof crypto.getRandomValues==="function"){return byteLength=>{return crypto.getRandomValues(webByteUtils.allocate(byteLength))}}else{if(isReactNative()){const{console:console2}=globalThis;console2?.warn?.("BSON: For React Native please polyfill crypto.getRandomValues, e.g. using: https://www.npmjs.com/package/react-native-get-random-values.")}return webMathRandomBytes}})();var HEX_DIGIT=/(\d|[a-f])/i;var webByteUtils={toLocalBufferType(potentialUint8array){const stringTag=potentialUint8array?.[Symbol.toStringTag]??Object.prototype.toString.call(potentialUint8array);if(stringTag==="Uint8Array"){return potentialUint8array}if(ArrayBuffer.isView(potentialUint8array)){return new Uint8Array(potentialUint8array.buffer.slice(potentialUint8array.byteOffset,potentialUint8array.byteOffset+potentialUint8array.byteLength))}if(stringTag==="ArrayBuffer"||stringTag==="SharedArrayBuffer"||stringTag==="[object ArrayBuffer]"||stringTag==="[object SharedArrayBuffer]"){return new Uint8Array(potentialUint8array)}throw new BSONError(`Cannot make a Uint8Array from ${String(potentialUint8array)}`)},allocate(size){if(typeof size!=="number"){throw new TypeError(`The "size" argument must be of type number. Received ${String(size)}`)}return new Uint8Array(size)},equals(a,b){if(a.byteLength!==b.byteLength){return false}for(let i=0;ic.charCodeAt(0))},toBase64(uint8array){return btoa(webByteUtils.toISO88591(uint8array))},fromISO88591(codePoints){return Uint8Array.from(codePoints,c=>c.charCodeAt(0)&255)},toISO88591(uint8array){return Array.from(Uint16Array.from(uint8array),b=>String.fromCharCode(b)).join("")},fromHex(hex){const evenLengthHex=hex.length%2===0?hex:hex.slice(0,hex.length-1);const buffer2=[];for(let i=0;ibyte.toString(16).padStart(2,"0")).join("")},fromUTF8(text){return new TextEncoder().encode(text)},toUTF8(uint8array){return new TextDecoder("utf8",{fatal:false}).decode(uint8array)},utf8ByteLength(input){return webByteUtils.fromUTF8(input).byteLength},encodeUTF8Into(buffer2,source,byteOffset){const bytes=webByteUtils.fromUTF8(source);buffer2.set(bytes,byteOffset);return bytes.byteLength},randomBytes:webRandomBytes};var hasGlobalBuffer=typeof Buffer==="function"&&Buffer.prototype?._isBuffer!==true;var ByteUtils=hasGlobalBuffer?nodeJsByteUtils:webByteUtils;var BSONDataView=class extends DataView{static fromUint8Array(input){return new DataView(input.buffer,input.byteOffset,input.byteLength)}};var VALIDATION_REGEX=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15})$/i;var uuidValidateString=str2=>typeof str2==="string"&&VALIDATION_REGEX.test(str2);var uuidHexStringToBuffer=hexString=>{if(!uuidValidateString(hexString)){throw new BSONError('UUID string representations must be a 32 or 36 character hex string (dashes excluded/included). Format: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" or "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".')}const sanitizedHexString=hexString.replace(/-/g,"");return ByteUtils.fromHex(sanitizedHexString)};function bufferToUuidHexString(buffer2,includeDashes=true){if(includeDashes){return[ByteUtils.toHex(buffer2.subarray(0,4)),ByteUtils.toHex(buffer2.subarray(4,6)),ByteUtils.toHex(buffer2.subarray(6,8)),ByteUtils.toHex(buffer2.subarray(8,10)),ByteUtils.toHex(buffer2.subarray(10,16))].join("-")}return ByteUtils.toHex(buffer2)}function isAnyArrayBuffer(value){return["[object ArrayBuffer]","[object SharedArrayBuffer]"].includes(Object.prototype.toString.call(value))}function isUint8Array(value){return Object.prototype.toString.call(value)==="[object Uint8Array]"}function isRegExp(d){return Object.prototype.toString.call(d)==="[object RegExp]"}function isMap(d){return Object.prototype.toString.call(d)==="[object Map]"}function isDate(d){return Object.prototype.toString.call(d)==="[object Date]"}var BSONValue=class{get[Symbol.for("@@mdb.bson.version")](){return BSON_MAJOR_VERSION}};var Binary=class _Binary extends BSONValue{get _bsontype(){return"Binary"}constructor(buffer2,subType){super();if(!(buffer2==null)&&!(typeof buffer2==="string")&&!ArrayBuffer.isView(buffer2)&&!(buffer2 instanceof ArrayBuffer)&&!Array.isArray(buffer2)){throw new BSONError("Binary can only be constructed from string, Buffer, TypedArray, or Array")}this.sub_type=subType??_Binary.BSON_BINARY_SUBTYPE_DEFAULT;if(buffer2==null){this.buffer=ByteUtils.allocate(_Binary.BUFFER_SIZE);this.position=0}else{if(typeof buffer2==="string"){this.buffer=ByteUtils.fromISO88591(buffer2)}else if(Array.isArray(buffer2)){this.buffer=ByteUtils.fromNumberArray(buffer2)}else{this.buffer=ByteUtils.toLocalBufferType(buffer2)}this.position=this.buffer.byteLength}}put(byteValue){if(typeof byteValue==="string"&&byteValue.length!==1){throw new BSONError("only accepts single character String")}else if(typeof byteValue!=="number"&&byteValue.length!==1)throw new BSONError("only accepts single character Uint8Array or Array");let decodedByte;if(typeof byteValue==="string"){decodedByte=byteValue.charCodeAt(0)}else if(typeof byteValue==="number"){decodedByte=byteValue}else{decodedByte=byteValue[0]}if(decodedByte<0||decodedByte>255){throw new BSONError("only accepts number in a valid unsigned byte range 0-255")}if(this.buffer.byteLength>this.position){this.buffer[this.position++]=decodedByte}else{const newSpace=ByteUtils.allocate(_Binary.BUFFER_SIZE+this.buffer.length);newSpace.set(this.buffer,0);this.buffer=newSpace;this.buffer[this.position++]=decodedByte}}write(sequence,offset){offset=typeof offset==="number"?offset:this.position;if(this.buffer.byteLengththis.position?offset+sequence.length:this.position}else if(typeof sequence==="string"){const bytes=ByteUtils.fromISO88591(sequence);this.buffer.set(bytes,offset);this.position=offset+sequence.length>this.position?offset+sequence.length:this.position}}read(position,length){length=length&&length>0?length:this.position;return this.buffer.slice(position,position+length)}value(asRaw){asRaw=!!asRaw;if(asRaw&&this.buffer.length===this.position){return this.buffer}if(asRaw){return this.buffer.slice(0,this.position)}return ByteUtils.toISO88591(this.buffer.subarray(0,this.position))}length(){return this.position}toJSON(){return ByteUtils.toBase64(this.buffer)}toString(encoding){if(encoding==="hex")return ByteUtils.toHex(this.buffer);if(encoding==="base64")return ByteUtils.toBase64(this.buffer);if(encoding==="utf8"||encoding==="utf-8")return ByteUtils.toUTF8(this.buffer);return ByteUtils.toUTF8(this.buffer)}toExtendedJSON(options){options=options||{};const base64String=ByteUtils.toBase64(this.buffer);const subType=Number(this.sub_type).toString(16);if(options.legacy){return{$binary:base64String,$type:subType.length===1?"0"+subType:subType}}return{$binary:{base64:base64String,subType:subType.length===1?"0"+subType:subType}}}toUUID(){if(this.sub_type===_Binary.SUBTYPE_UUID){return new UUID(this.buffer.slice(0,this.position))}throw new BSONError(`Binary sub_type "${this.sub_type}" is not supported for converting to UUID. Only "${_Binary.SUBTYPE_UUID}" is currently supported.`)}static fromExtendedJSON(doc,options){options=options||{};let data;let type;if("$binary"in doc){if(options.legacy&&typeof doc.$binary==="string"&&"$type"in doc){type=doc.$type?parseInt(doc.$type,16):0;data=ByteUtils.fromBase64(doc.$binary)}else{if(typeof doc.$binary!=="string"){type=doc.$binary.subType?parseInt(doc.$binary.subType,16):0;data=ByteUtils.fromBase64(doc.$binary.base64)}}}else if("$uuid"in doc){type=4;data=uuidHexStringToBuffer(doc.$uuid)}if(!data){throw new BSONError(`Unexpected Binary Extended JSON format ${JSON.stringify(doc)}`)}return type===BSON_BINARY_SUBTYPE_UUID_NEW?new UUID(data):new _Binary(data,type)}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){return`new Binary(Buffer.from("${ByteUtils.toHex(this.buffer)}", "hex"), ${this.sub_type})`}};Binary.BSON_BINARY_SUBTYPE_DEFAULT=0;Binary.BUFFER_SIZE=256;Binary.SUBTYPE_DEFAULT=0;Binary.SUBTYPE_FUNCTION=1;Binary.SUBTYPE_BYTE_ARRAY=2;Binary.SUBTYPE_UUID_OLD=3;Binary.SUBTYPE_UUID=4;Binary.SUBTYPE_MD5=5;Binary.SUBTYPE_ENCRYPTED=6;Binary.SUBTYPE_COLUMN=7;Binary.SUBTYPE_USER_DEFINED=128;var UUID_BYTE_LENGTH=16;var UUID=class _UUID extends Binary{constructor(input){let bytes;let hexStr;if(input==null){bytes=_UUID.generate()}else if(input instanceof _UUID){bytes=ByteUtils.toLocalBufferType(new Uint8Array(input.buffer));hexStr=input.__id}else if(ArrayBuffer.isView(input)&&input.byteLength===UUID_BYTE_LENGTH){bytes=ByteUtils.toLocalBufferType(input)}else if(typeof input==="string"){bytes=uuidHexStringToBuffer(input)}else{throw new BSONError("Argument passed in UUID constructor must be a UUID, a 16 byte Buffer or a 32/36 character hex string (dashes excluded/included, format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).")}super(bytes,BSON_BINARY_SUBTYPE_UUID_NEW);this.__id=hexStr}get id(){return this.buffer}set id(value){this.buffer=value;if(_UUID.cacheHexString){this.__id=bufferToUuidHexString(value)}}toHexString(includeDashes=true){if(_UUID.cacheHexString&&this.__id){return this.__id}const uuidHexString=bufferToUuidHexString(this.id,includeDashes);if(_UUID.cacheHexString){this.__id=uuidHexString}return uuidHexString}toString(encoding){if(encoding==="hex")return ByteUtils.toHex(this.id);if(encoding==="base64")return ByteUtils.toBase64(this.id);return this.toHexString()}toJSON(){return this.toHexString()}equals(otherId){if(!otherId){return false}if(otherId instanceof _UUID){return ByteUtils.equals(otherId.id,this.id)}try{return ByteUtils.equals(new _UUID(otherId).id,this.id)}catch{return false}}toBinary(){return new Binary(this.id,Binary.SUBTYPE_UUID)}static generate(){const bytes=ByteUtils.randomBytes(UUID_BYTE_LENGTH);bytes[6]=bytes[6]&15|64;bytes[8]=bytes[8]&63|128;return bytes}static isValid(input){if(!input){return false}if(input instanceof _UUID){return true}if(typeof input==="string"){return uuidValidateString(input)}if(isUint8Array(input)){if(input.byteLength!==UUID_BYTE_LENGTH){return false}return(input[6]&240)===64&&(input[8]&128)===128}return false}static createFromHexString(hexString){const buffer2=uuidHexStringToBuffer(hexString);return new _UUID(buffer2)}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){return`new UUID("${this.toHexString()}")`}};var Code=class _Code extends BSONValue{get _bsontype(){return"Code"}constructor(code,scope){super();this.code=code.toString();this.scope=scope??null}toJSON(){if(this.scope!=null){return{code:this.code,scope:this.scope}}return{code:this.code}}toExtendedJSON(){if(this.scope){return{$code:this.code,$scope:this.scope}}return{$code:this.code}}static fromExtendedJSON(doc){return new _Code(doc.$code,doc.$scope)}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){const codeJson=this.toJSON();return`new Code("${String(codeJson.code)}"${codeJson.scope!=null?`, ${JSON.stringify(codeJson.scope)}`:""})`}};function isDBRefLike(value){return value!=null&&typeof value==="object"&&"$id"in value&&value.$id!=null&&"$ref"in value&&typeof value.$ref==="string"&&(!("$db"in value)||"$db"in value&&typeof value.$db==="string")}var DBRef=class _DBRef extends BSONValue{get _bsontype(){return"DBRef"}constructor(collection,oid,db,fields){super();const parts=collection.split(".");if(parts.length===2){db=parts.shift();collection=parts.shift()}this.collection=collection;this.oid=oid;this.db=db;this.fields=fields||{}}get namespace(){return this.collection}set namespace(value){this.collection=value}toJSON(){const o=Object.assign({$ref:this.collection,$id:this.oid},this.fields);if(this.db!=null)o.$db=this.db;return o}toExtendedJSON(options){options=options||{};let o={$ref:this.collection,$id:this.oid};if(options.legacy){return o}if(this.db)o.$db=this.db;o=Object.assign(o,this.fields);return o}static fromExtendedJSON(doc){const copy=Object.assign({},doc);delete copy.$ref;delete copy.$id;delete copy.$db;return new _DBRef(doc.$ref,doc.$id,doc.$db,copy)}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){const oid=this.oid===void 0||this.oid.toString===void 0?this.oid:this.oid.toString();return`new DBRef("${this.namespace}", new ObjectId("${String(oid)}")${this.db?`, "${this.db}"`:""})`}};var wasm=void 0;try{wasm=new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0,97,115,109,1,0,0,0,1,13,2,96,0,1,127,96,4,127,127,127,127,1,127,3,7,6,0,1,1,1,1,1,6,6,1,127,1,65,0,11,7,50,6,3,109,117,108,0,1,5,100,105,118,95,115,0,2,5,100,105,118,95,117,0,3,5,114,101,109,95,115,0,4,5,114,101,109,95,117,0,5,8,103,101,116,95,104,105,103,104,0,0,10,191,1,6,4,0,35,0,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,126,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,127,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,128,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,129,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,130,34,4,66,32,135,167,36,0,32,4,167,11])),{}).exports}catch{}var TWO_PWR_16_DBL=1<<16;var TWO_PWR_24_DBL=1<<24;var TWO_PWR_32_DBL=TWO_PWR_16_DBL*TWO_PWR_16_DBL;var TWO_PWR_64_DBL=TWO_PWR_32_DBL*TWO_PWR_32_DBL;var TWO_PWR_63_DBL=TWO_PWR_64_DBL/2;var INT_CACHE={};var UINT_CACHE={};var MAX_INT64_STRING_LENGTH=20;var DECIMAL_REG_EX=/^(\+?0|(\+|-)?[1-9][0-9]*)$/;var Long=class _Long extends BSONValue{get _bsontype(){return"Long"}get __isLong__(){return true}constructor(low=0,high,unsigned){super();if(typeof low==="bigint"){Object.assign(this,_Long.fromBigInt(low,!!high))}else if(typeof low==="string"){Object.assign(this,_Long.fromString(low,!!high))}else{this.low=low|0;this.high=high|0;this.unsigned=!!unsigned}}static fromBits(lowBits,highBits,unsigned){return new _Long(lowBits,highBits,unsigned)}static fromInt(value,unsigned){let obj,cachedObj,cache;if(unsigned){value>>>=0;if(cache=0<=value&&value<256){cachedObj=UINT_CACHE[value];if(cachedObj)return cachedObj}obj=_Long.fromBits(value,(value|0)<0?-1:0,true);if(cache)UINT_CACHE[value]=obj;return obj}else{value|=0;if(cache=-128<=value&&value<128){cachedObj=INT_CACHE[value];if(cachedObj)return cachedObj}obj=_Long.fromBits(value,value<0?-1:0,false);if(cache)INT_CACHE[value]=obj;return obj}}static fromNumber(value,unsigned){if(isNaN(value))return unsigned?_Long.UZERO:_Long.ZERO;if(unsigned){if(value<0)return _Long.UZERO;if(value>=TWO_PWR_64_DBL)return _Long.MAX_UNSIGNED_VALUE}else{if(value<=-TWO_PWR_63_DBL)return _Long.MIN_VALUE;if(value+1>=TWO_PWR_63_DBL)return _Long.MAX_VALUE}if(value<0)return _Long.fromNumber(-value,unsigned).neg();return _Long.fromBits(value%TWO_PWR_32_DBL|0,value/TWO_PWR_32_DBL|0,unsigned)}static fromBigInt(value,unsigned){return _Long.fromString(value.toString(),unsigned)}static fromString(str2,unsigned,radix){if(str2.length===0)throw new BSONError("empty string");if(str2==="NaN"||str2==="Infinity"||str2==="+Infinity"||str2==="-Infinity")return _Long.ZERO;if(typeof unsigned==="number"){radix=unsigned,unsigned=false}else{unsigned=!!unsigned}radix=radix||10;if(radix<2||360)throw new BSONError("interior hyphen");else if(p===0){return _Long.fromString(str2.substring(1),unsigned,radix).neg()}const radixToPower=_Long.fromNumber(Math.pow(radix,8));let result=_Long.ZERO;for(let i=0;i>>16;const a32=this.high&65535;const a16=this.low>>>16;const a00=this.low&65535;const b48=addend.high>>>16;const b32=addend.high&65535;const b16=addend.low>>>16;const b00=addend.low&65535;let c48=0,c32=0,c16=0,c00=0;c00+=a00+b00;c16+=c00>>>16;c00&=65535;c16+=a16+b16;c32+=c16>>>16;c16&=65535;c32+=a32+b32;c48+=c32>>>16;c32&=65535;c48+=a48+b48;c48&=65535;return _Long.fromBits(c16<<16|c00,c48<<16|c32,this.unsigned)}and(other){if(!_Long.isLong(other))other=_Long.fromValue(other);return _Long.fromBits(this.low&other.low,this.high&other.high,this.unsigned)}compare(other){if(!_Long.isLong(other))other=_Long.fromValue(other);if(this.eq(other))return 0;const thisNeg=this.isNegative(),otherNeg=other.isNegative();if(thisNeg&&!otherNeg)return-1;if(!thisNeg&&otherNeg)return 1;if(!this.unsigned)return this.sub(other).isNegative()?-1:1;return other.high>>>0>this.high>>>0||other.high===this.high&&other.low>>>0>this.low>>>0?-1:1}comp(other){return this.compare(other)}divide(divisor){if(!_Long.isLong(divisor))divisor=_Long.fromValue(divisor);if(divisor.isZero())throw new BSONError("division by zero");if(wasm){if(!this.unsigned&&this.high===-2147483648&&divisor.low===-1&&divisor.high===-1){return this}const low=(this.unsigned?wasm.div_u:wasm.div_s)(this.low,this.high,divisor.low,divisor.high);return _Long.fromBits(low,wasm.get_high(),this.unsigned)}if(this.isZero())return this.unsigned?_Long.UZERO:_Long.ZERO;let approx,rem,res;if(!this.unsigned){if(this.eq(_Long.MIN_VALUE)){if(divisor.eq(_Long.ONE)||divisor.eq(_Long.NEG_ONE))return _Long.MIN_VALUE;else if(divisor.eq(_Long.MIN_VALUE))return _Long.ONE;else{const halfThis=this.shr(1);approx=halfThis.div(divisor).shl(1);if(approx.eq(_Long.ZERO)){return divisor.isNegative()?_Long.ONE:_Long.NEG_ONE}else{rem=this.sub(divisor.mul(approx));res=approx.add(rem.div(divisor));return res}}}else if(divisor.eq(_Long.MIN_VALUE))return this.unsigned?_Long.UZERO:_Long.ZERO;if(this.isNegative()){if(divisor.isNegative())return this.neg().div(divisor.neg());return this.neg().div(divisor).neg()}else if(divisor.isNegative())return this.div(divisor.neg()).neg();res=_Long.ZERO}else{if(!divisor.unsigned)divisor=divisor.toUnsigned();if(divisor.gt(this))return _Long.UZERO;if(divisor.gt(this.shru(1)))return _Long.UONE;res=_Long.UZERO}rem=this;while(rem.gte(divisor)){approx=Math.max(1,Math.floor(rem.toNumber()/divisor.toNumber()));const log2=Math.ceil(Math.log(approx)/Math.LN2);const delta=log2<=48?1:Math.pow(2,log2-48);let approxRes=_Long.fromNumber(approx);let approxRem=approxRes.mul(divisor);while(approxRem.isNegative()||approxRem.gt(rem)){approx-=delta;approxRes=_Long.fromNumber(approx,this.unsigned);approxRem=approxRes.mul(divisor)}if(approxRes.isZero())approxRes=_Long.ONE;res=res.add(approxRes);rem=rem.sub(approxRem)}return res}div(divisor){return this.divide(divisor)}equals(other){if(!_Long.isLong(other))other=_Long.fromValue(other);if(this.unsigned!==other.unsigned&&this.high>>>31===1&&other.high>>>31===1)return false;return this.high===other.high&&this.low===other.low}eq(other){return this.equals(other)}getHighBits(){return this.high}getHighBitsUnsigned(){return this.high>>>0}getLowBits(){return this.low}getLowBitsUnsigned(){return this.low>>>0}getNumBitsAbs(){if(this.isNegative()){return this.eq(_Long.MIN_VALUE)?64:this.neg().getNumBitsAbs()}const val=this.high!==0?this.high:this.low;let bit;for(bit=31;bit>0;bit--)if((val&1<0}gt(other){return this.greaterThan(other)}greaterThanOrEqual(other){return this.comp(other)>=0}gte(other){return this.greaterThanOrEqual(other)}ge(other){return this.greaterThanOrEqual(other)}isEven(){return(this.low&1)===0}isNegative(){return!this.unsigned&&this.high<0}isOdd(){return(this.low&1)===1}isPositive(){return this.unsigned||this.high>=0}isZero(){return this.high===0&&this.low===0}lessThan(other){return this.comp(other)<0}lt(other){return this.lessThan(other)}lessThanOrEqual(other){return this.comp(other)<=0}lte(other){return this.lessThanOrEqual(other)}modulo(divisor){if(!_Long.isLong(divisor))divisor=_Long.fromValue(divisor);if(wasm){const low=(this.unsigned?wasm.rem_u:wasm.rem_s)(this.low,this.high,divisor.low,divisor.high);return _Long.fromBits(low,wasm.get_high(),this.unsigned)}return this.sub(this.div(divisor).mul(divisor))}mod(divisor){return this.modulo(divisor)}rem(divisor){return this.modulo(divisor)}multiply(multiplier){if(this.isZero())return _Long.ZERO;if(!_Long.isLong(multiplier))multiplier=_Long.fromValue(multiplier);if(wasm){const low=wasm.mul(this.low,this.high,multiplier.low,multiplier.high);return _Long.fromBits(low,wasm.get_high(),this.unsigned)}if(multiplier.isZero())return _Long.ZERO;if(this.eq(_Long.MIN_VALUE))return multiplier.isOdd()?_Long.MIN_VALUE:_Long.ZERO;if(multiplier.eq(_Long.MIN_VALUE))return this.isOdd()?_Long.MIN_VALUE:_Long.ZERO;if(this.isNegative()){if(multiplier.isNegative())return this.neg().mul(multiplier.neg());else return this.neg().mul(multiplier).neg()}else if(multiplier.isNegative())return this.mul(multiplier.neg()).neg();if(this.lt(_Long.TWO_PWR_24)&&multiplier.lt(_Long.TWO_PWR_24))return _Long.fromNumber(this.toNumber()*multiplier.toNumber(),this.unsigned);const a48=this.high>>>16;const a32=this.high&65535;const a16=this.low>>>16;const a00=this.low&65535;const b48=multiplier.high>>>16;const b32=multiplier.high&65535;const b16=multiplier.low>>>16;const b00=multiplier.low&65535;let c48=0,c32=0,c16=0,c00=0;c00+=a00*b00;c16+=c00>>>16;c00&=65535;c16+=a16*b00;c32+=c16>>>16;c16&=65535;c16+=a00*b16;c32+=c16>>>16;c16&=65535;c32+=a32*b00;c48+=c32>>>16;c32&=65535;c32+=a16*b16;c48+=c32>>>16;c32&=65535;c32+=a00*b32;c48+=c32>>>16;c32&=65535;c48+=a48*b00+a32*b16+a16*b32+a00*b48;c48&=65535;return _Long.fromBits(c16<<16|c00,c48<<16|c32,this.unsigned)}mul(multiplier){return this.multiply(multiplier)}negate(){if(!this.unsigned&&this.eq(_Long.MIN_VALUE))return _Long.MIN_VALUE;return this.not().add(_Long.ONE)}neg(){return this.negate()}not(){return _Long.fromBits(~this.low,~this.high,this.unsigned)}notEquals(other){return!this.equals(other)}neq(other){return this.notEquals(other)}ne(other){return this.notEquals(other)}or(other){if(!_Long.isLong(other))other=_Long.fromValue(other);return _Long.fromBits(this.low|other.low,this.high|other.high,this.unsigned)}shiftLeft(numBits){if(_Long.isLong(numBits))numBits=numBits.toInt();if((numBits&=63)===0)return this;else if(numBits<32)return _Long.fromBits(this.low<>>32-numBits,this.unsigned);else return _Long.fromBits(0,this.low<>>numBits|this.high<<32-numBits,this.high>>numBits,this.unsigned);else return _Long.fromBits(this.high>>numBits-32,this.high>=0?0:-1,this.unsigned)}shr(numBits){return this.shiftRight(numBits)}shiftRightUnsigned(numBits){if(_Long.isLong(numBits))numBits=numBits.toInt();numBits&=63;if(numBits===0)return this;else{const high=this.high;if(numBits<32){const low=this.low;return _Long.fromBits(low>>>numBits|high<<32-numBits,high>>>numBits,this.unsigned)}else if(numBits===32)return _Long.fromBits(high,0,this.unsigned);else return _Long.fromBits(high>>>numBits-32,0,this.unsigned)}}shr_u(numBits){return this.shiftRightUnsigned(numBits)}shru(numBits){return this.shiftRightUnsigned(numBits)}subtract(subtrahend){if(!_Long.isLong(subtrahend))subtrahend=_Long.fromValue(subtrahend);return this.add(subtrahend.neg())}sub(subtrahend){return this.subtract(subtrahend)}toInt(){return this.unsigned?this.low>>>0:this.low}toNumber(){if(this.unsigned)return(this.high>>>0)*TWO_PWR_32_DBL+(this.low>>>0);return this.high*TWO_PWR_32_DBL+(this.low>>>0)}toBigInt(){return BigInt(this.toString())}toBytes(le){return le?this.toBytesLE():this.toBytesBE()}toBytesLE(){const hi=this.high,lo=this.low;return[lo&255,lo>>>8&255,lo>>>16&255,lo>>>24,hi&255,hi>>>8&255,hi>>>16&255,hi>>>24]}toBytesBE(){const hi=this.high,lo=this.low;return[hi>>>24,hi>>>16&255,hi>>>8&255,hi&255,lo>>>24,lo>>>16&255,lo>>>8&255,lo&255]}toSigned(){if(!this.unsigned)return this;return _Long.fromBits(this.low,this.high,false)}toString(radix){radix=radix||10;if(radix<2||36>>0;let digits=intval.toString(radix);rem=remDiv;if(rem.isZero()){return digits+result}else{while(digits.length<6)digits="0"+digits;result=""+digits+result}}}toUnsigned(){if(this.unsigned)return this;return _Long.fromBits(this.low,this.high,true)}xor(other){if(!_Long.isLong(other))other=_Long.fromValue(other);return _Long.fromBits(this.low^other.low,this.high^other.high,this.unsigned)}eqz(){return this.isZero()}le(other){return this.lessThanOrEqual(other)}toExtendedJSON(options){if(options&&options.relaxed)return this.toNumber();return{$numberLong:this.toString()}}static fromExtendedJSON(doc,options){const{useBigInt64=false,relaxed=true}={...options};if(doc.$numberLong.length>MAX_INT64_STRING_LENGTH){throw new BSONError("$numberLong string is too long")}if(!DECIMAL_REG_EX.test(doc.$numberLong)){throw new BSONError(`$numberLong string "${doc.$numberLong}" is in an invalid format`)}if(useBigInt64){const bigIntResult=BigInt(doc.$numberLong);return BigInt.asIntN(64,bigIntResult)}const longResult=_Long.fromString(doc.$numberLong);if(relaxed){return longResult.toNumber()}return longResult}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){return`new Long("${this.toString()}"${this.unsigned?", true":""})`}};Long.TWO_PWR_24=Long.fromInt(TWO_PWR_24_DBL);Long.MAX_UNSIGNED_VALUE=Long.fromBits(4294967295|0,4294967295|0,true);Long.ZERO=Long.fromInt(0);Long.UZERO=Long.fromInt(0,true);Long.ONE=Long.fromInt(1);Long.UONE=Long.fromInt(1,true);Long.NEG_ONE=Long.fromInt(-1);Long.MAX_VALUE=Long.fromBits(4294967295|0,2147483647|0,false);Long.MIN_VALUE=Long.fromBits(0,2147483648|0,false);var PARSE_STRING_REGEXP=/^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/;var PARSE_INF_REGEXP=/^(\+|-)?(Infinity|inf)$/i;var PARSE_NAN_REGEXP=/^(\+|-)?NaN$/i;var EXPONENT_MAX=6111;var EXPONENT_MIN=-6176;var EXPONENT_BIAS=6176;var MAX_DIGITS=34;var NAN_BUFFER=ByteUtils.fromNumberArray([124,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].reverse());var INF_NEGATIVE_BUFFER=ByteUtils.fromNumberArray([248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].reverse());var INF_POSITIVE_BUFFER=ByteUtils.fromNumberArray([120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].reverse());var EXPONENT_REGEX=/^([-+])?(\d+)?$/;var COMBINATION_MASK=31;var EXPONENT_MASK=16383;var COMBINATION_INFINITY=30;var COMBINATION_NAN=31;function isDigit(value){return!isNaN(parseInt(value,10))}function divideu128(value){const DIVISOR=Long.fromNumber(1e3*1e3*1e3);let _rem=Long.fromNumber(0);if(!value.parts[0]&&!value.parts[1]&&!value.parts[2]&&!value.parts[3]){return{quotient:value,rem:_rem}}for(let i=0;i<=3;i++){_rem=_rem.shiftLeft(32);_rem=_rem.add(new Long(value.parts[i],0));value.parts[i]=_rem.div(DIVISOR).low;_rem=_rem.modulo(DIVISOR)}return{quotient:value,rem:_rem}}function multiply64x2(left,right){if(!left&&!right){return{high:Long.fromNumber(0),low:Long.fromNumber(0)}}const leftHigh=left.shiftRightUnsigned(32);const leftLow=new Long(left.getLowBits(),0);const rightHigh=right.shiftRightUnsigned(32);const rightLow=new Long(right.getLowBits(),0);let productHigh=leftHigh.multiply(rightHigh);let productMid=leftHigh.multiply(rightLow);const productMid2=leftLow.multiply(rightHigh);let productLow=leftLow.multiply(rightLow);productHigh=productHigh.add(productMid.shiftRightUnsigned(32));productMid=new Long(productMid.getLowBits(),0).add(productMid2).add(productLow.shiftRightUnsigned(32));productHigh=productHigh.add(productMid.shiftRightUnsigned(32));productLow=productMid.shiftLeft(32).add(new Long(productLow.getLowBits(),0));return{high:productHigh,low:productLow}}function lessThan(left,right){const uhleft=left.high>>>0;const uhright=right.high>>>0;if(uhleft>>0;const ulright=right.low>>>0;if(ulleft=7e3){throw new BSONError(""+representation+" not a valid Decimal128 string")}const stringMatch=representation.match(PARSE_STRING_REGEXP);const infMatch=representation.match(PARSE_INF_REGEXP);const nanMatch=representation.match(PARSE_NAN_REGEXP);if(!stringMatch&&!infMatch&&!nanMatch||representation.length===0){throw new BSONError(""+representation+" not a valid Decimal128 string")}if(stringMatch){const unsignedNumber=stringMatch[2];const e=stringMatch[4];const expSign=stringMatch[5];const expNumber=stringMatch[6];if(e&&expNumber===void 0)invalidErr(representation,"missing exponent power");if(e&&unsignedNumber===void 0)invalidErr(representation,"missing exponent base");if(e===void 0&&(expSign||expNumber)){invalidErr(representation,"missing e before exponent")}}if(representation[index]==="+"||representation[index]==="-"){isNegative=representation[index++]==="-"}if(!isDigit(representation[index])&&representation[index]!=="."){if(representation[index]==="i"||representation[index]==="I"){return new _Decimal128(isNegative?INF_NEGATIVE_BUFFER:INF_POSITIVE_BUFFER)}else if(representation[index]==="N"){return new _Decimal128(NAN_BUFFER)}}while(isDigit(representation[index])||representation[index]==="."){if(representation[index]==="."){if(sawRadix)invalidErr(representation,"contains multiple periods");sawRadix=true;index=index+1;continue}if(nDigitsStored<34){if(representation[index]!=="0"||foundNonZero){if(!foundNonZero){firstNonZero=nDigitsRead}foundNonZero=true;digits[digitsInsert++]=parseInt(representation[index],10);nDigitsStored=nDigitsStored+1}}if(foundNonZero)nDigits=nDigits+1;if(sawRadix)radixPosition=radixPosition+1;nDigitsRead=nDigitsRead+1;index=index+1}if(sawRadix&&!nDigitsRead)throw new BSONError(""+representation+" not a valid Decimal128 string");if(representation[index]==="e"||representation[index]==="E"){const match=representation.substr(++index).match(EXPONENT_REGEX);if(!match||!match[2])return new _Decimal128(NAN_BUFFER);exponent=parseInt(match[0],10);index=index+match[0].length}if(representation[index])return new _Decimal128(NAN_BUFFER);firstDigit=0;if(!nDigitsStored){firstDigit=0;lastDigit=0;digits[0]=0;nDigits=1;nDigitsStored=1;significantDigits=0}else{lastDigit=nDigitsStored-1;significantDigits=nDigits;if(significantDigits!==1){while(digits[firstNonZero+significantDigits-1]===0){significantDigits=significantDigits-1}}}if(exponent<=radixPosition&&radixPosition-exponent>1<<14){exponent=EXPONENT_MIN}else{exponent=exponent-radixPosition}while(exponent>EXPONENT_MAX){lastDigit=lastDigit+1;if(lastDigit-firstDigit>MAX_DIGITS){const digitsString=digits.join("");if(digitsString.match(/^0+$/)){exponent=EXPONENT_MAX;break}invalidErr(representation,"overflow")}exponent=exponent-1}while(exponent=5){roundBit=1;if(roundDigit===5){roundBit=digits[lastDigit]%2===1?1:0;for(i=firstNonZero+lastDigit+2;i=0;dIdx--){if(++digits[dIdx]>9){digits[dIdx]=0;if(dIdx===0){if(exponent>8&255;buffer2[index++]=dec.low.low>>16&255;buffer2[index++]=dec.low.low>>24&255;buffer2[index++]=dec.low.high&255;buffer2[index++]=dec.low.high>>8&255;buffer2[index++]=dec.low.high>>16&255;buffer2[index++]=dec.low.high>>24&255;buffer2[index++]=dec.high.low&255;buffer2[index++]=dec.high.low>>8&255;buffer2[index++]=dec.high.low>>16&255;buffer2[index++]=dec.high.low>>24&255;buffer2[index++]=dec.high.high&255;buffer2[index++]=dec.high.high>>8&255;buffer2[index++]=dec.high.high>>16&255;buffer2[index++]=dec.high.high>>24&255;return new _Decimal128(buffer2)}toString(){let biased_exponent;let significand_digits=0;const significand=new Array(36);for(let i=0;i>26&COMBINATION_MASK;if(combination>>3===3){if(combination===COMBINATION_INFINITY){return string.join("")+"Infinity"}else if(combination===COMBINATION_NAN){return"NaN"}else{biased_exponent=high>>15&EXPONENT_MASK;significand_msb=8+(high>>14&1)}}else{significand_msb=high>>14&7;biased_exponent=high>>17&EXPONENT_MASK}const exponent=biased_exponent-EXPONENT_BIAS;significand128.parts[0]=(high&16383)+((significand_msb&15)<<14);significand128.parts[1]=midh;significand128.parts[2]=midl;significand128.parts[3]=low;if(significand128.parts[0]===0&&significand128.parts[1]===0&&significand128.parts[2]===0&&significand128.parts[3]===0){is_zero=true}else{for(k=3;k>=0;k--){let least_digits=0;const result=divideu128(significand128);significand128=result.quotient;least_digits=result.rem.low;if(!least_digits)continue;for(j=8;j>=0;j--){significand[k*9+j]=least_digits%10;least_digits=Math.floor(least_digits/10)}}}if(is_zero){significand_digits=1;significand[index]=0}else{significand_digits=36;while(!significand[index]){significand_digits=significand_digits-1;index=index+1}}const scientific_exponent=significand_digits-1+exponent;if(scientific_exponent>=34||scientific_exponent<=-7||exponent>0){if(significand_digits>34){string.push(`${0}`);if(exponent>0)string.push(`E+${exponent}`);else if(exponent<0)string.push(`E${exponent}`);return string.join("")}string.push(`${significand[index++]}`);significand_digits=significand_digits-1;if(significand_digits){string.push(".")}for(let i=0;i0){string.push(`+${scientific_exponent}`)}else{string.push(`${scientific_exponent}`)}}else{if(exponent>=0){for(let i=0;i0){for(let i=0;i>8&255;buffer2[9]=inc>>16&255;return buffer2}toString(encoding){if(encoding==="base64")return ByteUtils.toBase64(this.id);if(encoding==="hex")return this.toHexString();return this.toHexString()}toJSON(){return this.toHexString()}equals(otherId){if(otherId===void 0||otherId===null){return false}if(otherId instanceof _ObjectId){return this[kId][11]===otherId[kId][11]&&ByteUtils.equals(this[kId],otherId[kId])}if(typeof otherId==="string"&&_ObjectId.isValid(otherId)&&otherId.length===12&&isUint8Array(this.id)){return ByteUtils.equals(this.id,ByteUtils.fromISO88591(otherId))}if(typeof otherId==="string"&&_ObjectId.isValid(otherId)&&otherId.length===24){return otherId.toLowerCase()===this.toHexString()}if(typeof otherId==="string"&&_ObjectId.isValid(otherId)&&otherId.length===12){return ByteUtils.equals(ByteUtils.fromUTF8(otherId),this.id)}if(typeof otherId==="object"&&"toHexString"in otherId&&typeof otherId.toHexString==="function"){const otherIdString=otherId.toHexString();const thisIdString=this.toHexString().toLowerCase();return typeof otherIdString==="string"&&otherIdString.toLowerCase()===thisIdString}return false}getTimestamp(){const timestamp=new Date;const time=BSONDataView.fromUint8Array(this.id).getUint32(0,false);timestamp.setTime(Math.floor(time)*1e3);return timestamp}static createPk(){return new _ObjectId}static createFromTime(time){const buffer2=ByteUtils.fromNumberArray([0,0,0,0,0,0,0,0,0,0,0,0]);BSONDataView.fromUint8Array(buffer2).setUint32(0,time,false);return new _ObjectId(buffer2)}static createFromHexString(hexString){if(typeof hexString==="undefined"||hexString!=null&&hexString.length!==24){throw new BSONError("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters")}return new _ObjectId(ByteUtils.fromHex(hexString))}static isValid(id){if(id==null)return false;try{new _ObjectId(id);return true}catch{return false}}toExtendedJSON(){if(this.toHexString)return{$oid:this.toHexString()};return{$oid:this.toString("hex")}}static fromExtendedJSON(doc){return new _ObjectId(doc.$oid)}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){return`new ObjectId("${this.toHexString()}")`}};ObjectId2.index=Math.floor(Math.random()*16777215);function internalCalculateObjectSize(object,serializeFunctions,ignoreUndefined){let totalLength=4+1;if(Array.isArray(object)){for(let i=0;i=JS_INT_MIN&&value<=JS_INT_MAX){if(value>=BSON_INT32_MIN&&value<=BSON_INT32_MAX){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(4+1)}else{return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(8+1)}}else{return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(8+1)}case"undefined":if(isArray||!ignoreUndefined)return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1;return 0;case"boolean":return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(1+1);case"object":if(value!=null&&typeof value._bsontype==="string"&&value[Symbol.for("@@mdb.bson.version")]!==BSON_MAJOR_VERSION){throw new BSONVersionError}else if(value==null||value._bsontype==="MinKey"||value._bsontype==="MaxKey"){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1}else if(value._bsontype==="ObjectId"){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(12+1)}else if(value instanceof Date||isDate(value)){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(8+1)}else if(ArrayBuffer.isView(value)||value instanceof ArrayBuffer||isAnyArrayBuffer(value)){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(1+4+1)+value.byteLength}else if(value._bsontype==="Long"||value._bsontype==="Double"||value._bsontype==="Timestamp"){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(8+1)}else if(value._bsontype==="Decimal128"){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(16+1)}else if(value._bsontype==="Code"){if(value.scope!=null&&Object.keys(value.scope).length>0){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1+4+4+ByteUtils.utf8ByteLength(value.code.toString())+1+internalCalculateObjectSize(value.scope,serializeFunctions,ignoreUndefined)}else{return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1+4+ByteUtils.utf8ByteLength(value.code.toString())+1}}else if(value._bsontype==="Binary"){const binary=value;if(binary.sub_type===Binary.SUBTYPE_BYTE_ARRAY){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(binary.position+1+4+1+4)}else{return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+(binary.position+1+4+1)}}else if(value._bsontype==="Symbol"){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+ByteUtils.utf8ByteLength(value.value)+4+1+1}else if(value._bsontype==="DBRef"){const ordered_values=Object.assign({$ref:value.collection,$id:value.oid},value.fields);if(value.db!=null){ordered_values["$db"]=value.db}return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1+internalCalculateObjectSize(ordered_values,serializeFunctions,ignoreUndefined)}else if(value instanceof RegExp||isRegExp(value)){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1+ByteUtils.utf8ByteLength(value.source)+1+(value.global?1:0)+(value.ignoreCase?1:0)+(value.multiline?1:0)+1}else if(value._bsontype==="BSONRegExp"){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1+ByteUtils.utf8ByteLength(value.pattern)+1+ByteUtils.utf8ByteLength(value.options)+1}else{return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+internalCalculateObjectSize(value,serializeFunctions,ignoreUndefined)+1}case"function":if(serializeFunctions){return(name!=null?ByteUtils.utf8ByteLength(name)+1:0)+1+4+ByteUtils.utf8ByteLength(value.toString())+1}}return 0}function alphabetize(str2){return str2.split("").sort().join("")}var BSONRegExp=class _BSONRegExp extends BSONValue{get _bsontype(){return"BSONRegExp"}constructor(pattern,options){super();this.pattern=pattern;this.options=alphabetize(options??"");if(this.pattern.indexOf("\0")!==-1){throw new BSONError(`BSON Regex patterns cannot contain null bytes, found: ${JSON.stringify(this.pattern)}`)}if(this.options.indexOf("\0")!==-1){throw new BSONError(`BSON Regex options cannot contain null bytes, found: ${JSON.stringify(this.options)}`)}for(let i=0;i4294967295){throw new BSONError("Timestamp constructed from { t, i } must provide t equal or less than uint32 max")}if(low.i>4294967295){throw new BSONError("Timestamp constructed from { t, i } must provide i equal or less than uint32 max")}super(low.i.valueOf(),low.t.valueOf(),true)}else{throw new BSONError("A Timestamp can only be constructed with: bigint, Long, or { t: number; i: number }")}}toJSON(){return{$timestamp:this.toString()}}static fromInt(value){return new _Timestamp(Long.fromInt(value,true))}static fromNumber(value){return new _Timestamp(Long.fromNumber(value,true))}static fromBits(lowBits,highBits){return new _Timestamp({i:lowBits,t:highBits})}static fromString(str2,optRadix){return new _Timestamp(Long.fromString(str2,true,optRadix))}toExtendedJSON(){return{$timestamp:{t:this.high>>>0,i:this.low>>>0}}}static fromExtendedJSON(doc){const i=Long.isLong(doc.$timestamp.i)?doc.$timestamp.i.getLowBitsUnsigned():doc.$timestamp.i;const t=Long.isLong(doc.$timestamp.t)?doc.$timestamp.t.getLowBitsUnsigned():doc.$timestamp.t;return new _Timestamp({t,i})}[Symbol.for("nodejs.util.inspect.custom")](){return this.inspect()}inspect(){return`new Timestamp({ t: ${this.getHighBits()}, i: ${this.getLowBits()} })`}};Timestamp.MAX_VALUE=Long.MAX_UNSIGNED_VALUE;var FIRST_BIT=128;var FIRST_TWO_BITS=192;var FIRST_THREE_BITS=224;var FIRST_FOUR_BITS=240;var FIRST_FIVE_BITS=248;var TWO_BIT_CHAR=192;var THREE_BIT_CHAR=224;var FOUR_BIT_CHAR=240;var CONTINUING_CHAR=128;function validateUtf8(bytes,start,end){let continuation=0;for(let i=start;i= 5, is ${size}`)}if(options.allowObjectSmallerThanBufferSize&&buffer2.length= bson size ${size}`)}if(!options.allowObjectSmallerThanBufferSize&&buffer2.length!==size){throw new BSONError(`buffer length ${buffer2.length} must === bson size ${size}`)}if(size+index>buffer2.byteLength){throw new BSONError(`(bson size ${size} + options.index ${index} must be <= buffer length ${buffer2.byteLength})`)}if(buffer2[index+size-1]!==0){throw new BSONError("One object, sized correctly, with a spot for an EOO, but the EOO isn't 0x00")}return deserializeObject(buffer2,index,options,isArray)}var allowedDBRefKeys=/^\$ref$|^\$id$|^\$db$/;function deserializeObject(buffer2,index,options,isArray=false){const fieldsAsRaw=options["fieldsAsRaw"]==null?null:options["fieldsAsRaw"];const raw=options["raw"]==null?false:options["raw"];const bsonRegExp=typeof options["bsonRegExp"]==="boolean"?options["bsonRegExp"]:false;const promoteBuffers=options.promoteBuffers??false;const promoteLongs=options.promoteLongs??true;const promoteValues=options.promoteValues??true;const useBigInt64=options.useBigInt64??false;if(useBigInt64&&!promoteValues){throw new BSONError("Must either request bigint or Long for int64 deserialization")}if(useBigInt64&&!promoteLongs){throw new BSONError("Must either request bigint or Long for int64 deserialization")}const validation=options.validation==null?{utf8:true}:options.validation;let globalUTFValidation=true;let validationSetting;const utf8KeysSet=new Set;const utf8ValidatedKeys=validation.utf8;if(typeof utf8ValidatedKeys==="boolean"){validationSetting=utf8ValidatedKeys}else{globalUTFValidation=false;const utf8ValidationValues=Object.keys(utf8ValidatedKeys).map(function(key){return utf8ValidatedKeys[key]});if(utf8ValidationValues.length===0){throw new BSONError("UTF-8 validation setting cannot be empty")}if(typeof utf8ValidationValues[0]!=="boolean"){throw new BSONError("Invalid UTF-8 validation option, must specify boolean values")}validationSetting=utf8ValidationValues[0];if(!utf8ValidationValues.every(item=>item===validationSetting)){throw new BSONError("Invalid UTF-8 validation option - keys must be all true or all false")}}if(!globalUTFValidation){for(const key of Object.keys(utf8ValidatedKeys)){utf8KeysSet.add(key)}}const startIndex=index;if(buffer2.length<5)throw new BSONError("corrupt bson message < 5 bytes long");const size=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(size<5||size>buffer2.length)throw new BSONError("corrupt bson message");const object=isArray?[]:{};let arrayIndex=0;const done=false;let isPossibleDBRef=isArray?false:null;const dataview=new DataView(buffer2.buffer,buffer2.byteOffset,buffer2.byteLength);while(!done){const elementType=buffer2[index++];if(elementType===0)break;let i=index;while(buffer2[i]!==0&&i=buffer2.byteLength)throw new BSONError("Bad BSON Document: illegal CString");const name=isArray?arrayIndex++:ByteUtils.toUTF8(buffer2.subarray(index,i));let shouldValidateKey=true;if(globalUTFValidation||utf8KeysSet.has(name)){shouldValidateKey=validationSetting}else{shouldValidateKey=!validationSetting}if(isPossibleDBRef!==false&&name[0]==="$"){isPossibleDBRef=allowedDBRefKeys.test(name)}let value;index=i+1;if(elementType===BSON_DATA_STRING){const stringSize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(stringSize<=0||stringSize>buffer2.length-index||buffer2[index+stringSize-1]!==0){throw new BSONError("bad string length in bson")}value=getValidatedString(buffer2,index,index+stringSize-1,shouldValidateKey);index=index+stringSize}else if(elementType===BSON_DATA_OID){const oid=ByteUtils.allocate(12);oid.set(buffer2.subarray(index,index+12));value=new ObjectId2(oid);index=index+12}else if(elementType===BSON_DATA_INT&&promoteValues===false){value=new Int32(buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24)}else if(elementType===BSON_DATA_INT){value=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24}else if(elementType===BSON_DATA_NUMBER&&promoteValues===false){value=new Double(dataview.getFloat64(index,true));index=index+8}else if(elementType===BSON_DATA_NUMBER){value=dataview.getFloat64(index,true);index=index+8}else if(elementType===BSON_DATA_DATE){const lowBits=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;const highBits=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;value=new Date(new Long(lowBits,highBits).toNumber())}else if(elementType===BSON_DATA_BOOLEAN){if(buffer2[index]!==0&&buffer2[index]!==1)throw new BSONError("illegal boolean type value");value=buffer2[index++]===1}else if(elementType===BSON_DATA_OBJECT){const _index=index;const objectSize=buffer2[index]|buffer2[index+1]<<8|buffer2[index+2]<<16|buffer2[index+3]<<24;if(objectSize<=0||objectSize>buffer2.length-index)throw new BSONError("bad embedded document length in bson");if(raw){value=buffer2.slice(index,index+objectSize)}else{let objectOptions=options;if(!globalUTFValidation){objectOptions={...options,validation:{utf8:shouldValidateKey}}}value=deserializeObject(buffer2,_index,objectOptions,false)}index=index+objectSize}else if(elementType===BSON_DATA_ARRAY){const _index=index;const objectSize=buffer2[index]|buffer2[index+1]<<8|buffer2[index+2]<<16|buffer2[index+3]<<24;let arrayOptions=options;const stopIndex=index+objectSize;if(fieldsAsRaw&&fieldsAsRaw[name]){arrayOptions={...options,raw:true}}if(!globalUTFValidation){arrayOptions={...arrayOptions,validation:{utf8:shouldValidateKey}}}value=deserializeObject(buffer2,_index,arrayOptions,true);index=index+objectSize;if(buffer2[index-1]!==0)throw new BSONError("invalid array terminator byte");if(index!==stopIndex)throw new BSONError("corrupted array bson")}else if(elementType===BSON_DATA_UNDEFINED){value=void 0}else if(elementType===BSON_DATA_NULL){value=null}else if(elementType===BSON_DATA_LONG){const dataview2=BSONDataView.fromUint8Array(buffer2.subarray(index,index+8));const lowBits=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;const highBits=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;const long=new Long(lowBits,highBits);if(useBigInt64){value=dataview2.getBigInt64(0,true)}else if(promoteLongs&&promoteValues===true){value=long.lessThanOrEqual(JS_INT_MAX_LONG)&&long.greaterThanOrEqual(JS_INT_MIN_LONG)?long.toNumber():long}else{value=long}}else if(elementType===BSON_DATA_DECIMAL128){const bytes=ByteUtils.allocate(16);bytes.set(buffer2.subarray(index,index+16),0);index=index+16;value=new Decimal128(bytes)}else if(elementType===BSON_DATA_BINARY){let binarySize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;const totalBinarySize=binarySize;const subType=buffer2[index++];if(binarySize<0)throw new BSONError("Negative binary type element size found");if(binarySize>buffer2.byteLength)throw new BSONError("Binary type size larger than document size");if(buffer2["slice"]!=null){if(subType===Binary.SUBTYPE_BYTE_ARRAY){binarySize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(binarySize<0)throw new BSONError("Negative binary type element size found for subtype 0x02");if(binarySize>totalBinarySize-4)throw new BSONError("Binary type with subtype 0x02 contains too long binary size");if(binarySizetotalBinarySize-4)throw new BSONError("Binary type with subtype 0x02 contains too long binary size");if(binarySize=buffer2.length)throw new BSONError("Bad BSON Document: illegal CString");const source=ByteUtils.toUTF8(buffer2.subarray(index,i));index=i+1;i=index;while(buffer2[i]!==0&&i=buffer2.length)throw new BSONError("Bad BSON Document: illegal CString");const regExpOptions=ByteUtils.toUTF8(buffer2.subarray(index,i));index=i+1;const optionsArray=new Array(regExpOptions.length);for(i=0;i=buffer2.length)throw new BSONError("Bad BSON Document: illegal CString");const source=ByteUtils.toUTF8(buffer2.subarray(index,i));index=i+1;i=index;while(buffer2[i]!==0&&i=buffer2.length)throw new BSONError("Bad BSON Document: illegal CString");const regExpOptions=ByteUtils.toUTF8(buffer2.subarray(index,i));index=i+1;value=new BSONRegExp(source,regExpOptions)}else if(elementType===BSON_DATA_SYMBOL){const stringSize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(stringSize<=0||stringSize>buffer2.length-index||buffer2[index+stringSize-1]!==0){throw new BSONError("bad string length in bson")}const symbol=getValidatedString(buffer2,index,index+stringSize-1,shouldValidateKey);value=promoteValues?symbol:new BSONSymbol(symbol);index=index+stringSize}else if(elementType===BSON_DATA_TIMESTAMP){const i2=buffer2[index++]+buffer2[index++]*(1<<8)+buffer2[index++]*(1<<16)+buffer2[index++]*(1<<24);const t=buffer2[index++]+buffer2[index++]*(1<<8)+buffer2[index++]*(1<<16)+buffer2[index++]*(1<<24);value=new Timestamp({i:i2,t})}else if(elementType===BSON_DATA_MIN_KEY){value=new MinKey}else if(elementType===BSON_DATA_MAX_KEY){value=new MaxKey}else if(elementType===BSON_DATA_CODE){const stringSize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(stringSize<=0||stringSize>buffer2.length-index||buffer2[index+stringSize-1]!==0){throw new BSONError("bad string length in bson")}const functionString=getValidatedString(buffer2,index,index+stringSize-1,shouldValidateKey);value=new Code(functionString);index=index+stringSize}else if(elementType===BSON_DATA_CODE_W_SCOPE){const totalSize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(totalSize<4+4+4+1){throw new BSONError("code_w_scope total size shorter minimum expected length")}const stringSize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(stringSize<=0||stringSize>buffer2.length-index||buffer2[index+stringSize-1]!==0){throw new BSONError("bad string length in bson")}const functionString=getValidatedString(buffer2,index,index+stringSize-1,shouldValidateKey);index=index+stringSize;const _index=index;const objectSize=buffer2[index]|buffer2[index+1]<<8|buffer2[index+2]<<16|buffer2[index+3]<<24;const scopeObject=deserializeObject(buffer2,_index,options,false);index=index+objectSize;if(totalSize<4+4+objectSize+stringSize){throw new BSONError("code_w_scope total size is too short, truncating scope")}if(totalSize>4+4+objectSize+stringSize){throw new BSONError("code_w_scope total size is too long, clips outer document")}value=new Code(functionString,scopeObject)}else if(elementType===BSON_DATA_DBPOINTER){const stringSize=buffer2[index++]|buffer2[index++]<<8|buffer2[index++]<<16|buffer2[index++]<<24;if(stringSize<=0||stringSize>buffer2.length-index||buffer2[index+stringSize-1]!==0)throw new BSONError("bad string length in bson");if(validation!=null&&validation.utf8){if(!validateUtf8(buffer2,index,index+stringSize-1)){throw new BSONError("Invalid UTF-8 string in BSON document")}}const namespace=ByteUtils.toUTF8(buffer2.subarray(index,index+stringSize-1));index=index+stringSize;const oidBuffer=ByteUtils.allocate(12);oidBuffer.set(buffer2.subarray(index,index+12),0);const oid=new ObjectId2(oidBuffer);index=index+12;value=new DBRef(namespace,oid)}else{throw new BSONError(`Detected unknown BSON type ${elementType.toString(16)} for fieldname "${name}"`)}if(name==="__proto__"){Object.defineProperty(object,name,{value,writable:true,enumerable:true,configurable:true})}else{object[name]=value}}if(size!==index-startIndex){if(isArray)throw new BSONError("corrupt array bson");throw new BSONError("corrupt object bson")}if(!isPossibleDBRef)return object;if(isDBRefLike(object)){const copy=Object.assign({},object);delete copy.$ref;delete copy.$id;delete copy.$db;return new DBRef(object.$ref,object.$id,object.$db,copy)}return object}function getValidatedString(buffer2,start,end,shouldValidateUtf8){const value=ByteUtils.toUTF8(buffer2.subarray(start,end));if(shouldValidateUtf8){for(let i=0;i>24&255;buffer2[index+2]=size+1>>16&255;buffer2[index+1]=size+1>>8&255;buffer2[index]=size+1&255;index=index+4+size;buffer2[index++]=0;return index}var NUMBER_SPACE=new DataView(new ArrayBuffer(8),0,8);var FOUR_BYTE_VIEW_ON_NUMBER=new Uint8Array(NUMBER_SPACE.buffer,0,4);var EIGHT_BYTE_VIEW_ON_NUMBER=new Uint8Array(NUMBER_SPACE.buffer,0,8);function serializeNumber(buffer2,key,value,index){const isNegativeZero=Object.is(value,-0);const type=!isNegativeZero&&Number.isSafeInteger(value)&&value<=BSON_INT32_MAX&&value>=BSON_INT32_MIN?BSON_DATA_INT:BSON_DATA_NUMBER;if(type===BSON_DATA_INT){NUMBER_SPACE.setInt32(0,value,true)}else{NUMBER_SPACE.setFloat64(0,value,true)}const bytes=type===BSON_DATA_INT?FOUR_BYTE_VIEW_ON_NUMBER:EIGHT_BYTE_VIEW_ON_NUMBER;buffer2[index++]=type;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;buffer2.set(bytes,index);index+=bytes.byteLength;return index}function serializeBigInt(buffer2,key,value,index){buffer2[index++]=BSON_DATA_LONG;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index+=numberOfWrittenBytes;buffer2[index++]=0;NUMBER_SPACE.setBigInt64(0,value,true);buffer2.set(EIGHT_BYTE_VIEW_ON_NUMBER,index);index+=EIGHT_BYTE_VIEW_ON_NUMBER.byteLength;return index}function serializeNull(buffer2,key,_,index){buffer2[index++]=BSON_DATA_NULL;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;return index}function serializeBoolean(buffer2,key,value,index){buffer2[index++]=BSON_DATA_BOOLEAN;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;buffer2[index++]=value?1:0;return index}function serializeDate(buffer2,key,value,index){buffer2[index++]=BSON_DATA_DATE;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const dateInMilis=Long.fromNumber(value.getTime());const lowBits=dateInMilis.getLowBits();const highBits=dateInMilis.getHighBits();buffer2[index++]=lowBits&255;buffer2[index++]=lowBits>>8&255;buffer2[index++]=lowBits>>16&255;buffer2[index++]=lowBits>>24&255;buffer2[index++]=highBits&255;buffer2[index++]=highBits>>8&255;buffer2[index++]=highBits>>16&255;buffer2[index++]=highBits>>24&255;return index}function serializeRegExp(buffer2,key,value,index){buffer2[index++]=BSON_DATA_REGEXP;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;if(value.source&&value.source.match(regexp)!=null){throw new BSONError("value "+value.source+" must not contain null bytes")}index=index+ByteUtils.encodeUTF8Into(buffer2,value.source,index);buffer2[index++]=0;if(value.ignoreCase)buffer2[index++]=105;if(value.global)buffer2[index++]=115;if(value.multiline)buffer2[index++]=109;buffer2[index++]=0;return index}function serializeBSONRegExp(buffer2,key,value,index){buffer2[index++]=BSON_DATA_REGEXP;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;if(value.pattern.match(regexp)!=null){throw new BSONError("pattern "+value.pattern+" must not contain null bytes")}index=index+ByteUtils.encodeUTF8Into(buffer2,value.pattern,index);buffer2[index++]=0;const sortedOptions=value.options.split("").sort().join("");index=index+ByteUtils.encodeUTF8Into(buffer2,sortedOptions,index);buffer2[index++]=0;return index}function serializeMinMax(buffer2,key,value,index){if(value===null){buffer2[index++]=BSON_DATA_NULL}else if(value._bsontype==="MinKey"){buffer2[index++]=BSON_DATA_MIN_KEY}else{buffer2[index++]=BSON_DATA_MAX_KEY}const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;return index}function serializeObjectId(buffer2,key,value,index){buffer2[index++]=BSON_DATA_OID;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;if(isUint8Array(value.id)){buffer2.set(value.id.subarray(0,12),index)}else{throw new BSONError("object ["+JSON.stringify(value)+"] is not a valid ObjectId")}return index+12}function serializeBuffer(buffer2,key,value,index){buffer2[index++]=BSON_DATA_BINARY;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const size=value.length;buffer2[index++]=size&255;buffer2[index++]=size>>8&255;buffer2[index++]=size>>16&255;buffer2[index++]=size>>24&255;buffer2[index++]=BSON_BINARY_SUBTYPE_DEFAULT;buffer2.set(value,index);index=index+size;return index}function serializeObject(buffer2,key,value,index,checkKeys,depth,serializeFunctions,ignoreUndefined,path){if(path.has(value)){throw new BSONError("Cannot convert circular structure to BSON")}path.add(value);buffer2[index++]=Array.isArray(value)?BSON_DATA_ARRAY:BSON_DATA_OBJECT;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const endIndex=serializeInto(buffer2,value,checkKeys,index,depth+1,serializeFunctions,ignoreUndefined,path);path.delete(value);return endIndex}function serializeDecimal128(buffer2,key,value,index){buffer2[index++]=BSON_DATA_DECIMAL128;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;buffer2.set(value.bytes.subarray(0,16),index);return index+16}function serializeLong(buffer2,key,value,index){buffer2[index++]=value._bsontype==="Long"?BSON_DATA_LONG:BSON_DATA_TIMESTAMP;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const lowBits=value.getLowBits();const highBits=value.getHighBits();buffer2[index++]=lowBits&255;buffer2[index++]=lowBits>>8&255;buffer2[index++]=lowBits>>16&255;buffer2[index++]=lowBits>>24&255;buffer2[index++]=highBits&255;buffer2[index++]=highBits>>8&255;buffer2[index++]=highBits>>16&255;buffer2[index++]=highBits>>24&255;return index}function serializeInt32(buffer2,key,value,index){value=value.valueOf();buffer2[index++]=BSON_DATA_INT;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;buffer2[index++]=value&255;buffer2[index++]=value>>8&255;buffer2[index++]=value>>16&255;buffer2[index++]=value>>24&255;return index}function serializeDouble(buffer2,key,value,index){buffer2[index++]=BSON_DATA_NUMBER;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;NUMBER_SPACE.setFloat64(0,value.value,true);buffer2.set(EIGHT_BYTE_VIEW_ON_NUMBER,index);index=index+8;return index}function serializeFunction(buffer2,key,value,index){buffer2[index++]=BSON_DATA_CODE;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const functionString=value.toString();const size=ByteUtils.encodeUTF8Into(buffer2,functionString,index+4)+1;buffer2[index]=size&255;buffer2[index+1]=size>>8&255;buffer2[index+2]=size>>16&255;buffer2[index+3]=size>>24&255;index=index+4+size-1;buffer2[index++]=0;return index}function serializeCode(buffer2,key,value,index,checkKeys=false,depth=0,serializeFunctions=false,ignoreUndefined=true,path){if(value.scope&&typeof value.scope==="object"){buffer2[index++]=BSON_DATA_CODE_W_SCOPE;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;let startIndex=index;const functionString=value.code;index=index+4;const codeSize=ByteUtils.encodeUTF8Into(buffer2,functionString,index+4)+1;buffer2[index]=codeSize&255;buffer2[index+1]=codeSize>>8&255;buffer2[index+2]=codeSize>>16&255;buffer2[index+3]=codeSize>>24&255;buffer2[index+4+codeSize-1]=0;index=index+codeSize+4;const endIndex=serializeInto(buffer2,value.scope,checkKeys,index,depth+1,serializeFunctions,ignoreUndefined,path);index=endIndex-1;const totalSize=endIndex-startIndex;buffer2[startIndex++]=totalSize&255;buffer2[startIndex++]=totalSize>>8&255;buffer2[startIndex++]=totalSize>>16&255;buffer2[startIndex++]=totalSize>>24&255;buffer2[index++]=0}else{buffer2[index++]=BSON_DATA_CODE;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const functionString=value.code.toString();const size=ByteUtils.encodeUTF8Into(buffer2,functionString,index+4)+1;buffer2[index]=size&255;buffer2[index+1]=size>>8&255;buffer2[index+2]=size>>16&255;buffer2[index+3]=size>>24&255;index=index+4+size-1;buffer2[index++]=0}return index}function serializeBinary(buffer2,key,value,index){buffer2[index++]=BSON_DATA_BINARY;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const data=value.buffer;let size=value.position;if(value.sub_type===Binary.SUBTYPE_BYTE_ARRAY)size=size+4;buffer2[index++]=size&255;buffer2[index++]=size>>8&255;buffer2[index++]=size>>16&255;buffer2[index++]=size>>24&255;buffer2[index++]=value.sub_type;if(value.sub_type===Binary.SUBTYPE_BYTE_ARRAY){size=size-4;buffer2[index++]=size&255;buffer2[index++]=size>>8&255;buffer2[index++]=size>>16&255;buffer2[index++]=size>>24&255}buffer2.set(data,index);index=index+value.position;return index}function serializeSymbol(buffer2,key,value,index){buffer2[index++]=BSON_DATA_SYMBOL;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;const size=ByteUtils.encodeUTF8Into(buffer2,value.value,index+4)+1;buffer2[index]=size&255;buffer2[index+1]=size>>8&255;buffer2[index+2]=size>>16&255;buffer2[index+3]=size>>24&255;index=index+4+size-1;buffer2[index++]=0;return index}function serializeDBRef(buffer2,key,value,index,depth,serializeFunctions,path){buffer2[index++]=BSON_DATA_OBJECT;const numberOfWrittenBytes=ByteUtils.encodeUTF8Into(buffer2,key,index);index=index+numberOfWrittenBytes;buffer2[index++]=0;let startIndex=index;let output={$ref:value.collection||value.namespace,$id:value.oid};if(value.db!=null){output.$db=value.db}output=Object.assign(output,value.fields);const endIndex=serializeInto(buffer2,output,false,index,depth+1,serializeFunctions,true,path);const size=endIndex-startIndex;buffer2[startIndex++]=size&255;buffer2[startIndex++]=size>>8&255;buffer2[startIndex++]=size>>16&255;buffer2[startIndex++]=size>>24&255;return endIndex}function serializeInto(buffer2,object,checkKeys,startingIndex,depth,serializeFunctions,ignoreUndefined,path){if(path==null){if(object==null){buffer2[0]=5;buffer2[1]=0;buffer2[2]=0;buffer2[3]=0;buffer2[4]=0;return 5}if(Array.isArray(object)){throw new BSONError("serialize does not support an array as the root input")}if(typeof object!=="object"){throw new BSONError("serialize does not support non-object as the root input")}else if("_bsontype"in object&&typeof object._bsontype==="string"){throw new BSONError(`BSON types cannot be serialized as a document`)}else if(isDate(object)||isRegExp(object)||isUint8Array(object)||isAnyArrayBuffer(object)){throw new BSONError(`date, regexp, typedarray, and arraybuffer cannot be BSON documents`)}path=new Set}path.add(object);let index=startingIndex+4;if(Array.isArray(object)){for(let i=0;i>8&255;buffer2[startingIndex++]=size>>16&255;buffer2[startingIndex++]=size>>24&255;return index}function isBSONType(value){return value!=null&&typeof value==="object"&&"_bsontype"in value&&typeof value._bsontype==="string"}var keysToCodecs={$oid:ObjectId2,$binary:Binary,$uuid:Binary,$symbol:BSONSymbol,$numberInt:Int32,$numberDecimal:Decimal128,$numberDouble:Double,$numberLong:Long,$minKey:MinKey,$maxKey:MaxKey,$regex:BSONRegExp,$regularExpression:BSONRegExp,$timestamp:Timestamp};function deserializeValue(value,options={}){if(typeof value==="number"){const in32BitRange=value<=BSON_INT32_MAX&&value>=BSON_INT32_MIN;const in64BitRange=value<=BSON_INT64_MAX&&value>=BSON_INT64_MIN;if(options.relaxed||options.legacy){return value}if(Number.isInteger(value)&&!Object.is(value,-0)){if(in32BitRange){return new Int32(value)}if(in64BitRange){if(options.useBigInt64){return BigInt(value)}return Long.fromNumber(value)}}return new Double(value)}if(value==null||typeof value!=="object")return value;if(value.$undefined)return null;const keys=Object.keys(value).filter(k=>k.startsWith("$")&&value[k]!=null);for(let i=0;ik.startsWith("$"));let valid=true;dollarKeys.forEach(k=>{if(["$ref","$id","$db"].indexOf(k)===-1)valid=false});if(valid)return DBRef.fromExtendedJSON(v)}return value}function serializeArray(array,options){return array.map((v,index)=>{options.seenObjects.push({propertyName:`index ${index}`,obj:null});try{return serializeValue(v,options)}finally{options.seenObjects.pop()}})}function getISOString(date){const isoStr=date.toISOString();return date.getUTCMilliseconds()!==0?isoStr:isoStr.slice(0,-5)+"Z"}function serializeValue(value,options){if(value instanceof Map||isMap(value)){const obj=Object.create(null);for(const[k,v]of value){if(typeof k!=="string"){throw new BSONError("Can only serialize maps with string keys")}obj[k]=v}return serializeValue(obj,options)}if((typeof value==="object"||typeof value==="function")&&value!==null){const index=options.seenObjects.findIndex(entry=>entry.obj===value);if(index!==-1){const props=options.seenObjects.map(entry=>entry.propertyName);const leadingPart=props.slice(0,index).map(prop=>`${prop} -> `).join("");const alreadySeen=props[index];const circularPart=" -> "+props.slice(index+1,props.length-1).map(prop=>`${prop} -> `).join("");const current=props[props.length-1];const leadingSpace=" ".repeat(leadingPart.length+alreadySeen.length/2);const dashes="-".repeat(circularPart.length+(alreadySeen.length+current.length)/2-1);throw new BSONError(`Converting circular structure to EJSON: - ${leadingPart}${alreadySeen}${circularPart}${current} - ${leadingSpace}\\${dashes}/`)}options.seenObjects[options.seenObjects.length-1].obj=value}if(Array.isArray(value))return serializeArray(value,options);if(value===void 0)return null;if(value instanceof Date||isDate(value)){const dateNum=value.getTime(),inRange=dateNum>-1&&dateNum<2534023188e5;if(options.legacy){return options.relaxed&&inRange?{$date:value.getTime()}:{$date:getISOString(value)}}return options.relaxed&&inRange?{$date:getISOString(value)}:{$date:{$numberLong:value.getTime().toString()}}}if(typeof value==="number"&&(!options.relaxed||!isFinite(value))){if(Number.isInteger(value)&&!Object.is(value,-0)){if(value>=BSON_INT32_MIN&&value<=BSON_INT32_MAX){return{$numberInt:value.toString()}}if(value>=BSON_INT64_MIN&&value<=BSON_INT64_MAX){return{$numberLong:value.toString()}}}return{$numberDouble:Object.is(value,-0)?"-0.0":value.toString()}}if(typeof value==="bigint"){if(!options.relaxed){return{$numberLong:BigInt.asIntN(64,value).toString()}}return Number(BigInt.asIntN(64,value))}if(value instanceof RegExp||isRegExp(value)){let flags=value.flags;if(flags===void 0){const match=value.toString().match(/[gimuy]*$/);if(match){flags=match[0]}}const rx=new BSONRegExp(value.source,flags);return rx.toExtendedJSON(options)}if(value!=null&&typeof value==="object")return serializeDocument(value,options);return value}var BSON_TYPE_MAPPINGS={Binary:o=>new Binary(o.value(),o.sub_type),Code:o=>new Code(o.code,o.scope),DBRef:o=>new DBRef(o.collection||o.namespace,o.oid,o.db,o.fields),Decimal128:o=>new Decimal128(o.bytes),Double:o=>new Double(o.value),Int32:o=>new Int32(o.value),Long:o=>Long.fromBits(o.low!=null?o.low:o.low_,o.low!=null?o.high:o.high_,o.low!=null?o.unsigned:o.unsigned_),MaxKey:()=>new MaxKey,MinKey:()=>new MinKey,ObjectId:o=>new ObjectId2(o),BSONRegExp:o=>new BSONRegExp(o.pattern,o.options),BSONSymbol:o=>new BSONSymbol(o.value),Timestamp:o=>Timestamp.fromBits(o.low,o.high)};function serializeDocument(doc,options){if(doc==null||typeof doc!=="object")throw new BSONError("not an object instance");const bsontype=doc._bsontype;if(typeof bsontype==="undefined"){const _doc={};for(const name of Object.keys(doc)){options.seenObjects.push({propertyName:name,obj:null});try{const value=serializeValue(doc[name],options);if(name==="__proto__"){Object.defineProperty(_doc,name,{value,writable:true,enumerable:true,configurable:true})}else{_doc[name]=value}}finally{options.seenObjects.pop()}}return _doc}else if(doc!=null&&typeof doc==="object"&&typeof doc._bsontype==="string"&&doc[Symbol.for("@@mdb.bson.version")]!==BSON_MAJOR_VERSION){throw new BSONVersionError}else if(isBSONType(doc)){let outDoc=doc;if(typeof outDoc.toExtendedJSON!=="function"){const mapper=BSON_TYPE_MAPPINGS[doc._bsontype];if(!mapper){throw new BSONError("Unrecognized or invalid _bsontype: "+doc._bsontype)}outDoc=mapper(outDoc)}if(bsontype==="Code"&&outDoc.scope){outDoc=new Code(outDoc.code,serializeValue(outDoc.scope,options))}else if(bsontype==="DBRef"&&outDoc.oid){outDoc=new DBRef(serializeValue(outDoc.collection,options),serializeValue(outDoc.oid,options),serializeValue(outDoc.db,options),serializeValue(outDoc.fields,options))}return outDoc.toExtendedJSON(options)}else{throw new BSONError("_bsontype must be a string, but was: "+typeof bsontype)}}function parse(text,options){const ejsonOptions={useBigInt64:options?.useBigInt64??false,relaxed:options?.relaxed??true,legacy:options?.legacy??false};return JSON.parse(text,(key,value)=>{if(key.indexOf("\0")!==-1){throw new BSONError(`BSON Document field names cannot contain null bytes, found: ${JSON.stringify(key)}`)}return deserializeValue(value,ejsonOptions)})}function stringify(value,replacer,space,options){if(space!=null&&typeof space==="object"){options=space;space=0}if(replacer!=null&&typeof replacer==="object"&&!Array.isArray(replacer)){options=replacer;replacer=void 0;space=0}const serializeOptions=Object.assign({relaxed:true,legacy:false},options,{seenObjects:[{propertyName:"(root)",obj:null}]});const doc=serializeValue(value,serializeOptions);return JSON.stringify(doc,replacer,space)}function EJSONserialize(value,options){options=options||{};return JSON.parse(stringify(value,options))}function EJSONdeserialize(ejson,options){options=options||{};return parse(JSON.stringify(ejson),options)}var EJSON=Object.create(null);EJSON.parse=parse;EJSON.stringify=stringify;EJSON.serialize=EJSONserialize;EJSON.deserialize=EJSONdeserialize;Object.freeze(EJSON);var MAXSIZE=1024*1024*17;var buffer=ByteUtils.allocate(MAXSIZE);function setInternalBufferSize(size){if(buffer.lengthStructBackend,StructFrontend:()=>StructFrontend,Systems:()=>Systems,WebglLinePlotInfo:()=>void 0,WebglLinePlotProps:()=>void 0,WebglLinePlotUtil:()=>void 0,WebglLineProps:()=>void 0,algorithms:()=>algorithms,defaultSpecifiers:()=>defaultSpecifiers,genTimeSpecifiers:()=>genTimeSpecifiers,genTimestampFromString:()=>genTimestampFromString,getStringId:()=>getStringId,pseudoObjectId:()=>pseudoObjectId,randomId:()=>randomId,setSignalControls:()=>setSignalControls,toObjectId:()=>toObjectId,webglPlotRoutes:()=>webglPlotRoutes});module.exports=__toCommonJS(index_services_exports);var DataStructures_exports={};__export(DataStructures_exports,{AuthorizationStruct:()=>AuthorizationStruct,ChatroomStruct:()=>ChatroomStruct,CoherenceMap:()=>CoherenceMap,CoherenceStruct:()=>CoherenceStruct,CommentStruct:()=>CommentStruct,Data:()=>Data,DataStruct:()=>DataStruct,DateStruct:()=>DateStruct,ECGStruct:()=>ECGStruct,EDAStruct:()=>EDAStruct,EEGCoordinates:()=>EEGCoordinates,EEGStruct:()=>EEGStruct,EMGStruct:()=>EMGStruct,EventStruct:()=>EventStruct,EyeTrackerStruct:()=>EyeTrackerStruct,FNIRSStruct:()=>FNIRSStruct,FrequencyBandsStruct:()=>FrequencyBandsStruct,GroupStruct:()=>GroupStruct,HRVStruct:()=>HRVStruct,IMUStruct:()=>IMUStruct,NotificationStruct:()=>NotificationStruct,PPGStruct:()=>PPGStruct,ProfileStruct:()=>ProfileStruct,ScheduleStruct:()=>ScheduleStruct,Struct:()=>Struct,eegCoordinates:()=>eegCoordinates,setCoordinate:()=>setCoordinate,structRegistry:()=>structRegistry});function Struct(structType="struct",assignProps={},parentUser={_id:""},parentStruct={structType:"struct",_id:""}){function randomId3(tag=""){return`${tag+Math.floor(Math.random()+Math.random()*Math.random()*1e16)}`}let struct={_id:randomId3(structType+"defaultId"),structType,ownerId:parentUser?._id,timestamp:Date.now(),parent:{structType:parentStruct?.structType,_id:parentStruct?._id}};if(!struct.ownerId)delete struct.ownerId;if(!struct?.parent?._id)delete struct.parent;if(Object.keys(assignProps).length>0)Object.assign(struct,assignProps);return struct}var eegCoordinates={FP1:[-21.2,66.9,12.1],FPZ:[1.4,65.1,11.3],FP2:[24.3,66.3,12.5],AF7:[-41.7,52.8,11.3],AF3:[-32.7,48.4,32.8],AFZ:[1.8,54.8,37.9],AF4:[35.1,50.1,31.1],AF8:[43.9,52.7,9.3],F5:[-51.4,26.7,24.7],F3:[-39.7,25.3,44.7],F1:[-22.1,26.8,54.9],FZ:[0,26.8,60.6],F2:[23.6,28.2,55.6],F4:[41.9,27.5,43.9],F6:[52.9,28.7,25.2],F7:[-52.1,28.6,3.8],F8:[53.2,28.4,3.1],FC5:[-59.1,3,26.1],FC3:[-45.5,2.4,51.3],FC1:[-24.7,.3,66.4],FCZ:[1,1,72.8],FC2:[26.1,3.2,66],FC4:[47.5,4.6,49.7],FC6:[60.5,4.9,25.5],FT9:[-53.8,-2.1,-29.1],FT7:[-59.2,3.4,-2.1],FT8:[60.2,4.7,-2.8],FT10:[55,-3.6,-31],T7:[-65.8,-17.8,-2.9],T5:[-61.5,-65.3,1.1],T3:[-70.2,-21.3,-10.7],T4:[71.9,-25.2,-8.2],T6:[59.3,-67.6,3.8],T8:[67.4,-18.5,-3.4],C5:[-63.6,-18.9,25.8],C3:[-49.1,-20.7,53.2],C1:[-25.1,-22.5,70.1],CZ:[.8,-21.9,77.4],C2:[26.7,-20.9,69.5],C4:[50.3,-18.8,53],C6:[65.2,-18,26.4],CP5:[-61.8,-46.2,22.5],CP3:[-46.9,-47.7,49.7],CP1:[-24,-49.1,66.1],CPZ:[.7,-47.9,72.6],CP2:[25.8,-47.1,66],CP4:[49.5,-45.5,50.7],CP6:[62.9,-44.6,24.4],TP9:[-73.6,-46.7,-4],TP7:[-63.6,-44.7,-4],TP8:[64.6,-45.4,-3.7],TP10:[74.6,-47.4,-3.7],P9:[-50.8,-51.3,-37.7],P7:[-55.9,-64.8,0],P5:[-52.7,-67.1,19.9],P3:[-41.4,-67.8,42.4],P1:[-21.6,-71.3,52.6],PZ:[.7,-69.3,56.9],P2:[24.4,-69.9,53.5],P4:[44.2,-65.8,42.7],P6:[54.4,-65.3,20.2],P8:[56.4,-64.4,.1],P10:[51,-53.9,-36.5],PO7:[-44,-81.7,1.6],PO3:[-33.3,-84.3,26.5],POZ:[0,-87.9,33.5],PO4:[35.2,-82.6,26.1],PO8:[43.3,-82,.7],O1:[-25.8,-93.3,7.7],OZ:[.3,-97.1,8.7],O2:[25,-95.2,6.2]};function setCoordinate(channelDict,assignTo={}){if(!eegCoordinates[channelDict.tag]&&channelDict.position){eegCoordinates[channelDict.tag]=[channelDict.position.x,channelDict.position.y,channelDict.position.z]}if(eegCoordinates[channelDict.tag]){let props={channel:"",position:{x:eegCoordinates[channelDict.tag][0],y:eegCoordinates[channelDict.tag][1],z:eegCoordinates[channelDict.tag][2]}};return Object.assign(assignTo,props)}else return Object.assign(assignTo,channelDict)}function EEGCoordinates(channelDicts=[],genCoherenceMap=true){let structs=[];for(let channelDict of channelDicts){let struct=EEGStruct(channelDict);structs.push(struct)}if(genCoherenceMap){structs.push(...CoherenceMap({channelDicts}))}return structs}function FrequencyBandsStruct(additionalBands=[],assignTo={}){let bands={scp:[],delta:[],theta:[],alpha1:[],alpha2:[],beta:[],lowgamma:[],highgamma:[]};additionalBands.forEach(band=>bands[band]=[]);return Object.assign(assignTo,bands)}function EEGStruct(tag="",assignProps={},parentUser={_id:""},parentStruct={structType:"struct",_id:""}){let bands=FrequencyBandsStruct();let props={tag,position:{x:0,y:0,z:0},count:0,times:[],raw:[],filtered:[],fftCount:0,fftTimes:[],ffts:[],slices:JSON.parse(JSON.stringify(bands)),means:JSON.parse(JSON.stringify(bands)),startTime:Date.now()};let struct=Struct("eeg",props,parentUser,parentStruct);if(tag)setCoordinate(props,struct);return Object.assign(struct,assignProps)}function CoherenceStruct(coords={0:EEGStruct("FP1"),1:EEGStruct("FP2")},assignProps={},parentUser={_id:""},parentStruct={structType:"struct",_id:""}){let bands=FrequencyBandsStruct();let props={tag:coords[0]?.tag+"::"+coords[1]?.tag,x0:coords[0]?.position?.x,y0:coords[0]?.position?.y,z0:coords[0]?.position?.z,x1:coords[1]?.position?.x,y1:coords[1]?.position?.y,z1:coords[1]?.position?.z,fftCount:0,fftTimes:[],ffts:[],slices:JSON.parse(JSON.stringify(bands)),means:JSON.parse(JSON.stringify(bands)),startTime:Date.now()};let struct=Struct("coherence",props,parentUser,parentStruct);return Object.assign(struct,assignProps)}function CoherenceMap(opts={channelDicts:[{ch:0,tag:"FP1",analyze:false},{ch:1,tag:"FP2",analyze:false}],taggedOnly:true},_={},parentUser={_id:""},parentStruct={structType:"struct",_id:""}){var cmap=[];var l=1,k=0;for(var i=0;i{if(!this.data.events[dataObj.timestamp])this.data.events[dataObj.timestamp]=[dataObj];else this.data.events[dataObj.timestamp].push(dataObj);if(dataObj.event==="sleep"){if(!this.data.sleep[dataObj.timestamp])this.data.sleep[dataObj.timestamp]=[dataObj];else this.data.sleep[dataObj.timestamp].push(dataObj)}return dataObj});this.setSort(["notes","note","link"],dataObj=>{if(!this.data.notes[dataObj.timestamp])this.data.notes[dataObj.timestamp]=[dataObj];else this.data.notes[dataObj.timestamp].push(dataObj);if(!this.data.byTime[dataObj.timestamp])this.data.byTime[dataObj.timestamp]=[dataObj];else this.data.byTime[dataObj.timestamp].push(dataObj);return dataObj});this.id=this.randomId("dataTablet")}randomId(tag=""){return`${tag+Math.floor(Math.random()+Math.random()*Math.random()*1e16)}`}setLocalData(structs){let setInCollection=s=>{let type=s.structType;let collection=this.collections.get(type);if(!collection){collection=new Map;this.collections.set(type,collection)}collection.set(s._id,s);this.onCollectionSet(type,collection)};if(Array.isArray(structs)){structs.forEach(s=>{setInCollection(s)})}else setInCollection(structs)}getLocalData(collection,query){let ownerId="";let key="";let value="";if(typeof query==="object"){ownerId=query.ownerId;const keys=Object.keys(query).filter(k=>k!="ownerId");key=keys[0];value=query[key]}else value=query;if(!collection&&!ownerId&&!key&&!value)return[];let result=[];if(!collection&&(ownerId||key)){this.collections.forEach(c=>{if((key==="_id"||key==="id")&&value){let found=c.get(value);if(found)result.push(found)}else{c.forEach(struct=>{if(key&&value){if(struct[key]===value&&struct.ownerId===ownerId){result.push(struct)}}else if(struct.ownerId===ownerId){result.push(struct)}})}});return result}else{let c=this.collections.get(collection);if(!c)return result;if(!key&&!ownerId){c.forEach(struct=>{result.push(struct)});return result}if((key==="_id"||key==="id")&&value)return c.get(value);else{c.forEach((struct,_)=>{if(key&&value&&!ownerId){if(struct[key]===value)result.push(struct)}else if(ownerId&&!key){if(struct.ownerId===ownerId)result.push(struct)}else if(ownerId&&key&&value){if(struct.ownerId===ownerId&&struct[key]){if(struct[key]===value)result.push(struct)}}})}}return result}onCollectionSet=(type,collection)=>{};runSort(key,dataObj={},newdata=[],tablet=this){let result;let sort=this.getSort(key);if(sort)result=sort(dataObj,newdata,tablet);else return false;return result}setSort(key,response=(data,newdata=[],tablet=this)=>{}){if(Array.isArray(key))key.forEach(k=>{this.dataSorts.set(k,response)});else this.dataSorts.set(key,response)}getSort(key){return this.dataSorts.get(key)}checkWatches(sorted={}){for(const prop in this.watches){let triggered=this.watches[prop].ondata(sorted,this.watches[prop].accum,this.watches[prop].ownerId);if(triggered){this.watches[prop].ontrigger(this.watches[prop].accum);this.watches[prop].triggered=false}}}setWatch(name,ownerId,ondata=(sorted,accum,ownerId2)=>{if(sorted.ownerId===ownerId2)accum.data[sorted._id]=sorted;if(Object.keys(accum.data).length>10){return true}else return false},ontrigger=accum=>{console.log(accum);let alert=Struct("alert",{alert:true,data:accum},{_id:accum[Object.keys(accum)[0]].ownerId});accum={}}){this.watches[name]={accum:{},ownerId,ondata,ontrigger}}getWatch(name){return this.watches[name]}async sortStructsIntoTable(datastructs=[]){let ascending=function(a,b){if(a.timestamp&&b.timestamp)return a.timestamp-b.timestamp};datastructs.sort(ascending);let newdata=[];for(let i=0;i{if(typeof dat==="object"&&!Array.isArray(dat)){let typ=dat.dataType;dat.ownerId=struct.ownerId;if(!dat.timestamp)dat.timestamp=timestamp;if(typ){let sorted=this.runSort(typ,dat,newdata,this);if(!sorted){if(!this.data[typ])this.data[typ]={};dat.timestamp=timestamp;if(!this.data[typ][timestamp])this.data[typ][timestamp]=[dat];else this.data[typ][timestamp].push(dat);if(!this.data.byTime[timestamp])this.data.byTime[timestamp]=[dat];else this.data.byTime[timestamp].push(dat);this.checkWatches(dat);this.onUpdate(timestamp,dat);newdata.push(dat)}else{if(sorted.constructor?.name!=="Promise"){this.checkWatches(sorted);this.onUpdate(timestamp,sorted);newdata.push(sorted)}}}}})}else{let sorted=this.runSort(struct.structType,struct,newdata,this);if(!sorted){let typ=struct.structType;if(!this.data[typ])this.data[typ]={};if(!this.data[typ][timestamp])this.data[typ][timestamp]=[struct];else this.data[typ][timestamp].push(struct);this.checkWatches(struct);this.onUpdate(timestamp,struct);newdata.push(struct)}else{this.checkWatches(sorted);this.onUpdate(timestamp,sorted);newdata.push(sorted)}}}for(const prop in this.data){this.data[prop]=this.sortObjectByPropName(this.data[prop])}this.onSorted(newdata)}onUpdate(_,__,___=this.data){}onSorted(_=[]){}getDataByTimestamp(timestamp,ownerId){let result=this.data.byTime[timestamp];if(ownerId&&result)result=result.filter(o=>{if(!ownerId)return true;else if(ownerId===o.ownerId)return true;else return false});return result}getDataByTimeRange(begin,end,type,ownerId){let result={};if(type){for(const key in this.data[type]){let t=parseInt(key);if(t>begin&&tbegin&&t{if(o.ownerId!==ownerId){popidx.push(i)}});popidx.reverse().forEach(idx=>{result[key].splice(idx,1)});if(result[key].length===0)delete result[key]}}return result}getDataByType(type,timestamp,ownerId){if(!this.data[type])return void 0;let result={...this.data[type]};if(timestamp)result=[...result[timestamp]];if(ownerId&&result){for(const key in result){let popidx=[];result[key]=[...result[key]];result[key].forEach((o,i)=>{if(o.ownerId!==ownerId){popidx.push(i)}});popidx.reverse().forEach(idx=>{result[key].splice(idx,1)});if(result[key].length===0)delete result[key]}}if(type==="sleep"){result=this.filterSleepResults(result)}return result}filterSleepResults(unfiltered={}){let events=[];for(const key in unfiltered){unfiltered[key]=[...unfiltered[key]];events.push(...unfiltered[key].filter(o=>{if(o.structType==="event")return true;else return false}))}events.forEach(ev2=>{let foundidx;for(const key in unfiltered){unfiltered[key].forEach((o,i)=>{if(o.structType==="fitbitsleep"&&ev2.startTime&&ev2.endTime){if(Math.abs(o.startTime-ev2.startTime)<1e3*12*3600&&Math.abs(o.endTime-ev2.endTime)<1e3*12*3600&&ev2.endTime-ev2.startTime>1e3*2*3600){foundidx=i;return true}else return false}else return false});if(foundidx)unfiltered[key].splice(foundidx,1)}});let result=unfiltered;return result}sortObjectByPropName(object){const ordered=Object.keys(object).sort().reduce((obj,key)=>{obj[key]=object[key];return obj},{});return ordered}checkRollover(collection,limit=this.rolloverLimit){if(!collection)return false;let c=this.collections.get(collection);if(!c)return false;c.forEach(struct=>{for(const prop in struct){if(Array.isArray(struct[prop])){if(struct[prop].length>limit){struct[prop].slice(struct[prop].length-limit);if(prop==="ffts"){struct.fftCount=struct[prop].length}else if(prop==="times"){struct.count=struct[prop].length}}}else if(typeof struct[prop]==="object"){this.checkRollover(struct[prop])}}});return true}};var defaultSpecifiers=["now","minute","5 minutes","30 minutes","hour","6 hours","12 hours","day","3 days","week","2 weeks","month","6 months","year","5 years","decade"];function genTimeSpecifiers(specifiers=defaultSpecifiers){let result=["now"];specifiers.forEach(s=>{if(s!=="now")result.push(`last ${s}`);else result.push(s)});return result}function genTimestampFromString(specifier){const now=new Date;if(specifier==="now"){}else if(specifier==="last minute"){now.setMinutes(now.getMinutes()-1)}else if(specifier==="last hour"){now.setHours(now.getHours()-1)}else if(specifier==="last day"){now.setDate(now.getDate()-1)}else if(specifier==="last week"){now.setDate(now.getDate()-7)}else if(specifier==="last month"){now.setMonth(now.getMonth()-1)}else if(specifier==="last year"){now.setFullYear(now.getFullYear()-1)}else if(specifier==="last decade"){now.setFullYear(now.getFullYear()-1*10)}else if(specifier==="last century"){now.setFullYear(now.getFullYear()-1*100)}else if(specifier==="last millennium"){now.setFullYear(now.getFullYear()-1*1e3)}else if(specifier==="last microsecond"){now.setMilliseconds(now.getMilliseconds()-1)}else if(specifier==="last nanosecond"){now.setMilliseconds(now.getMilliseconds()-1*.001)}else if(specifier.startsWith("last")){const[,count,unit]=specifier.match(/last (\d+) (\w+)/)||[];if(count&&unit){const num=parseInt(count,10);if(unit.includes("minute")){now.setMinutes(now.getMinutes()-num)}else if(unit.includes("hour")){now.setHours(now.getHours()-num)}else if(unit.includes("day")){now.setDate(now.getDate()-num)}else if(unit.includes("week")){now.setDate(now.getDate()-num*7)}else if(unit.includes("month")){now.setMonth(now.getMonth()-num)}else if(unit.includes("year")){now.setFullYear(now.getFullYear()-num)}else if(unit.includes("decade")){now.setFullYear(now.getFullYear()-num*10)}else if(unit.includes("century")){now.setFullYear(now.getFullYear()-num*100)}else if(unit.includes("millennium")){now.setFullYear(now.getFullYear()-num*1e3)}else if(unit.includes("microsecond")){now.setMilliseconds(now.getMilliseconds()-num)}else if(unit.includes("nanosecond")){now.setMilliseconds(now.getMilliseconds()-num*.001)}}}return now.getTime()}var EventHandler=class{data={};triggers={};ctr=0;constructor(data){if(typeof data==="object")this.data=data}setState=updateObj=>{Object.assign(this.data,updateObj);let props=Object.getOwnPropertyNames(updateObj);for(const prop of props){this.triggerEvent(prop,this.data[prop])}if(this.triggers[statesubKey]){let run=fn=>{fn(updateObj)};const l=this.triggers[statesubKey].length;for(let i=l-1;i>=0;i--){run(this.triggers[statesubKey][i].onchange)}}return this.data};setValue=(key,value)=>{this.data[key]=value;this.triggerEvent(key,value)};triggerEvent=(key,value)=>{if(this.triggers[key]){let fn=obj=>{obj.onchange(value)};const l=this.triggers[key].length;for(let i=l-1;i>=0;i--){fn(this.triggers[key][i])}}};subscribeState=onchange=>{return this.subscribeEvent(statesubKey,onchange)};unsubscribeState=sub=>{return this.unsubscribeEvent(statesubKey,sub)};subscribeEvent=(key,onchange,refObject,refKey)=>{if(key){if(refObject&&refKey&&!this.triggers[key]){Object.defineProperty(this.data,key,{get:()=>{return refObject[refKey]},set:value=>{refObject[refKey]=value},enumerable:true,configurable:true})}if(!this.triggers[key]){this.triggers[key]=[]}let l=this.ctr;this.ctr++;this.triggers[key].push({sub:l,onchange});return l}else return void 0};unsubscribeEvent=(key,sub)=>{let triggers=this.triggers[key];if(triggers){if(sub===void 0){delete this.triggers[key];delete this.data[key]}else{let idx=void 0;let obj=triggers.find((o,i)=>{if(o.sub===sub){idx=i;return true}});if(obj)triggers.splice(idx,1);if(Object.keys(triggers).length===0){delete this.triggers[key];delete this.data[key]}if(this.onRemoved)this.onRemoved(obj);return true}}};subscribeEventOnce=(key,onchange)=>{let sub;let changed=value=>{onchange(value);this.unsubscribeEvent(key,sub)};sub=this.subscribeEvent(key,changed);return sub};getEvent=(key,sub)=>{if(typeof sub!=="number")return this.triggers[key];for(const s in this.triggers[key]){if(this.triggers[key][s].sub===sub)return this.triggers[key][s]}};getSnapshot=()=>{const snapshot={};for(const key in this.data){snapshot[key]=this.data[key]}};onRemoved};var statesubKey="*s";var state=new EventHandler;var Callable=class extends Function{__bound;__call;constructor(){super("return this.__bound.__call.apply(this.__bound, arguments)");this.__bound=this.bind(this);return this.__bound}};var GraphNode=class _GraphNode{__node={tag:`node${Math.floor(Math.random()*1e15)}`,unique:`${Math.floor(Math.random()*1e15)}`,state};__children;__parent;__operator;__listeners;__props;__args;constructor(properties,parent,graph){this.__setProperties(properties,parent,graph);if(typeof properties==="function"||properties?.__callable){const callableInstance=new Callable;callableInstance.__call=(...args)=>this.__operator(...args);const proxy=new Proxy(callableInstance,{get:(target,prop,receiver)=>{if(Reflect.has(this,prop)){return Reflect.get(this,prop,receiver)}return Reflect.get(target,prop,receiver)},set:(target,prop,value,receiver)=>{if(Reflect.has(this,prop)){return Reflect.set(this,prop,value,receiver)}return Reflect.set(target,prop,value,receiver)}});Object.setPrototypeOf(proxy,this);return proxy}}get __graph(){return this.__node?.graph}set __graph(graph){this.__node.graph=graph}__setProperties=(properties,parent,graph)=>{let enforceProperties=()=>{let orig=properties;if(typeof properties==="function"){if(isNativeClass(properties)){properties=new properties}else properties={__operator:properties,__node:{forward:true,tag:properties.name}}}else if(typeof properties==="string"){if(graph?.get(properties)){properties=graph.get(properties)}}if(!("__node"in properties))properties.__node={};if(!properties.__node.initial)properties.__node.initial=orig};enforceProperties();if(typeof properties==="object"){let assignState=()=>{if(properties.__node?.state)this.__node.state=properties.__node.state;else if(graph){properties.__node.state=graph.__node.state}};let setProps=()=>{if(properties.__props){if(typeof properties.__props==="function")properties.__props=new properties.__props;if(typeof properties.__props==="object"){this.__proxyObject(properties.__props)}}};let setTag=()=>{if(!properties.__node.tag){if(properties.__operator?.name)properties.__node.tag=properties.__operator.name;else properties.__node.tag=`node${Math.floor(Math.random()*1e15)}`}};let setNode=()=>{if(typeof properties.__node==="string"){if(graph?.get(properties.__node.tag)){properties=graph.get(properties.__node.tag)}else properties.__node={}}else if(!properties.__node)properties.__node={};if(graph){properties.__node.graph=graph}if(properties instanceof Graph)properties.__node.source=properties};let setParent=()=>{if(!properties.__parent&&parent)properties.__parent=parent;if(parent?.__node&&!(parent instanceof Graph||properties instanceof Graph))properties.__node.tag=parent.__node.tag+"."+properties.__node.tag;if(parent instanceof Graph&&properties instanceof Graph){if(properties.__node.loaders)Object.assign(parent.__node.loaders?parent.__node.loaders:{},properties.__node.loaders);if(parent.__node.mapGraphs){properties.__node.nodes.forEach(n=>{parent.set(properties.__node.tag+"."+n.__node.tag,n)});let ondelete=()=>{properties.__node.nodes.forEach(n=>{parent.__node.nodes.delete(properties.__node.tag+"."+n.__node.tag)})};this.__addOndisconnected(ondelete)}}};let setOp=()=>{if(typeof properties.default==="function"&&!properties.__operator){properties.__operator=properties.default}if(properties.__operator){if(typeof properties.__operator==="string"){if(graph){let n=graph.get(properties.__operator);if(n)properties.__operator=n.__operator;if(!properties.__node.tag&&properties.__operator.name)properties.__node.tag=properties.__operator.name}}if(typeof properties.__operator==="function")properties.__operator=this.__setOperator(properties.__operator);if(properties.default)properties.default=properties.__operator}};let assignProps=()=>{properties.__node=Object.assign(this.__node,properties.__node);let keys=Object.getOwnPropertyNames(properties).filter(v=>{if(!objProps[v])return true});for(const key of keys){if(key in properties&&key!=="name")this[key]=properties[key]}};let bindCallbacks=()=>{if(this.__onconnected){if(typeof this.__onconnected==="function"){this.__onconnected=this.__onconnected.bind(this)}else if(Array.isArray(this.__onconnected)){this.__onconnected=this.__onconnected.map(f=>{return f.bind(this)})}if(typeof this.__ondisconnected==="function"){this.__ondisconnected=this.__ondisconnected.bind(this)}else if(Array.isArray(this.__ondisconnected)){this.__ondisconnected=this.__ondisconnected.map(f=>{return f.bind(this)})}}};assignState();setTag();setProps();setNode();setParent();assignProps();bindCallbacks();setOp()}};__subscribe=(callback,key,subInput,target,tkey,args,callbackStr)=>{const subscribeToFunction=(k,setTarget=(callback2,target2)=>target2?target2:callback2,triggerCallback=callback)=>{let wrappedArgs;if(args){let wrapped=wrapArgs(triggerCallback,args,this.__node.graph);triggerCallback=wrapped.__callback;wrappedArgs=wrapped.__args}let sub=this.__node.state.subscribeEvent(k,triggerCallback,this,key);let trigger=this.__node.state.getEvent(k,sub);if(!this.__listeners)this.__listeners={};this.__listeners[k]=this.__node.state.triggers[k];if(!trigger)return sub;trigger.source=this.__node.tag;if(key)trigger.key=key;trigger.target=setTarget(callback,target);if(tkey)trigger.tkey=tkey;if(subInput)trigger.subInput=subInput;if(args){trigger.arguments=wrappedArgs;trigger.__args=args}if(callbackStr)trigger.__callback=callbackStr;trigger.node=this;trigger.graph=this.__node.graph;return sub};const getCallbackFromGraph=callback2=>{let fn=this.__node.graph.get(callback2);if(!fn&&callback2.includes(".")){target=callback2.substring(0,callback2.lastIndexOf("."));let n=this.__node.graph.get(callback2.substring(0,target));tkey=callback2.lastIndexOf(".")+1;if(n&&typeof n[key]==="function")callback2=(...args2)=>{return n[tkey](...args2)}}else if(fn.__operator){callback2=fn.__operator;tkey="__operator"}return callback2};if(key){if(!this.__node.localState||!this.__node.localState[key]){this.__addLocalState(this,key)}if(typeof callback==="string"){callbackStr=this.__node.tag+"."+callback;tkey=callback;if(target){if(this.__node.graph?.get(target)){let n=this.__node.graph?.get(target);if(typeof n[callback]==="function"){let fn=n[callback];callback=(...inp)=>{fn(...inp)}}else{let k2=callback;let setter=inp=>{n[k2]=inp};callback=setter}}}else if(typeof this[callback]==="function"){let fn=this[callback];callback=(...inp)=>{fn(...inp)}}else if(this.__node.graph?.get(callback))callback=getCallbackFromGraph(callback);if(typeof callback!=="function")return void 0}let sub;let k=subInput?this.__node.unique+"."+key+"input":this.__node.unique+"."+key;if(typeof callback==="function"&&!callback?.__node)sub=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2,callback);else if(callback?.__node)sub=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2.__node.unique,(...inp)=>{if(callback.__operator)callback.__operator(...inp)});return sub}else{if(typeof callback==="string"){callbackStr=callback;if(!target)target=callback;if(this.__node.graph.get(callback))callback=this.__node.graph.get(callback);tkey="__operator";if(typeof callback!=="object")return void 0}let sub;let k=subInput?this.__node.unique+"input":this.__node.unique;if(typeof callback==="function"&&!callback?.__node)sub=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2,callback);else if(callback?.__node){sub=subscribeToFunction(k,(callback2,target2)=>target2?target2:callback2.__node.unique,(...inp)=>{if(callback.__operator)callback.__operator(...inp)})}return sub}};__unsubscribe=(sub,key,unsubInput)=>{if(key){return this.__node.state.unsubscribeEvent(unsubInput?this.__node.unique+"."+key+"input":this.__node.unique+"."+key,sub)}else return this.__node.state.unsubscribeEvent(unsubInput?this.__node.unique+"input":this.__node.unique,sub)};__setOperator=fn=>{fn=fn.bind(this);if(this.__args&&this.__node.graph){fn=wrapArgs(fn,this.__args,this.__node.graph).__callback}let inpstr=`${this.__node.unique}input`;this.__operator=(...args)=>{if(this.__node.state.triggers[inpstr])this.__node.state.setValue(inpstr,args);let result=fn(...args);if(this.__node.state.triggers[this.__node.unique]){if(typeof result?.then==="function"){result.then(res=>{if(res!==void 0)this.__node.state.setValue(this.__node.unique,res)}).catch(console.error)}else if(result!==void 0)this.__node.state.setValue(this.__node.unique,result)}return result};if(this.__parent instanceof _GraphNode&&!this.__subscribedToParent){if(this.__parent.__operator){let sub=this.__parent.__subscribe(this);let ondelete=()=>{this.__parent?.__unsubscribe(sub);delete this.__subscribedToParent};this.__addOndisconnected(ondelete);this.__subscribedToParent=true}}return this.__operator};__addLocalState=(props,key)=>{if(!props)return;if(!this.__node.localState){this.__node.localState={}}const localState=this.__node.localState;const initState=(props2,k)=>{let str2=this.__node.unique+"."+k;let inpstr=`${str2}input`;let get,set;let obj,descriptor;if(typeof props2[k]==="function"&&k!=="__operator"){if(this.__props?.[k]){obj=this.__props}else{obj=localState}get=()=>{return obj[k]};set=fn=>{if(!this.__props?.[k])fn=fn.bind(this);obj[k]=(...args)=>{if(this.__node.state.triggers[inpstr])this.__node.state.setValue(inpstr,args);let result=fn(...args);if(this.__node.state.triggers[str2]){if(typeof result?.then==="function"){result.then(res=>{this.__node.state.triggerEvent(str2,res)}).catch(console.error)}else this.__node.state.triggerEvent(str2,result)}return result}};localState[k]=props2[k].bind(this);descriptor={get,set,enumerable:true,configurable:true}}else if(k!=="__graph"){let get2,set2;let obj2;if(this.__props?.[k]){obj2=this.__props}else{obj2=localState}get2=()=>{return obj2[k]};set2=v=>{obj2[k]=v;if(this.__node.state.triggers[str2])this.__node.state.triggerEvent(str2,v)};localState[k]=props2[k];descriptor={get:get2,set:set2,enumerable:true,configurable:true}}Object.defineProperty(props2,k,descriptor);if(typeof this.__node.initial==="object"){let dec=Object.getOwnPropertyDescriptor(this.__node.initial,k);if(dec===void 0||dec?.configurable){Object.defineProperty(this.__node.initial,k,descriptor)}}};if(key)initState(props,key);else{for(let k in props){initState(props,k)}}};__proxyObject=obj=>{const allProps=getAllProperties(obj);for(const k of allProps){const descriptor={get:()=>{return obj[k]},set:value=>{obj[k]=value},enumerable:true,configurable:true};Object.defineProperty(this,k,descriptor);if(typeof this.__node.initial==="object"){let dec=Object.getOwnPropertyDescriptor(this.__node.initial,k);if(dec===void 0||dec?.configurable){Object.defineProperty(this.__node.initial,k,descriptor)}}}};__addOnconnected(callback){callback=callback.bind(this);if(Array.isArray(this.__onconnected)){this.__onconnected.push(callback)}else if(typeof this.__onconnected==="function"){this.__onconnected=[callback,this.__onconnected]}else this.__onconnected=callback}__addOndisconnected(callback){callback=callback.bind(this);if(Array.isArray(this.__ondisconnected)){this.__ondisconnected.push(callback)}else if(typeof this.__ondisconnected==="function"){this.__ondisconnected=[callback,this.__ondisconnected]}else this.__ondisconnected=callback}__callConnected(node=this){if(typeof this.__onconnected==="function"){this.__onconnected(this)}else if(Array.isArray(this.__onconnected)){let fn=o=>{o(this)};this.__onconnected.forEach(fn)}}__callDisconnected(node=this){if(typeof this.__ondisconnected==="function")this.__ondisconnected(this);else if(Array.isArray(this.__ondisconnected)){let fn=o=>{o(this)};this.__ondisconnected.forEach(fn)}}};var Graph=class _Graph{__node={tag:`graph${Math.floor(Math.random()*1e15)}`,unique:`${Math.random()}`,nodes:new Map,state,roots:{}};constructor(options){this.init(options)}init=options=>{if(options){let cpy=Object.assign({},options);delete cpy.roots;recursivelyAssign(this.__node,cpy);if(options.roots)this.load(options.roots)}};load=(roots,overwrite=false)=>{function recursivelyAssignChildren(target,obj,inChildren=true,top=true){if(top){if(!target)target={};for(const key in obj){if(!key.startsWith("__")&&obj[key]&&typeof obj[key]==="object"){target[key]=obj[key];if(obj[key]?.__children){recursivelyAssignChildren({},obj[key].__children,false,false)}}else if(typeof obj[key]==="function")target[key]=obj[key]}recursivelyAssignChildren(target,obj,true,false)}else{if(obj?.__children&&!inChildren){if(obj.__children?.constructor.name==="Object"){if(target.__children?.constructor.name==="Object")target.__children=recursivelyAssignChildren(target.__children,obj.__children,true,false);else target.__children=recursivelyAssignChildren({},obj.__children,true,false)}else{target.__children=obj.__children}}else if(inChildren){for(const key in obj){if(!key.startsWith("__")&&obj[key]&&typeof obj[key]==="object"){target[key]=Object.assign({},obj[key]);if(obj[key]?.__children){target[key].__children=recursivelyAssignChildren({},obj[key].__children,false,false)}}else if(typeof obj[key]==="function")target[key]=obj[key]}}}return target}this.__node.roots=recursivelyAssignChildren(this.__node.roots?this.__node.roots:{},roots);let cpy=Object.assign({},roots);if(cpy.__node)delete cpy.__node;let listeners=this.recursiveSet(cpy,this,void 0,roots,overwrite);if(roots.__node){if(!roots.__node.tag)roots.__node._tag=`roots${Math.floor(Math.random()*1e15)}`;else if(!this.get(roots.__node.tag)){let node=new GraphNode(roots,this,this);this.set(node.__node.tag,node);this.runLoaders(node,this,roots,roots.__node.tag);if(node.__listeners){listeners[node.__node.tag]=node.__listeners}}}else if(roots.__listeners){this.setListeners(roots.__listeners)}this.setListeners(listeners);return cpy};setLoaders=(loaders2,replace)=>{if(replace)this.__node.loaders=loaders2;else Object.assign(this.__node.loaders,loaders2);return this.__node.loaders};runLoaders=(node,parent,properties,key)=>{for(const l in this.__node.loaders){if(typeof this.__node.loaders[l]==="object"){if(this.__node.loaders[l].init)this.__node.loaders[l](node,parent,this,this.__node.roots,properties,key);if(this.__node.loaders[l].connected)node.__addOnconnected(this.__node.loaders[l].connect);if(this.__node.loaders[l].disconnected)node.__addOndisconnected(this.__node.loaders[l].disconnect)}else if(typeof this.__node.loaders[l]==="function")this.__node.loaders[l](node,parent,this,this.__node.roots,properties,key)}};add=(properties,parent,overwrite=true)=>{let listeners={};if(typeof parent==="string")parent=this.get(parent);let instanced;if(typeof properties==="function"){if(isNativeClass(properties)){if(properties.prototype instanceof GraphNode){properties=properties.prototype.constructor(properties,parent,this);instanced=true}else properties=new properties}else properties={__operator:properties,__callable:true}}else if(typeof properties==="string"){properties=this.__node.roots[properties]}if(!properties)return;if(!instanced){let keys=Object.getOwnPropertyNames(properties);let nonArrowFunctions=Object.getOwnPropertyNames(Object.getPrototypeOf(properties));keys.push(...nonArrowFunctions);keys=keys.filter(v=>!objProps.includes(v));let cpy={};for(const key of keys){cpy[key]=properties[key]}properties=cpy}if(!properties.__node)properties.__node={};properties.__node.initial=properties;if(typeof properties==="object"&&this.get(properties.__node.tag)){if(overwrite)this.remove(properties.__node.tag,true);else return}else if(properties.__node.tag&&this.get(properties.__node.tag))return this.get(properties.__node.tag);let node;let root=recursivelyAssign({},properties,2);if(instanced)node=properties;else node=new GraphNode(properties,parent,this);this.set(node.__node.tag,node);this.runLoaders(node,parent,properties,node.__node.tag);this.__node.roots[node.__node.tag]=root;if(node.__children){node.__children=Object.assign({},node.__children);this.recursiveSet(node.__children,node,listeners,node.__children)}if(node.__listeners){listeners[node.__node.tag]=Object.assign({},node.__listeners);for(const key in node.__listeners){let listener=node.__listeners[key];if(node[key]){delete listeners[node.__node.tag][key];listeners[node.__node.tag][node.__node.tag+"."+key]=listener}if(typeof listener==="string"){if(node.__children?.[listener]){listeners[node.__node.tag][key]=node.__node.tag+"."+listener}else if(parent instanceof GraphNode&&(parent.__node.tag===listener||parent.__node.tag.includes(".")&&parent.__node.tag.split(".").pop()===listener)){listeners[node.__node.tag][key]=parent.__node.tag}}}}this.setListeners(listeners);node.__callConnected();return node};recursiveSet=(originCpy,parent,listeners={},origin,overwrite=false)=>{let keys=Object.getOwnPropertyNames(origin).filter(v=>!objProps.includes(v));let nonArrowFunctions=Object.getOwnPropertyNames(Object.getPrototypeOf(origin)).filter(v=>!objProps.includes(v));keys.push(...nonArrowFunctions);for(const key of keys){if(key.includes("__"))continue;let p=origin[key];if(Array.isArray(p))continue;let instanced;if(typeof p==="function"){if(isNativeClass(p)){p=new p;if(p instanceof GraphNode){p=p.prototype.constructor(p,parent,this);instanced=true}}else p={__operator:p,__callable:true}}else if(typeof p==="string"){if(this.__node.nodes.get(p))p=this.__node.nodes.get(p);else p=this.__node.roots[p]}else if(typeof p==="boolean"){if(this.__node.nodes.get(key))p=this.__node.nodes.get(key);else p=this.__node.roots[key]}if(p&&typeof p==="object"){if(!instanced&&!(p instanceof GraphNode)){let ks=Object.getOwnPropertyNames(p).filter(v=>!objProps.includes(v));let nonArrowFunctions2=Object.getOwnPropertyNames(Object.getPrototypeOf(p)).filter(v=>!objProps.includes(v));nonArrowFunctions2.splice(nonArrowFunctions2.indexOf("constructor"),1);ks.push(...nonArrowFunctions2);let cpy={};for(const key2 of ks){cpy[key2]=p[key2]}p=cpy}if(!p.__node)p.__node={};if(!p.__node.tag)p.__node.tag=key;if(!p.__node.initial)p.__node.initial=originCpy[key];if(overwrite&&this.get(p.__node.tag)){this.remove(p.__node.tag,true)}else if(this.get(p.__node.tag)&&!(!(parent instanceof _Graph)&&parent?.__node)||parent?.__node&&this.get(parent.__node.tag+"."+p.__node.tag))continue;let node;let newnode=false;let root=recursivelyAssign({},p,2);if(instanced||p instanceof GraphNode){node=p}else{node=new GraphNode(p,parent,this);newnode=true}if(!newnode&&p instanceof GraphNode&&!instanced&&parent instanceof GraphNode){let sub=this.subscribe(parent.__node.tag,node.__node.tag);let ondelete=node2=>{this.unsubscribe(parent.__node.tag,sub)};node.__addOndisconnected(ondelete)}else if(node){this.set(node.__node.tag,node);this.runLoaders(node,parent,originCpy[key],key);originCpy[key]=node;this.__node.roots[node.__node.tag]=root;if(node.__children){node.__children=Object.assign({},node.__children);this.recursiveSet(node.__children,node,listeners,node.__children)}if(node.__listeners){listeners[node.__node.tag]=Object.assign({},node.__listeners);for(const key2 in node.__listeners){let listener=node.__listeners[key2];let k=key2;if(node[key2]){delete listeners[node.__node.tag][key2];k=node.__node.tag+"."+key2;listeners[node.__node.tag][k]=listener}if(typeof listener==="string"){if(node.__children?.[listener]){listeners[node.__node.tag][k]=node.__node.tag+"."+listener}else if(parent instanceof GraphNode&&(parent.__node.tag===listener||parent.__node.tag.includes(".")&&parent.__node.tag.split(".").pop()===listener)){listeners[node.__node.tag][k]=parent.__node.tag}}}}node.__callConnected()}}}return listeners};remove=(node,clearListeners=true)=>{this.unsubscribe(node);if(typeof node==="string")node=this.get(node);if(node instanceof GraphNode){this.delete(node.__node.tag);delete this.__node.roots[node.__node.tag];if(clearListeners){this.clearListeners(node)}node.__callDisconnected();const recursiveRemove=t=>{for(const key in t){this.unsubscribe(t[key]);this.delete(t[key].__node.tag);delete this.__node.roots[t[key].__node.tag];this.delete(key);delete this.__node.roots[key];t[key].__node.tag=t[key].__node.tag.substring(t[key].__node.tag.lastIndexOf(".")+1);if(clearListeners){this.clearListeners(t[key])}t[key].__callDisconnected();if(t[key].__children){recursiveRemove(t[key].__children)}}};if(node.__children){recursiveRemove(node.__children)}}if(node?.__node.tag&&node?.__parent){delete node?.__parent;node.__node.tag=node.__node.tag.substring(node.__node.tag.indexOf(".")+1)}if(node?.__node.graph)node.__node.graph=void 0;return node};run=(node,...args)=>{if(typeof node==="string"){let nd=this.get(node);if(!nd&&node.includes(".")){nd=this.get(node.substring(0,node.lastIndexOf(".")));if(typeof nd?.[node.substring(node.lastIndexOf(".")+1)]==="function")return nd[node.substring(node.lastIndexOf(".")+1)](...args)}else if(nd?.__operator)return nd.__operator(...args)}if(node?.__operator){return node?.__operator(...args)}};setListeners=listeners=>{for(const key in listeners){let node=this.get(key);if(typeof listeners[key]==="object"){for(const k in listeners[key]){let n=this.get(k);let sub;if(typeof listeners[key][k]!=="object")listeners[key][k]={__callback:listeners[key][k]};else if(!listeners[key][k].__callback){for(const kk in listeners[key][k]){if(typeof listeners[key][k][kk]!=="object"){listeners[key][k][kk]={__callback:listeners[key][k][kk]};if(node.__operator&&(listeners[key][k][kk].__callback===true||typeof listeners[key][k][kk].__callback==="undefined"))listeners[key][k][kk].__callback=node.__operator}let nn=this.get(kk);if(!nn){let tag=k.substring(0,k.lastIndexOf("."));nn=this.get(tag);if(nn){let prop=k.substring(k.lastIndexOf(".")+1);sub=this.subscribe(nn,listeners[key][k][kk].__callback,listeners[key][k][kk].__args,prop,listeners[key][k][kk].subInput,key)}}else{sub=this.subscribe(nn,listeners[key][k][kk].__callback,listeners[key][k][kk].__args,void 0,listeners[key][k][kk].subInput,key)}}}if("__callback"in listeners[key][k]){if(node){if(listeners[key][k].__callback===true||typeof listeners[key][k].__callback==="undefined")listeners[key][k].__callback=node.__operator;if(typeof listeners[key][k].__callback==="function")listeners[key][k].__callback=listeners[key][k].__callback.bind(node)}if(!n){let tag=k.substring(0,k.lastIndexOf("."));n=this.get(tag);if(n){sub=this.subscribe(n,listeners[key][k].__callback,listeners[key][k].__args,k.substring(k.lastIndexOf(".")+1),listeners[key][k].subInput,key)}}else{sub=this.subscribe(n,listeners[key][k].__callback,listeners[key][k].__args,void 0,listeners[key][k].subInput,key)}}}}}};clearListeners=(node,listener)=>{if(typeof node==="string")node=this.get(node);if(node?.__listeners){for(const key in node.__listeners){if(listener&&key!==listener)continue;if(typeof node.__listeners[key]?.sub!=="number")continue;let n=this.get(key);if(!n){n=this.get(key.substring(0,key.lastIndexOf(".")));if(n){if(typeof node.__listeners[key]==="object"&&!node.__listeners[key]?.__callback){for(const k in node.__listeners[key]){if(typeof node.__listeners[key][k]?.sub==="number"){this.unsubscribe(n,node.__listeners[key][k].sub,key.substring(key.lastIndexOf(".")+1),node.__listeners[key][k].subInput);node.__listeners[key][k].sub=void 0}}}else if(typeof node.__listeners[key]?.sub==="number"){this.unsubscribe(n,node.__listeners[key].sub,key.substring(key.lastIndexOf(".")+1),node.__listeners[key].subInput);node.__listeners[key].sub=void 0}}}else{if(typeof!node.__listeners[key]?.__callback==="number"){for(const k in node.__listeners[key]){if(node.__listeners[key][k]?.sub){this.unsubscribe(n,node.__listeners[key][k].sub,void 0,node.__listeners[key][k].subInput);node.__listeners[key][k].sub=void 0}}}else if(typeof node.__listeners[key]?.sub==="number"){this.unsubscribe(n,node.__listeners[key].sub,void 0,node.__listeners[key].subInput);node.__listeners[key].sub=void 0}}}}};get=tag=>{return this.__node.nodes.get(tag)};getByUnique=unique=>{return Array.from(this.__node.nodes.values()).find(node=>{if(node.__node.unique===unique)return true})};set=(tag,node)=>{return this.__node.nodes.set(tag,node)};delete=tag=>{return this.__node.nodes.delete(tag)};list=()=>{return Array.from(this.__node.nodes.keys())};getListener=(nodeTag,key,sub)=>{let node=this.get(nodeTag);if(node){let k=node.__node.unique;if(key){k+="."+key}return this.__node.state.getEvent(k,sub)}};getProps=(node,getInitial)=>{if(typeof node==="string")node=this.get(node);if(node instanceof GraphNode){let cpy;if(getInitial)cpy=Object.assign({},this.__node.roots[node.__node.tag]);else{cpy=Object.assign({},node);for(const key in cpy){if(key.includes("__"))delete cpy[key]}}}};subscribe=(nodeEvent,onEvent,args,key,subInput,target,tkey)=>{let nd=nodeEvent;if(typeof nodeEvent==="string"){nd=this.get(nodeEvent);if(!nd&&nodeEvent.includes(".")){nd=this.get(nodeEvent.substring(0,nodeEvent.lastIndexOf(".")));key=nodeEvent.substring(nodeEvent.lastIndexOf(".")+1)}}if(target instanceof GraphNode)target=target.__node.tag;let callbackStr;if(typeof onEvent==="string"){callbackStr=onEvent;let setOnEventFromString=onEvent2=>{if(this.get(onEvent2)?.__operator){let node=this.get(onEvent2);target=onEvent2;onEvent2=function(...inp){return node.__operator(...inp)}}else if(onEvent2.includes(".")){target=onEvent2.substring(0,onEvent2.lastIndexOf("."));let n=this.get(target);let k=onEvent2.substring(onEvent2.lastIndexOf(".")+1);tkey=k;if(typeof n[k]==="function"){if(n[k]instanceof GraphNode)onEvent2=n[k];else onEvent2=function(...inp){return n[k](...inp)}}else{onEvent2=function(inp){n[k]=inp;return n[k]}}}return onEvent2};if(target){let node=this.get(target);if(typeof node?.[onEvent]==="function"){tkey=onEvent;onEvent=function(...inp){return node[key](...inp)}}else if(node?.[key]){tkey=key;if(node[key]instanceof GraphNode)onEvent=node[key];else onEvent=function(inp){node[key]=inp;return node[key]}}else{onEvent=setOnEventFromString(onEvent)}}else{onEvent=setOnEventFromString(onEvent)}}let sub;if(nd instanceof GraphNode){const doSub=()=>{sub=nd.__subscribe(onEvent,key,subInput,target,tkey,args,callbackStr);let ondelete=()=>{if(sub!==void 0)nd.__unsubscribe(sub,key,subInput);sub=void 0};nd.__addOndisconnected(()=>{ondelete();nd.__addOnconnected(()=>{if(sub===void 0&&nd.__node.graph.__node.tag===this.__node.tag)doSub()})});if(typeof onEvent==="string"&&this.get(onEvent))onEvent=this.get(onEvent);if(onEvent instanceof GraphNode){onEvent.__addOndisconnected(()=>{ondelete()})}};doSub()}else if(typeof nodeEvent==="string"){let node=this.get(nodeEvent);if(node){if(onEvent instanceof GraphNode&&onEvent.__operator){const doSub=()=>{sub=node.__subscribe(onEvent.__operator,key,subInput,target,tkey,args,callbackStr);let ondelete=()=>{if(sub!==void 0)node.__unsubscribe(sub,key,subInput)};node.__addOndisconnected(()=>{ondelete();node.__addOnconnected(()=>{if(sub===void 0&&node.__node.graph.__node.tag===this.__node.tag)doSub()})});onEvent.__addOndisconnected(ondelete)};doSub()}else if(typeof onEvent==="function"||typeof onEvent==="string"){const doSub=()=>{sub=node.__subscribe(onEvent,key,subInput,target,tkey,args,callbackStr);let ondelete=()=>{if(sub!==void 0)node.__unsubscribe(sub,key,subInput);sub=void 0};node.__addOndisconnected(()=>{ondelete();node.__addOnconnected(()=>{if(sub===void 0&&node.__node.graph.__node.tag===this.__node.tag)doSub()})});if(typeof onEvent==="string"&&this.get(onEvent))this.get(onEvent).__addOndisconnected(ondelete)};doSub()}}else{if(typeof onEvent==="string")onEvent=this.__node.nodes.get(onEvent).__operator;if(typeof onEvent==="function"&&!onEvent?.__node)sub=this.__node.state.subscribeEvent(nodeEvent,onEvent)}}return sub};unsubscribe=(node,sub,key,subInput)=>{if(node instanceof GraphNode){return node.__unsubscribe(sub,key,subInput)}else return this.get(node)?.__unsubscribe(sub,key,subInput)};setState=update=>{this.__node.state.setState(update)}};function recursivelyAssign(target,obj,maxDepth=Infinity,curDepth=0){for(const key in obj){if(obj[key]?.constructor.name==="Object"&&curDepth{if(graph.get(a)?.__operator){let node=graph.get(a);return(...inp)=>{node.__operator(...inp)}}else if(a.includes(".")){let split=a.split(".");let popped=split.pop();let joined=split.join(".");let node=graph.get(joined);if(typeof graph.get(joined)?.[popped]==="function"){return(...inp)=>{return node[popped](...inp)}}else return()=>{return node[popped]}}else if(graph.get(a)){let node=graph.get(a);return()=>{return node}}else{let arg=a;return()=>{return arg}}};var wrapArgs=(callback,argOrder,graph)=>{let args=[];let forArg=(a,i)=>{if(a==="__output"||a==="__input"||a==="__callback"){args[i]={__callback:inp=>{return inp},__args:void 0,idx:i}}else if(typeof a==="string"){args[i]={__callback:getCallbackFromString(a,graph),__args:void 0,idx:i}}else if(typeof a==="function"){let fn2=a;args[i]={__callback:(...inp)=>{return fn2(...inp)},__args:void 0,idx:i}}else if(typeof a==="object"&&(a.__input||a.__callback)){let recursivelyCreateCallback=function(c){let input=c.__input?c.__input:c.__callback;if(typeof c.__input==="string"){input={__callback:getCallbackFromString(c.__input,graph),__args:void 0,idx:i}}if(c.__args){let wrapped=wrapArgs(input,c.__args,graph);input={__callback:wrapped.__callback,__args:wrapped.__args,idx:i}}else{input={__callback:input,__args:void 0,idx:i}}if(c.__output){let output=c.__output;if(typeof c.__output==="string"){output={__callback:getCallbackFromString(output,graph),__args:void 0,idx:i}}else if(typeof a.__output==="object"){output=recursivelyCreateCallback(output)}if(typeof output?.__callback==="function"){let fn2=input.__callback;let callback2=output.__callback;input={__callback:(...inp)=>{return callback2(fn2(...inp))},__args:output.__args,idx:i}}}return input};args[i]=recursivelyCreateCallback(a)}else{let arg=a;args[i]={__callback:()=>{return arg},__args:void 0,idx:i}}};argOrder.forEach(forArg);if(typeof callback==="string")callback={__callback:getCallbackFromString(callback,graph),__args:void 0};let fn=typeof callback==="function"?callback:callback.__callback;callback=function(...inp){let mapArg=arg=>{return arg.__callback(...inp)};const result=fn(...args.map(mapArg));return result};return{__callback:callback,__args:args}};var objProps=Object.getOwnPropertyNames(Object.getPrototypeOf({}));var backprop=(node,parent,graph)=>{if(node.__node.backward&&parent instanceof GraphNode){graph.setListeners({[parent.__node.tag]:{[node.__node.tag]:parent}})}};var loop=(node,parent,graph)=>{if(node.__operator){let loopId=Math.random();if(!node.__node.loops)node.__node.loops={};if(typeof node.__node.delay==="number"){let fn=node.__operator;node.__setOperator((...args)=>{return new Promise((res,rej)=>{node.__node.loops[loopId]=setTimeout(async()=>{res(await fn(...args))},node.__node.delay)})})}else if(node.__node.frame===true){let fn=node.__operator;node.__setOperator((...args)=>{return new Promise((res,rej)=>{node.__node.loops[loopId]=requestAnimationFrame(async()=>{res(await fn(...args))})})})}if(typeof node.__node.repeat==="number"||typeof node.__node.recursive==="number"){let fn=node.__operator;node.__setOperator(async(...args)=>{let i=node.__node.repeat?node.__node.repeat:node.__node.recursive;let result;let repeater=async(tick,...inp)=>{while(tick>0){if(node.__node.delay||node.__node.frame){fn(...inp).then(async res=>{if(node.__node.recursive){await repeater(tick,res)}else await repeater(tick,...inp)});break}else result=await fn(...args);tick--}};await repeater(i,...args);return result})}if(node.__node.loop&&typeof node.__node.loop==="number"){let fn=node.__operator;let time=node.__node.loop;node.__setOperator((...args)=>{if(!("looping"in node.__node))node.__node.looping=true;if(node.__node.looping){let last=performance.now();fn(...args);node.__node.loops[loopId]=setTimeout(()=>{let now=performance.now();let overshoot=now-last-node.__node.loop;if(overshoot>0)time=node.__node.loop-overshoot;else time=node.__node.loop;if(time<=0)time=node.__node.loop;node.__operator(...args)},time)}});if(node.__node.looping)node.__operator();let ondelete=node2=>{if(node2.__node.looping)node2.__node.looping=false;if(node2.__node.loops[loopId]){clearTimeout(node2.__node.loops[loopId]);cancelAnimationFrame(node2.__node.loops[loopId])}};node.__addOndisconnected(ondelete)}}};var animate=(node,parent,graph)=>{if(node.__node.animate===true||node.__animation){let fn=node.__operator;node.__setOperator((...args)=>{if(!("animating"in node.__node))node.__node.animating=true;if(node.__node.animating){if(typeof node.__animation==="function")node.__animation(...args);else fn(...args);node.__node.animationFrame=requestAnimationFrame(()=>{node.__operator(...args)})}});if(node.__node.animating||(!("animating"in node.__node)||node.__node.animating)&&node.__animation)setTimeout(()=>{node.__node.animationFrame=requestAnimationFrame(node.__operator)},10);let ondelete=node2=>{if(node2.__node.animating)node2.__node.animating=false;if(node2.__node.animationFrame)cancelAnimationFrame(node2.__node.animationFrame)};node.__addOndisconnected(ondelete)}};var branching=(node,parent,graph)=>{if(typeof node.__branch==="object"&&node.__operator&&!node.__branchApplied){let fn=node.__operator;node.__branchApplied=true;node.__operator=(...args)=>{let result=fn(...args);for(const key in node.__branch){let triggered=()=>{if(typeof node.__branch[key].then==="function"){node.__branch[key].then(result)}else if(node.__branch[key].then instanceof GraphNode&&node.__branch[key].then.__operator){node.__branch[key].then.__operator(result)}else result=node.__branch[key].then};if(typeof node.__branch[key].if==="function"){if(node.__branch[key].if(result)==true){triggered()}}else if(node.__branch[key].if===result){triggered()}}return result}}if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(node.__listeners[key].branch&&!node.__listeners[key].branchApplied){let fn=node.__listeners[key].callback;node.__listeners[key].branchApplied=true;node.__listeners.callback=ret=>{let triggered=()=>{if(typeof node.__listeners[key].branch.then==="function"){ret=node.__listeners[key].branch.then(ret)}else if(node.__listeners[key].branch.then instanceof GraphNode&&node.__listeners[key].branch.then.__operator){ret=node.__listeners[key].branch.then.__operator(ret)}else ret=node.__listeners[key].branch.then};if(typeof node.__listeners[key].branch.if==="function"){if(node.__listeners[key].branch.if(ret)){triggered()}}else if(node.__listeners[key].branch.if===ret){triggered()}return fn(ret)}}}}}};var triggerListenerOncreate=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(node.__listeners[key].oncreate){node.__listeners[key].callback(node.__listeners[key].oncreate)}}}}};var bindListener=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(typeof node.__listeners[key].binding==="object"){node.__listeners.callback=node.__listeners.callback.bind(node.__listeners[key].binding)}}}}};var transformListenerResult=(node,parent,graph)=>{if(node.__listeners){for(const key in node.__listeners){if(typeof node.__listeners[key]==="object"){if(typeof node.__listeners[key].transform==="function"&&!node.__listeners[key].transformApplied){let fn=node.__listeners[key].callback;node.__listeners[key].transformApplied=true;node.__listeners.callback=ret=>{ret=node.__listeners[key].transform(ret);return fn(ret)}}}}}};var substitute__operator=(node,parent,graph)=>{if(node.post&&!node.__operator){node.__setOperator(node.post)}else if(!node.__operator&&typeof node.get=="function"){node.__setOperator(node.get)}if(!node.get&&node.__operator){}if(node.aliases){node.aliases.forEach(a=>{graph.set(a,node);let ondelete=node2=>{graph.__node.nodes.delete(a)};node.__addOndisconnected(ondelete)})}if(typeof graph.__node.roots?.[node.__node.tag]==="object"&&node.get)graph.__node.roots[node.__node.tag].get=node.get};var loaders={backprop,loop,animate,branching,triggerListenerOncreate,bindListener,transformListenerResult,substitute__operator};var Service=class extends Graph{name=`service${Math.floor(Math.random()*1e15)}`;restrict;constructor(options){super({...options,loaders:options?.loaders?Object.assign({...loaders},options.loaders):{...loaders}});if(options?.services)this.addServices(options.services);if(options?.restrict)this.restrict=options.restrict;this.load(this)}addServices=services=>{for(const s in services){if(typeof services[s]==="function")services[s]=new services[s];if(services[s]?.__node?.loaders)Object.assign(this.__node.loaders,services[s].__node.loaders);if(services[s]?.__node?.nodes){services[s].__node.nodes.forEach((n,tag)=>{if(!this.get(tag)){this.set(tag,n)}else this.set(s+"."+tag,n)});this.__node.nodes.forEach((n,k)=>{if(!services[s].__node.nodes.get(k))services[s].__node.nodes.set(k,n)});let set=this.set;this.set=(tag,node)=>{services[s].set(tag,node);return set(tag,node)};let del=this.delete;this.delete=tag=>{services[s].delete(tag);return del(tag)}}else if(typeof services[s]==="object"){this.load(services[s])}}};handleMethod=(route,method,args)=>{let m=method.toLowerCase();let src=this.__node.nodes.get(route);if(!src){src=this.__node.roots[route]}if(src?.[m]){if(typeof src[m]!=="function"){if(args){if(Array.isArray(args)&&args.length===1)src[m]=args[0];else src[m]=args;return}return src[m]}else{if(Array.isArray(args))return src[m](...args);else return src[m](args)}}else return this.handleServiceMessage({route,args,method})};handleServiceMessage(message){let call;if(typeof message==="object"){if(message.route)call=message.route;else if(message.node)call=message.node}if(call){if(Array.isArray(message.args))return this.run(call,...message.args);else return this.run(call,message.args)}else return message}handleGraphNodeCall(route,args){if(!route)return args;if(args?.args){this.handleServiceMessage(args)}else if(Array.isArray(args))return this.run(route,...args);else return this.run(route,args)}transmit=(...args)=>{if(typeof args[0]==="object"){const message=args[0];if(message.method){return this.handleMethod(message.route,message.method,message.args)}else if(message.route){return this.handleServiceMessage(message)}else if(message.node){return this.handleGraphNodeCall(message.node,message.args)}else if(this.__node.keepState){if(message.route)this.setState({[message.route]:message.args});if(message.node)this.setState({[message.node]:message.args})}return void 0}else return void 0};receive=(...args)=>{if(args[0]){let message=args[0];if(typeof message==="string"){let substr=message.substring(0,8);if(substr.includes("{")||substr.includes("[")){if(substr.includes("\\"))message=message.replace(/\\/g,"");if(message[0]==='"'){message=message.substring(1,message.length-1)};message=JSON.parse(message)}}if(typeof message==="object"){if(message.method){if(this.restrict?.[message.route])return void 0;return this.handleMethod(message.route,message.method,message.args)}else if(message.route){if(this.restrict?.[message.route])return void 0;return this.handleServiceMessage(message)}else if(message.node){if(typeof message.node==="string"&&this.restrict?.[message.node])return void 0;return this.handleGraphNodeCall(message.node,message.args)}else if(this.__node.keepState){if(message.route)this.setState({[message.route]:message.args});if(message.node)this.setState({[message.node]:message.args})}return void 0}}return void 0};pipe=(source,destination,endpoint,method,callback)=>{if(source instanceof GraphNode){if(callback)return this.subscribe(source,res=>{let mod=callback(res);if(mod!==void 0)this.transmit({route:destination,args:mod,method});else this.transmit({route:destination,args:res,method},endpoint)});else return this.subscribe(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})}else if(typeof source==="string")return this.subscribe(source,res=>{this.transmit({route:destination,args:res,method},endpoint)})};pipeOnce=(source,destination,endpoint,method,callback)=>{if(source instanceof GraphNode){if(callback)return source.__node.state.subscribeEventOnce(source.__node.unique,res=>{let mod=callback(res);if(mod!==void 0)this.transmit({route:destination,args:mod,method});else this.transmit({route:destination,args:res,method},endpoint)});else return this.__node.state.subscribeEventOnce(source.__node.unique,res=>{this.transmit({route:destination,args:res,method},endpoint)})}else if(typeof source==="string")return this.__node.state.subscribeEventOnce(this.__node.nodes.get(source).__node.unique,res=>{this.transmit({route:destination,args:res,method},endpoint)})};terminate=(...args)=>{};isTypedArray=isTypedArray;recursivelyAssign=recursivelyAssign2;spliceTypedArray=spliceTypedArray;ping=()=>{console.log("pinged!");return"pong"};echo=(...args)=>{this.transmit(...args);return args};log=(...args)=>{console.log(...args);return true};error=(...args)=>{console.error(...args);return true}};function isTypedArray(x2){return ArrayBuffer.isView(x2)&&Object.prototype.toString.call(x2)!=="[object DataView]"}var recursivelyAssign2=(target,obj)=>{for(const key in obj){if(obj[key]?.constructor.name==="Object"&&!Array.isArray(obj[key])){if(target[key]?.constructor.name==="Object"&&!Array.isArray(target[key]))recursivelyAssign2(target[key],obj[key]);else target[key]=recursivelyAssign2({},obj[key])}else target[key]=obj[key]}return target};function spliceTypedArray(arr,start,end){let s=arr.subarray(0,start);let e;if(end){e=arr.subarray(end+1)}let ta;if(s.length>0||e?.length>0)ta=new arr.constructor(s.length+e.length);if(ta){if(s.length>0)ta.set(s);if(e&&e.length>0)ta.set(e,s.length)}return ta}var randomId=prefix=>(prefix?`${prefix}`:"")+Math.floor(1e15*Math.random());var pseudoObjectId=(m=Math,d=Date,h=16,s=s2=>m.floor(s2).toString(h))=>s(d.now()/1e3)+" ".repeat(h).replace(/./g,()=>s(m.random()*h));var StructFrontend=class extends Service{name="structs";currentUser;tablet=new DataTablet;collections=this.tablet.collections;id=randomId();useAccessTokens=false;useRefreshTokens=false;constructor(options,user){super(options);this.load(this);if(options.useAccessTokens)this.useAccessTokens=options.useAccessTokens;if(options.useRefreshTokens)this.useRefreshTokens=options.useRefreshTokens;if(user instanceof Object&&Object.keys(user).length>0)this.setupUser(user)}getToken(user){if(this.useAccessTokens)return user.accessToken;else if(this.useRefreshTokens)return user.refreshToken}setupUser=async(userinfo,callback=currentUser=>{})=>{if(!userinfo){console.error('must provide a minimum info object! e.g. {_id:"abc123"}');callback(void 0);return void 0}let changed=false;if(userinfo.id&&!userinfo._id)userinfo._id=userinfo.id;else if(userinfo._id)userinfo.id=userinfo._id;let res=await this.getUser(userinfo._id);let user=res?.user;let u;let newu=false;if(!user||!user._id){u=this.userStruct(userinfo,false);newu=true;let wasSet=await this.setUser(u);let structs=this.getLocalData(void 0,{"ownerId":u._id});if(structs?.length>0)this.updateServerData(structs);this.setAuthorizationsByGroup(u)}else{u=user;let toUpdate={_id:userinfo._id,ownerId:userinfo._id};let struct=this.userStruct(userinfo,false);for(const key in struct){if(userinfo[key]&&user[key]!==userinfo[key]){toUpdate[key]=userinfo[key];user[key]=userinfo[key]}else if(struct[key]&&!user[key]){toUpdate[key]=struct[key];user[key]=struct[key]}}if(Object.keys(toUpdate).length>2)await this.setUser(toUpdate);if(res?.authorizations){if(Array.isArray(res.authorizations)){this.setLocalData(res.authorizations)}}if(res?.groups){if(Array.isArray(res.groups)){this.setLocalData(res.groups)}}}if(newu){this.setLocalData(u)}else{let data=await this.getAllUserData(u._id,void 0,[genTimestampFromString("last day"),Date.now()]);if(!data||data.length===0){}else{this.setLocalData(data);let notes=data.filter(s=>{if(s.structType==="notification"){if(this.getLocalData("authorization",s.parent._id)){return true}if(s.parent.structType==="user"||s.parent.structType==="authorization"){return true}if(!this.getLocalData(s.parent.structType,s.parent._id))return true}});let comments=data.filter(s=>{if(s.structType==="comment"){return true}});let toDelete=[];comments.forEach(comment=>{if(!this.getLocalData("comment",{"_id":comment._id}))toDelete.push(comment._id)});if(toDelete.length>0)this.deleteData(toDelete);if(notes.length>0){this.resolveNotifications(notes,false,void 0);changed=true}let filtered=data.filter(o=>{if(o.structType!=="notification")return true});if(this.tablet)this.tablet.sortStructsIntoTable(filtered)}this.setLocalData(u)}if(u){if(this.currentUser)Object.assign(this.currentUser,u);else this.currentUser=u;callback(this.currentUser);return this.currentUser}else{callback(u);return u}};baseServerCallback=data=>{let structs=data;if(typeof data==="object"&&data?.structType)structs=[data];if(Array.isArray(structs)){let filtered=structs.filter(o=>{if(o.structType!=="notification")return true});if(this.tablet)this.tablet.sortStructsIntoTable(filtered);structs.forEach(struct=>{if(typeof struct==="object"){if(!struct.structType||struct.structType==="USER"){if(struct.email)struct.structType="user";else struct.structType="uncategorized"}if(struct.structType==="user"||struct.structType==="authorization"||struct.structType==="group"){if(struct.structType==="user"){struct._id=struct.id}else if(struct.structType==="group"){if(this.currentUser){let uset=false;if(struct.admins[this.currentUser?._id]&&!this.currentUser.userRoles?.[struct.name+"_admin"]){this.currentUser.userRoles[struct.name+"_admin"]=true;uset=true}else if(!struct.admins[this.currentUser?._id]&&this.currentUser.userRoles?.[struct.name+"_admin"]){delete this.currentUser.userRoles[struct.name+"_admin"];uset=true}if(struct.admins[this.currentUser?._id]&&!this.currentUser.userRoles?.[struct.name+"_peer"]){this.currentUser.userRoles[struct.name+"_peer"]=true;uset=true}else if(!struct.admins[this.currentUser?._id]&&this.currentUser.userRoles?.[struct.name+"_peer"]){delete this.currentUser.userRoles[struct.name+"_peer"];uset=true}if(struct.admins[this.currentUser?._id]&&!this.currentUser.userRoles?.[struct.name+"_client"]){this.currentUser.userRoles[struct.name+"_client"]=true;uset=true}else if(!struct.admins[this.currentUser?._id]&&this.currentUser.userRoles?.[struct.name+"_client"]){delete this.currentUser.userRoles[struct.name+"_client"];uset=true}if(uset)this.setUser(this.currentUser)}}this.setLocalData(struct)}else{if(struct.structType==="notification"){let found=this.getLocalData("notification",{"ownerId":struct.ownerId,"_id":struct.parent._id});if(found){this.setLocalData(struct)}else{if(this.getLocalData(struct.structType,{"_id":struct.parent._id})){}else{this.overwriteLocalData(struct)}}if(struct.ownerId===this.currentUser?._id&&(struct.parent.structType==="user"||struct.parent.structType==="dataInstance"||struct.parent.structType==="schedule"||struct.parent.structType==="authorization")){this.resolveNotifications([struct],true)}}else{this.overwriteLocalData(struct)}}}})}this.onResult(data)};structNotification=()=>{this.checkForNotifications()};structDeleted=struct=>{this.deleteLocalData([struct])};onResult=data=>{};randomId(tag=""){return`${tag+Math.floor(Math.random()+Math.random()*Math.random()*1e16)}`}addStruct=async(structType="struct",props={},parentUser,parentStruct,updateServer=true)=>{let newStruct=DataStructures_exports.Struct(structType,props,parentUser,parentStruct);if(updateServer)newStruct=await this.updateServerData([newStruct])[0];return newStruct};getUser=async(info="",basicInfo,callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"getUser",args:[this.currentUser._id,info,basicInfo,this.getToken(this.currentUser)]});callback(res);return res}};queryUsers=async(info,skip,limit,callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"queryUsers",args:[this.currentUser._id,info,skip,limit,void 0,this.getToken(this.currentUser)]});callback(res);return res}};getUsers=async(ids=[],basicInfo,callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"getUsersByIds",args:[this.currentUser._id,ids,basicInfo]});callback(res);return res}};getUsersByRole=async(userRole,callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"getUsersByRole",args:[this.currentUser._id,userRole]});callback(res);return res}};getAllUserData=async(ownerId,excluded=[],timeRange,callback=this.baseServerCallback)=>{if(timeRange){if(typeof timeRange[0]==="string")timeRange[0]=genTimestampFromString(timeRange[0]);if(typeof timeRange[1]==="string")timeRange[1]=genTimestampFromString(timeRange[1])}if(this.currentUser?.request){let res=await this.currentUser.request({route:"getAllData",args:[this.currentUser._id,ownerId,excluded,timeRange,this.getToken(this.currentUser)]});callback(res);return res}};query=async(collection,mongoQuery={},findOne=false,skip=0,callback=this.baseServerCallback)=>{if(this.currentUser?.request){if(!collection||!mongoQuery)return void 0;let res=await this.currentUser.request({route:"query",args:[this.currentUser._id,collection,mongoQuery,findOne,skip,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};getDataByTimeRange(collection,timeRange,ownerId,limit=0,skip=0,key){let query={};if(timeRange){if(typeof timeRange[0]==="string")timeRange[0]=genTimestampFromString(timeRange[0]);if(typeof timeRange[1]==="string")timeRange[1]=genTimestampFromString(timeRange[1])}let range={$gt:timeRange[0],$lt:timeRange[1]};if(key)query[key]=range;else query.timestamp=range;return this.getData(collection,ownerId,query,limit,skip)}getData=async(collection,ownerId,searchDict,limit=0,skip=0,callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"getData",args:[this.currentUser._id,collection,ownerId,searchDict,limit,skip,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};getDataByIds=async(structIds=[],ownerId,collection,callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"getDataByIds",args:[this.currentUser._id,structIds,ownerId,collection,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};getStructParentData=async(struct,callback=this.baseServerCallback)=>{if(!struct?.parent)return;if(this.currentUser?.request){let args=[this.currentUser._id,struct.parent?.structType,"_id",struct.parent?._id,this.getToken(this.currentUser)];let res=(await this.currentUser.request({route:"getData",args}))?.[0];if(typeof callback==="function")callback(res);return res}};setUser=async(userStruct,callback=this.baseServerCallback)=>{if(userStruct&&this.currentUser?.request){let res=await this.currentUser.request({route:"setUser",args:[this.currentUser._id,this.stripStruct(userStruct),this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};checkUserToken=async(usertoken,user=this.currentUser,callback=this.baseServerCallback)=>{if(!usertoken)return false;let changed=false;for(const prop in usertoken){let dummystruct=this.userStruct();if(user[prop]&&prop!=="_id"){if(Array.isArray(usertoken[prop])){for(let i=0;i{if(this.currentUser?.request){const copies=new Array;if(!Array.isArray(structs)&&typeof structs==="object")structs=[structs];structs.forEach(struct=>{copies.push(this.stripStruct(struct))});let res=await this.currentUser.request({route:"setData",args:[this.currentUser._id,copies,notify,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};updateServerData=this.setData;deleteData=async(structs=[],callback=this.baseServerCallback)=>{if(this.currentUser?.request){let toDelete=[];structs.forEach(struct=>{if(typeof struct==="object"){if(struct?.structType&&struct?._id){toDelete.push({structType:struct.structType,_id:struct._id});this.deleteLocalData(struct)}}else if(typeof struct==="string"){let localstruct=this.getLocalData(void 0,{_id:struct});if(localstruct&&!Array.isArray(localstruct)){toDelete.push({structType:localstruct.structType,_id:localstruct._id})}else{toDelete.push({_id:struct})}}});let res=await this.currentUser.request({route:"deleteData",args:[this.currentUser._id,toDelete,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};deleteUser=async(userId=this.currentUser._id,deleteData,callback=this.baseServerCallback)=>{if(this.currentUser?.request){if(!userId)return;let res=await this.currentUser.request({route:"deleteUser",args:[this.currentUser._id,userId,deleteData,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};setGroup=async(groupStruct,callback=this.baseServerCallback)=>{if(groupStruct&&this.currentUser?.request){let res=await this.currentUser.request({route:"setGroup",args:[this.currentUser._id,this.stripStruct(groupStruct),this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};getUserGroups=async(userId=this.currentUser._id,groupId="",callback=this.baseServerCallback)=>{if(this.currentUser?.request){let res=await this.currentUser.request({route:"getUserGroups",args:[this.currentUser._id,userId,groupId,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};deleteGroup=async(groupId,callback=this.baseServerCallback)=>{if(this.currentUser?.request){if(!groupId)return;this.deleteLocalData(groupId);let res=await this.currentUser.request({route:"deleteGroup",args:[this.currentUser._id,groupId,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};setAuthorization=async(authorizationStruct,callback=this.baseServerCallback)=>{if(authorizationStruct&&this.currentUser?.request){let res=await this.currentUser.request({route:"setAuthorization",args:[this.currentUser._id,this.stripStruct(authorizationStruct),this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};getAuthorizations=async(userId=this.currentUser?._id,authorizationId="",callback=this.baseServerCallback)=>{if(this.currentUser?.request){if(userId===void 0)return;let res=await this.currentUser.request({route:"getAuthorizations",args:[this.currentUser._id,userId,authorizationId,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};deleteAuthorization=async(authorizationId,callback=this.baseServerCallback)=>{if(this.currentUser?.request){if(!authorizationId)return;this.deleteLocalData(authorizationId);let res=await this.currentUser.request({route:"deleteAuthorization",args:[this.currentUser._id,authorizationId,this.getToken(this.currentUser)]});if(typeof callback==="function")callback(res);return res}};checkForNotifications=async(userId=this.currentUser?._id)=>{return await this.getData("notification",userId)};resolveNotifications=async(notifications=[],pull=true,user=this.currentUser)=>{if(!user||notifications.length===0)return;let structIds=[];let notificationIds=[];let nTypes=[];let unote=false;if(notifications.length===0)notifications=this.getLocalData("notification",{"ownerId":user._id});notifications.forEach(struct=>{if(struct.parent.structType==="user")unote=true;nTypes.push(struct.parent.structType);structIds.push(struct.parent._id);notificationIds.push(struct._id);this.deleteLocalData(struct)});this.deleteData(notifications);if(pull){nTypes.reverse().forEach((note,i)=>{if(note==="user"){this.getUser(structIds[i]);structIds.splice(structIds.length-i-1,1)}});if(structIds.length===1)return await this.getDataByIds(structIds,void 0,notifications[0].parent.structType);if(structIds.length>0)return await this.getDataByIds(structIds)}return true};setAuthorizationsByGroup=async(user=this.currentUser)=>{let auths=this.getLocalData("authorization",{"ownerId":user._id});let newauths=[];if(user.userRoles)await Promise.all(Object.keys(user.userRoles).map(async role=>{let split=role.split("_");let team=split[0];let otherrole;if(role.includes("client")){otherrole=team+"_peer"}else if(role.includes("peer")){otherrole=team+"_client"}else if(role.includes("admin")){otherrole=team+"_owner"}if(otherrole){let users=await this.getUsersByRole(otherrole);if(users)await Promise.all(users.map(async groupie=>{let theirname=groupie.username;if(!theirname)theirname=groupie.email;if(!theirname)theirname=groupie._id;let myname=user.username;if(!myname)myname=user.email;if(!myname)myname=user._id;if(theirname!==myname){if(role.includes("client")){let found=auths.find(a=>{if(a.authorizerId===groupie._id&&a.authorizedId===user._id)return true});if(!found){let auth=await this.authorizeUser(DataStructures_exports.ProfileStruct("user",user,user),groupie._id,theirname,user._id,myname,{"peer":true},void 0,{group:team});newauths.push(auth)}}else if(role.includes("peer")){let found=auths.find(a=>{if(a.authorizedId===groupie._id&&a.authorizerId===user._id)return true});if(!found){let auth=await this.authorizeUser(DataStructures_exports.ProfileStruct("user",user,user),user._id,myname,groupie._id,theirname,{"peer":true},void 0,{group:team});newauths.push(auth)}}}}))}}));if(newauths.length>0)return newauths;return void 0};deleteRoom=async roomStruct=>{if(!roomStruct)return false;let toDelete=[roomStruct];roomStruct.comments?.forEach(id=>{let struct=this.getLocalData("comment",{"_id":id});toDelete.push(struct)});if(roomStruct)return await this.deleteData(toDelete);else return false};deleteComment=async commentStruct=>{let allReplies=[commentStruct];let getRepliesRecursive=(head=commentStruct)=>{if(head?.replies){head.replies.forEach(replyId=>{let reply=this.getLocalData("comment",{"_id":replyId});if(reply){if(reply.replies.length>0){reply.replies.forEach(replyId2=>{getRepliesRecursive(replyId2)})}allReplies.push(reply)}})}};getRepliesRecursive(commentStruct);let parent=this.getLocalData(commentStruct.parent?.structType,{"_id":commentStruct.parent?._id});let toUpdate=[];if(parent){toUpdate=[parent];allReplies.forEach(r=>{let idx=parent.replies?.indexOf(r._id);if(idx>-1)parent.replies.splice(idx,1);let idx2=parent.comments?.indexOf(r._id);if(idx2>-1)parent.comments.splice(idx2,1)})}let replyTo=this.getLocalData("comment",{"_id":commentStruct.replyTo});if(replyTo?._id!==parent?._id){let idx=replyTo.replies?.indexOf(parent._id);if(idx>-1)replyTo.replies.splice(idx,1);toUpdate.push(replyTo)}if(toUpdate.length>0)await this.updateServerData(toUpdate);return await this.deleteData(allReplies)};getUserDataByAuthorization=async(authorizationStruct,collection,searchDict,limit=0,skip=0,callback=this.baseServerCallback)=>{let u=authorizationStruct.authorizerId;if(u){return new Promise(async resolve=>{this.getUser(u,true,async data=>{let res;if(!collection)res=await this.getAllUserData(u,["notification"],void 0,callback);else res=await this.getData(collection,u,searchDict,limit,skip,callback);resolve(res);callback(res)})})}else return void 0};getUserDataByAuthorizationGroup=async(groupId="",collection,searchDict,limit=0,skip=0,callback=this.baseServerCallback)=>{let auths=this.getLocalData("authorization");let results=[];await Promise.all(auths.map(async o=>{if(o.groups?.includes(groupId)){let u=o.authorizerId;if(u){let data;let user=await this.getUser(u,true,callback);if(user)results.push(user);if(!collection)data=await this.getAllUserData(u,["notification"],void 0,callback);else data=await this.getData(collection,u,searchDict,limit,skip,callback);if(data)results.push(data)}return true}}));return results};overwriteLocalData(structs){if(Array.isArray(structs)){structs.forEach(struct=>{let localdat=this.getLocalData(struct.structType,{"ownerId":struct.ownerId,"_id":struct._id});if(!localdat||localdat?.length===0){this.setLocalData(struct)}else Object.assign(localdat,struct)})}else{let localdat=this.getLocalData(structs.structType,{"ownerId":structs.ownerId,"_id":structs._id});if(!localdat||localdat?.length===0){this.setLocalData(structs)}else Object.assign(localdat,structs)}}setLocalData(structs){this.tablet.setLocalData(structs)}getLocalData(collection,query){return this.tablet.getLocalData(collection,query)}getLocalUserPeerIds=(user=this.currentUser)=>{if(!user)return{};let result={};let authorizations=this.getLocalData("authorization",user._id);authorizations.forEach(a=>{if(a.authorizations["peer"]&&a.authorizerId===user._id)result[a.authorizedId]=true});return result};getLocalReplies(struct){let replies=[];if(!struct.replies)return replies;else if(struct.replies.reduce((a,b)=>a*(typeof b==="object"?1:0),1))return struct.replies;replies=this.getLocalData("comment",{"replyTo":struct._id});return replies}hasLocalAuthorization(otherUserId,ownerId=this.currentUser._id){let auths=this.getLocalData("authorization",{ownerId});let found=auths.find(a=>{if(a.authorizedId===ownerId&&a.authorizerId===otherUserId)return true;if(a.authorizerId===ownerId&&a.authorizedId===otherUserId)return true});if(found){return found}else return false}deleteLocalData(structs){if(Array.isArray(structs))structs.forEach(s=>this.deleteStruct(s));else this.deleteStruct(structs);return true}deleteStruct(struct){if(typeof struct==="string")struct=this.getLocalData(void 0,{_id:struct});if(!struct)throw new Error("Struct not supplied");if(!struct.structType||!struct._id)return false;this.tablet.collections.get(struct.structType).delete(struct._id);return true}stripStruct(struct){const copy=Object.assign({},struct);for(const prop in copy){if(copy[prop]===void 0||copy[prop]===""||copy[prop].constructor.name==="Map"||copy[prop].constructor.name==="Set"||typeof copy[prop]==="function")delete copy[prop];else if(Array.isArray(copy[prop])&©[prop].length===0)delete copy[prop];else if(typeof copy[prop]==="object"&&Object.keys(copy[prop]).length===0)delete copy[prop]}return copy}createStruct(structType,props,parentUser=this.currentUser,parentStruct){let struct=DataStructures_exports.Struct(structType,props,parentUser,parentStruct);return struct}userStruct(props={},currentUser=false){let user=DataStructures_exports.ProfileStruct(void 0,props,props);if(!user.name&&user.firstName)user.name=user.firstName+" "+user.lastName;else if(user.name&&!user.firstName){let split=user.name.split(" ");user.firstName=split[0];user.lastName=split[split.length-1]}if(props._id)user.id=props._id;else if(props.id)user.id=props.id;else user.id="user"+Math.floor(Math.random()*1e15);user._id=user.id;user.ownerId=user.id;let dummy=DataStructures_exports.ProfileStruct();for(const prop in props){if(Object.keys(dummy).indexOf(prop)<0){delete user[prop]}}if(currentUser)this.currentUser=user;return user}authorizeUser=async(parentUser,authorizerUserId="",authorizerUserName="",authorizedUserId="",authorizedUserName="",authorizations={},structs={},excluded={},groups={},expires=false)=>{if(!parentUser)return void 0;let newAuthorization=this.createStruct("authorization",void 0,parentUser,void 0);newAuthorization.authorizedId=authorizedUserId;newAuthorization.authorizedName=authorizedUserName;newAuthorization.authorizerId=authorizerUserId;newAuthorization.authorizerName=authorizerUserName;newAuthorization.authorizations=authorizations;newAuthorization.structs=structs;newAuthorization.excluded=excluded;newAuthorization.groups=groups;newAuthorization.expires=expires;newAuthorization.status="PENDING";newAuthorization.associatedAuthId="";newAuthorization=await this.setAuthorization(newAuthorization);return newAuthorization};addGroup=async(parentUser,name="",details="",admins={},peers={},clients={},updateServer=true)=>{if(!parentUser)return void 0;let newGroup=this.createStruct("group",void 0,parentUser);newGroup.name=name;newGroup.details=details;newGroup.admins=admins;newGroup.peers=peers;newGroup.clients=clients;newGroup.users={};Object.assign(newGroup.users,newGroup.admins);Object.assign(newGroup.users,newGroup.peers);Object.assign(newGroup.users,newGroup.clients);if(updateServer){newGroup=await this.setGroup(newGroup)}return newGroup};dataObject(data=void 0,type="any",timestamp=Date.now()){return{type,data,timestamp}}addData=async(parentUser,author="",title="",type="",data=[],expires=false,updateServer=true)=>{if(!parentUser)return void 0;let newDataInstance=this.createStruct("dataInstance",void 0,parentUser);newDataInstance.author=author;newDataInstance.title=title;newDataInstance.type=type;newDataInstance.data=data;newDataInstance.expires=expires;if(updateServer)newDataInstance=await this.updateServerData([newDataInstance])[0];return newDataInstance};addEvent=async(parentUser,author="",event="",notes="",startTime=void 0,endTime=void 0,grade=void 0,value=void 0,units=void 0,location=void 0,attachments=void 0,users=void 0,updateServer=true)=>{if(!parentUser)return void 0;if(users&&Object.keys(users).length===0)users=this.getLocalUserPeerIds(parentUser);let newEvent=this.createStruct("event",void 0,parentUser);newEvent.author=author;newEvent.event=event;newEvent.notes=notes;newEvent.startTime=startTime;newEvent.endTime=endTime;newEvent.grade=grade;newEvent.attachments=attachments;newEvent.value=value;newEvent.units=units;newEvent.users=users;newEvent.location=location;if(updateServer)newEvent=await this.updateServerData([newEvent])[0];return newEvent};addChatroom=async(parentUser,authorId="",message="",attachments=void 0,users=void 0,updateServer=true)=>{if(!parentUser)return void 0;if(users&&Object.keys(users).length===0)users=this.getLocalUserPeerIds(parentUser);let newChatroom=this.createStruct("chatroom",void 0,parentUser);newChatroom.message=message;newChatroom.attachments=attachments;newChatroom.authorId=authorId;newChatroom.users=users;newChatroom.replies=[];newChatroom.comments=[];let update=[newChatroom];if(updateServer)newChatroom=await this.updateServerData(update)[0];return newChatroom};addComment=async(parentUser,roomStruct,replyTo,authorId="",message="",attachments=void 0,updateServer=true)=>{if(!roomStruct)return void 0;if(!replyTo)replyTo=roomStruct;if(!parentUser)return void 0;let newComment=this.createStruct("comment",void 0,parentUser,roomStruct);newComment.authorId=authorId;newComment.replyTo=replyTo?._id;newComment.message=message;newComment.attachments=attachments;newComment.users=roomStruct?.users;newComment.replies=[];if(!updateServer)replyTo?.replies.push(newComment._id);if(!updateServer)roomStruct?.comments.push(newComment._id);let update=[newComment,roomStruct];if(replyTo?._id!==roomStruct._id)update.push(replyTo);let res;if(updateServer)res=await this.updateServerData(update);let updatedComment;if(typeof res==="object"){updatedComment=res.find(s=>{if(newComment.ownerId===s.ownerId&&newComment.timestamp===s.timestamp&&newComment.message===s.message){return true}})}if(updatedComment)return updatedComment;return res}};var import_bson=__toESM(require_bson());var randomId2=prefix=>(prefix?`${prefix}_`:"")+Math.floor(1e15*Math.random());var toObjectId=str2=>{return typeof str2==="string"&&str2.length===24?new import_bson.ObjectId(str2):str2};var getStringId=mongoid=>{if(typeof mongoid==="object")return mongoid.toString();else return mongoid};var defaultCollections=["profile","group","authorization","discussion","chatroom","comment","dataInstance","event","notification","schedule","date"];var StructBackend=class extends Service{name="structs";debug=false;db;users={};collections={};mode="local";useAuths=true;useAccessTokens=false;useRefreshTokens=false;accessTokens=new Map;refreshTokens=new Map;constructor(options,dboptions){super(options);this.load(this);if(dboptions){this.initDB(dboptions)}}initDB=dboptions=>{this.db=dboptions.db;if(dboptions?.users)this.users=dboptions.users;if(dboptions.mode)this.mode=dboptions.mode;if(dboptions?.collections)this.collections=dboptions.collections;if(dboptions.debug)this.debug=dboptions.debug;if(dboptions.useAccessTokens)this.useAccessTokens=dboptions.useAccessTokens;if(dboptions.useRefreshTokens)this.useRefreshTokens=dboptions.useRefreshTokens;if("useAuths"in dboptions)this.useAuths=dboptions.useAuths;defaultCollections.forEach(k=>{if(!this.collections[k]){this.collections[k]=this.db?{instance:this.db.collection(k)}:{};this.collections[k].reference={}}})};query=async(requestingUserId,collection,queryObj,findOne,skip,token)=>{let user=this.users[requestingUserId];if(!user)return false;if(this.mode.indexOf("mongo")>-1){return await this.queryMongo(user,collection,queryObj,findOne,skip,token)}else{let res=this.getLocalData(user,collection);if(res&&!Array.isArray(res)){let passed=!this.useAuths;if(!res?.ownerId)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,res,"READ",token);if(passed)return res}if(typeof skip==="number"&&Array.isArray(res)){if(res.length>skip)res.splice(0,skip)}let data=[];if(res)await Promise.all(res.map(async s=>{let struct=this.getLocalData(getStringId(s._id));let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);if(passed)data.push(struct)}));return data}};getUser=async(requestingUserId,lookupId,basicInfo,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.indexOf("mongo")>-1){data=await this.getMongoUser(user,lookupId,void 0,basicInfo,token)}else{let struct=this.getLocalData("profile",{_id:lookupId});if(!struct)data={user:void 0};else{let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);if(passed){let groups=this.getLocalData("group",{ownerId:lookupId});let auths=this.getLocalData("authorization",{ownerId:lookupId});data={user:struct,groups,authorizations:auths}}else data={user:{}}}}if(this.debug)console.log("getUser: user:",user,"input:",lookupId,"output",data);return data};setUser=async(requestingUserId,struct,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(struct.accessToken){this.accessTokens.set(requestingUserId,token)}if(struct.refreshToken){this.refreshTokens.set(requestingUserId,struct.refreshToken)}delete struct.accessToken;delete struct.refreshToken;delete user.accessToken;delete user.refreshToken;if(this.mode.indexOf("mongo")>-1){data=await this.setMongoUser(user,struct,token)}else{let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(passed)this.setLocalData(struct);return true}if(this.debug)console.log("setUser user:",user,"input:",struct,"output",data);return data};getUsersByIds=async(requestingUserId,userIds,basicInfo)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getMongoUsersByIds(user,userIds,basicInfo)}else{data=[];if(Array.isArray(userIds)){let struct=this.getLocalData("profile",{_id:userIds});if(struct){if(basicInfo)data.push({_id:struct._id,username:struct.username,firstName:struct.firstName,lastName:struct.lastName,fullName:struct.fullName,pictureUrl:struct.pictureUrl});else data.push(struct)}}}if(this.debug)console.log("getUserByIds: user:",user,"input:",userIds,"output",data);return data};getUsersByRole=async(requestingUserId,role)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getMongoUsersByRole(user,role)}else{let profiles=this.getLocalData("profile");data=[];profiles.forEach(struct=>{if(struct.userRoles[role]){data.push(struct)}})}if(this.debug)console.log("getUserByRoles: user:",user,"input:",role,"output",data);return data};deleteUser=async(requestingUserId,userId,deleteData,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.deleteMongoUser(user,userId,deleteData,token)}else{data=false;let struct=this.getLocalData(userId);if(struct){let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(passed)data=this.deleteLocalData(struct)}}if(this.debug)console.log("deleteUser: user:",user,"input:",userId,"output",data);return data};setData=async(requestingUserId,structs,notify,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.setMongoData(user,structs,notify,token)}else{let non_notes=[];data=[];await Promise.all(structs.map(async structId=>{let struct=this.getLocalData(structId);let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(passed){if(!this.collections[struct.structType]){this.collections[struct.structType]={};this.collections[struct.structType].reference={}}this.setLocalData(struct);data.push(struct);if(struct.structType!=="notification")non_notes.push(struct)}}));if(non_notes.length>0&&(notify===true||typeof notify==="undefined"))this.checkToNotify(user,non_notes,this.mode);if(this.debug)console.log("setData:",user,structs,data);return true}if(this.debug)console.log("setData: user:",user,"input:",structs,notify,"output",data);return data};getData=async(requestingUserId,collection,ownerId,dict,limit,skip,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getMongoData(user,collection,ownerId,dict,limit,skip,token)}else{data=[];let structs;if(collection)structs=this.getLocalData(collection);if(structs&&ownerId)structs=structs.filter(o=>{if(o.ownerId===ownerId)return true});if(structs)await Promise.all(structs.map(async s=>{let struct=this.getLocalData(getStringId(s._id));let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);if(passed)data.push(struct)}))}if(this.debug)console.log("getData: user:",user,"input:",collection,ownerId,dict,limit,skip,"output",data);return data};getDataByIds=async(requestingUserId,structIds,ownerId,collection,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getMongoDataByIds(user,structIds,ownerId,collection,token)}else{data=[];let structs;if(collection)structs=this.getLocalData(collection);if(structs&&ownerId)structs=structs.filter(o=>{if(o.ownerId===ownerId)return true});if(structs)await Promise.all(structs.map(async s=>{let struct=this.getLocalData(getStringId(s._id));let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);if(passed)data.push(struct)}))}if(this.debug)console.log("getDataByIds: user:",user,"input:",structIds,ownerId,collection,"output",data);return data};getAllData=async(requestingUserId,ownerId,excludedCollections,timeRange,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getAllUserMongoData(user,ownerId,excludedCollections,timeRange,token)}else{let result=this.getLocalData(void 0,{ownerId});data=[];await Promise.all(result.map(async struct=>{if(excludedCollections){if(excludedCollections.indexOf(struct.structType)<0){let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);if(passed)data.push(struct)}}else{let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);if(passed)data.push(struct)}}))}if(this.debug)console.log("getAllData: user:",user,"input:",ownerId,excludedCollections,"output",data);return data};deleteData=async(requestingUserId,structIds,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.deleteMongoData(user,structIds,token)}else{data=false;await Promise.all(structIds.map(async structId=>{let struct=this.getLocalData(structId);let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(passed)this.deleteLocalData(struct);data=true}))}if(this.debug)console.log("deleteData: user:",user,"input:",structIds,"output",data);return data};getUserGroups=async(requestingUserId,userId,groupId)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getMongoGroups(user,userId,groupId)}else{if(typeof groupId==="string"){data=this.getLocalData("group",{_id:groupId})}else{data=[];let result=this.getLocalData("group");if(userId){result.forEach(struct=>{if(Object.keys(struct.users).includes(userId))data.push(struct)})}else{result.forEach(struct=>{if(Object.keys(struct.users).includes(getStringId(user._id)))data.push(struct)})}}}if(this.debug)console.log("getGroups: user:",user,"input:",userId,groupId,"output",data);return data};deleteGroup=async(requestingUserId,groupId,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.deleteMongoGroup(user,groupId,token)}else{let struct=this.getLocalData("group",groupId);let passed=!this.useAuths;if(struct){if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token)}if(passed){data=true}}if(this.debug)console.log("deleteGroup: user:",user,"input:",groupId,"output",data);return data};getAuthorizations=async(requestingUserId,ownerId,authId,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.getMongoAuthorizations(user,ownerId,authId,token)}else{if(authId){let result=this.getLocalData("authorization",{_id:authId});if(result)data=[result]}else{data=this.getLocalData("authorization",{ownerId})}}if(this.debug)console.log("getAuthorizations: user:",user,"input:",ownerId,authId,"output",data);return data};deleteAuthorization=async(requestingUserId,authId,token)=>{let user=this.users[requestingUserId];if(!user)return false;let data;if(this.mode.includes("mongo")){data=await this.deleteMongoAuthorization(user,authId,token)}else{data=true;let struct=this.getLocalData("authorization",{_id:authId});if(struct){let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(passed)data=this.deleteLocalData(struct)}}if(this.debug)console.log("deleteAuthorization: user:",user,"input:",authId,"output",data);return data};getToken=user=>{return this.useAccessTokens?this.accessTokens.get(user._id):this.useRefreshTokens?this.refreshTokens.get(user._id):void 0};notificationStruct=(parentStruct={})=>{let structType="notification";let struct={structType,timestamp:Date.now(),_id:randomId2(structType),note:"",alert:false,ownerId:"",parentUserId:"",parent:{structType:parentStruct?.structType,_id:getStringId(parentStruct?._id)}};return struct};checkToNotify=async(user,structs=[],mode=this.mode)=>{if(structs.length===0)return false;if(typeof user==="string"){for(let key in this.users){const obj=this.users[key];if(getStringId(obj._id)===user)user=obj}}if(typeof user==="string"||user==null)return false;let usersToNotify={};let newNotifications=[];structs.forEach(async struct=>{if(struct?._id){if(struct.ownerId&&user?._id!==struct.ownerId){let newNotification=this.notificationStruct(struct);newNotification._id="notification_"+getStringId(struct._id)+"_"+struct.ownerId;newNotification.ownerId=struct.ownerId;newNotification.note=struct.structType;newNotification.parentUserId=struct.ownerId;if(struct.alert)newNotification.alert=struct.alert;newNotifications.push(newNotification);usersToNotify[struct.ownerId]=struct.ownerId}if(struct.users){Object.keys(struct.users).forEach(usr=>{if(usr!==user._id){let newNotification=this.notificationStruct(struct);newNotification._id="notification_"+getStringId(struct._id)+"_"+usr;newNotification.ownerId=usr;newNotification.note=struct.structType;if(struct.alert)newNotification.alert=struct.alert;newNotification.parentUserId=struct.ownerId;newNotifications.push(newNotification);usersToNotify[usr]=usr}})}else{let auths=[];if(mode.includes("mongo")){let s=this.collections.authorization.instance.find({$or:[{authorizedId:user._id},{authorizerId:user._id}]});let arr=await s.toArray();if(arr.length>0){arr.forEach(d=>auths.push(d))}}else{auths=this.getLocalData("authorization",{authorizedId:user._id});auths.push(...this.getLocalData("authorization",{authorizerId:user._id}))}if(auths.length>0){auths.forEach(auth=>{if(struct.authorizerId===struct.ownerId&&!usersToNotify[struct.authorizedId]){if(auth.status==="OKAY"&&auth.authorizations["peer"]){let newNotification=this.notificationStruct(struct);newNotification.ownerId=auth.authorizedId;newNotification._id="notification_"+getStringId(struct._id)+"_"+auth.authorizedId;newNotification.note=struct.structType;newNotification.parentUserId=struct.ownerId;if(struct.alert)newNotification.alert=struct.alert;newNotifications.push(newNotification);usersToNotify[newNotification.ownerId]=newNotification.ownerId}}})}}}});if(newNotifications.length>0){if(mode.includes("mongo")){await this.setMongoData(user,newNotifications,true,this.getToken(user))}else{this.setLocalData(newNotifications)}for(const uid in usersToNotify){this.users[uid]?.sendAll({route:"structNotification",args:true})}return true}else return false};queryMongo=async(user,collection,queryObj={},findOne=false,skip=0,token)=>{if(!collection&&!queryObj)return void 0;else if(findOne){let res=await this.db.collection(collection).findOne(queryObj);if(!res)return void 0;let passed=!this.useAuths;if(!res?.ownerId){passed=true}else if(getStringId(user._id)!==res.ownerId||getStringId(user._id)===res.ownerId&&user.userRoles?.admincontrol){if(this.useAuths)passed=await this.checkAuthorization(user,res,"READ",token)}if(passed)return res;else return void 0}else{let res=this.db.collection(collection).find(queryObj).sort({$natural:-1}).skip(skip);let structs=[];let arr=await res.toArray();if(arr.length>0){let passed=!this.useAuths;let checkedAuth="";for(const s of arr){if(!s?.ownerId){passed=true}else if((getStringId(user._id)!==s.ownerId||getStringId(user._id)===s.ownerId&&user.userRoles?.admincontrol)&&checkedAuth!==s.ownerId){if(this.useAuths)passed=await this.checkAuthorization(user,s,"READ",token);checkedAuth=s.ownerId}if(passed)structs.push(s)}}return structs}};setMongoData=async(user,structs=[],notify=true,token)=>{let firstwrite=false;if(structs.length>0){let passed=!this.useAuths;let checkedAuth="";await Promise.all(structs.map(async struct=>{let secondary={};if(Array.isArray(struct)){secondary=struct[1];struct=struct[0]}if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if((getStringId(user._id)!==struct.ownerId||getStringId(user._id)===struct.ownerId&&user.userRoles?.admincontrol)&&checkedAuth!==struct.ownerId){if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);checkedAuth=struct.ownerId}if(passed){if(struct.structType){if(!this.collections[struct.structType]){this.collections[struct.structType]={};this.collections[struct.structType].reference={}}let copy=JSON.parse(JSON.stringify(struct));if(copy._id)delete copy._id;if(struct._id){if(getStringId(struct._id).includes("defaultId")){await this.db.collection(struct.structType?struct.structType:"data").insertOne(copy);firstwrite=true}else if(struct.structType==="notification")await this.db.collection(struct.structType?struct.structType:"data").updateOne({_id:struct._id},{$set:copy,...secondary},{upsert:true,unique:false});else await this.db.collection(struct.structType?struct.structType:"data").updateOne({_id:toObjectId(struct._id)},{$set:copy,...secondary},{upsert:true})}else if(struct.structType){this.db.collection(struct.structType?struct.structType:"data").insertOne(copy)}}}}));if(firstwrite===true){let toReturn=[];await Promise.all(structs.map(async(struct,j)=>{let copy=JSON.parse(JSON.stringify(struct));if(copy._id&©.structType!=="profile")delete copy._id;if(struct.structType!=="comment"){let pulled;if(struct.structType!=="notification")pulled=await this.db.collection(copy.structType).findOne(copy);if(pulled){pulled._id=getStringId(pulled._id);toReturn.push(pulled)}}else if(struct.structType==="comment"){let comment=struct;let copy2=JSON.parse(JSON.stringify(comment));if(copy2._id)delete copy2._id;let pulledComment=await this.db.collection("comment").findOne(copy2);let replyToId=pulledComment?.replyTo;let replyTo=structs.find(s=>{if(getStringId(s._id)===replyToId)return true});if(replyTo){let copy3=JSON.parse(JSON.stringify(replyTo));if(copy3._id)delete copy3._id;let pulledReply;await Promise.all(["discussion","chatroom","comment"].map(async name=>{let found=await this.db.collection(name).findOne({_id:toObjectId(replyToId)});if(found)pulledReply=found}));if(pulledReply){let roomId=getStringId(pulledComment.parent._id);let room,pulledRoom;if(roomId!==replyToId){room=structs.find(s=>{if(getStringId(s._id)===roomId)return true});if(room){delete room._id;await Promise.all(["discussion","chatroom"].map(async name=>{let found=await this.db.collection(name).findOne(room);if(found)pulledRoom=found}))}}else pulledRoom=pulledReply;let toUpdate=[pulledComment];if(pulledReply){let i=pulledReply.replies.indexOf(getStringId(pulledComment._id));if(i<0){pulledReply.replies.push(getStringId(pulledComment._id));pulledComment.replyTo=getStringId(pulledReply._id)}toUpdate.push(pulledReply)}if(pulledRoom){let i=pulledRoom.comments.indexOf(pulledComment._id);if(i<0){pulledRoom.comments.push(getStringId(pulledComment._id));pulledComment.parent._id=getStringId(pulledRoom._id)}}await Promise.all(toUpdate.map(async s=>{let copy4=JSON.parse(JSON.stringify(s));delete copy4._id;await this.db.collection(s.structType).updateOne({_id:toObjectId(s._id)},{$set:copy4},{upsert:false})}));[...toReturn].reverse().forEach((s,j2)=>{if(toUpdate.find(o=>{if(getStringId(s._id)===getStringId(o._id))return true})){toReturn.splice(toReturn.length-j2-1,1)}});toReturn.push(...toUpdate)}}else if(pulledComment){toReturn.push(pulledComment)}}}));if(notify)this.checkToNotify(user,toReturn);return toReturn}else{let non_notes=[];structs.forEach(s=>{if(s.structType!=="notification")non_notes.push(s)});if(notify)this.checkToNotify(user,non_notes);return true}}else return false};setMongoUser=async(user,struct,token)=>{if(struct._id){const _id=toObjectId(struct._id);let usersearch={_id};let userexists=await this.collections.profile.instance.findOne(usersearch);if(userexists){if(getStringId(user._id)!==struct.ownerId||getStringId(user._id)===struct.ownerId&&user.userRoles?.admincontrol){let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(!passed)return false}}let copy=JSON.parse(JSON.stringify(struct));copy._id=_id;if(this.debug)console.log("RETURNS PROFILE",struct);await this.collections.profile.instance.updateOne(usersearch,{$set:copy},{upsert:true});user=await this.collections.profile.instance.findOne(usersearch);this.checkToNotify(user,[struct]);return user}else return false};setGroup=async(user,struct,mode=this.mode,token)=>{if(struct?._id){let uid=getStringId(user._id);let exists=void 0;if(mode.includes("mongo")){exists=await this.collections.group.instance.findOne({name:struct.name})}else{exists=this.getLocalData("group",{_id:getStringId(struct._id)})}if(exists&&(exists.ownerId!==struct.ownerId||struct.admins.indexOf(uid)<0))return false;if(uid!==struct.ownerId){let passed=!this.useAuths;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token);if(!passed)return false}let allusers=[];Object.keys(struct.users).forEach(u=>{allusers.push({email:u},{id:u},{username:u})});let users={};let ids={};if(mode.includes("mongo")){let cursor=this.collections.profile.instance.find({$or:allusers});let arr=cursor.toArray();if(arr.length>0){arr.forEach(user2=>{users[uid]=user2;ids[uid]=true})}}else{allusers.forEach(search=>{let result=this.getLocalData("profile",search);if(result.length>0){users[getStringId(result[0]._id)]=result[0];ids[getStringId(result[0]._id)]=true}})}struct.users=ids;let admins={};let peers={};let clients={};Object.keys(users).forEach(id=>{let u=users[id];if(struct.admins[getStringId(u._id)]||struct.admins[u.email]||struct.admins[u.username]||struct.admins[struct.ownerId]){if(!admins[getStringId(u._id)])admins[getStringId(u._id)]=true}if(struct.peers[getStringId(u._id)]||struct.peers[u.email]||struct.peers[u.username]||struct.peers[struct.ownerId]){if(!peers[getStringId(u._id)])peers[getStringId(u._id)]=true}if(struct.clients[getStringId(u._id)]||struct.clients[u.email]||struct.clients[u.username]||struct.clients[struct.ownerId]){if(!clients[getStringId(u._id)])clients[getStringId(u._id)]=true}});struct.admins=admins;struct.peers=peers;struct.clients=clients;let copy=JSON.parse(JSON.stringify(struct));if(copy._id)delete copy._id;if(mode.includes("mongo")){if(getStringId(struct._id).includes("defaultId")){await this.db.collection(struct.structType?struct.structType:"data").insertOne(copy);delete struct._id;struct=await this.db.collection(struct.structType?struct.structType:"data").findOne(struct);struct._id=getStringId(struct._id)}else await this.collections.group.instance.updateOne({_id:toObjectId(struct._id)},{$set:copy},{upsert:true})}else{this.setLocalData(struct)}this.checkToNotify(user,[struct],this.mode);if(this.debug)console.log("setGroup: user:",user,"output",struct);return struct}else return false};getMongoUser=(user,info="",requireAuth=true,basicInfo=false,token)=>{return new Promise(async resolve=>{const query=[{email:info},{id:info},{username:info}];try{query.push({_id:toObjectId(info)})}catch(e){console.log("error creating ObjectId with ",info)}let u=await this.collections.profile.instance.findOne({$or:query});if(!u||u==null)resolve(void 0);else{u._id=getStringId(u._id);if(!u.ownerId)u.ownerId=u._id;if(basicInfo){if(this.useAccessTokens||this.useRefreshTokens){if(this.getToken(user)!==token)resolve(void 0)}let stripped={username:u.username,firstName:u.firstName,lastName:u.lastName,fullName:u.fullName,pictureUrl:u.pictureUrl,_id:u._id};u=stripped;resolve({user:u})}else if(requireAuth){if(getStringId(user._id)!==u._id||getStringId(user._id)===u._id&&user.userRoles?.admincontrol){let passed=!this.useAuths;if(this.useAuths)passed=await this.checkAuthorization(user,u,"READ",token);if(!passed)resolve(void 0)}let authorizations=[];let auths=this.collections.authorization.instance.find({ownerId:u._id});let aarr=await auths.toArray();if(auths.toArray().length>0){aarr.forEach(d=>authorizations.push(d))}let gs=this.collections.group.instance.find({users:{$all:[u._id]}});let arr=await gs.toArray();let groups=[];if(arr.length>0){arr.forEach(d=>groups.push(d))}resolve({user:u,authorizations,groups})}else{if(this.useAccessTokens||this.useRefreshTokens){if(this.getToken(user)!==token)resolve(void 0)}resolve({user:u})}}})};queryUsers=(user,info="",limit=0,skip=0,requireAuth=false,token)=>{if(typeof user==="string")user=this.users[user];if(!user)return;return new Promise(async resolve=>{let q={$regex:`^${info}`,$options:"i"};const query=[{email:q},{username:q},{firstName:q},{lastName:q},{name:q}];let arr;if(this.mode.includes("mongo")){let users=this.collections.profile.instance.find({$or:query},{projection:shallowqueryDummy}).skip(skip);if(limit>0)users.limit(limit);await users;arr=await users.toArray()}else{arr=[];for(let i=0;i{arr.push({firstName:u.firstName,lastName:u.lastName,fullName:u.fullName,username:u.username,pictureUrl:u.pictureUrl})})}else if(dat)arr.push({firstName:dat.firstName,lastName:dat.lastName,fullName:dat.fullName,username:dat.username,pictureUrl:dat.pictureUrl})}}if(requireAuth){let result=[];let strid=getStringId(user._id);for(let i=0;i{let usrs=[];userIds.forEach(u=>{try{usrs.push({_id:toObjectId(u)})}catch{}});let found=[];if(usrs.length>0){let users=this.collections.profile.instance.find({$or:usrs});let arr=await users.toArray();if(arr.length>0){arr.forEach(u=>{if(basicInfo){found.push({username:u.username,firstName:u.firstName,lastName:u.lastName,fullName:u.fullName,pictureUrl:u.pictureUrl,_id:u._id})}else found.push(u)})}}return found};getMongoUsersByRole=async(user,role)=>{let users=this.collections.profile.instance.find({userRoles:{$all:{[role]:true}}});let found=[];let arr=await users.toArray();if(arr.length>0){arr.forEach(u=>{found.push(u)})}return found};getMongoDataByIds=async(user,structIds,ownerId,collection,token)=>{let uid=getStringId(user._id);if(structIds.length>0){let query=[];structIds.forEach(_id=>{let q={_id:toObjectId(_id)};if(ownerId)q.ownerId=ownerId;query.push(q)});let found=[];if(!collection){await Promise.all(Object.keys(this.collections).map(async name=>{let cursor=await this.db.collection(name).find({$or:query});let arr=await cursor.toArray();if(arr.length>0){let passed=true;let checkedAuth="";for(let i=0;i0){let passed=true;let checkedAuth="";arr.forEach(async s=>{if(!s?.ownerId)passed=true;else if((uid!==s.ownerId||uid===s.ownerId&&user.userRoles?.admincontrol)&&checkedAuth!==s.ownerId){if(this.useAuths)passed=await this.checkAuthorization(user,s,"READ",token);checkedAuth=s.ownerId}if(passed)found.push(s)})}}return found}};getMongoData=async(user,collection,ownerId,dict={},limit=0,skip=0,token)=>{if(!ownerId)ownerId=dict?.ownerId;if(!dict)dict={};if(dict._id)dict._id=toObjectId(dict._id);let uid=getStringId(user._id);let structs=[];let passed=true;let checkedAuth="";let cursor;if(!collection&&!ownerId&&!dict)return[];else if(!collection&&ownerId&&Object.keys(dict).length===0)return await this.getAllUserMongoData(user,ownerId);else if((!dict||Object.keys(dict).length===0)&&ownerId&&collection){cursor=this.db.collection(collection).find({ownerId}).sort({$natural:-1}).skip(skip)}else if(collection&&Object.keys(dict).length>0){if(ownerId)dict.ownerId=ownerId;cursor=await this.db.collection(collection).find(dict).sort({$natural:-1}).skip(skip)}if(cursor){if(limit>0)cursor.limit(limit);let arr=await cursor.toArray();if(arr.length>0){for(let i=0;i0&&!ownerId){await Promise.all(Object.keys(this.collections).map(async name=>{cursor=await this.db.collection(name).find(dict).sort({$natural:-1}).skip(skip);;if(cursor){if(limit>0)cursor.limit(limit);let arr=await cursor.toArray();if(arr.length>0){for(let i=0;i{let structs=[];let passed=true;let checkedId="";await Promise.all(Object.keys(this.collections).map(async(name,j)=>{if(passed&&excluded.indexOf(name)<0){let query={ownerId};if(timeRange){if(typeof timeRange[0]==="string")timeRange[0]=genTimestampFromString(timeRange[0]);if(typeof timeRange[1]==="string")timeRange[1]=genTimestampFromString(timeRange[1]);query.timestamp={$gt:timeRange[0],$lt:timeRange[1]}}let cursor=this.db.collection(name).find(query);let arr=await cursor.toArray();let count=arr.length;for(let k=0;k{let structs=[];if(structs.length>0){let checkedAuth="";structRefs.forEach(async ref=>{if(ref.structType&&getStringId(ref._id)){let struct=await this.db.collection(ref.structType).findOne({_id:toObjectId(ref._id)});if(struct){let passed=true;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if((getStringId(user._id)!==struct.ownerId||getStringId(user._id)===struct.ownerId&&user.userRoles?.admincontrol)&&checkedAuth!==struct.ownerId){if(this.useAuths)passed=await this.checkAuthorization(user,struct,"READ",token);checkedAuth=struct.ownerId}if(passed===true){structs.push(struct)}}}})}return structs};getMongoAuthorizations=async(user,ownerId=getStringId(user._id),authId="",token)=>{let auths=[];if(authId.length===0){let cursor=this.collections.authorization.instance.find({ownerId});let arr=await cursor.toArray();if(arr.length>0){arr.forEach(a=>{auths.push(a)})}}else auths.push(await this.collections.authorization.instance.findOne({_id:toObjectId(authId),ownerId}));if(!auths[0]?.ownerId)true;else if(getStringId(user._id)!==auths[0]?.ownerId){let passed=!this.useAuths;if(this.useAuths)passed=await this.checkAuthorization(user,auths[0],"READ",token);if(!passed)return void 0}return auths};getMongoGroups=async(user,userId=getStringId(user._id),groupId="")=>{let groups=[];if(groupId.length===0){let cursor=this.collections.group.instance.find({users:{$all:[userId]}});let arr=await cursor.toArray();if(arr.length>0){arr.forEach(a=>{groups.push(a)})}}else{try{groups.push(await this.collections.group.instance.findOne({_id:toObjectId(groupId),users:{$all:[userId]}}))}catch{}}return groups};deleteMongoData=async(user,structRefs=[],token)=>{let structs=[];await Promise.all(structRefs.map(async ref=>{try{let _id=toObjectId(ref._id);let struct=await this.db.collection(ref.structType).findOne({_id});if(struct){structs.push(struct);let notifications=await this.collections.notifications.instance.find({parent:{structType:ref.structType,_id:getStringId(ref._id)}});let count=notifications.toArray().length;for(let i=0;i{let passed=true;if(!struct?.ownerId||struct.ownerId===user._id)passed=true;else if((struct.ownerId!==getStringId(user._id)||getStringId(user._id)===struct.ownerId&&user.userRoles?.admincontrol)&&struct.ownerId!==checkedOwner){checkedOwner=struct.ownerId;if(this.useAuths)passed=await this.checkAuthorization(user,struct,"WRITE",token)}if(passed){await this.db.collection(struct.structType?struct.structType:"data").deleteOne({_id:toObjectId(struct._id)});if(struct.users){Object.keys(struct.users).forEach(uid=>{if(uid!==getStringId(user._id)&&uid!==struct.ownerId&&this.users[uid])this.users[uid]?.sendAll({route:"structDeleted",args:{_id:getStringId(struct._id),structType:struct.structType}})})}if(struct.ownerId!==user._id&&this.users[struct.ownerId]){this.users[struct.ownerId]?.sendAll({route:"structDeleted",args:{_id:getStringId(struct._id),structType:struct.structType}})}}}));return true};deleteMongoUser=async(user,userId,deleteData,token)=>{if(getStringId(user._id)!==userId||getStringId(user._id)===userId&&user.userRoles?.admincontrol){let u=await this.collections.profile.instance.findOne({id:userId});let passed=!this.useAuths;if(!u?.ownerId)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,u,"WRITE",token);if(!passed)return false}await this.collections.profile.instance.deleteOne({id:userId});if(deleteData){for(const key in this.collections){this.collections[key].instance.deleteMany({ownerId:userId});this.collections[key].instance.updateMany({users:{[userId]:true}},{$unset:{[`users.${userId}`]:""}})}}if(getStringId(user._id)!==userId&&this.users[userId])this.users[userId]?.sendAll({route:"structDeleted",args:{_id:userId,structType:"profile"}});return true};deleteMongoGroup=async(user,groupId,token)=>{let s=await this.collections.group.instance.findOne({_id:toObjectId(groupId)});if(s){if(!s?.ownerId)true;else if(getStringId(user._id)!==s.ownerId||getStringId(user._id)===s.ownerId&&user.userRoles?.admincontrol){let passed=!this.useAuths;if(this.useAuths)passed=await this.checkAuthorization(user,s,"WRITE",token);if(!passed)return false}if(s.users){Object.keys(s.users).forEach(u=>{this.users[u]?.sendAll({route:"structDeleted",args:{_id:getStringId(s._id),structType:s.structType}})})}await this.collections.group.instance.deleteOne({_id:toObjectId(groupId)});return true}else return false};deleteMongoAuthorization=async(user,authId,token)=>{let s=await this.collections.authorization.instance.findOne({_id:toObjectId(authId)});let uid=getStringId(user._id);if(s){if(uid!==s.ownerId||uid===s.ownerId&&user.userRoles?.admincontrol){let passed=!this.useAuths;if(!s?.ownerId)passed=true;else if(this.useAuths)passed=await this.checkAuthorization(user,s,"WRITE",token);if(!passed)return false}if(s.associatedAuthId){if(this.debug)console.log(s);await this.collections.authorization.instance.deleteOne({_id:toObjectId(s.associatedAuthId)});if(s.authorizerId!==uid)this.users[s.authorizerId]?.sendAll({route:"structDeleted",args:{_id:getStringId(s.associatedAuthId),structType:s.structType}});else if(s.authorizedId!==uid)this.users[s.authorizedId]?.sendAll({route:"structDeleted",args:{_id:getStringId(s.associatedAuthId),structType:s.structType}})}await this.collections.authorization.instance.deleteOne({_id:toObjectId(authId)});if(s.authorizerId===uid)this.users[s.authorizerId]?.sendAll({route:"structDeleted",args:{_id:getStringId(s._id),structType:s.structType}});else if(s.authorizedId===uid)this.users[s.authorizedId]?.sendAll({route:"structDeleted",args:{_id:getStringId(s._id),structType:s.structType}});return true}else return false};setAuthorization=async(user,authStruct,token)=>{let u1,u2;let mmode=this.mode.includes("mongo");if(mmode){u1=(await this.getMongoUser(user,authStruct.authorizedId,false)).user;u2=(await this.getMongoUser(user,authStruct.authorizerId,false)).user}else{u1=this.getLocalData("profile",{"_id":authStruct.authorizedId})?.[0];u2=this.getLocalData("profile",{"_id":authStruct.authorizerId})?.[0]}if(!u1||!u2)return false;if(authStruct.authorizedId!==getStringId(u1._id))authStruct.authorizedId=getStringId(u1._id);if(authStruct.authorizerId!==getStringId(u2._id))authStruct.authorizerId=getStringId(u2._id);if(!authStruct.authorizedName){if(u1.name)authStruct.authorizedName=u1.name;else if(u1.username)authStruct.authorizedName=u1.username;else if(u1.email)authStruct.authorizedName=u1.email}if(!authStruct.authorizerName){if(u1.name)authStruct.authorizedName=u1.name;else if(u2.username)authStruct.authorizerName=u2.username;else if(u2.email)authStruct.authorizerName=u2.email}if(!authStruct?.ownerId)true;else if((getStringId(user._id)!==authStruct.ownerId||getStringId(user._id)===authStruct.ownerId&&user.userRoles?.admincontrol)&&(getStringId(user._id)!==authStruct.authorizedId&&getStringId(user._id)!==authStruct.authorizerId)){let passed=!this.useAuths;if(this.useAuths)passed=await this.checkAuthorization(user,authStruct,"WRITE",token);if(!passed)return false}let auths=[];if(mmode){let s=await this.collections.authorization.instance.find({$and:[{authorizedId:authStruct.authorizedId},{authorizerId:authStruct.authorizerId}]});let arr=await s.toArray();if(arr.length>0){arr.forEach(d=>auths.push(d))}}else{let s=this.getLocalData("authorization",{authorizedId:authStruct.authorizedId});if(Array.isArray(s)){s.forEach(d=>{if(d.authorizerId===authStruct.authorizerId)auths.push(d)})}}let otherAuthset;if(Array.isArray(auths)){for(let i=0;i{if(typeof user==="string"){if(this.users[user])user=this.users[user];else user={_id:user}}if(!user||!struct)return false;if(!struct.ownerId)return true;if(typeof user==="object"){if(struct.ownerId===getStringId(user._id)){if(user.userRoles?.["admincontrol"]){}return true}}if(this.useAccessTokens){if(!this.accessTokens.get(user._id)||this.accessTokens.get(user._id)!==token){return false}}else if(this.useRefreshTokens){if(!this.refreshTokens.get(user._id)||this.refreshTokens.get(user._id)!==token){return false}}let auth1,auth2;if(this.mode.includes("mongo")){auth1=await this.collections.authorization.instance.findOne({$or:[{authorizedId:getStringId(user._id),authorizerId:struct.ownerId,ownerId:getStringId(user._id)},{authorizedId:struct.ownerId,authorizerId:getStringId(user._id),ownerId:getStringId(user._id)}]});if(!auth1)return false;auth2=await this.collections.authorization.instance.findOne({$or:[{authorizedId:getStringId(user._id),authorizerId:struct.ownerId,ownerId:getStringId(struct.ownerId)},{authorizedId:struct.ownerId,authorizerId:getStringId(user._id),ownerId:getStringId(struct.ownerId)}]})}else{auth1=this.getLocalData("authorization",{ownerId:getStringId(user._id)}).find(o=>{if(o.authorizedId===getStringId(user._id)&&o.authorizerId===struct.ownerId)return true});auth2=this.getLocalData("authorization",{ownerId:struct.ownerId}).find(o=>{if(o.authorizedId===getStringId(user._id)&&o.authorizerId===struct.ownerId)return true})}if(!auth1||!auth2){return false}let passed=false;if(auth1.status==="OKAY"&&auth2.status==="OKAY"){if(struct.structType==="group"){if(auth1.authorizations[struct.name+"_admin"]&&auth2.authorizations[struct.name+"_admin"])passed=true}else if(auth1.authorizations["peer"]&&auth2.authorizations["peer"])passed=true;else if(auth1.authorizations["admincontrol"]&&auth2.authorizations["admincontrol"])passed=true;else if(auth1.structIds[getStringId(struct._id)]&&auth2.structIds[getStringId(struct._id)])passed=true;else if(auth1.excluded[struct.structType]&&struct.ownerId===getStringId(user._id)&&request==="WRITE")passed=false}return passed};wipeDB=async()=>{await Promise.all(Object.values(this.collections).map(c=>{try{c.instance.remove({})}catch(err){}}));return true};overwriteLocalData=structs=>{if(Array.isArray(structs)){structs.forEach(struct=>{let localdat=this.getLocalData(struct.structType,{"ownerId":struct.ownerId,"_id":getStringId(struct._id)});if(!localdat||localdat?.length===0){this.setLocalData(struct)}else Object.assign(localdat,struct)})}else{let localdat=this.getLocalData(structs.structType,{"ownerId":structs.ownerId,"_id":getStringId(structs._id)});if(!localdat||localdat?.length===0){this.setLocalData(structs)}else Object.assign(localdat,structs)}};setLocalData=structs=>{let setInCollection=s=>{let type=s.structType;let collection=this.collections[type]?.reference;if(!collection){collection={};if(!this.collections[type])this.collections[type]={};this.collections[type].reference=collection}collection[getStringId(s._id)]=s};if(Array.isArray(structs)){structs.forEach(s=>{setInCollection(s)})}else setInCollection(structs)};getLocalData=(collection,query)=>{let ownerId,key,value;if(typeof query==="object"){ownerId=query.ownerId;const keys=Object.keys(query).filter(k=>k!="ownerId");key=keys[0];value=query[key]}else value=query;if(!collection&&!ownerId&&!key&&!value)return[];let result=[];if(!collection&&(ownerId||key)){Object.values(this.collections).forEach(c=>{c=c.reference;if((key==="_id"||key==="id")&&value){let found=c[value];if(found)result.push(found)}else{Object.values(c).forEach(struct=>{if(key&&value){if(struct[key]===value&&struct.ownerId===ownerId){result.push(struct)}}else if(struct.ownerId===ownerId){result.push(struct)}})}});return result}else{let c=this.collections[collection]?.reference;if(!c)return result;if(!key&&!ownerId){Object.values(c).forEach(struct=>{result.push(struct)});return result}if((key==="_id"||key==="id")&&value)return getStringId(c[value]);else{Object.keys(c).forEach(k=>{const struct=c[k];if(key&&value&&!ownerId){if(struct[key]===value)result.push(struct)}else if(ownerId&&!key){if(struct.ownerId===ownerId)result.push(struct)}else if(ownerId&&key&&value){if(struct.ownerId===ownerId&&struct[key]){if(struct[key]===value)result.push(struct)}}})}}return result};deleteLocalData=struct=>{if(!struct)throw new Error("Struct not supplied");if(!struct.structType||!struct._id)return false;if(this.collections[struct.structType])delete this.collections[struct.structType].reference[struct._id];return true}};var shallowqueryDummy=DataStructures_exports.ProfileStruct();for(const key in shallowqueryDummy){if(key==="username"||key==="lastName"||key==="firstName"||key==="name"||key==="_id"||key==="pictureUrl")shallowqueryDummy[key]=1;else delete shallowqueryDummy[key]}var Systems={collision:{setupEntities:function(entities){for(const key in entities){const entity=entities[key];if(entity.components){if(!entity.components[this.__node.tag])continue}this.setupEntity(entity)}return entities},setupEntity:function(entity){if(!("collisionEnabled"in entity))entity.collisionEnabled=true;if(!entity.collisionType)entity.collisionType="sphere";if(!entity.collisionRadius)entity.collisionRadius=1;if(!entity.collisionBoundsScale)entity.collisionBoundsScale={x:1,y:1,z:1};if(!entity.colliding)entity.colliding={};if(!entity.position)entity.position={x:0,y:0,z:0};return entity},__node:{tag:"collision"},__operator:function(entities){let keys=this.entityKeys;for(let i=0;i{if(body1.collisionEnabled===false||body2.collisionEnabled===false)return false;const dist=Systems.collision.distance(body1.position,body2.position);if(dist{if(dist===void 0)dist=Systems.collision.distance(body1.position,body2.position);return dist{let body1minX=(body1.position.x-body1.collisionRadius)*body1.collisionBoundsScale.x;let body1maxX=(body1.position.x+body1.collisionRadius)*body1.collisionBoundsScale.x;let body1minY=(body1.position.y-body1.collisionRadius)*body1.collisionBoundsScale.y;let body1maxY=(body1.position.y+body1.collisionRadius)*body1.collisionBoundsScale.y;let body1minZ=(body1.position.z-body1.collisionRadius)*body1.collisionBoundsScale.z;let body1maxZ=(body1.position.z+body1.collisionRadius)*body1.collisionBoundsScale.z;let body2minX=(body2.position.x-body2.collisionRadius)*body1.collisionBoundsScale.x;let body2maxX=(body2.position.x+body2.collisionRadius)*body1.collisionBoundsScale.x;let body2minY=(body2.position.y-body2.collisionRadius)*body1.collisionBoundsScale.y;let body2maxY=(body2.position.y+body2.collisionRadius)*body1.collisionBoundsScale.y;let body2minZ=(body2.position.z-body2.collisionRadius)*body1.collisionBoundsScale.z;let body2maxZ=(body2.position.z+body2.collisionRadius)*body1.collisionBoundsScale.z;return(body1maxX<=body2maxX&&body1maxX>=body2minX||body1minX<=body2maxX&&body1minX>=body2minX)&&(body1maxY<=body2maxY&&body1maxY>=body2minY||body1minY<=body2maxY&&body1minY>=body2minY)&&(body1maxZ<=body2maxZ&&body1maxZ>=body2minZ||body1minZ<=body2maxZ&&body1minZ>=body2minZ)},sphereBoxCollisionCheck:(sphere,box,dist)=>{let boxMinX=(box.position.x-box.collisionRadius)*box.collisionBoundsScale.x;let boxMaxX=(box.position.x+box.collisionRadius)*box.collisionBoundsScale.x;let boxMinY=(box.position.y-box.collisionRadius)*box.collisionBoundsScale.y;let boxMaxY=(box.position.y+box.collisionRadius)*box.collisionBoundsScale.y;let boxMinZ=(box.position.z-box.collisionRadius)*box.collisionBoundsScale.z;let boxMaxZ=(box.position.z+box.collisionRadius)*box.collisionBoundsScale.z;let clamp={x:Math.max(boxMinX,Math.min(sphere.position.x,boxMaxX)),y:Math.max(boxMinY,Math.min(sphere.position.y,boxMaxY)),z:Math.max(boxMinZ,Math.min(sphere.position.z,boxMaxZ))};if(dist===void 0)dist=Systems.collision.distance(sphere.position,clamp);return dist>sphere.collisionRadius},isPointInsideSphere:(point,sphere,dist)=>{if(dist===void 0)dist=Systems.collision.distance(point,sphere.position);return dist{let boxminX=(box.position.x-box.collisionRadius)*box.collisionBoundsScale.x;let boxmaxX=(box.position.x+box.collisionRadius)*box.collisionBoundsScale.x;let boxminY=(box.position.y-box.collisionRadius)*box.collisionBoundsScale.x;let boxmaxY=(box.position.y+box.collisionRadius)*box.collisionBoundsScale.x;let boxminZ=(box.position.z-box.collisionRadius)*box.collisionBoundsScale.x;let boxmaxZ=(box.position.z+box.collisionRadius)*box.collisionBoundsScale.x;return point.x>=boxminX&&point.x<=boxmaxX&&(point.y>=boxminY&&point.y<=boxmaxY)&&(point.z>=boxminZ&&point.z<=boxmaxZ)},closestPointOnLine:(point,lineStart,lineEnd)=>{let a={x:lineEnd.x-lineStart.x,y:lineEnd.y-lineStart.y,z:lineEnd.z-lineStart.z};let b={x:lineStart.x-point.x,y:lineStart.y-point.y,z:lineStart.z-point.z};let c={x:lineEnd.x-point.x,y:lineEnd.y-point.y,z:lineEnd.z-point.z};let bdota=Systems.collision.dot(b,a);if(bdota<=0)return lineStart;let cdota=Systems.collision.dot(c,a);if(cdota<=0)return lineEnd;let _bdotapluscdota=1/(bdota+cdota);return{x:lineStart.x+(lineEnd.x-lineStart.x)*bdota*_bdotapluscdota,y:lineStart.y+(lineEnd.y-lineStart.y)*bdota*_bdotapluscdota,z:lineStart.z+(lineEnd.z-lineStart.z)*bdota*_bdotapluscdota}},closestPointOnPolygon:(point,t0,t1,t2)=>{let n=Systems.collision.calcNormal(t0,t1,t2);let dist=Systems.collision.dot(point,n)-Systems.collision.dot(t0,n);let projection=Systems.collision.vecadd(point,Systems.collision.vecscale(n,-dist));let v0x=t2[0]-t0[0];let v0y=t2[1]-t0[1];let v0z=t2[2]-t0[2];let v1x=t1[0]-t0[0];let v1y=t1[1]-t0[1];let v1z=t1[2]-t0[2];let v2x=projection[0]-t0[0];let v2y=projection[1]-t0[1];let v2z=projection[2]-t0[2];let dot00=v0x*v0x+v0y*v0y+v0z*v0z;let dot01=v0x*v1x+v0y*v1y+v0z*v1z;let dot02=v0x*v2x+v0y*v2y+v0z*v2z;let dot11=v1x*v1x+v1y*v1y+v1z*v1z;let dot12=v1x*v2x+v1y*v2y+v1z*v2z;let denom=dot00*dot11-dot01*dot01;if(Math.abs(denom)<1e-30){return void 0}let _denom=1/denom;let u=(dot11*dot02-dot01*dot12)*_denom;let v=(dot00*dot12-dot01*dot02)*_denom;if(u>=0&&v>=0&&u+v<1){return projection}else return void 0},calcNormal:(t0,t1,t2,positive=true)=>{var QR=Systems.collision.makeVec(t0,t1);var QS=Systems.collision.makeVec(t0,t2);if(positive===true){return Systems.collision.normalize(Systems.collision.cross3D(QR,QS))}else{return Systems.collision.normalize(Systems.collision.cross3D(QS,QR))}},dot:(v1,v2)=>{let dot=0;for(const key in v1){dot+=v1[key]*v2[key]}return dot},makeVec(p1,p2){return{x:p2.x-p1.x,y:p2.y-p1.y,z:p2.z-p1.z}},vecadd:(v1,v2)=>{let result=Object.assign({},v1);for(const key in result){result[key]+=v2[key]}return result},vecsub:(v1,v2)=>{let result=Object.assign({},v1);for(const key in result){result[key]-=v2[key]}return result},vecmul:(v1,v2)=>{let result=Object.assign({},v1);for(const key in result){result[key]*=v2[key]}return result},vecdiv:(v1,v2)=>{let result=Object.assign({},v1);for(const key in result){result[key]/=v2[key]}return result},vecscale:(v1,scalar)=>{let result=Object.assign({},v1);for(const key in result){result[key]*=scalar}return result},distance:(v1,v2)=>{let distance=0;for(const key in v1){distance+=Math.pow(v1[key]-v2[key],2)}return Math.sqrt(distance)},magnitude:v=>{let magnitude=0;for(const key in v){magnitude+=v[key]*v[key]}return Math.sqrt(magnitude)},normalize:v=>{let magnitude=Systems.collision.magnitude(v);let _mag=magnitude?1/magnitude:0;let vn={};for(const key in v){vn[key]=v[key]*_mag}return vn},distance3D(v1,v2){return Math.sqrt((v1.x-v2.x)*(v1.x-v2.x)+(v1.y-v2.y)*(v1.y-v2.y)+(v1.z-v2.z)*(v1.z-v2.z))},cross3D(v1,v2){return{x:v1.y*v2.z-v1.z*v2.y,y:v1.z*v2.x-v1.x*v2.z,z:v1.x*v2.y-v1.y*v2.x}},nearestNeighborSearch(entities,isWithinRadius=1e15){var tree={};;for(const key in entities){let newnode={tag:key,position:void 0,neighbors:[]};newnode.position=entities[key].position;tree[key]=newnode}for(const i in tree){for(const j in tree){var dist=Systems.collision.distance3D(tree[i].position,tree[j].position);if(distxx)minX=xx;if(maxYyy)minY=yy;if(maxZzz)minZ=zz;if(minRadius>body.collisionRadius)minRadius=body.collisionRadius;positions[key]=body.position};let head=JSON.parse(JSON.stringify(dynamicBoundingVolumeTree.proto));let boxpos={x:(maxX+minX)*.5,y:(maxY+minY)*.5,z:(maxZ+minZ)*.5};let boxbounds={x:maxX-boxpos.x,y:maxY-boxpos.y,z:maxZ-boxpos.z};head.position=boxpos;head.collisionBoundsScale=boxbounds;head.entities=entities;dynamicBoundingVolumeTree.tree=head;minRadius*=2;if(mode==="octree"){let genOct=function(parentPos,halfbounds){let oct1={x:parentPos.x+halfbounds.x,y:parentPos.y+halfbounds.y,z:parentPos.z+halfbounds.z};let oct2={x:parentPos.x-halfbounds.x,y:parentPos.y+halfbounds.y,z:parentPos.z+halfbounds.z};let oct3={x:parentPos.x+halfbounds.x,y:parentPos.y-halfbounds.y,z:parentPos.z+halfbounds.z};let oct4={x:parentPos.x+halfbounds.x,y:parentPos.y+halfbounds.y,z:parentPos.z-halfbounds.z};let oct5={x:parentPos.x-halfbounds.x,y:parentPos.y-halfbounds.y,z:parentPos.z+halfbounds.z};let oct6={x:parentPos.x-halfbounds.x,y:parentPos.y+halfbounds.y,z:parentPos.z-halfbounds.z};let oct7={x:parentPos.x+halfbounds.x,y:parentPos.y-halfbounds.y,z:parentPos.z-halfbounds.z};let oct8={x:parentPos.x-halfbounds.x,y:parentPos.y-halfbounds.y,z:parentPos.z-halfbounds.z};return[oct1,oct2,oct3,oct4,oct5,oct6,oct7,oct8]},genOctTree=function(head2){let halfbounds={x:head2.collisionBoundsScale.x*.5,y:head2.collisionBoundsScale.y*.5,z:head2.collisionBoundsScale.z*.5};let octPos=genOct(head2.position,halfbounds);let check=Object.assign({},head2.bodies);for(let i=0;i<8;i++){let octquadrant=Object.assign(JSON.parse(JSON.stringify(dynamicBoundingVolumeTree.proto)),{position:octPos[i],collisionBoundsScale:halfbounds});octquadrant.parent=head2;for(const j in check){let collided=Systems.collision.collisionCheck(check[j],octquadrant);if(collided){octquadrant.entities[j]=check[j];delete check[j]}}if(Object.keys(octquadrant.entities).length>minEntities-1){head2.children[i]=octquadrant;octquadrant.parent=head2;if(Object.keys(octquadrant.entities).length>minEntities&&octquadrant.collisionRadius*.5>minRadius){genOctTree(octquadrant)}}}};genOctTree(head);return head}else{let tree=Systems.collision.nearestNeighborSearch(positions,withinRadius);let keys=Object.keys(tree);let tag=keys[Math.floor(Math.random()*keys.length)];let searching=true;let count=0;let genBoundingBoxLevel=(tree2,volumes)=>{let newVolumes={};let foundidxs={};let treekeys=Object.keys(tree2);while(searching&&countuxn)ux=uxn;if(mxuyn)uy=uyn;if(myuzn)uz=uzn;if(mz2){let nextTree=Systems.collision.nearestNeighborSearch(result,withinRadius);result=genBoundingBoxLevel(nextTree,result)}head.children=result;head.children.forEach(n=>{n.parent=head});return head}}},collider:{lastTime:performance.now(),setupEntities:function(entities){for(const key in entities){const entity=entities[key];if(entity.components){if(!entity.components[this.__node.tag])continue}this.setupEntity(entity)}return entities},setupEntity:function(entity){if(!("collisionEnabled"in entity))Systems.collision.setupEntity(entity);if(!("boundingBox"in entity))entity.boundingBox={bot:0,top:100,left:0,right:100,front:0,back:100};if(!("position"in entity)){Systems.movement.setupEntity(entity)}if(!("restitution"in entity))entity.restitution=1;if(!("useBoundingBox"in entity))entity.useBoundingBox=true;if(!entity.position.x&&!entity.position.y&&!entity.position.z){entity.position.x=Math.random()*entity.boundingBox.right;entity.position.y=Math.random()*entity.boundingBox.back;entity.position.z=Math.random()*entity.boundingBox.top}return entity},__operator:function(entities){let keys=this.entityKeys;for(let i=0;i{const xsize=entity.collisionRadius*entity.collisionBoundsScale.x;const ysize=entity.collisionRadius*entity.collisionBoundsScale.y;const zsize=entity.collisionRadius*entity.collisionBoundsScale.z;if(entity.position.y-ysize<=entity.boundingBox.front){entity.velocity.y*=-entity.restitution;entity.position.y=entity.boundingBox.front+ysize}if(entity.position.y+ysize>=entity.boundingBox.back){entity.velocity.y*=-entity.restitution;entity.position.y=entity.boundingBox.back-ysize}if(entity.position.x-xsize<=entity.boundingBox.left){entity.velocity.x*=-entity.restitution;entity.position.x=entity.boundingBox.left+xsize}if(entity.position.x+xsize>=entity.boundingBox.right){entity.velocity.x*=-entity.restitution;entity.position.x=entity.boundingBox.right-xsize}if(entity.position.z-zsize<=entity.boundingBox.bot){entity.velocity.z*=-entity.restitution;entity.position.z=entity.boundingBox.bot+zsize}if(entity.position.z+zsize>=entity.boundingBox.top){entity.velocity.z*=-entity.restitution;entity.position.z=entity.boundingBox.top-zsize}},resolveBoxCollision:(body1,box,negate)=>{let positionVec=Systems.collision.makeVec(body1.position,box.position);var directionVec=Object.values(positionVec);let closestSide;let closestDist=Infinity;let mul=-1;if(directionVec[idx]<0)mul=1;if(negate)mul=-mul;for(const key in body1.position){let dist=Math.abs(box.position[key]-body1.position[key]);if(dist{if(dist===void 0)dist=Systems.collision.distance(entity1.position,entity2.position);let vecn=Systems.collision.normalize(Systems.collision.makeVec(entity1.position,entity2.position));let sumMass=entity1.mass+entity2.mass;let ratio=entity1.mass/sumMass;let rmin=1-ratio;if(entity1.fixed===false){entity1.position.x+=vecn.x*rmin*1.01;entity1.position.y+=vecn.y*rmin*1.01;entity1.position.z+=vecn.z*rmin*1.001}else{entity2.position.x-=vecn.x*1.01;entity2.position.y-=vecn.y*1.01;entity2.position.z-=vecn.z*1.01}if(entity2.fixed===false){entity2.position.x+=vecn.x*ratio*1.01;entity2.position.y+=vecn.y*ratio*1.01;entity2.position.z+=vecn.z*ratio*1.01}else{entity1.position.x+=vecn.x*1.01;entity1.position.y+=vecn.y*1.01;entity1.position.z+=vecn.z*1.01}dist=Systems.collision.distance(entity1.position,entity2.position);let vrel={x:entity1.velocity.x-entity2.velocity.x,y:entity1.velocity.y-entity2.velocity.y,z:entity1.velocity.z-entity2.velocity.z};let speed=vrel.x*vecn.x+vrel.y*vecn.y+vrel.z*vecn.z;if(speed>0){let impulse=2*speed/sumMass;if(entity1.fixed===false){entity1.velocity.x-=impulse*vecn.x*entity2.mass*entity1.restitution;entity1.velocity.y-=impulse*vecn.y*entity2.mass*entity1.restitution;entity1.velocity.z-=impulse*vecn.z*entity2.mass*entity1.restitution}if(entity2.fixed===false){entity2.velocity.x+=impulse*vecn.x*entity2.mass*entity2.restitution/entity2.mass;entity2.velocity.y+=impulse*vecn.y*entity2.mass*entity2.restitution/entity2.mass;entity2.velocity.z+=impulse*vecn.z*entity2.mass*entity2.restitution/entity2.mass}}}},nbody:{lastTime:performance.now(),G:6674e-14,setupEntities:function(entities){for(const key in entities){const entity=entities[key];if(entity.components){if(!entity.components[this.__node.tag])continue}this.setupEntity(entity)}return entities},setupEntity:function(entity){if(!("collisionEnabled"in entity))Systems.collider.setupEntity(entity);entity.isAttractor=true;if(!("attractorGroup"in entity))entity.attractorGroup=0;if(!("attractorFrameSearchMax"in entity))entity.attractorFrameSearchMax=10;if(!("attractorGroupRules"in entity))entity.attractorGroupRules={0:{G:this.G,maxDist:void 0}};return entity},__operator:function(entities){let keys=this.entityKeys;for(let i=0;ientity.attractorFrameSearchMax)break nested}}return entities},__node:{tag:"nbody"},attract:function(body1,body2,dist,G=this.G,vecn){if(dist===void 0)dist=Systems.collision.distance3D(body1.position,body2.position);if(vecn===void 0)vecn=Systems.collision.normalize(Systems.collision.makeVec(body1.position,body2.position));let Fg=0;if(dist<.01)dist=.01;if(body1.attractorGroupRules[body2.attractorGroup]){if(typeof body1.attractorGroupRules[body2.attractorGroup]==="object"){if(body1.attractorGroupRules[body2.attractorGroup].maxDist&&body1.attractorGroupRules[body2.attractorGroup].maxDist1e3){entity.boid.groupSize=1;entity.boid.searchLimit=1}return entity},__operator:function(entities){let now=performance.now();let timeStep=now-this.lastTime;this.lastTime=now;let keys=this.entityKeys;let length=keys.length;let _timeStep=1/timeStep;let w=-1;outer:for(let i=0;ip0.boid.groupSize||k>p0.boid.searchLimit){break nested}let randj=keys[Math.floor(Math.random()*length)];if(k===w||randj===keys[i]||inRange.indexOf(randj)>-1){continue nested}else{let pr=entities[randj];let disttemp=Math.sqrt((p0.position.x-pr.position.x)*(p0.position.x-pr.position.x)+(p0.position.y-pr.position.y)*(p0.position.y-pr.position.y)+(p0.position.z-pr.position.z)*(p0.position.z-pr.position.z));if(disttemp>p0.boid.groupRadius){continue nested}else{distances.push(disttemp);inRange.push(randj);let distInv;if(p0.boid.useSeparation||p0.boid.useAlignment){distInv=p0.boid.groupRadius/(disttemp*disttemp);if(distInv>p0.maxSpeed)distInv=p0.maxSpeed;else if(distInv<-p0.maxSpeed)distInv=-p0.maxSpeed}if(p0.boid.useCohesion){boidVelocities[0]+=(pr.position.x-p0.position.x)*.5*disttemp*_timeStep;boidVelocities[1]+=(pr.position.y-p0.position.y)*.5*disttemp*_timeStep;boidVelocities[2]+=(pr.position.z-p0.position.z)*.5*disttemp*_timeStep}if(isNaN(disttemp)||isNaN(boidVelocities[0])||isNaN(pr.position.x)){console.log(disttemp,i,randj,p0.position,pr.position,boidVelocities);p0.position.x=NaN;return}if(p0.boid.useSeparation){boidVelocities[3]=boidVelocities[3]+(p0.position.x-pr.position.x)*distInv;boidVelocities[4]=boidVelocities[4]+(p0.position.y-pr.position.y)*distInv;boidVelocities[5]=boidVelocities[5]+(p0.position.z-pr.position.z)*distInv}if(p0.boid.useAttraction&&pr.boid.useAttraction){Systems.nbody.attract(p0,pr,disttemp)}if(p0.boid.useAlignment){boidVelocities[6]=boidVelocities[6]+pr.velocity.x*distInv;boidVelocities[7]=boidVelocities[7]+pr.velocity.y*distInv;boidVelocities[8]=boidVelocities[8]+pr.velocity.z*distInv}groupCount++}}}let _groupCount=1/groupCount;if(p0.boid.useCohesion){boidVelocities[0]=p0.boid.cohesion*(boidVelocities[0]*_groupCount);boidVelocities[1]=p0.boid.cohesion*(boidVelocities[1]*_groupCount);boidVelocities[2]=p0.boid.cohesion*(boidVelocities[2]*_groupCount)}else{boidVelocities[0]=0;boidVelocities[1]=0;boidVelocities[2]=0}if(p0.boid.useSeparation){boidVelocities[3]=p0.boid.separation*boidVelocities[3];boidVelocities[4]=p0.boid.separation*boidVelocities[4];boidVelocities[5]=p0.boid.separation*boidVelocities[5]}else{boidVelocities[3]=0;boidVelocities[4]=0;boidVelocities[5]=0}if(p0.boid.useAlignment){boidVelocities[6]=-(p0.boid.alignment*boidVelocities[6]*_groupCount);boidVelocities[7]=p0.boid.alignment*boidVelocities[7]*_groupCount;boidVelocities[8]=p0.boid.alignment*boidVelocities[8]*_groupCount}else{boidVelocities[6]=0;boidVelocities[7]=0;boidVelocities[8]=0}const swirlVec=[0,0,0];if(p0.boid.useSwirl==true){boidVelocities[9]=-(p0.position.y-p0.boid.swirl.y)*p0.boid.swirl.mul;boidVelocities[10]=(p0.position.z-p0.boid.swirl.z)*p0.boid.swirl.mul;boidVelocities[11]=(p0.position.x-p0.boid.swirl.x)*p0.boid.swirl.mul}const attractorVec=[0,0,0];if(p0.boid.useAttractor==true){boidVelocities[12]=(p0.boid.attractor.x-p0.position.x)*p0.boid.attractor.mul;if(p0.position.x>p0.boundingBox.left||p0.position.xp0.boundingBox.top||p0.position.yp0.boundingBox.front||p0.position.z0){let magnitude=Systems.collision.magnitude(entity.velocity);if(magnitude>entity.maxSpeed){let scalar=entity.maxSpeed/magnitude;entity.velocity.x*=scalar;entity.velocity.y*=scalar;entity.velocity.z*=scalar}}if(entity.velocity.x)entity.position.x+=entity.velocity.x*timeStep;if(entity.velocity.y)entity.position.y+=entity.velocity.y*timeStep;if(entity.velocity.z)entity.position.z+=entity.velocity.z*timeStep}return entities}}};var webglPlotRoutes={setupChart:function setupChart(settings){console.log("initializing chart",settings);if(!this?.__node?.graph?.plotter){this.__node.graph.plotter=new(void 0);return this.__node.graph.plotter.initPlot(settings).settings._id}else{globalThis.plotter=new(void 0);return globalThis.plotter.initPlot(settings).settings._id}},updateChartData:function updateChartData(plot,lines,draw=true){if(typeof lines==="object"){if(globalThis.plotter)globalThis.plotter.update(plot,lines,draw);else if(this?.__node?.graph?.plotter)this.__node.graph.plotter.update(plot,lines,draw);return true}return false},clearChart:function clearChart(plot){if(globalThis.plotter)globalThis.plotter.deinitPlot(plot);else if(this?.__node?.graph?.plotter)this.__node.graph.plotter.deinitPlot(plot);return true},resetChart:function resetChart(plot,settings){if(globalThis.plotter)globalThis.plotter.reinitPlot(plot,settings);else if(this?.__node?.graph?.plotter)this.__node.graph.plotter.reinitPlot(plot,settings);return settings._id},getChartSettings:function getChartSettings(plotId){let settings;if(globalThis.plotter)settings=globalThis.plotter.getChartSettings(plotId);else if(this?.__node?.graph?.plotter)settings=this.__node.graph.plotter.getChartSettings(plotId);return settings}};async function setSignalControls(controlsDiv,plotId,streamworker,chartworker,chartSettings,filterSettings){let controls=controlsDiv;if(!controls)return false;if(!chartSettings&&chartworker)chartSettings=await chartworker.run("getChartSettings",plotId);if(!filterSettings&&streamworker)filterSettings=await streamworker.run("getFilterSettings");if(chartSettings?.lines){let body=``;let viewingall=true;let scalingall=true;let n50all=true;let n60all=true;let dcall=true;let lpall=true;let bpall=true;for(const prop in chartSettings.lines){let line=chartSettings.lines[prop];body+=` - - ${prop} - - - - - - - - - - Hz - Hz to Hz - `;if(!line.viewing)viewingall=false;if(!filterSettings[prop]?.useScaling)scalingall=false;if(!filterSettings[prop]?.useNotch50)n50all=false;if(!filterSettings[prop]?.useNotch60)n60all=false;if(!filterSettings[prop]?.useDCBlock)dcall=false;if(!filterSettings[prop]?.useLowpass)lpall=false;if(!filterSettings[prop]?.useBandpass)bpall=false}let head=` - - Name - SPS - Plot nSec - Scalar - Units - Lower Bound - Upper Bound - 50Hz Notch - 60Hz Notch - DC Block - Lowpass - Bandpass - - `;controls.innerHTML=head+body;let viewall=document.getElementById(plotId+"viewing");let usescalar=document.getElementById(plotId+"useScaling");let usen50=document.getElementById(plotId+"useNotch50");let usen60=document.getElementById(plotId+"useNotch60");let usedcb=document.getElementById(plotId+"useDCBlock");let uselp=document.getElementById(plotId+"useLowpass");let usebp=document.getElementById(plotId+"useBandpass");let headeronchange=(checked,idsuffix)=>{for(const prop in chartSettings.lines){let elm=document.getElementById(plotId+prop+idsuffix);if(elm?.checked!==checked)elm.click()}};viewall.onchange=ev2=>{headeronchange(ev2.target.checked,"viewing")};usescalar.onchange=ev2=>{headeronchange(ev2.target.checked,"useScaling")};usen50.onchange=ev2=>{headeronchange(ev2.target.checked,"useNotch50")};usen60.onchange=ev2=>{headeronchange(ev2.target.checked,"useNotch60")};usedcb.onchange=ev2=>{headeronchange(ev2.target.checked,"useDCBlock")};uselp.onchange=ev2=>{headeronchange(ev2.target.checked,"useLowpass")};usebp.onchange=ev2=>{headeronchange(ev2.target.checked,"useBandpass")};for(const prop in chartSettings.lines){let viewing=document.getElementById(plotId+prop+"viewing");let sps=document.getElementById(plotId+prop+"sps");let nSec=document.getElementById(plotId+prop+"nSec");let useScaling=document.getElementById(plotId+prop+"useScaling");let scalar=document.getElementById(plotId+prop+"scalar");let units=document.getElementById(plotId+prop+"units");let ymin=document.getElementById(plotId+prop+"ymin");let ymax=document.getElementById(plotId+prop+"ymax");let useNotch50=document.getElementById(plotId+prop+"useNotch50");let useNotch60=document.getElementById(plotId+prop+"useNotch60");let useDCBlock=document.getElementById(plotId+prop+"useDCBlock");let useLowpass=document.getElementById(plotId+prop+"useLowpass");let lowpassHz=document.getElementById(plotId+prop+"lowpassHz");let useBandpass=document.getElementById(plotId+prop+"useBandpass");let bandpassLower=document.getElementById(plotId+prop+"bandpassLower");let bandpassUpper=document.getElementById(plotId+prop+"bandpassUpper");viewing.onchange=()=>{if(!Array.isArray(chartSettings.lines?.[prop])){(chartSettings.lines?.[prop]).viewing=viewing.checked;chartSettings.generateNewLines=false;chartworker.run("resetChart",[plotId,chartSettings])}};let filteronchange=()=>{let setting={[prop]:{sps:sps.value?parseFloat(sps.value):100,useScaling:useScaling.checked,scalar:scalar.value?parseFloat(scalar.value):1,useNotch50:useNotch50.checked,useNotch60:useNotch60.checked,useDCBlock:useDCBlock.checked,useLowpass:useLowpass.checked,lowpassHz:lowpassHz.value?parseFloat(lowpassHz.value):100,useBandpass:useBandpass.checked,bandpassLower:bandpassLower.value?parseFloat(bandpassLower.value):3,bandpassUpper:bandpassUpper.value?parseFloat(bandpassUpper.value):45,trimOutliers:filterSettings[prop]?.trimOutliers,outlierTolerance:filterSettings[prop]?.outlierTolerance}};streamworker.post("setFilters",setting)};sps.onchange=()=>{filteronchange();(chartSettings.lines?.[prop]).sps=parseFloat(sps.value);(chartSettings.lines?.[prop]).nSec=parseFloat(nSec.value);delete(chartSettings.lines?.[prop]).points;delete(chartSettings.lines?.[prop]).nPoints;chartworker.run("resetChart",[plotId,chartSettings])};units.onchange=()=>{if(!Array.isArray(chartSettings.lines?.[prop])){(chartSettings.lines?.[prop]).units=units.value;chartworker.run("resetChart",[plotId,chartSettings])}};ymax.onchange=()=>{if(!Array.isArray(chartSettings.lines?.[prop])){(chartSettings.lines?.[prop]).ymax=ymax.value?parseFloat(ymax.value):1;(chartSettings.lines?.[prop]).ymin=ymin.value?parseFloat(ymin.value):0;chartworker.run("resetChart",[plotId,chartSettings])}};ymin.onchange=()=>{if(!Array.isArray(chartSettings.lines?.[prop])){(chartSettings.lines?.[prop]).ymax=ymax.value?parseFloat(ymax.value):1;(chartSettings.lines?.[prop]).ymin=ymin.value?parseFloat(ymin.value):0;chartworker.run("resetChart",[plotId,chartSettings])}};nSec.onchange=()=>{if(!Array.isArray(chartSettings.lines?.[prop])){(chartSettings.lines?.[prop]).sps=parseFloat(sps.value);(chartSettings.lines?.[prop]).nSec=parseFloat(nSec.value);delete(chartSettings.lines?.[prop]).points;delete(chartSettings.lines?.[prop]).nPoints;chartworker.run("resetChart",[plotId,chartSettings])}};useScaling.onchange=filteronchange;useNotch50.onchange=filteronchange;useNotch60.onchange=filteronchange;useDCBlock.onchange=filteronchange;useLowpass.onchange=filteronchange;useBandpass.onchange=filteronchange;lowpassHz.onchange=filteronchange;scalar.onchange=filteronchange;bandpassLower.onchange=filteronchange;bandpassUpper.onchange=filteronchange}}}var Math2=class _Math2{constructor(){}static TWO_PI=Math.PI*2;static C=299792458;static G=66743e-15;static h=662607015e-42;static R=8314.32;static Ra=287;static H=69.3;static kbar=1054571817e-43;static kB=1380649e-29;static ke=89875517923e-1;static me=91093837015e-41;static mp=167262192369e-38;static mn=167492749804e-38;static P0=101325;static T0=288.15;static p0=1.225;static Na=60220978e16;static y=1.405;static M0=28.96643;static g0=9.80665;static Re=6378100;static B=1458e-9;static S=110.4;static Sigma=365e-12;static imgkernels={edgeDetection:[[-1,-1,-1],[-1,8,-1],[-1,-1,-1]],boxBlur:[[1/9,1/9,1/9],[1/9,1/9,1/9],[1/9,1/9,1/9]],sobelLeft:[[1,0,-1],[2,0,-2],[1,0,-1]],sobelRight:[[-1,0,1],[-2,0,2],[-1,0,1]],sobelTop:[[1,2,1],[0,0,0],[-1,-2,-1]],sobelBottom:[[-1,2,1],[0,0,0],[1,2,1]],identity:[[0,0,0],[0,1,0],[0,0,0]],gaussian3x3:[[1,2,1],[2,4,2],[1,2,1]],guassian7x7:[[0,0,0,5,0,0,0],[0,5,18,32,18,5,0],[0,18,64,100,64,18,0],[5,32,100,100,100,32,5],[0,18,64,100,64,18,0],[0,5,18,32,18,5,0],[0,0,0,5,0,0,0]],emboss:[[-2,-1,0],[-1,1,1],[0,1,2]],sharpen:[[0,-1,0],[-1,5,-1],[0,-1,0]]};static HSLToRGB=(h,s,l,scalar=255)=>{s/=100;l/=100;let c=(1-Math.abs(2*l-1))*s,x2=c*(1-Math.abs(h/60%2-1)),m=l-c/2,r=0,g=0,b=0;if(0<=h&&h<60){r=c;g=x2;b=0}else if(60<=h&&h<120){r=x2;g=c;b=0}else if(120<=h&&h<180){r=0;g=c;b=x2}else if(180<=h&&h<240){r=0;g=x2;b=c}else if(240<=h&&h<300){r=x2;g=0;b=c}else if(300<=h&&h<360){r=c;g=0;b=x2}r=(r+m)*scalar;g=(g+m)*scalar;b=(b+m)*scalar;return[r,g,b]};static genSineWave=(freq=20,peakAmp=1,nSec=1,fs=512,freq2=0,peakAmp2=1)=>{var sineWave=[];var t=[];var increment=1/fs;for(var ti=0;ti{return Math.sin(this.TWO_PI*frequency*ti+tOffset)*peakAmplitude};static mean=arr=>{var sum=arr.reduce((prev,curr)=>curr+=prev);return sum/arr.length};static median=data=>{const sortedData=data.slice().sort((a,b)=>a-b);const middle=Math.floor(sortedData.length/2);if(sortedData.length%2===0){return(sortedData[middle-1]+sortedData[middle])/2}else{return sortedData[middle]}};static mode=arr=>{return arr.sort((a,b)=>arr.filter(v=>v===a).length-arr.filter(v=>v===b).length).pop()};static range=data=>{return Math.max(...data)-Math.min(...data)};static std=(arr,mean=void 0)=>{let avg=mean;if(!mean)avg=this.mean(arr);let summed=0;for(let i=0;i{if(actual.length!==forecast.length)throw new Error("Input arrays of same length!");let i=actual.length;let d=new Array(actual.length);for(let j=0;j{let len=probabilities.length;let entropy=new Array(len);for(let i=0;i{let mean=this.mean(arr);let std=this.std(arr,mean);let z=new Array(arr.length);for(let i=0;ia+(b-mean)**2,0)/arr.length}static coeffVariation=(arr,populationMean)=>{let mean=this.mean(arr);let std=this.std(arr,mean);return populationMean?std/populationMean:std/mean};static coeffDetermination=(observed,expected)=>{const meanY=this.mean(observed);const ssTotal=observed.reduce((acc,y)=>acc+Math.pow(y-meanY,2),0);const ssResidual=observed.reduce((acc,y,i)=>acc+Math.pow(y-expected[i],2),0);return 1-ssResidual/ssTotal};static percentile=(arr,p)=>{const sortedData=arr.slice().sort((a,b)=>a-b);const index=Math.ceil(p*(sortedData.length-1));return sortedData[index]};static interquartileRange=arr=>{const sortedData=arr.slice().sort((a,b)=>a-b);const index=Math.ceil(.25*(sortedData.length-1));const index2=Math.ceil(.75*(sortedData.length-1));const q1=sortedData[index];const q3=sortedData[index2];return q3-q1};static skewness=arr=>{const n=arr.length;const meanValue=this.mean(arr);const stdDevValue=this.std(arr);const sumCubedDeviation=arr.reduce((acc,value)=>acc+Math.pow(value-meanValue,3),0);const skew=sumCubedDeviation/(n*Math.pow(stdDevValue,3));return skew};static kurtosis=arr=>{const n=arr.length;const meanValue=this.mean(arr);const stdDevValue=this.std(arr);const sumFourthDeviation=arr.reduce((acc,value)=>acc+Math.pow(value-meanValue,4),0);const kurt=sumFourthDeviation/(n*Math.pow(stdDevValue,4))-3;return kurt};static chiSquareTest=(observed,expected)=>{const chiSquared=observed.reduce((acc,obs,i)=>{const exp=expected[i];return acc+Math.pow(obs-exp,2)/exp},0);return chiSquared};static simpleLinearRegression=(xCoords,yCoords)=>{const n=xCoords.length;const sumX=xCoords.reduce((sum,x2)=>sum+x2,0);const sumY=yCoords.reduce((sum,y)=>sum+y,0);const sumXY=xCoords.reduce((sum,x2,i)=>sum+x2*yCoords[i],0);const sumX2=xCoords.reduce((sum,x2)=>sum+x2*x2,0);const slope=(n*sumXY-sumX*sumY)/(n*sumX2-sumX*sumX);const intercept=(sumY-slope*sumX)/n;return{slope,intercept}};static pad=(arr,pad=1,padValue=0)=>{if(Array.isArray(arr[0]))return pad2D(arr,pad);if(pad>0){let pads=new Array(pad).fill(padValue);arr=[...pads,...arr,...pads]}return arr};static pad2D=(array,pad,padValue=0)=>{let pads=new Array(pad).fill(padValue);const paddedArray=array.map(row=>{return[...pads,...row,...pads]});const paddedRow=new Array(array[0].length+2*pad).fill(padValue);for(let i=0;i{const firstElem=array[0];const lastElem=array[array.length-1];const startPadding=new Array(padSize).fill(firstElem);const endPadding=new Array(padSize).fill(lastElem);return startPadding.concat(array,endPadding)};static edgePad2D=(matrix,padSize)=>{const topRows=Array(padSize).fill(matrix[0]);const bottomRows=Array(padSize).fill(matrix[matrix.length-1]);const paddedMatrix=topRows.concat(matrix,bottomRows);for(let i=0;i{const nVecs=vectors.length;return vectors[0].map((v,i)=>{for(let j=1;j{const nVecs=vectors.length;return vectors[0].map((v,i)=>{for(let j=1;j{return vec.map((v,i)=>v-subvec[i])};static vecdiv=(numvec,denvec)=>{return numvec.map((v,i)=>v/denvec[i])};static vecscale=(vec,scalar)=>{return vec.map((v,i)=>v*scalar)};static vecaddScalar=(vec,scalar)=>{return vec.map((v,i)=>v+scalar)};static vecmulScalar=(vec,scalar)=>{return vec.map((v,i)=>v*scalar)};static vecsubScalar=(vec,scalar)=>{return vec.map((v,i)=>v-scalar)};static vecdivScalar=(vec,scalar)=>{return vec.map((v,i)=>v/scalar)};static dot=(vec1,vec2)=>{var dot=0;for(var i=0;i{return[vec1[1]*vec2[2]-vec1[2]*vec2[1],vec1[2]*vec2[0]-vec1[0]*vec2[2],vec1[0]*vec2[1]-vec1[1]*vec2[0]]};static sphericalToCartesian=(r,theta,phi)=>{return{x:r*Math.sin(phi)*Math.cos(theta),y:r*Math.sin(phi)*Math.sin(theta),z:r*Math.cos(phi)}};static cartesianToSpherical=(x2,y,z)=>{var r=Math.sqrt(x2*x2+y*y+z*z);var theta=Math.atan2(y,x2);var phi=Math.acos(z/r);return{r,theta,phi}};static magnitude=vec=>{var sqrd=0;vec.forEach(c=>{sqrd+=c*c});return Math.sqrt(sqrd)};static distance=(point1,point2)=>{var dsqrd=0;point1.forEach((c,i)=>{dsqrd+=(point2[i]-c)*(point2[i]-c)});return Math.sqrt(dsqrd)};static midpoint=(point1=[1,2,3],point2=[3,4,5])=>{return point1.map((c,i)=>{return(c+point2[i])*.5})};static project=(vec1,vec2)=>{const dot=this.dot(vec1,vec2);const magSqrd=this.magnitude(vec2)**2;return this.vecmulScalar(vec2,dot/magSqrd)};static angleBetween=(vec1,vec2)=>{const dotProduct=this.dot(vec1,vec2);const magProduct=this.magnitude(vec1)*this.magnitude(vec2);return Math.acos(dotProduct/magProduct)};static normalize=vec=>{var norm=0;norm=1/this.magnitude(vec);var vecn=new Array(vec.length);vec.forEach((c,i)=>{vecn[i]=c*norm});return vecn};static normalizeSeries=(arr=[],fromZero=true)=>{let max=Math.max(...arr);let min=Math.min(...arr);if(fromZero==false){max=Math.max(max,Math.abs(min));min=0}if(max-min===0){min=0;if(max===0)max=1e-13}return arr.map(v=>(v-min)/(max-min))};static quadraticFormula=(a,b,c)=>{let bbmac4=Math.sqrt(b*b-4*a*c);if(!isNaN(bbmac4))return["complex","complex"];let _a2=1/(2*a);if(bbmac4===0)return[b*_a2];let nb=-b;return[(nb+bbmac4)*_a2,(nb-bbmac4)*_a2]};static newtonsMethod1D=(foo=x2=>{return Math.pow(x2,5)+x2*x2-x2-.2},start=0,end=1,precision=.01,attempts=10)=>{let roots=[];for(let i=0;iprecision){let step=-guess/slope2;let xn12=xn+step;guess=guess2;guess2=foo(xn12);let slope2=(guess2-guess)/(xn12-xn)}let idx;let f=roots.find((root,i2)=>{if(Math.abs(xn1-root){let y=x2;return y},range=[0,1],stepx=.01)=>{let area=0;for(let i=range[0];i{let z=x2+y;return z},range=[[0,1],[0,1]],stepx=.01,stepy=stepx)=>{let volume=0;for(let i=range[0][0]+stepx;i{let w=x2+y+z;return w},range=[[0,1],[0,1],[0,1]],stepx=.01,stepy=stepx,stepz=stepx)=>{let volume=0;for(let i=range[0][0]+stepx;i{let y=x2;return y},range=[0,1],stepx=.01)=>{let length=0;let y0=func(range[0]);for(let i=range[0]+stepx;i<=range[1];i+=stepx){let yi=func(i);length+=Math.sqrt(stepx**2+(yi-y0)**2);y0=yi}return length};static pathIntegral2D=(xFunc=t=>{let x2=Math.cos(t);return x2},yFunc=t=>{let y=Math.sin(t);return y},range=[[0,1],[0,1]],stept=.01)=>{let length=0;let x0=xFunc(range[0][0]);let y0=yFunc(range[1][0]);let tMaxX=range[0][1];let tMaxY=range[1][1];let tMax=Math.max(tMaxX,tMaxY);for(let t=0;t<=tMax;t+=stept){let xi=xFunc(Math.min(t,tMaxX));let yi=yFunc(Math.min(t,tMaxY));length+=Math.sqrt((xi-x0)**2+(yi-y0)**2);x0=xi;y0=yi}return length};static pathIntegral3D=(xFunc=(u,v)=>u,yFunc=(u,v)=>v,zFunc=(u,v)=>u+v,rangeU=[0,1],rangeV=[0,1],stepU=.01,stepV=.01)=>{let area=0;for(let u=rangeU[0];u{var vec=[];point1.forEach((c,i)=>{vec.push(point2[i]-c)});return vec};static getBufferedValueByCoordinates=(vb=new Array(300).fill(1),dims=[10,10,2],coordinate=[1,2,1],cardinal=void 0)=>{let getIdx=(foundIdx=0,dimIdx=0)=>{if(dimIdx===dims.length)return foundIdx;if(dimIdx==0)foundIdx+=coordinate[dimIdx];else if(dims[dimIdx]==0)dimsAt0++;else{let reMul=(val=coordinate[dimIdx],di=dimIdx-1)=>{val*=dims[di];di--;if(di==0)return val;else return reMul(val,di)};foundIdx+=reMul(coordinate[dimIdx]+1,dimIdx-1)}dimIdx++;return getIdx(foundIdx,dimIdx)};let found=getIdx();if(cardinal){if(coordinate[coordinate.length-1]===0){let lastnonzero=0;let idx=0;while(idx!==coordinate.length-1){if(coordinate[idx]!==0)lastnonzero=idx;idx++}return vb[found-lastnonzero+cardinal]}return vb[found-dims.length+cardinal]}else{if(coordinate[coordinate.length-1]===0){let lastnonzero=0;let idx=0;while(idx!==coordinate.length-1){if(coordinate[idx]!==0)lastnonzero=idx;idx++}return vb.slice(found-lastnonzero,found+1)}return vb.slice(found-dims.length,found+1)}};static forBufferedMat=(vb=new Array(100).fill(1),dims=[10,10],asIndex=(v,i,x2,y)=>{return v+x2+y})=>{let coordinate=[];let idx=0;let recurseFor=(depth=0,nextDepth=depth+1)=>{let result=new Array(vb.length);for(let di=0;di{let result=new Array(vb.length);for(let di=0;di{console.log(`value:${v}, idx:${idx}, x:${i},y:${j}`);return v+i+j})=>{let coordinate=new Array(dimensions.length).fill(0);const iterateCoordinate=(coord,idx=0)=>{if(coord[idx]>=dimensions[idx]){coord[idx]=0;idx++;if(idx===dimensions.length)return;iterateCoordinate(coord,idx)}else coord[idx]++};let result=new Array(buffer.length);let i=0;if(typeof asIndex==="function"){while(i{result[i]=func(buffer[i],i,...coordinate);i++;iterateCoordinate(coordinate)})}}return result};static combinations=(choices=["a","b","c"],vecsize=3)=>{var result=[];if(vecsize<=0){result.push([])}else{_Math2.combinations(choices,vecsize-1).forEach(function(previousComb){choices.forEach(function(element){result.push([element].concat(previousComb))})})}return result};static generateCoordinateSpace=(upperBounds=[10,10,10],lowerBounds=[-10,-10,-10],steps=[1,1,1],mutater=void 0)=>{for(let i=0;iupperBounds[i]){let temp=upperBounds[i];upperBounds[i]=lowerBounds[i];lowerBounds[i]=temp}}let result=[];let copy=[...upperBounds];let lastindex=copy.length-1;result.push([...copy]);while(copy[0]>=lowerBounds[0]){let checkNextIndex=decrIdx2=>{if(copy[decrIdx2]<=lowerBounds[decrIdx2]){if(decrIdx2===0)return;copy[decrIdx2]=upperBounds[decrIdx2];decrIdx2--;if(decrIdx2<0)return;if(typeof steps[decrIdx2]=="function")copy[decrIdx2]-=steps[decrIdx2](copy[decrIdx2]);else copy[decrIdx2]-=steps[decrIdx2];checkNextIndex(decrIdx2)}};let decrIdx=lastindex;if(typeof steps[decrIdx]=="function")copy[decrIdx]-=steps[decrIdx](copy[decrIdx]);else copy[decrIdx]-=steps[decrIdx];result.push([...copy]);checkNextIndex(decrIdx);if(mutater)result[result.length-1]=mutater(result[result.length-1])}return result};static meshgrid=_Math2.generateCoordinateSpace;static calcVectorField=(coordinates=[[0,0],[0,1],[1,0],[1,1]],formula=(x2,y)=>{return[x2*10,y*10]})=>{return coordinates.map(vec=>formula(...vec))};static randomMatrix=(rows,cols)=>{return Array.from({length:rows},()=>Array.from({length:cols},()=>Math.random()))};static identityMatrix=size=>{return Array.from({length:size},(_,i)=>Array.from({length:size},(_2,j)=>i===j?1:0))};static diagonalMatrix=values=>{return values.map((value,index)=>{const row=Array(values.length).fill(0);row[index]=value;return row})};static householderMatrix=v=>{const size=v.length;const vvT=v.map(rowVal=>v.map(colVal=>rowVal*colVal));const vTv=this.normalize(v)**2;return Array.from({length:size},(_,i)=>Array.from({length:size},(_2,j)=>(i===j?1:0)-2*vvT[i][j]/vTv))};static transpose=mat=>{return mat[0].map((_,colIndex)=>mat.map(row=>row[colIndex]))};static clone=mat=>{return mat.map(row=>{if(Array.isArray(row[0]))return this.clone(row);else return[...row]})};static getColumn(matrix,col){return matrix.map(row=>row[col])}static matmul=(A,B)=>{return A.map(row=>B[0].map((_,colIndex)=>row.reduce((sum,cell,rowIndex)=>sum+cell*B[rowIndex][colIndex],0)))};static matscale=(mat,scalar)=>{return mat.map(row=>row.map(cell=>cell*scalar))};static matadd=(A,B)=>{return A.map((row,rowIndex)=>row.map((cell,colIndex)=>cell+B[rowIndex][colIndex]))};static matsub=(A,B)=>{return A.map((row,rowIndex)=>row.map((cell,colIndex)=>cell-B[rowIndex][colIndex]))};static inverse=matrix=>{const numRows=matrix.length;const numCols=matrix[0].length;if(numRows!==numCols){throw new Error("Matrix must be square to compute its inverse.")}const augmentedMatrix=matrix.map((row,rowIndex)=>{const identityRow=Array(numRows).fill(0);identityRow[rowIndex]=1;return row.concat(identityRow)});for(let pivotRow=0;pivotRowrow.slice(numCols))};static pseudoInverse=matrix=>{const numRows=matrix.length;const numCols=matrix[0].length;if(numRows>numCols){const ata=this.matmul(this.transpose(matrix),matrix);const ataInv=this.inverse(ata);return this.matmul(ataInv,this.transpose(matrix))}else{const aat=this.matmul(matrix,this.transpose(matrix));const aatInv=this.inverse(aat);return this.matmul(this.transpose(matrix),aatInv)}};static histogram=(arr=[],binSize=1,nBins=void 0)=>{let copy=[...arr];copy.sort(function(a,b){return a-b});let binStart=Math.min(...copy);if(typeof nBins==="number"){let binEnd=Math.max(...copy);binSize=Math.abs((binEnd-binStart)/(nBins-1))}let j=binStart;let binx=[];let biny=[];for(let i=0;ibinStart+binidx){j++;binidx+=binSize;let binmin=binStart+binidx;let binmid=binmin+binidx*.5;binx.push(binmid);biny.push(0)}biny[biny.length-1]++}return[binx,biny]};static normalDistribution=(samples=[],normalize=true,cutoff=1e-4)=>{let m=this.mean(samples);let vari=this.variance(samples);let nSamples=samples.length;let probabilities=[];let denom=1/(this.TWO_PI*vari);let _variance=1/vari;let sum=0;for(let i=0;ix2*_sum)}return probabilities};static expectedValue=(samples=[],probabilities=this.normalDistribution(samples))=>{return samples.reduce((sum,item,idx)=>sum+item*probabilities[idx])};static originMoment=(samples=[],probabilities=this.normalDistribution(samples),order=1)=>{return samples.reduce((sum,item,idx)=>sum+Math.pow(item,order)*probabilities[idx])};static centralMoment=(samples=[],probabilities=this.normalDistribution(samples),order=1)=>{let m=this.mean(samples);return samples.reduce((sum,item,idx)=>sum+Math.pow(item-m,order)*probabilities[idx]/samples.length)};static linearDiscriminantAnalysis=(samples=[],classifier=[])=>{let mean=this.mean(samples);let meank=this.mean(classifier);let covariance=this.cov1d(samples,classifier);let probs=this.normalDistribution(samples);let dk=[];for(let i=0;i{const padlen=deconstructionLowPass.length;let sg=this.edgePad(signal,padlen);let approxCoeffs=this.conv1D(sg,deconstructionLowPass).slice(1+padlen,-padlen).filter((_,idx)=>idx%2===0);let detailCoeffs=this.conv1D(sg,deconstructionHighPass).slice(1+padlen,-padlen).filter((_,idx)=>idx%2===0);let results=[detailCoeffs];for(let i=0;iidx%2===0));approxCoeffs=this.conv1D(approxCoeffs,deconstructionLowPass).slice(1+padlen,-padlen).filter((_,idx)=>idx%2===0)}return[approxCoeffs].concat(results.reverse())};static idwt=(approxCoeffs=[],detailCoeffs=[],reconstructionHighPass=[],reconstructionLowPass=[])=>{if(approxCoeffs.length!==detailCoeffs.length){approxCoeffs.pop()}const _ca=this.dyadicUpsample(approxCoeffs,true);const _cd=this.dyadicUpsample(detailCoeffs,true);const halfa=this.conv1D(_ca,reconstructionLowPass);const halfb=this.conv1D(_cd,reconstructionHighPass);const sig=halfa.map((val,idx)=>val+halfb[idx]);const padlen=reconstructionLowPass.length;const lo=padlen-1;const hi=sig.length-(padlen-2);return sig.slice(lo,hi)};static dwtMaxLevel=(dataLength,waveletLength)=>{return Math.floor(Math.log2(dataLength/(waveletLength-1)))};static minMaxScaler=data=>{const min=Math.min(...data);const max=Math.max(...data);return data.map(value=>(value-min)/(max-min))};static garroteThreshold=(data,value)=>{return data.map(x2=>{if(Math.abs(x2)<=value){return 0}else{return x2-value*value/x2}})};static conv1D=(s,kernel)=>{const revKernel=[...kernel].reverse();const padsize=kernel.length-1;const paddedS=new Array(padsize).fill(0).concat(s).concat(new Array(padsize).fill(0));const nSteps=paddedS.length-kernel.length+1;const result=new Array(nSteps).fill(0);const nKer=kernel.length;for(let i=0;i{const rows=matrix.length;const cols=matrix[0].length;const kRows=kernel.length;const kCols=kernel[0].length;const halfKRows=Math.floor(kRows/2);const halfKCols=Math.floor(kCols/2);const output=new Array(rows).fill(0).map(()=>new Array(cols).fill(0));for(let i=0;i=0&&xi=0&&yj{if(matrix.length===0||kernel.length===0)return[];function getShape(arr){const shape=[];while(Array.isArray(arr)){shape.push(arr.length);arr=arr[0]}return shape}function convolveRecurse(mat,ker,matrixShape2,kernelShape2,matIndices=[],kerIndices=[]){const depth=matIndices.length;if(depth===matrixShape2.length){let sum=0;for(let i=0;i=0&&matIndex{const mean1=this.mean(arr1);const mean2=this.mean(arr2);return arr1.map((v,i)=>(v-mean1)*(arr2[i]-mean2))};static cov1d=(arr1,arr2)=>{this.mean(this.covVec(arr1,arr2))};static cov2d=mat=>{var mattransposed=this.transpose(mat);var matproducts=[];var rowmeans=[];var colmeans=[];mat.forEach((row,idx)=>{rowmeans.push(this.mean(row))});mattransposed.forEach((col,idx)=>{colmeans.push(this.mean(col))});mat.forEach((row,idx)=>{matproducts.push([]);for(var col=0;col{return[[this.cov1d(x2,x2),this.cov1d(x2,y),this.cov1d(x2,z)],[this.cov1d(y,x2),this.cov1d(y,y),this.cov1d(y,z)],[this.cov1d(z,x2),this.cov1d(z,y),this.cov1d(z,z)]]};static covNd=(dimensionalData=[])=>{let covariance=[];dimensionalData.forEach((arr,i)=>{covariance.push([]);dimensionalData.forEach((arr2,j)=>{covariance[i].push(this.cov1d(arr,arr2))})})};static correlationCoeff=(arr1,arr2)=>{const cov=this.cov1d(arr1,arr2);const stdDev1=this.std(arr1);const stdDev2=this.std(arr2);return cov/(stdDev1*stdDev2)};static pearsonCorrelation=(arr1,arr2)=>{let sumX=0,sumY=0,sumXY=0,sumX2=0,sumY2=0;const n=arr1.length>arr2.length?arr2.length:arr1.length;for(let i=0;i{let det=mat[0][0]*mat[1][1]-mat[0][1]*mat[1][0];let mean=(mat[0][0]+mat[1][1])*.5;let sqrt=Math.sqrt(mean*mean-det);let eig1=mean+sqrt;let eig2=mean-sqrt;return[eig1,eig2]};static eigenvectors2x2=(mat=[[1,2],[3,4]],eigens=[1,2])=>{let v1=[-mat[0][1],mat[0][0]-eigens[0]];if(v1[0]===0&&v1[1]===0){v1[0]=mat[1][1]-eigens[0];v1[1]=-mat[1][0]}let v2=[-mat[0][1],mat[0][0]-eigens[1]];if(v2[0]===0&&v2[1]===0){v2[0]=mat[1][1]-eigens[1];v2[1]=-mat[1][0]}return[v1,v2]};static fastpca2d=(xarr,yarr)=>{let covMat=this.cov2d(xarr,yarr);let eigs=this.eigens2x2(covMat);if(eigs[1]>eigs[0])eigs.reverse();let evs=this.eigenvectors2x2(covMat,eigs);return[eigs,evs]};static centerData=data=>{const mean=data.reduce((sum,val)=>sum+val,0)/data.length;return data.map(v=>v-mean)};static crosscorrelation=(signalA,signalB,posOnly=false)=>{const N=signalA.length;const M=signalB.length;const result=[];const normFactor=1/Math.sqrt(signalA.reduce((acc,val)=>acc+val*val,0)*signalB.reduce((acc,val)=>acc+val*val,0));if(posOnly){result.length=signalA.length;for(let lag=0;lag=0&&m{const lags=[];const timeResolution=samplingRate?1/samplingRate:0;const center=centered?correlogram.length/2:null;const len=correlogram.length-1;for(let i=1;icorrelogram[i-1]&&correlogram[i]>correlogram[i+1]){let lag={offset:centered?i-center:i,value:correlogram[i]};if(timeResolution)lag.offset*=timeResolution;lags.push(lag)}}if(getMax)return lags.reduce((maxObj,currentObj)=>{return currentObj.value>maxObj.value?currentObj:maxObj},lags[0]);else return lags};static autocorrelation=arr1=>{var delaybuf=[...arr1,...Array(arr1.length).fill(0)];var mean1=this.mean(arr1);var arr1Est=arr1.reduce((sum,item)=>sum+=Math.pow(item-mean1,2));arr1Est=Math.sqrt(Math.abs(arr1Est));let denom=arr1Est*arr2Est;if(denom===0)denom=1e-26;var _arr1estsqrd=1/denom;var correlations=new Array(arr1.length).fill(0);for(var delay=0;delaysum+=(item-mean1)*(delaybuf[delay+i]-mean1));correlations[delay]=r*_arr1estsqrd}return correlations};static autocorrelation2d=mat2d2=>{let result=[];for(let y=0;y{let result=[];for(let y=0;y{let result=[];for(let y=0;y{let result=[];for(let y=0;y{var correlograms=[];dat.forEach((row1,i)=>{dat.forEach((row2,j)=>{if(j>=i){correlograms.push(_Math2.crosscorrelation(row1,row2))}})});return correlograms};static dft=(sineWave=[],sampleRate=250,frequencyResolution=.25)=>{const N=sineWave.length;const NyquistLimit=Math.floor(sampleRate/2);const totalFreqs=Math.floor(NyquistLimit/frequencyResolution);const Npadded=Math.ceil(sampleRate/frequencyResolution);const TWOPI=2*3.141592653589793;const real=new Array(Npadded).fill(0);const imag=new Array(Npadded).fill(0);const amplitudes=new Array(Npadded);const zerosToAdd=Npadded-N;if(zerosToAdd<0){throw new Error("Desired resolution is not achievable with current sample size.")}const paddedSineWave=zerosToAdd?[...sineWave,...Array(zerosToAdd).fill(0)]:sineWave;let orderedFrequencies;if(totalFreqs%2===0){orderedFrequencies=[...new Array(totalFreqs).fill(0).map((x2,i)=>-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs).fill(0).map((x2,i)=>i*frequencyResolution)]}else{orderedFrequencies=[...new Array(totalFreqs).fill(0).map((x2,i)=>-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs+1).fill(0).map((x2,i)=>i*frequencyResolution)]}for(let k=0;k-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs).fill(0).map((x2,i)=>(i+1)*frequencyResolution)]}else{orderedMagnitudes=[...amplitudes.slice(totalFreqs,2*totalFreqs),...amplitudes.slice(0,totalFreqs+1)];orderedFrequencies=[...new Array(totalFreqs).fill(0).map((x2,i)=>-NyquistLimit+i*frequencyResolution),...new Array(totalFreqs+1).fill(0).map((x2,i)=>i*frequencyResolution)]}return{real,imag,freqs:orderedFrequencies,amplitudes:orderedMagnitudes}};static eulerTransform=(dataSeries=[],timeTransform=(j,dataSeries2,real,imag,magnitudes)=>{return dataSeries2[j]},stepTransform=(k,j,length,real,imag,magnitudes)=>{return 2*Math.PI*k*j/length},kN=dataSeries.length)=>{var real=[];var imag=[];var magnitudes=[];for(var k=0;k{var smaArr=[];for(var i=0;icurrent+=previous)/(i+1))}else{var arrslice=arr.slice(i-window,i);smaArr.push(arrslice.reduce((previous,current)=>current+=previous)/window)}}return smaArr};static sum=(arr=[])=>{if(arr.length>0){var sum=arr.reduce((prev,curr)=>curr+=prev);return sum}else{return 0}};static reduceArrByFactor=(arr,factor=2)=>{let x2=arr.filter((element,index)=>{return index%factor===0});return x2};static makeArr=(startValue,stopValue,nSteps)=>{var arr=[];var step=(stopValue-startValue)/(nSteps-1);for(var i=0;i{if(array?.length===0)return array;let max=Math.max(...array);let min=Math.min(...array);let _lines=1/stackedLines;let scalar;if(centerZero){let absmax=Math.max(Math.abs(min),Math.abs(max));scalar=_lines/absmax;return array.map(y=>y*scalar+(_lines*(stackPosition+1)*2-1-_lines))}else{scalar=_lines/(max-min);return array.map(y=>2*((y-min)*scalar-1/(2*stackedLines))+(_lines*(stackPosition+1)*2-1-_lines))}};static absmax=array=>{return Math.max(Math.abs(Math.min(...array)),Math.max(...array))};static downsample=(array,fitCount,scalar=1)=>{if(array.length>fitCount){let output=new Array(fitCount);let incr=array.length/fitCount;let lastIdx=array.length-1;let last=0;let counter=0;for(let i=incr;ilastIdx)rounded=lastIdx;for(let j=last;j{var linearInterpolate=function(before2,after2,atPoint2){return(before2+(after2-before2)*atPoint2)*scalar};var newData=new Array;var springFactor=(array.length-1)/(fitCount-1);newData[0]=array[0];for(var i=1;i{const start=even?1:0;const out=new Array(a.length*2).fill(0);for(let i=0;i{if(array.length===fitCount)return array;if(array.length>fitCount){return this.downsample(array,fitCount,scalar)}else{return this.upsample(array,fitCount,scalar)}};static lerp=(v0,v1,t)=>{return(1-t)*v0+t*v1};static linspace=(start,end,num,floor=false)=>{const arr=new Array(num);const step=(end-start)/(num-1);for(let i=0;i{let ref=[...arr];if(ref.length%2===0)ref.pop();if(arr.length>1){let pass=true;for(let i=0;i=ref[Math.floor(ref.length*.5)]){pass=false;break}else if(i>Math.floor(ref.length*.5)&&val>=ref[Math.floor(ref.length*.5)]){pass=false;break}}else if(critical==="valley"){if(iMath.floor(ref.length*.5)&&val<=ref[Math.floor(ref.length*.5)]){pass=false;break}}else{if(iMath.floor(ref.length*.5)&&val<=ref[Math.floor(ref.length*.5)]){pass=false;break}}}if(critical!=="peak"&&critical!=="valley"&&pass===false){pass=true;for(let i=0;i=ref[Math.floor(ref.length*.5)]){pass=false;break}else if(i>Math.floor(ref.length*.5)&&val>=ref[Math.floor(ref.length*.5)]){pass=false;break}}}return pass}else return void 0};static isCriticalPoint=(arr,critical="peak")=>{let ref=[...arr];if(ref.length%2===0)ref.pop();if(arr.length>1){let pass=true;for(let i=0;iref.length*.5&&val>0){pass=false;break}}else if(critical==="valley"){if(i=0){pass=false;break}else if(i>ref.length*.5&&val<0){pass=false;break}}else{if(i=0){pass=false;break}else if(i>ref.length*.5&&val<0){pass=false;break}}}if(critical!=="peak"&&critical!=="valley"&&pass===false){pass=true;for(let i=0;iref.length*.5&&val>0){pass=false;break}}}return pass}else return void 0};static peakDetect=(smoothedArray,type="peak",window=49)=>{let mid=Math.floor(window*.5);let peaks=[];for(let i=0;i{let threshold;let filtered=arr.filter((o,i)=>{if(peakIndices.indexOf(i)>-1)return true});if(thresholdVar===0){threshold=this.mean(filtered)}else threshold=(thresholdVar+this.mean(filtered))*.5;return threshold};static column=(mat,x2)=>{let col=new Array(mat.length).fill(0).map(()=>new Array(1).fill(0));for(let i=0;i{let v_new=[];for(let i=0;i{let sum=0;for(let i=0;i{let len=Math.sqrt(this.matmul(this.transpose(eigenvector),eigenvector));let U=this.matscale(eigenvector,1/len);let delta=this.matscale(this.matmul(U,this.transpose(U)),eigenvalue);let M_new=this.matsub(mat,delta);return M_new};static eigenvalue_of_vector=(mat,eigenvector)=>{ev=this.matmul(this.matmul(this.transpose(eigenvector),mat),eigenvector);return ev};static power_iteration=(A,numIter=100)=>{let b=Array(A.length).fill(1);for(let i=0;i{let eigenvalues=[];let eigenvectors=[];for(let i=0;i{if(A[0].length>A.length){A=this.transpose(A)}const m=A.length;const n=A[0].length;const prec=Number.EPSILON;const tolerance=1e-64/prec;const itmax=50;const leftSingularVectors=this.clone(A);const offDiagonalValues=Array(n).fill(0);const singularValues=Array(n).fill(0);const rightSingularVectors=Array.from({length:n},()=>Array(n).fill(0));function pythag(a,b){if(a===0||b===0)return a+b;const absA=Math.abs(a),absB=Math.abs(b);if(absA>absB){const t=absB/absA;return absA*Math.sqrt(1+t*t)}else{const t=absA/absB;return absB*Math.sqrt(1+t*t)}}let scaleFactorF=0;let scaleFactorG=0;let scaleFactorH=0;let maxMagnitude=0;let intermediateY=0;let intermediateZ=0;let sumValue=0;let cosineTheta=0;let limitIndex=0;for(let i=0;i=0)scaleFactorG=-scaleFactorG;scaleFactorH=scaleFactorF*scaleFactorG-sumValue;leftSingularVectors[i][i]=scaleFactorF-scaleFactorG;for(let j=limitIndex;j=0)scaleFactorG=-scaleFactorG;scaleFactorH=scaleFactorF*scaleFactorG-sumValue;leftSingularVectors[i][i+1]=scaleFactorF-scaleFactorG;for(let j=limitIndex;jmaxMagnitude)maxMagnitude=intermediateY}for(let i=n-1;i>=0;i--){if(scaleFactorG!==0){scaleFactorH=scaleFactorG*leftSingularVectors[i][i+1];for(let j=limitIndex;j=0;i--){limitIndex=i+1;scaleFactorG=singularValues[i];for(let j=limitIndex;j=0;k--){for(let iteration=0;iteration=0;limitIndex--){if(Math.abs(offDiagonalValues[limitIndex])<=eps){testConvergence=true;break}if(Math.abs(singularValues[limitIndex-1])<=eps)break}if(!testConvergence){cosineTheta=0;sumValue=1;const l1=limitIndex-1;for(let i=limitIndex;i=itmax-1)throw new Error("No convergence.");maxMagnitude=singularValues[limitIndex];intermediateY=singularValues[k-1];scaleFactorG=offDiagonalValues[k-1];scaleFactorH=offDiagonalValues[k];scaleFactorF=((intermediateY-intermediateZ)*(intermediateY+intermediateZ)+(scaleFactorG-scaleFactorH)*(scaleFactorG+scaleFactorH))/(2*scaleFactorH*intermediateY);scaleFactorG=pythag(scaleFactorF,1);if(scaleFactorF<0)scaleFactorF=((maxMagnitude-intermediateZ)*(maxMagnitude+intermediateZ)+scaleFactorH*(intermediateY/(scaleFactorF-scaleFactorG)-scaleFactorH))/maxMagnitude;else scaleFactorF=((maxMagnitude-intermediateZ)*(maxMagnitude+intermediateZ)+scaleFactorH*(intermediateY/(scaleFactorF+scaleFactorG)-scaleFactorH))/maxMagnitude;cosineTheta=1;sumValue=1;for(let i=limitIndex+1;i=0;j--){if(singularValues[j]row.slice());for(let k=0;k0?-this.normalize(x2):this.normalize(x2);const u=this.vecsub(x2,e);const normU=this.normalize(u);const v=u.map(val=>val/normU);const Qk=this.householderMatrix(v);const QkFull=this.identityMatrix(numRows);for(let row=k;row{const numRowsOriginal=matrixA.length;const numColsOriginal=matrixA[0].length;if(!numComponents){numComponents=Math.min(numRowsOriginal,numColsOriginal)}let matrixACopy=[...matrixA.map(row=>[...row])];if(numRowsOriginal>numColsOriginal){matrixA=this.matmul(this.transpose(matrixA),matrixA)}else if(numRowsOriginalsum+row.reduce((rowSum,val)=>rowSum+val*val,0),0);previousMatrixQ=matrixQ;if(errorMath.sqrt(row[row.indexOf(Math.max(...row))]));let leftVectors,rightVectors;if(numRowsOriginalval*val)}else{rightVectors=this.transpose(matrixQ);leftVectors=this.matmul(this.matmul(matrixACopy,rightVectors),this.inverse(this.diagonalMatrix(singularValues)))}return{U:leftVectors,S:singularValues,V:rightVectors}};static pca=(mat,tolerance=1e-5)=>{let dims=mat.length;let t=new Array(dims);let p=new Array(dims);let mat_t=this.transpose(mat);t[0]=this.column(mat,0);let epsilon=1;let iter=0;while(espilon>tolerance){iter++;p[0]=this.matmul(mat_t,t[0]);let tp=this.matmul(this.transpose(t[0]),t[0]);p[0]=this.matscale(p[0],1/tp);let p_length=Math.sqrt(this.matmul(this.transpose(p[0]),p[0]));p[0]=this.matscale(p[0],1/p_length);let t_new=this.matmul(mat,p[0]);let pp=this.matmul(this.transpose(p[0]),p[0]);t_new=this.matscale(t_new,1/pp);epsilon=this.squared_difference(t[0],t_new);t[0]=JSON.parse(JSON.stringify(t_new))}let components=this.matmul(this.transpose(t[0]),t[0]);return components};static circularBuffer=(arr,newEntries)=>{if(Array.isArray(newEntries)){if(newEntries.lengtharr.length){let len=arr.length;arr.splice(0,len,newEntries.slice(len-newEntries.length))}else{arr.splice(0,arr.length,...newEntries)}}else{arr.push(newEntries);arr.shift()}return arr};static reshape=(arr,shape)=>{const totalSize=shape.reduce((acc,val)=>acc*val,1);const flatArr=this.flatten(arr);if(flatArr.length!==totalSize){throw new Error("The given shape is incompatible with the array size.")}function buildArray(shape2,flatData){const dim=shape2[0];if(shape2.length===1){return flatData.splice(0,dim)}let result=[];for(let i=0;i{if(!Array.isArray(arr)){return[arr]}return arr.reduce((acc,val)=>acc.concat(flatten(val)),[])};static p300=(event_timestamps=[],raw_signal=[],signal_timestamps=[],sps=256)=>{let smoothingstep=Math.floor(sps/10);let smoothed=this.sma(raw_signal,smoothingstep);let peaks=this.peakDetect(smoothed,"peak",smoothingstep);let mean=this.mean(smoothed);let std=this.std(smoothed,mean);let p_idx=0;let candidates=[];if(peaks.length>0){event_timestamps.forEach((t,j)=>{while(signal_timestamps[peaks[p_idx]]1){let peakvals=[];tempcandidates.forEach(tc=>{peakvals.push(smoothed[peaks[tc]])});let max=Math.max(...peakvals);let maxi=tempcandidates[peakvals.indexOf(max)];candidates.push({event_timestamp:t,event_index:j,peak_timestamp:signal_timestamps[[peaks[maxi]]],signal_index:[peaks[maxi]],signal_amplitude:raw_signal[[peaks[maxi]]],zscore:(smoothed[peaks[maxi]]-mean)/std})}else if(tempcandidates.length===1)candidates.push({event_timestamp:t,event_index:j,peak_timestamp:signal_timestamps[peaks[tempcandidates[0]]],signal_index:peaks[tempcandidates[0]],signal_amplitude:raw_signal[[peaks[tempcandidates[0]]]],zscore:(smoothed[peaks[tempcandidates[0]]]-mean)/std})})}return candidates};static dec_lo=[-.07576571478927333,-.02963552764599851,.49761866763201545,.8037387518059161,.29785779560527736,-.09921954357684722,-.012603967262037833,.0322231006040427];static dec_hi=[-.0322231006040427,-.012603967262037833,.09921954357684722,.29785779560527736,-.8037387518059161,.49761866763201545,.02963552764599851,-.07576571478927333];static rec_lo=[.0322231006040427,-.012603967262037833,-.09921954357684722,.29785779560527736,.8037387518059161,.49761866763201545,-.02963552764599851,-.07576571478927333];static rec_hi=[-.07576571478927333,.02963552764599851,.49761866763201545,-.8037387518059161,.29785779560527736,.09921954357684722,-.012603967262037833,-.0322231006040427];static waveletFiltering=(signal=[],wavelets={dec_hi:this.dec_hi,dec_lo:this.dec_lo,rec_hi:this.rec_hi,rec_lo:this.rec_lo})=>{let maxlevel=this.dwtMaxLevel(signal.length,wavelets.dec_lo.length);let decomposed=this.decompose(signal,maxlevel,wavelets.dec_hi,wavelets.dec_lo);for(let i=2;i{ax=ax*this.accelConstant;ay=ay*this.accelConstant;az=az*this.accelConstant;const accelXAngle=Math.atan(ay/Math.sqrt(ax*ax)+az*az*180/Math.PI)+this.accelXError;const accelYAngle=Math.atan(-ax/Math.sqrt(ay*ay)+az*az*180/Math.PI)+this.accelYError;return{ax,ay,az,roll:accelXAngle,pitch:accelYAngle}};if(Array.isArray(data.timestamp)){result=data.timestamp.map((v,i)=>{return apass(v,data.ax[i],data.ay[i],data.az[i])})}else result=apass(data.timestamp,data.ax,data.ay,data.az)}if(data.gx){let gpass=(timestamp,gx,gy,gz)=>{const elapsed=timestamp-this.lastGyroTime;this.lastGyroTime=timestamp;gx=gx*this.gyroConstant+this.gyroXError;gy=gy*this.gyroConstant+this.gyroYError;gz=gz*this.gyroConstant+this.gyroZError;this.gyroXAngle+=gx*elapsed;this.gyroYAngle+=gy*elapsed;this.gyroZAngle+=gz*elapsed;return{gx,gy,gz,roll:this.gyroXAngle,pitch:this.gyroYAngle,yaw:this.gyroZAngle}};let res;if(Array.isArray(data.timestamp)){res=data.timestamp.map((v,i)=>{if(result){let r=gpass(v,data.gx[i],data.gy[i],data.gz[i]);result.roll=result.roll*.04+r.roll*.96;result.pitch=result.pitch*.04+r.pitch*.96;result.yaw=res.yaw}else return gpass(v,data.gx[i],data.gy[i],data.gz[i])});if(!result)result=res}else{res=gpass(data.timestamp,data.gx,data.gy,data.gz);if(result){result.roll=result.roll*.04+res.roll*.96;result.pitch=result.pitch*.04+res.pitch*.96;result.yaw=res.yaw}else result=res}}else if(this.gyroXAngle||this.gyroYAngle||this.gyroZAngle){result.roll=result.roll*.04+this.gyroXAngle*.96;result.pitch=result.pitch*.04+this.gyroYAngle*.96;result.yaw=this.gyroXAngle}if(result.ax){const setPositionOffset=(timestamp,result2)=>{const elapsed=timestamp-this.lastAccelTime;this.lastAccelTime=timestamp;this.px+=result2.ax*elapsed*elapsed*Math.cos(this.pitch*Math.PI*.005555555555);this.py+=result2.ay*elapsed*elapsed*Math.cos(this.roll*Math.PI*.005555555555);this.pz+=result2.az*elapsed*elapsed*Math.sin(this.pitch*Math.PI*.005555555555);result2.px=this.px;result2.py=this.py;result2.pz=this.pz;return result2};if(Array.isArray(data.timestamp)){data.timestamp.map((timestamp,i)=>{setPositionOffset(timestamp,result)})}else{setPositionOffset(data.timestamp,result)}}return result}};var Biquad=class{type;freq;sps;Q;dbGain;a0=0;a1=0;a2=0;b0=0;b1=0;b2=0;x1=0;x2=0;y1=0;y2=0;constructor(type,freq,sps,Q=1/Math.sqrt(2),dbGain=0){let types=["lowpass","highpass","bandpass","notch","peak","lowshelf","highshelf"];if(types.indexOf(type)<0){console.error("Valid types: 'lowpass','highpass','bandpass','notch','peak','lowshelf','highshelf'");return}this.type=type;this.freq=freq;this.sps=sps;this.Q=Q;this.dbGain=dbGain;let A=Math.pow(10,dbGain/40);let omega=2*Math.PI*freq/sps;let sn=Math.sin(omega);let cs=Math.cos(omega);let alpha=sn/(2*Q);let beta=Math.sqrt(A+A);this[type](A,sn,cs,alpha,beta);this.b0/=this.a0;this.b1/=this.a0;this.b2/=this.a0;this.a1/=this.a0;this.a2/=this.a0}lowpass(A,sn,cs,alpha,beta){this.b0=(1-cs)*.5;this.b1=1-cs;this.b2=(1-cs)*.5;this.a0=1+alpha;this.a1=-2*cs;this.a2=1-alpha}highpass(A,sn,cs,alpha,beta){this.b0=(1+cs)*.5;this.b1=-(1+cs);this.b2=(1+cs)*.5;this.a0=1+alpha;this.a1=-2*cs;this.a2=1-alpha}bandpass(A,sn,cs,alpha,beta){this.b0=alpha;this.b1=0;this.b2=-alpha;this.a0=1+alpha;this.a1=-2*cs;this.a2=1-alpha}notch(A,sn,cs,alpha,beta){this.b0=1;this.b1=-2*cs;this.b2=1;this.a0=1+alpha;this.a1=-2*cs;this.a2=1-alpha}peak(A,sn,cs,alpha,beta){this.b0=1+alpha*A;this.b1=-2*cs;this.b2=1-alpha*A;this.a0=1+alpha/A;this.a1=-2*cs;this.a2=1-alpha/A}lowshelf(A,sn,cs,alpha,beta){this.b0=A*(A+1-(A-1)*cs+beta*sn);this.b1=2*A*(A-1-(A+1)*cs);this.b2=A*(A+1-(A-1)*cs-beta*sn);this.a0=A+1+(A+1)*cs+beta*sn;this.a1=2*(A-1+(A+1)*cs);this.a2=A+1+(A-1)*cs-beta*sn}highshelf(A,sn,cs,alpha,beta){this.b0=A*(A+1+(A-1)*cs+beta*sn);this.b1=2*A*(A-1+(A+1)*cs);this.b2=A*(A+1-(A-1)*cs-beta*sn);this.a0=A+1-(A+1)*cs-beta*sn;this.a1=2*(A-1-(A+1)*cs);this.a2=A+1-(A-1)*cs-beta*sn}applyFilter(signal_step){let y=this.b0*signal_step+this.b1*this.x1+this.b2*this.x2-this.a1*this.y1-this.a2*this.y2;this.x2=this.x1;this.x1=signal_step;this.y2=this.y1;this.y1=y;return y}zResult(freq){try{let phi=Math.pow(Math.sin(Math.PI*freq*2/(2*this.sps)),2);let result=(Math.pow(this.b0+this.b1+this.b2,2)-4*(this.b0*this.b1+4*this.b0*this.b2+this.b1*this.b2)*phi+16*this.b0*this.b2*phi*phi)/(Math.pow(1+this.a1+this.a2,2)-4*(this.a1+4*this.a2+this.a1*this.a2)*phi+16*this.a2*phi*phi);return result}catch(err){return-200}}static calcCenterFrequency(freqStart,freqEnd){return(freqStart+freqEnd)/2}static calcBandwidth(freqStart,freqEnd){return freqEnd-this.calcCenterFrequency(freqStart,freqEnd)}static calcBandpassQ(frequency,bandwidth,resonance=Math.pow(10,Math.floor(Math.log10(frequency)))){let Q=resonance*Math.sqrt((frequency-bandwidth)*(frequency+bandwidth))/(2*bandwidth);return Q}static calcNotchQ(frequency,bandwidth,resonance=Math.pow(10,Math.floor(Math.log10(frequency)))){let Q=resonance*frequency*bandwidth/Math.sqrt((frequency-bandwidth)*(frequency+bandwidth));return Q}};var beat_detect={refdata:[],lowpass:void 0,smoothed:[],timestamp:[],peaks:[],valleys:[],peak_distances:[],valley_distances:[],beats:[],lastPeak:0,lastValley:0,sps:100,maxFreq:4,limit:10,__onconnected:function(){if(!this.lowpass){let freq=this.maxFreq;if(!freq)freq=1;if(freq>1)freq*=.5;this.lowpass=new Biquad("lowpass",this.maxFreq,this.sps);this.peakFinderWindow=Math.floor(this.sps/this.maxFreq);if(this.peakFinderWindow%2===0)this.peakFinderWindow+=1;if(this.peakFinderWindow<5)this.peakFinderWindow=5;this.midpoint=Math.round(this.peakFinderWindow*.5)}},__operator:function(data){if(!("red"in data)&&!("heg"in data)&&!("raw"in data))return void 0;let refdata=data.red?data.red:data.heg?data.heg:data.raw;if(!("timestamp"in data)){if(Array.isArray(refdata)){let now=Date.now();let len;if(refdata)len=refdata.length;let toInterp=[now-refdata.length*this.sps*1e3,now];data.timestamp=Math2.upsample(toInterp,refdata.length)}else{data.timestamp=Date.now()}}let pass=(amplitude,timestamp)=>{if(amplitude){this.refdata.push(amplitude)}this.timestamp.push(timestamp);let beat;if(this.refdata.length>this.peakFinderWindow){this.refdata.shift();this.timestamp.shift()}this.smoothed.push(this.lowpass.applyFilter(this.refdata[this.refdata.length-1]));if(this.smoothed.length>this.peakFinderWindow){this.smoothed.shift()}if(this.smoothed.length===this.peakFinderWindow){if(Math2.isExtrema(this.smoothed,"valley")){this.valleys.push({value:this.smoothed[this.smoothed.length-this.midpoint?this.midpoint:1],timestamp:this.timestamp[this.timestamp.length-this.midpoint?this.midpoint:1]})}else if(Math2.isExtrema(this.smoothed,"peak")){this.peaks.push({value:this.smoothed[this.smoothed.length-this.midpoint?this.midpoint:1],timestamp:this.timestamp[this.timestamp.length-this.midpoint?this.midpoint:1]})}if(this.valleys.length>2&&this.peaks.length>2){if(this.valleys[this.valleys.length-1].timestamp1&&this.valley_distances.length>1){if(this.lastPeakthis.peak_distances[this.peak_distances.length-1].timestamp){let bpm,change=0;if(this.beats.length<1){bpm=60/(5e-4*(this.peak_distances[this.peak_distances.length-1].distance+this.valley_distances[this.valley_distances.length-1].distance))}else if(this.beats[this.beats.length-1].timestamp!==this.peak_distances[this.peak_distances.length-1].timestamp){bpm=60/(5e-4*(this.peak_distances[this.peak_distances.length-1].dt+this.valley_distances[this.valley_distances.length-1].dt));change=Math.abs(bpm-this.beats[this.beats.length-1].bpm)}beat={timestamp:this.peak_distances[this.peak_distances.length-1].timestamp,change,bpm,height0:this.peak_distances[this.peak_distances.length-1].peak0-this.valley_distances[this.valley_distances.length-1].peak0,height1:this.peak_distances[this.peak_distances.length-1].peak1-this.valley_distances[this.valley_distances.length-1].peak1};this.beats.push(beat);this.lastPeak=this.peaks[this.peaks.length-1].timestamp;this.lastValley=this.peaks[this.peaks.length-1].timestamp}else{let bpm,change=0;if(this.beats.length<2){bpm=60/(5e-4*(this.peak_distances[this.peak_distances.length-2].distance+this.valley_distances[this.valley_distances.length-2].distance))}else if(this.beats[this.beats.length-1].timestamp!==this.peak_distances[this.peak_distances.length-2].timestamp){bpm=60/(5e-4*(this.peak_distances[this.peak_distances.length-2].distance+this.valley_distances[this.valley_distances.length-2].distance));change=Math.abs(bpm-this.beats[this.beats.length-2].bpm)}beat={timestamp:this.peak_distances[this.peak_distances.length-2].timestamp,change,bpm,height0:this.peak_distances[this.peak_distances.length-2].peak0-this.valley_distances[this.valley_distances.length-2].peak0,height1:this.peak_distances[this.peak_distances.length-2].peak1-this.valley_distances[this.valley_distances.length-2].peak1};if(Array.isArray(beat.timestamp))beat.timestamp=beat.timestamp[0];this.beats.push(beat);this.lastPeak=this.peaks[this.peaks.length-1].timestamp;this.lastValley=this.peaks[this.peaks.length-1].timestamp}}}if(this.peaks.length>this.limit){this.peaks.shift()}if(this.valleys.length>this.limit){this.valleys.shift()}if(this.peak_distances.length>this.limit){this.peak_distances.shift()}if(this.valley_distances.length>this.limit){this.valley_distances.shift()}if(this.beats.length>this.limit){this.beats.shift()}}}return beat};if(data.red){if("ir"in data&&!Array.isArray(data.red))return pass(data.red+data.ir,data.timestamp);let result;if(data.ir)result=data.red.map((v,i)=>{return pass(v+data.ir[i],data.timestamp[i])}).filter(v=>{if(v)return true});else result=data.red.map((v,i)=>{return pass(v,data.timestamp[i])}).filter(v=>{if(v)return true});return result}else if(data.raw){if(!Array.isArray(data.raw))return pass(data.raw,data.timestamp);let result=data.raw.map((v,i)=>{return pass(v,data.timestamp[i])}).filter(v=>{if(v)return true});return result}else if(Array.isArray(data.heg)){if(!Array.isArray(data.heg))return pass(data.heg,data.timestamp);let result=data.heg.map((v,i)=>{return pass(v,data.timestamp[i])}).filter(v=>{if(v)return true});return result}}};var blink_detect={sps:250,intervals:{},watch:["0"],tolerance:.2,__onconnected:node=>{node.watch.forEach(ch=>node.intervals[ch]={lowpass:new Biquad("lowpass",20,node.sps),filtered:[],averaged:[]})},__operator:function(data){let checkCt=5;let averageCt=50;let found={};let passed=false;let pass=(key,n)=>{let next=this.intervals[key].lowpass.applyFilter(n);this.intervals[key].filtered.push(next);this.intervals[key].averaged.push(next);if(this.intervals[key].filtered.length>checkCt){if(this.intervals[key].averaged.length>averageCt){this.intervals[key].averaged.splice(0,checkCt);let mean=Math2.mean(this.intervals[key].averaged);if(Math.abs(Math.min(...this.intervals[key].filtered))>Math.abs(mean)+this.tolerance){this.intervals[key].filtered.length=0;passed=true;found[key]=true}}else this.intervals[key].filtered.shift()}};for(const key in this.intervals){if(data[key]){if(Array.isArray(data[key])){data[key].forEach(n=>{pass(key,n)})}else if(typeof data[key]==="number")pass(key,data[key])}}if(passed)return found}};var ArrayManip=class _ArrayManip{static autoscale(array,lineIdx=0,nLines=1,centerZero=false,ymin,ymax,clamp){if(array?.length===0)return array;let max=ymax?ymax:Math.max(...array);let min=ymin?ymin:Math.min(...array);let _lines=1/nLines;let scalar=1;if(centerZero){let absmax=Math.max(Math.abs(min),Math.abs(max));if(absmax!==0)scalar=_lines/absmax;return array.map(y=>{if(clamp){if(ymax)y=max}return y*scalar+(_lines*(lineIdx+1)*2-1-_lines)})}else{if(max===min){if(max!==0){scalar=_lines/max}else if(min!==0){scalar=_lines/Math.abs(min)}}else scalar=_lines/(max-min);return array.map(y=>{if(clamp){if(ymax)y=max}return 2*((y-min)*scalar-1/(2*nLines))+(_lines*(lineIdx+1)*2-1-_lines)})}}static genTimestamps(ct,sps){let now=Date.now();let toInterp=[now-ct*1e3/sps,now];return _ArrayManip.upsample(toInterp,ct)}static absmax(array){return Math.max(Math.abs(Math.min(...array)),Math.max(...array))}static downsample(array,fitCount,scalar=1){if(array.length>fitCount){let output=new Array(fitCount);let incr=array.length/fitCount;let lastIdx=array.length-1;let last=0;let counter=0;for(let i=incr;ilastIdx)rounded=lastIdx;for(let j=last;jfitCount){return _ArrayManip.downsample(array,fitCount,scalar)}else if(array.lengtharr.length){let len=arr.length;arr.splice(0,len,...newEntries.slice(newEntries.length-len))}else{arr.splice(0,arr.length,...newEntries)}return arr}static reformatData(data,key){if(Array.isArray(data)){if(Array.isArray(data[0])){let d={};data.forEach((arr,i)=>{d[i]=arr});data=d;if(isNaN(data[0][0]))return void 0}else if(key){data={[key]:data};if(isNaN(data[key][0]))return void 0}else{data={0:data};if(isNaN(data[0][0]))return void 0}}else if(typeof data==="object"){for(const key2 in data){if(typeof data[key2]==="number")data[key2]=[data[key2]];else if(data[key2]?.values){if(typeof data[key2].values==="number")data[key2].values=[data[key2].values]}if(isNaN(data[key2][0]))return void 0}}else if(typeof data==="string"){let split;if(data.includes("\r\n")){let lines=data.split("\r\n");data={};lines.forEach((l,j)=>{if(l.includes(" ")){split=l.split(" ")}else if(l.includes(",")){split=l.split(",")}else if(l.includes("|")){split=l.split("|")}if(Array.isArray(split)){split.forEach((val,i)=>{if(val.includes(":")){let[key2,v]=val.split(":");let fl=parseFloat(v);if(fl)data[key2]=[fl];else return void 0}else{let fl=parseFloat(val);if(fl)data[i]=[fl];else return void 0}})}})}else if(data.includes(" ")){split=data.split(" ")}else if(data.includes(",")){split=data.split(",")}else if(data.includes("|")){split=data.split("|")}data={};if(Array.isArray(split)){split.forEach((val,i)=>{if(val.includes(":")){let[key2,v]=val.split(":");let fl=parseFloat(v);if(fl)data[key2]=[fl];else return void 0}else{let fl=parseFloat(val);if(fl)data[i]=[fl];else return void 0}})}}else if(typeof data==="number"){if(key)data={[key]:[data]};else data={0:[data]}}return data}static padTime(data,lastValue,time,targetFit){let slopeIncr=(data[0]-lastValue)/time/targetFit;let padded=[...new Array(targetFit-data.length).map((_,i)=>lastValue+slopeIncr*(i+1)),...data];return padded}static interpolateForTime(data,time,targetSPS){return _ArrayManip.interpolate(data,Math.ceil(targetSPS*time))}static bufferValues=(objects,property,keys,buffer)=>{if(!Array.isArray(keys)&&typeof keys==="object")keys=Object.keys(keys);if(!buffer){let object_keys=Object.keys(objects);if(keys)buffer=new Float32Array(object_keys.length*keys.length);else{if(typeof objects[object_keys[0]][property]==="object"){keys=Object.keys(objects[object_keys[0]][property]);buffer=new Float32Array(object_keys.length*keys.length)}else buffer=new Float32Array(object_keys.length)}}let i=0;for(const key in objects){if(objects[key][property]){if(keys){for(let j=0;j{for(const key in obj){if(typeof obj[key]==="object"){if(typeof target[key]==="object")this.recursivelyAssign(target[key],obj[key]);else target[key]=this.recursivelyAssign({},obj[key])}else target[key]=obj[key]}return target};spliceTypedArray(arr,start,end){let s=arr.subarray(0,start);let e;if(end){e=arr.subarray(end+1)}let n;if(s.length>0||e?.length>0)n=new arr.constructor(s.length+e.length);if(s.length>0)n.set(s);if(e&&e.length>0)n.set(e,s.length);return n}};var rechk=/^([<>])?(([1-9]\d*)?([xcbB?hHiIfdsp]))*$/;var refmt=/([1-9]\d*)?([xcbB?hHiIfdsp])/g;var str=(v,o,c)=>String.fromCharCode(...new Uint8Array(v.buffer,v.byteOffset+o,c));var rts=(v,o,c,s)=>new Uint8Array(v.buffer,v.byteOffset+o,c).set(s.split("").map(str2=>str2.charCodeAt(0)));var pst=(v,o,c)=>str(v,o+1,Math.min(v.getUint8(o),c-1));var tsp=(v,o,c,s)=>{v.setUint8(o,s.length);rts(v,o+1,c-1,s)};var lut=le=>({x:c=>[1,c,0],c:c=>[c,1,o=>({u:v=>str(v,o,1),p:(v,c2)=>rts(v,o,1,c2)})],"?":c=>[c,1,o=>({u:v=>Boolean(v.getUint8(o)),p:(v,B)=>v.setUint8(o,B)})],b:c=>[c,1,o=>({u:v=>v.getInt8(o),p:(v,b)=>v.setInt8(o,b)})],B:c=>[c,1,o=>({u:v=>v.getUint8(o),p:(v,B)=>v.setUint8(o,B)})],h:c=>[c,2,o=>({u:v=>v.getInt16(o,le),p:(v,h)=>v.setInt16(o,h,le)})],H:c=>[c,2,o=>({u:v=>v.getUint16(o,le),p:(v,H)=>v.setUint16(o,H,le)})],i:c=>[c,4,o=>({u:v=>v.getInt32(o,le),p:(v,i)=>v.setInt32(o,i,le)})],I:c=>[c,4,o=>({u:v=>v.getUint32(o,le),p:(v,I)=>v.setUint32(o,I,le)})],f:c=>[c,4,o=>({u:v=>v.getFloat32(o,le),p:(v,f)=>v.setFloat32(o,f,le)})],d:c=>[c,8,o=>({u:v=>v.getFloat64(o,le),p:(v,d)=>v.setFloat64(o,d,le)})],s:c=>[1,c,o=>({u:v=>str(v,o,c),p:(v,s)=>rts(v,o,c,s.slice(0,c))})],p:c=>[1,c,o=>({u:v=>pst(v,o,c),p:(v,s)=>tsp(v,o,c,s.slice(0,c-1))})]});var errbuf=new RangeError("Structure larger than remaining buffer");var errval=new RangeError("Not enough values for structure");var ByteParser=class _ByteParser extends ArrayManip{static codes={"\\n":10,"\\r":13,"\\t":9,"\\s":32,"\\b":8,"\\f":12,"\\":92};static toDataView(value){if(!(value instanceof DataView)){if(typeof value==="string"&&parseInt(value))value=parseInt(value);if(typeof value==="string"){let enc=new TextEncoder;let hascodes={};for(const code in _ByteParser.codes){while(value.indexOf(code)>-1){let idx=value.indexOf(code);value=value.replace(code,"");hascodes[idx]=code}}let encoded=Array.from(enc.encode(value));for(const key in hascodes){encoded.splice(parseInt(key),0,_ByteParser.codes[hascodes[key]])}value=new DataView(new Uint8Array(encoded).buffer)}else if(typeof value==="number"){let tmp=value;if(value<256){value=new DataView(new ArrayBuffer(1));value.setUint8(0,tmp)}else if(value<65536){value=new DataView(new ArrayBuffer(2));value.setInt16(0,tmp)}else{value=new DataView(new ArrayBuffer(4));value.setUint32(0,tmp)}}else if(value instanceof ArrayBuffer||typeof SharedArrayBuffer!=="undefined"&&value instanceof SharedArrayBuffer){value=new DataView(value)}else if(Array.isArray(value)){value=new DataView(Uint8Array.from(value).buffer)}else if(typeof value==="object"){value=new TextEncoder().encode(JSON.stringify(value))}}return value}static searchBuffer(buffer,searchString,limit){var needle=searchString;var haystack=buffer;var search=_ByteParser.boyerMoore(needle);var skip=search.byteLength;var indices=[];for(var i=search(haystack);i!==-1;i=search(haystack,i+skip)){indices.push(i);if(limit){if(indices.length>=limit)break}}return indices}static bytesToInt16(x0,x1){let int16=(255&x0)<<8|255&x1;if((int16&32768)>0){int16|=4294901760}else{int16&=65535}return int16}static bytesToUInt16(x0,x1){return x0*256+x1}static Uint16ToBytes(y){return[y&255,y>>8&255]}static bytesToInt24(x0,x1,x2){let int24=(255&x0)<<16|(255&x1)<<8|255&x2;if((int24&8388608)>0){int24|=4278190080}else{int24&=16777215}return int24}static bytesToUInt24(x0,x1,x2){return x0*65536+x1*256+x2}static Uint24ToBytes(y){return[y&255,y>>8&255,y>>16&255]}static bytesToInt32(x0,x1,x2,x3){let int32=(255&x0)<<24|(255&x1)<<16|(255&x2)<<8|255&x3;if((int32&2147483648)>0){int32|=0}else{int32&=4294967295}return int32}static bytesToUInt32(x0,x1,x2,x3){return x0*16777216+x1*65536+x2*256+x3}static Uint32ToBytes(y){return[y&255,y>>8&255,y>>16&255,y>>24&255]}static get2sCompliment(val,nbits){if(val>4294967296)return null;return val<<32-nbits>>32-nbits}static getSignedInt(...args){let pos=0;function getInt(size){var value=0;var first=true;while(size--){if(first){let byte=args[pos++];value+=byte&127;if(byte&128){value-=128}first=false}else{value*=256;value+=args[pos++]}}return value}return getInt(args.length)}static asUint8Array(input){if(input instanceof Uint8Array){return input}else if(typeof input==="string"){var arr=new Uint8Array(input.length);for(var i=0;i127){throw new TypeError("Only ASCII patterns are supported")}arr[i]=c}return arr}else{return new Uint8Array(input)}}static boyerMoore(patternBuffer){var pattern=_ByteParser.asUint8Array(patternBuffer);var M=pattern.length;if(M===0){throw new TypeError("patternBuffer must be at least 1 byte long")}var R=256;var rightmost_positions=new Int32Array(R);for(var c=0;c{var txt=_ByteParser.asUint8Array(txtBuffer);if(start===void 0)start=0;if(end===void 0)end=txt.length;var pat=pattern;var right=rightmost_positions;var lastIndex=end-pat.length;var lastPatIndex=pat.length-1;var skip;for(var i=start;i<=lastIndex;i+=skip){skip=0;for(var j2=lastPatIndex;j2>=0;j2--){var c2=txt[i+j2];if(pat[j2]!==c2){skip=Math.max(1,j2-right[c2]);break}}if(skip===0){return i}}return-1};boyerMooreSearch.byteLength=pattern.byteLength;return boyerMooreSearch}static struct(format){let fns=[],size=0,m=rechk.exec(format);if(!m){throw new RangeError("Invalid format string")}const t=lut("<"===m[1]),lu=(n,c)=>t[c](n?parseInt(n,10):1);while(m=refmt.exec(format)){((r,s,f)=>{for(let i=0;i{if(arrb.byteLength<(offs|0)+size){throw errbuf}let v=new DataView(arrb,offs|0);return fns.map(f=>f.u(v))};const pack_into=(arrb,offs,...values)=>{if(values.lengthf.p(v,values[i]))};const pack=(...values)=>{let b=new ArrayBuffer(size);pack_into(b,0,...values);return b};const unpack=arrb=>unpack_from(arrb,0);function*iter_unpack(arrb){for(let offs=0;offs+size<=arrb.byteLength;offs+=size){yield unpack_from(arrb,offs)}}return Object.freeze({unpack,pack,unpack_from,pack_into,iter_unpack,format,size})}};var rms={sps:250,nSec:1,watch:["0","1","2","3"],data:{},rms:{},__operator:function(data){this.watch.forEach(key=>{if(data[key]){if(!this.data[key]){if(Array.isArray(data[key])){this.data[key]=new Array(Math.floor(this.sps*this.nSec)).fill(data[key][0])}else this.data[key]=new Array(Math.floor(this.sps*this.nSec)).fill(data[key])}ByteParser.circularBuffer(this.data[key],data[key])}});if(data.timestamp){if(Array.isArray(data.timestamp)){this.rms.timestamp=data.timestamp[data.timestamp.length-1]}else this.rms.timestamp=data.timestamp}else this.rms.timestamp=Date.now();return new Promise(async res=>{await Promise.all(this.watch.map(async key=>{if(this.data[key])this.rms[key]=Math.sqrt(Math.abs(this.data[key].reduce((p,v,i)=>p+v*v)/this.data[key].length));else delete this.rms[key]}));res(this.rms)})}};var circularBuffer2d={bufferSize:250,watch:["0","1","2","3"],data:{},blocking:false,__onconnected:function(node){for(const key in node.watch){node.data[key]=new Array(node.bufferSize).fill(0)}},__operator:function(data){let buffer2d=[];this.watch.forEach(key=>{if(data[key]){ByteParser.circularBuffer(this.data[key],data[key]);buffer2d.push(this.data[key])}});return buffer2d}};var algorithms={beat_detect,accel_gyro,heartrate:beat_detect,breath:Object.assign({},beat_detect),blink_detect,rms,circularBuffer2d};algorithms["breath"].maxFreq=.2;0&&(module.exports={StructBackend,StructFrontend,Systems,WebglLinePlotInfo,WebglLinePlotProps,WebglLinePlotUtil,WebglLineProps,algorithms,defaultSpecifiers,genTimeSpecifiers,genTimestampFromString,getStringId,pseudoObjectId,randomId,setSignalControls,toObjectId,webglPlotRoutes}); diff --git a/src/extras/dist/index.storage.services.d.ts b/src/extras/dist/index.storage.services.d.ts deleted file mode 100644 index 7a6a642f..00000000 --- a/src/extras/dist/index.storage.services.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './storage/csv'; -export * from './storage/BFSUtils'; -export * from './storage/BFS_CSV'; diff --git a/src/extras/dist/index.storage.services.esm.js b/src/extras/dist/index.storage.services.esm.js deleted file mode 100644 index 9d23db51..00000000 --- a/src/extras/dist/index.storage.services.esm.js +++ /dev/null @@ -1,16 +0,0 @@ -var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf;var __hasOwnProp=Object.prototype.hasOwnProperty;var __commonJS=(cb,mod)=>function __require(){return mod||(0,cb[__getOwnPropNames(cb)[0]])((mod={exports:{}}).exports,mod),mod.exports};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from==="object"||typeof from==="function"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:true}):target,mod));var require_browserfs=__commonJS({"node_modules/browserfs/dist/browserfs.js"(exports,module){(function webpackUniversalModuleDefinition(root,factory){if(typeof exports==="object"&&typeof module==="object")module.exports=factory();else if(typeof define==="function"&&define.amd)define([],factory);else if(typeof exports==="object")exports["BrowserFS"]=factory();else root["BrowserFS"]=factory()})(exports,function(){return function(modules){var installedModules={};function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module2=installedModules[moduleId]={exports:{},id:moduleId,loaded:false};modules[moduleId].call(module2.exports,module2,module2.exports,__webpack_require__);module2.loaded=true;return module2.exports}__webpack_require__.m=modules;__webpack_require__.c=installedModules;__webpack_require__.p="";return __webpack_require__(0)}([function(module2,exports2,__webpack_require__){(function(Buffer2,global,module3,process){"use strict";Object.defineProperty(exports2,"__esModule",{value:true});var buffer=__webpack_require__(2);var path=__webpack_require__(9);var ErrorCode;(function(ErrorCode2){ErrorCode2[ErrorCode2["EPERM"]=1]="EPERM";ErrorCode2[ErrorCode2["ENOENT"]=2]="ENOENT";ErrorCode2[ErrorCode2["EIO"]=5]="EIO";ErrorCode2[ErrorCode2["EBADF"]=9]="EBADF";ErrorCode2[ErrorCode2["EACCES"]=13]="EACCES";ErrorCode2[ErrorCode2["EBUSY"]=16]="EBUSY";ErrorCode2[ErrorCode2["EEXIST"]=17]="EEXIST";ErrorCode2[ErrorCode2["ENOTDIR"]=20]="ENOTDIR";ErrorCode2[ErrorCode2["EISDIR"]=21]="EISDIR";ErrorCode2[ErrorCode2["EINVAL"]=22]="EINVAL";ErrorCode2[ErrorCode2["EFBIG"]=27]="EFBIG";ErrorCode2[ErrorCode2["ENOSPC"]=28]="ENOSPC";ErrorCode2[ErrorCode2["EROFS"]=30]="EROFS";ErrorCode2[ErrorCode2["ENOTEMPTY"]=39]="ENOTEMPTY";ErrorCode2[ErrorCode2["ENOTSUP"]=95]="ENOTSUP"})(ErrorCode||(ErrorCode={}));var ErrorStrings={};ErrorStrings[ErrorCode.EPERM]="Operation not permitted.";ErrorStrings[ErrorCode.ENOENT]="No such file or directory.";ErrorStrings[ErrorCode.EIO]="Input/output error.";ErrorStrings[ErrorCode.EBADF]="Bad file descriptor.";ErrorStrings[ErrorCode.EACCES]="Permission denied.";ErrorStrings[ErrorCode.EBUSY]="Resource busy or locked.";ErrorStrings[ErrorCode.EEXIST]="File exists.";ErrorStrings[ErrorCode.ENOTDIR]="File is not a directory.";ErrorStrings[ErrorCode.EISDIR]="File is a directory.";ErrorStrings[ErrorCode.EINVAL]="Invalid argument.";ErrorStrings[ErrorCode.EFBIG]="File is too big.";ErrorStrings[ErrorCode.ENOSPC]="No space left on disk.";ErrorStrings[ErrorCode.EROFS]="Cannot modify a read-only file system.";ErrorStrings[ErrorCode.ENOTEMPTY]="Directory is not empty.";ErrorStrings[ErrorCode.ENOTSUP]="Operation is not supported.";var ApiError=function(Error2){function ApiError2(type,message,path$$1){if(message===void 0)message=ErrorStrings[type];Error2.call(this,message);this.syscall="";this.errno=type;this.code=ErrorCode[type];this.path=path$$1;this.stack=new Error2().stack;this.message="Error: "+this.code+": "+message+(this.path?", '"+this.path+"'":"")}if(Error2)ApiError2.__proto__=Error2;ApiError2.prototype=Object.create(Error2&&Error2.prototype);ApiError2.prototype.constructor=ApiError2;ApiError2.fromJSON=function fromJSON(json){var err=new ApiError2(0);err.errno=json.errno;err.code=json.code;err.path=json.path;err.stack=json.stack;err.message=json.message;return err};ApiError2.fromBuffer=function fromBuffer(buffer$$1,i2){if(i2===void 0)i2=0;return ApiError2.fromJSON(JSON.parse(buffer$$1.toString("utf8",i2+4,i2+4+buffer$$1.readUInt32LE(i2))))};ApiError2.FileError=function FileError(code,p){return new ApiError2(code,ErrorStrings[code],p)};ApiError2.ENOENT=function ENOENT(path$$1){return this.FileError(ErrorCode.ENOENT,path$$1)};ApiError2.EEXIST=function EEXIST(path$$1){return this.FileError(ErrorCode.EEXIST,path$$1)};ApiError2.EISDIR=function EISDIR(path$$1){return this.FileError(ErrorCode.EISDIR,path$$1)};ApiError2.ENOTDIR=function ENOTDIR(path$$1){return this.FileError(ErrorCode.ENOTDIR,path$$1)};ApiError2.EPERM=function EPERM(path$$1){return this.FileError(ErrorCode.EPERM,path$$1)};ApiError2.ENOTEMPTY=function ENOTEMPTY(path$$1){return this.FileError(ErrorCode.ENOTEMPTY,path$$1)};ApiError2.prototype.toString=function toString(){return this.message};ApiError2.prototype.toJSON=function toJSON(){return{errno:this.errno,code:this.code,path:this.path,stack:this.stack,message:this.message}};ApiError2.prototype.writeToBuffer=function writeToBuffer(buffer$$1,i2){if(buffer$$1===void 0)buffer$$1=Buffer2.alloc(this.bufferSize());if(i2===void 0)i2=0;var bytesWritten=buffer$$1.write(JSON.stringify(this.toJSON()),i2+4);buffer$$1.writeUInt32LE(bytesWritten,i2);return buffer$$1};ApiError2.prototype.bufferSize=function bufferSize(){return 4+Buffer2.byteLength(JSON.stringify(this.toJSON()))};return ApiError2}(Error);var api_error=Object.freeze({get ErrorCode(){return ErrorCode},ErrorStrings,ApiError});var ActionType;(function(ActionType2){ActionType2[ActionType2["NOP"]=0]="NOP";ActionType2[ActionType2["THROW_EXCEPTION"]=1]="THROW_EXCEPTION";ActionType2[ActionType2["TRUNCATE_FILE"]=2]="TRUNCATE_FILE";ActionType2[ActionType2["CREATE_FILE"]=3]="CREATE_FILE"})(ActionType||(ActionType={}));var FileFlag=function FileFlag2(flagStr){this.flagStr=flagStr;if(FileFlag2.validFlagStrs.indexOf(flagStr)<0){throw new ApiError(ErrorCode.EINVAL,"Invalid flag: "+flagStr)}};FileFlag.getFileFlag=function getFileFlag(flagStr){if(FileFlag.flagCache.hasOwnProperty(flagStr)){return FileFlag.flagCache[flagStr]}return FileFlag.flagCache[flagStr]=new FileFlag(flagStr)};FileFlag.prototype.getFlagString=function getFlagString(){return this.flagStr};FileFlag.prototype.isReadable=function isReadable(){return this.flagStr.indexOf("r")!==-1||this.flagStr.indexOf("+")!==-1};FileFlag.prototype.isWriteable=function isWriteable(){return this.flagStr.indexOf("w")!==-1||this.flagStr.indexOf("a")!==-1||this.flagStr.indexOf("+")!==-1};FileFlag.prototype.isTruncating=function isTruncating(){return this.flagStr.indexOf("w")!==-1};FileFlag.prototype.isAppendable=function isAppendable(){return this.flagStr.indexOf("a")!==-1};FileFlag.prototype.isSynchronous=function isSynchronous(){return this.flagStr.indexOf("s")!==-1};FileFlag.prototype.isExclusive=function isExclusive(){return this.flagStr.indexOf("x")!==-1};FileFlag.prototype.pathExistsAction=function pathExistsAction(){if(this.isExclusive()){return ActionType.THROW_EXCEPTION}else if(this.isTruncating()){return ActionType.TRUNCATE_FILE}else{return ActionType.NOP}};FileFlag.prototype.pathNotExistsAction=function pathNotExistsAction(){if((this.isWriteable()||this.isAppendable())&&this.flagStr!=="r+"){return ActionType.CREATE_FILE}else{return ActionType.THROW_EXCEPTION}};FileFlag.flagCache={};FileFlag.validFlagStrs=["r","r+","rs","rs+","w","wx","w+","wx+","a","ax","a+","ax+"];var FileType;(function(FileType2){FileType2[FileType2["FILE"]=32768]="FILE";FileType2[FileType2["DIRECTORY"]=16384]="DIRECTORY";FileType2[FileType2["SYMLINK"]=40960]="SYMLINK"})(FileType||(FileType={}));var Stats=function Stats2(itemType,size,mode,atime,mtime,ctime){if(atime===void 0)atime=new Date;if(mtime===void 0)mtime=new Date;if(ctime===void 0)ctime=new Date;this.size=size;this.atime=atime;this.mtime=mtime;this.ctime=ctime;this.dev=0;this.ino=0;this.rdev=0;this.nlink=1;this.blksize=4096;this.uid=0;this.gid=0;this.birthtime=new Date(0);this.fileData=null;if(!mode){switch(itemType){case FileType.FILE:this.mode=420;break;case FileType.DIRECTORY:default:this.mode=511}}else{this.mode=mode}this.blocks=Math.ceil(size/512);if(this.mode<4096){this.mode|=itemType}};Stats.fromBuffer=function fromBuffer(buffer$$1){var size=buffer$$1.readUInt32LE(0),mode=buffer$$1.readUInt32LE(4),atime=buffer$$1.readDoubleLE(8),mtime=buffer$$1.readDoubleLE(16),ctime=buffer$$1.readDoubleLE(24);return new Stats(mode&61440,size,mode&4095,new Date(atime),new Date(mtime),new Date(ctime))};Stats.prototype.toBuffer=function toBuffer(){var buffer$$1=Buffer2.alloc(32);buffer$$1.writeUInt32LE(this.size,0);buffer$$1.writeUInt32LE(this.mode,4);buffer$$1.writeDoubleLE(this.atime.getTime(),8);buffer$$1.writeDoubleLE(this.mtime.getTime(),16);buffer$$1.writeDoubleLE(this.ctime.getTime(),24);return buffer$$1};Stats.prototype.clone=function clone(){return new Stats(this.mode&61440,this.size,this.mode&4095,this.atime,this.mtime,this.ctime)};Stats.prototype.isFile=function isFile(){return(this.mode&61440)===FileType.FILE};Stats.prototype.isDirectory=function isDirectory(){return(this.mode&61440)===FileType.DIRECTORY};Stats.prototype.isSymbolicLink=function isSymbolicLink(){return(this.mode&61440)===FileType.SYMLINK};Stats.prototype.chmod=function chmod(mode){this.mode=this.mode&61440|mode};Stats.prototype.isSocket=function isSocket(){return false};Stats.prototype.isBlockDevice=function isBlockDevice(){return false};Stats.prototype.isCharacterDevice=function isCharacterDevice(){return false};Stats.prototype.isFIFO=function isFIFO(){return false};var wrapCb=function(cb,numArgs){return cb};function assertRoot(fs4){if(fs4){return fs4}throw new ApiError(ErrorCode.EIO,"Initialize BrowserFS with a file system using BrowserFS.initialize(filesystem)")}function normalizeMode(mode,def){switch(typeof mode){case"number":return mode;case"string":var trueMode=parseInt(mode,8);if(!isNaN(trueMode)){return trueMode}return def;default:return def}}function normalizeTime(time){if(time instanceof Date){return time}else if(typeof time==="number"){return new Date(time*1e3)}else{throw new ApiError(ErrorCode.EINVAL,"Invalid time.")}}function normalizePath(p){if(p.indexOf("\0")>=0){throw new ApiError(ErrorCode.EINVAL,"Path must be a string without null bytes.")}else if(p===""){throw new ApiError(ErrorCode.EINVAL,"Path must not be empty.")}return path.resolve(p)}function normalizeOptions(options,defEnc,defFlag,defMode){switch(typeof options){case"object":return{encoding:typeof options["encoding"]!=="undefined"?options["encoding"]:defEnc,flag:typeof options["flag"]!=="undefined"?options["flag"]:defFlag,mode:normalizeMode(options["mode"],defMode)};case"string":return{encoding:options,flag:defFlag,mode:defMode};default:return{encoding:defEnc,flag:defFlag,mode:defMode}}}function nopCb(){}var FS=function FS2(){this.F_OK=0;this.R_OK=4;this.W_OK=2;this.X_OK=1;this.root=null;this.fdMap={};this.nextFd=100};FS.prototype.initialize=function initialize3(rootFS){if(!rootFS.constructor.isAvailable()){throw new ApiError(ErrorCode.EINVAL,"Tried to instantiate BrowserFS with an unavailable file system.")}return this.root=rootFS};FS.prototype._toUnixTimestamp=function _toUnixTimestamp(time){if(typeof time==="number"){return time}else if(time instanceof Date){return time.getTime()/1e3}throw new Error("Cannot parse time: "+time)};FS.prototype.getRootFS=function getRootFS(){if(this.root){return this.root}else{return null}};FS.prototype.rename=function rename(oldPath,newPath,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{assertRoot(this.root).rename(normalizePath(oldPath),normalizePath(newPath),newCb)}catch(e){newCb(e)}};FS.prototype.renameSync=function renameSync(oldPath,newPath){assertRoot(this.root).renameSync(normalizePath(oldPath),normalizePath(newPath))};FS.prototype.exists=function exists2(path$$1,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{return assertRoot(this.root).exists(normalizePath(path$$1),newCb)}catch(e){return newCb(false)}};FS.prototype.existsSync=function existsSync(path$$1){try{return assertRoot(this.root).existsSync(normalizePath(path$$1))}catch(e){return false}};FS.prototype.stat=function stat(path$$1,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,2);try{return assertRoot(this.root).stat(normalizePath(path$$1),false,newCb)}catch(e){return newCb(e)}};FS.prototype.statSync=function statSync(path$$1){return assertRoot(this.root).statSync(normalizePath(path$$1),false)};FS.prototype.lstat=function lstat(path$$1,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,2);try{return assertRoot(this.root).stat(normalizePath(path$$1),true,newCb)}catch(e){return newCb(e)}};FS.prototype.lstatSync=function lstatSync(path$$1){return assertRoot(this.root).statSync(normalizePath(path$$1),true)};FS.prototype.truncate=function truncate(path$$1,arg2,cb){if(arg2===void 0)arg2=0;if(cb===void 0)cb=nopCb;var len=0;if(typeof arg2==="function"){cb=arg2}else if(typeof arg2==="number"){len=arg2}var newCb=wrapCb(cb,1);try{if(len<0){throw new ApiError(ErrorCode.EINVAL)}return assertRoot(this.root).truncate(normalizePath(path$$1),len,newCb)}catch(e){return newCb(e)}};FS.prototype.truncateSync=function truncateSync(path$$1,len){if(len===void 0)len=0;if(len<0){throw new ApiError(ErrorCode.EINVAL)}return assertRoot(this.root).truncateSync(normalizePath(path$$1),len)};FS.prototype.unlink=function unlink(path$$1,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{return assertRoot(this.root).unlink(normalizePath(path$$1),newCb)}catch(e){return newCb(e)}};FS.prototype.unlinkSync=function unlinkSync(path$$1){return assertRoot(this.root).unlinkSync(normalizePath(path$$1))};FS.prototype.open=function open(path$$1,flag,arg2,cb){var this$1=this;if(cb===void 0)cb=nopCb;var mode=normalizeMode(arg2,420);cb=typeof arg2==="function"?arg2:cb;var newCb=wrapCb(cb,2);try{assertRoot(this.root).open(normalizePath(path$$1),FileFlag.getFileFlag(flag),mode,function(e,file){if(file){newCb(e,this$1.getFdForFile(file))}else{newCb(e)}})}catch(e){newCb(e)}};FS.prototype.openSync=function openSync(path$$1,flag,mode){if(mode===void 0)mode=420;return this.getFdForFile(assertRoot(this.root).openSync(normalizePath(path$$1),FileFlag.getFileFlag(flag),normalizeMode(mode,420)))};FS.prototype.readFile=function readFile2(filename,arg2,cb){if(arg2===void 0)arg2={};if(cb===void 0)cb=nopCb;var options=normalizeOptions(arg2,null,"r",null);cb=typeof arg2==="function"?arg2:cb;var newCb=wrapCb(cb,2);try{var flag=FileFlag.getFileFlag(options["flag"]);if(!flag.isReadable()){return newCb(new ApiError(ErrorCode.EINVAL,"Flag passed to readFile must allow for reading."))}return assertRoot(this.root).readFile(normalizePath(filename),options.encoding,flag,newCb)}catch(e){return newCb(e)}};FS.prototype.readFileSync=function readFileSync(filename,arg2){if(arg2===void 0)arg2={};var options=normalizeOptions(arg2,null,"r",null);var flag=FileFlag.getFileFlag(options.flag);if(!flag.isReadable()){throw new ApiError(ErrorCode.EINVAL,"Flag passed to readFile must allow for reading.")}return assertRoot(this.root).readFileSync(normalizePath(filename),options.encoding,flag)};FS.prototype.writeFile=function writeFile2(filename,data,arg3,cb){if(arg3===void 0)arg3={};if(cb===void 0)cb=nopCb;var options=normalizeOptions(arg3,"utf8","w",420);cb=typeof arg3==="function"?arg3:cb;var newCb=wrapCb(cb,1);try{var flag=FileFlag.getFileFlag(options.flag);if(!flag.isWriteable()){return newCb(new ApiError(ErrorCode.EINVAL,"Flag passed to writeFile must allow for writing."))}return assertRoot(this.root).writeFile(normalizePath(filename),data,options.encoding,flag,options.mode,newCb)}catch(e){return newCb(e)}};FS.prototype.writeFileSync=function writeFileSync(filename,data,arg3){var options=normalizeOptions(arg3,"utf8","w",420);var flag=FileFlag.getFileFlag(options.flag);if(!flag.isWriteable()){throw new ApiError(ErrorCode.EINVAL,"Flag passed to writeFile must allow for writing.")}return assertRoot(this.root).writeFileSync(normalizePath(filename),data,options.encoding,flag,options.mode)};FS.prototype.appendFile=function appendFile3(filename,data,arg3,cb){if(cb===void 0)cb=nopCb;var options=normalizeOptions(arg3,"utf8","a",420);cb=typeof arg3==="function"?arg3:cb;var newCb=wrapCb(cb,1);try{var flag=FileFlag.getFileFlag(options.flag);if(!flag.isAppendable()){return newCb(new ApiError(ErrorCode.EINVAL,"Flag passed to appendFile must allow for appending."))}assertRoot(this.root).appendFile(normalizePath(filename),data,options.encoding,flag,options.mode,newCb)}catch(e){newCb(e)}};FS.prototype.appendFileSync=function appendFileSync(filename,data,arg3){var options=normalizeOptions(arg3,"utf8","a",420);var flag=FileFlag.getFileFlag(options.flag);if(!flag.isAppendable()){throw new ApiError(ErrorCode.EINVAL,"Flag passed to appendFile must allow for appending.")}return assertRoot(this.root).appendFileSync(normalizePath(filename),data,options.encoding,flag,options.mode)};FS.prototype.fstat=function fstat(fd,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,2);try{var file=this.fd2file(fd);file.stat(newCb)}catch(e){newCb(e)}};FS.prototype.fstatSync=function fstatSync(fd){return this.fd2file(fd).statSync()};FS.prototype.close=function close(fd,cb){var this$1=this;if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{this.fd2file(fd).close(function(e){if(!e){this$1.closeFd(fd)}newCb(e)})}catch(e){newCb(e)}};FS.prototype.closeSync=function closeSync(fd){this.fd2file(fd).closeSync();this.closeFd(fd)};FS.prototype.ftruncate=function ftruncate(fd,arg2,cb){if(cb===void 0)cb=nopCb;var length=typeof arg2==="number"?arg2:0;cb=typeof arg2==="function"?arg2:cb;var newCb=wrapCb(cb,1);try{var file=this.fd2file(fd);if(length<0){throw new ApiError(ErrorCode.EINVAL)}file.truncate(length,newCb)}catch(e){newCb(e)}};FS.prototype.ftruncateSync=function ftruncateSync(fd,len){if(len===void 0)len=0;var file=this.fd2file(fd);if(len<0){throw new ApiError(ErrorCode.EINVAL)}file.truncateSync(len)};FS.prototype.fsync=function fsync(fd,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{this.fd2file(fd).sync(newCb)}catch(e){newCb(e)}};FS.prototype.fsyncSync=function fsyncSync(fd){this.fd2file(fd).syncSync()};FS.prototype.fdatasync=function fdatasync(fd,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{this.fd2file(fd).datasync(newCb)}catch(e){newCb(e)}};FS.prototype.fdatasyncSync=function fdatasyncSync(fd){this.fd2file(fd).datasyncSync()};FS.prototype.write=function write(fd,arg2,arg3,arg4,arg5,cb){if(cb===void 0)cb=nopCb;var buffer$$1,offset,length,position=null;if(typeof arg2==="string"){var encoding="utf8";switch(typeof arg3){case"function":cb=arg3;break;case"number":position=arg3;encoding=typeof arg4==="string"?arg4:"utf8";cb=typeof arg5==="function"?arg5:cb;break;default:cb=typeof arg4==="function"?arg4:typeof arg5==="function"?arg5:cb;return cb(new ApiError(ErrorCode.EINVAL,"Invalid arguments."))}buffer$$1=Buffer2.from(arg2,encoding);offset=0;length=buffer$$1.length}else{buffer$$1=arg2;offset=arg3;length=arg4;position=typeof arg5==="number"?arg5:null;cb=typeof arg5==="function"?arg5:cb}var newCb=wrapCb(cb,3);try{var file=this.fd2file(fd);if(position===void 0||position===null){position=file.getPos()}file.write(buffer$$1,offset,length,position,newCb)}catch(e){newCb(e)}};FS.prototype.writeSync=function writeSync(fd,arg2,arg3,arg4,arg5){var buffer$$1,offset=0,length,position;if(typeof arg2==="string"){position=typeof arg3==="number"?arg3:null;var encoding=typeof arg4==="string"?arg4:"utf8";offset=0;buffer$$1=Buffer2.from(arg2,encoding);length=buffer$$1.length}else{buffer$$1=arg2;offset=arg3;length=arg4;position=typeof arg5==="number"?arg5:null}var file=this.fd2file(fd);if(position===void 0||position===null){position=file.getPos()}return file.writeSync(buffer$$1,offset,length,position)};FS.prototype.read=function read(fd,arg2,arg3,arg4,arg5,cb){if(cb===void 0)cb=nopCb;var position,offset,length,buffer$$1,newCb;if(typeof arg2==="number"){length=arg2;position=arg3;var encoding=arg4;cb=typeof arg5==="function"?arg5:cb;offset=0;buffer$$1=Buffer2.alloc(length);newCb=wrapCb(function(err,bytesRead,buf){if(err){return cb(err)}cb(err,buf.toString(encoding),bytesRead)},3)}else{buffer$$1=arg2;offset=arg3;length=arg4;position=arg5;newCb=wrapCb(cb,3)}try{var file=this.fd2file(fd);if(position===void 0||position===null){position=file.getPos()}file.read(buffer$$1,offset,length,position,newCb)}catch(e){newCb(e)}};FS.prototype.readSync=function readSync(fd,arg2,arg3,arg4,arg5){var shenanigans=false;var buffer$$1,offset,length,position,encoding="utf8";if(typeof arg2==="number"){length=arg2;position=arg3;encoding=arg4;offset=0;buffer$$1=Buffer2.alloc(length);shenanigans=true}else{buffer$$1=arg2;offset=arg3;length=arg4;position=arg5}var file=this.fd2file(fd);if(position===void 0||position===null){position=file.getPos()}var rv=file.readSync(buffer$$1,offset,length,position);if(!shenanigans){return rv}else{return[buffer$$1.toString(encoding),rv]}};FS.prototype.fchown=function fchown(fd,uid,gid,callback){if(callback===void 0)callback=nopCb;var newCb=wrapCb(callback,1);try{this.fd2file(fd).chown(uid,gid,newCb)}catch(e){newCb(e)}};FS.prototype.fchownSync=function fchownSync(fd,uid,gid){this.fd2file(fd).chownSync(uid,gid)};FS.prototype.fchmod=function fchmod(fd,mode,cb){var newCb=wrapCb(cb,1);try{var numMode=typeof mode==="string"?parseInt(mode,8):mode;this.fd2file(fd).chmod(numMode,newCb)}catch(e){newCb(e)}};FS.prototype.fchmodSync=function fchmodSync(fd,mode){var numMode=typeof mode==="string"?parseInt(mode,8):mode;this.fd2file(fd).chmodSync(numMode)};FS.prototype.futimes=function futimes(fd,atime,mtime,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{var file=this.fd2file(fd);if(typeof atime==="number"){atime=new Date(atime*1e3)}if(typeof mtime==="number"){mtime=new Date(mtime*1e3)}file.utimes(atime,mtime,newCb)}catch(e){newCb(e)}};FS.prototype.futimesSync=function futimesSync(fd,atime,mtime){this.fd2file(fd).utimesSync(normalizeTime(atime),normalizeTime(mtime))};FS.prototype.rmdir=function rmdir(path$$1,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{path$$1=normalizePath(path$$1);assertRoot(this.root).rmdir(path$$1,newCb)}catch(e){newCb(e)}};FS.prototype.rmdirSync=function rmdirSync(path$$1){path$$1=normalizePath(path$$1);return assertRoot(this.root).rmdirSync(path$$1)};FS.prototype.mkdir=function mkdir(path$$1,mode,cb){if(cb===void 0)cb=nopCb;if(typeof mode==="function"){cb=mode;mode=511}var newCb=wrapCb(cb,1);try{path$$1=normalizePath(path$$1);assertRoot(this.root).mkdir(path$$1,mode,newCb)}catch(e){newCb(e)}};FS.prototype.mkdirSync=function mkdirSync(path$$1,mode){assertRoot(this.root).mkdirSync(normalizePath(path$$1),normalizeMode(mode,511))};FS.prototype.readdir=function readdir(path$$1,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,2);try{path$$1=normalizePath(path$$1);assertRoot(this.root).readdir(path$$1,newCb)}catch(e){newCb(e)}};FS.prototype.readdirSync=function readdirSync(path$$1){path$$1=normalizePath(path$$1);return assertRoot(this.root).readdirSync(path$$1)};FS.prototype.link=function link(srcpath,dstpath,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{srcpath=normalizePath(srcpath);dstpath=normalizePath(dstpath);assertRoot(this.root).link(srcpath,dstpath,newCb)}catch(e){newCb(e)}};FS.prototype.linkSync=function linkSync(srcpath,dstpath){srcpath=normalizePath(srcpath);dstpath=normalizePath(dstpath);return assertRoot(this.root).linkSync(srcpath,dstpath)};FS.prototype.symlink=function symlink(srcpath,dstpath,arg3,cb){if(cb===void 0)cb=nopCb;var type=typeof arg3==="string"?arg3:"file";cb=typeof arg3==="function"?arg3:cb;var newCb=wrapCb(cb,1);try{if(type!=="file"&&type!=="dir"){return newCb(new ApiError(ErrorCode.EINVAL,"Invalid type: "+type))}srcpath=normalizePath(srcpath);dstpath=normalizePath(dstpath);assertRoot(this.root).symlink(srcpath,dstpath,type,newCb)}catch(e){newCb(e)}};FS.prototype.symlinkSync=function symlinkSync(srcpath,dstpath,type){if(!type){type="file"}else if(type!=="file"&&type!=="dir"){throw new ApiError(ErrorCode.EINVAL,"Invalid type: "+type)}srcpath=normalizePath(srcpath);dstpath=normalizePath(dstpath);return assertRoot(this.root).symlinkSync(srcpath,dstpath,type)};FS.prototype.readlink=function readlink(path$$1,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,2);try{path$$1=normalizePath(path$$1);assertRoot(this.root).readlink(path$$1,newCb)}catch(e){newCb(e)}};FS.prototype.readlinkSync=function readlinkSync(path$$1){path$$1=normalizePath(path$$1);return assertRoot(this.root).readlinkSync(path$$1)};FS.prototype.chown=function chown(path$$1,uid,gid,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{path$$1=normalizePath(path$$1);assertRoot(this.root).chown(path$$1,false,uid,gid,newCb)}catch(e){newCb(e)}};FS.prototype.chownSync=function chownSync(path$$1,uid,gid){path$$1=normalizePath(path$$1);assertRoot(this.root).chownSync(path$$1,false,uid,gid)};FS.prototype.lchown=function lchown(path$$1,uid,gid,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{path$$1=normalizePath(path$$1);assertRoot(this.root).chown(path$$1,true,uid,gid,newCb)}catch(e){newCb(e)}};FS.prototype.lchownSync=function lchownSync(path$$1,uid,gid){path$$1=normalizePath(path$$1);assertRoot(this.root).chownSync(path$$1,true,uid,gid)};FS.prototype.chmod=function chmod(path$$1,mode,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{var numMode=normalizeMode(mode,-1);if(numMode<0){throw new ApiError(ErrorCode.EINVAL,"Invalid mode.")}assertRoot(this.root).chmod(normalizePath(path$$1),false,numMode,newCb)}catch(e){newCb(e)}};FS.prototype.chmodSync=function chmodSync(path$$1,mode){var numMode=normalizeMode(mode,-1);if(numMode<0){throw new ApiError(ErrorCode.EINVAL,"Invalid mode.")}path$$1=normalizePath(path$$1);assertRoot(this.root).chmodSync(path$$1,false,numMode)};FS.prototype.lchmod=function lchmod(path$$1,mode,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{var numMode=normalizeMode(mode,-1);if(numMode<0){throw new ApiError(ErrorCode.EINVAL,"Invalid mode.")}assertRoot(this.root).chmod(normalizePath(path$$1),true,numMode,newCb)}catch(e){newCb(e)}};FS.prototype.lchmodSync=function lchmodSync(path$$1,mode){var numMode=normalizeMode(mode,-1);if(numMode<1){throw new ApiError(ErrorCode.EINVAL,"Invalid mode.")}assertRoot(this.root).chmodSync(normalizePath(path$$1),true,numMode)};FS.prototype.utimes=function utimes(path$$1,atime,mtime,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{assertRoot(this.root).utimes(normalizePath(path$$1),normalizeTime(atime),normalizeTime(mtime),newCb)}catch(e){newCb(e)}};FS.prototype.utimesSync=function utimesSync(path$$1,atime,mtime){assertRoot(this.root).utimesSync(normalizePath(path$$1),normalizeTime(atime),normalizeTime(mtime))};FS.prototype.realpath=function realpath(path$$1,arg2,cb){if(cb===void 0)cb=nopCb;var cache=typeof arg2==="object"?arg2:{};cb=typeof arg2==="function"?arg2:nopCb;var newCb=wrapCb(cb,2);try{path$$1=normalizePath(path$$1);assertRoot(this.root).realpath(path$$1,cache,newCb)}catch(e){newCb(e)}};FS.prototype.realpathSync=function realpathSync(path$$1,cache){if(cache===void 0)cache={};path$$1=normalizePath(path$$1);return assertRoot(this.root).realpathSync(path$$1,cache)};FS.prototype.watchFile=function watchFile(filename,arg2,listener){if(listener===void 0)listener=nopCb;throw new ApiError(ErrorCode.ENOTSUP)};FS.prototype.unwatchFile=function unwatchFile(filename,listener){if(listener===void 0)listener=nopCb;throw new ApiError(ErrorCode.ENOTSUP)};FS.prototype.watch=function watch(filename,arg2,listener){if(listener===void 0)listener=nopCb;throw new ApiError(ErrorCode.ENOTSUP)};FS.prototype.access=function access(path$$1,arg2,cb){if(cb===void 0)cb=nopCb;throw new ApiError(ErrorCode.ENOTSUP)};FS.prototype.accessSync=function accessSync(path$$1,mode){throw new ApiError(ErrorCode.ENOTSUP)};FS.prototype.createReadStream=function createReadStream(path$$1,options){throw new ApiError(ErrorCode.ENOTSUP)};FS.prototype.createWriteStream=function createWriteStream(path$$1,options){throw new ApiError(ErrorCode.ENOTSUP)};FS.prototype.wrapCallbacks=function wrapCallbacks(cbWrapper){wrapCb=cbWrapper};FS.prototype.getFdForFile=function getFdForFile(file){var fd=this.nextFd++;this.fdMap[fd]=file;return fd};FS.prototype.fd2file=function fd2file(fd){var rv=this.fdMap[fd];if(rv){return rv}else{throw new ApiError(ErrorCode.EBADF,"Invalid file descriptor.")}};FS.prototype.closeFd=function closeFd(fd){delete this.fdMap[fd]};FS.Stats=Stats;var fs3=new FS;var _fsMock={};var fsProto=FS.prototype;Object.keys(fsProto).forEach(function(key){if(typeof fs3[key]==="function"){_fsMock[key]=function(){return fs3[key].apply(fs3,arguments)}}else{_fsMock[key]=fs3[key]}});_fsMock["changeFSModule"]=function(newFs){fs3=newFs};_fsMock["getFSModule"]=function(){return fs3};_fsMock["FS"]=FS;function _min(d0,d1,d2,bx,ay){return d0d2?d2+1:d0+1:bx===ay?d1:d1+1}function levenshtein(a,b){if(a===b){return 0}if(a.length>b.length){var tmp=a;a=b;b=tmp}var la=a.length;var lb=b.length;while(la>0&&a.charCodeAt(la-1)===b.charCodeAt(lb-1)){la--;lb--}var offset=0;while(offsetdd?dd+1:dy$1+1:bx0$1===vector[la+y$2]?d0:d0+1;d0=dy$1}}return dd}function deprecationMessage(print,fsName,opts){if(print){console.warn("["+fsName+"] Direct file system constructor usage is deprecated for this file system, and will be removed in the next major version. Please use the '"+fsName+".Create("+JSON.stringify(opts)+", callback)' method instead. See https://github.com/jvilk/BrowserFS/issues/176 for more details.")}}var isIE=typeof navigator!=="undefined"&&!!(/(msie) ([\w.]+)/.exec(navigator.userAgent.toLowerCase())||navigator.userAgent.indexOf("Trident")!==-1);var isWebWorker=typeof window==="undefined";function fail(){throw new Error("BFS has reached an impossible code path; please file a bug.")}function mkdirpSync(p,mode,fs4){if(!fs4.existsSync(p)){mkdirpSync(path.dirname(p),mode,fs4);fs4.mkdirSync(p,mode)}}function buffer2ArrayBuffer(buff){var u8=buffer2Uint8array(buff),u8offset=u8.byteOffset,u8Len=u8.byteLength;if(u8offset===0&&u8Len===u8.buffer.byteLength){return u8.buffer}else{return u8.buffer.slice(u8offset,u8offset+u8Len)}}function buffer2Uint8array(buff){if(buff instanceof Uint8Array){return buff}else{return new Uint8Array(buff)}}function arrayish2Buffer(arr){if(arr instanceof Buffer2){return arr}else if(arr instanceof Uint8Array){return uint8Array2Buffer(arr)}else{return Buffer2.from(arr)}}function uint8Array2Buffer(u8){if(u8 instanceof Buffer2){return u8}else if(u8.byteOffset===0&&u8.byteLength===u8.buffer.byteLength){return arrayBuffer2Buffer(u8.buffer)}else{return Buffer2.from(u8.buffer,u8.byteOffset,u8.byteLength)}}function arrayBuffer2Buffer(ab){return Buffer2.from(ab)}function copyingSlice(buff,start,end){if(start===void 0)start=0;if(end===void 0)end=buff.length;if(start<0||end<0||end>buff.length||start>end){throw new TypeError("Invalid slice bounds on buffer of length "+buff.length+": ["+start+", "+end+"]")}if(buff.length===0){return emptyBuffer()}else{var u8=buffer2Uint8array(buff),s0=buff[0],newS0=(s0+1)%255;buff[0]=newS0;if(u8[0]===newS0){u8[0]=s0;return uint8Array2Buffer(u8.slice(start,end))}else{buff[0]=s0;return uint8Array2Buffer(u8.subarray(start,end))}}}var emptyBuff=null;function emptyBuffer(){if(emptyBuff){return emptyBuff}return emptyBuff=Buffer2.alloc(0)}function bufferValidator(v,cb){if(Buffer2.isBuffer(v)){cb()}else{cb(new ApiError(ErrorCode.EINVAL,"option must be a Buffer."))}}function checkOptions(fsType,opts,cb){var optsInfo=fsType.Options;var fsName=fsType.Name;var pendingValidators=0;var callbackCalled=false;var loopEnded=false;function validatorCallback(e){if(!callbackCalled){if(e){callbackCalled=true;cb(e)}pendingValidators--;if(pendingValidators===0&&loopEnded){cb()}}}var loop=function(optName2){if(optsInfo.hasOwnProperty(optName2)){var opt=optsInfo[optName2];var providedValue=opts[optName2];if(providedValue===void 0||providedValue===null){if(!opt.optional){var incorrectOptions=Object.keys(opts).filter(function(o){return!(o in optsInfo)}).map(function(a){return{str:a,distance:levenshtein(optName2,a)}}).filter(function(o){return o.distance<5}).sort(function(a,b){return a.distance-b.distance});if(callbackCalled){return{}}callbackCalled=true;return{v:cb(new ApiError(ErrorCode.EINVAL,"["+fsName+"] Required option '"+optName2+"' not provided."+(incorrectOptions.length>0?" You provided unrecognized option '"+incorrectOptions[0].str+"'; perhaps you meant to type '"+optName2+"'.":"")+"\nOption description: "+opt.description))}}}else{var typeMatches=false;if(Array.isArray(opt.type)){typeMatches=opt.type.indexOf(typeof providedValue)!==-1}else{typeMatches=typeof providedValue===opt.type}if(!typeMatches){if(callbackCalled){return{}}callbackCalled=true;return{v:cb(new ApiError(ErrorCode.EINVAL,"["+fsName+"] Value provided for option "+optName2+" is not the proper type. Expected "+(Array.isArray(opt.type)?"one of {"+opt.type.join(", ")+"}":opt.type)+", but received "+typeof providedValue+"\nOption description: "+opt.description))}}else if(opt.validator){pendingValidators++;opt.validator(providedValue,validatorCallback)}}}};for(var optName in optsInfo){var returned=loop(optName);if(returned)return returned.v}loopEnded=true;if(pendingValidators===0&&!callbackCalled){cb()}}var BFSUtils=Object.freeze({deprecationMessage,isIE,isWebWorker,fail,mkdirpSync,buffer2ArrayBuffer,buffer2Uint8array,arrayish2Buffer,uint8Array2Buffer,arrayBuffer2Buffer,copyingSlice,emptyBuffer,bufferValidator,checkOptions});var BFSEmscriptenStreamOps=function BFSEmscriptenStreamOps2(fs4){this.fs=fs4;this.nodefs=fs4.getNodeFS();this.FS=fs4.getFS();this.PATH=fs4.getPATH();this.ERRNO_CODES=fs4.getERRNO_CODES()};BFSEmscriptenStreamOps.prototype.open=function open(stream){var path$$1=this.fs.realPath(stream.node);var FS2=this.FS;try{if(FS2.isFile(stream.node.mode)){stream.nfd=this.nodefs.openSync(path$$1,this.fs.flagsToPermissionString(stream.flags))}}catch(e){if(!e.code){throw e}throw new FS2.ErrnoError(this.ERRNO_CODES[e.code])}};BFSEmscriptenStreamOps.prototype.close=function close(stream){var FS2=this.FS;try{if(FS2.isFile(stream.node.mode)&&stream.nfd){this.nodefs.closeSync(stream.nfd)}}catch(e){if(!e.code){throw e}throw new FS2.ErrnoError(this.ERRNO_CODES[e.code])}};BFSEmscriptenStreamOps.prototype.read=function read(stream,buffer$$1,offset,length,position){try{return this.nodefs.readSync(stream.nfd,uint8Array2Buffer(buffer$$1),offset,length,position)}catch(e){throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}};BFSEmscriptenStreamOps.prototype.write=function write(stream,buffer$$1,offset,length,position){try{return this.nodefs.writeSync(stream.nfd,uint8Array2Buffer(buffer$$1),offset,length,position)}catch(e){throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}};BFSEmscriptenStreamOps.prototype.llseek=function llseek(stream,offset,whence){var position=offset;if(whence===1){position+=stream.position}else if(whence===2){if(this.FS.isFile(stream.node.mode)){try{var stat=this.nodefs.fstatSync(stream.nfd);position+=stat.size}catch(e){throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}}}if(position<0){throw new this.FS.ErrnoError(this.ERRNO_CODES.EINVAL)}stream.position=position;return position};var BFSEmscriptenNodeOps=function BFSEmscriptenNodeOps2(fs4){this.fs=fs4;this.nodefs=fs4.getNodeFS();this.FS=fs4.getFS();this.PATH=fs4.getPATH();this.ERRNO_CODES=fs4.getERRNO_CODES()};BFSEmscriptenNodeOps.prototype.getattr=function getattr(node){var path$$1=this.fs.realPath(node);var stat;try{stat=this.nodefs.lstatSync(path$$1)}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}return{dev:stat.dev,ino:stat.ino,mode:stat.mode,nlink:stat.nlink,uid:stat.uid,gid:stat.gid,rdev:stat.rdev,size:stat.size,atime:stat.atime,mtime:stat.mtime,ctime:stat.ctime,blksize:stat.blksize,blocks:stat.blocks}};BFSEmscriptenNodeOps.prototype.setattr=function setattr(node,attr){var path$$1=this.fs.realPath(node);try{if(attr.mode!==void 0){this.nodefs.chmodSync(path$$1,attr.mode);node.mode=attr.mode}if(attr.timestamp!==void 0){var date=new Date(attr.timestamp);this.nodefs.utimesSync(path$$1,date,date)}}catch(e){if(!e.code){throw e}if(e.code!=="ENOTSUP"){throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}}if(attr.size!==void 0){try{this.nodefs.truncateSync(path$$1,attr.size)}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}}};BFSEmscriptenNodeOps.prototype.lookup=function lookup(parent,name){var path$$1=this.PATH.join2(this.fs.realPath(parent),name);var mode=this.fs.getMode(path$$1);return this.fs.createNode(parent,name,mode)};BFSEmscriptenNodeOps.prototype.mknod=function mknod(parent,name,mode,dev){var node=this.fs.createNode(parent,name,mode,dev);var path$$1=this.fs.realPath(node);try{if(this.FS.isDir(node.mode)){this.nodefs.mkdirSync(path$$1,node.mode)}else{this.nodefs.writeFileSync(path$$1,"",{mode:node.mode})}}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}return node};BFSEmscriptenNodeOps.prototype.rename=function rename(oldNode,newDir,newName){var oldPath=this.fs.realPath(oldNode);var newPath=this.PATH.join2(this.fs.realPath(newDir),newName);try{this.nodefs.renameSync(oldPath,newPath);oldNode.name=newName;oldNode.parent=newDir}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}};BFSEmscriptenNodeOps.prototype.unlink=function unlink(parent,name){var path$$1=this.PATH.join2(this.fs.realPath(parent),name);try{this.nodefs.unlinkSync(path$$1)}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}};BFSEmscriptenNodeOps.prototype.rmdir=function rmdir(parent,name){var path$$1=this.PATH.join2(this.fs.realPath(parent),name);try{this.nodefs.rmdirSync(path$$1)}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}};BFSEmscriptenNodeOps.prototype.readdir=function readdir(node){var path$$1=this.fs.realPath(node);try{var contents=this.nodefs.readdirSync(path$$1);contents.push(".","..");return contents}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}};BFSEmscriptenNodeOps.prototype.symlink=function symlink(parent,newName,oldPath){var newPath=this.PATH.join2(this.fs.realPath(parent),newName);try{this.nodefs.symlinkSync(oldPath,newPath)}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}};BFSEmscriptenNodeOps.prototype.readlink=function readlink(node){var path$$1=this.fs.realPath(node);try{return this.nodefs.readlinkSync(path$$1)}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}};var BFSEmscriptenFS=function BFSEmscriptenFS2(_FS,_PATH,_ERRNO_CODES,nodefs){if(_FS===void 0)_FS=self["FS"];if(_PATH===void 0)_PATH=self["PATH"];if(_ERRNO_CODES===void 0)_ERRNO_CODES=self["ERRNO_CODES"];if(nodefs===void 0)nodefs=_fsMock;this.flagsToPermissionStringMap={0:"r",1:"r+",2:"r+",64:"r",65:"r+",66:"r+",129:"rx+",193:"rx+",514:"w+",577:"w",578:"w+",705:"wx",706:"wx+",1024:"a",1025:"a",1026:"a+",1089:"a",1090:"a+",1153:"ax",1154:"ax+",1217:"ax",1218:"ax+",4096:"rs",4098:"rs+"};this.nodefs=nodefs;this.FS=_FS;this.PATH=_PATH;this.ERRNO_CODES=_ERRNO_CODES;this.node_ops=new BFSEmscriptenNodeOps(this);this.stream_ops=new BFSEmscriptenStreamOps(this)};BFSEmscriptenFS.prototype.mount=function mount(m){return this.createNode(null,"/",this.getMode(m.opts.root),0)};BFSEmscriptenFS.prototype.createNode=function createNode(parent,name,mode,dev){var FS2=this.FS;if(!FS2.isDir(mode)&&!FS2.isFile(mode)&&!FS2.isLink(mode)){throw new FS2.ErrnoError(this.ERRNO_CODES.EINVAL)}var node=FS2.createNode(parent,name,mode);node.node_ops=this.node_ops;node.stream_ops=this.stream_ops;return node};BFSEmscriptenFS.prototype.getMode=function getMode(path$$1){var stat;try{stat=this.nodefs.lstatSync(path$$1)}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}return stat.mode};BFSEmscriptenFS.prototype.realPath=function realPath(node){var parts=[];while(node.parent!==node){parts.push(node.name);node=node.parent}parts.push(node.mount.opts.root);parts.reverse();return this.PATH.join.apply(null,parts)};BFSEmscriptenFS.prototype.flagsToPermissionString=function flagsToPermissionString(flags){var parsedFlags=typeof flags==="string"?parseInt(flags,10):flags;parsedFlags&=8191;if(parsedFlags in this.flagsToPermissionStringMap){return this.flagsToPermissionStringMap[parsedFlags]}else{return flags}};BFSEmscriptenFS.prototype.getNodeFS=function getNodeFS(){return this.nodefs};BFSEmscriptenFS.prototype.getFS=function getFS(){return this.FS};BFSEmscriptenFS.prototype.getPATH=function getPATH(){return this.PATH};BFSEmscriptenFS.prototype.getERRNO_CODES=function getERRNO_CODES(){return this.ERRNO_CODES};var BaseFileSystem=function BaseFileSystem2(){};BaseFileSystem.prototype.supportsLinks=function supportsLinks(){return false};BaseFileSystem.prototype.diskSpace=function diskSpace(p,cb){cb(0,0)};BaseFileSystem.prototype.openFile=function openFile(p,flag,cb){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.createFile=function createFile(p,flag,mode,cb){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.open=function open(p,flag,mode,cb){var this$1=this;var mustBeFile=function(e,stats){if(e){switch(flag.pathNotExistsAction()){case ActionType.CREATE_FILE:return this$1.stat(path.dirname(p),false,function(e2,parentStats){if(e2){cb(e2)}else if(parentStats&&!parentStats.isDirectory()){cb(ApiError.ENOTDIR(path.dirname(p)))}else{this$1.createFile(p,flag,mode,cb)}});case ActionType.THROW_EXCEPTION:return cb(ApiError.ENOENT(p));default:return cb(new ApiError(ErrorCode.EINVAL,"Invalid FileFlag object."))}}else{if(stats&&stats.isDirectory()){return cb(ApiError.EISDIR(p))}switch(flag.pathExistsAction()){case ActionType.THROW_EXCEPTION:return cb(ApiError.EEXIST(p));case ActionType.TRUNCATE_FILE:return this$1.openFile(p,flag,function(e2,fd){if(e2){cb(e2)}else if(fd){fd.truncate(0,function(){fd.sync(function(){cb(null,fd)})})}else{fail()}});case ActionType.NOP:return this$1.openFile(p,flag,cb);default:return cb(new ApiError(ErrorCode.EINVAL,"Invalid FileFlag object."))}}};this.stat(p,false,mustBeFile)};BaseFileSystem.prototype.rename=function rename(oldPath,newPath,cb){cb(new ApiError(ErrorCode.ENOTSUP))};BaseFileSystem.prototype.renameSync=function renameSync(oldPath,newPath){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.stat=function stat(p,isLstat,cb){cb(new ApiError(ErrorCode.ENOTSUP))};BaseFileSystem.prototype.statSync=function statSync(p,isLstat){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.openFileSync=function openFileSync(p,flag,mode){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.createFileSync=function createFileSync(p,flag,mode){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.openSync=function openSync(p,flag,mode){var stats;try{stats=this.statSync(p,false)}catch(e){switch(flag.pathNotExistsAction()){case ActionType.CREATE_FILE:var parentStats=this.statSync(path.dirname(p),false);if(!parentStats.isDirectory()){throw ApiError.ENOTDIR(path.dirname(p))}return this.createFileSync(p,flag,mode);case ActionType.THROW_EXCEPTION:throw ApiError.ENOENT(p);default:throw new ApiError(ErrorCode.EINVAL,"Invalid FileFlag object.")}}if(stats.isDirectory()){throw ApiError.EISDIR(p)}switch(flag.pathExistsAction()){case ActionType.THROW_EXCEPTION:throw ApiError.EEXIST(p);case ActionType.TRUNCATE_FILE:this.unlinkSync(p);return this.createFileSync(p,flag,stats.mode);case ActionType.NOP:return this.openFileSync(p,flag,mode);default:throw new ApiError(ErrorCode.EINVAL,"Invalid FileFlag object.")}};BaseFileSystem.prototype.unlink=function unlink(p,cb){cb(new ApiError(ErrorCode.ENOTSUP))};BaseFileSystem.prototype.unlinkSync=function unlinkSync(p){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.rmdir=function rmdir(p,cb){cb(new ApiError(ErrorCode.ENOTSUP))};BaseFileSystem.prototype.rmdirSync=function rmdirSync(p){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.mkdir=function mkdir(p,mode,cb){cb(new ApiError(ErrorCode.ENOTSUP))};BaseFileSystem.prototype.mkdirSync=function mkdirSync(p,mode){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.readdir=function readdir(p,cb){cb(new ApiError(ErrorCode.ENOTSUP))};BaseFileSystem.prototype.readdirSync=function readdirSync(p){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.exists=function exists2(p,cb){this.stat(p,null,function(err){cb(!err)})};BaseFileSystem.prototype.existsSync=function existsSync(p){try{this.statSync(p,true);return true}catch(e){return false}};BaseFileSystem.prototype.realpath=function realpath(p,cache,cb){if(this.supportsLinks()){var splitPath=p.split(path.sep);for(var i2=0;i2this._buffer.length){var buf=Buffer2.alloc(len-this._buffer.length,0);this.writeSync(buf,0,buf.length,this._buffer.length);if(this._flag.isSynchronous()&&_fsMock.getRootFS().supportsSynch()){this.syncSync()}return}this._stat.size=len;var newBuff=Buffer2.alloc(len);this._buffer.copy(newBuff,0,0,len);this._buffer=newBuff;if(this._flag.isSynchronous()&&_fsMock.getRootFS().supportsSynch()){this.syncSync()}};PreloadFile2.prototype.write=function write(buffer$$1,offset,length,position,cb){try{cb(null,this.writeSync(buffer$$1,offset,length,position),buffer$$1)}catch(e){cb(e)}};PreloadFile2.prototype.writeSync=function writeSync(buffer$$1,offset,length,position){this._dirty=true;if(position===void 0||position===null){position=this.getPos()}if(!this._flag.isWriteable()){throw new ApiError(ErrorCode.EPERM,"File not opened with a writeable mode.")}var endFp=position+length;if(endFp>this._stat.size){this._stat.size=endFp;if(endFp>this._buffer.length){var newBuff=Buffer2.alloc(endFp);this._buffer.copy(newBuff);this._buffer=newBuff}}var len=buffer$$1.copy(this._buffer,position,offset,offset+length);this._stat.mtime=new Date;if(this._flag.isSynchronous()){this.syncSync();return len}this.setPos(position+len);return len};PreloadFile2.prototype.read=function read(buffer$$1,offset,length,position,cb){try{cb(null,this.readSync(buffer$$1,offset,length,position),buffer$$1)}catch(e){cb(e)}};PreloadFile2.prototype.readSync=function readSync(buffer$$1,offset,length,position){if(!this._flag.isReadable()){throw new ApiError(ErrorCode.EPERM,"File not opened with a readable mode.")}if(position===void 0||position===null){position=this.getPos()}var endRead=position+length;if(endRead>this._stat.size){length=this._stat.size-position}var rv=this._buffer.copy(buffer$$1,offset,position,position+length);this._stat.atime=new Date;this._pos=position+length;return rv};PreloadFile2.prototype.chmod=function chmod(mode,cb){try{this.chmodSync(mode);cb()}catch(e){cb(e)}};PreloadFile2.prototype.chmodSync=function chmodSync(mode){if(!this._fs.supportsProps()){throw new ApiError(ErrorCode.ENOTSUP)}this._dirty=true;this._stat.chmod(mode);this.syncSync()};PreloadFile2.prototype.isDirty=function isDirty(){return this._dirty};PreloadFile2.prototype.resetDirty=function resetDirty(){this._dirty=false};return PreloadFile2}(BaseFile);var NoSyncFile=function(PreloadFile2){function NoSyncFile2(_fs,_path,_flag,_stat,contents){PreloadFile2.call(this,_fs,_path,_flag,_stat,contents)}if(PreloadFile2)NoSyncFile2.__proto__=PreloadFile2;NoSyncFile2.prototype=Object.create(PreloadFile2&&PreloadFile2.prototype);NoSyncFile2.prototype.constructor=NoSyncFile2;NoSyncFile2.prototype.sync=function sync(cb){cb()};NoSyncFile2.prototype.syncSync=function syncSync(){};NoSyncFile2.prototype.close=function close(cb){cb()};NoSyncFile2.prototype.closeSync=function closeSync(){};return NoSyncFile2}(PreloadFile);var MirrorFile=function(PreloadFile$$1){function MirrorFile2(fs4,path$$1,flag,stat,data){PreloadFile$$1.call(this,fs4,path$$1,flag,stat,data)}if(PreloadFile$$1)MirrorFile2.__proto__=PreloadFile$$1;MirrorFile2.prototype=Object.create(PreloadFile$$1&&PreloadFile$$1.prototype);MirrorFile2.prototype.constructor=MirrorFile2;MirrorFile2.prototype.syncSync=function syncSync(){if(this.isDirty()){this._fs._syncSync(this);this.resetDirty()}};MirrorFile2.prototype.closeSync=function closeSync(){this.syncSync()};return MirrorFile2}(PreloadFile);var AsyncMirror=function(SynchronousFileSystem$$1){function AsyncMirror2(sync,async,deprecateMsg){if(deprecateMsg===void 0)deprecateMsg=true;SynchronousFileSystem$$1.call(this);this._queue=[];this._queueRunning=false;this._isInitialized=false;this._initializeCallbacks=[];this._sync=sync;this._async=async;if(!sync.supportsSynch()){throw new Error("The first argument to AsyncMirror needs to be a synchronous file system.")}deprecationMessage(deprecateMsg,AsyncMirror2.Name,{sync:"sync file system instance",async:"async file system instance"})}if(SynchronousFileSystem$$1)AsyncMirror2.__proto__=SynchronousFileSystem$$1;AsyncMirror2.prototype=Object.create(SynchronousFileSystem$$1&&SynchronousFileSystem$$1.prototype);AsyncMirror2.prototype.constructor=AsyncMirror2;AsyncMirror2.Create=function Create(opts,cb){try{var fs4=new AsyncMirror2(opts.sync,opts.async,false);fs4.initialize(function(e){if(e){cb(e)}else{cb(null,fs4)}},false)}catch(e){cb(e)}};AsyncMirror2.isAvailable=function isAvailable(){return true};AsyncMirror2.prototype.getName=function getName(){return AsyncMirror2.Name};AsyncMirror2.prototype._syncSync=function _syncSync(fd){this._sync.writeFileSync(fd.getPath(),fd.getBuffer(),null,FileFlag.getFileFlag("w"),fd.getStats().mode);this.enqueueOp({apiMethod:"writeFile",arguments:[fd.getPath(),fd.getBuffer(),null,fd.getFlag(),fd.getStats().mode]})};AsyncMirror2.prototype.initialize=function initialize3(userCb,deprecateMsg){var this$1=this;if(deprecateMsg===void 0)deprecateMsg=true;if(deprecateMsg){console.warn("[AsyncMirror] AsyncMirror.initialize() is deprecated and will be removed in the next major version. Please use 'AsyncMirror.Create({ sync: (sync file system instance), async: (async file system instance)}, cb)' to create and initialize AsyncMirror instances.")}var callbacks=this._initializeCallbacks;var end=function(e){this$1._isInitialized=!e;this$1._initializeCallbacks=[];callbacks.forEach(function(cb){return cb(e)})};if(!this._isInitialized){if(callbacks.push(userCb)===1){var copyDirectory=function(p,mode,cb){if(p!=="/"){this$1._sync.mkdirSync(p,mode)}this$1._async.readdir(p,function(err,files){var i2=0;function copyNextFile(err2){if(err2){cb(err2)}else if(i20){var op2=this$1._queue.shift(),args=op2.arguments;args.push(doNextOp);this$1._async[op2.apiMethod].apply(this$1._async,args)}else{this$1._queueRunning=false}};doNextOp()}};return AsyncMirror2}(SynchronousFileSystem);AsyncMirror.Name="AsyncMirror";AsyncMirror.Options={sync:{type:"object",description:"The synchronous file system to mirror the asynchronous file system to."},async:{type:"object",description:"The asynchronous file system to mirror."}};function apply(func,thisArg,args){switch(args.length){case 0:return func.call(thisArg);case 1:return func.call(thisArg,args[0]);case 2:return func.call(thisArg,args[0],args[1]);case 3:return func.call(thisArg,args[0],args[1],args[2])}return func.apply(thisArg,args)}var nativeMax=Math.max;function overRest$1(func,start,transform){start=nativeMax(start===void 0?func.length-1:start,0);return function(){var args=arguments,index=-1,length=nativeMax(args.length-start,0),array=Array(length);while(++index-1&&value%1==0&&value<=MAX_SAFE_INTEGER}function isArrayLike(value){return value!=null&&isLength(value.length)&&!isFunction(value)}var breakLoop={};function noop(){}function once(fn){return function(){if(fn===null){return}var callFn=fn;fn=null;callFn.apply(this,arguments)}}var iteratorSymbol=typeof Symbol==="function"&&Symbol.iterator;var getIterator=function(coll){return iteratorSymbol&&coll[iteratorSymbol]&&coll[iteratorSymbol]()};function baseTimes(n,iteratee){var index=-1,result=Array(n);while(++index-1&&value%1==0&&value++numRun){switch(error.status){case Dropbox.ApiError.SERVER_ERROR:case Dropbox.ApiError.NETWORK_ERROR:case Dropbox.ApiError.RATE_LIMITED:setTimeout(function(){performOp(interceptCb)},timeoutDuration*1e3);break;default:cb.apply(null,arguments);break}}else{cb.apply(null,arguments)}};performOp(interceptCb)};CachedDropboxClient.prototype.getCachedInfo=function getCachedInfo(p){return this._cache[p.toLowerCase()]};CachedDropboxClient.prototype.putCachedInfo=function putCachedInfo(p,cache){this._cache[p.toLowerCase()]=cache};CachedDropboxClient.prototype.deleteCachedInfo=function deleteCachedInfo(p){delete this._cache[p.toLowerCase()]};CachedDropboxClient.prototype.getCachedDirInfo=function getCachedDirInfo(p){var info=this.getCachedInfo(p);if(isDirInfo(info)){return info}else{return null}};CachedDropboxClient.prototype.getCachedFileInfo=function getCachedFileInfo(p){var info=this.getCachedInfo(p);if(isFileInfo(info)){return info}else{return null}};CachedDropboxClient.prototype.updateCachedDirInfo=function updateCachedDirInfo(p,stat,contents){if(contents===void 0)contents=null;var cachedInfo=this.getCachedInfo(p);if(stat.contentHash!==null&&(cachedInfo===void 0||cachedInfo.stat.contentHash!==stat.contentHash)){this.putCachedInfo(p,{stat,contents})}};CachedDropboxClient.prototype.updateCachedFileInfo=function updateCachedFileInfo(p,stat,contents){if(contents===void 0)contents=null;var cachedInfo=this.getCachedInfo(p);if(stat.versionTag!==null&&(cachedInfo===void 0||cachedInfo.stat.versionTag!==stat.versionTag)){this.putCachedInfo(p,{stat,contents})}};CachedDropboxClient.prototype.updateCachedInfo=function updateCachedInfo(p,stat,contents){if(contents===void 0)contents=null;if(stat.isFile&&isArrayBuffer(contents)){this.updateCachedFileInfo(p,stat,contents)}else if(stat.isFolder&&Array.isArray(contents)){this.updateCachedDirInfo(p,stat,contents)}};var DropboxFile=function(PreloadFile$$1){function DropboxFile2(_fs,_path,_flag,_stat,contents){PreloadFile$$1.call(this,_fs,_path,_flag,_stat,contents)}if(PreloadFile$$1)DropboxFile2.__proto__=PreloadFile$$1;DropboxFile2.prototype=Object.create(PreloadFile$$1&&PreloadFile$$1.prototype);DropboxFile2.prototype.constructor=DropboxFile2;DropboxFile2.prototype.sync=function sync(cb){var this$1=this;if(this.isDirty()){var buffer$$1=this.getBuffer(),arrayBuffer=buffer2ArrayBuffer(buffer$$1);this._fs._writeFileStrict(this.getPath(),arrayBuffer,function(e){if(!e){this$1.resetDirty()}cb(e)})}else{cb()}};DropboxFile2.prototype.close=function close(cb){this.sync(cb)};return DropboxFile2}(PreloadFile);var DropboxFileSystem=function(BaseFileSystem$$1){function DropboxFileSystem2(client,deprecateMsg){if(deprecateMsg===void 0)deprecateMsg=true;BaseFileSystem$$1.call(this);this._client=new CachedDropboxClient(client);deprecationMessage(deprecateMsg,DropboxFileSystem2.Name,{client:"authenticated dropbox client instance"});constructErrorCodeLookup()}if(BaseFileSystem$$1)DropboxFileSystem2.__proto__=BaseFileSystem$$1;DropboxFileSystem2.prototype=Object.create(BaseFileSystem$$1&&BaseFileSystem$$1.prototype);DropboxFileSystem2.prototype.constructor=DropboxFileSystem2;DropboxFileSystem2.Create=function Create(opts,cb){cb(null,new DropboxFileSystem2(opts.client,false))};DropboxFileSystem2.isAvailable=function isAvailable(){return typeof Dropbox!=="undefined"};DropboxFileSystem2.prototype.getName=function getName(){return DropboxFileSystem2.Name};DropboxFileSystem2.prototype.isReadOnly=function isReadOnly(){return false};DropboxFileSystem2.prototype.supportsSymlinks=function supportsSymlinks(){return false};DropboxFileSystem2.prototype.supportsProps=function supportsProps(){return false};DropboxFileSystem2.prototype.supportsSynch=function supportsSynch(){return false};DropboxFileSystem2.prototype.empty=function empty(mainCb){var this$1=this;this._client.readdir("/",function(error,files){if(error){mainCb(this$1.convert(error,"/"))}else{var deleteFile2=function(file,cb){var p=path.join("/",file);this$1._client.remove(p,function(err){cb(err?this$1.convert(err,p):null)})};var finished=function(err){if(err){mainCb(err)}else{mainCb()}};eachLimit(files,deleteFile2,finished)}})};DropboxFileSystem2.prototype.rename=function rename(oldPath,newPath,cb){var this$1=this;this._client.move(oldPath,newPath,function(error){if(error){this$1._client.stat(newPath,function(error2,stat){if(error2||stat.isFolder){var missingPath=error.response.error.indexOf(oldPath)>-1?oldPath:newPath;cb(this$1.convert(error,missingPath))}else{this$1._client.remove(newPath,function(error22){if(error22){cb(this$1.convert(error22,newPath))}else{this$1.rename(oldPath,newPath,cb)}})}})}else{cb()}})};DropboxFileSystem2.prototype.stat=function stat(path$$1,isLstat,cb){var this$1=this;this._client.stat(path$$1,function(error,stat2){if(error){cb(this$1.convert(error,path$$1))}else if(stat2&&stat2.isRemoved){cb(ApiError.FileError(ErrorCode.ENOENT,path$$1))}else{var stats=new Stats(this$1._statType(stat2),stat2.size);return cb(null,stats)}})};DropboxFileSystem2.prototype.open=function open(path$$1,flags,mode,cb){var this$1=this;this._client.readFile(path$$1,function(error,content,dbStat){if(error){if(flags.isReadable()){cb(this$1.convert(error,path$$1))}else{switch(error.status){case Dropbox.ApiError.NOT_FOUND:var ab=new ArrayBuffer(0);return this$1._writeFileStrict(path$$1,ab,function(error2,stat){if(error2){cb(error2)}else{var file2=this$1._makeFile(path$$1,flags,stat,arrayBuffer2Buffer(ab));cb(null,file2)}});default:return cb(this$1.convert(error,path$$1))}}}else{var buffer$$1;if(content===null){buffer$$1=emptyBuffer()}else{buffer$$1=arrayBuffer2Buffer(content)}var file=this$1._makeFile(path$$1,flags,dbStat,buffer$$1);return cb(null,file)}})};DropboxFileSystem2.prototype._writeFileStrict=function _writeFileStrict(p,data,cb){var this$1=this;var parent=path.dirname(p);this.stat(parent,false,function(error,stat){if(error){cb(ApiError.FileError(ErrorCode.ENOENT,parent))}else{this$1._client.writeFile(p,data,function(error2,stat2){if(error2){cb(this$1.convert(error2,p))}else{cb(null,stat2)}})}})};DropboxFileSystem2.prototype._statType=function _statType(stat){return stat.isFile?FileType.FILE:FileType.DIRECTORY};DropboxFileSystem2.prototype._makeFile=function _makeFile(path$$1,flag,stat,buffer$$1){var type=this._statType(stat);var stats=new Stats(type,stat.size);return new DropboxFile(this,path$$1,flag,stats,buffer$$1)};DropboxFileSystem2.prototype._remove=function _remove(path$$1,cb,isFile){var this$1=this;this._client.stat(path$$1,function(error,stat){if(error){cb(this$1.convert(error,path$$1))}else{if(stat.isFile&&!isFile){cb(ApiError.FileError(ErrorCode.ENOTDIR,path$$1))}else if(!stat.isFile&&isFile){cb(ApiError.FileError(ErrorCode.EISDIR,path$$1))}else{this$1._client.remove(path$$1,function(error2){if(error2){cb(this$1.convert(error2,path$$1))}else{cb(null)}})}}})};DropboxFileSystem2.prototype.unlink=function unlink(path$$1,cb){this._remove(path$$1,cb,true)};DropboxFileSystem2.prototype.rmdir=function rmdir(path$$1,cb){this._remove(path$$1,cb,false)};DropboxFileSystem2.prototype.mkdir=function mkdir(p,mode,cb){var this$1=this;var parent=path.dirname(p);this._client.stat(parent,function(error,stat){if(error){cb(this$1.convert(error,parent))}else{this$1._client.mkdir(p,function(error2){if(error2){cb(ApiError.FileError(ErrorCode.EEXIST,p))}else{cb(null)}})}})};DropboxFileSystem2.prototype.readdir=function readdir(path$$1,cb){var this$1=this;this._client.readdir(path$$1,function(error,files){if(error){return cb(this$1.convert(error))}else{return cb(null,files)}})};DropboxFileSystem2.prototype.convert=function convert(err,path$$1){if(path$$1===void 0)path$$1=null;var errorCode=errorCodeLookup[err.status];if(errorCode===void 0){errorCode=ErrorCode.EIO}if(!path$$1){return new ApiError(errorCode)}else{return ApiError.FileError(errorCode,path$$1)}};return DropboxFileSystem2}(BaseFileSystem);DropboxFileSystem.Name="Dropbox";DropboxFileSystem.Options={client:{type:"object",description:"An *authenticated* Dropbox client. Must be from the 0.10 JS SDK.",validator:function(opt,cb){if(opt.isAuthenticated&&opt.isAuthenticated()){cb()}else{cb(new ApiError(ErrorCode.EINVAL,"'client' option must be an authenticated Dropbox client from the v0.10 JS SDK."))}}}};function convertError(e,path$$1){if(path$$1===void 0)path$$1="";var errno=e.errno;var parent=e.node;var paths=[];while(parent){paths.unshift(parent.name);if(parent===parent.parent){break}parent=parent.parent}return new ApiError(errno,ErrorStrings[errno],paths.length>0?"/"+paths.join("/"):path$$1)}var EmscriptenFile=function(BaseFile$$1){function EmscriptenFile2(_fs,_FS,_path,_stream){BaseFile$$1.call(this);this._fs=_fs;this._FS=_FS;this._path=_path;this._stream=_stream}if(BaseFile$$1)EmscriptenFile2.__proto__=BaseFile$$1;EmscriptenFile2.prototype=Object.create(BaseFile$$1&&BaseFile$$1.prototype);EmscriptenFile2.prototype.constructor=EmscriptenFile2;EmscriptenFile2.prototype.getPos=function getPos(){return void 0};EmscriptenFile2.prototype.close=function close(cb){var err=null;try{this.closeSync()}catch(e){err=e}finally{cb(err)}};EmscriptenFile2.prototype.closeSync=function closeSync(){try{this._FS.close(this._stream)}catch(e){throw convertError(e,this._path)}};EmscriptenFile2.prototype.stat=function stat(cb){try{cb(null,this.statSync())}catch(e){cb(e)}};EmscriptenFile2.prototype.statSync=function statSync(){try{return this._fs.statSync(this._path,false)}catch(e){throw convertError(e,this._path)}};EmscriptenFile2.prototype.truncate=function truncate(len,cb){var err=null;try{this.truncateSync(len)}catch(e){err=e}finally{cb(err)}};EmscriptenFile2.prototype.truncateSync=function truncateSync(len){try{this._FS.ftruncate(this._stream.fd,len)}catch(e){throw convertError(e,this._path)}};EmscriptenFile2.prototype.write=function write(buffer$$1,offset,length,position,cb){try{cb(null,this.writeSync(buffer$$1,offset,length,position),buffer$$1)}catch(e){cb(e)}};EmscriptenFile2.prototype.writeSync=function writeSync(buffer$$1,offset,length,position){try{var u8=buffer2Uint8array(buffer$$1);var emPosition=position===null?void 0:position;return this._FS.write(this._stream,u8,offset,length,emPosition)}catch(e){throw convertError(e,this._path)}};EmscriptenFile2.prototype.read=function read(buffer$$1,offset,length,position,cb){try{cb(null,this.readSync(buffer$$1,offset,length,position),buffer$$1)}catch(e){cb(e)}};EmscriptenFile2.prototype.readSync=function readSync(buffer$$1,offset,length,position){try{var u8=buffer2Uint8array(buffer$$1);var emPosition=position===null?void 0:position;return this._FS.read(this._stream,u8,offset,length,emPosition)}catch(e){throw convertError(e,this._path)}};EmscriptenFile2.prototype.sync=function sync(cb){cb()};EmscriptenFile2.prototype.syncSync=function syncSync(){};EmscriptenFile2.prototype.chown=function chown(uid,gid,cb){var err=null;try{this.chownSync(uid,gid)}catch(e){err=e}finally{cb(err)}};EmscriptenFile2.prototype.chownSync=function chownSync(uid,gid){try{this._FS.fchown(this._stream.fd,uid,gid)}catch(e){throw convertError(e,this._path)}};EmscriptenFile2.prototype.chmod=function chmod(mode,cb){var err=null;try{this.chmodSync(mode)}catch(e){err=e}finally{cb(err)}};EmscriptenFile2.prototype.chmodSync=function chmodSync(mode){try{this._FS.fchmod(this._stream.fd,mode)}catch(e){throw convertError(e,this._path)}};EmscriptenFile2.prototype.utimes=function utimes(atime,mtime,cb){var err=null;try{this.utimesSync(atime,mtime)}catch(e){err=e}finally{cb(err)}};EmscriptenFile2.prototype.utimesSync=function utimesSync(atime,mtime){this._fs.utimesSync(this._path,atime,mtime)};return EmscriptenFile2}(BaseFile);var EmscriptenFileSystem=function(SynchronousFileSystem$$1){function EmscriptenFileSystem2(_FS){SynchronousFileSystem$$1.call(this);this._FS=_FS}if(SynchronousFileSystem$$1)EmscriptenFileSystem2.__proto__=SynchronousFileSystem$$1;EmscriptenFileSystem2.prototype=Object.create(SynchronousFileSystem$$1&&SynchronousFileSystem$$1.prototype);EmscriptenFileSystem2.prototype.constructor=EmscriptenFileSystem2;EmscriptenFileSystem2.Create=function Create(opts,cb){cb(null,new EmscriptenFileSystem2(opts.FS))};EmscriptenFileSystem2.isAvailable=function isAvailable(){return true};EmscriptenFileSystem2.prototype.getName=function getName(){return this._FS.DB_NAME()};EmscriptenFileSystem2.prototype.isReadOnly=function isReadOnly(){return false};EmscriptenFileSystem2.prototype.supportsLinks=function supportsLinks(){return true};EmscriptenFileSystem2.prototype.supportsProps=function supportsProps(){return true};EmscriptenFileSystem2.prototype.supportsSynch=function supportsSynch(){return true};EmscriptenFileSystem2.prototype.renameSync=function renameSync(oldPath,newPath){try{this._FS.rename(oldPath,newPath)}catch(e){if(e.errno===ErrorCode.ENOENT){throw convertError(e,this.existsSync(oldPath)?newPath:oldPath)}else{throw convertError(e)}}};EmscriptenFileSystem2.prototype.statSync=function statSync(p,isLstat){try{var stats=isLstat?this._FS.lstat(p):this._FS.stat(p);var itemType=this.modeToFileType(stats.mode);return new Stats(itemType,stats.size,stats.mode,stats.atime,stats.mtime,stats.ctime)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.openSync=function openSync(p,flag,mode){try{var stream=this._FS.open(p,flag.getFlagString(),mode);if(this._FS.isDir(stream.node.mode)){this._FS.close(stream);throw ApiError.EISDIR(p)}return new EmscriptenFile(this,this._FS,p,stream)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.unlinkSync=function unlinkSync(p){try{this._FS.unlink(p)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.rmdirSync=function rmdirSync(p){try{this._FS.rmdir(p)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.mkdirSync=function mkdirSync(p,mode){try{this._FS.mkdir(p,mode)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.readdirSync=function readdirSync(p){try{return this._FS.readdir(p).filter(function(p2){return p2!=="."&&p2!==".."})}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.truncateSync=function truncateSync(p,len){try{this._FS.truncate(p,len)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.readFileSync=function readFileSync(p,encoding,flag){try{var data=this._FS.readFile(p,{flags:flag.getFlagString()});var buff=uint8Array2Buffer(data);if(encoding){return buff.toString(encoding)}else{return buff}}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.writeFileSync=function writeFileSync(p,data,encoding,flag,mode){try{if(encoding){data=Buffer2.from(data,encoding)}var u8=buffer2Uint8array(data);this._FS.writeFile(p,u8,{flags:flag.getFlagString(),encoding:"binary"});this._FS.chmod(p,mode)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.chmodSync=function chmodSync(p,isLchmod,mode){try{isLchmod?this._FS.lchmod(p,mode):this._FS.chmod(p,mode)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.chownSync=function chownSync(p,isLchown,uid,gid){try{isLchown?this._FS.lchown(p,uid,gid):this._FS.chown(p,uid,gid)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.symlinkSync=function symlinkSync(srcpath,dstpath,type){try{this._FS.symlink(srcpath,dstpath)}catch(e){throw convertError(e)}};EmscriptenFileSystem2.prototype.readlinkSync=function readlinkSync(p){try{return this._FS.readlink(p)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.utimesSync=function utimesSync(p,atime,mtime){try{this._FS.utime(p,atime.getTime(),mtime.getTime())}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.modeToFileType=function modeToFileType(mode){if(this._FS.isDir(mode)){return FileType.DIRECTORY}else if(this._FS.isFile(mode)){return FileType.FILE}else if(this._FS.isLink(mode)){return FileType.SYMLINK}else{throw ApiError.EPERM("Invalid mode: "+mode)}};return EmscriptenFileSystem2}(SynchronousFileSystem);EmscriptenFileSystem.Name="EmscriptenFileSystem";EmscriptenFileSystem.Options={FS:{type:"object",description:"The Emscripten file system to use (the `FS` variable)"}};var FolderAdapter=function(BaseFileSystem$$1){function FolderAdapter2(folder,wrapped){BaseFileSystem$$1.call(this);this._folder=folder;this._wrapped=wrapped}if(BaseFileSystem$$1)FolderAdapter2.__proto__=BaseFileSystem$$1;FolderAdapter2.prototype=Object.create(BaseFileSystem$$1&&BaseFileSystem$$1.prototype);FolderAdapter2.prototype.constructor=FolderAdapter2;FolderAdapter2.Create=function Create(opts,cb){cb(null,new FolderAdapter2(opts.folder,opts.wrapped))};FolderAdapter2.isAvailable=function isAvailable(){return true};FolderAdapter2.prototype.initialize=function initialize3(cb){var this$1=this;this._wrapped.exists(this._folder,function(exists2){if(exists2){cb()}else if(this$1._wrapped.isReadOnly()){cb(ApiError.ENOENT(this$1._folder))}else{this$1._wrapped.mkdir(this$1._folder,511,cb)}})};FolderAdapter2.prototype.getName=function getName(){return this._wrapped.getName()};FolderAdapter2.prototype.isReadOnly=function isReadOnly(){return this._wrapped.isReadOnly()};FolderAdapter2.prototype.supportsProps=function supportsProps(){return this._wrapped.supportsProps()};FolderAdapter2.prototype.supportsSynch=function supportsSynch(){return this._wrapped.supportsSynch()};FolderAdapter2.prototype.supportsLinks=function supportsLinks(){return false};return FolderAdapter2}(BaseFileSystem);FolderAdapter.Name="FolderAdapter";FolderAdapter.Options={folder:{type:"string",description:"The folder to use as the root directory"},wrapped:{type:"object",description:"The file system to wrap"}};function translateError(folder,e){if(e!==null&&typeof e==="object"){var err=e;var p=err.path;if(p){p="/"+path.relative(folder,p);err.message=err.message.replace(err.path,p);err.path=p}}return e}function wrapCallback(folder,cb){if(typeof cb==="function"){return function(err){if(arguments.length>0){arguments[0]=translateError(folder,err)}cb.apply(null,arguments)}}else{return cb}}function wrapFunction(name,wrapFirst,wrapSecond){if(name.slice(name.length-4)!=="Sync"){return function(){if(arguments.length>0){if(wrapFirst){arguments[0]=path.join(this._folder,arguments[0])}if(wrapSecond){arguments[1]=path.join(this._folder,arguments[1])}arguments[arguments.length-1]=wrapCallback(this._folder,arguments[arguments.length-1])}return this._wrapped[name].apply(this._wrapped,arguments)}}else{return function(){try{if(wrapFirst){arguments[0]=path.join(this._folder,arguments[0])}if(wrapSecond){arguments[1]=path.join(this._folder,arguments[1])}return this._wrapped[name].apply(this._wrapped,arguments)}catch(e){throw translateError(this._folder,e)}}}}["diskSpace","stat","statSync","open","openSync","unlink","unlinkSync","rmdir","rmdirSync","mkdir","mkdirSync","readdir","readdirSync","exists","existsSync","realpath","realpathSync","truncate","truncateSync","readFile","readFileSync","writeFile","writeFileSync","appendFile","appendFileSync","chmod","chmodSync","chown","chownSync","utimes","utimesSync","readlink","readlinkSync"].forEach(function(name){FolderAdapter.prototype[name]=wrapFunction(name,true,false)});["rename","renameSync","link","linkSync","symlink","symlinkSync"].forEach(function(name){FolderAdapter.prototype[name]=wrapFunction(name,true,true)});var toExport;if(typeof window!=="undefined"){toExport=window}else if(typeof self!=="undefined"){toExport=self}else{toExport=global}var global$1=toExport;function isDirectoryEntry(entry){return entry.isDirectory}var _getFS=global$1.webkitRequestFileSystem||global$1.requestFileSystem||null;function _requestQuota(type,size,success,errorCallback){if(typeof navigator["webkitPersistentStorage"]!=="undefined"){switch(type){case global$1.PERSISTENT:navigator.webkitPersistentStorage.requestQuota(size,success,errorCallback);break;case global$1.TEMPORARY:navigator.webkitTemporaryStorage.requestQuota(size,success,errorCallback);break;default:errorCallback(new TypeError("Invalid storage type: "+type));break}}else{global$1.webkitStorageInfo.requestQuota(type,size,success,errorCallback)}}function _toArray(list2){return Array.prototype.slice.call(list2||[],0)}function convertError$1(err,p,expectedDir){switch(err.name){case"PathExistsError":return ApiError.EEXIST(p);case"QuotaExceededError":return ApiError.FileError(ErrorCode.ENOSPC,p);case"NotFoundError":return ApiError.ENOENT(p);case"SecurityError":return ApiError.FileError(ErrorCode.EACCES,p);case"InvalidModificationError":return ApiError.FileError(ErrorCode.EPERM,p);case"TypeMismatchError":return ApiError.FileError(expectedDir?ErrorCode.ENOTDIR:ErrorCode.EISDIR,p);case"EncodingError":case"InvalidStateError":case"NoModificationAllowedError":default:return ApiError.FileError(ErrorCode.EINVAL,p)}}var HTML5FSFile=function(PreloadFile$$1){function HTML5FSFile2(fs4,entry,path$$1,flag,stat,contents){PreloadFile$$1.call(this,fs4,path$$1,flag,stat,contents);this._entry=entry}if(PreloadFile$$1)HTML5FSFile2.__proto__=PreloadFile$$1;HTML5FSFile2.prototype=Object.create(PreloadFile$$1&&PreloadFile$$1.prototype);HTML5FSFile2.prototype.constructor=HTML5FSFile2;HTML5FSFile2.prototype.sync=function sync(cb){var this$1=this;if(!this.isDirty()){return cb()}this._entry.createWriter(function(writer){var buffer$$1=this$1.getBuffer();var blob=new Blob([buffer2ArrayBuffer(buffer$$1)]);var length=blob.size;writer.onwriteend=function(err){writer.onwriteend=null;writer.onerror=null;writer.truncate(length);this$1.resetDirty();cb()};writer.onerror=function(err){cb(convertError$1(err,this$1.getPath(),false))};writer.write(blob)})};HTML5FSFile2.prototype.close=function close(cb){this.sync(cb)};return HTML5FSFile2}(PreloadFile);var HTML5FS=function(BaseFileSystem$$1){function HTML5FS2(size,type,deprecateMsg){if(size===void 0)size=5;if(type===void 0)type=global$1.PERSISTENT;if(deprecateMsg===void 0)deprecateMsg=true;BaseFileSystem$$1.call(this);this.size=1024*1024*size;this.type=type;deprecationMessage(deprecateMsg,HTML5FS2.Name,{size,type})}if(BaseFileSystem$$1)HTML5FS2.__proto__=BaseFileSystem$$1;HTML5FS2.prototype=Object.create(BaseFileSystem$$1&&BaseFileSystem$$1.prototype);HTML5FS2.prototype.constructor=HTML5FS2;HTML5FS2.Create=function Create(opts,cb){var fs4=new HTML5FS2(opts.size,opts.type,false);fs4.allocate(function(e){return e?cb(e):cb(null,fs4)},false)};HTML5FS2.isAvailable=function isAvailable(){return!!_getFS};HTML5FS2.prototype.getName=function getName(){return HTML5FS2.Name};HTML5FS2.prototype.isReadOnly=function isReadOnly(){return false};HTML5FS2.prototype.supportsSymlinks=function supportsSymlinks(){return false};HTML5FS2.prototype.supportsProps=function supportsProps(){return false};HTML5FS2.prototype.supportsSynch=function supportsSynch(){return false};HTML5FS2.prototype.allocate=function allocate(cb,deprecateMsg){var this$1=this;if(cb===void 0)cb=function(){};if(deprecateMsg===void 0)deprecateMsg=true;if(deprecateMsg){console.warn("[HTML5FS] HTML5FS.allocate() is deprecated and will be removed in the next major release. Please use 'HTML5FS.Create({type: "+this.type+", size: "+this.size+"}, cb)' to create and allocate HTML5FS instances.")}var success=function(fs4){this$1.fs=fs4;cb()};var error=function(err){cb(convertError$1(err,"/",true))};if(this.type===global$1.PERSISTENT){_requestQuota(this.type,this.size,function(granted){_getFS(this$1.type,granted,success,error)},error)}else{_getFS(this.type,this.size,success,error)}};HTML5FS2.prototype.empty=function empty(mainCb){this._readdir("/",function(err,entries){if(err){console.error("Failed to empty FS");mainCb(err)}else{var finished=function(er){if(err){console.error("Failed to empty FS");mainCb(err)}else{mainCb()}};var deleteEntry=function(entry,cb){var succ=function(){cb()};var error=function(err2){cb(convertError$1(err2,entry.fullPath,!entry.isDirectory))};if(isDirectoryEntry(entry)){entry.removeRecursively(succ,error)}else{entry.remove(succ,error)}};eachLimit(entries,deleteEntry,finished)}})};HTML5FS2.prototype.rename=function rename(oldPath,newPath,cb){var this$1=this;var semaphore=2;var successCount=0;var root2=this.fs.root;var currentPath=oldPath;var error=function(err){if(--semaphore<=0){cb(convertError$1(err,currentPath,false))}};var success=function(file){if(++successCount===2){return cb(new ApiError(ErrorCode.EINVAL,"Something was identified as both a file and a directory. This should never happen."))}if(oldPath===newPath){return cb()}currentPath=path.dirname(newPath);root2.getDirectory(currentPath,{},function(parentDir){currentPath=path.basename(newPath);file.moveTo(parentDir,currentPath,function(entry){cb()},function(err){if(file.isDirectory){currentPath=newPath;this$1.unlink(newPath,function(e){if(e){error(err)}else{this$1.rename(oldPath,newPath,cb)}})}else{error(err)}})},error)};root2.getFile(oldPath,{},success,error);root2.getDirectory(oldPath,{},success,error)};HTML5FS2.prototype.stat=function stat(path$$1,isLstat,cb){var this$1=this;var opts={create:false};var loadAsFile=function(entry){var fileFromEntry=function(file){var stat2=new Stats(FileType.FILE,file.size);cb(null,stat2)};entry.file(fileFromEntry,failedToLoad)};var loadAsDir=function(dir$$1){var size=4096;var stat2=new Stats(FileType.DIRECTORY,size);cb(null,stat2)};var failedToLoad=function(err){cb(convertError$1(err,path$$1,false))};var failedToLoadAsFile=function(){this$1.fs.root.getDirectory(path$$1,opts,loadAsDir,failedToLoad)};this.fs.root.getFile(path$$1,opts,loadAsFile,failedToLoadAsFile)};HTML5FS2.prototype.open=function open(p,flags,mode,cb){var this$1=this;var error=function(err){if(err.name==="InvalidModificationError"&&flags.isExclusive()){cb(ApiError.EEXIST(p))}else{cb(convertError$1(err,p,false))}};this.fs.root.getFile(p,{create:flags.pathNotExistsAction()===ActionType.CREATE_FILE,exclusive:flags.isExclusive()},function(entry){entry.file(function(file){var reader=new FileReader;reader.onloadend=function(event){var bfsFile=this$1._makeFile(p,entry,flags,file,reader.result);cb(null,bfsFile)};reader.onerror=function(ev){error(reader.error)};reader.readAsArrayBuffer(file)},error)},error)};HTML5FS2.prototype.unlink=function unlink(path$$1,cb){this._remove(path$$1,cb,true)};HTML5FS2.prototype.rmdir=function rmdir(path$$1,cb){var this$1=this;this.readdir(path$$1,function(e,files){if(e){cb(e)}else if(files.length>0){cb(ApiError.ENOTEMPTY(path$$1))}else{this$1._remove(path$$1,cb,false)}})};HTML5FS2.prototype.mkdir=function mkdir(path$$1,mode,cb){var opts={create:true,exclusive:true};var success=function(dir$$1){cb()};var error=function(err){cb(convertError$1(err,path$$1,true))};this.fs.root.getDirectory(path$$1,opts,success,error)};HTML5FS2.prototype.readdir=function readdir(path$$1,cb){this._readdir(path$$1,function(e,entries){if(entries){var rv=[];for(var i2=0,list2=entries;i20){throw ApiError.ENOTEMPTY(p)}else{this.removeEntry(p,true)}};SyncKeyValueFileSystem2.prototype.mkdirSync=function mkdirSync(p,mode){var tx=this.store.beginTransaction("readwrite"),data=Buffer2.from("{}");this.commitNewFile(tx,p,FileType.DIRECTORY,mode,data)};SyncKeyValueFileSystem2.prototype.readdirSync=function readdirSync(p){var tx=this.store.beginTransaction("readonly");return Object.keys(this.getDirListing(tx,p,this.findINode(tx,p)))};SyncKeyValueFileSystem2.prototype._syncSync=function _syncSync(p,data,stats){var tx=this.store.beginTransaction("readwrite"),fileInodeId=this._findINode(tx,path.dirname(p),path.basename(p)),fileInode=this.getINode(tx,p,fileInodeId),inodeChanged=fileInode.update(stats);try{tx.put(fileInode.id,data,true);if(inodeChanged){tx.put(fileInodeId,fileInode.toBuffer(),true)}}catch(e){tx.abort();throw e}tx.commit()};SyncKeyValueFileSystem2.prototype.makeRootDirectory=function makeRootDirectory(){var tx=this.store.beginTransaction("readwrite");if(tx.get(ROOT_NODE_ID)===void 0){var currTime=new Date().getTime(),dirInode=new Inode(GenerateRandomID(),4096,511|FileType.DIRECTORY,currTime,currTime,currTime);tx.put(dirInode.id,getEmptyDirNode(),false);tx.put(ROOT_NODE_ID,dirInode.toBuffer(),false);tx.commit()}};SyncKeyValueFileSystem2.prototype._findINode=function _findINode(tx,parent,filename){var this$1=this;var readDirectory=function(inode){var dirList=this$1.getDirListing(tx,parent,inode);if(dirList[filename]){return dirList[filename]}else{throw ApiError.ENOENT(path.resolve(parent,filename))}};if(parent==="/"){if(filename===""){return ROOT_NODE_ID}else{return readDirectory(this.getINode(tx,parent,ROOT_NODE_ID))}}else{return readDirectory(this.getINode(tx,parent+path.sep+filename,this._findINode(tx,path.dirname(parent),path.basename(parent))))}};SyncKeyValueFileSystem2.prototype.findINode=function findINode(tx,p){return this.getINode(tx,p,this._findINode(tx,path.dirname(p),path.basename(p)))};SyncKeyValueFileSystem2.prototype.getINode=function getINode(tx,p,id){var inode=tx.get(id);if(inode===void 0){throw ApiError.ENOENT(p)}return Inode.fromBuffer(inode)};SyncKeyValueFileSystem2.prototype.getDirListing=function getDirListing(tx,p,inode){if(!inode.isDirectory()){throw ApiError.ENOTDIR(p)}var data=tx.get(inode.id);if(data===void 0){throw ApiError.ENOENT(p)}return JSON.parse(data.toString())};SyncKeyValueFileSystem2.prototype.addNewNode=function addNewNode(tx,data){var retries=0;var currId;while(retries<5){try{currId=GenerateRandomID();tx.put(currId,data,false);return currId}catch(e){}}throw new ApiError(ErrorCode.EIO,"Unable to commit data to key-value store.")};SyncKeyValueFileSystem2.prototype.commitNewFile=function commitNewFile(tx,p,type,mode,data){var parentDir=path.dirname(p),fname=path.basename(p),parentNode=this.findINode(tx,parentDir),dirListing=this.getDirListing(tx,parentDir,parentNode),currTime=new Date().getTime();if(p==="/"){throw ApiError.EEXIST(p)}if(dirListing[fname]){throw ApiError.EEXIST(p)}var fileNode;try{var dataId=this.addNewNode(tx,data);fileNode=new Inode(dataId,data.length,mode|type,currTime,currTime,currTime);var fileNodeId=this.addNewNode(tx,fileNode.toBuffer());dirListing[fname]=fileNodeId;tx.put(parentNode.id,Buffer2.from(JSON.stringify(dirListing)),true)}catch(e){tx.abort();throw e}tx.commit();return fileNode};SyncKeyValueFileSystem2.prototype.removeEntry=function removeEntry(p,isDir){var tx=this.store.beginTransaction("readwrite"),parent=path.dirname(p),parentNode=this.findINode(tx,parent),parentListing=this.getDirListing(tx,parent,parentNode),fileName=path.basename(p);if(!parentListing[fileName]){throw ApiError.ENOENT(p)}var fileNodeId=parentListing[fileName];delete parentListing[fileName];var fileNode=this.getINode(tx,p,fileNodeId);if(!isDir&&fileNode.isDirectory()){throw ApiError.EISDIR(p)}else if(isDir&&!fileNode.isDirectory()){throw ApiError.ENOTDIR(p)}try{tx.del(fileNode.id);tx.del(fileNodeId);tx.put(parentNode.id,Buffer2.from(JSON.stringify(parentListing)),true)}catch(e){tx.abort();throw e}tx.commit()};return SyncKeyValueFileSystem2}(SynchronousFileSystem);var AsyncKeyValueFile=function(PreloadFile$$1){function AsyncKeyValueFile2(_fs,_path,_flag,_stat,contents){PreloadFile$$1.call(this,_fs,_path,_flag,_stat,contents)}if(PreloadFile$$1)AsyncKeyValueFile2.__proto__=PreloadFile$$1;AsyncKeyValueFile2.prototype=Object.create(PreloadFile$$1&&PreloadFile$$1.prototype);AsyncKeyValueFile2.prototype.constructor=AsyncKeyValueFile2;AsyncKeyValueFile2.prototype.sync=function sync(cb){var this$1=this;if(this.isDirty()){this._fs._sync(this.getPath(),this.getBuffer(),this.getStats(),function(e){if(!e){this$1.resetDirty()}cb(e)})}else{cb()}};AsyncKeyValueFile2.prototype.close=function close(cb){this.sync(cb)};return AsyncKeyValueFile2}(PreloadFile);var AsyncKeyValueFileSystem=function(BaseFileSystem$$1){function AsyncKeyValueFileSystem2(){BaseFileSystem$$1.apply(this,arguments)}if(BaseFileSystem$$1)AsyncKeyValueFileSystem2.__proto__=BaseFileSystem$$1;AsyncKeyValueFileSystem2.prototype=Object.create(BaseFileSystem$$1&&BaseFileSystem$$1.prototype);AsyncKeyValueFileSystem2.prototype.constructor=AsyncKeyValueFileSystem2;AsyncKeyValueFileSystem2.isAvailable=function isAvailable(){return true};AsyncKeyValueFileSystem2.prototype.init=function init(store,cb){this.store=store;this.makeRootDirectory(cb)};AsyncKeyValueFileSystem2.prototype.getName=function getName(){return this.store.name()};AsyncKeyValueFileSystem2.prototype.isReadOnly=function isReadOnly(){return false};AsyncKeyValueFileSystem2.prototype.supportsSymlinks=function supportsSymlinks(){return false};AsyncKeyValueFileSystem2.prototype.supportsProps=function supportsProps(){return false};AsyncKeyValueFileSystem2.prototype.supportsSynch=function supportsSynch(){return false};AsyncKeyValueFileSystem2.prototype.empty=function empty(cb){var this$1=this;this.store.clear(function(e){if(noError(e,cb)){this$1.makeRootDirectory(cb)}})};AsyncKeyValueFileSystem2.prototype.rename=function rename(oldPath,newPath,cb){var this$1=this;var tx=this.store.beginTransaction("readwrite");var oldParent=path.dirname(oldPath),oldName=path.basename(oldPath);var newParent=path.dirname(newPath),newName=path.basename(newPath);var inodes={};var lists={};var errorOccurred=false;if((newParent+"/").indexOf(oldPath+"/")===0){return cb(new ApiError(ErrorCode.EBUSY,oldParent))}var theOleSwitcharoo=function(){if(errorOccurred||!lists.hasOwnProperty(oldParent)||!lists.hasOwnProperty(newParent)){return}var oldParentList=lists[oldParent],oldParentINode=inodes[oldParent],newParentList=lists[newParent],newParentINode=inodes[newParent];if(!oldParentList[oldName]){cb(ApiError.ENOENT(oldPath))}else{var fileId=oldParentList[oldName];delete oldParentList[oldName];var completeRename=function(){newParentList[newName]=fileId;tx.put(oldParentINode.id,Buffer2.from(JSON.stringify(oldParentList)),true,function(e){if(noErrorTx(e,tx,cb)){if(oldParent===newParent){tx.commit(cb)}else{tx.put(newParentINode.id,Buffer2.from(JSON.stringify(newParentList)),true,function(e2){if(noErrorTx(e2,tx,cb)){tx.commit(cb)}})}}})};if(newParentList[newName]){this$1.getINode(tx,newPath,newParentList[newName],function(e,inode){if(noErrorTx(e,tx,cb)){if(inode.isFile()){tx.del(inode.id,function(e2){if(noErrorTx(e2,tx,cb)){tx.del(newParentList[newName],function(e3){if(noErrorTx(e3,tx,cb)){completeRename()}})}})}else{tx.abort(function(e2){cb(ApiError.EPERM(newPath))})}}})}else{completeRename()}}};var processInodeAndListings=function(p){this$1.findINodeAndDirListing(tx,p,function(e,node,dirList){if(e){if(!errorOccurred){errorOccurred=true;tx.abort(function(){cb(e)})}}else{inodes[p]=node;lists[p]=dirList;theOleSwitcharoo()}})};processInodeAndListings(oldParent);if(oldParent!==newParent){processInodeAndListings(newParent)}};AsyncKeyValueFileSystem2.prototype.stat=function stat(p,isLstat,cb){var tx=this.store.beginTransaction("readonly");this.findINode(tx,p,function(e,inode){if(noError(e,cb)){cb(null,inode.toStats())}})};AsyncKeyValueFileSystem2.prototype.createFile=function createFile(p,flag,mode,cb){var this$1=this;var tx=this.store.beginTransaction("readwrite"),data=emptyBuffer();this.commitNewFile(tx,p,FileType.FILE,mode,data,function(e,newFile){if(noError(e,cb)){cb(null,new AsyncKeyValueFile(this$1,p,flag,newFile.toStats(),data))}})};AsyncKeyValueFileSystem2.prototype.openFile=function openFile(p,flag,cb){var this$1=this;var tx=this.store.beginTransaction("readonly");this.findINode(tx,p,function(e,inode){if(noError(e,cb)){tx.get(inode.id,function(e2,data){if(noError(e2,cb)){if(data===void 0){cb(ApiError.ENOENT(p))}else{cb(null,new AsyncKeyValueFile(this$1,p,flag,inode.toStats(),data))}}})}})};AsyncKeyValueFileSystem2.prototype.unlink=function unlink(p,cb){this.removeEntry(p,false,cb)};AsyncKeyValueFileSystem2.prototype.rmdir=function rmdir(p,cb){var this$1=this;this.readdir(p,function(err,files){if(err){cb(err)}else if(files.length>0){cb(ApiError.ENOTEMPTY(p))}else{this$1.removeEntry(p,true,cb)}})};AsyncKeyValueFileSystem2.prototype.mkdir=function mkdir(p,mode,cb){var tx=this.store.beginTransaction("readwrite"),data=Buffer2.from("{}");this.commitNewFile(tx,p,FileType.DIRECTORY,mode,data,cb)};AsyncKeyValueFileSystem2.prototype.readdir=function readdir(p,cb){var this$1=this;var tx=this.store.beginTransaction("readonly");this.findINode(tx,p,function(e,inode){if(noError(e,cb)){this$1.getDirListing(tx,p,inode,function(e2,dirListing){if(noError(e2,cb)){cb(null,Object.keys(dirListing))}})}})};AsyncKeyValueFileSystem2.prototype._sync=function _sync(p,data,stats,cb){var this$1=this;var tx=this.store.beginTransaction("readwrite");this._findINode(tx,path.dirname(p),path.basename(p),function(e,fileInodeId){if(noErrorTx(e,tx,cb)){this$1.getINode(tx,p,fileInodeId,function(e2,fileInode){if(noErrorTx(e2,tx,cb)){var inodeChanged=fileInode.update(stats);tx.put(fileInode.id,data,true,function(e3){if(noErrorTx(e3,tx,cb)){if(inodeChanged){tx.put(fileInodeId,fileInode.toBuffer(),true,function(e4){if(noErrorTx(e4,tx,cb)){tx.commit(cb)}})}else{tx.commit(cb)}}})}})}})};AsyncKeyValueFileSystem2.prototype.makeRootDirectory=function makeRootDirectory(cb){var tx=this.store.beginTransaction("readwrite");tx.get(ROOT_NODE_ID,function(e,data){if(e||data===void 0){var currTime=new Date().getTime(),dirInode=new Inode(GenerateRandomID(),4096,511|FileType.DIRECTORY,currTime,currTime,currTime);tx.put(dirInode.id,getEmptyDirNode(),false,function(e2){if(noErrorTx(e2,tx,cb)){tx.put(ROOT_NODE_ID,dirInode.toBuffer(),false,function(e3){if(e3){tx.abort(function(){cb(e3)})}else{tx.commit(cb)}})}})}else{tx.commit(cb)}})};AsyncKeyValueFileSystem2.prototype._findINode=function _findINode(tx,parent,filename,cb){var this$1=this;var handleDirectoryListings=function(e,inode,dirList){if(e){cb(e)}else if(dirList[filename]){cb(null,dirList[filename])}else{cb(ApiError.ENOENT(path.resolve(parent,filename)))}};if(parent==="/"){if(filename===""){cb(null,ROOT_NODE_ID)}else{this.getINode(tx,parent,ROOT_NODE_ID,function(e,inode){if(noError(e,cb)){this$1.getDirListing(tx,parent,inode,function(e2,dirList){handleDirectoryListings(e2,inode,dirList)})}})}}else{this.findINodeAndDirListing(tx,parent,handleDirectoryListings)}};AsyncKeyValueFileSystem2.prototype.findINode=function findINode(tx,p,cb){var this$1=this;this._findINode(tx,path.dirname(p),path.basename(p),function(e,id){if(noError(e,cb)){this$1.getINode(tx,p,id,cb)}})};AsyncKeyValueFileSystem2.prototype.getINode=function getINode(tx,p,id,cb){tx.get(id,function(e,data){if(noError(e,cb)){if(data===void 0){cb(ApiError.ENOENT(p))}else{cb(null,Inode.fromBuffer(data))}}})};AsyncKeyValueFileSystem2.prototype.getDirListing=function getDirListing(tx,p,inode,cb){if(!inode.isDirectory()){cb(ApiError.ENOTDIR(p))}else{tx.get(inode.id,function(e,data){if(noError(e,cb)){try{cb(null,JSON.parse(data.toString()))}catch(e2){cb(ApiError.ENOENT(p))}}})}};AsyncKeyValueFileSystem2.prototype.findINodeAndDirListing=function findINodeAndDirListing(tx,p,cb){var this$1=this;this.findINode(tx,p,function(e,inode){if(noError(e,cb)){this$1.getDirListing(tx,p,inode,function(e2,listing){if(noError(e2,cb)){cb(null,inode,listing)}})}})};AsyncKeyValueFileSystem2.prototype.addNewNode=function addNewNode(tx,data,cb){var retries=0,currId;var reroll=function(){if(++retries===5){cb(new ApiError(ErrorCode.EIO,"Unable to commit data to key-value store."))}else{currId=GenerateRandomID();tx.put(currId,data,false,function(e,committed){if(e||!committed){reroll()}else{cb(null,currId)}})}};reroll()};AsyncKeyValueFileSystem2.prototype.commitNewFile=function commitNewFile(tx,p,type,mode,data,cb){var this$1=this;var parentDir=path.dirname(p),fname=path.basename(p),currTime=new Date().getTime();if(p==="/"){return cb(ApiError.EEXIST(p))}this.findINodeAndDirListing(tx,parentDir,function(e,parentNode,dirListing){if(noErrorTx(e,tx,cb)){if(dirListing[fname]){tx.abort(function(){cb(ApiError.EEXIST(p))})}else{this$1.addNewNode(tx,data,function(e2,dataId){if(noErrorTx(e2,tx,cb)){var fileInode=new Inode(dataId,data.length,mode|type,currTime,currTime,currTime);this$1.addNewNode(tx,fileInode.toBuffer(),function(e3,fileInodeId){if(noErrorTx(e3,tx,cb)){dirListing[fname]=fileInodeId;tx.put(parentNode.id,Buffer2.from(JSON.stringify(dirListing)),true,function(e4){if(noErrorTx(e4,tx,cb)){tx.commit(function(e5){if(noErrorTx(e5,tx,cb)){cb(null,fileInode)}})}})}})}})}}})};AsyncKeyValueFileSystem2.prototype.removeEntry=function removeEntry(p,isDir,cb){var this$1=this;var tx=this.store.beginTransaction("readwrite"),parent=path.dirname(p),fileName=path.basename(p);this.findINodeAndDirListing(tx,parent,function(e,parentNode,parentListing){if(noErrorTx(e,tx,cb)){if(!parentListing[fileName]){tx.abort(function(){cb(ApiError.ENOENT(p))})}else{var fileNodeId=parentListing[fileName];delete parentListing[fileName];this$1.getINode(tx,p,fileNodeId,function(e2,fileNode){if(noErrorTx(e2,tx,cb)){if(!isDir&&fileNode.isDirectory()){tx.abort(function(){cb(ApiError.EISDIR(p))})}else if(isDir&&!fileNode.isDirectory()){tx.abort(function(){cb(ApiError.ENOTDIR(p))})}else{tx.del(fileNode.id,function(e3){if(noErrorTx(e3,tx,cb)){tx.del(fileNodeId,function(e4){if(noErrorTx(e4,tx,cb)){tx.put(parentNode.id,Buffer2.from(JSON.stringify(parentListing)),true,function(e5){if(noErrorTx(e5,tx,cb)){tx.commit(cb)}})}})}})}}})}}})};return AsyncKeyValueFileSystem2}(BaseFileSystem);var InMemoryStore=function InMemoryStore2(){this.store={}};InMemoryStore.prototype.name=function name(){return InMemoryFileSystem.Name};InMemoryStore.prototype.clear=function clear(){this.store={}};InMemoryStore.prototype.beginTransaction=function beginTransaction(type){return new SimpleSyncRWTransaction(this)};InMemoryStore.prototype.get=function get(key){return this.store[key]};InMemoryStore.prototype.put=function put(key,data,overwrite){if(!overwrite&&this.store.hasOwnProperty(key)){return false}this.store[key]=data;return true};InMemoryStore.prototype.del=function del(key){delete this.store[key]};var InMemoryFileSystem=function(SyncKeyValueFileSystem$$1){function InMemoryFileSystem2(){SyncKeyValueFileSystem$$1.call(this,{store:new InMemoryStore})}if(SyncKeyValueFileSystem$$1)InMemoryFileSystem2.__proto__=SyncKeyValueFileSystem$$1;InMemoryFileSystem2.prototype=Object.create(SyncKeyValueFileSystem$$1&&SyncKeyValueFileSystem$$1.prototype);InMemoryFileSystem2.prototype.constructor=InMemoryFileSystem2;InMemoryFileSystem2.Create=function Create(options,cb){cb(null,new InMemoryFileSystem2)};return InMemoryFileSystem2}(SyncKeyValueFileSystem);InMemoryFileSystem.Name="InMemory";InMemoryFileSystem.Options={};var indexedDB=global$1.indexedDB||global$1.mozIndexedDB||global$1.webkitIndexedDB||global$1.msIndexedDB;function convertError$2(e,message){if(message===void 0)message=e.toString();switch(e.name){case"NotFoundError":return new ApiError(ErrorCode.ENOENT,message);case"QuotaExceededError":return new ApiError(ErrorCode.ENOSPC,message);default:return new ApiError(ErrorCode.EIO,message)}}function onErrorHandler(cb,code,message){if(code===void 0)code=ErrorCode.EIO;if(message===void 0)message=null;return function(e){e.preventDefault();cb(new ApiError(code,message!==null?message:void 0))}}var IndexedDBROTransaction=function IndexedDBROTransaction2(tx,store){this.tx=tx;this.store=store};IndexedDBROTransaction.prototype.get=function get(key,cb){try{var r=this.store.get(key);r.onerror=onErrorHandler(cb);r.onsuccess=function(event){var result=event.target.result;if(result===void 0){cb(null,result)}else{cb(null,arrayBuffer2Buffer(result))}}}catch(e){cb(convertError$2(e))}};var IndexedDBRWTransaction=function(IndexedDBROTransaction2){function IndexedDBRWTransaction2(tx,store){IndexedDBROTransaction2.call(this,tx,store)}if(IndexedDBROTransaction2)IndexedDBRWTransaction2.__proto__=IndexedDBROTransaction2;IndexedDBRWTransaction2.prototype=Object.create(IndexedDBROTransaction2&&IndexedDBROTransaction2.prototype);IndexedDBRWTransaction2.prototype.constructor=IndexedDBRWTransaction2;IndexedDBRWTransaction2.prototype.put=function put(key,data,overwrite,cb){try{var arraybuffer=buffer2ArrayBuffer(data);var r;if(overwrite){r=this.store.put(arraybuffer,key)}else{r=this.store.add(arraybuffer,key)}r.onerror=onErrorHandler(cb);r.onsuccess=function(event){cb(null,true)}}catch(e){cb(convertError$2(e))}};IndexedDBRWTransaction2.prototype.del=function del(key,cb){try{var r=this.store["delete"](key);r.onerror=onErrorHandler(cb);r.onsuccess=function(event){cb()}}catch(e){cb(convertError$2(e))}};IndexedDBRWTransaction2.prototype.commit=function commit(cb){setTimeout(cb,0)};IndexedDBRWTransaction2.prototype.abort=function abort(cb){var _e=null;try{this.tx.abort()}catch(e){_e=convertError$2(e)}finally{cb(_e)}};return IndexedDBRWTransaction2}(IndexedDBROTransaction);var IndexedDBStore=function IndexedDBStore2(cb,storeName){var this$1=this;if(storeName===void 0)storeName="browserfs";this.storeName=storeName;var openReq=indexedDB.open(this.storeName,1);openReq.onupgradeneeded=function(event){var db=event.target.result;if(db.objectStoreNames.contains(this$1.storeName)){db.deleteObjectStore(this$1.storeName)}db.createObjectStore(this$1.storeName)};openReq.onsuccess=function(event){this$1.db=event.target.result;cb(null,this$1)};openReq.onerror=onErrorHandler(cb,ErrorCode.EACCES)};IndexedDBStore.prototype.name=function name(){return IndexedDBFileSystem.Name+" - "+this.storeName};IndexedDBStore.prototype.clear=function clear(cb){try{var tx=this.db.transaction(this.storeName,"readwrite"),objectStore=tx.objectStore(this.storeName),r=objectStore.clear();r.onsuccess=function(event){setTimeout(cb,0)};r.onerror=onErrorHandler(cb)}catch(e){cb(convertError$2(e))}};IndexedDBStore.prototype.beginTransaction=function beginTransaction(type){if(type===void 0)type="readonly";var tx=this.db.transaction(this.storeName,type),objectStore=tx.objectStore(this.storeName);if(type==="readwrite"){return new IndexedDBRWTransaction(tx,objectStore)}else if(type==="readonly"){return new IndexedDBROTransaction(tx,objectStore)}else{throw new ApiError(ErrorCode.EINVAL,"Invalid transaction type.")}};var IndexedDBFileSystem=function(AsyncKeyValueFileSystem$$1){function IndexedDBFileSystem2(cb,storeName,deprecateMsg){var this$1=this;if(deprecateMsg===void 0)deprecateMsg=true;AsyncKeyValueFileSystem$$1.call(this);this.store=new IndexedDBStore(function(e){if(e){cb(e)}else{this$1.init(this$1.store,function(e2){cb(e2,this$1)})}},storeName);deprecationMessage(deprecateMsg,IndexedDBFileSystem2.Name,{storeName})}if(AsyncKeyValueFileSystem$$1)IndexedDBFileSystem2.__proto__=AsyncKeyValueFileSystem$$1;IndexedDBFileSystem2.prototype=Object.create(AsyncKeyValueFileSystem$$1&&AsyncKeyValueFileSystem$$1.prototype);IndexedDBFileSystem2.prototype.constructor=IndexedDBFileSystem2;IndexedDBFileSystem2.Create=function Create(opts,cb){new IndexedDBFileSystem2(cb,opts.storeName,false)};IndexedDBFileSystem2.isAvailable=function isAvailable(){try{return typeof indexedDB!=="undefined"&&null!==indexedDB.open("__browserfs_test__")}catch(e){return false}};return IndexedDBFileSystem2}(AsyncKeyValueFileSystem);IndexedDBFileSystem.Name="IndexedDB";IndexedDBFileSystem.Options={storeName:{type:"string",optional:true,description:"The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name."}};var supportsBinaryString=false;var binaryEncoding;try{global$1.localStorage.setItem("__test__",String.fromCharCode(55296));supportsBinaryString=global$1.localStorage.getItem("__test__")===String.fromCharCode(55296)}catch(e){supportsBinaryString=false}binaryEncoding=supportsBinaryString?"binary_string":"binary_string_ie";if(!Buffer2.isEncoding(binaryEncoding)){binaryEncoding="base64"}var LocalStorageStore=function LocalStorageStore2(){};LocalStorageStore.prototype.name=function name(){return LocalStorageFileSystem.Name};LocalStorageStore.prototype.clear=function clear(){global$1.localStorage.clear()};LocalStorageStore.prototype.beginTransaction=function beginTransaction(type){return new SimpleSyncRWTransaction(this)};LocalStorageStore.prototype.get=function get(key){try{var data=global$1.localStorage.getItem(key);if(data!==null){return Buffer2.from(data,binaryEncoding)}}catch(e){}return void 0};LocalStorageStore.prototype.put=function put(key,data,overwrite){try{if(!overwrite&&global$1.localStorage.getItem(key)!==null){return false}global$1.localStorage.setItem(key,data.toString(binaryEncoding));return true}catch(e){throw new ApiError(ErrorCode.ENOSPC,"LocalStorage is full.")}};LocalStorageStore.prototype.del=function del(key){try{global$1.localStorage.removeItem(key)}catch(e){throw new ApiError(ErrorCode.EIO,"Unable to delete key "+key+": "+e)}};var LocalStorageFileSystem=function(SyncKeyValueFileSystem$$1){function LocalStorageFileSystem2(){SyncKeyValueFileSystem$$1.call(this,{store:new LocalStorageStore})}if(SyncKeyValueFileSystem$$1)LocalStorageFileSystem2.__proto__=SyncKeyValueFileSystem$$1;LocalStorageFileSystem2.prototype=Object.create(SyncKeyValueFileSystem$$1&&SyncKeyValueFileSystem$$1.prototype);LocalStorageFileSystem2.prototype.constructor=LocalStorageFileSystem2;LocalStorageFileSystem2.Create=function Create(options,cb){cb(null,new LocalStorageFileSystem2)};LocalStorageFileSystem2.isAvailable=function isAvailable(){return typeof global$1.localStorage!=="undefined"};return LocalStorageFileSystem2}(SyncKeyValueFileSystem);LocalStorageFileSystem.Name="LocalStorage";LocalStorageFileSystem.Options={};var MountableFileSystem=function(BaseFileSystem$$1){function MountableFileSystem2(){BaseFileSystem$$1.call(this);this.mountList=[];this.mntMap={};this.rootFs=new InMemoryFileSystem}if(BaseFileSystem$$1)MountableFileSystem2.__proto__=BaseFileSystem$$1;MountableFileSystem2.prototype=Object.create(BaseFileSystem$$1&&BaseFileSystem$$1.prototype);MountableFileSystem2.prototype.constructor=MountableFileSystem2;MountableFileSystem2.Create=function Create(opts,cb){var fs4=new MountableFileSystem2;Object.keys(opts).forEach(function(mountPoint){fs4.mount(mountPoint,opts[mountPoint])});cb(null,fs4)};MountableFileSystem2.isAvailable=function isAvailable(){return true};MountableFileSystem2.prototype.mount=function mount(mountPoint,fs4){if(mountPoint[0]!=="/"){mountPoint="/"+mountPoint}mountPoint=path.resolve(mountPoint);if(this.mntMap[mountPoint]){throw new ApiError(ErrorCode.EINVAL,"Mount point "+mountPoint+" is already taken.")}mkdirpSync(mountPoint,511,this.rootFs);this.mntMap[mountPoint]=fs4;this.mountList.push(mountPoint);this.mountList=this.mountList.sort(function(a,b){return b.length-a.length})};MountableFileSystem2.prototype.umount=function umount(mountPoint){var this$1=this;if(mountPoint[0]!=="/"){mountPoint="/"+mountPoint}mountPoint=path.resolve(mountPoint);if(!this.mntMap[mountPoint]){throw new ApiError(ErrorCode.EINVAL,"Mount point "+mountPoint+" is already unmounted.")}delete this.mntMap[mountPoint];this.mountList.splice(this.mountList.indexOf(mountPoint),1);while(mountPoint!=="/"){if(this$1.rootFs.readdirSync(mountPoint).length===0){this$1.rootFs.rmdirSync(mountPoint);mountPoint=path.dirname(mountPoint)}else{break}}};MountableFileSystem2.prototype._getFs=function _getFs(path$$1){var this$1=this;var mountList=this.mountList,len=mountList.length;for(var i2=0;i21?mountPoint.length:0);if(path$$1===""){path$$1="/"}return{fs:this$1.mntMap[mountPoint],path:path$$1}}}return{fs:this.rootFs,path:path$$1}};MountableFileSystem2.prototype.getName=function getName(){return MountableFileSystem2.Name};MountableFileSystem2.prototype.diskSpace=function diskSpace(path$$1,cb){cb(0,0)};MountableFileSystem2.prototype.isReadOnly=function isReadOnly(){return false};MountableFileSystem2.prototype.supportsLinks=function supportsLinks(){return false};MountableFileSystem2.prototype.supportsProps=function supportsProps(){return false};MountableFileSystem2.prototype.supportsSynch=function supportsSynch(){return true};MountableFileSystem2.prototype.standardizeError=function standardizeError(err,path$$1,realPath){var index=err.message.indexOf(path$$1);if(index!==-1){err.message=err.message.substr(0,index)+realPath+err.message.substr(index+path$$1.length);err.path=realPath}return err};MountableFileSystem2.prototype.rename=function rename(oldPath,newPath,cb){var this$1=this;var fs1rv=this._getFs(oldPath);var fs2rv=this._getFs(newPath);if(fs1rv.fs===fs2rv.fs){return fs1rv.fs.rename(fs1rv.path,fs2rv.path,function(e){if(e){this$1.standardizeError(this$1.standardizeError(e,fs1rv.path,oldPath),fs2rv.path,newPath)}cb(e)})}return _fsMock.readFile(oldPath,function(err,data){if(err){return cb(err)}_fsMock.writeFile(newPath,data,function(err2){if(err2){return cb(err2)}_fsMock.unlink(oldPath,cb)})})};MountableFileSystem2.prototype.renameSync=function renameSync(oldPath,newPath){var fs1rv=this._getFs(oldPath);var fs2rv=this._getFs(newPath);if(fs1rv.fs===fs2rv.fs){try{return fs1rv.fs.renameSync(fs1rv.path,fs2rv.path)}catch(e){this.standardizeError(this.standardizeError(e,fs1rv.path,oldPath),fs2rv.path,newPath);throw e}}var data=_fsMock.readFileSync(oldPath);_fsMock.writeFileSync(newPath,data);return _fsMock.unlinkSync(oldPath)};MountableFileSystem2.prototype.readdirSync=function readdirSync(p){var fsInfo=this._getFs(p);var rv=null;if(fsInfo.fs!==this.rootFs){try{rv=this.rootFs.readdirSync(p)}catch(e){}}try{var rv2=fsInfo.fs.readdirSync(fsInfo.path);if(rv===null){return rv2}else{return rv2.concat(rv.filter(function(val){return rv2.indexOf(val)===-1}))}}catch(e){if(rv===null){throw this.standardizeError(e,fsInfo.path,p)}else{return rv}}};MountableFileSystem2.prototype.readdir=function readdir(p,cb){var this$1=this;var fsInfo=this._getFs(p);fsInfo.fs.readdir(fsInfo.path,function(err,files){if(fsInfo.fs!==this$1.rootFs){try{var rv=this$1.rootFs.readdirSync(p);if(files){files=files.concat(rv.filter(function(val){return files.indexOf(val)===-1}))}else{files=rv}}catch(e){if(err){return cb(this$1.standardizeError(err,fsInfo.path,p))}}}else if(err){return cb(this$1.standardizeError(err,fsInfo.path,p))}cb(null,files)})};MountableFileSystem2.prototype.rmdirSync=function rmdirSync(p){var fsInfo=this._getFs(p);if(this._containsMountPt(p)){throw ApiError.ENOTEMPTY(p)}else{try{fsInfo.fs.rmdirSync(fsInfo.path)}catch(e){throw this.standardizeError(e,fsInfo.path,p)}}};MountableFileSystem2.prototype.rmdir=function rmdir(p,cb){var this$1=this;var fsInfo=this._getFs(p);if(this._containsMountPt(p)){cb(ApiError.ENOTEMPTY(p))}else{fsInfo.fs.rmdir(fsInfo.path,function(err){cb(err?this$1.standardizeError(err,fsInfo.path,p):null)})}};MountableFileSystem2.prototype._containsMountPt=function _containsMountPt(p){var mountPoints=this.mountList,len=mountPoints.length;for(var i2=0;i2=p.length&&pt.slice(0,p.length)===p){return true}}return false};return MountableFileSystem2}(BaseFileSystem);MountableFileSystem.Name="MountableFileSystem";MountableFileSystem.Options={};function defineFcn(name,isSync,numArgs){if(isSync){return function(){var args=[],len=arguments.length;while(len--)args[len]=arguments[len];var path$$1=args[0];var rv=this._getFs(path$$1);args[0]=rv.path;try{return rv.fs[name].apply(rv.fs,args)}catch(e){this.standardizeError(e,rv.path,path$$1);throw e}}}else{return function(){var this$1=this;var args=[],len=arguments.length;while(len--)args[len]=arguments[len];var path$$1=args[0];var rv=this._getFs(path$$1);args[0]=rv.path;if(typeof args[args.length-1]==="function"){var cb=args[args.length-1];args[args.length-1]=function(){var args2=[],len2=arguments.length;while(len2--)args2[len2]=arguments[len2];if(args2.length>0&&args2[0]instanceof ApiError){this$1.standardizeError(args2[0],rv.path,path$$1)}cb.apply(null,args2)}}return rv.fs[name].apply(rv.fs,args)}}}var fsCmdMap=[["exists","unlink","readlink"],["stat","mkdir","realpath","truncate"],["open","readFile","chmod","utimes"],["chown"],["writeFile","appendFile"]];for(var i=0;i0){var fn=timeouts.shift();return fn()}}};if(gScope.addEventListener){gScope.addEventListener("message",handleMessage,true)}else{gScope.attachEvent("onmessage",handleMessage)}}else if(gScope.MessageChannel){var channel=new gScope.MessageChannel;channel.port1.onmessage=function(event){if(timeouts.length>0){return timeouts.shift()()}};bfsSetImmediate=function(fn){timeouts.push(fn);channel.port2.postMessage("")}}else{bfsSetImmediate=function(fn){return setTimeout(fn,0)}}}var setImmediate$3=bfsSetImmediate;var Mutex=function Mutex2(){this._locked=false;this._waiters=[]};Mutex.prototype.lock=function lock(cb){if(this._locked){this._waiters.push(cb);return}this._locked=true;cb()};Mutex.prototype.unlock=function unlock(){if(!this._locked){throw new Error("unlock of a non-locked mutex")}var next=this._waiters.shift();if(next){setImmediate$3(next);return}this._locked=false};Mutex.prototype.tryLock=function tryLock(){if(this._locked){return false}this._locked=true;return true};Mutex.prototype.isLocked=function isLocked(){return this._locked};var LockedFS=function LockedFS2(fs4){this._fs=fs4;this._mu=new Mutex};LockedFS.prototype.getName=function getName(){return"LockedFS<"+this._fs.getName()+">"};LockedFS.prototype.getFSUnlocked=function getFSUnlocked(){return this._fs};LockedFS.prototype.initialize=function initialize3(cb){this._fs.initialize(cb)};LockedFS.prototype.diskSpace=function diskSpace(p,cb){this._fs.diskSpace(p,cb)};LockedFS.prototype.isReadOnly=function isReadOnly(){return this._fs.isReadOnly()};LockedFS.prototype.supportsLinks=function supportsLinks(){return this._fs.supportsLinks()};LockedFS.prototype.supportsProps=function supportsProps(){return this._fs.supportsProps()};LockedFS.prototype.supportsSynch=function supportsSynch(){return this._fs.supportsSynch()};LockedFS.prototype.rename=function rename(oldPath,newPath,cb){var this$1=this;this._mu.lock(function(){this$1._fs.rename(oldPath,newPath,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.renameSync=function renameSync(oldPath,newPath){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.renameSync(oldPath,newPath)};LockedFS.prototype.stat=function stat(p,isLstat,cb){var this$1=this;this._mu.lock(function(){this$1._fs.stat(p,isLstat,function(err,stat2){this$1._mu.unlock();cb(err,stat2)})})};LockedFS.prototype.statSync=function statSync(p,isLstat){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.statSync(p,isLstat)};LockedFS.prototype.open=function open(p,flag,mode,cb){var this$1=this;this._mu.lock(function(){this$1._fs.open(p,flag,mode,function(err,fd){this$1._mu.unlock();cb(err,fd)})})};LockedFS.prototype.openSync=function openSync(p,flag,mode){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.openSync(p,flag,mode)};LockedFS.prototype.unlink=function unlink(p,cb){var this$1=this;this._mu.lock(function(){this$1._fs.unlink(p,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.unlinkSync=function unlinkSync(p){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.unlinkSync(p)};LockedFS.prototype.rmdir=function rmdir(p,cb){var this$1=this;this._mu.lock(function(){this$1._fs.rmdir(p,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.rmdirSync=function rmdirSync(p){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.rmdirSync(p)};LockedFS.prototype.mkdir=function mkdir(p,mode,cb){var this$1=this;this._mu.lock(function(){this$1._fs.mkdir(p,mode,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.mkdirSync=function mkdirSync(p,mode){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.mkdirSync(p,mode)};LockedFS.prototype.readdir=function readdir(p,cb){var this$1=this;this._mu.lock(function(){this$1._fs.readdir(p,function(err,files){this$1._mu.unlock();cb(err,files)})})};LockedFS.prototype.readdirSync=function readdirSync(p){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.readdirSync(p)};LockedFS.prototype.exists=function exists2(p,cb){var this$1=this;this._mu.lock(function(){this$1._fs.exists(p,function(exists3){this$1._mu.unlock();cb(exists3)})})};LockedFS.prototype.existsSync=function existsSync(p){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.existsSync(p)};LockedFS.prototype.realpath=function realpath(p,cache,cb){var this$1=this;this._mu.lock(function(){this$1._fs.realpath(p,cache,function(err,resolvedPath){this$1._mu.unlock();cb(err,resolvedPath)})})};LockedFS.prototype.realpathSync=function realpathSync(p,cache){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.realpathSync(p,cache)};LockedFS.prototype.truncate=function truncate(p,len,cb){var this$1=this;this._mu.lock(function(){this$1._fs.truncate(p,len,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.truncateSync=function truncateSync(p,len){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.truncateSync(p,len)};LockedFS.prototype.readFile=function readFile2(fname,encoding,flag,cb){var this$1=this;this._mu.lock(function(){this$1._fs.readFile(fname,encoding,flag,function(err,data){this$1._mu.unlock();cb(err,data)})})};LockedFS.prototype.readFileSync=function readFileSync(fname,encoding,flag){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.readFileSync(fname,encoding,flag)};LockedFS.prototype.writeFile=function writeFile2(fname,data,encoding,flag,mode,cb){var this$1=this;this._mu.lock(function(){this$1._fs.writeFile(fname,data,encoding,flag,mode,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.writeFileSync=function writeFileSync(fname,data,encoding,flag,mode){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.writeFileSync(fname,data,encoding,flag,mode)};LockedFS.prototype.appendFile=function appendFile3(fname,data,encoding,flag,mode,cb){var this$1=this;this._mu.lock(function(){this$1._fs.appendFile(fname,data,encoding,flag,mode,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.appendFileSync=function appendFileSync(fname,data,encoding,flag,mode){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.appendFileSync(fname,data,encoding,flag,mode)};LockedFS.prototype.chmod=function chmod(p,isLchmod,mode,cb){var this$1=this;this._mu.lock(function(){this$1._fs.chmod(p,isLchmod,mode,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.chmodSync=function chmodSync(p,isLchmod,mode){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.chmodSync(p,isLchmod,mode)};LockedFS.prototype.chown=function chown(p,isLchown,uid,gid,cb){var this$1=this;this._mu.lock(function(){this$1._fs.chown(p,isLchown,uid,gid,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.chownSync=function chownSync(p,isLchown,uid,gid){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.chownSync(p,isLchown,uid,gid)};LockedFS.prototype.utimes=function utimes(p,atime,mtime,cb){var this$1=this;this._mu.lock(function(){this$1._fs.utimes(p,atime,mtime,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.utimesSync=function utimesSync(p,atime,mtime){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.utimesSync(p,atime,mtime)};LockedFS.prototype.link=function link(srcpath,dstpath,cb){var this$1=this;this._mu.lock(function(){this$1._fs.link(srcpath,dstpath,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.linkSync=function linkSync(srcpath,dstpath){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.linkSync(srcpath,dstpath)};LockedFS.prototype.symlink=function symlink(srcpath,dstpath,type,cb){var this$1=this;this._mu.lock(function(){this$1._fs.symlink(srcpath,dstpath,type,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.symlinkSync=function symlinkSync(srcpath,dstpath,type){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.symlinkSync(srcpath,dstpath,type)};LockedFS.prototype.readlink=function readlink(p,cb){var this$1=this;this._mu.lock(function(){this$1._fs.readlink(p,function(err,linkString){this$1._mu.unlock();cb(err,linkString)})})};LockedFS.prototype.readlinkSync=function readlinkSync(p){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.readlinkSync(p)};var deletionLogPath="/.deletedFiles.log";function makeModeWritable(mode){return 146|mode}function getFlag(f){return FileFlag.getFileFlag(f)}var OverlayFile=function(PreloadFile$$1){function OverlayFile2(fs4,path$$1,flag,stats,data){PreloadFile$$1.call(this,fs4,path$$1,flag,stats,data)}if(PreloadFile$$1)OverlayFile2.__proto__=PreloadFile$$1;OverlayFile2.prototype=Object.create(PreloadFile$$1&&PreloadFile$$1.prototype);OverlayFile2.prototype.constructor=OverlayFile2;OverlayFile2.prototype.sync=function sync(cb){var this$1=this;if(!this.isDirty()){cb(null);return}this._fs._syncAsync(this,function(err){this$1.resetDirty();cb(err)})};OverlayFile2.prototype.syncSync=function syncSync(){if(this.isDirty()){this._fs._syncSync(this);this.resetDirty()}};OverlayFile2.prototype.close=function close(cb){this.sync(cb)};OverlayFile2.prototype.closeSync=function closeSync(){this.syncSync()};return OverlayFile2}(PreloadFile);var UnlockedOverlayFS=function(BaseFileSystem$$1){function UnlockedOverlayFS2(writable,readable){BaseFileSystem$$1.call(this);this._isInitialized=false;this._initializeCallbacks=[];this._deletedFiles={};this._deleteLog="";this._deleteLogUpdatePending=false;this._deleteLogUpdateNeeded=false;this._deleteLogError=null;this._writable=writable;this._readable=readable;if(this._writable.isReadOnly()){throw new ApiError(ErrorCode.EINVAL,"Writable file system must be writable.")}}if(BaseFileSystem$$1)UnlockedOverlayFS2.__proto__=BaseFileSystem$$1;UnlockedOverlayFS2.prototype=Object.create(BaseFileSystem$$1&&BaseFileSystem$$1.prototype);UnlockedOverlayFS2.prototype.constructor=UnlockedOverlayFS2;UnlockedOverlayFS2.isAvailable=function isAvailable(){return true};UnlockedOverlayFS2.prototype.getOverlayedFileSystems=function getOverlayedFileSystems(){return{readable:this._readable,writable:this._writable}};UnlockedOverlayFS2.prototype._syncAsync=function _syncAsync(file,cb){var this$1=this;this.createParentDirectoriesAsync(file.getPath(),function(err){if(err){return cb(err)}this$1._writable.writeFile(file.getPath(),file.getBuffer(),null,getFlag("w"),file.getStats().mode,cb)})};UnlockedOverlayFS2.prototype._syncSync=function _syncSync(file){this.createParentDirectories(file.getPath());this._writable.writeFileSync(file.getPath(),file.getBuffer(),null,getFlag("w"),file.getStats().mode)};UnlockedOverlayFS2.prototype.getName=function getName(){return OverlayFS.Name};UnlockedOverlayFS2.prototype.initialize=function initialize3(cb){var this$1=this;var callbackArray=this._initializeCallbacks;var end=function(e){this$1._isInitialized=!e;this$1._initializeCallbacks=[];callbackArray.forEach(function(cb2){return cb2(e)})};if(this._isInitialized){return cb()}callbackArray.push(cb);if(callbackArray.length!==1){return}this._writable.readFile(deletionLogPath,"utf8",getFlag("r"),function(err,data){if(err){if(err.errno!==ErrorCode.ENOENT){return end(err)}}else{this$1._deleteLog=data}this$1._reparseDeletionLog();end()})};UnlockedOverlayFS2.prototype.isReadOnly=function isReadOnly(){return false};UnlockedOverlayFS2.prototype.supportsSynch=function supportsSynch(){return this._readable.supportsSynch()&&this._writable.supportsSynch()};UnlockedOverlayFS2.prototype.supportsLinks=function supportsLinks(){return false};UnlockedOverlayFS2.prototype.supportsProps=function supportsProps(){return this._readable.supportsProps()&&this._writable.supportsProps()};UnlockedOverlayFS2.prototype.getDeletionLog=function getDeletionLog(){return this._deleteLog};UnlockedOverlayFS2.prototype.restoreDeletionLog=function restoreDeletionLog(log){this._deleteLog=log;this._reparseDeletionLog();this.updateLog("")};UnlockedOverlayFS2.prototype.rename=function rename(oldPath,newPath,cb){var this$1=this;if(!this.checkInitAsync(cb)||this.checkPathAsync(oldPath,cb)||this.checkPathAsync(newPath,cb)){return}if(oldPath===deletionLogPath||newPath===deletionLogPath){return cb(ApiError.EPERM("Cannot rename deletion log."))}if(oldPath===newPath){return cb()}this.stat(oldPath,false,function(oldErr,oldStats){if(oldErr){return cb(oldErr)}return this$1.stat(newPath,false,function(newErr,newStats){var self2=this$1;function copyDirContents(files){var file=files.shift();if(!file){return cb()}var oldFile=path.resolve(oldPath,file);var newFile=path.resolve(newPath,file);self2.rename(oldFile,newFile,function(err){if(err){return cb(err)}copyDirContents(files)})}var mode=511;if(oldStats.isDirectory()){if(newErr){if(newErr.errno!==ErrorCode.ENOENT){return cb(newErr)}return this$1._writable.exists(oldPath,function(exists2){if(exists2){return this$1._writable.rename(oldPath,newPath,cb)}this$1._writable.mkdir(newPath,mode,function(mkdirErr){if(mkdirErr){return cb(mkdirErr)}this$1._readable.readdir(oldPath,function(err,files){if(err){return cb()}copyDirContents(files)})})})}mode=newStats.mode;if(!newStats.isDirectory()){return cb(ApiError.ENOTDIR(newPath))}this$1.readdir(newPath,function(readdirErr,files){if(files&&files.length){return cb(ApiError.ENOTEMPTY(newPath))}this$1._readable.readdir(oldPath,function(err,files2){if(err){return cb()}copyDirContents(files2)})})}if(newStats&&newStats.isDirectory()){return cb(ApiError.EISDIR(newPath))}this$1.readFile(oldPath,null,getFlag("r"),function(err,data){if(err){return cb(err)}return this$1.writeFile(newPath,data,null,getFlag("w"),oldStats.mode,function(err2){if(err2){return cb(err2)}return this$1.unlink(oldPath,cb)})})})})};UnlockedOverlayFS2.prototype.renameSync=function renameSync(oldPath,newPath){var this$1=this;this.checkInitialized();this.checkPath(oldPath);this.checkPath(newPath);if(oldPath===deletionLogPath||newPath===deletionLogPath){throw ApiError.EPERM("Cannot rename deletion log.")}var oldStats=this.statSync(oldPath,false);if(oldStats.isDirectory()){if(oldPath===newPath){return}var mode=511;if(this.existsSync(newPath)){var stats=this.statSync(newPath,false);mode=stats.mode;if(stats.isDirectory()){if(this.readdirSync(newPath).length>0){throw ApiError.ENOTEMPTY(newPath)}}else{throw ApiError.ENOTDIR(newPath)}}if(this._writable.existsSync(oldPath)){this._writable.renameSync(oldPath,newPath)}else if(!this._writable.existsSync(newPath)){this._writable.mkdirSync(newPath,mode)}if(this._readable.existsSync(oldPath)){this._readable.readdirSync(oldPath).forEach(function(name){this$1.renameSync(path.resolve(oldPath,name),path.resolve(newPath,name))})}}else{if(this.existsSync(newPath)&&this.statSync(newPath,false).isDirectory()){throw ApiError.EISDIR(newPath)}this.writeFileSync(newPath,this.readFileSync(oldPath,null,getFlag("r")),null,getFlag("w"),oldStats.mode)}if(oldPath!==newPath&&this.existsSync(oldPath)){this.unlinkSync(oldPath)}};UnlockedOverlayFS2.prototype.stat=function stat(p,isLstat,cb){var this$1=this;if(!this.checkInitAsync(cb)){return}this._writable.stat(p,isLstat,function(err,stat2){if(err&&err.errno===ErrorCode.ENOENT){if(this$1._deletedFiles[p]){cb(ApiError.ENOENT(p))}this$1._readable.stat(p,isLstat,function(err2,stat3){if(stat3){stat3=stat3.clone();stat3.mode=makeModeWritable(stat3.mode)}cb(err2,stat3)})}else{cb(err,stat2)}})};UnlockedOverlayFS2.prototype.statSync=function statSync(p,isLstat){this.checkInitialized();try{return this._writable.statSync(p,isLstat)}catch(e){if(this._deletedFiles[p]){throw ApiError.ENOENT(p)}var oldStat=this._readable.statSync(p,isLstat).clone();oldStat.mode=makeModeWritable(oldStat.mode);return oldStat}};UnlockedOverlayFS2.prototype.open=function open(p,flag,mode,cb){var this$1=this;if(!this.checkInitAsync(cb)||this.checkPathAsync(p,cb)){return}this.stat(p,false,function(err,stats){if(stats){switch(flag.pathExistsAction()){case ActionType.TRUNCATE_FILE:return this$1.createParentDirectoriesAsync(p,function(err2){if(err2){return cb(err2)}this$1._writable.open(p,flag,mode,cb)});case ActionType.NOP:return this$1._writable.exists(p,function(exists2){if(exists2){this$1._writable.open(p,flag,mode,cb)}else{stats=stats.clone();stats.mode=mode;this$1._readable.readFile(p,null,getFlag("r"),function(readFileErr,data){if(readFileErr){return cb(readFileErr)}if(stats.size===-1){stats.size=data.length}var f=new OverlayFile(this$1,p,flag,stats,data);cb(null,f)})}});default:return cb(ApiError.EEXIST(p))}}else{switch(flag.pathNotExistsAction()){case ActionType.CREATE_FILE:return this$1.createParentDirectoriesAsync(p,function(err2){if(err2){return cb(err2)}return this$1._writable.open(p,flag,mode,cb)});default:return cb(ApiError.ENOENT(p))}}})};UnlockedOverlayFS2.prototype.openSync=function openSync(p,flag,mode){this.checkInitialized();this.checkPath(p);if(p===deletionLogPath){throw ApiError.EPERM("Cannot open deletion log.")}if(this.existsSync(p)){switch(flag.pathExistsAction()){case ActionType.TRUNCATE_FILE:this.createParentDirectories(p);return this._writable.openSync(p,flag,mode);case ActionType.NOP:if(this._writable.existsSync(p)){return this._writable.openSync(p,flag,mode)}else{var buf=this._readable.readFileSync(p,null,getFlag("r"));var stats=this._readable.statSync(p,false).clone();stats.mode=mode;return new OverlayFile(this,p,flag,stats,buf)}default:throw ApiError.EEXIST(p)}}else{switch(flag.pathNotExistsAction()){case ActionType.CREATE_FILE:this.createParentDirectories(p);return this._writable.openSync(p,flag,mode);default:throw ApiError.ENOENT(p)}}};UnlockedOverlayFS2.prototype.unlink=function unlink(p,cb){var this$1=this;if(!this.checkInitAsync(cb)||this.checkPathAsync(p,cb)){return}this.exists(p,function(exists2){if(!exists2){return cb(ApiError.ENOENT(p))}this$1._writable.exists(p,function(writableExists){if(writableExists){return this$1._writable.unlink(p,function(err){if(err){return cb(err)}this$1.exists(p,function(readableExists){if(readableExists){this$1.deletePath(p)}cb(null)})})}else{this$1.deletePath(p);cb(null)}})})};UnlockedOverlayFS2.prototype.unlinkSync=function unlinkSync(p){this.checkInitialized();this.checkPath(p);if(this.existsSync(p)){if(this._writable.existsSync(p)){this._writable.unlinkSync(p)}if(this.existsSync(p)){this.deletePath(p)}}else{throw ApiError.ENOENT(p)}};UnlockedOverlayFS2.prototype.rmdir=function rmdir(p,cb){var this$1=this;if(!this.checkInitAsync(cb)){return}var rmdirLower=function(){this$1.readdir(p,function(err,files){if(err){return cb(err)}if(files.length){return cb(ApiError.ENOTEMPTY(p))}this$1.deletePath(p);cb(null)})};this.exists(p,function(exists2){if(!exists2){return cb(ApiError.ENOENT(p))}this$1._writable.exists(p,function(writableExists){if(writableExists){this$1._writable.rmdir(p,function(err){if(err){return cb(err)}this$1._readable.exists(p,function(readableExists){if(readableExists){rmdirLower()}else{cb()}})})}else{rmdirLower()}})})};UnlockedOverlayFS2.prototype.rmdirSync=function rmdirSync(p){this.checkInitialized();if(this.existsSync(p)){if(this._writable.existsSync(p)){this._writable.rmdirSync(p)}if(this.existsSync(p)){if(this.readdirSync(p).length>0){throw ApiError.ENOTEMPTY(p)}else{this.deletePath(p)}}}else{throw ApiError.ENOENT(p)}};UnlockedOverlayFS2.prototype.mkdir=function mkdir(p,mode,cb){var this$1=this;if(!this.checkInitAsync(cb)){return}this.exists(p,function(exists2){if(exists2){return cb(ApiError.EEXIST(p))}this$1.createParentDirectoriesAsync(p,function(err){if(err){return cb(err)}this$1._writable.mkdir(p,mode,cb)})})};UnlockedOverlayFS2.prototype.mkdirSync=function mkdirSync(p,mode){this.checkInitialized();if(this.existsSync(p)){throw ApiError.EEXIST(p)}else{this.createParentDirectories(p);this._writable.mkdirSync(p,mode)}};UnlockedOverlayFS2.prototype.readdir=function readdir(p,cb){var this$1=this;if(!this.checkInitAsync(cb)){return}this.stat(p,false,function(err,dirStats){if(err){return cb(err)}if(!dirStats.isDirectory()){return cb(ApiError.ENOTDIR(p))}this$1._writable.readdir(p,function(err2,wFiles){if(err2&&err2.code!=="ENOENT"){return cb(err2)}else if(err2||!wFiles){wFiles=[]}this$1._readable.readdir(p,function(err3,rFiles){if(err3||!rFiles){rFiles=[]}var seenMap={};var filtered=wFiles.concat(rFiles.filter(function(fPath){return!this$1._deletedFiles[p+"/"+fPath]})).filter(function(fPath){var result=!seenMap[fPath];seenMap[fPath]=true;return result});cb(null,filtered)})})})};UnlockedOverlayFS2.prototype.readdirSync=function readdirSync(p){var this$1=this;this.checkInitialized();var dirStats=this.statSync(p,false);if(!dirStats.isDirectory()){throw ApiError.ENOTDIR(p)}var contents=[];try{contents=contents.concat(this._writable.readdirSync(p))}catch(e){}try{contents=contents.concat(this._readable.readdirSync(p).filter(function(fPath){return!this$1._deletedFiles[p+"/"+fPath]}))}catch(e){}var seenMap={};return contents.filter(function(fileP){var result=!seenMap[fileP];seenMap[fileP]=true;return result})};UnlockedOverlayFS2.prototype.exists=function exists2(p,cb){var this$1=this;this.checkInitialized();this._writable.exists(p,function(existsWritable){if(existsWritable){return cb(true)}this$1._readable.exists(p,function(existsReadable){cb(existsReadable&&this$1._deletedFiles[p]!==true)})})};UnlockedOverlayFS2.prototype.existsSync=function existsSync(p){this.checkInitialized();return this._writable.existsSync(p)||this._readable.existsSync(p)&&this._deletedFiles[p]!==true};UnlockedOverlayFS2.prototype.chmod=function chmod(p,isLchmod,mode,cb){var this$1=this;if(!this.checkInitAsync(cb)){return}this.operateOnWritableAsync(p,function(err){if(err){return cb(err)}else{this$1._writable.chmod(p,isLchmod,mode,cb)}})};UnlockedOverlayFS2.prototype.chmodSync=function chmodSync(p,isLchmod,mode){var this$1=this;this.checkInitialized();this.operateOnWritable(p,function(){this$1._writable.chmodSync(p,isLchmod,mode)})};UnlockedOverlayFS2.prototype.chown=function chown(p,isLchmod,uid,gid,cb){var this$1=this;if(!this.checkInitAsync(cb)){return}this.operateOnWritableAsync(p,function(err){if(err){return cb(err)}else{this$1._writable.chown(p,isLchmod,uid,gid,cb)}})};UnlockedOverlayFS2.prototype.chownSync=function chownSync(p,isLchown,uid,gid){var this$1=this;this.checkInitialized();this.operateOnWritable(p,function(){this$1._writable.chownSync(p,isLchown,uid,gid)})};UnlockedOverlayFS2.prototype.utimes=function utimes(p,atime,mtime,cb){var this$1=this;if(!this.checkInitAsync(cb)){return}this.operateOnWritableAsync(p,function(err){if(err){return cb(err)}else{this$1._writable.utimes(p,atime,mtime,cb)}})};UnlockedOverlayFS2.prototype.utimesSync=function utimesSync(p,atime,mtime){var this$1=this;this.checkInitialized();this.operateOnWritable(p,function(){this$1._writable.utimesSync(p,atime,mtime)})};UnlockedOverlayFS2.prototype.deletePath=function deletePath(p){this._deletedFiles[p]=true;this.updateLog("d"+p+"\n")};UnlockedOverlayFS2.prototype.updateLog=function updateLog(addition){var this$1=this;this._deleteLog+=addition;if(this._deleteLogUpdatePending){this._deleteLogUpdateNeeded=true}else{this._deleteLogUpdatePending=true;this._writable.writeFile(deletionLogPath,this._deleteLog,"utf8",FileFlag.getFileFlag("w"),420,function(e){this$1._deleteLogUpdatePending=false;if(e){this$1._deleteLogError=e}else if(this$1._deleteLogUpdateNeeded){this$1._deleteLogUpdateNeeded=false;this$1.updateLog("")}})}};UnlockedOverlayFS2.prototype._reparseDeletionLog=function _reparseDeletionLog(){var this$1=this;this._deletedFiles={};this._deleteLog.split("\n").forEach(function(path$$1){this$1._deletedFiles[path$$1.slice(1)]=path$$1.slice(0,1)==="d"})};UnlockedOverlayFS2.prototype.checkInitialized=function checkInitialized(){if(!this._isInitialized){throw new ApiError(ErrorCode.EPERM,"OverlayFS is not initialized. Please initialize OverlayFS using its initialize() method before using it.")}else if(this._deleteLogError!==null){var e=this._deleteLogError;this._deleteLogError=null;throw e}};UnlockedOverlayFS2.prototype.checkInitAsync=function checkInitAsync(cb){if(!this._isInitialized){cb(new ApiError(ErrorCode.EPERM,"OverlayFS is not initialized. Please initialize OverlayFS using its initialize() method before using it."));return false}else if(this._deleteLogError!==null){var e=this._deleteLogError;this._deleteLogError=null;cb(e);return false}return true};UnlockedOverlayFS2.prototype.checkPath=function checkPath(p){if(p===deletionLogPath){throw ApiError.EPERM(p)}};UnlockedOverlayFS2.prototype.checkPathAsync=function checkPathAsync(p,cb){if(p===deletionLogPath){cb(ApiError.EPERM(p));return true}return false};UnlockedOverlayFS2.prototype.createParentDirectoriesAsync=function createParentDirectoriesAsync(p,cb){var parent=path.dirname(p);var toCreate=[];var self2=this;this._writable.stat(parent,false,statDone);function statDone(err,stat){if(err){toCreate.push(parent);parent=path.dirname(parent);self2._writable.stat(parent,false,statDone)}else{createParents()}}function createParents(){if(!toCreate.length){return cb()}var dir=toCreate.pop();self2._readable.stat(dir,false,function(err,stats){if(!stats){return cb()}self2._writable.mkdir(dir,stats.mode,function(err2){if(err2){return cb(err2)}createParents()})})}};UnlockedOverlayFS2.prototype.createParentDirectories=function createParentDirectories(p){var this$1=this;var parent=path.dirname(p),toCreate=[];while(!this._writable.existsSync(parent)){toCreate.push(parent);parent=path.dirname(parent)}toCreate=toCreate.reverse();toCreate.forEach(function(p2){this$1._writable.mkdirSync(p2,this$1.statSync(p2,false).mode)})};UnlockedOverlayFS2.prototype.operateOnWritable=function operateOnWritable(p,f){if(this.existsSync(p)){if(!this._writable.existsSync(p)){this.copyToWritable(p)}f()}else{throw ApiError.ENOENT(p)}};UnlockedOverlayFS2.prototype.operateOnWritableAsync=function operateOnWritableAsync(p,cb){var this$1=this;this.exists(p,function(exists2){if(!exists2){return cb(ApiError.ENOENT(p))}this$1._writable.exists(p,function(existsWritable){if(existsWritable){cb()}else{return this$1.copyToWritableAsync(p,cb)}})})};UnlockedOverlayFS2.prototype.copyToWritable=function copyToWritable(p){var pStats=this.statSync(p,false);if(pStats.isDirectory()){this._writable.mkdirSync(p,pStats.mode)}else{this.writeFileSync(p,this._readable.readFileSync(p,null,getFlag("r")),null,getFlag("w"),this.statSync(p,false).mode)}};UnlockedOverlayFS2.prototype.copyToWritableAsync=function copyToWritableAsync(p,cb){var this$1=this;this.stat(p,false,function(err,pStats){if(err){return cb(err)}if(pStats.isDirectory()){return this$1._writable.mkdir(p,pStats.mode,cb)}this$1._readable.readFile(p,null,getFlag("r"),function(err2,data){if(err2){return cb(err2)}this$1.writeFile(p,data,null,getFlag("w"),pStats.mode,cb)})})};return UnlockedOverlayFS2}(BaseFileSystem);var OverlayFS=function(LockedFS$$1){function OverlayFS2(writable,readable,deprecateMsg){if(deprecateMsg===void 0)deprecateMsg=true;LockedFS$$1.call(this,new UnlockedOverlayFS(writable,readable));deprecationMessage(deprecateMsg,OverlayFS2.Name,{readable:"readable file system",writable:"writable file system"})}if(LockedFS$$1)OverlayFS2.__proto__=LockedFS$$1;OverlayFS2.prototype=Object.create(LockedFS$$1&&LockedFS$$1.prototype);OverlayFS2.prototype.constructor=OverlayFS2;OverlayFS2.Create=function Create(opts,cb){try{var fs4=new OverlayFS2(opts.writable,opts.readable,false);fs4.initialize(function(e){cb(e,fs4)},false)}catch(e){cb(e)}};OverlayFS2.isAvailable=function isAvailable(){return UnlockedOverlayFS.isAvailable()};OverlayFS2.prototype.initialize=function initialize3(cb,deprecateMsg){if(deprecateMsg===void 0)deprecateMsg=true;if(deprecateMsg){console.warn("[OverlayFS] OverlayFS.initialize() is deprecated and will be removed in the next major release. Please use 'OverlayFS.Create({readable: readable file system instance, writable: writable file system instance}, cb)' to create and initialize OverlayFS instances.")}LockedFS$$1.prototype.initialize.call(this,cb)};OverlayFS2.prototype.getOverlayedFileSystems=function getOverlayedFileSystems(){return LockedFS$$1.prototype.getFSUnlocked.call(this).getOverlayedFileSystems()};OverlayFS2.prototype.unwrap=function unwrap(){return LockedFS$$1.prototype.getFSUnlocked.call(this)};return OverlayFS2}(LockedFS);OverlayFS.Name="OverlayFS";OverlayFS.Options={writable:{type:"object",description:"The file system to write modified files to."},readable:{type:"object",description:"The file system that initially populates this file system."}};var SpecialArgType;(function(SpecialArgType2){SpecialArgType2[SpecialArgType2["CB"]=0]="CB";SpecialArgType2[SpecialArgType2["FD"]=1]="FD";SpecialArgType2[SpecialArgType2["API_ERROR"]=2]="API_ERROR";SpecialArgType2[SpecialArgType2["STATS"]=3]="STATS";SpecialArgType2[SpecialArgType2["PROBE"]=4]="PROBE";SpecialArgType2[SpecialArgType2["FILEFLAG"]=5]="FILEFLAG";SpecialArgType2[SpecialArgType2["BUFFER"]=6]="BUFFER";SpecialArgType2[SpecialArgType2["ERROR"]=7]="ERROR"})(SpecialArgType||(SpecialArgType={}));var CallbackArgumentConverter=function CallbackArgumentConverter2(){this._callbacks={};this._nextId=0};CallbackArgumentConverter.prototype.toRemoteArg=function toRemoteArg(cb){var id=this._nextId++;this._callbacks[id]=cb;return{type:SpecialArgType.CB,id}};CallbackArgumentConverter.prototype.toLocalArg=function toLocalArg(id){var cb=this._callbacks[id];delete this._callbacks[id];return cb};var FileDescriptorArgumentConverter=function FileDescriptorArgumentConverter2(){this._fileDescriptors={};this._nextId=0};FileDescriptorArgumentConverter.prototype.toRemoteArg=function toRemoteArg(fd,p,flag,cb){var id=this._nextId++;var data;var stat;this._fileDescriptors[id]=fd;fd.stat(function(err,stats){if(err){cb(err)}else{stat=bufferToTransferrableObject(stats.toBuffer());if(flag.isReadable()){fd.read(Buffer2.alloc(stats.size),0,stats.size,0,function(err2,bytesRead,buff){if(err2){cb(err2)}else{data=bufferToTransferrableObject(buff);cb(null,{type:SpecialArgType.FD,id,data,stat,path:p,flag:flag.getFlagString()})}})}else{cb(null,{type:SpecialArgType.FD,id,data:new ArrayBuffer(0),stat,path:p,flag:flag.getFlagString()})}}})};FileDescriptorArgumentConverter.prototype.applyFdAPIRequest=function applyFdAPIRequest(request,cb){var this$1=this;var fdArg=request.args[0];this._applyFdChanges(fdArg,function(err,fd){if(err){cb(err)}else{fd[request.method](function(e){if(request.method==="close"){delete this$1._fileDescriptors[fdArg.id]}cb(e)})}})};FileDescriptorArgumentConverter.prototype._applyFdChanges=function _applyFdChanges(remoteFd,cb){var fd=this._fileDescriptors[remoteFd.id],data=transferrableObjectToBuffer(remoteFd.data),remoteStats=Stats.fromBuffer(transferrableObjectToBuffer(remoteFd.stat));var flag=FileFlag.getFileFlag(remoteFd.flag);if(flag.isWriteable()){fd.write(data,0,data.length,flag.isAppendable()?fd.getPos():0,function(e){function applyStatChanges(){fd.stat(function(e2,stats){if(e2){cb(e2)}else{if(stats.mode!==remoteStats.mode){fd.chmod(remoteStats.mode,function(e3){cb(e3,fd)})}else{cb(e2,fd)}}})}if(e){cb(e)}else{if(!flag.isAppendable()){fd.truncate(data.length,function(){applyStatChanges()})}else{applyStatChanges()}}})}else{cb(null,fd)}};function apiErrorLocal2Remote(e){return{type:SpecialArgType.API_ERROR,errorData:bufferToTransferrableObject(e.writeToBuffer())}}function apiErrorRemote2Local(e){return ApiError.fromBuffer(transferrableObjectToBuffer(e.errorData))}function errorLocal2Remote(e){return{type:SpecialArgType.ERROR,name:e.name,message:e.message,stack:e.stack}}function errorRemote2Local(e){var cnstr=global$1[e.name];if(typeof cnstr!=="function"){cnstr=Error}var err=new cnstr(e.message);err.stack=e.stack;return err}function statsLocal2Remote(stats){return{type:SpecialArgType.STATS,statsData:bufferToTransferrableObject(stats.toBuffer())}}function statsRemote2Local(stats){return Stats.fromBuffer(transferrableObjectToBuffer(stats.statsData))}function fileFlagLocal2Remote(flag){return{type:SpecialArgType.FILEFLAG,flagStr:flag.getFlagString()}}function fileFlagRemote2Local(remoteFlag){return FileFlag.getFileFlag(remoteFlag.flagStr)}function bufferToTransferrableObject(buff){return buffer2ArrayBuffer(buff)}function transferrableObjectToBuffer(buff){return arrayBuffer2Buffer(buff)}function bufferLocal2Remote(buff){return{type:SpecialArgType.BUFFER,data:bufferToTransferrableObject(buff)}}function bufferRemote2Local(buffArg){return transferrableObjectToBuffer(buffArg.data)}function isAPIRequest(data){return data&&typeof data==="object"&&data.hasOwnProperty("browserfsMessage")&&data["browserfsMessage"]}function isAPIResponse(data){return data&&typeof data==="object"&&data.hasOwnProperty("browserfsMessage")&&data["browserfsMessage"]}var WorkerFile=function(PreloadFile$$1){function WorkerFile2(_fs,_path,_flag,_stat,remoteFdId,contents){PreloadFile$$1.call(this,_fs,_path,_flag,_stat,contents);this._remoteFdId=remoteFdId}if(PreloadFile$$1)WorkerFile2.__proto__=PreloadFile$$1;WorkerFile2.prototype=Object.create(PreloadFile$$1&&PreloadFile$$1.prototype);WorkerFile2.prototype.constructor=WorkerFile2;WorkerFile2.prototype.getRemoteFdId=function getRemoteFdId(){return this._remoteFdId};WorkerFile2.prototype.toRemoteArg=function toRemoteArg(){return{type:SpecialArgType.FD,id:this._remoteFdId,data:bufferToTransferrableObject(this.getBuffer()),stat:bufferToTransferrableObject(this.getStats().toBuffer()),path:this.getPath(),flag:this.getFlag().getFlagString()}};WorkerFile2.prototype.sync=function sync(cb){this._syncClose("sync",cb)};WorkerFile2.prototype.close=function close(cb){this._syncClose("close",cb)};WorkerFile2.prototype._syncClose=function _syncClose(type,cb){var this$1=this;if(this.isDirty()){this._fs.syncClose(type,this,function(e){if(!e){this$1.resetDirty()}cb(e)})}else{cb()}};return WorkerFile2}(PreloadFile);var WorkerFS=function(BaseFileSystem$$1){function WorkerFS2(worker,deprecateMsg){var this$1=this;if(deprecateMsg===void 0)deprecateMsg=true;BaseFileSystem$$1.call(this);this._callbackConverter=new CallbackArgumentConverter;this._isInitialized=false;this._isReadOnly=false;this._supportLinks=false;this._supportProps=false;this._worker=worker;deprecationMessage(deprecateMsg,WorkerFS2.Name,{worker:"Web Worker instance"});this._worker.addEventListener("message",function(e){var resp=e.data;if(isAPIResponse(resp)){var i2;var args=resp.args;var fixedArgs=new Array(args.length);for(i2=0;i20){countdown=-1;message={browserfsMessage:true,cbId,args:[apiErrorLocal2Remote(err)]};worker.postMessage(message)}}for(i2=0;i20){var inode=void 0;var next=queue.pop();var pwd=next[0];var tree=next[1];var parent=next[2];for(var node in tree){if(tree.hasOwnProperty(node)){var children=tree[node];var name=pwd+"/"+node;if(children){idx._index[name]=inode=new DirInode;queue.push([name,children,inode])}else{inode=new FileInode(new Stats(FileType.FILE,-1,365))}if(parent){parent._ls[node]=inode}}}}return idx};FileIndex.prototype.fileIterator=function fileIterator(cb){var this$1=this;for(var path$$1 in this$1._index){if(this$1._index.hasOwnProperty(path$$1)){var dir=this$1._index[path$$1];var files=dir.getListing();for(var i2=0,list2=files;i20&&prefixUrl.charAt(prefixUrl.length-1)!=="/"){prefixUrl=prefixUrl+"/"}this.prefixUrl=prefixUrl;var listing=null;if(typeof listingUrlOrObj==="string"){listing=this._requestFileSync(listingUrlOrObj,"json");if(!listing){throw new Error("Unable to find listing at URL: ${listingUrlOrObj}")}}else{listing=listingUrlOrObj}deprecationMessage(deprecateMsg,XmlHttpRequest2.Name,{index:typeof listingUrlOrObj==="string"?listingUrlOrObj:"file index as an object",baseUrl:prefixUrl});this._index=FileIndex.fromListing(listing)}if(BaseFileSystem$$1)XmlHttpRequest2.__proto__=BaseFileSystem$$1;XmlHttpRequest2.prototype=Object.create(BaseFileSystem$$1&&BaseFileSystem$$1.prototype);XmlHttpRequest2.prototype.constructor=XmlHttpRequest2;XmlHttpRequest2.Create=function Create(opts,cb){if(opts.index===void 0){opts.index="index.json"}if(typeof opts.index==="string"){XmlHttpRequest2.FromURL(opts.index,cb,opts.baseUrl,false)}else{cb(null,new XmlHttpRequest2(opts.index,opts.baseUrl,false))}};XmlHttpRequest2.isAvailable=function isAvailable(){return typeof XMLHttpRequest!=="undefined"&&XMLHttpRequest!==null};XmlHttpRequest2.FromURL=function FromURL(url,cb,baseUrl,deprecateMsg){if(baseUrl===void 0)baseUrl=url.slice(0,url.lastIndexOf("/")+1);if(deprecateMsg===void 0)deprecateMsg=true;if(deprecateMsg){console.warn(`[XmlHttpRequest] XmlHttpRequest.FromURL() is deprecated and will be removed in the next major release. Please use 'XmlHttpRequest.Create({ index: "`+url+'", baseUrl: "'+baseUrl+`" }, cb)' instead.`)}asyncDownloadFile(url,"json",function(e,data){if(e){cb(e)}else{cb(null,new XmlHttpRequest2(data,baseUrl,false))}})};XmlHttpRequest2.prototype.empty=function empty(){this._index.fileIterator(function(file){file.fileData=null})};XmlHttpRequest2.prototype.getName=function getName(){return XmlHttpRequest2.Name};XmlHttpRequest2.prototype.diskSpace=function diskSpace(path$$1,cb){cb(0,0)};XmlHttpRequest2.prototype.isReadOnly=function isReadOnly(){return true};XmlHttpRequest2.prototype.supportsLinks=function supportsLinks(){return false};XmlHttpRequest2.prototype.supportsProps=function supportsProps(){return false};XmlHttpRequest2.prototype.supportsSynch=function supportsSynch(){return true};XmlHttpRequest2.prototype.preloadFile=function preloadFile(path$$1,buffer$$1){var inode=this._index.getInode(path$$1);if(isFileInode(inode)){if(inode===null){throw ApiError.ENOENT(path$$1)}var stats=inode.getData();stats.size=buffer$$1.length;stats.fileData=buffer$$1}else{throw ApiError.EISDIR(path$$1)}};XmlHttpRequest2.prototype.stat=function stat(path$$1,isLstat,cb){var inode=this._index.getInode(path$$1);if(inode===null){return cb(ApiError.ENOENT(path$$1))}var stats;if(isFileInode(inode)){stats=inode.getData();if(stats.size<0){this._requestFileSizeAsync(path$$1,function(e,size){if(e){return cb(e)}stats.size=size;cb(null,stats.clone())})}else{cb(null,stats.clone())}}else if(isDirInode(inode)){stats=inode.getStats();cb(null,stats)}else{cb(ApiError.FileError(ErrorCode.EINVAL,path$$1))}};XmlHttpRequest2.prototype.statSync=function statSync(path$$1,isLstat){var inode=this._index.getInode(path$$1);if(inode===null){throw ApiError.ENOENT(path$$1)}var stats;if(isFileInode(inode)){stats=inode.getData();if(stats.size<0){stats.size=this._requestFileSizeSync(path$$1)}}else if(isDirInode(inode)){stats=inode.getStats()}else{throw ApiError.FileError(ErrorCode.EINVAL,path$$1)}return stats};XmlHttpRequest2.prototype.open=function open(path$$1,flags,mode,cb){if(flags.isWriteable()){return cb(new ApiError(ErrorCode.EPERM,path$$1))}var self2=this;var inode=this._index.getInode(path$$1);if(inode===null){return cb(ApiError.ENOENT(path$$1))}if(isFileInode(inode)){var stats=inode.getData();switch(flags.pathExistsAction()){case ActionType.THROW_EXCEPTION:case ActionType.TRUNCATE_FILE:return cb(ApiError.EEXIST(path$$1));case ActionType.NOP:if(stats.fileData){return cb(null,new NoSyncFile(self2,path$$1,flags,stats.clone(),stats.fileData))}this._requestFileAsync(path$$1,"buffer",function(err,buffer$$1){if(err){return cb(err)}stats.size=buffer$$1.length;stats.fileData=buffer$$1;return cb(null,new NoSyncFile(self2,path$$1,flags,stats.clone(),buffer$$1))});break;default:return cb(new ApiError(ErrorCode.EINVAL,"Invalid FileMode object."))}}else{return cb(ApiError.EISDIR(path$$1))}};XmlHttpRequest2.prototype.openSync=function openSync(path$$1,flags,mode){if(flags.isWriteable()){throw new ApiError(ErrorCode.EPERM,path$$1)}var inode=this._index.getInode(path$$1);if(inode===null){throw ApiError.ENOENT(path$$1)}if(isFileInode(inode)){var stats=inode.getData();switch(flags.pathExistsAction()){case ActionType.THROW_EXCEPTION:case ActionType.TRUNCATE_FILE:throw ApiError.EEXIST(path$$1);case ActionType.NOP:if(stats.fileData){return new NoSyncFile(this,path$$1,flags,stats.clone(),stats.fileData)}var buffer$$1=this._requestFileSync(path$$1,"buffer");stats.size=buffer$$1.length;stats.fileData=buffer$$1;return new NoSyncFile(this,path$$1,flags,stats.clone(),buffer$$1);default:throw new ApiError(ErrorCode.EINVAL,"Invalid FileMode object.")}}else{throw ApiError.EISDIR(path$$1)}};XmlHttpRequest2.prototype.readdir=function readdir(path$$1,cb){try{cb(null,this.readdirSync(path$$1))}catch(e){cb(e)}};XmlHttpRequest2.prototype.readdirSync=function readdirSync(path$$1){var inode=this._index.getInode(path$$1);if(inode===null){throw ApiError.ENOENT(path$$1)}else if(isDirInode(inode)){return inode.getListing()}else{throw ApiError.ENOTDIR(path$$1)}};XmlHttpRequest2.prototype.readFile=function readFile2(fname,encoding,flag,cb){var oldCb=cb;this.open(fname,flag,420,function(err,fd){if(err){return cb(err)}cb=function(err2,arg){fd.close(function(err22){if(!err2){err2=err22}return oldCb(err2,arg)})};var fdCast=fd;var fdBuff=fdCast.getBuffer();if(encoding===null){cb(err,copyingSlice(fdBuff))}else{tryToString(fdBuff,encoding,cb)}})};XmlHttpRequest2.prototype.readFileSync=function readFileSync(fname,encoding,flag){var fd=this.openSync(fname,flag,420);try{var fdCast=fd;var fdBuff=fdCast.getBuffer();if(encoding===null){return copyingSlice(fdBuff)}return fdBuff.toString(encoding)}finally{fd.closeSync()}};XmlHttpRequest2.prototype.getXhrPath=function getXhrPath(filePath){if(filePath.charAt(0)==="/"){filePath=filePath.slice(1)}return this.prefixUrl+filePath};XmlHttpRequest2.prototype._requestFileAsync=function _requestFileAsync(p,type,cb){asyncDownloadFile(this.getXhrPath(p),type,cb)};XmlHttpRequest2.prototype._requestFileSync=function _requestFileSync(p,type){return syncDownloadFile(this.getXhrPath(p),type)};XmlHttpRequest2.prototype._requestFileSizeAsync=function _requestFileSizeAsync(path$$1,cb){getFileSizeAsync(this.getXhrPath(path$$1),cb)};XmlHttpRequest2.prototype._requestFileSizeSync=function _requestFileSizeSync(path$$1){return getFileSizeSync(this.getXhrPath(path$$1))};return XmlHttpRequest2}(BaseFileSystem);XmlHttpRequest.Name="XmlHttpRequest";XmlHttpRequest.Options={index:{type:["string","object"],optional:true,description:"URL to a file index as a JSON file or the file index object itself, generated with the make_xhrfs_index script. Defaults to `index.json`."},baseUrl:{type:"string",optional:true,description:"Used as the URL prefix for fetched files. Default: Fetch files relative to the index."}};var ExtendedASCII=function ExtendedASCII2(){};ExtendedASCII.str2byte=function str2byte(str,buf){var length=str.length>buf.length?buf.length:str.length;for(var i2=0;i2127){var charIdx=ExtendedASCII.extendedChars.indexOf(str.charAt(i2));if(charIdx>-1){charCode=charIdx+128}}buf[charCode]=i2}return length};ExtendedASCII.byte2str=function byte2str(buff){var chars=new Array(buff.length);for(var i2=0;i2127){chars[i2]=ExtendedASCII.extendedChars[charCode-128]}else{chars[i2]=String.fromCharCode(charCode)}}return chars.join("")};ExtendedASCII.byteLength=function byteLength(str){return str.length};ExtendedASCII.extendedChars=["\xC7","\xFC","\xE9","\xE2","\xE4","\xE0","\xE5","\xE7","\xEA","\xEB","\xE8","\xEF","\xEE","\xEC","\xC4","\xC5","\xC9","\xE6","\xC6","\xF4","\xF6","\xF2","\xFB","\xF9","\xFF","\xD6","\xDC","\xF8","\xA3","\xD8","\xD7","\u0192","\xE1","\xED","\xF3","\xFA","\xF1","\xD1","\xAA","\xBA","\xBF","\xAE","\xAC","\xBD","\xBC","\xA1","\xAB","\xBB","_","_","_","\xA6","\xA6","\xC1","\xC2","\xC0","\xA9","\xA6","\xA6","+","+","\xA2","\xA5","+","+","-","-","+","-","+","\xE3","\xC3","+","+","-","-","\xA6","-","+","\xA4","\xF0","\xD0","\xCA","\xCB","\xC8","i","\xCD","\xCE","\xCF","+","+","_","_","\xA6","\xCC","_","\xD3","\xDF","\xD4","\xD2","\xF5","\xD5","\xB5","\xFE","\xDE","\xDA","\xDB","\xD9","\xFD","\xDD","\xAF","\xB4","\xAD","\xB1","_","\xBE","\xB6","\xA7","\xF7","\xB8","\xB0","\xA8","\xB7","\xB9","\xB3","\xB2","_"," "];var inflateRaw=__webpack_require__(31).inflateRaw;var decompressionMethods={};var ExternalFileAttributeType;(function(ExternalFileAttributeType2){ExternalFileAttributeType2[ExternalFileAttributeType2["MSDOS"]=0]="MSDOS";ExternalFileAttributeType2[ExternalFileAttributeType2["AMIGA"]=1]="AMIGA";ExternalFileAttributeType2[ExternalFileAttributeType2["OPENVMS"]=2]="OPENVMS";ExternalFileAttributeType2[ExternalFileAttributeType2["UNIX"]=3]="UNIX";ExternalFileAttributeType2[ExternalFileAttributeType2["VM_CMS"]=4]="VM_CMS";ExternalFileAttributeType2[ExternalFileAttributeType2["ATARI_ST"]=5]="ATARI_ST";ExternalFileAttributeType2[ExternalFileAttributeType2["OS2_HPFS"]=6]="OS2_HPFS";ExternalFileAttributeType2[ExternalFileAttributeType2["MAC"]=7]="MAC";ExternalFileAttributeType2[ExternalFileAttributeType2["Z_SYSTEM"]=8]="Z_SYSTEM";ExternalFileAttributeType2[ExternalFileAttributeType2["CP_M"]=9]="CP_M";ExternalFileAttributeType2[ExternalFileAttributeType2["NTFS"]=10]="NTFS";ExternalFileAttributeType2[ExternalFileAttributeType2["MVS"]=11]="MVS";ExternalFileAttributeType2[ExternalFileAttributeType2["VSE"]=12]="VSE";ExternalFileAttributeType2[ExternalFileAttributeType2["ACORN_RISC"]=13]="ACORN_RISC";ExternalFileAttributeType2[ExternalFileAttributeType2["VFAT"]=14]="VFAT";ExternalFileAttributeType2[ExternalFileAttributeType2["ALT_MVS"]=15]="ALT_MVS";ExternalFileAttributeType2[ExternalFileAttributeType2["BEOS"]=16]="BEOS";ExternalFileAttributeType2[ExternalFileAttributeType2["TANDEM"]=17]="TANDEM";ExternalFileAttributeType2[ExternalFileAttributeType2["OS_400"]=18]="OS_400";ExternalFileAttributeType2[ExternalFileAttributeType2["OSX"]=19]="OSX"})(ExternalFileAttributeType||(ExternalFileAttributeType={}));var CompressionMethod;(function(CompressionMethod2){CompressionMethod2[CompressionMethod2["STORED"]=0]="STORED";CompressionMethod2[CompressionMethod2["SHRUNK"]=1]="SHRUNK";CompressionMethod2[CompressionMethod2["REDUCED_1"]=2]="REDUCED_1";CompressionMethod2[CompressionMethod2["REDUCED_2"]=3]="REDUCED_2";CompressionMethod2[CompressionMethod2["REDUCED_3"]=4]="REDUCED_3";CompressionMethod2[CompressionMethod2["REDUCED_4"]=5]="REDUCED_4";CompressionMethod2[CompressionMethod2["IMPLODE"]=6]="IMPLODE";CompressionMethod2[CompressionMethod2["DEFLATE"]=8]="DEFLATE";CompressionMethod2[CompressionMethod2["DEFLATE64"]=9]="DEFLATE64";CompressionMethod2[CompressionMethod2["TERSE_OLD"]=10]="TERSE_OLD";CompressionMethod2[CompressionMethod2["BZIP2"]=12]="BZIP2";CompressionMethod2[CompressionMethod2["LZMA"]=14]="LZMA";CompressionMethod2[CompressionMethod2["TERSE_NEW"]=18]="TERSE_NEW";CompressionMethod2[CompressionMethod2["LZ77"]=19]="LZ77";CompressionMethod2[CompressionMethod2["WAVPACK"]=97]="WAVPACK";CompressionMethod2[CompressionMethod2["PPMD"]=98]="PPMD"})(CompressionMethod||(CompressionMethod={}));function msdos2date(time,date){var day=date&31;var month=(date>>5&15)-1;var year=(date>>9)+1980;var second=time&31;var minute=time>>5&63;var hour=time>>11;return new Date(year,month,day,hour,minute,second)}function safeToString(buff,useUTF8,start,length){if(length===0){return""}else if(useUTF8){return buff.toString("utf8",start,start+length)}else{return ExtendedASCII.byte2str(buff.slice(start,start+length))}}var FileHeader=function FileHeader2(data){this.data=data;if(data.readUInt32LE(0)!==67324752){throw new ApiError(ErrorCode.EINVAL,"Invalid Zip file: Local file header has invalid signature: "+this.data.readUInt32LE(0))}};FileHeader.prototype.versionNeeded=function versionNeeded(){return this.data.readUInt16LE(4)};FileHeader.prototype.flags=function flags(){return this.data.readUInt16LE(6)};FileHeader.prototype.compressionMethod=function compressionMethod(){return this.data.readUInt16LE(8)};FileHeader.prototype.lastModFileTime=function lastModFileTime(){return msdos2date(this.data.readUInt16LE(10),this.data.readUInt16LE(12))};FileHeader.prototype.rawLastModFileTime=function rawLastModFileTime(){return this.data.readUInt32LE(10)};FileHeader.prototype.crc32=function crc32(){return this.data.readUInt32LE(14)};FileHeader.prototype.fileNameLength=function fileNameLength(){return this.data.readUInt16LE(26)};FileHeader.prototype.extraFieldLength=function extraFieldLength(){return this.data.readUInt16LE(28)};FileHeader.prototype.fileName=function fileName(){return safeToString(this.data,this.useUTF8(),30,this.fileNameLength())};FileHeader.prototype.extraField=function extraField(){var start=30+this.fileNameLength();return this.data.slice(start,start+this.extraFieldLength())};FileHeader.prototype.totalSize=function totalSize(){return 30+this.fileNameLength()+this.extraFieldLength()};FileHeader.prototype.useUTF8=function useUTF8(){return(this.flags()&2048)===2048};var FileData=function FileData2(header,record,data){this.header=header;this.record=record;this.data=data};FileData.prototype.decompress=function decompress(){var compressionMethod=this.header.compressionMethod();var fcn=decompressionMethods[compressionMethod];if(fcn){return fcn(this.data,this.record.compressedSize(),this.record.uncompressedSize(),this.record.flag())}else{var name=CompressionMethod[compressionMethod];if(!name){name="Unknown: "+compressionMethod}throw new ApiError(ErrorCode.EINVAL,"Invalid compression method on file '"+this.header.fileName()+"': "+name)}};FileData.prototype.getHeader=function getHeader(){return this.header};FileData.prototype.getRecord=function getRecord(){return this.record};FileData.prototype.getRawData=function getRawData(){return this.data};var DataDescriptor=function DataDescriptor2(data){this.data=data};DataDescriptor.prototype.crc32=function crc32(){return this.data.readUInt32LE(0)};DataDescriptor.prototype.compressedSize=function compressedSize(){return this.data.readUInt32LE(4)};DataDescriptor.prototype.uncompressedSize=function uncompressedSize(){return this.data.readUInt32LE(8)};var ArchiveExtraDataRecord=function ArchiveExtraDataRecord2(data){this.data=data;if(this.data.readUInt32LE(0)!==134630224){throw new ApiError(ErrorCode.EINVAL,"Invalid archive extra data record signature: "+this.data.readUInt32LE(0))}};ArchiveExtraDataRecord.prototype.length=function length(){return this.data.readUInt32LE(4)};ArchiveExtraDataRecord.prototype.extraFieldData=function extraFieldData(){return this.data.slice(8,8+this.length())};var DigitalSignature=function DigitalSignature2(data){this.data=data;if(this.data.readUInt32LE(0)!==84233040){throw new ApiError(ErrorCode.EINVAL,"Invalid digital signature signature: "+this.data.readUInt32LE(0))}};DigitalSignature.prototype.size=function size(){return this.data.readUInt16LE(4)};DigitalSignature.prototype.signatureData=function signatureData(){return this.data.slice(6,6+this.size())};var CentralDirectory=function CentralDirectory2(zipData,data){this.zipData=zipData;this.data=data;if(this.data.readUInt32LE(0)!==33639248){throw new ApiError(ErrorCode.EINVAL,"Invalid Zip file: Central directory record has invalid signature: "+this.data.readUInt32LE(0))}this._filename=this.produceFilename()};CentralDirectory.prototype.versionMadeBy=function versionMadeBy(){return this.data.readUInt16LE(4)};CentralDirectory.prototype.versionNeeded=function versionNeeded(){return this.data.readUInt16LE(6)};CentralDirectory.prototype.flag=function flag(){return this.data.readUInt16LE(8)};CentralDirectory.prototype.compressionMethod=function compressionMethod(){return this.data.readUInt16LE(10)};CentralDirectory.prototype.lastModFileTime=function lastModFileTime(){return msdos2date(this.data.readUInt16LE(12),this.data.readUInt16LE(14))};CentralDirectory.prototype.rawLastModFileTime=function rawLastModFileTime(){return this.data.readUInt32LE(12)};CentralDirectory.prototype.crc32=function crc32(){return this.data.readUInt32LE(16)};CentralDirectory.prototype.compressedSize=function compressedSize(){return this.data.readUInt32LE(20)};CentralDirectory.prototype.uncompressedSize=function uncompressedSize(){return this.data.readUInt32LE(24)};CentralDirectory.prototype.fileNameLength=function fileNameLength(){return this.data.readUInt16LE(28)};CentralDirectory.prototype.extraFieldLength=function extraFieldLength(){return this.data.readUInt16LE(30)};CentralDirectory.prototype.fileCommentLength=function fileCommentLength(){return this.data.readUInt16LE(32)};CentralDirectory.prototype.diskNumberStart=function diskNumberStart(){return this.data.readUInt16LE(34)};CentralDirectory.prototype.internalAttributes=function internalAttributes(){return this.data.readUInt16LE(36)};CentralDirectory.prototype.externalAttributes=function externalAttributes(){return this.data.readUInt32LE(38)};CentralDirectory.prototype.headerRelativeOffset=function headerRelativeOffset(){return this.data.readUInt32LE(42)};CentralDirectory.prototype.produceFilename=function produceFilename(){var fileName=safeToString(this.data,this.useUTF8(),46,this.fileNameLength());return fileName.replace(/\\/g,"/")};CentralDirectory.prototype.fileName=function fileName(){return this._filename};CentralDirectory.prototype.rawFileName=function rawFileName(){return this.data.slice(46,46+this.fileNameLength())};CentralDirectory.prototype.extraField=function extraField(){var start=44+this.fileNameLength();return this.data.slice(start,start+this.extraFieldLength())};CentralDirectory.prototype.fileComment=function fileComment(){var start=46+this.fileNameLength()+this.extraFieldLength();return safeToString(this.data,this.useUTF8(),start,this.fileCommentLength())};CentralDirectory.prototype.rawFileComment=function rawFileComment(){var start=46+this.fileNameLength()+this.extraFieldLength();return this.data.slice(start,start+this.fileCommentLength())};CentralDirectory.prototype.totalSize=function totalSize(){return 46+this.fileNameLength()+this.extraFieldLength()+this.fileCommentLength()};CentralDirectory.prototype.isDirectory=function isDirectory(){var fileName=this.fileName();return(this.externalAttributes()&16?true:false)||fileName.charAt(fileName.length-1)==="/"};CentralDirectory.prototype.isFile=function isFile(){return!this.isDirectory()};CentralDirectory.prototype.useUTF8=function useUTF8(){return(this.flag()&2048)===2048};CentralDirectory.prototype.isEncrypted=function isEncrypted(){return(this.flag()&1)===1};CentralDirectory.prototype.getFileData=function getFileData(){var start=this.headerRelativeOffset();var header=new FileHeader(this.zipData.slice(start));return new FileData(header,this,this.zipData.slice(start+header.totalSize()))};CentralDirectory.prototype.getData=function getData(){return this.getFileData().decompress()};CentralDirectory.prototype.getRawData=function getRawData(){return this.getFileData().getRawData()};CentralDirectory.prototype.getStats=function getStats(){return new Stats(FileType.FILE,this.uncompressedSize(),365,new Date,this.lastModFileTime())};var EndOfCentralDirectory=function EndOfCentralDirectory2(data){this.data=data;if(this.data.readUInt32LE(0)!==101010256){throw new ApiError(ErrorCode.EINVAL,"Invalid Zip file: End of central directory record has invalid signature: "+this.data.readUInt32LE(0))}};EndOfCentralDirectory.prototype.diskNumber=function diskNumber(){return this.data.readUInt16LE(4)};EndOfCentralDirectory.prototype.cdDiskNumber=function cdDiskNumber(){return this.data.readUInt16LE(6)};EndOfCentralDirectory.prototype.cdDiskEntryCount=function cdDiskEntryCount(){return this.data.readUInt16LE(8)};EndOfCentralDirectory.prototype.cdTotalEntryCount=function cdTotalEntryCount(){return this.data.readUInt16LE(10)};EndOfCentralDirectory.prototype.cdSize=function cdSize(){return this.data.readUInt32LE(12)};EndOfCentralDirectory.prototype.cdOffset=function cdOffset(){return this.data.readUInt32LE(16)};EndOfCentralDirectory.prototype.cdZipCommentLength=function cdZipCommentLength(){return this.data.readUInt16LE(20)};EndOfCentralDirectory.prototype.cdZipComment=function cdZipComment(){return safeToString(this.data,true,22,this.cdZipCommentLength())};EndOfCentralDirectory.prototype.rawCdZipComment=function rawCdZipComment(){return this.data.slice(22,22+this.cdZipCommentLength())};var ZipTOC=function ZipTOC2(index,directoryEntries,eocd,data){this.index=index;this.directoryEntries=directoryEntries;this.eocd=eocd;this.data=data};var ZipFS=function(SynchronousFileSystem$$1){function ZipFS2(input,name,deprecateMsg){if(name===void 0)name="";if(deprecateMsg===void 0)deprecateMsg=true;SynchronousFileSystem$$1.call(this);this.name=name;this._index=new FileIndex;this._directoryEntries=[];this._eocd=null;deprecationMessage(deprecateMsg,ZipFS2.Name,{zipData:"zip data as a Buffer",name});if(input instanceof ZipTOC){this._index=input.index;this._directoryEntries=input.directoryEntries;this._eocd=input.eocd;this.data=input.data}else{this.data=input;this.populateIndex()}}if(SynchronousFileSystem$$1)ZipFS2.__proto__=SynchronousFileSystem$$1;ZipFS2.prototype=Object.create(SynchronousFileSystem$$1&&SynchronousFileSystem$$1.prototype);ZipFS2.prototype.constructor=ZipFS2;ZipFS2.Create=function Create(opts,cb){try{ZipFS2.computeIndex(opts.zipData,function(zipTOC){var fs4=new ZipFS2(zipTOC,opts.name,false);cb(null,fs4)},false)}catch(e){cb(e)}};ZipFS2.isAvailable=function isAvailable(){return true};ZipFS2.RegisterDecompressionMethod=function RegisterDecompressionMethod(m,fcn){decompressionMethods[m]=fcn};ZipFS2.computeIndex=function computeIndex(data,cb,deprecateMsg){if(deprecateMsg===void 0)deprecateMsg=true;if(deprecateMsg){console.warn("[ZipFS] ZipFS.computeIndex is now deprecated, and will be removed in the next major release. Please update your code to use 'ZipFS.Create({ zipData: zip file as a Buffer}, cb)' instead.")}var index=new FileIndex;var eocd=ZipFS2.getEOCD(data);if(eocd.diskNumber()!==eocd.cdDiskNumber()){throw new ApiError(ErrorCode.EINVAL,"ZipFS does not support spanned zip files.")}var cdPtr=eocd.cdOffset();if(cdPtr===4294967295){throw new ApiError(ErrorCode.EINVAL,"ZipFS does not support Zip64.")}var cdEnd=cdPtr+eocd.cdSize();ZipFS2.computeIndexResponsive(data,index,cdPtr,cdEnd,cb,[],eocd)};ZipFS2.getEOCD=function getEOCD(data){var startOffset=22;var endOffset=Math.min(startOffset+65535,data.length-1);for(var i2=startOffset;i2-1};DirectoryRecord.prototype.getRockRidgeOffset=function getRockRidgeOffset(){return this._rockRidgeOffset};DirectoryRecord.prototype.rootCheckForRockRidge=function rootCheckForRockRidge(isoData){var dir=this.getDirectory(isoData);this._rockRidgeOffset=dir.getDotEntry(isoData)._getRockRidgeOffset(isoData);if(this._rockRidgeOffset>-1){this._fileOrDir=null}};DirectoryRecord.prototype.length=function length(){return this._data[0]};DirectoryRecord.prototype.extendedAttributeRecordLength=function extendedAttributeRecordLength(){return this._data[1]};DirectoryRecord.prototype.lba=function lba(){return this._data.readUInt32LE(2)*2048};DirectoryRecord.prototype.dataLength=function dataLength(){return this._data.readUInt32LE(10)};DirectoryRecord.prototype.recordingDate=function recordingDate(){return getShortFormDate(this._data,18)};DirectoryRecord.prototype.fileFlags=function fileFlags(){return this._data[25]};DirectoryRecord.prototype.fileUnitSize=function fileUnitSize(){return this._data[26]};DirectoryRecord.prototype.interleaveGapSize=function interleaveGapSize(){return this._data[27]};DirectoryRecord.prototype.volumeSequenceNumber=function volumeSequenceNumber(){return this._data.readUInt16LE(28)};DirectoryRecord.prototype.identifier=function identifier(){return this._getString(33,this._data[32])};DirectoryRecord.prototype.fileName=function fileName(isoData){if(this.hasRockRidge()){var fn=this._rockRidgeFilename(isoData);if(fn!==null){return fn}}var ident=this.identifier();if(this.isDirectory(isoData)){return ident}var versionSeparator=ident.indexOf(";");if(versionSeparator===-1){return ident}else if(ident[versionSeparator-1]==="."){return ident.slice(0,versionSeparator-1)}else{return ident.slice(0,versionSeparator)}};DirectoryRecord.prototype.isDirectory=function isDirectory(isoData){var rv=!!(this.fileFlags()&2);if(!rv&&this.hasRockRidge()){rv=this.getSUEntries(isoData).filter(function(e){return e instanceof CLEntry}).length>0}return rv};DirectoryRecord.prototype.isSymlink=function isSymlink(isoData){return this.hasRockRidge()&&this.getSUEntries(isoData).filter(function(e){return e instanceof SLEntry}).length>0};DirectoryRecord.prototype.getSymlinkPath=function getSymlinkPath(isoData){var p="";var entries=this.getSUEntries(isoData);var getStr=this._getGetString();for(var i2=0,list2=entries;i21&&p[p.length-1]==="/"){return p.slice(0,p.length-1)}else{return p}};DirectoryRecord.prototype.getFile=function getFile(isoData){if(this.isDirectory(isoData)){throw new Error("Tried to get a File from a directory.")}if(this._fileOrDir===null){this._fileOrDir=isoData.slice(this.lba(),this.lba()+this.dataLength())}return this._fileOrDir};DirectoryRecord.prototype.getDirectory=function getDirectory(isoData){if(!this.isDirectory(isoData)){throw new Error("Tried to get a Directory from a file.")}if(this._fileOrDir===null){this._fileOrDir=this._constructDirectory(isoData)}return this._fileOrDir};DirectoryRecord.prototype.getSUEntries=function getSUEntries(isoData){if(!this._suEntries){this._constructSUEntries(isoData)}return this._suEntries};DirectoryRecord.prototype._rockRidgeFilename=function _rockRidgeFilename(isoData){var nmEntries=this.getSUEntries(isoData).filter(function(e2){return e2 instanceof NMEntry});if(nmEntries.length===0||nmEntries[0].flags()&(2|4)){return null}var str="";var getString=this._getGetString();for(var i2=0,list2=nmEntries;i20){var spEntry=suEntries[0];if(spEntry instanceof SPEntry&&spEntry.checkBytesPass()){for(var i2=1;i2K_MAX_LENGTH){throw new RangeError("Invalid typed array length")}var buf=new Uint8Array(length);buf.__proto__=Buffer2.prototype;return buf}function Buffer2(arg,encodingOrOffset,length){if(typeof arg==="number"){if(typeof encodingOrOffset==="string"){throw new Error("If encoding is specified then the first argument must be a string")}return allocUnsafe(arg)}return from(arg,encodingOrOffset,length)}if(typeof Symbol!=="undefined"&&Symbol.species&&Buffer2[Symbol.species]===Buffer2){Object.defineProperty(Buffer2,Symbol.species,{value:null,configurable:true,enumerable:false,writable:false})}Buffer2.poolSize=8192;function from(value,encodingOrOffset,length){if(typeof value==="number"){throw new TypeError('"value" argument must not be a number')}if(isArrayBuffer(value)){return fromArrayBuffer(value,encodingOrOffset,length)}if(typeof value==="string"){return fromString(value,encodingOrOffset)}return fromObject(value)}Buffer2.from=function(value,encodingOrOffset,length){return from(value,encodingOrOffset,length)};Buffer2.prototype.__proto__=Uint8Array.prototype;Buffer2.__proto__=Uint8Array;function assertSize(size){if(typeof size!=="number"){throw new TypeError('"size" argument must be a number')}else if(size<0){throw new RangeError('"size" argument must not be negative')}}function alloc(size,fill,encoding){assertSize(size);if(size<=0){return createBuffer(size)}if(fill!==void 0){return typeof encoding==="string"?createBuffer(size).fill(fill,encoding):createBuffer(size).fill(fill)}return createBuffer(size)}Buffer2.alloc=function(size,fill,encoding){return alloc(size,fill,encoding)};function allocUnsafe(size){assertSize(size);return createBuffer(size<0?0:checked(size)|0)}Buffer2.allocUnsafe=function(size){return allocUnsafe(size)};Buffer2.allocUnsafeSlow=function(size){return allocUnsafe(size)};function fromString(string,encoding){if(typeof encoding!=="string"||encoding===""){encoding="utf8"}if(!Buffer2.isEncoding(encoding)){throw new TypeError('"encoding" must be a valid string encoding')}var length=byteLength(string,encoding)|0;var buf=createBuffer(length);var actual=buf.write(string,encoding);if(actual!==length){buf=buf.slice(0,actual)}return buf}function fromArrayLike(array){var length=array.length<0?0:checked(array.length)|0;var buf=createBuffer(length);for(var i=0;i=K_MAX_LENGTH){throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+K_MAX_LENGTH.toString(16)+" bytes")}return length|0}function SlowBuffer(length){if(+length!=length){length=0}return Buffer2.alloc(+length)}Buffer2.isBuffer=function isBuffer(b){return b!=null&&b._isBuffer===true};Buffer2.compare=function compare(a,b){if(!Buffer2.isBuffer(a)||!Buffer2.isBuffer(b)){throw new TypeError("Arguments must be Buffers")}if(a===b)return 0;var x=a.length;var y=b.length;for(var i=0,len=Math.min(x,y);i>>1;case"base64":return base64ToBytes(string).length;default:if(loweredCase)return utf8ToBytes(string).length;encoding=(""+encoding).toLowerCase();loweredCase=true}}}Buffer2.byteLength=byteLength;function slowToString(encoding,start,end){var loweredCase=false;if(start===void 0||start<0){start=0}if(start>this.length){return""}if(end===void 0||end>this.length){end=this.length}if(end<=0){return""}end>>>=0;start>>>=0;if(end<=start){return""}if(!encoding)encoding="utf8";while(true){switch(encoding){case"hex":return hexSlice(this,start,end);case"utf8":case"utf-8":return utf8Slice(this,start,end);case"ascii":return asciiSlice(this,start,end);case"latin1":case"binary":return latin1Slice(this,start,end);case"base64":return base64Slice(this,start,end);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return utf16leSlice(this,start,end);default:if(loweredCase)throw new TypeError("Unknown encoding: "+encoding);encoding=(encoding+"").toLowerCase();loweredCase=true}}}Buffer2.prototype._isBuffer=true;function swap(b,n,m){var i=b[n];b[n]=b[m];b[m]=i}Buffer2.prototype.swap16=function swap16(){var len=this.length;if(len%2!==0){throw new RangeError("Buffer size must be a multiple of 16-bits")}for(var i=0;i0){str=this.toString("hex",0,max).match(/.{2}/g).join(" ");if(this.length>max)str+=" ... "}return""};Buffer2.prototype.compare=function compare(target,start,end,thisStart,thisEnd){if(!Buffer2.isBuffer(target)){throw new TypeError("Argument must be a Buffer")}if(start===void 0){start=0}if(end===void 0){end=target?target.length:0}if(thisStart===void 0){thisStart=0}if(thisEnd===void 0){thisEnd=this.length}if(start<0||end>target.length||thisStart<0||thisEnd>this.length){throw new RangeError("out of range index")}if(thisStart>=thisEnd&&start>=end){return 0}if(thisStart>=thisEnd){return-1}if(start>=end){return 1}start>>>=0;end>>>=0;thisStart>>>=0;thisEnd>>>=0;if(this===target)return 0;var x=thisEnd-thisStart;var y=end-start;var len=Math.min(x,y);var thisCopy=this.slice(thisStart,thisEnd);var targetCopy=target.slice(start,end);for(var i=0;i2147483647){byteOffset=2147483647}else if(byteOffset<-2147483648){byteOffset=-2147483648}byteOffset=+byteOffset;if(numberIsNaN(byteOffset)){byteOffset=dir?0:buffer.length-1}if(byteOffset<0)byteOffset=buffer.length+byteOffset;if(byteOffset>=buffer.length){if(dir)return-1;else byteOffset=buffer.length-1}else if(byteOffset<0){if(dir)byteOffset=0;else return-1}if(typeof val==="string"){val=Buffer2.from(val,encoding)}if(Buffer2.isBuffer(val)){if(val.length===0){return-1}return arrayIndexOf(buffer,val,byteOffset,encoding,dir)}else if(typeof val==="number"){val=val&255;if(typeof Uint8Array.prototype.indexOf==="function"){if(dir){return Uint8Array.prototype.indexOf.call(buffer,val,byteOffset)}else{return Uint8Array.prototype.lastIndexOf.call(buffer,val,byteOffset)}}return arrayIndexOf(buffer,[val],byteOffset,encoding,dir)}throw new TypeError("val must be string, number or Buffer")}function arrayIndexOf(arr,val,byteOffset,encoding,dir){var indexSize=1;var arrLength=arr.length;var valLength=val.length;if(encoding!==void 0){encoding=String(encoding).toLowerCase();if(encoding==="ucs2"||encoding==="ucs-2"||encoding==="utf16le"||encoding==="utf-16le"){if(arr.length<2||val.length<2){return-1}indexSize=2;arrLength/=2;valLength/=2;byteOffset/=2}}function read(buf,i2){if(indexSize===1){return buf[i2]}else{return buf.readUInt16BE(i2*indexSize)}}var i;if(dir){var foundIndex=-1;for(i=byteOffset;iarrLength)byteOffset=arrLength-valLength;for(i=byteOffset;i>=0;i--){var found=true;for(var j=0;jremaining){length=remaining}}var strLen=string.length;if(strLen%2!==0)throw new TypeError("Invalid hex string");if(length>strLen/2){length=strLen/2}for(var i=0;i>>0;if(isFinite(length)){length=length>>>0;if(encoding===void 0)encoding="utf8"}else{encoding=length;length=void 0}}else{throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported")}var remaining=this.length-offset;if(length===void 0||length>remaining)length=remaining;if(string.length>0&&(length<0||offset<0)||offset>this.length){throw new RangeError("Attempt to write outside buffer bounds")}if(!encoding)encoding="utf8";var loweredCase=false;for(;;){switch(encoding){case"hex":return hexWrite(this,string,offset,length);case"utf8":case"utf-8":return utf8Write(this,string,offset,length);case"ascii":return asciiWrite(this,string,offset,length);case"latin1":case"binary":return latin1Write(this,string,offset,length);case"base64":return base64Write(this,string,offset,length);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return ucs2Write(this,string,offset,length);default:if(loweredCase)throw new TypeError("Unknown encoding: "+encoding);encoding=(""+encoding).toLowerCase();loweredCase=true}}};Buffer2.prototype.toJSON=function toJSON(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function base64Slice(buf,start,end){if(start===0&&end===buf.length){return base64.fromByteArray(buf)}else{return base64.fromByteArray(buf.slice(start,end))}}function utf8Slice(buf,start,end){end=Math.min(buf.length,end);var res=[];var i=start;while(i239?4:firstByte>223?3:firstByte>191?2:1;if(i+bytesPerSequence<=end){var secondByte,thirdByte,fourthByte,tempCodePoint;switch(bytesPerSequence){case 1:if(firstByte<128){codePoint=firstByte}break;case 2:secondByte=buf[i+1];if((secondByte&192)===128){tempCodePoint=(firstByte&31)<<6|secondByte&63;if(tempCodePoint>127){codePoint=tempCodePoint}}break;case 3:secondByte=buf[i+1];thirdByte=buf[i+2];if((secondByte&192)===128&&(thirdByte&192)===128){tempCodePoint=(firstByte&15)<<12|(secondByte&63)<<6|thirdByte&63;if(tempCodePoint>2047&&(tempCodePoint<55296||tempCodePoint>57343)){codePoint=tempCodePoint}}break;case 4:secondByte=buf[i+1];thirdByte=buf[i+2];fourthByte=buf[i+3];if((secondByte&192)===128&&(thirdByte&192)===128&&(fourthByte&192)===128){tempCodePoint=(firstByte&15)<<18|(secondByte&63)<<12|(thirdByte&63)<<6|fourthByte&63;if(tempCodePoint>65535&&tempCodePoint<1114112){codePoint=tempCodePoint}}}}if(codePoint===null){codePoint=65533;bytesPerSequence=1}else if(codePoint>65535){codePoint-=65536;res.push(codePoint>>>10&1023|55296);codePoint=56320|codePoint&1023}res.push(codePoint);i+=bytesPerSequence}return decodeCodePointsArray(res)}var MAX_ARGUMENTS_LENGTH=4096;function decodeCodePointsArray(codePoints){var len=codePoints.length;if(len<=MAX_ARGUMENTS_LENGTH){return String.fromCharCode.apply(String,codePoints)}var res="";var i=0;while(ilen)end=len;var out="";for(var i=start;ilen){start=len}if(end<0){end+=len;if(end<0)end=0}else if(end>len){end=len}if(endlength)throw new RangeError("Trying to access beyond buffer length")}Buffer2.prototype.readUIntLE=function readUIntLE(offset,byteLength2,noAssert){offset=offset>>>0;byteLength2=byteLength2>>>0;if(!noAssert)checkOffset(offset,byteLength2,this.length);var val=this[offset];var mul=1;var i=0;while(++i>>0;byteLength2=byteLength2>>>0;if(!noAssert){checkOffset(offset,byteLength2,this.length)}var val=this[offset+--byteLength2];var mul=1;while(byteLength2>0&&(mul*=256)){val+=this[offset+--byteLength2]*mul}return val};Buffer2.prototype.readUInt8=function readUInt8(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,1,this.length);return this[offset]};Buffer2.prototype.readUInt16LE=function readUInt16LE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,2,this.length);return this[offset]|this[offset+1]<<8};Buffer2.prototype.readUInt16BE=function readUInt16BE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,2,this.length);return this[offset]<<8|this[offset+1]};Buffer2.prototype.readUInt32LE=function readUInt32LE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,4,this.length);return(this[offset]|this[offset+1]<<8|this[offset+2]<<16)+this[offset+3]*16777216};Buffer2.prototype.readUInt32BE=function readUInt32BE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,4,this.length);return this[offset]*16777216+(this[offset+1]<<16|this[offset+2]<<8|this[offset+3])};Buffer2.prototype.readIntLE=function readIntLE(offset,byteLength2,noAssert){offset=offset>>>0;byteLength2=byteLength2>>>0;if(!noAssert)checkOffset(offset,byteLength2,this.length);var val=this[offset];var mul=1;var i=0;while(++i=mul)val-=Math.pow(2,8*byteLength2);return val};Buffer2.prototype.readIntBE=function readIntBE(offset,byteLength2,noAssert){offset=offset>>>0;byteLength2=byteLength2>>>0;if(!noAssert)checkOffset(offset,byteLength2,this.length);var i=byteLength2;var mul=1;var val=this[offset+--i];while(i>0&&(mul*=256)){val+=this[offset+--i]*mul}mul*=128;if(val>=mul)val-=Math.pow(2,8*byteLength2);return val};Buffer2.prototype.readInt8=function readInt8(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,1,this.length);if(!(this[offset]&128))return this[offset];return(255-this[offset]+1)*-1};Buffer2.prototype.readInt16LE=function readInt16LE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,2,this.length);var val=this[offset]|this[offset+1]<<8;return val&32768?val|4294901760:val};Buffer2.prototype.readInt16BE=function readInt16BE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,2,this.length);var val=this[offset+1]|this[offset]<<8;return val&32768?val|4294901760:val};Buffer2.prototype.readInt32LE=function readInt32LE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,4,this.length);return this[offset]|this[offset+1]<<8|this[offset+2]<<16|this[offset+3]<<24};Buffer2.prototype.readInt32BE=function readInt32BE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,4,this.length);return this[offset]<<24|this[offset+1]<<16|this[offset+2]<<8|this[offset+3]};Buffer2.prototype.readFloatLE=function readFloatLE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,4,this.length);return ieee754.read(this,offset,true,23,4)};Buffer2.prototype.readFloatBE=function readFloatBE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,4,this.length);return ieee754.read(this,offset,false,23,4)};Buffer2.prototype.readDoubleLE=function readDoubleLE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,8,this.length);return ieee754.read(this,offset,true,52,8)};Buffer2.prototype.readDoubleBE=function readDoubleBE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,8,this.length);return ieee754.read(this,offset,false,52,8)};function checkInt(buf,value,offset,ext,max,min){if(!Buffer2.isBuffer(buf))throw new TypeError('"buffer" argument must be a Buffer instance');if(value>max||valuebuf.length)throw new RangeError("Index out of range")}Buffer2.prototype.writeUIntLE=function writeUIntLE(value,offset,byteLength2,noAssert){value=+value;offset=offset>>>0;byteLength2=byteLength2>>>0;if(!noAssert){var maxBytes=Math.pow(2,8*byteLength2)-1;checkInt(this,value,offset,byteLength2,maxBytes,0)}var mul=1;var i=0;this[offset]=value&255;while(++i>>0;byteLength2=byteLength2>>>0;if(!noAssert){var maxBytes=Math.pow(2,8*byteLength2)-1;checkInt(this,value,offset,byteLength2,maxBytes,0)}var i=byteLength2-1;var mul=1;this[offset+i]=value&255;while(--i>=0&&(mul*=256)){this[offset+i]=value/mul&255}return offset+byteLength2};Buffer2.prototype.writeUInt8=function writeUInt8(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,1,255,0);this[offset]=value&255;return offset+1};Buffer2.prototype.writeUInt16LE=function writeUInt16LE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,2,65535,0);this[offset]=value&255;this[offset+1]=value>>>8;return offset+2};Buffer2.prototype.writeUInt16BE=function writeUInt16BE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,2,65535,0);this[offset]=value>>>8;this[offset+1]=value&255;return offset+2};Buffer2.prototype.writeUInt32LE=function writeUInt32LE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,4,4294967295,0);this[offset+3]=value>>>24;this[offset+2]=value>>>16;this[offset+1]=value>>>8;this[offset]=value&255;return offset+4};Buffer2.prototype.writeUInt32BE=function writeUInt32BE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,4,4294967295,0);this[offset]=value>>>24;this[offset+1]=value>>>16;this[offset+2]=value>>>8;this[offset+3]=value&255;return offset+4};Buffer2.prototype.writeIntLE=function writeIntLE(value,offset,byteLength2,noAssert){value=+value;offset=offset>>>0;if(!noAssert){var limit=Math.pow(2,8*byteLength2-1);checkInt(this,value,offset,byteLength2,limit-1,-limit)}var i=0;var mul=1;var sub=0;this[offset]=value&255;while(++i>0)-sub&255}return offset+byteLength2};Buffer2.prototype.writeIntBE=function writeIntBE(value,offset,byteLength2,noAssert){value=+value;offset=offset>>>0;if(!noAssert){var limit=Math.pow(2,8*byteLength2-1);checkInt(this,value,offset,byteLength2,limit-1,-limit)}var i=byteLength2-1;var mul=1;var sub=0;this[offset+i]=value&255;while(--i>=0&&(mul*=256)){if(value<0&&sub===0&&this[offset+i+1]!==0){sub=1}this[offset+i]=(value/mul>>0)-sub&255}return offset+byteLength2};Buffer2.prototype.writeInt8=function writeInt8(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,1,127,-128);if(value<0)value=255+value+1;this[offset]=value&255;return offset+1};Buffer2.prototype.writeInt16LE=function writeInt16LE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,2,32767,-32768);this[offset]=value&255;this[offset+1]=value>>>8;return offset+2};Buffer2.prototype.writeInt16BE=function writeInt16BE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,2,32767,-32768);this[offset]=value>>>8;this[offset+1]=value&255;return offset+2};Buffer2.prototype.writeInt32LE=function writeInt32LE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,4,2147483647,-2147483648);this[offset]=value&255;this[offset+1]=value>>>8;this[offset+2]=value>>>16;this[offset+3]=value>>>24;return offset+4};Buffer2.prototype.writeInt32BE=function writeInt32BE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,4,2147483647,-2147483648);if(value<0)value=4294967295+value+1;this[offset]=value>>>24;this[offset+1]=value>>>16;this[offset+2]=value>>>8;this[offset+3]=value&255;return offset+4};function checkIEEE754(buf,value,offset,ext,max,min){if(offset+ext>buf.length)throw new RangeError("Index out of range");if(offset<0)throw new RangeError("Index out of range")}function writeFloat(buf,value,offset,littleEndian,noAssert){value=+value;offset=offset>>>0;if(!noAssert){checkIEEE754(buf,value,offset,4,34028234663852886e22,-34028234663852886e22)}ieee754.write(buf,value,offset,littleEndian,23,4);return offset+4}Buffer2.prototype.writeFloatLE=function writeFloatLE(value,offset,noAssert){return writeFloat(this,value,offset,true,noAssert)};Buffer2.prototype.writeFloatBE=function writeFloatBE(value,offset,noAssert){return writeFloat(this,value,offset,false,noAssert)};function writeDouble(buf,value,offset,littleEndian,noAssert){value=+value;offset=offset>>>0;if(!noAssert){checkIEEE754(buf,value,offset,8,17976931348623157e292,-17976931348623157e292)}ieee754.write(buf,value,offset,littleEndian,52,8);return offset+8}Buffer2.prototype.writeDoubleLE=function writeDoubleLE(value,offset,noAssert){return writeDouble(this,value,offset,true,noAssert)};Buffer2.prototype.writeDoubleBE=function writeDoubleBE(value,offset,noAssert){return writeDouble(this,value,offset,false,noAssert)};Buffer2.prototype.copy=function copy(target,targetStart,start,end){if(!start)start=0;if(!end&&end!==0)end=this.length;if(targetStart>=target.length)targetStart=target.length;if(!targetStart)targetStart=0;if(end>0&&end=this.length)throw new RangeError("sourceStart out of bounds");if(end<0)throw new RangeError("sourceEnd out of bounds");if(end>this.length)end=this.length;if(target.length-targetStart=0;--i){target[i+targetStart]=this[i+start]}}else if(len<1e3){for(i=0;i>>0;end=end===void 0?this.length:end>>>0;if(!val)val=0;var i;if(typeof val==="number"){for(i=start;i55295&&codePoint<57344){if(!leadSurrogate){if(codePoint>56319){if((units-=3)>-1)bytes.push(239,191,189);continue}else if(i+1===length){if((units-=3)>-1)bytes.push(239,191,189);continue}leadSurrogate=codePoint;continue}if(codePoint<56320){if((units-=3)>-1)bytes.push(239,191,189);leadSurrogate=codePoint;continue}codePoint=(leadSurrogate-55296<<10|codePoint-56320)+65536}else if(leadSurrogate){if((units-=3)>-1)bytes.push(239,191,189)}leadSurrogate=null;if(codePoint<128){if((units-=1)<0)break;bytes.push(codePoint)}else if(codePoint<2048){if((units-=2)<0)break;bytes.push(codePoint>>6|192,codePoint&63|128)}else if(codePoint<65536){if((units-=3)<0)break;bytes.push(codePoint>>12|224,codePoint>>6&63|128,codePoint&63|128)}else if(codePoint<1114112){if((units-=4)<0)break;bytes.push(codePoint>>18|240,codePoint>>12&63|128,codePoint>>6&63|128,codePoint&63|128)}else{throw new Error("Invalid code point")}}return bytes}function asciiToBytes(str){var byteArray=[];for(var i=0;i>8;lo=c%256;byteArray.push(lo);byteArray.push(hi)}return byteArray}function base64ToBytes(str){return base64.toByteArray(base64clean(str))}function blitBuffer(src,dst,offset,length){for(var i=0;i=dst.length||i>=src.length)break;dst[i+offset]=src[i]}return i}function isArrayBuffer(obj){return obj instanceof ArrayBuffer||obj!=null&&obj.constructor!=null&&obj.constructor.name==="ArrayBuffer"&&typeof obj.byteLength==="number"}function isArrayBufferView(obj){return typeof ArrayBuffer.isView==="function"&&ArrayBuffer.isView(obj)}function numberIsNaN(obj){return obj!==obj}}).call(exports2,__webpack_require__(1))},function(module2,exports2){"use strict";exports2.byteLength=byteLength;exports2.toByteArray=toByteArray;exports2.fromByteArray=fromByteArray;var lookup=[];var revLookup=[];var Arr=typeof Uint8Array!=="undefined"?Uint8Array:Array;var code="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(var i=0,len=code.length;i0){throw new Error("Invalid string. Length must be a multiple of 4")}return b64[len2-2]==="="?2:b64[len2-1]==="="?1:0}function byteLength(b64){return b64.length*3/4-placeHoldersCount(b64)}function toByteArray(b64){var i2,j,l,tmp,placeHolders,arr;var len2=b64.length;placeHolders=placeHoldersCount(b64);arr=new Arr(len2*3/4-placeHolders);l=placeHolders>0?len2-4:len2;var L=0;for(i2=0,j=0;i2>16&255;arr[L++]=tmp>>8&255;arr[L++]=tmp&255}if(placeHolders===2){tmp=revLookup[b64.charCodeAt(i2)]<<2|revLookup[b64.charCodeAt(i2+1)]>>4;arr[L++]=tmp&255}else if(placeHolders===1){tmp=revLookup[b64.charCodeAt(i2)]<<10|revLookup[b64.charCodeAt(i2+1)]<<4|revLookup[b64.charCodeAt(i2+2)]>>2;arr[L++]=tmp>>8&255;arr[L++]=tmp&255}return arr}function tripletToBase64(num){return lookup[num>>18&63]+lookup[num>>12&63]+lookup[num>>6&63]+lookup[num&63]}function encodeChunk(uint8,start,end){var tmp;var output=[];for(var i2=start;i2len22?len22:i2+maxChunkLength))}if(extraBytes===1){tmp=uint8[len2-1];output+=lookup[tmp>>2];output+=lookup[tmp<<4&63];output+="=="}else if(extraBytes===2){tmp=(uint8[len2-2]<<8)+uint8[len2-1];output+=lookup[tmp>>10];output+=lookup[tmp>>4&63];output+=lookup[tmp<<2&63];output+="="}parts.push(output);return parts.join("")}},function(module2,exports2){exports2.read=function(buffer,offset,isLE,mLen,nBytes){var e,m;var eLen=nBytes*8-mLen-1;var eMax=(1<>1;var nBits=-7;var i=isLE?nBytes-1:0;var d=isLE?-1:1;var s=buffer[offset+i];i+=d;e=s&(1<<-nBits)-1;s>>=-nBits;nBits+=eLen;for(;nBits>0;e=e*256+buffer[offset+i],i+=d,nBits-=8){}m=e&(1<<-nBits)-1;e>>=-nBits;nBits+=mLen;for(;nBits>0;m=m*256+buffer[offset+i],i+=d,nBits-=8){}if(e===0){e=1-eBias}else if(e===eMax){return m?NaN:(s?-1:1)*Infinity}else{m=m+Math.pow(2,mLen);e=e-eBias}return(s?-1:1)*m*Math.pow(2,e-mLen)};exports2.write=function(buffer,value,offset,isLE,mLen,nBytes){var e,m,c;var eLen=nBytes*8-mLen-1;var eMax=(1<>1;var rt=mLen===23?Math.pow(2,-24)-Math.pow(2,-77):0;var i=isLE?0:nBytes-1;var d=isLE?1:-1;var s=value<0||value===0&&1/value<0?1:0;value=Math.abs(value);if(isNaN(value)||value===Infinity){m=isNaN(value)?1:0;e=eMax}else{e=Math.floor(Math.log(value)/Math.LN2);if(value*(c=Math.pow(2,-e))<1){e--;c*=2}if(e+eBias>=1){value+=rt/c}else{value+=rt*Math.pow(2,1-eBias)}if(value*c>=2){e++;c/=2}if(e+eBias>=eMax){m=0;e=eMax}else if(e+eBias>=1){m=(value*c-1)*Math.pow(2,mLen);e=e+eBias}else{m=value*Math.pow(2,eBias-1)*Math.pow(2,mLen);e=0}}for(;mLen>=8;buffer[offset+i]=m&255,i+=d,m/=256,mLen-=8){}e=e<0;buffer[offset+i]=e&255,i+=d,e/=256,eLen-=8){}buffer[offset+i-d]|=s*128}},function(module2,exports2){module2.exports=function(module3){if(!module3.webpackPolyfill){module3.deprecate=function(){};module3.paths=[];module3.children=[];module3.webpackPolyfill=1}return module3}},function(module2,exports2,__webpack_require__){"use strict";var Process=__webpack_require__(7);var process=new Process,processProxy={};function defineKey(key2){if(processProxy[key2]){return}if(typeof process[key2]==="function"){processProxy[key2]=function(){return process[key2].apply(process,arguments)}}else{processProxy[key2]=process[key2]}}for(var key in process){defineKey(key)}processProxy.initializeTTYs=function(){if(process.stdin===null){process.initializeTTYs();processProxy.stdin=process.stdin;processProxy.stdout=process.stdout;processProxy.stderr=process.stderr}};process.nextTick(function(){processProxy.initializeTTYs()});module2.exports=processProxy},function(module2,exports2,__webpack_require__){(function(__dirname){"use strict";var __extends=this&&this.__extends||function(d,b){for(var p in b)if(b.hasOwnProperty(p))d[p]=b[p];function __(){this.constructor=d}d.prototype=b===null?Object.create(b):(__.prototype=b.prototype,new __)};var events=__webpack_require__(8);var path=null;var Item=function(){function Item2(fun,array){this.fun=fun;this.array=array}Item2.prototype.run=function(){this.fun.apply(null,this.array)};return Item2}();var NextTickQueue=function(){function NextTickQueue2(){this._queue=[];this._draining=false;this._currentQueue=null;this._queueIndex=-1}NextTickQueue2.prototype.push=function(item){var _this=this;if(this._queue.push(item)===1&&!this._draining){setTimeout(function(){return _this._drainQueue()},0)}};NextTickQueue2.prototype._cleanUpNextTick=function(){this._draining=false;if(this._currentQueue&&this._currentQueue.length){this._queue=this._currentQueue.concat(this._queue)}else{this._queueIndex=-1}if(this._queue.length){this._drainQueue()}};NextTickQueue2.prototype._drainQueue=function(){var _this=this;if(this._draining){return}var timeout=setTimeout(function(){return _this._cleanUpNextTick()});this._draining=true;var len=this._queue.length;while(len){this._currentQueue=this._queue;this._queue=[];while(++this._queueIndex0&&this._events[type].length>m){this._events[type].warned=true;console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[type].length);if(typeof console.trace==="function"){console.trace()}}}return this};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.once=function(type,listener){if(!isFunction(listener))throw TypeError("listener must be a function");var fired=false;function g(){this.removeListener(type,g);if(!fired){fired=true;listener.apply(this,arguments)}}g.listener=listener;this.on(type,g);return this};EventEmitter.prototype.removeListener=function(type,listener){var list,position,length,i;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events||!this._events[type])return this;list=this._events[type];length=list.length;position=-1;if(list===listener||isFunction(list.listener)&&list.listener===listener){delete this._events[type];if(this._events.removeListener)this.emit("removeListener",type,listener)}else if(isObject(list)){for(i=length;i-- >0;){if(list[i]===listener||list[i].listener&&list[i].listener===listener){position=i;break}}if(position<0)return this;if(list.length===1){list.length=0;delete this._events[type]}else{list.splice(position,1)}if(this._events.removeListener)this.emit("removeListener",type,listener)}return this};EventEmitter.prototype.removeAllListeners=function(type){var key,listeners;if(!this._events)return this;if(!this._events.removeListener){if(arguments.length===0)this._events={};else if(this._events[type])delete this._events[type];return this}if(arguments.length===0){for(key in this._events){if(key==="removeListener")continue;this.removeAllListeners(key)}this.removeAllListeners("removeListener");this._events={};return this}listeners=this._events[type];if(isFunction(listeners)){this.removeListener(type,listeners)}else if(listeners){while(listeners.length)this.removeListener(type,listeners[listeners.length-1])}delete this._events[type];return this};EventEmitter.prototype.listeners=function(type){var ret;if(!this._events||!this._events[type])ret=[];else if(isFunction(this._events[type]))ret=[this._events[type]];else ret=this._events[type].slice();return ret};EventEmitter.prototype.listenerCount=function(type){if(this._events){var evlistener=this._events[type];if(isFunction(evlistener))return 1;else if(evlistener)return evlistener.length}return 0};EventEmitter.listenerCount=function(emitter,type){return emitter.listenerCount(type)};function isFunction(arg){return typeof arg==="function"}function isNumber(arg){return typeof arg==="number"}function isObject(arg){return typeof arg==="object"&&arg!==null}function isUndefined(arg){return arg===void 0}},function(module2,exports2,__webpack_require__){(function(process){"use strict";var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;function posixSplitPath(filename){var out=splitPathRe.exec(filename);out.shift();return out}var path=function(){function path2(){}path2.normalize=function(p){if(p===""){p="."}var absolute=p.charAt(0)===path2.sep;p=path2._removeDuplicateSeps(p);var components=p.split(path2.sep);var goodComponents=[];for(var idx=0;idx0&&goodComponents[0]!=="..")){goodComponents.pop()}else{goodComponents.push(c)}}if(!absolute&&goodComponents.length<2){switch(goodComponents.length){case 1:if(goodComponents[0]===""){goodComponents.unshift(".")}break;default:goodComponents.push(".")}}p=goodComponents.join(path2.sep);if(absolute&&p.charAt(0)!==path2.sep){p=path2.sep+p}return p};path2.join=function(){var paths=[];for(var _i=0;_i1&&resolved.charAt(resolved.length-1)===path2.sep){return resolved.substr(0,resolved.length-1)}if(resolved.charAt(0)!==path2.sep){if(resolved.charAt(0)==="."&&(resolved.length===1||resolved.charAt(1)===path2.sep)){resolved=resolved.length===1?"":resolved.substr(2)}var cwd=process.cwd();if(resolved!==""){resolved=this.normalize(cwd+(cwd!=="/"?path2.sep:"")+resolved)}else{resolved=cwd}}return resolved};path2.relative=function(from,to){var i;from=path2.resolve(from);to=path2.resolve(to);var fromSegs=from.split(path2.sep);var toSegs=to.split(path2.sep);toSegs.shift();fromSegs.shift();var upCount=0;var downSegs=[];for(i=0;ifromSegs.length){upCount=fromSegs.length}var rv="";for(i=0;i1&&rv.charAt(rv.length-1)===path2.sep){rv=rv.substr(0,rv.length-1)}return rv};path2.dirname=function(p){p=path2._removeDuplicateSeps(p);var absolute=p.charAt(0)===path2.sep;var sections=p.split(path2.sep);if(sections.pop()===""&§ions.length>0){sections.pop()}if(sections.length>1||sections.length===1&&!absolute){return sections.join(path2.sep)}else if(absolute){return path2.sep}else{return"."}};path2.basename=function(p,ext){if(ext===void 0){ext=""}if(p===""){return p}p=path2.normalize(p);var sections=p.split(path2.sep);var lastPart=sections[sections.length-1];if(lastPart===""&§ions.length>1){return sections[sections.length-2]}if(ext.length>0){var lastPartExt=lastPart.substr(lastPart.length-ext.length);if(lastPartExt===ext){return lastPart.substr(0,lastPart.length-ext.length)}}return lastPart};path2.extname=function(p){p=path2.normalize(p);var sections=p.split(path2.sep);p=sections.pop();if(p===""&§ions.length>0){p=sections.pop()}if(p===".."){return""}var i=p.lastIndexOf(".");if(i===-1||i===0){return""}return p.substr(i)};path2.isAbsolute=function(p){return p.length>0&&p.charAt(0)===path2.sep};path2._makeLong=function(p){return p};path2.parse=function(p){var allParts=posixSplitPath(p);return{root:allParts[0],dir:allParts[0]+allParts[1].slice(0,-1),base:allParts[2],ext:allParts[3],name:allParts[2].slice(0,allParts[2].length-allParts[3].length)}};path2.format=function(pathObject){if(pathObject===null||typeof pathObject!=="object"){throw new TypeError("Parameter 'pathObject' must be an object, not "+typeof pathObject)}var root=pathObject.root||"";if(typeof root!=="string"){throw new TypeError("'pathObject.root' must be a string or undefined, not "+typeof pathObject.root)}var dir=pathObject.dir?pathObject.dir+path2.sep:"";var base=pathObject.base||"";return dir+base};path2._removeDuplicateSeps=function(p){p=p.replace(this._replaceRegex,this.sep);return p};path2.sep="/";path2._replaceRegex=new RegExp("//+","g");path2.delimiter=":";path2.posix=path2;path2.win32=path2;return path2}();var _=path;module2.exports=path}).call(exports2,__webpack_require__(6))},function(module2,exports2,__webpack_require__){(function(Buffer2){"use strict";var __extends=this&&this.__extends||function(d,b){for(var p in b)if(b.hasOwnProperty(p))d[p]=b[p];function __(){this.constructor=d}d.prototype=b===null?Object.create(b):(__.prototype=b.prototype,new __)};var stream=__webpack_require__(11);var TTY=function(_super){__extends(TTY2,_super);function TTY2(){_super.call(this);this.isRaw=false;this.columns=80;this.rows=120;this.isTTY=true;this._bufferedWrites=[];this._waitingForWrites=false}TTY2.prototype.setRawMode=function(mode){if(this.isRaw!==mode){this.isRaw=mode;this.emit("modeChange")}};TTY2.prototype.changeColumns=function(columns){if(columns!==this.columns){this.columns=columns;this.emit("resize")}};TTY2.prototype.changeRows=function(rows){if(rows!==this.rows){this.rows=rows;this.emit("resize")}};TTY2.isatty=function(fd){return fd&&fd instanceof TTY2};TTY2.prototype._write=function(chunk,encoding,cb){var error;try{var data;if(typeof chunk==="string"){data=new Buffer2(chunk,encoding)}else{data=chunk}this._bufferedWrites.push(data);if(this._waitingForWrites){this._read(1024)}}catch(e){error=e}finally{cb(error)}};TTY2.prototype._read=function(size){if(this._bufferedWrites.length===0){this._waitingForWrites=true}else{while(this._bufferedWrites.length>0){this._waitingForWrites=this.push(this._bufferedWrites.shift());if(!this._waitingForWrites){break}}}};return TTY2}(stream.Duplex);module2.exports=TTY}).call(exports2,__webpack_require__(1))},function(module2,exports2,__webpack_require__){module2.exports=Stream;var EE=__webpack_require__(8).EventEmitter;var inherits=__webpack_require__(12);inherits(Stream,EE);Stream.Readable=__webpack_require__(13);Stream.Writable=__webpack_require__(27);Stream.Duplex=__webpack_require__(28);Stream.Transform=__webpack_require__(29);Stream.PassThrough=__webpack_require__(30);Stream.Stream=Stream;function Stream(){EE.call(this)}Stream.prototype.pipe=function(dest,options){var source=this;function ondata(chunk){if(dest.writable){if(false===dest.write(chunk)&&source.pause){source.pause()}}}source.on("data",ondata);function ondrain(){if(source.readable&&source.resume){source.resume()}}dest.on("drain",ondrain);if(!dest._isStdio&&(!options||options.end!==false)){source.on("end",onend);source.on("close",onclose)}var didOnEnd=false;function onend(){if(didOnEnd)return;didOnEnd=true;dest.end()}function onclose(){if(didOnEnd)return;didOnEnd=true;if(typeof dest.destroy==="function")dest.destroy()}function onerror(er){cleanup();if(EE.listenerCount(this,"error")===0){throw er}}source.on("error",onerror);dest.on("error",onerror);function cleanup(){source.removeListener("data",ondata);dest.removeListener("drain",ondrain);source.removeListener("end",onend);source.removeListener("close",onclose);source.removeListener("error",onerror);dest.removeListener("error",onerror);source.removeListener("end",cleanup);source.removeListener("close",cleanup);dest.removeListener("close",cleanup)}source.on("end",cleanup);source.on("close",cleanup);dest.on("close",cleanup);dest.emit("pipe",source);return dest}},function(module2,exports2){if(typeof Object.create==="function"){module2.exports=function inherits(ctor,superCtor){ctor.super_=superCtor;ctor.prototype=Object.create(superCtor.prototype,{constructor:{value:ctor,enumerable:false,writable:true,configurable:true}})}}else{module2.exports=function inherits(ctor,superCtor){ctor.super_=superCtor;var TempCtor=function(){};TempCtor.prototype=superCtor.prototype;ctor.prototype=new TempCtor;ctor.prototype.constructor=ctor}}},function(module2,exports2,__webpack_require__){(function(process){var Stream=function(){try{return __webpack_require__(11)}catch(_){}}();exports2=module2.exports=__webpack_require__(14);exports2.Stream=Stream||exports2;exports2.Readable=exports2;exports2.Writable=__webpack_require__(22);exports2.Duplex=__webpack_require__(21);exports2.Transform=__webpack_require__(25);exports2.PassThrough=__webpack_require__(26);if(!process.browser&&process.env.READABLE_STREAM==="disable"&&Stream){module2.exports=Stream}}).call(exports2,__webpack_require__(6))},function(module2,exports2,__webpack_require__){(function(process){"use strict";module2.exports=Readable;var processNextTick=__webpack_require__(15);var isArray=__webpack_require__(16);var Duplex;Readable.ReadableState=ReadableState;var EE=__webpack_require__(8).EventEmitter;var EElistenerCount=function(emitter,type){return emitter.listeners(type).length};var Stream;(function(){try{Stream=__webpack_require__(11)}catch(_){}finally{if(!Stream)Stream=__webpack_require__(8).EventEmitter}})();var Buffer2=__webpack_require__(2).Buffer;var bufferShim=__webpack_require__(17);var util=__webpack_require__(18);util.inherits=__webpack_require__(12);var debugUtil=__webpack_require__(19);var debug=void 0;if(debugUtil&&debugUtil.debuglog){debug=debugUtil.debuglog("stream")}else{debug=function(){}}var BufferList=__webpack_require__(20);var StringDecoder;util.inherits(Readable,Stream);function prependListener(emitter,event,fn){if(typeof emitter.prependListener==="function"){return emitter.prependListener(event,fn)}else{if(!emitter._events||!emitter._events[event])emitter.on(event,fn);else if(isArray(emitter._events[event]))emitter._events[event].unshift(fn);else emitter._events[event]=[fn,emitter._events[event]]}}function ReadableState(options,stream){Duplex=Duplex||__webpack_require__(21);options=options||{};this.objectMode=!!options.objectMode;if(stream instanceof Duplex)this.objectMode=this.objectMode||!!options.readableObjectMode;var hwm=options.highWaterMark;var defaultHwm=this.objectMode?16:16*1024;this.highWaterMark=hwm||hwm===0?hwm:defaultHwm;this.highWaterMark=~~this.highWaterMark;this.buffer=new BufferList;this.length=0;this.pipes=null;this.pipesCount=0;this.flowing=null;this.ended=false;this.endEmitted=false;this.reading=false;this.sync=true;this.needReadable=false;this.emittedReadable=false;this.readableListening=false;this.resumeScheduled=false;this.defaultEncoding=options.defaultEncoding||"utf8";this.ranOut=false;this.awaitDrain=0;this.readingMore=false;this.decoder=null;this.encoding=null;if(options.encoding){if(!StringDecoder)StringDecoder=__webpack_require__(24).StringDecoder;this.decoder=new StringDecoder(options.encoding);this.encoding=options.encoding}}function Readable(options){Duplex=Duplex||__webpack_require__(21);if(!(this instanceof Readable))return new Readable(options);this._readableState=new ReadableState(options,this);this.readable=true;if(options&&typeof options.read==="function")this._read=options.read;Stream.call(this)}Readable.prototype.push=function(chunk,encoding){var state=this._readableState;if(!state.objectMode&&typeof chunk==="string"){encoding=encoding||state.defaultEncoding;if(encoding!==state.encoding){chunk=bufferShim.from(chunk,encoding);encoding=""}}return readableAddChunk(this,state,chunk,encoding,false)};Readable.prototype.unshift=function(chunk){var state=this._readableState;return readableAddChunk(this,state,chunk,"",true)};Readable.prototype.isPaused=function(){return this._readableState.flowing===false};function readableAddChunk(stream,state,chunk,encoding,addToFront){var er=chunkInvalid(state,chunk);if(er){stream.emit("error",er)}else if(chunk===null){state.reading=false;onEofChunk(stream,state)}else if(state.objectMode||chunk&&chunk.length>0){if(state.ended&&!addToFront){var e=new Error("stream.push() after EOF");stream.emit("error",e)}else if(state.endEmitted&&addToFront){var _e=new Error("stream.unshift() after end event");stream.emit("error",_e)}else{var skipAdd;if(state.decoder&&!addToFront&&!encoding){chunk=state.decoder.write(chunk);skipAdd=!state.objectMode&&chunk.length===0}if(!addToFront)state.reading=false;if(!skipAdd){if(state.flowing&&state.length===0&&!state.sync){stream.emit("data",chunk);stream.read(0)}else{state.length+=state.objectMode?1:chunk.length;if(addToFront)state.buffer.unshift(chunk);else state.buffer.push(chunk);if(state.needReadable)emitReadable(stream)}}maybeReadMore(stream,state)}}else if(!addToFront){state.reading=false}return needMoreData(state)}function needMoreData(state){return!state.ended&&(state.needReadable||state.length=MAX_HWM){n=MAX_HWM}else{n--;n|=n>>>1;n|=n>>>2;n|=n>>>4;n|=n>>>8;n|=n>>>16;n++}return n}function howMuchToRead(n,state){if(n<=0||state.length===0&&state.ended)return 0;if(state.objectMode)return 1;if(n!==n){if(state.flowing&&state.length)return state.buffer.head.data.length;else return state.length}if(n>state.highWaterMark)state.highWaterMark=computeNewHighWaterMark(n);if(n<=state.length)return n;if(!state.ended){state.needReadable=true;return 0}return state.length}Readable.prototype.read=function(n){debug("read",n);n=parseInt(n,10);var state=this._readableState;var nOrig=n;if(n!==0)state.emittedReadable=false;if(n===0&&state.needReadable&&(state.length>=state.highWaterMark||state.ended)){debug("read: emitReadable",state.length,state.ended);if(state.length===0&&state.ended)endReadable(this);else emitReadable(this);return null}n=howMuchToRead(n,state);if(n===0&&state.ended){if(state.length===0)endReadable(this);return null}var doRead=state.needReadable;debug("need readable",doRead);if(state.length===0||state.length-n0)ret=fromList(n,state);else ret=null;if(ret===null){state.needReadable=true;n=0}else{state.length-=n}if(state.length===0){if(!state.ended)state.needReadable=true;if(nOrig!==n&&state.ended)endReadable(this)}if(ret!==null)this.emit("data",ret);return ret};function chunkInvalid(state,chunk){var er=null;if(!Buffer2.isBuffer(chunk)&&typeof chunk!=="string"&&chunk!==null&&chunk!==void 0&&!state.objectMode){er=new TypeError("Invalid non-string/buffer chunk")}return er}function onEofChunk(stream,state){if(state.ended)return;if(state.decoder){var chunk=state.decoder.end();if(chunk&&chunk.length){state.buffer.push(chunk);state.length+=state.objectMode?1:chunk.length}}state.ended=true;emitReadable(stream)}function emitReadable(stream){var state=stream._readableState;state.needReadable=false;if(!state.emittedReadable){debug("emitReadable",state.flowing);state.emittedReadable=true;if(state.sync)processNextTick(emitReadable_,stream);else emitReadable_(stream)}}function emitReadable_(stream){debug("emit readable");stream.emit("readable");flow(stream)}function maybeReadMore(stream,state){if(!state.readingMore){state.readingMore=true;processNextTick(maybeReadMore_,stream,state)}}function maybeReadMore_(stream,state){var len=state.length;while(!state.reading&&!state.flowing&&!state.ended&&state.length1&&indexOf(state.pipes,dest)!==-1)&&!cleanedUp){debug("false write response, pause",src._readableState.awaitDrain);src._readableState.awaitDrain++;increasedAwaitDrain=true}src.pause()}}function onerror(er){debug("onerror",er);unpipe();dest.removeListener("error",onerror);if(EElistenerCount(dest,"error")===0)dest.emit("error",er)}prependListener(dest,"error",onerror);function onclose(){dest.removeListener("finish",onfinish);unpipe()}dest.once("close",onclose);function onfinish(){debug("onfinish");dest.removeListener("close",onclose);unpipe()}dest.once("finish",onfinish);function unpipe(){debug("unpipe");src.unpipe(dest)}dest.emit("pipe",src);if(!state.flowing){debug("pipe resume");src.resume()}return dest};function pipeOnDrain(src){return function(){var state=src._readableState;debug("pipeOnDrain",state.awaitDrain);if(state.awaitDrain)state.awaitDrain--;if(state.awaitDrain===0&&EElistenerCount(src,"data")){state.flowing=true;flow(src)}}}Readable.prototype.unpipe=function(dest){var state=this._readableState;if(state.pipesCount===0)return this;if(state.pipesCount===1){if(dest&&dest!==state.pipes)return this;if(!dest)dest=state.pipes;state.pipes=null;state.pipesCount=0;state.flowing=false;if(dest)dest.emit("unpipe",this);return this}if(!dest){var dests=state.pipes;var len=state.pipesCount;state.pipes=null;state.pipesCount=0;state.flowing=false;for(var i=0;i=state.length){if(state.decoder)ret=state.buffer.join("");else if(state.buffer.length===1)ret=state.buffer.head.data;else ret=state.buffer.concat(state.length);state.buffer.clear()}else{ret=fromListPartial(n,state.buffer,state.decoder)}return ret}function fromListPartial(n,list,hasStrings){var ret;if(nstr.length?str.length:n;if(nb===str.length)ret+=str;else ret+=str.slice(0,n);n-=nb;if(n===0){if(nb===str.length){++c;if(p.next)list.head=p.next;else list.head=list.tail=null}else{list.head=p;p.data=str.slice(nb)}break}++c}list.length-=c;return ret}function copyFromBuffer(n,list){var ret=bufferShim.allocUnsafe(n);var p=list.head;var c=1;p.data.copy(ret);n-=p.data.length;while(p=p.next){var buf=p.data;var nb=n>buf.length?buf.length:n;buf.copy(ret,ret.length-n,0,nb);n-=nb;if(n===0){if(nb===buf.length){++c;if(p.next)list.head=p.next;else list.head=list.tail=null}else{list.head=p;p.data=buf.slice(nb)}break}++c}list.length-=c;return ret}function endReadable(stream){var state=stream._readableState;if(state.length>0)throw new Error('"endReadable()" called on non-empty stream');if(!state.endEmitted){state.ended=true;processNextTick(endReadableNT,state,stream)}}function endReadableNT(state,stream){if(!state.endEmitted&&state.length===0){state.endEmitted=true;stream.readable=false;stream.emit("end")}}function forEach(xs,f){for(var i=0,l=xs.length;iMAX_LEN){throw new RangeError("size is too large")}var enc=encoding;var _fill=fill;if(_fill===void 0){enc=void 0;_fill=0}var buf=new Buffer2(size);if(typeof _fill==="string"){var fillBuf=new Buffer2(_fill,enc);var flen=fillBuf.length;var i=-1;while(++iMAX_LEN){throw new RangeError("size is too large")}return new Buffer2(size)};exports2.from=function from(value,encodingOrOffset,length){if(typeof Buffer2.from==="function"&&(!global.Uint8Array||Uint8Array.from!==Buffer2.from)){return Buffer2.from(value,encodingOrOffset,length)}if(typeof value==="number"){throw new TypeError('"value" argument must not be a number')}if(typeof value==="string"){return new Buffer2(value,encodingOrOffset)}if(typeof ArrayBuffer!=="undefined"&&value instanceof ArrayBuffer){var offset=encodingOrOffset;if(arguments.length===1){return new Buffer2(value)}if(typeof offset==="undefined"){offset=0}var len=length;if(typeof len==="undefined"){len=value.byteLength-offset}if(offset>=value.byteLength){throw new RangeError("'offset' is out of bounds")}if(len>value.byteLength-offset){throw new RangeError("'length' is out of bounds")}return new Buffer2(value.slice(offset,offset+len))}if(Buffer2.isBuffer(value)){var out=new Buffer2(value.length);value.copy(out,0,0,value.length);return out}if(value){if(Array.isArray(value)||typeof ArrayBuffer!=="undefined"&&value.buffer instanceof ArrayBuffer||"length"in value){return new Buffer2(value)}if(value.type==="Buffer"&&Array.isArray(value.data)){return new Buffer2(value.data)}}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")};exports2.allocUnsafeSlow=function allocUnsafeSlow(size){if(typeof Buffer2.allocUnsafeSlow==="function"){return Buffer2.allocUnsafeSlow(size)}if(typeof size!=="number"){throw new TypeError("size must be a number")}if(size>=MAX_LEN){throw new RangeError("size is too large")}return new SlowBuffer(size)}}).call(exports2,function(){return this}())},function(module2,exports2,__webpack_require__){(function(Buffer2){function isArray(arg){if(Array.isArray){return Array.isArray(arg)}return objectToString(arg)==="[object Array]"}exports2.isArray=isArray;function isBoolean(arg){return typeof arg==="boolean"}exports2.isBoolean=isBoolean;function isNull(arg){return arg===null}exports2.isNull=isNull;function isNullOrUndefined(arg){return arg==null}exports2.isNullOrUndefined=isNullOrUndefined;function isNumber(arg){return typeof arg==="number"}exports2.isNumber=isNumber;function isString(arg){return typeof arg==="string"}exports2.isString=isString;function isSymbol(arg){return typeof arg==="symbol"}exports2.isSymbol=isSymbol;function isUndefined(arg){return arg===void 0}exports2.isUndefined=isUndefined;function isRegExp(re){return objectToString(re)==="[object RegExp]"}exports2.isRegExp=isRegExp;function isObject(arg){return typeof arg==="object"&&arg!==null}exports2.isObject=isObject;function isDate(d){return objectToString(d)==="[object Date]"}exports2.isDate=isDate;function isError(e){return objectToString(e)==="[object Error]"||e instanceof Error}exports2.isError=isError;function isFunction(arg){return typeof arg==="function"}exports2.isFunction=isFunction;function isPrimitive(arg){return arg===null||typeof arg==="boolean"||typeof arg==="number"||typeof arg==="string"||typeof arg==="symbol"||typeof arg==="undefined"}exports2.isPrimitive=isPrimitive;exports2.isBuffer=Buffer2.isBuffer;function objectToString(o){return Object.prototype.toString.call(o)}}).call(exports2,__webpack_require__(1))},function(module2,exports2){},function(module2,exports2,__webpack_require__){"use strict";var Buffer2=__webpack_require__(2).Buffer;var bufferShim=__webpack_require__(17);module2.exports=BufferList;function BufferList(){this.head=null;this.tail=null;this.length=0}BufferList.prototype.push=function(v){var entry={data:v,next:null};if(this.length>0)this.tail.next=entry;else this.head=entry;this.tail=entry;++this.length};BufferList.prototype.unshift=function(v){var entry={data:v,next:this.head};if(this.length===0)this.tail=entry;this.head=entry;++this.length};BufferList.prototype.shift=function(){if(this.length===0)return;var ret=this.head.data;if(this.length===1)this.head=this.tail=null;else this.head=this.head.next;--this.length;return ret};BufferList.prototype.clear=function(){this.head=this.tail=null;this.length=0};BufferList.prototype.join=function(s){if(this.length===0)return"";var p=this.head;var ret=""+p.data;while(p=p.next){ret+=s+p.data}return ret};BufferList.prototype.concat=function(n){if(this.length===0)return bufferShim.alloc(0);if(this.length===1)return this.head.data;var ret=bufferShim.allocUnsafe(n>>>0);var p=this.head;var i=0;while(p){p.data.copy(ret,i);i+=p.data.length;p=p.next}return ret}},function(module2,exports2,__webpack_require__){"use strict";var objectKeys=Object.keys||function(obj){var keys2=[];for(var key in obj){keys2.push(key)}return keys2};module2.exports=Duplex;var processNextTick=__webpack_require__(15);var util=__webpack_require__(18);util.inherits=__webpack_require__(12);var Readable=__webpack_require__(14);var Writable=__webpack_require__(22);util.inherits(Duplex,Readable);var keys=objectKeys(Writable.prototype);for(var v=0;v-1?setImmediate:processNextTick;var Duplex;Writable.WritableState=WritableState;var util=__webpack_require__(18);util.inherits=__webpack_require__(12);var internalUtil={deprecate:__webpack_require__(23)};var Stream;(function(){try{Stream=__webpack_require__(11)}catch(_){}finally{if(!Stream)Stream=__webpack_require__(8).EventEmitter}})();var Buffer2=__webpack_require__(2).Buffer;var bufferShim=__webpack_require__(17);util.inherits(Writable,Stream);function nop(){}function WriteReq(chunk,encoding,cb){this.chunk=chunk;this.encoding=encoding;this.callback=cb;this.next=null}function WritableState(options,stream){Duplex=Duplex||__webpack_require__(21);options=options||{};this.objectMode=!!options.objectMode;if(stream instanceof Duplex)this.objectMode=this.objectMode||!!options.writableObjectMode;var hwm=options.highWaterMark;var defaultHwm=this.objectMode?16:16*1024;this.highWaterMark=hwm||hwm===0?hwm:defaultHwm;this.highWaterMark=~~this.highWaterMark;this.needDrain=false;this.ending=false;this.ended=false;this.finished=false;var noDecode=options.decodeStrings===false;this.decodeStrings=!noDecode;this.defaultEncoding=options.defaultEncoding||"utf8";this.length=0;this.writing=false;this.corked=0;this.sync=true;this.bufferProcessing=false;this.onwrite=function(er){onwrite(stream,er)};this.writecb=null;this.writelen=0;this.bufferedRequest=null;this.lastBufferedRequest=null;this.pendingcb=0;this.prefinished=false;this.errorEmitted=false;this.bufferedRequestCount=0;this.corkedRequestsFree=new CorkedRequest(this)}WritableState.prototype.getBuffer=function getBuffer(){var current=this.bufferedRequest;var out=[];while(current){out.push(current);current=current.next}return out};(function(){try{Object.defineProperty(WritableState.prototype,"buffer",{get:internalUtil.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.")})}catch(_){}})();var realHasInstance;if(typeof Symbol==="function"&&Symbol.hasInstance&&typeof Function.prototype[Symbol.hasInstance]==="function"){realHasInstance=Function.prototype[Symbol.hasInstance];Object.defineProperty(Writable,Symbol.hasInstance,{value:function(object){if(realHasInstance.call(this,object))return true;return object&&object._writableState instanceof WritableState}})}else{realHasInstance=function(object){return object instanceof this}}function Writable(options){Duplex=Duplex||__webpack_require__(21);if(!realHasInstance.call(Writable,this)&&!(this instanceof Duplex)){return new Writable(options)}this._writableState=new WritableState(options,this);this.writable=true;if(options){if(typeof options.write==="function")this._write=options.write;if(typeof options.writev==="function")this._writev=options.writev}Stream.call(this)}Writable.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))};function writeAfterEnd(stream,cb){var er=new Error("write after end");stream.emit("error",er);processNextTick(cb,er)}function validChunk(stream,state,chunk,cb){var valid=true;var er=false;if(chunk===null){er=new TypeError("May not write null values to stream")}else if(typeof chunk!=="string"&&chunk!==void 0&&!state.objectMode){er=new TypeError("Invalid non-string/buffer chunk")}if(er){stream.emit("error",er);processNextTick(cb,er);valid=false}return valid}Writable.prototype.write=function(chunk,encoding,cb){var state=this._writableState;var ret=false;var isBuf=Buffer2.isBuffer(chunk);if(typeof encoding==="function"){cb=encoding;encoding=null}if(isBuf)encoding="buffer";else if(!encoding)encoding=state.defaultEncoding;if(typeof cb!=="function")cb=nop;if(state.ended)writeAfterEnd(this,cb);else if(isBuf||validChunk(this,state,chunk,cb)){state.pendingcb++;ret=writeOrBuffer(this,state,isBuf,chunk,encoding,cb)}return ret};Writable.prototype.cork=function(){var state=this._writableState;state.corked++};Writable.prototype.uncork=function(){var state=this._writableState;if(state.corked){state.corked--;if(!state.writing&&!state.corked&&!state.finished&&!state.bufferProcessing&&state.bufferedRequest)clearBuffer(this,state)}};Writable.prototype.setDefaultEncoding=function setDefaultEncoding(encoding){if(typeof encoding==="string")encoding=encoding.toLowerCase();if(!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((encoding+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+encoding);this._writableState.defaultEncoding=encoding;return this};function decodeChunk(state,chunk,encoding){if(!state.objectMode&&state.decodeStrings!==false&&typeof chunk==="string"){chunk=bufferShim.from(chunk,encoding)}return chunk}function writeOrBuffer(stream,state,isBuf,chunk,encoding,cb){if(!isBuf){chunk=decodeChunk(state,chunk,encoding);if(Buffer2.isBuffer(chunk))encoding="buffer"}var len=state.objectMode?1:chunk.length;state.length+=len;var ret=state.length=this.charLength-this.charReceived?this.charLength-this.charReceived:buffer.length;buffer.copy(this.charBuffer,this.charReceived,0,available);this.charReceived+=available;if(this.charReceived=55296&&charCode<=56319){this.charLength+=this.surrogateSize;charStr="";continue}this.charReceived=this.charLength=0;if(buffer.length===0){return charStr}break}this.detectIncompleteChar(buffer);var end=buffer.length;if(this.charLength){buffer.copy(this.charBuffer,0,buffer.length-this.charReceived,end);end-=this.charReceived}charStr+=buffer.toString(this.encoding,0,end);var end=charStr.length-1;var charCode=charStr.charCodeAt(end);if(charCode>=55296&&charCode<=56319){var size=this.surrogateSize;this.charLength+=size;this.charReceived+=size;this.charBuffer.copy(this.charBuffer,size,0,size);buffer.copy(this.charBuffer,0,0,size);return charStr.substring(0,end)}return charStr};StringDecoder.prototype.detectIncompleteChar=function(buffer){var i=buffer.length>=3?3:buffer.length;for(;i>0;i--){var c=buffer[buffer.length-i];if(i==1&&c>>5==6){this.charLength=2;break}if(i<=2&&c>>4==14){this.charLength=3;break}if(i<=3&&c>>3==30){this.charLength=4;break}}this.charReceived=i};StringDecoder.prototype.end=function(buffer){var res="";if(buffer&&buffer.length)res=this.write(buffer);if(this.charReceived){var cr=this.charReceived;var buf=this.charBuffer;var enc=this.encoding;res+=buf.slice(0,cr).toString(enc)}return res};function passThroughWrite(buffer){return buffer.toString(this.encoding)}function utf16DetectIncompleteChar(buffer){this.charReceived=buffer.length%2;this.charLength=this.charReceived?2:0}function base64DetectIncompleteChar(buffer){this.charReceived=buffer.length%3;this.charLength=this.charReceived?3:0}},function(module2,exports2,__webpack_require__){"use strict";module2.exports=Transform;var Duplex=__webpack_require__(21);var util=__webpack_require__(18);util.inherits=__webpack_require__(12);util.inherits(Transform,Duplex);function TransformState(stream){this.afterTransform=function(er,data){return afterTransform(stream,er,data)};this.needTransform=false;this.transforming=false;this.writecb=null;this.writechunk=null;this.writeencoding=null}function afterTransform(stream,er,data){var ts=stream._transformState;ts.transforming=false;var cb=ts.writecb;if(!cb)return stream.emit("error",new Error("no writecb in Transform class"));ts.writechunk=null;ts.writecb=null;if(data!==null&&data!==void 0)stream.push(data);cb(er);var rs=stream._readableState;rs.reading=false;if(rs.needReadable||rs.length=0&&opt.windowBits<16){opt.windowBits=-opt.windowBits;if(opt.windowBits===0){opt.windowBits=-15}}if(opt.windowBits>=0&&opt.windowBits<16&&!(options&&options.windowBits)){opt.windowBits+=32}if(opt.windowBits>15&&opt.windowBits<48){if((opt.windowBits&15)===0){opt.windowBits|=15}}this.err=0;this.msg="";this.ended=false;this.chunks=[];this.strm=new ZStream;this.strm.avail_out=0;var status=zlib_inflate.inflateInit2(this.strm,opt.windowBits);if(status!==c.Z_OK){throw new Error(msg[status])}this.header=new GZheader;zlib_inflate.inflateGetHeader(this.strm,this.header)}Inflate.prototype.push=function(data,mode){var strm=this.strm;var chunkSize=this.options.chunkSize;var dictionary=this.options.dictionary;var status,_mode;var next_out_utf8,tail,utf8str;var dict;var allowBufError=false;if(this.ended){return false}_mode=mode===~~mode?mode:mode===true?c.Z_FINISH:c.Z_NO_FLUSH;if(typeof data==="string"){strm.input=strings.binstring2buf(data)}else if(toString.call(data)==="[object ArrayBuffer]"){strm.input=new Uint8Array(data)}else{strm.input=data}strm.next_in=0;strm.avail_in=strm.input.length;do{if(strm.avail_out===0){strm.output=new utils.Buf8(chunkSize);strm.next_out=0;strm.avail_out=chunkSize}status=zlib_inflate.inflate(strm,c.Z_NO_FLUSH);if(status===c.Z_NEED_DICT&&dictionary){if(typeof dictionary==="string"){dict=strings.string2buf(dictionary)}else if(toString.call(dictionary)==="[object ArrayBuffer]"){dict=new Uint8Array(dictionary)}else{dict=dictionary}status=zlib_inflate.inflateSetDictionary(this.strm,dict)}if(status===c.Z_BUF_ERROR&&allowBufError===true){status=c.Z_OK;allowBufError=false}if(status!==c.Z_STREAM_END&&status!==c.Z_OK){this.onEnd(status);this.ended=true;return false}if(strm.next_out){if(strm.avail_out===0||status===c.Z_STREAM_END||strm.avail_in===0&&(_mode===c.Z_FINISH||_mode===c.Z_SYNC_FLUSH)){if(this.options.to==="string"){next_out_utf8=strings.utf8border(strm.output,strm.next_out);tail=strm.next_out-next_out_utf8;utf8str=strings.buf2string(strm.output,next_out_utf8);strm.next_out=tail;strm.avail_out=chunkSize-tail;if(tail){utils.arraySet(strm.output,strm.output,next_out_utf8,tail,0)}this.onData(utf8str)}else{this.onData(utils.shrinkBuf(strm.output,strm.next_out))}}}if(strm.avail_in===0&&strm.avail_out===0){allowBufError=true}}while((strm.avail_in>0||strm.avail_out===0)&&status!==c.Z_STREAM_END);if(status===c.Z_STREAM_END){_mode=c.Z_FINISH}if(_mode===c.Z_FINISH){status=zlib_inflate.inflateEnd(this.strm);this.onEnd(status);this.ended=true;return status===c.Z_OK}if(_mode===c.Z_SYNC_FLUSH){this.onEnd(c.Z_OK);strm.avail_out=0;return true}return true};Inflate.prototype.onData=function(chunk){this.chunks.push(chunk)};Inflate.prototype.onEnd=function(status){if(status===c.Z_OK){if(this.options.to==="string"){this.result=this.chunks.join("")}else{this.result=utils.flattenChunks(this.chunks)}}this.chunks=[];this.err=status;this.msg=this.strm.msg};function inflate(input,options){var inflator=new Inflate(options);inflator.push(input,true);if(inflator.err){throw inflator.msg||msg[inflator.err]}return inflator.result}function inflateRaw(input,options){options=options||{};options.raw=true;return inflate(input,options)}exports2.Inflate=Inflate;exports2.inflate=inflate;exports2.inflateRaw=inflateRaw;exports2.ungzip=inflate},function(module2,exports2,__webpack_require__){"use strict";var utils=__webpack_require__(33);var adler32=__webpack_require__(34);var crc32=__webpack_require__(35);var inflate_fast=__webpack_require__(36);var inflate_table=__webpack_require__(37);var CODES=0;var LENS=1;var DISTS=2;var Z_FINISH=4;var Z_BLOCK=5;var Z_TREES=6;var Z_OK=0;var Z_STREAM_END=1;var Z_NEED_DICT=2;var Z_STREAM_ERROR=-2;var Z_DATA_ERROR=-3;var Z_MEM_ERROR=-4;var Z_BUF_ERROR=-5;var Z_DEFLATED=8;var HEAD=1;var FLAGS=2;var TIME=3;var OS=4;var EXLEN=5;var EXTRA=6;var NAME=7;var COMMENT=8;var HCRC=9;var DICTID=10;var DICT=11;var TYPE=12;var TYPEDO=13;var STORED=14;var COPY_=15;var COPY=16;var TABLE=17;var LENLENS=18;var CODELENS=19;var LEN_=20;var LEN=21;var LENEXT=22;var DIST=23;var DISTEXT=24;var MATCH=25;var LIT=26;var CHECK=27;var LENGTH=28;var DONE=29;var BAD=30;var MEM=31;var SYNC=32;var ENOUGH_LENS=852;var ENOUGH_DISTS=592;var MAX_WBITS=15;var DEF_WBITS=MAX_WBITS;function zswap32(q){return(q>>>24&255)+(q>>>8&65280)+((q&65280)<<8)+((q&255)<<24)}function InflateState(){this.mode=0;this.last=false;this.wrap=0;this.havedict=false;this.flags=0;this.dmax=0;this.check=0;this.total=0;this.head=null;this.wbits=0;this.wsize=0;this.whave=0;this.wnext=0;this.window=null;this.hold=0;this.bits=0;this.length=0;this.offset=0;this.extra=0;this.lencode=null;this.distcode=null;this.lenbits=0;this.distbits=0;this.ncode=0;this.nlen=0;this.ndist=0;this.have=0;this.next=null;this.lens=new utils.Buf16(320);this.work=new utils.Buf16(288);this.lendyn=null;this.distdyn=null;this.sane=0;this.back=0;this.was=0}function inflateResetKeep(strm){var state;if(!strm||!strm.state){return Z_STREAM_ERROR}state=strm.state;strm.total_in=strm.total_out=state.total=0;strm.msg="";if(state.wrap){strm.adler=state.wrap&1}state.mode=HEAD;state.last=0;state.havedict=0;state.dmax=32768;state.head=null;state.hold=0;state.bits=0;state.lencode=state.lendyn=new utils.Buf32(ENOUGH_LENS);state.distcode=state.distdyn=new utils.Buf32(ENOUGH_DISTS);state.sane=1;state.back=-1;return Z_OK}function inflateReset(strm){var state;if(!strm||!strm.state){return Z_STREAM_ERROR}state=strm.state;state.wsize=0;state.whave=0;state.wnext=0;return inflateResetKeep(strm)}function inflateReset2(strm,windowBits){var wrap;var state;if(!strm||!strm.state){return Z_STREAM_ERROR}state=strm.state;if(windowBits<0){wrap=0;windowBits=-windowBits}else{wrap=(windowBits>>4)+1;if(windowBits<48){windowBits&=15}}if(windowBits&&(windowBits<8||windowBits>15)){return Z_STREAM_ERROR}if(state.window!==null&&state.wbits!==windowBits){state.window=null}state.wrap=wrap;state.wbits=windowBits;return inflateReset(strm)}function inflateInit2(strm,windowBits){var ret;var state;if(!strm){return Z_STREAM_ERROR}state=new InflateState;strm.state=state;state.window=null;ret=inflateReset2(strm,windowBits);if(ret!==Z_OK){strm.state=null}return ret}function inflateInit(strm){return inflateInit2(strm,DEF_WBITS)}var virgin=true;var lenfix,distfix;function fixedtables(state){if(virgin){var sym;lenfix=new utils.Buf32(512);distfix=new utils.Buf32(32);sym=0;while(sym<144){state.lens[sym++]=8}while(sym<256){state.lens[sym++]=9}while(sym<280){state.lens[sym++]=7}while(sym<288){state.lens[sym++]=8}inflate_table(LENS,state.lens,0,288,lenfix,0,state.work,{bits:9});sym=0;while(sym<32){state.lens[sym++]=5}inflate_table(DISTS,state.lens,0,32,distfix,0,state.work,{bits:5});virgin=false}state.lencode=lenfix;state.lenbits=9;state.distcode=distfix;state.distbits=5}function updatewindow(strm,src,end,copy){var dist;var state=strm.state;if(state.window===null){state.wsize=1<=state.wsize){utils.arraySet(state.window,src,end-state.wsize,state.wsize,0);state.wnext=0;state.whave=state.wsize}else{dist=state.wsize-state.wnext;if(dist>copy){dist=copy}utils.arraySet(state.window,src,end-copy,dist,state.wnext);copy-=dist;if(copy){utils.arraySet(state.window,src,end-copy,copy,0);state.wnext=copy;state.whave=state.wsize}else{state.wnext+=dist;if(state.wnext===state.wsize){state.wnext=0}if(state.whave>>8&255;state.check=crc32(state.check,hbuf,2,0);hold=0;bits=0;state.mode=FLAGS;break}state.flags=0;if(state.head){state.head.done=false}if(!(state.wrap&1)||(((hold&255)<<8)+(hold>>8))%31){strm.msg="incorrect header check";state.mode=BAD;break}if((hold&15)!==Z_DEFLATED){strm.msg="unknown compression method";state.mode=BAD;break}hold>>>=4;bits-=4;len=(hold&15)+8;if(state.wbits===0){state.wbits=len}else if(len>state.wbits){strm.msg="invalid window size";state.mode=BAD;break}state.dmax=1<>8&1}if(state.flags&512){hbuf[0]=hold&255;hbuf[1]=hold>>>8&255;state.check=crc32(state.check,hbuf,2,0)}hold=0;bits=0;state.mode=TIME;case TIME:while(bits<32){if(have===0){break inf_leave}have--;hold+=input[next++]<>>8&255;hbuf[2]=hold>>>16&255;hbuf[3]=hold>>>24&255;state.check=crc32(state.check,hbuf,4,0)}hold=0;bits=0;state.mode=OS;case OS:while(bits<16){if(have===0){break inf_leave}have--;hold+=input[next++]<>8}if(state.flags&512){hbuf[0]=hold&255;hbuf[1]=hold>>>8&255;state.check=crc32(state.check,hbuf,2,0)}hold=0;bits=0;state.mode=EXLEN;case EXLEN:if(state.flags&1024){while(bits<16){if(have===0){break inf_leave}have--;hold+=input[next++]<>>8&255;state.check=crc32(state.check,hbuf,2,0)}hold=0;bits=0}else if(state.head){state.head.extra=null}state.mode=EXTRA;case EXTRA:if(state.flags&1024){copy=state.length;if(copy>have){copy=have}if(copy){if(state.head){len=state.head.extra_len-state.length;if(!state.head.extra){state.head.extra=new Array(state.head.extra_len)}utils.arraySet(state.head.extra,input,next,copy,len)}if(state.flags&512){state.check=crc32(state.check,input,copy,next)}have-=copy;next+=copy;state.length-=copy}if(state.length){break inf_leave}}state.length=0;state.mode=NAME;case NAME:if(state.flags&2048){if(have===0){break inf_leave}copy=0;do{len=input[next+copy++];if(state.head&&len&&state.length<65536){state.head.name+=String.fromCharCode(len)}}while(len&©>9&1;state.head.done=true}strm.adler=state.check=0;state.mode=TYPE;break;case DICTID:while(bits<32){if(have===0){break inf_leave}have--;hold+=input[next++]<>>=bits&7;bits-=bits&7;state.mode=CHECK;break}while(bits<3){if(have===0){break inf_leave}have--;hold+=input[next++]<>>=1;bits-=1;switch(hold&3){case 0:state.mode=STORED;break;case 1:fixedtables(state);state.mode=LEN_;if(flush===Z_TREES){hold>>>=2;bits-=2;break inf_leave}break;case 2:state.mode=TABLE;break;case 3:strm.msg="invalid block type";state.mode=BAD}hold>>>=2;bits-=2;break;case STORED:hold>>>=bits&7;bits-=bits&7;while(bits<32){if(have===0){break inf_leave}have--;hold+=input[next++]<>>16^65535)){strm.msg="invalid stored block lengths";state.mode=BAD;break}state.length=hold&65535;hold=0;bits=0;state.mode=COPY_;if(flush===Z_TREES){break inf_leave}case COPY_:state.mode=COPY;case COPY:copy=state.length;if(copy){if(copy>have){copy=have}if(copy>left){copy=left}if(copy===0){break inf_leave}utils.arraySet(output,input,next,copy,put);have-=copy;next+=copy;left-=copy;put+=copy;state.length-=copy;break}state.mode=TYPE;break;case TABLE:while(bits<14){if(have===0){break inf_leave}have--;hold+=input[next++]<>>=5;bits-=5;state.ndist=(hold&31)+1;hold>>>=5;bits-=5;state.ncode=(hold&15)+4;hold>>>=4;bits-=4;if(state.nlen>286||state.ndist>30){strm.msg="too many length or distance symbols";state.mode=BAD;break}state.have=0;state.mode=LENLENS;case LENLENS:while(state.have>>=3;bits-=3}while(state.have<19){state.lens[order[state.have++]]=0}state.lencode=state.lendyn;state.lenbits=7;opts={bits:state.lenbits};ret=inflate_table(CODES,state.lens,0,19,state.lencode,0,state.work,opts);state.lenbits=opts.bits;if(ret){strm.msg="invalid code lengths set";state.mode=BAD;break}state.have=0;state.mode=CODELENS;case CODELENS:while(state.have>>24;here_op=here>>>16&255;here_val=here&65535;if(here_bits<=bits){break}if(have===0){break inf_leave}have--;hold+=input[next++]<>>=here_bits;bits-=here_bits;state.lens[state.have++]=here_val}else{if(here_val===16){n=here_bits+2;while(bits>>=here_bits;bits-=here_bits;if(state.have===0){strm.msg="invalid bit length repeat";state.mode=BAD;break}len=state.lens[state.have-1];copy=3+(hold&3);hold>>>=2;bits-=2}else if(here_val===17){n=here_bits+3;while(bits>>=here_bits;bits-=here_bits;len=0;copy=3+(hold&7);hold>>>=3;bits-=3}else{n=here_bits+7;while(bits>>=here_bits;bits-=here_bits;len=0;copy=11+(hold&127);hold>>>=7;bits-=7}if(state.have+copy>state.nlen+state.ndist){strm.msg="invalid bit length repeat";state.mode=BAD;break}while(copy--){state.lens[state.have++]=len}}}if(state.mode===BAD){break}if(state.lens[256]===0){strm.msg="invalid code -- missing end-of-block";state.mode=BAD;break}state.lenbits=9;opts={bits:state.lenbits};ret=inflate_table(LENS,state.lens,0,state.nlen,state.lencode,0,state.work,opts);state.lenbits=opts.bits;if(ret){strm.msg="invalid literal/lengths set";state.mode=BAD;break}state.distbits=6;state.distcode=state.distdyn;opts={bits:state.distbits};ret=inflate_table(DISTS,state.lens,state.nlen,state.ndist,state.distcode,0,state.work,opts);state.distbits=opts.bits;if(ret){strm.msg="invalid distances set";state.mode=BAD;break}state.mode=LEN_;if(flush===Z_TREES){break inf_leave}case LEN_:state.mode=LEN;case LEN:if(have>=6&&left>=258){strm.next_out=put;strm.avail_out=left;strm.next_in=next;strm.avail_in=have;state.hold=hold;state.bits=bits;inflate_fast(strm,_out);put=strm.next_out;output=strm.output;left=strm.avail_out;next=strm.next_in;input=strm.input;have=strm.avail_in;hold=state.hold;bits=state.bits;if(state.mode===TYPE){state.back=-1}break}state.back=0;for(;;){here=state.lencode[hold&(1<>>24;here_op=here>>>16&255;here_val=here&65535;if(here_bits<=bits){break}if(have===0){break inf_leave}have--;hold+=input[next++]<>last_bits)];here_bits=here>>>24;here_op=here>>>16&255;here_val=here&65535;if(last_bits+here_bits<=bits){break}if(have===0){break inf_leave}have--;hold+=input[next++]<>>=last_bits;bits-=last_bits;state.back+=last_bits}hold>>>=here_bits;bits-=here_bits;state.back+=here_bits;state.length=here_val;if(here_op===0){state.mode=LIT;break}if(here_op&32){state.back=-1;state.mode=TYPE;break}if(here_op&64){strm.msg="invalid literal/length code";state.mode=BAD;break}state.extra=here_op&15;state.mode=LENEXT;case LENEXT:if(state.extra){n=state.extra;while(bits>>=state.extra;bits-=state.extra;state.back+=state.extra}state.was=state.length;state.mode=DIST;case DIST:for(;;){here=state.distcode[hold&(1<>>24;here_op=here>>>16&255;here_val=here&65535;if(here_bits<=bits){break}if(have===0){break inf_leave}have--;hold+=input[next++]<>last_bits)];here_bits=here>>>24;here_op=here>>>16&255;here_val=here&65535;if(last_bits+here_bits<=bits){break}if(have===0){break inf_leave}have--;hold+=input[next++]<>>=last_bits;bits-=last_bits;state.back+=last_bits}hold>>>=here_bits;bits-=here_bits;state.back+=here_bits;if(here_op&64){strm.msg="invalid distance code";state.mode=BAD;break}state.offset=here_val;state.extra=here_op&15;state.mode=DISTEXT;case DISTEXT:if(state.extra){n=state.extra;while(bits>>=state.extra;bits-=state.extra;state.back+=state.extra}if(state.offset>state.dmax){strm.msg="invalid distance too far back";state.mode=BAD;break}state.mode=MATCH;case MATCH:if(left===0){break inf_leave}copy=_out-left;if(state.offset>copy){copy=state.offset-copy;if(copy>state.whave){if(state.sane){strm.msg="invalid distance too far back";state.mode=BAD;break}}if(copy>state.wnext){copy-=state.wnext;from=state.wsize-copy}else{from=state.wnext-copy}if(copy>state.length){copy=state.length}from_source=state.window}else{from_source=output;from=put-state.offset;copy=state.length}if(copy>left){copy=left}left-=copy;state.length-=copy;do{output[put++]=from_source[from++]}while(--copy);if(state.length===0){state.mode=LEN}break;case LIT:if(left===0){break inf_leave}output[put++]=state.length;left--;state.mode=LEN;break;case CHECK:if(state.wrap){while(bits<32){if(have===0){break inf_leave}have--;hold|=input[next++]<>>16&65535|0,n=0;while(len!==0){n=len>2e3?2e3:len;len-=n;do{s1=s1+buf[pos++]|0;s2=s2+s1|0}while(--n);s1%=65521;s2%=65521}return s1|s2<<16|0}module2.exports=adler32},function(module2,exports2){"use strict";function makeTable(){var c,table=[];for(var n=0;n<256;n++){c=n;for(var k=0;k<8;k++){c=c&1?3988292384^c>>>1:c>>>1}table[n]=c}return table}var crcTable=makeTable();function crc32(crc,buf,len,pos){var t=crcTable,end=pos+len;crc^=-1;for(var i=pos;i>>8^t[(crc^buf[i])&255]}return crc^-1}module2.exports=crc32},function(module2,exports2){"use strict";var BAD=30;var TYPE=12;module2.exports=function inflate_fast(strm,start){var state;var _in;var last;var _out;var beg;var end;var dmax;var wsize;var whave;var wnext;var s_window;var hold;var bits;var lcode;var dcode;var lmask;var dmask;var here;var op;var len;var dist;var from;var from_source;var input,output;state=strm.state;_in=strm.next_in;input=strm.input;last=_in+(strm.avail_in-5);_out=strm.next_out;output=strm.output;beg=_out-(start-strm.avail_out);end=_out+(strm.avail_out-257);dmax=state.dmax;wsize=state.wsize;whave=state.whave;wnext=state.wnext;s_window=state.window;hold=state.hold;bits=state.bits;lcode=state.lencode;dcode=state.distcode;lmask=(1<>>24;hold>>>=op;bits-=op;op=here>>>16&255;if(op===0){output[_out++]=here&65535}else if(op&16){len=here&65535;op&=15;if(op){if(bits>>=op;bits-=op}if(bits<15){hold+=input[_in++]<>>24;hold>>>=op;bits-=op;op=here>>>16&255;if(op&16){dist=here&65535;op&=15;if(bitsdmax){strm.msg="invalid distance too far back";state.mode=BAD;break top}hold>>>=op;bits-=op;op=_out-beg;if(dist>op){op=dist-op;if(op>whave){if(state.sane){strm.msg="invalid distance too far back";state.mode=BAD;break top}}from=0;from_source=s_window;if(wnext===0){from+=wsize-op;if(op2){output[_out++]=from_source[from++];output[_out++]=from_source[from++];output[_out++]=from_source[from++];len-=3}if(len){output[_out++]=from_source[from++];if(len>1){output[_out++]=from_source[from++]}}}else{from=_out-dist;do{output[_out++]=output[from++];output[_out++]=output[from++];output[_out++]=output[from++];len-=3}while(len>2);if(len){output[_out++]=output[from++];if(len>1){output[_out++]=output[from++]}}}}else if((op&64)===0){here=dcode[(here&65535)+(hold&(1<>3;_in-=len;bits-=len<<3;hold&=(1<=1;max--){if(count[max]!==0){break}}if(root>max){root=max}if(max===0){table[table_index++]=1<<24|64<<16|0;table[table_index++]=1<<24|64<<16|0;opts.bits=1;return 0}for(min=1;min0&&(type===CODES||max!==1)){return-1}offs[1]=0;for(len=1;lenENOUGH_LENS||type===DISTS&&used>ENOUGH_DISTS){return 1}for(;;){here_bits=len-drop;if(work[sym]end){here_op=extra[extra_index+work[sym]];here_val=base[base_index+work[sym]]}else{here_op=32+64;here_val=0}incr=1<>drop)+fill]=here_bits<<24|here_op<<16|here_val|0}while(fill!==0);incr=1<>=1}if(incr!==0){huff&=incr-1;huff+=incr}else{huff=0}sym++;if(--count[len]===0){if(len===max){break}len=lens[lens_index+work[sym]]}if(len>root&&(huff&mask)!==low){if(drop===0){drop=root}next+=min;curr=len-drop;left=1<ENOUGH_LENS||type===DISTS&&used>ENOUGH_DISTS){return 1}low=huff&mask;table[low]=root<<24|curr<<16|next-table_index|0}}if(huff!==0){table[next+huff]=len-drop<<24|64<<16|0}opts.bits=root;return 0}},function(module2,exports2,__webpack_require__){"use strict";var utils=__webpack_require__(33);var STR_APPLY_OK=true;var STR_APPLY_UIA_OK=true;try{String.fromCharCode.apply(null,[0])}catch(__){STR_APPLY_OK=false}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(__){STR_APPLY_UIA_OK=false}var _utf8len=new utils.Buf8(256);for(var q=0;q<256;q++){_utf8len[q]=q>=252?6:q>=248?5:q>=240?4:q>=224?3:q>=192?2:1}_utf8len[254]=_utf8len[254]=1;exports2.string2buf=function(str){var buf,c,c2,m_pos,i,str_len=str.length,buf_len=0;for(m_pos=0;m_pos>>6;buf[i++]=128|c&63}else if(c<65536){buf[i++]=224|c>>>12;buf[i++]=128|c>>>6&63;buf[i++]=128|c&63}else{buf[i++]=240|c>>>18;buf[i++]=128|c>>>12&63;buf[i++]=128|c>>>6&63;buf[i++]=128|c&63}}return buf};function buf2binstring(buf,len){if(len<65537){if(buf.subarray&&STR_APPLY_UIA_OK||!buf.subarray&&STR_APPLY_OK){return String.fromCharCode.apply(null,utils.shrinkBuf(buf,len))}}var result="";for(var i=0;i4){utf16buf[out++]=65533;i+=c_len-1;continue}c&=c_len===2?31:c_len===3?15:7;while(c_len>1&&i1){utf16buf[out++]=65533;continue}if(c<65536){utf16buf[out++]=c}else{c-=65536;utf16buf[out++]=55296|c>>10&1023;utf16buf[out++]=56320|c&1023}}return buf2binstring(utf16buf,out)};exports2.utf8border=function(buf,max){var pos;max=max||buf.length;if(max>buf.length){max=buf.length}pos=max-1;while(pos>=0&&(buf[pos]&192)===128){pos--}if(pos<0){return max}if(pos===0){return max}return pos+_utf8len[buf[pos]]>max?pos:max}},function(module2,exports2){"use strict";module2.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},function(module2,exports2){"use strict";module2.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},function(module2,exports2){"use strict";function ZStream(){this.input=null;this.next_in=0;this.avail_in=0;this.total_in=0;this.output=null;this.next_out=0;this.avail_out=0;this.total_out=0;this.msg="";this.state=null;this.data_type=2;this.adler=0}module2.exports=ZStream},function(module2,exports2){"use strict";function GZheader(){this.text=0;this.time=0;this.xflags=0;this.os=0;this.extra=null;this.extra_len=0;this.name="";this.comment="";this.hcrc=0;this.done=false}module2.exports=GZheader}])})}});var CSV=class{constructor(onOpen=this.onOpen,saveButtonId=null,openButtonId=null){this.onOpen=onOpen;this.notes=[];if(saveButtonId!==null){document.getElementById(saveButtonId).addEventListener("click",this.saveCSV)}if(openButtonId!==null){document.getElementById(openButtonId).addEventListener("click",this.openCSV)}}processArraysForCSV(data=["1|2|3","3|2|1"],delimiter="|",header="a,b,c",saveNotes=false){let csvDat=header+"\n";let noteIdx=0;data.forEach((line,i)=>{if(data[i]==="string"&&delimiter!==","){csvDat+=line.split(delimiter).join(",")}else{csvData+=line.join(",")}if(saveNotes===true){if(this.notes[noteIdx].idx===i){line+=this.notes[noteIdx].text;noteIdx++}}if(line.indexOf("\n")<0){csvDat+="\n"}});return csvDat}static saveCSV(csvDat="a,b,c\n1,2,3\n3,2,1\n",name=new Date().toISOString()){var hiddenElement=document.createElement("a");hiddenElement.href="data:text/csv;charset=utf-8,"+encodeURI(csvDat);hiddenElement.target="_blank";if(name!==""){hiddenElement.download=name}else{hiddenElement.download=new Date().toISOString()+".csv"}hiddenElement.click()}static openCSV(delimiter=",",onOpen=(csvDat,header,path)=>{return csvDat,header,path}){return new Promise((res,rej)=>{var input=document.createElement("input");input.accept=".csv";input.type="file";input.onchange=e=>{var file=e.target.files[0];var reader=new FileReader;reader.onload=event=>{var tempcsvData=event.target.result;var tempcsvArr=tempcsvData.split("\n");let header=[];var csvDat=[];tempcsvArr.pop();tempcsvArr.forEach((row,i)=>{if(i==0){header=row.split(delimiter)}else{var temp=row.split(delimiter);csvDat.push(temp)}});onOpen(csvDat,header,input.value);input.value="";res({data:csvDat,header,filename:input.value})};reader.readAsText(file)};input.click()})}static openCSVRaw(onOpen=(csvDat,path)=>{return csvDat,path}){return new Promise((res,rej)=>{var input=document.createElement("input");input.accept=".csv";input.type="file";input.onchange=e=>{var file=e.target.files[0];var reader=new FileReader;reader.onload=event=>{var tempcsvData=event.target.result;onOpen(tempcsvData,input.value);input.value="";res({data:tempcsvData,filename:input.value})};reader.readAsText(file)};input.click()})}onOpen(csvDat=[],header=[]){console.log("CSV Opened!",header,csvDat)}};var parseCSVData=(data,filename,head,hasend=true,parser=(lines,filename2,head2)=>{let result={filename:filename2};let header=head2;if(typeof head2==="string")header=head2.split(",");result.header=header;for(let i=0;i{let lines;if(data.includes("\r"))lines=data.split("\r\n");else lines=data.split("\n");if(!head)head=lines[0];lines.shift();if(hasend===false)lines.pop();let result=parser(lines,filename,head);return result};function toISOLocal(d){d=new Date(d);var z=n=>("0"+n).slice(-2);var zz=n=>("00"+n).slice(-3);var off=d.getTimezoneOffset();var sign=off<0?"+":"-";off=Math.abs(off);return d.getFullYear()+"-"+z(d.getMonth()+1)+"-"+z(d.getDate())+"T"+z(d.getHours())+":"+z(d.getMinutes())+":"+z(d.getSeconds())+"."+zz(d.getMilliseconds())+"(UTC"+sign+z(off/60|0)+":00)"}var processDataForCSV=(options={})=>{if(!options.data)return void 0;if(!Array.isArray(options.data))options.data=[options.data];if(options.data&&!options.header)options.header=Object.keys(options.data[0]);let head=[...options.header];if(head.indexOf("timestamp")>-1){head.splice(head.indexOf("timestamp")+1,0,"localized")}let header=head.join(",");let headeridx=0;let lines=[];let foreach=(obj,i)=>{if(Array.isArray(obj)){for(let j=0;j{if(exists2)appendFile(options.filename,joined,options.dir);else appendFile(options.filename,header+joined,options.dir)})}return result};var BrowserFS=__toESM(require_browserfs());var fsInited=false;var fs2=BrowserFS.BFSRequire("fs");var BFSBuffer=BrowserFS.BFSRequire("buffer").Buffer;var initPromise;var initFS=async(dirs=["data"],oninit=(exists2=[])=>{},onerror=e=>{},filesystem="IndexedDB")=>{if(fsInited){if(initPromise){await initPromise}return true}else{fsInited=true;initPromise=new Promise((resolve,reject)=>{BrowserFS.FileSystem[filesystem].Create({},(e,mountableFileSystem)=>{if(e){reject(e);return}if(!mountableFileSystem){onerror(e);reject(new Error(`Error creating BrowserFS`));return}BrowserFS.initialize(mountableFileSystem);let promises=[];dirs.forEach(async dir=>{promises.push(dirExists(fs2,dir))});Promise.all(promises).then(values=>{oninit(values);resolve(true)})})});return await initPromise}};var exists=async(path="")=>{if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);return await new Promise(resolve=>{fs2.exists("/"+path,function(exists2){resolve(exists2)})})};var readFile=async(path="data")=>{if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);return await new Promise(resolve=>{fs2.readFile("/"+path,function(e,output){resolve(output)})})};async function readFileChunk(path="data",begin=0,end=5120,onread=data=>{}){if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);if(path!=""){return await new Promise(async(resolve,reject)=>{fs2.open("/"+path,"r",(e,fd)=>{if(e){reject(e);return}fs2.read(fd,end,begin,"utf-8",(er,output,bytesRead)=>{if(er){reject(er);return}if(bytesRead!==0){let data=output.toString();fs2.close(fd,()=>{onread(data,path);resolve(data)})}else resolve(void 0)})})})}else{console.error("Path name is not defined");return void 0}}var getFilenames=async(directory="data",onload=directory2=>{})=>{if(!fsInited)await initFS([directory]);else await dirExists(fs2,directory);return await new Promise((resolve,reject)=>{fs2.readdir("/"+directory,(e,dir)=>{if(e){reject(e);return}if(dir){onload(dir);resolve(dir)}else resolve(void 0)})})};var writeFile=async(path,data,onwrite=data2=>{})=>{if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);return await new Promise((resolve,reject)=>{fs2.writeFile("/"+path,data,err=>{if(err){reject(err);return}onwrite(data);resolve(true)})})};var appendFile2=async(path,data,onwrite=data2=>{})=>{if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);return await new Promise((resolve,reject)=>{fs2.appendFile("/"+path,data,err=>{if(err){reject(err);return}onwrite(data);resolve(true)})})};var deleteFile=async(path="data",ondelete=()=>{})=>{if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);return await new Promise(resolve=>{if(path!=""){fs2.unlink("/"+path,e=>{if(e)console.error(e);ondelete();resolve(true)})}else{console.error("Path name is not defined");resolve(false)}})};var readFileAsText=async(path="data",end="end",begin=0,onread=(data,filename)=>{})=>{if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);return await new Promise(async(resolve,reject)=>{let size=await getFileSize(path);if(end==="end"){end=size}else if(typeof end==="number"){if(end>size)end=size}fs2.open("/"+path,"r",(e,fd)=>{if(e){reject(e);return}fs2.read(fd,end,begin,"utf-8",(er,output,bytesRead)=>{if(er){reject(er);return}if(bytesRead!==0){let data=output.toString();fs2.close(fd,()=>{onread(data,path);resolve(data)})}else resolve(void 0)})})})};var listFiles=async(dir="data",onload=directory=>{})=>{if(!fsInited)await initFS([dir]);else await dirExists(fs2,dir);return await new Promise((resolve,reject)=>{fs2.readdir("/"+dir,(e,directory)=>{if(e){reject(e);return}if(directory){onload(directory)}resolve(directory)})})};var getFileSize=async(path="data",onread=size=>{})=>{if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);return await new Promise((resolve,reject)=>{fs2.stat("/"+path,(e,stats)=>{if(e){reject(e);return}let filesize=stats.size;onread(filesize);resolve(filesize)})})};var getCSVHeader=async(path="data",onopen=(header,filename)=>{})=>{if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);return await new Promise((resolve,reject)=>{fs2.open("/"+path,"r",(e,fd)=>{if(e){reject(e);return}fs2.read(fd,65535,0,"utf-8",(er,output,bytesRead)=>{if(er){reject(er);return}if(bytesRead!==0){let data=output.toString();let lines=data.split("\n");let header=lines[0];fs2.close(fd,()=>{onopen(header,path);resolve(header)})}else resolve(void 0)})})})};var writeToCSVFromDB=async(path="data",fileSizeLimitMb=10)=>{if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);return await new Promise((resolve,reject)=>{if(path!=""){fs2.stat("/"+path,(e,stats)=>{if(e){reject(e);return}let filesize=stats.size;fs2.open(path,"r",(e2,fd)=>{if(e2){reject(e2);return}let i=0;let maxFileSize=fileSizeLimitMb*1024*1024;let end=maxFileSize;if(filesize{if(e3){reject(e3);return}if(bytesRead!==0)CSV.saveCSV(output.toString(),path.split("/")[1]);fs2.close(fd);resolve(true)})}else{const writeChunkToFile=async()=>{if(ifilesize){end=filesize-i}let chunk=0;fs2.read(fd,end,i,"utf-8",(e3,output,bytesRead)=>{if(e3){reject(e3);return}if(bytesRead!==0){CSV.saveCSV(output.toString(),path.split("/")[1]+"_"+chunk);i+=maxFileSize;chunk++;writeChunkToFile();fs2.close(fd);resolve(true)}})}}}})})}else{console.error("File name is not defined.");resolve(false)}})};async function processCSVChunksFromDB(path="data",onData=(csvdata,start2,end2,size)=>{},maxChunkSize=1e4,start=0,end="end",options={}){let size=await getFileSize(path);let partition=start;return await new Promise((res,rej)=>{let processPartition=()=>{let endChunk=partition+maxChunkSize;if(endChunk>size){endChunk=size}readCSVChunkFromDB(path,partition,endChunk,options).then(async result=>{await onData(result,partition,endChunk,size);partition=endChunk;if(partition!==size){processPartition()}else{res(true)}}).catch(rej)};processPartition()})}async function readCSVChunkFromDB(path="data",start=0,end="end",options={}){if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);const transpose=options.transpose||false;let head=await getCSVHeader(path);if(head)head=head.split(",");else return void 0;let resultLengths=[];let resultNames=[];let results=transpose?[]:{};head.forEach(v=>{if(v){resultNames.push(v);resultLengths.push(1)}else resultLengths[resultLengths.length-1]++});let size=await getFileSize(path);if(end==="end")end=size;else if(end>size){start=size-(end-start);end=size}let data=(await readFileChunk(path,start,end))?.split("\n").slice(1,-1);let preprocess=value=>{try{value=JSON.parse(value)}catch{}return value};if(data)data.forEach((r,i)=>{let row=r.split(",");if(transpose){const entry={};if(options.json)row.forEach((v,idx)=>{if(options.json)entry[resultNames[idx]]=preprocess(v);else entry[resultNames[idx]]=v});results.push(entry)}else{row.forEach((v,i2)=>{const header=resultNames[i2];if(!results[header])results[header]=[];if(options.json)results[header].push(preprocess(v));else results[header].push(v)})}});return results}var directories={};var dirExists=async(fs3,directory)=>{if(!fsInited)await initFS([directory]);return await new Promise((resolve,reject)=>{if(!directory)reject(false);if(directories[directory]==="exists"||directories[directory]==="created"){resolve()}else{if(directory[0]==="/")directory=directory.substring(1);if(!directory)reject(false);fs3.exists(`/${directory}`,exists2=>{if(exists2){directories[directory]="exists";resolve()}else if(directories[directory]==="creating"){resolve()}else{directories[directory]="creating";fs3.mkdir(`/${directory}`,1,err=>{if(err){reject(err);return}directories[directory]="created";setTimeout(resolve,500)})}})}})};var BFSRoutes={initFS,dirExists,exists,readFile,readFileChunk,getFilenames,writeFile,appendFile:appendFile2,deleteFile,readFileAsText,getFileSize,getCSVHeader,listFiles};var CSV_REFERENCE={};function lerp(v0,v1,t){return(1-t)*v0+t*v1}function interpolerp(v0,v1,fit,floor=true){if(fit<=2)return[v0,v1];let a=1/fit;let result=new Array(fit);result[0]=v0;for(let i=1;i<=fit;i++){result[i]=lerp(v0,v1,a*i);if(floor)result[i]=Math.floor(result[i])}return result}var appendCSV=async(newData,filename,header,options)=>{if(!filename){let keys=Object.keys(CSV_REFERENCE);if(keys.length>0)filename=keys[keys.length-1];else filename=`csv${new Date().toISOString()}`}let csv=CSV_REFERENCE[filename];if(!csv){let keys=Array.from(Object.keys(newData));if(keys.indexOf("timestamp")>-1)keys.splice(keys.indexOf("timestamp"),1);CSV_REFERENCE[filename]={header:header?header:["timestamp","localized",...keys],lastX:void 0,buffer:"",buffered:0,bufferSize:options?.bufferSize?options.bufferSize:0,toFixed:options?.toFixed?options.toFixed:0,xIncrement:options?.xIncrement?options.xIncrement:0};csv=CSV_REFERENCE[filename];const existingHeader=await getCSVHeader(filename).catch(()=>null);const isDifferent=!existingHeader||existingHeader!==csv.header.join(",");if(isDifferent)header=csv.header}if(!csv.header||csv.header?.length===0){let keys=Array.from(Object.keys(newData));if(keys.indexOf("timestamp")>-1)keys.splice(keys.indexOf("timestamp"),1);csv.header=header?header:["timestamp","localized",...keys]}else if(header)csv.header=header;let maxLen=1;for(const key in newData){const value=newData[key];if(csv.header.indexOf(key)>-1&&value&&Array.isArray(value)&&value?.length>maxLen)maxLen=value?.length}let x;if(csv.xIncrement){if(!csv.lastX){if(typeof newData[csv.header[0]]!=="undefined"){x=newData[csv.header[0]]}else if(csv.header[0].toLowerCase().includes("time")||csv.header[0].toLowerCase().includes("unix"))x=Date.now()}else{if(newData[csv.header[2]]){if(Array.isArray(newData[csv.header[2]]))x=csv.lastX+csv.xIncrement*newData[csv.header[2]].length;else x=csv.lastX+csv.xIncrement}else if(newData[csv.header[0]]){if(Array.isArray(newData[csv.header[0]]))x=csv.lastX+csv.xIncrement*newData[csv.header[0]].length;else x=csv.lastX+csv.xIncrement}else x=csv.lastX+csv.xIncrement}}else if(newData[csv.header[0]])x=newData[csv.header[0]];else x=Date.now();if(typeof csv.lastX==="undefined")csv.lastX=Array.isArray(x)?x[0]:x;if(typeof x==="undefined"){if(csv.header[0].includes("time")){let now=Date.now();if(maxLen===1)x=Date.now();else{x=interpolerp(csv.lastX,now,maxLen);x.shift()}}else{let newX=csv.lastX+1;if(maxLen>1){x=new Array(maxLen).fill("");x[maxLen-1]=newX}else x=newX}}else if(maxLen>1&&x?.length!==maxLen){if(!Array.isArray(x)||x.length===1){x=interpolerp(csv.lastX,x,maxLen,true);x.shift()}else{x=interpolerp(x[0],x[x.length-1],maxLen,true);x.shift()}}let toAppend=[];if(Array.isArray(x)){let curIdcs={};for(let i=0;icurIdcs[csv.header[j]]){curIdcs[csv.header[j]]++;toAppend[i][j]=d[curIdcs[csv.header[j]]]}else{toAppend[i][j]=""}}}}else{if(i===x.length-1){toAppend[i][j]=d}else{toAppend[i][j]=""}}if(typeof toAppend[i][j]==="number"&&Math.floor(toAppend[i][j])!==toAppend[i][j])toAppend[i][j]=toAppend[i][j].toFixed(CSV_REFERENCE[filename].toFixed)}}}else{toAppend.push([]);for(let j=0;j{csvProcessed+=(options?.json?arr.map(v=>JSON.stringify(v)):arr).join(",")+"\n";if(csv.bufferSize)csv.buffered++});csv.lastX=toAppend[toAppend.length-1][0];if(csv.bufferSize){csv.buffer+=csvProcessed;if(csv.buffered>csv.bufferSize){let r=new Promise((res,rej)=>{exists(filename).then(fileExists=>{if(!fileExists){writeFile(filename,csv.buffer,written=>{res(written)})}else{appendFile2(filename,csv.buffer,written=>{res(written)})}})});await r;csv.buffer="";csv.buffered=0;return r}else return await Promise.resolve(true)}else{return await new Promise((res,rej)=>{exists(filename).then(fileExists=>{if(!fileExists){writeFile(filename,csvProcessed,written=>{res(written)})}else{appendFile2(filename,csvProcessed,written=>{res(written)})}})})}};var updateCSVHeader=(header,filename)=>{if(CSV_REFERENCE[filename]){CSV_REFERENCE[filename].header=header}};var createCSV=(filename,header,toFixed=5,bufferSize=0,xIncrement)=>{if(!CSV_REFERENCE[filename]){if(header?.indexOf("timestamp")>1){header.splice(header.indexOf("timestamp"),1);header.unshift("timestamp")}if((header?.[0].toLowerCase().includes("time")||header?.[0].toLowerCase().includes("unix"))&&header[1]!=="localized"){header.splice(1,0,"localized")}CSV_REFERENCE[filename]={header,lastX:header[1]==="localized"?Date.now():0,bufferSize,buffer:"",buffered:0,toFixed,xIncrement};return new Promise((res,rej)=>{exists(filename).then(doesExist=>{if(!doesExist){writeFile(filename,CSV_REFERENCE[filename].header?CSV_REFERENCE[filename].header.join(",")+"\n":"",written=>{res(written)}).catch(rej)}})})}};var visualizeDirectory=(dir,parentNode=document.body)=>{return new Promise(async(res,rej)=>{if(parentNode.querySelector("#bfs"+dir))parentNode.querySelector("#bfs"+dir)?.remove();parentNode.insertAdjacentHTML("beforeend",`
    `);let div=parentNode.querySelector("#bfs"+dir);await listFiles(dir).then(directory=>{if(directory.length===0)div.innerHTML="No Files!";else directory.forEach(listing=>{div?.insertAdjacentHTML("beforeend",`
    - Data: - ${listing} - - ${listing.indexOf(".")>-1?``:""} -
    `);if(document.getElementById(`delete${listing}`)){document.getElementById(`delete${listing}`).onclick=()=>{deleteFile(dir+"/"+listing,()=>{visualizeDirectory(dir,parentNode)})}}if(document.getElementById(`download${listing}`)){document.getElementById(`download${listing}`).onclick=()=>{writeToCSVFromDB(dir+"/"+listing,10)}}});res(directory)}).catch(rej)})};var csvRoutes={appendCSV,updateCSVHeader,createCSV,visualizeDirectory,openCSV:CSV.openCSV,saveCSV:CSV.saveCSV,openCSVRaw:CSV.openCSVRaw,parseCSVData,getCSVHeader,writeToCSVFromDB,readCSVChunkFromDB,processCSVChunksFromDB,toISOLocal};export{BFSRoutes,CSV,appendCSV,appendFile2 as appendFile,createCSV,csvRoutes,deleteFile,dirExists,exists,fs2 as fs,fsInited,getCSVHeader,getFileSize,getFilenames,initFS,listFiles,parseCSVData,processCSVChunksFromDB,processDataForCSV,readCSVChunkFromDB,readFile,readFileAsText,readFileChunk,toISOLocal,updateCSVHeader,visualizeDirectory,writeFile,writeToCSVFromDB}; -/*! Bundled license information: - -browserfs/dist/browserfs.js: - (*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT - *) -*/ diff --git a/src/extras/dist/index.storage.services.js b/src/extras/dist/index.storage.services.js deleted file mode 100644 index 40ef601c..00000000 --- a/src/extras/dist/index.storage.services.js +++ /dev/null @@ -1,16 +0,0 @@ -(()=>{var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf;var __hasOwnProp=Object.prototype.hasOwnProperty;var __commonJS=(cb,mod)=>function __require(){return mod||(0,cb[__getOwnPropNames(cb)[0]])((mod={exports:{}}).exports,mod),mod.exports};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from==="object"||typeof from==="function"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:true}):target,mod));var require_browserfs=__commonJS({"node_modules/browserfs/dist/browserfs.js"(exports,module){(function webpackUniversalModuleDefinition(root,factory){if(typeof exports==="object"&&typeof module==="object")module.exports=factory();else if(typeof define==="function"&&define.amd)define([],factory);else if(typeof exports==="object")exports["BrowserFS"]=factory();else root["BrowserFS"]=factory()})(exports,function(){return function(modules){var installedModules={};function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module2=installedModules[moduleId]={exports:{},id:moduleId,loaded:false};modules[moduleId].call(module2.exports,module2,module2.exports,__webpack_require__);module2.loaded=true;return module2.exports}__webpack_require__.m=modules;__webpack_require__.c=installedModules;__webpack_require__.p="";return __webpack_require__(0)}([function(module2,exports2,__webpack_require__){(function(Buffer2,global,module3,process){"use strict";Object.defineProperty(exports2,"__esModule",{value:true});var buffer=__webpack_require__(2);var path=__webpack_require__(9);var ErrorCode;(function(ErrorCode2){ErrorCode2[ErrorCode2["EPERM"]=1]="EPERM";ErrorCode2[ErrorCode2["ENOENT"]=2]="ENOENT";ErrorCode2[ErrorCode2["EIO"]=5]="EIO";ErrorCode2[ErrorCode2["EBADF"]=9]="EBADF";ErrorCode2[ErrorCode2["EACCES"]=13]="EACCES";ErrorCode2[ErrorCode2["EBUSY"]=16]="EBUSY";ErrorCode2[ErrorCode2["EEXIST"]=17]="EEXIST";ErrorCode2[ErrorCode2["ENOTDIR"]=20]="ENOTDIR";ErrorCode2[ErrorCode2["EISDIR"]=21]="EISDIR";ErrorCode2[ErrorCode2["EINVAL"]=22]="EINVAL";ErrorCode2[ErrorCode2["EFBIG"]=27]="EFBIG";ErrorCode2[ErrorCode2["ENOSPC"]=28]="ENOSPC";ErrorCode2[ErrorCode2["EROFS"]=30]="EROFS";ErrorCode2[ErrorCode2["ENOTEMPTY"]=39]="ENOTEMPTY";ErrorCode2[ErrorCode2["ENOTSUP"]=95]="ENOTSUP"})(ErrorCode||(ErrorCode={}));var ErrorStrings={};ErrorStrings[ErrorCode.EPERM]="Operation not permitted.";ErrorStrings[ErrorCode.ENOENT]="No such file or directory.";ErrorStrings[ErrorCode.EIO]="Input/output error.";ErrorStrings[ErrorCode.EBADF]="Bad file descriptor.";ErrorStrings[ErrorCode.EACCES]="Permission denied.";ErrorStrings[ErrorCode.EBUSY]="Resource busy or locked.";ErrorStrings[ErrorCode.EEXIST]="File exists.";ErrorStrings[ErrorCode.ENOTDIR]="File is not a directory.";ErrorStrings[ErrorCode.EISDIR]="File is a directory.";ErrorStrings[ErrorCode.EINVAL]="Invalid argument.";ErrorStrings[ErrorCode.EFBIG]="File is too big.";ErrorStrings[ErrorCode.ENOSPC]="No space left on disk.";ErrorStrings[ErrorCode.EROFS]="Cannot modify a read-only file system.";ErrorStrings[ErrorCode.ENOTEMPTY]="Directory is not empty.";ErrorStrings[ErrorCode.ENOTSUP]="Operation is not supported.";var ApiError=function(Error2){function ApiError2(type,message,path$$1){if(message===void 0)message=ErrorStrings[type];Error2.call(this,message);this.syscall="";this.errno=type;this.code=ErrorCode[type];this.path=path$$1;this.stack=new Error2().stack;this.message="Error: "+this.code+": "+message+(this.path?", '"+this.path+"'":"")}if(Error2)ApiError2.__proto__=Error2;ApiError2.prototype=Object.create(Error2&&Error2.prototype);ApiError2.prototype.constructor=ApiError2;ApiError2.fromJSON=function fromJSON(json){var err=new ApiError2(0);err.errno=json.errno;err.code=json.code;err.path=json.path;err.stack=json.stack;err.message=json.message;return err};ApiError2.fromBuffer=function fromBuffer(buffer$$1,i2){if(i2===void 0)i2=0;return ApiError2.fromJSON(JSON.parse(buffer$$1.toString("utf8",i2+4,i2+4+buffer$$1.readUInt32LE(i2))))};ApiError2.FileError=function FileError(code,p){return new ApiError2(code,ErrorStrings[code],p)};ApiError2.ENOENT=function ENOENT(path$$1){return this.FileError(ErrorCode.ENOENT,path$$1)};ApiError2.EEXIST=function EEXIST(path$$1){return this.FileError(ErrorCode.EEXIST,path$$1)};ApiError2.EISDIR=function EISDIR(path$$1){return this.FileError(ErrorCode.EISDIR,path$$1)};ApiError2.ENOTDIR=function ENOTDIR(path$$1){return this.FileError(ErrorCode.ENOTDIR,path$$1)};ApiError2.EPERM=function EPERM(path$$1){return this.FileError(ErrorCode.EPERM,path$$1)};ApiError2.ENOTEMPTY=function ENOTEMPTY(path$$1){return this.FileError(ErrorCode.ENOTEMPTY,path$$1)};ApiError2.prototype.toString=function toString(){return this.message};ApiError2.prototype.toJSON=function toJSON(){return{errno:this.errno,code:this.code,path:this.path,stack:this.stack,message:this.message}};ApiError2.prototype.writeToBuffer=function writeToBuffer(buffer$$1,i2){if(buffer$$1===void 0)buffer$$1=Buffer2.alloc(this.bufferSize());if(i2===void 0)i2=0;var bytesWritten=buffer$$1.write(JSON.stringify(this.toJSON()),i2+4);buffer$$1.writeUInt32LE(bytesWritten,i2);return buffer$$1};ApiError2.prototype.bufferSize=function bufferSize(){return 4+Buffer2.byteLength(JSON.stringify(this.toJSON()))};return ApiError2}(Error);var api_error=Object.freeze({get ErrorCode(){return ErrorCode},ErrorStrings,ApiError});var ActionType;(function(ActionType2){ActionType2[ActionType2["NOP"]=0]="NOP";ActionType2[ActionType2["THROW_EXCEPTION"]=1]="THROW_EXCEPTION";ActionType2[ActionType2["TRUNCATE_FILE"]=2]="TRUNCATE_FILE";ActionType2[ActionType2["CREATE_FILE"]=3]="CREATE_FILE"})(ActionType||(ActionType={}));var FileFlag=function FileFlag2(flagStr){this.flagStr=flagStr;if(FileFlag2.validFlagStrs.indexOf(flagStr)<0){throw new ApiError(ErrorCode.EINVAL,"Invalid flag: "+flagStr)}};FileFlag.getFileFlag=function getFileFlag(flagStr){if(FileFlag.flagCache.hasOwnProperty(flagStr)){return FileFlag.flagCache[flagStr]}return FileFlag.flagCache[flagStr]=new FileFlag(flagStr)};FileFlag.prototype.getFlagString=function getFlagString(){return this.flagStr};FileFlag.prototype.isReadable=function isReadable(){return this.flagStr.indexOf("r")!==-1||this.flagStr.indexOf("+")!==-1};FileFlag.prototype.isWriteable=function isWriteable(){return this.flagStr.indexOf("w")!==-1||this.flagStr.indexOf("a")!==-1||this.flagStr.indexOf("+")!==-1};FileFlag.prototype.isTruncating=function isTruncating(){return this.flagStr.indexOf("w")!==-1};FileFlag.prototype.isAppendable=function isAppendable(){return this.flagStr.indexOf("a")!==-1};FileFlag.prototype.isSynchronous=function isSynchronous(){return this.flagStr.indexOf("s")!==-1};FileFlag.prototype.isExclusive=function isExclusive(){return this.flagStr.indexOf("x")!==-1};FileFlag.prototype.pathExistsAction=function pathExistsAction(){if(this.isExclusive()){return ActionType.THROW_EXCEPTION}else if(this.isTruncating()){return ActionType.TRUNCATE_FILE}else{return ActionType.NOP}};FileFlag.prototype.pathNotExistsAction=function pathNotExistsAction(){if((this.isWriteable()||this.isAppendable())&&this.flagStr!=="r+"){return ActionType.CREATE_FILE}else{return ActionType.THROW_EXCEPTION}};FileFlag.flagCache={};FileFlag.validFlagStrs=["r","r+","rs","rs+","w","wx","w+","wx+","a","ax","a+","ax+"];var FileType;(function(FileType2){FileType2[FileType2["FILE"]=32768]="FILE";FileType2[FileType2["DIRECTORY"]=16384]="DIRECTORY";FileType2[FileType2["SYMLINK"]=40960]="SYMLINK"})(FileType||(FileType={}));var Stats=function Stats2(itemType,size,mode,atime,mtime,ctime){if(atime===void 0)atime=new Date;if(mtime===void 0)mtime=new Date;if(ctime===void 0)ctime=new Date;this.size=size;this.atime=atime;this.mtime=mtime;this.ctime=ctime;this.dev=0;this.ino=0;this.rdev=0;this.nlink=1;this.blksize=4096;this.uid=0;this.gid=0;this.birthtime=new Date(0);this.fileData=null;if(!mode){switch(itemType){case FileType.FILE:this.mode=420;break;case FileType.DIRECTORY:default:this.mode=511}}else{this.mode=mode}this.blocks=Math.ceil(size/512);if(this.mode<4096){this.mode|=itemType}};Stats.fromBuffer=function fromBuffer(buffer$$1){var size=buffer$$1.readUInt32LE(0),mode=buffer$$1.readUInt32LE(4),atime=buffer$$1.readDoubleLE(8),mtime=buffer$$1.readDoubleLE(16),ctime=buffer$$1.readDoubleLE(24);return new Stats(mode&61440,size,mode&4095,new Date(atime),new Date(mtime),new Date(ctime))};Stats.prototype.toBuffer=function toBuffer(){var buffer$$1=Buffer2.alloc(32);buffer$$1.writeUInt32LE(this.size,0);buffer$$1.writeUInt32LE(this.mode,4);buffer$$1.writeDoubleLE(this.atime.getTime(),8);buffer$$1.writeDoubleLE(this.mtime.getTime(),16);buffer$$1.writeDoubleLE(this.ctime.getTime(),24);return buffer$$1};Stats.prototype.clone=function clone(){return new Stats(this.mode&61440,this.size,this.mode&4095,this.atime,this.mtime,this.ctime)};Stats.prototype.isFile=function isFile(){return(this.mode&61440)===FileType.FILE};Stats.prototype.isDirectory=function isDirectory(){return(this.mode&61440)===FileType.DIRECTORY};Stats.prototype.isSymbolicLink=function isSymbolicLink(){return(this.mode&61440)===FileType.SYMLINK};Stats.prototype.chmod=function chmod(mode){this.mode=this.mode&61440|mode};Stats.prototype.isSocket=function isSocket(){return false};Stats.prototype.isBlockDevice=function isBlockDevice(){return false};Stats.prototype.isCharacterDevice=function isCharacterDevice(){return false};Stats.prototype.isFIFO=function isFIFO(){return false};var wrapCb=function(cb,numArgs){return cb};function assertRoot(fs4){if(fs4){return fs4}throw new ApiError(ErrorCode.EIO,"Initialize BrowserFS with a file system using BrowserFS.initialize(filesystem)")}function normalizeMode(mode,def){switch(typeof mode){case"number":return mode;case"string":var trueMode=parseInt(mode,8);if(!isNaN(trueMode)){return trueMode}return def;default:return def}}function normalizeTime(time){if(time instanceof Date){return time}else if(typeof time==="number"){return new Date(time*1e3)}else{throw new ApiError(ErrorCode.EINVAL,"Invalid time.")}}function normalizePath(p){if(p.indexOf("\0")>=0){throw new ApiError(ErrorCode.EINVAL,"Path must be a string without null bytes.")}else if(p===""){throw new ApiError(ErrorCode.EINVAL,"Path must not be empty.")}return path.resolve(p)}function normalizeOptions(options,defEnc,defFlag,defMode){switch(typeof options){case"object":return{encoding:typeof options["encoding"]!=="undefined"?options["encoding"]:defEnc,flag:typeof options["flag"]!=="undefined"?options["flag"]:defFlag,mode:normalizeMode(options["mode"],defMode)};case"string":return{encoding:options,flag:defFlag,mode:defMode};default:return{encoding:defEnc,flag:defFlag,mode:defMode}}}function nopCb(){}var FS=function FS2(){this.F_OK=0;this.R_OK=4;this.W_OK=2;this.X_OK=1;this.root=null;this.fdMap={};this.nextFd=100};FS.prototype.initialize=function initialize3(rootFS){if(!rootFS.constructor.isAvailable()){throw new ApiError(ErrorCode.EINVAL,"Tried to instantiate BrowserFS with an unavailable file system.")}return this.root=rootFS};FS.prototype._toUnixTimestamp=function _toUnixTimestamp(time){if(typeof time==="number"){return time}else if(time instanceof Date){return time.getTime()/1e3}throw new Error("Cannot parse time: "+time)};FS.prototype.getRootFS=function getRootFS(){if(this.root){return this.root}else{return null}};FS.prototype.rename=function rename(oldPath,newPath,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{assertRoot(this.root).rename(normalizePath(oldPath),normalizePath(newPath),newCb)}catch(e){newCb(e)}};FS.prototype.renameSync=function renameSync(oldPath,newPath){assertRoot(this.root).renameSync(normalizePath(oldPath),normalizePath(newPath))};FS.prototype.exists=function exists2(path$$1,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{return assertRoot(this.root).exists(normalizePath(path$$1),newCb)}catch(e){return newCb(false)}};FS.prototype.existsSync=function existsSync(path$$1){try{return assertRoot(this.root).existsSync(normalizePath(path$$1))}catch(e){return false}};FS.prototype.stat=function stat(path$$1,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,2);try{return assertRoot(this.root).stat(normalizePath(path$$1),false,newCb)}catch(e){return newCb(e)}};FS.prototype.statSync=function statSync(path$$1){return assertRoot(this.root).statSync(normalizePath(path$$1),false)};FS.prototype.lstat=function lstat(path$$1,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,2);try{return assertRoot(this.root).stat(normalizePath(path$$1),true,newCb)}catch(e){return newCb(e)}};FS.prototype.lstatSync=function lstatSync(path$$1){return assertRoot(this.root).statSync(normalizePath(path$$1),true)};FS.prototype.truncate=function truncate(path$$1,arg2,cb){if(arg2===void 0)arg2=0;if(cb===void 0)cb=nopCb;var len=0;if(typeof arg2==="function"){cb=arg2}else if(typeof arg2==="number"){len=arg2}var newCb=wrapCb(cb,1);try{if(len<0){throw new ApiError(ErrorCode.EINVAL)}return assertRoot(this.root).truncate(normalizePath(path$$1),len,newCb)}catch(e){return newCb(e)}};FS.prototype.truncateSync=function truncateSync(path$$1,len){if(len===void 0)len=0;if(len<0){throw new ApiError(ErrorCode.EINVAL)}return assertRoot(this.root).truncateSync(normalizePath(path$$1),len)};FS.prototype.unlink=function unlink(path$$1,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{return assertRoot(this.root).unlink(normalizePath(path$$1),newCb)}catch(e){return newCb(e)}};FS.prototype.unlinkSync=function unlinkSync(path$$1){return assertRoot(this.root).unlinkSync(normalizePath(path$$1))};FS.prototype.open=function open(path$$1,flag,arg2,cb){var this$1=this;if(cb===void 0)cb=nopCb;var mode=normalizeMode(arg2,420);cb=typeof arg2==="function"?arg2:cb;var newCb=wrapCb(cb,2);try{assertRoot(this.root).open(normalizePath(path$$1),FileFlag.getFileFlag(flag),mode,function(e,file){if(file){newCb(e,this$1.getFdForFile(file))}else{newCb(e)}})}catch(e){newCb(e)}};FS.prototype.openSync=function openSync(path$$1,flag,mode){if(mode===void 0)mode=420;return this.getFdForFile(assertRoot(this.root).openSync(normalizePath(path$$1),FileFlag.getFileFlag(flag),normalizeMode(mode,420)))};FS.prototype.readFile=function readFile2(filename,arg2,cb){if(arg2===void 0)arg2={};if(cb===void 0)cb=nopCb;var options=normalizeOptions(arg2,null,"r",null);cb=typeof arg2==="function"?arg2:cb;var newCb=wrapCb(cb,2);try{var flag=FileFlag.getFileFlag(options["flag"]);if(!flag.isReadable()){return newCb(new ApiError(ErrorCode.EINVAL,"Flag passed to readFile must allow for reading."))}return assertRoot(this.root).readFile(normalizePath(filename),options.encoding,flag,newCb)}catch(e){return newCb(e)}};FS.prototype.readFileSync=function readFileSync(filename,arg2){if(arg2===void 0)arg2={};var options=normalizeOptions(arg2,null,"r",null);var flag=FileFlag.getFileFlag(options.flag);if(!flag.isReadable()){throw new ApiError(ErrorCode.EINVAL,"Flag passed to readFile must allow for reading.")}return assertRoot(this.root).readFileSync(normalizePath(filename),options.encoding,flag)};FS.prototype.writeFile=function writeFile2(filename,data,arg3,cb){if(arg3===void 0)arg3={};if(cb===void 0)cb=nopCb;var options=normalizeOptions(arg3,"utf8","w",420);cb=typeof arg3==="function"?arg3:cb;var newCb=wrapCb(cb,1);try{var flag=FileFlag.getFileFlag(options.flag);if(!flag.isWriteable()){return newCb(new ApiError(ErrorCode.EINVAL,"Flag passed to writeFile must allow for writing."))}return assertRoot(this.root).writeFile(normalizePath(filename),data,options.encoding,flag,options.mode,newCb)}catch(e){return newCb(e)}};FS.prototype.writeFileSync=function writeFileSync(filename,data,arg3){var options=normalizeOptions(arg3,"utf8","w",420);var flag=FileFlag.getFileFlag(options.flag);if(!flag.isWriteable()){throw new ApiError(ErrorCode.EINVAL,"Flag passed to writeFile must allow for writing.")}return assertRoot(this.root).writeFileSync(normalizePath(filename),data,options.encoding,flag,options.mode)};FS.prototype.appendFile=function appendFile3(filename,data,arg3,cb){if(cb===void 0)cb=nopCb;var options=normalizeOptions(arg3,"utf8","a",420);cb=typeof arg3==="function"?arg3:cb;var newCb=wrapCb(cb,1);try{var flag=FileFlag.getFileFlag(options.flag);if(!flag.isAppendable()){return newCb(new ApiError(ErrorCode.EINVAL,"Flag passed to appendFile must allow for appending."))}assertRoot(this.root).appendFile(normalizePath(filename),data,options.encoding,flag,options.mode,newCb)}catch(e){newCb(e)}};FS.prototype.appendFileSync=function appendFileSync(filename,data,arg3){var options=normalizeOptions(arg3,"utf8","a",420);var flag=FileFlag.getFileFlag(options.flag);if(!flag.isAppendable()){throw new ApiError(ErrorCode.EINVAL,"Flag passed to appendFile must allow for appending.")}return assertRoot(this.root).appendFileSync(normalizePath(filename),data,options.encoding,flag,options.mode)};FS.prototype.fstat=function fstat(fd,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,2);try{var file=this.fd2file(fd);file.stat(newCb)}catch(e){newCb(e)}};FS.prototype.fstatSync=function fstatSync(fd){return this.fd2file(fd).statSync()};FS.prototype.close=function close(fd,cb){var this$1=this;if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{this.fd2file(fd).close(function(e){if(!e){this$1.closeFd(fd)}newCb(e)})}catch(e){newCb(e)}};FS.prototype.closeSync=function closeSync(fd){this.fd2file(fd).closeSync();this.closeFd(fd)};FS.prototype.ftruncate=function ftruncate(fd,arg2,cb){if(cb===void 0)cb=nopCb;var length=typeof arg2==="number"?arg2:0;cb=typeof arg2==="function"?arg2:cb;var newCb=wrapCb(cb,1);try{var file=this.fd2file(fd);if(length<0){throw new ApiError(ErrorCode.EINVAL)}file.truncate(length,newCb)}catch(e){newCb(e)}};FS.prototype.ftruncateSync=function ftruncateSync(fd,len){if(len===void 0)len=0;var file=this.fd2file(fd);if(len<0){throw new ApiError(ErrorCode.EINVAL)}file.truncateSync(len)};FS.prototype.fsync=function fsync(fd,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{this.fd2file(fd).sync(newCb)}catch(e){newCb(e)}};FS.prototype.fsyncSync=function fsyncSync(fd){this.fd2file(fd).syncSync()};FS.prototype.fdatasync=function fdatasync(fd,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{this.fd2file(fd).datasync(newCb)}catch(e){newCb(e)}};FS.prototype.fdatasyncSync=function fdatasyncSync(fd){this.fd2file(fd).datasyncSync()};FS.prototype.write=function write(fd,arg2,arg3,arg4,arg5,cb){if(cb===void 0)cb=nopCb;var buffer$$1,offset,length,position=null;if(typeof arg2==="string"){var encoding="utf8";switch(typeof arg3){case"function":cb=arg3;break;case"number":position=arg3;encoding=typeof arg4==="string"?arg4:"utf8";cb=typeof arg5==="function"?arg5:cb;break;default:cb=typeof arg4==="function"?arg4:typeof arg5==="function"?arg5:cb;return cb(new ApiError(ErrorCode.EINVAL,"Invalid arguments."))}buffer$$1=Buffer2.from(arg2,encoding);offset=0;length=buffer$$1.length}else{buffer$$1=arg2;offset=arg3;length=arg4;position=typeof arg5==="number"?arg5:null;cb=typeof arg5==="function"?arg5:cb}var newCb=wrapCb(cb,3);try{var file=this.fd2file(fd);if(position===void 0||position===null){position=file.getPos()}file.write(buffer$$1,offset,length,position,newCb)}catch(e){newCb(e)}};FS.prototype.writeSync=function writeSync(fd,arg2,arg3,arg4,arg5){var buffer$$1,offset=0,length,position;if(typeof arg2==="string"){position=typeof arg3==="number"?arg3:null;var encoding=typeof arg4==="string"?arg4:"utf8";offset=0;buffer$$1=Buffer2.from(arg2,encoding);length=buffer$$1.length}else{buffer$$1=arg2;offset=arg3;length=arg4;position=typeof arg5==="number"?arg5:null}var file=this.fd2file(fd);if(position===void 0||position===null){position=file.getPos()}return file.writeSync(buffer$$1,offset,length,position)};FS.prototype.read=function read(fd,arg2,arg3,arg4,arg5,cb){if(cb===void 0)cb=nopCb;var position,offset,length,buffer$$1,newCb;if(typeof arg2==="number"){length=arg2;position=arg3;var encoding=arg4;cb=typeof arg5==="function"?arg5:cb;offset=0;buffer$$1=Buffer2.alloc(length);newCb=wrapCb(function(err,bytesRead,buf){if(err){return cb(err)}cb(err,buf.toString(encoding),bytesRead)},3)}else{buffer$$1=arg2;offset=arg3;length=arg4;position=arg5;newCb=wrapCb(cb,3)}try{var file=this.fd2file(fd);if(position===void 0||position===null){position=file.getPos()}file.read(buffer$$1,offset,length,position,newCb)}catch(e){newCb(e)}};FS.prototype.readSync=function readSync(fd,arg2,arg3,arg4,arg5){var shenanigans=false;var buffer$$1,offset,length,position,encoding="utf8";if(typeof arg2==="number"){length=arg2;position=arg3;encoding=arg4;offset=0;buffer$$1=Buffer2.alloc(length);shenanigans=true}else{buffer$$1=arg2;offset=arg3;length=arg4;position=arg5}var file=this.fd2file(fd);if(position===void 0||position===null){position=file.getPos()}var rv=file.readSync(buffer$$1,offset,length,position);if(!shenanigans){return rv}else{return[buffer$$1.toString(encoding),rv]}};FS.prototype.fchown=function fchown(fd,uid,gid,callback){if(callback===void 0)callback=nopCb;var newCb=wrapCb(callback,1);try{this.fd2file(fd).chown(uid,gid,newCb)}catch(e){newCb(e)}};FS.prototype.fchownSync=function fchownSync(fd,uid,gid){this.fd2file(fd).chownSync(uid,gid)};FS.prototype.fchmod=function fchmod(fd,mode,cb){var newCb=wrapCb(cb,1);try{var numMode=typeof mode==="string"?parseInt(mode,8):mode;this.fd2file(fd).chmod(numMode,newCb)}catch(e){newCb(e)}};FS.prototype.fchmodSync=function fchmodSync(fd,mode){var numMode=typeof mode==="string"?parseInt(mode,8):mode;this.fd2file(fd).chmodSync(numMode)};FS.prototype.futimes=function futimes(fd,atime,mtime,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{var file=this.fd2file(fd);if(typeof atime==="number"){atime=new Date(atime*1e3)}if(typeof mtime==="number"){mtime=new Date(mtime*1e3)}file.utimes(atime,mtime,newCb)}catch(e){newCb(e)}};FS.prototype.futimesSync=function futimesSync(fd,atime,mtime){this.fd2file(fd).utimesSync(normalizeTime(atime),normalizeTime(mtime))};FS.prototype.rmdir=function rmdir(path$$1,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{path$$1=normalizePath(path$$1);assertRoot(this.root).rmdir(path$$1,newCb)}catch(e){newCb(e)}};FS.prototype.rmdirSync=function rmdirSync(path$$1){path$$1=normalizePath(path$$1);return assertRoot(this.root).rmdirSync(path$$1)};FS.prototype.mkdir=function mkdir(path$$1,mode,cb){if(cb===void 0)cb=nopCb;if(typeof mode==="function"){cb=mode;mode=511}var newCb=wrapCb(cb,1);try{path$$1=normalizePath(path$$1);assertRoot(this.root).mkdir(path$$1,mode,newCb)}catch(e){newCb(e)}};FS.prototype.mkdirSync=function mkdirSync(path$$1,mode){assertRoot(this.root).mkdirSync(normalizePath(path$$1),normalizeMode(mode,511))};FS.prototype.readdir=function readdir(path$$1,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,2);try{path$$1=normalizePath(path$$1);assertRoot(this.root).readdir(path$$1,newCb)}catch(e){newCb(e)}};FS.prototype.readdirSync=function readdirSync(path$$1){path$$1=normalizePath(path$$1);return assertRoot(this.root).readdirSync(path$$1)};FS.prototype.link=function link(srcpath,dstpath,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{srcpath=normalizePath(srcpath);dstpath=normalizePath(dstpath);assertRoot(this.root).link(srcpath,dstpath,newCb)}catch(e){newCb(e)}};FS.prototype.linkSync=function linkSync(srcpath,dstpath){srcpath=normalizePath(srcpath);dstpath=normalizePath(dstpath);return assertRoot(this.root).linkSync(srcpath,dstpath)};FS.prototype.symlink=function symlink(srcpath,dstpath,arg3,cb){if(cb===void 0)cb=nopCb;var type=typeof arg3==="string"?arg3:"file";cb=typeof arg3==="function"?arg3:cb;var newCb=wrapCb(cb,1);try{if(type!=="file"&&type!=="dir"){return newCb(new ApiError(ErrorCode.EINVAL,"Invalid type: "+type))}srcpath=normalizePath(srcpath);dstpath=normalizePath(dstpath);assertRoot(this.root).symlink(srcpath,dstpath,type,newCb)}catch(e){newCb(e)}};FS.prototype.symlinkSync=function symlinkSync(srcpath,dstpath,type){if(!type){type="file"}else if(type!=="file"&&type!=="dir"){throw new ApiError(ErrorCode.EINVAL,"Invalid type: "+type)}srcpath=normalizePath(srcpath);dstpath=normalizePath(dstpath);return assertRoot(this.root).symlinkSync(srcpath,dstpath,type)};FS.prototype.readlink=function readlink(path$$1,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,2);try{path$$1=normalizePath(path$$1);assertRoot(this.root).readlink(path$$1,newCb)}catch(e){newCb(e)}};FS.prototype.readlinkSync=function readlinkSync(path$$1){path$$1=normalizePath(path$$1);return assertRoot(this.root).readlinkSync(path$$1)};FS.prototype.chown=function chown(path$$1,uid,gid,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{path$$1=normalizePath(path$$1);assertRoot(this.root).chown(path$$1,false,uid,gid,newCb)}catch(e){newCb(e)}};FS.prototype.chownSync=function chownSync(path$$1,uid,gid){path$$1=normalizePath(path$$1);assertRoot(this.root).chownSync(path$$1,false,uid,gid)};FS.prototype.lchown=function lchown(path$$1,uid,gid,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{path$$1=normalizePath(path$$1);assertRoot(this.root).chown(path$$1,true,uid,gid,newCb)}catch(e){newCb(e)}};FS.prototype.lchownSync=function lchownSync(path$$1,uid,gid){path$$1=normalizePath(path$$1);assertRoot(this.root).chownSync(path$$1,true,uid,gid)};FS.prototype.chmod=function chmod(path$$1,mode,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{var numMode=normalizeMode(mode,-1);if(numMode<0){throw new ApiError(ErrorCode.EINVAL,"Invalid mode.")}assertRoot(this.root).chmod(normalizePath(path$$1),false,numMode,newCb)}catch(e){newCb(e)}};FS.prototype.chmodSync=function chmodSync(path$$1,mode){var numMode=normalizeMode(mode,-1);if(numMode<0){throw new ApiError(ErrorCode.EINVAL,"Invalid mode.")}path$$1=normalizePath(path$$1);assertRoot(this.root).chmodSync(path$$1,false,numMode)};FS.prototype.lchmod=function lchmod(path$$1,mode,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{var numMode=normalizeMode(mode,-1);if(numMode<0){throw new ApiError(ErrorCode.EINVAL,"Invalid mode.")}assertRoot(this.root).chmod(normalizePath(path$$1),true,numMode,newCb)}catch(e){newCb(e)}};FS.prototype.lchmodSync=function lchmodSync(path$$1,mode){var numMode=normalizeMode(mode,-1);if(numMode<1){throw new ApiError(ErrorCode.EINVAL,"Invalid mode.")}assertRoot(this.root).chmodSync(normalizePath(path$$1),true,numMode)};FS.prototype.utimes=function utimes(path$$1,atime,mtime,cb){if(cb===void 0)cb=nopCb;var newCb=wrapCb(cb,1);try{assertRoot(this.root).utimes(normalizePath(path$$1),normalizeTime(atime),normalizeTime(mtime),newCb)}catch(e){newCb(e)}};FS.prototype.utimesSync=function utimesSync(path$$1,atime,mtime){assertRoot(this.root).utimesSync(normalizePath(path$$1),normalizeTime(atime),normalizeTime(mtime))};FS.prototype.realpath=function realpath(path$$1,arg2,cb){if(cb===void 0)cb=nopCb;var cache=typeof arg2==="object"?arg2:{};cb=typeof arg2==="function"?arg2:nopCb;var newCb=wrapCb(cb,2);try{path$$1=normalizePath(path$$1);assertRoot(this.root).realpath(path$$1,cache,newCb)}catch(e){newCb(e)}};FS.prototype.realpathSync=function realpathSync(path$$1,cache){if(cache===void 0)cache={};path$$1=normalizePath(path$$1);return assertRoot(this.root).realpathSync(path$$1,cache)};FS.prototype.watchFile=function watchFile(filename,arg2,listener){if(listener===void 0)listener=nopCb;throw new ApiError(ErrorCode.ENOTSUP)};FS.prototype.unwatchFile=function unwatchFile(filename,listener){if(listener===void 0)listener=nopCb;throw new ApiError(ErrorCode.ENOTSUP)};FS.prototype.watch=function watch(filename,arg2,listener){if(listener===void 0)listener=nopCb;throw new ApiError(ErrorCode.ENOTSUP)};FS.prototype.access=function access(path$$1,arg2,cb){if(cb===void 0)cb=nopCb;throw new ApiError(ErrorCode.ENOTSUP)};FS.prototype.accessSync=function accessSync(path$$1,mode){throw new ApiError(ErrorCode.ENOTSUP)};FS.prototype.createReadStream=function createReadStream(path$$1,options){throw new ApiError(ErrorCode.ENOTSUP)};FS.prototype.createWriteStream=function createWriteStream(path$$1,options){throw new ApiError(ErrorCode.ENOTSUP)};FS.prototype.wrapCallbacks=function wrapCallbacks(cbWrapper){wrapCb=cbWrapper};FS.prototype.getFdForFile=function getFdForFile(file){var fd=this.nextFd++;this.fdMap[fd]=file;return fd};FS.prototype.fd2file=function fd2file(fd){var rv=this.fdMap[fd];if(rv){return rv}else{throw new ApiError(ErrorCode.EBADF,"Invalid file descriptor.")}};FS.prototype.closeFd=function closeFd(fd){delete this.fdMap[fd]};FS.Stats=Stats;var fs3=new FS;var _fsMock={};var fsProto=FS.prototype;Object.keys(fsProto).forEach(function(key){if(typeof fs3[key]==="function"){_fsMock[key]=function(){return fs3[key].apply(fs3,arguments)}}else{_fsMock[key]=fs3[key]}});_fsMock["changeFSModule"]=function(newFs){fs3=newFs};_fsMock["getFSModule"]=function(){return fs3};_fsMock["FS"]=FS;function _min(d0,d1,d2,bx,ay){return d0d2?d2+1:d0+1:bx===ay?d1:d1+1}function levenshtein(a,b){if(a===b){return 0}if(a.length>b.length){var tmp=a;a=b;b=tmp}var la=a.length;var lb=b.length;while(la>0&&a.charCodeAt(la-1)===b.charCodeAt(lb-1)){la--;lb--}var offset=0;while(offsetdd?dd+1:dy$1+1:bx0$1===vector[la+y$2]?d0:d0+1;d0=dy$1}}return dd}function deprecationMessage(print,fsName,opts){if(print){console.warn("["+fsName+"] Direct file system constructor usage is deprecated for this file system, and will be removed in the next major version. Please use the '"+fsName+".Create("+JSON.stringify(opts)+", callback)' method instead. See https://github.com/jvilk/BrowserFS/issues/176 for more details.")}}var isIE=typeof navigator!=="undefined"&&!!(/(msie) ([\w.]+)/.exec(navigator.userAgent.toLowerCase())||navigator.userAgent.indexOf("Trident")!==-1);var isWebWorker=typeof window==="undefined";function fail(){throw new Error("BFS has reached an impossible code path; please file a bug.")}function mkdirpSync(p,mode,fs4){if(!fs4.existsSync(p)){mkdirpSync(path.dirname(p),mode,fs4);fs4.mkdirSync(p,mode)}}function buffer2ArrayBuffer(buff){var u8=buffer2Uint8array(buff),u8offset=u8.byteOffset,u8Len=u8.byteLength;if(u8offset===0&&u8Len===u8.buffer.byteLength){return u8.buffer}else{return u8.buffer.slice(u8offset,u8offset+u8Len)}}function buffer2Uint8array(buff){if(buff instanceof Uint8Array){return buff}else{return new Uint8Array(buff)}}function arrayish2Buffer(arr){if(arr instanceof Buffer2){return arr}else if(arr instanceof Uint8Array){return uint8Array2Buffer(arr)}else{return Buffer2.from(arr)}}function uint8Array2Buffer(u8){if(u8 instanceof Buffer2){return u8}else if(u8.byteOffset===0&&u8.byteLength===u8.buffer.byteLength){return arrayBuffer2Buffer(u8.buffer)}else{return Buffer2.from(u8.buffer,u8.byteOffset,u8.byteLength)}}function arrayBuffer2Buffer(ab){return Buffer2.from(ab)}function copyingSlice(buff,start,end){if(start===void 0)start=0;if(end===void 0)end=buff.length;if(start<0||end<0||end>buff.length||start>end){throw new TypeError("Invalid slice bounds on buffer of length "+buff.length+": ["+start+", "+end+"]")}if(buff.length===0){return emptyBuffer()}else{var u8=buffer2Uint8array(buff),s0=buff[0],newS0=(s0+1)%255;buff[0]=newS0;if(u8[0]===newS0){u8[0]=s0;return uint8Array2Buffer(u8.slice(start,end))}else{buff[0]=s0;return uint8Array2Buffer(u8.subarray(start,end))}}}var emptyBuff=null;function emptyBuffer(){if(emptyBuff){return emptyBuff}return emptyBuff=Buffer2.alloc(0)}function bufferValidator(v,cb){if(Buffer2.isBuffer(v)){cb()}else{cb(new ApiError(ErrorCode.EINVAL,"option must be a Buffer."))}}function checkOptions(fsType,opts,cb){var optsInfo=fsType.Options;var fsName=fsType.Name;var pendingValidators=0;var callbackCalled=false;var loopEnded=false;function validatorCallback(e){if(!callbackCalled){if(e){callbackCalled=true;cb(e)}pendingValidators--;if(pendingValidators===0&&loopEnded){cb()}}}var loop=function(optName2){if(optsInfo.hasOwnProperty(optName2)){var opt=optsInfo[optName2];var providedValue=opts[optName2];if(providedValue===void 0||providedValue===null){if(!opt.optional){var incorrectOptions=Object.keys(opts).filter(function(o){return!(o in optsInfo)}).map(function(a){return{str:a,distance:levenshtein(optName2,a)}}).filter(function(o){return o.distance<5}).sort(function(a,b){return a.distance-b.distance});if(callbackCalled){return{}}callbackCalled=true;return{v:cb(new ApiError(ErrorCode.EINVAL,"["+fsName+"] Required option '"+optName2+"' not provided."+(incorrectOptions.length>0?" You provided unrecognized option '"+incorrectOptions[0].str+"'; perhaps you meant to type '"+optName2+"'.":"")+"\nOption description: "+opt.description))}}}else{var typeMatches=false;if(Array.isArray(opt.type)){typeMatches=opt.type.indexOf(typeof providedValue)!==-1}else{typeMatches=typeof providedValue===opt.type}if(!typeMatches){if(callbackCalled){return{}}callbackCalled=true;return{v:cb(new ApiError(ErrorCode.EINVAL,"["+fsName+"] Value provided for option "+optName2+" is not the proper type. Expected "+(Array.isArray(opt.type)?"one of {"+opt.type.join(", ")+"}":opt.type)+", but received "+typeof providedValue+"\nOption description: "+opt.description))}}else if(opt.validator){pendingValidators++;opt.validator(providedValue,validatorCallback)}}}};for(var optName in optsInfo){var returned=loop(optName);if(returned)return returned.v}loopEnded=true;if(pendingValidators===0&&!callbackCalled){cb()}}var BFSUtils=Object.freeze({deprecationMessage,isIE,isWebWorker,fail,mkdirpSync,buffer2ArrayBuffer,buffer2Uint8array,arrayish2Buffer,uint8Array2Buffer,arrayBuffer2Buffer,copyingSlice,emptyBuffer,bufferValidator,checkOptions});var BFSEmscriptenStreamOps=function BFSEmscriptenStreamOps2(fs4){this.fs=fs4;this.nodefs=fs4.getNodeFS();this.FS=fs4.getFS();this.PATH=fs4.getPATH();this.ERRNO_CODES=fs4.getERRNO_CODES()};BFSEmscriptenStreamOps.prototype.open=function open(stream){var path$$1=this.fs.realPath(stream.node);var FS2=this.FS;try{if(FS2.isFile(stream.node.mode)){stream.nfd=this.nodefs.openSync(path$$1,this.fs.flagsToPermissionString(stream.flags))}}catch(e){if(!e.code){throw e}throw new FS2.ErrnoError(this.ERRNO_CODES[e.code])}};BFSEmscriptenStreamOps.prototype.close=function close(stream){var FS2=this.FS;try{if(FS2.isFile(stream.node.mode)&&stream.nfd){this.nodefs.closeSync(stream.nfd)}}catch(e){if(!e.code){throw e}throw new FS2.ErrnoError(this.ERRNO_CODES[e.code])}};BFSEmscriptenStreamOps.prototype.read=function read(stream,buffer$$1,offset,length,position){try{return this.nodefs.readSync(stream.nfd,uint8Array2Buffer(buffer$$1),offset,length,position)}catch(e){throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}};BFSEmscriptenStreamOps.prototype.write=function write(stream,buffer$$1,offset,length,position){try{return this.nodefs.writeSync(stream.nfd,uint8Array2Buffer(buffer$$1),offset,length,position)}catch(e){throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}};BFSEmscriptenStreamOps.prototype.llseek=function llseek(stream,offset,whence){var position=offset;if(whence===1){position+=stream.position}else if(whence===2){if(this.FS.isFile(stream.node.mode)){try{var stat=this.nodefs.fstatSync(stream.nfd);position+=stat.size}catch(e){throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}}}if(position<0){throw new this.FS.ErrnoError(this.ERRNO_CODES.EINVAL)}stream.position=position;return position};var BFSEmscriptenNodeOps=function BFSEmscriptenNodeOps2(fs4){this.fs=fs4;this.nodefs=fs4.getNodeFS();this.FS=fs4.getFS();this.PATH=fs4.getPATH();this.ERRNO_CODES=fs4.getERRNO_CODES()};BFSEmscriptenNodeOps.prototype.getattr=function getattr(node){var path$$1=this.fs.realPath(node);var stat;try{stat=this.nodefs.lstatSync(path$$1)}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}return{dev:stat.dev,ino:stat.ino,mode:stat.mode,nlink:stat.nlink,uid:stat.uid,gid:stat.gid,rdev:stat.rdev,size:stat.size,atime:stat.atime,mtime:stat.mtime,ctime:stat.ctime,blksize:stat.blksize,blocks:stat.blocks}};BFSEmscriptenNodeOps.prototype.setattr=function setattr(node,attr){var path$$1=this.fs.realPath(node);try{if(attr.mode!==void 0){this.nodefs.chmodSync(path$$1,attr.mode);node.mode=attr.mode}if(attr.timestamp!==void 0){var date=new Date(attr.timestamp);this.nodefs.utimesSync(path$$1,date,date)}}catch(e){if(!e.code){throw e}if(e.code!=="ENOTSUP"){throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}}if(attr.size!==void 0){try{this.nodefs.truncateSync(path$$1,attr.size)}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}}};BFSEmscriptenNodeOps.prototype.lookup=function lookup(parent,name){var path$$1=this.PATH.join2(this.fs.realPath(parent),name);var mode=this.fs.getMode(path$$1);return this.fs.createNode(parent,name,mode)};BFSEmscriptenNodeOps.prototype.mknod=function mknod(parent,name,mode,dev){var node=this.fs.createNode(parent,name,mode,dev);var path$$1=this.fs.realPath(node);try{if(this.FS.isDir(node.mode)){this.nodefs.mkdirSync(path$$1,node.mode)}else{this.nodefs.writeFileSync(path$$1,"",{mode:node.mode})}}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}return node};BFSEmscriptenNodeOps.prototype.rename=function rename(oldNode,newDir,newName){var oldPath=this.fs.realPath(oldNode);var newPath=this.PATH.join2(this.fs.realPath(newDir),newName);try{this.nodefs.renameSync(oldPath,newPath);oldNode.name=newName;oldNode.parent=newDir}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}};BFSEmscriptenNodeOps.prototype.unlink=function unlink(parent,name){var path$$1=this.PATH.join2(this.fs.realPath(parent),name);try{this.nodefs.unlinkSync(path$$1)}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}};BFSEmscriptenNodeOps.prototype.rmdir=function rmdir(parent,name){var path$$1=this.PATH.join2(this.fs.realPath(parent),name);try{this.nodefs.rmdirSync(path$$1)}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}};BFSEmscriptenNodeOps.prototype.readdir=function readdir(node){var path$$1=this.fs.realPath(node);try{var contents=this.nodefs.readdirSync(path$$1);contents.push(".","..");return contents}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}};BFSEmscriptenNodeOps.prototype.symlink=function symlink(parent,newName,oldPath){var newPath=this.PATH.join2(this.fs.realPath(parent),newName);try{this.nodefs.symlinkSync(oldPath,newPath)}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}};BFSEmscriptenNodeOps.prototype.readlink=function readlink(node){var path$$1=this.fs.realPath(node);try{return this.nodefs.readlinkSync(path$$1)}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}};var BFSEmscriptenFS=function BFSEmscriptenFS2(_FS,_PATH,_ERRNO_CODES,nodefs){if(_FS===void 0)_FS=self["FS"];if(_PATH===void 0)_PATH=self["PATH"];if(_ERRNO_CODES===void 0)_ERRNO_CODES=self["ERRNO_CODES"];if(nodefs===void 0)nodefs=_fsMock;this.flagsToPermissionStringMap={0:"r",1:"r+",2:"r+",64:"r",65:"r+",66:"r+",129:"rx+",193:"rx+",514:"w+",577:"w",578:"w+",705:"wx",706:"wx+",1024:"a",1025:"a",1026:"a+",1089:"a",1090:"a+",1153:"ax",1154:"ax+",1217:"ax",1218:"ax+",4096:"rs",4098:"rs+"};this.nodefs=nodefs;this.FS=_FS;this.PATH=_PATH;this.ERRNO_CODES=_ERRNO_CODES;this.node_ops=new BFSEmscriptenNodeOps(this);this.stream_ops=new BFSEmscriptenStreamOps(this)};BFSEmscriptenFS.prototype.mount=function mount(m){return this.createNode(null,"/",this.getMode(m.opts.root),0)};BFSEmscriptenFS.prototype.createNode=function createNode(parent,name,mode,dev){var FS2=this.FS;if(!FS2.isDir(mode)&&!FS2.isFile(mode)&&!FS2.isLink(mode)){throw new FS2.ErrnoError(this.ERRNO_CODES.EINVAL)}var node=FS2.createNode(parent,name,mode);node.node_ops=this.node_ops;node.stream_ops=this.stream_ops;return node};BFSEmscriptenFS.prototype.getMode=function getMode(path$$1){var stat;try{stat=this.nodefs.lstatSync(path$$1)}catch(e){if(!e.code){throw e}throw new this.FS.ErrnoError(this.ERRNO_CODES[e.code])}return stat.mode};BFSEmscriptenFS.prototype.realPath=function realPath(node){var parts=[];while(node.parent!==node){parts.push(node.name);node=node.parent}parts.push(node.mount.opts.root);parts.reverse();return this.PATH.join.apply(null,parts)};BFSEmscriptenFS.prototype.flagsToPermissionString=function flagsToPermissionString(flags){var parsedFlags=typeof flags==="string"?parseInt(flags,10):flags;parsedFlags&=8191;if(parsedFlags in this.flagsToPermissionStringMap){return this.flagsToPermissionStringMap[parsedFlags]}else{return flags}};BFSEmscriptenFS.prototype.getNodeFS=function getNodeFS(){return this.nodefs};BFSEmscriptenFS.prototype.getFS=function getFS(){return this.FS};BFSEmscriptenFS.prototype.getPATH=function getPATH(){return this.PATH};BFSEmscriptenFS.prototype.getERRNO_CODES=function getERRNO_CODES(){return this.ERRNO_CODES};var BaseFileSystem=function BaseFileSystem2(){};BaseFileSystem.prototype.supportsLinks=function supportsLinks(){return false};BaseFileSystem.prototype.diskSpace=function diskSpace(p,cb){cb(0,0)};BaseFileSystem.prototype.openFile=function openFile(p,flag,cb){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.createFile=function createFile(p,flag,mode,cb){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.open=function open(p,flag,mode,cb){var this$1=this;var mustBeFile=function(e,stats){if(e){switch(flag.pathNotExistsAction()){case ActionType.CREATE_FILE:return this$1.stat(path.dirname(p),false,function(e2,parentStats){if(e2){cb(e2)}else if(parentStats&&!parentStats.isDirectory()){cb(ApiError.ENOTDIR(path.dirname(p)))}else{this$1.createFile(p,flag,mode,cb)}});case ActionType.THROW_EXCEPTION:return cb(ApiError.ENOENT(p));default:return cb(new ApiError(ErrorCode.EINVAL,"Invalid FileFlag object."))}}else{if(stats&&stats.isDirectory()){return cb(ApiError.EISDIR(p))}switch(flag.pathExistsAction()){case ActionType.THROW_EXCEPTION:return cb(ApiError.EEXIST(p));case ActionType.TRUNCATE_FILE:return this$1.openFile(p,flag,function(e2,fd){if(e2){cb(e2)}else if(fd){fd.truncate(0,function(){fd.sync(function(){cb(null,fd)})})}else{fail()}});case ActionType.NOP:return this$1.openFile(p,flag,cb);default:return cb(new ApiError(ErrorCode.EINVAL,"Invalid FileFlag object."))}}};this.stat(p,false,mustBeFile)};BaseFileSystem.prototype.rename=function rename(oldPath,newPath,cb){cb(new ApiError(ErrorCode.ENOTSUP))};BaseFileSystem.prototype.renameSync=function renameSync(oldPath,newPath){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.stat=function stat(p,isLstat,cb){cb(new ApiError(ErrorCode.ENOTSUP))};BaseFileSystem.prototype.statSync=function statSync(p,isLstat){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.openFileSync=function openFileSync(p,flag,mode){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.createFileSync=function createFileSync(p,flag,mode){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.openSync=function openSync(p,flag,mode){var stats;try{stats=this.statSync(p,false)}catch(e){switch(flag.pathNotExistsAction()){case ActionType.CREATE_FILE:var parentStats=this.statSync(path.dirname(p),false);if(!parentStats.isDirectory()){throw ApiError.ENOTDIR(path.dirname(p))}return this.createFileSync(p,flag,mode);case ActionType.THROW_EXCEPTION:throw ApiError.ENOENT(p);default:throw new ApiError(ErrorCode.EINVAL,"Invalid FileFlag object.")}}if(stats.isDirectory()){throw ApiError.EISDIR(p)}switch(flag.pathExistsAction()){case ActionType.THROW_EXCEPTION:throw ApiError.EEXIST(p);case ActionType.TRUNCATE_FILE:this.unlinkSync(p);return this.createFileSync(p,flag,stats.mode);case ActionType.NOP:return this.openFileSync(p,flag,mode);default:throw new ApiError(ErrorCode.EINVAL,"Invalid FileFlag object.")}};BaseFileSystem.prototype.unlink=function unlink(p,cb){cb(new ApiError(ErrorCode.ENOTSUP))};BaseFileSystem.prototype.unlinkSync=function unlinkSync(p){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.rmdir=function rmdir(p,cb){cb(new ApiError(ErrorCode.ENOTSUP))};BaseFileSystem.prototype.rmdirSync=function rmdirSync(p){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.mkdir=function mkdir(p,mode,cb){cb(new ApiError(ErrorCode.ENOTSUP))};BaseFileSystem.prototype.mkdirSync=function mkdirSync(p,mode){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.readdir=function readdir(p,cb){cb(new ApiError(ErrorCode.ENOTSUP))};BaseFileSystem.prototype.readdirSync=function readdirSync(p){throw new ApiError(ErrorCode.ENOTSUP)};BaseFileSystem.prototype.exists=function exists2(p,cb){this.stat(p,null,function(err){cb(!err)})};BaseFileSystem.prototype.existsSync=function existsSync(p){try{this.statSync(p,true);return true}catch(e){return false}};BaseFileSystem.prototype.realpath=function realpath(p,cache,cb){if(this.supportsLinks()){var splitPath=p.split(path.sep);for(var i2=0;i2this._buffer.length){var buf=Buffer2.alloc(len-this._buffer.length,0);this.writeSync(buf,0,buf.length,this._buffer.length);if(this._flag.isSynchronous()&&_fsMock.getRootFS().supportsSynch()){this.syncSync()}return}this._stat.size=len;var newBuff=Buffer2.alloc(len);this._buffer.copy(newBuff,0,0,len);this._buffer=newBuff;if(this._flag.isSynchronous()&&_fsMock.getRootFS().supportsSynch()){this.syncSync()}};PreloadFile2.prototype.write=function write(buffer$$1,offset,length,position,cb){try{cb(null,this.writeSync(buffer$$1,offset,length,position),buffer$$1)}catch(e){cb(e)}};PreloadFile2.prototype.writeSync=function writeSync(buffer$$1,offset,length,position){this._dirty=true;if(position===void 0||position===null){position=this.getPos()}if(!this._flag.isWriteable()){throw new ApiError(ErrorCode.EPERM,"File not opened with a writeable mode.")}var endFp=position+length;if(endFp>this._stat.size){this._stat.size=endFp;if(endFp>this._buffer.length){var newBuff=Buffer2.alloc(endFp);this._buffer.copy(newBuff);this._buffer=newBuff}}var len=buffer$$1.copy(this._buffer,position,offset,offset+length);this._stat.mtime=new Date;if(this._flag.isSynchronous()){this.syncSync();return len}this.setPos(position+len);return len};PreloadFile2.prototype.read=function read(buffer$$1,offset,length,position,cb){try{cb(null,this.readSync(buffer$$1,offset,length,position),buffer$$1)}catch(e){cb(e)}};PreloadFile2.prototype.readSync=function readSync(buffer$$1,offset,length,position){if(!this._flag.isReadable()){throw new ApiError(ErrorCode.EPERM,"File not opened with a readable mode.")}if(position===void 0||position===null){position=this.getPos()}var endRead=position+length;if(endRead>this._stat.size){length=this._stat.size-position}var rv=this._buffer.copy(buffer$$1,offset,position,position+length);this._stat.atime=new Date;this._pos=position+length;return rv};PreloadFile2.prototype.chmod=function chmod(mode,cb){try{this.chmodSync(mode);cb()}catch(e){cb(e)}};PreloadFile2.prototype.chmodSync=function chmodSync(mode){if(!this._fs.supportsProps()){throw new ApiError(ErrorCode.ENOTSUP)}this._dirty=true;this._stat.chmod(mode);this.syncSync()};PreloadFile2.prototype.isDirty=function isDirty(){return this._dirty};PreloadFile2.prototype.resetDirty=function resetDirty(){this._dirty=false};return PreloadFile2}(BaseFile);var NoSyncFile=function(PreloadFile2){function NoSyncFile2(_fs,_path,_flag,_stat,contents){PreloadFile2.call(this,_fs,_path,_flag,_stat,contents)}if(PreloadFile2)NoSyncFile2.__proto__=PreloadFile2;NoSyncFile2.prototype=Object.create(PreloadFile2&&PreloadFile2.prototype);NoSyncFile2.prototype.constructor=NoSyncFile2;NoSyncFile2.prototype.sync=function sync(cb){cb()};NoSyncFile2.prototype.syncSync=function syncSync(){};NoSyncFile2.prototype.close=function close(cb){cb()};NoSyncFile2.prototype.closeSync=function closeSync(){};return NoSyncFile2}(PreloadFile);var MirrorFile=function(PreloadFile$$1){function MirrorFile2(fs4,path$$1,flag,stat,data){PreloadFile$$1.call(this,fs4,path$$1,flag,stat,data)}if(PreloadFile$$1)MirrorFile2.__proto__=PreloadFile$$1;MirrorFile2.prototype=Object.create(PreloadFile$$1&&PreloadFile$$1.prototype);MirrorFile2.prototype.constructor=MirrorFile2;MirrorFile2.prototype.syncSync=function syncSync(){if(this.isDirty()){this._fs._syncSync(this);this.resetDirty()}};MirrorFile2.prototype.closeSync=function closeSync(){this.syncSync()};return MirrorFile2}(PreloadFile);var AsyncMirror=function(SynchronousFileSystem$$1){function AsyncMirror2(sync,async,deprecateMsg){if(deprecateMsg===void 0)deprecateMsg=true;SynchronousFileSystem$$1.call(this);this._queue=[];this._queueRunning=false;this._isInitialized=false;this._initializeCallbacks=[];this._sync=sync;this._async=async;if(!sync.supportsSynch()){throw new Error("The first argument to AsyncMirror needs to be a synchronous file system.")}deprecationMessage(deprecateMsg,AsyncMirror2.Name,{sync:"sync file system instance",async:"async file system instance"})}if(SynchronousFileSystem$$1)AsyncMirror2.__proto__=SynchronousFileSystem$$1;AsyncMirror2.prototype=Object.create(SynchronousFileSystem$$1&&SynchronousFileSystem$$1.prototype);AsyncMirror2.prototype.constructor=AsyncMirror2;AsyncMirror2.Create=function Create(opts,cb){try{var fs4=new AsyncMirror2(opts.sync,opts.async,false);fs4.initialize(function(e){if(e){cb(e)}else{cb(null,fs4)}},false)}catch(e){cb(e)}};AsyncMirror2.isAvailable=function isAvailable(){return true};AsyncMirror2.prototype.getName=function getName(){return AsyncMirror2.Name};AsyncMirror2.prototype._syncSync=function _syncSync(fd){this._sync.writeFileSync(fd.getPath(),fd.getBuffer(),null,FileFlag.getFileFlag("w"),fd.getStats().mode);this.enqueueOp({apiMethod:"writeFile",arguments:[fd.getPath(),fd.getBuffer(),null,fd.getFlag(),fd.getStats().mode]})};AsyncMirror2.prototype.initialize=function initialize3(userCb,deprecateMsg){var this$1=this;if(deprecateMsg===void 0)deprecateMsg=true;if(deprecateMsg){console.warn("[AsyncMirror] AsyncMirror.initialize() is deprecated and will be removed in the next major version. Please use 'AsyncMirror.Create({ sync: (sync file system instance), async: (async file system instance)}, cb)' to create and initialize AsyncMirror instances.")}var callbacks=this._initializeCallbacks;var end=function(e){this$1._isInitialized=!e;this$1._initializeCallbacks=[];callbacks.forEach(function(cb){return cb(e)})};if(!this._isInitialized){if(callbacks.push(userCb)===1){var copyDirectory=function(p,mode,cb){if(p!=="/"){this$1._sync.mkdirSync(p,mode)}this$1._async.readdir(p,function(err,files){var i2=0;function copyNextFile(err2){if(err2){cb(err2)}else if(i20){var op2=this$1._queue.shift(),args=op2.arguments;args.push(doNextOp);this$1._async[op2.apiMethod].apply(this$1._async,args)}else{this$1._queueRunning=false}};doNextOp()}};return AsyncMirror2}(SynchronousFileSystem);AsyncMirror.Name="AsyncMirror";AsyncMirror.Options={sync:{type:"object",description:"The synchronous file system to mirror the asynchronous file system to."},async:{type:"object",description:"The asynchronous file system to mirror."}};function apply(func,thisArg,args){switch(args.length){case 0:return func.call(thisArg);case 1:return func.call(thisArg,args[0]);case 2:return func.call(thisArg,args[0],args[1]);case 3:return func.call(thisArg,args[0],args[1],args[2])}return func.apply(thisArg,args)}var nativeMax=Math.max;function overRest$1(func,start,transform){start=nativeMax(start===void 0?func.length-1:start,0);return function(){var args=arguments,index=-1,length=nativeMax(args.length-start,0),array=Array(length);while(++index-1&&value%1==0&&value<=MAX_SAFE_INTEGER}function isArrayLike(value){return value!=null&&isLength(value.length)&&!isFunction(value)}var breakLoop={};function noop(){}function once(fn){return function(){if(fn===null){return}var callFn=fn;fn=null;callFn.apply(this,arguments)}}var iteratorSymbol=typeof Symbol==="function"&&Symbol.iterator;var getIterator=function(coll){return iteratorSymbol&&coll[iteratorSymbol]&&coll[iteratorSymbol]()};function baseTimes(n,iteratee){var index=-1,result=Array(n);while(++index-1&&value%1==0&&value++numRun){switch(error.status){case Dropbox.ApiError.SERVER_ERROR:case Dropbox.ApiError.NETWORK_ERROR:case Dropbox.ApiError.RATE_LIMITED:setTimeout(function(){performOp(interceptCb)},timeoutDuration*1e3);break;default:cb.apply(null,arguments);break}}else{cb.apply(null,arguments)}};performOp(interceptCb)};CachedDropboxClient.prototype.getCachedInfo=function getCachedInfo(p){return this._cache[p.toLowerCase()]};CachedDropboxClient.prototype.putCachedInfo=function putCachedInfo(p,cache){this._cache[p.toLowerCase()]=cache};CachedDropboxClient.prototype.deleteCachedInfo=function deleteCachedInfo(p){delete this._cache[p.toLowerCase()]};CachedDropboxClient.prototype.getCachedDirInfo=function getCachedDirInfo(p){var info=this.getCachedInfo(p);if(isDirInfo(info)){return info}else{return null}};CachedDropboxClient.prototype.getCachedFileInfo=function getCachedFileInfo(p){var info=this.getCachedInfo(p);if(isFileInfo(info)){return info}else{return null}};CachedDropboxClient.prototype.updateCachedDirInfo=function updateCachedDirInfo(p,stat,contents){if(contents===void 0)contents=null;var cachedInfo=this.getCachedInfo(p);if(stat.contentHash!==null&&(cachedInfo===void 0||cachedInfo.stat.contentHash!==stat.contentHash)){this.putCachedInfo(p,{stat,contents})}};CachedDropboxClient.prototype.updateCachedFileInfo=function updateCachedFileInfo(p,stat,contents){if(contents===void 0)contents=null;var cachedInfo=this.getCachedInfo(p);if(stat.versionTag!==null&&(cachedInfo===void 0||cachedInfo.stat.versionTag!==stat.versionTag)){this.putCachedInfo(p,{stat,contents})}};CachedDropboxClient.prototype.updateCachedInfo=function updateCachedInfo(p,stat,contents){if(contents===void 0)contents=null;if(stat.isFile&&isArrayBuffer(contents)){this.updateCachedFileInfo(p,stat,contents)}else if(stat.isFolder&&Array.isArray(contents)){this.updateCachedDirInfo(p,stat,contents)}};var DropboxFile=function(PreloadFile$$1){function DropboxFile2(_fs,_path,_flag,_stat,contents){PreloadFile$$1.call(this,_fs,_path,_flag,_stat,contents)}if(PreloadFile$$1)DropboxFile2.__proto__=PreloadFile$$1;DropboxFile2.prototype=Object.create(PreloadFile$$1&&PreloadFile$$1.prototype);DropboxFile2.prototype.constructor=DropboxFile2;DropboxFile2.prototype.sync=function sync(cb){var this$1=this;if(this.isDirty()){var buffer$$1=this.getBuffer(),arrayBuffer=buffer2ArrayBuffer(buffer$$1);this._fs._writeFileStrict(this.getPath(),arrayBuffer,function(e){if(!e){this$1.resetDirty()}cb(e)})}else{cb()}};DropboxFile2.prototype.close=function close(cb){this.sync(cb)};return DropboxFile2}(PreloadFile);var DropboxFileSystem=function(BaseFileSystem$$1){function DropboxFileSystem2(client,deprecateMsg){if(deprecateMsg===void 0)deprecateMsg=true;BaseFileSystem$$1.call(this);this._client=new CachedDropboxClient(client);deprecationMessage(deprecateMsg,DropboxFileSystem2.Name,{client:"authenticated dropbox client instance"});constructErrorCodeLookup()}if(BaseFileSystem$$1)DropboxFileSystem2.__proto__=BaseFileSystem$$1;DropboxFileSystem2.prototype=Object.create(BaseFileSystem$$1&&BaseFileSystem$$1.prototype);DropboxFileSystem2.prototype.constructor=DropboxFileSystem2;DropboxFileSystem2.Create=function Create(opts,cb){cb(null,new DropboxFileSystem2(opts.client,false))};DropboxFileSystem2.isAvailable=function isAvailable(){return typeof Dropbox!=="undefined"};DropboxFileSystem2.prototype.getName=function getName(){return DropboxFileSystem2.Name};DropboxFileSystem2.prototype.isReadOnly=function isReadOnly(){return false};DropboxFileSystem2.prototype.supportsSymlinks=function supportsSymlinks(){return false};DropboxFileSystem2.prototype.supportsProps=function supportsProps(){return false};DropboxFileSystem2.prototype.supportsSynch=function supportsSynch(){return false};DropboxFileSystem2.prototype.empty=function empty(mainCb){var this$1=this;this._client.readdir("/",function(error,files){if(error){mainCb(this$1.convert(error,"/"))}else{var deleteFile2=function(file,cb){var p=path.join("/",file);this$1._client.remove(p,function(err){cb(err?this$1.convert(err,p):null)})};var finished=function(err){if(err){mainCb(err)}else{mainCb()}};eachLimit(files,deleteFile2,finished)}})};DropboxFileSystem2.prototype.rename=function rename(oldPath,newPath,cb){var this$1=this;this._client.move(oldPath,newPath,function(error){if(error){this$1._client.stat(newPath,function(error2,stat){if(error2||stat.isFolder){var missingPath=error.response.error.indexOf(oldPath)>-1?oldPath:newPath;cb(this$1.convert(error,missingPath))}else{this$1._client.remove(newPath,function(error22){if(error22){cb(this$1.convert(error22,newPath))}else{this$1.rename(oldPath,newPath,cb)}})}})}else{cb()}})};DropboxFileSystem2.prototype.stat=function stat(path$$1,isLstat,cb){var this$1=this;this._client.stat(path$$1,function(error,stat2){if(error){cb(this$1.convert(error,path$$1))}else if(stat2&&stat2.isRemoved){cb(ApiError.FileError(ErrorCode.ENOENT,path$$1))}else{var stats=new Stats(this$1._statType(stat2),stat2.size);return cb(null,stats)}})};DropboxFileSystem2.prototype.open=function open(path$$1,flags,mode,cb){var this$1=this;this._client.readFile(path$$1,function(error,content,dbStat){if(error){if(flags.isReadable()){cb(this$1.convert(error,path$$1))}else{switch(error.status){case Dropbox.ApiError.NOT_FOUND:var ab=new ArrayBuffer(0);return this$1._writeFileStrict(path$$1,ab,function(error2,stat){if(error2){cb(error2)}else{var file2=this$1._makeFile(path$$1,flags,stat,arrayBuffer2Buffer(ab));cb(null,file2)}});default:return cb(this$1.convert(error,path$$1))}}}else{var buffer$$1;if(content===null){buffer$$1=emptyBuffer()}else{buffer$$1=arrayBuffer2Buffer(content)}var file=this$1._makeFile(path$$1,flags,dbStat,buffer$$1);return cb(null,file)}})};DropboxFileSystem2.prototype._writeFileStrict=function _writeFileStrict(p,data,cb){var this$1=this;var parent=path.dirname(p);this.stat(parent,false,function(error,stat){if(error){cb(ApiError.FileError(ErrorCode.ENOENT,parent))}else{this$1._client.writeFile(p,data,function(error2,stat2){if(error2){cb(this$1.convert(error2,p))}else{cb(null,stat2)}})}})};DropboxFileSystem2.prototype._statType=function _statType(stat){return stat.isFile?FileType.FILE:FileType.DIRECTORY};DropboxFileSystem2.prototype._makeFile=function _makeFile(path$$1,flag,stat,buffer$$1){var type=this._statType(stat);var stats=new Stats(type,stat.size);return new DropboxFile(this,path$$1,flag,stats,buffer$$1)};DropboxFileSystem2.prototype._remove=function _remove(path$$1,cb,isFile){var this$1=this;this._client.stat(path$$1,function(error,stat){if(error){cb(this$1.convert(error,path$$1))}else{if(stat.isFile&&!isFile){cb(ApiError.FileError(ErrorCode.ENOTDIR,path$$1))}else if(!stat.isFile&&isFile){cb(ApiError.FileError(ErrorCode.EISDIR,path$$1))}else{this$1._client.remove(path$$1,function(error2){if(error2){cb(this$1.convert(error2,path$$1))}else{cb(null)}})}}})};DropboxFileSystem2.prototype.unlink=function unlink(path$$1,cb){this._remove(path$$1,cb,true)};DropboxFileSystem2.prototype.rmdir=function rmdir(path$$1,cb){this._remove(path$$1,cb,false)};DropboxFileSystem2.prototype.mkdir=function mkdir(p,mode,cb){var this$1=this;var parent=path.dirname(p);this._client.stat(parent,function(error,stat){if(error){cb(this$1.convert(error,parent))}else{this$1._client.mkdir(p,function(error2){if(error2){cb(ApiError.FileError(ErrorCode.EEXIST,p))}else{cb(null)}})}})};DropboxFileSystem2.prototype.readdir=function readdir(path$$1,cb){var this$1=this;this._client.readdir(path$$1,function(error,files){if(error){return cb(this$1.convert(error))}else{return cb(null,files)}})};DropboxFileSystem2.prototype.convert=function convert(err,path$$1){if(path$$1===void 0)path$$1=null;var errorCode=errorCodeLookup[err.status];if(errorCode===void 0){errorCode=ErrorCode.EIO}if(!path$$1){return new ApiError(errorCode)}else{return ApiError.FileError(errorCode,path$$1)}};return DropboxFileSystem2}(BaseFileSystem);DropboxFileSystem.Name="Dropbox";DropboxFileSystem.Options={client:{type:"object",description:"An *authenticated* Dropbox client. Must be from the 0.10 JS SDK.",validator:function(opt,cb){if(opt.isAuthenticated&&opt.isAuthenticated()){cb()}else{cb(new ApiError(ErrorCode.EINVAL,"'client' option must be an authenticated Dropbox client from the v0.10 JS SDK."))}}}};function convertError(e,path$$1){if(path$$1===void 0)path$$1="";var errno=e.errno;var parent=e.node;var paths=[];while(parent){paths.unshift(parent.name);if(parent===parent.parent){break}parent=parent.parent}return new ApiError(errno,ErrorStrings[errno],paths.length>0?"/"+paths.join("/"):path$$1)}var EmscriptenFile=function(BaseFile$$1){function EmscriptenFile2(_fs,_FS,_path,_stream){BaseFile$$1.call(this);this._fs=_fs;this._FS=_FS;this._path=_path;this._stream=_stream}if(BaseFile$$1)EmscriptenFile2.__proto__=BaseFile$$1;EmscriptenFile2.prototype=Object.create(BaseFile$$1&&BaseFile$$1.prototype);EmscriptenFile2.prototype.constructor=EmscriptenFile2;EmscriptenFile2.prototype.getPos=function getPos(){return void 0};EmscriptenFile2.prototype.close=function close(cb){var err=null;try{this.closeSync()}catch(e){err=e}finally{cb(err)}};EmscriptenFile2.prototype.closeSync=function closeSync(){try{this._FS.close(this._stream)}catch(e){throw convertError(e,this._path)}};EmscriptenFile2.prototype.stat=function stat(cb){try{cb(null,this.statSync())}catch(e){cb(e)}};EmscriptenFile2.prototype.statSync=function statSync(){try{return this._fs.statSync(this._path,false)}catch(e){throw convertError(e,this._path)}};EmscriptenFile2.prototype.truncate=function truncate(len,cb){var err=null;try{this.truncateSync(len)}catch(e){err=e}finally{cb(err)}};EmscriptenFile2.prototype.truncateSync=function truncateSync(len){try{this._FS.ftruncate(this._stream.fd,len)}catch(e){throw convertError(e,this._path)}};EmscriptenFile2.prototype.write=function write(buffer$$1,offset,length,position,cb){try{cb(null,this.writeSync(buffer$$1,offset,length,position),buffer$$1)}catch(e){cb(e)}};EmscriptenFile2.prototype.writeSync=function writeSync(buffer$$1,offset,length,position){try{var u8=buffer2Uint8array(buffer$$1);var emPosition=position===null?void 0:position;return this._FS.write(this._stream,u8,offset,length,emPosition)}catch(e){throw convertError(e,this._path)}};EmscriptenFile2.prototype.read=function read(buffer$$1,offset,length,position,cb){try{cb(null,this.readSync(buffer$$1,offset,length,position),buffer$$1)}catch(e){cb(e)}};EmscriptenFile2.prototype.readSync=function readSync(buffer$$1,offset,length,position){try{var u8=buffer2Uint8array(buffer$$1);var emPosition=position===null?void 0:position;return this._FS.read(this._stream,u8,offset,length,emPosition)}catch(e){throw convertError(e,this._path)}};EmscriptenFile2.prototype.sync=function sync(cb){cb()};EmscriptenFile2.prototype.syncSync=function syncSync(){};EmscriptenFile2.prototype.chown=function chown(uid,gid,cb){var err=null;try{this.chownSync(uid,gid)}catch(e){err=e}finally{cb(err)}};EmscriptenFile2.prototype.chownSync=function chownSync(uid,gid){try{this._FS.fchown(this._stream.fd,uid,gid)}catch(e){throw convertError(e,this._path)}};EmscriptenFile2.prototype.chmod=function chmod(mode,cb){var err=null;try{this.chmodSync(mode)}catch(e){err=e}finally{cb(err)}};EmscriptenFile2.prototype.chmodSync=function chmodSync(mode){try{this._FS.fchmod(this._stream.fd,mode)}catch(e){throw convertError(e,this._path)}};EmscriptenFile2.prototype.utimes=function utimes(atime,mtime,cb){var err=null;try{this.utimesSync(atime,mtime)}catch(e){err=e}finally{cb(err)}};EmscriptenFile2.prototype.utimesSync=function utimesSync(atime,mtime){this._fs.utimesSync(this._path,atime,mtime)};return EmscriptenFile2}(BaseFile);var EmscriptenFileSystem=function(SynchronousFileSystem$$1){function EmscriptenFileSystem2(_FS){SynchronousFileSystem$$1.call(this);this._FS=_FS}if(SynchronousFileSystem$$1)EmscriptenFileSystem2.__proto__=SynchronousFileSystem$$1;EmscriptenFileSystem2.prototype=Object.create(SynchronousFileSystem$$1&&SynchronousFileSystem$$1.prototype);EmscriptenFileSystem2.prototype.constructor=EmscriptenFileSystem2;EmscriptenFileSystem2.Create=function Create(opts,cb){cb(null,new EmscriptenFileSystem2(opts.FS))};EmscriptenFileSystem2.isAvailable=function isAvailable(){return true};EmscriptenFileSystem2.prototype.getName=function getName(){return this._FS.DB_NAME()};EmscriptenFileSystem2.prototype.isReadOnly=function isReadOnly(){return false};EmscriptenFileSystem2.prototype.supportsLinks=function supportsLinks(){return true};EmscriptenFileSystem2.prototype.supportsProps=function supportsProps(){return true};EmscriptenFileSystem2.prototype.supportsSynch=function supportsSynch(){return true};EmscriptenFileSystem2.prototype.renameSync=function renameSync(oldPath,newPath){try{this._FS.rename(oldPath,newPath)}catch(e){if(e.errno===ErrorCode.ENOENT){throw convertError(e,this.existsSync(oldPath)?newPath:oldPath)}else{throw convertError(e)}}};EmscriptenFileSystem2.prototype.statSync=function statSync(p,isLstat){try{var stats=isLstat?this._FS.lstat(p):this._FS.stat(p);var itemType=this.modeToFileType(stats.mode);return new Stats(itemType,stats.size,stats.mode,stats.atime,stats.mtime,stats.ctime)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.openSync=function openSync(p,flag,mode){try{var stream=this._FS.open(p,flag.getFlagString(),mode);if(this._FS.isDir(stream.node.mode)){this._FS.close(stream);throw ApiError.EISDIR(p)}return new EmscriptenFile(this,this._FS,p,stream)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.unlinkSync=function unlinkSync(p){try{this._FS.unlink(p)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.rmdirSync=function rmdirSync(p){try{this._FS.rmdir(p)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.mkdirSync=function mkdirSync(p,mode){try{this._FS.mkdir(p,mode)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.readdirSync=function readdirSync(p){try{return this._FS.readdir(p).filter(function(p2){return p2!=="."&&p2!==".."})}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.truncateSync=function truncateSync(p,len){try{this._FS.truncate(p,len)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.readFileSync=function readFileSync(p,encoding,flag){try{var data=this._FS.readFile(p,{flags:flag.getFlagString()});var buff=uint8Array2Buffer(data);if(encoding){return buff.toString(encoding)}else{return buff}}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.writeFileSync=function writeFileSync(p,data,encoding,flag,mode){try{if(encoding){data=Buffer2.from(data,encoding)}var u8=buffer2Uint8array(data);this._FS.writeFile(p,u8,{flags:flag.getFlagString(),encoding:"binary"});this._FS.chmod(p,mode)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.chmodSync=function chmodSync(p,isLchmod,mode){try{isLchmod?this._FS.lchmod(p,mode):this._FS.chmod(p,mode)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.chownSync=function chownSync(p,isLchown,uid,gid){try{isLchown?this._FS.lchown(p,uid,gid):this._FS.chown(p,uid,gid)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.symlinkSync=function symlinkSync(srcpath,dstpath,type){try{this._FS.symlink(srcpath,dstpath)}catch(e){throw convertError(e)}};EmscriptenFileSystem2.prototype.readlinkSync=function readlinkSync(p){try{return this._FS.readlink(p)}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.utimesSync=function utimesSync(p,atime,mtime){try{this._FS.utime(p,atime.getTime(),mtime.getTime())}catch(e){throw convertError(e,p)}};EmscriptenFileSystem2.prototype.modeToFileType=function modeToFileType(mode){if(this._FS.isDir(mode)){return FileType.DIRECTORY}else if(this._FS.isFile(mode)){return FileType.FILE}else if(this._FS.isLink(mode)){return FileType.SYMLINK}else{throw ApiError.EPERM("Invalid mode: "+mode)}};return EmscriptenFileSystem2}(SynchronousFileSystem);EmscriptenFileSystem.Name="EmscriptenFileSystem";EmscriptenFileSystem.Options={FS:{type:"object",description:"The Emscripten file system to use (the `FS` variable)"}};var FolderAdapter=function(BaseFileSystem$$1){function FolderAdapter2(folder,wrapped){BaseFileSystem$$1.call(this);this._folder=folder;this._wrapped=wrapped}if(BaseFileSystem$$1)FolderAdapter2.__proto__=BaseFileSystem$$1;FolderAdapter2.prototype=Object.create(BaseFileSystem$$1&&BaseFileSystem$$1.prototype);FolderAdapter2.prototype.constructor=FolderAdapter2;FolderAdapter2.Create=function Create(opts,cb){cb(null,new FolderAdapter2(opts.folder,opts.wrapped))};FolderAdapter2.isAvailable=function isAvailable(){return true};FolderAdapter2.prototype.initialize=function initialize3(cb){var this$1=this;this._wrapped.exists(this._folder,function(exists2){if(exists2){cb()}else if(this$1._wrapped.isReadOnly()){cb(ApiError.ENOENT(this$1._folder))}else{this$1._wrapped.mkdir(this$1._folder,511,cb)}})};FolderAdapter2.prototype.getName=function getName(){return this._wrapped.getName()};FolderAdapter2.prototype.isReadOnly=function isReadOnly(){return this._wrapped.isReadOnly()};FolderAdapter2.prototype.supportsProps=function supportsProps(){return this._wrapped.supportsProps()};FolderAdapter2.prototype.supportsSynch=function supportsSynch(){return this._wrapped.supportsSynch()};FolderAdapter2.prototype.supportsLinks=function supportsLinks(){return false};return FolderAdapter2}(BaseFileSystem);FolderAdapter.Name="FolderAdapter";FolderAdapter.Options={folder:{type:"string",description:"The folder to use as the root directory"},wrapped:{type:"object",description:"The file system to wrap"}};function translateError(folder,e){if(e!==null&&typeof e==="object"){var err=e;var p=err.path;if(p){p="/"+path.relative(folder,p);err.message=err.message.replace(err.path,p);err.path=p}}return e}function wrapCallback(folder,cb){if(typeof cb==="function"){return function(err){if(arguments.length>0){arguments[0]=translateError(folder,err)}cb.apply(null,arguments)}}else{return cb}}function wrapFunction(name,wrapFirst,wrapSecond){if(name.slice(name.length-4)!=="Sync"){return function(){if(arguments.length>0){if(wrapFirst){arguments[0]=path.join(this._folder,arguments[0])}if(wrapSecond){arguments[1]=path.join(this._folder,arguments[1])}arguments[arguments.length-1]=wrapCallback(this._folder,arguments[arguments.length-1])}return this._wrapped[name].apply(this._wrapped,arguments)}}else{return function(){try{if(wrapFirst){arguments[0]=path.join(this._folder,arguments[0])}if(wrapSecond){arguments[1]=path.join(this._folder,arguments[1])}return this._wrapped[name].apply(this._wrapped,arguments)}catch(e){throw translateError(this._folder,e)}}}}["diskSpace","stat","statSync","open","openSync","unlink","unlinkSync","rmdir","rmdirSync","mkdir","mkdirSync","readdir","readdirSync","exists","existsSync","realpath","realpathSync","truncate","truncateSync","readFile","readFileSync","writeFile","writeFileSync","appendFile","appendFileSync","chmod","chmodSync","chown","chownSync","utimes","utimesSync","readlink","readlinkSync"].forEach(function(name){FolderAdapter.prototype[name]=wrapFunction(name,true,false)});["rename","renameSync","link","linkSync","symlink","symlinkSync"].forEach(function(name){FolderAdapter.prototype[name]=wrapFunction(name,true,true)});var toExport;if(typeof window!=="undefined"){toExport=window}else if(typeof self!=="undefined"){toExport=self}else{toExport=global}var global$1=toExport;function isDirectoryEntry(entry){return entry.isDirectory}var _getFS=global$1.webkitRequestFileSystem||global$1.requestFileSystem||null;function _requestQuota(type,size,success,errorCallback){if(typeof navigator["webkitPersistentStorage"]!=="undefined"){switch(type){case global$1.PERSISTENT:navigator.webkitPersistentStorage.requestQuota(size,success,errorCallback);break;case global$1.TEMPORARY:navigator.webkitTemporaryStorage.requestQuota(size,success,errorCallback);break;default:errorCallback(new TypeError("Invalid storage type: "+type));break}}else{global$1.webkitStorageInfo.requestQuota(type,size,success,errorCallback)}}function _toArray(list2){return Array.prototype.slice.call(list2||[],0)}function convertError$1(err,p,expectedDir){switch(err.name){case"PathExistsError":return ApiError.EEXIST(p);case"QuotaExceededError":return ApiError.FileError(ErrorCode.ENOSPC,p);case"NotFoundError":return ApiError.ENOENT(p);case"SecurityError":return ApiError.FileError(ErrorCode.EACCES,p);case"InvalidModificationError":return ApiError.FileError(ErrorCode.EPERM,p);case"TypeMismatchError":return ApiError.FileError(expectedDir?ErrorCode.ENOTDIR:ErrorCode.EISDIR,p);case"EncodingError":case"InvalidStateError":case"NoModificationAllowedError":default:return ApiError.FileError(ErrorCode.EINVAL,p)}}var HTML5FSFile=function(PreloadFile$$1){function HTML5FSFile2(fs4,entry,path$$1,flag,stat,contents){PreloadFile$$1.call(this,fs4,path$$1,flag,stat,contents);this._entry=entry}if(PreloadFile$$1)HTML5FSFile2.__proto__=PreloadFile$$1;HTML5FSFile2.prototype=Object.create(PreloadFile$$1&&PreloadFile$$1.prototype);HTML5FSFile2.prototype.constructor=HTML5FSFile2;HTML5FSFile2.prototype.sync=function sync(cb){var this$1=this;if(!this.isDirty()){return cb()}this._entry.createWriter(function(writer){var buffer$$1=this$1.getBuffer();var blob=new Blob([buffer2ArrayBuffer(buffer$$1)]);var length=blob.size;writer.onwriteend=function(err){writer.onwriteend=null;writer.onerror=null;writer.truncate(length);this$1.resetDirty();cb()};writer.onerror=function(err){cb(convertError$1(err,this$1.getPath(),false))};writer.write(blob)})};HTML5FSFile2.prototype.close=function close(cb){this.sync(cb)};return HTML5FSFile2}(PreloadFile);var HTML5FS=function(BaseFileSystem$$1){function HTML5FS2(size,type,deprecateMsg){if(size===void 0)size=5;if(type===void 0)type=global$1.PERSISTENT;if(deprecateMsg===void 0)deprecateMsg=true;BaseFileSystem$$1.call(this);this.size=1024*1024*size;this.type=type;deprecationMessage(deprecateMsg,HTML5FS2.Name,{size,type})}if(BaseFileSystem$$1)HTML5FS2.__proto__=BaseFileSystem$$1;HTML5FS2.prototype=Object.create(BaseFileSystem$$1&&BaseFileSystem$$1.prototype);HTML5FS2.prototype.constructor=HTML5FS2;HTML5FS2.Create=function Create(opts,cb){var fs4=new HTML5FS2(opts.size,opts.type,false);fs4.allocate(function(e){return e?cb(e):cb(null,fs4)},false)};HTML5FS2.isAvailable=function isAvailable(){return!!_getFS};HTML5FS2.prototype.getName=function getName(){return HTML5FS2.Name};HTML5FS2.prototype.isReadOnly=function isReadOnly(){return false};HTML5FS2.prototype.supportsSymlinks=function supportsSymlinks(){return false};HTML5FS2.prototype.supportsProps=function supportsProps(){return false};HTML5FS2.prototype.supportsSynch=function supportsSynch(){return false};HTML5FS2.prototype.allocate=function allocate(cb,deprecateMsg){var this$1=this;if(cb===void 0)cb=function(){};if(deprecateMsg===void 0)deprecateMsg=true;if(deprecateMsg){console.warn("[HTML5FS] HTML5FS.allocate() is deprecated and will be removed in the next major release. Please use 'HTML5FS.Create({type: "+this.type+", size: "+this.size+"}, cb)' to create and allocate HTML5FS instances.")}var success=function(fs4){this$1.fs=fs4;cb()};var error=function(err){cb(convertError$1(err,"/",true))};if(this.type===global$1.PERSISTENT){_requestQuota(this.type,this.size,function(granted){_getFS(this$1.type,granted,success,error)},error)}else{_getFS(this.type,this.size,success,error)}};HTML5FS2.prototype.empty=function empty(mainCb){this._readdir("/",function(err,entries){if(err){console.error("Failed to empty FS");mainCb(err)}else{var finished=function(er){if(err){console.error("Failed to empty FS");mainCb(err)}else{mainCb()}};var deleteEntry=function(entry,cb){var succ=function(){cb()};var error=function(err2){cb(convertError$1(err2,entry.fullPath,!entry.isDirectory))};if(isDirectoryEntry(entry)){entry.removeRecursively(succ,error)}else{entry.remove(succ,error)}};eachLimit(entries,deleteEntry,finished)}})};HTML5FS2.prototype.rename=function rename(oldPath,newPath,cb){var this$1=this;var semaphore=2;var successCount=0;var root2=this.fs.root;var currentPath=oldPath;var error=function(err){if(--semaphore<=0){cb(convertError$1(err,currentPath,false))}};var success=function(file){if(++successCount===2){return cb(new ApiError(ErrorCode.EINVAL,"Something was identified as both a file and a directory. This should never happen."))}if(oldPath===newPath){return cb()}currentPath=path.dirname(newPath);root2.getDirectory(currentPath,{},function(parentDir){currentPath=path.basename(newPath);file.moveTo(parentDir,currentPath,function(entry){cb()},function(err){if(file.isDirectory){currentPath=newPath;this$1.unlink(newPath,function(e){if(e){error(err)}else{this$1.rename(oldPath,newPath,cb)}})}else{error(err)}})},error)};root2.getFile(oldPath,{},success,error);root2.getDirectory(oldPath,{},success,error)};HTML5FS2.prototype.stat=function stat(path$$1,isLstat,cb){var this$1=this;var opts={create:false};var loadAsFile=function(entry){var fileFromEntry=function(file){var stat2=new Stats(FileType.FILE,file.size);cb(null,stat2)};entry.file(fileFromEntry,failedToLoad)};var loadAsDir=function(dir$$1){var size=4096;var stat2=new Stats(FileType.DIRECTORY,size);cb(null,stat2)};var failedToLoad=function(err){cb(convertError$1(err,path$$1,false))};var failedToLoadAsFile=function(){this$1.fs.root.getDirectory(path$$1,opts,loadAsDir,failedToLoad)};this.fs.root.getFile(path$$1,opts,loadAsFile,failedToLoadAsFile)};HTML5FS2.prototype.open=function open(p,flags,mode,cb){var this$1=this;var error=function(err){if(err.name==="InvalidModificationError"&&flags.isExclusive()){cb(ApiError.EEXIST(p))}else{cb(convertError$1(err,p,false))}};this.fs.root.getFile(p,{create:flags.pathNotExistsAction()===ActionType.CREATE_FILE,exclusive:flags.isExclusive()},function(entry){entry.file(function(file){var reader=new FileReader;reader.onloadend=function(event){var bfsFile=this$1._makeFile(p,entry,flags,file,reader.result);cb(null,bfsFile)};reader.onerror=function(ev){error(reader.error)};reader.readAsArrayBuffer(file)},error)},error)};HTML5FS2.prototype.unlink=function unlink(path$$1,cb){this._remove(path$$1,cb,true)};HTML5FS2.prototype.rmdir=function rmdir(path$$1,cb){var this$1=this;this.readdir(path$$1,function(e,files){if(e){cb(e)}else if(files.length>0){cb(ApiError.ENOTEMPTY(path$$1))}else{this$1._remove(path$$1,cb,false)}})};HTML5FS2.prototype.mkdir=function mkdir(path$$1,mode,cb){var opts={create:true,exclusive:true};var success=function(dir$$1){cb()};var error=function(err){cb(convertError$1(err,path$$1,true))};this.fs.root.getDirectory(path$$1,opts,success,error)};HTML5FS2.prototype.readdir=function readdir(path$$1,cb){this._readdir(path$$1,function(e,entries){if(entries){var rv=[];for(var i2=0,list2=entries;i20){throw ApiError.ENOTEMPTY(p)}else{this.removeEntry(p,true)}};SyncKeyValueFileSystem2.prototype.mkdirSync=function mkdirSync(p,mode){var tx=this.store.beginTransaction("readwrite"),data=Buffer2.from("{}");this.commitNewFile(tx,p,FileType.DIRECTORY,mode,data)};SyncKeyValueFileSystem2.prototype.readdirSync=function readdirSync(p){var tx=this.store.beginTransaction("readonly");return Object.keys(this.getDirListing(tx,p,this.findINode(tx,p)))};SyncKeyValueFileSystem2.prototype._syncSync=function _syncSync(p,data,stats){var tx=this.store.beginTransaction("readwrite"),fileInodeId=this._findINode(tx,path.dirname(p),path.basename(p)),fileInode=this.getINode(tx,p,fileInodeId),inodeChanged=fileInode.update(stats);try{tx.put(fileInode.id,data,true);if(inodeChanged){tx.put(fileInodeId,fileInode.toBuffer(),true)}}catch(e){tx.abort();throw e}tx.commit()};SyncKeyValueFileSystem2.prototype.makeRootDirectory=function makeRootDirectory(){var tx=this.store.beginTransaction("readwrite");if(tx.get(ROOT_NODE_ID)===void 0){var currTime=new Date().getTime(),dirInode=new Inode(GenerateRandomID(),4096,511|FileType.DIRECTORY,currTime,currTime,currTime);tx.put(dirInode.id,getEmptyDirNode(),false);tx.put(ROOT_NODE_ID,dirInode.toBuffer(),false);tx.commit()}};SyncKeyValueFileSystem2.prototype._findINode=function _findINode(tx,parent,filename){var this$1=this;var readDirectory=function(inode){var dirList=this$1.getDirListing(tx,parent,inode);if(dirList[filename]){return dirList[filename]}else{throw ApiError.ENOENT(path.resolve(parent,filename))}};if(parent==="/"){if(filename===""){return ROOT_NODE_ID}else{return readDirectory(this.getINode(tx,parent,ROOT_NODE_ID))}}else{return readDirectory(this.getINode(tx,parent+path.sep+filename,this._findINode(tx,path.dirname(parent),path.basename(parent))))}};SyncKeyValueFileSystem2.prototype.findINode=function findINode(tx,p){return this.getINode(tx,p,this._findINode(tx,path.dirname(p),path.basename(p)))};SyncKeyValueFileSystem2.prototype.getINode=function getINode(tx,p,id){var inode=tx.get(id);if(inode===void 0){throw ApiError.ENOENT(p)}return Inode.fromBuffer(inode)};SyncKeyValueFileSystem2.prototype.getDirListing=function getDirListing(tx,p,inode){if(!inode.isDirectory()){throw ApiError.ENOTDIR(p)}var data=tx.get(inode.id);if(data===void 0){throw ApiError.ENOENT(p)}return JSON.parse(data.toString())};SyncKeyValueFileSystem2.prototype.addNewNode=function addNewNode(tx,data){var retries=0;var currId;while(retries<5){try{currId=GenerateRandomID();tx.put(currId,data,false);return currId}catch(e){}}throw new ApiError(ErrorCode.EIO,"Unable to commit data to key-value store.")};SyncKeyValueFileSystem2.prototype.commitNewFile=function commitNewFile(tx,p,type,mode,data){var parentDir=path.dirname(p),fname=path.basename(p),parentNode=this.findINode(tx,parentDir),dirListing=this.getDirListing(tx,parentDir,parentNode),currTime=new Date().getTime();if(p==="/"){throw ApiError.EEXIST(p)}if(dirListing[fname]){throw ApiError.EEXIST(p)}var fileNode;try{var dataId=this.addNewNode(tx,data);fileNode=new Inode(dataId,data.length,mode|type,currTime,currTime,currTime);var fileNodeId=this.addNewNode(tx,fileNode.toBuffer());dirListing[fname]=fileNodeId;tx.put(parentNode.id,Buffer2.from(JSON.stringify(dirListing)),true)}catch(e){tx.abort();throw e}tx.commit();return fileNode};SyncKeyValueFileSystem2.prototype.removeEntry=function removeEntry(p,isDir){var tx=this.store.beginTransaction("readwrite"),parent=path.dirname(p),parentNode=this.findINode(tx,parent),parentListing=this.getDirListing(tx,parent,parentNode),fileName=path.basename(p);if(!parentListing[fileName]){throw ApiError.ENOENT(p)}var fileNodeId=parentListing[fileName];delete parentListing[fileName];var fileNode=this.getINode(tx,p,fileNodeId);if(!isDir&&fileNode.isDirectory()){throw ApiError.EISDIR(p)}else if(isDir&&!fileNode.isDirectory()){throw ApiError.ENOTDIR(p)}try{tx.del(fileNode.id);tx.del(fileNodeId);tx.put(parentNode.id,Buffer2.from(JSON.stringify(parentListing)),true)}catch(e){tx.abort();throw e}tx.commit()};return SyncKeyValueFileSystem2}(SynchronousFileSystem);var AsyncKeyValueFile=function(PreloadFile$$1){function AsyncKeyValueFile2(_fs,_path,_flag,_stat,contents){PreloadFile$$1.call(this,_fs,_path,_flag,_stat,contents)}if(PreloadFile$$1)AsyncKeyValueFile2.__proto__=PreloadFile$$1;AsyncKeyValueFile2.prototype=Object.create(PreloadFile$$1&&PreloadFile$$1.prototype);AsyncKeyValueFile2.prototype.constructor=AsyncKeyValueFile2;AsyncKeyValueFile2.prototype.sync=function sync(cb){var this$1=this;if(this.isDirty()){this._fs._sync(this.getPath(),this.getBuffer(),this.getStats(),function(e){if(!e){this$1.resetDirty()}cb(e)})}else{cb()}};AsyncKeyValueFile2.prototype.close=function close(cb){this.sync(cb)};return AsyncKeyValueFile2}(PreloadFile);var AsyncKeyValueFileSystem=function(BaseFileSystem$$1){function AsyncKeyValueFileSystem2(){BaseFileSystem$$1.apply(this,arguments)}if(BaseFileSystem$$1)AsyncKeyValueFileSystem2.__proto__=BaseFileSystem$$1;AsyncKeyValueFileSystem2.prototype=Object.create(BaseFileSystem$$1&&BaseFileSystem$$1.prototype);AsyncKeyValueFileSystem2.prototype.constructor=AsyncKeyValueFileSystem2;AsyncKeyValueFileSystem2.isAvailable=function isAvailable(){return true};AsyncKeyValueFileSystem2.prototype.init=function init(store,cb){this.store=store;this.makeRootDirectory(cb)};AsyncKeyValueFileSystem2.prototype.getName=function getName(){return this.store.name()};AsyncKeyValueFileSystem2.prototype.isReadOnly=function isReadOnly(){return false};AsyncKeyValueFileSystem2.prototype.supportsSymlinks=function supportsSymlinks(){return false};AsyncKeyValueFileSystem2.prototype.supportsProps=function supportsProps(){return false};AsyncKeyValueFileSystem2.prototype.supportsSynch=function supportsSynch(){return false};AsyncKeyValueFileSystem2.prototype.empty=function empty(cb){var this$1=this;this.store.clear(function(e){if(noError(e,cb)){this$1.makeRootDirectory(cb)}})};AsyncKeyValueFileSystem2.prototype.rename=function rename(oldPath,newPath,cb){var this$1=this;var tx=this.store.beginTransaction("readwrite");var oldParent=path.dirname(oldPath),oldName=path.basename(oldPath);var newParent=path.dirname(newPath),newName=path.basename(newPath);var inodes={};var lists={};var errorOccurred=false;if((newParent+"/").indexOf(oldPath+"/")===0){return cb(new ApiError(ErrorCode.EBUSY,oldParent))}var theOleSwitcharoo=function(){if(errorOccurred||!lists.hasOwnProperty(oldParent)||!lists.hasOwnProperty(newParent)){return}var oldParentList=lists[oldParent],oldParentINode=inodes[oldParent],newParentList=lists[newParent],newParentINode=inodes[newParent];if(!oldParentList[oldName]){cb(ApiError.ENOENT(oldPath))}else{var fileId=oldParentList[oldName];delete oldParentList[oldName];var completeRename=function(){newParentList[newName]=fileId;tx.put(oldParentINode.id,Buffer2.from(JSON.stringify(oldParentList)),true,function(e){if(noErrorTx(e,tx,cb)){if(oldParent===newParent){tx.commit(cb)}else{tx.put(newParentINode.id,Buffer2.from(JSON.stringify(newParentList)),true,function(e2){if(noErrorTx(e2,tx,cb)){tx.commit(cb)}})}}})};if(newParentList[newName]){this$1.getINode(tx,newPath,newParentList[newName],function(e,inode){if(noErrorTx(e,tx,cb)){if(inode.isFile()){tx.del(inode.id,function(e2){if(noErrorTx(e2,tx,cb)){tx.del(newParentList[newName],function(e3){if(noErrorTx(e3,tx,cb)){completeRename()}})}})}else{tx.abort(function(e2){cb(ApiError.EPERM(newPath))})}}})}else{completeRename()}}};var processInodeAndListings=function(p){this$1.findINodeAndDirListing(tx,p,function(e,node,dirList){if(e){if(!errorOccurred){errorOccurred=true;tx.abort(function(){cb(e)})}}else{inodes[p]=node;lists[p]=dirList;theOleSwitcharoo()}})};processInodeAndListings(oldParent);if(oldParent!==newParent){processInodeAndListings(newParent)}};AsyncKeyValueFileSystem2.prototype.stat=function stat(p,isLstat,cb){var tx=this.store.beginTransaction("readonly");this.findINode(tx,p,function(e,inode){if(noError(e,cb)){cb(null,inode.toStats())}})};AsyncKeyValueFileSystem2.prototype.createFile=function createFile(p,flag,mode,cb){var this$1=this;var tx=this.store.beginTransaction("readwrite"),data=emptyBuffer();this.commitNewFile(tx,p,FileType.FILE,mode,data,function(e,newFile){if(noError(e,cb)){cb(null,new AsyncKeyValueFile(this$1,p,flag,newFile.toStats(),data))}})};AsyncKeyValueFileSystem2.prototype.openFile=function openFile(p,flag,cb){var this$1=this;var tx=this.store.beginTransaction("readonly");this.findINode(tx,p,function(e,inode){if(noError(e,cb)){tx.get(inode.id,function(e2,data){if(noError(e2,cb)){if(data===void 0){cb(ApiError.ENOENT(p))}else{cb(null,new AsyncKeyValueFile(this$1,p,flag,inode.toStats(),data))}}})}})};AsyncKeyValueFileSystem2.prototype.unlink=function unlink(p,cb){this.removeEntry(p,false,cb)};AsyncKeyValueFileSystem2.prototype.rmdir=function rmdir(p,cb){var this$1=this;this.readdir(p,function(err,files){if(err){cb(err)}else if(files.length>0){cb(ApiError.ENOTEMPTY(p))}else{this$1.removeEntry(p,true,cb)}})};AsyncKeyValueFileSystem2.prototype.mkdir=function mkdir(p,mode,cb){var tx=this.store.beginTransaction("readwrite"),data=Buffer2.from("{}");this.commitNewFile(tx,p,FileType.DIRECTORY,mode,data,cb)};AsyncKeyValueFileSystem2.prototype.readdir=function readdir(p,cb){var this$1=this;var tx=this.store.beginTransaction("readonly");this.findINode(tx,p,function(e,inode){if(noError(e,cb)){this$1.getDirListing(tx,p,inode,function(e2,dirListing){if(noError(e2,cb)){cb(null,Object.keys(dirListing))}})}})};AsyncKeyValueFileSystem2.prototype._sync=function _sync(p,data,stats,cb){var this$1=this;var tx=this.store.beginTransaction("readwrite");this._findINode(tx,path.dirname(p),path.basename(p),function(e,fileInodeId){if(noErrorTx(e,tx,cb)){this$1.getINode(tx,p,fileInodeId,function(e2,fileInode){if(noErrorTx(e2,tx,cb)){var inodeChanged=fileInode.update(stats);tx.put(fileInode.id,data,true,function(e3){if(noErrorTx(e3,tx,cb)){if(inodeChanged){tx.put(fileInodeId,fileInode.toBuffer(),true,function(e4){if(noErrorTx(e4,tx,cb)){tx.commit(cb)}})}else{tx.commit(cb)}}})}})}})};AsyncKeyValueFileSystem2.prototype.makeRootDirectory=function makeRootDirectory(cb){var tx=this.store.beginTransaction("readwrite");tx.get(ROOT_NODE_ID,function(e,data){if(e||data===void 0){var currTime=new Date().getTime(),dirInode=new Inode(GenerateRandomID(),4096,511|FileType.DIRECTORY,currTime,currTime,currTime);tx.put(dirInode.id,getEmptyDirNode(),false,function(e2){if(noErrorTx(e2,tx,cb)){tx.put(ROOT_NODE_ID,dirInode.toBuffer(),false,function(e3){if(e3){tx.abort(function(){cb(e3)})}else{tx.commit(cb)}})}})}else{tx.commit(cb)}})};AsyncKeyValueFileSystem2.prototype._findINode=function _findINode(tx,parent,filename,cb){var this$1=this;var handleDirectoryListings=function(e,inode,dirList){if(e){cb(e)}else if(dirList[filename]){cb(null,dirList[filename])}else{cb(ApiError.ENOENT(path.resolve(parent,filename)))}};if(parent==="/"){if(filename===""){cb(null,ROOT_NODE_ID)}else{this.getINode(tx,parent,ROOT_NODE_ID,function(e,inode){if(noError(e,cb)){this$1.getDirListing(tx,parent,inode,function(e2,dirList){handleDirectoryListings(e2,inode,dirList)})}})}}else{this.findINodeAndDirListing(tx,parent,handleDirectoryListings)}};AsyncKeyValueFileSystem2.prototype.findINode=function findINode(tx,p,cb){var this$1=this;this._findINode(tx,path.dirname(p),path.basename(p),function(e,id){if(noError(e,cb)){this$1.getINode(tx,p,id,cb)}})};AsyncKeyValueFileSystem2.prototype.getINode=function getINode(tx,p,id,cb){tx.get(id,function(e,data){if(noError(e,cb)){if(data===void 0){cb(ApiError.ENOENT(p))}else{cb(null,Inode.fromBuffer(data))}}})};AsyncKeyValueFileSystem2.prototype.getDirListing=function getDirListing(tx,p,inode,cb){if(!inode.isDirectory()){cb(ApiError.ENOTDIR(p))}else{tx.get(inode.id,function(e,data){if(noError(e,cb)){try{cb(null,JSON.parse(data.toString()))}catch(e2){cb(ApiError.ENOENT(p))}}})}};AsyncKeyValueFileSystem2.prototype.findINodeAndDirListing=function findINodeAndDirListing(tx,p,cb){var this$1=this;this.findINode(tx,p,function(e,inode){if(noError(e,cb)){this$1.getDirListing(tx,p,inode,function(e2,listing){if(noError(e2,cb)){cb(null,inode,listing)}})}})};AsyncKeyValueFileSystem2.prototype.addNewNode=function addNewNode(tx,data,cb){var retries=0,currId;var reroll=function(){if(++retries===5){cb(new ApiError(ErrorCode.EIO,"Unable to commit data to key-value store."))}else{currId=GenerateRandomID();tx.put(currId,data,false,function(e,committed){if(e||!committed){reroll()}else{cb(null,currId)}})}};reroll()};AsyncKeyValueFileSystem2.prototype.commitNewFile=function commitNewFile(tx,p,type,mode,data,cb){var this$1=this;var parentDir=path.dirname(p),fname=path.basename(p),currTime=new Date().getTime();if(p==="/"){return cb(ApiError.EEXIST(p))}this.findINodeAndDirListing(tx,parentDir,function(e,parentNode,dirListing){if(noErrorTx(e,tx,cb)){if(dirListing[fname]){tx.abort(function(){cb(ApiError.EEXIST(p))})}else{this$1.addNewNode(tx,data,function(e2,dataId){if(noErrorTx(e2,tx,cb)){var fileInode=new Inode(dataId,data.length,mode|type,currTime,currTime,currTime);this$1.addNewNode(tx,fileInode.toBuffer(),function(e3,fileInodeId){if(noErrorTx(e3,tx,cb)){dirListing[fname]=fileInodeId;tx.put(parentNode.id,Buffer2.from(JSON.stringify(dirListing)),true,function(e4){if(noErrorTx(e4,tx,cb)){tx.commit(function(e5){if(noErrorTx(e5,tx,cb)){cb(null,fileInode)}})}})}})}})}}})};AsyncKeyValueFileSystem2.prototype.removeEntry=function removeEntry(p,isDir,cb){var this$1=this;var tx=this.store.beginTransaction("readwrite"),parent=path.dirname(p),fileName=path.basename(p);this.findINodeAndDirListing(tx,parent,function(e,parentNode,parentListing){if(noErrorTx(e,tx,cb)){if(!parentListing[fileName]){tx.abort(function(){cb(ApiError.ENOENT(p))})}else{var fileNodeId=parentListing[fileName];delete parentListing[fileName];this$1.getINode(tx,p,fileNodeId,function(e2,fileNode){if(noErrorTx(e2,tx,cb)){if(!isDir&&fileNode.isDirectory()){tx.abort(function(){cb(ApiError.EISDIR(p))})}else if(isDir&&!fileNode.isDirectory()){tx.abort(function(){cb(ApiError.ENOTDIR(p))})}else{tx.del(fileNode.id,function(e3){if(noErrorTx(e3,tx,cb)){tx.del(fileNodeId,function(e4){if(noErrorTx(e4,tx,cb)){tx.put(parentNode.id,Buffer2.from(JSON.stringify(parentListing)),true,function(e5){if(noErrorTx(e5,tx,cb)){tx.commit(cb)}})}})}})}}})}}})};return AsyncKeyValueFileSystem2}(BaseFileSystem);var InMemoryStore=function InMemoryStore2(){this.store={}};InMemoryStore.prototype.name=function name(){return InMemoryFileSystem.Name};InMemoryStore.prototype.clear=function clear(){this.store={}};InMemoryStore.prototype.beginTransaction=function beginTransaction(type){return new SimpleSyncRWTransaction(this)};InMemoryStore.prototype.get=function get(key){return this.store[key]};InMemoryStore.prototype.put=function put(key,data,overwrite){if(!overwrite&&this.store.hasOwnProperty(key)){return false}this.store[key]=data;return true};InMemoryStore.prototype.del=function del(key){delete this.store[key]};var InMemoryFileSystem=function(SyncKeyValueFileSystem$$1){function InMemoryFileSystem2(){SyncKeyValueFileSystem$$1.call(this,{store:new InMemoryStore})}if(SyncKeyValueFileSystem$$1)InMemoryFileSystem2.__proto__=SyncKeyValueFileSystem$$1;InMemoryFileSystem2.prototype=Object.create(SyncKeyValueFileSystem$$1&&SyncKeyValueFileSystem$$1.prototype);InMemoryFileSystem2.prototype.constructor=InMemoryFileSystem2;InMemoryFileSystem2.Create=function Create(options,cb){cb(null,new InMemoryFileSystem2)};return InMemoryFileSystem2}(SyncKeyValueFileSystem);InMemoryFileSystem.Name="InMemory";InMemoryFileSystem.Options={};var indexedDB=global$1.indexedDB||global$1.mozIndexedDB||global$1.webkitIndexedDB||global$1.msIndexedDB;function convertError$2(e,message){if(message===void 0)message=e.toString();switch(e.name){case"NotFoundError":return new ApiError(ErrorCode.ENOENT,message);case"QuotaExceededError":return new ApiError(ErrorCode.ENOSPC,message);default:return new ApiError(ErrorCode.EIO,message)}}function onErrorHandler(cb,code,message){if(code===void 0)code=ErrorCode.EIO;if(message===void 0)message=null;return function(e){e.preventDefault();cb(new ApiError(code,message!==null?message:void 0))}}var IndexedDBROTransaction=function IndexedDBROTransaction2(tx,store){this.tx=tx;this.store=store};IndexedDBROTransaction.prototype.get=function get(key,cb){try{var r=this.store.get(key);r.onerror=onErrorHandler(cb);r.onsuccess=function(event){var result=event.target.result;if(result===void 0){cb(null,result)}else{cb(null,arrayBuffer2Buffer(result))}}}catch(e){cb(convertError$2(e))}};var IndexedDBRWTransaction=function(IndexedDBROTransaction2){function IndexedDBRWTransaction2(tx,store){IndexedDBROTransaction2.call(this,tx,store)}if(IndexedDBROTransaction2)IndexedDBRWTransaction2.__proto__=IndexedDBROTransaction2;IndexedDBRWTransaction2.prototype=Object.create(IndexedDBROTransaction2&&IndexedDBROTransaction2.prototype);IndexedDBRWTransaction2.prototype.constructor=IndexedDBRWTransaction2;IndexedDBRWTransaction2.prototype.put=function put(key,data,overwrite,cb){try{var arraybuffer=buffer2ArrayBuffer(data);var r;if(overwrite){r=this.store.put(arraybuffer,key)}else{r=this.store.add(arraybuffer,key)}r.onerror=onErrorHandler(cb);r.onsuccess=function(event){cb(null,true)}}catch(e){cb(convertError$2(e))}};IndexedDBRWTransaction2.prototype.del=function del(key,cb){try{var r=this.store["delete"](key);r.onerror=onErrorHandler(cb);r.onsuccess=function(event){cb()}}catch(e){cb(convertError$2(e))}};IndexedDBRWTransaction2.prototype.commit=function commit(cb){setTimeout(cb,0)};IndexedDBRWTransaction2.prototype.abort=function abort(cb){var _e=null;try{this.tx.abort()}catch(e){_e=convertError$2(e)}finally{cb(_e)}};return IndexedDBRWTransaction2}(IndexedDBROTransaction);var IndexedDBStore=function IndexedDBStore2(cb,storeName){var this$1=this;if(storeName===void 0)storeName="browserfs";this.storeName=storeName;var openReq=indexedDB.open(this.storeName,1);openReq.onupgradeneeded=function(event){var db=event.target.result;if(db.objectStoreNames.contains(this$1.storeName)){db.deleteObjectStore(this$1.storeName)}db.createObjectStore(this$1.storeName)};openReq.onsuccess=function(event){this$1.db=event.target.result;cb(null,this$1)};openReq.onerror=onErrorHandler(cb,ErrorCode.EACCES)};IndexedDBStore.prototype.name=function name(){return IndexedDBFileSystem.Name+" - "+this.storeName};IndexedDBStore.prototype.clear=function clear(cb){try{var tx=this.db.transaction(this.storeName,"readwrite"),objectStore=tx.objectStore(this.storeName),r=objectStore.clear();r.onsuccess=function(event){setTimeout(cb,0)};r.onerror=onErrorHandler(cb)}catch(e){cb(convertError$2(e))}};IndexedDBStore.prototype.beginTransaction=function beginTransaction(type){if(type===void 0)type="readonly";var tx=this.db.transaction(this.storeName,type),objectStore=tx.objectStore(this.storeName);if(type==="readwrite"){return new IndexedDBRWTransaction(tx,objectStore)}else if(type==="readonly"){return new IndexedDBROTransaction(tx,objectStore)}else{throw new ApiError(ErrorCode.EINVAL,"Invalid transaction type.")}};var IndexedDBFileSystem=function(AsyncKeyValueFileSystem$$1){function IndexedDBFileSystem2(cb,storeName,deprecateMsg){var this$1=this;if(deprecateMsg===void 0)deprecateMsg=true;AsyncKeyValueFileSystem$$1.call(this);this.store=new IndexedDBStore(function(e){if(e){cb(e)}else{this$1.init(this$1.store,function(e2){cb(e2,this$1)})}},storeName);deprecationMessage(deprecateMsg,IndexedDBFileSystem2.Name,{storeName})}if(AsyncKeyValueFileSystem$$1)IndexedDBFileSystem2.__proto__=AsyncKeyValueFileSystem$$1;IndexedDBFileSystem2.prototype=Object.create(AsyncKeyValueFileSystem$$1&&AsyncKeyValueFileSystem$$1.prototype);IndexedDBFileSystem2.prototype.constructor=IndexedDBFileSystem2;IndexedDBFileSystem2.Create=function Create(opts,cb){new IndexedDBFileSystem2(cb,opts.storeName,false)};IndexedDBFileSystem2.isAvailable=function isAvailable(){try{return typeof indexedDB!=="undefined"&&null!==indexedDB.open("__browserfs_test__")}catch(e){return false}};return IndexedDBFileSystem2}(AsyncKeyValueFileSystem);IndexedDBFileSystem.Name="IndexedDB";IndexedDBFileSystem.Options={storeName:{type:"string",optional:true,description:"The name of this file system. You can have multiple IndexedDB file systems operating at once, but each must have a different name."}};var supportsBinaryString=false;var binaryEncoding;try{global$1.localStorage.setItem("__test__",String.fromCharCode(55296));supportsBinaryString=global$1.localStorage.getItem("__test__")===String.fromCharCode(55296)}catch(e){supportsBinaryString=false}binaryEncoding=supportsBinaryString?"binary_string":"binary_string_ie";if(!Buffer2.isEncoding(binaryEncoding)){binaryEncoding="base64"}var LocalStorageStore=function LocalStorageStore2(){};LocalStorageStore.prototype.name=function name(){return LocalStorageFileSystem.Name};LocalStorageStore.prototype.clear=function clear(){global$1.localStorage.clear()};LocalStorageStore.prototype.beginTransaction=function beginTransaction(type){return new SimpleSyncRWTransaction(this)};LocalStorageStore.prototype.get=function get(key){try{var data=global$1.localStorage.getItem(key);if(data!==null){return Buffer2.from(data,binaryEncoding)}}catch(e){}return void 0};LocalStorageStore.prototype.put=function put(key,data,overwrite){try{if(!overwrite&&global$1.localStorage.getItem(key)!==null){return false}global$1.localStorage.setItem(key,data.toString(binaryEncoding));return true}catch(e){throw new ApiError(ErrorCode.ENOSPC,"LocalStorage is full.")}};LocalStorageStore.prototype.del=function del(key){try{global$1.localStorage.removeItem(key)}catch(e){throw new ApiError(ErrorCode.EIO,"Unable to delete key "+key+": "+e)}};var LocalStorageFileSystem=function(SyncKeyValueFileSystem$$1){function LocalStorageFileSystem2(){SyncKeyValueFileSystem$$1.call(this,{store:new LocalStorageStore})}if(SyncKeyValueFileSystem$$1)LocalStorageFileSystem2.__proto__=SyncKeyValueFileSystem$$1;LocalStorageFileSystem2.prototype=Object.create(SyncKeyValueFileSystem$$1&&SyncKeyValueFileSystem$$1.prototype);LocalStorageFileSystem2.prototype.constructor=LocalStorageFileSystem2;LocalStorageFileSystem2.Create=function Create(options,cb){cb(null,new LocalStorageFileSystem2)};LocalStorageFileSystem2.isAvailable=function isAvailable(){return typeof global$1.localStorage!=="undefined"};return LocalStorageFileSystem2}(SyncKeyValueFileSystem);LocalStorageFileSystem.Name="LocalStorage";LocalStorageFileSystem.Options={};var MountableFileSystem=function(BaseFileSystem$$1){function MountableFileSystem2(){BaseFileSystem$$1.call(this);this.mountList=[];this.mntMap={};this.rootFs=new InMemoryFileSystem}if(BaseFileSystem$$1)MountableFileSystem2.__proto__=BaseFileSystem$$1;MountableFileSystem2.prototype=Object.create(BaseFileSystem$$1&&BaseFileSystem$$1.prototype);MountableFileSystem2.prototype.constructor=MountableFileSystem2;MountableFileSystem2.Create=function Create(opts,cb){var fs4=new MountableFileSystem2;Object.keys(opts).forEach(function(mountPoint){fs4.mount(mountPoint,opts[mountPoint])});cb(null,fs4)};MountableFileSystem2.isAvailable=function isAvailable(){return true};MountableFileSystem2.prototype.mount=function mount(mountPoint,fs4){if(mountPoint[0]!=="/"){mountPoint="/"+mountPoint}mountPoint=path.resolve(mountPoint);if(this.mntMap[mountPoint]){throw new ApiError(ErrorCode.EINVAL,"Mount point "+mountPoint+" is already taken.")}mkdirpSync(mountPoint,511,this.rootFs);this.mntMap[mountPoint]=fs4;this.mountList.push(mountPoint);this.mountList=this.mountList.sort(function(a,b){return b.length-a.length})};MountableFileSystem2.prototype.umount=function umount(mountPoint){var this$1=this;if(mountPoint[0]!=="/"){mountPoint="/"+mountPoint}mountPoint=path.resolve(mountPoint);if(!this.mntMap[mountPoint]){throw new ApiError(ErrorCode.EINVAL,"Mount point "+mountPoint+" is already unmounted.")}delete this.mntMap[mountPoint];this.mountList.splice(this.mountList.indexOf(mountPoint),1);while(mountPoint!=="/"){if(this$1.rootFs.readdirSync(mountPoint).length===0){this$1.rootFs.rmdirSync(mountPoint);mountPoint=path.dirname(mountPoint)}else{break}}};MountableFileSystem2.prototype._getFs=function _getFs(path$$1){var this$1=this;var mountList=this.mountList,len=mountList.length;for(var i2=0;i21?mountPoint.length:0);if(path$$1===""){path$$1="/"}return{fs:this$1.mntMap[mountPoint],path:path$$1}}}return{fs:this.rootFs,path:path$$1}};MountableFileSystem2.prototype.getName=function getName(){return MountableFileSystem2.Name};MountableFileSystem2.prototype.diskSpace=function diskSpace(path$$1,cb){cb(0,0)};MountableFileSystem2.prototype.isReadOnly=function isReadOnly(){return false};MountableFileSystem2.prototype.supportsLinks=function supportsLinks(){return false};MountableFileSystem2.prototype.supportsProps=function supportsProps(){return false};MountableFileSystem2.prototype.supportsSynch=function supportsSynch(){return true};MountableFileSystem2.prototype.standardizeError=function standardizeError(err,path$$1,realPath){var index=err.message.indexOf(path$$1);if(index!==-1){err.message=err.message.substr(0,index)+realPath+err.message.substr(index+path$$1.length);err.path=realPath}return err};MountableFileSystem2.prototype.rename=function rename(oldPath,newPath,cb){var this$1=this;var fs1rv=this._getFs(oldPath);var fs2rv=this._getFs(newPath);if(fs1rv.fs===fs2rv.fs){return fs1rv.fs.rename(fs1rv.path,fs2rv.path,function(e){if(e){this$1.standardizeError(this$1.standardizeError(e,fs1rv.path,oldPath),fs2rv.path,newPath)}cb(e)})}return _fsMock.readFile(oldPath,function(err,data){if(err){return cb(err)}_fsMock.writeFile(newPath,data,function(err2){if(err2){return cb(err2)}_fsMock.unlink(oldPath,cb)})})};MountableFileSystem2.prototype.renameSync=function renameSync(oldPath,newPath){var fs1rv=this._getFs(oldPath);var fs2rv=this._getFs(newPath);if(fs1rv.fs===fs2rv.fs){try{return fs1rv.fs.renameSync(fs1rv.path,fs2rv.path)}catch(e){this.standardizeError(this.standardizeError(e,fs1rv.path,oldPath),fs2rv.path,newPath);throw e}}var data=_fsMock.readFileSync(oldPath);_fsMock.writeFileSync(newPath,data);return _fsMock.unlinkSync(oldPath)};MountableFileSystem2.prototype.readdirSync=function readdirSync(p){var fsInfo=this._getFs(p);var rv=null;if(fsInfo.fs!==this.rootFs){try{rv=this.rootFs.readdirSync(p)}catch(e){}}try{var rv2=fsInfo.fs.readdirSync(fsInfo.path);if(rv===null){return rv2}else{return rv2.concat(rv.filter(function(val){return rv2.indexOf(val)===-1}))}}catch(e){if(rv===null){throw this.standardizeError(e,fsInfo.path,p)}else{return rv}}};MountableFileSystem2.prototype.readdir=function readdir(p,cb){var this$1=this;var fsInfo=this._getFs(p);fsInfo.fs.readdir(fsInfo.path,function(err,files){if(fsInfo.fs!==this$1.rootFs){try{var rv=this$1.rootFs.readdirSync(p);if(files){files=files.concat(rv.filter(function(val){return files.indexOf(val)===-1}))}else{files=rv}}catch(e){if(err){return cb(this$1.standardizeError(err,fsInfo.path,p))}}}else if(err){return cb(this$1.standardizeError(err,fsInfo.path,p))}cb(null,files)})};MountableFileSystem2.prototype.rmdirSync=function rmdirSync(p){var fsInfo=this._getFs(p);if(this._containsMountPt(p)){throw ApiError.ENOTEMPTY(p)}else{try{fsInfo.fs.rmdirSync(fsInfo.path)}catch(e){throw this.standardizeError(e,fsInfo.path,p)}}};MountableFileSystem2.prototype.rmdir=function rmdir(p,cb){var this$1=this;var fsInfo=this._getFs(p);if(this._containsMountPt(p)){cb(ApiError.ENOTEMPTY(p))}else{fsInfo.fs.rmdir(fsInfo.path,function(err){cb(err?this$1.standardizeError(err,fsInfo.path,p):null)})}};MountableFileSystem2.prototype._containsMountPt=function _containsMountPt(p){var mountPoints=this.mountList,len=mountPoints.length;for(var i2=0;i2=p.length&&pt.slice(0,p.length)===p){return true}}return false};return MountableFileSystem2}(BaseFileSystem);MountableFileSystem.Name="MountableFileSystem";MountableFileSystem.Options={};function defineFcn(name,isSync,numArgs){if(isSync){return function(){var args=[],len=arguments.length;while(len--)args[len]=arguments[len];var path$$1=args[0];var rv=this._getFs(path$$1);args[0]=rv.path;try{return rv.fs[name].apply(rv.fs,args)}catch(e){this.standardizeError(e,rv.path,path$$1);throw e}}}else{return function(){var this$1=this;var args=[],len=arguments.length;while(len--)args[len]=arguments[len];var path$$1=args[0];var rv=this._getFs(path$$1);args[0]=rv.path;if(typeof args[args.length-1]==="function"){var cb=args[args.length-1];args[args.length-1]=function(){var args2=[],len2=arguments.length;while(len2--)args2[len2]=arguments[len2];if(args2.length>0&&args2[0]instanceof ApiError){this$1.standardizeError(args2[0],rv.path,path$$1)}cb.apply(null,args2)}}return rv.fs[name].apply(rv.fs,args)}}}var fsCmdMap=[["exists","unlink","readlink"],["stat","mkdir","realpath","truncate"],["open","readFile","chmod","utimes"],["chown"],["writeFile","appendFile"]];for(var i=0;i0){var fn=timeouts.shift();return fn()}}};if(gScope.addEventListener){gScope.addEventListener("message",handleMessage,true)}else{gScope.attachEvent("onmessage",handleMessage)}}else if(gScope.MessageChannel){var channel=new gScope.MessageChannel;channel.port1.onmessage=function(event){if(timeouts.length>0){return timeouts.shift()()}};bfsSetImmediate=function(fn){timeouts.push(fn);channel.port2.postMessage("")}}else{bfsSetImmediate=function(fn){return setTimeout(fn,0)}}}var setImmediate$3=bfsSetImmediate;var Mutex=function Mutex2(){this._locked=false;this._waiters=[]};Mutex.prototype.lock=function lock(cb){if(this._locked){this._waiters.push(cb);return}this._locked=true;cb()};Mutex.prototype.unlock=function unlock(){if(!this._locked){throw new Error("unlock of a non-locked mutex")}var next=this._waiters.shift();if(next){setImmediate$3(next);return}this._locked=false};Mutex.prototype.tryLock=function tryLock(){if(this._locked){return false}this._locked=true;return true};Mutex.prototype.isLocked=function isLocked(){return this._locked};var LockedFS=function LockedFS2(fs4){this._fs=fs4;this._mu=new Mutex};LockedFS.prototype.getName=function getName(){return"LockedFS<"+this._fs.getName()+">"};LockedFS.prototype.getFSUnlocked=function getFSUnlocked(){return this._fs};LockedFS.prototype.initialize=function initialize3(cb){this._fs.initialize(cb)};LockedFS.prototype.diskSpace=function diskSpace(p,cb){this._fs.diskSpace(p,cb)};LockedFS.prototype.isReadOnly=function isReadOnly(){return this._fs.isReadOnly()};LockedFS.prototype.supportsLinks=function supportsLinks(){return this._fs.supportsLinks()};LockedFS.prototype.supportsProps=function supportsProps(){return this._fs.supportsProps()};LockedFS.prototype.supportsSynch=function supportsSynch(){return this._fs.supportsSynch()};LockedFS.prototype.rename=function rename(oldPath,newPath,cb){var this$1=this;this._mu.lock(function(){this$1._fs.rename(oldPath,newPath,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.renameSync=function renameSync(oldPath,newPath){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.renameSync(oldPath,newPath)};LockedFS.prototype.stat=function stat(p,isLstat,cb){var this$1=this;this._mu.lock(function(){this$1._fs.stat(p,isLstat,function(err,stat2){this$1._mu.unlock();cb(err,stat2)})})};LockedFS.prototype.statSync=function statSync(p,isLstat){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.statSync(p,isLstat)};LockedFS.prototype.open=function open(p,flag,mode,cb){var this$1=this;this._mu.lock(function(){this$1._fs.open(p,flag,mode,function(err,fd){this$1._mu.unlock();cb(err,fd)})})};LockedFS.prototype.openSync=function openSync(p,flag,mode){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.openSync(p,flag,mode)};LockedFS.prototype.unlink=function unlink(p,cb){var this$1=this;this._mu.lock(function(){this$1._fs.unlink(p,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.unlinkSync=function unlinkSync(p){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.unlinkSync(p)};LockedFS.prototype.rmdir=function rmdir(p,cb){var this$1=this;this._mu.lock(function(){this$1._fs.rmdir(p,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.rmdirSync=function rmdirSync(p){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.rmdirSync(p)};LockedFS.prototype.mkdir=function mkdir(p,mode,cb){var this$1=this;this._mu.lock(function(){this$1._fs.mkdir(p,mode,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.mkdirSync=function mkdirSync(p,mode){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.mkdirSync(p,mode)};LockedFS.prototype.readdir=function readdir(p,cb){var this$1=this;this._mu.lock(function(){this$1._fs.readdir(p,function(err,files){this$1._mu.unlock();cb(err,files)})})};LockedFS.prototype.readdirSync=function readdirSync(p){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.readdirSync(p)};LockedFS.prototype.exists=function exists2(p,cb){var this$1=this;this._mu.lock(function(){this$1._fs.exists(p,function(exists3){this$1._mu.unlock();cb(exists3)})})};LockedFS.prototype.existsSync=function existsSync(p){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.existsSync(p)};LockedFS.prototype.realpath=function realpath(p,cache,cb){var this$1=this;this._mu.lock(function(){this$1._fs.realpath(p,cache,function(err,resolvedPath){this$1._mu.unlock();cb(err,resolvedPath)})})};LockedFS.prototype.realpathSync=function realpathSync(p,cache){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.realpathSync(p,cache)};LockedFS.prototype.truncate=function truncate(p,len,cb){var this$1=this;this._mu.lock(function(){this$1._fs.truncate(p,len,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.truncateSync=function truncateSync(p,len){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.truncateSync(p,len)};LockedFS.prototype.readFile=function readFile2(fname,encoding,flag,cb){var this$1=this;this._mu.lock(function(){this$1._fs.readFile(fname,encoding,flag,function(err,data){this$1._mu.unlock();cb(err,data)})})};LockedFS.prototype.readFileSync=function readFileSync(fname,encoding,flag){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.readFileSync(fname,encoding,flag)};LockedFS.prototype.writeFile=function writeFile2(fname,data,encoding,flag,mode,cb){var this$1=this;this._mu.lock(function(){this$1._fs.writeFile(fname,data,encoding,flag,mode,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.writeFileSync=function writeFileSync(fname,data,encoding,flag,mode){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.writeFileSync(fname,data,encoding,flag,mode)};LockedFS.prototype.appendFile=function appendFile3(fname,data,encoding,flag,mode,cb){var this$1=this;this._mu.lock(function(){this$1._fs.appendFile(fname,data,encoding,flag,mode,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.appendFileSync=function appendFileSync(fname,data,encoding,flag,mode){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.appendFileSync(fname,data,encoding,flag,mode)};LockedFS.prototype.chmod=function chmod(p,isLchmod,mode,cb){var this$1=this;this._mu.lock(function(){this$1._fs.chmod(p,isLchmod,mode,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.chmodSync=function chmodSync(p,isLchmod,mode){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.chmodSync(p,isLchmod,mode)};LockedFS.prototype.chown=function chown(p,isLchown,uid,gid,cb){var this$1=this;this._mu.lock(function(){this$1._fs.chown(p,isLchown,uid,gid,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.chownSync=function chownSync(p,isLchown,uid,gid){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.chownSync(p,isLchown,uid,gid)};LockedFS.prototype.utimes=function utimes(p,atime,mtime,cb){var this$1=this;this._mu.lock(function(){this$1._fs.utimes(p,atime,mtime,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.utimesSync=function utimesSync(p,atime,mtime){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.utimesSync(p,atime,mtime)};LockedFS.prototype.link=function link(srcpath,dstpath,cb){var this$1=this;this._mu.lock(function(){this$1._fs.link(srcpath,dstpath,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.linkSync=function linkSync(srcpath,dstpath){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.linkSync(srcpath,dstpath)};LockedFS.prototype.symlink=function symlink(srcpath,dstpath,type,cb){var this$1=this;this._mu.lock(function(){this$1._fs.symlink(srcpath,dstpath,type,function(err){this$1._mu.unlock();cb(err)})})};LockedFS.prototype.symlinkSync=function symlinkSync(srcpath,dstpath,type){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.symlinkSync(srcpath,dstpath,type)};LockedFS.prototype.readlink=function readlink(p,cb){var this$1=this;this._mu.lock(function(){this$1._fs.readlink(p,function(err,linkString){this$1._mu.unlock();cb(err,linkString)})})};LockedFS.prototype.readlinkSync=function readlinkSync(p){if(this._mu.isLocked()){throw new Error("invalid sync call")}return this._fs.readlinkSync(p)};var deletionLogPath="/.deletedFiles.log";function makeModeWritable(mode){return 146|mode}function getFlag(f){return FileFlag.getFileFlag(f)}var OverlayFile=function(PreloadFile$$1){function OverlayFile2(fs4,path$$1,flag,stats,data){PreloadFile$$1.call(this,fs4,path$$1,flag,stats,data)}if(PreloadFile$$1)OverlayFile2.__proto__=PreloadFile$$1;OverlayFile2.prototype=Object.create(PreloadFile$$1&&PreloadFile$$1.prototype);OverlayFile2.prototype.constructor=OverlayFile2;OverlayFile2.prototype.sync=function sync(cb){var this$1=this;if(!this.isDirty()){cb(null);return}this._fs._syncAsync(this,function(err){this$1.resetDirty();cb(err)})};OverlayFile2.prototype.syncSync=function syncSync(){if(this.isDirty()){this._fs._syncSync(this);this.resetDirty()}};OverlayFile2.prototype.close=function close(cb){this.sync(cb)};OverlayFile2.prototype.closeSync=function closeSync(){this.syncSync()};return OverlayFile2}(PreloadFile);var UnlockedOverlayFS=function(BaseFileSystem$$1){function UnlockedOverlayFS2(writable,readable){BaseFileSystem$$1.call(this);this._isInitialized=false;this._initializeCallbacks=[];this._deletedFiles={};this._deleteLog="";this._deleteLogUpdatePending=false;this._deleteLogUpdateNeeded=false;this._deleteLogError=null;this._writable=writable;this._readable=readable;if(this._writable.isReadOnly()){throw new ApiError(ErrorCode.EINVAL,"Writable file system must be writable.")}}if(BaseFileSystem$$1)UnlockedOverlayFS2.__proto__=BaseFileSystem$$1;UnlockedOverlayFS2.prototype=Object.create(BaseFileSystem$$1&&BaseFileSystem$$1.prototype);UnlockedOverlayFS2.prototype.constructor=UnlockedOverlayFS2;UnlockedOverlayFS2.isAvailable=function isAvailable(){return true};UnlockedOverlayFS2.prototype.getOverlayedFileSystems=function getOverlayedFileSystems(){return{readable:this._readable,writable:this._writable}};UnlockedOverlayFS2.prototype._syncAsync=function _syncAsync(file,cb){var this$1=this;this.createParentDirectoriesAsync(file.getPath(),function(err){if(err){return cb(err)}this$1._writable.writeFile(file.getPath(),file.getBuffer(),null,getFlag("w"),file.getStats().mode,cb)})};UnlockedOverlayFS2.prototype._syncSync=function _syncSync(file){this.createParentDirectories(file.getPath());this._writable.writeFileSync(file.getPath(),file.getBuffer(),null,getFlag("w"),file.getStats().mode)};UnlockedOverlayFS2.prototype.getName=function getName(){return OverlayFS.Name};UnlockedOverlayFS2.prototype.initialize=function initialize3(cb){var this$1=this;var callbackArray=this._initializeCallbacks;var end=function(e){this$1._isInitialized=!e;this$1._initializeCallbacks=[];callbackArray.forEach(function(cb2){return cb2(e)})};if(this._isInitialized){return cb()}callbackArray.push(cb);if(callbackArray.length!==1){return}this._writable.readFile(deletionLogPath,"utf8",getFlag("r"),function(err,data){if(err){if(err.errno!==ErrorCode.ENOENT){return end(err)}}else{this$1._deleteLog=data}this$1._reparseDeletionLog();end()})};UnlockedOverlayFS2.prototype.isReadOnly=function isReadOnly(){return false};UnlockedOverlayFS2.prototype.supportsSynch=function supportsSynch(){return this._readable.supportsSynch()&&this._writable.supportsSynch()};UnlockedOverlayFS2.prototype.supportsLinks=function supportsLinks(){return false};UnlockedOverlayFS2.prototype.supportsProps=function supportsProps(){return this._readable.supportsProps()&&this._writable.supportsProps()};UnlockedOverlayFS2.prototype.getDeletionLog=function getDeletionLog(){return this._deleteLog};UnlockedOverlayFS2.prototype.restoreDeletionLog=function restoreDeletionLog(log){this._deleteLog=log;this._reparseDeletionLog();this.updateLog("")};UnlockedOverlayFS2.prototype.rename=function rename(oldPath,newPath,cb){var this$1=this;if(!this.checkInitAsync(cb)||this.checkPathAsync(oldPath,cb)||this.checkPathAsync(newPath,cb)){return}if(oldPath===deletionLogPath||newPath===deletionLogPath){return cb(ApiError.EPERM("Cannot rename deletion log."))}if(oldPath===newPath){return cb()}this.stat(oldPath,false,function(oldErr,oldStats){if(oldErr){return cb(oldErr)}return this$1.stat(newPath,false,function(newErr,newStats){var self2=this$1;function copyDirContents(files){var file=files.shift();if(!file){return cb()}var oldFile=path.resolve(oldPath,file);var newFile=path.resolve(newPath,file);self2.rename(oldFile,newFile,function(err){if(err){return cb(err)}copyDirContents(files)})}var mode=511;if(oldStats.isDirectory()){if(newErr){if(newErr.errno!==ErrorCode.ENOENT){return cb(newErr)}return this$1._writable.exists(oldPath,function(exists2){if(exists2){return this$1._writable.rename(oldPath,newPath,cb)}this$1._writable.mkdir(newPath,mode,function(mkdirErr){if(mkdirErr){return cb(mkdirErr)}this$1._readable.readdir(oldPath,function(err,files){if(err){return cb()}copyDirContents(files)})})})}mode=newStats.mode;if(!newStats.isDirectory()){return cb(ApiError.ENOTDIR(newPath))}this$1.readdir(newPath,function(readdirErr,files){if(files&&files.length){return cb(ApiError.ENOTEMPTY(newPath))}this$1._readable.readdir(oldPath,function(err,files2){if(err){return cb()}copyDirContents(files2)})})}if(newStats&&newStats.isDirectory()){return cb(ApiError.EISDIR(newPath))}this$1.readFile(oldPath,null,getFlag("r"),function(err,data){if(err){return cb(err)}return this$1.writeFile(newPath,data,null,getFlag("w"),oldStats.mode,function(err2){if(err2){return cb(err2)}return this$1.unlink(oldPath,cb)})})})})};UnlockedOverlayFS2.prototype.renameSync=function renameSync(oldPath,newPath){var this$1=this;this.checkInitialized();this.checkPath(oldPath);this.checkPath(newPath);if(oldPath===deletionLogPath||newPath===deletionLogPath){throw ApiError.EPERM("Cannot rename deletion log.")}var oldStats=this.statSync(oldPath,false);if(oldStats.isDirectory()){if(oldPath===newPath){return}var mode=511;if(this.existsSync(newPath)){var stats=this.statSync(newPath,false);mode=stats.mode;if(stats.isDirectory()){if(this.readdirSync(newPath).length>0){throw ApiError.ENOTEMPTY(newPath)}}else{throw ApiError.ENOTDIR(newPath)}}if(this._writable.existsSync(oldPath)){this._writable.renameSync(oldPath,newPath)}else if(!this._writable.existsSync(newPath)){this._writable.mkdirSync(newPath,mode)}if(this._readable.existsSync(oldPath)){this._readable.readdirSync(oldPath).forEach(function(name){this$1.renameSync(path.resolve(oldPath,name),path.resolve(newPath,name))})}}else{if(this.existsSync(newPath)&&this.statSync(newPath,false).isDirectory()){throw ApiError.EISDIR(newPath)}this.writeFileSync(newPath,this.readFileSync(oldPath,null,getFlag("r")),null,getFlag("w"),oldStats.mode)}if(oldPath!==newPath&&this.existsSync(oldPath)){this.unlinkSync(oldPath)}};UnlockedOverlayFS2.prototype.stat=function stat(p,isLstat,cb){var this$1=this;if(!this.checkInitAsync(cb)){return}this._writable.stat(p,isLstat,function(err,stat2){if(err&&err.errno===ErrorCode.ENOENT){if(this$1._deletedFiles[p]){cb(ApiError.ENOENT(p))}this$1._readable.stat(p,isLstat,function(err2,stat3){if(stat3){stat3=stat3.clone();stat3.mode=makeModeWritable(stat3.mode)}cb(err2,stat3)})}else{cb(err,stat2)}})};UnlockedOverlayFS2.prototype.statSync=function statSync(p,isLstat){this.checkInitialized();try{return this._writable.statSync(p,isLstat)}catch(e){if(this._deletedFiles[p]){throw ApiError.ENOENT(p)}var oldStat=this._readable.statSync(p,isLstat).clone();oldStat.mode=makeModeWritable(oldStat.mode);return oldStat}};UnlockedOverlayFS2.prototype.open=function open(p,flag,mode,cb){var this$1=this;if(!this.checkInitAsync(cb)||this.checkPathAsync(p,cb)){return}this.stat(p,false,function(err,stats){if(stats){switch(flag.pathExistsAction()){case ActionType.TRUNCATE_FILE:return this$1.createParentDirectoriesAsync(p,function(err2){if(err2){return cb(err2)}this$1._writable.open(p,flag,mode,cb)});case ActionType.NOP:return this$1._writable.exists(p,function(exists2){if(exists2){this$1._writable.open(p,flag,mode,cb)}else{stats=stats.clone();stats.mode=mode;this$1._readable.readFile(p,null,getFlag("r"),function(readFileErr,data){if(readFileErr){return cb(readFileErr)}if(stats.size===-1){stats.size=data.length}var f=new OverlayFile(this$1,p,flag,stats,data);cb(null,f)})}});default:return cb(ApiError.EEXIST(p))}}else{switch(flag.pathNotExistsAction()){case ActionType.CREATE_FILE:return this$1.createParentDirectoriesAsync(p,function(err2){if(err2){return cb(err2)}return this$1._writable.open(p,flag,mode,cb)});default:return cb(ApiError.ENOENT(p))}}})};UnlockedOverlayFS2.prototype.openSync=function openSync(p,flag,mode){this.checkInitialized();this.checkPath(p);if(p===deletionLogPath){throw ApiError.EPERM("Cannot open deletion log.")}if(this.existsSync(p)){switch(flag.pathExistsAction()){case ActionType.TRUNCATE_FILE:this.createParentDirectories(p);return this._writable.openSync(p,flag,mode);case ActionType.NOP:if(this._writable.existsSync(p)){return this._writable.openSync(p,flag,mode)}else{var buf=this._readable.readFileSync(p,null,getFlag("r"));var stats=this._readable.statSync(p,false).clone();stats.mode=mode;return new OverlayFile(this,p,flag,stats,buf)}default:throw ApiError.EEXIST(p)}}else{switch(flag.pathNotExistsAction()){case ActionType.CREATE_FILE:this.createParentDirectories(p);return this._writable.openSync(p,flag,mode);default:throw ApiError.ENOENT(p)}}};UnlockedOverlayFS2.prototype.unlink=function unlink(p,cb){var this$1=this;if(!this.checkInitAsync(cb)||this.checkPathAsync(p,cb)){return}this.exists(p,function(exists2){if(!exists2){return cb(ApiError.ENOENT(p))}this$1._writable.exists(p,function(writableExists){if(writableExists){return this$1._writable.unlink(p,function(err){if(err){return cb(err)}this$1.exists(p,function(readableExists){if(readableExists){this$1.deletePath(p)}cb(null)})})}else{this$1.deletePath(p);cb(null)}})})};UnlockedOverlayFS2.prototype.unlinkSync=function unlinkSync(p){this.checkInitialized();this.checkPath(p);if(this.existsSync(p)){if(this._writable.existsSync(p)){this._writable.unlinkSync(p)}if(this.existsSync(p)){this.deletePath(p)}}else{throw ApiError.ENOENT(p)}};UnlockedOverlayFS2.prototype.rmdir=function rmdir(p,cb){var this$1=this;if(!this.checkInitAsync(cb)){return}var rmdirLower=function(){this$1.readdir(p,function(err,files){if(err){return cb(err)}if(files.length){return cb(ApiError.ENOTEMPTY(p))}this$1.deletePath(p);cb(null)})};this.exists(p,function(exists2){if(!exists2){return cb(ApiError.ENOENT(p))}this$1._writable.exists(p,function(writableExists){if(writableExists){this$1._writable.rmdir(p,function(err){if(err){return cb(err)}this$1._readable.exists(p,function(readableExists){if(readableExists){rmdirLower()}else{cb()}})})}else{rmdirLower()}})})};UnlockedOverlayFS2.prototype.rmdirSync=function rmdirSync(p){this.checkInitialized();if(this.existsSync(p)){if(this._writable.existsSync(p)){this._writable.rmdirSync(p)}if(this.existsSync(p)){if(this.readdirSync(p).length>0){throw ApiError.ENOTEMPTY(p)}else{this.deletePath(p)}}}else{throw ApiError.ENOENT(p)}};UnlockedOverlayFS2.prototype.mkdir=function mkdir(p,mode,cb){var this$1=this;if(!this.checkInitAsync(cb)){return}this.exists(p,function(exists2){if(exists2){return cb(ApiError.EEXIST(p))}this$1.createParentDirectoriesAsync(p,function(err){if(err){return cb(err)}this$1._writable.mkdir(p,mode,cb)})})};UnlockedOverlayFS2.prototype.mkdirSync=function mkdirSync(p,mode){this.checkInitialized();if(this.existsSync(p)){throw ApiError.EEXIST(p)}else{this.createParentDirectories(p);this._writable.mkdirSync(p,mode)}};UnlockedOverlayFS2.prototype.readdir=function readdir(p,cb){var this$1=this;if(!this.checkInitAsync(cb)){return}this.stat(p,false,function(err,dirStats){if(err){return cb(err)}if(!dirStats.isDirectory()){return cb(ApiError.ENOTDIR(p))}this$1._writable.readdir(p,function(err2,wFiles){if(err2&&err2.code!=="ENOENT"){return cb(err2)}else if(err2||!wFiles){wFiles=[]}this$1._readable.readdir(p,function(err3,rFiles){if(err3||!rFiles){rFiles=[]}var seenMap={};var filtered=wFiles.concat(rFiles.filter(function(fPath){return!this$1._deletedFiles[p+"/"+fPath]})).filter(function(fPath){var result=!seenMap[fPath];seenMap[fPath]=true;return result});cb(null,filtered)})})})};UnlockedOverlayFS2.prototype.readdirSync=function readdirSync(p){var this$1=this;this.checkInitialized();var dirStats=this.statSync(p,false);if(!dirStats.isDirectory()){throw ApiError.ENOTDIR(p)}var contents=[];try{contents=contents.concat(this._writable.readdirSync(p))}catch(e){}try{contents=contents.concat(this._readable.readdirSync(p).filter(function(fPath){return!this$1._deletedFiles[p+"/"+fPath]}))}catch(e){}var seenMap={};return contents.filter(function(fileP){var result=!seenMap[fileP];seenMap[fileP]=true;return result})};UnlockedOverlayFS2.prototype.exists=function exists2(p,cb){var this$1=this;this.checkInitialized();this._writable.exists(p,function(existsWritable){if(existsWritable){return cb(true)}this$1._readable.exists(p,function(existsReadable){cb(existsReadable&&this$1._deletedFiles[p]!==true)})})};UnlockedOverlayFS2.prototype.existsSync=function existsSync(p){this.checkInitialized();return this._writable.existsSync(p)||this._readable.existsSync(p)&&this._deletedFiles[p]!==true};UnlockedOverlayFS2.prototype.chmod=function chmod(p,isLchmod,mode,cb){var this$1=this;if(!this.checkInitAsync(cb)){return}this.operateOnWritableAsync(p,function(err){if(err){return cb(err)}else{this$1._writable.chmod(p,isLchmod,mode,cb)}})};UnlockedOverlayFS2.prototype.chmodSync=function chmodSync(p,isLchmod,mode){var this$1=this;this.checkInitialized();this.operateOnWritable(p,function(){this$1._writable.chmodSync(p,isLchmod,mode)})};UnlockedOverlayFS2.prototype.chown=function chown(p,isLchmod,uid,gid,cb){var this$1=this;if(!this.checkInitAsync(cb)){return}this.operateOnWritableAsync(p,function(err){if(err){return cb(err)}else{this$1._writable.chown(p,isLchmod,uid,gid,cb)}})};UnlockedOverlayFS2.prototype.chownSync=function chownSync(p,isLchown,uid,gid){var this$1=this;this.checkInitialized();this.operateOnWritable(p,function(){this$1._writable.chownSync(p,isLchown,uid,gid)})};UnlockedOverlayFS2.prototype.utimes=function utimes(p,atime,mtime,cb){var this$1=this;if(!this.checkInitAsync(cb)){return}this.operateOnWritableAsync(p,function(err){if(err){return cb(err)}else{this$1._writable.utimes(p,atime,mtime,cb)}})};UnlockedOverlayFS2.prototype.utimesSync=function utimesSync(p,atime,mtime){var this$1=this;this.checkInitialized();this.operateOnWritable(p,function(){this$1._writable.utimesSync(p,atime,mtime)})};UnlockedOverlayFS2.prototype.deletePath=function deletePath(p){this._deletedFiles[p]=true;this.updateLog("d"+p+"\n")};UnlockedOverlayFS2.prototype.updateLog=function updateLog(addition){var this$1=this;this._deleteLog+=addition;if(this._deleteLogUpdatePending){this._deleteLogUpdateNeeded=true}else{this._deleteLogUpdatePending=true;this._writable.writeFile(deletionLogPath,this._deleteLog,"utf8",FileFlag.getFileFlag("w"),420,function(e){this$1._deleteLogUpdatePending=false;if(e){this$1._deleteLogError=e}else if(this$1._deleteLogUpdateNeeded){this$1._deleteLogUpdateNeeded=false;this$1.updateLog("")}})}};UnlockedOverlayFS2.prototype._reparseDeletionLog=function _reparseDeletionLog(){var this$1=this;this._deletedFiles={};this._deleteLog.split("\n").forEach(function(path$$1){this$1._deletedFiles[path$$1.slice(1)]=path$$1.slice(0,1)==="d"})};UnlockedOverlayFS2.prototype.checkInitialized=function checkInitialized(){if(!this._isInitialized){throw new ApiError(ErrorCode.EPERM,"OverlayFS is not initialized. Please initialize OverlayFS using its initialize() method before using it.")}else if(this._deleteLogError!==null){var e=this._deleteLogError;this._deleteLogError=null;throw e}};UnlockedOverlayFS2.prototype.checkInitAsync=function checkInitAsync(cb){if(!this._isInitialized){cb(new ApiError(ErrorCode.EPERM,"OverlayFS is not initialized. Please initialize OverlayFS using its initialize() method before using it."));return false}else if(this._deleteLogError!==null){var e=this._deleteLogError;this._deleteLogError=null;cb(e);return false}return true};UnlockedOverlayFS2.prototype.checkPath=function checkPath(p){if(p===deletionLogPath){throw ApiError.EPERM(p)}};UnlockedOverlayFS2.prototype.checkPathAsync=function checkPathAsync(p,cb){if(p===deletionLogPath){cb(ApiError.EPERM(p));return true}return false};UnlockedOverlayFS2.prototype.createParentDirectoriesAsync=function createParentDirectoriesAsync(p,cb){var parent=path.dirname(p);var toCreate=[];var self2=this;this._writable.stat(parent,false,statDone);function statDone(err,stat){if(err){toCreate.push(parent);parent=path.dirname(parent);self2._writable.stat(parent,false,statDone)}else{createParents()}}function createParents(){if(!toCreate.length){return cb()}var dir=toCreate.pop();self2._readable.stat(dir,false,function(err,stats){if(!stats){return cb()}self2._writable.mkdir(dir,stats.mode,function(err2){if(err2){return cb(err2)}createParents()})})}};UnlockedOverlayFS2.prototype.createParentDirectories=function createParentDirectories(p){var this$1=this;var parent=path.dirname(p),toCreate=[];while(!this._writable.existsSync(parent)){toCreate.push(parent);parent=path.dirname(parent)}toCreate=toCreate.reverse();toCreate.forEach(function(p2){this$1._writable.mkdirSync(p2,this$1.statSync(p2,false).mode)})};UnlockedOverlayFS2.prototype.operateOnWritable=function operateOnWritable(p,f){if(this.existsSync(p)){if(!this._writable.existsSync(p)){this.copyToWritable(p)}f()}else{throw ApiError.ENOENT(p)}};UnlockedOverlayFS2.prototype.operateOnWritableAsync=function operateOnWritableAsync(p,cb){var this$1=this;this.exists(p,function(exists2){if(!exists2){return cb(ApiError.ENOENT(p))}this$1._writable.exists(p,function(existsWritable){if(existsWritable){cb()}else{return this$1.copyToWritableAsync(p,cb)}})})};UnlockedOverlayFS2.prototype.copyToWritable=function copyToWritable(p){var pStats=this.statSync(p,false);if(pStats.isDirectory()){this._writable.mkdirSync(p,pStats.mode)}else{this.writeFileSync(p,this._readable.readFileSync(p,null,getFlag("r")),null,getFlag("w"),this.statSync(p,false).mode)}};UnlockedOverlayFS2.prototype.copyToWritableAsync=function copyToWritableAsync(p,cb){var this$1=this;this.stat(p,false,function(err,pStats){if(err){return cb(err)}if(pStats.isDirectory()){return this$1._writable.mkdir(p,pStats.mode,cb)}this$1._readable.readFile(p,null,getFlag("r"),function(err2,data){if(err2){return cb(err2)}this$1.writeFile(p,data,null,getFlag("w"),pStats.mode,cb)})})};return UnlockedOverlayFS2}(BaseFileSystem);var OverlayFS=function(LockedFS$$1){function OverlayFS2(writable,readable,deprecateMsg){if(deprecateMsg===void 0)deprecateMsg=true;LockedFS$$1.call(this,new UnlockedOverlayFS(writable,readable));deprecationMessage(deprecateMsg,OverlayFS2.Name,{readable:"readable file system",writable:"writable file system"})}if(LockedFS$$1)OverlayFS2.__proto__=LockedFS$$1;OverlayFS2.prototype=Object.create(LockedFS$$1&&LockedFS$$1.prototype);OverlayFS2.prototype.constructor=OverlayFS2;OverlayFS2.Create=function Create(opts,cb){try{var fs4=new OverlayFS2(opts.writable,opts.readable,false);fs4.initialize(function(e){cb(e,fs4)},false)}catch(e){cb(e)}};OverlayFS2.isAvailable=function isAvailable(){return UnlockedOverlayFS.isAvailable()};OverlayFS2.prototype.initialize=function initialize3(cb,deprecateMsg){if(deprecateMsg===void 0)deprecateMsg=true;if(deprecateMsg){console.warn("[OverlayFS] OverlayFS.initialize() is deprecated and will be removed in the next major release. Please use 'OverlayFS.Create({readable: readable file system instance, writable: writable file system instance}, cb)' to create and initialize OverlayFS instances.")}LockedFS$$1.prototype.initialize.call(this,cb)};OverlayFS2.prototype.getOverlayedFileSystems=function getOverlayedFileSystems(){return LockedFS$$1.prototype.getFSUnlocked.call(this).getOverlayedFileSystems()};OverlayFS2.prototype.unwrap=function unwrap(){return LockedFS$$1.prototype.getFSUnlocked.call(this)};return OverlayFS2}(LockedFS);OverlayFS.Name="OverlayFS";OverlayFS.Options={writable:{type:"object",description:"The file system to write modified files to."},readable:{type:"object",description:"The file system that initially populates this file system."}};var SpecialArgType;(function(SpecialArgType2){SpecialArgType2[SpecialArgType2["CB"]=0]="CB";SpecialArgType2[SpecialArgType2["FD"]=1]="FD";SpecialArgType2[SpecialArgType2["API_ERROR"]=2]="API_ERROR";SpecialArgType2[SpecialArgType2["STATS"]=3]="STATS";SpecialArgType2[SpecialArgType2["PROBE"]=4]="PROBE";SpecialArgType2[SpecialArgType2["FILEFLAG"]=5]="FILEFLAG";SpecialArgType2[SpecialArgType2["BUFFER"]=6]="BUFFER";SpecialArgType2[SpecialArgType2["ERROR"]=7]="ERROR"})(SpecialArgType||(SpecialArgType={}));var CallbackArgumentConverter=function CallbackArgumentConverter2(){this._callbacks={};this._nextId=0};CallbackArgumentConverter.prototype.toRemoteArg=function toRemoteArg(cb){var id=this._nextId++;this._callbacks[id]=cb;return{type:SpecialArgType.CB,id}};CallbackArgumentConverter.prototype.toLocalArg=function toLocalArg(id){var cb=this._callbacks[id];delete this._callbacks[id];return cb};var FileDescriptorArgumentConverter=function FileDescriptorArgumentConverter2(){this._fileDescriptors={};this._nextId=0};FileDescriptorArgumentConverter.prototype.toRemoteArg=function toRemoteArg(fd,p,flag,cb){var id=this._nextId++;var data;var stat;this._fileDescriptors[id]=fd;fd.stat(function(err,stats){if(err){cb(err)}else{stat=bufferToTransferrableObject(stats.toBuffer());if(flag.isReadable()){fd.read(Buffer2.alloc(stats.size),0,stats.size,0,function(err2,bytesRead,buff){if(err2){cb(err2)}else{data=bufferToTransferrableObject(buff);cb(null,{type:SpecialArgType.FD,id,data,stat,path:p,flag:flag.getFlagString()})}})}else{cb(null,{type:SpecialArgType.FD,id,data:new ArrayBuffer(0),stat,path:p,flag:flag.getFlagString()})}}})};FileDescriptorArgumentConverter.prototype.applyFdAPIRequest=function applyFdAPIRequest(request,cb){var this$1=this;var fdArg=request.args[0];this._applyFdChanges(fdArg,function(err,fd){if(err){cb(err)}else{fd[request.method](function(e){if(request.method==="close"){delete this$1._fileDescriptors[fdArg.id]}cb(e)})}})};FileDescriptorArgumentConverter.prototype._applyFdChanges=function _applyFdChanges(remoteFd,cb){var fd=this._fileDescriptors[remoteFd.id],data=transferrableObjectToBuffer(remoteFd.data),remoteStats=Stats.fromBuffer(transferrableObjectToBuffer(remoteFd.stat));var flag=FileFlag.getFileFlag(remoteFd.flag);if(flag.isWriteable()){fd.write(data,0,data.length,flag.isAppendable()?fd.getPos():0,function(e){function applyStatChanges(){fd.stat(function(e2,stats){if(e2){cb(e2)}else{if(stats.mode!==remoteStats.mode){fd.chmod(remoteStats.mode,function(e3){cb(e3,fd)})}else{cb(e2,fd)}}})}if(e){cb(e)}else{if(!flag.isAppendable()){fd.truncate(data.length,function(){applyStatChanges()})}else{applyStatChanges()}}})}else{cb(null,fd)}};function apiErrorLocal2Remote(e){return{type:SpecialArgType.API_ERROR,errorData:bufferToTransferrableObject(e.writeToBuffer())}}function apiErrorRemote2Local(e){return ApiError.fromBuffer(transferrableObjectToBuffer(e.errorData))}function errorLocal2Remote(e){return{type:SpecialArgType.ERROR,name:e.name,message:e.message,stack:e.stack}}function errorRemote2Local(e){var cnstr=global$1[e.name];if(typeof cnstr!=="function"){cnstr=Error}var err=new cnstr(e.message);err.stack=e.stack;return err}function statsLocal2Remote(stats){return{type:SpecialArgType.STATS,statsData:bufferToTransferrableObject(stats.toBuffer())}}function statsRemote2Local(stats){return Stats.fromBuffer(transferrableObjectToBuffer(stats.statsData))}function fileFlagLocal2Remote(flag){return{type:SpecialArgType.FILEFLAG,flagStr:flag.getFlagString()}}function fileFlagRemote2Local(remoteFlag){return FileFlag.getFileFlag(remoteFlag.flagStr)}function bufferToTransferrableObject(buff){return buffer2ArrayBuffer(buff)}function transferrableObjectToBuffer(buff){return arrayBuffer2Buffer(buff)}function bufferLocal2Remote(buff){return{type:SpecialArgType.BUFFER,data:bufferToTransferrableObject(buff)}}function bufferRemote2Local(buffArg){return transferrableObjectToBuffer(buffArg.data)}function isAPIRequest(data){return data&&typeof data==="object"&&data.hasOwnProperty("browserfsMessage")&&data["browserfsMessage"]}function isAPIResponse(data){return data&&typeof data==="object"&&data.hasOwnProperty("browserfsMessage")&&data["browserfsMessage"]}var WorkerFile=function(PreloadFile$$1){function WorkerFile2(_fs,_path,_flag,_stat,remoteFdId,contents){PreloadFile$$1.call(this,_fs,_path,_flag,_stat,contents);this._remoteFdId=remoteFdId}if(PreloadFile$$1)WorkerFile2.__proto__=PreloadFile$$1;WorkerFile2.prototype=Object.create(PreloadFile$$1&&PreloadFile$$1.prototype);WorkerFile2.prototype.constructor=WorkerFile2;WorkerFile2.prototype.getRemoteFdId=function getRemoteFdId(){return this._remoteFdId};WorkerFile2.prototype.toRemoteArg=function toRemoteArg(){return{type:SpecialArgType.FD,id:this._remoteFdId,data:bufferToTransferrableObject(this.getBuffer()),stat:bufferToTransferrableObject(this.getStats().toBuffer()),path:this.getPath(),flag:this.getFlag().getFlagString()}};WorkerFile2.prototype.sync=function sync(cb){this._syncClose("sync",cb)};WorkerFile2.prototype.close=function close(cb){this._syncClose("close",cb)};WorkerFile2.prototype._syncClose=function _syncClose(type,cb){var this$1=this;if(this.isDirty()){this._fs.syncClose(type,this,function(e){if(!e){this$1.resetDirty()}cb(e)})}else{cb()}};return WorkerFile2}(PreloadFile);var WorkerFS=function(BaseFileSystem$$1){function WorkerFS2(worker,deprecateMsg){var this$1=this;if(deprecateMsg===void 0)deprecateMsg=true;BaseFileSystem$$1.call(this);this._callbackConverter=new CallbackArgumentConverter;this._isInitialized=false;this._isReadOnly=false;this._supportLinks=false;this._supportProps=false;this._worker=worker;deprecationMessage(deprecateMsg,WorkerFS2.Name,{worker:"Web Worker instance"});this._worker.addEventListener("message",function(e){var resp=e.data;if(isAPIResponse(resp)){var i2;var args=resp.args;var fixedArgs=new Array(args.length);for(i2=0;i20){countdown=-1;message={browserfsMessage:true,cbId,args:[apiErrorLocal2Remote(err)]};worker.postMessage(message)}}for(i2=0;i20){var inode=void 0;var next=queue.pop();var pwd=next[0];var tree=next[1];var parent=next[2];for(var node in tree){if(tree.hasOwnProperty(node)){var children=tree[node];var name=pwd+"/"+node;if(children){idx._index[name]=inode=new DirInode;queue.push([name,children,inode])}else{inode=new FileInode(new Stats(FileType.FILE,-1,365))}if(parent){parent._ls[node]=inode}}}}return idx};FileIndex.prototype.fileIterator=function fileIterator(cb){var this$1=this;for(var path$$1 in this$1._index){if(this$1._index.hasOwnProperty(path$$1)){var dir=this$1._index[path$$1];var files=dir.getListing();for(var i2=0,list2=files;i20&&prefixUrl.charAt(prefixUrl.length-1)!=="/"){prefixUrl=prefixUrl+"/"}this.prefixUrl=prefixUrl;var listing=null;if(typeof listingUrlOrObj==="string"){listing=this._requestFileSync(listingUrlOrObj,"json");if(!listing){throw new Error("Unable to find listing at URL: ${listingUrlOrObj}")}}else{listing=listingUrlOrObj}deprecationMessage(deprecateMsg,XmlHttpRequest2.Name,{index:typeof listingUrlOrObj==="string"?listingUrlOrObj:"file index as an object",baseUrl:prefixUrl});this._index=FileIndex.fromListing(listing)}if(BaseFileSystem$$1)XmlHttpRequest2.__proto__=BaseFileSystem$$1;XmlHttpRequest2.prototype=Object.create(BaseFileSystem$$1&&BaseFileSystem$$1.prototype);XmlHttpRequest2.prototype.constructor=XmlHttpRequest2;XmlHttpRequest2.Create=function Create(opts,cb){if(opts.index===void 0){opts.index="index.json"}if(typeof opts.index==="string"){XmlHttpRequest2.FromURL(opts.index,cb,opts.baseUrl,false)}else{cb(null,new XmlHttpRequest2(opts.index,opts.baseUrl,false))}};XmlHttpRequest2.isAvailable=function isAvailable(){return typeof XMLHttpRequest!=="undefined"&&XMLHttpRequest!==null};XmlHttpRequest2.FromURL=function FromURL(url,cb,baseUrl,deprecateMsg){if(baseUrl===void 0)baseUrl=url.slice(0,url.lastIndexOf("/")+1);if(deprecateMsg===void 0)deprecateMsg=true;if(deprecateMsg){console.warn(`[XmlHttpRequest] XmlHttpRequest.FromURL() is deprecated and will be removed in the next major release. Please use 'XmlHttpRequest.Create({ index: "`+url+'", baseUrl: "'+baseUrl+`" }, cb)' instead.`)}asyncDownloadFile(url,"json",function(e,data){if(e){cb(e)}else{cb(null,new XmlHttpRequest2(data,baseUrl,false))}})};XmlHttpRequest2.prototype.empty=function empty(){this._index.fileIterator(function(file){file.fileData=null})};XmlHttpRequest2.prototype.getName=function getName(){return XmlHttpRequest2.Name};XmlHttpRequest2.prototype.diskSpace=function diskSpace(path$$1,cb){cb(0,0)};XmlHttpRequest2.prototype.isReadOnly=function isReadOnly(){return true};XmlHttpRequest2.prototype.supportsLinks=function supportsLinks(){return false};XmlHttpRequest2.prototype.supportsProps=function supportsProps(){return false};XmlHttpRequest2.prototype.supportsSynch=function supportsSynch(){return true};XmlHttpRequest2.prototype.preloadFile=function preloadFile(path$$1,buffer$$1){var inode=this._index.getInode(path$$1);if(isFileInode(inode)){if(inode===null){throw ApiError.ENOENT(path$$1)}var stats=inode.getData();stats.size=buffer$$1.length;stats.fileData=buffer$$1}else{throw ApiError.EISDIR(path$$1)}};XmlHttpRequest2.prototype.stat=function stat(path$$1,isLstat,cb){var inode=this._index.getInode(path$$1);if(inode===null){return cb(ApiError.ENOENT(path$$1))}var stats;if(isFileInode(inode)){stats=inode.getData();if(stats.size<0){this._requestFileSizeAsync(path$$1,function(e,size){if(e){return cb(e)}stats.size=size;cb(null,stats.clone())})}else{cb(null,stats.clone())}}else if(isDirInode(inode)){stats=inode.getStats();cb(null,stats)}else{cb(ApiError.FileError(ErrorCode.EINVAL,path$$1))}};XmlHttpRequest2.prototype.statSync=function statSync(path$$1,isLstat){var inode=this._index.getInode(path$$1);if(inode===null){throw ApiError.ENOENT(path$$1)}var stats;if(isFileInode(inode)){stats=inode.getData();if(stats.size<0){stats.size=this._requestFileSizeSync(path$$1)}}else if(isDirInode(inode)){stats=inode.getStats()}else{throw ApiError.FileError(ErrorCode.EINVAL,path$$1)}return stats};XmlHttpRequest2.prototype.open=function open(path$$1,flags,mode,cb){if(flags.isWriteable()){return cb(new ApiError(ErrorCode.EPERM,path$$1))}var self2=this;var inode=this._index.getInode(path$$1);if(inode===null){return cb(ApiError.ENOENT(path$$1))}if(isFileInode(inode)){var stats=inode.getData();switch(flags.pathExistsAction()){case ActionType.THROW_EXCEPTION:case ActionType.TRUNCATE_FILE:return cb(ApiError.EEXIST(path$$1));case ActionType.NOP:if(stats.fileData){return cb(null,new NoSyncFile(self2,path$$1,flags,stats.clone(),stats.fileData))}this._requestFileAsync(path$$1,"buffer",function(err,buffer$$1){if(err){return cb(err)}stats.size=buffer$$1.length;stats.fileData=buffer$$1;return cb(null,new NoSyncFile(self2,path$$1,flags,stats.clone(),buffer$$1))});break;default:return cb(new ApiError(ErrorCode.EINVAL,"Invalid FileMode object."))}}else{return cb(ApiError.EISDIR(path$$1))}};XmlHttpRequest2.prototype.openSync=function openSync(path$$1,flags,mode){if(flags.isWriteable()){throw new ApiError(ErrorCode.EPERM,path$$1)}var inode=this._index.getInode(path$$1);if(inode===null){throw ApiError.ENOENT(path$$1)}if(isFileInode(inode)){var stats=inode.getData();switch(flags.pathExistsAction()){case ActionType.THROW_EXCEPTION:case ActionType.TRUNCATE_FILE:throw ApiError.EEXIST(path$$1);case ActionType.NOP:if(stats.fileData){return new NoSyncFile(this,path$$1,flags,stats.clone(),stats.fileData)}var buffer$$1=this._requestFileSync(path$$1,"buffer");stats.size=buffer$$1.length;stats.fileData=buffer$$1;return new NoSyncFile(this,path$$1,flags,stats.clone(),buffer$$1);default:throw new ApiError(ErrorCode.EINVAL,"Invalid FileMode object.")}}else{throw ApiError.EISDIR(path$$1)}};XmlHttpRequest2.prototype.readdir=function readdir(path$$1,cb){try{cb(null,this.readdirSync(path$$1))}catch(e){cb(e)}};XmlHttpRequest2.prototype.readdirSync=function readdirSync(path$$1){var inode=this._index.getInode(path$$1);if(inode===null){throw ApiError.ENOENT(path$$1)}else if(isDirInode(inode)){return inode.getListing()}else{throw ApiError.ENOTDIR(path$$1)}};XmlHttpRequest2.prototype.readFile=function readFile2(fname,encoding,flag,cb){var oldCb=cb;this.open(fname,flag,420,function(err,fd){if(err){return cb(err)}cb=function(err2,arg){fd.close(function(err22){if(!err2){err2=err22}return oldCb(err2,arg)})};var fdCast=fd;var fdBuff=fdCast.getBuffer();if(encoding===null){cb(err,copyingSlice(fdBuff))}else{tryToString(fdBuff,encoding,cb)}})};XmlHttpRequest2.prototype.readFileSync=function readFileSync(fname,encoding,flag){var fd=this.openSync(fname,flag,420);try{var fdCast=fd;var fdBuff=fdCast.getBuffer();if(encoding===null){return copyingSlice(fdBuff)}return fdBuff.toString(encoding)}finally{fd.closeSync()}};XmlHttpRequest2.prototype.getXhrPath=function getXhrPath(filePath){if(filePath.charAt(0)==="/"){filePath=filePath.slice(1)}return this.prefixUrl+filePath};XmlHttpRequest2.prototype._requestFileAsync=function _requestFileAsync(p,type,cb){asyncDownloadFile(this.getXhrPath(p),type,cb)};XmlHttpRequest2.prototype._requestFileSync=function _requestFileSync(p,type){return syncDownloadFile(this.getXhrPath(p),type)};XmlHttpRequest2.prototype._requestFileSizeAsync=function _requestFileSizeAsync(path$$1,cb){getFileSizeAsync(this.getXhrPath(path$$1),cb)};XmlHttpRequest2.prototype._requestFileSizeSync=function _requestFileSizeSync(path$$1){return getFileSizeSync(this.getXhrPath(path$$1))};return XmlHttpRequest2}(BaseFileSystem);XmlHttpRequest.Name="XmlHttpRequest";XmlHttpRequest.Options={index:{type:["string","object"],optional:true,description:"URL to a file index as a JSON file or the file index object itself, generated with the make_xhrfs_index script. Defaults to `index.json`."},baseUrl:{type:"string",optional:true,description:"Used as the URL prefix for fetched files. Default: Fetch files relative to the index."}};var ExtendedASCII=function ExtendedASCII2(){};ExtendedASCII.str2byte=function str2byte(str,buf){var length=str.length>buf.length?buf.length:str.length;for(var i2=0;i2127){var charIdx=ExtendedASCII.extendedChars.indexOf(str.charAt(i2));if(charIdx>-1){charCode=charIdx+128}}buf[charCode]=i2}return length};ExtendedASCII.byte2str=function byte2str(buff){var chars=new Array(buff.length);for(var i2=0;i2127){chars[i2]=ExtendedASCII.extendedChars[charCode-128]}else{chars[i2]=String.fromCharCode(charCode)}}return chars.join("")};ExtendedASCII.byteLength=function byteLength(str){return str.length};ExtendedASCII.extendedChars=["\xC7","\xFC","\xE9","\xE2","\xE4","\xE0","\xE5","\xE7","\xEA","\xEB","\xE8","\xEF","\xEE","\xEC","\xC4","\xC5","\xC9","\xE6","\xC6","\xF4","\xF6","\xF2","\xFB","\xF9","\xFF","\xD6","\xDC","\xF8","\xA3","\xD8","\xD7","\u0192","\xE1","\xED","\xF3","\xFA","\xF1","\xD1","\xAA","\xBA","\xBF","\xAE","\xAC","\xBD","\xBC","\xA1","\xAB","\xBB","_","_","_","\xA6","\xA6","\xC1","\xC2","\xC0","\xA9","\xA6","\xA6","+","+","\xA2","\xA5","+","+","-","-","+","-","+","\xE3","\xC3","+","+","-","-","\xA6","-","+","\xA4","\xF0","\xD0","\xCA","\xCB","\xC8","i","\xCD","\xCE","\xCF","+","+","_","_","\xA6","\xCC","_","\xD3","\xDF","\xD4","\xD2","\xF5","\xD5","\xB5","\xFE","\xDE","\xDA","\xDB","\xD9","\xFD","\xDD","\xAF","\xB4","\xAD","\xB1","_","\xBE","\xB6","\xA7","\xF7","\xB8","\xB0","\xA8","\xB7","\xB9","\xB3","\xB2","_"," "];var inflateRaw=__webpack_require__(31).inflateRaw;var decompressionMethods={};var ExternalFileAttributeType;(function(ExternalFileAttributeType2){ExternalFileAttributeType2[ExternalFileAttributeType2["MSDOS"]=0]="MSDOS";ExternalFileAttributeType2[ExternalFileAttributeType2["AMIGA"]=1]="AMIGA";ExternalFileAttributeType2[ExternalFileAttributeType2["OPENVMS"]=2]="OPENVMS";ExternalFileAttributeType2[ExternalFileAttributeType2["UNIX"]=3]="UNIX";ExternalFileAttributeType2[ExternalFileAttributeType2["VM_CMS"]=4]="VM_CMS";ExternalFileAttributeType2[ExternalFileAttributeType2["ATARI_ST"]=5]="ATARI_ST";ExternalFileAttributeType2[ExternalFileAttributeType2["OS2_HPFS"]=6]="OS2_HPFS";ExternalFileAttributeType2[ExternalFileAttributeType2["MAC"]=7]="MAC";ExternalFileAttributeType2[ExternalFileAttributeType2["Z_SYSTEM"]=8]="Z_SYSTEM";ExternalFileAttributeType2[ExternalFileAttributeType2["CP_M"]=9]="CP_M";ExternalFileAttributeType2[ExternalFileAttributeType2["NTFS"]=10]="NTFS";ExternalFileAttributeType2[ExternalFileAttributeType2["MVS"]=11]="MVS";ExternalFileAttributeType2[ExternalFileAttributeType2["VSE"]=12]="VSE";ExternalFileAttributeType2[ExternalFileAttributeType2["ACORN_RISC"]=13]="ACORN_RISC";ExternalFileAttributeType2[ExternalFileAttributeType2["VFAT"]=14]="VFAT";ExternalFileAttributeType2[ExternalFileAttributeType2["ALT_MVS"]=15]="ALT_MVS";ExternalFileAttributeType2[ExternalFileAttributeType2["BEOS"]=16]="BEOS";ExternalFileAttributeType2[ExternalFileAttributeType2["TANDEM"]=17]="TANDEM";ExternalFileAttributeType2[ExternalFileAttributeType2["OS_400"]=18]="OS_400";ExternalFileAttributeType2[ExternalFileAttributeType2["OSX"]=19]="OSX"})(ExternalFileAttributeType||(ExternalFileAttributeType={}));var CompressionMethod;(function(CompressionMethod2){CompressionMethod2[CompressionMethod2["STORED"]=0]="STORED";CompressionMethod2[CompressionMethod2["SHRUNK"]=1]="SHRUNK";CompressionMethod2[CompressionMethod2["REDUCED_1"]=2]="REDUCED_1";CompressionMethod2[CompressionMethod2["REDUCED_2"]=3]="REDUCED_2";CompressionMethod2[CompressionMethod2["REDUCED_3"]=4]="REDUCED_3";CompressionMethod2[CompressionMethod2["REDUCED_4"]=5]="REDUCED_4";CompressionMethod2[CompressionMethod2["IMPLODE"]=6]="IMPLODE";CompressionMethod2[CompressionMethod2["DEFLATE"]=8]="DEFLATE";CompressionMethod2[CompressionMethod2["DEFLATE64"]=9]="DEFLATE64";CompressionMethod2[CompressionMethod2["TERSE_OLD"]=10]="TERSE_OLD";CompressionMethod2[CompressionMethod2["BZIP2"]=12]="BZIP2";CompressionMethod2[CompressionMethod2["LZMA"]=14]="LZMA";CompressionMethod2[CompressionMethod2["TERSE_NEW"]=18]="TERSE_NEW";CompressionMethod2[CompressionMethod2["LZ77"]=19]="LZ77";CompressionMethod2[CompressionMethod2["WAVPACK"]=97]="WAVPACK";CompressionMethod2[CompressionMethod2["PPMD"]=98]="PPMD"})(CompressionMethod||(CompressionMethod={}));function msdos2date(time,date){var day=date&31;var month=(date>>5&15)-1;var year=(date>>9)+1980;var second=time&31;var minute=time>>5&63;var hour=time>>11;return new Date(year,month,day,hour,minute,second)}function safeToString(buff,useUTF8,start,length){if(length===0){return""}else if(useUTF8){return buff.toString("utf8",start,start+length)}else{return ExtendedASCII.byte2str(buff.slice(start,start+length))}}var FileHeader=function FileHeader2(data){this.data=data;if(data.readUInt32LE(0)!==67324752){throw new ApiError(ErrorCode.EINVAL,"Invalid Zip file: Local file header has invalid signature: "+this.data.readUInt32LE(0))}};FileHeader.prototype.versionNeeded=function versionNeeded(){return this.data.readUInt16LE(4)};FileHeader.prototype.flags=function flags(){return this.data.readUInt16LE(6)};FileHeader.prototype.compressionMethod=function compressionMethod(){return this.data.readUInt16LE(8)};FileHeader.prototype.lastModFileTime=function lastModFileTime(){return msdos2date(this.data.readUInt16LE(10),this.data.readUInt16LE(12))};FileHeader.prototype.rawLastModFileTime=function rawLastModFileTime(){return this.data.readUInt32LE(10)};FileHeader.prototype.crc32=function crc32(){return this.data.readUInt32LE(14)};FileHeader.prototype.fileNameLength=function fileNameLength(){return this.data.readUInt16LE(26)};FileHeader.prototype.extraFieldLength=function extraFieldLength(){return this.data.readUInt16LE(28)};FileHeader.prototype.fileName=function fileName(){return safeToString(this.data,this.useUTF8(),30,this.fileNameLength())};FileHeader.prototype.extraField=function extraField(){var start=30+this.fileNameLength();return this.data.slice(start,start+this.extraFieldLength())};FileHeader.prototype.totalSize=function totalSize(){return 30+this.fileNameLength()+this.extraFieldLength()};FileHeader.prototype.useUTF8=function useUTF8(){return(this.flags()&2048)===2048};var FileData=function FileData2(header,record,data){this.header=header;this.record=record;this.data=data};FileData.prototype.decompress=function decompress(){var compressionMethod=this.header.compressionMethod();var fcn=decompressionMethods[compressionMethod];if(fcn){return fcn(this.data,this.record.compressedSize(),this.record.uncompressedSize(),this.record.flag())}else{var name=CompressionMethod[compressionMethod];if(!name){name="Unknown: "+compressionMethod}throw new ApiError(ErrorCode.EINVAL,"Invalid compression method on file '"+this.header.fileName()+"': "+name)}};FileData.prototype.getHeader=function getHeader(){return this.header};FileData.prototype.getRecord=function getRecord(){return this.record};FileData.prototype.getRawData=function getRawData(){return this.data};var DataDescriptor=function DataDescriptor2(data){this.data=data};DataDescriptor.prototype.crc32=function crc32(){return this.data.readUInt32LE(0)};DataDescriptor.prototype.compressedSize=function compressedSize(){return this.data.readUInt32LE(4)};DataDescriptor.prototype.uncompressedSize=function uncompressedSize(){return this.data.readUInt32LE(8)};var ArchiveExtraDataRecord=function ArchiveExtraDataRecord2(data){this.data=data;if(this.data.readUInt32LE(0)!==134630224){throw new ApiError(ErrorCode.EINVAL,"Invalid archive extra data record signature: "+this.data.readUInt32LE(0))}};ArchiveExtraDataRecord.prototype.length=function length(){return this.data.readUInt32LE(4)};ArchiveExtraDataRecord.prototype.extraFieldData=function extraFieldData(){return this.data.slice(8,8+this.length())};var DigitalSignature=function DigitalSignature2(data){this.data=data;if(this.data.readUInt32LE(0)!==84233040){throw new ApiError(ErrorCode.EINVAL,"Invalid digital signature signature: "+this.data.readUInt32LE(0))}};DigitalSignature.prototype.size=function size(){return this.data.readUInt16LE(4)};DigitalSignature.prototype.signatureData=function signatureData(){return this.data.slice(6,6+this.size())};var CentralDirectory=function CentralDirectory2(zipData,data){this.zipData=zipData;this.data=data;if(this.data.readUInt32LE(0)!==33639248){throw new ApiError(ErrorCode.EINVAL,"Invalid Zip file: Central directory record has invalid signature: "+this.data.readUInt32LE(0))}this._filename=this.produceFilename()};CentralDirectory.prototype.versionMadeBy=function versionMadeBy(){return this.data.readUInt16LE(4)};CentralDirectory.prototype.versionNeeded=function versionNeeded(){return this.data.readUInt16LE(6)};CentralDirectory.prototype.flag=function flag(){return this.data.readUInt16LE(8)};CentralDirectory.prototype.compressionMethod=function compressionMethod(){return this.data.readUInt16LE(10)};CentralDirectory.prototype.lastModFileTime=function lastModFileTime(){return msdos2date(this.data.readUInt16LE(12),this.data.readUInt16LE(14))};CentralDirectory.prototype.rawLastModFileTime=function rawLastModFileTime(){return this.data.readUInt32LE(12)};CentralDirectory.prototype.crc32=function crc32(){return this.data.readUInt32LE(16)};CentralDirectory.prototype.compressedSize=function compressedSize(){return this.data.readUInt32LE(20)};CentralDirectory.prototype.uncompressedSize=function uncompressedSize(){return this.data.readUInt32LE(24)};CentralDirectory.prototype.fileNameLength=function fileNameLength(){return this.data.readUInt16LE(28)};CentralDirectory.prototype.extraFieldLength=function extraFieldLength(){return this.data.readUInt16LE(30)};CentralDirectory.prototype.fileCommentLength=function fileCommentLength(){return this.data.readUInt16LE(32)};CentralDirectory.prototype.diskNumberStart=function diskNumberStart(){return this.data.readUInt16LE(34)};CentralDirectory.prototype.internalAttributes=function internalAttributes(){return this.data.readUInt16LE(36)};CentralDirectory.prototype.externalAttributes=function externalAttributes(){return this.data.readUInt32LE(38)};CentralDirectory.prototype.headerRelativeOffset=function headerRelativeOffset(){return this.data.readUInt32LE(42)};CentralDirectory.prototype.produceFilename=function produceFilename(){var fileName=safeToString(this.data,this.useUTF8(),46,this.fileNameLength());return fileName.replace(/\\/g,"/")};CentralDirectory.prototype.fileName=function fileName(){return this._filename};CentralDirectory.prototype.rawFileName=function rawFileName(){return this.data.slice(46,46+this.fileNameLength())};CentralDirectory.prototype.extraField=function extraField(){var start=44+this.fileNameLength();return this.data.slice(start,start+this.extraFieldLength())};CentralDirectory.prototype.fileComment=function fileComment(){var start=46+this.fileNameLength()+this.extraFieldLength();return safeToString(this.data,this.useUTF8(),start,this.fileCommentLength())};CentralDirectory.prototype.rawFileComment=function rawFileComment(){var start=46+this.fileNameLength()+this.extraFieldLength();return this.data.slice(start,start+this.fileCommentLength())};CentralDirectory.prototype.totalSize=function totalSize(){return 46+this.fileNameLength()+this.extraFieldLength()+this.fileCommentLength()};CentralDirectory.prototype.isDirectory=function isDirectory(){var fileName=this.fileName();return(this.externalAttributes()&16?true:false)||fileName.charAt(fileName.length-1)==="/"};CentralDirectory.prototype.isFile=function isFile(){return!this.isDirectory()};CentralDirectory.prototype.useUTF8=function useUTF8(){return(this.flag()&2048)===2048};CentralDirectory.prototype.isEncrypted=function isEncrypted(){return(this.flag()&1)===1};CentralDirectory.prototype.getFileData=function getFileData(){var start=this.headerRelativeOffset();var header=new FileHeader(this.zipData.slice(start));return new FileData(header,this,this.zipData.slice(start+header.totalSize()))};CentralDirectory.prototype.getData=function getData(){return this.getFileData().decompress()};CentralDirectory.prototype.getRawData=function getRawData(){return this.getFileData().getRawData()};CentralDirectory.prototype.getStats=function getStats(){return new Stats(FileType.FILE,this.uncompressedSize(),365,new Date,this.lastModFileTime())};var EndOfCentralDirectory=function EndOfCentralDirectory2(data){this.data=data;if(this.data.readUInt32LE(0)!==101010256){throw new ApiError(ErrorCode.EINVAL,"Invalid Zip file: End of central directory record has invalid signature: "+this.data.readUInt32LE(0))}};EndOfCentralDirectory.prototype.diskNumber=function diskNumber(){return this.data.readUInt16LE(4)};EndOfCentralDirectory.prototype.cdDiskNumber=function cdDiskNumber(){return this.data.readUInt16LE(6)};EndOfCentralDirectory.prototype.cdDiskEntryCount=function cdDiskEntryCount(){return this.data.readUInt16LE(8)};EndOfCentralDirectory.prototype.cdTotalEntryCount=function cdTotalEntryCount(){return this.data.readUInt16LE(10)};EndOfCentralDirectory.prototype.cdSize=function cdSize(){return this.data.readUInt32LE(12)};EndOfCentralDirectory.prototype.cdOffset=function cdOffset(){return this.data.readUInt32LE(16)};EndOfCentralDirectory.prototype.cdZipCommentLength=function cdZipCommentLength(){return this.data.readUInt16LE(20)};EndOfCentralDirectory.prototype.cdZipComment=function cdZipComment(){return safeToString(this.data,true,22,this.cdZipCommentLength())};EndOfCentralDirectory.prototype.rawCdZipComment=function rawCdZipComment(){return this.data.slice(22,22+this.cdZipCommentLength())};var ZipTOC=function ZipTOC2(index,directoryEntries,eocd,data){this.index=index;this.directoryEntries=directoryEntries;this.eocd=eocd;this.data=data};var ZipFS=function(SynchronousFileSystem$$1){function ZipFS2(input,name,deprecateMsg){if(name===void 0)name="";if(deprecateMsg===void 0)deprecateMsg=true;SynchronousFileSystem$$1.call(this);this.name=name;this._index=new FileIndex;this._directoryEntries=[];this._eocd=null;deprecationMessage(deprecateMsg,ZipFS2.Name,{zipData:"zip data as a Buffer",name});if(input instanceof ZipTOC){this._index=input.index;this._directoryEntries=input.directoryEntries;this._eocd=input.eocd;this.data=input.data}else{this.data=input;this.populateIndex()}}if(SynchronousFileSystem$$1)ZipFS2.__proto__=SynchronousFileSystem$$1;ZipFS2.prototype=Object.create(SynchronousFileSystem$$1&&SynchronousFileSystem$$1.prototype);ZipFS2.prototype.constructor=ZipFS2;ZipFS2.Create=function Create(opts,cb){try{ZipFS2.computeIndex(opts.zipData,function(zipTOC){var fs4=new ZipFS2(zipTOC,opts.name,false);cb(null,fs4)},false)}catch(e){cb(e)}};ZipFS2.isAvailable=function isAvailable(){return true};ZipFS2.RegisterDecompressionMethod=function RegisterDecompressionMethod(m,fcn){decompressionMethods[m]=fcn};ZipFS2.computeIndex=function computeIndex(data,cb,deprecateMsg){if(deprecateMsg===void 0)deprecateMsg=true;if(deprecateMsg){console.warn("[ZipFS] ZipFS.computeIndex is now deprecated, and will be removed in the next major release. Please update your code to use 'ZipFS.Create({ zipData: zip file as a Buffer}, cb)' instead.")}var index=new FileIndex;var eocd=ZipFS2.getEOCD(data);if(eocd.diskNumber()!==eocd.cdDiskNumber()){throw new ApiError(ErrorCode.EINVAL,"ZipFS does not support spanned zip files.")}var cdPtr=eocd.cdOffset();if(cdPtr===4294967295){throw new ApiError(ErrorCode.EINVAL,"ZipFS does not support Zip64.")}var cdEnd=cdPtr+eocd.cdSize();ZipFS2.computeIndexResponsive(data,index,cdPtr,cdEnd,cb,[],eocd)};ZipFS2.getEOCD=function getEOCD(data){var startOffset=22;var endOffset=Math.min(startOffset+65535,data.length-1);for(var i2=startOffset;i2-1};DirectoryRecord.prototype.getRockRidgeOffset=function getRockRidgeOffset(){return this._rockRidgeOffset};DirectoryRecord.prototype.rootCheckForRockRidge=function rootCheckForRockRidge(isoData){var dir=this.getDirectory(isoData);this._rockRidgeOffset=dir.getDotEntry(isoData)._getRockRidgeOffset(isoData);if(this._rockRidgeOffset>-1){this._fileOrDir=null}};DirectoryRecord.prototype.length=function length(){return this._data[0]};DirectoryRecord.prototype.extendedAttributeRecordLength=function extendedAttributeRecordLength(){return this._data[1]};DirectoryRecord.prototype.lba=function lba(){return this._data.readUInt32LE(2)*2048};DirectoryRecord.prototype.dataLength=function dataLength(){return this._data.readUInt32LE(10)};DirectoryRecord.prototype.recordingDate=function recordingDate(){return getShortFormDate(this._data,18)};DirectoryRecord.prototype.fileFlags=function fileFlags(){return this._data[25]};DirectoryRecord.prototype.fileUnitSize=function fileUnitSize(){return this._data[26]};DirectoryRecord.prototype.interleaveGapSize=function interleaveGapSize(){return this._data[27]};DirectoryRecord.prototype.volumeSequenceNumber=function volumeSequenceNumber(){return this._data.readUInt16LE(28)};DirectoryRecord.prototype.identifier=function identifier(){return this._getString(33,this._data[32])};DirectoryRecord.prototype.fileName=function fileName(isoData){if(this.hasRockRidge()){var fn=this._rockRidgeFilename(isoData);if(fn!==null){return fn}}var ident=this.identifier();if(this.isDirectory(isoData)){return ident}var versionSeparator=ident.indexOf(";");if(versionSeparator===-1){return ident}else if(ident[versionSeparator-1]==="."){return ident.slice(0,versionSeparator-1)}else{return ident.slice(0,versionSeparator)}};DirectoryRecord.prototype.isDirectory=function isDirectory(isoData){var rv=!!(this.fileFlags()&2);if(!rv&&this.hasRockRidge()){rv=this.getSUEntries(isoData).filter(function(e){return e instanceof CLEntry}).length>0}return rv};DirectoryRecord.prototype.isSymlink=function isSymlink(isoData){return this.hasRockRidge()&&this.getSUEntries(isoData).filter(function(e){return e instanceof SLEntry}).length>0};DirectoryRecord.prototype.getSymlinkPath=function getSymlinkPath(isoData){var p="";var entries=this.getSUEntries(isoData);var getStr=this._getGetString();for(var i2=0,list2=entries;i21&&p[p.length-1]==="/"){return p.slice(0,p.length-1)}else{return p}};DirectoryRecord.prototype.getFile=function getFile(isoData){if(this.isDirectory(isoData)){throw new Error("Tried to get a File from a directory.")}if(this._fileOrDir===null){this._fileOrDir=isoData.slice(this.lba(),this.lba()+this.dataLength())}return this._fileOrDir};DirectoryRecord.prototype.getDirectory=function getDirectory(isoData){if(!this.isDirectory(isoData)){throw new Error("Tried to get a Directory from a file.")}if(this._fileOrDir===null){this._fileOrDir=this._constructDirectory(isoData)}return this._fileOrDir};DirectoryRecord.prototype.getSUEntries=function getSUEntries(isoData){if(!this._suEntries){this._constructSUEntries(isoData)}return this._suEntries};DirectoryRecord.prototype._rockRidgeFilename=function _rockRidgeFilename(isoData){var nmEntries=this.getSUEntries(isoData).filter(function(e2){return e2 instanceof NMEntry});if(nmEntries.length===0||nmEntries[0].flags()&(2|4)){return null}var str="";var getString=this._getGetString();for(var i2=0,list2=nmEntries;i20){var spEntry=suEntries[0];if(spEntry instanceof SPEntry&&spEntry.checkBytesPass()){for(var i2=1;i2K_MAX_LENGTH){throw new RangeError("Invalid typed array length")}var buf=new Uint8Array(length);buf.__proto__=Buffer2.prototype;return buf}function Buffer2(arg,encodingOrOffset,length){if(typeof arg==="number"){if(typeof encodingOrOffset==="string"){throw new Error("If encoding is specified then the first argument must be a string")}return allocUnsafe(arg)}return from(arg,encodingOrOffset,length)}if(typeof Symbol!=="undefined"&&Symbol.species&&Buffer2[Symbol.species]===Buffer2){Object.defineProperty(Buffer2,Symbol.species,{value:null,configurable:true,enumerable:false,writable:false})}Buffer2.poolSize=8192;function from(value,encodingOrOffset,length){if(typeof value==="number"){throw new TypeError('"value" argument must not be a number')}if(isArrayBuffer(value)){return fromArrayBuffer(value,encodingOrOffset,length)}if(typeof value==="string"){return fromString(value,encodingOrOffset)}return fromObject(value)}Buffer2.from=function(value,encodingOrOffset,length){return from(value,encodingOrOffset,length)};Buffer2.prototype.__proto__=Uint8Array.prototype;Buffer2.__proto__=Uint8Array;function assertSize(size){if(typeof size!=="number"){throw new TypeError('"size" argument must be a number')}else if(size<0){throw new RangeError('"size" argument must not be negative')}}function alloc(size,fill,encoding){assertSize(size);if(size<=0){return createBuffer(size)}if(fill!==void 0){return typeof encoding==="string"?createBuffer(size).fill(fill,encoding):createBuffer(size).fill(fill)}return createBuffer(size)}Buffer2.alloc=function(size,fill,encoding){return alloc(size,fill,encoding)};function allocUnsafe(size){assertSize(size);return createBuffer(size<0?0:checked(size)|0)}Buffer2.allocUnsafe=function(size){return allocUnsafe(size)};Buffer2.allocUnsafeSlow=function(size){return allocUnsafe(size)};function fromString(string,encoding){if(typeof encoding!=="string"||encoding===""){encoding="utf8"}if(!Buffer2.isEncoding(encoding)){throw new TypeError('"encoding" must be a valid string encoding')}var length=byteLength(string,encoding)|0;var buf=createBuffer(length);var actual=buf.write(string,encoding);if(actual!==length){buf=buf.slice(0,actual)}return buf}function fromArrayLike(array){var length=array.length<0?0:checked(array.length)|0;var buf=createBuffer(length);for(var i=0;i=K_MAX_LENGTH){throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+K_MAX_LENGTH.toString(16)+" bytes")}return length|0}function SlowBuffer(length){if(+length!=length){length=0}return Buffer2.alloc(+length)}Buffer2.isBuffer=function isBuffer(b){return b!=null&&b._isBuffer===true};Buffer2.compare=function compare(a,b){if(!Buffer2.isBuffer(a)||!Buffer2.isBuffer(b)){throw new TypeError("Arguments must be Buffers")}if(a===b)return 0;var x=a.length;var y=b.length;for(var i=0,len=Math.min(x,y);i>>1;case"base64":return base64ToBytes(string).length;default:if(loweredCase)return utf8ToBytes(string).length;encoding=(""+encoding).toLowerCase();loweredCase=true}}}Buffer2.byteLength=byteLength;function slowToString(encoding,start,end){var loweredCase=false;if(start===void 0||start<0){start=0}if(start>this.length){return""}if(end===void 0||end>this.length){end=this.length}if(end<=0){return""}end>>>=0;start>>>=0;if(end<=start){return""}if(!encoding)encoding="utf8";while(true){switch(encoding){case"hex":return hexSlice(this,start,end);case"utf8":case"utf-8":return utf8Slice(this,start,end);case"ascii":return asciiSlice(this,start,end);case"latin1":case"binary":return latin1Slice(this,start,end);case"base64":return base64Slice(this,start,end);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return utf16leSlice(this,start,end);default:if(loweredCase)throw new TypeError("Unknown encoding: "+encoding);encoding=(encoding+"").toLowerCase();loweredCase=true}}}Buffer2.prototype._isBuffer=true;function swap(b,n,m){var i=b[n];b[n]=b[m];b[m]=i}Buffer2.prototype.swap16=function swap16(){var len=this.length;if(len%2!==0){throw new RangeError("Buffer size must be a multiple of 16-bits")}for(var i=0;i0){str=this.toString("hex",0,max).match(/.{2}/g).join(" ");if(this.length>max)str+=" ... "}return""};Buffer2.prototype.compare=function compare(target,start,end,thisStart,thisEnd){if(!Buffer2.isBuffer(target)){throw new TypeError("Argument must be a Buffer")}if(start===void 0){start=0}if(end===void 0){end=target?target.length:0}if(thisStart===void 0){thisStart=0}if(thisEnd===void 0){thisEnd=this.length}if(start<0||end>target.length||thisStart<0||thisEnd>this.length){throw new RangeError("out of range index")}if(thisStart>=thisEnd&&start>=end){return 0}if(thisStart>=thisEnd){return-1}if(start>=end){return 1}start>>>=0;end>>>=0;thisStart>>>=0;thisEnd>>>=0;if(this===target)return 0;var x=thisEnd-thisStart;var y=end-start;var len=Math.min(x,y);var thisCopy=this.slice(thisStart,thisEnd);var targetCopy=target.slice(start,end);for(var i=0;i2147483647){byteOffset=2147483647}else if(byteOffset<-2147483648){byteOffset=-2147483648}byteOffset=+byteOffset;if(numberIsNaN(byteOffset)){byteOffset=dir?0:buffer.length-1}if(byteOffset<0)byteOffset=buffer.length+byteOffset;if(byteOffset>=buffer.length){if(dir)return-1;else byteOffset=buffer.length-1}else if(byteOffset<0){if(dir)byteOffset=0;else return-1}if(typeof val==="string"){val=Buffer2.from(val,encoding)}if(Buffer2.isBuffer(val)){if(val.length===0){return-1}return arrayIndexOf(buffer,val,byteOffset,encoding,dir)}else if(typeof val==="number"){val=val&255;if(typeof Uint8Array.prototype.indexOf==="function"){if(dir){return Uint8Array.prototype.indexOf.call(buffer,val,byteOffset)}else{return Uint8Array.prototype.lastIndexOf.call(buffer,val,byteOffset)}}return arrayIndexOf(buffer,[val],byteOffset,encoding,dir)}throw new TypeError("val must be string, number or Buffer")}function arrayIndexOf(arr,val,byteOffset,encoding,dir){var indexSize=1;var arrLength=arr.length;var valLength=val.length;if(encoding!==void 0){encoding=String(encoding).toLowerCase();if(encoding==="ucs2"||encoding==="ucs-2"||encoding==="utf16le"||encoding==="utf-16le"){if(arr.length<2||val.length<2){return-1}indexSize=2;arrLength/=2;valLength/=2;byteOffset/=2}}function read(buf,i2){if(indexSize===1){return buf[i2]}else{return buf.readUInt16BE(i2*indexSize)}}var i;if(dir){var foundIndex=-1;for(i=byteOffset;iarrLength)byteOffset=arrLength-valLength;for(i=byteOffset;i>=0;i--){var found=true;for(var j=0;jremaining){length=remaining}}var strLen=string.length;if(strLen%2!==0)throw new TypeError("Invalid hex string");if(length>strLen/2){length=strLen/2}for(var i=0;i>>0;if(isFinite(length)){length=length>>>0;if(encoding===void 0)encoding="utf8"}else{encoding=length;length=void 0}}else{throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported")}var remaining=this.length-offset;if(length===void 0||length>remaining)length=remaining;if(string.length>0&&(length<0||offset<0)||offset>this.length){throw new RangeError("Attempt to write outside buffer bounds")}if(!encoding)encoding="utf8";var loweredCase=false;for(;;){switch(encoding){case"hex":return hexWrite(this,string,offset,length);case"utf8":case"utf-8":return utf8Write(this,string,offset,length);case"ascii":return asciiWrite(this,string,offset,length);case"latin1":case"binary":return latin1Write(this,string,offset,length);case"base64":return base64Write(this,string,offset,length);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return ucs2Write(this,string,offset,length);default:if(loweredCase)throw new TypeError("Unknown encoding: "+encoding);encoding=(""+encoding).toLowerCase();loweredCase=true}}};Buffer2.prototype.toJSON=function toJSON(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function base64Slice(buf,start,end){if(start===0&&end===buf.length){return base64.fromByteArray(buf)}else{return base64.fromByteArray(buf.slice(start,end))}}function utf8Slice(buf,start,end){end=Math.min(buf.length,end);var res=[];var i=start;while(i239?4:firstByte>223?3:firstByte>191?2:1;if(i+bytesPerSequence<=end){var secondByte,thirdByte,fourthByte,tempCodePoint;switch(bytesPerSequence){case 1:if(firstByte<128){codePoint=firstByte}break;case 2:secondByte=buf[i+1];if((secondByte&192)===128){tempCodePoint=(firstByte&31)<<6|secondByte&63;if(tempCodePoint>127){codePoint=tempCodePoint}}break;case 3:secondByte=buf[i+1];thirdByte=buf[i+2];if((secondByte&192)===128&&(thirdByte&192)===128){tempCodePoint=(firstByte&15)<<12|(secondByte&63)<<6|thirdByte&63;if(tempCodePoint>2047&&(tempCodePoint<55296||tempCodePoint>57343)){codePoint=tempCodePoint}}break;case 4:secondByte=buf[i+1];thirdByte=buf[i+2];fourthByte=buf[i+3];if((secondByte&192)===128&&(thirdByte&192)===128&&(fourthByte&192)===128){tempCodePoint=(firstByte&15)<<18|(secondByte&63)<<12|(thirdByte&63)<<6|fourthByte&63;if(tempCodePoint>65535&&tempCodePoint<1114112){codePoint=tempCodePoint}}}}if(codePoint===null){codePoint=65533;bytesPerSequence=1}else if(codePoint>65535){codePoint-=65536;res.push(codePoint>>>10&1023|55296);codePoint=56320|codePoint&1023}res.push(codePoint);i+=bytesPerSequence}return decodeCodePointsArray(res)}var MAX_ARGUMENTS_LENGTH=4096;function decodeCodePointsArray(codePoints){var len=codePoints.length;if(len<=MAX_ARGUMENTS_LENGTH){return String.fromCharCode.apply(String,codePoints)}var res="";var i=0;while(ilen)end=len;var out="";for(var i=start;ilen){start=len}if(end<0){end+=len;if(end<0)end=0}else if(end>len){end=len}if(endlength)throw new RangeError("Trying to access beyond buffer length")}Buffer2.prototype.readUIntLE=function readUIntLE(offset,byteLength2,noAssert){offset=offset>>>0;byteLength2=byteLength2>>>0;if(!noAssert)checkOffset(offset,byteLength2,this.length);var val=this[offset];var mul=1;var i=0;while(++i>>0;byteLength2=byteLength2>>>0;if(!noAssert){checkOffset(offset,byteLength2,this.length)}var val=this[offset+--byteLength2];var mul=1;while(byteLength2>0&&(mul*=256)){val+=this[offset+--byteLength2]*mul}return val};Buffer2.prototype.readUInt8=function readUInt8(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,1,this.length);return this[offset]};Buffer2.prototype.readUInt16LE=function readUInt16LE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,2,this.length);return this[offset]|this[offset+1]<<8};Buffer2.prototype.readUInt16BE=function readUInt16BE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,2,this.length);return this[offset]<<8|this[offset+1]};Buffer2.prototype.readUInt32LE=function readUInt32LE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,4,this.length);return(this[offset]|this[offset+1]<<8|this[offset+2]<<16)+this[offset+3]*16777216};Buffer2.prototype.readUInt32BE=function readUInt32BE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,4,this.length);return this[offset]*16777216+(this[offset+1]<<16|this[offset+2]<<8|this[offset+3])};Buffer2.prototype.readIntLE=function readIntLE(offset,byteLength2,noAssert){offset=offset>>>0;byteLength2=byteLength2>>>0;if(!noAssert)checkOffset(offset,byteLength2,this.length);var val=this[offset];var mul=1;var i=0;while(++i=mul)val-=Math.pow(2,8*byteLength2);return val};Buffer2.prototype.readIntBE=function readIntBE(offset,byteLength2,noAssert){offset=offset>>>0;byteLength2=byteLength2>>>0;if(!noAssert)checkOffset(offset,byteLength2,this.length);var i=byteLength2;var mul=1;var val=this[offset+--i];while(i>0&&(mul*=256)){val+=this[offset+--i]*mul}mul*=128;if(val>=mul)val-=Math.pow(2,8*byteLength2);return val};Buffer2.prototype.readInt8=function readInt8(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,1,this.length);if(!(this[offset]&128))return this[offset];return(255-this[offset]+1)*-1};Buffer2.prototype.readInt16LE=function readInt16LE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,2,this.length);var val=this[offset]|this[offset+1]<<8;return val&32768?val|4294901760:val};Buffer2.prototype.readInt16BE=function readInt16BE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,2,this.length);var val=this[offset+1]|this[offset]<<8;return val&32768?val|4294901760:val};Buffer2.prototype.readInt32LE=function readInt32LE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,4,this.length);return this[offset]|this[offset+1]<<8|this[offset+2]<<16|this[offset+3]<<24};Buffer2.prototype.readInt32BE=function readInt32BE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,4,this.length);return this[offset]<<24|this[offset+1]<<16|this[offset+2]<<8|this[offset+3]};Buffer2.prototype.readFloatLE=function readFloatLE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,4,this.length);return ieee754.read(this,offset,true,23,4)};Buffer2.prototype.readFloatBE=function readFloatBE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,4,this.length);return ieee754.read(this,offset,false,23,4)};Buffer2.prototype.readDoubleLE=function readDoubleLE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,8,this.length);return ieee754.read(this,offset,true,52,8)};Buffer2.prototype.readDoubleBE=function readDoubleBE(offset,noAssert){offset=offset>>>0;if(!noAssert)checkOffset(offset,8,this.length);return ieee754.read(this,offset,false,52,8)};function checkInt(buf,value,offset,ext,max,min){if(!Buffer2.isBuffer(buf))throw new TypeError('"buffer" argument must be a Buffer instance');if(value>max||valuebuf.length)throw new RangeError("Index out of range")}Buffer2.prototype.writeUIntLE=function writeUIntLE(value,offset,byteLength2,noAssert){value=+value;offset=offset>>>0;byteLength2=byteLength2>>>0;if(!noAssert){var maxBytes=Math.pow(2,8*byteLength2)-1;checkInt(this,value,offset,byteLength2,maxBytes,0)}var mul=1;var i=0;this[offset]=value&255;while(++i>>0;byteLength2=byteLength2>>>0;if(!noAssert){var maxBytes=Math.pow(2,8*byteLength2)-1;checkInt(this,value,offset,byteLength2,maxBytes,0)}var i=byteLength2-1;var mul=1;this[offset+i]=value&255;while(--i>=0&&(mul*=256)){this[offset+i]=value/mul&255}return offset+byteLength2};Buffer2.prototype.writeUInt8=function writeUInt8(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,1,255,0);this[offset]=value&255;return offset+1};Buffer2.prototype.writeUInt16LE=function writeUInt16LE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,2,65535,0);this[offset]=value&255;this[offset+1]=value>>>8;return offset+2};Buffer2.prototype.writeUInt16BE=function writeUInt16BE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,2,65535,0);this[offset]=value>>>8;this[offset+1]=value&255;return offset+2};Buffer2.prototype.writeUInt32LE=function writeUInt32LE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,4,4294967295,0);this[offset+3]=value>>>24;this[offset+2]=value>>>16;this[offset+1]=value>>>8;this[offset]=value&255;return offset+4};Buffer2.prototype.writeUInt32BE=function writeUInt32BE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,4,4294967295,0);this[offset]=value>>>24;this[offset+1]=value>>>16;this[offset+2]=value>>>8;this[offset+3]=value&255;return offset+4};Buffer2.prototype.writeIntLE=function writeIntLE(value,offset,byteLength2,noAssert){value=+value;offset=offset>>>0;if(!noAssert){var limit=Math.pow(2,8*byteLength2-1);checkInt(this,value,offset,byteLength2,limit-1,-limit)}var i=0;var mul=1;var sub=0;this[offset]=value&255;while(++i>0)-sub&255}return offset+byteLength2};Buffer2.prototype.writeIntBE=function writeIntBE(value,offset,byteLength2,noAssert){value=+value;offset=offset>>>0;if(!noAssert){var limit=Math.pow(2,8*byteLength2-1);checkInt(this,value,offset,byteLength2,limit-1,-limit)}var i=byteLength2-1;var mul=1;var sub=0;this[offset+i]=value&255;while(--i>=0&&(mul*=256)){if(value<0&&sub===0&&this[offset+i+1]!==0){sub=1}this[offset+i]=(value/mul>>0)-sub&255}return offset+byteLength2};Buffer2.prototype.writeInt8=function writeInt8(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,1,127,-128);if(value<0)value=255+value+1;this[offset]=value&255;return offset+1};Buffer2.prototype.writeInt16LE=function writeInt16LE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,2,32767,-32768);this[offset]=value&255;this[offset+1]=value>>>8;return offset+2};Buffer2.prototype.writeInt16BE=function writeInt16BE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,2,32767,-32768);this[offset]=value>>>8;this[offset+1]=value&255;return offset+2};Buffer2.prototype.writeInt32LE=function writeInt32LE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,4,2147483647,-2147483648);this[offset]=value&255;this[offset+1]=value>>>8;this[offset+2]=value>>>16;this[offset+3]=value>>>24;return offset+4};Buffer2.prototype.writeInt32BE=function writeInt32BE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,4,2147483647,-2147483648);if(value<0)value=4294967295+value+1;this[offset]=value>>>24;this[offset+1]=value>>>16;this[offset+2]=value>>>8;this[offset+3]=value&255;return offset+4};function checkIEEE754(buf,value,offset,ext,max,min){if(offset+ext>buf.length)throw new RangeError("Index out of range");if(offset<0)throw new RangeError("Index out of range")}function writeFloat(buf,value,offset,littleEndian,noAssert){value=+value;offset=offset>>>0;if(!noAssert){checkIEEE754(buf,value,offset,4,34028234663852886e22,-34028234663852886e22)}ieee754.write(buf,value,offset,littleEndian,23,4);return offset+4}Buffer2.prototype.writeFloatLE=function writeFloatLE(value,offset,noAssert){return writeFloat(this,value,offset,true,noAssert)};Buffer2.prototype.writeFloatBE=function writeFloatBE(value,offset,noAssert){return writeFloat(this,value,offset,false,noAssert)};function writeDouble(buf,value,offset,littleEndian,noAssert){value=+value;offset=offset>>>0;if(!noAssert){checkIEEE754(buf,value,offset,8,17976931348623157e292,-17976931348623157e292)}ieee754.write(buf,value,offset,littleEndian,52,8);return offset+8}Buffer2.prototype.writeDoubleLE=function writeDoubleLE(value,offset,noAssert){return writeDouble(this,value,offset,true,noAssert)};Buffer2.prototype.writeDoubleBE=function writeDoubleBE(value,offset,noAssert){return writeDouble(this,value,offset,false,noAssert)};Buffer2.prototype.copy=function copy(target,targetStart,start,end){if(!start)start=0;if(!end&&end!==0)end=this.length;if(targetStart>=target.length)targetStart=target.length;if(!targetStart)targetStart=0;if(end>0&&end=this.length)throw new RangeError("sourceStart out of bounds");if(end<0)throw new RangeError("sourceEnd out of bounds");if(end>this.length)end=this.length;if(target.length-targetStart=0;--i){target[i+targetStart]=this[i+start]}}else if(len<1e3){for(i=0;i>>0;end=end===void 0?this.length:end>>>0;if(!val)val=0;var i;if(typeof val==="number"){for(i=start;i55295&&codePoint<57344){if(!leadSurrogate){if(codePoint>56319){if((units-=3)>-1)bytes.push(239,191,189);continue}else if(i+1===length){if((units-=3)>-1)bytes.push(239,191,189);continue}leadSurrogate=codePoint;continue}if(codePoint<56320){if((units-=3)>-1)bytes.push(239,191,189);leadSurrogate=codePoint;continue}codePoint=(leadSurrogate-55296<<10|codePoint-56320)+65536}else if(leadSurrogate){if((units-=3)>-1)bytes.push(239,191,189)}leadSurrogate=null;if(codePoint<128){if((units-=1)<0)break;bytes.push(codePoint)}else if(codePoint<2048){if((units-=2)<0)break;bytes.push(codePoint>>6|192,codePoint&63|128)}else if(codePoint<65536){if((units-=3)<0)break;bytes.push(codePoint>>12|224,codePoint>>6&63|128,codePoint&63|128)}else if(codePoint<1114112){if((units-=4)<0)break;bytes.push(codePoint>>18|240,codePoint>>12&63|128,codePoint>>6&63|128,codePoint&63|128)}else{throw new Error("Invalid code point")}}return bytes}function asciiToBytes(str){var byteArray=[];for(var i=0;i>8;lo=c%256;byteArray.push(lo);byteArray.push(hi)}return byteArray}function base64ToBytes(str){return base64.toByteArray(base64clean(str))}function blitBuffer(src,dst,offset,length){for(var i=0;i=dst.length||i>=src.length)break;dst[i+offset]=src[i]}return i}function isArrayBuffer(obj){return obj instanceof ArrayBuffer||obj!=null&&obj.constructor!=null&&obj.constructor.name==="ArrayBuffer"&&typeof obj.byteLength==="number"}function isArrayBufferView(obj){return typeof ArrayBuffer.isView==="function"&&ArrayBuffer.isView(obj)}function numberIsNaN(obj){return obj!==obj}}).call(exports2,__webpack_require__(1))},function(module2,exports2){"use strict";exports2.byteLength=byteLength;exports2.toByteArray=toByteArray;exports2.fromByteArray=fromByteArray;var lookup=[];var revLookup=[];var Arr=typeof Uint8Array!=="undefined"?Uint8Array:Array;var code="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(var i=0,len=code.length;i0){throw new Error("Invalid string. Length must be a multiple of 4")}return b64[len2-2]==="="?2:b64[len2-1]==="="?1:0}function byteLength(b64){return b64.length*3/4-placeHoldersCount(b64)}function toByteArray(b64){var i2,j,l,tmp,placeHolders,arr;var len2=b64.length;placeHolders=placeHoldersCount(b64);arr=new Arr(len2*3/4-placeHolders);l=placeHolders>0?len2-4:len2;var L=0;for(i2=0,j=0;i2>16&255;arr[L++]=tmp>>8&255;arr[L++]=tmp&255}if(placeHolders===2){tmp=revLookup[b64.charCodeAt(i2)]<<2|revLookup[b64.charCodeAt(i2+1)]>>4;arr[L++]=tmp&255}else if(placeHolders===1){tmp=revLookup[b64.charCodeAt(i2)]<<10|revLookup[b64.charCodeAt(i2+1)]<<4|revLookup[b64.charCodeAt(i2+2)]>>2;arr[L++]=tmp>>8&255;arr[L++]=tmp&255}return arr}function tripletToBase64(num){return lookup[num>>18&63]+lookup[num>>12&63]+lookup[num>>6&63]+lookup[num&63]}function encodeChunk(uint8,start,end){var tmp;var output=[];for(var i2=start;i2len22?len22:i2+maxChunkLength))}if(extraBytes===1){tmp=uint8[len2-1];output+=lookup[tmp>>2];output+=lookup[tmp<<4&63];output+="=="}else if(extraBytes===2){tmp=(uint8[len2-2]<<8)+uint8[len2-1];output+=lookup[tmp>>10];output+=lookup[tmp>>4&63];output+=lookup[tmp<<2&63];output+="="}parts.push(output);return parts.join("")}},function(module2,exports2){exports2.read=function(buffer,offset,isLE,mLen,nBytes){var e,m;var eLen=nBytes*8-mLen-1;var eMax=(1<>1;var nBits=-7;var i=isLE?nBytes-1:0;var d=isLE?-1:1;var s=buffer[offset+i];i+=d;e=s&(1<<-nBits)-1;s>>=-nBits;nBits+=eLen;for(;nBits>0;e=e*256+buffer[offset+i],i+=d,nBits-=8){}m=e&(1<<-nBits)-1;e>>=-nBits;nBits+=mLen;for(;nBits>0;m=m*256+buffer[offset+i],i+=d,nBits-=8){}if(e===0){e=1-eBias}else if(e===eMax){return m?NaN:(s?-1:1)*Infinity}else{m=m+Math.pow(2,mLen);e=e-eBias}return(s?-1:1)*m*Math.pow(2,e-mLen)};exports2.write=function(buffer,value,offset,isLE,mLen,nBytes){var e,m,c;var eLen=nBytes*8-mLen-1;var eMax=(1<>1;var rt=mLen===23?Math.pow(2,-24)-Math.pow(2,-77):0;var i=isLE?0:nBytes-1;var d=isLE?1:-1;var s=value<0||value===0&&1/value<0?1:0;value=Math.abs(value);if(isNaN(value)||value===Infinity){m=isNaN(value)?1:0;e=eMax}else{e=Math.floor(Math.log(value)/Math.LN2);if(value*(c=Math.pow(2,-e))<1){e--;c*=2}if(e+eBias>=1){value+=rt/c}else{value+=rt*Math.pow(2,1-eBias)}if(value*c>=2){e++;c/=2}if(e+eBias>=eMax){m=0;e=eMax}else if(e+eBias>=1){m=(value*c-1)*Math.pow(2,mLen);e=e+eBias}else{m=value*Math.pow(2,eBias-1)*Math.pow(2,mLen);e=0}}for(;mLen>=8;buffer[offset+i]=m&255,i+=d,m/=256,mLen-=8){}e=e<0;buffer[offset+i]=e&255,i+=d,e/=256,eLen-=8){}buffer[offset+i-d]|=s*128}},function(module2,exports2){module2.exports=function(module3){if(!module3.webpackPolyfill){module3.deprecate=function(){};module3.paths=[];module3.children=[];module3.webpackPolyfill=1}return module3}},function(module2,exports2,__webpack_require__){"use strict";var Process=__webpack_require__(7);var process=new Process,processProxy={};function defineKey(key2){if(processProxy[key2]){return}if(typeof process[key2]==="function"){processProxy[key2]=function(){return process[key2].apply(process,arguments)}}else{processProxy[key2]=process[key2]}}for(var key in process){defineKey(key)}processProxy.initializeTTYs=function(){if(process.stdin===null){process.initializeTTYs();processProxy.stdin=process.stdin;processProxy.stdout=process.stdout;processProxy.stderr=process.stderr}};process.nextTick(function(){processProxy.initializeTTYs()});module2.exports=processProxy},function(module2,exports2,__webpack_require__){(function(__dirname){"use strict";var __extends=this&&this.__extends||function(d,b){for(var p in b)if(b.hasOwnProperty(p))d[p]=b[p];function __(){this.constructor=d}d.prototype=b===null?Object.create(b):(__.prototype=b.prototype,new __)};var events=__webpack_require__(8);var path=null;var Item=function(){function Item2(fun,array){this.fun=fun;this.array=array}Item2.prototype.run=function(){this.fun.apply(null,this.array)};return Item2}();var NextTickQueue=function(){function NextTickQueue2(){this._queue=[];this._draining=false;this._currentQueue=null;this._queueIndex=-1}NextTickQueue2.prototype.push=function(item){var _this=this;if(this._queue.push(item)===1&&!this._draining){setTimeout(function(){return _this._drainQueue()},0)}};NextTickQueue2.prototype._cleanUpNextTick=function(){this._draining=false;if(this._currentQueue&&this._currentQueue.length){this._queue=this._currentQueue.concat(this._queue)}else{this._queueIndex=-1}if(this._queue.length){this._drainQueue()}};NextTickQueue2.prototype._drainQueue=function(){var _this=this;if(this._draining){return}var timeout=setTimeout(function(){return _this._cleanUpNextTick()});this._draining=true;var len=this._queue.length;while(len){this._currentQueue=this._queue;this._queue=[];while(++this._queueIndex0&&this._events[type].length>m){this._events[type].warned=true;console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[type].length);if(typeof console.trace==="function"){console.trace()}}}return this};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.once=function(type,listener){if(!isFunction(listener))throw TypeError("listener must be a function");var fired=false;function g(){this.removeListener(type,g);if(!fired){fired=true;listener.apply(this,arguments)}}g.listener=listener;this.on(type,g);return this};EventEmitter.prototype.removeListener=function(type,listener){var list,position,length,i;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events||!this._events[type])return this;list=this._events[type];length=list.length;position=-1;if(list===listener||isFunction(list.listener)&&list.listener===listener){delete this._events[type];if(this._events.removeListener)this.emit("removeListener",type,listener)}else if(isObject(list)){for(i=length;i-- >0;){if(list[i]===listener||list[i].listener&&list[i].listener===listener){position=i;break}}if(position<0)return this;if(list.length===1){list.length=0;delete this._events[type]}else{list.splice(position,1)}if(this._events.removeListener)this.emit("removeListener",type,listener)}return this};EventEmitter.prototype.removeAllListeners=function(type){var key,listeners;if(!this._events)return this;if(!this._events.removeListener){if(arguments.length===0)this._events={};else if(this._events[type])delete this._events[type];return this}if(arguments.length===0){for(key in this._events){if(key==="removeListener")continue;this.removeAllListeners(key)}this.removeAllListeners("removeListener");this._events={};return this}listeners=this._events[type];if(isFunction(listeners)){this.removeListener(type,listeners)}else if(listeners){while(listeners.length)this.removeListener(type,listeners[listeners.length-1])}delete this._events[type];return this};EventEmitter.prototype.listeners=function(type){var ret;if(!this._events||!this._events[type])ret=[];else if(isFunction(this._events[type]))ret=[this._events[type]];else ret=this._events[type].slice();return ret};EventEmitter.prototype.listenerCount=function(type){if(this._events){var evlistener=this._events[type];if(isFunction(evlistener))return 1;else if(evlistener)return evlistener.length}return 0};EventEmitter.listenerCount=function(emitter,type){return emitter.listenerCount(type)};function isFunction(arg){return typeof arg==="function"}function isNumber(arg){return typeof arg==="number"}function isObject(arg){return typeof arg==="object"&&arg!==null}function isUndefined(arg){return arg===void 0}},function(module2,exports2,__webpack_require__){(function(process){"use strict";var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;function posixSplitPath(filename){var out=splitPathRe.exec(filename);out.shift();return out}var path=function(){function path2(){}path2.normalize=function(p){if(p===""){p="."}var absolute=p.charAt(0)===path2.sep;p=path2._removeDuplicateSeps(p);var components=p.split(path2.sep);var goodComponents=[];for(var idx=0;idx0&&goodComponents[0]!=="..")){goodComponents.pop()}else{goodComponents.push(c)}}if(!absolute&&goodComponents.length<2){switch(goodComponents.length){case 1:if(goodComponents[0]===""){goodComponents.unshift(".")}break;default:goodComponents.push(".")}}p=goodComponents.join(path2.sep);if(absolute&&p.charAt(0)!==path2.sep){p=path2.sep+p}return p};path2.join=function(){var paths=[];for(var _i=0;_i1&&resolved.charAt(resolved.length-1)===path2.sep){return resolved.substr(0,resolved.length-1)}if(resolved.charAt(0)!==path2.sep){if(resolved.charAt(0)==="."&&(resolved.length===1||resolved.charAt(1)===path2.sep)){resolved=resolved.length===1?"":resolved.substr(2)}var cwd=process.cwd();if(resolved!==""){resolved=this.normalize(cwd+(cwd!=="/"?path2.sep:"")+resolved)}else{resolved=cwd}}return resolved};path2.relative=function(from,to){var i;from=path2.resolve(from);to=path2.resolve(to);var fromSegs=from.split(path2.sep);var toSegs=to.split(path2.sep);toSegs.shift();fromSegs.shift();var upCount=0;var downSegs=[];for(i=0;ifromSegs.length){upCount=fromSegs.length}var rv="";for(i=0;i1&&rv.charAt(rv.length-1)===path2.sep){rv=rv.substr(0,rv.length-1)}return rv};path2.dirname=function(p){p=path2._removeDuplicateSeps(p);var absolute=p.charAt(0)===path2.sep;var sections=p.split(path2.sep);if(sections.pop()===""&§ions.length>0){sections.pop()}if(sections.length>1||sections.length===1&&!absolute){return sections.join(path2.sep)}else if(absolute){return path2.sep}else{return"."}};path2.basename=function(p,ext){if(ext===void 0){ext=""}if(p===""){return p}p=path2.normalize(p);var sections=p.split(path2.sep);var lastPart=sections[sections.length-1];if(lastPart===""&§ions.length>1){return sections[sections.length-2]}if(ext.length>0){var lastPartExt=lastPart.substr(lastPart.length-ext.length);if(lastPartExt===ext){return lastPart.substr(0,lastPart.length-ext.length)}}return lastPart};path2.extname=function(p){p=path2.normalize(p);var sections=p.split(path2.sep);p=sections.pop();if(p===""&§ions.length>0){p=sections.pop()}if(p===".."){return""}var i=p.lastIndexOf(".");if(i===-1||i===0){return""}return p.substr(i)};path2.isAbsolute=function(p){return p.length>0&&p.charAt(0)===path2.sep};path2._makeLong=function(p){return p};path2.parse=function(p){var allParts=posixSplitPath(p);return{root:allParts[0],dir:allParts[0]+allParts[1].slice(0,-1),base:allParts[2],ext:allParts[3],name:allParts[2].slice(0,allParts[2].length-allParts[3].length)}};path2.format=function(pathObject){if(pathObject===null||typeof pathObject!=="object"){throw new TypeError("Parameter 'pathObject' must be an object, not "+typeof pathObject)}var root=pathObject.root||"";if(typeof root!=="string"){throw new TypeError("'pathObject.root' must be a string or undefined, not "+typeof pathObject.root)}var dir=pathObject.dir?pathObject.dir+path2.sep:"";var base=pathObject.base||"";return dir+base};path2._removeDuplicateSeps=function(p){p=p.replace(this._replaceRegex,this.sep);return p};path2.sep="/";path2._replaceRegex=new RegExp("//+","g");path2.delimiter=":";path2.posix=path2;path2.win32=path2;return path2}();var _=path;module2.exports=path}).call(exports2,__webpack_require__(6))},function(module2,exports2,__webpack_require__){(function(Buffer2){"use strict";var __extends=this&&this.__extends||function(d,b){for(var p in b)if(b.hasOwnProperty(p))d[p]=b[p];function __(){this.constructor=d}d.prototype=b===null?Object.create(b):(__.prototype=b.prototype,new __)};var stream=__webpack_require__(11);var TTY=function(_super){__extends(TTY2,_super);function TTY2(){_super.call(this);this.isRaw=false;this.columns=80;this.rows=120;this.isTTY=true;this._bufferedWrites=[];this._waitingForWrites=false}TTY2.prototype.setRawMode=function(mode){if(this.isRaw!==mode){this.isRaw=mode;this.emit("modeChange")}};TTY2.prototype.changeColumns=function(columns){if(columns!==this.columns){this.columns=columns;this.emit("resize")}};TTY2.prototype.changeRows=function(rows){if(rows!==this.rows){this.rows=rows;this.emit("resize")}};TTY2.isatty=function(fd){return fd&&fd instanceof TTY2};TTY2.prototype._write=function(chunk,encoding,cb){var error;try{var data;if(typeof chunk==="string"){data=new Buffer2(chunk,encoding)}else{data=chunk}this._bufferedWrites.push(data);if(this._waitingForWrites){this._read(1024)}}catch(e){error=e}finally{cb(error)}};TTY2.prototype._read=function(size){if(this._bufferedWrites.length===0){this._waitingForWrites=true}else{while(this._bufferedWrites.length>0){this._waitingForWrites=this.push(this._bufferedWrites.shift());if(!this._waitingForWrites){break}}}};return TTY2}(stream.Duplex);module2.exports=TTY}).call(exports2,__webpack_require__(1))},function(module2,exports2,__webpack_require__){module2.exports=Stream;var EE=__webpack_require__(8).EventEmitter;var inherits=__webpack_require__(12);inherits(Stream,EE);Stream.Readable=__webpack_require__(13);Stream.Writable=__webpack_require__(27);Stream.Duplex=__webpack_require__(28);Stream.Transform=__webpack_require__(29);Stream.PassThrough=__webpack_require__(30);Stream.Stream=Stream;function Stream(){EE.call(this)}Stream.prototype.pipe=function(dest,options){var source=this;function ondata(chunk){if(dest.writable){if(false===dest.write(chunk)&&source.pause){source.pause()}}}source.on("data",ondata);function ondrain(){if(source.readable&&source.resume){source.resume()}}dest.on("drain",ondrain);if(!dest._isStdio&&(!options||options.end!==false)){source.on("end",onend);source.on("close",onclose)}var didOnEnd=false;function onend(){if(didOnEnd)return;didOnEnd=true;dest.end()}function onclose(){if(didOnEnd)return;didOnEnd=true;if(typeof dest.destroy==="function")dest.destroy()}function onerror(er){cleanup();if(EE.listenerCount(this,"error")===0){throw er}}source.on("error",onerror);dest.on("error",onerror);function cleanup(){source.removeListener("data",ondata);dest.removeListener("drain",ondrain);source.removeListener("end",onend);source.removeListener("close",onclose);source.removeListener("error",onerror);dest.removeListener("error",onerror);source.removeListener("end",cleanup);source.removeListener("close",cleanup);dest.removeListener("close",cleanup)}source.on("end",cleanup);source.on("close",cleanup);dest.on("close",cleanup);dest.emit("pipe",source);return dest}},function(module2,exports2){if(typeof Object.create==="function"){module2.exports=function inherits(ctor,superCtor){ctor.super_=superCtor;ctor.prototype=Object.create(superCtor.prototype,{constructor:{value:ctor,enumerable:false,writable:true,configurable:true}})}}else{module2.exports=function inherits(ctor,superCtor){ctor.super_=superCtor;var TempCtor=function(){};TempCtor.prototype=superCtor.prototype;ctor.prototype=new TempCtor;ctor.prototype.constructor=ctor}}},function(module2,exports2,__webpack_require__){(function(process){var Stream=function(){try{return __webpack_require__(11)}catch(_){}}();exports2=module2.exports=__webpack_require__(14);exports2.Stream=Stream||exports2;exports2.Readable=exports2;exports2.Writable=__webpack_require__(22);exports2.Duplex=__webpack_require__(21);exports2.Transform=__webpack_require__(25);exports2.PassThrough=__webpack_require__(26);if(!process.browser&&process.env.READABLE_STREAM==="disable"&&Stream){module2.exports=Stream}}).call(exports2,__webpack_require__(6))},function(module2,exports2,__webpack_require__){(function(process){"use strict";module2.exports=Readable;var processNextTick=__webpack_require__(15);var isArray=__webpack_require__(16);var Duplex;Readable.ReadableState=ReadableState;var EE=__webpack_require__(8).EventEmitter;var EElistenerCount=function(emitter,type){return emitter.listeners(type).length};var Stream;(function(){try{Stream=__webpack_require__(11)}catch(_){}finally{if(!Stream)Stream=__webpack_require__(8).EventEmitter}})();var Buffer2=__webpack_require__(2).Buffer;var bufferShim=__webpack_require__(17);var util=__webpack_require__(18);util.inherits=__webpack_require__(12);var debugUtil=__webpack_require__(19);var debug=void 0;if(debugUtil&&debugUtil.debuglog){debug=debugUtil.debuglog("stream")}else{debug=function(){}}var BufferList=__webpack_require__(20);var StringDecoder;util.inherits(Readable,Stream);function prependListener(emitter,event,fn){if(typeof emitter.prependListener==="function"){return emitter.prependListener(event,fn)}else{if(!emitter._events||!emitter._events[event])emitter.on(event,fn);else if(isArray(emitter._events[event]))emitter._events[event].unshift(fn);else emitter._events[event]=[fn,emitter._events[event]]}}function ReadableState(options,stream){Duplex=Duplex||__webpack_require__(21);options=options||{};this.objectMode=!!options.objectMode;if(stream instanceof Duplex)this.objectMode=this.objectMode||!!options.readableObjectMode;var hwm=options.highWaterMark;var defaultHwm=this.objectMode?16:16*1024;this.highWaterMark=hwm||hwm===0?hwm:defaultHwm;this.highWaterMark=~~this.highWaterMark;this.buffer=new BufferList;this.length=0;this.pipes=null;this.pipesCount=0;this.flowing=null;this.ended=false;this.endEmitted=false;this.reading=false;this.sync=true;this.needReadable=false;this.emittedReadable=false;this.readableListening=false;this.resumeScheduled=false;this.defaultEncoding=options.defaultEncoding||"utf8";this.ranOut=false;this.awaitDrain=0;this.readingMore=false;this.decoder=null;this.encoding=null;if(options.encoding){if(!StringDecoder)StringDecoder=__webpack_require__(24).StringDecoder;this.decoder=new StringDecoder(options.encoding);this.encoding=options.encoding}}function Readable(options){Duplex=Duplex||__webpack_require__(21);if(!(this instanceof Readable))return new Readable(options);this._readableState=new ReadableState(options,this);this.readable=true;if(options&&typeof options.read==="function")this._read=options.read;Stream.call(this)}Readable.prototype.push=function(chunk,encoding){var state=this._readableState;if(!state.objectMode&&typeof chunk==="string"){encoding=encoding||state.defaultEncoding;if(encoding!==state.encoding){chunk=bufferShim.from(chunk,encoding);encoding=""}}return readableAddChunk(this,state,chunk,encoding,false)};Readable.prototype.unshift=function(chunk){var state=this._readableState;return readableAddChunk(this,state,chunk,"",true)};Readable.prototype.isPaused=function(){return this._readableState.flowing===false};function readableAddChunk(stream,state,chunk,encoding,addToFront){var er=chunkInvalid(state,chunk);if(er){stream.emit("error",er)}else if(chunk===null){state.reading=false;onEofChunk(stream,state)}else if(state.objectMode||chunk&&chunk.length>0){if(state.ended&&!addToFront){var e=new Error("stream.push() after EOF");stream.emit("error",e)}else if(state.endEmitted&&addToFront){var _e=new Error("stream.unshift() after end event");stream.emit("error",_e)}else{var skipAdd;if(state.decoder&&!addToFront&&!encoding){chunk=state.decoder.write(chunk);skipAdd=!state.objectMode&&chunk.length===0}if(!addToFront)state.reading=false;if(!skipAdd){if(state.flowing&&state.length===0&&!state.sync){stream.emit("data",chunk);stream.read(0)}else{state.length+=state.objectMode?1:chunk.length;if(addToFront)state.buffer.unshift(chunk);else state.buffer.push(chunk);if(state.needReadable)emitReadable(stream)}}maybeReadMore(stream,state)}}else if(!addToFront){state.reading=false}return needMoreData(state)}function needMoreData(state){return!state.ended&&(state.needReadable||state.length=MAX_HWM){n=MAX_HWM}else{n--;n|=n>>>1;n|=n>>>2;n|=n>>>4;n|=n>>>8;n|=n>>>16;n++}return n}function howMuchToRead(n,state){if(n<=0||state.length===0&&state.ended)return 0;if(state.objectMode)return 1;if(n!==n){if(state.flowing&&state.length)return state.buffer.head.data.length;else return state.length}if(n>state.highWaterMark)state.highWaterMark=computeNewHighWaterMark(n);if(n<=state.length)return n;if(!state.ended){state.needReadable=true;return 0}return state.length}Readable.prototype.read=function(n){debug("read",n);n=parseInt(n,10);var state=this._readableState;var nOrig=n;if(n!==0)state.emittedReadable=false;if(n===0&&state.needReadable&&(state.length>=state.highWaterMark||state.ended)){debug("read: emitReadable",state.length,state.ended);if(state.length===0&&state.ended)endReadable(this);else emitReadable(this);return null}n=howMuchToRead(n,state);if(n===0&&state.ended){if(state.length===0)endReadable(this);return null}var doRead=state.needReadable;debug("need readable",doRead);if(state.length===0||state.length-n0)ret=fromList(n,state);else ret=null;if(ret===null){state.needReadable=true;n=0}else{state.length-=n}if(state.length===0){if(!state.ended)state.needReadable=true;if(nOrig!==n&&state.ended)endReadable(this)}if(ret!==null)this.emit("data",ret);return ret};function chunkInvalid(state,chunk){var er=null;if(!Buffer2.isBuffer(chunk)&&typeof chunk!=="string"&&chunk!==null&&chunk!==void 0&&!state.objectMode){er=new TypeError("Invalid non-string/buffer chunk")}return er}function onEofChunk(stream,state){if(state.ended)return;if(state.decoder){var chunk=state.decoder.end();if(chunk&&chunk.length){state.buffer.push(chunk);state.length+=state.objectMode?1:chunk.length}}state.ended=true;emitReadable(stream)}function emitReadable(stream){var state=stream._readableState;state.needReadable=false;if(!state.emittedReadable){debug("emitReadable",state.flowing);state.emittedReadable=true;if(state.sync)processNextTick(emitReadable_,stream);else emitReadable_(stream)}}function emitReadable_(stream){debug("emit readable");stream.emit("readable");flow(stream)}function maybeReadMore(stream,state){if(!state.readingMore){state.readingMore=true;processNextTick(maybeReadMore_,stream,state)}}function maybeReadMore_(stream,state){var len=state.length;while(!state.reading&&!state.flowing&&!state.ended&&state.length1&&indexOf(state.pipes,dest)!==-1)&&!cleanedUp){debug("false write response, pause",src._readableState.awaitDrain);src._readableState.awaitDrain++;increasedAwaitDrain=true}src.pause()}}function onerror(er){debug("onerror",er);unpipe();dest.removeListener("error",onerror);if(EElistenerCount(dest,"error")===0)dest.emit("error",er)}prependListener(dest,"error",onerror);function onclose(){dest.removeListener("finish",onfinish);unpipe()}dest.once("close",onclose);function onfinish(){debug("onfinish");dest.removeListener("close",onclose);unpipe()}dest.once("finish",onfinish);function unpipe(){debug("unpipe");src.unpipe(dest)}dest.emit("pipe",src);if(!state.flowing){debug("pipe resume");src.resume()}return dest};function pipeOnDrain(src){return function(){var state=src._readableState;debug("pipeOnDrain",state.awaitDrain);if(state.awaitDrain)state.awaitDrain--;if(state.awaitDrain===0&&EElistenerCount(src,"data")){state.flowing=true;flow(src)}}}Readable.prototype.unpipe=function(dest){var state=this._readableState;if(state.pipesCount===0)return this;if(state.pipesCount===1){if(dest&&dest!==state.pipes)return this;if(!dest)dest=state.pipes;state.pipes=null;state.pipesCount=0;state.flowing=false;if(dest)dest.emit("unpipe",this);return this}if(!dest){var dests=state.pipes;var len=state.pipesCount;state.pipes=null;state.pipesCount=0;state.flowing=false;for(var i=0;i=state.length){if(state.decoder)ret=state.buffer.join("");else if(state.buffer.length===1)ret=state.buffer.head.data;else ret=state.buffer.concat(state.length);state.buffer.clear()}else{ret=fromListPartial(n,state.buffer,state.decoder)}return ret}function fromListPartial(n,list,hasStrings){var ret;if(nstr.length?str.length:n;if(nb===str.length)ret+=str;else ret+=str.slice(0,n);n-=nb;if(n===0){if(nb===str.length){++c;if(p.next)list.head=p.next;else list.head=list.tail=null}else{list.head=p;p.data=str.slice(nb)}break}++c}list.length-=c;return ret}function copyFromBuffer(n,list){var ret=bufferShim.allocUnsafe(n);var p=list.head;var c=1;p.data.copy(ret);n-=p.data.length;while(p=p.next){var buf=p.data;var nb=n>buf.length?buf.length:n;buf.copy(ret,ret.length-n,0,nb);n-=nb;if(n===0){if(nb===buf.length){++c;if(p.next)list.head=p.next;else list.head=list.tail=null}else{list.head=p;p.data=buf.slice(nb)}break}++c}list.length-=c;return ret}function endReadable(stream){var state=stream._readableState;if(state.length>0)throw new Error('"endReadable()" called on non-empty stream');if(!state.endEmitted){state.ended=true;processNextTick(endReadableNT,state,stream)}}function endReadableNT(state,stream){if(!state.endEmitted&&state.length===0){state.endEmitted=true;stream.readable=false;stream.emit("end")}}function forEach(xs,f){for(var i=0,l=xs.length;iMAX_LEN){throw new RangeError("size is too large")}var enc=encoding;var _fill=fill;if(_fill===void 0){enc=void 0;_fill=0}var buf=new Buffer2(size);if(typeof _fill==="string"){var fillBuf=new Buffer2(_fill,enc);var flen=fillBuf.length;var i=-1;while(++iMAX_LEN){throw new RangeError("size is too large")}return new Buffer2(size)};exports2.from=function from(value,encodingOrOffset,length){if(typeof Buffer2.from==="function"&&(!global.Uint8Array||Uint8Array.from!==Buffer2.from)){return Buffer2.from(value,encodingOrOffset,length)}if(typeof value==="number"){throw new TypeError('"value" argument must not be a number')}if(typeof value==="string"){return new Buffer2(value,encodingOrOffset)}if(typeof ArrayBuffer!=="undefined"&&value instanceof ArrayBuffer){var offset=encodingOrOffset;if(arguments.length===1){return new Buffer2(value)}if(typeof offset==="undefined"){offset=0}var len=length;if(typeof len==="undefined"){len=value.byteLength-offset}if(offset>=value.byteLength){throw new RangeError("'offset' is out of bounds")}if(len>value.byteLength-offset){throw new RangeError("'length' is out of bounds")}return new Buffer2(value.slice(offset,offset+len))}if(Buffer2.isBuffer(value)){var out=new Buffer2(value.length);value.copy(out,0,0,value.length);return out}if(value){if(Array.isArray(value)||typeof ArrayBuffer!=="undefined"&&value.buffer instanceof ArrayBuffer||"length"in value){return new Buffer2(value)}if(value.type==="Buffer"&&Array.isArray(value.data)){return new Buffer2(value.data)}}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")};exports2.allocUnsafeSlow=function allocUnsafeSlow(size){if(typeof Buffer2.allocUnsafeSlow==="function"){return Buffer2.allocUnsafeSlow(size)}if(typeof size!=="number"){throw new TypeError("size must be a number")}if(size>=MAX_LEN){throw new RangeError("size is too large")}return new SlowBuffer(size)}}).call(exports2,function(){return this}())},function(module2,exports2,__webpack_require__){(function(Buffer2){function isArray(arg){if(Array.isArray){return Array.isArray(arg)}return objectToString(arg)==="[object Array]"}exports2.isArray=isArray;function isBoolean(arg){return typeof arg==="boolean"}exports2.isBoolean=isBoolean;function isNull(arg){return arg===null}exports2.isNull=isNull;function isNullOrUndefined(arg){return arg==null}exports2.isNullOrUndefined=isNullOrUndefined;function isNumber(arg){return typeof arg==="number"}exports2.isNumber=isNumber;function isString(arg){return typeof arg==="string"}exports2.isString=isString;function isSymbol(arg){return typeof arg==="symbol"}exports2.isSymbol=isSymbol;function isUndefined(arg){return arg===void 0}exports2.isUndefined=isUndefined;function isRegExp(re){return objectToString(re)==="[object RegExp]"}exports2.isRegExp=isRegExp;function isObject(arg){return typeof arg==="object"&&arg!==null}exports2.isObject=isObject;function isDate(d){return objectToString(d)==="[object Date]"}exports2.isDate=isDate;function isError(e){return objectToString(e)==="[object Error]"||e instanceof Error}exports2.isError=isError;function isFunction(arg){return typeof arg==="function"}exports2.isFunction=isFunction;function isPrimitive(arg){return arg===null||typeof arg==="boolean"||typeof arg==="number"||typeof arg==="string"||typeof arg==="symbol"||typeof arg==="undefined"}exports2.isPrimitive=isPrimitive;exports2.isBuffer=Buffer2.isBuffer;function objectToString(o){return Object.prototype.toString.call(o)}}).call(exports2,__webpack_require__(1))},function(module2,exports2){},function(module2,exports2,__webpack_require__){"use strict";var Buffer2=__webpack_require__(2).Buffer;var bufferShim=__webpack_require__(17);module2.exports=BufferList;function BufferList(){this.head=null;this.tail=null;this.length=0}BufferList.prototype.push=function(v){var entry={data:v,next:null};if(this.length>0)this.tail.next=entry;else this.head=entry;this.tail=entry;++this.length};BufferList.prototype.unshift=function(v){var entry={data:v,next:this.head};if(this.length===0)this.tail=entry;this.head=entry;++this.length};BufferList.prototype.shift=function(){if(this.length===0)return;var ret=this.head.data;if(this.length===1)this.head=this.tail=null;else this.head=this.head.next;--this.length;return ret};BufferList.prototype.clear=function(){this.head=this.tail=null;this.length=0};BufferList.prototype.join=function(s){if(this.length===0)return"";var p=this.head;var ret=""+p.data;while(p=p.next){ret+=s+p.data}return ret};BufferList.prototype.concat=function(n){if(this.length===0)return bufferShim.alloc(0);if(this.length===1)return this.head.data;var ret=bufferShim.allocUnsafe(n>>>0);var p=this.head;var i=0;while(p){p.data.copy(ret,i);i+=p.data.length;p=p.next}return ret}},function(module2,exports2,__webpack_require__){"use strict";var objectKeys=Object.keys||function(obj){var keys2=[];for(var key in obj){keys2.push(key)}return keys2};module2.exports=Duplex;var processNextTick=__webpack_require__(15);var util=__webpack_require__(18);util.inherits=__webpack_require__(12);var Readable=__webpack_require__(14);var Writable=__webpack_require__(22);util.inherits(Duplex,Readable);var keys=objectKeys(Writable.prototype);for(var v=0;v-1?setImmediate:processNextTick;var Duplex;Writable.WritableState=WritableState;var util=__webpack_require__(18);util.inherits=__webpack_require__(12);var internalUtil={deprecate:__webpack_require__(23)};var Stream;(function(){try{Stream=__webpack_require__(11)}catch(_){}finally{if(!Stream)Stream=__webpack_require__(8).EventEmitter}})();var Buffer2=__webpack_require__(2).Buffer;var bufferShim=__webpack_require__(17);util.inherits(Writable,Stream);function nop(){}function WriteReq(chunk,encoding,cb){this.chunk=chunk;this.encoding=encoding;this.callback=cb;this.next=null}function WritableState(options,stream){Duplex=Duplex||__webpack_require__(21);options=options||{};this.objectMode=!!options.objectMode;if(stream instanceof Duplex)this.objectMode=this.objectMode||!!options.writableObjectMode;var hwm=options.highWaterMark;var defaultHwm=this.objectMode?16:16*1024;this.highWaterMark=hwm||hwm===0?hwm:defaultHwm;this.highWaterMark=~~this.highWaterMark;this.needDrain=false;this.ending=false;this.ended=false;this.finished=false;var noDecode=options.decodeStrings===false;this.decodeStrings=!noDecode;this.defaultEncoding=options.defaultEncoding||"utf8";this.length=0;this.writing=false;this.corked=0;this.sync=true;this.bufferProcessing=false;this.onwrite=function(er){onwrite(stream,er)};this.writecb=null;this.writelen=0;this.bufferedRequest=null;this.lastBufferedRequest=null;this.pendingcb=0;this.prefinished=false;this.errorEmitted=false;this.bufferedRequestCount=0;this.corkedRequestsFree=new CorkedRequest(this)}WritableState.prototype.getBuffer=function getBuffer(){var current=this.bufferedRequest;var out=[];while(current){out.push(current);current=current.next}return out};(function(){try{Object.defineProperty(WritableState.prototype,"buffer",{get:internalUtil.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.")})}catch(_){}})();var realHasInstance;if(typeof Symbol==="function"&&Symbol.hasInstance&&typeof Function.prototype[Symbol.hasInstance]==="function"){realHasInstance=Function.prototype[Symbol.hasInstance];Object.defineProperty(Writable,Symbol.hasInstance,{value:function(object){if(realHasInstance.call(this,object))return true;return object&&object._writableState instanceof WritableState}})}else{realHasInstance=function(object){return object instanceof this}}function Writable(options){Duplex=Duplex||__webpack_require__(21);if(!realHasInstance.call(Writable,this)&&!(this instanceof Duplex)){return new Writable(options)}this._writableState=new WritableState(options,this);this.writable=true;if(options){if(typeof options.write==="function")this._write=options.write;if(typeof options.writev==="function")this._writev=options.writev}Stream.call(this)}Writable.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))};function writeAfterEnd(stream,cb){var er=new Error("write after end");stream.emit("error",er);processNextTick(cb,er)}function validChunk(stream,state,chunk,cb){var valid=true;var er=false;if(chunk===null){er=new TypeError("May not write null values to stream")}else if(typeof chunk!=="string"&&chunk!==void 0&&!state.objectMode){er=new TypeError("Invalid non-string/buffer chunk")}if(er){stream.emit("error",er);processNextTick(cb,er);valid=false}return valid}Writable.prototype.write=function(chunk,encoding,cb){var state=this._writableState;var ret=false;var isBuf=Buffer2.isBuffer(chunk);if(typeof encoding==="function"){cb=encoding;encoding=null}if(isBuf)encoding="buffer";else if(!encoding)encoding=state.defaultEncoding;if(typeof cb!=="function")cb=nop;if(state.ended)writeAfterEnd(this,cb);else if(isBuf||validChunk(this,state,chunk,cb)){state.pendingcb++;ret=writeOrBuffer(this,state,isBuf,chunk,encoding,cb)}return ret};Writable.prototype.cork=function(){var state=this._writableState;state.corked++};Writable.prototype.uncork=function(){var state=this._writableState;if(state.corked){state.corked--;if(!state.writing&&!state.corked&&!state.finished&&!state.bufferProcessing&&state.bufferedRequest)clearBuffer(this,state)}};Writable.prototype.setDefaultEncoding=function setDefaultEncoding(encoding){if(typeof encoding==="string")encoding=encoding.toLowerCase();if(!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((encoding+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+encoding);this._writableState.defaultEncoding=encoding;return this};function decodeChunk(state,chunk,encoding){if(!state.objectMode&&state.decodeStrings!==false&&typeof chunk==="string"){chunk=bufferShim.from(chunk,encoding)}return chunk}function writeOrBuffer(stream,state,isBuf,chunk,encoding,cb){if(!isBuf){chunk=decodeChunk(state,chunk,encoding);if(Buffer2.isBuffer(chunk))encoding="buffer"}var len=state.objectMode?1:chunk.length;state.length+=len;var ret=state.length=this.charLength-this.charReceived?this.charLength-this.charReceived:buffer.length;buffer.copy(this.charBuffer,this.charReceived,0,available);this.charReceived+=available;if(this.charReceived=55296&&charCode<=56319){this.charLength+=this.surrogateSize;charStr="";continue}this.charReceived=this.charLength=0;if(buffer.length===0){return charStr}break}this.detectIncompleteChar(buffer);var end=buffer.length;if(this.charLength){buffer.copy(this.charBuffer,0,buffer.length-this.charReceived,end);end-=this.charReceived}charStr+=buffer.toString(this.encoding,0,end);var end=charStr.length-1;var charCode=charStr.charCodeAt(end);if(charCode>=55296&&charCode<=56319){var size=this.surrogateSize;this.charLength+=size;this.charReceived+=size;this.charBuffer.copy(this.charBuffer,size,0,size);buffer.copy(this.charBuffer,0,0,size);return charStr.substring(0,end)}return charStr};StringDecoder.prototype.detectIncompleteChar=function(buffer){var i=buffer.length>=3?3:buffer.length;for(;i>0;i--){var c=buffer[buffer.length-i];if(i==1&&c>>5==6){this.charLength=2;break}if(i<=2&&c>>4==14){this.charLength=3;break}if(i<=3&&c>>3==30){this.charLength=4;break}}this.charReceived=i};StringDecoder.prototype.end=function(buffer){var res="";if(buffer&&buffer.length)res=this.write(buffer);if(this.charReceived){var cr=this.charReceived;var buf=this.charBuffer;var enc=this.encoding;res+=buf.slice(0,cr).toString(enc)}return res};function passThroughWrite(buffer){return buffer.toString(this.encoding)}function utf16DetectIncompleteChar(buffer){this.charReceived=buffer.length%2;this.charLength=this.charReceived?2:0}function base64DetectIncompleteChar(buffer){this.charReceived=buffer.length%3;this.charLength=this.charReceived?3:0}},function(module2,exports2,__webpack_require__){"use strict";module2.exports=Transform;var Duplex=__webpack_require__(21);var util=__webpack_require__(18);util.inherits=__webpack_require__(12);util.inherits(Transform,Duplex);function TransformState(stream){this.afterTransform=function(er,data){return afterTransform(stream,er,data)};this.needTransform=false;this.transforming=false;this.writecb=null;this.writechunk=null;this.writeencoding=null}function afterTransform(stream,er,data){var ts=stream._transformState;ts.transforming=false;var cb=ts.writecb;if(!cb)return stream.emit("error",new Error("no writecb in Transform class"));ts.writechunk=null;ts.writecb=null;if(data!==null&&data!==void 0)stream.push(data);cb(er);var rs=stream._readableState;rs.reading=false;if(rs.needReadable||rs.length=0&&opt.windowBits<16){opt.windowBits=-opt.windowBits;if(opt.windowBits===0){opt.windowBits=-15}}if(opt.windowBits>=0&&opt.windowBits<16&&!(options&&options.windowBits)){opt.windowBits+=32}if(opt.windowBits>15&&opt.windowBits<48){if((opt.windowBits&15)===0){opt.windowBits|=15}}this.err=0;this.msg="";this.ended=false;this.chunks=[];this.strm=new ZStream;this.strm.avail_out=0;var status=zlib_inflate.inflateInit2(this.strm,opt.windowBits);if(status!==c.Z_OK){throw new Error(msg[status])}this.header=new GZheader;zlib_inflate.inflateGetHeader(this.strm,this.header)}Inflate.prototype.push=function(data,mode){var strm=this.strm;var chunkSize=this.options.chunkSize;var dictionary=this.options.dictionary;var status,_mode;var next_out_utf8,tail,utf8str;var dict;var allowBufError=false;if(this.ended){return false}_mode=mode===~~mode?mode:mode===true?c.Z_FINISH:c.Z_NO_FLUSH;if(typeof data==="string"){strm.input=strings.binstring2buf(data)}else if(toString.call(data)==="[object ArrayBuffer]"){strm.input=new Uint8Array(data)}else{strm.input=data}strm.next_in=0;strm.avail_in=strm.input.length;do{if(strm.avail_out===0){strm.output=new utils.Buf8(chunkSize);strm.next_out=0;strm.avail_out=chunkSize}status=zlib_inflate.inflate(strm,c.Z_NO_FLUSH);if(status===c.Z_NEED_DICT&&dictionary){if(typeof dictionary==="string"){dict=strings.string2buf(dictionary)}else if(toString.call(dictionary)==="[object ArrayBuffer]"){dict=new Uint8Array(dictionary)}else{dict=dictionary}status=zlib_inflate.inflateSetDictionary(this.strm,dict)}if(status===c.Z_BUF_ERROR&&allowBufError===true){status=c.Z_OK;allowBufError=false}if(status!==c.Z_STREAM_END&&status!==c.Z_OK){this.onEnd(status);this.ended=true;return false}if(strm.next_out){if(strm.avail_out===0||status===c.Z_STREAM_END||strm.avail_in===0&&(_mode===c.Z_FINISH||_mode===c.Z_SYNC_FLUSH)){if(this.options.to==="string"){next_out_utf8=strings.utf8border(strm.output,strm.next_out);tail=strm.next_out-next_out_utf8;utf8str=strings.buf2string(strm.output,next_out_utf8);strm.next_out=tail;strm.avail_out=chunkSize-tail;if(tail){utils.arraySet(strm.output,strm.output,next_out_utf8,tail,0)}this.onData(utf8str)}else{this.onData(utils.shrinkBuf(strm.output,strm.next_out))}}}if(strm.avail_in===0&&strm.avail_out===0){allowBufError=true}}while((strm.avail_in>0||strm.avail_out===0)&&status!==c.Z_STREAM_END);if(status===c.Z_STREAM_END){_mode=c.Z_FINISH}if(_mode===c.Z_FINISH){status=zlib_inflate.inflateEnd(this.strm);this.onEnd(status);this.ended=true;return status===c.Z_OK}if(_mode===c.Z_SYNC_FLUSH){this.onEnd(c.Z_OK);strm.avail_out=0;return true}return true};Inflate.prototype.onData=function(chunk){this.chunks.push(chunk)};Inflate.prototype.onEnd=function(status){if(status===c.Z_OK){if(this.options.to==="string"){this.result=this.chunks.join("")}else{this.result=utils.flattenChunks(this.chunks)}}this.chunks=[];this.err=status;this.msg=this.strm.msg};function inflate(input,options){var inflator=new Inflate(options);inflator.push(input,true);if(inflator.err){throw inflator.msg||msg[inflator.err]}return inflator.result}function inflateRaw(input,options){options=options||{};options.raw=true;return inflate(input,options)}exports2.Inflate=Inflate;exports2.inflate=inflate;exports2.inflateRaw=inflateRaw;exports2.ungzip=inflate},function(module2,exports2,__webpack_require__){"use strict";var utils=__webpack_require__(33);var adler32=__webpack_require__(34);var crc32=__webpack_require__(35);var inflate_fast=__webpack_require__(36);var inflate_table=__webpack_require__(37);var CODES=0;var LENS=1;var DISTS=2;var Z_FINISH=4;var Z_BLOCK=5;var Z_TREES=6;var Z_OK=0;var Z_STREAM_END=1;var Z_NEED_DICT=2;var Z_STREAM_ERROR=-2;var Z_DATA_ERROR=-3;var Z_MEM_ERROR=-4;var Z_BUF_ERROR=-5;var Z_DEFLATED=8;var HEAD=1;var FLAGS=2;var TIME=3;var OS=4;var EXLEN=5;var EXTRA=6;var NAME=7;var COMMENT=8;var HCRC=9;var DICTID=10;var DICT=11;var TYPE=12;var TYPEDO=13;var STORED=14;var COPY_=15;var COPY=16;var TABLE=17;var LENLENS=18;var CODELENS=19;var LEN_=20;var LEN=21;var LENEXT=22;var DIST=23;var DISTEXT=24;var MATCH=25;var LIT=26;var CHECK=27;var LENGTH=28;var DONE=29;var BAD=30;var MEM=31;var SYNC=32;var ENOUGH_LENS=852;var ENOUGH_DISTS=592;var MAX_WBITS=15;var DEF_WBITS=MAX_WBITS;function zswap32(q){return(q>>>24&255)+(q>>>8&65280)+((q&65280)<<8)+((q&255)<<24)}function InflateState(){this.mode=0;this.last=false;this.wrap=0;this.havedict=false;this.flags=0;this.dmax=0;this.check=0;this.total=0;this.head=null;this.wbits=0;this.wsize=0;this.whave=0;this.wnext=0;this.window=null;this.hold=0;this.bits=0;this.length=0;this.offset=0;this.extra=0;this.lencode=null;this.distcode=null;this.lenbits=0;this.distbits=0;this.ncode=0;this.nlen=0;this.ndist=0;this.have=0;this.next=null;this.lens=new utils.Buf16(320);this.work=new utils.Buf16(288);this.lendyn=null;this.distdyn=null;this.sane=0;this.back=0;this.was=0}function inflateResetKeep(strm){var state;if(!strm||!strm.state){return Z_STREAM_ERROR}state=strm.state;strm.total_in=strm.total_out=state.total=0;strm.msg="";if(state.wrap){strm.adler=state.wrap&1}state.mode=HEAD;state.last=0;state.havedict=0;state.dmax=32768;state.head=null;state.hold=0;state.bits=0;state.lencode=state.lendyn=new utils.Buf32(ENOUGH_LENS);state.distcode=state.distdyn=new utils.Buf32(ENOUGH_DISTS);state.sane=1;state.back=-1;return Z_OK}function inflateReset(strm){var state;if(!strm||!strm.state){return Z_STREAM_ERROR}state=strm.state;state.wsize=0;state.whave=0;state.wnext=0;return inflateResetKeep(strm)}function inflateReset2(strm,windowBits){var wrap;var state;if(!strm||!strm.state){return Z_STREAM_ERROR}state=strm.state;if(windowBits<0){wrap=0;windowBits=-windowBits}else{wrap=(windowBits>>4)+1;if(windowBits<48){windowBits&=15}}if(windowBits&&(windowBits<8||windowBits>15)){return Z_STREAM_ERROR}if(state.window!==null&&state.wbits!==windowBits){state.window=null}state.wrap=wrap;state.wbits=windowBits;return inflateReset(strm)}function inflateInit2(strm,windowBits){var ret;var state;if(!strm){return Z_STREAM_ERROR}state=new InflateState;strm.state=state;state.window=null;ret=inflateReset2(strm,windowBits);if(ret!==Z_OK){strm.state=null}return ret}function inflateInit(strm){return inflateInit2(strm,DEF_WBITS)}var virgin=true;var lenfix,distfix;function fixedtables(state){if(virgin){var sym;lenfix=new utils.Buf32(512);distfix=new utils.Buf32(32);sym=0;while(sym<144){state.lens[sym++]=8}while(sym<256){state.lens[sym++]=9}while(sym<280){state.lens[sym++]=7}while(sym<288){state.lens[sym++]=8}inflate_table(LENS,state.lens,0,288,lenfix,0,state.work,{bits:9});sym=0;while(sym<32){state.lens[sym++]=5}inflate_table(DISTS,state.lens,0,32,distfix,0,state.work,{bits:5});virgin=false}state.lencode=lenfix;state.lenbits=9;state.distcode=distfix;state.distbits=5}function updatewindow(strm,src,end,copy){var dist;var state=strm.state;if(state.window===null){state.wsize=1<=state.wsize){utils.arraySet(state.window,src,end-state.wsize,state.wsize,0);state.wnext=0;state.whave=state.wsize}else{dist=state.wsize-state.wnext;if(dist>copy){dist=copy}utils.arraySet(state.window,src,end-copy,dist,state.wnext);copy-=dist;if(copy){utils.arraySet(state.window,src,end-copy,copy,0);state.wnext=copy;state.whave=state.wsize}else{state.wnext+=dist;if(state.wnext===state.wsize){state.wnext=0}if(state.whave>>8&255;state.check=crc32(state.check,hbuf,2,0);hold=0;bits=0;state.mode=FLAGS;break}state.flags=0;if(state.head){state.head.done=false}if(!(state.wrap&1)||(((hold&255)<<8)+(hold>>8))%31){strm.msg="incorrect header check";state.mode=BAD;break}if((hold&15)!==Z_DEFLATED){strm.msg="unknown compression method";state.mode=BAD;break}hold>>>=4;bits-=4;len=(hold&15)+8;if(state.wbits===0){state.wbits=len}else if(len>state.wbits){strm.msg="invalid window size";state.mode=BAD;break}state.dmax=1<>8&1}if(state.flags&512){hbuf[0]=hold&255;hbuf[1]=hold>>>8&255;state.check=crc32(state.check,hbuf,2,0)}hold=0;bits=0;state.mode=TIME;case TIME:while(bits<32){if(have===0){break inf_leave}have--;hold+=input[next++]<>>8&255;hbuf[2]=hold>>>16&255;hbuf[3]=hold>>>24&255;state.check=crc32(state.check,hbuf,4,0)}hold=0;bits=0;state.mode=OS;case OS:while(bits<16){if(have===0){break inf_leave}have--;hold+=input[next++]<>8}if(state.flags&512){hbuf[0]=hold&255;hbuf[1]=hold>>>8&255;state.check=crc32(state.check,hbuf,2,0)}hold=0;bits=0;state.mode=EXLEN;case EXLEN:if(state.flags&1024){while(bits<16){if(have===0){break inf_leave}have--;hold+=input[next++]<>>8&255;state.check=crc32(state.check,hbuf,2,0)}hold=0;bits=0}else if(state.head){state.head.extra=null}state.mode=EXTRA;case EXTRA:if(state.flags&1024){copy=state.length;if(copy>have){copy=have}if(copy){if(state.head){len=state.head.extra_len-state.length;if(!state.head.extra){state.head.extra=new Array(state.head.extra_len)}utils.arraySet(state.head.extra,input,next,copy,len)}if(state.flags&512){state.check=crc32(state.check,input,copy,next)}have-=copy;next+=copy;state.length-=copy}if(state.length){break inf_leave}}state.length=0;state.mode=NAME;case NAME:if(state.flags&2048){if(have===0){break inf_leave}copy=0;do{len=input[next+copy++];if(state.head&&len&&state.length<65536){state.head.name+=String.fromCharCode(len)}}while(len&©>9&1;state.head.done=true}strm.adler=state.check=0;state.mode=TYPE;break;case DICTID:while(bits<32){if(have===0){break inf_leave}have--;hold+=input[next++]<>>=bits&7;bits-=bits&7;state.mode=CHECK;break}while(bits<3){if(have===0){break inf_leave}have--;hold+=input[next++]<>>=1;bits-=1;switch(hold&3){case 0:state.mode=STORED;break;case 1:fixedtables(state);state.mode=LEN_;if(flush===Z_TREES){hold>>>=2;bits-=2;break inf_leave}break;case 2:state.mode=TABLE;break;case 3:strm.msg="invalid block type";state.mode=BAD}hold>>>=2;bits-=2;break;case STORED:hold>>>=bits&7;bits-=bits&7;while(bits<32){if(have===0){break inf_leave}have--;hold+=input[next++]<>>16^65535)){strm.msg="invalid stored block lengths";state.mode=BAD;break}state.length=hold&65535;hold=0;bits=0;state.mode=COPY_;if(flush===Z_TREES){break inf_leave}case COPY_:state.mode=COPY;case COPY:copy=state.length;if(copy){if(copy>have){copy=have}if(copy>left){copy=left}if(copy===0){break inf_leave}utils.arraySet(output,input,next,copy,put);have-=copy;next+=copy;left-=copy;put+=copy;state.length-=copy;break}state.mode=TYPE;break;case TABLE:while(bits<14){if(have===0){break inf_leave}have--;hold+=input[next++]<>>=5;bits-=5;state.ndist=(hold&31)+1;hold>>>=5;bits-=5;state.ncode=(hold&15)+4;hold>>>=4;bits-=4;if(state.nlen>286||state.ndist>30){strm.msg="too many length or distance symbols";state.mode=BAD;break}state.have=0;state.mode=LENLENS;case LENLENS:while(state.have>>=3;bits-=3}while(state.have<19){state.lens[order[state.have++]]=0}state.lencode=state.lendyn;state.lenbits=7;opts={bits:state.lenbits};ret=inflate_table(CODES,state.lens,0,19,state.lencode,0,state.work,opts);state.lenbits=opts.bits;if(ret){strm.msg="invalid code lengths set";state.mode=BAD;break}state.have=0;state.mode=CODELENS;case CODELENS:while(state.have>>24;here_op=here>>>16&255;here_val=here&65535;if(here_bits<=bits){break}if(have===0){break inf_leave}have--;hold+=input[next++]<>>=here_bits;bits-=here_bits;state.lens[state.have++]=here_val}else{if(here_val===16){n=here_bits+2;while(bits>>=here_bits;bits-=here_bits;if(state.have===0){strm.msg="invalid bit length repeat";state.mode=BAD;break}len=state.lens[state.have-1];copy=3+(hold&3);hold>>>=2;bits-=2}else if(here_val===17){n=here_bits+3;while(bits>>=here_bits;bits-=here_bits;len=0;copy=3+(hold&7);hold>>>=3;bits-=3}else{n=here_bits+7;while(bits>>=here_bits;bits-=here_bits;len=0;copy=11+(hold&127);hold>>>=7;bits-=7}if(state.have+copy>state.nlen+state.ndist){strm.msg="invalid bit length repeat";state.mode=BAD;break}while(copy--){state.lens[state.have++]=len}}}if(state.mode===BAD){break}if(state.lens[256]===0){strm.msg="invalid code -- missing end-of-block";state.mode=BAD;break}state.lenbits=9;opts={bits:state.lenbits};ret=inflate_table(LENS,state.lens,0,state.nlen,state.lencode,0,state.work,opts);state.lenbits=opts.bits;if(ret){strm.msg="invalid literal/lengths set";state.mode=BAD;break}state.distbits=6;state.distcode=state.distdyn;opts={bits:state.distbits};ret=inflate_table(DISTS,state.lens,state.nlen,state.ndist,state.distcode,0,state.work,opts);state.distbits=opts.bits;if(ret){strm.msg="invalid distances set";state.mode=BAD;break}state.mode=LEN_;if(flush===Z_TREES){break inf_leave}case LEN_:state.mode=LEN;case LEN:if(have>=6&&left>=258){strm.next_out=put;strm.avail_out=left;strm.next_in=next;strm.avail_in=have;state.hold=hold;state.bits=bits;inflate_fast(strm,_out);put=strm.next_out;output=strm.output;left=strm.avail_out;next=strm.next_in;input=strm.input;have=strm.avail_in;hold=state.hold;bits=state.bits;if(state.mode===TYPE){state.back=-1}break}state.back=0;for(;;){here=state.lencode[hold&(1<>>24;here_op=here>>>16&255;here_val=here&65535;if(here_bits<=bits){break}if(have===0){break inf_leave}have--;hold+=input[next++]<>last_bits)];here_bits=here>>>24;here_op=here>>>16&255;here_val=here&65535;if(last_bits+here_bits<=bits){break}if(have===0){break inf_leave}have--;hold+=input[next++]<>>=last_bits;bits-=last_bits;state.back+=last_bits}hold>>>=here_bits;bits-=here_bits;state.back+=here_bits;state.length=here_val;if(here_op===0){state.mode=LIT;break}if(here_op&32){state.back=-1;state.mode=TYPE;break}if(here_op&64){strm.msg="invalid literal/length code";state.mode=BAD;break}state.extra=here_op&15;state.mode=LENEXT;case LENEXT:if(state.extra){n=state.extra;while(bits>>=state.extra;bits-=state.extra;state.back+=state.extra}state.was=state.length;state.mode=DIST;case DIST:for(;;){here=state.distcode[hold&(1<>>24;here_op=here>>>16&255;here_val=here&65535;if(here_bits<=bits){break}if(have===0){break inf_leave}have--;hold+=input[next++]<>last_bits)];here_bits=here>>>24;here_op=here>>>16&255;here_val=here&65535;if(last_bits+here_bits<=bits){break}if(have===0){break inf_leave}have--;hold+=input[next++]<>>=last_bits;bits-=last_bits;state.back+=last_bits}hold>>>=here_bits;bits-=here_bits;state.back+=here_bits;if(here_op&64){strm.msg="invalid distance code";state.mode=BAD;break}state.offset=here_val;state.extra=here_op&15;state.mode=DISTEXT;case DISTEXT:if(state.extra){n=state.extra;while(bits>>=state.extra;bits-=state.extra;state.back+=state.extra}if(state.offset>state.dmax){strm.msg="invalid distance too far back";state.mode=BAD;break}state.mode=MATCH;case MATCH:if(left===0){break inf_leave}copy=_out-left;if(state.offset>copy){copy=state.offset-copy;if(copy>state.whave){if(state.sane){strm.msg="invalid distance too far back";state.mode=BAD;break}}if(copy>state.wnext){copy-=state.wnext;from=state.wsize-copy}else{from=state.wnext-copy}if(copy>state.length){copy=state.length}from_source=state.window}else{from_source=output;from=put-state.offset;copy=state.length}if(copy>left){copy=left}left-=copy;state.length-=copy;do{output[put++]=from_source[from++]}while(--copy);if(state.length===0){state.mode=LEN}break;case LIT:if(left===0){break inf_leave}output[put++]=state.length;left--;state.mode=LEN;break;case CHECK:if(state.wrap){while(bits<32){if(have===0){break inf_leave}have--;hold|=input[next++]<>>16&65535|0,n=0;while(len!==0){n=len>2e3?2e3:len;len-=n;do{s1=s1+buf[pos++]|0;s2=s2+s1|0}while(--n);s1%=65521;s2%=65521}return s1|s2<<16|0}module2.exports=adler32},function(module2,exports2){"use strict";function makeTable(){var c,table=[];for(var n=0;n<256;n++){c=n;for(var k=0;k<8;k++){c=c&1?3988292384^c>>>1:c>>>1}table[n]=c}return table}var crcTable=makeTable();function crc32(crc,buf,len,pos){var t=crcTable,end=pos+len;crc^=-1;for(var i=pos;i>>8^t[(crc^buf[i])&255]}return crc^-1}module2.exports=crc32},function(module2,exports2){"use strict";var BAD=30;var TYPE=12;module2.exports=function inflate_fast(strm,start){var state;var _in;var last;var _out;var beg;var end;var dmax;var wsize;var whave;var wnext;var s_window;var hold;var bits;var lcode;var dcode;var lmask;var dmask;var here;var op;var len;var dist;var from;var from_source;var input,output;state=strm.state;_in=strm.next_in;input=strm.input;last=_in+(strm.avail_in-5);_out=strm.next_out;output=strm.output;beg=_out-(start-strm.avail_out);end=_out+(strm.avail_out-257);dmax=state.dmax;wsize=state.wsize;whave=state.whave;wnext=state.wnext;s_window=state.window;hold=state.hold;bits=state.bits;lcode=state.lencode;dcode=state.distcode;lmask=(1<>>24;hold>>>=op;bits-=op;op=here>>>16&255;if(op===0){output[_out++]=here&65535}else if(op&16){len=here&65535;op&=15;if(op){if(bits>>=op;bits-=op}if(bits<15){hold+=input[_in++]<>>24;hold>>>=op;bits-=op;op=here>>>16&255;if(op&16){dist=here&65535;op&=15;if(bitsdmax){strm.msg="invalid distance too far back";state.mode=BAD;break top}hold>>>=op;bits-=op;op=_out-beg;if(dist>op){op=dist-op;if(op>whave){if(state.sane){strm.msg="invalid distance too far back";state.mode=BAD;break top}}from=0;from_source=s_window;if(wnext===0){from+=wsize-op;if(op2){output[_out++]=from_source[from++];output[_out++]=from_source[from++];output[_out++]=from_source[from++];len-=3}if(len){output[_out++]=from_source[from++];if(len>1){output[_out++]=from_source[from++]}}}else{from=_out-dist;do{output[_out++]=output[from++];output[_out++]=output[from++];output[_out++]=output[from++];len-=3}while(len>2);if(len){output[_out++]=output[from++];if(len>1){output[_out++]=output[from++]}}}}else if((op&64)===0){here=dcode[(here&65535)+(hold&(1<>3;_in-=len;bits-=len<<3;hold&=(1<=1;max--){if(count[max]!==0){break}}if(root>max){root=max}if(max===0){table[table_index++]=1<<24|64<<16|0;table[table_index++]=1<<24|64<<16|0;opts.bits=1;return 0}for(min=1;min0&&(type===CODES||max!==1)){return-1}offs[1]=0;for(len=1;lenENOUGH_LENS||type===DISTS&&used>ENOUGH_DISTS){return 1}for(;;){here_bits=len-drop;if(work[sym]end){here_op=extra[extra_index+work[sym]];here_val=base[base_index+work[sym]]}else{here_op=32+64;here_val=0}incr=1<>drop)+fill]=here_bits<<24|here_op<<16|here_val|0}while(fill!==0);incr=1<>=1}if(incr!==0){huff&=incr-1;huff+=incr}else{huff=0}sym++;if(--count[len]===0){if(len===max){break}len=lens[lens_index+work[sym]]}if(len>root&&(huff&mask)!==low){if(drop===0){drop=root}next+=min;curr=len-drop;left=1<ENOUGH_LENS||type===DISTS&&used>ENOUGH_DISTS){return 1}low=huff&mask;table[low]=root<<24|curr<<16|next-table_index|0}}if(huff!==0){table[next+huff]=len-drop<<24|64<<16|0}opts.bits=root;return 0}},function(module2,exports2,__webpack_require__){"use strict";var utils=__webpack_require__(33);var STR_APPLY_OK=true;var STR_APPLY_UIA_OK=true;try{String.fromCharCode.apply(null,[0])}catch(__){STR_APPLY_OK=false}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(__){STR_APPLY_UIA_OK=false}var _utf8len=new utils.Buf8(256);for(var q=0;q<256;q++){_utf8len[q]=q>=252?6:q>=248?5:q>=240?4:q>=224?3:q>=192?2:1}_utf8len[254]=_utf8len[254]=1;exports2.string2buf=function(str){var buf,c,c2,m_pos,i,str_len=str.length,buf_len=0;for(m_pos=0;m_pos>>6;buf[i++]=128|c&63}else if(c<65536){buf[i++]=224|c>>>12;buf[i++]=128|c>>>6&63;buf[i++]=128|c&63}else{buf[i++]=240|c>>>18;buf[i++]=128|c>>>12&63;buf[i++]=128|c>>>6&63;buf[i++]=128|c&63}}return buf};function buf2binstring(buf,len){if(len<65537){if(buf.subarray&&STR_APPLY_UIA_OK||!buf.subarray&&STR_APPLY_OK){return String.fromCharCode.apply(null,utils.shrinkBuf(buf,len))}}var result="";for(var i=0;i4){utf16buf[out++]=65533;i+=c_len-1;continue}c&=c_len===2?31:c_len===3?15:7;while(c_len>1&&i1){utf16buf[out++]=65533;continue}if(c<65536){utf16buf[out++]=c}else{c-=65536;utf16buf[out++]=55296|c>>10&1023;utf16buf[out++]=56320|c&1023}}return buf2binstring(utf16buf,out)};exports2.utf8border=function(buf,max){var pos;max=max||buf.length;if(max>buf.length){max=buf.length}pos=max-1;while(pos>=0&&(buf[pos]&192)===128){pos--}if(pos<0){return max}if(pos===0){return max}return pos+_utf8len[buf[pos]]>max?pos:max}},function(module2,exports2){"use strict";module2.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},function(module2,exports2){"use strict";module2.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},function(module2,exports2){"use strict";function ZStream(){this.input=null;this.next_in=0;this.avail_in=0;this.total_in=0;this.output=null;this.next_out=0;this.avail_out=0;this.total_out=0;this.msg="";this.state=null;this.data_type=2;this.adler=0}module2.exports=ZStream},function(module2,exports2){"use strict";function GZheader(){this.text=0;this.time=0;this.xflags=0;this.os=0;this.extra=null;this.extra_len=0;this.name="";this.comment="";this.hcrc=0;this.done=false}module2.exports=GZheader}])})}});var CSV=class{constructor(onOpen=this.onOpen,saveButtonId=null,openButtonId=null){this.onOpen=onOpen;this.notes=[];if(saveButtonId!==null){document.getElementById(saveButtonId).addEventListener("click",this.saveCSV)}if(openButtonId!==null){document.getElementById(openButtonId).addEventListener("click",this.openCSV)}}processArraysForCSV(data=["1|2|3","3|2|1"],delimiter="|",header="a,b,c",saveNotes=false){let csvDat=header+"\n";let noteIdx=0;data.forEach((line,i)=>{if(data[i]==="string"&&delimiter!==","){csvDat+=line.split(delimiter).join(",")}else{csvData+=line.join(",")}if(saveNotes===true){if(this.notes[noteIdx].idx===i){line+=this.notes[noteIdx].text;noteIdx++}}if(line.indexOf("\n")<0){csvDat+="\n"}});return csvDat}static saveCSV(csvDat="a,b,c\n1,2,3\n3,2,1\n",name=new Date().toISOString()){var hiddenElement=document.createElement("a");hiddenElement.href="data:text/csv;charset=utf-8,"+encodeURI(csvDat);hiddenElement.target="_blank";if(name!==""){hiddenElement.download=name}else{hiddenElement.download=new Date().toISOString()+".csv"}hiddenElement.click()}static openCSV(delimiter=",",onOpen=(csvDat,header,path)=>{return csvDat,header,path}){return new Promise((res,rej)=>{var input=document.createElement("input");input.accept=".csv";input.type="file";input.onchange=e=>{var file=e.target.files[0];var reader=new FileReader;reader.onload=event=>{var tempcsvData=event.target.result;var tempcsvArr=tempcsvData.split("\n");let header=[];var csvDat=[];tempcsvArr.pop();tempcsvArr.forEach((row,i)=>{if(i==0){header=row.split(delimiter)}else{var temp=row.split(delimiter);csvDat.push(temp)}});onOpen(csvDat,header,input.value);input.value="";res({data:csvDat,header,filename:input.value})};reader.readAsText(file)};input.click()})}static openCSVRaw(onOpen=(csvDat,path)=>{return csvDat,path}){return new Promise((res,rej)=>{var input=document.createElement("input");input.accept=".csv";input.type="file";input.onchange=e=>{var file=e.target.files[0];var reader=new FileReader;reader.onload=event=>{var tempcsvData=event.target.result;onOpen(tempcsvData,input.value);input.value="";res({data:tempcsvData,filename:input.value})};reader.readAsText(file)};input.click()})}onOpen(csvDat=[],header=[]){console.log("CSV Opened!",header,csvDat)}};var parseCSVData=(data,filename,head,hasend=true,parser=(lines,filename2,head2)=>{let result={filename:filename2};let header=head2;if(typeof head2==="string")header=head2.split(",");result.header=header;for(let i=0;i{let lines;if(data.includes("\r"))lines=data.split("\r\n");else lines=data.split("\n");if(!head)head=lines[0];lines.shift();if(hasend===false)lines.pop();let result=parser(lines,filename,head);return result};function toISOLocal(d){d=new Date(d);var z=n=>("0"+n).slice(-2);var zz=n=>("00"+n).slice(-3);var off=d.getTimezoneOffset();var sign=off<0?"+":"-";off=Math.abs(off);return d.getFullYear()+"-"+z(d.getMonth()+1)+"-"+z(d.getDate())+"T"+z(d.getHours())+":"+z(d.getMinutes())+":"+z(d.getSeconds())+"."+zz(d.getMilliseconds())+"(UTC"+sign+z(off/60|0)+":00)"}var processDataForCSV=(options={})=>{if(!options.data)return void 0;if(!Array.isArray(options.data))options.data=[options.data];if(options.data&&!options.header)options.header=Object.keys(options.data[0]);let head=[...options.header];if(head.indexOf("timestamp")>-1){head.splice(head.indexOf("timestamp")+1,0,"localized")}let header=head.join(",");let headeridx=0;let lines=[];let foreach=(obj,i)=>{if(Array.isArray(obj)){for(let j=0;j{if(exists2)appendFile(options.filename,joined,options.dir);else appendFile(options.filename,header+joined,options.dir)})}return result};var BrowserFS=__toESM(require_browserfs());var fsInited=false;var fs2=BrowserFS.BFSRequire("fs");var BFSBuffer=BrowserFS.BFSRequire("buffer").Buffer;var initPromise;var initFS=async(dirs=["data"],oninit=(exists2=[])=>{},onerror=e=>{},filesystem="IndexedDB")=>{if(fsInited){if(initPromise){await initPromise}return true}else{fsInited=true;initPromise=new Promise((resolve,reject)=>{BrowserFS.FileSystem[filesystem].Create({},(e,mountableFileSystem)=>{if(e){reject(e);return}if(!mountableFileSystem){onerror(e);reject(new Error(`Error creating BrowserFS`));return}BrowserFS.initialize(mountableFileSystem);let promises=[];dirs.forEach(async dir=>{promises.push(dirExists(fs2,dir))});Promise.all(promises).then(values=>{oninit(values);resolve(true)})})});return await initPromise}};var exists=async(path="")=>{if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);return await new Promise(resolve=>{fs2.exists("/"+path,function(exists2){resolve(exists2)})})};var readFile=async(path="data")=>{if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);return await new Promise(resolve=>{fs2.readFile("/"+path,function(e,output){resolve(output)})})};async function readFileChunk(path="data",begin=0,end=5120,onread=data=>{}){if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);if(path!=""){return await new Promise(async(resolve,reject)=>{fs2.open("/"+path,"r",(e,fd)=>{if(e){reject(e);return}fs2.read(fd,end,begin,"utf-8",(er,output,bytesRead)=>{if(er){reject(er);return}if(bytesRead!==0){let data=output.toString();fs2.close(fd,()=>{onread(data,path);resolve(data)})}else resolve(void 0)})})})}else{console.error("Path name is not defined");return void 0}}var getFilenames=async(directory="data",onload=directory2=>{})=>{if(!fsInited)await initFS([directory]);else await dirExists(fs2,directory);return await new Promise((resolve,reject)=>{fs2.readdir("/"+directory,(e,dir)=>{if(e){reject(e);return}if(dir){onload(dir);resolve(dir)}else resolve(void 0)})})};var writeFile=async(path,data,onwrite=data2=>{})=>{if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);return await new Promise((resolve,reject)=>{fs2.writeFile("/"+path,data,err=>{if(err){reject(err);return}onwrite(data);resolve(true)})})};var appendFile2=async(path,data,onwrite=data2=>{})=>{if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);return await new Promise((resolve,reject)=>{fs2.appendFile("/"+path,data,err=>{if(err){reject(err);return}onwrite(data);resolve(true)})})};var deleteFile=async(path="data",ondelete=()=>{})=>{if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);return await new Promise(resolve=>{if(path!=""){fs2.unlink("/"+path,e=>{if(e)console.error(e);ondelete();resolve(true)})}else{console.error("Path name is not defined");resolve(false)}})};var readFileAsText=async(path="data",end="end",begin=0,onread=(data,filename)=>{})=>{if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);return await new Promise(async(resolve,reject)=>{let size=await getFileSize(path);if(end==="end"){end=size}else if(typeof end==="number"){if(end>size)end=size}fs2.open("/"+path,"r",(e,fd)=>{if(e){reject(e);return}fs2.read(fd,end,begin,"utf-8",(er,output,bytesRead)=>{if(er){reject(er);return}if(bytesRead!==0){let data=output.toString();fs2.close(fd,()=>{onread(data,path);resolve(data)})}else resolve(void 0)})})})};var listFiles=async(dir="data",onload=directory=>{})=>{if(!fsInited)await initFS([dir]);else await dirExists(fs2,dir);return await new Promise((resolve,reject)=>{fs2.readdir("/"+dir,(e,directory)=>{if(e){reject(e);return}if(directory){onload(directory)}resolve(directory)})})};var getFileSize=async(path="data",onread=size=>{})=>{if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);return await new Promise((resolve,reject)=>{fs2.stat("/"+path,(e,stats)=>{if(e){reject(e);return}let filesize=stats.size;onread(filesize);resolve(filesize)})})};var getCSVHeader=async(path="data",onopen=(header,filename)=>{})=>{if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);return await new Promise((resolve,reject)=>{fs2.open("/"+path,"r",(e,fd)=>{if(e){reject(e);return}fs2.read(fd,65535,0,"utf-8",(er,output,bytesRead)=>{if(er){reject(er);return}if(bytesRead!==0){let data=output.toString();let lines=data.split("\n");let header=lines[0];fs2.close(fd,()=>{onopen(header,path);resolve(header)})}else resolve(void 0)})})})};var writeToCSVFromDB=async(path="data",fileSizeLimitMb=10)=>{if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);return await new Promise((resolve,reject)=>{if(path!=""){fs2.stat("/"+path,(e,stats)=>{if(e){reject(e);return}let filesize=stats.size;fs2.open(path,"r",(e2,fd)=>{if(e2){reject(e2);return}let i=0;let maxFileSize=fileSizeLimitMb*1024*1024;let end=maxFileSize;if(filesize{if(e3){reject(e3);return}if(bytesRead!==0)CSV.saveCSV(output.toString(),path.split("/")[1]);fs2.close(fd);resolve(true)})}else{const writeChunkToFile=async()=>{if(ifilesize){end=filesize-i}let chunk=0;fs2.read(fd,end,i,"utf-8",(e3,output,bytesRead)=>{if(e3){reject(e3);return}if(bytesRead!==0){CSV.saveCSV(output.toString(),path.split("/")[1]+"_"+chunk);i+=maxFileSize;chunk++;writeChunkToFile();fs2.close(fd);resolve(true)}})}}}})})}else{console.error("File name is not defined.");resolve(false)}})};async function processCSVChunksFromDB(path="data",onData=(csvdata,start2,end2,size)=>{},maxChunkSize=1e4,start=0,end="end",options={}){let size=await getFileSize(path);let partition=start;return await new Promise((res,rej)=>{let processPartition=()=>{let endChunk=partition+maxChunkSize;if(endChunk>size){endChunk=size}readCSVChunkFromDB(path,partition,endChunk,options).then(async result=>{await onData(result,partition,endChunk,size);partition=endChunk;if(partition!==size){processPartition()}else{res(true)}}).catch(rej)};processPartition()})}async function readCSVChunkFromDB(path="data",start=0,end="end",options={}){if(!fsInited)await initFS([path.split("/")[0]]);else await dirExists(fs2,path.split("/")[0]);const transpose=options.transpose||false;let head=await getCSVHeader(path);if(head)head=head.split(",");else return void 0;let resultLengths=[];let resultNames=[];let results=transpose?[]:{};head.forEach(v=>{if(v){resultNames.push(v);resultLengths.push(1)}else resultLengths[resultLengths.length-1]++});let size=await getFileSize(path);if(end==="end")end=size;else if(end>size){start=size-(end-start);end=size}let data=(await readFileChunk(path,start,end))?.split("\n").slice(1,-1);let preprocess=value=>{try{value=JSON.parse(value)}catch{}return value};if(data)data.forEach((r,i)=>{let row=r.split(",");if(transpose){const entry={};if(options.json)row.forEach((v,idx)=>{if(options.json)entry[resultNames[idx]]=preprocess(v);else entry[resultNames[idx]]=v});results.push(entry)}else{row.forEach((v,i2)=>{const header=resultNames[i2];if(!results[header])results[header]=[];if(options.json)results[header].push(preprocess(v));else results[header].push(v)})}});return results}var directories={};var dirExists=async(fs3,directory)=>{if(!fsInited)await initFS([directory]);return await new Promise((resolve,reject)=>{if(!directory)reject(false);if(directories[directory]==="exists"||directories[directory]==="created"){resolve()}else{if(directory[0]==="/")directory=directory.substring(1);if(!directory)reject(false);fs3.exists(`/${directory}`,exists2=>{if(exists2){directories[directory]="exists";resolve()}else if(directories[directory]==="creating"){resolve()}else{directories[directory]="creating";fs3.mkdir(`/${directory}`,1,err=>{if(err){reject(err);return}directories[directory]="created";setTimeout(resolve,500)})}})}})};var BFSRoutes={initFS,dirExists,exists,readFile,readFileChunk,getFilenames,writeFile,appendFile:appendFile2,deleteFile,readFileAsText,getFileSize,getCSVHeader,listFiles};var CSV_REFERENCE={};function lerp(v0,v1,t){return(1-t)*v0+t*v1}function interpolerp(v0,v1,fit,floor=true){if(fit<=2)return[v0,v1];let a=1/fit;let result=new Array(fit);result[0]=v0;for(let i=1;i<=fit;i++){result[i]=lerp(v0,v1,a*i);if(floor)result[i]=Math.floor(result[i])}return result}var appendCSV=async(newData,filename,header,options)=>{if(!filename){let keys=Object.keys(CSV_REFERENCE);if(keys.length>0)filename=keys[keys.length-1];else filename=`csv${new Date().toISOString()}`}let csv=CSV_REFERENCE[filename];if(!csv){let keys=Array.from(Object.keys(newData));if(keys.indexOf("timestamp")>-1)keys.splice(keys.indexOf("timestamp"),1);CSV_REFERENCE[filename]={header:header?header:["timestamp","localized",...keys],lastX:void 0,buffer:"",buffered:0,bufferSize:options?.bufferSize?options.bufferSize:0,toFixed:options?.toFixed?options.toFixed:0,xIncrement:options?.xIncrement?options.xIncrement:0};csv=CSV_REFERENCE[filename];const existingHeader=await getCSVHeader(filename).catch(()=>null);const isDifferent=!existingHeader||existingHeader!==csv.header.join(",");if(isDifferent)header=csv.header}if(!csv.header||csv.header?.length===0){let keys=Array.from(Object.keys(newData));if(keys.indexOf("timestamp")>-1)keys.splice(keys.indexOf("timestamp"),1);csv.header=header?header:["timestamp","localized",...keys]}else if(header)csv.header=header;let maxLen=1;for(const key in newData){const value=newData[key];if(csv.header.indexOf(key)>-1&&value&&Array.isArray(value)&&value?.length>maxLen)maxLen=value?.length}let x;if(csv.xIncrement){if(!csv.lastX){if(typeof newData[csv.header[0]]!=="undefined"){x=newData[csv.header[0]]}else if(csv.header[0].toLowerCase().includes("time")||csv.header[0].toLowerCase().includes("unix"))x=Date.now()}else{if(newData[csv.header[2]]){if(Array.isArray(newData[csv.header[2]]))x=csv.lastX+csv.xIncrement*newData[csv.header[2]].length;else x=csv.lastX+csv.xIncrement}else if(newData[csv.header[0]]){if(Array.isArray(newData[csv.header[0]]))x=csv.lastX+csv.xIncrement*newData[csv.header[0]].length;else x=csv.lastX+csv.xIncrement}else x=csv.lastX+csv.xIncrement}}else if(newData[csv.header[0]])x=newData[csv.header[0]];else x=Date.now();if(typeof csv.lastX==="undefined")csv.lastX=Array.isArray(x)?x[0]:x;if(typeof x==="undefined"){if(csv.header[0].includes("time")){let now=Date.now();if(maxLen===1)x=Date.now();else{x=interpolerp(csv.lastX,now,maxLen);x.shift()}}else{let newX=csv.lastX+1;if(maxLen>1){x=new Array(maxLen).fill("");x[maxLen-1]=newX}else x=newX}}else if(maxLen>1&&x?.length!==maxLen){if(!Array.isArray(x)||x.length===1){x=interpolerp(csv.lastX,x,maxLen,true);x.shift()}else{x=interpolerp(x[0],x[x.length-1],maxLen,true);x.shift()}}let toAppend=[];if(Array.isArray(x)){let curIdcs={};for(let i=0;icurIdcs[csv.header[j]]){curIdcs[csv.header[j]]++;toAppend[i][j]=d[curIdcs[csv.header[j]]]}else{toAppend[i][j]=""}}}}else{if(i===x.length-1){toAppend[i][j]=d}else{toAppend[i][j]=""}}if(typeof toAppend[i][j]==="number"&&Math.floor(toAppend[i][j])!==toAppend[i][j])toAppend[i][j]=toAppend[i][j].toFixed(CSV_REFERENCE[filename].toFixed)}}}else{toAppend.push([]);for(let j=0;j{csvProcessed+=(options?.json?arr.map(v=>JSON.stringify(v)):arr).join(",")+"\n";if(csv.bufferSize)csv.buffered++});csv.lastX=toAppend[toAppend.length-1][0];if(csv.bufferSize){csv.buffer+=csvProcessed;if(csv.buffered>csv.bufferSize){let r=new Promise((res,rej)=>{exists(filename).then(fileExists=>{if(!fileExists){writeFile(filename,csv.buffer,written=>{res(written)})}else{appendFile2(filename,csv.buffer,written=>{res(written)})}})});await r;csv.buffer="";csv.buffered=0;return r}else return await Promise.resolve(true)}else{return await new Promise((res,rej)=>{exists(filename).then(fileExists=>{if(!fileExists){writeFile(filename,csvProcessed,written=>{res(written)})}else{appendFile2(filename,csvProcessed,written=>{res(written)})}})})}};var updateCSVHeader=(header,filename)=>{if(CSV_REFERENCE[filename]){CSV_REFERENCE[filename].header=header}};var createCSV=(filename,header,toFixed=5,bufferSize=0,xIncrement)=>{if(!CSV_REFERENCE[filename]){if(header?.indexOf("timestamp")>1){header.splice(header.indexOf("timestamp"),1);header.unshift("timestamp")}if((header?.[0].toLowerCase().includes("time")||header?.[0].toLowerCase().includes("unix"))&&header[1]!=="localized"){header.splice(1,0,"localized")}CSV_REFERENCE[filename]={header,lastX:header[1]==="localized"?Date.now():0,bufferSize,buffer:"",buffered:0,toFixed,xIncrement};return new Promise((res,rej)=>{exists(filename).then(doesExist=>{if(!doesExist){writeFile(filename,CSV_REFERENCE[filename].header?CSV_REFERENCE[filename].header.join(",")+"\n":"",written=>{res(written)}).catch(rej)}})})}};var visualizeDirectory=(dir,parentNode=document.body)=>{return new Promise(async(res,rej)=>{if(parentNode.querySelector("#bfs"+dir))parentNode.querySelector("#bfs"+dir)?.remove();parentNode.insertAdjacentHTML("beforeend",`
    `);let div=parentNode.querySelector("#bfs"+dir);await listFiles(dir).then(directory=>{if(directory.length===0)div.innerHTML="No Files!";else directory.forEach(listing=>{div?.insertAdjacentHTML("beforeend",`
    - Data: - ${listing} - - ${listing.indexOf(".")>-1?``:""} -
    `);if(document.getElementById(`delete${listing}`)){document.getElementById(`delete${listing}`).onclick=()=>{deleteFile(dir+"/"+listing,()=>{visualizeDirectory(dir,parentNode)})}}if(document.getElementById(`download${listing}`)){document.getElementById(`download${listing}`).onclick=()=>{writeToCSVFromDB(dir+"/"+listing,10)}}});res(directory)}).catch(rej)})};var csvRoutes={appendCSV,updateCSVHeader,createCSV,visualizeDirectory,openCSV:CSV.openCSV,saveCSV:CSV.saveCSV,openCSVRaw:CSV.openCSVRaw,parseCSVData,getCSVHeader,writeToCSVFromDB,readCSVChunkFromDB,processCSVChunksFromDB,toISOLocal};})(); -/*! Bundled license information: - -browserfs/dist/browserfs.js: - (*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT - *) -*/ diff --git a/src/extras/dist/loaders/index.d.ts b/src/extras/dist/loaders/index.d.ts deleted file mode 100644 index 229b9ec7..00000000 --- a/src/extras/dist/loaders/index.d.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { GraphNode, Graph, GraphNodeProperties } from "../core/Graph"; -/** - * setting nodeA.__node.backward:true propagates operator results to parent - */ -export declare const backprop: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; -/** - * - * Specify a timer loop, will stop when node is popped or nodeA.__node.isLooping is set false - * nodeA.__node.loop = 100 will loop the operator every 100 milliseconds - * - * Or - * nodeA.__node.delay will delay the operator by specified millisecond number and resolve the result as a promise - * nodeA.__node.frame will use requestAnimationFrame to call the function and resolve the result as a promise - * - * Use in combination with: - * nodeA.__node.repeat will repeat the operator the specified number of times - * nodeA.__node.recursive will do the same as repeat but will pass in the previous operator call's results - * - * - */ -export declare const loop: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; -/** Animations - * - * nodeA.__node.animate = true; - * then __operator becomes a requestAnimationFrame function - * start with a call the __operator or by setting node.__node.animating = true; - * - * or node.__animation = (...args) => {} - * - */ -export declare const animate: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; -/** Branching operations - * - * //runs a function or node if the if-conditions are satisfied, which can be a function that returns a true or false - * nodeA.__branch = {[key:string]:{if:Function|any, then:Function|any|GraphNode}} - * - * nodeA.__listeners['nodeB.x'] = { - * callback:(result)=>void, - * branch:{ - * if:Function|any, //if a function using the result evaluates to true or if the value equals the if value - * then:Function|any|GraphNode //call a function, return a different result, or call a node - * } - * } - * - */ -export declare const branching: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; -/** Trigger listeners oncreate with specific arguments - * - * nodeA.__listeners['nodeB.x'] = { callback:(result)=>void, oncreate:any } - * - */ -export declare const triggerListenerOncreate: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; -/** Bind listeners to a specific object instead of the node that owns it - * - * nodeA.__listeners['nodeB.x'] = { callback:(result)=>void, binding:{[key:string]:any} } - * - */ -export declare const bindListener: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; -/** - * - * nodeA.__listeners['nodeB.x'] = { callback:(result)=>void, transform:(result)=>any } - * - */ -export declare const transformListenerResult: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; -export declare const substitute__operator: (node: GraphNode & GraphNodeProperties, parent: GraphNode | Graph, graph: Graph) => void; -export declare const loaders: { - backprop: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; - loop: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; - animate: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; - branching: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; - triggerListenerOncreate: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; - bindListener: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; - transformListenerResult: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; - substitute__operator: (node: GraphNode & GraphNodeProperties, parent: GraphNode | Graph, graph: Graph) => void; -}; diff --git a/src/extras/dist/loaders/methodstrings.d.ts b/src/extras/dist/loaders/methodstrings.d.ts deleted file mode 100644 index 978aabc8..00000000 --- a/src/extras/dist/loaders/methodstrings.d.ts +++ /dev/null @@ -1 +0,0 @@ -export declare function methodstrings(node: any): void; diff --git a/src/extras/dist/services/Service.d.ts b/src/extras/dist/services/Service.d.ts deleted file mode 100644 index a5558998..00000000 --- a/src/extras/dist/services/Service.d.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Graph, GraphNode, GraphOptions } from "../../src/core/Graph"; -export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array; -export type ServiceMessage = { - route?: string; - args?: any; - method?: string; - node?: string | GraphNode; - [key: string]: any; -}; -export type ServiceOptions = GraphOptions & { - services?: { - [key: string]: Service | Function | { - [key: string]: any; - }; - }; - restrict?: { - [key: string]: boolean; - }; -}; -export declare class Service extends Graph { - name: string; - restrict?: { - [key: string]: boolean; - }; - constructor(options?: ServiceOptions); - addServices: (services: { - [key: string]: Function | Graph | Service | { - [key: string]: any; - }; - }) => void; - handleMethod: (route: string, method: string, args?: any) => any; - handleServiceMessage(message: ServiceMessage): any; - handleGraphNodeCall(route: string | GraphNode, args: any): any; - transmit: (...args: any[]) => any | void; - receive: (...args: any[]) => any | void; - pipe: (source: GraphNode | string, destination: string, endpoint?: string | any, method?: string, callback?: (res: any) => any | void) => number; - pipeOnce: (source: GraphNode | string, destination: string, endpoint?: string | any, method?: string, callback?: (res: any) => any | void) => any; - terminate: (...args: any) => void; - isTypedArray: typeof isTypedArray; - recursivelyAssign: (target: any, obj: any) => any; - spliceTypedArray: typeof spliceTypedArray; - ping: () => string; - echo: (...args: any) => any; - log: (...args: any) => boolean; - error: (...args: any) => boolean; -} -export declare function isTypedArray(x: any): boolean; -export declare const recursivelyAssign: (target: any, obj: any) => any; -export declare function spliceTypedArray(arr: TypedArray, start: number, end?: number): TypedArray; diff --git a/src/extras/dist/services/router/Router.d.ts b/src/extras/dist/services/router/Router.d.ts deleted file mode 100644 index 3d6e0348..00000000 --- a/src/extras/dist/services/router/Router.d.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { Graph, GraphNode } from "../../core/Graph"; -import { Service, ServiceOptions } from "../Service"; -export type User = { - _id: string; - send: (...args: any[]) => any; - request: (...args: any[]) => Promise | Promise[] | undefined; - post: (...args: any[]) => void; - run: (...args: any[]) => Promise | Promise[] | undefined; - subscribe: (...args: any[]) => Promise | Promise[] | undefined; - unsubscribe: (...args: any[]) => Promise | Promise[] | undefined; - sendAll?: (...args: any[]) => any; - requestAll?: (...args: any[]) => Promise | undefined; - postAll?: (...args: any[]) => void; - runAll?: (...args: any[]) => Promise | undefined; - subscribeAll?: (...args: any[]) => Promise | undefined; - unsubscribeAll?: (...args: any[]) => Promise | undefined; - terminate: (...args: any[]) => boolean; - onmessage?: (...args: any[]) => void; - onerror?: (...args: any[]) => void; - onclose?: ((user: User) => void) | ((...args: any[]) => void); - [key: string]: any; -}; -export type ConnectionProps = { - connection: GraphNode | Graph | { - [key: string]: any; - } | string; - service?: string | Graph | Service; - source?: string; - onclose?: (connection: ConnectionInfo, ...args: any[]) => void; -}; -export type ConnectionInfo = { - connection: GraphNode | Graph | { - [key: string]: any; - }; - service?: string | Service | Graph; - _id: string; - source: string; - connectionType?: string; - connectionsKey?: string; - send?: (message: any, ...a: any[]) => any; - request?: (message: any, method?: any, ...a: any[]) => Promise | Promise[]; - post?: (route: any, args?: any, method?: string, ...a: any[]) => void; - run?: (route: any, args?: any, method?: string, ...a: any[]) => Promise | Promise[]; - subscribe?: (route: any, callback?: ((res: any) => void) | string, ...a: any[]) => Promise | undefined; - unsubscribe?: (route: any, sub: number, ...arrayBuffer: any[]) => Promise | Promise[]; - terminate: (...a: any[]) => boolean; - onclose?: (connection: ConnectionInfo, ...args: any[]) => void; -}; -export type RouterOptions = { - graph?: { - [key: string]: Service | Graph | any | { - service: Service | Graph | any; - connections: string[] | { - [key: string]: any; - }; - config?: { - [key: string]: { - _id?: string; - source?: string; - onclose?: (c: ConnectionInfo, ...args: any[]) => void; - args?: any[]; - [key: string]: any; - }; - }; - }; - }; - timeout?: number; - order?: string[]; - [key: string]: any; -} & ServiceOptions; -export declare class Router extends Service { - name: string; - connections: { - [key: string]: ConnectionInfo; - }; - sources: { - [key: string]: { - [key: string]: ConnectionInfo; - }; - }; - services: { - [key: string]: Service; - }; - serviceConnections: { - [key: string]: { - [key: string]: { - [key: string]: any; - }; - }; - }; - users: { - [key: string]: User; - }; - userTimeout: number; - order: string[]; - constructor(options?: RouterOptions); - addUser: (info: { - _id: string; - } & { - onclose?: (connection: ConnectionInfo, ...args: any[]) => void; - }, connections?: { - [key: string]: string | ConnectionInfo | ConnectionProps; - }, config?: { - [key: string]: { - [key: string]: any; - service: Service; - _id?: string; - onclose?: (c: ConnectionInfo, ...args: any[]) => void; - args?: any[]; - }; - }, receiving?: boolean) => Promise; - removeUser(profile: string | User | { - _id: string; - [key: string]: any; - }, terminate?: boolean): boolean; - getConnection: (sourceId: string, hasMethod?: string, connectionId?: string) => User | ConnectionInfo | undefined; - getConnections: (sourceId: string, hasMethod?: string, props?: {}) => {}; - runConnection: (userId: string, method: 'run' | 'post' | 'subscribe' | 'unsubscribe' | 'terminate' | 'send' | 'request' | 'runAll' | 'postAll' | 'subscribeAll' | 'unsubscribeAll' | 'sendAll' | 'requestAll', args: any[], connectionId?: string) => Promise; - subscribeThroughConnection: (route: string, remoteRelay: string | ConnectionInfo, remoteEndpoint: string, callback: string | ((res: any) => void), ...args: any[]) => Promise; - addConnection: (options: ConnectionProps | ConnectionInfo | string, source?: string, autoRemove?: boolean) => ConnectionInfo; - removeConnection: (connection: string | ConnectionInfo | { - [key: string]: any; - _id: string; - }, terminate?: boolean) => boolean; - routeService: (service: Service, connections?: any, source?: string, order?: string[]) => void; - addServiceConnections: (service: Service | string, connectionsKey: any, source?: string) => {}; - openConnection: (service: string | Service, options: { - [key: string]: any; - }, source?: string, ...args: any[]) => Promise; - terminate: (connection: string | ConnectionInfo) => boolean; - routeConnections: (route: string, transmitter: string | ConnectionInfo, receiver: string | ConnectionInfo, ...args: any[]) => Promise; - setUserData: (user: string | User, data: string | { - [key: string]: any; - }) => boolean; -} -export declare function connectionHasId(connection: { - _id?: string; - [key: string]: any; -}, timeout?: number): Promise; diff --git a/src/extras/dist/services/utils.d.ts b/src/extras/dist/services/utils.d.ts deleted file mode 100644 index 9efee154..00000000 --- a/src/extras/dist/services/utils.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -export declare let recursivelyStringifyFunctions: (obj: { - [key: string]: any; -}) => {}; -export declare function getFnParamNames(fn: any): any; -export declare let getFunctionHead: (methodString: any) => any; -export declare function parseFunctionFromText(method?: string): any; -export declare function reconstructObject(json?: string | { - [x: string]: any; -}): any; -export declare const stringifyWithCircularRefs: (obj: any, space?: any) => string; -export declare const stringifyWithFunctionsAndCircularRefs: (obj: any, space?: any) => string; -export declare const stringifyFast: (obj: any, space?: any) => string; diff --git a/src/extras/dist/services/worker/Worker.service.d.ts b/src/extras/dist/services/worker/Worker.service.d.ts deleted file mode 100644 index 9539bb89..00000000 --- a/src/extras/dist/services/worker/Worker.service.d.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { Service, ServiceMessage, ServiceOptions } from "../Service"; -import Worker from 'web-worker'; -import { GraphNode, GraphNodeProperties } from "../../core/Graph"; -export type WorkerRoute = { - worker?: WorkerInfo; - workerUrl?: string | URL | Blob; - transferFunctions?: { - [key: string]: Function; - }; - transferClasses?: { - [key: string]: Function; - }; - parentRoute?: string; - portId?: string; - callback?: string; - stopped?: boolean; - blocking?: boolean; - init?: string; - initArgs?: any[]; - initTransfer?: any[]; -} & GraphNodeProperties & WorkerProps; -export type WorkerProps = { - worker?: WorkerInfo; - workerUrl?: string | URL | Blob; - url?: URL | string | Blob; - _id?: string; - port?: MessagePort; - onmessage?: (ev: any) => void; - onerror?: (ev: any) => void; - onclose?: (worker: Worker | MessagePort) => void; -}; -export type WorkerInfo = { - worker: Worker | MessagePort; - send: (message: any, transfer?: any) => void; - request: (message: any, method?: string, transfer?: any) => Promise; - post: (route: any, args?: any, method?: string, transfer?: any) => void; - run: (route: any, args?: any, method?: string, transfer?: any) => Promise; - subscribe: (route: any, callback?: ((res: any) => void) | string, args?: any[], key?: string, subInput?: boolean, blocking?: boolean) => Promise; - unsubscribe: (route: any, sub: number) => Promise; - start: (route?: any, portId?: string, callback?: ((res: any) => void) | string, blocking?: boolean) => Promise; - stop: (route?: string, portId?: string) => Promise; - workerSubs: { - [key: string]: { - sub: number | false; - route: string; - portId: string; - callback?: ((res: any) => void) | string; - blocking?: boolean; - }; - }; - terminate: () => boolean; - postMessage: (message: any, transfer?: any[]) => void; - graph: WorkerService; - _id: string; -} & WorkerProps & WorkerRoute; -export declare class WorkerService extends Service { - name: string; - workers: { - [key: string]: WorkerInfo; - }; - threadRot: number; - connections: any; - constructor(options?: ServiceOptions); - loadWorkerRoute: (node: WorkerRoute & GraphNode, routeKey: string) => WorkerInfo; - workerloader: any; - addDefaultMessageListener: () => void; - postMessage: (message: any, target: string, transfer?: Transferable[]) => void; - addWorker: (options: { - url?: URL | string | Blob; - port?: MessagePort; - _id?: string; - onmessage?: (ev: any) => void; - onerror?: (ev: any) => void; - }) => WorkerInfo; - open: (options: { - url?: URL | string | Blob; - port?: MessagePort; - _id?: string; - onmessage?: (ev: any) => void; - onerror?: (ev: any) => void; - }) => WorkerInfo; - close: () => void; - toObjectURL: (scriptTemplate: string) => string; - getTransferable(message: any): any; - transmit: (message: ServiceMessage | any, worker?: Worker | MessagePort | string, transfer?: StructuredSerializeOptions) => any; - terminate: (worker: Worker | MessagePort | string | WorkerInfo) => boolean; - establishMessageChannel: (worker: Worker | string | MessagePort | WorkerInfo, worker2?: Worker | string | MessagePort | WorkerInfo) => string | false; - request: (message: ServiceMessage | any, workerId: string, transfer?: any, method?: string) => Promise; - runRequest: (message: ServiceMessage | any, worker: undefined | string | Worker | MessagePort, callbackId: string | number, getTransferable?: boolean) => any; - subscribeWorker: (route: string, worker: WorkerInfo | Worker | string | MessagePort, args?: any[], key?: string, subInput?: boolean, blocking?: boolean, getTransferable?: boolean) => number; - subscribeToWorker: (route: string, workerId: string, callback?: string | ((res: any) => void), args?: any[], key?: string, subInput?: boolean, blocking?: boolean, getTransferable?: boolean) => Promise; - triggerSubscription: (route: string, workerId: string, result: any) => Promise; - pipeWorkers: (sourceWorker: WorkerInfo | string, listenerWorker: WorkerInfo | string, sourceRoute: string, listenerRoute: string, portId?: string, args?: any[], key?: any, subInput?: boolean, blocking?: boolean, getTransferable?: boolean) => Promise; - unpipeWorkers: (sourceRoute: string, sourceWorker: WorkerInfo | string, sub?: number) => Promise; -} diff --git a/src/extras/dist/src/core/EventHandler.d.ts b/src/extras/dist/src/core/EventHandler.d.ts deleted file mode 100644 index 2f00b243..00000000 --- a/src/extras/dist/src/core/EventHandler.d.ts +++ /dev/null @@ -1,44 +0,0 @@ -export declare class EventHandler { - data: { - [key: string]: any; - }; - triggers: { - [key: string]: { - [key: string]: any; - sub: number; - onchange: Function; - }[]; - }; - ctr: number; - constructor(data?: { - [key: string]: any; - }); - setState: (updateObj: { - [key: string]: any; - }) => { - [key: string]: any; - }; - setValue: (key: any, value: any) => void; - triggerEvent: (key: any, value: any) => void; - subscribeState: (onchange: (res: any) => void) => number; - unsubscribeState: (sub: number) => boolean; - subscribeEvent: (key: string, onchange: (res: any) => void, refObject?: { - [key: string]: any; - }, refKey?: string) => number; - unsubscribeEvent: (key: string, sub?: number) => boolean; - subscribeEventOnce: (key: string, onchange: (res: any) => void) => any; - getEvent: (key: any, sub?: any) => { - [key: string]: any; - sub: number; - onchange: Function; - } | { - [key: string]: any; - sub: number; - onchange: Function; - }[]; - getSnapshot: () => void; - onRemoved: (trigger: { - sub: number; - onchange: Function; - }) => void; -} diff --git a/src/extras/dist/src/core/Graph.d.ts b/src/extras/dist/src/core/Graph.d.ts deleted file mode 100644 index f77b09bd..00000000 --- a/src/extras/dist/src/core/Graph.d.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { EventHandler } from "./EventHandler"; -export declare const state: EventHandler; -export type GraphNodeProperties = { - __props?: Function | { - [key: string]: any; - } | GraphNodeProperties | GraphNode; - __operator?: ((...args: any[]) => any) | string; - __children?: { - [key: string]: any; - }; - __listeners?: { - [key: string]: true | string | ((result: any) => void) | { - __callback: string | ((result: any) => void) | true; - subInput?: boolean; - [key: string]: any; - }; - } | { - [key: string]: ((result: any) => void) | true | string; - }; - __onconnected?: ((node: any) => void | ((node: any) => void)[]); - __ondisconnected?: ((node: any) => void | ((node: any) => void)[]); - __node?: { - tag?: string; - state?: EventHandler; - [key: string]: any; - }; - __args?: any[]; - __callable?: boolean; - [key: string]: any; -}; -export type Loader = (node: GraphNode, parent: Graph | GraphNode, graph: Graph, roots: any, properties: GraphNodeProperties, key: string) => void; -export type Roots = { - [key: string]: any; -}; -export type GraphOptions = { - roots?: Roots; - loaders?: { - [key: string]: Loader | { - init?: Loader; - connected?: (node: any) => void; - disconnected?: (node: any) => void; - }; - }; - state?: EventHandler; - mapGraphs?: false; - [key: string]: any; -}; -export type argObject = { - __input?: string | ((...args: any[]) => any); - __callback: string | ((...args: any[]) => any); - __args?: any[]; - __output?: string | argObject | ((...args: any[]) => any); -}; -export type Listener = { - __callback?: string; - __args?: (argObject | Function | string)[]; - sub: number; - node: GraphNode; - graph: Graph; - source?: string; - key?: string; - target?: string; - tkey?: string; - arguments?: Function[]; - subInput?: boolean; - onchange: Function; -}; -export declare class Callable extends Function { - __bound: Callable; - __call: ((...args: any[]) => any); - [key: string]: any; - constructor(); -} -export declare class GraphNode { - __node: { - tag: string; - unique: string; - state: EventHandler; - [key: string]: any; - }; - __children?: { - [key: string]: GraphNode; - }; - __parent?: Graph | GraphNode; - __operator?: any; - __listeners?: any; - __props?: any; - __args: any[]; - [key: string]: any; - constructor(properties: GraphNodeProperties, parent?: { - [key: string]: any; - }, graph?: Graph); - get __graph(): any; - set __graph(graph: any); - __setProperties: (properties: any, parent: any, graph: any) => void; - __subscribe: (callback: string | GraphNode | ((res: any) => void), key?: string, subInput?: boolean, target?: string, tkey?: string, args?: any[], callbackStr?: string) => any; - __unsubscribe: (sub?: number, key?: string, unsubInput?: boolean) => boolean; - __setOperator: (fn: (...args: any[]) => any) => any; - __addLocalState: (props?: { - [key: string]: any; - }, key?: string) => void; - __proxyObject: (obj: any) => void; - __addOnconnected(callback: (node: any) => void): void; - __addOndisconnected(callback: (node: any) => void): void; - __callConnected(node?: this): void; - __callDisconnected(node?: this): void; -} -export declare class Graph { - [key: string]: any; - __node: { - tag: string; - unique: string; - state: EventHandler; - nodes: Map; - roots: { - [key: string]: any; - }; - mapGraphs?: boolean; - [key: string]: any; - }; - constructor(options?: GraphOptions); - init: (options?: GraphOptions) => void; - load: (roots: { - [key: string]: any; - }, overwrite?: boolean) => { - [key: string]: any; - }; - setLoaders: (loaders: { - [key: string]: (node: GraphNode, parent: Graph | GraphNode, graph: Graph, roots: any, props: any, key: string) => void; - }, replace?: boolean) => any; - runLoaders: (node: any, parent: any, properties: any, key: any) => void; - add: (properties: any, parent?: GraphNode | string, overwrite?: boolean) => GraphNode; - recursiveSet: (originCpy: any, parent: any, listeners: any, origin: any, overwrite?: boolean) => any; - remove: (node: GraphNode | string, clearListeners?: boolean) => string | GraphNode; - run: (node: string | GraphNode, ...args: any[]) => any; - /** - * - * Listeners are an object where each key is a node tag, and each value is an object specifying callbacks or multiple callback for events on the graph, e.g. function outputs or variable changes. - * { - * [node.__node.tag (or arbitrary)]:{ - * [node.key (key optional)]:{__callback:string|Function, __args?:[], subInput?:boolean} | Function (bound to main node tag if specified) | string - * } - * } - * - * __args can be strings referencing other nodes/methods or values to pass correct inputs into the callback if more than one is required, else the output of the thing listened to is used by default - */ - setListeners: (listeners: { - [key: string]: { - [key: string]: any; - }; - }) => void; - clearListeners: (node: GraphNode | string, listener?: string) => void; - get: (tag: string) => any; - getByUnique: (unique: string) => any; - set: (tag: string, node: GraphNode) => Map; - delete: (tag: string) => boolean; - list: () => string[]; - getListener: (nodeTag: string, key?: string, sub?: number) => Listener; - getProps: (node: GraphNode | string, getInitial?: boolean) => void; - subscribe: (nodeEvent: GraphNode | string, onEvent: string | GraphNode | ((...res: any) => void), args?: any[], key?: string | undefined, subInput?: boolean, target?: string | GraphNode, tkey?: string) => number; - unsubscribe: (node: GraphNode | string, sub?: number, key?: string, subInput?: boolean) => any; - setState: (update: { - [key: string]: any; - }) => void; -} -export declare function getAllProperties(obj: any): any[]; -export declare function instanceObject(obj: any): any; -export declare function isNativeClass(thing: any): boolean; -export declare function isFunction(x: any): "function" | "class" | "async" | "arrow" | ""; -export declare let getCallbackFromString: (a: any, graph: any) => (...inp: any[]) => any; -export declare const wrapArgs: (callback: any, argOrder: any, graph: any) => { - __callback: any; - __args: any[]; -}; diff --git a/src/extras/dist/src/extras/algorithms/accel_gyro.d.ts b/src/extras/dist/src/extras/algorithms/accel_gyro.d.ts deleted file mode 100644 index c98cb706..00000000 --- a/src/extras/dist/src/extras/algorithms/accel_gyro.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { GraphNodeProperties } from '../../core/Graph'; -export declare const accel_gyro: GraphNodeProperties; diff --git a/src/extras/dist/src/extras/algorithms/beat_detect.d.ts b/src/extras/dist/src/extras/algorithms/beat_detect.d.ts deleted file mode 100644 index bc3fb33d..00000000 --- a/src/extras/dist/src/extras/algorithms/beat_detect.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { GraphNodeProperties } from '../../core/Graph'; -export declare const beat_detect: GraphNodeProperties; diff --git a/src/extras/dist/src/extras/algorithms/blink.d.ts b/src/extras/dist/src/extras/algorithms/blink.d.ts deleted file mode 100644 index 4743de8d..00000000 --- a/src/extras/dist/src/extras/algorithms/blink.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { GraphNodeProperties } from '../../core/Graph'; -export declare const blink_detect: GraphNodeProperties; diff --git a/src/extras/dist/src/extras/algorithms/buffering.d.ts b/src/extras/dist/src/extras/algorithms/buffering.d.ts deleted file mode 100644 index 71e1efac..00000000 --- a/src/extras/dist/src/extras/algorithms/buffering.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { GraphNodeProperties } from '../../core/Graph'; -export declare const circularBuffer2d: GraphNodeProperties; diff --git a/src/extras/dist/src/extras/algorithms/coherence.d.ts b/src/extras/dist/src/extras/algorithms/coherence.d.ts deleted file mode 100644 index 0b35b736..00000000 --- a/src/extras/dist/src/extras/algorithms/coherence.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { GraphNodeProperties } from '../../core/Graph'; -export declare const coherence: GraphNodeProperties; diff --git a/src/extras/dist/src/extras/algorithms/dft.d.ts b/src/extras/dist/src/extras/algorithms/dft.d.ts deleted file mode 100644 index ccd239c3..00000000 --- a/src/extras/dist/src/extras/algorithms/dft.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { GraphNodeProperties } from '../../core/Graph'; -export declare const dft: GraphNodeProperties; diff --git a/src/extras/dist/src/extras/algorithms/index.d.ts b/src/extras/dist/src/extras/algorithms/index.d.ts deleted file mode 100644 index c3ec990e..00000000 --- a/src/extras/dist/src/extras/algorithms/index.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { GraphNodeProperties } from "../../core/Graph"; -declare const algorithms: { - [key: string]: GraphNodeProperties; -}; -export { algorithms }; diff --git a/src/extras/dist/src/extras/algorithms/index.gpu.d.ts b/src/extras/dist/src/extras/algorithms/index.gpu.d.ts deleted file mode 100644 index fcfc3ef0..00000000 --- a/src/extras/dist/src/extras/algorithms/index.gpu.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -export declare const gpualgorithms: { - dft: import("../../core/Graph").GraphNodeProperties; - coherence: import("../../core/Graph").GraphNodeProperties; -}; diff --git a/src/extras/dist/src/extras/algorithms/rms.d.ts b/src/extras/dist/src/extras/algorithms/rms.d.ts deleted file mode 100644 index 39ad84d0..00000000 --- a/src/extras/dist/src/extras/algorithms/rms.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { GraphNodeProperties } from "../../core/Graph"; -export declare const rms: GraphNodeProperties; diff --git a/src/extras/dist/src/extras/algorithms/util/ArrayManip.d.ts b/src/extras/dist/src/extras/algorithms/util/ArrayManip.d.ts deleted file mode 100644 index b6d5e3ad..00000000 --- a/src/extras/dist/src/extras/algorithms/util/ArrayManip.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array; -export declare class ArrayManip { - static autoscale(array: any, lineIdx?: number, nLines?: number, centerZero?: boolean, ymin?: number, ymax?: number, clamp?: boolean): any; - static genTimestamps(ct: any, sps: any): any[]; - static absmax(array: any): number; - static downsample(array: any, fitCount: any, scalar?: number): any; - static upsample(array: any, fitCount: any, scalar?: number): any[]; - static interpolate(array: number[], fitCount: number, scalar?: number): any; - static HSLToRGB(h: any, s: any, l: any, scalar?: number): [number, number, number]; - static circularBuffer(arr: any[], newEntries: any[]): any[]; - static reformatData(data: { - [key: string]: number[] | number | { - values: number[] | number; - [key: string]: any; - }; - } | string | ((number | number[])[]) | number, key?: string): string | number | { - [key: string]: number | number[] | { - [key: string]: any; - values: number[] | number; - }; - } | (number | number[])[]; - static padTime(data: number[], //new data, assumed to be sequential between a gap - lastValue: number, //the last data point before the gap - time: number, //interval that's passed to determine slope between samples - targetFit: number): number[]; - static interpolateForTime(data: number[], //new data, assumed to be evenly spread over a time interval - time: number, //the time interval passed (s) - targetSPS: number): any; - static bufferValues: (objects: { - [key: string]: { - [key: string]: any; - }; - }, property: string, keys?: string[] | { - [key: string]: any; - }, buffer?: ArrayBufferLike) => ArrayBufferLike; - isTypedArray(x: any): boolean; - recursivelyAssign: (target: any, obj: any) => any; - spliceTypedArray(arr: TypedArray, start: number, end?: number): TypedArray; -} diff --git a/src/extras/dist/src/extras/algorithms/util/ByteParser.d.ts b/src/extras/dist/src/extras/algorithms/util/ByteParser.d.ts deleted file mode 100644 index 178a7329..00000000 --- a/src/extras/dist/src/extras/algorithms/util/ByteParser.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { ArrayManip } from "./ArrayManip"; -export declare class ByteParser extends ArrayManip { - static codes: { - '\\n': number; - '\\r': number; - '\\t': number; - '\\s': number; - '\\b': number; - '\\f': number; - '\\': number; - }; - static toDataView(value: string | number | ArrayBufferLike | DataView | number[]): DataView; - static searchBuffer(buffer: number[] | ArrayBuffer, searchString: Uint8Array, limit?: number): any[]; - static bytesToInt16(x0: number, x1: number): number; - static bytesToUInt16(x0: number, x1: number): number; - static Uint16ToBytes(y: number): number[]; - static bytesToInt24(x0: number, x1: number, x2: number): number; - static bytesToUInt24(x0: number, x1: number, x2: number): number; - static Uint24ToBytes(y: number): number[]; - static bytesToInt32(x0: number, x1: number, x2: number, x3: number): number; - static bytesToUInt32(x0: number, x1: number, x2: number, x3: number): number; - static Uint32ToBytes(y: number): number[]; - static get2sCompliment(val: number, nbits: number): number; - static getSignedInt(...args: number[]): number; - static asUint8Array(input: any): Uint8Array; - static boyerMoore(patternBuffer: any): any; - static struct(format: string): Readonly<{ - unpack: (arrb: any) => any[]; - pack: (...values: any[]) => ArrayBuffer; - unpack_from: (arrb: any, offs: any) => any[]; - pack_into: (arrb: any, offs: any, ...values: any[]) => void; - iter_unpack: (arrb: any) => Generator; - format: string; - size: number; - }>; -} diff --git a/src/extras/dist/src/extras/gpu/GPU.service.d.ts b/src/extras/dist/src/extras/gpu/GPU.service.d.ts deleted file mode 100644 index 547ea325..00000000 --- a/src/extras/dist/src/extras/gpu/GPU.service.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Service } from "../../services/Service"; -import { gpuUtils } from 'gpujsutils'; -export declare class GPUService extends Service { - gpu: gpuUtils; - constructor(options?: any); - addFunc: (fn: string | Function) => void; - addKernel: (name: string, fn: string | Function, options?: any) => void; - combineKernels: (name: string, fs: (string | Function)[], ckrnl?: () => void) => void; - callKernel: (name: string, ...args: any[]) => void; - dft: (signalBuffer: number[], nSeconds: any, scalar?: number) => any; - multidft: (signalBuffer: number[], nSeconds: any, scalar?: number) => any; - multidftbandpass: (buffered: number[][], nSeconds: number, freqStart: number, freqEnd: number, scalar?: number) => any; - coherence: (buffered: number[][], nSeconds: number, freqStart: number, freqEnd: number) => any[]; -} diff --git a/src/extras/dist/src/extras/index.gpu.services.d.ts b/src/extras/dist/src/extras/index.gpu.services.d.ts deleted file mode 100644 index a1d3d930..00000000 --- a/src/extras/dist/src/extras/index.gpu.services.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './gpu/GPU.service'; -export { gpualgorithms } from './algorithms/index.gpu'; diff --git a/src/extras/dist/src/extras/index.services.d.ts b/src/extras/dist/src/extras/index.services.d.ts deleted file mode 100644 index 4c38107e..00000000 --- a/src/extras/dist/src/extras/index.services.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './struct/Struct.frontend'; -export * from './struct/Struct.backend'; -export * from './struct/genTimestamps'; -export * from './ecs/ECS.systems'; -export * from './webgl-plot/webglplot.routes'; -export { algorithms } from './algorithms/index'; diff --git a/src/extras/dist/src/extras/struct/Struct.backend.d.ts b/src/extras/dist/src/extras/struct/Struct.backend.d.ts deleted file mode 100644 index 278d1ebe..00000000 --- a/src/extras/dist/src/extras/struct/Struct.backend.d.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { ObjectId } from "./datastructures/bson.cjs"; -import { AuthorizationStruct, GroupStruct, ProfileStruct } from "./datastructures/types"; -import { TimeSpecifier } from './genTimestamps'; -import { Service } from "../../services/Service"; -import { User } from '../../services/router/Router'; -export declare const toObjectId: (str: any) => any; -export declare const getStringId: (mongoid: string | ObjectId) => any; -type CollectionsType = { - [x: string]: CollectionType; -}; -type CollectionType = any | { - instance?: any; - reference: { - [key: string]: any; - }; -}; -export declare class StructBackend extends Service { - name: string; - debug: boolean; - db: any; - users: { - [key: string]: User; - }; - collections: CollectionsType; - mode: 'local' | 'mongo' | string; - useAuths: boolean; - useAccessTokens: boolean; - useRefreshTokens: boolean; - accessTokens: Map; - refreshTokens: Map; - constructor(options?: any, dboptions?: { - users?: { - [key: string]: User; - }; - mode?: 'local' | 'mongo' | string; - db?: any; - collections?: CollectionsType; - useAuths?: boolean; - debug?: boolean; - useAccessTokens?: boolean; - useRefreshTokens?: boolean; - }); - initDB: (dboptions: any) => void; - query: (requestingUserId: string, collection?: any, queryObj?: any, findOne?: boolean, skip?: number, token?: string) => Promise; - getUser: (requestingUserId: string, lookupId: string, basicInfo?: boolean, token?: string) => Promise; - setUser: (requestingUserId: string, struct: Partial, token: string) => Promise; - getUsersByIds: (requestingUserId: string, userIds: string[], basicInfo?: boolean) => Promise; - getUsersByRole: (requestingUserId: string, role: string) => Promise; - deleteUser: (requestingUserId: string, userId: string, deleteData?: boolean, token?: string) => Promise; - setData: (requestingUserId: string, structs: any[], notify?: boolean, token?: string) => Promise; - getData: (requestingUserId: string, collection?: string, ownerId?: string, dict?: any, limit?: number, skip?: number, token?: string) => Promise; - getDataByIds: (requestingUserId: string, structIds: string[], ownerId?: string, collection?: string, token?: string) => Promise; - getAllData: (requestingUserId: string, ownerId: string, excludedCollections?: string[], timeRange?: [number | TimeSpecifier, number | TimeSpecifier], token?: string) => Promise; - deleteData: (requestingUserId: string, structIds: string[], token?: string) => Promise; - getUserGroups: (requestingUserId: string, userId?: string, groupId?: string) => Promise; - deleteGroup: (requestingUserId: string, groupId: string, token?: string) => Promise; - getAuthorizations: (requestingUserId: string, ownerId?: string, authId?: string, token?: string) => Promise; - deleteAuthorization: (requestingUserId: string, authId: string, token?: string) => Promise; - getToken: (user: Partial) => string; - notificationStruct: (parentStruct?: any) => { - structType: string; - timestamp: number; - _id: string; - note: string; - alert: boolean; - ownerId: string; - parentUserId: string; - parent: { - structType: any; - _id: any; - }; - }; - checkToNotify: (user: Partial, structs?: any[], mode?: string) => Promise; - queryMongo: (user: Partial, collection: string, queryObj?: any, findOne?: boolean, skip?: number, token?: string) => Promise; - setMongoData: (user: Partial, structs?: any[], notify?: boolean, token?: string) => Promise; - setMongoUser: (user: Partial, struct: Partial, token?: string) => Promise; - setGroup: (user: Partial, struct: any, mode?: string, token?: string) => Promise; - getMongoUser: (user: Partial, info?: string, requireAuth?: boolean, basicInfo?: boolean, token?: string) => Promise<{} | { - user: ProfileStruct; - authorizations: AuthorizationStruct[]; - groups: GroupStruct[] | { - user: ProfileStruct; - }; - }>; - queryUsers: (user: Partial, info?: string, limit?: number, skip?: number, requireAuth?: boolean, token?: string) => Promise<{} | { - user: ProfileStruct; - authorizations: AuthorizationStruct[]; - groups: GroupStruct[] | { - user: ProfileStruct; - }; - }>; - getMongoUsersByIds: (user: Partial, userIds?: any[], basicInfo?: boolean) => Promise; - getMongoUsersByRole: (user: Partial, role: string) => Promise; - getMongoDataByIds: (user: Partial, structIds: string[], ownerId: string | undefined, collection: string | undefined, token?: string) => Promise; - getMongoData: (user: Partial, collection: string | undefined, ownerId: string | undefined, dict?: any | undefined, limit?: number, skip?: number, token?: string) => Promise; - getAllUserMongoData: (user: Partial, ownerId: any, excluded?: any[], timeRange?: [number | TimeSpecifier, number | TimeSpecifier], token?: string) => Promise; - getMongoDataByRefs: (user: Partial, structRefs?: any[], token?: string) => Promise; - getMongoAuthorizations: (user: Partial, ownerId?: any, authId?: string, token?: string) => Promise; - getMongoGroups: (user: Partial, userId?: any, groupId?: string) => Promise; - deleteMongoData: (user: Partial, structRefs?: any[], token?: string) => Promise; - deleteMongoUser: (user: Partial, userId: any, deleteData?: boolean, token?: string) => Promise; - deleteMongoGroup: (user: Partial, groupId: any, token?: string) => Promise; - deleteMongoAuthorization: (user: Partial, authId: any, token?: string) => Promise; - setAuthorization: (user: Partial, authStruct: any, token?: string) => Promise; - checkAuthorization: (user: string | Partial | { - _id: string; - }, struct: any, request?: string, token?: string) => Promise; - wipeDB: () => Promise; - overwriteLocalData: (structs: any) => void; - setLocalData: (structs: any) => void; - getLocalData: (collection: any, query?: any) => any; - deleteLocalData: (struct: any) => boolean; -} -export {}; diff --git a/src/extras/dist/src/extras/struct/Struct.frontend.d.ts b/src/extras/dist/src/extras/struct/Struct.frontend.d.ts deleted file mode 100644 index 3b0ef8dc..00000000 --- a/src/extras/dist/src/extras/struct/Struct.frontend.d.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { DataTablet } from './datastructures/index'; -import { Data, ProfileStruct, AuthorizationStruct, GroupStruct, DataStruct, EventStruct, ChatroomStruct, CommentStruct, Struct } from './datastructures/types'; -import { TimeSpecifier } from './genTimestamps'; -import { Service } from '../../services/Service'; -import { User } from '../../services/router/Router'; -import { GraphNodeProperties } from '../../core/Graph'; -export declare const randomId: (prefix?: any) => string; -export declare const pseudoObjectId: (m?: Math, d?: DateConstructor, h?: number, s?: (s: any) => string) => string; -export type StructFrontendProps = { - useAccessTokens?: boolean; - useRefreshTokens?: boolean; -} & GraphNodeProperties; -export declare class StructFrontend extends Service { - name: string; - currentUser: User; - tablet: DataTablet; - collections: Map; - id: string; - useAccessTokens: boolean; - useRefreshTokens: boolean; - constructor(options?: any, user?: Partial); - getToken(user: Partial): string; - setupUser: (userinfo: Partial, callback?: (currentUser: any) => void) => Promise; - baseServerCallback: (data: any) => void; - structNotification: () => void; - structDeleted: (struct: { - _id: string; - structType: string; - }) => void; - onResult: (data: any) => void; - randomId(tag?: string): string; - /** - let struct = { - _id: randomId(structType+'defaultId'), //random id associated for unique identification, used for lookup and indexing - structType: structType, //this is how you will look it up by type in the server - ownerId: parentUser?._id, //owner user - timestamp: Date.now(), //date of creation - parent: {structType:parentStruct?.structType,_id:parentStruct?._id}, //parent struct it's associated with (e.g. if it needs to spawn with it) - } - */ - addStruct: (structType?: string, props?: any, parentUser?: { - [key: string]: any; - }, parentStruct?: { - [key: string]: any; - }, updateServer?: boolean) => Promise; - getUser: (info?: string | number, basicInfo?: boolean, callback?: (data: any) => void) => Promise<{ - user: ProfileStruct; - groups: GroupStruct[]; - authorizations: AuthorizationStruct[]; - }>; - queryUsers: (info: string, skip?: number, limit?: number, callback?: (data: any) => void) => Promise; - getUsers: (ids?: (string | number)[], basicInfo?: boolean, callback?: (data: any) => void) => Promise; - getUsersByRole: (userRole: string, callback?: (data: any) => void) => Promise; - getAllUserData: (ownerId: string | number, excluded?: any[], timeRange?: [number | TimeSpecifier, number | TimeSpecifier], callback?: (data: any) => void) => Promise; - query: (collection: string, mongoQuery?: {}, findOne?: boolean, skip?: number, callback?: (data: any) => void) => Promise; - getDataByTimeRange(collection: any, timeRange?: [number | TimeSpecifier, number | TimeSpecifier], ownerId?: string | number | undefined, limit?: number, skip?: number, key?: string): Promise; - getData: (collection: string, ownerId?: string | number | undefined, searchDict?: any, limit?: number, skip?: number, callback?: (data: any) => void) => Promise; - getDataByIds: (structIds?: any[], ownerId?: string | number | undefined, collection?: string | undefined, callback?: (data: any) => void) => Promise; - getStructParentData: (struct: Struct, callback?: (data: any) => void) => Promise; - setUser: (userStruct: ProfileStruct, callback?: (data: any) => void) => Promise; - checkUserToken: (usertoken: any, user?: User, callback?: (data: any) => void) => Promise; - setData: (structs?: Partial | Partial[], notify?: boolean, callback?: (data: any) => void) => Promise; - updateServerData: (structs?: Partial | Partial[], notify?: boolean, callback?: (data: any) => void) => Promise; - deleteData: (structs?: any[], callback?: (data: any) => void) => Promise; - deleteUser: (userId?: string, deleteData?: boolean, callback?: (data: any) => void) => Promise; - setGroup: (groupStruct: GroupStruct, callback?: (data: any) => void) => Promise; - getUserGroups: (userId?: string, groupId?: string, callback?: (data: any) => void) => Promise; - deleteGroup: (groupId: any, callback?: (data: any) => void) => Promise; - setAuthorization: (authorizationStruct: AuthorizationStruct, callback?: (data: any) => void) => Promise; - getAuthorizations: (userId?: string, authorizationId?: string, callback?: (data: any) => void) => Promise; - deleteAuthorization: (authorizationId: any, callback?: (data: any) => void) => Promise; - checkForNotifications: (userId?: string) => Promise; - resolveNotifications: (notifications?: any[], pull?: boolean, user?: Partial) => Promise; - setAuthorizationsByGroup: (user?: User) => Promise; - deleteRoom: (roomStruct: any) => Promise; - deleteComment: (commentStruct: any) => Promise; - getUserDataByAuthorization: (authorizationStruct: any, collection: any, searchDict: any, limit?: number, skip?: number, callback?: (data: any) => void) => Promise; - getUserDataByAuthorizationGroup: (groupId: string, collection: any, searchDict: any, limit?: number, skip?: number, callback?: (data: any) => void) => Promise; - overwriteLocalData(structs: any): void; - setLocalData(structs: any): void; - getLocalData(collection: any, query?: any): any; - getLocalUserPeerIds: (user?: User) => any; - getLocalReplies(struct: any): any; - hasLocalAuthorization(otherUserId: any, ownerId?: string): any; - deleteLocalData(structs: Struct[]): boolean; - deleteStruct(struct: Struct): boolean; - stripStruct(struct: Struct): Struct; - createStruct(structType: string, props: { - [key: string]: any; - }, parentUser?: User, parentStruct?: Struct): any; - userStruct(props?: Partial, currentUser?: boolean): ProfileStruct; - authorizeUser: (parentUser: Partial, authorizerUserId?: string, authorizerUserName?: string, authorizedUserId?: string, authorizedUserName?: string, authorizations?: {}, structs?: {}, excluded?: {}, groups?: {}, expires?: boolean) => Promise; - addGroup: (parentUser: Partial, name?: string, details?: string, admins?: {}, peers?: {}, clients?: {}, updateServer?: boolean) => Promise; - dataObject(data?: any, type?: string, timestamp?: string | number): { - type: string; - data: any; - timestamp: string | number; - }; - addData: (parentUser: Partial, author?: string, title?: string, type?: string, data?: string | Data[], expires?: boolean, updateServer?: boolean) => Promise; - addEvent: (parentUser: Partial, author?: string, event?: string | number, notes?: string, startTime?: string | number, endTime?: string | number, grade?: string | number, value?: any, units?: string, location?: any, attachments?: string | Data[], users?: { - [key: string]: true; - }, updateServer?: boolean) => Promise; - addChatroom: (parentUser: Partial, authorId?: string, message?: string, attachments?: string | Data[], users?: { - [key: string]: true; - }, updateServer?: boolean) => Promise; - addComment: (parentUser: Partial, roomStruct?: { - _id: string; - users: any[]; - comments: any[]; - }, replyTo?: { - _id: string; - replies: any[]; - }, authorId?: string, message?: string, attachments?: string | Data[], updateServer?: boolean) => Promise; -} diff --git a/src/extras/dist/src/extras/struct/datastructures/DataStructures.d.ts b/src/extras/dist/src/extras/struct/datastructures/DataStructures.d.ts deleted file mode 100644 index 3da6e206..00000000 --- a/src/extras/dist/src/extras/struct/datastructures/DataStructures.d.ts +++ /dev/null @@ -1,140 +0,0 @@ -import * as types from './types'; -export declare function Struct(structType?: string | number | undefined, assignProps?: types.ArbitraryObject, parentUser?: Partial | { - _id: string; -}, parentStruct?: types.ArbitraryObject): types.Struct; -export declare const eegCoordinates: { - [x: string]: number[]; -}; -export declare function setCoordinate(channelDict: any, assignTo?: {}): any; -export declare function EEGCoordinates(channelDicts?: [], genCoherenceMap?: boolean): types.EEGStruct[]; -export declare function FrequencyBandsStruct(additionalBands?: types.FrequencyBandNames[], //add whatever tags -assignTo?: {}): types.FrequencyBandsStruct; -export declare function EEGStruct(tag?: string | number | undefined, assignProps?: types.ArbitraryObject, parentUser?: Partial | { - _id: string; -}, parentStruct?: types.ArbitraryObject): types.EEGStruct; -export declare function CoherenceStruct(coords?: { - 0: types.EEGStruct; - 1: types.EEGStruct; -}, assignProps?: types.ArbitraryObject, parentUser?: Partial | { - _id: string; -}, parentStruct?: types.ArbitraryObject): types.CoherenceStruct; -export declare function CoherenceMap(opts?: { - channelDicts: any[]; - taggedOnly?: boolean; -}, _?: types.ArbitraryObject, parentUser?: Partial | { - _id: string; -}, parentStruct?: types.ArbitraryObject): types.CoherenceStruct[]; -export declare function FNIRSStruct(tag?: string | number | undefined, assignProps?: types.ArbitraryObject, parentUser?: Partial | { - _id: string; -}, parentStruct?: types.ArbitraryObject): types.FNIRSStruct; -export declare function IMUStruct(tag?: string | number | undefined, assignProps?: types.ArbitraryObject, parentUser?: Partial | { - _id: string; -}, parentStruct?: types.ArbitraryObject): types.IMUStruct; -export declare function EyeTrackerStruct(tag?: string | number | undefined, assignProps?: types.ArbitraryObject, parentUser?: Partial | { - _id: string; -}, parentStruct?: types.ArbitraryObject): types.EyeTrackerStruct; -export declare function ECGStruct(tag?: string | number | undefined, assignProps?: types.ArbitraryObject, parentUser?: Partial | { - _id: string; -}, parentStruct?: types.ArbitraryObject): types.ECGStruct; -export declare function EDAStruct(_?: string, __?: {}, ___?: { - _id: string; -}, ____?: { - structType: string; - _id: string; -}): void; -export declare function PPGStruct(tag?: string | number | undefined, assignProps?: types.ArbitraryObject, parentUser?: Partial | { - _id: string; -}, parentStruct?: types.ArbitraryObject): types.FNIRSStruct; -export declare function HRVStruct(tag?: string | number | undefined, assignProps?: types.ArbitraryObject, parentUser?: Partial | { - _id: string; -}, parentStruct?: types.ArbitraryObject): types.ECGStruct; -export declare function EMGStruct(tag?: string | number | undefined, assignProps?: types.ArbitraryObject, parentUser?: Partial | { - _id: string; -}, parentStruct?: types.ArbitraryObject): types.EEGStruct; -export declare function ProfileStruct(tag?: string | number | undefined, assignProps?: types.ArbitraryObject, parentUser?: Partial | { - _id: string; -}, parentStruct?: types.ArbitraryObject): types.ProfileStruct; -export declare function AuthorizationStruct(tag?: string | number | undefined, assignProps?: {}, parentUser?: Partial | { - _id: string; -}, parentStruct?: { - structType: string; - _id: string; -}): types.AuthorizationStruct; -export declare function GroupStruct(tag?: string | number | undefined, assignProps?: {}, parentUser?: Partial | { - _id: string; -}, parentStruct?: { - structType: string; - _id: string; -}): types.GroupStruct; -export declare function Data(type: string, data: any): { - type: string; - data: any; - timestamp: number; -}; -export declare function DataStruct(tag?: string | number | undefined, assignProps?: {}, parentUser?: Partial | { - _id: string; -}, parentStruct?: { - structType: string; - _id: string; -}): types.DataStruct; -export declare function EventStruct(tag?: string | number | undefined, assignProps?: {}, parentUser?: Partial | { - _id: string; -}, parentStruct?: { - structType: string; - _id: string; -}): types.EventStruct; -export declare function ChatroomStruct(tag?: string | number | undefined, assignProps?: {}, parentUser?: Partial | { - _id: string; -}, parentStruct?: { - structType: string; - _id: string; -}): types.ChatroomStruct; -export declare function CommentStruct(tag?: string | number | undefined, assignProps?: {}, parentUser?: Partial | { - _id: string; -}, parentStruct?: { - structType: string; - _id: string; -}): types.CommentStruct; -export declare function NotificationStruct(tag?: string | number | undefined, assignProps?: {}, parentUser?: Partial | { - _id: string; -}, parentStruct?: { - structType: string; - _id: string; -}): types.NotificationStruct; -export declare function ScheduleStruct(tag?: string | number | undefined, assignProps?: {}, parentUser?: Partial | { - _id: string; -}, parentStruct?: { - structType: string; - _id: string; -}): types.ScheduleStruct; -export declare function DateStruct(tag?: string | number | undefined, assignProps?: {}, parentUser?: Partial | { - _id: string; -}, parentStruct?: { - structType: string; - _id: string; -}): types.DateStruct; -export declare const structRegistry: { - Struct: typeof Struct; - EEGStruct: typeof EEGStruct; - FNIRSStruct: typeof FNIRSStruct; - CoherenceStruct: typeof CoherenceStruct; - CoherenceMap: typeof CoherenceMap; - FrequencyBandsStruct: typeof FrequencyBandsStruct; - IMUStruct: typeof IMUStruct; - EyeTrackerStruct: typeof EyeTrackerStruct; - ECGStruct: typeof ECGStruct; - EDAStruct: typeof EDAStruct; - PPGStruct: typeof PPGStruct; - HRVStruct: typeof HRVStruct; - EMGStruct: typeof EMGStruct; - ProfileStruct: typeof ProfileStruct; - AuthorizationStruct: typeof AuthorizationStruct; - GroupStruct: typeof GroupStruct; - DataStruct: typeof DataStruct; - EventStruct: typeof EventStruct; - ChatroomStruct: typeof ChatroomStruct; - CommentStruct: typeof CommentStruct; - NotificationStruct: typeof NotificationStruct; - ScheduleStruct: typeof ScheduleStruct; - DateStruct: typeof DateStruct; -}; diff --git a/src/extras/dist/src/extras/struct/datastructures/DataTablet.d.ts b/src/extras/dist/src/extras/struct/datastructures/DataTablet.d.ts deleted file mode 100644 index 967adeae..00000000 --- a/src/extras/dist/src/extras/struct/datastructures/DataTablet.d.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { ArbitraryObject, Struct } from './types'; -export declare class DataTablet { - workerId: any; - id: any; - threaded: boolean; - workers: any; - DS: any; - collections: Map; - data: any; - rolloverLimit: number; - dataSorts: Map; - watches: any; - constructor(props?: {}); - randomId(tag?: string): string; - setLocalData(structs: (Partial)[] | (Partial)): void; - getLocalData(collection: string, query: any): any; - onCollectionSet: (type: any, collection: any) => void; - runSort(key: string, dataObj?: {}, newdata?: any[], tablet?: this): any; - /** - * Unsorted data structs come in with a minimum 'structType' and 'timestamp' set of values. - * - * If a sort key matches the structType or dataType (from a data struct.data array), - * it can return a modified struct or push to the newdata array with a set of newly made structs. - * Return undefined to process the input data by default structType/dataType and timestamp into the tablet, so you can do this - * plus split up additional structs or processed structs into each other. This is intentionally vague until we refine this idea into clearer hooks. - * The newdata array accumulates all of the data structs supplied on a sort pass which gets sent to this.onSorted() at the end of the sorting pass. - */ - setSort(key: string | string[], response?: (data: any, newdata?: any[], tablet?: this) => void): void; - getSort(key: string): any; - checkWatches(sorted?: ArbitraryObject): void; - /** - * - pass the sorted structure to the accumulator object which is just an empty object you can do whatever with - * - ondata checks the data if it's relevant and keeps a record via the accumulator - * - if the accumlator condition is satisfied, return true which triggers ontrigger(accum), else return a falsey value - * - ontrigger function then is passed the accumulator object to do whatever with, - * e.g. supply it to an 'alert' struct, set alert:true, and data:accum, and update the server to notify any connected peers. - */ - setWatch(name: string, ownerId: string | undefined, ondata?: (sorted: any, accum: any, ownerId: string) => boolean, ontrigger?: (accum: any) => void): void; - getWatch(name: string): any; - sortStructsIntoTable(datastructs?: Struct[]): Promise; - onUpdate(_: any, __: any, ___?: any): void; - onSorted(_?: any[]): void; - getDataByTimestamp(timestamp: number, ownerId: string): any; - getDataByTimeRange(begin: number, end: number, type: string, ownerId: string): ArbitraryObject; - getDataByType(type: string, timestamp: number, ownerId: string): any; - filterSleepResults(unfiltered?: ArbitraryObject): ArbitraryObject; - sortObjectByPropName(object: ArbitraryObject): ArbitraryObject; - checkRollover(collection: string, limit?: number): boolean; -} diff --git a/src/extras/dist/src/extras/struct/datastructures/bson.d.cts b/src/extras/dist/src/extras/struct/datastructures/bson.d.cts deleted file mode 100644 index 2efd64df..00000000 --- a/src/extras/dist/src/extras/struct/datastructures/bson.d.cts +++ /dev/null @@ -1,419 +0,0 @@ -declare var bson: Readonly<{ - __proto__: any; - Code: typeof Code; - BSONSymbol: typeof BSONSymbol; - DBRef: typeof DBRef; - Binary: typeof Binary; - ObjectId: typeof ObjectId; - UUID: typeof UUID; - Long: typeof Long; - Timestamp: typeof Timestamp; - Double: typeof Double; - Int32: typeof Int32; - MinKey: typeof MinKey; - MaxKey: typeof MaxKey; - BSONRegExp: typeof BSONRegExp; - Decimal128: typeof Decimal128; - setInternalBufferSize: typeof setInternalBufferSize; - serialize: typeof serialize; - serializeWithBufferAndIndex: typeof serializeWithBufferAndIndex; - deserialize: typeof deserialize; - calculateObjectSize: typeof calculateObjectSize; - deserializeStream: typeof deserializeStream; - BSONValue: typeof BSONValue; - BSONError: typeof BSONError; - BSONVersionError: typeof BSONVersionError; - BSONRuntimeError: typeof BSONRuntimeError; - BSONType: Readonly<{ - double: 1; - string: 2; - object: 3; - array: 4; - binData: 5; - undefined: 6; - objectId: 7; - bool: 8; - date: 9; - null: 10; - regex: 11; - dbPointer: 12; - javascript: 13; - symbol: 14; - javascriptWithScope: 15; - int: 16; - timestamp: 17; - long: 18; - decimal: 19; - minKey: -1; - maxKey: 127; - }>; - EJSON: any; -}>; -export class BSONError extends Error { - static isBSONError(value: any): boolean; - constructor(message: any); - get bsonError(): boolean; - get name(): string; -} -export class BSONRegExp extends BSONValue { - static parseOptions(options: any): any; - static fromExtendedJSON(doc: any): any; - constructor(pattern: any, options: any); - get _bsontype(): string; - pattern: any; - options: any; - toExtendedJSON(options: any): { - $regex: any; - $options: any; - $regularExpression?: undefined; - } | { - $regularExpression: { - pattern: any; - options: any; - }; - $regex?: undefined; - $options?: undefined; - }; - inspect(): string; -} -export class BSONRuntimeError extends BSONError { -} -export class BSONSymbol extends BSONValue { - static fromExtendedJSON(doc: any): BSONSymbol; - constructor(value: any); - get _bsontype(): string; - value: any; - valueOf(): any; - toString(): any; - inspect(): string; - toJSON(): any; - toExtendedJSON(): { - $symbol: any; - }; -} -export const BSONType: Readonly<{ - double: 1; - string: 2; - object: 3; - array: 4; - binData: 5; - undefined: 6; - objectId: 7; - bool: 8; - date: 9; - null: 10; - regex: 11; - dbPointer: 12; - javascript: 13; - symbol: 14; - javascriptWithScope: 15; - int: 16; - timestamp: 17; - long: 18; - decimal: 19; - minKey: -1; - maxKey: 127; -}>; -export class BSONValue { -} -export class BSONVersionError extends BSONError { - constructor(); -} -export class Binary extends BSONValue { - static fromExtendedJSON(doc: any, options: any): Binary; - constructor(buffer: any, subType: any); - get _bsontype(): string; - sub_type: any; - buffer: any; - position: any; - put(byteValue: any): void; - write(sequence: any, offset: any): void; - read(position: any, length: any): any; - value(asRaw: any): any; - length(): any; - toJSON(): any; - toString(encoding: any): any; - toExtendedJSON(options: any): { - $binary: any; - $type: string; - } | { - $binary: { - base64: any; - subType: string; - }; - $type?: undefined; - }; - toUUID(): UUID; - inspect(): string; -} -export namespace Binary { - let BSON_BINARY_SUBTYPE_DEFAULT: number; - let BUFFER_SIZE: number; - let SUBTYPE_DEFAULT: number; - let SUBTYPE_FUNCTION: number; - let SUBTYPE_BYTE_ARRAY: number; - let SUBTYPE_UUID_OLD: number; - let SUBTYPE_UUID: number; - let SUBTYPE_MD5: number; - let SUBTYPE_ENCRYPTED: number; - let SUBTYPE_COLUMN: number; - let SUBTYPE_USER_DEFINED: number; -} -export class Code extends BSONValue { - static fromExtendedJSON(doc: any): Code; - constructor(code: any, scope: any); - get _bsontype(): string; - code: any; - scope: any; - toJSON(): { - code: any; - scope: any; - } | { - code: any; - scope?: undefined; - }; - toExtendedJSON(): { - $code: any; - $scope: any; - } | { - $code: any; - $scope?: undefined; - }; - inspect(): string; -} -export class DBRef extends BSONValue { - static fromExtendedJSON(doc: any): DBRef; - constructor(collection: any, oid: any, db: any, fields: any); - get _bsontype(): string; - collection: any; - oid: any; - db: any; - fields: any; - set namespace(value: any); - get namespace(): any; - toJSON(): any; - toExtendedJSON(options: any): { - $ref: any; - $id: any; - }; - inspect(): string; -} -export class Decimal128 extends BSONValue { - static fromString(representation: any): Decimal128; - static fromExtendedJSON(doc: any): Decimal128; - constructor(bytes: any); - get _bsontype(): string; - bytes: any; - toJSON(): { - $numberDecimal: string; - }; - toExtendedJSON(): { - $numberDecimal: string; - }; - inspect(): string; -} -export class Double extends BSONValue { - static fromExtendedJSON(doc: any, options: any): number | Double; - constructor(value: any); - get _bsontype(): string; - value: number; - valueOf(): number; - toJSON(): number; - toString(radix: any): string; - toExtendedJSON(options: any): number | { - $numberDouble: string; - }; - inspect(): string; -} -export const EJSON: any; -export class Int32 extends BSONValue { - static fromExtendedJSON(doc: any, options: any): number | Int32; - constructor(value: any); - get _bsontype(): string; - value: number; - valueOf(): number; - toString(radix: any): string; - toJSON(): number; - toExtendedJSON(options: any): number | { - $numberInt: string; - }; - inspect(): string; -} -export class Long extends BSONValue { - static fromBits(lowBits: any, highBits: any, unsigned: any): Long; - static fromInt(value: any, unsigned: any): any; - static fromNumber(value: any, unsigned: any): any; - static fromBigInt(value: any, unsigned: any): any; - static fromString(str: any, unsigned: any, radix: any): any; - static fromBytes(bytes: any, unsigned: any, le: any): Long; - static fromBytesLE(bytes: any, unsigned: any): Long; - static fromBytesBE(bytes: any, unsigned: any): Long; - static isLong(value: any): boolean; - static fromValue(val: any, unsigned: any): any; - static fromExtendedJSON(doc: any, options: any): any; - constructor(low: number, high: any, unsigned: any); - get _bsontype(): string; - get __isLong__(): boolean; - low: number; - high: number; - unsigned: boolean; - add(addend: any): Long; - and(other: any): Long; - compare(other: any): 0 | 1 | -1; - comp(other: any): 0 | 1 | -1; - divide(divisor: any): any; - div(divisor: any): any; - equals(other: any): boolean; - eq(other: any): boolean; - getHighBits(): number; - getHighBitsUnsigned(): number; - getLowBits(): number; - getLowBitsUnsigned(): number; - getNumBitsAbs(): any; - greaterThan(other: any): boolean; - gt(other: any): boolean; - greaterThanOrEqual(other: any): boolean; - gte(other: any): boolean; - ge(other: any): boolean; - isEven(): boolean; - isNegative(): boolean; - isOdd(): boolean; - isPositive(): boolean; - isZero(): boolean; - lessThan(other: any): boolean; - lt(other: any): boolean; - lessThanOrEqual(other: any): boolean; - lte(other: any): boolean; - modulo(divisor: any): Long; - mod(divisor: any): Long; - rem(divisor: any): Long; - multiply(multiplier: any): any; - mul(multiplier: any): any; - negate(): Long; - neg(): Long; - not(): Long; - notEquals(other: any): boolean; - neq(other: any): boolean; - ne(other: any): boolean; - or(other: any): Long; - shiftLeft(numBits: any): Long; - shl(numBits: any): Long; - shiftRight(numBits: any): Long; - shr(numBits: any): Long; - shiftRightUnsigned(numBits: any): Long; - shr_u(numBits: any): Long; - shru(numBits: any): Long; - subtract(subtrahend: any): Long; - sub(subtrahend: any): Long; - toInt(): number; - toNumber(): number; - toBigInt(): bigint; - toBytes(le: any): number[]; - toBytesLE(): number[]; - toBytesBE(): number[]; - toSigned(): Long; - toString(radix: any): any; - toUnsigned(): Long; - xor(other: any): Long; - eqz(): boolean; - le(other: any): boolean; - toExtendedJSON(options: any): number | { - $numberLong: any; - }; - inspect(): string; -} -export namespace Long { - let TWO_PWR_24: any; - let MAX_UNSIGNED_VALUE: Long; - let ZERO: any; - let UZERO: any; - let ONE: any; - let UONE: any; - let NEG_ONE: any; - let MAX_VALUE: Long; - let MIN_VALUE: Long; -} -export class MaxKey extends BSONValue { - static fromExtendedJSON(): MaxKey; - get _bsontype(): string; - toExtendedJSON(): { - $maxKey: number; - }; - inspect(): string; -} -export class MinKey extends BSONValue { - static fromExtendedJSON(): MinKey; - get _bsontype(): string; - toExtendedJSON(): { - $minKey: number; - }; - inspect(): string; -} -export class ObjectId extends BSONValue { - static getInc(): number; - static generate(time: any): any; - static createPk(): ObjectId; - static createFromTime(time: any): ObjectId; - static createFromHexString(hexString: any): ObjectId; - static isValid(id: any): boolean; - static fromExtendedJSON(doc: any): ObjectId; - constructor(inputId: any); - get _bsontype(): string; - __id: any; - set id(value: any); - get id(): any; - toHexString(): any; - toString(encoding: any): any; - toJSON(): any; - equals(otherId: any): any; - getTimestamp(): Date; - toExtendedJSON(): { - $oid: any; - }; - inspect(): string; - [kId]: any; -} -export namespace ObjectId { - let index: number; -} -export class Timestamp extends Long { - static fromInt(value: any): Timestamp; - static fromNumber(value: any): Timestamp; - static fromBits(lowBits: any, highBits: any): Timestamp; - static fromString(str: any, optRadix: any): Timestamp; - static fromExtendedJSON(doc: any): Timestamp; - constructor(low: any); - toJSON(): { - $timestamp: any; - }; - toExtendedJSON(): { - $timestamp: { - t: number; - i: number; - }; - }; -} -export namespace Timestamp { - import MAX_VALUE_1 = Long.MAX_UNSIGNED_VALUE; - export { MAX_VALUE_1 as MAX_VALUE }; -} -export class UUID extends Binary { - static generate(): any; - static isValid(input: any): boolean; - static createFromHexString(hexString: any): UUID; - constructor(input: any); - __id: any; - set id(value: any); - get id(): any; - toHexString(includeDashes?: boolean): any; - equals(otherId: any): any; - toBinary(): Binary; -} -export function calculateObjectSize(object: any, options?: {}): number; -export function deserialize(buffer: any, options?: {}): {}; -export function deserializeStream(data: any, startIndex: any, numberOfDocuments: any, documents: any, docStartIndex: any, options: any): any; -export function serialize(object: any, options?: {}): any; -export function serializeWithBufferAndIndex(object: any, finalBuffer: any, options?: {}): number; -export function setInternalBufferSize(size: any): void; -declare const kId: unique symbol; -export { bson as BSON }; diff --git a/src/extras/dist/src/extras/struct/datastructures/index.d.ts b/src/extras/dist/src/extras/struct/datastructures/index.d.ts deleted file mode 100644 index 07efe2c4..00000000 --- a/src/extras/dist/src/extras/struct/datastructures/index.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './DataStructures'; -export * from './DataTablet'; -export * as DS from './DataStructures'; diff --git a/src/extras/dist/src/extras/struct/genTimestamps.d.ts b/src/extras/dist/src/extras/struct/genTimestamps.d.ts deleted file mode 100644 index 69253e3d..00000000 --- a/src/extras/dist/src/extras/struct/genTimestamps.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export type TimeUnit = 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year' | 'decade' | 'century' | 'millennium' | 'microsecond' | 'nanosecond'; -type Plural = `${T}s`; -export type TimeSpecifier = `now` | `last ${string} ${Plural}` | `last ${TimeUnit}`; -export declare let defaultSpecifiers: (TimeUnit | "now")[]; -export declare function genTimeSpecifiers(specifiers?: (TimeUnit | "now")[]): string[]; -export declare function genTimestampFromString(specifier: TimeSpecifier): number; -export {}; diff --git a/src/extras/dist/src/extras/webgl-plot/webglplot.routes.d.ts b/src/extras/dist/src/extras/webgl-plot/webglplot.routes.d.ts deleted file mode 100644 index 26ef2e6b..00000000 --- a/src/extras/dist/src/extras/webgl-plot/webglplot.routes.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { WorkerInfo } from '../../services/worker/Worker.service'; -import { WebglLinePlotInfo, WebglLinePlotProps, WebglLinePlotUtil, WebglLineProps } from "webgl-plot-utils"; -import { FilterSettings } from "../algorithms/util/BiquadFilters"; -export { WebglLinePlotUtil, WebglLineProps, WebglLinePlotProps, WebglLinePlotInfo }; -export declare const webglPlotRoutes: { - setupChart: (settings: WebglLinePlotProps) => any; - updateChartData: (plot: WebglLinePlotInfo | string, lines?: { - [key: string]: number[] | WebglLineProps | { - [key: string]: any; - values: number[]; - }; - }, draw?: boolean) => boolean; - clearChart: (plot: WebglLinePlotInfo | string) => boolean; - resetChart: (plot: WebglLinePlotInfo | string, settings: WebglLinePlotProps) => any; - getChartSettings: (plotId: any) => any; -}; -export declare function setSignalControls(controlsDiv: HTMLElement, plotId: string, streamworker: WorkerInfo, chartworker: WorkerInfo, chartSettings: Partial, filterSettings: FilterSettings): Promise; diff --git a/src/extras/dist/src/loaders/index.d.ts b/src/extras/dist/src/loaders/index.d.ts deleted file mode 100644 index 229b9ec7..00000000 --- a/src/extras/dist/src/loaders/index.d.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { GraphNode, Graph, GraphNodeProperties } from "../core/Graph"; -/** - * setting nodeA.__node.backward:true propagates operator results to parent - */ -export declare const backprop: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; -/** - * - * Specify a timer loop, will stop when node is popped or nodeA.__node.isLooping is set false - * nodeA.__node.loop = 100 will loop the operator every 100 milliseconds - * - * Or - * nodeA.__node.delay will delay the operator by specified millisecond number and resolve the result as a promise - * nodeA.__node.frame will use requestAnimationFrame to call the function and resolve the result as a promise - * - * Use in combination with: - * nodeA.__node.repeat will repeat the operator the specified number of times - * nodeA.__node.recursive will do the same as repeat but will pass in the previous operator call's results - * - * - */ -export declare const loop: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; -/** Animations - * - * nodeA.__node.animate = true; - * then __operator becomes a requestAnimationFrame function - * start with a call the __operator or by setting node.__node.animating = true; - * - * or node.__animation = (...args) => {} - * - */ -export declare const animate: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; -/** Branching operations - * - * //runs a function or node if the if-conditions are satisfied, which can be a function that returns a true or false - * nodeA.__branch = {[key:string]:{if:Function|any, then:Function|any|GraphNode}} - * - * nodeA.__listeners['nodeB.x'] = { - * callback:(result)=>void, - * branch:{ - * if:Function|any, //if a function using the result evaluates to true or if the value equals the if value - * then:Function|any|GraphNode //call a function, return a different result, or call a node - * } - * } - * - */ -export declare const branching: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; -/** Trigger listeners oncreate with specific arguments - * - * nodeA.__listeners['nodeB.x'] = { callback:(result)=>void, oncreate:any } - * - */ -export declare const triggerListenerOncreate: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; -/** Bind listeners to a specific object instead of the node that owns it - * - * nodeA.__listeners['nodeB.x'] = { callback:(result)=>void, binding:{[key:string]:any} } - * - */ -export declare const bindListener: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; -/** - * - * nodeA.__listeners['nodeB.x'] = { callback:(result)=>void, transform:(result)=>any } - * - */ -export declare const transformListenerResult: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; -export declare const substitute__operator: (node: GraphNode & GraphNodeProperties, parent: GraphNode | Graph, graph: Graph) => void; -export declare const loaders: { - backprop: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; - loop: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; - animate: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; - branching: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; - triggerListenerOncreate: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; - bindListener: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; - transformListenerResult: (node: GraphNode, parent: GraphNode | Graph, graph: Graph) => void; - substitute__operator: (node: GraphNode & GraphNodeProperties, parent: GraphNode | Graph, graph: Graph) => void; -}; diff --git a/src/extras/dist/src/loaders/methodstrings.d.ts b/src/extras/dist/src/loaders/methodstrings.d.ts deleted file mode 100644 index 978aabc8..00000000 --- a/src/extras/dist/src/loaders/methodstrings.d.ts +++ /dev/null @@ -1 +0,0 @@ -export declare function methodstrings(node: any): void; diff --git a/src/extras/dist/src/services/Service.d.ts b/src/extras/dist/src/services/Service.d.ts deleted file mode 100644 index a5558998..00000000 --- a/src/extras/dist/src/services/Service.d.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Graph, GraphNode, GraphOptions } from "../../src/core/Graph"; -export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array; -export type ServiceMessage = { - route?: string; - args?: any; - method?: string; - node?: string | GraphNode; - [key: string]: any; -}; -export type ServiceOptions = GraphOptions & { - services?: { - [key: string]: Service | Function | { - [key: string]: any; - }; - }; - restrict?: { - [key: string]: boolean; - }; -}; -export declare class Service extends Graph { - name: string; - restrict?: { - [key: string]: boolean; - }; - constructor(options?: ServiceOptions); - addServices: (services: { - [key: string]: Function | Graph | Service | { - [key: string]: any; - }; - }) => void; - handleMethod: (route: string, method: string, args?: any) => any; - handleServiceMessage(message: ServiceMessage): any; - handleGraphNodeCall(route: string | GraphNode, args: any): any; - transmit: (...args: any[]) => any | void; - receive: (...args: any[]) => any | void; - pipe: (source: GraphNode | string, destination: string, endpoint?: string | any, method?: string, callback?: (res: any) => any | void) => number; - pipeOnce: (source: GraphNode | string, destination: string, endpoint?: string | any, method?: string, callback?: (res: any) => any | void) => any; - terminate: (...args: any) => void; - isTypedArray: typeof isTypedArray; - recursivelyAssign: (target: any, obj: any) => any; - spliceTypedArray: typeof spliceTypedArray; - ping: () => string; - echo: (...args: any) => any; - log: (...args: any) => boolean; - error: (...args: any) => boolean; -} -export declare function isTypedArray(x: any): boolean; -export declare const recursivelyAssign: (target: any, obj: any) => any; -export declare function spliceTypedArray(arr: TypedArray, start: number, end?: number): TypedArray; diff --git a/src/extras/dist/src/services/ecs/ECS.service.d.ts b/src/extras/dist/src/services/ecs/ECS.service.d.ts deleted file mode 100644 index cb3252b8..00000000 --- a/src/extras/dist/src/services/ecs/ECS.service.d.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { GraphNode, GraphNodeProperties } from '../../core/Graph'; -import { Service, ServiceOptions } from '../Service'; -export type EntityProps = { - components: { - [key: string]: any; - }; -} & (GraphNodeProperties | GraphNode); -export type SystemProps = (GraphNodeProperties & { - __operator: (entities: { - [key: string]: Entity; - }) => any; - setupEntities: (entities: { - [key: string]: Entity; - }) => { - [key: string]: Entity; - }; - setupEntity: (entity: Entity) => Entity; -}) | GraphNode; -export type Entity = { - components: { - [key: string]: any; - }; - [key: string]: any; -} & GraphNode; -export type System = { - __operator: (entities: { - [key: string]: Entity; - }) => any; - setupEntities: (entities: { - [key: string]: Entity; - }) => { - [key: string]: Entity; - }; - setupEntity: (entity: Entity) => Entity; - remove?: (entity: Entity, entitities: { - [key: string]: Entity; - }) => Entity; - entities: { - [key: string]: Entity; - }; - entityKeys: string[]; -} & GraphNode; -export type ECSOptions = { - entities: { - [key: string]: EntityProps; - }; - systems: { - [key: string]: SystemProps; - }; - order?: string[]; - [key: string]: any; -} & ServiceOptions; -export declare class ECSService extends Service { - entities: { - [key: string]: Entity; - }; - systems: { - [key: string]: System; - }; - entityMap: Map; - entityKeyMap: Map; - order: string[]; - animating: boolean; - entityCt: number; - systemCt: number; - constructor(options?: ECSOptions); - updateEntities: (order?: string[], filter?: boolean, debug?: any) => void; - animateEntities: (filter?: boolean, order?: string[]) => void; - stop: () => void; - start: (filter?: boolean) => void; - addEntities: (prototype: EntityProps, components?: { - [key: string]: any; - }, count?: number) => string[]; - addEntity: (prototype?: EntityProps, components?: { - [key: string]: any; - }) => Entity; - addSystems: (systems?: { - [key: string]: SystemProps; - }, order?: string[]) => { - [key: string]: System; - }; - addSystem: (prototype: SystemProps, setupEntities?: (entities: { - [key: string]: Entity; - }) => any, setupEntity?: (entity: Entity) => any, operator?: (entities: any) => any, remove?: (entities: any) => any, order?: string[]) => System; - setupEntity: (entity: Entity) => void; - removeEntity: (tag: string) => string | GraphNode; - removeEntities(entities: string[] | { - [key: string]: Entity; - }): void; - removeSystem: (tag: string) => string | GraphNode; - filterObject(o: { - [key: string]: any; - }, filter: (string: any, any: any) => boolean | undefined): { - [k: string]: any; - }; - setEntities: (entities: string[] | { - [key: string]: Entity; - }, props: { - [key: string]: any; - }) => boolean; - setEntity: (entity: Entity, props: { - [key: string]: any; - }) => any; - bufferValues: (entities: { - [key: string]: Entity; - }, property: string, keys?: string[] | { - [key: string]: any; - }, buffer?: ArrayBufferLike) => ArrayBufferLike; -} diff --git a/src/extras/dist/src/services/utils.d.ts b/src/extras/dist/src/services/utils.d.ts deleted file mode 100644 index 9efee154..00000000 --- a/src/extras/dist/src/services/utils.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -export declare let recursivelyStringifyFunctions: (obj: { - [key: string]: any; -}) => {}; -export declare function getFnParamNames(fn: any): any; -export declare let getFunctionHead: (methodString: any) => any; -export declare function parseFunctionFromText(method?: string): any; -export declare function reconstructObject(json?: string | { - [x: string]: any; -}): any; -export declare const stringifyWithCircularRefs: (obj: any, space?: any) => string; -export declare const stringifyWithFunctionsAndCircularRefs: (obj: any, space?: any) => string; -export declare const stringifyFast: (obj: any, space?: any) => string; diff --git a/src/extras/dist/src/services/worker/Worker.service.d.ts b/src/extras/dist/src/services/worker/Worker.service.d.ts deleted file mode 100644 index 730d0214..00000000 --- a/src/extras/dist/src/services/worker/Worker.service.d.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { Service, ServiceMessage, ServiceOptions } from "../Service"; -import Worker from 'web-worker'; -import { GraphNode, GraphNodeProperties } from "../../core/Graph"; -export type WorkerRoute = { - worker?: WorkerInfo; - workerUrl?: string | URL | Blob; - transferFunctions?: { - [key: string]: Function; - }; - transferClasses?: { - [key: string]: Function; - }; - parentRoute?: string; - portId?: string; - callback?: string; - stopped?: boolean; - blocking?: boolean; - init?: string; - initArgs?: any[]; - initTransfer?: any[]; -} & GraphNodeProperties & WorkerProps; -export type WorkerProps = { - worker?: WorkerInfo; - workerUrl?: string | URL | Blob; - url?: URL | string | Blob; - _id?: string; - port?: MessagePort; - onmessage?: (ev: any) => void; - onerror?: (ev: any) => void; - onclose?: (worker: Worker | MessagePort) => void; -}; -export type WorkerInfo = { - worker: Worker | MessagePort; - send: (message: any, transfer?: any) => void; - request: (message: any, method?: string, transfer?: any) => Promise; - post: (route: any, args?: any, method?: string, transfer?: any) => void; - run: (route: any, args?: any, method?: string, transfer?: any) => Promise; - subscribe: (route: any, callback?: ((res: any) => void) | string, args?: any[], key?: string, subInput?: boolean, blocking?: boolean) => Promise; - unsubscribe: (route: any, sub: number) => Promise; - start: (route?: any, portId?: string, callback?: ((res: any) => void) | string, blocking?: boolean) => Promise; - stop: (route?: string, portId?: string) => Promise; - workerSubs: { - [key: string]: { - sub: number | false; - route: string; - portId: string; - callback?: ((res: any) => void) | string; - blocking?: boolean; - }; - }; - terminate: () => boolean; - postMessage: (message: any, transfer?: any[]) => void; - graph: WorkerService; - _id: string; -} & WorkerProps & WorkerRoute; -export declare class WorkerService extends Service { - name: string; - workers: { - [key: string]: WorkerInfo; - }; - threadRot: number; - connections: any; - constructor(options?: ServiceOptions); - loadWorkerRoute: (node: WorkerRoute & GraphNode, routeKey: string) => WorkerInfo; - workerloader: any; - addDefaultMessageListener: () => void; - postMessage: (message: any, target: string, transfer?: Transferable[]) => void; - addWorker: (options: { - url?: URL | string | Blob; - port?: MessagePort; - _id?: string; - onmessage?: (ev: any) => void; - onerror?: (ev: any) => void; - }) => WorkerInfo; - open: (options: { - url?: URL | string | Blob; - port?: MessagePort; - _id?: string; - onmessage?: (ev: any) => void; - onerror?: (ev: any) => void; - }) => WorkerInfo; - close: () => void; - toObjectURL: (scriptTemplate: string) => string; - getTransferable(message: any): any; - transmit: (message: ServiceMessage | any, worker?: Worker | MessagePort | string, transfer?: StructuredSerializeOptions) => any; - terminate: (worker: Worker | MessagePort | string | WorkerInfo) => boolean; - establishMessageChannel: (worker: Worker | string | MessagePort | WorkerInfo, worker2?: Worker | string | MessagePort | WorkerInfo) => string | false; - request: (message: ServiceMessage | any, workerId: string, transfer?: any, method?: string) => Promise; - runRequest: (message: ServiceMessage | any, worker: undefined | string | Worker | MessagePort, callbackId: string | number) => any; - subscribeWorker: (route: string, worker: WorkerInfo | Worker | string | MessagePort, args?: any[], key?: string, subInput?: boolean, blocking?: boolean) => number; - subscribeToWorker: (route: string, workerId: string, callback?: string | ((res: any) => void), args?: any[], key?: string, subInput?: boolean, blocking?: boolean) => Promise; - triggerSubscription: (route: string, workerId: string, result: any) => Promise; - pipeWorkers: (sourceWorker: WorkerInfo | string, listenerWorker: WorkerInfo | string, sourceRoute: string, listenerRoute: string, portId?: string, args?: any[], key?: any, subInput?: boolean, blocking?: boolean) => Promise; - unpipeWorkers: (sourceRoute: string, sourceWorker: WorkerInfo | string, sub?: number) => Promise; -} diff --git a/src/extras/dist/src/storage/csv.d.ts b/src/extras/dist/src/storage/csv.d.ts deleted file mode 100644 index 030f67f5..00000000 --- a/src/extras/dist/src/storage/csv.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -export function toISOLocal(d: any): string; -export class CSV { - static saveCSV(csvDat?: string, name?: string): void; - static openCSV(delimiter?: string, onOpen?: (csvDat: any, header: any, path: any) => any): Promise; - static openCSVRaw(onOpen?: (csvDat: any, path: any) => any): Promise; - constructor(onOpen?: (csvDat?: any[], header?: any[]) => void, saveButtonId?: any, openButtonId?: any); - onOpen(csvDat?: any[], header?: any[]): void; - notes: any[]; - processArraysForCSV(data?: string[], delimiter?: string, header?: string, saveNotes?: boolean): string; -} -export function parseCSVData(data: any, filename: any, head: any, hasend?: boolean, parser?: (lines: any, filename: any, head: any) => { - filename: any; -}): { - filename: any; -}; -export function processDataForCSV(options?: {}): { - filename: any; - header: string; - body: string; -}; diff --git a/src/extras/dist/storage/BFSUtils.d.ts b/src/extras/dist/storage/BFSUtils.d.ts deleted file mode 100644 index be89548b..00000000 --- a/src/extras/dist/storage/BFSUtils.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -export function readFileChunk(path?: string, begin?: number, end?: number, onread?: (data: any) => void): Promise; -export function processCSVChunksFromDB(path?: string, onData?: (csvdata: any, start: any, end: any, size: any) => void, maxChunkSize?: number, start?: number, end?: string, options?: {}): Promise; -export function readCSVChunkFromDB(path?: string, start?: number, end?: string, options?: {}): Promise<{}>; -export let fsInited: boolean; -export const fs: import("browserfs/dist/node/core/FS.js").FSModule; -export function initFS(dirs?: string[], oninit?: (exists?: any[]) => void, onerror?: (e: any) => void, filesystem?: string): Promise; -export function exists(path?: string): Promise; -export function readFile(path?: string): Promise; -export function getFilenames(directory?: string, onload?: (directory: any) => void): Promise; -export function writeFile(path: any, data: any, onwrite?: (data: any) => void): Promise; -export function appendFile(path: any, data: any, onwrite?: (data: any) => void): Promise; -export function deleteFile(path?: string, ondelete?: () => void): Promise; -export function readFileAsText(path?: string, end?: string, begin?: number, onread?: (data: any, filename: any) => void): Promise; -export function listFiles(dir?: string, onload?: (directory: any) => void): Promise; -export function getFileSize(path?: string, onread?: (size: any) => void): Promise; -export function getCSVHeader(path?: string, onopen?: (header: any, filename: any) => void): Promise; -export function writeToCSVFromDB(path?: string, fileSizeLimitMb?: number): Promise; -export function dirExists(fs: any, directory: any): Promise; -export namespace BFSRoutes { - export { initFS }; - export { dirExists }; - export { exists }; - export { readFile }; - export { readFileChunk }; - export { getFilenames }; - export { writeFile }; - export { appendFile }; - export { deleteFile }; - export { readFileAsText }; - export { getFileSize }; - export { getCSVHeader }; - export { listFiles }; -} diff --git a/src/extras/dist/storage/BFS_CSV.d.ts b/src/extras/dist/storage/BFS_CSV.d.ts deleted file mode 100644 index d18aaee3..00000000 --- a/src/extras/dist/storage/BFS_CSV.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { processCSVChunksFromDB, readCSVChunkFromDB } from './BFSUtils'; -import { CSV, toISOLocal } from './csv'; -export declare const appendCSV: (newData: { - [key: string]: number | number[]; -}, filename: string, header?: string[], options?: { - json?: boolean; - toFixed?: number; - bufferSize?: number; - xIncrement?: number; -}) => Promise; -export declare const updateCSVHeader: (header: any[], filename: string) => void; -export declare const createCSV: (filename: string, header: string[], toFixed?: number, bufferSize?: number, xIncrement?: number) => Promise; -export declare const visualizeDirectory: (dir: string, parentNode?: HTMLElement) => Promise; -export declare const csvRoutes: { - appendCSV: (newData: { - [key: string]: number | number[]; - }, filename: string, header?: string[], options?: { - json?: boolean; - toFixed?: number; - bufferSize?: number; - xIncrement?: number; - }) => Promise; - updateCSVHeader: (header: any[], filename: string) => void; - createCSV: (filename: string, header: string[], toFixed?: number, bufferSize?: number, xIncrement?: number) => Promise; - visualizeDirectory: (dir: string, parentNode?: HTMLElement) => Promise; - openCSV: typeof CSV.openCSV; - saveCSV: typeof CSV.saveCSV; - openCSVRaw: typeof CSV.openCSVRaw; - parseCSVData: (data: any, filename: any, head: any, hasend?: boolean, parser?: (lines: any, filename: any, head: any) => { - filename: any; - }) => { - filename: any; - }; - getCSVHeader: (path?: string, onopen?: (header: any, filename: any) => void) => Promise; - writeToCSVFromDB: (path?: string, fileSizeLimitMb?: number) => Promise; - readCSVChunkFromDB: typeof readCSVChunkFromDB; - processCSVChunksFromDB: typeof processCSVChunksFromDB; - toISOLocal: typeof toISOLocal; -}; diff --git a/src/extras/index.gpu.services.ts b/src/extras/index.gpu.services.ts deleted file mode 100644 index 6ab447b6..00000000 --- a/src/extras/index.gpu.services.ts +++ /dev/null @@ -1,4 +0,0 @@ -//for all the extra services we want to export but are too bulky for the core - -export * from './gpu/GPU.service' //~500kb -export { gpualgorithms } from './algorithms/index.gpu'; //modified algorithms object with presets \ No newline at end of file diff --git a/src/extras/index.storage.services.ts b/src/extras/index.storage.services.ts deleted file mode 100644 index 9b76b24c..00000000 --- a/src/extras/index.storage.services.ts +++ /dev/null @@ -1,5 +0,0 @@ -//for all the extra services we want to export but are too bulky for the core - -export * from './storage/csv' -export * from './storage/BFSUtils' -export * from './storage/BFS_CSV' diff --git a/src/extras/storage/BFS_CSV.ts b/src/extras/storage/BFS_CSV.ts deleted file mode 100644 index 29df8331..00000000 --- a/src/extras/storage/BFS_CSV.ts +++ /dev/null @@ -1,389 +0,0 @@ -import { appendFile, deleteFile, exists, getCSVHeader, listFiles, processCSVChunksFromDB, readCSVChunkFromDB, writeFile, writeToCSVFromDB } from './BFSUtils'; -import { CSV, parseCSVData, toISOLocal } from './csv'; -//We have object formats coming in like {x,y,z}, tied to devices with USB data or BLE data with specifiers - -//so we should ned up with a CSV that has one header for device info, one header for the actual column tops, -// then it should dynamically append whatever data/devices we feed it and handle general timestamping for us -//temp -const CSV_REFERENCE:{ - [filename:string]:{ //key is filename - header:string[], - lastX:number, //latest line, unjoined - buffer:string, //appended strings waiting to be written to browserfs - buffered:number, - toFixed:number, - bufferSize:number|undefined, - xIncrement?:number|undefined - } -} = {} - -function lerp(v0, v1, t) { - return ((1 - t) * v0) + (t * v1); -} - -function interpolerp(v0,v1,fit, floor=true) { - if(fit <= 2) return [v0, v1]; - let a = 1/fit; - let result = new Array(fit); - result[0] = v0; - for(let i = 1; i <= fit; i++) { - result[i] = lerp(v0,v1,a*i); - if(floor) result[i] = Math.floor(result[i]); - } - return result; -} - - -//in our case we are receiving data in a uniform format -export const appendCSV = async ( - newData:{[key:string]:number|number[]}, //assume uniformly sized data is passed in, so pass separate timestamp intervals separately - filename:string, - header?:string[], - options?: { - json?:boolean, - toFixed?:number, - bufferSize?:number, - xIncrement?:number - } -) => { - - //console.log(newData); - - //console.log('append',filename); - if(!filename) { - let keys = Object.keys(CSV_REFERENCE); - if(keys.length > 0) filename = keys[keys.length - 1]; - else filename = `csv${new Date().toISOString()}`; - } - - //console.log(filename); - - let csv = CSV_REFERENCE[filename]; - if(!csv) { - let keys = Array.from(Object.keys(newData)); if (keys.indexOf('timestamp') > -1) keys.splice(keys.indexOf('timestamp'), 1); - CSV_REFERENCE[filename] = { - header:header ? header : ['timestamp','localized',...keys] as string[], - lastX:undefined as any, - buffer:'', - buffered:0, //buffer numbers to be appended? - bufferSize:options?.bufferSize ? options.bufferSize : 0, - toFixed:options?.toFixed ? options.toFixed : 0, - xIncrement:options?.xIncrement ? options.xIncrement : 0 - }; - csv = CSV_REFERENCE[filename]; - - const existingHeader = await getCSVHeader(filename).catch(() => null); - const isDifferent = (!existingHeader || existingHeader !== csv.header.join(',')) - if (isDifferent) header = csv.header; // Only push header if it's different - } - if (!csv.header || csv.header?.length === 0) { - let keys = Array.from(Object.keys(newData)); if (keys.indexOf('timestamp') > -1) keys.splice(keys.indexOf('timestamp'), 1); - csv.header = header ? header : ['timestamp','localized',...keys] as string[]; - } - else if(header) csv.header = header; //set a new header? File needs to be rewritten if so, but this works if you make a new file (just change the input file name) - - - let maxLen = 1; //max length of new arrays being appended, if any - for(const key in newData) { - const value = newData[key] - if(csv.header.indexOf(key) > -1 && value && Array.isArray(value) && value?.length > maxLen) maxLen = value?.length; - } - - let x; - - if(csv.xIncrement) { - if(!csv.lastX) { - if(typeof newData[csv.header[0]] !== 'undefined') { - x = newData[csv.header[0]]; - } else if (csv.header[0].toLowerCase().includes('time') || csv.header[0].toLowerCase().includes('unix')) - x = Date.now(); - } - else { - if(newData[csv.header[2]]) { - if(Array.isArray(newData[csv.header[2]])) x = csv.lastX + csv.xIncrement*(newData[csv.header[2]] as any[]).length; - else x = csv.lastX + csv.xIncrement; - } - else if(newData[csv.header[0]]) { - if(Array.isArray(newData[csv.header[0]])) x = csv.lastX + csv.xIncrement*(newData[csv.header[0]] as any[]).length; - else x = csv.lastX + csv.xIncrement; - } - else x = csv.lastX + csv.xIncrement; - - } - } - else if(newData[csv.header[0]]) x = newData[csv.header[0]]; //first csv value treated as x for reference for growing the csv, mainly to generate timestamps if being used but not defined - else x = Date.now(); - - if(typeof csv.lastX === 'undefined') csv.lastX = Array.isArray(x) ? x[0] : x; - if(typeof x === 'undefined') { - if(csv.header[0].includes('time')) { - let now = Date.now(); - if(maxLen === 1) x = Date.now(); - else { - x = interpolerp(csv.lastX,now,maxLen); //we are gonna upsample x to the maximum size array that's been passed in - x.shift(); - } - } else { - let newX = csv.lastX+1; //just an assumption to spit something into the x column - if(maxLen > 1) { - x = new Array(maxLen).fill(''); - x[maxLen-1] = newX; - } - else x = newX; - } - } else if (maxLen > 1 && (x as any)?.length !== maxLen) { - if(!Array.isArray(x) || x.length === 1) { - x = interpolerp(csv.lastX,x,maxLen,true); //we are gonna upsample x to the maximum size array that's been passed in - x.shift(); - } else { - x = interpolerp(x[0],x[x.length-1],maxLen,true); //upsample using new timestamps - x.shift(); - } - } - - let toAppend = [] as any[][]; - - if(Array.isArray(x)) { - let curIdcs = {}; - for(let i = 0; i < x.length; i++) { - toAppend.push([]); - for(let j = 0; j < csv.header.length; j++) { - let d = newData[csv.header[j]]; - if(j === 0) { - toAppend[i][0] = x[i]; - if (csv.header[j+1] === 'localized') { j++; toAppend[i][j] = toISOLocal(x[i]); } - continue; - } - - - if(d === undefined) { - toAppend[i][j] = ''; - } else if (Array.isArray(d)) { - if(d.length === x.length) toAppend[i][j] = d[i]; - else { - if(!(csv.header[j] in curIdcs)) { - curIdcs[csv.header[j]] = i; - if(d.length !== 1) toAppend[i][j] = d[i]; //0 - } else { - if(d.length === 1 && i === x.length-1) { - toAppend[i][j] = d[curIdcs[csv.header[j]]]; - } else if(Math.floor(d.length * i/x.length) > curIdcs[csv.header[j]]) { - curIdcs[csv.header[j]]++; - toAppend[i][j] = d[curIdcs[csv.header[j]]]; - } else { - toAppend[i][j] = ''; //include a blank to preserve the header order - } - } - } - } else { - if(i === x.length-1) { - toAppend[i][j] = d; - } else { - toAppend[i][j] = ''; - } - } - - if(typeof toAppend[i][j] === 'number' && Math.floor(toAppend[i][j]) !== toAppend[i][j]) - toAppend[i][j] = toAppend[i][j].toFixed(CSV_REFERENCE[filename].toFixed) - - } - } - } else { - toAppend.push([]); - for(let j = 0; j < csv.header.length; j++) { - - if(j === 0) { - toAppend[0][0] = x; - if (csv.header[j+1] === 'localized') { j++; toAppend[0][j] = toISOLocal(x); } - continue; - } - - if((csv.header[j] in newData)) toAppend[0][j] = newData[csv.header[j]]; - else toAppend[0][j] = ''; - - - if(typeof toAppend[0][j] === 'number' && Math.floor(toAppend[0][j]) !== toAppend[0][j]) - toAppend[0][j] = toAppend[0][j].toFixed(CSV_REFERENCE[filename].toFixed); - - } - - } - - - let csvProcessed = ''; - - if(header) csvProcessed += header.join(',') + '\n'; //append new headers when they show up - toAppend.forEach((arr) => { - csvProcessed += ((options?.json) ? arr.map(v => JSON.stringify(v)) : arr).join(',') + '\n'; - // csvProcessed += arr.join(',') + '\n'; - if(csv.bufferSize) csv.buffered++; - }); - - csv.lastX = toAppend[toAppend.length-1][0]; //reference the last array written as the latest data for if we don't pass timestamps - - //okay we are ready to append arrays to the file - - if(csv.bufferSize) { - csv.buffer += csvProcessed; - if(csv.buffered > csv.bufferSize) { - let r = new Promise((res,rej) => { - exists(filename).then((fileExists) => { - if(!fileExists) { - writeFile( - filename, - csv.buffer, - (written:boolean) => { - res(written); - } - ); - } else { - appendFile( - filename, - csv.buffer, - (written:boolean) => { - res(written); - } - ); - } - }); - }) as Promise - - await r; - - csv.buffer = ''; - csv.buffered = 0; - - return r; - } - else return await Promise.resolve(true); - } - else { - return await new Promise((res,rej) => { - exists(filename).then((fileExists) => { - if(!fileExists) { - writeFile( - filename, - csvProcessed, - (written:boolean) => { - res(written); - } - ); - } else { - appendFile( - filename, - csvProcessed, - (written:boolean) => { - res(written); - } - ); - } - }); - }) as any as Promise - - } //e.g. generalize this for other data types -} - -//todo: rewrite saved file with the new header (which requires fully rewriting a file chunk to shift the bytes in IndexedDB) -export const updateCSVHeader = (header:any[],filename:string) => { - if(CSV_REFERENCE[filename]) { - CSV_REFERENCE[filename].header = header; - } -} - -export const createCSV = ( - filename:string, - header:string[], - toFixed:number=5, //limit decimals (saves a ton of memory), set to 0 for integers - bufferSize:number=0, //accumulate a certain number of lines before writing to BFS? (necessary for > 100 updates/sec fyi) - xIncrement?:number //fixed time increment for newlines? -) => { - - if(!CSV_REFERENCE[filename]) { - if(header?.indexOf('timestamp') > 1) {header.splice(header.indexOf('timestamp'),1); header.unshift('timestamp')} - if((header?.[0].toLowerCase().includes('time') || header?.[0].toLowerCase().includes('unix')) && header[1] !== 'localized') { - header.splice(1,0,'localized') //toISOLocal - } - - CSV_REFERENCE[filename] = { - header, - lastX:header[1] === 'localized' ? Date.now() : 0, - bufferSize, - buffer:'', - buffered:0, - toFixed, - xIncrement - }; - - //overwrite existing files - return new Promise((res,rej) => { - exists(filename).then((doesExist) => { - if(!doesExist) { //try not to overwrite - writeFile( - filename, - CSV_REFERENCE[filename].header? CSV_REFERENCE[filename].header.join(',')+'\n' : '', - (written:boolean) => { - res(written); - } - ).catch(rej); - } - }); - }); - } -} - - -//returns a basic html needed to visualize csv directory contents -export const visualizeDirectory = (dir:string, parentNode=document.body) => { - return new Promise(async (res,rej) => { - if(parentNode.querySelector('#bfs' + dir)) parentNode.querySelector('#bfs' + dir)?.remove(); - parentNode.insertAdjacentHTML('beforeend',`
    `); - let div = parentNode.querySelector('#bfs'+dir); - await listFiles(dir).then((directory) => { - //returns an array of directory listings - if(directory.length === 0) (div as any).innerHTML = 'No Files!'; - else directory.forEach((listing) => { - div?.insertAdjacentHTML( - 'beforeend', - `
    - Data: - ${listing} - - ${listing.indexOf('.') > -1 ? `` : ''} -
    ` - ); - - if(document.getElementById(`delete${listing}`)) { - (document.getElementById(`delete${listing}`) as HTMLButtonElement).onclick = () => { - deleteFile(dir+'/'+listing, ()=>{ - visualizeDirectory(dir,parentNode); //reload - }); - } - } - - if(document.getElementById(`download${listing}`)) { - (document.getElementById(`download${listing}`) as HTMLButtonElement).onclick = () => { - writeToCSVFromDB(dir+'/'+listing,10); //will save data in chunks if exceeding maximum limit (for speed, else the screen locks) - } - } - }) - res(directory); - }).catch(rej) - - }); -} - -export const csvRoutes = { - appendCSV:appendCSV, - updateCSVHeader:updateCSVHeader, - createCSV:createCSV, - visualizeDirectory:visualizeDirectory, - openCSV:CSV.openCSV, - saveCSV:CSV.saveCSV, - openCSVRaw:CSV.openCSVRaw, - parseCSVData:parseCSVData, - getCSVHeader:getCSVHeader, - writeToCSVFromDB:writeToCSVFromDB, - readCSVChunkFromDB:readCSVChunkFromDB, - processCSVChunksFromDB:processCSVChunksFromDB, - toISOLocal:toISOLocal -} \ No newline at end of file diff --git a/src/extras/storage/BFS_GDrive.ts b/src/extras/storage/BFS_GDrive.ts deleted file mode 100644 index ab9dcfdb..00000000 --- a/src/extras/storage/BFS_GDrive.ts +++ /dev/null @@ -1,669 +0,0 @@ - -import { fs, fsInited, initFS } from "./BFSUtils"; - -declare var window; - - - -export class GDrive { - //------------------------ - //-GOOGLE DRIVE FUNCTIONS- - //------------------------ - - google = (window as any).google; - gapi = (window as any).gapi; - tokenClient = (window as any).tokenClient; - gapiInited = this.gapi !== undefined; - gsiInited = this.google !== undefined; - isLoggedIn = false; - previousPageTokens = [] as any[]; - nextPageToken: any; previousPageToken:any; currentFolderId; - container:any; - - directory = "Graphscript" - fs = fs; - - constructor(apiKey?, googleClientId?) { - if(apiKey && googleClientId) - this.initGapi(apiKey, googleClientId); - } - - //this is deprecated now?: https://developers.google.com/identity/gsi/web/guides/overview - initGapi = async ( - apiKey:string, - googleClientID:string - ) => { - - return new Promise(async (resolve,rej) => { - - //console.log('initializing gapi'); - - const DISCOVERY_DOC = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest'; - const SCOPES = 'https://www.googleapis.com/auth/drive'; - this.gapiInited = false; - this.gsiInited = false; - - - await Promise.all( - [new Promise((res) => { - const initializeGapiClient = async () => { - await this.gapi.client.init({ - apiKey: apiKey, - discoveryDocs: [DISCOVERY_DOC], - }); - this.gapiInited = true; - //console.log('gapi', window.gapi); - } - - const gapiLoaded = () => { - this.gapi = window.gapi; - this.gapi.load('client', initializeGapiClient); - } - - const script1 = document.createElement('script'); - script1.type = "text/javascript"; - script1.src = "https://apis.google.com/js/api.js"; - script1.async = true; - script1.defer = true; - script1.onload = gapiLoaded; - document.head.appendChild(script1); - - }), - new Promise((res) => { - - const gsiLoaded =() => { - this.google = window.google; - this.tokenClient = this.google.accounts.oauth2.initTokenClient({ - client_id: googleClientID, - scope: SCOPES, - callback: '', // defined later - }); - this.gsiInited = true; - //console.log('google', window.google) - res(true); - } - - const script2 = document.createElement('script'); - script2.type = "text/javascript"; - script2.src = "https://accounts.google.com/gsi/client"; - script2.async = true; - script2.defer = true; - script2.onload = gsiLoaded; - document.head.appendChild(script2); - - }) - ]); - - resolve(true); - - // function updateSigninStatus(isSignedIn) { - // if (isSignedIn) { - // console.log("Signed in with Google.") - // } else { - // console.log("Signed out of Google") - // } - // } - - }) - - } - - handleUserSignIn = () => { - return new Promise(async (res,rej) => { - if(!this.tokenClient) { - console.error('Google API not found'); - return; - } - - this.tokenClient.callback = async (resp) => { - if (resp.error !== undefined) { - rej(resp); - } - this.isLoggedIn = true; - res(resp); - }; - - if (this.gapi.client.getToken() === null) { - // Prompt the user to select a Google Account and ask for consent to share their data - // when establishing a new session. - this.tokenClient.requestAccessToken({prompt: 'consent'}); - } else { - // Skip display of account chooser and consent dialog for an existing session. - this.tokenClient.requestAccessToken({prompt: ''}); - } - }); - } - - checkFolder = ( - name=this.directory, - onResponse=(result)=>{} - ) => { - return new Promise((res,rej) => { - - this.gapi.client.drive.files.list({ - q:"name='"+name+"' and mimeType='application/vnd.google-apps.folder'", - }).then((response) => { - if(response.result.files.length === 0) { - this.createDriveFolder(); - if(onResponse) onResponse(response.result); - res(response.result as any); - } - else if(onResponse) onResponse(response.result); - res(response.result as any); - }); - }) - } - - createDriveFolder = ( - name=this.directory - ) => { - return new Promise((res,rej) => { - if(this.isLoggedIn) { - let data = new Object() as any; - data.name = name; - data.mimeType = "application/vnd.google-apps.folder"; - this.gapi.client.drive.files.create({'resource': data}).then((response)=>{ - console.log("Created Folder:",response.result); - res(response.result as any); - }); - } else { - console.error("Sign in with Google first!"); - this.handleUserSignIn().then(async () => { - if(this.isLoggedIn) { - res(await this.createDriveFolder(name)); //rerun - } - }); - } - }); - } - - async listFolders(directory = this.directory, parent='parents') { - try { - const response = await this.gapi.client.drive.files.list({ - q: `'${directory}' in ${parent} and mimeType='application/vnd.google-apps.folder'`, - fields: 'nextPageToken, files(id, name, mimeType)' - }); - return response.result.files || []; - } catch (error) { - console.error('Error listing folders:', error); - throw error; - } - } - - - async getFileMetadata(fileId) { - try { - const response = await this.gapi.client.drive.files.get({ - fileId, - fields: 'id, name, mimeType, parents', - }); - return response.result; - } catch (error) { - console.error('Error getting file metadata:', error); - throw error; - } - } - - async getFolderId(folderName, parentFolder = 'root') { - try { - const query = `mimeType='application/vnd.google-apps.folder' and name='${folderName}' ${parentFolder ? `and '${parentFolder}' ` : ``}in parents and trashed=false`; - const response = await this.gapi.client.drive.files.list({ - q: query, - fields: 'files(id, name)', - pageSize: 1 - }); - - const folder = response.result.files && response.result.files[0]; - if (folder) { - return folder.id; - } else { - console.error('Folder not found'); - return null; - } - } catch (error) { - console.error('Error getting folder ID:', error); - throw error; - } - } - - async downloadFile(fileId, mimeType) { - try { - const response = await this.gapi.client.drive.files.get({ - fileId, - alt: 'media' - }, { responseType: 'blob' }); - - const blob = new Blob([response.body], { type: mimeType }); - const link = document.createElement('a'); - link.href = URL.createObjectURL(blob); - link.download = 'downloaded_file'; - //document.body.appendChild(link); - link.click(); - //document.body.removeChild(link); - } catch (error) { - console.error('Error downloading file:', error); - throw error; - } - } - - async uploadFileToGoogleDrive( - data:Blob|string='a,b,c,1,2,3\nd,e,f,4,5,6\n', - fileName=`${new Date().toISOString()}.csv`, - mimeType='application/vnd.google-apps.spreadsheet', - directory=this.directory, - onProgress:((this: XMLHttpRequest, ev: ProgressEvent) => any) | null - ) { - - if (typeof data === 'string') { - const type = fileName.endsWith('.csv') ? 'text/csv' : 'text/plain'; - data = new Blob([data], { type }); - } - - const metadata = { - 'name': fileName, - 'mimeType': mimeType, - 'parents': [directory], // upload to the current directory - }; - - const form = new FormData(); - form.append('metadata', new Blob([JSON.stringify(metadata)], { type: 'application/json' })); - form.append('file', data); - - const xhr = new XMLHttpRequest(); - xhr.open('POST', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart'); - - const token = this.gapi.auth.getToken().access_token; - xhr.setRequestHeader('Authorization', 'Bearer ' + token); - - xhr.upload.onprogress = onProgress; - - return new Promise((resolve, reject) => { - xhr.onload = () => { - if (xhr.status === 200) { - resolve(JSON.parse(xhr.responseText)); - } else { - reject(xhr.responseText); - } - }; - xhr.onerror = () => reject(xhr.statusText); - xhr.send(form); - }); - } - - // Add this method to your GDrive class - async uploadFiles( - files:{name:string,mimeType:string,data:Blob|string}[], - directory=this.directory, - uploadProgress:HTMLProgressElement|string, - defaultBrowser=false - ) { - if(typeof uploadProgress === 'string') uploadProgress = document.getElementById('upload-progress') as HTMLProgressElement; - if(uploadProgress) uploadProgress.style.display = 'block'; - - for (let i = 0; i < files.length; i++) { - const file = files[i]; - try { - await this.uploadFileToGoogleDrive( - file.data, - file.name, - file.mimeType, - directory, - (progressEvent) => { - const progress = (progressEvent.loaded / progressEvent.total) * 100; - (uploadProgress as HTMLProgressElement).value = progress; - } - ); - if(uploadProgress) uploadProgress.value = 0; // Reset the progress bar after each file is uploaded - } catch (error) { - console.error('Error uploading file:', (file as any).name, error); - } - } - - if(uploadProgress) uploadProgress.style.display = 'none'; // Hide the progress bar after all files are uploaded - if(defaultBrowser) this.updateFileList(directory, this.nextPageToken, undefined, this.container); // Refresh the file list to show the newly uploaded files - } - - - async listDriveFiles( - folderId = this.directory, - pageSize = 100, - onload?:(files)=>{}, - pageToken = null, - parentFolder?:string - ) { - - if(this.isLoggedIn) { - try { - const response = await this.gapi.client.drive.files.list({ - q: `'${folderId}' ${parentFolder ? `and '${parentFolder}' ` : ``}in parents and trashed=false`, - pageSize, - fields: 'nextPageToken, files(id, name, mimeType)', - pageToken, - }); - - if (response.result?.files && response.result.files.length > 0) { - if(onload) onload(response.result.files); - } - - return { - files: response.result.files, - nextPageToken: response.result.nextPageToken, - }; - - } catch (error) { - console.error('Error listing Drive files:', error); - throw error; - } - - } else { - console.error("Sign in with Google first!"); - this.handleUserSignIn().then(async () => { - if(this.isLoggedIn) { - return await this.listDriveFiles( - folderId, - pageSize, - onload, //rerun - pageToken, - parentFolder - ) - } - }); - } - } - - createFileBrowser( - container, - folderId=this.directory, - nextPageToken=this.nextPageToken, - parentFolder - ) { - if (typeof container === 'string') { - container = document.getElementById(container); - } - - if (!container) { - console.error('Container element not found'); - return; - } - this.container = container; - container.innerHTML = `
    -
    - - -
    -
    Drop files here to upload
    - -
    -
    - - -
    `; - - this.updateFileList(folderId, nextPageToken, parentFolder, container); // Initially load the root directory - this.setupDragAndDrop(folderId, nextPageToken, parentFolder, container); - this.setupUploadButton(folderId, nextPageToken, parentFolder, container); - this.setupPaginationButtons(folderId, parentFolder, container); - } - - setupUploadButton(folderId, nextPageToken, parentFolder, container) { - const uploadButton = container.querySelector('#upload-button') as HTMLButtonElement; - const fileInput = container.querySelector('#file-input') as HTMLInputElement; - - if (!uploadButton || !fileInput) { - console.error('Upload button or file input not found'); - return; - } - - uploadButton.addEventListener('click', () => { - fileInput.click(); - }); - - fileInput.addEventListener('change', async () => { - const files = fileInput.files as any; - if (files.length > 0) { - const uploadFiles = Array.from(files).map((file:any) => ({ - name: file.name, - mimeType: file.type, - data: file, - })); - - const uploadProgress = container.querySelector('#upload-progress') as HTMLProgressElement; - await this.uploadFiles(uploadFiles, this.directory, uploadProgress); - this.updateFileList(folderId, nextPageToken, parentFolder, container); - fileInput.value = ''; // Clear the file input - } - }); - } - - setupDragAndDrop(currentFolderId:string, nextPageToken, parentFolder, container:HTMLElement) { - const dropZone = container.querySelector('#drop-zone'); - if (!dropZone) { - console.error('Drop zone element not found'); - return; - } - - dropZone.addEventListener('dragover', (e) => { - e.preventDefault(); - e.stopPropagation(); - dropZone.classList.add('highlight'); - }); - - dropZone.addEventListener('dragleave', (e) => { - e.preventDefault(); - e.stopPropagation(); - dropZone.classList.remove('highlight'); - }); - - dropZone.addEventListener('drop', async (e:any) => { - e.preventDefault(); - e.stopPropagation(); - dropZone.classList.remove('highlight'); - - const files = e.dataTransfer.files; - if (files.length > 0) { - const uploadFiles = Array.from(files).map((file:any) => ({ - name: file.name, - mimeType: file.type, - data: file, - })); - - const uploadProgress = container.querySelector('#upload-progress') as HTMLProgressElement; - await this.uploadFiles(uploadFiles, this.directory, uploadProgress); - this.updateFileList(currentFolderId, nextPageToken, parentFolder, container); - } - }); - } - - async updateFileList(currentFolderId = this.directory, pageToken = null, parentFolder, container:HTMLElement) { - try { - const { files, nextPageToken } = await this.listDriveFiles(currentFolderId, 100, undefined, pageToken, parentFolder) as any; - this.renderFileList(files, currentFolderId, parentFolder, container); - - // Update the previous page token when navigating forward. - if (pageToken !== null) { - this.previousPageToken = pageToken; - } - // Update the next page token. - this.nextPageToken = nextPageToken; - // Update the visibility of the pagination buttons. - (container.querySelector('#previous-page') as any).style.display = this.previousPageToken ? 'block' : 'none'; - (container.querySelector('#next-page') as any).style.display = this.nextPageToken ? 'block' : 'none'; - } catch (error) { - console.error('Error updating file list:', error); - } - } - - - renderFileList(files, currentFolderId = this.directory, parentFolder, container:HTMLElement) { - const fileListContainer = container.querySelector('#file-list'); - const folderPathContainer = container.querySelector('#folder-path'); - - if (!fileListContainer || !folderPathContainer) { - console.error('File browser elements not found'); - return; - } - - let html = ''; - files.forEach(file => { - html += `
    - ${file.name} -
    `; - }); - fileListContainer.innerHTML = html; - - this.setupFileItemClick(parentFolder, container); - - if (currentFolderId !== this.directory) { - folderPathContainer.innerHTML = ``; - (container.querySelector('#parent-folder') as any).addEventListener('click', () => { - this.goBackToParentFolder(container); - }); - } else { - folderPathContainer.innerHTML = ''; - } - } - - async goBackToParentFolder(container) { - try { - const currentFolderMetadata = await this.getFileMetadata(this.currentFolderId); - if (currentFolderMetadata && currentFolderMetadata.parents && currentFolderMetadata.parents.length > 0) { - const parentFolderId = currentFolderMetadata.parents[0]; - this.updateFileList(parentFolderId, null, 'parents', container); - this.currentFolderId = parentFolderId; // Update currentFolderId - } else { - console.error('This folder does not have a parent.'); - } - } catch (error) { - console.error('Error going back to parent folder:', error); - } - } - - setupFileItemClick(parentFolder, container) { - const fileItems = container.querySelectorAll('.file-item'); - fileItems.forEach(item => { - item.addEventListener('click', async () => { - const fileId = item.getAttribute('data-id'); - const mimeType = item.getAttribute('data-mime-type'); - const fileName = item.getAttribute('data-name'); - - if (mimeType === 'application/vnd.google-apps.folder') { - this.updateFileList(fileId, null, parentFolder, container); // Updated to navigate into the folder - this.currentFolderId = fileId; // Update currentFolderId - } else { - const downloadedFile = await this.downloadFile(fileId, mimeType); - console.log('Downloaded file:', fileName, downloadedFile); - } - }); - }); - } - - - setupPaginationButtons(folderId, parentFolder, container) { - (container.querySelector('#previous-page') as any).addEventListener('click', () => { - if (this.previousPageToken !== null) { - this.updateFileList(folderId, this.previousPageToken, parentFolder, container); - // Clear the previous page token since we've navigated back. - this.previousPageToken = null; - } - }); - - (container.querySelector('#next-page') as any).addEventListener('click', () => { - if (this.nextPageToken) { - this.updateFileList(folderId, this.nextPageToken, parentFolder, container); - } - }); - } - - - //backup BFS file to drive by name (requires gapi authorization) - backupBFSToDrive = ( - bfsPath:string, - bfsDir='data', - mimeType='application/vnd.google-apps.spreadsheet' - ) => { - return new Promise(async (res,rej) => { - if(!fsInited) await initFS(['data']); - if(this.isLoggedIn){ - fs.readFile(bfsDir+'/'+bfsPath, (e,output)=>{ - if(e) throw e; if(!output) return; - let file = new Blob([output.toString()],{type:'text/csv'}); - this.checkFolder(this.directory, (result)=>{ - console.log(result); - let metadata = { - 'name':bfsPath, - 'mimeType':mimeType, - 'parents':[result.files[0].id] - } - let token = this.gapi.auth.getToken().access_token; - var form = new FormData(); - form.append('metadata', new Blob([JSON.stringify(metadata)], {type: 'application/json'})); - form.append('file', file); - - var xhr = new XMLHttpRequest(); - xhr.open('post', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id'); - xhr.setRequestHeader('Authorization', 'Bearer ' + token); - xhr.responseType = 'json'; - xhr.onload = () => { - console.log("Uploaded file id: ",xhr.response.id); // Retrieve uploaded file ID. - //this.listDriveFiles(); - res(true); - }; - xhr.send(form); - }); - }); - } else { - console.error("Sign in with Google first!"); - this.handleUserSignIn().then(async () => { - if(this.isLoggedIn) { - res(await this.backupBFSToDrive(bfsPath)); //rerun - } - }); - - } - }); - - } - - - //pass a queried drive folder (i.e. from listDriveFiles) - driveToBFS = ( - file:{id:string, name:string, [key:string]:any}, //you need the file id from gdrive - bfsDir='data', - ondownload=(body)=>{}, - mimeType='text/csv' - ) => { - return new Promise((res,rej) => { - if(this.isLoggedIn) { - var request = this.gapi.client.drive.files.export({'fileId': file.id, 'mimeType':mimeType}); - request.then(async (resp) => { - let filename = file.name; - if(!fsInited) await initFS(['data']); - fs.appendFile( - '/'+bfsDir+'/'+filename, - resp.body, - (e)=>{ - if(e) throw e; - ondownload(resp.body); - res(resp.body); - }); - }); - } else { - console.error("Sign in with Google first!"); - this.handleUserSignIn().then(async () => { - if(this.isLoggedIn) { - res(await this.driveToBFS( - file, - bfsDir, //rerun - ondownload - )) - } - }); - } - }); - } - - -} - - -export const GDriveRoutes = new GDrive(); //need to call init(apiKey,clientId); \ No newline at end of file diff --git a/src/extras/storage/gdrivetest/.gitignore b/src/extras/storage/gdrivetest/.gitignore deleted file mode 100644 index ac756779..00000000 --- a/src/extras/storage/gdrivetest/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ - -dist -**/node_modules/** -**/*.pem -**/*.pfxs -**/*.key -**/*.lock -**/package-lock.json -**/*.key -**/*.log diff --git a/src/extras/storage/gdrivetest/index.css b/src/extras/storage/gdrivetest/index.css deleted file mode 100644 index d5ea5431..00000000 --- a/src/extras/storage/gdrivetest/index.css +++ /dev/null @@ -1,9 +0,0 @@ -#floatingDiv { - position: absolute; - width: 100px; - height: 100px; - background-color: red; - text-align: center; - vertical-align: middle; - line-height: 100px; /* The same as your div height */ -} \ No newline at end of file diff --git a/src/extras/storage/gdrivetest/index.html b/src/extras/storage/gdrivetest/index.html deleted file mode 100644 index a5aa66e1..00000000 --- a/src/extras/storage/gdrivetest/index.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - Google Drive File Browser - - - - -

    Google Drive File Browser

    -
    Sign in with Google
    -
    - - - - - \ No newline at end of file diff --git a/src/extras/storage/gdrivetest/index.js b/src/extras/storage/gdrivetest/index.js deleted file mode 100644 index 47635f08..00000000 --- a/src/extras/storage/gdrivetest/index.js +++ /dev/null @@ -1,28 +0,0 @@ -/* - esbuild + nodejs development server. - Begin your javascript application here. This file serves as a simplified entry point to your app, - all other scripts you want to build can stem from here if you don't want to define more entryPoints - and an outdir in the bundler settings. - - Just ctrl-A + delete all this to get started on your app. - -*/ - -import { GDrive } from '../BFS_GDrive'; - -const apiKey = 'YOUR_GOOGLE_API_KEY'; -const clientId = 'YOUR_GOOGLE_CLIENT_ID'; - -const gdrive = new GDrive(apiKey, clientId); - -const authButton = document.getElementById('auth-button'); -authButton.addEventListener('click', async () => { - try { - await gdrive.handleUserSignIn(); - authButton.style.display = 'none'; - gdrive.createFileBrowser('file-browser-container'); - } catch (error) { - console.error('Error signing in:', error); - } -}); - diff --git a/src/extras/storage/gdrivetest/package.json b/src/extras/storage/gdrivetest/package.json deleted file mode 100644 index 271c951d..00000000 --- a/src/extras/storage/gdrivetest/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "tinybuildapp7431", - "version": "0.0.0", - "description": "Barebones esbuild and test node server implementation. For building", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "type": "module", - "scripts": { - "start": "tinybuild", - "build": "tinybuild build", - "serve": "tinybuild serve", - "init": "node tinybuild/init.js", - "concurrent": "concurrently \"npm run python\" \"npm start\"", - "dev": "npm run pip && npm i --save-dev concurrently && npm i --save-dev nodemon && npm run concurrent", - "startdev": "nodemon --exec \"node tinybuild.js\" -e ejs,js,ts,jsx,tsx,css,html,jpg,png,scss,txt,csv", - "python": "python python/server.py", - "pip": "pip install quart && pip install websockets", - "pwa": "npm i workbox-cli && workbox generateSW node_server/pwa/workbox-config.js && npm run build && npm start" - }, - "keywords": [ - "esbuild" - ], - "author": "", - "license": "", - "dependencies": { - "browserfs": "^1.4.3" - }, - "nodemonConfig": { - "env": { - "NODEMON": true - }, - "ignore": [ - "dist/", - ".temp/" - ] - } -} diff --git a/src/extras/storage/gdrivetest/tinybuild.config.js b/src/extras/storage/gdrivetest/tinybuild.config.js deleted file mode 100644 index cf06d3b8..00000000 --- a/src/extras/storage/gdrivetest/tinybuild.config.js +++ /dev/null @@ -1,58 +0,0 @@ -const config = { - bundler: { //esbuild settings, set false to skip build step or add bundle:true to config object to only bundle (alt methods) - entryPoints: [ //entry point file(s). These can include .js, .mjs, .ts, .jsx, .tsx, or other javascript files. Make sure your entry point is a ts file if you want to generate types - "index.js" - ], - outfile: "dist/index", //exit point file, will append .js as well as indicators like .esm.js, .node.js for other build flags - //outdir:'dist' //exit point folder, define for multiple entryPoints - bundleBrowser: true, //create plain js build? Can include globals and init scripts - bundleESM: false, //create esm module js files // { platform:'node' } //etc you can also supply an object here to add more specific esbuild settings - bundleTypes: false, //create .d.ts files, //you need a .tsconfig for this to work - bundleNode: false, //create node platform plain js build, specify platform:'node' to do the rest of the files - bundleHTML: false, //wrap the first entry point file as a plain js script in a boilerplate html file, frontend scripts can be run standalone like a .exe! Server serves this as start page if set to true. - //bundleIIFE:false, //create an iife build, this is compiled temporarily to create the types files and only saved with bundleIIFE:true - //bundleCommonJS:false, //cjs format outputted as .cjs - minify: true, - sourcemap: false, - //plugins:{} //custom esbuild plugins? e.g. esbuild-sass-plugin for scss support - //includeDefaultPlugins:true //true by default, includes the presets for the streaming imports, worker bundling, and auto npm install - //blobWorkers:true, //package workers as blobs or files? blobs are faster but inflate the main package size - //workerBundler:{minifyWhitespace:true} //bundler settings specific to the worker. e.g. apply platform:'node' when bundling node workers, - //globalThis:null //'mymodule' - //globals:{'index.js':['Graph']} - //init:{'index.js':function(bundle) { console.log('prepackaged bundle script!', bundle); }.toString(); } - // outputs:{ //overwrites main config settings for specific use cases - // node:{ //e.g. for bundleNode - // // external:[] //externals for node environment builds - // }, - // //commonjs:{} //bundleCommonJS - // //browser:{} - // //esm:{} - // iife:{ - // // external:[] //we only use the iife for types so it doesn't really matter if it bundles node, just note otherwise if you need iife for some obscure reason - // } - // }, - - //refer to esbuild docs for more settings - }, - server: { //node server settings, set false to skip server step or add serve:true to config object to only serve (alt methods) - debug: false, - protocol: "http", //'http' or 'https'. HTTPS required for Nodejs <---> Python sockets. If using http, set production to False in python/server.py as well - host: "localhost", //'localhost' or '127.0.0.1' etc. - port: 8080, //e.g. port 80, 443, 8000 - //redirect: 'http://localhost:8082' //instead of serving the default content, redirect ot another url e.g. another server - startpage: "index.html", //home page - socket_protocol: "ws", //frontend socket protocol, wss for served, ws for localhost - hotreload: 5000, //hotreload websocket server port - reloadscripts: false, //hot swap scripts, can break things if script handles initializations, otherwise css, link, srcs all hot swap without page reloading fairly intelligently - //delay: 50, //millisecond delay on the watch command for hot reloading - //pwa: "dist/service-worker.js", //pwa mode? Injects service worker registry code in (see pwa README.md) - //watch: ['../'], //watch additional directories other than the current working directory - python: false,//7000, //quart server port (configured via the python server script file still) - python_node:7001, //websocket relay port (relays messages to client from nodejs that were sent to it by python) - errpage: 'node_modules/tinybuild/tinybuild/node_server/other/404.html', //default error page, etc. - certpath:'node_modules/tinybuild/tinybuild/node_server/ssl/cert.pem',//if using https, this is required. See cert.pfx.md for instructions - keypath:'node_modules/tinybuild/tinybuild/node_server/ssl/key.pem'//if using https, this is required. See cert.pfx.md for instructions - } -} -export default config; //module.exports = config; //es5 \ No newline at end of file diff --git a/src/extras/storage/sheets_rest.ts b/src/extras/storage/sheets_rest.ts deleted file mode 100644 index 54408e72..00000000 --- a/src/extras/storage/sheets_rest.ts +++ /dev/null @@ -1,210 +0,0 @@ - -function getOrCreateSheet(spreadsheetOptions) { - let { spreadsheetId, sheetName, accessToken } = spreadsheetOptions; - - return fetch(`https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}?fields=sheets.properties`, { - headers: { - 'Authorization': `Bearer ${accessToken}` - } - }) - .then(response => { - const body = typeof response.body === 'string' ? JSON.parse(response.body) : response.body; - const sheets = body.sheets || []; - const sheet = sheets.find(s => s.properties.title === sheetName); - - if (sheet) { - return sheet.properties; - } else { - return createSheet({ spreadsheetId, sheetName, accessToken }); - } - }); -} - -function createSheet(spreadsheetOptions: { - spreadsheetId?: string; - sheetName: string; - accessToken: string; -}) { - - let { spreadsheetId, sheetName, accessToken } = spreadsheetOptions; - - const data = { - requests: [{ - addSheet: { - properties: { - title: sheetName - } - } - }] - }; - - return fetch(`https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}:batchUpdate`, { - method: 'POST', - headers: { - 'Authorization': `Bearer ${accessToken}`, - 'Content-Type': 'application/json' - }, - body: JSON.stringify(data) - }) - .then(response => { - const body = typeof response.body === 'string' ? JSON.parse(response.body) : response.body; - const sheet = body.replies[0].addSheet.properties; - return sheet; - }); - -} - -async function init(spreadsheetOptions: { - accessToken: string; - spreadsheetName?: string; //either - spreadsheetId?: string; //or - sheetName?: string; -}) { - if (!spreadsheetOptions.spreadsheetId) { - if (!spreadsheetOptions.spreadsheetName) { - throw new Error('Either spreadsheetId or spreadsheetName must be provided'); - } - - // Query Google Drive API to get the spreadsheet ID by name - const driveApiUrl = `https://www.googleapis.com/drive/v3/files?q=name='${spreadsheetOptions.spreadsheetName}'&mimeType='application/vnd.google-apps.spreadsheet'&fields=files(id,name)`; - const driveResponse = await fetch(driveApiUrl, { - headers: { - 'Authorization': `Bearer ${spreadsheetOptions.accessToken}` - } - }); - const driveResponseBody = typeof driveResponse.body === 'string' ? JSON.parse(driveResponse.body) : driveResponse.body; - const file = driveResponseBody.files[0]; - - if (file) { - spreadsheetOptions.spreadsheetId = file.id; - } else { - // If spreadsheet not found, create a new one - const createResponse = await fetch('https://www.googleapis.com/drive/v3/files', { - method: 'POST', - headers: { - 'Authorization': `Bearer ${spreadsheetOptions.accessToken}`, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - mimeType: 'application/vnd.google-apps.spreadsheet', - name: spreadsheetOptions.spreadsheetName, - }) - }); - let createData = await createResponse.json(); - createData = typeof createData === 'string' ? JSON.parse(createData) : createData; - spreadsheetOptions.spreadsheetId = createData.id; - } - } - - // Fetch spreadsheet to get sheets info - const sheetsResponse = await fetch(`https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetOptions.spreadsheetId}?fields=sheets.properties`, { - headers: { - 'Authorization': `Bearer ${spreadsheetOptions.accessToken}` - } - }); - let sheetsData = await sheetsResponse.json(); - sheetsData = typeof sheetsData === 'string' ? JSON.parse(sheetsData) : sheetsData; - - if (!spreadsheetOptions.sheetName) { - if (sheetsData.sheets && sheetsData.sheets.length > 0) { - spreadsheetOptions.sheetName = sheetsData.sheets[0].properties.title; - } else { - throw new Error('No sheets found in the spreadsheet'); - } - } - - const sheetProperties = await getOrCreateSheet({ spreadsheetId: spreadsheetOptions.spreadsheetId, sheetName: spreadsheetOptions.sheetName, accessToken: spreadsheetOptions.accessToken }); - const sheetIndex = sheetProperties.sheetId; - console.log('Sheet exists or was created:', sheetProperties.title, 'with Sheet Index:', sheetIndex); -} - -async function readRange(spreadsheetOptions: { - spreadsheetId: string; - sheetName: string; - range?: string; - accessToken: string; - }): Promise { - const { spreadsheetId, sheetName, range, accessToken } = spreadsheetOptions; - - // If range is provided, use it; otherwise, default to the entire sheet - const fullRange = range ? `${sheetName}!${range}` : sheetName; - const url = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/${fullRange}`; - const response = await fetch(url, { - headers: { - 'Authorization': `Bearer ${accessToken}` - } - }); - - if (!response.ok) { - throw new Error('Network response was not ok: ' + response.statusText); - } - - const responseBody = typeof response.body === 'string' ? JSON.parse(response.body) : response.body; - return responseBody.values || []; -} - -async function writeRange(spreadsheetOptions: { - spreadsheetId: string; - range: string; - values: any[][]; - accessToken: string; -}): Promise { - const { spreadsheetId, range, values, accessToken } = spreadsheetOptions; - - const url = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/${range}:batchUpdate`; - const response = await fetch(url, { - method: 'POST', - headers: { - 'Authorization': `Bearer ${accessToken}`, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - valueInputOption: 'USER_ENTERED', - data: [ - { - range: range, - values: values - } - ] - }) - }); - - const responseBody = typeof response.body === 'string' ? JSON.parse(response.body) : response.body; - if (!response.ok) { - throw new Error('Network response was not ok ' + (responseBody.error?.message || response.statusText)); - } - return responseBody; -} - - -async function demo( - accessToken='YOUR_ACCESS_TOKEN', - spreadsheetName='MySpreadsheet', - sheetName='Sheet1' -) { - const spreadsheetOptions = { - accessToken, - spreadsheetName, // Either provide this... - //spreadsheetId: 'your-spreadsheet-id', // Or provide this - sheetName - } as any; - - // Initialize the spreadsheet - await init(spreadsheetOptions); - console.log('Spreadsheet initialized.'); - - // Read data from the spreadsheet - const readOptions = { ...spreadsheetOptions, range: 'A1:B2' }; - const data = await readRange(readOptions); - console.log('Data read from the spreadsheet:', data, readOptions); - - // Write data to the spreadsheet - const writeOptions = { ...spreadsheetOptions, range: 'A3', values: [['Hello', 'World'], ['How', 'are you?']] }; - await writeRange(writeOptions); - console.log('Data written to the spreadsheet.', writeOptions); -} - -// // Run the demo -// demo() -// .then(() => console.log('Demo completed successfully')) -// .catch(error => console.error('Demo failed with error:', error)); \ No newline at end of file diff --git a/src/extras/struct/datastructures/bson.cjs b/src/extras/struct/datastructures/bson.cjs deleted file mode 100644 index fb846640..00000000 --- a/src/extras/struct/datastructures/bson.cjs +++ /dev/null @@ -1,4095 +0,0 @@ -'use strict'; - -const BSON_MAJOR_VERSION = 5; -const BSON_INT32_MAX = 0x7fffffff; -const BSON_INT32_MIN = -0x80000000; -const BSON_INT64_MAX = Math.pow(2, 63) - 1; -const BSON_INT64_MIN = -Math.pow(2, 63); -const JS_INT_MAX = Math.pow(2, 53); -const JS_INT_MIN = -Math.pow(2, 53); -const BSON_DATA_NUMBER = 1; -const BSON_DATA_STRING = 2; -const BSON_DATA_OBJECT = 3; -const BSON_DATA_ARRAY = 4; -const BSON_DATA_BINARY = 5; -const BSON_DATA_UNDEFINED = 6; -const BSON_DATA_OID = 7; -const BSON_DATA_BOOLEAN = 8; -const BSON_DATA_DATE = 9; -const BSON_DATA_NULL = 10; -const BSON_DATA_REGEXP = 11; -const BSON_DATA_DBPOINTER = 12; -const BSON_DATA_CODE = 13; -const BSON_DATA_SYMBOL = 14; -const BSON_DATA_CODE_W_SCOPE = 15; -const BSON_DATA_INT = 16; -const BSON_DATA_TIMESTAMP = 17; -const BSON_DATA_LONG = 18; -const BSON_DATA_DECIMAL128 = 19; -const BSON_DATA_MIN_KEY = 0xff; -const BSON_DATA_MAX_KEY = 0x7f; -const BSON_BINARY_SUBTYPE_DEFAULT = 0; -const BSON_BINARY_SUBTYPE_UUID_NEW = 4; -const BSONType = Object.freeze({ - double: 1, - string: 2, - object: 3, - array: 4, - binData: 5, - undefined: 6, - objectId: 7, - bool: 8, - date: 9, - null: 10, - regex: 11, - dbPointer: 12, - javascript: 13, - symbol: 14, - javascriptWithScope: 15, - int: 16, - timestamp: 17, - long: 18, - decimal: 19, - minKey: -1, - maxKey: 127 -}); - -class BSONError extends Error { - get bsonError() { - return true; - } - get name() { - return 'BSONError'; - } - constructor(message) { - super(message); - } - static isBSONError(value) { - return (value != null && - typeof value === 'object' && - 'bsonError' in value && - value.bsonError === true && - 'name' in value && - 'message' in value && - 'stack' in value); - } -} -class BSONVersionError extends BSONError { - get name() { - return 'BSONVersionError'; - } - constructor() { - super(`Unsupported BSON version, bson types must be from bson ${BSON_MAJOR_VERSION}.0 or later`); - } -} -class BSONRuntimeError extends BSONError { - get name() { - return 'BSONRuntimeError'; - } - constructor(message) { - super(message); - } -} - -function nodejsMathRandomBytes(byteLength) { - return nodeJsByteUtils.fromNumberArray(Array.from({ length: byteLength }, () => Math.floor(Math.random() * 256))); -} -const nodejsRandomBytes = (() => { - try { - return require('crypto').randomBytes; - } - catch { - return nodejsMathRandomBytes; - } -})(); -const nodeJsByteUtils = { - toLocalBufferType(potentialBuffer) { - if (Buffer.isBuffer(potentialBuffer)) { - return potentialBuffer; - } - if (ArrayBuffer.isView(potentialBuffer)) { - return Buffer.from(potentialBuffer.buffer, potentialBuffer.byteOffset, potentialBuffer.byteLength); - } - const stringTag = potentialBuffer?.[Symbol.toStringTag] ?? Object.prototype.toString.call(potentialBuffer); - if (stringTag === 'ArrayBuffer' || - stringTag === 'SharedArrayBuffer' || - stringTag === '[object ArrayBuffer]' || - stringTag === '[object SharedArrayBuffer]') { - return Buffer.from(potentialBuffer); - } - throw new BSONError(`Cannot create Buffer from ${String(potentialBuffer)}`); - }, - allocate(size) { - return Buffer.alloc(size); - }, - equals(a, b) { - return nodeJsByteUtils.toLocalBufferType(a).equals(b); - }, - fromNumberArray(array) { - return Buffer.from(array); - }, - fromBase64(base64) { - return Buffer.from(base64, 'base64'); - }, - toBase64(buffer) { - return nodeJsByteUtils.toLocalBufferType(buffer).toString('base64'); - }, - fromISO88591(codePoints) { - return Buffer.from(codePoints, 'binary'); - }, - toISO88591(buffer) { - return nodeJsByteUtils.toLocalBufferType(buffer).toString('binary'); - }, - fromHex(hex) { - return Buffer.from(hex, 'hex'); - }, - toHex(buffer) { - return nodeJsByteUtils.toLocalBufferType(buffer).toString('hex'); - }, - fromUTF8(text) { - return Buffer.from(text, 'utf8'); - }, - toUTF8(buffer) { - return nodeJsByteUtils.toLocalBufferType(buffer).toString('utf8'); - }, - utf8ByteLength(input) { - return Buffer.byteLength(input, 'utf8'); - }, - encodeUTF8Into(buffer, source, byteOffset) { - return nodeJsByteUtils.toLocalBufferType(buffer).write(source, byteOffset, undefined, 'utf8'); - }, - randomBytes: nodejsRandomBytes -}; - -function isReactNative() { - const { navigator } = globalThis; - return typeof navigator === 'object' && navigator.product === 'ReactNative'; -} -function webMathRandomBytes(byteLength) { - if (byteLength < 0) { - throw new RangeError(`The argument 'byteLength' is invalid. Received ${byteLength}`); - } - return webByteUtils.fromNumberArray(Array.from({ length: byteLength }, () => Math.floor(Math.random() * 256))); -} -const webRandomBytes = (() => { - const { crypto } = globalThis; - if (crypto != null && typeof crypto.getRandomValues === 'function') { - return (byteLength) => { - return crypto.getRandomValues(webByteUtils.allocate(byteLength)); - }; - } - else { - if (isReactNative()) { - const { console } = globalThis; - console?.warn?.('BSON: For React Native please polyfill crypto.getRandomValues, e.g. using: https://www.npmjs.com/package/react-native-get-random-values.'); - } - return webMathRandomBytes; - } -})(); -const HEX_DIGIT = /(\d|[a-f])/i; -const webByteUtils = { - toLocalBufferType(potentialUint8array) { - const stringTag = potentialUint8array?.[Symbol.toStringTag] ?? - Object.prototype.toString.call(potentialUint8array); - if (stringTag === 'Uint8Array') { - return potentialUint8array; - } - if (ArrayBuffer.isView(potentialUint8array)) { - return new Uint8Array(potentialUint8array.buffer.slice(potentialUint8array.byteOffset, potentialUint8array.byteOffset + potentialUint8array.byteLength)); - } - if (stringTag === 'ArrayBuffer' || - stringTag === 'SharedArrayBuffer' || - stringTag === '[object ArrayBuffer]' || - stringTag === '[object SharedArrayBuffer]') { - return new Uint8Array(potentialUint8array); - } - throw new BSONError(`Cannot make a Uint8Array from ${String(potentialUint8array)}`); - }, - allocate(size) { - if (typeof size !== 'number') { - throw new TypeError(`The "size" argument must be of type number. Received ${String(size)}`); - } - return new Uint8Array(size); - }, - equals(a, b) { - if (a.byteLength !== b.byteLength) { - return false; - } - for (let i = 0; i < a.byteLength; i++) { - if (a[i] !== b[i]) { - return false; - } - } - return true; - }, - fromNumberArray(array) { - return Uint8Array.from(array); - }, - fromBase64(base64) { - return Uint8Array.from(atob(base64), c => c.charCodeAt(0)); - }, - toBase64(uint8array) { - return btoa(webByteUtils.toISO88591(uint8array)); - }, - fromISO88591(codePoints) { - return Uint8Array.from(codePoints, c => c.charCodeAt(0) & 0xff); - }, - toISO88591(uint8array) { - return Array.from(Uint16Array.from(uint8array), b => String.fromCharCode(b)).join(''); - }, - fromHex(hex) { - const evenLengthHex = hex.length % 2 === 0 ? hex : hex.slice(0, hex.length - 1); - const buffer = []; - for (let i = 0; i < evenLengthHex.length; i += 2) { - const firstDigit = evenLengthHex[i]; - const secondDigit = evenLengthHex[i + 1]; - if (!HEX_DIGIT.test(firstDigit)) { - break; - } - if (!HEX_DIGIT.test(secondDigit)) { - break; - } - const hexDigit = Number.parseInt(`${firstDigit}${secondDigit}`, 16); - buffer.push(hexDigit); - } - return Uint8Array.from(buffer); - }, - toHex(uint8array) { - return Array.from(uint8array, byte => byte.toString(16).padStart(2, '0')).join(''); - }, - fromUTF8(text) { - return new TextEncoder().encode(text); - }, - toUTF8(uint8array) { - return new TextDecoder('utf8', { fatal: false }).decode(uint8array); - }, - utf8ByteLength(input) { - return webByteUtils.fromUTF8(input).byteLength; - }, - encodeUTF8Into(buffer, source, byteOffset) { - const bytes = webByteUtils.fromUTF8(source); - buffer.set(bytes, byteOffset); - return bytes.byteLength; - }, - randomBytes: webRandomBytes -}; - -const hasGlobalBuffer = typeof Buffer === 'function' && Buffer.prototype?._isBuffer !== true; -const ByteUtils = hasGlobalBuffer ? nodeJsByteUtils : webByteUtils; -class BSONDataView extends DataView { - static fromUint8Array(input) { - return new DataView(input.buffer, input.byteOffset, input.byteLength); - } -} - -const VALIDATION_REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15})$/i; -const uuidValidateString = (str) => typeof str === 'string' && VALIDATION_REGEX.test(str); -const uuidHexStringToBuffer = (hexString) => { - if (!uuidValidateString(hexString)) { - throw new BSONError('UUID string representations must be a 32 or 36 character hex string (dashes excluded/included). Format: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" or "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".'); - } - const sanitizedHexString = hexString.replace(/-/g, ''); - return ByteUtils.fromHex(sanitizedHexString); -}; -function bufferToUuidHexString(buffer, includeDashes = true) { - if (includeDashes) { - return [ - ByteUtils.toHex(buffer.subarray(0, 4)), - ByteUtils.toHex(buffer.subarray(4, 6)), - ByteUtils.toHex(buffer.subarray(6, 8)), - ByteUtils.toHex(buffer.subarray(8, 10)), - ByteUtils.toHex(buffer.subarray(10, 16)) - ].join('-'); - } - return ByteUtils.toHex(buffer); -} - -function isAnyArrayBuffer(value) { - return ['[object ArrayBuffer]', '[object SharedArrayBuffer]'].includes(Object.prototype.toString.call(value)); -} -function isUint8Array(value) { - return Object.prototype.toString.call(value) === '[object Uint8Array]'; -} -function isRegExp(d) { - return Object.prototype.toString.call(d) === '[object RegExp]'; -} -function isMap(d) { - return Object.prototype.toString.call(d) === '[object Map]'; -} -function isDate(d) { - return Object.prototype.toString.call(d) === '[object Date]'; -} - -class BSONValue { - get [Symbol.for('@@mdb.bson.version')]() { - return BSON_MAJOR_VERSION; - } -} - -class Binary extends BSONValue { - get _bsontype() { - return 'Binary'; - } - constructor(buffer, subType) { - super(); - if (!(buffer == null) && - !(typeof buffer === 'string') && - !ArrayBuffer.isView(buffer) && - !(buffer instanceof ArrayBuffer) && - !Array.isArray(buffer)) { - throw new BSONError('Binary can only be constructed from string, Buffer, TypedArray, or Array'); - } - this.sub_type = subType ?? Binary.BSON_BINARY_SUBTYPE_DEFAULT; - if (buffer == null) { - this.buffer = ByteUtils.allocate(Binary.BUFFER_SIZE); - this.position = 0; - } - else { - if (typeof buffer === 'string') { - this.buffer = ByteUtils.fromISO88591(buffer); - } - else if (Array.isArray(buffer)) { - this.buffer = ByteUtils.fromNumberArray(buffer); - } - else { - this.buffer = ByteUtils.toLocalBufferType(buffer); - } - this.position = this.buffer.byteLength; - } - } - put(byteValue) { - if (typeof byteValue === 'string' && byteValue.length !== 1) { - throw new BSONError('only accepts single character String'); - } - else if (typeof byteValue !== 'number' && byteValue.length !== 1) - throw new BSONError('only accepts single character Uint8Array or Array'); - let decodedByte; - if (typeof byteValue === 'string') { - decodedByte = byteValue.charCodeAt(0); - } - else if (typeof byteValue === 'number') { - decodedByte = byteValue; - } - else { - decodedByte = byteValue[0]; - } - if (decodedByte < 0 || decodedByte > 255) { - throw new BSONError('only accepts number in a valid unsigned byte range 0-255'); - } - if (this.buffer.byteLength > this.position) { - this.buffer[this.position++] = decodedByte; - } - else { - const newSpace = ByteUtils.allocate(Binary.BUFFER_SIZE + this.buffer.length); - newSpace.set(this.buffer, 0); - this.buffer = newSpace; - this.buffer[this.position++] = decodedByte; - } - } - write(sequence, offset) { - offset = typeof offset === 'number' ? offset : this.position; - if (this.buffer.byteLength < offset + sequence.length) { - const newSpace = ByteUtils.allocate(this.buffer.byteLength + sequence.length); - newSpace.set(this.buffer, 0); - this.buffer = newSpace; - } - if (ArrayBuffer.isView(sequence)) { - this.buffer.set(ByteUtils.toLocalBufferType(sequence), offset); - this.position = - offset + sequence.byteLength > this.position ? offset + sequence.length : this.position; - } - else if (typeof sequence === 'string') { - const bytes = ByteUtils.fromISO88591(sequence); - this.buffer.set(bytes, offset); - this.position = - offset + sequence.length > this.position ? offset + sequence.length : this.position; - } - } - read(position, length) { - length = length && length > 0 ? length : this.position; - return this.buffer.slice(position, position + length); - } - value(asRaw) { - asRaw = !!asRaw; - if (asRaw && this.buffer.length === this.position) { - return this.buffer; - } - if (asRaw) { - return this.buffer.slice(0, this.position); - } - return ByteUtils.toISO88591(this.buffer.subarray(0, this.position)); - } - length() { - return this.position; - } - toJSON() { - return ByteUtils.toBase64(this.buffer); - } - toString(encoding) { - if (encoding === 'hex') - return ByteUtils.toHex(this.buffer); - if (encoding === 'base64') - return ByteUtils.toBase64(this.buffer); - if (encoding === 'utf8' || encoding === 'utf-8') - return ByteUtils.toUTF8(this.buffer); - return ByteUtils.toUTF8(this.buffer); - } - toExtendedJSON(options) { - options = options || {}; - const base64String = ByteUtils.toBase64(this.buffer); - const subType = Number(this.sub_type).toString(16); - if (options.legacy) { - return { - $binary: base64String, - $type: subType.length === 1 ? '0' + subType : subType - }; - } - return { - $binary: { - base64: base64String, - subType: subType.length === 1 ? '0' + subType : subType - } - }; - } - toUUID() { - if (this.sub_type === Binary.SUBTYPE_UUID) { - return new UUID(this.buffer.slice(0, this.position)); - } - throw new BSONError(`Binary sub_type "${this.sub_type}" is not supported for converting to UUID. Only "${Binary.SUBTYPE_UUID}" is currently supported.`); - } - static fromExtendedJSON(doc, options) { - options = options || {}; - let data; - let type; - if ('$binary' in doc) { - if (options.legacy && typeof doc.$binary === 'string' && '$type' in doc) { - type = doc.$type ? parseInt(doc.$type, 16) : 0; - data = ByteUtils.fromBase64(doc.$binary); - } - else { - if (typeof doc.$binary !== 'string') { - type = doc.$binary.subType ? parseInt(doc.$binary.subType, 16) : 0; - data = ByteUtils.fromBase64(doc.$binary.base64); - } - } - } - else if ('$uuid' in doc) { - type = 4; - data = uuidHexStringToBuffer(doc.$uuid); - } - if (!data) { - throw new BSONError(`Unexpected Binary Extended JSON format ${JSON.stringify(doc)}`); - } - return type === BSON_BINARY_SUBTYPE_UUID_NEW ? new UUID(data) : new Binary(data, type); - } - [Symbol.for('nodejs.util.inspect.custom')]() { - return this.inspect(); - } - inspect() { - return `new Binary(Buffer.from("${ByteUtils.toHex(this.buffer)}", "hex"), ${this.sub_type})`; - } -} -Binary.BSON_BINARY_SUBTYPE_DEFAULT = 0; -Binary.BUFFER_SIZE = 256; -Binary.SUBTYPE_DEFAULT = 0; -Binary.SUBTYPE_FUNCTION = 1; -Binary.SUBTYPE_BYTE_ARRAY = 2; -Binary.SUBTYPE_UUID_OLD = 3; -Binary.SUBTYPE_UUID = 4; -Binary.SUBTYPE_MD5 = 5; -Binary.SUBTYPE_ENCRYPTED = 6; -Binary.SUBTYPE_COLUMN = 7; -Binary.SUBTYPE_USER_DEFINED = 128; -const UUID_BYTE_LENGTH = 16; -class UUID extends Binary { - constructor(input) { - let bytes; - let hexStr; - if (input == null) { - bytes = UUID.generate(); - } - else if (input instanceof UUID) { - bytes = ByteUtils.toLocalBufferType(new Uint8Array(input.buffer)); - hexStr = input.__id; - } - else if (ArrayBuffer.isView(input) && input.byteLength === UUID_BYTE_LENGTH) { - bytes = ByteUtils.toLocalBufferType(input); - } - else if (typeof input === 'string') { - bytes = uuidHexStringToBuffer(input); - } - else { - throw new BSONError('Argument passed in UUID constructor must be a UUID, a 16 byte Buffer or a 32/36 character hex string (dashes excluded/included, format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).'); - } - super(bytes, BSON_BINARY_SUBTYPE_UUID_NEW); - this.__id = hexStr; - } - get id() { - return this.buffer; - } - set id(value) { - this.buffer = value; - if (UUID.cacheHexString) { - this.__id = bufferToUuidHexString(value); - } - } - toHexString(includeDashes = true) { - if (UUID.cacheHexString && this.__id) { - return this.__id; - } - const uuidHexString = bufferToUuidHexString(this.id, includeDashes); - if (UUID.cacheHexString) { - this.__id = uuidHexString; - } - return uuidHexString; - } - toString(encoding) { - if (encoding === 'hex') - return ByteUtils.toHex(this.id); - if (encoding === 'base64') - return ByteUtils.toBase64(this.id); - return this.toHexString(); - } - toJSON() { - return this.toHexString(); - } - equals(otherId) { - if (!otherId) { - return false; - } - if (otherId instanceof UUID) { - return ByteUtils.equals(otherId.id, this.id); - } - try { - return ByteUtils.equals(new UUID(otherId).id, this.id); - } - catch { - return false; - } - } - toBinary() { - return new Binary(this.id, Binary.SUBTYPE_UUID); - } - static generate() { - const bytes = ByteUtils.randomBytes(UUID_BYTE_LENGTH); - bytes[6] = (bytes[6] & 0x0f) | 0x40; - bytes[8] = (bytes[8] & 0x3f) | 0x80; - return bytes; - } - static isValid(input) { - if (!input) { - return false; - } - if (input instanceof UUID) { - return true; - } - if (typeof input === 'string') { - return uuidValidateString(input); - } - if (isUint8Array(input)) { - if (input.byteLength !== UUID_BYTE_LENGTH) { - return false; - } - return (input[6] & 0xf0) === 0x40 && (input[8] & 0x80) === 0x80; - } - return false; - } - static createFromHexString(hexString) { - const buffer = uuidHexStringToBuffer(hexString); - return new UUID(buffer); - } - [Symbol.for('nodejs.util.inspect.custom')]() { - return this.inspect(); - } - inspect() { - return `new UUID("${this.toHexString()}")`; - } -} - -class Code extends BSONValue { - get _bsontype() { - return 'Code'; - } - constructor(code, scope) { - super(); - this.code = code.toString(); - this.scope = scope ?? null; - } - toJSON() { - if (this.scope != null) { - return { code: this.code, scope: this.scope }; - } - return { code: this.code }; - } - toExtendedJSON() { - if (this.scope) { - return { $code: this.code, $scope: this.scope }; - } - return { $code: this.code }; - } - static fromExtendedJSON(doc) { - return new Code(doc.$code, doc.$scope); - } - [Symbol.for('nodejs.util.inspect.custom')]() { - return this.inspect(); - } - inspect() { - const codeJson = this.toJSON(); - return `new Code("${String(codeJson.code)}"${codeJson.scope != null ? `, ${JSON.stringify(codeJson.scope)}` : ''})`; - } -} - -function isDBRefLike(value) { - return (value != null && - typeof value === 'object' && - '$id' in value && - value.$id != null && - '$ref' in value && - typeof value.$ref === 'string' && - (!('$db' in value) || ('$db' in value && typeof value.$db === 'string'))); -} -class DBRef extends BSONValue { - get _bsontype() { - return 'DBRef'; - } - constructor(collection, oid, db, fields) { - super(); - const parts = collection.split('.'); - if (parts.length === 2) { - db = parts.shift(); - collection = parts.shift(); - } - this.collection = collection; - this.oid = oid; - this.db = db; - this.fields = fields || {}; - } - get namespace() { - return this.collection; - } - set namespace(value) { - this.collection = value; - } - toJSON() { - const o = Object.assign({ - $ref: this.collection, - $id: this.oid - }, this.fields); - if (this.db != null) - o.$db = this.db; - return o; - } - toExtendedJSON(options) { - options = options || {}; - let o = { - $ref: this.collection, - $id: this.oid - }; - if (options.legacy) { - return o; - } - if (this.db) - o.$db = this.db; - o = Object.assign(o, this.fields); - return o; - } - static fromExtendedJSON(doc) { - const copy = Object.assign({}, doc); - delete copy.$ref; - delete copy.$id; - delete copy.$db; - return new DBRef(doc.$ref, doc.$id, doc.$db, copy); - } - [Symbol.for('nodejs.util.inspect.custom')]() { - return this.inspect(); - } - inspect() { - const oid = this.oid === undefined || this.oid.toString === undefined ? this.oid : this.oid.toString(); - return `new DBRef("${this.namespace}", new ObjectId("${String(oid)}")${this.db ? `, "${this.db}"` : ''})`; - } -} - -let wasm = undefined; -try { - wasm = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 13, 2, 96, 0, 1, 127, 96, 4, 127, 127, 127, 127, 1, 127, 3, 7, 6, 0, 1, 1, 1, 1, 1, 6, 6, 1, 127, 1, 65, 0, 11, 7, 50, 6, 3, 109, 117, 108, 0, 1, 5, 100, 105, 118, 95, 115, 0, 2, 5, 100, 105, 118, 95, 117, 0, 3, 5, 114, 101, 109, 95, 115, 0, 4, 5, 114, 101, 109, 95, 117, 0, 5, 8, 103, 101, 116, 95, 104, 105, 103, 104, 0, 0, 10, 191, 1, 6, 4, 0, 35, 0, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 126, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 127, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 128, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 129, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 130, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11])), {}).exports; -} -catch { -} -const TWO_PWR_16_DBL = 1 << 16; -const TWO_PWR_24_DBL = 1 << 24; -const TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL; -const TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL; -const TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2; -const INT_CACHE = {}; -const UINT_CACHE = {}; -const MAX_INT64_STRING_LENGTH = 20; -const DECIMAL_REG_EX = /^(\+?0|(\+|-)?[1-9][0-9]*)$/; -class Long extends BSONValue { - get _bsontype() { - return 'Long'; - } - get __isLong__() { - return true; - } - constructor(low = 0, high, unsigned) { - super(); - if (typeof low === 'bigint') { - Object.assign(this, Long.fromBigInt(low, !!high)); - } - else if (typeof low === 'string') { - Object.assign(this, Long.fromString(low, !!high)); - } - else { - this.low = low | 0; - this.high = high | 0; - this.unsigned = !!unsigned; - } - } - static fromBits(lowBits, highBits, unsigned) { - return new Long(lowBits, highBits, unsigned); - } - static fromInt(value, unsigned) { - let obj, cachedObj, cache; - if (unsigned) { - value >>>= 0; - if ((cache = 0 <= value && value < 256)) { - cachedObj = UINT_CACHE[value]; - if (cachedObj) - return cachedObj; - } - obj = Long.fromBits(value, (value | 0) < 0 ? -1 : 0, true); - if (cache) - UINT_CACHE[value] = obj; - return obj; - } - else { - value |= 0; - if ((cache = -128 <= value && value < 128)) { - cachedObj = INT_CACHE[value]; - if (cachedObj) - return cachedObj; - } - obj = Long.fromBits(value, value < 0 ? -1 : 0, false); - if (cache) - INT_CACHE[value] = obj; - return obj; - } - } - static fromNumber(value, unsigned) { - if (isNaN(value)) - return unsigned ? Long.UZERO : Long.ZERO; - if (unsigned) { - if (value < 0) - return Long.UZERO; - if (value >= TWO_PWR_64_DBL) - return Long.MAX_UNSIGNED_VALUE; - } - else { - if (value <= -TWO_PWR_63_DBL) - return Long.MIN_VALUE; - if (value + 1 >= TWO_PWR_63_DBL) - return Long.MAX_VALUE; - } - if (value < 0) - return Long.fromNumber(-value, unsigned).neg(); - return Long.fromBits(value % TWO_PWR_32_DBL | 0, (value / TWO_PWR_32_DBL) | 0, unsigned); - } - static fromBigInt(value, unsigned) { - return Long.fromString(value.toString(), unsigned); - } - static fromString(str, unsigned, radix) { - if (str.length === 0) - throw new BSONError('empty string'); - if (str === 'NaN' || str === 'Infinity' || str === '+Infinity' || str === '-Infinity') - return Long.ZERO; - if (typeof unsigned === 'number') { - (radix = unsigned), (unsigned = false); - } - else { - unsigned = !!unsigned; - } - radix = radix || 10; - if (radix < 2 || 36 < radix) - throw new BSONError('radix'); - let p; - if ((p = str.indexOf('-')) > 0) - throw new BSONError('interior hyphen'); - else if (p === 0) { - return Long.fromString(str.substring(1), unsigned, radix).neg(); - } - const radixToPower = Long.fromNumber(Math.pow(radix, 8)); - let result = Long.ZERO; - for (let i = 0; i < str.length; i += 8) { - const size = Math.min(8, str.length - i), value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - const power = Long.fromNumber(Math.pow(radix, size)); - result = result.mul(power).add(Long.fromNumber(value)); - } - else { - result = result.mul(radixToPower); - result = result.add(Long.fromNumber(value)); - } - } - result.unsigned = unsigned; - return result; - } - static fromBytes(bytes, unsigned, le) { - return le ? Long.fromBytesLE(bytes, unsigned) : Long.fromBytesBE(bytes, unsigned); - } - static fromBytesLE(bytes, unsigned) { - return new Long(bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24), bytes[4] | (bytes[5] << 8) | (bytes[6] << 16) | (bytes[7] << 24), unsigned); - } - static fromBytesBE(bytes, unsigned) { - return new Long((bytes[4] << 24) | (bytes[5] << 16) | (bytes[6] << 8) | bytes[7], (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3], unsigned); - } - static isLong(value) { - return (value != null && - typeof value === 'object' && - '__isLong__' in value && - value.__isLong__ === true); - } - static fromValue(val, unsigned) { - if (typeof val === 'number') - return Long.fromNumber(val, unsigned); - if (typeof val === 'string') - return Long.fromString(val, unsigned); - return Long.fromBits(val.low, val.high, typeof unsigned === 'boolean' ? unsigned : val.unsigned); - } - add(addend) { - if (!Long.isLong(addend)) - addend = Long.fromValue(addend); - const a48 = this.high >>> 16; - const a32 = this.high & 0xffff; - const a16 = this.low >>> 16; - const a00 = this.low & 0xffff; - const b48 = addend.high >>> 16; - const b32 = addend.high & 0xffff; - const b16 = addend.low >>> 16; - const b00 = addend.low & 0xffff; - let c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xffff; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xffff; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xffff; - c48 += a48 + b48; - c48 &= 0xffff; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned); - } - and(other) { - if (!Long.isLong(other)) - other = Long.fromValue(other); - return Long.fromBits(this.low & other.low, this.high & other.high, this.unsigned); - } - compare(other) { - if (!Long.isLong(other)) - other = Long.fromValue(other); - if (this.eq(other)) - return 0; - const thisNeg = this.isNegative(), otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) - return -1; - if (!thisNeg && otherNeg) - return 1; - if (!this.unsigned) - return this.sub(other).isNegative() ? -1 : 1; - return other.high >>> 0 > this.high >>> 0 || - (other.high === this.high && other.low >>> 0 > this.low >>> 0) - ? -1 - : 1; - } - comp(other) { - return this.compare(other); - } - divide(divisor) { - if (!Long.isLong(divisor)) - divisor = Long.fromValue(divisor); - if (divisor.isZero()) - throw new BSONError('division by zero'); - if (wasm) { - if (!this.unsigned && - this.high === -0x80000000 && - divisor.low === -1 && - divisor.high === -1) { - return this; - } - const low = (this.unsigned ? wasm.div_u : wasm.div_s)(this.low, this.high, divisor.low, divisor.high); - return Long.fromBits(low, wasm.get_high(), this.unsigned); - } - if (this.isZero()) - return this.unsigned ? Long.UZERO : Long.ZERO; - let approx, rem, res; - if (!this.unsigned) { - if (this.eq(Long.MIN_VALUE)) { - if (divisor.eq(Long.ONE) || divisor.eq(Long.NEG_ONE)) - return Long.MIN_VALUE; - else if (divisor.eq(Long.MIN_VALUE)) - return Long.ONE; - else { - const halfThis = this.shr(1); - approx = halfThis.div(divisor).shl(1); - if (approx.eq(Long.ZERO)) { - return divisor.isNegative() ? Long.ONE : Long.NEG_ONE; - } - else { - rem = this.sub(divisor.mul(approx)); - res = approx.add(rem.div(divisor)); - return res; - } - } - } - else if (divisor.eq(Long.MIN_VALUE)) - return this.unsigned ? Long.UZERO : Long.ZERO; - if (this.isNegative()) { - if (divisor.isNegative()) - return this.neg().div(divisor.neg()); - return this.neg().div(divisor).neg(); - } - else if (divisor.isNegative()) - return this.div(divisor.neg()).neg(); - res = Long.ZERO; - } - else { - if (!divisor.unsigned) - divisor = divisor.toUnsigned(); - if (divisor.gt(this)) - return Long.UZERO; - if (divisor.gt(this.shru(1))) - return Long.UONE; - res = Long.UZERO; - } - rem = this; - while (rem.gte(divisor)) { - approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber())); - const log2 = Math.ceil(Math.log(approx) / Math.LN2); - const delta = log2 <= 48 ? 1 : Math.pow(2, log2 - 48); - let approxRes = Long.fromNumber(approx); - let approxRem = approxRes.mul(divisor); - while (approxRem.isNegative() || approxRem.gt(rem)) { - approx -= delta; - approxRes = Long.fromNumber(approx, this.unsigned); - approxRem = approxRes.mul(divisor); - } - if (approxRes.isZero()) - approxRes = Long.ONE; - res = res.add(approxRes); - rem = rem.sub(approxRem); - } - return res; - } - div(divisor) { - return this.divide(divisor); - } - equals(other) { - if (!Long.isLong(other)) - other = Long.fromValue(other); - if (this.unsigned !== other.unsigned && this.high >>> 31 === 1 && other.high >>> 31 === 1) - return false; - return this.high === other.high && this.low === other.low; - } - eq(other) { - return this.equals(other); - } - getHighBits() { - return this.high; - } - getHighBitsUnsigned() { - return this.high >>> 0; - } - getLowBits() { - return this.low; - } - getLowBitsUnsigned() { - return this.low >>> 0; - } - getNumBitsAbs() { - if (this.isNegative()) { - return this.eq(Long.MIN_VALUE) ? 64 : this.neg().getNumBitsAbs(); - } - const val = this.high !== 0 ? this.high : this.low; - let bit; - for (bit = 31; bit > 0; bit--) - if ((val & (1 << bit)) !== 0) - break; - return this.high !== 0 ? bit + 33 : bit + 1; - } - greaterThan(other) { - return this.comp(other) > 0; - } - gt(other) { - return this.greaterThan(other); - } - greaterThanOrEqual(other) { - return this.comp(other) >= 0; - } - gte(other) { - return this.greaterThanOrEqual(other); - } - ge(other) { - return this.greaterThanOrEqual(other); - } - isEven() { - return (this.low & 1) === 0; - } - isNegative() { - return !this.unsigned && this.high < 0; - } - isOdd() { - return (this.low & 1) === 1; - } - isPositive() { - return this.unsigned || this.high >= 0; - } - isZero() { - return this.high === 0 && this.low === 0; - } - lessThan(other) { - return this.comp(other) < 0; - } - lt(other) { - return this.lessThan(other); - } - lessThanOrEqual(other) { - return this.comp(other) <= 0; - } - lte(other) { - return this.lessThanOrEqual(other); - } - modulo(divisor) { - if (!Long.isLong(divisor)) - divisor = Long.fromValue(divisor); - if (wasm) { - const low = (this.unsigned ? wasm.rem_u : wasm.rem_s)(this.low, this.high, divisor.low, divisor.high); - return Long.fromBits(low, wasm.get_high(), this.unsigned); - } - return this.sub(this.div(divisor).mul(divisor)); - } - mod(divisor) { - return this.modulo(divisor); - } - rem(divisor) { - return this.modulo(divisor); - } - multiply(multiplier) { - if (this.isZero()) - return Long.ZERO; - if (!Long.isLong(multiplier)) - multiplier = Long.fromValue(multiplier); - if (wasm) { - const low = wasm.mul(this.low, this.high, multiplier.low, multiplier.high); - return Long.fromBits(low, wasm.get_high(), this.unsigned); - } - if (multiplier.isZero()) - return Long.ZERO; - if (this.eq(Long.MIN_VALUE)) - return multiplier.isOdd() ? Long.MIN_VALUE : Long.ZERO; - if (multiplier.eq(Long.MIN_VALUE)) - return this.isOdd() ? Long.MIN_VALUE : Long.ZERO; - if (this.isNegative()) { - if (multiplier.isNegative()) - return this.neg().mul(multiplier.neg()); - else - return this.neg().mul(multiplier).neg(); - } - else if (multiplier.isNegative()) - return this.mul(multiplier.neg()).neg(); - if (this.lt(Long.TWO_PWR_24) && multiplier.lt(Long.TWO_PWR_24)) - return Long.fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned); - const a48 = this.high >>> 16; - const a32 = this.high & 0xffff; - const a16 = this.low >>> 16; - const a00 = this.low & 0xffff; - const b48 = multiplier.high >>> 16; - const b32 = multiplier.high & 0xffff; - const b16 = multiplier.low >>> 16; - const b00 = multiplier.low & 0xffff; - let c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xffff; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xffff; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xffff; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xffff; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xffff; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xffff; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xffff; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned); - } - mul(multiplier) { - return this.multiply(multiplier); - } - negate() { - if (!this.unsigned && this.eq(Long.MIN_VALUE)) - return Long.MIN_VALUE; - return this.not().add(Long.ONE); - } - neg() { - return this.negate(); - } - not() { - return Long.fromBits(~this.low, ~this.high, this.unsigned); - } - notEquals(other) { - return !this.equals(other); - } - neq(other) { - return this.notEquals(other); - } - ne(other) { - return this.notEquals(other); - } - or(other) { - if (!Long.isLong(other)) - other = Long.fromValue(other); - return Long.fromBits(this.low | other.low, this.high | other.high, this.unsigned); - } - shiftLeft(numBits) { - if (Long.isLong(numBits)) - numBits = numBits.toInt(); - if ((numBits &= 63) === 0) - return this; - else if (numBits < 32) - return Long.fromBits(this.low << numBits, (this.high << numBits) | (this.low >>> (32 - numBits)), this.unsigned); - else - return Long.fromBits(0, this.low << (numBits - 32), this.unsigned); - } - shl(numBits) { - return this.shiftLeft(numBits); - } - shiftRight(numBits) { - if (Long.isLong(numBits)) - numBits = numBits.toInt(); - if ((numBits &= 63) === 0) - return this; - else if (numBits < 32) - return Long.fromBits((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >> numBits, this.unsigned); - else - return Long.fromBits(this.high >> (numBits - 32), this.high >= 0 ? 0 : -1, this.unsigned); - } - shr(numBits) { - return this.shiftRight(numBits); - } - shiftRightUnsigned(numBits) { - if (Long.isLong(numBits)) - numBits = numBits.toInt(); - numBits &= 63; - if (numBits === 0) - return this; - else { - const high = this.high; - if (numBits < 32) { - const low = this.low; - return Long.fromBits((low >>> numBits) | (high << (32 - numBits)), high >>> numBits, this.unsigned); - } - else if (numBits === 32) - return Long.fromBits(high, 0, this.unsigned); - else - return Long.fromBits(high >>> (numBits - 32), 0, this.unsigned); - } - } - shr_u(numBits) { - return this.shiftRightUnsigned(numBits); - } - shru(numBits) { - return this.shiftRightUnsigned(numBits); - } - subtract(subtrahend) { - if (!Long.isLong(subtrahend)) - subtrahend = Long.fromValue(subtrahend); - return this.add(subtrahend.neg()); - } - sub(subtrahend) { - return this.subtract(subtrahend); - } - toInt() { - return this.unsigned ? this.low >>> 0 : this.low; - } - toNumber() { - if (this.unsigned) - return (this.high >>> 0) * TWO_PWR_32_DBL + (this.low >>> 0); - return this.high * TWO_PWR_32_DBL + (this.low >>> 0); - } - toBigInt() { - return BigInt(this.toString()); - } - toBytes(le) { - return le ? this.toBytesLE() : this.toBytesBE(); - } - toBytesLE() { - const hi = this.high, lo = this.low; - return [ - lo & 0xff, - (lo >>> 8) & 0xff, - (lo >>> 16) & 0xff, - lo >>> 24, - hi & 0xff, - (hi >>> 8) & 0xff, - (hi >>> 16) & 0xff, - hi >>> 24 - ]; - } - toBytesBE() { - const hi = this.high, lo = this.low; - return [ - hi >>> 24, - (hi >>> 16) & 0xff, - (hi >>> 8) & 0xff, - hi & 0xff, - lo >>> 24, - (lo >>> 16) & 0xff, - (lo >>> 8) & 0xff, - lo & 0xff - ]; - } - toSigned() { - if (!this.unsigned) - return this; - return Long.fromBits(this.low, this.high, false); - } - toString(radix) { - radix = radix || 10; - if (radix < 2 || 36 < radix) - throw new BSONError('radix'); - if (this.isZero()) - return '0'; - if (this.isNegative()) { - if (this.eq(Long.MIN_VALUE)) { - const radixLong = Long.fromNumber(radix), div = this.div(radixLong), rem1 = div.mul(radixLong).sub(this); - return div.toString(radix) + rem1.toInt().toString(radix); - } - else - return '-' + this.neg().toString(radix); - } - const radixToPower = Long.fromNumber(Math.pow(radix, 6), this.unsigned); - let rem = this; - let result = ''; - while (true) { - const remDiv = rem.div(radixToPower); - const intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0; - let digits = intval.toString(radix); - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } - else { - while (digits.length < 6) - digits = '0' + digits; - result = '' + digits + result; - } - } - } - toUnsigned() { - if (this.unsigned) - return this; - return Long.fromBits(this.low, this.high, true); - } - xor(other) { - if (!Long.isLong(other)) - other = Long.fromValue(other); - return Long.fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned); - } - eqz() { - return this.isZero(); - } - le(other) { - return this.lessThanOrEqual(other); - } - toExtendedJSON(options) { - if (options && options.relaxed) - return this.toNumber(); - return { $numberLong: this.toString() }; - } - static fromExtendedJSON(doc, options) { - const { useBigInt64 = false, relaxed = true } = { ...options }; - if (doc.$numberLong.length > MAX_INT64_STRING_LENGTH) { - throw new BSONError('$numberLong string is too long'); - } - if (!DECIMAL_REG_EX.test(doc.$numberLong)) { - throw new BSONError(`$numberLong string "${doc.$numberLong}" is in an invalid format`); - } - if (useBigInt64) { - const bigIntResult = BigInt(doc.$numberLong); - return BigInt.asIntN(64, bigIntResult); - } - const longResult = Long.fromString(doc.$numberLong); - if (relaxed) { - return longResult.toNumber(); - } - return longResult; - } - [Symbol.for('nodejs.util.inspect.custom')]() { - return this.inspect(); - } - inspect() { - return `new Long("${this.toString()}"${this.unsigned ? ', true' : ''})`; - } -} -Long.TWO_PWR_24 = Long.fromInt(TWO_PWR_24_DBL); -Long.MAX_UNSIGNED_VALUE = Long.fromBits(0xffffffff | 0, 0xffffffff | 0, true); -Long.ZERO = Long.fromInt(0); -Long.UZERO = Long.fromInt(0, true); -Long.ONE = Long.fromInt(1); -Long.UONE = Long.fromInt(1, true); -Long.NEG_ONE = Long.fromInt(-1); -Long.MAX_VALUE = Long.fromBits(0xffffffff | 0, 0x7fffffff | 0, false); -Long.MIN_VALUE = Long.fromBits(0, 0x80000000 | 0, false); - -const PARSE_STRING_REGEXP = /^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/; -const PARSE_INF_REGEXP = /^(\+|-)?(Infinity|inf)$/i; -const PARSE_NAN_REGEXP = /^(\+|-)?NaN$/i; -const EXPONENT_MAX = 6111; -const EXPONENT_MIN = -6176; -const EXPONENT_BIAS = 6176; -const MAX_DIGITS = 34; -const NAN_BUFFER = ByteUtils.fromNumberArray([ - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -].reverse()); -const INF_NEGATIVE_BUFFER = ByteUtils.fromNumberArray([ - 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -].reverse()); -const INF_POSITIVE_BUFFER = ByteUtils.fromNumberArray([ - 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -].reverse()); -const EXPONENT_REGEX = /^([-+])?(\d+)?$/; -const COMBINATION_MASK = 0x1f; -const EXPONENT_MASK = 0x3fff; -const COMBINATION_INFINITY = 30; -const COMBINATION_NAN = 31; -function isDigit(value) { - return !isNaN(parseInt(value, 10)); -} -function divideu128(value) { - const DIVISOR = Long.fromNumber(1000 * 1000 * 1000); - let _rem = Long.fromNumber(0); - if (!value.parts[0] && !value.parts[1] && !value.parts[2] && !value.parts[3]) { - return { quotient: value, rem: _rem }; - } - for (let i = 0; i <= 3; i++) { - _rem = _rem.shiftLeft(32); - _rem = _rem.add(new Long(value.parts[i], 0)); - value.parts[i] = _rem.div(DIVISOR).low; - _rem = _rem.modulo(DIVISOR); - } - return { quotient: value, rem: _rem }; -} -function multiply64x2(left, right) { - if (!left && !right) { - return { high: Long.fromNumber(0), low: Long.fromNumber(0) }; - } - const leftHigh = left.shiftRightUnsigned(32); - const leftLow = new Long(left.getLowBits(), 0); - const rightHigh = right.shiftRightUnsigned(32); - const rightLow = new Long(right.getLowBits(), 0); - let productHigh = leftHigh.multiply(rightHigh); - let productMid = leftHigh.multiply(rightLow); - const productMid2 = leftLow.multiply(rightHigh); - let productLow = leftLow.multiply(rightLow); - productHigh = productHigh.add(productMid.shiftRightUnsigned(32)); - productMid = new Long(productMid.getLowBits(), 0) - .add(productMid2) - .add(productLow.shiftRightUnsigned(32)); - productHigh = productHigh.add(productMid.shiftRightUnsigned(32)); - productLow = productMid.shiftLeft(32).add(new Long(productLow.getLowBits(), 0)); - return { high: productHigh, low: productLow }; -} -function lessThan(left, right) { - const uhleft = left.high >>> 0; - const uhright = right.high >>> 0; - if (uhleft < uhright) { - return true; - } - else if (uhleft === uhright) { - const ulleft = left.low >>> 0; - const ulright = right.low >>> 0; - if (ulleft < ulright) - return true; - } - return false; -} -function invalidErr(string, message) { - throw new BSONError(`"${string}" is not a valid Decimal128 string - ${message}`); -} -class Decimal128 extends BSONValue { - get _bsontype() { - return 'Decimal128'; - } - constructor(bytes) { - super(); - if (typeof bytes === 'string') { - this.bytes = Decimal128.fromString(bytes).bytes; - } - else if (isUint8Array(bytes)) { - if (bytes.byteLength !== 16) { - throw new BSONError('Decimal128 must take a Buffer of 16 bytes'); - } - this.bytes = bytes; - } - else { - throw new BSONError('Decimal128 must take a Buffer or string'); - } - } - static fromString(representation) { - let isNegative = false; - let sawRadix = false; - let foundNonZero = false; - let significantDigits = 0; - let nDigitsRead = 0; - let nDigits = 0; - let radixPosition = 0; - let firstNonZero = 0; - const digits = [0]; - let nDigitsStored = 0; - let digitsInsert = 0; - let firstDigit = 0; - let lastDigit = 0; - let exponent = 0; - let i = 0; - let significandHigh = new Long(0, 0); - let significandLow = new Long(0, 0); - let biasedExponent = 0; - let index = 0; - if (representation.length >= 7000) { - throw new BSONError('' + representation + ' not a valid Decimal128 string'); - } - const stringMatch = representation.match(PARSE_STRING_REGEXP); - const infMatch = representation.match(PARSE_INF_REGEXP); - const nanMatch = representation.match(PARSE_NAN_REGEXP); - if ((!stringMatch && !infMatch && !nanMatch) || representation.length === 0) { - throw new BSONError('' + representation + ' not a valid Decimal128 string'); - } - if (stringMatch) { - const unsignedNumber = stringMatch[2]; - const e = stringMatch[4]; - const expSign = stringMatch[5]; - const expNumber = stringMatch[6]; - if (e && expNumber === undefined) - invalidErr(representation, 'missing exponent power'); - if (e && unsignedNumber === undefined) - invalidErr(representation, 'missing exponent base'); - if (e === undefined && (expSign || expNumber)) { - invalidErr(representation, 'missing e before exponent'); - } - } - if (representation[index] === '+' || representation[index] === '-') { - isNegative = representation[index++] === '-'; - } - if (!isDigit(representation[index]) && representation[index] !== '.') { - if (representation[index] === 'i' || representation[index] === 'I') { - return new Decimal128(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER); - } - else if (representation[index] === 'N') { - return new Decimal128(NAN_BUFFER); - } - } - while (isDigit(representation[index]) || representation[index] === '.') { - if (representation[index] === '.') { - if (sawRadix) - invalidErr(representation, 'contains multiple periods'); - sawRadix = true; - index = index + 1; - continue; - } - if (nDigitsStored < 34) { - if (representation[index] !== '0' || foundNonZero) { - if (!foundNonZero) { - firstNonZero = nDigitsRead; - } - foundNonZero = true; - digits[digitsInsert++] = parseInt(representation[index], 10); - nDigitsStored = nDigitsStored + 1; - } - } - if (foundNonZero) - nDigits = nDigits + 1; - if (sawRadix) - radixPosition = radixPosition + 1; - nDigitsRead = nDigitsRead + 1; - index = index + 1; - } - if (sawRadix && !nDigitsRead) - throw new BSONError('' + representation + ' not a valid Decimal128 string'); - if (representation[index] === 'e' || representation[index] === 'E') { - const match = representation.substr(++index).match(EXPONENT_REGEX); - if (!match || !match[2]) - return new Decimal128(NAN_BUFFER); - exponent = parseInt(match[0], 10); - index = index + match[0].length; - } - if (representation[index]) - return new Decimal128(NAN_BUFFER); - firstDigit = 0; - if (!nDigitsStored) { - firstDigit = 0; - lastDigit = 0; - digits[0] = 0; - nDigits = 1; - nDigitsStored = 1; - significantDigits = 0; - } - else { - lastDigit = nDigitsStored - 1; - significantDigits = nDigits; - if (significantDigits !== 1) { - while (digits[firstNonZero + significantDigits - 1] === 0) { - significantDigits = significantDigits - 1; - } - } - } - if (exponent <= radixPosition && radixPosition - exponent > 1 << 14) { - exponent = EXPONENT_MIN; - } - else { - exponent = exponent - radixPosition; - } - while (exponent > EXPONENT_MAX) { - lastDigit = lastDigit + 1; - if (lastDigit - firstDigit > MAX_DIGITS) { - const digitsString = digits.join(''); - if (digitsString.match(/^0+$/)) { - exponent = EXPONENT_MAX; - break; - } - invalidErr(representation, 'overflow'); - } - exponent = exponent - 1; - } - while (exponent < EXPONENT_MIN || nDigitsStored < nDigits) { - if (lastDigit === 0 && significantDigits < nDigitsStored) { - exponent = EXPONENT_MIN; - significantDigits = 0; - break; - } - if (nDigitsStored < nDigits) { - nDigits = nDigits - 1; - } - else { - lastDigit = lastDigit - 1; - } - if (exponent < EXPONENT_MAX) { - exponent = exponent + 1; - } - else { - const digitsString = digits.join(''); - if (digitsString.match(/^0+$/)) { - exponent = EXPONENT_MAX; - break; - } - invalidErr(representation, 'overflow'); - } - } - if (lastDigit - firstDigit + 1 < significantDigits) { - let endOfString = nDigitsRead; - if (sawRadix) { - firstNonZero = firstNonZero + 1; - endOfString = endOfString + 1; - } - if (isNegative) { - firstNonZero = firstNonZero + 1; - endOfString = endOfString + 1; - } - const roundDigit = parseInt(representation[firstNonZero + lastDigit + 1], 10); - let roundBit = 0; - if (roundDigit >= 5) { - roundBit = 1; - if (roundDigit === 5) { - roundBit = digits[lastDigit] % 2 === 1 ? 1 : 0; - for (i = firstNonZero + lastDigit + 2; i < endOfString; i++) { - if (parseInt(representation[i], 10)) { - roundBit = 1; - break; - } - } - } - } - if (roundBit) { - let dIdx = lastDigit; - for (; dIdx >= 0; dIdx--) { - if (++digits[dIdx] > 9) { - digits[dIdx] = 0; - if (dIdx === 0) { - if (exponent < EXPONENT_MAX) { - exponent = exponent + 1; - digits[dIdx] = 1; - } - else { - return new Decimal128(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER); - } - } - } - } - } - } - significandHigh = Long.fromNumber(0); - significandLow = Long.fromNumber(0); - if (significantDigits === 0) { - significandHigh = Long.fromNumber(0); - significandLow = Long.fromNumber(0); - } - else if (lastDigit - firstDigit < 17) { - let dIdx = firstDigit; - significandLow = Long.fromNumber(digits[dIdx++]); - significandHigh = new Long(0, 0); - for (; dIdx <= lastDigit; dIdx++) { - significandLow = significandLow.multiply(Long.fromNumber(10)); - significandLow = significandLow.add(Long.fromNumber(digits[dIdx])); - } - } - else { - let dIdx = firstDigit; - significandHigh = Long.fromNumber(digits[dIdx++]); - for (; dIdx <= lastDigit - 17; dIdx++) { - significandHigh = significandHigh.multiply(Long.fromNumber(10)); - significandHigh = significandHigh.add(Long.fromNumber(digits[dIdx])); - } - significandLow = Long.fromNumber(digits[dIdx++]); - for (; dIdx <= lastDigit; dIdx++) { - significandLow = significandLow.multiply(Long.fromNumber(10)); - significandLow = significandLow.add(Long.fromNumber(digits[dIdx])); - } - } - const significand = multiply64x2(significandHigh, Long.fromString('100000000000000000')); - significand.low = significand.low.add(significandLow); - if (lessThan(significand.low, significandLow)) { - significand.high = significand.high.add(Long.fromNumber(1)); - } - biasedExponent = exponent + EXPONENT_BIAS; - const dec = { low: Long.fromNumber(0), high: Long.fromNumber(0) }; - if (significand.high.shiftRightUnsigned(49).and(Long.fromNumber(1)).equals(Long.fromNumber(1))) { - dec.high = dec.high.or(Long.fromNumber(0x3).shiftLeft(61)); - dec.high = dec.high.or(Long.fromNumber(biasedExponent).and(Long.fromNumber(0x3fff).shiftLeft(47))); - dec.high = dec.high.or(significand.high.and(Long.fromNumber(0x7fffffffffff))); - } - else { - dec.high = dec.high.or(Long.fromNumber(biasedExponent & 0x3fff).shiftLeft(49)); - dec.high = dec.high.or(significand.high.and(Long.fromNumber(0x1ffffffffffff))); - } - dec.low = significand.low; - if (isNegative) { - dec.high = dec.high.or(Long.fromString('9223372036854775808')); - } - const buffer = ByteUtils.allocate(16); - index = 0; - buffer[index++] = dec.low.low & 0xff; - buffer[index++] = (dec.low.low >> 8) & 0xff; - buffer[index++] = (dec.low.low >> 16) & 0xff; - buffer[index++] = (dec.low.low >> 24) & 0xff; - buffer[index++] = dec.low.high & 0xff; - buffer[index++] = (dec.low.high >> 8) & 0xff; - buffer[index++] = (dec.low.high >> 16) & 0xff; - buffer[index++] = (dec.low.high >> 24) & 0xff; - buffer[index++] = dec.high.low & 0xff; - buffer[index++] = (dec.high.low >> 8) & 0xff; - buffer[index++] = (dec.high.low >> 16) & 0xff; - buffer[index++] = (dec.high.low >> 24) & 0xff; - buffer[index++] = dec.high.high & 0xff; - buffer[index++] = (dec.high.high >> 8) & 0xff; - buffer[index++] = (dec.high.high >> 16) & 0xff; - buffer[index++] = (dec.high.high >> 24) & 0xff; - return new Decimal128(buffer); - } - toString() { - let biased_exponent; - let significand_digits = 0; - const significand = new Array(36); - for (let i = 0; i < significand.length; i++) - significand[i] = 0; - let index = 0; - let is_zero = false; - let significand_msb; - let significand128 = { parts: [0, 0, 0, 0] }; - let j, k; - const string = []; - index = 0; - const buffer = this.bytes; - const low = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24); - const midl = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24); - const midh = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24); - const high = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24); - index = 0; - const dec = { - low: new Long(low, midl), - high: new Long(midh, high) - }; - if (dec.high.lessThan(Long.ZERO)) { - string.push('-'); - } - const combination = (high >> 26) & COMBINATION_MASK; - if (combination >> 3 === 3) { - if (combination === COMBINATION_INFINITY) { - return string.join('') + 'Infinity'; - } - else if (combination === COMBINATION_NAN) { - return 'NaN'; - } - else { - biased_exponent = (high >> 15) & EXPONENT_MASK; - significand_msb = 0x08 + ((high >> 14) & 0x01); - } - } - else { - significand_msb = (high >> 14) & 0x07; - biased_exponent = (high >> 17) & EXPONENT_MASK; - } - const exponent = biased_exponent - EXPONENT_BIAS; - significand128.parts[0] = (high & 0x3fff) + ((significand_msb & 0xf) << 14); - significand128.parts[1] = midh; - significand128.parts[2] = midl; - significand128.parts[3] = low; - if (significand128.parts[0] === 0 && - significand128.parts[1] === 0 && - significand128.parts[2] === 0 && - significand128.parts[3] === 0) { - is_zero = true; - } - else { - for (k = 3; k >= 0; k--) { - let least_digits = 0; - const result = divideu128(significand128); - significand128 = result.quotient; - least_digits = result.rem.low; - if (!least_digits) - continue; - for (j = 8; j >= 0; j--) { - significand[k * 9 + j] = least_digits % 10; - least_digits = Math.floor(least_digits / 10); - } - } - } - if (is_zero) { - significand_digits = 1; - significand[index] = 0; - } - else { - significand_digits = 36; - while (!significand[index]) { - significand_digits = significand_digits - 1; - index = index + 1; - } - } - const scientific_exponent = significand_digits - 1 + exponent; - if (scientific_exponent >= 34 || scientific_exponent <= -7 || exponent > 0) { - if (significand_digits > 34) { - string.push(`${0}`); - if (exponent > 0) - string.push(`E+${exponent}`); - else if (exponent < 0) - string.push(`E${exponent}`); - return string.join(''); - } - string.push(`${significand[index++]}`); - significand_digits = significand_digits - 1; - if (significand_digits) { - string.push('.'); - } - for (let i = 0; i < significand_digits; i++) { - string.push(`${significand[index++]}`); - } - string.push('E'); - if (scientific_exponent > 0) { - string.push(`+${scientific_exponent}`); - } - else { - string.push(`${scientific_exponent}`); - } - } - else { - if (exponent >= 0) { - for (let i = 0; i < significand_digits; i++) { - string.push(`${significand[index++]}`); - } - } - else { - let radix_position = significand_digits + exponent; - if (radix_position > 0) { - for (let i = 0; i < radix_position; i++) { - string.push(`${significand[index++]}`); - } - } - else { - string.push('0'); - } - string.push('.'); - while (radix_position++ < 0) { - string.push('0'); - } - for (let i = 0; i < significand_digits - Math.max(radix_position - 1, 0); i++) { - string.push(`${significand[index++]}`); - } - } - } - return string.join(''); - } - toJSON() { - return { $numberDecimal: this.toString() }; - } - toExtendedJSON() { - return { $numberDecimal: this.toString() }; - } - static fromExtendedJSON(doc) { - return Decimal128.fromString(doc.$numberDecimal); - } - [Symbol.for('nodejs.util.inspect.custom')]() { - return this.inspect(); - } - inspect() { - return `new Decimal128("${this.toString()}")`; - } -} - -class Double extends BSONValue { - get _bsontype() { - return 'Double'; - } - constructor(value) { - super(); - if (value instanceof Number) { - value = value.valueOf(); - } - this.value = +value; - } - valueOf() { - return this.value; - } - toJSON() { - return this.value; - } - toString(radix) { - return this.value.toString(radix); - } - toExtendedJSON(options) { - if (options && (options.legacy || (options.relaxed && isFinite(this.value)))) { - return this.value; - } - if (Object.is(Math.sign(this.value), -0)) { - return { $numberDouble: '-0.0' }; - } - return { - $numberDouble: Number.isInteger(this.value) ? this.value.toFixed(1) : this.value.toString() - }; - } - static fromExtendedJSON(doc, options) { - const doubleValue = parseFloat(doc.$numberDouble); - return options && options.relaxed ? doubleValue : new Double(doubleValue); - } - [Symbol.for('nodejs.util.inspect.custom')]() { - return this.inspect(); - } - inspect() { - const eJSON = this.toExtendedJSON(); - return `new Double(${eJSON.$numberDouble})`; - } -} - -class Int32 extends BSONValue { - get _bsontype() { - return 'Int32'; - } - constructor(value) { - super(); - if (value instanceof Number) { - value = value.valueOf(); - } - this.value = +value | 0; - } - valueOf() { - return this.value; - } - toString(radix) { - return this.value.toString(radix); - } - toJSON() { - return this.value; - } - toExtendedJSON(options) { - if (options && (options.relaxed || options.legacy)) - return this.value; - return { $numberInt: this.value.toString() }; - } - static fromExtendedJSON(doc, options) { - return options && options.relaxed ? parseInt(doc.$numberInt, 10) : new Int32(doc.$numberInt); - } - [Symbol.for('nodejs.util.inspect.custom')]() { - return this.inspect(); - } - inspect() { - return `new Int32(${this.valueOf()})`; - } -} - -class MaxKey extends BSONValue { - get _bsontype() { - return 'MaxKey'; - } - toExtendedJSON() { - return { $maxKey: 1 }; - } - static fromExtendedJSON() { - return new MaxKey(); - } - [Symbol.for('nodejs.util.inspect.custom')]() { - return this.inspect(); - } - inspect() { - return 'new MaxKey()'; - } -} - -class MinKey extends BSONValue { - get _bsontype() { - return 'MinKey'; - } - toExtendedJSON() { - return { $minKey: 1 }; - } - static fromExtendedJSON() { - return new MinKey(); - } - [Symbol.for('nodejs.util.inspect.custom')]() { - return this.inspect(); - } - inspect() { - return 'new MinKey()'; - } -} - -const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$'); -let PROCESS_UNIQUE = null; -const kId = Symbol('id'); -class ObjectId extends BSONValue { - get _bsontype() { - return 'ObjectId'; - } - constructor(inputId) { - super(); - let workingId; - if (typeof inputId === 'object' && inputId && 'id' in inputId) { - if (typeof inputId.id !== 'string' && !ArrayBuffer.isView(inputId.id)) { - throw new BSONError('Argument passed in must have an id that is of type string or Buffer'); - } - if ('toHexString' in inputId && typeof inputId.toHexString === 'function') { - workingId = ByteUtils.fromHex(inputId.toHexString()); - } - else { - workingId = inputId.id; - } - } - else { - workingId = inputId; - } - if (workingId == null || typeof workingId === 'number') { - this[kId] = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined); - } - else if (ArrayBuffer.isView(workingId) && workingId.byteLength === 12) { - this[kId] = ByteUtils.toLocalBufferType(workingId); - } - else if (typeof workingId === 'string') { - if (workingId.length === 12) { - const bytes = ByteUtils.fromUTF8(workingId); - if (bytes.byteLength === 12) { - this[kId] = bytes; - } - else { - throw new BSONError('Argument passed in must be a string of 12 bytes'); - } - } - else if (workingId.length === 24 && checkForHexRegExp.test(workingId)) { - this[kId] = ByteUtils.fromHex(workingId); - } - else { - throw new BSONError('Argument passed in must be a string of 12 bytes or a string of 24 hex characters or an integer'); - } - } - else { - throw new BSONError('Argument passed in does not match the accepted types'); - } - if (ObjectId.cacheHexString) { - this.__id = ByteUtils.toHex(this.id); - } - } - get id() { - return this[kId]; - } - set id(value) { - this[kId] = value; - if (ObjectId.cacheHexString) { - this.__id = ByteUtils.toHex(value); - } - } - toHexString() { - if (ObjectId.cacheHexString && this.__id) { - return this.__id; - } - const hexString = ByteUtils.toHex(this.id); - if (ObjectId.cacheHexString && !this.__id) { - this.__id = hexString; - } - return hexString; - } - static getInc() { - return (ObjectId.index = (ObjectId.index + 1) % 0xffffff); - } - static generate(time) { - if ('number' !== typeof time) { - time = Math.floor(Date.now() / 1000); - } - const inc = ObjectId.getInc(); - const buffer = ByteUtils.allocate(12); - BSONDataView.fromUint8Array(buffer).setUint32(0, time, false); - if (PROCESS_UNIQUE === null) { - PROCESS_UNIQUE = ByteUtils.randomBytes(5); - } - buffer[4] = PROCESS_UNIQUE[0]; - buffer[5] = PROCESS_UNIQUE[1]; - buffer[6] = PROCESS_UNIQUE[2]; - buffer[7] = PROCESS_UNIQUE[3]; - buffer[8] = PROCESS_UNIQUE[4]; - buffer[11] = inc & 0xff; - buffer[10] = (inc >> 8) & 0xff; - buffer[9] = (inc >> 16) & 0xff; - return buffer; - } - toString(encoding) { - if (encoding === 'base64') - return ByteUtils.toBase64(this.id); - if (encoding === 'hex') - return this.toHexString(); - return this.toHexString(); - } - toJSON() { - return this.toHexString(); - } - equals(otherId) { - if (otherId === undefined || otherId === null) { - return false; - } - if (otherId instanceof ObjectId) { - return this[kId][11] === otherId[kId][11] && ByteUtils.equals(this[kId], otherId[kId]); - } - if (typeof otherId === 'string' && - ObjectId.isValid(otherId) && - otherId.length === 12 && - isUint8Array(this.id)) { - return ByteUtils.equals(this.id, ByteUtils.fromISO88591(otherId)); - } - if (typeof otherId === 'string' && ObjectId.isValid(otherId) && otherId.length === 24) { - return otherId.toLowerCase() === this.toHexString(); - } - if (typeof otherId === 'string' && ObjectId.isValid(otherId) && otherId.length === 12) { - return ByteUtils.equals(ByteUtils.fromUTF8(otherId), this.id); - } - if (typeof otherId === 'object' && - 'toHexString' in otherId && - typeof otherId.toHexString === 'function') { - const otherIdString = otherId.toHexString(); - const thisIdString = this.toHexString().toLowerCase(); - return typeof otherIdString === 'string' && otherIdString.toLowerCase() === thisIdString; - } - return false; - } - getTimestamp() { - const timestamp = new Date(); - const time = BSONDataView.fromUint8Array(this.id).getUint32(0, false); - timestamp.setTime(Math.floor(time) * 1000); - return timestamp; - } - static createPk() { - return new ObjectId(); - } - static createFromTime(time) { - const buffer = ByteUtils.fromNumberArray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - BSONDataView.fromUint8Array(buffer).setUint32(0, time, false); - return new ObjectId(buffer); - } - static createFromHexString(hexString) { - if (typeof hexString === 'undefined' || (hexString != null && hexString.length !== 24)) { - throw new BSONError('Argument passed in must be a single String of 12 bytes or a string of 24 hex characters'); - } - return new ObjectId(ByteUtils.fromHex(hexString)); - } - static isValid(id) { - if (id == null) - return false; - try { - new ObjectId(id); - return true; - } - catch { - return false; - } - } - toExtendedJSON() { - if (this.toHexString) - return { $oid: this.toHexString() }; - return { $oid: this.toString('hex') }; - } - static fromExtendedJSON(doc) { - return new ObjectId(doc.$oid); - } - [Symbol.for('nodejs.util.inspect.custom')]() { - return this.inspect(); - } - inspect() { - return `new ObjectId("${this.toHexString()}")`; - } -} -ObjectId.index = Math.floor(Math.random() * 0xffffff); - -function internalCalculateObjectSize(object, serializeFunctions, ignoreUndefined) { - let totalLength = 4 + 1; - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - totalLength += calculateElement(i.toString(), object[i], serializeFunctions, true, ignoreUndefined); - } - } - else { - if (typeof object?.toBSON === 'function') { - object = object.toBSON(); - } - for (const key of Object.keys(object)) { - totalLength += calculateElement(key, object[key], serializeFunctions, false, ignoreUndefined); - } - } - return totalLength; -} -function calculateElement(name, value, serializeFunctions = false, isArray = false, ignoreUndefined = false) { - if (typeof value?.toBSON === 'function') { - value = value.toBSON(); - } - switch (typeof value) { - case 'string': - return 1 + ByteUtils.utf8ByteLength(name) + 1 + 4 + ByteUtils.utf8ByteLength(value) + 1; - case 'number': - if (Math.floor(value) === value && - value >= JS_INT_MIN && - value <= JS_INT_MAX) { - if (value >= BSON_INT32_MIN && value <= BSON_INT32_MAX) { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (4 + 1); - } - else { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1); - } - } - else { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1); - } - case 'undefined': - if (isArray || !ignoreUndefined) - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1; - return 0; - case 'boolean': - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (1 + 1); - case 'object': - if (value != null && - typeof value._bsontype === 'string' && - value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) { - throw new BSONVersionError(); - } - else if (value == null || value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1; - } - else if (value._bsontype === 'ObjectId') { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (12 + 1); - } - else if (value instanceof Date || isDate(value)) { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1); - } - else if (ArrayBuffer.isView(value) || - value instanceof ArrayBuffer || - isAnyArrayBuffer(value)) { - return ((name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (1 + 4 + 1) + value.byteLength); - } - else if (value._bsontype === 'Long' || - value._bsontype === 'Double' || - value._bsontype === 'Timestamp') { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1); - } - else if (value._bsontype === 'Decimal128') { - return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (16 + 1); - } - else if (value._bsontype === 'Code') { - if (value.scope != null && Object.keys(value.scope).length > 0) { - return ((name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + - 1 + - 4 + - 4 + - ByteUtils.utf8ByteLength(value.code.toString()) + - 1 + - internalCalculateObjectSize(value.scope, serializeFunctions, ignoreUndefined)); - } - else { - return ((name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + - 1 + - 4 + - ByteUtils.utf8ByteLength(value.code.toString()) + - 1); - } - } - else if (value._bsontype === 'Binary') { - const binary = value; - if (binary.sub_type === Binary.SUBTYPE_BYTE_ARRAY) { - return ((name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + - (binary.position + 1 + 4 + 1 + 4)); - } - else { - return ((name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (binary.position + 1 + 4 + 1)); - } - } - else if (value._bsontype === 'Symbol') { - return ((name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + - ByteUtils.utf8ByteLength(value.value) + - 4 + - 1 + - 1); - } - else if (value._bsontype === 'DBRef') { - const ordered_values = Object.assign({ - $ref: value.collection, - $id: value.oid - }, value.fields); - if (value.db != null) { - ordered_values['$db'] = value.db; - } - return ((name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + - 1 + - internalCalculateObjectSize(ordered_values, serializeFunctions, ignoreUndefined)); - } - else if (value instanceof RegExp || isRegExp(value)) { - return ((name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + - 1 + - ByteUtils.utf8ByteLength(value.source) + - 1 + - (value.global ? 1 : 0) + - (value.ignoreCase ? 1 : 0) + - (value.multiline ? 1 : 0) + - 1); - } - else if (value._bsontype === 'BSONRegExp') { - return ((name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + - 1 + - ByteUtils.utf8ByteLength(value.pattern) + - 1 + - ByteUtils.utf8ByteLength(value.options) + - 1); - } - else { - return ((name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + - internalCalculateObjectSize(value, serializeFunctions, ignoreUndefined) + - 1); - } - case 'function': - if (serializeFunctions) { - return ((name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + - 1 + - 4 + - ByteUtils.utf8ByteLength(value.toString()) + - 1); - } - } - return 0; -} - -function alphabetize(str) { - return str.split('').sort().join(''); -} -class BSONRegExp extends BSONValue { - get _bsontype() { - return 'BSONRegExp'; - } - constructor(pattern, options) { - super(); - this.pattern = pattern; - this.options = alphabetize(options ?? ''); - if (this.pattern.indexOf('\x00') !== -1) { - throw new BSONError(`BSON Regex patterns cannot contain null bytes, found: ${JSON.stringify(this.pattern)}`); - } - if (this.options.indexOf('\x00') !== -1) { - throw new BSONError(`BSON Regex options cannot contain null bytes, found: ${JSON.stringify(this.options)}`); - } - for (let i = 0; i < this.options.length; i++) { - if (!(this.options[i] === 'i' || - this.options[i] === 'm' || - this.options[i] === 'x' || - this.options[i] === 'l' || - this.options[i] === 's' || - this.options[i] === 'u')) { - throw new BSONError(`The regular expression option [${this.options[i]}] is not supported`); - } - } - } - static parseOptions(options) { - return options ? options.split('').sort().join('') : ''; - } - toExtendedJSON(options) { - options = options || {}; - if (options.legacy) { - return { $regex: this.pattern, $options: this.options }; - } - return { $regularExpression: { pattern: this.pattern, options: this.options } }; - } - static fromExtendedJSON(doc) { - if ('$regex' in doc) { - if (typeof doc.$regex !== 'string') { - if (doc.$regex._bsontype === 'BSONRegExp') { - return doc; - } - } - else { - return new BSONRegExp(doc.$regex, BSONRegExp.parseOptions(doc.$options)); - } - } - if ('$regularExpression' in doc) { - return new BSONRegExp(doc.$regularExpression.pattern, BSONRegExp.parseOptions(doc.$regularExpression.options)); - } - throw new BSONError(`Unexpected BSONRegExp EJSON object form: ${JSON.stringify(doc)}`); - } - [Symbol.for('nodejs.util.inspect.custom')]() { - return this.inspect(); - } - inspect() { - return `new BSONRegExp(${JSON.stringify(this.pattern)}, ${JSON.stringify(this.options)})`; - } -} - -class BSONSymbol extends BSONValue { - get _bsontype() { - return 'BSONSymbol'; - } - constructor(value) { - super(); - this.value = value; - } - valueOf() { - return this.value; - } - toString() { - return this.value; - } - inspect() { - return `new BSONSymbol("${this.value}")`; - } - toJSON() { - return this.value; - } - toExtendedJSON() { - return { $symbol: this.value }; - } - static fromExtendedJSON(doc) { - return new BSONSymbol(doc.$symbol); - } - [Symbol.for('nodejs.util.inspect.custom')]() { - return this.inspect(); - } -} - -const LongWithoutOverridesClass = Long; -class Timestamp extends LongWithoutOverridesClass { - get _bsontype() { - return 'Timestamp'; - } - constructor(low) { - if (low == null) { - super(0, 0, true); - } - else if (typeof low === 'bigint') { - super(low, true); - } - else if (Long.isLong(low)) { - super(low.low, low.high, true); - } - else if (typeof low === 'object' && 't' in low && 'i' in low) { - if (typeof low.t !== 'number' && (typeof low.t !== 'object' || low.t._bsontype !== 'Int32')) { - throw new BSONError('Timestamp constructed from { t, i } must provide t as a number'); - } - if (typeof low.i !== 'number' && (typeof low.i !== 'object' || low.i._bsontype !== 'Int32')) { - throw new BSONError('Timestamp constructed from { t, i } must provide i as a number'); - } - if (low.t < 0) { - throw new BSONError('Timestamp constructed from { t, i } must provide a positive t'); - } - if (low.i < 0) { - throw new BSONError('Timestamp constructed from { t, i } must provide a positive i'); - } - if (low.t > 4294967295) { - throw new BSONError('Timestamp constructed from { t, i } must provide t equal or less than uint32 max'); - } - if (low.i > 4294967295) { - throw new BSONError('Timestamp constructed from { t, i } must provide i equal or less than uint32 max'); - } - super(low.i.valueOf(), low.t.valueOf(), true); - } - else { - throw new BSONError('A Timestamp can only be constructed with: bigint, Long, or { t: number; i: number }'); - } - } - toJSON() { - return { - $timestamp: this.toString() - }; - } - static fromInt(value) { - return new Timestamp(Long.fromInt(value, true)); - } - static fromNumber(value) { - return new Timestamp(Long.fromNumber(value, true)); - } - static fromBits(lowBits, highBits) { - return new Timestamp({ i: lowBits, t: highBits }); - } - static fromString(str, optRadix) { - return new Timestamp(Long.fromString(str, true, optRadix)); - } - toExtendedJSON() { - return { $timestamp: { t: this.high >>> 0, i: this.low >>> 0 } }; - } - static fromExtendedJSON(doc) { - const i = Long.isLong(doc.$timestamp.i) - ? doc.$timestamp.i.getLowBitsUnsigned() - : doc.$timestamp.i; - const t = Long.isLong(doc.$timestamp.t) - ? doc.$timestamp.t.getLowBitsUnsigned() - : doc.$timestamp.t; - return new Timestamp({ t, i }); - } - [Symbol.for('nodejs.util.inspect.custom')]() { - return this.inspect(); - } - inspect() { - return `new Timestamp({ t: ${this.getHighBits()}, i: ${this.getLowBits()} })`; - } -} -Timestamp.MAX_VALUE = Long.MAX_UNSIGNED_VALUE; - -const FIRST_BIT = 0x80; -const FIRST_TWO_BITS = 0xc0; -const FIRST_THREE_BITS = 0xe0; -const FIRST_FOUR_BITS = 0xf0; -const FIRST_FIVE_BITS = 0xf8; -const TWO_BIT_CHAR = 0xc0; -const THREE_BIT_CHAR = 0xe0; -const FOUR_BIT_CHAR = 0xf0; -const CONTINUING_CHAR = 0x80; -function validateUtf8(bytes, start, end) { - let continuation = 0; - for (let i = start; i < end; i += 1) { - const byte = bytes[i]; - if (continuation) { - if ((byte & FIRST_TWO_BITS) !== CONTINUING_CHAR) { - return false; - } - continuation -= 1; - } - else if (byte & FIRST_BIT) { - if ((byte & FIRST_THREE_BITS) === TWO_BIT_CHAR) { - continuation = 1; - } - else if ((byte & FIRST_FOUR_BITS) === THREE_BIT_CHAR) { - continuation = 2; - } - else if ((byte & FIRST_FIVE_BITS) === FOUR_BIT_CHAR) { - continuation = 3; - } - else { - return false; - } - } - } - return !continuation; -} - -const JS_INT_MAX_LONG = Long.fromNumber(JS_INT_MAX); -const JS_INT_MIN_LONG = Long.fromNumber(JS_INT_MIN); -function internalDeserialize(buffer, options, isArray) { - options = options == null ? {} : options; - const index = options && options.index ? options.index : 0; - const size = buffer[index] | - (buffer[index + 1] << 8) | - (buffer[index + 2] << 16) | - (buffer[index + 3] << 24); - if (size < 5) { - throw new BSONError(`bson size must be >= 5, is ${size}`); - } - if (options.allowObjectSmallerThanBufferSize && buffer.length < size) { - throw new BSONError(`buffer length ${buffer.length} must be >= bson size ${size}`); - } - if (!options.allowObjectSmallerThanBufferSize && buffer.length !== size) { - throw new BSONError(`buffer length ${buffer.length} must === bson size ${size}`); - } - if (size + index > buffer.byteLength) { - throw new BSONError(`(bson size ${size} + options.index ${index} must be <= buffer length ${buffer.byteLength})`); - } - if (buffer[index + size - 1] !== 0) { - throw new BSONError("One object, sized correctly, with a spot for an EOO, but the EOO isn't 0x00"); - } - return deserializeObject(buffer, index, options, isArray); -} -const allowedDBRefKeys = /^\$ref$|^\$id$|^\$db$/; -function deserializeObject(buffer, index, options, isArray = false) { - const fieldsAsRaw = options['fieldsAsRaw'] == null ? null : options['fieldsAsRaw']; - const raw = options['raw'] == null ? false : options['raw']; - const bsonRegExp = typeof options['bsonRegExp'] === 'boolean' ? options['bsonRegExp'] : false; - const promoteBuffers = options.promoteBuffers ?? false; - const promoteLongs = options.promoteLongs ?? true; - const promoteValues = options.promoteValues ?? true; - const useBigInt64 = options.useBigInt64 ?? false; - if (useBigInt64 && !promoteValues) { - throw new BSONError('Must either request bigint or Long for int64 deserialization'); - } - if (useBigInt64 && !promoteLongs) { - throw new BSONError('Must either request bigint or Long for int64 deserialization'); - } - const validation = options.validation == null ? { utf8: true } : options.validation; - let globalUTFValidation = true; - let validationSetting; - const utf8KeysSet = new Set(); - const utf8ValidatedKeys = validation.utf8; - if (typeof utf8ValidatedKeys === 'boolean') { - validationSetting = utf8ValidatedKeys; - } - else { - globalUTFValidation = false; - const utf8ValidationValues = Object.keys(utf8ValidatedKeys).map(function (key) { - return utf8ValidatedKeys[key]; - }); - if (utf8ValidationValues.length === 0) { - throw new BSONError('UTF-8 validation setting cannot be empty'); - } - if (typeof utf8ValidationValues[0] !== 'boolean') { - throw new BSONError('Invalid UTF-8 validation option, must specify boolean values'); - } - validationSetting = utf8ValidationValues[0]; - if (!utf8ValidationValues.every(item => item === validationSetting)) { - throw new BSONError('Invalid UTF-8 validation option - keys must be all true or all false'); - } - } - if (!globalUTFValidation) { - for (const key of Object.keys(utf8ValidatedKeys)) { - utf8KeysSet.add(key); - } - } - const startIndex = index; - if (buffer.length < 5) - throw new BSONError('corrupt bson message < 5 bytes long'); - const size = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24); - if (size < 5 || size > buffer.length) - throw new BSONError('corrupt bson message'); - const object = isArray ? [] : {}; - let arrayIndex = 0; - const done = false; - let isPossibleDBRef = isArray ? false : null; - const dataview = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength); - while (!done) { - const elementType = buffer[index++]; - if (elementType === 0) - break; - let i = index; - while (buffer[i] !== 0x00 && i < buffer.length) { - i++; - } - if (i >= buffer.byteLength) - throw new BSONError('Bad BSON Document: illegal CString'); - const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer.subarray(index, i)); - let shouldValidateKey = true; - if (globalUTFValidation || utf8KeysSet.has(name)) { - shouldValidateKey = validationSetting; - } - else { - shouldValidateKey = !validationSetting; - } - if (isPossibleDBRef !== false && name[0] === '$') { - isPossibleDBRef = allowedDBRefKeys.test(name); - } - let value; - index = i + 1; - if (elementType === BSON_DATA_STRING) { - const stringSize = buffer[index++] | - (buffer[index++] << 8) | - (buffer[index++] << 16) | - (buffer[index++] << 24); - if (stringSize <= 0 || - stringSize > buffer.length - index || - buffer[index + stringSize - 1] !== 0) { - throw new BSONError('bad string length in bson'); - } - value = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey); - index = index + stringSize; - } - else if (elementType === BSON_DATA_OID) { - const oid = ByteUtils.allocate(12); - oid.set(buffer.subarray(index, index + 12)); - value = new ObjectId(oid); - index = index + 12; - } - else if (elementType === BSON_DATA_INT && promoteValues === false) { - value = new Int32(buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24)); - } - else if (elementType === BSON_DATA_INT) { - value = - buffer[index++] | - (buffer[index++] << 8) | - (buffer[index++] << 16) | - (buffer[index++] << 24); - } - else if (elementType === BSON_DATA_NUMBER && promoteValues === false) { - value = new Double(dataview.getFloat64(index, true)); - index = index + 8; - } - else if (elementType === BSON_DATA_NUMBER) { - value = dataview.getFloat64(index, true); - index = index + 8; - } - else if (elementType === BSON_DATA_DATE) { - const lowBits = buffer[index++] | - (buffer[index++] << 8) | - (buffer[index++] << 16) | - (buffer[index++] << 24); - const highBits = buffer[index++] | - (buffer[index++] << 8) | - (buffer[index++] << 16) | - (buffer[index++] << 24); - value = new Date(new Long(lowBits, highBits).toNumber()); - } - else if (elementType === BSON_DATA_BOOLEAN) { - if (buffer[index] !== 0 && buffer[index] !== 1) - throw new BSONError('illegal boolean type value'); - value = buffer[index++] === 1; - } - else if (elementType === BSON_DATA_OBJECT) { - const _index = index; - const objectSize = buffer[index] | - (buffer[index + 1] << 8) | - (buffer[index + 2] << 16) | - (buffer[index + 3] << 24); - if (objectSize <= 0 || objectSize > buffer.length - index) - throw new BSONError('bad embedded document length in bson'); - if (raw) { - value = buffer.slice(index, index + objectSize); - } - else { - let objectOptions = options; - if (!globalUTFValidation) { - objectOptions = { ...options, validation: { utf8: shouldValidateKey } }; - } - value = deserializeObject(buffer, _index, objectOptions, false); - } - index = index + objectSize; - } - else if (elementType === BSON_DATA_ARRAY) { - const _index = index; - const objectSize = buffer[index] | - (buffer[index + 1] << 8) | - (buffer[index + 2] << 16) | - (buffer[index + 3] << 24); - let arrayOptions = options; - const stopIndex = index + objectSize; - if (fieldsAsRaw && fieldsAsRaw[name]) { - arrayOptions = { ...options, raw: true }; - } - if (!globalUTFValidation) { - arrayOptions = { ...arrayOptions, validation: { utf8: shouldValidateKey } }; - } - value = deserializeObject(buffer, _index, arrayOptions, true); - index = index + objectSize; - if (buffer[index - 1] !== 0) - throw new BSONError('invalid array terminator byte'); - if (index !== stopIndex) - throw new BSONError('corrupted array bson'); - } - else if (elementType === BSON_DATA_UNDEFINED) { - value = undefined; - } - else if (elementType === BSON_DATA_NULL) { - value = null; - } - else if (elementType === BSON_DATA_LONG) { - const dataview = BSONDataView.fromUint8Array(buffer.subarray(index, index + 8)); - const lowBits = buffer[index++] | - (buffer[index++] << 8) | - (buffer[index++] << 16) | - (buffer[index++] << 24); - const highBits = buffer[index++] | - (buffer[index++] << 8) | - (buffer[index++] << 16) | - (buffer[index++] << 24); - const long = new Long(lowBits, highBits); - if (useBigInt64) { - value = dataview.getBigInt64(0, true); - } - else if (promoteLongs && promoteValues === true) { - value = - long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG) - ? long.toNumber() - : long; - } - else { - value = long; - } - } - else if (elementType === BSON_DATA_DECIMAL128) { - const bytes = ByteUtils.allocate(16); - bytes.set(buffer.subarray(index, index + 16), 0); - index = index + 16; - value = new Decimal128(bytes); - } - else if (elementType === BSON_DATA_BINARY) { - let binarySize = buffer[index++] | - (buffer[index++] << 8) | - (buffer[index++] << 16) | - (buffer[index++] << 24); - const totalBinarySize = binarySize; - const subType = buffer[index++]; - if (binarySize < 0) - throw new BSONError('Negative binary type element size found'); - if (binarySize > buffer.byteLength) - throw new BSONError('Binary type size larger than document size'); - if (buffer['slice'] != null) { - if (subType === Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = - buffer[index++] | - (buffer[index++] << 8) | - (buffer[index++] << 16) | - (buffer[index++] << 24); - if (binarySize < 0) - throw new BSONError('Negative binary type element size found for subtype 0x02'); - if (binarySize > totalBinarySize - 4) - throw new BSONError('Binary type with subtype 0x02 contains too long binary size'); - if (binarySize < totalBinarySize - 4) - throw new BSONError('Binary type with subtype 0x02 contains too short binary size'); - } - if (promoteBuffers && promoteValues) { - value = ByteUtils.toLocalBufferType(buffer.slice(index, index + binarySize)); - } - else { - value = new Binary(buffer.slice(index, index + binarySize), subType); - if (subType === BSON_BINARY_SUBTYPE_UUID_NEW) { - value = value.toUUID(); - } - } - } - else { - const _buffer = ByteUtils.allocate(binarySize); - if (subType === Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = - buffer[index++] | - (buffer[index++] << 8) | - (buffer[index++] << 16) | - (buffer[index++] << 24); - if (binarySize < 0) - throw new BSONError('Negative binary type element size found for subtype 0x02'); - if (binarySize > totalBinarySize - 4) - throw new BSONError('Binary type with subtype 0x02 contains too long binary size'); - if (binarySize < totalBinarySize - 4) - throw new BSONError('Binary type with subtype 0x02 contains too short binary size'); - } - for (i = 0; i < binarySize; i++) { - _buffer[i] = buffer[index + i]; - } - if (promoteBuffers && promoteValues) { - value = _buffer; - } - else if (subType === BSON_BINARY_SUBTYPE_UUID_NEW) { - value = new Binary(buffer.slice(index, index + binarySize), subType).toUUID(); - } - else { - value = new Binary(buffer.slice(index, index + binarySize), subType); - } - } - index = index + binarySize; - } - else if (elementType === BSON_DATA_REGEXP && bsonRegExp === false) { - i = index; - while (buffer[i] !== 0x00 && i < buffer.length) { - i++; - } - if (i >= buffer.length) - throw new BSONError('Bad BSON Document: illegal CString'); - const source = ByteUtils.toUTF8(buffer.subarray(index, i)); - index = i + 1; - i = index; - while (buffer[i] !== 0x00 && i < buffer.length) { - i++; - } - if (i >= buffer.length) - throw new BSONError('Bad BSON Document: illegal CString'); - const regExpOptions = ByteUtils.toUTF8(buffer.subarray(index, i)); - index = i + 1; - const optionsArray = new Array(regExpOptions.length); - for (i = 0; i < regExpOptions.length; i++) { - switch (regExpOptions[i]) { - case 'm': - optionsArray[i] = 'm'; - break; - case 's': - optionsArray[i] = 'g'; - break; - case 'i': - optionsArray[i] = 'i'; - break; - } - } - value = new RegExp(source, optionsArray.join('')); - } - else if (elementType === BSON_DATA_REGEXP && bsonRegExp === true) { - i = index; - while (buffer[i] !== 0x00 && i < buffer.length) { - i++; - } - if (i >= buffer.length) - throw new BSONError('Bad BSON Document: illegal CString'); - const source = ByteUtils.toUTF8(buffer.subarray(index, i)); - index = i + 1; - i = index; - while (buffer[i] !== 0x00 && i < buffer.length) { - i++; - } - if (i >= buffer.length) - throw new BSONError('Bad BSON Document: illegal CString'); - const regExpOptions = ByteUtils.toUTF8(buffer.subarray(index, i)); - index = i + 1; - value = new BSONRegExp(source, regExpOptions); - } - else if (elementType === BSON_DATA_SYMBOL) { - const stringSize = buffer[index++] | - (buffer[index++] << 8) | - (buffer[index++] << 16) | - (buffer[index++] << 24); - if (stringSize <= 0 || - stringSize > buffer.length - index || - buffer[index + stringSize - 1] !== 0) { - throw new BSONError('bad string length in bson'); - } - const symbol = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey); - value = promoteValues ? symbol : new BSONSymbol(symbol); - index = index + stringSize; - } - else if (elementType === BSON_DATA_TIMESTAMP) { - const i = buffer[index++] + - buffer[index++] * (1 << 8) + - buffer[index++] * (1 << 16) + - buffer[index++] * (1 << 24); - const t = buffer[index++] + - buffer[index++] * (1 << 8) + - buffer[index++] * (1 << 16) + - buffer[index++] * (1 << 24); - value = new Timestamp({ i, t }); - } - else if (elementType === BSON_DATA_MIN_KEY) { - value = new MinKey(); - } - else if (elementType === BSON_DATA_MAX_KEY) { - value = new MaxKey(); - } - else if (elementType === BSON_DATA_CODE) { - const stringSize = buffer[index++] | - (buffer[index++] << 8) | - (buffer[index++] << 16) | - (buffer[index++] << 24); - if (stringSize <= 0 || - stringSize > buffer.length - index || - buffer[index + stringSize - 1] !== 0) { - throw new BSONError('bad string length in bson'); - } - const functionString = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey); - value = new Code(functionString); - index = index + stringSize; - } - else if (elementType === BSON_DATA_CODE_W_SCOPE) { - const totalSize = buffer[index++] | - (buffer[index++] << 8) | - (buffer[index++] << 16) | - (buffer[index++] << 24); - if (totalSize < 4 + 4 + 4 + 1) { - throw new BSONError('code_w_scope total size shorter minimum expected length'); - } - const stringSize = buffer[index++] | - (buffer[index++] << 8) | - (buffer[index++] << 16) | - (buffer[index++] << 24); - if (stringSize <= 0 || - stringSize > buffer.length - index || - buffer[index + stringSize - 1] !== 0) { - throw new BSONError('bad string length in bson'); - } - const functionString = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey); - index = index + stringSize; - const _index = index; - const objectSize = buffer[index] | - (buffer[index + 1] << 8) | - (buffer[index + 2] << 16) | - (buffer[index + 3] << 24); - const scopeObject = deserializeObject(buffer, _index, options, false); - index = index + objectSize; - if (totalSize < 4 + 4 + objectSize + stringSize) { - throw new BSONError('code_w_scope total size is too short, truncating scope'); - } - if (totalSize > 4 + 4 + objectSize + stringSize) { - throw new BSONError('code_w_scope total size is too long, clips outer document'); - } - value = new Code(functionString, scopeObject); - } - else if (elementType === BSON_DATA_DBPOINTER) { - const stringSize = buffer[index++] | - (buffer[index++] << 8) | - (buffer[index++] << 16) | - (buffer[index++] << 24); - if (stringSize <= 0 || - stringSize > buffer.length - index || - buffer[index + stringSize - 1] !== 0) - throw new BSONError('bad string length in bson'); - if (validation != null && validation.utf8) { - if (!validateUtf8(buffer, index, index + stringSize - 1)) { - throw new BSONError('Invalid UTF-8 string in BSON document'); - } - } - const namespace = ByteUtils.toUTF8(buffer.subarray(index, index + stringSize - 1)); - index = index + stringSize; - const oidBuffer = ByteUtils.allocate(12); - oidBuffer.set(buffer.subarray(index, index + 12), 0); - const oid = new ObjectId(oidBuffer); - index = index + 12; - value = new DBRef(namespace, oid); - } - else { - throw new BSONError(`Detected unknown BSON type ${elementType.toString(16)} for fieldname "${name}"`); - } - if (name === '__proto__') { - Object.defineProperty(object, name, { - value, - writable: true, - enumerable: true, - configurable: true - }); - } - else { - object[name] = value; - } - } - if (size !== index - startIndex) { - if (isArray) - throw new BSONError('corrupt array bson'); - throw new BSONError('corrupt object bson'); - } - if (!isPossibleDBRef) - return object; - if (isDBRefLike(object)) { - const copy = Object.assign({}, object); - delete copy.$ref; - delete copy.$id; - delete copy.$db; - return new DBRef(object.$ref, object.$id, object.$db, copy); - } - return object; -} -function getValidatedString(buffer, start, end, shouldValidateUtf8) { - const value = ByteUtils.toUTF8(buffer.subarray(start, end)); - if (shouldValidateUtf8) { - for (let i = 0; i < value.length; i++) { - if (value.charCodeAt(i) === 0xfffd) { - if (!validateUtf8(buffer, start, end)) { - throw new BSONError('Invalid UTF-8 string in BSON document'); - } - break; - } - } - } - return value; -} - -const regexp = /\x00/; -const ignoreKeys = new Set(['$db', '$ref', '$id', '$clusterTime']); -function serializeString(buffer, key, value, index) { - buffer[index++] = BSON_DATA_STRING; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - const size = ByteUtils.encodeUTF8Into(buffer, value, index + 4); - buffer[index + 3] = ((size + 1) >> 24) & 0xff; - buffer[index + 2] = ((size + 1) >> 16) & 0xff; - buffer[index + 1] = ((size + 1) >> 8) & 0xff; - buffer[index] = (size + 1) & 0xff; - index = index + 4 + size; - buffer[index++] = 0; - return index; -} -const NUMBER_SPACE = new DataView(new ArrayBuffer(8), 0, 8); -const FOUR_BYTE_VIEW_ON_NUMBER = new Uint8Array(NUMBER_SPACE.buffer, 0, 4); -const EIGHT_BYTE_VIEW_ON_NUMBER = new Uint8Array(NUMBER_SPACE.buffer, 0, 8); -function serializeNumber(buffer, key, value, index) { - const isNegativeZero = Object.is(value, -0); - const type = !isNegativeZero && - Number.isSafeInteger(value) && - value <= BSON_INT32_MAX && - value >= BSON_INT32_MIN - ? BSON_DATA_INT - : BSON_DATA_NUMBER; - if (type === BSON_DATA_INT) { - NUMBER_SPACE.setInt32(0, value, true); - } - else { - NUMBER_SPACE.setFloat64(0, value, true); - } - const bytes = type === BSON_DATA_INT ? FOUR_BYTE_VIEW_ON_NUMBER : EIGHT_BYTE_VIEW_ON_NUMBER; - buffer[index++] = type; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0x00; - buffer.set(bytes, index); - index += bytes.byteLength; - return index; -} -function serializeBigInt(buffer, key, value, index) { - buffer[index++] = BSON_DATA_LONG; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index += numberOfWrittenBytes; - buffer[index++] = 0; - NUMBER_SPACE.setBigInt64(0, value, true); - buffer.set(EIGHT_BYTE_VIEW_ON_NUMBER, index); - index += EIGHT_BYTE_VIEW_ON_NUMBER.byteLength; - return index; -} -function serializeNull(buffer, key, _, index) { - buffer[index++] = BSON_DATA_NULL; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - return index; -} -function serializeBoolean(buffer, key, value, index) { - buffer[index++] = BSON_DATA_BOOLEAN; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - buffer[index++] = value ? 1 : 0; - return index; -} -function serializeDate(buffer, key, value, index) { - buffer[index++] = BSON_DATA_DATE; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - const dateInMilis = Long.fromNumber(value.getTime()); - const lowBits = dateInMilis.getLowBits(); - const highBits = dateInMilis.getHighBits(); - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; -} -function serializeRegExp(buffer, key, value, index) { - buffer[index++] = BSON_DATA_REGEXP; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - if (value.source && value.source.match(regexp) != null) { - throw new BSONError('value ' + value.source + ' must not contain null bytes'); - } - index = index + ByteUtils.encodeUTF8Into(buffer, value.source, index); - buffer[index++] = 0x00; - if (value.ignoreCase) - buffer[index++] = 0x69; - if (value.global) - buffer[index++] = 0x73; - if (value.multiline) - buffer[index++] = 0x6d; - buffer[index++] = 0x00; - return index; -} -function serializeBSONRegExp(buffer, key, value, index) { - buffer[index++] = BSON_DATA_REGEXP; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - if (value.pattern.match(regexp) != null) { - throw new BSONError('pattern ' + value.pattern + ' must not contain null bytes'); - } - index = index + ByteUtils.encodeUTF8Into(buffer, value.pattern, index); - buffer[index++] = 0x00; - const sortedOptions = value.options.split('').sort().join(''); - index = index + ByteUtils.encodeUTF8Into(buffer, sortedOptions, index); - buffer[index++] = 0x00; - return index; -} -function serializeMinMax(buffer, key, value, index) { - if (value === null) { - buffer[index++] = BSON_DATA_NULL; - } - else if (value._bsontype === 'MinKey') { - buffer[index++] = BSON_DATA_MIN_KEY; - } - else { - buffer[index++] = BSON_DATA_MAX_KEY; - } - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - return index; -} -function serializeObjectId(buffer, key, value, index) { - buffer[index++] = BSON_DATA_OID; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - if (isUint8Array(value.id)) { - buffer.set(value.id.subarray(0, 12), index); - } - else { - throw new BSONError('object [' + JSON.stringify(value) + '] is not a valid ObjectId'); - } - return index + 12; -} -function serializeBuffer(buffer, key, value, index) { - buffer[index++] = BSON_DATA_BINARY; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - const size = value.length; - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - buffer[index++] = BSON_BINARY_SUBTYPE_DEFAULT; - buffer.set(value, index); - index = index + size; - return index; -} -function serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path) { - if (path.has(value)) { - throw new BSONError('Cannot convert circular structure to BSON'); - } - path.add(value); - buffer[index++] = Array.isArray(value) ? BSON_DATA_ARRAY : BSON_DATA_OBJECT; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - const endIndex = serializeInto(buffer, value, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined, path); - path.delete(value); - return endIndex; -} -function serializeDecimal128(buffer, key, value, index) { - buffer[index++] = BSON_DATA_DECIMAL128; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - buffer.set(value.bytes.subarray(0, 16), index); - return index + 16; -} -function serializeLong(buffer, key, value, index) { - buffer[index++] = - value._bsontype === 'Long' ? BSON_DATA_LONG : BSON_DATA_TIMESTAMP; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - const lowBits = value.getLowBits(); - const highBits = value.getHighBits(); - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; -} -function serializeInt32(buffer, key, value, index) { - value = value.valueOf(); - buffer[index++] = BSON_DATA_INT; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - buffer[index++] = value & 0xff; - buffer[index++] = (value >> 8) & 0xff; - buffer[index++] = (value >> 16) & 0xff; - buffer[index++] = (value >> 24) & 0xff; - return index; -} -function serializeDouble(buffer, key, value, index) { - buffer[index++] = BSON_DATA_NUMBER; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - NUMBER_SPACE.setFloat64(0, value.value, true); - buffer.set(EIGHT_BYTE_VIEW_ON_NUMBER, index); - index = index + 8; - return index; -} -function serializeFunction(buffer, key, value, index) { - buffer[index++] = BSON_DATA_CODE; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - const functionString = value.toString(); - const size = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1; - buffer[index] = size & 0xff; - buffer[index + 1] = (size >> 8) & 0xff; - buffer[index + 2] = (size >> 16) & 0xff; - buffer[index + 3] = (size >> 24) & 0xff; - index = index + 4 + size - 1; - buffer[index++] = 0; - return index; -} -function serializeCode(buffer, key, value, index, checkKeys = false, depth = 0, serializeFunctions = false, ignoreUndefined = true, path) { - if (value.scope && typeof value.scope === 'object') { - buffer[index++] = BSON_DATA_CODE_W_SCOPE; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - let startIndex = index; - const functionString = value.code; - index = index + 4; - const codeSize = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1; - buffer[index] = codeSize & 0xff; - buffer[index + 1] = (codeSize >> 8) & 0xff; - buffer[index + 2] = (codeSize >> 16) & 0xff; - buffer[index + 3] = (codeSize >> 24) & 0xff; - buffer[index + 4 + codeSize - 1] = 0; - index = index + codeSize + 4; - const endIndex = serializeInto(buffer, value.scope, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined, path); - index = endIndex - 1; - const totalSize = endIndex - startIndex; - buffer[startIndex++] = totalSize & 0xff; - buffer[startIndex++] = (totalSize >> 8) & 0xff; - buffer[startIndex++] = (totalSize >> 16) & 0xff; - buffer[startIndex++] = (totalSize >> 24) & 0xff; - buffer[index++] = 0; - } - else { - buffer[index++] = BSON_DATA_CODE; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - const functionString = value.code.toString(); - const size = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1; - buffer[index] = size & 0xff; - buffer[index + 1] = (size >> 8) & 0xff; - buffer[index + 2] = (size >> 16) & 0xff; - buffer[index + 3] = (size >> 24) & 0xff; - index = index + 4 + size - 1; - buffer[index++] = 0; - } - return index; -} -function serializeBinary(buffer, key, value, index) { - buffer[index++] = BSON_DATA_BINARY; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - const data = value.buffer; - let size = value.position; - if (value.sub_type === Binary.SUBTYPE_BYTE_ARRAY) - size = size + 4; - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - buffer[index++] = value.sub_type; - if (value.sub_type === Binary.SUBTYPE_BYTE_ARRAY) { - size = size - 4; - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - } - buffer.set(data, index); - index = index + value.position; - return index; -} -function serializeSymbol(buffer, key, value, index) { - buffer[index++] = BSON_DATA_SYMBOL; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - const size = ByteUtils.encodeUTF8Into(buffer, value.value, index + 4) + 1; - buffer[index] = size & 0xff; - buffer[index + 1] = (size >> 8) & 0xff; - buffer[index + 2] = (size >> 16) & 0xff; - buffer[index + 3] = (size >> 24) & 0xff; - index = index + 4 + size - 1; - buffer[index++] = 0x00; - return index; -} -function serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path) { - buffer[index++] = BSON_DATA_OBJECT; - const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); - index = index + numberOfWrittenBytes; - buffer[index++] = 0; - let startIndex = index; - let output = { - $ref: value.collection || value.namespace, - $id: value.oid - }; - if (value.db != null) { - output.$db = value.db; - } - output = Object.assign(output, value.fields); - const endIndex = serializeInto(buffer, output, false, index, depth + 1, serializeFunctions, true, path); - const size = endIndex - startIndex; - buffer[startIndex++] = size & 0xff; - buffer[startIndex++] = (size >> 8) & 0xff; - buffer[startIndex++] = (size >> 16) & 0xff; - buffer[startIndex++] = (size >> 24) & 0xff; - return endIndex; -} -function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializeFunctions, ignoreUndefined, path) { - if (path == null) { - if (object == null) { - buffer[0] = 0x05; - buffer[1] = 0x00; - buffer[2] = 0x00; - buffer[3] = 0x00; - buffer[4] = 0x00; - return 5; - } - if (Array.isArray(object)) { - throw new BSONError('serialize does not support an array as the root input'); - } - if (typeof object !== 'object') { - throw new BSONError('serialize does not support non-object as the root input'); - } - else if ('_bsontype' in object && typeof object._bsontype === 'string') { - throw new BSONError(`BSON types cannot be serialized as a document`); - } - else if (isDate(object) || - isRegExp(object) || - isUint8Array(object) || - isAnyArrayBuffer(object)) { - throw new BSONError(`date, regexp, typedarray, and arraybuffer cannot be BSON documents`); - } - path = new Set(); - } - path.add(object); - let index = startingIndex + 4; - if (Array.isArray(object)) { - for (let i = 0; i < object.length; i++) { - const key = `${i}`; - let value = object[i]; - if (typeof value?.toBSON === 'function') { - value = value.toBSON(); - } - if (typeof value === 'string') { - index = serializeString(buffer, key, value, index); - } - else if (typeof value === 'number') { - index = serializeNumber(buffer, key, value, index); - } - else if (typeof value === 'bigint') { - index = serializeBigInt(buffer, key, value, index); - } - else if (typeof value === 'boolean') { - index = serializeBoolean(buffer, key, value, index); - } - else if (value instanceof Date || isDate(value)) { - index = serializeDate(buffer, key, value, index); - } - else if (value === undefined) { - index = serializeNull(buffer, key, value, index); - } - else if (value === null) { - index = serializeNull(buffer, key, value, index); - } - else if (isUint8Array(value)) { - index = serializeBuffer(buffer, key, value, index); - } - else if (value instanceof RegExp || isRegExp(value)) { - index = serializeRegExp(buffer, key, value, index); - } - else if (typeof value === 'object' && value._bsontype == null) { - index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path); - } - else if (typeof value === 'object' && - value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) { - throw new BSONVersionError(); - } - else if (value._bsontype === 'ObjectId') { - index = serializeObjectId(buffer, key, value, index); - } - else if (value._bsontype === 'Decimal128') { - index = serializeDecimal128(buffer, key, value, index); - } - else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') { - index = serializeLong(buffer, key, value, index); - } - else if (value._bsontype === 'Double') { - index = serializeDouble(buffer, key, value, index); - } - else if (typeof value === 'function' && serializeFunctions) { - index = serializeFunction(buffer, key, value, index); - } - else if (value._bsontype === 'Code') { - index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path); - } - else if (value._bsontype === 'Binary') { - index = serializeBinary(buffer, key, value, index); - } - else if (value._bsontype === 'BSONSymbol') { - index = serializeSymbol(buffer, key, value, index); - } - else if (value._bsontype === 'DBRef') { - index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path); - } - else if (value._bsontype === 'BSONRegExp') { - index = serializeBSONRegExp(buffer, key, value, index); - } - else if (value._bsontype === 'Int32') { - index = serializeInt32(buffer, key, value, index); - } - else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') { - index = serializeMinMax(buffer, key, value, index); - } - else if (typeof value._bsontype !== 'undefined') { - throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); - } - } - } - else if (object instanceof Map || isMap(object)) { - const iterator = object.entries(); - let done = false; - while (!done) { - const entry = iterator.next(); - done = !!entry.done; - if (done) - continue; - const key = entry.value[0]; - let value = entry.value[1]; - if (typeof value?.toBSON === 'function') { - value = value.toBSON(); - } - const type = typeof value; - if (typeof key === 'string' && !ignoreKeys.has(key)) { - if (key.match(regexp) != null) { - throw new BSONError('key ' + key + ' must not contain null bytes'); - } - if (checkKeys) { - if ('$' === key[0]) { - throw new BSONError('key ' + key + " must not start with '$'"); - } - else if (~key.indexOf('.')) { - throw new BSONError('key ' + key + " must not contain '.'"); - } - } - } - if (type === 'string') { - index = serializeString(buffer, key, value, index); - } - else if (type === 'number') { - index = serializeNumber(buffer, key, value, index); - } - else if (type === 'bigint') { - index = serializeBigInt(buffer, key, value, index); - } - else if (type === 'boolean') { - index = serializeBoolean(buffer, key, value, index); - } - else if (value instanceof Date || isDate(value)) { - index = serializeDate(buffer, key, value, index); - } - else if (value === null || (value === undefined && ignoreUndefined === false)) { - index = serializeNull(buffer, key, value, index); - } - else if (isUint8Array(value)) { - index = serializeBuffer(buffer, key, value, index); - } - else if (value instanceof RegExp || isRegExp(value)) { - index = serializeRegExp(buffer, key, value, index); - } - else if (type === 'object' && value._bsontype == null) { - index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path); - } - else if (typeof value === 'object' && - value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) { - throw new BSONVersionError(); - } - else if (value._bsontype === 'ObjectId') { - index = serializeObjectId(buffer, key, value, index); - } - else if (type === 'object' && value._bsontype === 'Decimal128') { - index = serializeDecimal128(buffer, key, value, index); - } - else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') { - index = serializeLong(buffer, key, value, index); - } - else if (value._bsontype === 'Double') { - index = serializeDouble(buffer, key, value, index); - } - else if (value._bsontype === 'Code') { - index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path); - } - else if (typeof value === 'function' && serializeFunctions) { - index = serializeFunction(buffer, key, value, index); - } - else if (value._bsontype === 'Binary') { - index = serializeBinary(buffer, key, value, index); - } - else if (value._bsontype === 'BSONSymbol') { - index = serializeSymbol(buffer, key, value, index); - } - else if (value._bsontype === 'DBRef') { - index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path); - } - else if (value._bsontype === 'BSONRegExp') { - index = serializeBSONRegExp(buffer, key, value, index); - } - else if (value._bsontype === 'Int32') { - index = serializeInt32(buffer, key, value, index); - } - else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') { - index = serializeMinMax(buffer, key, value, index); - } - else if (typeof value._bsontype !== 'undefined') { - throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); - } - } - } - else { - if (typeof object?.toBSON === 'function') { - object = object.toBSON(); - if (object != null && typeof object !== 'object') { - throw new BSONError('toBSON function did not return an object'); - } - } - for (const key of Object.keys(object)) { - let value = object[key]; - if (typeof value?.toBSON === 'function') { - value = value.toBSON(); - } - const type = typeof value; - if (typeof key === 'string' && !ignoreKeys.has(key)) { - if (key.match(regexp) != null) { - throw new BSONError('key ' + key + ' must not contain null bytes'); - } - if (checkKeys) { - if ('$' === key[0]) { - throw new BSONError('key ' + key + " must not start with '$'"); - } - else if (~key.indexOf('.')) { - throw new BSONError('key ' + key + " must not contain '.'"); - } - } - } - if (type === 'string') { - index = serializeString(buffer, key, value, index); - } - else if (type === 'number') { - index = serializeNumber(buffer, key, value, index); - } - else if (type === 'bigint') { - index = serializeBigInt(buffer, key, value, index); - } - else if (type === 'boolean') { - index = serializeBoolean(buffer, key, value, index); - } - else if (value instanceof Date || isDate(value)) { - index = serializeDate(buffer, key, value, index); - } - else if (value === undefined) { - if (ignoreUndefined === false) - index = serializeNull(buffer, key, value, index); - } - else if (value === null) { - index = serializeNull(buffer, key, value, index); - } - else if (isUint8Array(value)) { - index = serializeBuffer(buffer, key, value, index); - } - else if (value instanceof RegExp || isRegExp(value)) { - index = serializeRegExp(buffer, key, value, index); - } - else if (type === 'object' && value._bsontype == null) { - index = serializeObject(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path); - } - else if (typeof value === 'object' && - value[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) { - throw new BSONVersionError(); - } - else if (value._bsontype === 'ObjectId') { - index = serializeObjectId(buffer, key, value, index); - } - else if (type === 'object' && value._bsontype === 'Decimal128') { - index = serializeDecimal128(buffer, key, value, index); - } - else if (value._bsontype === 'Long' || value._bsontype === 'Timestamp') { - index = serializeLong(buffer, key, value, index); - } - else if (value._bsontype === 'Double') { - index = serializeDouble(buffer, key, value, index); - } - else if (value._bsontype === 'Code') { - index = serializeCode(buffer, key, value, index, checkKeys, depth, serializeFunctions, ignoreUndefined, path); - } - else if (typeof value === 'function' && serializeFunctions) { - index = serializeFunction(buffer, key, value, index); - } - else if (value._bsontype === 'Binary') { - index = serializeBinary(buffer, key, value, index); - } - else if (value._bsontype === 'BSONSymbol') { - index = serializeSymbol(buffer, key, value, index); - } - else if (value._bsontype === 'DBRef') { - index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path); - } - else if (value._bsontype === 'BSONRegExp') { - index = serializeBSONRegExp(buffer, key, value, index); - } - else if (value._bsontype === 'Int32') { - index = serializeInt32(buffer, key, value, index); - } - else if (value._bsontype === 'MinKey' || value._bsontype === 'MaxKey') { - index = serializeMinMax(buffer, key, value, index); - } - else if (typeof value._bsontype !== 'undefined') { - throw new BSONError(`Unrecognized or invalid _bsontype: ${String(value._bsontype)}`); - } - } - } - path.delete(object); - buffer[index++] = 0x00; - const size = index - startingIndex; - buffer[startingIndex++] = size & 0xff; - buffer[startingIndex++] = (size >> 8) & 0xff; - buffer[startingIndex++] = (size >> 16) & 0xff; - buffer[startingIndex++] = (size >> 24) & 0xff; - return index; -} - -function isBSONType(value) { - return (value != null && - typeof value === 'object' && - '_bsontype' in value && - typeof value._bsontype === 'string'); -} -const keysToCodecs = { - $oid: ObjectId, - $binary: Binary, - $uuid: Binary, - $symbol: BSONSymbol, - $numberInt: Int32, - $numberDecimal: Decimal128, - $numberDouble: Double, - $numberLong: Long, - $minKey: MinKey, - $maxKey: MaxKey, - $regex: BSONRegExp, - $regularExpression: BSONRegExp, - $timestamp: Timestamp -}; -function deserializeValue(value, options = {}) { - if (typeof value === 'number') { - const in32BitRange = value <= BSON_INT32_MAX && value >= BSON_INT32_MIN; - const in64BitRange = value <= BSON_INT64_MAX && value >= BSON_INT64_MIN; - if (options.relaxed || options.legacy) { - return value; - } - if (Number.isInteger(value) && !Object.is(value, -0)) { - if (in32BitRange) { - return new Int32(value); - } - if (in64BitRange) { - if (options.useBigInt64) { - return BigInt(value); - } - return Long.fromNumber(value); - } - } - return new Double(value); - } - if (value == null || typeof value !== 'object') - return value; - if (value.$undefined) - return null; - const keys = Object.keys(value).filter(k => k.startsWith('$') && value[k] != null); - for (let i = 0; i < keys.length; i++) { - const c = keysToCodecs[keys[i]]; - if (c) - return c.fromExtendedJSON(value, options); - } - if (value.$date != null) { - const d = value.$date; - const date = new Date(); - if (options.legacy) { - if (typeof d === 'number') - date.setTime(d); - else if (typeof d === 'string') - date.setTime(Date.parse(d)); - else if (typeof d === 'bigint') - date.setTime(Number(d)); - else - throw new BSONRuntimeError(`Unrecognized type for EJSON date: ${typeof d}`); - } - else { - if (typeof d === 'string') - date.setTime(Date.parse(d)); - else if (Long.isLong(d)) - date.setTime(d.toNumber()); - else if (typeof d === 'number' && options.relaxed) - date.setTime(d); - else if (typeof d === 'bigint') - date.setTime(Number(d)); - else - throw new BSONRuntimeError(`Unrecognized type for EJSON date: ${typeof d}`); - } - return date; - } - if (value.$code != null) { - const copy = Object.assign({}, value); - if (value.$scope) { - copy.$scope = deserializeValue(value.$scope); - } - return Code.fromExtendedJSON(value); - } - if (isDBRefLike(value) || value.$dbPointer) { - const v = value.$ref ? value : value.$dbPointer; - if (v instanceof DBRef) - return v; - const dollarKeys = Object.keys(v).filter(k => k.startsWith('$')); - let valid = true; - dollarKeys.forEach(k => { - if (['$ref', '$id', '$db'].indexOf(k) === -1) - valid = false; - }); - if (valid) - return DBRef.fromExtendedJSON(v); - } - return value; -} -function serializeArray(array, options) { - return array.map((v, index) => { - options.seenObjects.push({ propertyName: `index ${index}`, obj: null }); - try { - return serializeValue(v, options); - } - finally { - options.seenObjects.pop(); - } - }); -} -function getISOString(date) { - const isoStr = date.toISOString(); - return date.getUTCMilliseconds() !== 0 ? isoStr : isoStr.slice(0, -5) + 'Z'; -} -function serializeValue(value, options) { - if (value instanceof Map || isMap(value)) { - const obj = Object.create(null); - for (const [k, v] of value) { - if (typeof k !== 'string') { - throw new BSONError('Can only serialize maps with string keys'); - } - obj[k] = v; - } - return serializeValue(obj, options); - } - if ((typeof value === 'object' || typeof value === 'function') && value !== null) { - const index = options.seenObjects.findIndex(entry => entry.obj === value); - if (index !== -1) { - const props = options.seenObjects.map(entry => entry.propertyName); - const leadingPart = props - .slice(0, index) - .map(prop => `${prop} -> `) - .join(''); - const alreadySeen = props[index]; - const circularPart = ' -> ' + - props - .slice(index + 1, props.length - 1) - .map(prop => `${prop} -> `) - .join(''); - const current = props[props.length - 1]; - const leadingSpace = ' '.repeat(leadingPart.length + alreadySeen.length / 2); - const dashes = '-'.repeat(circularPart.length + (alreadySeen.length + current.length) / 2 - 1); - throw new BSONError('Converting circular structure to EJSON:\n' + - ` ${leadingPart}${alreadySeen}${circularPart}${current}\n` + - ` ${leadingSpace}\\${dashes}/`); - } - options.seenObjects[options.seenObjects.length - 1].obj = value; - } - if (Array.isArray(value)) - return serializeArray(value, options); - if (value === undefined) - return null; - if (value instanceof Date || isDate(value)) { - const dateNum = value.getTime(), inRange = dateNum > -1 && dateNum < 253402318800000; - if (options.legacy) { - return options.relaxed && inRange - ? { $date: value.getTime() } - : { $date: getISOString(value) }; - } - return options.relaxed && inRange - ? { $date: getISOString(value) } - : { $date: { $numberLong: value.getTime().toString() } }; - } - if (typeof value === 'number' && (!options.relaxed || !isFinite(value))) { - if (Number.isInteger(value) && !Object.is(value, -0)) { - if (value >= BSON_INT32_MIN && value <= BSON_INT32_MAX) { - return { $numberInt: value.toString() }; - } - if (value >= BSON_INT64_MIN && value <= BSON_INT64_MAX) { - return { $numberLong: value.toString() }; - } - } - return { $numberDouble: Object.is(value, -0) ? '-0.0' : value.toString() }; - } - if (typeof value === 'bigint') { - if (!options.relaxed) { - return { $numberLong: BigInt.asIntN(64, value).toString() }; - } - return Number(BigInt.asIntN(64, value)); - } - if (value instanceof RegExp || isRegExp(value)) { - let flags = value.flags; - if (flags === undefined) { - const match = value.toString().match(/[gimuy]*$/); - if (match) { - flags = match[0]; - } - } - const rx = new BSONRegExp(value.source, flags); - return rx.toExtendedJSON(options); - } - if (value != null && typeof value === 'object') - return serializeDocument(value, options); - return value; -} -const BSON_TYPE_MAPPINGS = { - Binary: (o) => new Binary(o.value(), o.sub_type), - Code: (o) => new Code(o.code, o.scope), - DBRef: (o) => new DBRef(o.collection || o.namespace, o.oid, o.db, o.fields), - Decimal128: (o) => new Decimal128(o.bytes), - Double: (o) => new Double(o.value), - Int32: (o) => new Int32(o.value), - Long: (o) => Long.fromBits(o.low != null ? o.low : o.low_, o.low != null ? o.high : o.high_, o.low != null ? o.unsigned : o.unsigned_), - MaxKey: () => new MaxKey(), - MinKey: () => new MinKey(), - ObjectId: (o) => new ObjectId(o), - BSONRegExp: (o) => new BSONRegExp(o.pattern, o.options), - BSONSymbol: (o) => new BSONSymbol(o.value), - Timestamp: (o) => Timestamp.fromBits(o.low, o.high) -}; -function serializeDocument(doc, options) { - if (doc == null || typeof doc !== 'object') - throw new BSONError('not an object instance'); - const bsontype = doc._bsontype; - if (typeof bsontype === 'undefined') { - const _doc = {}; - for (const name of Object.keys(doc)) { - options.seenObjects.push({ propertyName: name, obj: null }); - try { - const value = serializeValue(doc[name], options); - if (name === '__proto__') { - Object.defineProperty(_doc, name, { - value, - writable: true, - enumerable: true, - configurable: true - }); - } - else { - _doc[name] = value; - } - } - finally { - options.seenObjects.pop(); - } - } - return _doc; - } - else if (doc != null && - typeof doc === 'object' && - typeof doc._bsontype === 'string' && - doc[Symbol.for('@@mdb.bson.version')] !== BSON_MAJOR_VERSION) { - throw new BSONVersionError(); - } - else if (isBSONType(doc)) { - let outDoc = doc; - if (typeof outDoc.toExtendedJSON !== 'function') { - const mapper = BSON_TYPE_MAPPINGS[doc._bsontype]; - if (!mapper) { - throw new BSONError('Unrecognized or invalid _bsontype: ' + doc._bsontype); - } - outDoc = mapper(outDoc); - } - if (bsontype === 'Code' && outDoc.scope) { - outDoc = new Code(outDoc.code, serializeValue(outDoc.scope, options)); - } - else if (bsontype === 'DBRef' && outDoc.oid) { - outDoc = new DBRef(serializeValue(outDoc.collection, options), serializeValue(outDoc.oid, options), serializeValue(outDoc.db, options), serializeValue(outDoc.fields, options)); - } - return outDoc.toExtendedJSON(options); - } - else { - throw new BSONError('_bsontype must be a string, but was: ' + typeof bsontype); - } -} -function parse(text, options) { - const ejsonOptions = { - useBigInt64: options?.useBigInt64 ?? false, - relaxed: options?.relaxed ?? true, - legacy: options?.legacy ?? false - }; - return JSON.parse(text, (key, value) => { - if (key.indexOf('\x00') !== -1) { - throw new BSONError(`BSON Document field names cannot contain null bytes, found: ${JSON.stringify(key)}`); - } - return deserializeValue(value, ejsonOptions); - }); -} -function stringify(value, replacer, space, options) { - if (space != null && typeof space === 'object') { - options = space; - space = 0; - } - if (replacer != null && typeof replacer === 'object' && !Array.isArray(replacer)) { - options = replacer; - replacer = undefined; - space = 0; - } - const serializeOptions = Object.assign({ relaxed: true, legacy: false }, options, { - seenObjects: [{ propertyName: '(root)', obj: null }] - }); - const doc = serializeValue(value, serializeOptions); - return JSON.stringify(doc, replacer, space); -} -function EJSONserialize(value, options) { - options = options || {}; - return JSON.parse(stringify(value, options)); -} -function EJSONdeserialize(ejson, options) { - options = options || {}; - return parse(JSON.stringify(ejson), options); -} -const EJSON = Object.create(null); -EJSON.parse = parse; -EJSON.stringify = stringify; -EJSON.serialize = EJSONserialize; -EJSON.deserialize = EJSONdeserialize; -Object.freeze(EJSON); - -const MAXSIZE = 1024 * 1024 * 17; -let buffer = ByteUtils.allocate(MAXSIZE); -function setInternalBufferSize(size) { - if (buffer.length < size) { - buffer = ByteUtils.allocate(size); - } -} -function serialize(object, options = {}) { - const checkKeys = typeof options.checkKeys === 'boolean' ? options.checkKeys : false; - const serializeFunctions = typeof options.serializeFunctions === 'boolean' ? options.serializeFunctions : false; - const ignoreUndefined = typeof options.ignoreUndefined === 'boolean' ? options.ignoreUndefined : true; - const minInternalBufferSize = typeof options.minInternalBufferSize === 'number' ? options.minInternalBufferSize : MAXSIZE; - if (buffer.length < minInternalBufferSize) { - buffer = ByteUtils.allocate(minInternalBufferSize); - } - const serializationIndex = serializeInto(buffer, object, checkKeys, 0, 0, serializeFunctions, ignoreUndefined, null); - const finishedBuffer = ByteUtils.allocate(serializationIndex); - finishedBuffer.set(buffer.subarray(0, serializationIndex), 0); - return finishedBuffer; -} -function serializeWithBufferAndIndex(object, finalBuffer, options = {}) { - const checkKeys = typeof options.checkKeys === 'boolean' ? options.checkKeys : false; - const serializeFunctions = typeof options.serializeFunctions === 'boolean' ? options.serializeFunctions : false; - const ignoreUndefined = typeof options.ignoreUndefined === 'boolean' ? options.ignoreUndefined : true; - const startIndex = typeof options.index === 'number' ? options.index : 0; - const serializationIndex = serializeInto(buffer, object, checkKeys, 0, 0, serializeFunctions, ignoreUndefined, null); - finalBuffer.set(buffer.subarray(0, serializationIndex), startIndex); - return startIndex + serializationIndex - 1; -} -function deserialize(buffer, options = {}) { - return internalDeserialize(ByteUtils.toLocalBufferType(buffer), options); -} -function calculateObjectSize(object, options = {}) { - options = options || {}; - const serializeFunctions = typeof options.serializeFunctions === 'boolean' ? options.serializeFunctions : false; - const ignoreUndefined = typeof options.ignoreUndefined === 'boolean' ? options.ignoreUndefined : true; - return internalCalculateObjectSize(object, serializeFunctions, ignoreUndefined); -} -function deserializeStream(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - const internalOptions = Object.assign({ allowObjectSmallerThanBufferSize: true, index: 0 }, options); - const bufferData = ByteUtils.toLocalBufferType(data); - let index = startIndex; - for (let i = 0; i < numberOfDocuments; i++) { - const size = bufferData[index] | - (bufferData[index + 1] << 8) | - (bufferData[index + 2] << 16) | - (bufferData[index + 3] << 24); - internalOptions.index = index; - documents[docStartIndex + i] = internalDeserialize(bufferData, internalOptions); - index = index + size; - } - return index; -} - -var bson = /*#__PURE__*/Object.freeze({ - __proto__: null, - Code: Code, - BSONSymbol: BSONSymbol, - DBRef: DBRef, - Binary: Binary, - ObjectId: ObjectId, - UUID: UUID, - Long: Long, - Timestamp: Timestamp, - Double: Double, - Int32: Int32, - MinKey: MinKey, - MaxKey: MaxKey, - BSONRegExp: BSONRegExp, - Decimal128: Decimal128, - setInternalBufferSize: setInternalBufferSize, - serialize: serialize, - serializeWithBufferAndIndex: serializeWithBufferAndIndex, - deserialize: deserialize, - calculateObjectSize: calculateObjectSize, - deserializeStream: deserializeStream, - BSONValue: BSONValue, - BSONError: BSONError, - BSONVersionError: BSONVersionError, - BSONRuntimeError: BSONRuntimeError, - BSONType: BSONType, - EJSON: EJSON -}); - -exports.BSON = bson; -exports.BSONError = BSONError; -exports.BSONRegExp = BSONRegExp; -exports.BSONRuntimeError = BSONRuntimeError; -exports.BSONSymbol = BSONSymbol; -exports.BSONType = BSONType; -exports.BSONValue = BSONValue; -exports.BSONVersionError = BSONVersionError; -exports.Binary = Binary; -exports.Code = Code; -exports.DBRef = DBRef; -exports.Decimal128 = Decimal128; -exports.Double = Double; -exports.EJSON = EJSON; -exports.Int32 = Int32; -exports.Long = Long; -exports.MaxKey = MaxKey; -exports.MinKey = MinKey; -exports.ObjectId = ObjectId; -exports.Timestamp = Timestamp; -exports.UUID = UUID; -exports.calculateObjectSize = calculateObjectSize; -exports.deserialize = deserialize; -exports.deserializeStream = deserializeStream; -exports.serialize = serialize; -exports.serializeWithBufferAndIndex = serializeWithBufferAndIndex; -exports.setInternalBufferSize = setInternalBufferSize; -//# sourceMappingURL=bson.cjs.map diff --git a/src/extras/struct/genTimestamps.ts b/src/extras/struct/genTimestamps.ts deleted file mode 100644 index 38c74670..00000000 --- a/src/extras/struct/genTimestamps.ts +++ /dev/null @@ -1,110 +0,0 @@ - -//thanks gpt -export type TimeUnit = - | 'second' - | 'minute' - | 'hour' - | 'day' - | 'week' - | 'month' - | 'year' - | 'decade' - | 'century' - | 'millennium' - | 'microsecond' - | 'nanosecond'; - -type Plural = `${T}s`; - -export type TimeSpecifier = `now` | `last ${string} ${Plural}` | `last ${TimeUnit}`; - -export let defaultSpecifiers = [ - 'now', - 'minute', - '5 minutes', - '30 minutes', - 'hour', - '6 hours', - '12 hours', - 'day', - '3 days', - 'week', - '2 weeks', - 'month', - '6 months', - 'year', - '5 years', - 'decade', -] as ('now'|TimeUnit)[]; - -export function genTimeSpecifiers( - specifiers = defaultSpecifiers as ('now'|TimeUnit)[] -) { - let result = ['now']; - specifiers.forEach((s) => { - if(s !== 'now') - result.push(`last ${s}`); - else result.push(s); - }); - - return result; -} - -export function genTimestampFromString(specifier: TimeSpecifier): number { - const now = new Date(); - - if(specifier === 'now') {} - else if (specifier === 'last minute') { - now.setMinutes(now.getMinutes() - 1); - } else if (specifier === 'last hour') { - now.setHours(now.getHours() - 1); - } else if (specifier === 'last day') { - now.setDate(now.getDate() - 1); - } else if (specifier === 'last week') { - now.setDate(now.getDate() - 7); - } else if (specifier === 'last month') { - now.setMonth(now.getMonth() - 1); - } else if (specifier === 'last year') { - now.setFullYear(now.getFullYear() - 1); - } else if (specifier === 'last decade') { - now.setFullYear(now.getFullYear() - 1 * 10); - } else if (specifier === 'last century') { - now.setFullYear(now.getFullYear() - 1 * 100); - } else if (specifier === 'last millennium') { - now.setFullYear(now.getFullYear() - 1 * 1000); - } else if (specifier === 'last microsecond') { - now.setMilliseconds(now.getMilliseconds() - 1); - } else if (specifier === 'last nanosecond') { - now.setMilliseconds(now.getMilliseconds() - 1 * 0.001); - } else if (specifier.startsWith('last')) { - const [, count, unit] = specifier.match(/last (\d+) (\w+)/) || []; - if (count && unit) { - const num = parseInt(count, 10); - if (unit.includes('minute')) { - now.setMinutes(now.getMinutes() - num); - } else if (unit.includes('hour')) { - now.setHours(now.getHours() - num); - } else if (unit.includes('day')) { - now.setDate(now.getDate() - num); - } else if (unit.includes('week')) { - now.setDate(now.getDate() - num * 7); - } else if (unit.includes('month')) { - now.setMonth(now.getMonth() - num); - } else if (unit.includes('year')) { - now.setFullYear(now.getFullYear() - num); - } else if (unit.includes('decade')) { - now.setFullYear(now.getFullYear() - num * 10); - } else if (unit.includes('century')) { - now.setFullYear(now.getFullYear() - num * 100); - } else if (unit.includes('millennium')) { - now.setFullYear(now.getFullYear() - num * 1000); - } else if (unit.includes('microsecond')) { - now.setMilliseconds(now.getMilliseconds() - num); - } else if (unit.includes('nanosecond')) { - now.setMilliseconds(now.getMilliseconds() - num * 0.001); - } - } - } - - return now.getTime(); - } \ No newline at end of file diff --git a/src/extras/tinybuild.gpu.config.js b/src/extras/tinybuild.gpu.config.js deleted file mode 100644 index fd0a0e63..00000000 --- a/src/extras/tinybuild.gpu.config.js +++ /dev/null @@ -1,40 +0,0 @@ - -const config = { - bundler: { //esbuild settings, set false to skip build step or add bundle:true to config object to only bundle (alt methods) - entryPoints: [ //entry point file(s). These can include .js, .mjs, .ts, .jsx, .tsx, or other javascript files. Make sure your entry point is a ts file if you want to generate types - "index.gpu.services.ts" - ], - outfile: "dist/index.gpu.services", //exit point file, will append .js as well as indicators like .esm.js, .node.js for other build flags - //outdir:[] //exit point files, define for multiple bundle files - bundleBrowser: true, //create plain js build? Can include globals and init scripts - bundleESM: true, //create esm module js files - bundleTypes: true, //create .d.ts files, the entry point must be a typescript file! (ts, tsx, etc) - bundleNode: false, //create node platform plain js build, specify platform:'node' to do the rest of the files - bundleHTML: false, //wrap the first entry point file as a plain js script in a boilerplate html file, frontend scripts can be run standalone like a .exe! Server serves this as start page if set to true. - //minify: false, - minifyWhitespace:true, - sourcemap: false - //platform:'node' //for bundling the node.ts file - //globalThis:null //'mymodule' - //globals:{'index.js':['Graph']} - //init:{'index.js':function(bundle) { console.log('prepackaged bundle script!', bundle); }} - }, - server: false//{ //node server settings, set false to skip server step or add serve:true to config object to only serve (alt methods) - // debug: false, - // protocol: "http", //'http' or 'https'. HTTPS required for Nodejs <---> Python sockets. If using http, set production to False in python/server.py as well - // host: "localhost", //'localhost' or '127.0.0.1' etc. - // port: 8080, //e.g. port 80, 443, 8000 - // startpage: "index.html", //home page - // socket_protocol: "ws", //frontend socket protocol, wss for served, ws for localhost - // hotreload: 5000, //hotreload websocket server port - // //watch: ['../'], //watch additional directories other than the current working directory - // pwa: "dist/service-worker.js", //pwa mode? Injects service worker registry code in (see pwa README.md) - // python: false,//7000, //quart server port (configured via the python server script file still) - // python__node: 7001, //websocket relay port (relays messages to client from nodejs that were sent to it by python) - // errpage: "node_modules/tinybuild/tinybuild/node_server/other/404.html", //default error page, etc. - // certpath: "node_modules/tinybuild/tinybuild/node_server/ssl/cert.pem", //if using https, this is required. See cert.pfx.md for instructions - // keypath: "node_modules/tinybuild/tinybuild/node_server/ssl/key.pem" //if using https, this is required. See cert.pfx.md for instructions - // } -} - -module.exports = config; //es5 //export default config; // \ No newline at end of file diff --git a/src/extras/tinybuild.storage.config.js b/src/extras/tinybuild.storage.config.js deleted file mode 100644 index 87424eb8..00000000 --- a/src/extras/tinybuild.storage.config.js +++ /dev/null @@ -1,40 +0,0 @@ - -const config = { - bundler: { //esbuild settings, set false to skip build step or add bundle:true to config object to only bundle (alt methods) - entryPoints: [ //entry point file(s). These can include .js, .mjs, .ts, .jsx, .tsx, or other javascript files. Make sure your entry point is a ts file if you want to generate types - "index.storage.services.ts" - ], - outfile: "dist/index.storage.services", //exit point file, will append .js as well as indicators like .esm.js, .node.js for other build flags - //outdir:[] //exit point files, define for multiple bundle files - bundleBrowser: true, //create plain js build? Can include globals and init scripts - bundleESM: true, //create esm module js files - bundleTypes: true, //create .d.ts files, the entry point must be a typescript file! (ts, tsx, etc) - bundleNode: false, //create node platform plain js build, specify platform:'node' to do the rest of the files - bundleHTML: false, //wrap the first entry point file as a plain js script in a boilerplate html file, frontend scripts can be run standalone like a .exe! Server serves this as start page if set to true. - //minify: false, - minifyWhitespace:true, - sourcemap: false - //platform:'node' //for bundling the node.ts file - //globalThis:null //'mymodule' - //globals:{'index.js':['Graph']} - //init:{'index.js':function(bundle) { console.log('prepackaged bundle script!', bundle); }} - }, - server: false//{ //node server settings, set false to skip server step or add serve:true to config object to only serve (alt methods) - // debug: false, - // protocol: "http", //'http' or 'https'. HTTPS required for Nodejs <---> Python sockets. If using http, set production to False in python/server.py as well - // host: "localhost", //'localhost' or '127.0.0.1' etc. - // port: 8080, //e.g. port 80, 443, 8000 - // startpage: "index.html", //home page - // socket_protocol: "ws", //frontend socket protocol, wss for served, ws for localhost - // hotreload: 5000, //hotreload websocket server port - // //watch: ['../'], //watch additional directories other than the current working directory - // pwa: "dist/service-worker.js", //pwa mode? Injects service worker registry code in (see pwa README.md) - // python: false,//7000, //quart server port (configured via the python server script file still) - // python__node: 7001, //websocket relay port (relays messages to client from nodejs that were sent to it by python) - // errpage: "node_modules/tinybuild/tinybuild/node_server/other/404.html", //default error page, etc. - // certpath: "node_modules/tinybuild/tinybuild/node_server/ssl/cert.pem", //if using https, this is required. See cert.pfx.md for instructions - // keypath: "node_modules/tinybuild/tinybuild/node_server/ssl/key.pem" //if using https, this is required. See cert.pfx.md for instructions - // } -} - -module.exports = config; //es5 //export default config; // \ No newline at end of file diff --git a/src/extras/todo.md b/src/extras/todo.md deleted file mode 100644 index df0255f6..00000000 --- a/src/extras/todo.md +++ /dev/null @@ -1 +0,0 @@ -Really need to fix the dist splitting types up \ No newline at end of file diff --git a/src/extras/webgl-plot/webglplot.routes.ts b/src/extras/webgl-plot/webglplot.routes.ts deleted file mode 100644 index 24f2c378..00000000 --- a/src/extras/webgl-plot/webglplot.routes.ts +++ /dev/null @@ -1,287 +0,0 @@ -import { WorkerInfo } from '../../services/worker/Worker.service'//"graphscript"; -import { WebglLinePlotInfo,WebglLinePlotProps,WebglLinePlotUtil, WebglLineProps } from "webgl-plot-utils"//'../../../BrainsAtPlay_Libraries/webgl-plot-utils/webgl-plot-utils'//"webgl-plot-utils"//'../../BrainsAtPlay_Libraries/webgl-plot-utils/webgl-plot-utils'//"webgl-plot-utils"; -import { FilterSettings } from "../algorithms/util/BiquadFilters"; - -export { WebglLinePlotUtil, WebglLineProps, WebglLinePlotProps, WebglLinePlotInfo } //re-export types for reference - -export const webglPlotRoutes = { - setupChart:function setupChart(settings:WebglLinePlotProps) { - console.log('initializing chart', settings) - if(!this?.__node?.graph?.plotter) { - this.__node.graph.plotter = new WebglLinePlotUtil(); - return this.__node.graph.plotter.initPlot(settings).settings._id; - } - else { - globalThis.plotter = new WebglLinePlotUtil(); - return globalThis.plotter.initPlot(settings).settings._id; - } - }, - updateChartData:function updateChartData( - plot:WebglLinePlotInfo|string, - lines?:{ - [key: string]: WebglLineProps | number[] | { - [key: string]: any; - values: number[]; - } - }, - draw:boolean=true - ) { - //let parsed = globalThis.WebglLinePlotUtil.formatDataForCharts(lines); - if(typeof lines === 'object') - { - //console.log(parsed); - if(globalThis.plotter) globalThis.plotter.update(plot,lines,draw); - else if(this?.__node?.graph?.plotter)this.__node.graph.plotter.update(plot,lines,draw); - return true; - } return false; - }, - clearChart:function clearChart( - plot:WebglLinePlotInfo|string - ) { - - if(globalThis.plotter) globalThis.plotter.deinitPlot(plot); - else if(this?.__node?.graph?.plotter) - this.__node.graph.plotter.deinitPlot(plot); - - return true; - }, - resetChart:function resetChart( - plot:WebglLinePlotInfo|string, - settings:WebglLinePlotProps - ) { - if(globalThis.plotter) globalThis.plotter.reinitPlot(plot,settings); - else if(this?.__node?.graph?.plotter) this.__node.graph.plotter.reinitPlot(plot,settings); - return settings._id; - }, - getChartSettings:function getChartSettings(plotId) { - - let settings; - - if(globalThis.plotter) settings = globalThis.plotter.getChartSettings(plotId); - else if(this?.__node?.graph?.plotter) settings = this.__node.graph.plotter.getChartSettings(plotId); - //console.log(settings); - return settings; - } -} - - -export async function setSignalControls( - controlsDiv:HTMLElement, - plotId:string, - streamworker:WorkerInfo, - chartworker:WorkerInfo, - chartSettings:Partial, - filterSettings:FilterSettings, -) { - let controls = controlsDiv; - if(!controls) return false; - - if(!chartSettings && chartworker) chartSettings = await chartworker.run('getChartSettings',plotId); - if(!filterSettings && streamworker) filterSettings = await streamworker.run('getFilterSettings'); - - if(chartSettings?.lines) { - //console.log(chartSettings); - let body = ``; - - let viewingall = true; - let scalingall = true; - let n50all = true; - let n60all = true; - let dcall = true; - let lpall = true; - let bpall = true; - - for(const prop in chartSettings.lines) { - let line = chartSettings.lines[prop] as WebglLineProps - body += ` - - ${prop} - - - - - - - - - - Hz - Hz to Hz - ` - - if(!line.viewing) viewingall = false; - if(!filterSettings[prop]?.useScaling) scalingall = false; - if(!filterSettings[prop]?.useNotch50) n50all = false; - if(!filterSettings[prop]?.useNotch60) n60all = false; - if(!filterSettings[prop]?.useDCBlock) dcall = false; - if(!filterSettings[prop]?.useLowpass) lpall = false; - if(!filterSettings[prop]?.useBandpass) bpall = false; - - } - - let head = ` - - Name - SPS - Plot nSec - Scalar - Units - Lower Bound - Upper Bound - 50Hz Notch - 60Hz Notch - DC Block - Lowpass - Bandpass - - `; - - - controls.innerHTML = head + body; - - //apply to all - let viewall = document.getElementById(plotId+'viewing') as HTMLInputElement; - let usescalar = document.getElementById(plotId+'useScaling') as HTMLInputElement; - let usen50 = document.getElementById(plotId+'useNotch50') as HTMLInputElement; - let usen60 = document.getElementById(plotId+'useNotch60') as HTMLInputElement; - let usedcb = document.getElementById(plotId+'useDCBlock') as HTMLInputElement; - let uselp = document.getElementById(plotId+'useLowpass') as HTMLInputElement; - let usebp = document.getElementById(plotId+'useBandpass') as HTMLInputElement; - - let headeronchange = (checked, idsuffix) => { - for(const prop in chartSettings.lines) { - let elm = document.getElementById(plotId+prop+idsuffix) as HTMLInputElement; - if(elm?.checked !== checked) elm.click(); //trigger its onchange to set reset the filter - } - } - - viewall.onchange = (ev) => { - headeronchange((ev.target as HTMLInputElement).checked,'viewing') - } - usescalar.onchange = (ev) => { - headeronchange((ev.target as HTMLInputElement).checked,'useScaling') - } - usen50.onchange = (ev) => { - headeronchange((ev.target as HTMLInputElement).checked,'useNotch50') - } - usen60.onchange = (ev) => { - headeronchange((ev.target as HTMLInputElement).checked,'useNotch60') - } - usedcb.onchange = (ev) => { - headeronchange((ev.target as HTMLInputElement).checked,'useDCBlock') - } - uselp.onchange = (ev) => { - headeronchange((ev.target as HTMLInputElement).checked,'useLowpass') - } - usebp.onchange = (ev) => { - headeronchange((ev.target as HTMLInputElement).checked,'useBandpass') - } - - for(const prop in chartSettings.lines) { - let viewing = document.getElementById(plotId+prop+'viewing') as HTMLInputElement; - let sps = document.getElementById(plotId+prop+'sps') as HTMLInputElement; - let nSec = document.getElementById(plotId+prop+'nSec') as HTMLInputElement; - let useScaling = document.getElementById(plotId+prop+'useScaling') as HTMLInputElement; - let scalar = document.getElementById(plotId+prop+'scalar') as HTMLInputElement; - let units = document.getElementById(plotId+prop+'units') as HTMLInputElement; - let ymin = document.getElementById(plotId+prop+'ymin') as HTMLInputElement; - let ymax = document.getElementById(plotId+prop+'ymax') as HTMLInputElement; - let useNotch50 = document.getElementById(plotId+prop+'useNotch50') as HTMLInputElement; - let useNotch60 = document.getElementById(plotId+prop+'useNotch60') as HTMLInputElement; - let useDCBlock = document.getElementById(plotId+prop+'useDCBlock') as HTMLInputElement; - let useLowpass = document.getElementById(plotId+prop+'useLowpass') as HTMLInputElement; - let lowpassHz = document.getElementById(plotId+prop+'lowpassHz') as HTMLInputElement; - let useBandpass = document.getElementById(plotId+prop+'useBandpass') as HTMLInputElement; - let bandpassLower = document.getElementById(plotId+prop+'bandpassLower') as HTMLInputElement; - let bandpassUpper = document.getElementById(plotId+prop+'bandpassUpper') as HTMLInputElement; - - - viewing.onchange = () => { - - if((!Array.isArray(chartSettings.lines?.[prop] as WebglLineProps))) { - - (chartSettings.lines?.[prop] as WebglLineProps).viewing = viewing.checked; - (chartSettings as WebglLinePlotProps).generateNewLines = false; //make sure the lines don't regenerate automatically - chartworker.run('resetChart', [plotId,chartSettings]); - - } - } - - let filteronchange = () => { - - let setting = { - [prop]:{ - sps: sps.value ? parseFloat(sps.value) : 100, - useScaling:useScaling.checked, - scalar: scalar.value ? parseFloat(scalar.value) : 1, - useNotch50:useNotch50.checked, - useNotch60:useNotch60.checked, - useDCBlock:useDCBlock.checked, - useLowpass:useLowpass.checked, - lowpassHz: lowpassHz.value ? parseFloat(lowpassHz.value) : 100, - useBandpass: useBandpass.checked, - bandpassLower: bandpassLower.value ? parseFloat(bandpassLower.value) : 3, - bandpassUpper: bandpassUpper.value ? parseFloat(bandpassUpper.value) : 45, - trimOutliers: filterSettings[prop]?.trimOutliers, - outlierTolerance: filterSettings[prop]?.outlierTolerance - } as FilterSettings - } - - //console.log(setting); - - streamworker.post('setFilters', setting); //replace current filter for this line - } - - sps.onchange = () => { - filteronchange(); - (chartSettings.lines?.[prop] as WebglLineProps).sps = parseFloat(sps.value); - (chartSettings.lines?.[prop] as WebglLineProps).nSec = parseFloat(nSec.value); - delete (chartSettings.lines?.[prop] as WebglLineProps).points; - delete (chartSettings.lines?.[prop] as WebglLineProps).nPoints; - chartworker.run('resetChart', [plotId,chartSettings]); - } - - units.onchange = () => { - if((!Array.isArray(chartSettings.lines?.[prop] as WebglLineProps))) { - (chartSettings.lines?.[prop] as WebglLineProps).units = units.value; - chartworker.run('resetChart', [plotId,chartSettings]); - } - } - ymax.onchange = () => { - if((!Array.isArray(chartSettings.lines?.[prop] as WebglLineProps))) { - (chartSettings.lines?.[prop] as WebglLineProps).ymax = ymax.value ? parseFloat(ymax.value) : 1; - (chartSettings.lines?.[prop] as WebglLineProps).ymin = ymin.value ? parseFloat(ymin.value) : 0; - chartworker.run('resetChart', [plotId,chartSettings]); - } - } - ymin.onchange = () => { - if((!Array.isArray(chartSettings.lines?.[prop] as WebglLineProps))) { - (chartSettings.lines?.[prop] as WebglLineProps).ymax = ymax.value ? parseFloat(ymax.value) : 1; - (chartSettings.lines?.[prop] as WebglLineProps).ymin = ymin.value ? parseFloat(ymin.value) : 0; - chartworker.run('resetChart', [plotId,chartSettings]); - } - } - - nSec.onchange = () => { - if((!Array.isArray(chartSettings.lines?.[prop] as WebglLineProps))) { - (chartSettings.lines?.[prop] as WebglLineProps).sps = parseFloat(sps.value); - (chartSettings.lines?.[prop] as WebglLineProps).nSec = parseFloat(nSec.value); - delete (chartSettings.lines?.[prop] as WebglLineProps).points; - delete (chartSettings.lines?.[prop] as WebglLineProps).nPoints; - chartworker.run('resetChart', [plotId,chartSettings]); - } - } - - useScaling.onchange = filteronchange; - useNotch50.onchange = filteronchange; - useNotch60.onchange = filteronchange; - useDCBlock.onchange = filteronchange; - useLowpass.onchange = filteronchange; - useBandpass.onchange = filteronchange; - lowpassHz.onchange = filteronchange; - scalar.onchange = filteronchange; - bandpassLower.onchange = filteronchange; - bandpassUpper.onchange = filteronchange; - } - } -} diff --git a/src/loaders/html/html.loader.ts b/src/loaders/html/html.loader.ts deleted file mode 100644 index 9cc7fb3a..00000000 --- a/src/loaders/html/html.loader.ts +++ /dev/null @@ -1,143 +0,0 @@ - -import {GraphNode, GraphNodeProperties,Graph} from '../../core/Graph' - -export type HTMLNodeProperties = GraphNodeProperties & { - __props?:HTMLElement, - __onresize?:(elm:HTMLElement) => void, - __onremove?:(elm:HTMLElement) => void, - __onrender?:(elm:HTMLElement) => void, - tagName?:string, //can provide this instead of an element or html template string - parentNode?:string|HTMLElement, //can define a specific parentNode, else a parent graph node with an HTMLElement as __props will be selected, else graph.parentNode if defined, else document.body - style?:Partial, //supply an object with style properties for this element's inline styles - //applies to custom webcomponent only (wchtmlloader): - __template?:string|((...args:any[]) => string), - __renderonchanged?:(elm:HTMLElement) => void, - useShadow?:boolean, - __css?:string, //stylesheet template string for use with web components (just prepends a `; delete node.__css; - } - - - const registerElement = (node, tagNameOverride?:string) => { - if (isNativeClass(node)) node = new node(); - else if (typeof node === 'function' && !node.__node) node = node(); - - class CustomElement extends DOMElement { - props = node.props; - styles = node.__css; - useShadow = node.useShadow; - template = node.__template as any; - oncreate = node.__onrender; - onresize = node.__onresize; - ondelete = node.__onremove; - renderonchanged = node.__renderonchanged as any; - } - - if (tagNameOverride?.includes('-')) node.tagName = tagNameOverride - else if(node.__element) node.tagName = node.__element; - - if(!node.tagName) node.tagName = `element${Math.floor(Math.random()*1000000000000000)}-`; - - CustomElement.addElement(node.tagName); - } - - - if ('__components' in node) { - if (Array.isArray(node.__components)) node.__components.forEach(c => registerElement(c)) - else Object.entries(node.__components).forEach(([k, c]) => registerElement(c, k.includes('-') ? k : undefined)) - } - - if ('__template' in node) { - - if(typeof node.__renderonchanged === 'function') { - let renderonchanged = node.__renderonchanged; - node.__renderonchanged = (element:DOMElement) => { - renderonchanged.call((element as any).node, element); - } - } - - registerElement(node); - node.__props = document.createElement(node.tagName); - - let cpy = Object.assign({},node); - let keys = Object.getOwnPropertyNames(cpy); - for(const k of keys) { - if(k === 'style' && typeof node[k] === 'object') {Object.assign(node.__props.style,cpy[k]);} - else if (k === 'className') node.__props.setAttribute('class', cpy[k]); - else if (!k.includes('outer')) node.__props[k] = cpy[k]; - } - - if(node.__attributes) { - for(const k in node.__attributes) { - if(k === 'style' && typeof node.__attributes[k] === 'object') {Object.assign(node.__props.style,node.__attributes[k]);} - else if (k === 'className') node.__props.setAttribute('class', node.__attributes[k]); - else if (!k.includes('outer')) node.__props[k] = node.__attributes[k]; - } - } - node.__proxyObject(node.__props); - - //fix for event listeners - for(const k of keys) { - if(typeof cpy[k] === 'function') { - let fn = cpy[k]; - node.__props[k] = (...inp) => { let res = fn(...inp); node.__node.state.triggerEvent(node.__node.unique+'.'+k, res); }; - } - } - - if(node.__attributes) { - for(const k in node.__attributes) { - if(typeof cpy[k] === 'function') { - let fn = node.__attributes[k]; - node.__props[k] = (...inp) => { let res = fn(...inp); node.__node.state.triggerEvent(node.__node.unique+'.'+k, res); }; - } - } - } - /// - - } else if(node.__props instanceof HTMLElement) { - let cpy = Object.assign({},node); - let keys = Object.getOwnPropertyNames(cpy); - - for(const k of keys) { - if(k === 'style' && typeof node[k] === 'object') {Object.assign(node.__props.style,cpy[k]);} - else if (k === 'className') node.__props.setAttribute('class', cpy[k]); - else if (!k.includes('outer')) node.__props[k] = cpy[k]; - } - - if(node.__attributes) { - for(const k in node.__attributes) { - if(k === 'style' && typeof node.__attributes[k] === 'object') {Object.assign(node.__props.style,node.__attributes[k]);} - else if (k === 'className') node.__props.setAttribute('class', cpy[k]); - else if (!k.includes('outer')) node.__props[k] = node.__attributes[k]; - } - } - - node.__proxyObject(node.__props); - - //fix for event listeners - for(const k of keys) { - if(typeof cpy[k] === 'function') { - let fn = cpy[k]; - node.__props[k] = (...inp) => { let res = fn(...inp); node.__node.state.triggerEvent(node.__node.unique+'.'+k, res); }; - node[k] = node.__props[k]; - } - } - - if(node.__attributes) { - for(const k in node.__attributes) { - if(typeof cpy[k] === 'function') { - let fn = node.__attributes[k]; - node.__props[k] = (...inp) => { let res = fn(...inp); node.__node.state.triggerEvent(node.__node.unique+'.'+k, res); }; - node[k] = node.__props[k]; - } - } - } - /// - - if(node.__onresize) - window.addEventListener('resize', node.__onresize as EventListener); - - } - - if(node.__props instanceof HTMLElement) { - node.__props.id = key; - (node.__props as any).node = node; - - node.__addOnconnected((n) => { - if(!(node.__props instanceof HTMLBodyElement || node.__props instanceof HTMLHeadElement) && n.__props.parentNode) (n.__props as HTMLElement).remove(); - if(properties.parentNode) { - if(typeof properties.parentNode === 'string' && document.getElementById(properties.parentNode)) - document.getElementById(properties.parentNode)?.appendChild(n.__props); - else if (properties.parentNode instanceof HTMLElement) properties.parentNode.appendChild(n.__props); - } else if(parent?.__props instanceof HTMLElement) { - parent.__props.appendChild(node.__props); - } else if (typeof graph.parentNode === 'string' && document.getElementById(properties.parentNode)) { - document.getElementById(properties.parentNode)?.appendChild(graph.__props); - } else if(graph.parentNode instanceof HTMLElement) { - graph.parentNode.appendChild(node.__props); - } else if(!(node.__props instanceof HTMLBodyElement || node.__props instanceof HTMLHeadElement)) - document.body.appendChild(node.__props); - - //add slight delay for sizing etc to kick in correctly - if(node.__onrender && !(node.__props instanceof DOMElement) && !node.__template) setTimeout(()=>{node.__onrender(node.__props)},0.01); - - }); - - node.__addOndisconnected((n) => { - (n.__props as HTMLElement).remove(); - - if(typeof n.__onremove === 'function') { - n.__onremove(n.__props) - } - - if(n.__onresize) { - window.removeEventListener('resize', n.__onresize); - } - }); - } - - -} \ No newline at end of file diff --git a/src/loaders/index.ts b/src/loaders/index.ts deleted file mode 100644 index 16b4a0c3..00000000 --- a/src/loaders/index.ts +++ /dev/null @@ -1,322 +0,0 @@ -import { GraphNode, Graph, GraphNodeProperties } from "../core/Graph"; - -//loaders are triggered just after graphnode creation, after oncreate() is called - -/** - * setting nodeA.__node.backward:true propagates operator results to parent - */ -export const backprop = (node:GraphNode,parent:GraphNode|Graph,graph:Graph) => { - - if(node.__node.backward && parent instanceof GraphNode) { - - graph.setListeners({ - [parent.__node.tag]:{ - [node.__node.tag]:parent - } - }) - } - - -} - -/** - * - * Specify a timer loop, will stop when node is popped or nodeA.__node.isLooping is set false - * nodeA.__node.loop = 100 will loop the operator every 100 milliseconds - * - * Or - * nodeA.__node.delay will delay the operator by specified millisecond number and resolve the result as a promise - * nodeA.__node.frame will use requestAnimationFrame to call the function and resolve the result as a promise - * - * Use in combination with: - * nodeA.__node.repeat will repeat the operator the specified number of times - * nodeA.__node.recursive will do the same as repeat but will pass in the previous operator call's results - * - * - */ -export const loop = (node:GraphNode,parent:GraphNode|Graph,graph:Graph)=>{ - - if( - node.__operator - //&& !node.__node.looperSet //not using this allows multiple loops to run, just set looping=false and wait for all to finish otherwise - ) { - let loopId = Math.random(); - if(!node.__node.loops) node.__node.loops = {}; - if(typeof node.__node.delay === 'number') { - let fn = node.__operator; - node.__setOperator((...args:any[]) => { - return new Promise((res,rej) => { - node.__node.loops[loopId] = setTimeout(async ()=>{ - res(await fn(...args));},node.__node.delay); - }); - }); - } else if (node.__node.frame === true) { - let fn = node.__operator; - node.__setOperator((...args:any[]) => { - return new Promise((res,rej) => { - node.__node.loops[loopId] = requestAnimationFrame(async ()=>{res(await fn(...args));}); - }); - }); - } - - if(typeof node.__node.repeat === 'number' || typeof node.__node.recursive === 'number') { - let fn = node.__operator; - node.__setOperator(async (...args:any[]) => { - let i = node.__node.repeat ? node.__node.repeat : node.__node.recursive; - let result; - let repeater = async (tick,...inp:any[]) => { - while(tick > 0) { - if(node.__node.delay || node.__node.frame) { - fn(...inp).then(async (res) => { - if(node.__node.recursive) { - await repeater(tick,res); - } - else await repeater(tick,...inp); - }) - break; - } - else result = await fn(...args); - tick--; - } - } - await repeater(i,...args); - return result; - }); - } - - if(node.__node.loop && typeof node.__node.loop === 'number') { - - //node.__node.looperSet = true; - let fn = node.__operator; - let time = node.__node.loop; - node.__setOperator((...args) => { - if(!('looping' in node.__node)) node.__node.looping = true; - if(node.__node.looping) { - let last = performance.now(); - fn(...args); - node.__node.loops[loopId] = setTimeout( - ()=>{ - let now = performance.now(); - let overshoot = (now - last) - node.__node.loop; - if(overshoot > 0) time = node.__node.loop - overshoot; - else time = node.__node.loop; - if(time <= 0) time = node.__node.loop; - node.__operator(...args); - // - }, - time - ); - } - }); - if(node.__node.looping) node.__operator(); - - let ondelete = (node) => { - if(node.__node.looping) node.__node.looping = false; - if(node.__node.loops[loopId]) { - clearTimeout(node.__node.loops[loopId]); - cancelAnimationFrame(node.__node.loops[loopId]); - } - } - - node.__addOndisconnected(ondelete); - } - } - -} - -/** Animations - * - * nodeA.__node.animate = true; - * then __operator becomes a requestAnimationFrame function - * start with a call the __operator or by setting node.__node.animating = true; - * - * or node.__animation = (...args) => {} - * - */ -export const animate = (node:GraphNode,parent:GraphNode|Graph,graph:Graph) => { - if(node.__node.animate === true || node.__animation) { - let fn = node.__operator; - - node.__setOperator((...args) => { - if(!('animating' in node.__node)) node.__node.animating = true; - if(node.__node.animating) { - if(typeof node.__animation === 'function') node.__animation(...args); - else fn(...args); - node.__node.animationFrame = requestAnimationFrame(()=>{node.__operator(...args);}); - } - }); - if(node.__node.animating || ((!('animating' in node.__node) || node.__node.animating) && node.__animation)) - setTimeout(()=>{ - node.__node.animationFrame = requestAnimationFrame(node.__operator) - },10); - - - let ondelete = (node) => { - if(node.__node.animating) node.__node.animating = false; - if(node.__node.animationFrame) cancelAnimationFrame(node.__node.animationFrame); - } - - node.__addOndisconnected(ondelete); - } -} - - -/** Branching operations - * - * //runs a function or node if the if-conditions are satisfied, which can be a function that returns a true or false - * nodeA.__branch = {[key:string]:{if:Function|any, then:Function|any|GraphNode}} - * - * nodeA.__listeners['nodeB.x'] = { - * callback:(result)=>void, - * branch:{ - * if:Function|any, //if a function using the result evaluates to true or if the value equals the if value - * then:Function|any|GraphNode //call a function, return a different result, or call a node - * } - * } - * - */ -export const branching = (node:GraphNode,parent:GraphNode|Graph,graph:Graph) => { - if(typeof node.__branch === 'object' && node.__operator && !node.__branchApplied) { - let fn = node.__operator; - node.__branchApplied = true; - node.__operator = ((...args:any[]) => { - let result = fn(...args); - for(const key in node.__branch) { //run branching operations - let triggered = () => { - if(typeof node.__branch[key].then === 'function') { - node.__branch[key].then(result); //trigger a callback - } else if(node.__branch[key].then instanceof GraphNode && node.__branch[key].then.__operator) { - node.__branch[key].then.__operator(result); //run a node - } else result = node.__branch[key].then; //just replace the result in this case - } - if(typeof node.__branch[key].if === 'function') { - if(node.__branch[key].if(result) == true) { - triggered(); - } - } else if(node.__branch[key].if === result) { - triggered(); - } - } - return result; - }); - } - if(node.__listeners) { - for(const key in node.__listeners) { - if(typeof node.__listeners[key] === 'object') { - if(node.__listeners[key].branch && !node.__listeners[key].branchApplied) { - let fn = node.__listeners[key].callback; - - node.__listeners[key].branchApplied = true; - node.__listeners.callback = (ret) => { - let triggered = () => { - if(typeof node.__listeners[key].branch.then === 'function') { - ret = node.__listeners[key].branch.then(ret); //trigger a callback - } else if(node.__listeners[key].branch.then instanceof GraphNode && node.__listeners[key].branch.then.__operator) { - ret = node.__listeners[key].branch.then.__operator(ret); //run a node - } else ret = node.__listeners[key].branch.then; //just replace the result in this case - } - if(typeof node.__listeners[key].branch.if === 'function') { - if(node.__listeners[key].branch.if(ret)) { - triggered(); - } - } else if(node.__listeners[key].branch.if === ret) { - triggered(); - } - return fn(ret); - } - } - } - } - } -} - -/** Trigger listeners oncreate with specific arguments - * - * nodeA.__listeners['nodeB.x'] = { callback:(result)=>void, oncreate:any } - * - */ -export const triggerListenerOncreate = (node:GraphNode,parent:GraphNode|Graph,graph:Graph) => { - if(node.__listeners) { - for(const key in node.__listeners) { - if(typeof node.__listeners[key] === 'object') { - if(node.__listeners[key].oncreate) { - node.__listeners[key].callback(node.__listeners[key].oncreate); - } - } - } - } -} - -/** Bind listeners to a specific object instead of the node that owns it - * - * nodeA.__listeners['nodeB.x'] = { callback:(result)=>void, binding:{[key:string]:any} } - * - */ -export const bindListener = (node:GraphNode,parent:GraphNode|Graph,graph:Graph) => { - if(node.__listeners) { - for(const key in node.__listeners) { - if(typeof node.__listeners[key] === 'object') { - if(typeof node.__listeners[key].binding === 'object') { - node.__listeners.callback = node.__listeners.callback.bind(node.__listeners[key].binding); - } - } - } - } -} - - -/** - * - * nodeA.__listeners['nodeB.x'] = { callback:(result)=>void, transform:(result)=>any } - * - */ -export const transformListenerResult = (node:GraphNode,parent:GraphNode|Graph,graph:Graph) => { - if(node.__listeners) { - for(const key in node.__listeners) { - if(typeof node.__listeners[key] === 'object') { - if(typeof node.__listeners[key].transform === 'function' && !node.__listeners[key].transformApplied) { - let fn = node.__listeners[key].callback; - node.__listeners[key].transformApplied = true; - node.__listeners.callback = (ret) => { - ret = node.__listeners[key].transform(ret) - return fn(ret); - } - } - } - } - } -} - - -export const substitute__operator = (node:GraphNode & GraphNodeProperties, parent:GraphNode|Graph,graph:Graph) => { - //console.log('route', r) - if(node.post && !node.__operator) { - node.__setOperator(node.post); - } else if (!node.__operator && typeof node.get == 'function') { - node.__setOperator(node.get); - } if(!node.get && node.__operator) { - //node.get = node.__operator; - } if(node.aliases) { - node.aliases.forEach((a) => { - graph.set(a,node); - let ondelete = (node) => { - graph.__node.nodes.delete(a); - } - - node.__addOndisconnected(ondelete); - }) - } - if(typeof graph.__node.roots?.[node.__node.tag] === 'object' && node.get) graph.__node.roots[node.__node.tag].get = node.get; -} - -//standard loaders with flow logic for operators and listeners -export const loaders = { - backprop, - loop, - animate, - branching, - triggerListenerOncreate, - bindListener, - transformListenerResult, - substitute__operator -} \ No newline at end of file diff --git a/src/loaders/methodstrings.ts b/src/loaders/methodstrings.ts deleted file mode 100644 index f96e7677..00000000 --- a/src/loaders/methodstrings.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {parseFunctionFromText} from '../services/utils' - -export function methodstrings (node) { - if(typeof node.__methods === 'object') { - for(const key in node.__methods) { - let fstr = node.__methods[key]; - let fn = typeof fstr === 'function' ? fstr : parseFunctionFromText(fstr); - if(key === '__operator') { - node.__setOperator(fn as any); - } - else { - node[key] = fn.bind(node); - } - } - } -} \ No newline at end of file diff --git a/src/services/Service.ts b/src/services/Service.ts deleted file mode 100644 index bd4d7462..00000000 --- a/src/services/Service.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { Graph, GraphNode, GraphOptions } from "../../src/core/Graph"; -import {loaders} from '../../src/loaders'; - - -export type TypedArray = -| Int8Array -| Uint8Array -| Uint8ClampedArray -| Int16Array -| Uint16Array -| Int32Array -| Uint32Array -| Float32Array -| Float64Array; - -export type ServiceMessage = { - route?:string, //the function/node to execute - args?:any, //route args or data depending on what we're handling - method?:string, //can specify get, post, etc. on http requests or on multiplexed routes using the RouteProp format - node?:string|GraphNode, //alt tag for routes - [key:string]:any //it's an object so do whatever, any messages meant for web protocols need to be stringified or buffered -} - -export type ServiceOptions = - GraphOptions & { - services?:{[key:string]:Service|Function|{[key:string]:any}}, - restrict?:{[key:string]:boolean} //only allow the receive() (and on some services the remote subscribe() calls) to run specific nodes - } - -export class Service extends Graph { - - name = `service${Math.floor(Math.random()*1000000000000000)}`; - - restrict?:{[key:string]:boolean}; - - constructor(options?:ServiceOptions) { - super({ //assign properties to the graph - ...options, - loaders: options?.loaders ? Object.assign({...loaders},options.loaders) : {...loaders} - //roots: - }); - - if(options?.services) this.addServices(options.services); - if(options?.restrict) this.restrict = options.restrict; - - this.load(this); - } - - addServices = (services:{[key:string]:Graph|Service|Function|{[key:string]:any}}) => { - for(const s in services) { - if(typeof services[s] === 'function') services[s] = new (services as any)[s](); //instantiate a constructor - if((services[s] as Graph)?.__node?.loaders) - Object.assign(this.__node.loaders,(services[s] as Graph).__node.loaders); - if((services[s] as Graph)?.__node?.nodes) { - (services[s] as Graph).__node.nodes.forEach((n,tag) => { - if(!this.get(tag)) { - this.set(tag,n); - } else this.set(s+'.'+tag,n); - }); - - this.__node.nodes.forEach((n,k) => { - if(!(services[s] as Service).__node.nodes.get(k)) - (services[s] as Graph).__node.nodes.set(k,n) - }) - - let set = this.set; - - this.set = (tag:string,node:GraphNode) => { - (services[s] as Graph).set(tag,node); - return set(tag,node); - } - - let del = this.delete; - - this.delete = (tag:string) => { - (services[s] as Graph).delete(tag); - return del(tag); - } - - } - else if(typeof services[s] === 'object') { - this.load(services[s]); //just a roots - } - } - } - - handleMethod = ( - route:string, - method:string, - args?:any - ) => { //For handling RouteProp or other routes with multiple methods - let m = method.toLowerCase(); //lower case is enforced in the route keys - let src = this.__node.nodes.get(route); - if(!src) { - src = this.__node.roots[route]; - } - if(src?.[m]) { - if(typeof src[m] !== 'function') { - if(args) { - if(Array.isArray(args) && args.length === 1) src[m] = args[0]; - else src[m] = args; - return; //set value, don't echo - } //if args were passed set the value - return src[m]; //could just be a stored local variable we are returning like a string or object - } - else { - if(Array.isArray(args)) return src[m](...args); - else return src[m](args); - } - - }//these could be any function or property call - else return this.handleServiceMessage({route,args,method}) //process normally if the method doesn't return - } - - handleServiceMessage(message:ServiceMessage) { - let call; - //console.log(message); - if(typeof message === 'object') { - if(message.route) call = message.route; else if (message.node) call = message.node; - } - if(call) { - //console.log('call',call,'message',message, 'nodes:', this.nodes.keys(),this) - if(Array.isArray(message.args)) return this.run(call,...message.args); - else return this.run(call,message.args); - } else return message; - } - - handleGraphNodeCall(route:string|GraphNode, args:any) { - if(!route) return args; - if((args as ServiceMessage)?.args) { - this.handleServiceMessage(args); - } - else if(Array.isArray(args)) return this.run(route,...args); - else return this.run(route, args); - } - - //transmit http requests, socket messages, webrtc, osc, etc. with this customizable callback - transmit:(...args)=>any|void = ( - ...args:[ServiceMessage|any,...any[]]|any[] - ) => { - if(typeof args[0] === 'object') { - const message = args[0]; - if(message.method) { //run a route method directly, results not linked to graph - return this.handleMethod(message.route, message.method, message.args); - } else if(message.route) { - return this.handleServiceMessage(message); - } else if (message.node){ - return this.handleGraphNodeCall(message.node, message.args); - } else if(this.__node.keepState) { - if(message.route) - this.setState({[message.route]:message.args}); - if(message.node) - this.setState({[message.node]:message.args}); - } - return undefined; - } else return undefined; - } - - //process http requests, socket messages, webrtc, osc, etc. with this customizable callback. This default still works in some scenarios - receive:(...args)=>any|void = ( - ...args:[ServiceMessage|any,...any[]]|any[] //generalized args for customizing, it looks weird I know - ) => { - if(args[0]) { - let message = args[0]; - if(typeof message === 'string') { - let substr = message.substring(0,8); - if(substr.includes('{') || substr.includes('[')) { - if(substr.includes('\\')) message = message.replace(/\\/g,""); //double jsonified string - if(message[0] === '"') { message = message.substring(1,message.length-1)}; - //console.log(message) - message = JSON.parse(message); //parse stringified args - } - } - - if(typeof message === 'object') { - if(message.method) { //run a route method directly, results not linked to graph - if(this.restrict?.[message.route]) return undefined; - return this.handleMethod(message.route, message.method, message.args); - } else if(message.route) { - if(this.restrict?.[message.route]) return undefined; - return this.handleServiceMessage(message); - } else if (message.node){ - if(typeof message.node === 'string' && this.restrict?.[message.node]) return undefined; - return this.handleGraphNodeCall(message.node, message.args); - } else if(this.__node.keepState) { - if(message.route) - this.setState({[message.route]:message.args}); - if(message.node) - this.setState({[message.node]:message.args}); - } - return undefined; - } - } - return undefined; - }//these are fairly identical on the base template plus json parsing on the receive end - - //we may want to auto pipe outputs from a node through our frontend<-->backend service protocol - pipe = ( - source:GraphNode|string, - destination:string, - endpoint?:string|any, //the address or websocket etc. of the endpoint on the service we're using, this is different e.g. for sockets or http - method?:string, - callback?:(res:any)=>any|void - ) => { - if(source instanceof GraphNode) { - if(callback) return this.subscribe(source,(res)=>{ - let mod = callback(res); //either a modifier or a void function to do a thing before transmitting the data - if(mod !== undefined) this.transmit({route:destination, args:mod, method}); - else this.transmit({route:destination, args:res, method}, endpoint); - }) - else return this.subscribe(source,(res)=>{ this.transmit({route:destination, args:res, method}, endpoint); }); - } - else if(typeof source === 'string') - return this.subscribe(source,(res)=>{ - this.transmit({route:destination, args:res, method}, endpoint); - }); - } - - //one-shot callback pipe e.g. to return results back through an endpoint - pipeOnce = ( - source:GraphNode|string, - destination:string, - endpoint?:string|any, //the address or websocket etc. of the endpoint on the service we're using, this is different e.g. for sockets or http - method?:string, - callback?:(res:any)=>any|void - ) => { - if(source instanceof GraphNode) { - if(callback) return source.__node.state.subscribeEventOnce(source.__node.unique,(res)=>{ - let mod = callback(res); //either a modifier or a void function to do a thing before transmitting the data - if(mod !== undefined) this.transmit({route:destination, args:mod, method}); - else this.transmit({route:destination, args:res, method},endpoint); - }) - else return this.__node.state.subscribeEventOnce(source.__node.unique,(res)=>{ - this.transmit({route:destination, args:res, method},endpoint); }); - } - else if(typeof source === 'string') - return this.__node.state.subscribeEventOnce(this.__node.nodes.get(source).__node.unique,(res)=>{ - this.transmit({route:destination, args:res, method},endpoint); - }); - } - - terminate = (...args:any) => {} - - isTypedArray = isTypedArray; - recursivelyAssign = recursivelyAssign; - spliceTypedArray = spliceTypedArray; - ping = ()=>{ //define functions, graph props, etc. All methods defined in a route object are callable - console.log('pinged!');//this.transmit('pong'); - return 'pong'; - } - echo = (...args:any)=>{ //this transmits input arguments, so to echo on a specific service do e.g. 'wss/echo' - this.transmit(...args); - return args; - } - log = (...args:any)=>{ - console.log(...args); - return true; - } - error = (...args:any) => { - console.error(...args); - return true; - } - -} - - -export function isTypedArray(x:any) { //https://stackoverflow.com/a/40319428 - return (ArrayBuffer.isView(x) && Object.prototype.toString.call(x) !== "[object DataView]"); -} - -export const recursivelyAssign = (target,obj) => { - for(const key in obj) { - if(obj[key]?.constructor.name === 'Object' && !Array.isArray(obj[key])) { - if(target[key]?.constructor.name === 'Object' && !Array.isArray(target[key])) recursivelyAssign(target[key], obj[key]); - else target[key] = recursivelyAssign({},obj[key]); - } else target[key] = obj[key]; - } - - return target; -} - -//splice out a section of a typed array. If end is undefined we'll splice all values from the starting position to the end -//if you want to replace values, just use .set, this is for quickly removing values to trim arrays e.g. if an entity is popped -export function spliceTypedArray(arr:TypedArray,start:number,end?:number):TypedArray { - let s = arr.subarray(0,start) - let e; - if(end) { - e = arr.subarray(end+1); - } - - let ta; - if(s.length > 0 || e?.length > 0) ta = new (arr as any).constructor(s.length+e.length); //use the same constructor - if(ta) { - if(s.length > 0) ta.set(s); - if(e && e.length > 0) ta.set(e,s.length); - } - return ta as TypedArray; -} diff --git a/src/services/http/HTTP.node.ts b/src/services/http/HTTP.node.ts deleted file mode 100644 index 210e579f..00000000 --- a/src/services/http/HTTP.node.ts +++ /dev/null @@ -1,1268 +0,0 @@ -import { Service, ServiceMessage, ServiceOptions } from "../Service"; -import * as http from 'http' -import * as https from 'https' -import * as fs from 'fs' -import * as path from 'path' -import { GraphNode, GraphNodeProperties } from "../../core/Graph"; -import { defaultManifest, defaultServiceWorker } from "./boilerplate/index"; - -export * from './boilerplate/index' - -export type ServerProps = { - host:string, - port:number, - certpath?:string, - keypath?:string, - passphrase?:string, - startpage?: string, - errpage?:string, - pages?:{ - [key:'all'|string]:string|{ //objects get loaded as nodes which you can modify props on - headers?:{[key:string]:any}, //page specific headers to assign on page response - template?:string, - onrequest?:GraphNode|string|((self:HTTPbackend, node:GraphNode, request:http.IncomingMessage, response:http.ServerResponse)=>void), //run a function or node? the template, request and response are passed as arguments, you can write custom node logic within this function to customize inputs etc. - redirect?:string, // can redirect the url to call a different route instead, e.g. '/':{redirect:'home'} sets the route passed to the receiver as 'home' - inject?:{[key:string]:any}|any[]|string| ((...args:any)=>any) //append html - } & GraphNodeProperties - }, - protocol?:'http'|'https', - type?:'httpserver'|string, - keepState?:boolean, //setState whenever a route is run? State will be available at the address (same key of the object storing it here) - onopen?:(served:ServerInfo)=>void, //onopen callback - onerror?:(er:Error,served:ServerInfo)=>void, - onclose?:(served:ServerInfo)=>void, //server close callback - onupgrade?:(request, socket, head, served:ServerInfo)=>void, - timeout?:number, //request timeout, default is 1 second - _id?:string, - debug?:boolean, - [key:string]:any -} - -export type ServerInfo = { - server:https.Server|http.Server, - address:string, - terminate:()=>void, - graph:HTTPbackend, - _id:string -} & ServerProps - -export type ReqOptions = { - protocol:'http'|'https'|string - host:string, - port:number, - method:string, - path?:string, - headers?:{ - [key:string]:any, - 'Content-Type'?:string, //e.g... - 'Content-Length'?:number - } -} - -//http/s server -export class HTTPbackend extends Service { - - name='http'; - - server:any - - debug:boolean=false - - servers:{ - [key:string]:ServerInfo - }={} - - mimeTypes:{[key:string]:string} = { - '.html': 'text/html', '.htm': 'text/html', '.js': 'text/javascript', '.css': 'text/css', '.json': 'application/json', '.txt':'text/plain', - '.png': 'image/png', '.jpg': 'image/jpg', '.jpeg': 'image/jpg','.gif': 'image/gif', '.svg': 'image/svg+xml', '.xhtml':'application/xhtml+xml', '.bmp':'image/bmp', - '.wav': 'audio/wav', '.mp3':'audio/mpeg', '.mp4': 'video/mp4', '.xml':'application/xml', '.webm':'video/webm', '.webp':'image/webp', '.weba':'audio/webm', - '.woff': 'font/woff', 'woff2':'font/woff2', '.ttf': 'application/font-ttf', '.eot': 'application/vnd.ms-fontobject', '.otf': 'application/font-otf', - '.wasm': 'application/wasm', '.zip':'application/zip','.xlsx':'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', '.tif':'image/tiff', - '.sh':'application/x-sh', '.csh':'application/x-csh', '.rar':'application/vnd.rar','.ppt':'application/vnd.ms-powerpoint', '.pptx':'application/vnd.openxmlformats-officedocument.presentationml.presentation', - '.odt':'application/vnd.oasis.opendocument.text','.ods':'application/vnd.oasis.opendocument.spreadsheet','.odp':'application/vnd.oasis.opendocument.presentation', - '.mpeg':'video/mpeg','.mjs':'text/javascript','.cjs':'text/javascript','.jsonld':'application/ld+json', '.jar':'application/java-archive', '.ico':'image/vnd.microsoft.icon', - '.gz':'application/gzip', 'epub':'application/epub+zip', '.doc':'application/msword', '.docx':'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - '.csv':'text/csv', '.avi':'video/x-msvideo', '.aac':'audio/aac', '.mpkg':'application/vnd.apple.installer+xml','.oga':'audio/ogg','.ogv':'video/ogg','ogx':'application/ogg', - '.php':'application/x-httpd-php', '.rtf':'application/rtf', '.swf':'application/x-shockwave-flash', '.7z':'application/x-7z-compressed', '.3gp':'video/3gpp' - }; - - constructor( - options?:ServiceOptions, - settings?:ServerProps - ) { - super(options); - this.load(this); - - //console.log(settings); - if(settings) { - this.setupServer(settings); - } - - } - - //on server started - onStarted = (protocol:'http'|'https'|string,host:string,port:number) => { - console.log(`🐱 Node server running at - ${protocol}://${host}:${port}/` - ); - } - - setupServer = ( - options:ServerProps={ - protocol:'http', - host:'localhost', - port:8080, - startpage:'index.html' - }, - requestListener?:http.RequestListener, - onStarted?:()=>void - )=>{ - //console.log(options); - if(options.pages) { - for(const key in options.pages) { - if (typeof options.pages[key] === 'string') { - this.addPage(`${options.port}/${key}`, options.pages[key] as string) - } else if (typeof options.pages[key] === 'object' || typeof options.pages[key] === 'function') { - if((options.pages[key] as any).template) { - (options.pages[key] as any).get = (options.pages[key] as any).template; - } - let rt = `${options.port}/${key}`; - if(key !== '_all') this.load({[rt]:options.pages[key]}); - } - } - } - - //create http or https server - this.setupHTTPserver(options, requestListener, onStarted); - } - - open = this.setupServer; - - //Define the server via http or https - setupHTTPserver = ( - options:(ServerProps & { - certpath?:string, - keypath?:string, - passphrase?:string - })={ - host:'localhost' as string, - port:8080 as number, - startpage:'index.html', - errpage:undefined - }, - requestListener?:http.RequestListener, - onStarted:()=>void = ()=>{this.onStarted('http',options.host,options.port)} - ) => { - - const host = options.host ? options.host : 'localhost'; - const port = options.port ? options.port : 8000; - - if(!host || !port) return; - - const address = `${host}:${port}`; - - if(this.servers[address]) this.terminate(this.servers[address]); - - if(!('keepState' in options)) options.keepState = true; //default true - - const served = { - server:undefined as any, - type:'httpserver', - address, - ...options - } as ServerInfo - - //default requestListener propagates to graphscript - if(!requestListener) - requestListener = ( - request:http.IncomingMessage, - response:http.ServerResponse - ) => { - - let received:any = { - args:{request, response}, - method:request.method, - served - } - - let url = (request as any).url.slice(1); - if(!url) url = '/'; - //console.log(options) - - if(options.debug) { - let time = getHoursAndMinutes(new Date()); - console.log( - time, ' | ', - 'From: ', request.socket?.remoteAddress, - 'For: ', request.url, ' | ', request.method - ); - } - - if(options.pages) { - getPageOptions.call(this, url, received, options.pages, request, response, options.port); - } else received.route = url; - - this.receive(received); - } //default requestListener - - //var http = require('http'); - let server:http.Server|https.Server = undefined as any; - if(options.protocol === 'http') - server = http.createServer( - requestListener - ); - else { - let opts; - if(options.keypath && options.certpath) { - opts = { - key: fs.readFileSync(options.keypath), - cert: fs.readFileSync(options.certpath), - passphrase:options.passphrase - } - server = https.createServer( - opts, - requestListener - ) - } else - console.error('Error, key and/or cert .pem SSL files not provided. See OpenSSL certbot for more info on how to create free SSL certifications, or create your own self-signed one for local development.') - - - } - - if(!server) { - console.error("Server not successfully created."); - return undefined; - } - - served.server = server; - served.terminate = () => { - this.terminate(served); - } - served.service = this; - - // server.on('upgrade', (request, socket, head) => { - // this.onUpgrade(request, socket, head); - // }); - - this.servers[address] = served; - served._id = options._id ? options._id : address; - - - - //SITE AVAILABLE ON PORT: - return new Promise((resolve,reject) => { - let resolved; - // server.on('connection',(socket) => { - // //DDOS protection? - // //Rate limiting? - // }); - server.on('error',(err)=>{ - if(served.onerror) served.onerror(err, served); - else console.error('Server error:', err.toString()); - if(!resolved) reject(err); - }); - server.on('clientError',(err, socket:http.IncomingMessage["socket"]) =>{ - if(served.onerror) served.onerror(err, served); - else console.error(getHoursAndMinutes(new Date()), ' | Server clientError:', err.toString(), ' | From: ', socket.remoteAddress); - if(socket) socket.destroy(); - }); - server.on('tlsClientError',(err, socket:http.IncomingMessage["socket"]) =>{ - if(served.onerror) served.onerror(err, served); - else console.error(getHoursAndMinutes(new Date()), ' | Server tlsClientError: ', err.toString(), ' | From: ', socket.remoteAddress); - if(socket) socket.destroy(); - }); - server.on('upgrade',(request, socket, head) => { - if(served.onupgrade) served.onupgrade(request,socket,head,served); - }); - server.listen( - port, host, - ()=>{ - onStarted(); - if(served.onopen) served.onopen(served); - resolved = true; - resolve(served); - } - ); - }) as Promise ; - } - - transmit = ( //generalized http request. The default will try to post back to the first server in the list - message:any | ServiceMessage, - options:string|{ - protocol:'http'|'https'|string - host:string, - port:number, - method:string, - path?:string, - headers?:{ - [key:string]:any, - 'Content-Type'?:string, - 'Content-Length'?:number - } - }, - ondata?:(chunk:any)=>void, - onend?:()=>void - - ) => { - let input = message; - if(typeof input === 'object' && !input.byteLength) input = JSON.stringify(input); - - if(typeof options === 'string' && message) return this.POST(options,message); - else if(typeof options === 'string') return this.GET(options); - - if(!options) { //fill a generic post request for the first server if none provided - let server = this.servers[Object.keys(this.servers)[0]]; - options = { - protocol:server.protocol as any, - host:server.host, - port:server.port, - method:'POST', - path:message.route, - headers:{ - 'Content-Type':'application/json', - 'Content-Length':input.length - } - }; - } //get first server and use its settings for a generic post request - else if (!options.headers) { - options.headers = { - 'Content-Type':'application/json', - 'Content-Length':input.length - } - } - - return this.request(options,input,ondata,onend); - } - - withResult = ( - response:http.ServerResponse, - result:any, - message:{ - route:string, - args:{request:http.IncomingMessage,response:http.ServerResponse}, //data will be an object containing request, response - method?:string, - served?:ServerInfo //server deets - } - ) => { - if(result && !response.writableEnded && !response.destroyed) { - - let mimeType = 'text/plain'; - - let head = {} as any; - - if(typeof result === 'string') { - let extname = path.extname(result); - - if(extname && fs.existsSync(path.join(process.cwd(),result))) { //load file paths if returned - mimeType = this.mimeTypes[extname] || 'application/octet-stream'; - - result = fs.readFileSync(path.join(process.cwd(),result)); - if(mimeType === 'text/html' && (message.served?.pages?._all || message.served?.pages?.[message.route])) { - let { templateString, headers } = this.injectPageCode(result.toString(),message.route,message.served as any) as any; - result = templateString; - Object.assign(head, headers); - } - } - else if(typeof result === 'string' && result.includes('<') && result.includes('>') && (result.indexOf('<') < result.indexOf('>'))) //probably an html template - { - head['Content-Type'] = 'text/html'; - if(message?.served?.pages?._all || message?.served?.pages?.[message.route]) { - let { templateString, headers } = this.injectPageCode(result,message.route,message.served) as any; - result = templateString; - Object.assign(head, headers); - } - response.writeHead(200,head); - response.end(result,'utf-8'); - return; - } - } else if(typeof result === 'object') { - result = JSON.stringify(result); - mimeType = 'application/json' - } - head['Content-Type'] = mimeType; - response.writeHead(200,head); - response.end(result,'utf-8'); - } else { - try {response.destroy();} catch {} - } - } - - injectPageCode = ( - templateString:string, - url:string, - served:ServerInfo - ):{templateString:string,headers:{[key:string]:any}} => { - if ((served?.pages?.[url] as any)?.inject) { //inject per url - if(typeof (served as any).pages[url].inject === 'object') - templateString = this.buildPage((served as any).pages[url].inject as any, templateString); - else if (typeof (served as any).pages[url].inject === 'function') - templateString += ((served as any).pages[url].inject as any)(); - else if (typeof (served as any).pages[url].inject === 'string' || typeof (served as any).pages[url].inject === 'number') - templateString += (served as any).pages[url].inject; - } - if((served?.pages?._all as any)?.inject) { //any per server - if(typeof (served.pages as any)._all.inject === 'object') - templateString = this.buildPage((served as any).pages._all.inject, templateString); - else if (typeof (served as any).pages._all.inject === 'function') - templateString += (served as any).pages._all.inject(); - else if (typeof (served as any).pages._all.inject === 'string' || typeof (served as any).pages._all.inject === 'number') - templateString += (served as any).pages._all.inject; - } - - let headers = {}; - if((served as any).pages._all.headers) - Object.assign(headers,(served as any).pages._all.headers); - - if((served as any).pages[url].headers) - Object.assign(headers,(served as any).pages[url].headers); - - - return {templateString, headers}; - } - - receive = ( //our fancy request response handler - message:{ - route:string, - args:{request:http.IncomingMessage,response:http.ServerResponse}, //data will be an object containing request, response - method?:string, - node?:string, // alt for route - served?:ServerInfo, //server deets - redirect?:string //if we redirected the route according to page options - } - ) => { - if(this.debug) console.log(message.args.request.method, message.args.request.url); - //console.log(request); //debug - - let result = new Promise((resolve,reject) => { - this.responsePromiseHandler(resolve, reject, message, message.args.request, message.args.response, message.method as string, message.served as ServerInfo); - }).catch((er)=>{ console.error("Request Error:", er); }); - - return result; - } - - //internal - responseOnErrorPromiseHandler = (response:http.ServerResponse, reject, err) => { - if(!response.writableEnded || !response.destroyed ) { - response.statusCode = 400; - response.end(undefined,undefined as any); - reject(err); - } else { - try {response.destroy();} catch {} - reject(err); - } - } - - //internal - getFailedPromiseHandler = (resolve, reject, requestURL, message, response:http.ServerResponse, served) => { - if(response.writableEnded || response.destroyed) reject(requestURL); - if(requestURL == './' || requestURL == served?.startpage) { - let template = `

    Brains@Play Server

    `; //start page dummy - if(served?.pages?._all || served?.pages?.error) { - let {templateString, headers} = this.injectPageCode(template,message.route,served) as any; - template = templateString; - } - response.writeHead(200, { 'Content-Type': 'text/html' }); - response.end(template,'utf-8'); //write some boilerplate server page, we should make this an interactive debug page - resolve(template); - if(served?.keepState) this.setState({[served.address]:template}); - return; - } - else if(this.debug) console.log(`File ${requestURL} does not exist on path!`); - - response.writeHead(500); //set response headers - response.end(undefined,undefined as any); - reject(requestURL); - - //return; - } - - //internal - handleBufferedPostBodyPromiseHandler = (resolve, body, message, response:http.ServerResponse, served) => { - - body = Buffer.concat(body).toString(); //now it's a string - - if(typeof body === 'string') { - let substr = body.substring(0,8); - if(substr.includes('{') || substr.includes('[')) { - if(substr.includes('\\')) body = body.replace(/\\/g,""); - if(body[0] === '"') { body = body.substring(1,body.length-1)}; - body = JSON.parse(body); //parse stringified args, this is safer in a step - } - } - - let route,method,args; - - if(body?.route){ //if arguments were posted - route = body.route; - method = body.method; - args = body.args; - if(!route) { - if(typeof body.route === 'string') if(body.route.includes('/') && body.route.length > 1) body.route = body.route.split('/').pop(); - route = body.route; - } - } - if(!route) { //body post did not provide argument so use the request route - if (message?.route) { - let route = message.route; - method = message.method; - args = message.args; - if(!route) { - if(typeof message.route === 'string') - if(message.route.includes('/') && message.route.length > 1) - message.route = message.route.split('/').pop() as string; - - route = message.route; - } - } - } - let res:any = body; - if(route) { - - if(this.restrict?.[route]) { - try {response.destroy();} catch {} - resolve(res); - } else { - if(body.method) { - res = this.handleMethod(route, method, args); - } - else if (body.node) { - res = this.handleGraphNodeCall(body.node, body.args); - } - else res = this.handleServiceMessage({route, args:args, method:method}); - - if(res instanceof Promise) { - res.then((r) => { - this.withResult(response,r,message); - if(served?.keepState) this.setState({[served.address]:res}); - resolve(res); - }); - } else { - this.withResult(response,res,message); - if(served?.keepState) this.setState({[served.address]:res}); - resolve(res); - } - } - } - else if(!response.writableEnded || !response.destroyed) { - response.statusCode = 200; - response.end(undefined,undefined as any); //posts etc. shouldn't return anything but a 200 usually - resolve(res); - } else { - try {response.destroy();} catch {} - resolve(res); //get requests resolve first and return otherwise this will resolve - } - - } - - //internal - onRequestFileReadPromiseHandler = (error, content, resolve, reject, requestURL, response:http.ServerResponse, message, served:ServerInfo) => { - if (error) { - if(error.code == 'ENOENT') { //page not found: 404 - if(served?.errpage) { - fs.readFile(served.errpage, (er, content) => { - response.writeHead(404, { 'Content-Type': 'text/html' }); //set response headers - - - //add hot reload if specified - // if(process.env.HOTRELOAD && requestURL.endsWith('.html') && cfg.hotreload) { - // content = addHotReloadClient(content,`${cfg.socket_protocol}://${cfg.host}:${cfg.port}/hotreload`); - // } - - if(served.pages?._all || served.pages?.error) { - let {templateString, headers} = this.injectPageCode(content.toString(),message.route,served) as any; - content = templateString; - } - - response.end(content, 'utf-8'); //set response content - reject(content); - //console.log(content); //debug - }); - } - else { - response.writeHead(404, { 'Content-Type': 'text/html' }); - let content = `

    Error: ${error.code}

    ` - if(served?.pages?._all || served?.pages?.[message.route]) { - let {templateString, headers} = this.injectPageCode(content.toString(),message.route,served as any) as any; - content = templateString; - } - response.end(content,'utf-8'); - reject(error.code); - //return; - } - } - else { //other error - response.writeHead(500); //set response headers - response.end('Something went wrong: '+error.code+' ..\n','utf-8'); //set response content - reject(error.code); - //return; - - } - } - else { //file read successfully, serve the content back - - //set content type based on file path extension for the browser to read it properly - var extname = String(path.extname(requestURL)).toLowerCase(); - - var contentType = this.mimeTypes[extname] || 'application/octet-stream'; - - let head = { 'Content-Type': contentType }; - - if(contentType === 'text/html' && (served?.pages?._all || served?.pages?.[message.route])) { - let {templateString, headers} = this.injectPageCode(content.toString(),message.route, served as any) as any; - Object.assign(head, headers); - content = templateString; - } - - response.writeHead(200, head); //set response headers - response.end(content, 'utf-8'); //set response content - resolve(content); - - //console.log(content); //debug - //return; - } - } - - //internal - responsePromiseHandler = (resolve, reject, message, request:http.IncomingMessage, response:http.ServerResponse, method:string, served:ServerInfo) => { - - response.on('error', (err) => { - if(served.debug) { - let time = getHoursAndMinutes(new Date()); - console.error(time,'| Response Error: ', err, ' From: ', request.socket?.remoteAddress, ' For: ', request.url, ' | ', request.method); - } - this.responseOnErrorPromiseHandler(response, reject, err); - request.destroy(); - request.socket?.destroy(); - }); - - if(method === 'GET' || method === 'get') { - //process the request, in this case simply reading a file based on the request url - var requestURL = '.' + request.url; - if(request.url && this.restrict?.[request.url]) reject(request.url); - - if (requestURL == './' && served?.startpage) { //root should point to start page - requestURL = served.startpage; //point to the start page - } - - //lets remove ? mark url extensions for now - if(requestURL.includes('?')) requestURL = requestURL.substring(0,requestURL.indexOf('?')); - - if((request.url !== '/' || served?.startpage) && fs.existsSync(path.join(process.cwd(),requestURL))) { - if(response.writableEnded || response.destroyed) reject(requestURL); - else { - //read the file on the server - fs.readFile(path.join(process.cwd(),requestURL), (error, content) => { - this.onRequestFileReadPromiseHandler(error, content, resolve, reject, requestURL, response, message, served); - }); - } - } else if (message.route) { - let route; - if(served) { - let rt = `${served.port}/${message.route}`; - if(this.__node.nodes.get(rt)) route = rt - } - if(!route && this.__node.nodes.get(message.route)) route = message.route; - - if(route) { - let res:any; - if(message.method) { - res = this.handleMethod(route, message.method, undefined); //these methods are being passed request/response in the data here, post methods will parse the command objects instead while this can be used to get html templates or play with req/res custom callbakcs - } - else if (message.node) { - res = this.handleGraphNodeCall(message.node, undefined); - } - else res = this.handleServiceMessage({route,args:undefined,method:message.method}); - - if(res instanceof Promise) res.then((r) => { - if(served?.keepState) this.setState({[served.address]:res}); - this.withResult(response,r,message); - resolve(res); - - //return; - }) - else if(res) { - if(served?.keepState) this.setState({[served.address]:res}); - this.withResult(response,res,message); - resolve(res); - // return; - } //else we can move on to check the get post - } - else if (message.redirect) { - response.writeHead(301, {'Location':message.redirect}); - response.end(); - resolve(true); - } - else this.getFailedPromiseHandler(resolve,reject,requestURL,message,response,served); - } else this.getFailedPromiseHandler(resolve,reject,requestURL,message,response,served); - } else { - //get post/put/etc body if any - let requestBody; - let timedOut = true; - let timeout; - - request.on('data',(chunk)=>{ //https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/ - if(!requestBody) requestBody = [] as any[]; - requestBody.push(chunk); - if(timedOut) { - timedOut = false; - if(timeout) clearTimeout(timeout); - } - }).on('end',() => { - this.handleBufferedPostBodyPromiseHandler(resolve,requestBody,message,response,served); - }); - - //timeout posts/puts/etc if no body - timeout = setTimeout(() => { - if(timedOut) { - let errMessage = new Error(`Request timed out from | ${request.socket?.remoteAddress} | For: ${request.url} | ${request.method}`); - request.destroy(errMessage); - served.server.emit('clientError', errMessage, request.socket); - if(served.debug) { - console.error(errMessage); - } - reject(errMessage); - } - }, served.timeout ? served.timeout : 1000); //most likely an unhandled method - - } - - - } - - request = ( - options:ReqOptions|any, - send?:any, - ondata?:(chunk:any)=>void, - onend?:()=>void - ) => { - - let client = http; - - if ((options.protocol as string)?.includes('https')) { - client = https as any; - } - - delete options.protocol; - - const req = client.request(options,(res)=>{ - if(ondata) res.on('data',ondata) - if(onend) res.on('end',onend); - }); - - if(options.headers) { - for(const head in options.headers) { - req.setHeader(head,options.headers[head]) - } - } - - if(send) req.write(send); - req.end(); - - return req; - } - - POST = ( - url:string|URL, - data:any, - headers?:{ - 'Content-Type'?:string, - 'Content-Length'?:number, - [key:string]:any - } - ) => { - - let urlstring = url; - if(urlstring instanceof URL) urlstring = url.toString(); - let protocol = urlstring.startsWith('https') ? 'https' : 'http'; - let host, port,path; - let split = urlstring.split('/'); - split.forEach((s) => { - if(s.includes(':')) { - let ss = s.split(':'); - host = ss[0]; port = ss[1]; - } - }); - - if(split.length > 3) { - path = split.slice(3).join('/'); - } - - let req = this.request( - { - protocol, - host, - port, - path, - method:'POST', - headers - }, - data - ); - - return req; - } - - GET = (url:string|URL|http.RequestOptions) => { - return new Promise((resolve, reject) => { - - let client = http; - - let urlstring = url; - if(url instanceof URL) urlstring = url.toString(); - - if ((urlstring as string).includes('https')) { - client = https as any; - } - - client.get(url, (resp) => { - let chunks:any[] = []; - - // A chunk of data has been recieved. - resp.on('data', (chunk) => { - chunks.push(chunk); - }); - - // The whole response has been received. Print out the result. - resp.on('end', () => { - resolve(Buffer.concat(chunks)); - }); - - }).on("error", (err) => { - reject(err); - }); - }); - } - - terminate = (served:string|ServerInfo) => { - if(typeof served === 'string') served = this.servers[served]; - - if(typeof served === 'object') { - served.server.close(); - if(served.onclose) served.onclose(served); - } - } - - getRequestBody(req:http.IncomingMessage) { - let chunks:any[] = []; - return new Promise((resolve,reject) => { - req.on('data',(chunk) => { - chunks.push(chunk); - }).on('end',() => { - resolve(Buffer.concat(chunks)); - }).on('error',(er)=>{ - let errMessage = new Error(`Request timed out from | ${req.socket?.remoteAddress} | For: ${req.url} | ${req.method}`); - req.destroy(errMessage); - reject(errMessage); - }) - }); - } - - //??? just need a way to pass a fake request/response in - // spoofRequest = (url:string, body:any, type:string='json', server:http.Server|https.Server) => { - // return this.receive({ - // route:url, - // args:{request:{ - // url, - // } as http.IncomingMessage, response:{} as http.ServerResponse}, - // method:'GET' - // }) - // } - - addPage = (path:string, template:string) => { //add an html page template as a get - if(typeof template === 'string') { - if(!template.includes(''; //add a root - } - if(typeof this.__node.roots?.[path] === 'object') { - (this.__node.roots[path] as any).get = template; - this.__node.nodes.get(path).get = template; - } - else this.load({ - [path]: { - get:template - } - }); - } - - addHTML = (path:string, template:string) => { //add an html component template e.g. route: component/button then set up logic to chain - if(typeof template === 'string') { - if(!template.includes('<') || (!template.includes('>'))) template = '
    '+template+'
    '; - } - if(typeof this.__node.roots?.[path] === 'object') { - (this.__node.roots[path] as any).get = template; - this.__node.nodes.get(path).get = template; - } - else this.load({ - [path]: { - get:template - } - }); - } - - buildPage = (pageStructure:{[key:string]:{}|null|any} | string[] | string | ((...args:any)=>any), baseTemplate:string) => { //construct a page from available components, child component templates will be inserted before the last '<' symbol or at end of the previous string depending - let result = ``; if(baseTemplate) result += baseTemplate; - let appendTemplate = (obj:{[key:string]:{}|null|any}|string[],r:string|any, res:string) => { - if(!Array.isArray(obj[r]) && typeof obj[r] === 'object') { - for(const key in obj) { - appendTemplate(obj, key, res); //recursive append - } - } else if(this.__node.nodes.get(r)?.get) { - let toAdd = this.__node.nodes.get(r)?.get; - if(typeof toAdd === 'function') { - if(Array.isArray(obj[r])) { - toAdd = toAdd(...obj[r]); - } - else toAdd = toAdd(obj[r]); - } - if(typeof toAdd === 'string') { - let lastDiv = res.lastIndexOf('<'); - if(lastDiv > 0) { - let end = res.substring(lastDiv) - res = res.substring(0,lastDiv) + toAdd + end; - } else res += toAdd; - } - - } else if (this.__node.nodes.get(r)?.__operator) { - let routeresult; - if(this.__node.nodes.get(r)?.__operator) routeresult = this.__node.nodes.get(r).__operator(obj[r]); - if(typeof routeresult === 'string') { - let lastDiv = res.lastIndexOf('<'); - if(lastDiv > 0) { - let end = res.substring(lastDiv) - res = res.substring(0,lastDiv) + routeresult + end; - } - else res += routeresult; - //console.log(lastDiv, res, routeresult) - } - } else if (typeof this.__node.nodes.get(r) === 'string') res += this.__node.nodes.get(r); - return res; - } - - if(Array.isArray(pageStructure)) { - pageStructure.forEach((r)=>{ - result = appendTemplate(pageStructure, r, result); - }) - } else if (typeof pageStructure === 'object') { - for(const r in pageStructure) { - result = appendTemplate(pageStructure, r, result); - } - } else if (typeof pageStructure === 'string') result += pageStructure; - else if (typeof pageStructure === 'function') result += pageStructure(); - return result; - } - - hotreload = (socketURL:string|URL=`http://localhost:8080/wss`, esbuild_cssFileName?:string) => { - if(socketURL instanceof URL) socketURL = socketURL.toString(); - - - const HotReloadClient = (socketUrl, esbuild_cssFileName) => { - //hot reload code injected from backend - //const socketUrl = `ws://${cfg.host}:${cfg.hotreload}`; - let socket = new WebSocket(socketUrl); - - - function reloadLink(file?) { - - let split = file.includes('/') ? file.split('/') : file.split('\\'); - let fname = split[split.length-1]; - - var links = document.getElementsByTagName("link") as any as HTMLLinkElement; - for (var cl in links) - { - var link = links[cl]; - - if(!file || link.href?.includes(fname)) { - let href = link.getAttribute('href') - .split('?')[0]; - - let newHref = href += ""; - - link.setAttribute('href', newHref); - - } - } - } - - - function reloadAsset(file, reloadscripts?, isJs?) { //reloads src tag elements - let split = file.includes('/') ? file.split('/') : file.split('\\'); - let fname = split[split.length-1]; - let elements = document.querySelectorAll('[src]') as any as HTMLScriptElement[]; - let found = false; - for(const s of elements) { - if(s.src.includes(fname)) { //esbuild compiles entire file so just reload app - if(s.tagName === 'SCRIPT' && !reloadscripts) {//&& s.tagName === 'SCRIPT' - window.location.reload(); - return; - } else { - let placeholder = document.createElement('object'); - s.insertAdjacentElement('afterend', placeholder); - s.remove(); - let elm = s.cloneNode(true) as HTMLElement; - placeholder.insertAdjacentElement('beforebegin',elm); - placeholder.remove(); - found = true; - } - } - } - if(!found) window.location.reload(); - } - - - socket.addEventListener('message',(ev) => { - let message = ev.data; - - if(typeof message === 'string' && message.startsWith('{')) { - message = JSON.parse(message); - } - if(message.file) { - let f = message.file; - let rs = message.reloadscripts; - if(f.endsWith('html') || f.endsWith('xml') || f.endsWith('wasm')) { //could add other formats - window.location.reload(); - } else if(f.endsWith('css')) { - if(!esbuild_cssFileName.endsWith('css')) esbuild_cssFileName += '.css'; - reloadLink(esbuild_cssFileName); //reload all css since esbuild typically bundles one file same name as the dist file - } else if (f.endsWith('js') || f.endsWith('ts') || f.endsWith('jsx') || f.endsWith('tsx') || f.endsWith('vue')) { //IDK what other third party formats would be nice to haves - reloadAsset(f, rs); - } else { - //could be an href or src - reloadLink(f); - reloadAsset(f); - } - } - }); - - - socket.addEventListener('close',()=>{ - // Then the server has been turned off, - // either due to file-change-triggered reboot, - // or to truly being turned off. - - // Attempt to re-establish a connection until it works, - // failing after a few seconds (at that point things are likely - // turned off/permanantly broken instead of rebooting) - const interAttemptTimeoutMilliseconds = 100; - const maxDisconnectedTimeMilliseconds = 3000; - const maxAttempts = Math.round(maxDisconnectedTimeMilliseconds/interAttemptTimeoutMilliseconds); - let attempts = 0; - const reloadIfCanConnect = ()=>{ - attempts ++ ; - if(attempts > maxAttempts){ - console.error("Could not reconnect to dev server."); - return; - } - socket = new WebSocket(socketUrl); - socket.onerror = (er) => { - console.error(`Hot reload port disconnected, will reload on reconnected. Attempt ${attempts} of ${maxAttempts}`); - } - socket.addEventListener('error',()=>{ - setTimeout(reloadIfCanConnect,interAttemptTimeoutMilliseconds); - }); - socket.addEventListener('open',()=>{ - location.reload(); - }); - }; - reloadIfCanConnect(); - }); - } - - return ` - - `; - } - - pwa = (pwaName = "PWA", cacheExpirationDays=4/24, serviceWorkerUrl="service-worker.js") => { - - //check for serviceWorkerUrl, if none install the default template - if(!fs.existsSync(serviceWorkerUrl)) { - fs.writeFileSync(path.join(process.cwd(),serviceWorkerUrl), defaultServiceWorker(cacheExpirationDays)); - } - if(!fs.existsSync('manifest.webmanifest')) { - fs.writeFileSync(path.join(process.cwd(),'/manifest.webmanifest'), defaultManifest(pwaName)); - } - - function ServiceWorkerInstaller(serviceWorkerUrl) { - // Check that service workers are supported - - if(!Array.from(document.head.querySelectorAll('link')).find((elm:HTMLLinkElement) => { - if(elm.href.includes('manifest')) return true; - })) { - document.head.insertAdjacentHTML('beforeend',``) - } - - const isLocalhost = Boolean( - window.location.hostname === 'localhost' || - // [::1] is the IPv6 localhost address. - window.location.hostname === '[::1]' || - // 127.0.0.1/8 is considered localhost for IPv4. - window.location.hostname.match( - /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ - ) - ); - - function registerSW() { - navigator.serviceWorker - .register(serviceWorkerUrl) - .then(registration => { - registration.onupdatefound = () => { - const installingWorker = registration.installing; - if (installingWorker == null) { - return; - } - installingWorker.onstatechange = () => { - if (installingWorker.state === 'installed') { - if (navigator.serviceWorker.controller) { - // At this point, the updated pre-cached content has been fetched, - // but the previous service worker will still serve the older - // content until all client tabs are closed. - console.log( - 'New content is available and will be used when all tabs for this page are closed.' - ); - - } else { - // At this point, everything has been pre-cached. - // It's the perfect time to display a - // "Content is cached for offline use." message. - console.log('Content is cached for offline use.'); - - } - } - }; - }; - }) - .catch(error => { - console.error('Error during service worker registration:', error); - }); - } - - if ("serviceWorker" in navigator) addEventListener('load', () => { - if(isLocalhost) { - // Add some additional logging to localhost, pointing developers to the - - // Check if the service worker can be found. If it can't reload the page. - fetch(serviceWorkerUrl) - .then(response => { - // Ensure service worker exists, and that we really are getting a JS file. - const contentType = response.headers.get('content-type'); - if ( - response.status === 404 || - (contentType != null && contentType.indexOf('javascript') === -1) - ) { - // No service worker found. Probably a different app. Reload the page. - navigator.serviceWorker.ready.then(registration => { - registration.unregister().then(() => { - window.location.reload(); - }); - }); - } else { - // Service worker found. Proceed as normal. - registerSW(); - } - }) - .catch(() => { - console.log( - 'No internet connection found. App is running in offline mode.' - ); - }); - - // service worker/PWA documentation. - navigator.serviceWorker.ready.then(() => { - console.log('This web app is being served cache-first by a service worker.'); - }); - } - else { - registerSW(); - } - }); - } - - return ` - - `; - } - -} - - - -function getPageOptions(url, received, pages, request, response, port) { - let pageOptions = pages[url]; - let key = url; - //check alternative page definition keys - if(!pageOptions) { - let url2 = '/'+url; // e.g. '/home' - pageOptions = pages[url2]; - key = url2; - if(!pageOptions && !path.extname(url)) { - let split = url.split('/'); - key = split[0]+'/*'; - if(pages[key]) { // e.g. /* or home/* - pageOptions = pages[key]; - received.route = key; - request.url = key; - } else { - // e.g. /home with /* specified, or /home/* etc. - let spl = url2.split('/'); //split the modified string so the beginning is a blank string - spl[spl.length-1] = ''; //replace with empty string e.g. /home -> ['',''] - key = spl.join('/')+'*'; //now merge url - if(pages[key]) { - pageOptions = pages[key]; - received.route = key; - request.url = key; - } - } - } else { - received.route = url2; - request.url = url2; - - } - } else { - received.route = url; - request.url = url; - } - if(typeof pageOptions === 'object') { - if((pageOptions as any).redirect) { - url = (pageOptions as any).redirect; - received.redirect = url; - received.route = url; - } - if((pageOptions as any).onrequest) { - if(typeof (pageOptions as any).onrequest === 'string') { - (pageOptions as any).onrequest = this.__node.nodes.get((pageOptions as any).onrequest); - } - if(typeof (pageOptions as any).onrequest === 'object') { - if((pageOptions as any).onrequest.__operator) { - ((pageOptions as any).onrequest as GraphNode).__operator(pageOptions, request, response); - } - } else if(typeof (pageOptions as any).onrequest === 'function') { - (pageOptions as any).onrequest( - this, - this.__node.nodes.get(`${port}/${key}`), - request, - response - ); - } - } - } - - return pageOptions; -} - - - - -function getHoursAndMinutes(date) { - let hours = date.getHours(); - let minutes = date.getMinutes(); - - // Convert the hours and minutes to two digits - hours = hours < 10 ? '0' + hours : hours; - minutes = minutes < 10 ? '0' + minutes : minutes; - - return `${hours}:${minutes}`; -} diff --git a/src/services/http/boilerplate/index.ts b/src/services/http/boilerplate/index.ts deleted file mode 100644 index 40fd5c34..00000000 --- a/src/services/http/boilerplate/index.ts +++ /dev/null @@ -1,133 +0,0 @@ - -export function htmlBodyBoilerPlate(html:string|string[]) { - let template = `` - if(Array.isArray(html)) { - html.forEach((src) => { - template += src; - }) - } else { - template += html; - } - template += `` - return template; -} - -export function scriptBoilerPlate(scripts:string|string[]) { - let template = `` - if(Array.isArray(scripts)) { - scripts.forEach((src) => { - template += ``; - }) - } else { - template += ``; - } - template += `` - return template; -} - - - -export const defaultServiceWorker = function (cacheExpirationDays=4/24) { //service-worker.js template for PWA - return `//https://github.com/ibrahima92/pwa-with-vanilla-js - -//https://github.com/ibrahima92/pwa-with-vanilla-js -let cacheName = 'pwa-assets'; -const assets = [ - "/", - "/index.html", - "/dist/index.css", //alt default paths - "/dist/index.js", - '/favicon.ico' -]; - -let cacheExpiration = 1000 * 60 * //seconds - 60 * //minutes - 24 * //hours - ${cacheExpirationDays}; //days - -let isValid = function (response) { - if (!response) return false; - var fetched = response.headers.get('sw-fetched-on'); - if (fetched && (!navigator.onLine || (parseFloat(fetched) + (cacheExpiration)) > new Date().getTime())) - return true; - return false; -}; - -self.addEventListener("install", installEvent => { - installEvent.waitUntil( - caches.open(cacheName).then(cache => { - cache.addAll(assets); - }) - ); -}); - -self.addEventListener("fetch", fetchEvent => { //https://gomakethings.com/how-to-set-an-expiration-date-for-items-in-a-service-worker-cache/ - fetchEvent.respondWith( - caches.match(fetchEvent.request).then(function (response) { - - // If there's a cached API and it's still valid, use it - if (isValid(response)) { - return response; - } - - // Otherwise, make a fresh API call - if(response && !assets.includes(fetchEvent.request.url)) return response; - // Otherwise, make a fresh API call - else return fetch(fetchEvent.request).then(function (response) { - - // Cache for offline access - if(assets.includes(fetchEvent.request.url)){ - var copy = response.clone(); - fetchEvent.waitUntil(caches.open(cacheName).then(function (cache) { - var headers = new Headers(copy.headers); - headers.append('sw-fetched-on', new Date().getTime()); - return copy.blob().then(function (body) { - return cache.put(fetchEvent.request, new Response(body, { - status: copy.status ? copy.status : 200, - statusText: copy.statusText, - headers: headers - })); - }); - })); - } - - // Return the requested file - return response; - - }) - // .catch(function (error) { - // return caches.match(request).then(function (response) { //fallback to offline cache - // return response || caches.match('/offline.json'); //todo: figure out what is supposed to go in offline.json (https://gomakethings.com/how-to-set-an-expiration-date-for-items-in-a-service-worker-cache/) - // }); - // }); - })); -}); - -`; -} - -//todo: make this even more customizable, just being lazy for now -export const defaultManifest = (pwaName = "PWA") => { - return `{ - "short_name": "${pwaName}", - "name": "${pwaName}", - "start_url": "/", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff", - "description": "${pwaName} Test", - "lang": "en-US", - "permissions": [ - "storage" - ], - "icons":[{ - "src": "./assets/logo196.png", - "sizes": "196x196" - }, - { - "src": "./assets/logo512.png", - "sizes": "512x512" - }] -}` //images are REQUIRED for PWA to work -} - diff --git a/src/services/http/boilerplate/pwa/README.md b/src/services/http/boilerplate/pwa/README.md deleted file mode 100644 index febdc916..00000000 --- a/src/services/http/boilerplate/pwa/README.md +++ /dev/null @@ -1,26 +0,0 @@ -## [Instructions](https://dev.to/digitalplayer1125/custom-service-worker-in-any-app-with-esbuild-3020) - - -### Compile & inject: - -Copy manifest.webmanifest to main folder of your app and customize. - -Code to paste or inject into html pages (our server does this if you specify the service-worker path in the server_settings.js file): -```html - - - - - - - -``` \ No newline at end of file diff --git a/src/services/http/boilerplate/pwa/manifest.webmanifest b/src/services/http/boilerplate/pwa/manifest.webmanifest deleted file mode 100644 index 0111fba1..00000000 --- a/src/services/http/boilerplate/pwa/manifest.webmanifest +++ /dev/null @@ -1,22 +0,0 @@ -{ - "short_name": "PWA", - "name": "PWA", - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff", - "description": "PWA Test", - "lang": "en-US", - "permissions": [ - "storage" - ], - "icons":[{ - "src": "./assets/logo196.png", - "sizes": "196x196" - }, - { - "src": "./assets/logo512.png", - "sizes": "512x512" - } - ] - } \ No newline at end of file diff --git a/src/services/http/boilerplate/pwa/service-worker-complex.js b/src/services/http/boilerplate/pwa/service-worker-complex.js deleted file mode 100644 index 4e841407..00000000 --- a/src/services/http/boilerplate/pwa/service-worker-complex.js +++ /dev/null @@ -1,120 +0,0 @@ -// This optional code is used to register a service worker. -// register() is not called by default. - -// This lets the app load faster on subsequent visits in production, and gives -// it offline capabilities. However, it also means that developers (and users) -// will only see deployed updates on subsequent visits to a page, after all the -// existing tabs open on the page have been closed, since previously cached -// resources are updated in the background. - -const isLocalhost = Boolean( - window.location.hostname === 'localhost' || - // [::1] is the IPv6 localhost address. - window.location.hostname === '[::1]' || - // 127.0.0.1/8 is considered localhost for IPv4. - window.location.hostname.match( - /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ - ) -); - -export function register(config) { - if ('serviceWorker' in navigator) { - window.addEventListener('load', () => { - const swUrl = "service-worker.js"; - - if (isLocalhost) { - // This is running on localhost. Let's check if a service worker still exists or not. - checkValidServiceWorker(swUrl, config); - - // Add some additional logging to localhost, pointing developers to the - // service worker/PWA documentation. - navigator.serviceWorker.ready.then(() => { - console.log('This web app is being served cache-first by a service worker.'); - }); - } else { - // Is not localhost. Just register service worker - registerValidSW(swUrl, config); - } - }); - } -} - -function registerValidSW(swUrl, config) { - navigator.serviceWorker - .register(swUrl) - .then(registration => { - registration.onupdatefound = () => { - const installingWorker = registration.installing; - if (installingWorker == null) { - return; - } - installingWorker.onstatechange = () => { - if (installingWorker.state === 'installed') { - if (navigator.serviceWorker.controller) { - // At this point, the updated pre-cached content has been fetched, - // but the previous service worker will still serve the older - // content until all client tabs are closed. - console.log( - 'New content is available and will be used when all ' + - 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' - ); - - // Execute callback - if (config && config.onUpdate) { - config.onUpdate(registration); - } - } else { - // At this point, everything has been pre-cached. - // It's the perfect time to display a - // "Content is cached for offline use." message. - console.log('Content is cached for offline use.'); - - // Execute callback - if (config && config.onSuccess) { - config.onSuccess(registration); - } - } - } - }; - }; - }) - .catch(error => { - console.error('Error during service worker registration:', error); - }); -} - -function checkValidServiceWorker(swUrl, config) { - // Check if the service worker can be found. If it can't reload the page. - fetch(swUrl) - .then(response => { - // Ensure service worker exists, and that we really are getting a JS file. - const contentType = response.headers.get('content-type'); - if ( - response.status === 404 || - (contentType != null && contentType.indexOf('javascript') === -1) - ) { - // No service worker found. Probably a different app. Reload the page. - navigator.serviceWorker.ready.then(registration => { - registration.unregister().then(() => { - window.location.reload(); - }); - }); - } else { - // Service worker found. Proceed as normal. - registerValidSW(swUrl, config); - } - }) - .catch(() => { - console.log( - 'No internet connection found. App is running in offline mode.' - ); - }); -} - -export function unregister() { - if ('serviceWorker' in navigator) { - navigator.serviceWorker.ready.then(registration => { - registration.unregister(); - }); - } -} diff --git a/src/services/http/boilerplate/pwa/service-worker.js b/src/services/http/boilerplate/pwa/service-worker.js deleted file mode 100644 index 5aad496f..00000000 --- a/src/services/http/boilerplate/pwa/service-worker.js +++ /dev/null @@ -1,81 +0,0 @@ - -//https://github.com/ibrahima92/pwa-with-vanilla-js -const version = '1.0'; // Increment this version to update all caches -const cacheNamePrefix = 'pwa-assets-'; -const cacheName = `${cacheNamePrefix}${version}`; -const assets = [ - "/", - "/index.html", - "/dist/index.css", //alt default paths - "/dist/index.js", - '/favicon.ico' -]; - -let cacheExpiration = 1000 * 60 * //seconds - 60 * //minutes - 24 * //hours - (4/24); //days (4 hours in this case) - -// Function to check if a cache name represents an expired cache -let isValidCacheName = function(cacheName) { - const cacheTimestamp = parseInt(cacheName.split('-').pop()); - const currentTime = new Date().getTime(); - return currentTime < cacheTimestamp + cacheExpiration; -}; - -self.addEventListener('fetch', event => { - event.respondWith( - caches.match(event.request).then(cachedResponse => { - - // Check if online; if not, return cached response immediately - if (!navigator.onLine) { - return cachedResponse; - } - - // Serve from cache if valid, otherwise fetch from network - return caches.keys().then(cacheNames => { - const relevantCacheName = cacheNames.find(name => name.startsWith(cacheNamePrefix)); - if (relevantCacheName && isValidCacheName(relevantCacheName)) { - return cachedResponse || fetchAndUpdateCache(event.request, relevantCacheName); - } else { - return fetchAndUpdateCache(event.request, cacheName); - } - }); - }) - ); -}); - -function fetchAndUpdateCache(request, cacheName) { - return fetch(request).then(response => { - // Only cache GET requests to whitelisted assets - if (request.method === 'GET' && assets.includes(new URL(request.url).pathname)) { - const responseToCache = response.clone(); - caches.open(cacheName).then(cache => { - cache.put(request, responseToCache); - }); - } - return response; - }).catch(() => { - // Attempt to serve from cache if the network request fails - return caches.match(request); - }); -} - -self.addEventListener('activate', event => { - event.waitUntil( - caches.keys().then(cacheNames => { - return Promise.all( - cacheNames.filter(name => name.startsWith(cacheNamePrefix) && !isValidCacheName(name)) - .map(invalidCacheName => caches.delete(invalidCacheName)) - ); - }).then(() => self.clients.claim()) - ); -}); - -self.addEventListener('install', event => { - event.waitUntil( - caches.open(cacheName) - .then(cache => cache.addAll(assets)) - .then(() => self.skipWaiting()) - ); -}); diff --git a/src/services/remote/remote.routes.ts b/src/services/remote/remote.routes.ts deleted file mode 100644 index e7f98bc7..00000000 --- a/src/services/remote/remote.routes.ts +++ /dev/null @@ -1,427 +0,0 @@ -import { getFnParamNames, getFunctionHead, parseFunctionFromText, recursivelyStringifyFunctions, stringifyWithCircularRefs, stringifyWithFunctionsAndCircularRefs } from "../utils" -import { Graph, GraphNodeProperties, Listener } from "../../core/Graph" -import { methodstrings } from "../../loaders/methodstrings"; -import { recursivelyAssign } from "../Service"; - -export const nodeTemplates = {}; - -//Contains evals and other things you probably don't want wide open on an API, for running graphs over remote contexts -export const remoteGraphRoutes = { - - transferNode: ( - properties:Function|(GraphNodeProperties & { __methods?:{[key:string]:Function|string} })|string, - connection:any | Worker | WebSocket, //put any info connection template in with - name?:string - ) => { - let str; - if(typeof properties === 'object') { - if(!properties.__node) { properties.__node = {}; } - if(name) properties.__node.tag = name; - - for(const key in properties) { - if(typeof properties[key] === 'function') { - if(!properties.__methods) properties.__methods = {}; - properties.__methods[key] = properties[key].toString(); - } - } - - str = recursivelyStringifyFunctions(properties); - - } else if (typeof properties === 'function') str = properties.toString(); - else if (typeof properties === 'string') str = properties; - if(str) { - - if((connection as any).run) - return (connection as any).run('setNode',[str]); - else if ((connection as Worker).postMessage) { - (connection as Worker).postMessage({route:'setNode', args:str},undefined); - return new Promise ((r) => r(name)); - } else if ((connection as WebSocket).send) { - (connection as WebSocket).send(JSON.stringify({route:'setNode', args:str})); - return new Promise ((r) => r(name)); - } - } - - }, - - setNode:function ( - properties:string|((...args:[])=>any)|(GraphNodeProperties & { __methods?:{[key:string]:Function|string} }), name?:string - ) { - //console.log('setting node', properties); - if(typeof properties === 'object') { - if(properties.__methods) { //stringified methods - if(!this.__node.graph.__node.loaders.methodstrings) { - this.__node.graph.__node.loaders.methodstrings = methodstrings; - } - } - } - if(typeof properties === 'string') { - let f = parseFunctionFromText(properties); - if(typeof f === 'function') properties = {__operator:f, __node:{tag:name ? name : f.name}}; - else { - f = JSON.parse(properties); - if(typeof f === 'object') properties = f; - } - } - if(typeof properties === 'object' || typeof properties === 'function') { - let template = {} as GraphNodeProperties; - if(typeof properties === 'object') Object.assign(template,properties); - else template.__operator = properties; - let node = this.__node.graph.add(template); - if(node) { - nodeTemplates[node.__node.tag] = template; //can just instantiate this again later - return node.__node?.tag; - } else return false; - } else return false; - }, - - makeNodeTransferrable:function ( - properties:GraphNodeProperties, - name?:string - ) { - if(!properties.__node) { properties.__node = {}; } - if(name) properties.__node.tag = name; - - for(const key in properties) { - if(typeof properties[key] === 'function') { - if(!properties.__methods) properties.__methods = {}; - properties.__methods[key] = properties[key].toString(); - } - } - - const str = recursivelyStringifyFunctions(properties); - - return str; - }, - - - getListenerJSON: function () { //reproducible json prototype, apply as __listeners in graph.load({__listeners:{...}}) - const triggers = this.__node.state.triggers; - let result = {} as any; - for(const key in triggers) { - triggers[key].forEach((trigger) => { - let t = trigger as any as Listener; - if(!result[t.target]) result[t.target] = {}; - let l = t.source + (t.key ? '.' + t.key : ''); - result[t.target][l] = { - __callback:t.__callback - } - if(t.__args) result[t.target][l].__args = t.__args; - if(t.subInput) result[t.target][l].subInput = t.subInput; - - }) - } - return result; - }, - - makeRootTransferrable: function () { - let roots = {}; - for(const r in this.__node.graph.__node.roots) { - let properties = this.__node.graph.__node.roots[r]; - if(typeof properties === 'function') { - roots[r] = properties.toString(); - } else if (typeof properties !== 'object') { - roots[r] = properties; - } else { - roots[r] = {}; - let keys = Object.getOwnPropertyNames(properties).filter((v) => !objProps.includes(v)); - //console.log([...keys]); - let nonArrowFunctions = Object.getOwnPropertyNames(Object.getPrototypeOf(properties)).filter((v) => !objProps.includes(v)); - keys.push(...nonArrowFunctions); //this is weird but it works - for(const key of keys) { - if(typeof properties[key] === 'function') { - roots[r][key] = properties[key].toString(); - } else if(typeof properties[key] === 'object') - roots[r][key] = stringifyWithFunctionsAndCircularRefs(properties[key]); - else roots[r][key] = properties[key]; - } - } - } - - return roots; - }, - - setTemplate:function( - properties:string|((...args:[])=>any)|(GraphNodeProperties & { __methods?:{[key:string]:Function|string} }), - name?:string - ) { - if(typeof properties === 'object') { - if(properties.__methods) { //stringified methods - if(!this.__node.graph.__node.loaders.methodstrings) { - this.__node.graph.__node.loaders.methodstrings = methodstrings; - } - } - } - if(typeof properties === 'string') { - let f = parseFunctionFromText(properties); - if(typeof f === 'function') { - if(!name) name = f.name; - properties = {__operator:f, __node:{tag:name}}; - } - else { - f = JSON.parse(properties); - if(typeof f === 'object') { - properties = f; - if(!name && f.__node?.tag) name = f.__node.tag; - } - } - } - if(!name) name = `node${Math.floor(Math.random()*1000000000000000)}` - if(typeof properties === 'object' || typeof properties === 'function') { - nodeTemplates[name] = properties; - return name; - } else return false; - }, - - loadFromTemplate:function( - templateName:string, - name?:string, - properties?:{[key:string]:any} - ) { - if(nodeTemplates[templateName]) { - let cpy = recursivelyAssign({},nodeTemplates[templateName]); - if(name) { - if(!cpy.__node) cpy.__node = {}; - cpy.__node.tag = name; - } - if(properties) Object.assign(cpy,properties); - let node = this.__node.graph.add(cpy); - return node.__node.tag; - } - }, - - setMethod:function( - nodeTag:string, - fn:string|((...args:[])=>any), - methodKey?:string - ){ //set a method on a route - //console.log(fn, fnName) - if(typeof fn === 'string') { - let f = parseFunctionFromText(fn); - if(typeof f === 'function') fn = f; - } - //console.log(fn); - if(!methodKey && typeof fn === 'function') methodKey = fn.name; - if(this.__node.graph.get(nodeTag)) { - this.__node.graph.get(nodeTag)[methodKey] = fn; //overwrite method - } - else (this.__node.graph as Graph).add({__node:{tag:methodKey,[methodKey]:fn}}); - //console.log(this) - return true; - }, - - assignNode:function(nodeTag:string,source:{[key:string]:any}) { //set values on a node - //console.log(fn, fnName) - if(this.__node.graph.get(nodeTag) && typeof source === 'object') { - Object.assign(this.__node.graph.get(nodeTag),source); - } - }, - - getNodeProperties:function(nodeTag:string) { - let node = this.__node.graph.get(nodeTag); - if(node) { - let properties = Object.getOwnPropertyNames(node); - let result = {}; - for(const key of properties) { - if(typeof node[key] === 'function') { - let str = node[key].toString() as string; - let isNative = str.indexOf('[native code]') > -1; - result[key] = { type:'function', args:getFnParamNames(node[key]), native:isNative} - } - else result[key] = typeof node[key]; - } - return result; - } return undefined; - }, - - proxyRemoteNode : function ( - name:string, - connection:any, //put any info connection template in with a .run function, does not work with base workers/sockets etc as it relies on our promise system - ):Promise { - - return new Promise((res,rej) => { - connection.run('getNodeProperties',name).then((props:any)=>{ - let proxy = {}; - if(typeof props === 'object') { - for(const key in props) { - if(props[key]?.type === 'function') { - if(props[key].native || props[key].args) { - proxy[key] = (...args:any[]) => { - return new Promise((r) => { - connection.run( - name, - args, - key - ).then(r); - }); - } - } - //else if(props[key].args) { //not easy to set arguments from remote, anonymous bound functions are unparseable - // let scope = { - // connection - // } as any; - // proxy[key] = new Function( - // ...props[key].args,//...args:any[]) => { //no way to transfer args to this function? - // `return new Promise((r) => { - // this.connection.run( - // ${name}, - // [${props[key].args.join(',')}], - // ${key} - // ).then(r); - // });` - // ).bind(scope); //will show up as "bound anonymous" but the arguments are parseable - // //console.log(getFunctionHead(proxy[key].toString()).split('(')[1].split(')')[0]); - //} - else { - proxy[key] = () => { - return new Promise((r) => { - connection.run( - name, - undefined, - key - ).then(r); - }); - } - } - } else { - Object.defineProperty( - proxy, - key, - { - get:()=>{ - return new Promise((r)=>{ - connection.run( - name, - undefined, - key - ).then((r)) - }); - }, - set:(value) => { - connection.post( - name, - value, - key - ) - }, - configurable:true, - enumerable:true - } - ) - } - } - } - - res(proxy); - - }); - }); - }, - - transferClass:( - classObj:any, - connection:any | Worker | WebSocket, - className?:string - )=>{ //send a class over a remote service - if(typeof classObj === 'object') { - let str = classObj.toString();//needs to be a class prototype - let message = {route:'receiveClass',args:[str,className]}; - if((connection as any).run) - return (connection as any).run('receiveClass',[str,className]); - else if ((connection as Worker).postMessage) { - (connection as Worker).postMessage({route:'receiveClass', args:[str,className]},undefined); - return new Promise ((r) => r(name)); - } else if ((connection as WebSocket).send) { - (connection as WebSocket).send(JSON.stringify({route:'receiveClass', args:[str,className]})); - return new Promise ((r) => r(name)); - } - return message; - } - return false; - }, - - receiveClass:function(stringified:string, className?:string){ //eval a class string and set it as a key on the local graph by class name, so this.__node.graph.method exists - if(typeof stringified === 'string') { - //console.log(stringified) - if(stringified.indexOf('class') === 0) { - let cls = (0,eval)('('+stringified+')'); - let name = className; - - if(!name) - name = cls.name; //get classname - this.__node.graph[name] = cls; - - return true; - } - } - return false; - }, - - //requires unsafe service to load on other end - transferFunction: (fn:Function, connection:any | Worker | WebSocket, fnName?:string) => { - if(!fnName) fnName = fn.name; - let str = fn.toString();//needs to be a class prototype - let message = {route:'setNode',args:[str,fnName]}; - if((connection as any).run) - return (connection as any).run('setNode',[str,fnName]); - else if ((connection as Worker).postMessage) { - (connection as Worker).postMessage({route:'setNode', args:[str,fnName]},undefined); - return new Promise ((r) => r(fnName)); - } else if ((connection as WebSocket).send) { - (connection as WebSocket).send(JSON.stringify({route:'setNode', args:[str,fnName]})); - return new Promise ((r) => r(fnName)); - } - return message; - }, - - setGlobal:(key:string, value:any) => { //set a value on the globalThis scope - globalThis[key] = value; - return true; - }, - - assignGlobalObject:(target:string, source:{[key:string]:any}) => { //assign a value on an object on the globalThis scope - if(!globalThis[target]) return false; - if(typeof source === 'object') Object.assign(globalThis[target],source); - return true; - }, - - setValue:function(key:string, value:any) { //set a value on the graph scope - this.__node.graph[key] = value; - return true; - }, - - assignObject:function(target:string, source:{[key:string]:any}){ //assign a value on an object on the globalThis scope - if(!this.__node.graph[target]) return false; - if(typeof source === 'object') Object.assign( this.__node.graph[target],source); - return true; - }, - - setGlobalFunction:(fn:any, fnName?:string) => { //set a value on the globalThis scope - if(typeof fn === 'string') fn = parseFunctionFromText(fn); - //console.log(fn); - if(typeof fn === 'function') { - if(!fnName) fnName = fn.name; - globalThis[fnName] = fn; - //console.log(this) - return true; - } - return false; - }, - - setGraphFunction:function(fn:any, fnName?:string){ //set a value on the graph scope - if(typeof fn === 'string') fn = parseFunctionFromText(fn); - //console.log(fn); - if(typeof fn === 'function') { - if(!fnName) fnName = fn.name; - this.__node.graph[fnName] = fn; - //console.log(this) - return true; - } - return false; - } - -} - -let objProps = Object.getOwnPropertyNames(Object.getPrototypeOf({})); - -//console.log(objProps); \ No newline at end of file diff --git a/src/services/todo/RemoteService.ts b/src/services/todo/RemoteService.ts deleted file mode 100644 index f2995ac5..00000000 --- a/src/services/todo/RemoteService.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { isNativeClass } from '../../core/Graph' -import {Service, ServiceMessage} from '../Service' - -//trying to generalize e.g. the Socket and Worker classes - -export class RemoteService extends Service { - - endpoints:{ - [key:string]:{ - connection:any, - postCmd:Function, - class:any, - classArgs?:any - } - } - - class:any; - onmessage:string; - close:string; - onerror?:string; - onclose?:string; - onmessageTransform?:(message:any) => any; - onerrorTransform?:(er:any) => any; - post:string; - - createConnection = (instanceArgs:any[], settings?:{[key:string]:Function}) => { - - let info = { - _id: `connection${Math.floor(Math.random()*1000000000000000)}` - } as any; - - if(typeof this.class === 'function') { - if(isNativeClass(this.class)) { - info.connection = new this.class(...instanceArgs); - } else { - info.connection = this.class(...instanceArgs); - } - } else info.connection = this.class; - - - //defaults - if(this.onmessage) { - info.connection[this.onmessage] = (message:any) => { - if(this.onmessageTransform) { - message = this.onmessageTransform(message); - } - this.receive(message); - this.setState({[info._id]:message}); - } - } - - if(this.onerror) { - info.connection[this.onerror] = (er) => { - if(this.onerrorTransform) er = this.onerrorTransform(er); - } - } - - //overwrite callbacks with settings - if(settings) { - for(const key in settings) { - info.connection[key] = settings[key]; - } - } - - return info; - } - - __wrapConnection = (info:any) => { - info.send = () => {}; - info.post = () => {}; - info.run = () => {}; - info.request = () => {}; - info.subscribe = () => {}; - info.unsubscribe = () => {}; - info.start = async () => {}; - info.stop = async () => {}; - info.terminate = () => {}; - return info; - } - - transmit = (message:ServiceMessage|any, endpoint:string|any, transformer?:(message:any,endpoint:any) => any[] ) => { - - // put in transformer - // if(!transfer) { - // transfer = this.getTransferable(message); //automatically transfer arraybuffers - // } - if(typeof endpoint === 'string') { - endpoint = this.endpoints[endpoint]; - } - - if(typeof endpoint === 'object') { - if(transformer) { - let args = transformer(message,endpoint) as any[]; - endpoint.connection[endpoint.post](...args); - } else { - endpoint.connection[endpoint.post](message); - } - - return true; - } - - return false; - } - -} \ No newline at end of file diff --git a/src/services/utils.ts b/src/services/utils.ts deleted file mode 100644 index 17cad895..00000000 --- a/src/services/utils.ts +++ /dev/null @@ -1,367 +0,0 @@ - - -export let recursivelyStringifyFunctions = (obj:{[key:string]:any}) => { - let cpy = {}; - for(const key in obj) { - if(typeof obj[key] === 'object') { - cpy[key] = recursivelyStringifyFunctions(obj[key]); - } - else if (typeof obj[key] === 'function') { - cpy[key] = obj[key].toString(); - } else cpy[key] = obj[key]; - } - return cpy; -} - -export function getFnParamNames(fn){ - if(typeof fn !== 'string') fn = fn.toString(); - const arrowMatch = fn.match(/\(?[^]*?\)?\s*=>/) - if (arrowMatch) return arrowMatch[0].replace(/[()\s]/gi,'').replace('=>','').split(',') - const match = fn.match(/\([^]*?\)/) - return match ? match[0].replace(/[()\s]/gi,'').split(',') : [] -} - -export let getFunctionHead = (methodString) => { - let startindex = methodString.indexOf('=>')+1; - if(startindex <= 0) { - startindex = methodString.indexOf('){'); - } - if(startindex <= 0) { - startindex = methodString.indexOf(') {'); - } - return methodString.slice(0, methodString.indexOf('{',startindex) + 1); -} - -export function parseFunctionFromText(method='') { - //Get the text inside of a function (regular or arrow); - let getFunctionBody = (methodString) => { - return methodString.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i, '$2$3$4'); - } - - let newFuncHead = getFunctionHead(method); - let newFuncBody = getFunctionBody(method); - - let newFunc; - if (newFuncHead.includes('function')) { - let varName = newFuncHead.substring(newFuncHead.indexOf('(')+1,newFuncHead.lastIndexOf(')')); - newFunc = new Function(varName, newFuncBody); - } else { - if (newFuncHead.substring(0, 6) === newFuncBody.substring(0, 6)) { - let varName = newFuncHead.substring(newFuncHead.indexOf('(')+1,newFuncHead.lastIndexOf(')')); - newFunc = new Function(varName, newFuncBody.substring(newFuncBody.indexOf('{') + 1, newFuncBody.length - 1)); - } else { - try { newFunc = (0, eval)(method); } catch { } // Just evaluate the method - } - } - - return newFunc; - -} - -//parse stringified object with stringified functions -export function reconstructObject(json:string|{[x:string]: any}='{}') { - try{ - - // Allow raw object - let parsed = (typeof json === 'string') ? JSON.parse(json) : json - - const parseObj = (obj) => { - for(const prop in obj) { - if(typeof obj[prop] === 'string') { - let funcParsed = parseFunctionFromText(obj[prop]); - if(typeof funcParsed === 'function') { - obj[prop] = funcParsed; - } - } else if (typeof obj[prop] === 'object') { - parseObj(obj[prop]); - } - } - return obj; - } - - return parseObj(parsed); - } catch(err) {console.error(err); return undefined;} - -} - -export const stringifyWithCircularRefs = (function() { - const refs = new Map(); - const parents:any[] = []; - const path = ["this"]; - - function clear() { - refs.clear(); - parents.length = 0; - path.length = 1; - } - - function updateParents(key, value) { - var idx = parents.length - 1; - var prev = parents[idx]; - if(typeof prev === 'object') { - if (prev[key] === value || idx === 0) { - path.push(key); - parents.push(value.pushed); - } else { - while (idx-- >= 0) { - prev = parents[idx]; - if(typeof prev === 'object') { - if (prev[key] === value) { - idx += 2; - parents.length = idx; - path.length = idx; - --idx; - parents[idx] = value; - path[idx] = key; - break; - } - } - idx--; - } - } - } - } - - function checkCircular(key, value) { - if (value != null) { - if (typeof value === "object") { - if (key) { updateParents(key, value); } - - let other = refs.get(value); - if (other) { - return '[Circular Reference]' + other; - } else { - refs.set(value, path.join('.')); - } - } - } - return value; - } - - return function stringifyWithCircularRefs(obj, space?) { - try { - parents.push(obj); - return JSON.stringify(obj, checkCircular, space); - } finally { - clear(); - } - } -})(); - -if((JSON as any).stringifyWithCircularRefs === undefined) { - //Workaround for objects containing DOM nodes, which can't be stringified with JSON. From: https://stackoverflow.com/questions/4816099/chrome-sendrequest-error-typeerror-converting-circular-structure-to-json - (JSON as any).stringifyWithCircularRefs = stringifyWithCircularRefs; -} - - -export const stringifyWithFunctionsAndCircularRefs = (function() { - const refs = new Map(); - const parents:any[] = []; - const path = ["this"]; - - function clear() { - refs.clear(); - parents.length = 0; - path.length = 1; - } - - function updateParents(key, value) { - var idx = parents.length - 1; - var prev = parents[idx]; - if(typeof prev === 'object') { - if (prev[key] === value || idx === 0) { - path.push(key); - parents.push(value.pushed); - } else { - while (idx-- >= 0) { - prev = parents[idx]; - if(typeof prev === 'object') { - if (prev[key] === value) { - idx += 2; - parents.length = idx; - path.length = idx; - --idx; - parents[idx] = value; - path[idx] = key; - break; - } - } - idx--; - } - } - } - } - - function checkCircular(key, value) { - if (value != null) { - if (typeof value === "object") { - if (key) { updateParents(key, value); } - - let other = refs.get(value); - if (other) { - return '[Circular Reference]' + other; - } else { - refs.set( typeof value === 'function' ? value.toString() : value, path.join('.')); - } - } - } - return typeof value === 'function' ? value.toString() : value; - } - - return function stringifyWithFunctionsAndCircularRefs(obj, space?) { - try { - parents.push(obj); - return JSON.stringify(obj, checkCircular, space); - } finally { - clear(); - } - } -})(); - -if((JSON as any).stringifyWithFunctionsAndCircularRefs === undefined) { - //Workaround for objects containing DOM nodes, which can't be stringified with JSON. From: https://stackoverflow.com/questions/4816099/chrome-sendrequest-error-typeerror-converting-circular-structure-to-json - (JSON as any).stringifyWithFunctionsAndCircularRefs = stringifyWithFunctionsAndCircularRefs; -} -//partial stringification for objects and removing circular references. This allows MUCH faster object equivalency comparison with three-tier depth checking -export const stringifyFast = (function() { - const refs = new Map(); - const parents:any = []; - const path = ["this"]; - - function clear() { - refs.clear(); - parents.length = 0; - path.length = 1; - } - - function updateParents(key, value) { - var idx = parents.length - 1; - //console.log(idx, parents[idx]) - if(parents[idx]){ - var prev = parents[idx]; - //console.log(value); - if(typeof prev === 'object') { - if (prev[key] === value || idx === 0) { - path.push(key); - parents.push(value.pushed); - } else { - while (idx-- >= 0) { - prev = parents[idx]; - if(typeof prev === 'object') { - if (prev[key] === value) { - idx += 2; - parents.length = idx; - path.length = idx; - --idx; - parents[idx] = value; - path[idx] = key; - break; - } - } - idx++; - } - } - } - } - } - - function checkValues(key, value) { - let val; - if (value != null) { - if (typeof value === "object") { - //if (key) { updateParents(key, value); } - let c = value.constructor.name; - if (key && c === 'Object') {updateParents(key, value); } - - let other = refs.get(value); - if (other) { - return '[Circular Reference]' + other; - } else { - refs.set(value, path.join('.')); - } - if(c === "Array") { //Cut arrays down to 100 samples for referencing - if(value.length > 20) { - val = value.slice(value.length-20); - } else val = value; - // refs.set(val, path.join('.')); - } - else if (c.includes("Set")) { - val = Array.from(value) - } - else if (c !== "Object" && c !== "Number" && c !== "String" && c !== "Boolean") { //simplify classes, objects, and functions, point to nested objects for the state manager to monitor those properly - val = "instanceof_"+c; - } - else if (c === 'Object') { - let obj = {}; - for(const prop in value) { - if (value[prop] == null){ - obj[prop] = value[prop]; - } - else if(Array.isArray(value[prop])) { - if(value[prop].length>20) - obj[prop] = value[prop].slice(value[prop].length-20); - else obj[prop] = value[prop]; - } //deal with arrays in nested objects (e.g. means, slices) - else if (value[prop].constructor.name === 'Object') { //additional layer of recursion for 3 object-deep array checks - obj[prop] = {}; - for(const p in value[prop]) { - if(Array.isArray(value[prop][p])) { - if(value[prop][p].length>20) - obj[prop][p] = value[prop][p].slice(value[prop][p].length-20); - else obj[prop][p] = value[prop][p]; - } - else { - if (value[prop][p] != null){ - let con = value[prop][p].constructor.name; - if (con.includes("Set")) { - obj[prop][p] = Array.from(value[prop][p]) - } else if(con !== "Number" && con !== "String" && con !== "Boolean") { - obj[prop][p] = "instanceof_"+con; //3-deep nested objects are cut off - } else { - obj[prop][p] = value[prop][p]; - } - } else { - obj[prop][p] = value[prop][p]; - } - } - } - } - else { - let con = value[prop].constructor.name; - if (con.includes("Set")) { - obj[prop] = Array.from(value[prop]) - } else if(con !== "Number" && con !== "String" && con !== "Boolean") { - obj[prop] = "instanceof_"+con; - } else { - obj[prop] = value[prop]; - } - } - } - //console.log(obj, value) - val = obj; - //refs.set(val, path.join('.')); - } - else { - val = value; - } - } else { - val = value; - } - } - //console.log(value, val) - return val; - } - - return function stringifyFast(obj, space?) { - parents.push(obj); - let res = JSON.stringify(obj, checkValues, space); - clear(); - return res; - } -})(); - -if((JSON as any).stringifyFast === undefined) { - //Workaround for objects containing DOM nodes, which can't be stringified with JSON. From: https://stackoverflow.com/questions/4816099/chrome-sendrequest-error-typeerror-converting-circular-structure-to-json - (JSON as any).stringifyFast = stringifyFast; -} - diff --git a/src/services/webrtc/WebRTC.browser.ts b/src/services/webrtc/WebRTC.browser.ts deleted file mode 100644 index a53cb43a..00000000 --- a/src/services/webrtc/WebRTC.browser.ts +++ /dev/null @@ -1,813 +0,0 @@ -import { Service, ServiceMessage, ServiceOptions } from "../Service"; - -//how it works: -//https://hacks.mozilla.org/2013/07/webrtc-and-the-ocean-of-acronyms/ - -export type WebRTCProps = { - _id?:string, - channels?:{ - [key:string]:(true|RTCDataChannelInit|RTCDataChannel) - }, - config?:RTCConfiguration, - description?:RTCSessionDescription|string, - offer?:RTCOfferOptions, - hostcandidates?:{[key:string]:RTCIceCandidate}, - peercandidates?:{[key:string]:RTCIceCandidate}, - candidates?:{[key:string]:RTCIceCandidate}, - answer?:RTCAnswerOptions, - ontrack?:(ev:RTCTrackEvent)=>void, - removetrack?:(ev:MediaStreamTrackEvent)=>void, //when a media stream track is removed by the peer - onicecandidate?:(ev:RTCPeerConnectionIceEvent)=>void, - onicecandidateerror?:(ev:Event)=>void, - onnegotiationneeded?:(ev:Event, description:RTCSessionDescription)=>void, - ondatachannel?:(ev:RTCDataChannelEvent)=>void, - ondata?:(ev:MessageEvent, channel:RTCDataChannel, room)=>void, - onconnectionstatechange?:(ev:Event)=>void, - oniceconnectionstatechange?:(ev:Event)=>void, - onclose?:(rtc:WebRTCInfo)=>void //custom callback - caller?:string, //e.g. caller's userId from Router - remoteId?:string, //e.g. set this when passing to the opposite user's 'receiveCallInformation' so you know which connection to call in the router for renegotiating - [key:string]:any //set whatever else for reference -} - -export type WebRTCInfo = { - _id:string, - rtc:RTCPeerConnection, - senders?:(RTCRtpSender|undefined)[], - receivers?:(RTCRtpReceiver|undefined)[], - streams?:(MediaStream|undefined)[], //received mediastreams - polite?:boolean, //peer will prevent race conditions for simultaneous negotiations - videoSender?:RTCRtpSender, //audio track channel - audioSender?:RTCRtpSender, //video track channel - videoStream?:MediaStream, //audio track channel - audioStream?:MediaStream, //video track channel - send:(message:any)=>void, //these callbacks work on the first available data channel to call to other webrtc services - request:(message:any, method?:string)=>Promise, - post:(route:any, args?:any)=>void, - run:(route:any, args?:any, method?:string)=>Promise, - subscribe:(route:any, callback?:((res:any)=>void)|string,args?:any[],key?:string,subInput?:boolean,channelId?:string)=>Promise, - unsubscribe:(route:any, sub:number)=>Promise, - terminate:()=>boolean, - graph:WebRTCfrontend -} & WebRTCProps - -//webrtc establishes secure P2P contexts between two users directly. -// However, we need a backend as a way to list available connections. -export class WebRTCfrontend extends Service { - - name='webrtc' - - rtc:{ - [key:string]:WebRTCInfo - } = {} - - unanswered:{ - [key:string]:WebRTCProps - } = {} - - iceServers:RTCIceServer[] = [ - { urls: ['stun:stun.l.google.com:19302'] }, - { urls: ['stun:stun1.l.google.com:19302'] }, - { urls: ['stun:stun2.l.google.com:19302'] }, - { urls: ['stun:stun3.l.google.com:19302'] }, - { urls: ['stun:stun4.l.google.com:19302'] } - ]; - - connections = { //higher level reference for router - rtc:this.rtc - } - - constructor( - options?:ServiceOptions, - iceServers?:RTCIceServer[] - ) { - super(options); - - if(iceServers) this.iceServers = iceServers; - - this.load(this); - //console.log(this) - } - - openRTC = async ( - options?:WebRTCProps - ):Promise => { - if(!options) options = {}; - if(!options._id) options._id = `rtc${Math.floor(Math.random()*1000000000000000)}`; - if(!options.config) options.config = {iceServers:this.iceServers}; - - - - if(!this.rtc[options._id]) { - let rtc = new RTCPeerConnection(options.config); - - if(!options.channels) options.channels = { 'data':true }; //need one channel at least for the default service stuff to work - - let firstChannel; - for(const key in options.channels) { - firstChannel = key; - break; - } - - let send = (message:any) => { - //console.log('sent', message) - return this.transmit(message,options._id,options.channels[firstChannel] as RTCDataChannel); - } - - let post = (route:any,args?:any, method?:string) => { - //console.log('sent', message) - let message:any = { - route, - args - }; - if(method) message.method = method; - - return this.transmit(message,options._id,options.channels[firstChannel] as RTCDataChannel); - } - - let run = (route:any,args?:any, method?:string):Promise => { - return new Promise ((res,rej) => { - let callbackId = Math.random(); - let req = {route:'runRequest', args:[{route, args}, options._id, callbackId]} as any; - //console.log(req) - if(method) req.args[0].method = method; - - let sub; - let ondata = (data:any)=>{ - if(typeof data === 'string' && data.indexOf('{') > -1) data = JSON.parse(data); - if(typeof data === 'object') { - if(data.callbackId === callbackId) { - //(options.channels[firstChannel] as RTCDataChannel).removeEventListener('message',onmessage); - this.unsubscribe(options._id,sub); - res(data.args); //resolve the request with the corresponding message - } - } - } - - sub = this.subscribe(options._id,ondata); - - //(options.channels[firstChannel] as RTCDataChannel).addEventListener('message',onmessage) - this.transmit(req, options._id,options.channels[firstChannel] as RTCDataChannel); - }); - } - - let request = (message:ServiceMessage|any, method?:string):Promise => { - return new Promise ((res,rej) => { - let callbackId = Math.random(); - let req = {route:'runRequest', args:[message,options._id,callbackId]} as any; - //console.log(req) - if(method) req.method = method; - - let sub; - let ondata = (data:any)=>{ - if(typeof data === 'string' && data.indexOf('{') > -1) data = JSON.parse(data); - if(typeof data === 'object') { - if(data.callbackId === callbackId) { - //(options.channels[firstChannel] as RTCDataChannel).removeEventListener('message',onmessage); - this.unsubscribe(options._id,sub); - res(data.args); //resolve the request with the corresponding message - } - } - } - - sub = this.subscribe(options._id,ondata); - this.transmit(req, options._id,options.channels[firstChannel] as RTCDataChannel); - }); - } - - let subscribe = (route:any, callback?:((res:any)=>void)|string, - args?:any[],key?:string, - subInput?:boolean, - channelId?:string - ) => { - return this.subscribeToRTC(route, options._id, channelId ? channelId : firstChannel, callback, args, key, subInput); - } - - let unsubscribe = (route:any, sub:number) => { - return run('unsubscribe',[route,sub]); - } - - let terminate = () => { - return this.terminate(options._id); - } - - this.rtc[options._id] = { - rtc, - _id:options._id, - request, - run, - post, - send, - subscribe, - unsubscribe, - terminate, - graph:this, - ...options - } - - const setMessageChannelHandle = (channel:RTCDataChannel) => { - if(!this.rtc[options._id].ondata) { - this.rtc[options._id].ondata = (mev) => { - //console.log('message on data channel', mev); - this.receive(mev.data, channel, this.rtc[options._id]); - this.setState({[options._id]:mev.data}); - } - channel.addEventListener('message', (mev) => { - //console.log('message on data channel', mev); - if(this.rtc[options._id].ondata) - this.rtc[options._id].ondata(mev, channel, this.rtc[options._id]); - }); - } - else { - channel.addEventListener('message', (mev) => { - if(this.rtc[options._id].ondata) - this.rtc[options._id].ondata(mev, channel, this.rtc[options._id]); - }); - } - } - - if(this.rtc[options._id].channels) { - for(const channel in this.rtc[options._id].channels) { - if(this.rtc[options._id].channels[channel] instanceof RTCDataChannel) { - //OK - } - else if( typeof this.rtc[options._id].channels[channel] === 'object') { - this.rtc[options._id].channels[channel] = this.addDataChannel(rtc,channel,(this.rtc[options._id].channels)[channel] as any); - } else { - this.rtc[options._id].channels[channel] = this.addDataChannel(rtc,channel); - } - - setMessageChannelHandle(this.rtc[options._id].channels[channel] as RTCDataChannel); - - } - } - - - rtc.ontrack = (ev) => { - if(!this.rtc[options._id].receivers) this.rtc[options._id].receivers = []; - this.rtc[options._id].receivers.push(ev.receiver); - - if(!this.rtc[options._id].streams) this.rtc[options._id].streams = []; - this.rtc[options._id].streams.push(...ev.streams); - - let rlength = this.rtc[options._id].receivers.length; - let slength = this.rtc[options._id].streams.length; - - ev.streams.forEach((s) => { - s.addEventListener('removetrack', (ev) => { - this.rtc[options._id].receivers[rlength] = undefined; - this.rtc[options._id].streams[slength] = undefined; - if(this.rtc[options._id].removetrack) this.rtc[options._id].removetrack(ev); - }) - }) - - if(this.rtc[options._id].ontrack) this.rtc[options._id].ontrack(ev); - }; - - rtc.ondatachannel = (ev) => { - this.rtc[options._id].channels[ev.channel.label] = ev.channel; - - setMessageChannelHandle(ev.channel); - - if(this.rtc[options._id].ondatachannel) - this.rtc[options._id].ondatachannel(ev); - }; - - rtc.onicecandidate = (ev) => { if(this.rtc[options._id].onicecandidate) this.rtc[options._id].onicecandidate(ev); }; - rtc.onicecandidateerror = (ev) => { if(this.rtc[options._id].onicecandidateerror) this.rtc[options._id].onicecandidateerror(ev); }; - - let initialOffer = this.rtc[options._id].description === undefined; - - rtc.onnegotiationneeded = async (ev) => { - if(!initialOffer) { - const offer = await rtc.createOffer(this.rtc[options._id].offer); - if (rtc.signalingState != "stable") return; - await rtc.setLocalDescription(offer); - - if(this.rtc[options._id].onnegotiationneeded) this.rtc[options._id].onnegotiationneeded(ev, rtc.localDescription); - } - }; - /* - rtc.onnegotiationneeded = async () => { //you need to implement this - const offer = await rtc.createOffer(); - if (rtc.signalingState != "stable") return; - await rtc.setLocalDescription(offer); - io.send({route:'negotiateCall', args: [options._id, rtc.localDescription]}); - } - */ - rtc.oniceconnectionstatechange = (ev) => { if(this.rtc[options._id].oniceconnectionstatechange) this.rtc[options._id].oniceconnectionstatechange(ev); }; - rtc.onconnectionstatechange = (ev) => { if(this.rtc[options._id].onconnectionstatechange) this.rtc[options._id].onconnectionstatechange(ev); }; - rtc.addEventListener('connectionstatechange', (ev) => { - if(rtc.connectionState === 'closed' || rtc.connectionState === 'failed') { - if(this.rtc[options._id].onclose) { - this.rtc[options._id].onclose(this.rtc[options._id]); - } - - delete this.rtc[options._id]; - } - }); - - - if(!this.rtc[options._id].onicecandidate) this.rtc[options._id].onicecandidate = (ev:RTCPeerConnectionIceEvent) => { - if(ev.candidate) { - let icecandidate = ev.candidate; - - if(!this.rtc[options._id].candidates) this.rtc[options._id].candidates = {}; - this.rtc[options._id].candidates[`candidate${Math.floor(Math.random()*1000000000000000)}`] = icecandidate; - - } - } - - if(!options.description) return await new Promise((res,rej) => { - this.rtc[options._id].rtc.createOffer(options.offer) - .then((offer) => this.rtc[options._id].rtc.setLocalDescription(offer)) - .then(()=>{ - initialOffer = false; - res(this.rtc[options._id]); //this is to be transmitted to the user - }); - }); - - } else { - Object.assign(this.rtc[options._id],options); - } - - - if(options.description) { - this.rtc[options._id].polite = true; - await this.negotiateCall(options._id, options.description, true); - } - - if(options.candidates) { - for(const prop in options.candidates) { - const candidate = new RTCIceCandidate(options.candidates[prop]) - this.rtc[options._id].rtc.addIceCandidate(candidate).catch(console.error); - } - } - - return this.rtc[options._id]; - - } - - open = this.openRTC; //for the router - - addIceCandidate = (rtc:RTCPeerConnection|string, candidate:RTCIceCandidate) => { - if(typeof rtc === 'string') rtc = this.rtc[rtc]?.rtc; - if(typeof candidate === 'string') candidate = JSON.parse(decodeURIComponent(candidate)); - if(rtc && rtc.remoteDescription) return rtc.addIceCandidate(candidate); - } - - //receive and compile unanswered/unadded call information (e.g. peer descriptions and ice candidates) - //https://hacks.mozilla.org/2013/07/webrtc-and-the-ocean-of-acronyms/ - receiveCallInformation = async ( options:WebRTCProps ) => { - if(!options._id) options._id = `rtc${Math.floor(Math.random()*1000000000000000)}`; - if (this.rtc[options._id]) { - if(options.candidates) { - for(const key in options.candidates) - this.addIceCandidate(this.rtc[options._id].rtc, options.candidates[key]); - delete options.candidates; - } - Object.assign(this.rtc[options._id],options); - } - else if(this.unanswered[options._id]) { - this.recursivelyAssign(this.unanswered[options._id], options); // - } else this.unanswered[options._id] = options; - - return options._id; - } - - answerCall = ( options:WebRTCProps|string ) => { - if(typeof options === 'string') options = this.unanswered[options]; - delete this.unanswered[options._id]; - return this.openRTC(options); - } - - rejectCall = ( options:WebRTCProps|string ) => { - if(typeof options === 'string') options = this.unanswered[options]; - delete this.unanswered[options._id]; - return true; - } - - negotiateCall = async ( rtc:RTCPeerConnection|string, description:string|RTCSessionDescription, polite?:boolean) => { - if(typeof rtc === 'string') { - if(polite === undefined) - polite = this.rtc[rtc].description !== undefined; //only the person called should have this defined - rtc = this.rtc[rtc].rtc; - } - if(typeof description === 'string') description = new RTCSessionDescription(JSON.parse(decodeURIComponent(description))); - if((description as RTCSessionDescription).type === 'offer' && rtc.signalingState !== 'stable') { - if(!polite) return; - await Promise.all([ - rtc.setLocalDescription({type:'rollback'}), - rtc.setRemoteDescription(description as RTCSessionDescription) - ]); - return encodeURIComponent(JSON.stringify((rtc as RTCPeerConnection).localDescription)); //we need to run negotiateCall on the other end now with this description to update the call information - } else { - await rtc.setRemoteDescription(description as RTCSessionDescription); - } if ((description as RTCSessionDescription).type == "offer") { - await rtc.setLocalDescription(await rtc.createAnswer()); - return encodeURIComponent(JSON.stringify((rtc as RTCPeerConnection).localDescription)); //we need to run negotiateCall on the other end now with this description to update the call information - } - } - - createOffer(rtc:RTCPeerConnection|string, options:WebRTCProps|string) { - if(typeof rtc === 'string') rtc = this.rtc[rtc].rtc; - if(typeof options === 'string') options = this.rtc[options]; - return new Promise((res,rej) => { - if(!rtc) rej(undefined); - (rtc as RTCPeerConnection).createOffer((options as WebRTCProps).offer) - .then((offer) => (rtc as RTCPeerConnection).setLocalDescription(offer)) - .then(()=>{ - let description = encodeURIComponent(JSON.stringify((rtc as RTCPeerConnection).localDescription)); - res(description); //this is to be transmitted to the user - }); - }) - } - - createAnswer(rtc:RTCPeerConnection|string, options:WebRTCProps|string) { - if(typeof rtc === 'string') rtc = this.rtc[rtc]?.rtc as RTCPeerConnection; - if(typeof options === 'string') options = this.rtc[options]; - - return new Promise((res,rej) => { - if(!rtc) rej(undefined); - (rtc as RTCPeerConnection).createAnswer((options as WebRTCProps).answer) - .then((answer)=> (rtc as RTCPeerConnection).setLocalDescription(answer)) - .then(()=>{ - let description = encodeURIComponent(JSON.stringify((rtc as RTCPeerConnection).localDescription)); - res(description); - }); - }); - } - - answerPeer = (rtc:RTCPeerConnection|string, options:WebRTCProps|string) => { - if(typeof rtc === 'string') { - let cpy = Object.assign(this.rtc[rtc],options); - delete cpy.description; - delete cpy.candidates; - Object.assign(this.rtc[rtc],cpy); - - rtc = this.rtc[rtc]?.rtc; - } - if(typeof options === 'string') options = this.rtc[options]; - return new Promise((res,rej) => { - if(typeof (options as WebRTCProps).description === 'string') { - (options as WebRTCProps).description = JSON.parse(decodeURIComponent((options as WebRTCProps).description as string)); - } - const description = new RTCSessionDescription((options as WebRTCProps).description as RTCSessionDescriptionInit); - - (rtc as RTCPeerConnection).setRemoteDescription(description).then(()=>{ - if((options as WebRTCProps).candidates) { - for(const prop in (options as WebRTCProps).candidates) { - const candidate = new RTCIceCandidate((options as WebRTCProps).candidates[prop]) - if(this.rtc[(options as WebRTCProps)._id]) this.rtc[(options as WebRTCProps)._id].candidates[prop] = (options as WebRTCProps).candidates[prop]; - (rtc as RTCPeerConnection).addIceCandidate(candidate).catch(console.error); - } - } - if(description.type === 'offer') { - this.rtc[(options as WebRTCProps)._id].rtc.createAnswer((options as WebRTCProps).answer).then((a) => { - this.rtc[(options as WebRTCProps)._id].rtc.setLocalDescription(a); - }); - } - res(this.rtc[(options as WebRTCProps)._id] ? this.rtc[(options as WebRTCProps)._id] : rtc); - }).catch(rej); //we can now receive data - }); - } - - createStream = ( //use navigator.mediaDevices.getUserMedia({audio:true,video:true}) for audio/video streams - options:{ - [key:string]:{ - track:MediaStreamTrack|MediaTrackConstraints, - onended:(ev)=>void, - onmute:(ev)=>void, - onunmute:(ev)=>void - } - } - ) => { - let stream = new MediaStream(); - for(const key in options) { - let track = options[key].track; - if(!(track instanceof MediaStreamTrack) && typeof track === 'object') { - track = new MediaStreamTrack(); - track.applyConstraints(options[key].track as MediaTrackConstraints) - stream.addTrack(track); - } - - if(track instanceof MediaStreamTrack) { - stream.addTrack(track as MediaStreamTrack); - track.onmute = options[key].onmute; - track.onunmute = options[key].onunmute; - track.onended = options[key].onended; - - } - } - return stream; - } - - addUserMedia = ( - rtc:RTCPeerConnection, - options:MediaStreamConstraints={ - audio:true, - video:{ - optional:[ - {minWidth: 320 }, - {minWidth: 640 }, - {minWidth: 1024 }, - {minWidth: 1280 }, - {minWidth: 1920 }, - {minWidth: 2560 }, - ] - } as MediaTrackConstraints - }, - info?:WebRTCInfo - ) => { - - return new Promise(async (res,rej) => { - - let RTCRtpSenders:any[] = []; - - let stream = await navigator.mediaDevices.getUserMedia(options) - - if(stream) { - let tracks = stream.getTracks() - tracks.forEach((track) => { - let sender = rtc.addTrack(track,stream); - if(track.kind === 'video' && info) {info.videoSender = sender; info.videoStream = stream; } - if(track.kind === 'audio' && info) {info.audioSender = sender; info.audioStream = stream; } - RTCRtpSenders.push(sender); - }); - let str = stream; - - if(info) info.senders = - info.senders ? - [...info.senders, ...RTCRtpSenders] : - RTCRtpSenders; - - res(str); - } - }); - } - - //add media streams to the dat channel - addTrack = (rtc:RTCPeerConnection, track:MediaStreamTrack, stream:MediaStream) => { - return rtc.addTrack(track,stream); - } - - removeTrack = (rtc:RTCPeerConnection,sender:RTCRtpSender) => { - rtc.removeTrack(sender); //e.g. remove the senders removed by addUserMedia - return true; - } - - addDataChannel = ( //send arbitrary strings - rtc:RTCPeerConnection, - name:string, - options?:RTCDataChannelInit//{ negotiated: false } - ) => { - return rtc.createDataChannel(name,options); - } - - enableAudio = async (call:WebRTCInfo, audioOptions:boolean|(MediaTrackConstraints & {deviceId?:string})=true) => { - if(call.audioStream) this.disableAudio(call); - let stream = await this.addUserMedia( - call.rtc, - { - audio:audioOptions, - video:false - }, - call - ); - - if((audioOptions as any)?.deviceId) (call.audioSender as any).deviceId = (audioOptions as any).deviceId; - - return stream; - } - - enableVideo = async ( - call:WebRTCInfo, - videoOptions:(MediaTrackConstraints & {deviceId?:string, optional?:{minWidth: number}[] }) = { - //deviceId: 'abc' //or below default setting: - optional:[ - {minWidth: 320}, - {minWidth: 640}, - {minWidth: 1024}, - {minWidth: 1280}, - {minWidth: 1920}, - {minWidth: 2560}, - {minWidth: 3840}, - ] - } as MediaTrackConstraints & { deviceId?:string, optional?:{minWidth: number}[] }, - includeAudio:boolean|(MediaTrackConstraints & {deviceId?:string}) = false - ) => { //the maximum available resolution will be selected if not specified - - if(call.videoStream) this.disableVideo(call); - - let stream = await this.addUserMedia( - call.rtc, - { - audio:includeAudio, - video:videoOptions ? videoOptions : { - optional: [ - {minWidth: 320}, - {minWidth: 640}, - {minWidth: 1024}, - {minWidth: 1280}, - {minWidth: 1920}, - {minWidth: 2560}, - {minWidth: 3840}, - ] - } as MediaTrackConstraints - }, - call - ); - - if(videoOptions?.deviceId) (call.videoSender as any).deviceId = videoOptions.deviceId; - if(includeAudio) { - if((includeAudio as any)?.deviceId) - (call.audioSender as any).deviceId = (includeAudio as any).deviceId; - else if(videoOptions?.deviceId) (call.audioSender as any).deviceId = (videoOptions as any).deviceId; - } - - return stream; - } - - disableAudio(call:WebRTCInfo) { - if(call.audioSender) { - call.senders?.find((s,i) => { - if(call.audioStream?.getAudioTracks()[0].id === s.track.id) { - call.senders.splice(i,1); - return true; - } - }); - call.rtc.removeTrack(call.audioSender); - call.audioSender = undefined; - } - call.audioStream?.getTracks().forEach((track) => { - if(track.kind === 'audio') track.stop(); - }); - call.audioStream = undefined; - } - - disableVideo(call:WebRTCInfo) { - if(call.videoSender) { - call.senders?.find((s,i) => { - if(call.videoStream?.getVideoTracks()[0].id === s.track.id) { - call.senders.splice(i,1); - return true; - } - }); - call.rtc.removeTrack(call.videoSender); - call.videoSender = undefined; - } - call.videoStream?.getTracks().forEach((track) => { - if(track.kind === 'video') track.stop(); - }); - call.videoStream = undefined; - } - - //send data on a data channel - transmit = (data:ServiceMessage|any, id?:string, channel?:string|RTCDataChannel ) => { - if((typeof data === 'object' && ((data.route || data.node) || !(data as ArrayBufferLike).byteLength && typeof (data as Blob).arrayBuffer !== 'function') || typeof data === 'number')) - data = JSON.stringify(data); //we need strings - - if(!channel && id) { //select first channel - let keys = Object.keys(this.rtc[id].channels); - if(keys[0]) - channel = this.rtc[id].channels[keys[0]] as RTCDataChannel; - } - - if(typeof channel === 'string') { - if(id) { - channel = this.rtc[id].channels[channel] as RTCDataChannel; - } else { //send on all channels on all rooms - for(const id in this.rtc) { - if(this.rtc[id].channels[channel] instanceof RTCDataChannel) - (this.rtc[id].channels[channel] as RTCDataChannel).send(data); // This may be a string, a Blob, an ArrayBuffer, a TypedArray or a DataView object. - } - } - } - - if(channel instanceof RTCDataChannel) - channel.send(data); // This may be a string, a Blob, an ArrayBuffer, a TypedArray or a DataView object. - - //console.log('sending',channel,data) - - return true; - } - - //close a channel - terminate = (rtc:RTCPeerConnection|WebRTCInfo|string) => { - let tx; - if(typeof rtc === 'string') { - let room = this.rtc[rtc]; - delete this.rtc[rtc]; - if(room) { - tx = room.rtc; - } - } - else if (typeof rtc === 'object') { - tx = (rtc as WebRTCInfo).rtc; - } - - if(rtc instanceof RTCPeerConnection && rtc.signalingState !== 'closed') { - rtc.close(); - } else if(tx && tx.signalingState !== 'closed') { - if(tx) tx.close(); - } - - return true; - } - - request = (message:ServiceMessage|any, channel:RTCDataChannel, _id:string, method?:string) => { //return a promise which can resolve with a server route result through the socket - let callbackId = `${Math.random()}`; - let req:any = {route:'runRequest', args:[message,_id,callbackId]}; - if(method) req.method = method; - return new Promise((res,rej) => { - let onmessage = (ev:any) => { - let data = ev.data; - if(typeof data === 'string' && data.indexOf('{') > -1) data = JSON.parse(ev.data); - if(typeof data === 'object') if(data.callbackId === callbackId) { - channel.removeEventListener('message',onmessage); - res(data.args); - } - } - - channel.addEventListener('message',onmessage); - channel.send(JSON.stringify(req)); - }); - } - - runRequest = ( - message:any, - channelOrRtcId:RTCDataChannel|string, //data channel or rtc id (which grabs the first channel) - callbackId:string|number - ) => { //send result back - let res = this.receive(message); - if(channelOrRtcId) { - if(typeof channelOrRtcId === 'string') { - for(const key in this.rtc) { - if(key === channelOrRtcId) {channelOrRtcId = this.rtc[key].channels.data ? this.rtc[key].channels.data as RTCDataChannel : this.rtc[key].channels[Object.keys(this.rtc[key].channels)[0]] as RTCDataChannel; break;} - } - } - if(res instanceof Promise) - res.then((v) => { - res = {args:v, callbackId}; - if(channelOrRtcId instanceof RTCDataChannel) channelOrRtcId.send(JSON.stringify(res)); - - return res; - }) - else { - res = {args:res, callbackId}; - if(channelOrRtcId instanceof RTCDataChannel) channelOrRtcId.send(JSON.stringify(res)); - } - } - return res; - } - - subscribeRTC = ( - route:string, - rtcId:string, - args?:any[], - key?:string, - subInput?:boolean, - channel?:string|RTCDataChannel - ) => { - if(this.restrict?.[route]) return undefined; - if(typeof channel === 'string' && this.rtc[rtcId]) { - channel = this.rtc[rtcId].channels[channel] as RTCDataChannel; - } else if (!channel) { channel = this.rtc[rtcId].channels[Object.keys(this.rtc[rtcId].channels)[0]] as RTCDataChannel } - return this.subscribe(route, (res:any) => { - //console.log('running request', message, 'for worker', worker, 'callback', callbackId) - if(res instanceof Promise) { - res.then((r) => { - (channel as RTCDataChannel).send(JSON.stringify({args:r, callbackId:route})); - }); - } else { - (channel as RTCDataChannel).send(JSON.stringify({args:res, callbackId:route})); - } - },args,key,subInput); - } - - subscribeToRTC = ( - route:string, rtcId:string, channelId:string, callback?:string|((res:any)=>void), - args?:any[], - key?:string, - subInput?:boolean - ) => { - if(typeof channelId === 'string' && this.rtc[rtcId]) { - let c = this.rtc[rtcId]; - let channel = c.channels[channelId]; - - if(channel) { - this.__node.state.subscribeEvent(rtcId, (res) => { - if(res?.callbackId === route) { - if(!callback) this.setState({[rtcId]:res.args}); //just set state - else if(typeof callback === 'string') { //run a local node - this.run(callback,res.args); - } - else callback(res.args); - } - }); - return c.request({route:'subscribeRTC', args:[route,rtcId,args,key,subInput,channelId]}); - } - } - } - -} \ No newline at end of file diff --git a/src/services/worker/Worker.service.ts b/src/services/worker/Worker.service.ts deleted file mode 100644 index d1e42aa9..00000000 --- a/src/services/worker/Worker.service.ts +++ /dev/null @@ -1,810 +0,0 @@ -import { Service, ServiceMessage, ServiceOptions } from "../Service"; -import Worker from 'web-worker' //cross platform for node and browser -import { Graph, GraphNode, GraphNodeProperties } from "../../core/Graph"; - -declare var WorkerGlobalScope; - -export type WorkerRoute = { - worker?:WorkerInfo - workerUrl?: string|URL|Blob, - transferFunctions?:{[key:string]:Function}, - transferClasses?:{[key:string]:Function}, - parentRoute?:string, //if a child of a worker node, subscribe to a route on a parent worker? - portId?:string, //port to subscribe to for the parent route? will establish new one if parent has a worker defined, there is no limit on MessagePorts so they can be useful for organizing - callback?:string, //Run this route on the worker when the operator is called. If this route is a child of another node, run this node on the child worker when it receives a message. - stopped?:boolean, // Don't run the callback until we call the thread to start? E.g. for recording data periodically. - blocking?:boolean, //should the subscribed worker wait for the subscriber to resolve before sending a new result? Prevents backup and makes async processing easier - init?:string, //run a callback on the worker on worker init? - initArgs?:any[] //arguments to go with the worker init? - initTransfer?:any[] //transferrable stuff with the init? -} & GraphNodeProperties & WorkerProps - -export type WorkerProps = { - worker?:WorkerInfo, - workerUrl?: string|URL|Blob, - url?:URL|string|Blob, - _id?:string, - port?:MessagePort, //message channel for this instance - onmessage?:(ev)=>void, - onerror?:(ev)=>void, - onclose?:(worker:Worker|MessagePort)=>void -} - -export type WorkerInfo = { - worker:Worker|MessagePort, - send:(message:any,transfer?:any)=>void, - request:(message:any, method?:string,transfer?:any)=>Promise, - post:(route:any, args?:any, method?:string, transfer?:any)=>void, - run:(route:any, args?:any, method?:string,transfer?:any)=>Promise - subscribe:(route:any, callback?:((res:any)=>void)|string, args?:any[], key?:string, subInput?:boolean, blocking?:boolean)=>Promise, - unsubscribe:(route:any, sub:number)=>Promise, - start:(route?:any, portId?:string, callback?:((res:any)=>void)|string, blocking?:boolean)=>Promise, - stop:(route?:string, portId?:string)=>Promise, - workerSubs:{[key:string]:{sub:number|false, route:string, portId:string, callback?:((res:any)=>void)|string, blocking?:boolean}}, - terminate:()=>boolean, - postMessage:(message:any,transfer?:any[])=>void, //original worker post message - graph:WorkerService, - _id:string -} & WorkerProps & WorkerRoute - -//this spawns the workers -export class WorkerService extends Service { - - name='worker' - - workers:{ - [key:string]:WorkerInfo - }={} - - threadRot = 0; //thread rotation if not specifying - - connections: any; - - constructor(options?:ServiceOptions) { - super(); - - this.connections = { //higher level reference for Router - workers:this.workers - } - - if(options?.services) this.addServices(options.services); - this.load(this); - this.setLoaders(this.workerloader); //add a custom route loader for the worker logic - if(options) this.init(options); - - if(typeof WorkerGlobalScope !== 'undefined' && globalThis instanceof WorkerGlobalScope) { - this.addDefaultMessageListener(); - } - } - - loadWorkerRoute = (node:WorkerRoute & GraphNode, routeKey:string) => { - if(node.workerUrl) node.url = node.workerUrl; - if(node._id) node.__node.tag = node._id; - if(!node.__node.tag) node.__node.tag = routeKey; - node._id = node.__node.tag; - - let worker:WorkerInfo; - if(this.workers[node._id]) worker = this.workers[node._id]; - else if (node.worker) worker = node.worker; - if(!worker) { - worker = this.addWorker(node); - } - - node.worker = worker; - - if(!node.__ondisconnected) { - let ondelete = (rt) => { //removing the original route will trigger ondelete - rt.worker?.terminate(); - } - node.__addOndisconnected(ondelete); - } - //console.log(rt); - - //requires remoteGraphRoutes on the worker (enabled on the default worker) - if(node.transferFunctions) { - for(const prop in node.transferFunctions) { - this.transferFunction(worker,node.transferFunctions[prop],prop) - } - } - if(node.transferClasses) { - for(const prop in node.transferClasses) { - this.transferClass(worker,node.transferClasses[prop],prop) - } - } - - if(worker) { - if(!node.__operator) { - node.__operator = (...args) => { - //console.log('operator', args) - if(node.callback) { - if(!this.__node.nodes.get(node.__node.tag)?.__children) worker.post(node.callback,args); - else return worker.run(node.callback,args); - } else { - if(!this.__node.nodes.get(node.__node.tag)?.__children) worker.send(args); - else return worker.request(args); - } - } - } - - if(node.init) { //requires remoteGraphRoutes - worker.run(node.init,node.initArgs,undefined,node.initTransfer); - } - - // //need remoteGraphRoutes loaded - // worker.run('setValue',[rt.callback+'_routeProxy', rt.callback]); - - // this.transferFunction( - // worker, - // function routeProxy(data:any) { - // let r = this.graph.nodes.get(this.graph[this.tag]).__operator(data); - - // if(this.graph.state.triggers[this.graph[this.tag]]) { - // if(r instanceof Promise) { - // r.then((rr) => { - // if(rr !== undefined) this.setState({[this.graph[this.tag]]:rr}); - // }); - // } - // else if(r !== undefined) this.setState({[this.graph[this.tag]]:r}); //so we can subscribe to the original route - // } - - // return r; - // }, - // rt.callback+'_routeProxy' - // ) - - // rt.callback = rt.callback+'_routeProxy'; //proxying through here - - return worker; - } - } - - workerloader:any = { //todo: clean this up and extrapolate to other services - 'workers':(node: WorkerRoute & GraphNode, parent:WorkerRoute & GraphNode, graph:Graph, roots:any) => { - let rt = node as WorkerRoute; - if(!node.parentRoute && (parent?.callback && parent?.worker)) node.parentRoute = parent?.callback; - if(rt?.worker || (rt?._id && this.workers[rt._id]) || (rt as WorkerRoute)?.workerUrl) { //each set of props with a worker will instantiate a new worker, else you can use the same worker elsewhere by passing the corresponding tag - - let worker = this.loadWorkerRoute(rt as any, rt.__node.tag); - - if(worker) { - if(!rt.parentRoute && (rt.__parent as any)?.callback) rt.parentRoute = (rt.__parent as any).callback; - if(rt.__parent && !rt.portId){ - if(typeof rt.__parent === 'string') { - if(rt.__node.tag !== rt.__parent && worker._id !== rt.__parent) - rt.portId = this.establishMessageChannel(worker, rt.__parent) as string; - } - else if(rt.__node.tag !== rt.__parent?.__node?.tag && worker._id !== rt.__parent?.tag) { - rt.portId = this.establishMessageChannel(worker, (rt.__parent as any).worker) as string; - } - }; - if(rt.parentRoute) { - if(!rt.stopped) { - if(typeof rt.__parent === 'string' && rt.__parent === worker._id) { - worker.run('subscribe', [rt.parentRoute, undefined, undefined, rt.callback]); - } - else if(rt.__node.tag === rt.__parent?.__node?.tag || worker._id === rt.__parent?.__node?.tag) { - worker.run('subscribe', [rt.parentRoute, undefined, undefined, rt.callback]); - } - else worker.run('subscribeToWorker', [rt.parentRoute, rt.portId, undefined, rt.callback, undefined, undefined, rt.blocking]).then((sub)=>{ //if no callback specified it will simply setState on the receiving thread according to the portId - worker.workerSubs[rt.parentRoute+rt.portId].sub = sub; - }); - } - if(!(typeof rt.__parent === 'string' && rt.__parent === worker._id) && !(rt.__node.tag === rt.__parent?.__node?.tag || worker._id === rt.__parent?.__node?.tag)) - worker.workerSubs[rt.parentRoute+rt.portId] = {sub:null, route:rt.parentRoute, portId:rt.portId, callback:rt.callback, blocking:rt.blocking }; - } else if (rt.__parent) { - if(typeof rt.__parent === 'string') { - if(!rt.stopped) { - if(rt.__parent === worker._id) { - worker.run('subscribe', [rt.__parent, undefined, rt.callback]); - } - else worker.run('subscribeToWorker', [rt.__parent, rt.portId, undefined, rt.callback, undefined, undefined, rt.blocking]).then((sub)=>{ //if no callback specified it will simply setState on the receiving thread according to the portId - worker.workerSubs[rt.__parent+rt.portId].sub = sub; - }); - } - if(!(typeof rt.__parent === 'string' && rt.__parent === worker._id)) - worker.workerSubs[rt.__parent+rt.portId] = {sub:null, route:worker._id, portId:rt.portId, callback:rt.callback, blocking:rt.blocking }; - - } else if(rt.__parent?.__node?.tag && rt.__parent?.worker) { - //console.log(rt); - if(!rt.stopped) { - if(rt.__node.tag === rt.__parent.__node.tag || worker._id === rt.__parent.__node.tag) { - worker.run('subscribe', [rt.__parent.__node.tag, undefined, undefined, rt.callback]); - } - else worker.run('subscribeToWorker', [rt.__parent.__node.tag, rt.portId, undefined, rt.callback, undefined, undefined, rt.blocking]).then((sub)=>{ //if no callback specified it will simply setState on the receiving thread according to the portId - worker.workerSubs[rt.__parent.__node.tag+rt.portId].sub = sub; - }); - } - if(!(rt.__node.tag === rt.__parent?.__node?.tag || worker._id === rt.__parent?.__node?.tag)) - worker.workerSubs[rt.__parent.__node.tag+rt.portId] = {sub:null, route:rt.__parent.__node.tag, portId:rt.portId, callback:rt.callback, blocking:rt.blocking }; - } - } - - } - } else if(rt.__parent && rt.parentRoute) { - if(typeof rt.__parent === 'string' && (roots[rt.__parent] as any)?.worker) { - ((roots[rt.__parent] as any).worker as WorkerInfo).subscribe(rt.parentRoute, rt.__operator, undefined, undefined, undefined, rt.blocking); - } else if((rt.__parent as any)?.worker) { - ((rt.__parent as any).worker as WorkerInfo).subscribe(rt.parentRoute, rt.__operator, undefined, undefined, undefined, rt.blocking); - } - } - //console.log(rt); - return rt; - } - } - - //works in window as well (caution) - addDefaultMessageListener = () => { - globalThis.onmessage = (ev:MessageEvent) => { - let result = this.receive(ev.data); //this will handle graph logic and can run requests for the window or messsage ports etc etc. - //console.log(JSON.stringify(ev.data), JSON.stringify(result),JSON.stringify(Array.from((self as any).SERVICE.nodes.keys()))) - //console.log(result); - - if(this.__node.keepState) this.setState({[this.name]:result}); //subscribe to all outputs - } //this will work for iframes too - } - - //post messages to workers or to window (or self as worker) - postMessage = (message:any, target:string, transfer?:Transferable[]) => { - if(this.workers[target]) { - this.workers[target].send(message,transfer); - } else { - globalThis.postMessage(message, target, transfer) - } - } - - addWorker = (options:{ - url?:URL|string|Blob, - port?:MessagePort, - _id?:string, - onmessage?:(ev)=>void, - onerror?:(ev)=>void - }) => { //pass file location, web url, or javascript dataurl string - let worker:Worker|MessagePort; - - if(!options._id) - options._id = `worker${Math.floor(Math.random()*1000000000000000)}`; - - if(options.url) worker = new Worker(options.url); - else if (options.port) { - worker = options.port; - } else if (this.workers[options._id]) { - if(this.workers[options._id].port) worker = this.workers[options._id].port; - else worker = this.workers[options._id].worker; - } - - //console.log('adding worker', options._id); - - if(!worker) return; - - let send = (message:any,transfer?:any) => { - //console.log('sent', message) - return this.transmit(message,worker,transfer); - } - - let post = (route:any,args?:any,method?:string, transfer?:any) => { - //console.log('sent', message) - let message:any = { - route, - args - }; - if(method) message.method = method; - //console.log(message); - return this.transmit(message,worker,transfer); - } - - let run = (route:any, args?:any, method?:string, transfer?:any) => { - return new Promise ((res,rej) => { - let callbackId = Math.random(); - let req = {route:'runRequest', args:[{route, args}, options._id, callbackId]} as any; - //console.log(req) - if(method) req.args[0].method = method; - let onmessage = (ev)=>{ - if(typeof ev.data === 'object') { - if(ev.data.callbackId === callbackId) { - worker.removeEventListener('message',onmessage); - res(ev.data.args); //resolve the request with the corresponding message - } - } - } - worker.addEventListener('message',onmessage); - - this.transmit(req, worker, transfer); - }); - } - - let request = (message:ServiceMessage|any, method?:string, transfer?:any) => { - return new Promise ((res,rej) => { - let callbackId = Math.random(); - let req = {route:'runRequest', args:[message,options._id,callbackId]} as any; - //console.log(req) - if(method) req.method = method; - let onmessage = (ev)=>{ - if(typeof ev.data === 'object') { - if(ev.data.callbackId === callbackId) { - worker.removeEventListener('message',onmessage); - res(ev.data.args); //resolve the request with the corresponding message - } - } - } - worker.addEventListener('message',onmessage) - this.transmit(req, worker, transfer); - }); - } - - let workerSubs = {}; - - //subscribe to this worker from the thread running this function - let subscribe = (route:any, callback?:((res:any)=>void)|string, args?:any[], key?:string, subInput?:boolean, blocking?:boolean) => { - return this.subscribeToWorker(route, options._id, callback, args, key, subInput, blocking); - } - - let unsubscribe = (route:any, sub:number):Promise => { - return run('unsubscribe',[route,sub]); - } - - //start a subscription to another worker/main thread on this worker - let start = async (route?:string, portId?:string, callback?:string, blocking?:boolean) => { - if(route) - await run('subscribeToWorker',[route, portId, undefined, callback, blocking]).then((sub) => { - if(sub) workerSubs[route+portId] = {sub, route, portId, callback, blocking}; - }); - else for(const key in workerSubs) { - if(typeof workerSubs[key].sub !== 'number') - await run('subscribeToWorker', [workerSubs[key].route, workerSubs[key].portId, undefined, workerSubs[key].callback, undefined, workerSubs[key].blocking]).then((sub) => { - workerSubs[key].sub = sub; - }); - - console.log(JSON.stringify(workerSubs)); - } - return true; - } - - //stop a subscription to another worker/main thread on this worker - let stop = async (route?:string, portId?:string) => { - if(route && portId && workerSubs[route+portId]) { - await run('unsubscribe',[route,workerSubs[route+portId].sub]); - workerSubs[route+portId].sub = false; - } else { - for(const key in workerSubs) { - if(typeof workerSubs[key].sub === 'number') { - await run('unpipeWorkers', [workerSubs[key].route, workerSubs[key].portId, workerSubs[key].sub]).then(console.log); - } workerSubs[key].sub = false; - - } - } - return true; - } - - let terminate = () => { - for(const key in workerSubs) { - if(typeof workerSubs[key].sub === 'number') { - run('unpipeWorkers', [workerSubs[key].route, workerSubs[key].portId, workerSubs[key].sub]); - } workerSubs[key].sub = false; - } - return this.terminate(options._id); - } - - if(!options.onmessage) options.onmessage = (ev) => { - this.receive(ev.data); - this.setState({[options._id as string]:ev.data}); - } - - if(!options.onerror) { - options.onerror = (ev) => { - console.error(ev.data); - } - } - - worker.onmessage = options.onmessage; - (worker as Worker).onerror = options.onerror; - - - let workersettings = { - worker:(worker as any), - __node:{tag:options._id}, - send, - post, - run, - request, - subscribe, - unsubscribe, - terminate, - start, - stop, - postMessage:worker.postMessage, - workerSubs, - graph:this, - ...options - } as WorkerInfo; - - let node = this.add(workersettings); - - this.workers[options._id] = node as GraphNode & WorkerInfo; - - node.__addOndisconnected(function() { terminate(); }); - - return this.workers[options._id]; - } - - open = this.addWorker; //for the router - - close = () => { - globalThis.close(); //workers can terminate themselves - } - - //new Worker(urlFromString) - toObjectURL = (scriptTemplate:string) => { - let blob = new Blob([scriptTemplate],{type:'text/javascript'}); - return URL.createObjectURL(blob); - } - - getTransferable(message:any) { - //automatic dataview/typedarray/arraybuffer transferring. - // There are more transferable types but we start to slow things - // down if we check too many cases so make transfer explicit in general! This is mainly for automating subscriptions - let transfer; - if(typeof message === 'object') { - if(message.args) { - if (message.args?.constructor?.name === 'Object') { - for(const key in message.args) { - if(ArrayBuffer.isView(message.args[key])) { - if(!transfer) - transfer = [message.args[key].buffer] as StructuredSerializeOptions; - else - (transfer as any[]).push(message.args[key].buffer); - } else if (message.args[key]?.constructor?.name === 'ArrayBuffer') { - if(!transfer) - transfer = [message.args[key]] as StructuredSerializeOptions; - else - (transfer as any[]).push(message.args[key]); - } - } - } - else if(Array.isArray(message.args) && message.args.length < 11) { //lets check any argument less size 10 or less for typed array inputs - message.args.forEach((arg) => { - if(ArrayBuffer.isView(arg)) { - transfer = [arg.buffer] as StructuredSerializeOptions; - } else if (arg?.constructor?.name === 'ArrayBuffer') - transfer = [arg] as StructuredSerializeOptions; - }); - } - else if(ArrayBuffer.isView(message.args)) { - transfer = [message.args.buffer] as StructuredSerializeOptions; - } - else if (message.args?.constructor?.name === 'ArrayBuffer') { - transfer = [message] as StructuredSerializeOptions; - } - } - else if (message?.constructor?.name === 'Object') { - for(const key in message) { - if(ArrayBuffer.isView(message[key])) { - if(!transfer) - transfer = [message[key].buffer] as StructuredSerializeOptions; - else - (transfer as any[]).push(message[key].buffer); - } else if (message[key]?.constructor?.name === 'ArrayBuffer') { - if(!transfer) - transfer = [message[key]] as StructuredSerializeOptions; - else - (transfer as any[]).push(message[key]); - } - } - } - else if(Array.isArray(message) && message.length < 11) { //lets check any argument size 10 or less for typed array inputs - message.forEach((arg) => { - if(ArrayBuffer.isView(arg)) { - transfer = [arg.buffer] as StructuredSerializeOptions; - } else if (arg.constructor?.name === 'ArrayBuffer') - transfer = [arg] as StructuredSerializeOptions; - }); - } - else if(ArrayBuffer.isView(message)) { - transfer = [message.buffer] as StructuredSerializeOptions; - } - else if (message.constructor?.name === 'ArrayBuffer') { - transfer = [message] as StructuredSerializeOptions; - } - } - - return transfer; - } - - transmit = (message:ServiceMessage|any, worker?:Worker|MessagePort|string, transfer?:StructuredSerializeOptions ) => { - - if(!transfer) { - transfer = this.getTransferable(message); //automatically transfer arraybuffers - } - - if(worker instanceof Worker || worker instanceof MessagePort) { - worker.postMessage(message,transfer); - } else if(typeof worker === 'string') { - if(this.workers[worker as string]) { - if(this.workers[worker as string].port) - (this.workers[worker as string].port as any).postMessage(message,transfer); - else if (this.workers[worker as string].worker) - this.workers[worker as string].worker.postMessage(message,transfer); - } - } else { - let keys = Object.keys(this.workers); - this.workers[keys[this.threadRot]].worker.postMessage(message,transfer); - this.threadRot++; - if(this.threadRot === keys.length) this.threadRot = 0; - } - return message; - } - - terminate = (worker:Worker|MessagePort|string|WorkerInfo) => { - let onclose; - - let str; - if(typeof worker === 'string') { - str = worker; - let obj = this.workers[worker]; - if(obj) { - delete this.workers[worker]; - worker = obj.worker; - if(obj.onclose) onclose = obj.onclose; - } - } else if (typeof worker === 'object') { - if((worker as WorkerInfo)?._id) { - worker = (worker as WorkerInfo).worker; - delete this.workers[(worker as WorkerInfo)?._id]; - } - } - if(worker instanceof Worker) { - worker.terminate(); - if(onclose) onclose(worker); - if(str && this.get(str)) this.remove(str); - return true; - } - if(worker instanceof MessagePort) { - worker.close(); - if(onclose) onclose(worker); - if(str && this.get(str)) this.remove(str); - return true; - } - return false; - } - - //if no second id provided, message channel will exist to this thread - establishMessageChannel = ( - worker:Worker|string|MessagePort|WorkerInfo, - worker2?:Worker|string|MessagePort|WorkerInfo - ) => { - - let workerId; - if(typeof worker === 'string') { - workerId = worker; - if(this.workers[worker]){ - if(this.workers[worker].port) worker = this.workers[worker].port; - else worker2 = this.workers[worker].worker; - } - } else if ((worker as WorkerInfo)?.worker) { - worker = (worker as WorkerInfo).worker - } - if(typeof worker2 === 'string') { - if(this.workers[worker2]){ - if(this.workers[worker2].port) worker2 = this.workers[worker2].port; - else worker2 = this.workers[worker2].worker; - } - } else if ((worker2 as WorkerInfo)?.worker) { - worker2 = (worker2 as WorkerInfo).worker - } - - if(worker instanceof Worker || worker instanceof MessagePort) { - let channel = new MessageChannel(); - let portId = `port${Math.floor(Math.random()*1000000000000000)}`; - - worker.postMessage({route:'addWorker',args:{port:channel.port1, _id:portId }},[channel.port1]); - - if(worker2 instanceof Worker || worker2 instanceof MessagePort) { - worker2.postMessage({route:'addWorker',args:{port:channel.port2, _id:portId }},[channel.port2]); - } else if(workerId && this.workers[workerId]) { - channel.port2.onmessage = this.workers[workerId].onmessage; - this.workers[workerId].port = channel.port2; - } - - return portId; - } - - return false; - - } - - request = (message:ServiceMessage|any, workerId:string, transfer?:any, method?:string) => { - let worker = this.workers[workerId].worker; - return new Promise ((res,rej) => { - let callbackId = Math.random(); - let req = {route:'runRequest', args:[message, callbackId]} as any; - if(method) req.method = method; - let onmessage = (ev)=>{ - if(typeof ev.data === 'object') { - if(ev.data.callbackId === callbackId) { - worker.removeEventListener('message',onmessage); - res(ev.data.args); //resolve the request with the corresponding message - } - } - } - worker.addEventListener('message',onmessage) - this.transmit(req, worker, transfer); - }); - } - - runRequest = (message:ServiceMessage|any, worker:undefined|string|Worker|MessagePort, callbackId:string|number, getTransferable=true) => { - - let res = this.receive(message); - - if(typeof worker === 'string' && this.workers[worker]) { - if(this.workers[worker].port) worker = this.workers[worker].port; - else worker = this.workers[worker].worker; - } - if(res instanceof Promise) { - res.then((r) => { - let transfer = getTransferable ? this.getTransferable(r) : undefined; - if(worker instanceof Worker || worker instanceof MessagePort) - worker.postMessage({args:r,callbackId}, transfer) - else if(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) - globalThis.postMessage({args:r,callbackId},transfer); - }); - } else { - let transfer = getTransferable ? this.getTransferable(res) : undefined; - if(worker instanceof Worker || worker instanceof MessagePort) - worker.postMessage({args:res,callbackId}, transfer) - else if(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) - globalThis.postMessage({args:res,callbackId}, transfer); - } - - return res; - } - - subscribeWorker = ( - route:string, - worker:WorkerInfo|Worker|string|MessagePort, - args?:any[], - key?:string, - subInput?:boolean, - blocking?:boolean, //requires a WorkerInfo object - getTransferable:boolean=true - ) => { - if(this.restrict?.[route]) return undefined; - - let callback:(res:any) => void; - - //console.log('subscribeWorker', route, worker, blocking); - - if(blocking) { - - let blocked = false; - - callback = (res:any) => { - //console.log(worker,res,route,blocked) - if(!blocked) { - blocked = true; - - if(res instanceof Promise) { - res.then((r) => { - if((worker as WorkerInfo)?.run) - (worker as WorkerInfo).run('triggerSubscription',[route,(worker as WorkerInfo)._id,r]).then((ret)=>{ - blocked = false; - //if(ret !== undefined) this.setState({[worker._id]:ret}); - //console.log(ret) - }); - }); - } else { - if((worker as WorkerInfo)?.run) - (worker as WorkerInfo).run('triggerSubscription',[route,(worker as WorkerInfo)._id,res]).then((ret)=>{ - blocked = false; - //if(ret !== undefined) this.setState({[worker._id]:ret}); - //console.log(ret) - }); - } - } - } - } - else { - callback = (res:any) => { - //console.log('subscription triggered for', route, 'to', worker instanceof Worker ? worker : 'window', 'result:', res); - if(res instanceof Promise) { - res.then((r) => { - let transfer = getTransferable ? this.getTransferable(r) : undefined; - //console.log(transfer); - if((worker as Worker)?.postMessage) - (worker as Worker).postMessage({args:r,callbackId:route}, transfer) - else if(globalThis.postMessage) - globalThis.postMessage({args:r,callbackId:route}, transfer); - }); - } else { - let transfer = getTransferable ? this.getTransferable(res) : undefined; - //console.log(transfer); - if((worker as Worker)?.postMessage) - (worker as Worker).postMessage({args:res,callbackId:route}, transfer) - else if(globalThis.postMessage) - globalThis.postMessage({args:res,callbackId:route}, transfer); - } - } - } - - if(!blocking && (worker as WorkerInfo)?.port) { - worker = (worker as WorkerInfo).port; - } - else if(!blocking && (worker as WorkerInfo)?.worker) { - worker = (worker as WorkerInfo).worker; - } - else if(typeof worker === 'string' && this.workers[worker]) { - if(blocking) worker = this.workers[worker]; - else if(this.workers[worker].port) worker = this.workers[worker].port; - else worker = this.workers[worker].worker; - } //else we are subscribing to window - - return this.subscribe(route, callback, args, key, subInput); - } - - subscribeToWorker = ( - route:string, - workerId:string, - callback?:((res:any)=>void)|string, - args?:any[], - key?:string, - subInput?:boolean, - blocking?:boolean, //blocking subscriptions won't return if the subscribing thread hasn't finished with the result - getTransferable = true //auto process transfer arrays (default true) - ) => { - - if(typeof workerId === 'string' && this.workers[workerId]) { - this.__node.state.subscribeEvent(workerId, (res) => { - if(res?.callbackId === route) { - if(!callback) this.setState({[workerId]:res.args}); //just set state - else if(typeof callback === 'string') { //run a local node - this.run(callback,res.args); - } - else callback(res.args); - } - }); - return this.workers[workerId].run('subscribeWorker', [route, workerId, args, key, subInput, blocking, getTransferable]); - } - } - - triggerSubscription = async ( - route:string, - workerId:string, - result:any - ) => { - if(this.__node.state.triggers[workerId]) for(let i = 0; i < this.__node.state.triggers[workerId].length; i++) { - await this.__node.state.triggers[workerId][i].onchange({args:result, callbackId:route});//make sure async stuff resolves too - } - return true; - } - - pipeWorkers = ( //worker a listens to worker b, be sure to unsubscribe on the source when terminating - sourceWorker:WorkerInfo|string, - listenerWorker:WorkerInfo|string, - sourceRoute:string, - listenerRoute:string, - portId?:string, - args?:any[], - key?:any, - subInput?:boolean, - blocking?:boolean, - getTransferable?:boolean - ) => { - if(typeof sourceWorker === 'string') sourceWorker = this.workers[sourceWorker]; - if(typeof listenerWorker === 'string') listenerWorker = this.workers[listenerWorker]; - if(!portId) { - portId = this.establishMessageChannel(sourceWorker.worker,listenerWorker.worker) as string; - } - return listenerWorker.run('subscribeToWorker',[sourceRoute,portId,listenerRoute,args,key,subInput,blocking,getTransferable]) as Promise; //just run .unsubscribe on worker2. - } - - unpipeWorkers = ( - sourceRoute:string, - sourceWorker:WorkerInfo|string, - sub?:number - ) => { - if(typeof sourceWorker === 'string') sourceWorker = this.workers[sourceWorker]; - if(typeof sourceWorker === 'object') { - //console.log(sourceWorker,sourceRoute); - return sourceWorker.run('unsubscribe',[sourceRoute,sub]); - } - } - -} \ No newline at end of file diff --git a/src/services/worker/WorkerCanvas.ts b/src/services/worker/WorkerCanvas.ts deleted file mode 100644 index e023b800..00000000 --- a/src/services/worker/WorkerCanvas.ts +++ /dev/null @@ -1,572 +0,0 @@ -//provide routes for applying canvases to workers - -import worker from './canvas.worker' -import { proxyElementWorkerRoutes, initProxyElement } from './ProxyListener'; - -declare var WorkerGlobalScope; - -export type WorkerCanvasTransferProps = { //defined in main thread to send to worker - canvas:HTMLCanvasElement, - context?:string, - _id?:string, - draw?:string|((self:any,canvas:any,context:any)=>void), - update?:string|((self:any,canvas:any,context:any,input:any)=>void), - init?:string|((self,canvas:any,context:any)=>void), - clear?:string|((self,canvas:any,context:any)=>void), - transfer?:any[], - animating?:boolean, //animation will start automatically, else you can call draw conditionally - [key:string]:any //any transferrable props you want to use in your animation -} - -export type CanvasProps = { //defined in worker thread - canvas:any, //offscreen canvas - context?:string|CanvasRenderingContext2D|WebGL2RenderingContext|WebGLRenderingContext, - _id:string, - width?:number, - height?:number, - draw?:string|((self:any,canvas:any,context:any)=>void), - update?:string|((self:any,canvas:any,context:any,input:any)=>void), - init?:string|((self,canvas:any,context:any)=>void), - clear?:string|((self,canvas:any,context:any)=>void), - animating?:boolean, - preventDefault?:boolean, //we can generically prevent defaults on key events (except F1-12 for debug reasons) - [key:string]:any -} - -export type CanvasControls = { - _id:string, - draw:(props?:any,transfer?:any)=>void, //if you set props they will be available on "self" or "this" in the draw functions - update:(props:{[key:string]:any},transfer?:any)=>void, - clear:()=>void, - init:()=>void, - stop:()=>void, - start:()=>void, - set:(newDrawProps:CanvasProps,transfer?:any)=>void -} - -export type WorkerCanvasControls = { - worker:Worker|MessagePort, - terminate:()=>void -} & CanvasControls - -export type WorkerCanvas = { //this is the object stored on the worker to track this canvas context - graph:any, //Graph or Service class - canvas:any, //OffscreenCanvas - context?:CanvasRenderingContext2D|WebGL2RenderingContext|WebGLRenderingContext, - _id:string, - draw?:((self:WorkerCanvas,canvas:WorkerCanvas['canvas'],context:WorkerCanvas['context'])=>void), //runs in animation loop or on drawFrame calls - update?:((self:WorkerCanvas,canvas:WorkerCanvas['canvas'],context:WorkerCanvas['context'],input:any)=>void), - init?:((self:WorkerCanvas,canvas:WorkerCanvas['canvas'],context:WorkerCanvas['context'])=>void), - clear?:((self:WorkerCanvas,canvas:WorkerCanvas['canvas'],context:WorkerCanvas['context'])=>void), - stop:()=>void, - start:()=>void, - set:(newDrawProps:CanvasProps,transfer?:any)=>void, - terminate:()=>void, - animating:boolean, //animation will start automatically, else you can call draw conditionally - [key:string]:any //any transferrable props you want to use in your animation -} - -export function Renderer( - options:CanvasProps & { - worker?:Worker|string|Blob|MessagePort|true, - route?:string - } -) { - if(options.worker === true) { - options.worker = worker - } - if(options.worker) { - let worker = options.worker; - let route = options.route; - - if(worker instanceof Blob || typeof worker === 'string') { - worker = new Worker(worker as any); - } - delete options.worker; - delete options.route; - - return transferCanvas(worker as any, options as WorkerCanvasTransferProps, route); - } - else { - initProxyElement(options.canvas,undefined,options._id, options.preventDefault); - return setupCanvas(options); - } -} - - -export function transferCanvas( - worker:Worker|MessagePort, - options:WorkerCanvasTransferProps, - route?:string //we can reroute from the default 'setupCanvas' e.g. for other rendering init processes like in threejs -) { - - //console.log(options); - - if(!options) return undefined; - if(!options._id) options._id = `canvas${Math.floor(Math.random()*1000000000000000)}`; - - let offscreen = options.canvas instanceof OffscreenCanvas ? options.canvas : (options.canvas as any).transferControlToOffscreen(); - if(!options.width) options.width = options.canvas.clientWidth; - if(!options.height) options.height = options.canvas.clientHeight; - - let message:any = {route:route ? route : 'setupCanvas', args:{ - ...options, - canvas:offscreen, - }}; - - let proxy; - if(this?.__node?.graph) proxy = this.__node.graph.run('initProxyElement', options.canvas, worker, options._id, options.preventDefault); //initiate an element proxy - else proxy = initProxyElement(options.canvas,worker,options._id, options.preventDefault); - - if(options.draw) { - if(typeof options.draw === 'function') message.args.draw = options.draw.toString() - else message.args.draw = options.draw; - } - if(options.update) { - if(typeof options.update === 'function') message.args.update = options.update.toString() - else message.args.update = options.update; - } - if(options.init) { - if(typeof options.init === 'function') message.args.init = options.init.toString() - else message.args.init = options.init; - } - if(options.clear) { - if(typeof options.clear === 'function') message.args.clear = options.clear.toString() - else message.args.clear = options.clear; - } - - let tr = [offscreen]; - if(options.transfer) { - tr.push(...options.transfer); - delete options.transfer; - } - - //console.log(worker,message); - - worker.postMessage(message,tr); - - //lets add some utilities to make it easy to update the thread - const canvascontrols = { - _id:options._id, - width:options.width, - height:options.height, - worker, - draw:(props?:any,transfer?:any)=>{ - worker.postMessage({route:'drawFrame',args:[props,options._id]},transfer); - }, - update:(props:{[key:string]:any},transfer?:any)=>{ - worker.postMessage({route:'updateCanvas',args:[props,options._id]}, transfer); - }, - clear:()=>{ - worker.postMessage({route:'clearCanvas',args:options._id}) - }, - init:()=>{ - //console.log('Posting init') - worker.postMessage({route:'initCanvas',args:options._id}); - }, - stop:()=>{ - worker.postMessage({route:'stopAnim',args:options._id}) - }, - start:()=>{ - worker.postMessage({route:'startAnim',args:options._id}) - }, - set:(newDrawProps:CanvasProps,transfer?:any)=>{ - worker.postMessage({route:'setDraw',args:[newDrawProps,options._id]},transfer); - }, - terminate:()=>{ - if(proxy) proxy.terminate(); - (worker as Worker).terminate(); - } - } - - return canvascontrols as WorkerCanvasControls; -} - -export function setDraw( - settings:CanvasProps, - _id?:string -) { - let canvasopts; - if(this?.__node?.graph) { - if(_id) canvasopts = this.__node.graph.CANVASES?.[settings._id]; - else if(settings._id) canvasopts = this.__node.graph.CANVASES?.[settings._id]; - else canvasopts = this.__node.graph.CANVASES?.[Object.keys(this.__node.graph.CANVASES)[0]]; - } else { - if(_id) canvasopts = globalThis.CANVASES?.[settings._id]; - else if(settings._id) canvasopts = globalThis.CANVASES?.[settings._id]; - else canvasopts = globalThis.CANVASES?.[Object.keys(globalThis.CANVASES)[0]]; - } - - if(canvasopts) { - if(settings.canvas) { - canvasopts.canvas = settings.canvas; - - if(canvasopts.proxy) canvasopts.proxy.terminate(); - let proxy; - //create an element proxy to add event listener functionality - if(this?.__node?.graph) proxy = this.__node.graph.run('makeProxy', canvasopts._id, canvasopts.canvas); - else proxy = proxyElementWorkerRoutes.makeProxy(canvasopts._id, canvasopts.canvas); - - canvasopts.proxy = proxy; - //now the canvas can handle mouse and resize events, more can be implemented - } - if(typeof settings.context === 'string') canvasopts.context = canvasopts.canvas.getContext(settings.context); - else if(settings.context) canvasopts.context = settings.context; - - if(settings.width) canvasopts.canvas.width = settings.width; - if(settings.height) canvasopts.canvas.height = settings.height; - if(typeof settings.draw === 'string') settings.draw = parseFunctionFromText(settings.draw); - if(typeof settings.draw === 'function') { - canvasopts.draw = settings.draw.bind(settings); - } - if(typeof settings.update === 'string') settings.update = parseFunctionFromText(settings.update); - if(typeof settings.update === 'function') { - canvasopts.update = settings.update.bind(settings); - } - if(typeof settings.init === 'string') settings.init = parseFunctionFromText(settings.init); - if(typeof settings.init === 'function') { - canvasopts.init = settings.init.bind(settings); - } - if(typeof settings.clear === 'string') settings.clear = parseFunctionFromText(settings.clear); - if(typeof settings.clear === 'function') { - canvasopts.clear = settings.clear.bind(settings); - } - return settings._id; - } - return undefined; -} - - -export function setupCanvas( - options:CanvasProps -){ - if(this?.__node?.graph) { - if(!this.__node.graph.CANVASES) this.__node.graph.CANVASES = {} as {[key:string]:WorkerCanvas}; - } - else if(!globalThis.CANVASES) globalThis.CANVASES = {} as {[key:string]:WorkerCanvas}; - - let canvasOptions = options; - - options._id ? canvasOptions._id = options._id : canvasOptions._id = `canvas${Math.floor(Math.random()*1000000000000000)}`; - typeof options.context === 'string' ? canvasOptions.context = options.canvas.getContext(options.context) : canvasOptions.context = options.context; //get the rendering context based on string passed - ('animating' in options) ? canvasOptions.animating = options.animating : canvasOptions.animating = true; - - let proxy; - if(this?.__node?.graph?.CANVASES[canvasOptions._id]) { - this.__node.graph.run('setDraw',canvasOptions); - } else if(globalThis.CANVASES?.[canvasOptions._id]) { - setDraw(canvasOptions); - } else { - if(this?.__node?.graph) { - canvasOptions.graph = this.__node.graph; - if(!canvasOptions.__node) {canvasOptions.__node = {}} - if(!canvasOptions.__node.tag) canvasOptions.__node.tag = canvasOptions._id; - canvasOptions = this.__node.graph.add(canvasOptions); //replace with node - canvasOptions.__addOndisconnected = () => { - canvasOptions.stop(); - delete this.__node.graph.CANVASES[canvasOptions._id]; - } - } - - if(this?.__node?.graph) this.__node.graph.CANVASES[canvasOptions._id] = canvasOptions; - else globalThis.CANVASES[canvasOptions._id] = canvasOptions; - - //create an element proxy to add event listener functionality - if(this?.__node?.graph) proxy = this.__node.graph.run('makeProxy', canvasOptions._id, canvasOptions.canvas); - else proxy = proxyElementWorkerRoutes.makeProxy(canvasOptions._id, canvasOptions.canvas); - //now the canvas can handle mouse and resize events, more can be implemented - - if(options.width) canvasOptions.canvas.width = options.width; - if(options.height) canvasOptions.canvas.height = options.height; - - if(typeof canvasOptions.draw === 'string') { - canvasOptions.draw = parseFunctionFromText(canvasOptions.draw); - } else if(typeof canvasOptions.draw === 'function') { - canvasOptions.draw = canvasOptions.draw.bind(canvasOptions); - } - if(typeof canvasOptions.update === 'string') { - canvasOptions.update = parseFunctionFromText(canvasOptions.update); - } else if(typeof canvasOptions.update === 'function') { - canvasOptions.update = canvasOptions.update.bind(canvasOptions); - } - if(typeof canvasOptions.init === 'string') { - canvasOptions.init = parseFunctionFromText(canvasOptions.init); - } else if(typeof canvasOptions.init === 'function') { - canvasOptions.init = canvasOptions.init.bind(canvasOptions); - } - if(typeof canvasOptions.clear === 'string') { - canvasOptions.clear = parseFunctionFromText(canvasOptions.clear); - } else if(typeof canvasOptions.clear === 'function') { - canvasOptions.clear = canvasOptions.clear.bind(canvasOptions); - } - - - const finishSetup = () => { - canvasOptions.stop = () => {stopAnim(canvasOptions._id);}; - canvasOptions.start = (draw?:any) => {startAnim(canvasOptions._id,draw);}; - canvasOptions.set = (settings:any) => {setDraw(settings,canvasOptions._id);} - - if(typeof canvasOptions.draw === 'function' && canvasOptions.animating) { - let draw = (s,canvas,context) => { - if(s.animating) { - let res = s.draw(s,canvas,context); - if(res?.then) { - res.then(() => { - requestAnimationFrame(()=>{ - draw(s,canvas,context); - }); - }) - } - else requestAnimationFrame(()=>{ - draw(s,canvas,context); - }); - } - } - - draw(canvasOptions, canvasOptions.canvas,canvasOptions.context); - - } - - if(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) - return canvasOptions._id as string; - else { - //lets add some utilities to make it easy to update the thread - const canvascontrols = { - _id:options._id, - width:options.width, - height:options.height, - proxy, - draw:(props?:any)=>{ - drawFrame(props,options._id); - }, - update:(props:{[key:string]:any})=>{ - updateCanvas(props,options._id); - }, - clear:()=>{ - clearCanvas(options._id); - }, - init:()=>{ - //console.log('Posting init') - initCanvas(options._id); - }, - stop:()=>{ - stopAnim(options._id); - }, - start:()=>{ - startAnim(options._id); - }, - set:(newDrawProps:CanvasProps)=>{ - setDraw(newDrawProps,options._id); - }, - terminate:()=>{ - if(canvascontrols.proxy) { - canvascontrols.proxy.terminate(); - } - if(this.__node?.graph) this.__node.graph.remove(options._id); - else { - stopAnim(options._id); - if(this?.__node?.graph) delete this.__node.graph.CANVASES[canvasOptions._id]; - else delete globalThis.CANVASES[canvasOptions._id]; - } - } - } - - return canvascontrols as CanvasControls; - } - } - - if(typeof canvasOptions.init === 'function') { - let res = (canvasOptions.init as any)(canvasOptions, canvasOptions.canvas,canvasOptions.context); - if(res?.then) { - return new Promise((resolve) => { - res.then(()=>{ - resolve(finishSetup()) - }); - }) as Promise; - } - } - return finishSetup(); - - } -} - -//local function copy, same thing but returns the whole canvas object - -export function drawFrame(props?:{[key:string]:any},_id?:string) { //can update props when calling draw - - let canvasopts = getCanvas.call(this, _id); - - if(canvasopts) { - if(props) Object.assign(canvasopts,props); - if(canvasopts.draw) { - canvasopts.draw(canvasopts,canvasopts.canvas,canvasopts.context); - return _id; - } - } - return undefined; -} - - -export function clearCanvas(_id?:string) { - - let canvasopts = getCanvas.call(this, _id); - - if(canvasopts?.clear) { - canvasopts.clear(canvasopts,canvasopts.canvas,canvasopts.context); - return _id; - } - return undefined; -} - -export function initCanvas(_id?:string){ - - let canvasopts = getCanvas.call(this, _id); - - if(canvasopts?.init) { - canvasopts.init(canvasopts,canvasopts.canvas,canvasopts.context); - return _id; - } - return undefined; -} - -export function updateCanvas(input?:any,_id?:string){ - - let canvasopts = getCanvas.call(this, _id); - - if(canvasopts?.update) { - canvasopts.update(canvasopts,canvasopts.canvas,canvasopts.context,input); - return _id; - } - return undefined; -} - -export function setProps(props?:{[key:string]:any},_id?:string){ //update animation props, e.g. the radius or color of a circle you are drawing with a stored value - - let canvasopts = getCanvas.call(this, _id); - - if(canvasopts && props) { - Object.assign(canvasopts,props); - if(props.width) canvasopts.canvas.width = props.width; - if(props.height) canvasopts.canvas.height = props.height; - return _id; - } - return undefined; -} - -export function startAnim(_id?:string, draw?:string|((this:any,canvas:any,context:any)=>void)){ //run the draw function applied to the animation or provide a new one - - let canvasopts = getCanvas.call(this, _id); - - canvasopts.animating = true; - if(canvasopts && draw) { - if(typeof draw === 'string') draw = parseFunctionFromText(draw); - if(typeof draw === 'function') { - canvasopts.draw = draw; - } - return _id; - } - - if(typeof canvasopts?.draw === 'function') { - let draw = (s,canvas,context) => { - if(s.animating) { - s.draw(s,canvas,context); - requestAnimationFrame(()=>{ - draw(s,canvas,context); - }) - } - } - - if(typeof canvasopts.clear === 'function') (canvasopts.clear as any)(canvasopts, canvasopts.canvas, canvasopts.context); - if(typeof canvasopts.init === 'function') (canvasopts.init as any)(canvasopts, canvasopts.canvas, canvasopts.context); - - draw(canvasopts,canvasopts.canvas,canvasopts.context); - return _id; - } - return undefined; -} - -export function stopAnim(_id:string){ - - let canvasopts = getCanvas.call(this, _id); - - if(canvasopts) { - canvasopts.animating = false; - if(typeof canvasopts.clear === 'function') - requestAnimationFrame(canvasopts.clear(canvasopts, canvasopts.canvas, canvasopts.context)); - return _id; - } - return undefined; -} - -export function getCanvas (_id?:string) { - let canvasopts; - if(this?.__node?.graph) { - if(!_id) canvasopts = this.__node.graph.CANVASES?.[Object.keys(this.__node.graph.CANVASES)[0]]; - else canvasopts = this.__node.graph.CANVASES?.[_id]; - } else { - if(!_id) canvasopts = globalThis.CANVASES?.[Object.keys(globalThis.CANVASES)[0]]; - else canvasopts = globalThis.CANVASES?.[_id]; - } - return canvasopts; -} - -//load on front and backend -export const workerCanvasRoutes = { - ...proxyElementWorkerRoutes, - Renderer:Renderer, - transferCanvas:transferCanvas, - setupCanvas:setupCanvas, - setDraw:setDraw, - drawFrame:drawFrame, - clearCanvas:clearCanvas, - initCanvas:initCanvas, - updateCanvas:updateCanvas, - setProps:setProps, - startAnim:startAnim, - stopAnim:stopAnim, - getCanvas:getCanvas -}; - -function parseFunctionFromText(method='') { - //Get the text inside of a function (regular or arrow); - let getFunctionBody = (methodString) => { - return methodString.replace(/^\W*(function[^{]+\{([\s\S]*)\}|[^=]+=>[^{]*\{([\s\S]*)\}|[^=]+=>(.+))/i, '$2$3$4'); - } - - let getFunctionHead = (methodString) => { - let startindex = methodString.indexOf('=>')+1; - if(startindex <= 0) { - startindex = methodString.indexOf('){'); - } - if(startindex <= 0) { - startindex = methodString.indexOf(') {'); - } - return methodString.slice(0, methodString.indexOf('{',startindex) + 1); - } - - let newFuncHead = getFunctionHead(method); - let newFuncBody = getFunctionBody(method); - - - let newFunc; - if (newFuncHead.includes('function')) { - let varName = newFuncHead.split('(')[1].split(')')[0] - newFunc = new Function(varName, newFuncBody); - } else { - if(newFuncHead.substring(0,6) === newFuncBody.substring(0,6)) { - //newFuncBody = newFuncBody.substring(newFuncHead.length); - let varName = newFuncHead.split('(')[1].split(')')[0] - //console.log(varName, newFuncHead ,newFuncBody); - newFunc = new Function(varName, newFuncBody.substring(newFuncBody.indexOf('{')+1,newFuncBody.length-1)); - } - else { - try {newFunc = (0,eval)(newFuncHead + newFuncBody + "}");} catch {} - } - } - - return newFunc; - -} - - - diff --git a/src/services/worker/canvas.worker.ts b/src/services/worker/canvas.worker.ts deleted file mode 100644 index 8078f85a..00000000 --- a/src/services/worker/canvas.worker.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { workerCanvasRoutes } from './WorkerCanvas'; -//minimal web worker for running offscreen canvases, -//no graphscript required - -declare var WorkerGlobalScope; - -if(typeof WorkerGlobalScope !== 'undefined') { - - const routes = { - ...workerCanvasRoutes - //add more compatible routes that don't require graphscript - }; - - self.onmessage = (ev) => { - if(ev.data.route) { - if(Array.isArray(ev.data.args)) { - routes[ev.data.route](...ev.data.args); - } else routes[ev.data.route](ev.data.args); - } //that's it! The functions handle worker communication internally - - } - -} - -export default self as any; \ No newline at end of file diff --git a/src/services/wss/WSS.browser.ts b/src/services/wss/WSS.browser.ts deleted file mode 100644 index 6bed648f..00000000 --- a/src/services/wss/WSS.browser.ts +++ /dev/null @@ -1,452 +0,0 @@ - -import { GraphNode, GraphNodeProperties } from "../../core/Graph"; -import { Service, ServiceMessage, ServiceOptions } from "../Service"; - -export type WSSRoute = { - socket?:WebSocketInfo - transferFunctions?:{[key:string]:Function}, - transferClasses?:{[key:string]:Function}, - parentRoute?:string, //if a child of a socket node, subscribe to a route on a parent worker? - callback?:string, //Run this route on the socket when the operator is called. If this route is a child of another node, run this node on the child worker when it receives a message. - stopped?:boolean, // Don't run the callback until we call the thread to start? E.g. for recording data periodically. - blocking?:boolean, //should the subscribed socket wait for the subscriber to resolve before sending a new result? Prevents backup and makes async processing easier - init?:string, //run a callback on the socket on socket init? - initArgs?:any[] //arguments to go with the socket init? -} & GraphNodeProperties & WebSocketProps - -export type WebSocketProps = { - host:string, - port:number, - path?:string, - debug?:boolean, - onmessage?:(data:string | ArrayBufferLike | Blob | ArrayBufferView, ws:WebSocket, wsinfo:WebSocketInfo)=>void, //will use this.receive as default - onopen?:(ev:any, ws:WebSocket, wsinfo:WebSocketInfo)=>void, - onclose?:(ev:any, ws:WebSocket, wsinfo:WebSocketInfo)=>void, - onerror?:(ev:any, ws:WebSocket, wsinfo:WebSocketInfo)=>void, - protocol?:'ws'|'wss', - keepState?:boolean, - type?:'socket', - _id?:string, - [key:string]:any -} & GraphNodeProperties - -export type WebSocketInfo = { - socket:WebSocket, - address:string, - send:(message:any)=>void, - request:(message:any, method?:string)=>Promise, - post:(route:any, args?:any)=>void, - run:(route:any, args?:any, method?:string)=>Promise, - subscribe:(route:any, callback?:((res:any)=>void)|string, args?: any[], key?: string, subInput?: boolean)=>any, - unsubscribe:(route:any, sub:number)=>Promise, - terminate:()=>boolean, - _id?:string, - graph:WSSfrontend -} & WebSocketProps & GraphNode - -//browser side websockets -export class WSSfrontend extends Service { - - name='wss' - - sockets:{ - [key:string]:WebSocketInfo & GraphNode - } = { } - - connections = { //higher level reference for Router - sockets:this.sockets - } - - - constructor(options?:ServiceOptions) { - super(options) - this.load(this); - } - - loadWebSocketRoute = (node: WebSocketProps & GraphNode) => { - let wsInfo = this.openWS(node); - - if (!wsInfo.__ondisconnected) { - wsInfo.__addOndisconnected(() => { - wsInfo.terminate(); - }); - } - - if (!node.__operator) { - node.__operator = (...args) => { - //console.log('operator', args) - if(node.callback) { - if(!this.__node.nodes.get(node.__node.tag)?.__children) wsInfo.post(node.callback,args); - else return wsInfo.run(node.callback,args); - } else { - if(!this.__node.nodes.get(node.__node.tag)?.__children) wsInfo.send(args); - else return wsInfo.request(args); - } - } - } - - if(!node.__ondisconnected) { - let ondelete = (rt) => { //removing the original route will trigger ondelete - rt?.terminate(); - } - node.__addOndisconnected(ondelete); - } - - // Additional setup or event handlers can be added here - // ... - - return wsInfo; - }; - - socketloader = { - 'websockets': (node: WebSocketProps & GraphNode, parent: WebSocketProps & GraphNode, graph: WSSfrontend, roots: any) => { - node._id = node.__node.tag; - let ws = this.loadWebSocketRoute(node); - Object.assign(node,ws); - if (parent && parent.type === 'socket') { - let parentWs = this.sockets[parent._id]; - - // Logic to subscribe child node to parent WebSocket - if (node.parentRoute) { - parentWs.subscribe(node.parentRoute, node.__operator); - } - } - } - } - - openWS = ( - options:WebSocketProps = { - host:'localhost', - port:7000, - path:undefined, - protocol:'ws' - } - ) => { - - let protocol = options.protocol; - if(!protocol) protocol = 'ws'; - let address = `${protocol}://${options.host}`; - - if(!('keepState' in options)) options.keepState = true; - if(options.port) address+= ':'+options.port; - if(options.path && !options.path?.startsWith('/')) address += '/'; - if(options.path) address += options.path; - - if(this.sockets[address]?.socket) - if(this.sockets[address].socket.readyState === this.sockets[address].socket.OPEN) - this.sockets[address].socket.close(); //we'll try refresh the socket - - const socket = new WebSocket(address); - - if(!options.onmessage) { - if(!options._id) { - options.onmessage = (data:any, ws:WebSocket, wsinfo:WebSocketInfo) => { - if(data) if(typeof data === 'string') { - if(options.debug) { - console.log("Message from ",address, ": ", data); - } - let substr = data.substring(0,8); - if(substr.includes('{') || substr.includes('[')) { - if(substr.includes('\\')) data = data.replace(/\\/g,""); - if(data[0] === '"') { data = data.substring(1,data.length-1)}; - //console.log(message) - data = JSON.parse(data); //parse stringified objects - - if(data.route === 'setId') { - this.sockets[address]._id = data.args; - - options.onmessage = (data:any, ws:WebSocket, wsinfo:WebSocketInfo) => { //clear extra logic after id is set - if(options.debug) { - console.log("Message from ",address, ": ", data); - } - this.receive(data); - if(options.keepState) { - this.setState({[address as string]:data}); - } - } - } - } - } - - let res = this.receive(data); - if(options.keepState) this.setState({[address]:data}); - } //default onmessage - } - else { - options.onmessage = (data:any, ws:WebSocket, wsinfo:WebSocketInfo)=> { - if(options.debug) { - console.log("Message from ",(socket as WebSocket).url, ": ", data); - } - this.receive(data,socket,this.sockets[address]); - if(options.keepState) { - this.setState({[address]:data}); - } - }; - } - } - - if((options as any).onmessage) { - socket.addEventListener('message',(ev)=>{ - (this.sockets[address] as any).onmessage(ev.data, socket, this.sockets[address]); - }); - } - - socket.addEventListener('open',(ev)=>{ - if(this.sockets[address].onopen) (this.sockets[address] as any).onopen(ev, socket, this.sockets[address]); - }); - - socket.addEventListener('close',(ev)=>{ - let obj = this.sockets[address]; - let onclose = obj.onclose; - - delete this.sockets[address]; //delete by default onclose (memory saving) - this.remove(address); - - if(onclose) onclose(ev,socket, obj); - - }); - - socket.addEventListener('error',(ev)=>{ - if(this.sockets[address].onerror) (this.sockets[address] as any).onerror(ev,socket, this.sockets[address]); - }); - - - let send = (message:ServiceMessage|any) => { - //console.log('sent', message) - return this.transmit(message,socket); - } - - let post = (route:any,args?:any, method?:string) => { - //console.log('sent', message) - let message:any = { - route, - args - }; - if(method) message.method = method; - - return this.transmit(message,socket); - } - - let run = (route:any,args?:any,method?:string) => { - return new Promise ((res,rej) => { - let callbackId = Math.random(); - let req = { - route:'runRequest', - args:[{route, args}, this.sockets[address]._id, callbackId] - } as any; - if(method) req.args[0].method = method; - let onmessage = (ev)=>{ - let data = ev.data; - if(typeof data === 'string' && data.indexOf('{') > -1) data = JSON.parse(ev.data); - if(typeof data === 'object') { - if(data.callbackId === callbackId) { - socket.removeEventListener('message',onmessage); - res(data.args); //resolve the request with the corresponding message - } - } - } - socket.addEventListener('message',onmessage) - this.transmit(req, socket); - }); - } - - let request = (message:ServiceMessage|any, method?:string) => { - return new Promise ((res,rej) => { - let callbackId = Math.random(); - let req = {route:'runRequest', args:[message, this.sockets[address]._id, callbackId]} as any; - //console.log(req) - if(method) req.method = method; - let onmessage = (ev)=>{ - let data = ev.data; - if(typeof data === 'string' && data.indexOf('{') > -1) data = JSON.parse(ev.data); - if(typeof data === 'object') { - if(data.callbackId === callbackId) { - socket.removeEventListener('message',onmessage); - res(data.args); //resolve the request with the corresponding message - } - } - } - socket.addEventListener('message',onmessage) - this.transmit(req, socket); - }); - } - - let subscribe = (route:any, callback?:((res:any)=>void)|string, args?: any[], key?: string, subInput?: boolean):Promise => { - return this.subscribeToSocket(route, this.sockets[address]._id, callback, args, key, subInput); - } - - let unsubscribe = (route:any, sub:number):Promise => { - return run('unsubscribe',[route,sub]); - } - - let terminate = () => { - return this.terminate(address); - } - - Object.assign(options, { - type:'socket', - socket, - address, - send, - post, - run, - request, - subscribe, - unsubscribe, - terminate - }); - - if(!(options instanceof GraphNode)) { - let node = this.add(options); - node.__addOndisconnected(function() { terminate(); }); - options = node as any; - } - this.sockets[address] = options as GraphNode & WebSocketInfo; - //console.log(node,this.get(address),this.sockets[address]); - - return options as WebSocketInfo; - } - - open = this.openWS; - - transmit = ( - data:string | ArrayBufferLike | Blob | ArrayBufferView | ServiceMessage, - ws:WebSocket - ) => { - if( - (typeof data === 'object' && - (((data as ServiceMessage)?.route || ((data as ServiceMessage)?.node)) || ( - typeof (data as Blob).arrayBuffer !== 'function' && - typeof (data as ArrayBufferLike).byteLength !== 'number' - ))) || typeof data === 'number' - ) data = JSON.stringify(data); - if(!ws) { - let s = this.sockets[Object.keys(this.sockets)[0]]; - if(s) ws = s.socket; - } - if(ws instanceof WebSocket && ws?.readyState === 1) ws.send(data as any); - - return true; - } - - terminate = (ws:WebSocket|string) => { - - let str; - if(!ws) { - //terminate all - let keys = Object.keys(this.sockets) - for(const key in keys) { - this.terminate(key); - } - } - else if(typeof ws === 'string') { - str = ws; - for(const k in this.sockets) { - if(k.includes(ws) || this.sockets[k]._id === k) { - ws = this.sockets[k].socket; - break; - } - } - } - - if(ws instanceof WebSocket) { - if(ws.readyState === ws.OPEN) - ws.close(); - - if(this.get(str ? str : ws.url)) this.remove(str ? str : ws.url); - } - - return true; - } - - request = ( - message:ServiceMessage|any, - ws:WebSocket, - _id:string, - method?:string - ) => { //return a promise which can resolve with a server route result through the socket - let callbackId = `${Math.random()}`; - let req:any = {route:'runRequest', args:[message,_id,callbackId]}; - if(method) req.method = method; - return new Promise((res,rej) => { - let onmessage = (ev:any) => { - let data = ev.data; - if(typeof data === 'string') if(data.includes('callbackId')) data = JSON.parse(data); - if(typeof data === 'object') if(data.callbackId === callbackId) { - ws.removeEventListener('message',onmessage); - res(data.args); - } - } - - ws.addEventListener('message',onmessage); - ws.send(JSON.stringify(req)); - }) - } - - runRequest = ( - message:any, - ws:WebSocket|string, - callbackId:string|number - ) => { //send result back - //console.log('running request', message, this.__node.nodes); - let res = this.receive(message); - if(typeof ws === 'string') { - for(const s in this.sockets) { - if(s === ws || this.sockets[s]._id === ws) {ws = this.sockets[s].socket; break;} - } - } - if(ws) { - if(res instanceof Promise) { - res.then((v) => { - res = {args:v, callbackId}; - if(ws instanceof WebSocket) ws.send(JSON.stringify(res)); - }) - } - else { - res = {args:res, callbackId}; - if(ws instanceof WebSocket) ws.send(JSON.stringify(res)); - } - } - - return res; - } - - subscribeSocket = (route:string, socket:WebSocket|string, args?:any[], key?:string, subInput?:boolean) => { - if(this.restrict?.[route]) return undefined; - if(typeof socket === 'string' && this.sockets[socket]) { - socket = this.sockets[socket].socket; - } - - if(typeof socket === 'object') { - return this.subscribe(route, (res:any) => { - //console.log('running request', message, 'for worker', worker, 'callback', callbackId) - if((socket as WebSocket).readyState === (socket as WebSocket).OPEN) { - if(res instanceof Promise) { - res.then((r) => { - (socket as WebSocket).send(JSON.stringify({args:r, callbackId:route})); - }); - } else { - (socket as WebSocket).send(JSON.stringify({args:res, callbackId:route})); - } - } - },args,key,subInput); - } - } - - subscribeToSocket = (route:string, socketId:string, callback?:((res:any)=>void)|string, args?:any[], key?:string,subInput?:boolean) => { - if(typeof socketId === 'string' && this.sockets[socketId]) { - this.__node.state.subscribeEvent(socketId, (res) => { - let msg = JSON.parse(res); - if(msg?.callbackId === route) { - if(!callback) this.setState({[socketId]:msg.args}); //just set state - else if(typeof callback === 'string') { //run a local node - this.run(callback,msg.args); - } - else callback(msg.args); - } - }); - return this.sockets[socketId].request({route:'subscribeSocket', args:[route,socketId, args, key,subInput]}); - } - } - -} diff --git a/tinybuild.node.config.js b/tinybuild.node.config.js index 8268b979..8e468636 100644 --- a/tinybuild.node.config.js +++ b/tinybuild.node.config.js @@ -4,7 +4,7 @@ const config = { entryPoints: [ //entry point file(s). These can include .js, .mjs, .ts, .jsx, .tsx, or other javascript files. Make sure your entry point is a ts file if you want to generate types "index.node.ts" ], - outfile: "dist/index.node", //exit point file, will append .js as well as indicators like .esm.js, .node.js for other build flags + outfile: "dist/index", //exit point file, will append .js as well as indicators like .esm.js, .node.js for other build flags //outdir:[] //exit point files, define for multiple bundle files bundleBrowser: false, //create plain js build? Can include globals and init scripts bundleESM: false, //create esm module js files diff --git a/todo.md b/todo.md deleted file mode 100644 index 7363da63..00000000 --- a/todo.md +++ /dev/null @@ -1,19 +0,0 @@ -## TODO - -- Make proper loaders for all of our services so they can be declared and used in the tree definitions - -- Optimize some of the remote callback system, use a single callback and just check a list of callbackIds instead of a new messageevent for every request as it will parse JSON for each callback (much more inefficient). This is only for going pedal-to-the-metal with sockets etc but why shouldn't we. - -- Make definitive benchmarks - -- Document the router etc in great detail, need to streamline it a bit more as it introduces a lot of weird options structures that are a bit convoluted. - -- fix the local struct backend, it just seems to be stringifying for some reason. - -- Forever bug testing and trying to raise things to "industry standard" without making it artificially difficult to use the whole system. We want this to be baby's first super API - -## Demos todo - -- Editor: demonstrate live editing on a multithreaded + server application - -- bring other examples more up to date, try to get closer to more typical game logic standards our examples are all made by flying by the seat of our pants and not trying to seriously model standard engine code. That's part of the point though so there's a balance to strike between creative code and familiarity. Priority 1 is readability of the logic however, as it makes complex systems that much easier to build. \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index baefe6fe..cf913bf7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,10 +4,10 @@ /* Visit https://aka.ms/tsconfig.json to read more about this file */ /* Basic Options */ // "incremental": true, /* Enable incremental compilation */ - "target": "ESNext" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, - "module": "ESNext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, + "target": "es2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, + "module": "es2020" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, "declaration": true, /* Generates corresponding '.d.ts' file. */ - "allowJs": true, /* Allow javascript files to be compiled. */ + "allowJs": false, /* Allow javascript files to be compiled. */ "skipLibCheck": true /* Skip type checking of declaration files. */, "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, "outDir": "./dist" /* Redirect output structure to the directory. */, diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000..01ea3df0 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,45 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@types/node@*": + version "17.0.36" + resolved "https://registry.npmjs.org/@types/node/-/node-17.0.36.tgz" + integrity sha512-V3orv+ggDsWVHP99K3JlwtH20R7J4IhI1Kksgc+64q5VxgfRkQG8Ws3MFm/FZOKDYGy9feGFlZ70/HpCNe9QaA== + +"@types/node@~18.7.15": + version "18.7.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.18.tgz#633184f55c322e4fb08612307c274ee6d5ed3154" + integrity sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg== + +"@types/ws@~8.5.3": + version "8.5.3" + resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== + dependencies: + "@types/node" "*" + +better-sse@~0.8.0: + version "0.8.0" + resolved "https://registry.npmjs.org/better-sse/-/better-sse-0.8.0.tgz" + integrity sha512-ymOse8R0L+R2S1W85yOGkkc+yTzAmo52S4erjxPyBVwpqjpS+X228BG7hDwgKsGV/D51YhCYd+eaDwJ+sL5JhA== + +brainsatplay-math@~0.0.22: + version "0.0.22" + resolved "https://registry.npmjs.org/brainsatplay-math/-/brainsatplay-math-0.0.22.tgz" + integrity sha512-er+7fobi+bgtuiaN5Pcg0cpOfl/d5hrM8W8sF5lnX9VWhcs2TvyG3J0UV+pozGYSBvtqij7Evs4HhhFIh3cfbQ== + +bson-objectid@~2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/bson-objectid/-/bson-objectid-2.0.3.tgz" + integrity sha512-WYwVtY9yqk179EPMNuF3vcxufdrGLEo2XwqdRVbfLVe9X6jLt7WKZQgP+ObOcprakBGbHxzl76tgTaieqsH29g== + +web-worker@~1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz" + integrity sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA== + +ws@~8.8.1: + version "8.8.1" + resolved "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz" + integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==