@kemu-io/edge-runtime 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/runner.js +1 -1
package/package.json
CHANGED
package/runner.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readFile as e,access as t}from"node:fs/promises";import{nanoid as n}from"nanoid";import r from"jsonp";import a from"crypto-js";import i from"util";import o from"emittery";import"axios";import s from"jszip";import{satisfies as c,compare as u}from"compare-versions";import d from"debug";import l,{join as p,resolve as g,dirname as m}from"path";import v from"node-ipc";import{readFile as f,access as y,constants as h,rm as I,mkdir as S}from"fs/promises";import $ from"minimist";import w,{promises as b}from"fs";import{spawn as N}from"child_process";import{createHash as A}from"crypto";import{homedir as x}from"os";import{WebSocketServer as C}from"ws";import{fileURLToPath as P}from"url";import E from"node:os";import{exec as j}from"node:child_process";import{createId as D}from"@paralleldrive/cuid2";import{dirname as k,join as O,resolve as T}from"node:path";import{ImageData as L,loadImage as M,createCanvas as B}from"@napi-rs/canvas";var R;!function(e){e.STARTING="STARTING",e.PENDING="PENDING",e.RUNNING="RUNNING",e.PAUSED="PAUSED",e.DRAINING="DRAINING",e.STOPPED="STOPPED",e.ERROR="ERROR"}(R=R||(R={}));const W={};let U=0,F="";const _=e=>W[e]?W[e]:null,G=(e,t)=>{const n=_(e);if(!n)return n;return n.blocks[t]||null},z=(e,t,n)=>{const r=G(e,t);if(!r)return r;return r.gates[n]},V=(e,t)=>{let r=n(4);for(;W[r];)r=n(4);const a=(i=e,JSON.parse(JSON.stringify(i)));var i;return a.logs="",a.addLog=e=>{a.logs+=`${(()=>{const e=Date.now();if(e!==U){const t=new Date;U=e,F=t.toJSON()}return F})()}:: ${e}\n`},a.dbInfo={...t},W[r]=a,r},H="interrupt_port",J="main.js",q="state.json",K="{#}",X="$var_",Y="default";var Z,Q,ee,te,ne,re,ae,ie;!function(e){e.Browser="browser",e.Cloud="cloud",e.Desktop="desktop"}(Z||(Z={})),function(e){e[e.Number=0]="Number",e[e.String=1]="String",e[e.ArrayBuffer=2]="ArrayBuffer",e[e.Array=3]="Array",e[e.Boolean=4]="Boolean",e[e.JsonObj=5]="JsonObj",e[e.Anything=6]="Anything",e[e.ImageData=7]="ImageData",e[e.AudioBuffer=8]="AudioBuffer",e[e.Rect=9]="Rect",e[e.Point=10]="Point",e[e.ImageBitmap=11]="ImageBitmap",e[e.BinaryFile=12]="BinaryFile"}(Q||(Q={})),function(e){e.Number="Number",e.String="String",e.ArrayBuffer="ArrayBuffer",e.Array="Array",e.Boolean="Boolean",e.JsonObj="JsonObj",e.Anything="Anything",e.ImageData="ImageData",e.AudioBuffer="AudioBuffer",e.Rect="Rect",e.Point="Point",e.ImageBitmap="ImageBitmap",e.BinaryFile="BinaryFile"}(ee||(ee={})),function(e){e.Javascript="js",e.Python="py",e.Executable="exe"}(te||(te={})),function(e){e.IpcAcknowledge="iack:",e.SocketAcknowledge="sack:",e.AcknowledgeResponse="ackr:",e.ServicesListChanged="update-services",e.SendManifest="send-manifest",e.BroadcastStart="broadcast-start",e.BroadcastEnd="broadcast-end",e.AssumeSession="assume:"}(ne||(ne={})),function(e){e.GetServices="getServices",e.SubscribeToService="subscribeToService",e.UnsubscribeFromService="unsubscribeFromService",e.GetServiceContents="getServiceContents",e.OnParentEvent="onParentEvent",e.GetDefaultState="getDefaultState",e.BroadcastEvent="broadcastEvent",e.HubBroadcastEvent="hubBroadcastEvent",e.ServiceManifest="serviceManifest",e.GetState="getState",e.SetState="setState",e.SetOutputs="setOutputs",e.UIEvent="uiEvent",e.InitializeInstance="initializeInstance",e.TerminateInstance="terminateInstance",e.ChooseDirectoryDialog="chooseDirectoryDialog",e.ChooseFileDialog="chooseFileDialog",e.GetUniqueId="getUniqueId"}(re||(re={})),function(e){e.SetDependencyPath="setDependencyPath",e.GetDependencyPath="getDependencyPath"}(ae||(ae={})),function(e){e.IPC="ipc",e.WS="ws"}(ie||(ie={}));const oe="undefined"!=typeof window&&void 0!==window.document&&void 0!==typeof window.document.createElement,se="object"==typeof self&&self.constructor&&"DedicatedWorkerGlobalScope"===self.constructor.name,ce="undefined"!=typeof process&&null!=process.versions&&null!=process.versions.node,ue="-",de=`inner${ue}`,le=`outer${ue}`,pe=`${le}input${ue}`,ge=`${le}output${ue}`,me=`${de}input${ue}`,ve=`${de}output${ue}`,fe=e=>(new TextEncoder).encode(e),ye=e=>e===H,he=e=>e&&void 0!==e.width&&void 0!==e.height&&void 0!==e.data&&e.data.constructor&&"Uint8ClampedArray"===e.data.constructor.name,Ie=e=>e&&void 0!==e.width&&void 0!==e.height&&void 0!==e.top&&void 0!==e.left&&"number"==typeof e.width&&"number"==typeof e.height&&"number"==typeof e.top&&"number"==typeof e.left,Se=e=>e&&"number"==typeof e.x&&"number"==typeof e.y,$e=e=>"number"==typeof e?Q.Number:"string"==typeof e?Q.String:"boolean"==typeof e?Q.Boolean:Array.isArray(e)?Q.Array:he(e)?Q.ImageData:e&&void 0!==e.duration&&void 0!==e.length&&void 0!==e.numberOfChannels&&void 0!==e.sampleRate&&"function"==typeof e.getChannelData&&"AudioBuffer"===e.constructor.name?Q.AudioBuffer:e&&void 0!==e.byteLength?Q.ArrayBuffer:Ie(e)?Q.Rect:e&&void 0!==e.x&&void 0!==e.y&&"number"==typeof e.x&&"number"==typeof e.y?Q.Point:Q.JsonObj,we=e=>{const t={};let n;n=Array.isArray(e)?e[0]:e;for(const e in n){const r=$e(n[e]);t[e]=r}return t},be=(e,t,n)=>"inner"===e?"input"===t?`${me}${n}`:`${ve}${n}`:"input"===t?`${pe}${n}`:`${ge}${n}`,Ne=e=>{const t=(e||"")?.split("_");if(t.length<3)throw new Error(`Unknown child identifier format [${e}]`);const n=t[0];return{portType:t[1],widgetId:n,portName:t[2]}},Ae=e=>new ImageData(e.data,e.width,e.height,{colorSpace:e.colorSpace});var xe,Ce;!function(e){e.Action="action",e.CustomInput="customInput"}(xe=xe||(xe={})),function(e){e.input="input",e.counter="counter",e.play="play",e.elapsed="elapsed",e.ifGate="ifGate",e.skipEvent="skipEvent",e.between="between",e.map="map",e.parser="parser",e.slider="slider",e.suspend="suspend",e.display="display",e.json="json",e.arrayItem="arrayItem",e.extractImage="extractImage",e.imageConvolution="imageConvolution",e.firstEvent="firstEvent",e.pixelDraw="pixelDraw",e.randomBetween="randomBetween",e.arrayCombine="arrayCombine",e.clock="clock",e.multiplication="multiplication",e.object="object",e.widgetGroup="widgetGroup",e.script="script",e.base64ToImageData="base64ToImageData",e.jsonParse="jsonParse",e.text="text",e.imageCrop="imageCrop",e.imageResize="imageResize",e.value="value",e.imageWarp="imageWarp",e.widgetBundle="widgetBundle",e.sequence="sequence",e.variable="variable",e.hubService="hubService",e.imageFilter="imageFilter"}(Ce=Ce||(Ce={}));const Pe={};let Ee;const je=async e=>{const t=Pe[e],n={name:H,type:Q.Boolean};if(t){const r={name:t.portName},a=t.data||{type:Q.Boolean,value:!0};Ee?(await Ee(!0,t.targetWidgetId,t.thingId,t.recipePoolId,n.name,r,{...a,timestamp:Date.now()},[n]),"timeout"===t.type&&De(e)):console.warn("Interrupt service has not been initialized")}},De=e=>{const t=Pe[e];return!!t&&(t.timerRef&&("interval"===t.type?clearInterval(t.timerRef):"timeout"===t.type&&clearTimeout(t.timerRef)),delete Pe[e],!0)};var ke={interruptHandler:je,createInterrupt:(e,t,r,a,i,o,s,c)=>{if(c&&Pe[c])throw new Error("The given interrupt id already exists");const u=c||n().replace(/_/g,"-");if("interval"===e&&!o.interval)throw new Error(`Invalid interval. Expected a number greater than 0, but got '${o.interval}'`);if("timeout"===e&&!o.timeout)throw new Error(`Invalid timeout. Expected a number greater than 0, but got '${o.timeout}'`);if(Pe[u]={data:s,portName:i,recipePoolId:t,targetWidgetId:a,thingId:r,type:e},"interval"===e)Pe[u].timerRef=setInterval((async()=>await je(u)),o.interval);else{if("timeout"!==e)throw new Error(`Invalid interrupt type '${e}'`);Pe[u].timerRef=setTimeout((async()=>await je(u)),o.timeout)}return u},destroyInterrupt:De,destroyAllInterrupts:()=>{Object.keys(Pe).forEach(De)},setInvokeChildGateCb:e=>{Ee=e}};const Oe=(e,t,n,r,a)=>{const i=z(e,n,r);if(!i)return console.warn(`Gate ${r} not found in block ${n} for recipe ${e}`),null;const o=(t,a,i,o)=>ke.createInterrupt(t,e,n,r,a,i,o),s=()=>Object.freeze({...i.state,...i.type===Ce.input&&{customInputs:[]}}),c=e=>{if("object"!=typeof e)return void console.warn(`Invalid state type [${typeof e}]. Expected an 'object'`);const t={...e,...i.type===Ce.input&&!e.customInputs&&{customInputs:[]}};i.state=t};if(a){return{getState:s,setState:c,registerInterrupt:o,getStorageData:async t=>{const r=((e,t,n)=>{const r=_(e);if(!r)throw new Error(`Recipe [${e} does not exist]`);if(!r.storage)return null;const a=G(e,t);if(!a)throw new Error(`The Thing "${t}" does not exist in recipe ${e}`);if(!(a.storageUnits||[]).includes(n))throw new Error(`The Thing "${t}" has no access to storage unit "${n}"`);return r.storage[n]||null})(e,n,t);return r},recipePoolId:e,recipeType:t,thingRecipeId:n,widgetThingId:r}}return{getState:s,setState:c,recipePoolId:e,widgetId:r}},Te=[10001,"Invalid `sourcePort` parameter"],Le=[10002,"The gate [%s] does not exist. Have you called `loadWidgets` yet?"],Me=[10110,"No storage medium has been loaded, call `loadMedium()` first"],Be=(e,...t)=>JSON.stringify({code:e[0],message:t[0]?i.format(e[1],...t):e[1].replace(/ \[%s\]/g,"")}),Re=()=>({inputName:"",dataType:Q.Anything}),We="output",Ue={processEvent:async(e,t)=>{const n=t.getState(),r={...Re(),...n};if(e.type===r.dataType)return t.nextWidget(We,{type:e.type,value:e.value});console.error(`Invalid data type: ${e.type} for input: ${r.inputName}. Expected: ${r.dataType}`)},getOutputNames:e=>{const t={...Re(),...e};return[{name:We,type:t.dataType}]},getInputNames:()=>[]},Fe=Object.freeze({in:"in",reset:"reset",increment:"increment"}),_e="output";var Ge={onParentEvent:async(e,t,n,r)=>{if(!e)throw new Error(Be(Te));const a={currentValue:0,increment:1,...r.getState()};let i=a.increment,o=a.currentValue;const s=await r.getParentAtPort(Fe.increment);if(t.name===Fe.increment)return void(n.data.type===Q.Number&&r.setState({...a,increment:Number(n.data.value)}));if(s){const e=s.getValue();null!==e&&(i=e)}if(t.name===Fe.reset)return r.setState({...a,currentValue:0});o+=i,r.setState({currentValue:o,increment:i});const c={type:Q.Number,value:o};return r.nextGate(_e,c)},getInputNames:()=>[{name:Fe.in,type:Q.Anything},{name:Fe.reset,type:Q.Anything},{name:Fe.increment,type:Q.Number}],getOutputNames:()=>[{name:_e,type:Q.Number}]};const ze=Object.freeze({in:"in",reset:"reset"}),Ve="output";var He={onParentEvent:async(e,t,n,r)=>{const a={updatedAt:0,elapsed:0,...r.getState()},i=Date.now(),o=i-(a.updatedAt||i);return t.name===ze.reset?r.setState({...a,updatedAt:i,elapsed:0}):(r.setState({updatedAt:i,elapsed:o}),r.nextGate(Ve,{type:Q.Number,value:o}))},getInputNames:()=>[{name:ze.in,type:Q.Anything},{name:ze.reset,type:Q.Anything}],getOutputNames:()=>[{name:Ve,type:Q.Number}]};const Je=Object.freeze({data:"data",evaluation:"evaluation"}),qe="then",Ke="else";var Xe={onParentEvent:async(e,t,n,r)=>{const a={value:5,condition:"Equal",useDataPort:!1,...r.getState()},i=n.data.value,o=!isNaN(Number(i)),s="string"==typeof i;if(!a.useDataPort&&(n.data.type===Q.Number||n.data.type===Q.String||n.data.type===Q.Anything&&o||n.data.type===Q.Anything&&s)){let e=!1;return("Equal"===a.condition&&n.data.value==a.value||"Not Equal"===a.condition&&n.data.value!==a.value||"Greater"===a.condition&&n.data.value>Number(a.value)||"Less"===a.condition&&n.data.value<Number(a.value)||"Starts With"===a.condition&&String(n.data.value).startsWith(String(a.value))||"Ends With"===a.condition&&String(n.data.value).endsWith(String(a.value))||"Includes"===a.condition&&String(n.data.value).includes(String(a.value))||"Matches"===a.condition&&String(n.data.value).match(String(a.value)))&&(e=!0),e?r.nextGate(qe,n.data):r.nextGate(Ke,n.data)}if((t.name===Je.evaluation&&n.data.type===Q.Number||n.data.type===Q.String||n.data.type===Q.Anything&&(o||s))&&(a.$lastValue=n.data.value,r.setState({...a})),t.name===Je.data){let e=!1;return("Equal"===a.condition&&a.$lastValue==a.value||"Not Equal"===a.condition&&a.$lastValue!==a.value||"Greater"===a.condition&&Number(a.$lastValue)>Number(a.value)||"Less"===a.condition&&Number(a.$lastValue)<Number(a.value)||"Starts With"===a.condition&&String(a.$lastValue).startsWith(String(a.value))||"Ends With"===a.condition&&String(a.$lastValue).endsWith(String(a.value))||"Includes"===a.condition&&String(a.$lastValue).includes(String(a.value))||"Matches"===a.condition&&String(a.$lastValue).match(String(a.value)))&&(e=!0),r.setState({...a,$lastValue:void 0,$lastDataType:n.data.type}),e?r.nextGate(qe,n.data):r.nextGate(Ke,n.data)}},getInputNames:e=>e.useDataPort?[{name:Je.data,type:Q.Anything},{name:Je.evaluation,type:[Q.Number,Q.String]}]:[{name:"in",type:[Q.Number,Q.String]}],getOutputNames:e=>e.$lastDataType?[{name:qe,type:e.$lastDataType},{name:Ke,type:e.$lastDataType}]:[{name:qe,type:[Q.Number,Q.String]},{name:Ke,type:[Q.Number,Q.String]}]};const Ye=Object.freeze({in:"in",reset:"reset"}),Ze="out";var Qe={onParentEvent:async(e,t,n,r)=>{const a={totalCalls:0,callsLimit:1,...r.getState()};return t.name===Ye.reset?r.setState({...a,totalCalls:0}):(a.totalCalls=a.totalCalls+1,a.totalCalls>a.callsLimit?(a.totalCalls=0,r.setState(a),r.nextGate(Ze,n.data)):void r.setState(a))},getInputNames:()=>[{name:Ye.in,type:Q.Anything},{name:Ye.reset,type:Q.Anything}],getOutputNames:()=>[{name:Ze,type:Q.Anything}]};const et=Object.freeze({in:"in"}),tt="then",nt="else";var rt={onParentEvent:async(e,t,n,r)=>{const a={min:1,max:10,...r.getState()};if(n.data.type===Q.Number)return n.data.value>=a.min&&n.data.value<=a.max?r.nextGate(tt,n.data):r.nextGate(nt,n.data)},getInputNames:()=>[{name:et.in,type:Q.Number}],getOutputNames:()=>[{name:tt,type:Q.Number},{name:nt,type:Q.Number}]};const at=Object.freeze({in:"in"}),it="out";var ot={onParentEvent:async(e,t,n,r)=>{const a={clamp:!0,...r.getState()},i=Number(n.data.value);if(void 0!==a.fromMax&&void 0!==a.fromMin&&void 0!==a.toMax&&void 0!==a.toMin&&""!==a.fromMax&&""!==a.fromMin&&""!==a.toMax&&""!==a.toMin&&(n.data.type===Q.Number||n.data.type===Q.Anything&&!isNaN(Number(i)))){let e=((e,t,n,r,a)=>(e-t)*(a-r)/(n-t)+r)(i,Number(a.fromMin),Number(a.fromMax),Number(a.toMin),Number(a.toMax));if(isNaN(e))return;return a.clamp&&(e<Number(a.toMin)&&(e=Number(a.toMin)),e>Number(a.toMax)&&(e=Number(a.toMax))),r.nextGate(it,{type:Q.Number,value:Number(e)})}},getInputNames:()=>[{name:at.in,type:Q.Number}],getOutputNames:()=>[{name:it,type:Q.Number}]};const st=Object.freeze({in:"in"}),ct="out";var ut={onParentEvent:async(e,t,n,r)=>{const a={convertTo:"Integer",floatPlaces:2,...r.getState()};let i=n.data.value;if(n.data.type===Q.Number||n.data.type===Q.Anything||n.data.type===Q.String){if((!isNaN(Number(i))||"string"==typeof i)&&!Array.isArray(i))return"Integer"===a.convertTo?i=parseInt(i):"Decimal"===a.convertTo?i=parseFloat(Number(i).toFixed(a.floatPlaces)):"String"===a.convertTo?i=String(i):"Abs"===a.convertTo?i=Math.abs(Number(i)):"Round"===a.convertTo&&(i=Math.round(Number(i))),r.nextGate(ct,{type:"String"===a.convertTo?Q.String:Q.Number,value:i})}},getInputNames:()=>[{name:st.in,type:Q.Number}],getOutputNames:e=>{const t="String"===e?.convertTo?Q.String:Q.Number;return[{name:ct,type:t}]}};const dt=Object.freeze({in:"in"}),lt="out";var pt={onParentEvent:async(e,t,n,r)=>{const a={currentValue:50,min:0,max:100,...r.getState()};let i=!1;return a.currentValue<a.min&&(a.currentValue=a.min,i=!0),a.currentValue>a.max&&(a.currentValue=a.max,i=!0),i&&r.setState(a),r.nextGate(lt,{type:Q.Number,value:a.currentValue})},getInputNames:()=>[{name:dt.in,type:Q.Anything}],getOutputNames:()=>[{name:lt,type:Q.Number}]};const gt=Object.freeze({in:"in",reset:"reset"}),mt="out";var vt={onParentEvent:async(e,t,n,r)=>{const a={lastCalledAt:0,delayMs:500},i={lastCalledAt:0,delayMs:500,...r.getState()};if(t.name===gt.reset)return r.setState({...i,lastCalledAt:0});const o=Date.now(),s=o-i.lastCalledAt;return i.lastCalledAt===a.lastCalledAt||s>=i.delayMs&&i.delayMs>0?(i.lastCalledAt=o,r.setState(i),r.nextGate(mt,n.data)):void 0},getInputNames:()=>[{name:gt.in,type:Q.Anything},{name:gt.reset,type:Q.Anything}],getOutputNames:()=>[{name:mt,type:Q.Anything}]};const ft="in";var yt={onParentEvent:async()=>{},getInputNames:()=>[{name:ft,type:[Q.ImageData,Q.Number]}],getOutputNames:()=>[]};const ht=()=>({properties:[{label:"property1",name:"property1"}],detectedProperties:{}}),It=(e,t)=>t.split(".").reduce(((e,t)=>null!=e?e[t]:e),e);var St={onParentEvent:async(e,t,n,r)=>{const a={properties:[{label:"property1",name:"property1"}],detectedProperties:{},...r.getState()},i=n?.data?.value,o=Array.isArray(i);if(n.data.type===Q.JsonObj||n.data.type===Q.Rect||n.data.type===Q.Anything||o){let e=!1;for(const t in i){const n=$e(i[t]),r=!!a.detectedProperties[t],o=a.detectedProperties[t]?.type!==n;if(!r||o){const r=n===Q.JsonObj||n===Q.Rect||n===Q.Array;a.detectedProperties[t]={type:n,...r?{shape:we(i[t])}:void 0},e=!0}}if(o&&void 0===a.detectedProperties.length&&(a.detectedProperties.length={type:Q.Number}),e&&r.setState(a),i){const e=[];for(const t of a.properties||[]){const n=It(i,t.label),o=t.label.includes(".");if(void 0!==n){const i=o?$e(n):void 0!==a.detectedProperties[t.label]?.type?a.detectedProperties[t.label].type:Q.Anything;e.push(r.nextGate(t.name,{type:i,value:n}))}}await Promise.allSettled(e)}}},getInputNames:()=>[{name:"in",type:Q.JsonObj}],getOutputNames:e=>{const t={properties:[{label:"property1",name:"property1"}],detectedProperties:{},...e};return t.properties.map((e=>{const n=void 0!==t.detectedProperties[e.label]?t.detectedProperties[e.label]?.type:Q.Anything,r=t.detectedProperties[e.label]?.shape||void 0,a="string"==typeof e;return{name:a?e:e.name,label:a?e:e.label,type:n,jsonShape:r}}))},getDefaultState:ht};const $t="output",wt="noItem";var bt={onParentEvent:async(e,t,n,r)=>{const a={index:0,...r.getState()};let i=a.index;const o=n.data.value,s="string"==typeof n.data.value,c=Array.isArray(n.data.value);if(n.data.type===Q.Anything&&(c||s)||n.data.type===Q.String&&s||n.data.type===Q.Array&&c){i<0&&(i=o.length+i);const e=s?Q.String:$e(o[i]);return e!==a.$$lastDetectedType&&r.setState({...a,$$lastDetectedType:e}),void 0!==o[i]?r.nextGate($t,{value:o[i],type:e}):r.nextGate(wt,{value:!0,type:Q.Boolean})}},getInputNames:()=>[{name:"in",type:[Q.Array,Q.String]}],getOutputNames:e=>[{name:$t,type:e.$$lastDetectedType??Q.Anything},{name:wt,type:Q.Boolean}]};let Nt;const At=e=>{Nt=e},xt=(e,t)=>(()=>{if(!Nt)throw new Error("CanvasManager not set");return Nt})().createCanvas(e,t),Ct=e=>oe?e.getContext("2d",{willReadFrequently:!0}):e.getContext("2d"),Pt=Object.freeze({image:"image",rect:"rect"}),Et="image";var jt={onParentEvent:async(e,t,n,r)=>{const a={offset:{height:0,left:0,top:0,width:0},...r.getState()},i=await r.getParentAtPort(Pt.rect),o=[Q.Anything,Q.Rect,Q.JsonObj];if(t.name!==Pt.rect){if(i){const e=i.getValue();null!==e&&(a.rect={...e},r.setState(a))}if(!oe)return n.data.type===Q.ImageData?r.nextGate(Et,n.data):void 0;if(a.$$canvasFrom&&a.$$canvasFrom.getContext||(a.$$canvasFrom=xt(320,240)),a.$$canvasTo&&a.$$canvasTo.getContext||(a.$$canvasTo=xt(320,240)),(n.data.type===Q.ImageData||n.data.type===Q.Anything&&he(n.data.value))&&!a.$$processing&&a.$$canvasFrom&&a.rect){const e=((e,t,n,r,a)=>{if(r&&r.getContext){const i=r.getContext("2d"),o=n.getContext("2d");if(i&&o){n.width=e.width,n.height=e.height,o.putImageData(e,0,0);const s={...a};a&&(s.height=Number(a.height),s.width=Number(a.width),s.left=Number(a.left),s.top=Number(a.top));const c={top:0,width:0,left:0,height:0,...s};return a&&(Number.isInteger(c.width)||(c.width=t.width*c.width),Number.isInteger(c.height)||(c.height=t.height*c.height),Number.isInteger(c.left)||(c.left=t.left+t.width*c.left),Number.isInteger(c.top)||(c.top=t.top+t.height*c.top)),r.width=t.width+c.width,r.height=t.height+c.height,i.drawImage(n,t.left+c.left,t.top+c.top,t.width+c.width,t.height+c.height,0,0,r.width+c.width,r.height+c.height),i.getImageData(0,0,r.width||1,r.height||1)}}return e})(n.data.value,a.rect,a.$$canvasFrom,a.$$canvasTo,a.offset);return r.nextGate(Et,{type:Q.ImageData,value:e})}}else Ie(n.data.value)&&o.includes(n.data.type)&&r.setState({...a,rect:n.data.value})},getInputNames:()=>[{name:Pt.image,type:Q.ImageData},{name:Pt.rect,type:[Q.Rect,Q.JsonObj]}],getOutputNames:()=>[{name:Et,type:Q.ImageData}]};const Dt=(e,t)=>{const n=Math.round(Math.sqrt(t.length)),r=Math.floor(n/2),a=e.data,i=e.width,o=e.height,s=i,c=o,u=((e,t,n)=>{if(oe)return new ImageData(t,n);return console.warn("Node environment detected. Aborting new ImageData creation"),e})(e,s,c),d=u.data;for(let e=0;e<c;e++)for(let c=0;c<s;c++){const u=e,l=c,p=4*(e*s+c);let g=0,m=0,v=0,f=0;for(let e=0;e<n;e++)for(let s=0;s<n;s++){const c=u+e-r,d=l+s-r;if(c>=0&&c<o&&d>=0&&d<i){const r=4*(c*i+d),o=t[e*n+s];g+=a[r]*o,m+=a[r+1]*o,v+=a[r+2]*o,f+=a[r+3]*o}}d[p]=g,d[p+1]=m,d[p+2]=v,d[p+3]=f+1*(255-f)}return u},kt=[-1,0,1,-2,0,2,1,0,1],Ot=Object.freeze({image:"image"}),Tt="image";var Lt={onParentEvent:async(e,t,n,r)=>{const a=r.getState(),i={matrix:[...kt],...a};if(n.data.type===Q.ImageData||n.data.type===Q.Anything&&he(n.data.value)){const e=Dt(n.data.value,i.matrix);return r.nextGate(Tt,{type:Q.ImageData,value:e})}},getInputNames:()=>[{name:Ot.image,type:Q.ImageData}],getOutputNames:()=>[{name:Tt,type:Q.ImageData}]};const Mt=Object.freeze({output:"output",aborted:"aborted"}),Bt=()=>({inputs:2,matchingOutputs:!0,lastInputIndex:-1,delayMs:500,triggeredAt:0}),Rt=e=>{const t={inputs:2,matchingOutputs:!0,lastInputIndex:-1,delayMs:500,triggeredAt:0,...e},n=Array(t.inputs).fill(0).map(((e,t)=>({name:`input${t+1}`,type:Q.Anything})));return n.push({name:"reset",type:Q.Anything}),n};var Wt={onParentEvent:async(e,t,n,r)=>{const a={inputs:2,matchingOutputs:!0,lastInputIndex:-1,delayMs:500,triggeredAt:0,...r.getState()};if("reset"===t.name)return r.setState({...a,triggeredAt:0});const i=Date.now(),o=i-a.triggeredAt;if(a.triggeredAt&&!(o>=a.delayMs&&a.delayMs>0)&&a.delayMs)return r.nextGate(Mt.aborted,n.data);{a.triggeredAt=i;const e=Rt(a,(r.recipePoolId,r.recipeType,r.thingRecipeId,r.id)).findIndex((e=>e.name===t.name));-1!==e&&(a.lastInputIndex=e),a.matchingOutputs?-1!==e&&await r.nextGate(`output${e+1}`,n.data):await r.nextGate(Mt.output,n.data),r.setState(a)}},getInputNames:Rt,getOutputNames:e=>{const t={inputs:2,matchingOutputs:!0,lastInputIndex:-1,delayMs:500,triggeredAt:0,...e};if(e.matchingOutputs){const e=Array(t.inputs).fill(0).map(((e,t)=>({name:`output${t+1}`,type:Q.Anything})));return e.push({name:Mt.aborted,type:Q.Anything}),e}return[{name:Mt.output,type:Q.Anything},{name:Mt.aborted,type:Q.Anything}]},getDefaultState:Bt};const Ut=(e,t,n,r,a,i)=>{if(a){const o=e.measureText(a),s=o.fontBoundingBoxAscent+o.fontBoundingBoxDescent;e.fillStyle=r,e.fillRect(t,n-i,1.1*o.width,s),e.font=`${i}px Arial`,e.fillStyle="black",e.fillText(a,t,n)}},Ft=(e,t,n,r,a,i,o)=>{e.fillStyle=a,e.fillRect(t,n,r,r),Ut(e,t,n,a,i,o)},_t=(e,t,n,r,a,i)=>{e.beginPath(),e.strokeStyle=r,e.lineWidth=n,e.rect(t.left,t.top,t.width,t.height),e.stroke();const o=n/2;Ut(e,t.left-o,t.top-o,r,a,i)},Gt=Object.freeze({image:"image",pixels:"pixels"}),zt="image";var Vt={onParentEvent:async(e,t,n,r)=>{const a={fontSize:12,color:"#00ff00",size:2,...r.getState()},i=n.data.type===Q.ImageData||n.data.type===Q.Anything&&he(n.data.value);if(t.name===Gt.pixels){const e=((e,t)=>t===Q.Anything&&(he(e)||Se(e)||Ie(e)||Array.isArray(e))||t===Q.Array||t===Q.Rect||t===Q.Point)(n.data.value,n.data.type);if(!e)return;a.$$pixels=n.data.value}if(t.name===Gt.image&&i){const e=n.data.value;a.$$memCanvas&&a.$$memCanvas.getContext||(a.$$memCanvas=xt(e.width||1,e.height||1)),a.$$lastFrame=e}if(a.$$lastFrame&&a.$$pixels&&a.$$memCanvas){const e=(e=>{const{sourceImage:t,pixels:n,memCanvas:r,size:a,color:i,labelProp:o,fontSize:s}=e;if(r){const e=Ct(r);if(e){r.width!==t.width&&(r.width=t.width),r.height!==t.height&&(r.height=t.height),e.putImageData(t,0,0);const c=Array.isArray(n)?n:[n];for(let t=0;t<c.length;t++){const n=c[t],r=o?n[o]:"";Ie(n)?_t(e,n,a,i,r,s):Se(n)&&Ft(e,n.x,n.y,a,i,r,s)}return e.getImageData(0,0,r.width,r.height)}}return t})({sourceImage:a.$$lastFrame,pixels:a.$$pixels||[],memCanvas:a.$$memCanvas,size:a.size,color:a.color,labelProp:a.labelProp,fontSize:a.fontSize});return r.setState({...a,$$lastFrame:void 0,$$pixels:void 0}),r.nextWidget(zt,{type:Q.ImageData,value:e})}r.setState(a)},getInputNames:()=>[{name:Gt.image,type:Q.ImageData},{name:Gt.pixels,type:[Q.Rect,Q.Point,Q.Array]}],getOutputNames:()=>[{name:zt,type:Q.ImageData}]};const Ht=Object.freeze({in:"in"}),Jt="output",qt=e=>{const t=String(e).split(".");return t.length<2?0:t[1].length};var Kt={onParentEvent:async(e,t,n,r)=>{const a={min:1,max:100,...r.getState()},i=!Number.isInteger(a.min),o=!Number.isInteger(a.max),s=i||o;let c=(u=a.min,d=a.max,Math.random()*(d-u)+u);var u,d;if(s){let e=0;if(i&&(e=qt(a.min)),o){const t=qt(a.max);t>e&&(e=t)}c=Number(c.toFixed(e))}else c=Math.floor(c);return r.nextGate(Jt,{type:Q.Number,value:c})},getInputNames:()=>[{name:Ht.in,type:Q.Anything}],getOutputNames:()=>[{name:Jt,type:Q.Number}]};const Xt=Object.freeze({output:"output",totalItems:"totalItems"}),Yt=Object.freeze({trigger:"trigger",clear:"clear"}),Zt=()=>({totalSentItems:-1,totalSentAt:0,$$list:[],$$outputShape:{},totalInputs:1}),Qt=async(e,t)=>t.nextGate(Xt.totalItems,{type:Q.Number,value:e});var en={onParentEvent:async(e,t,n,r)=>{const a={totalSentItems:-1,totalSentAt:0,$$list:[],$$outputShape:{},totalInputs:1,...r.getState()};if(t.name===Yt.clear)return a.$$list=[],a.properties?.autoFilled&&delete a.properties,r.setState(a),Qt(a.$$list.length,r);const i=t.name===Yt.trigger;if(!i)if(Array.isArray(n.data.value))n.data.type!==Q.Array&&n.data.type!==Q.Anything||(a.$$outputShape={...a.$$outputShape,...e?.jsonShape},a.$$list=a.$$list.concat(n.data.value),r.setState({...a}),await Qt(a.$$list.length,r));else{const t=`$$primitive_${Object.keys(a.$$outputShape).length}`;n.data.type===Q.JsonObj?a.$$outputShape={...a.$$outputShape,...e?.jsonShape?e.jsonShape:void 0}:a.$$outputShape={...a.$$outputShape,[t]:n.data.type},a.$$list.push(n.data.value),r.setState({...a}),await Qt(a.$$list.length,r)}if(i){Object.keys(a.$$outputShape).length&&(a.properties={autoFilled:!0,jsonShape:{...a.$$outputShape}});const e=a.$$list.length,t=[...a.$$list];return a.$$list=[],r.setState({...a}),await Qt(e,r),r.nextGate(Xt.output,{type:Q.Array,value:t})}},getInputNames:e=>{const t={totalSentItems:-1,totalSentAt:0,$$list:[],$$outputShape:{},totalInputs:1,...e},n=Array(t.totalInputs||1).fill(0).map(((e,t)=>({name:`array${t+1}`,type:Q.Array})));return n.push({name:Yt.clear,type:Q.Anything},{name:Yt.trigger,type:Q.Anything}),n},getOutputNames:e=>[{name:Xt.output,type:Q.Array,...e.properties?{jsonShape:e.properties?.jsonShape}:void 0},{name:Xt.totalItems,label:"Total Items",type:Q.Number}],getDefaultState:Zt};const tn=Object.freeze({start:"start",stop:"stop"}),nn="output",rn="clock_interrupt";var an={onParentEvent:async(e,t,n,r)=>{const a={enabled:!1,interval:1e3,intervalMode:"ms",...r.getState()};if(ye(e?.name||"")&&t.name===rn)return r.nextGate(nn,{type:Q.Boolean,value:!0});if(t.name===tn.stop&&a.enabled&&a.$$interruptId){r.cancelInterrupt(a.$$interruptId)?(a.enabled=!1,a.$$interruptId=void 0,r.setState(a)):console.warn(`Failed to cancel interrupt [${a.$$interruptId}]`)}else t.name!==tn.start||a.enabled||a.$$interruptId||(a.$$interruptId=r.registerInterrupt("interval",rn,{interval:a.interval}),a.enabled=!0,r.setState(a))},getInputNames:()=>[{name:tn.start,type:Q.Anything},{name:tn.stop,type:Q.Anything}],getOutputNames:()=>[{name:nn,type:Q.Boolean}],initialize:async e=>{const t=e.getState();if(t.enabled&&!t.$$interruptId){const n=e.registerInterrupt("interval",rn,{interval:t.interval});e.setState({...t,$$interruptId:n})}}};const on=Object.freeze({in:"in"}),sn="output",cn=(e,t,n)=>"number"==typeof e?Number((e*t).toFixed(n)):e;var un={onParentEvent:async(e,t,n,r)=>{const a={userProperties:[],factor:2,decimalPoints:2,...r.getState()},i=n.data.type;let o=n.data.value,s=!1;return e?.jsonShape&&(a.detectedInputJson={...a.detectedInputJson,...e?.jsonShape},s=!0),a.detectedInputType||(a.detectedInputType=i,s=!0),n.data.type===Q.Array&&("number"==typeof n.data.value?.[0]?o=((e,t,n)=>{const r=(e||[]).map((e=>cn(e,t,n)));return r})(n.data.value,a.factor,a.decimalPoints):"object"==typeof n.data.value?.[0]&&(o=((e,t,n,r)=>{const a=(e||[]).map((e=>{const a={...e};return Object.keys(a).forEach((e=>{r?.length&&!r?.includes(e)||(a[e]=cn(a[e],t,n))})),a}));return a})(n.data.value,a.factor,a.decimalPoints,a.userProperties))),n.data.type===Q.Number&&(o=cn(n.data.value,a.factor,a.decimalPoints)),s&&r.setState(a),r.nextGate(sn,{type:i,value:o})},getInputNames:()=>[{name:on.in,type:[Q.Array,Q.Number]}],getOutputNames:e=>[{name:sn,type:e.detectedInputType||Q.Number,jsonShape:e.detectedInputJson}]};const dn=Object.freeze({output:"output"}),ln=Object.freeze({trigger:"trigger"}),pn=()=>({useTriggerPort:!0,properties:[{name:"x",label:"x",type:Q.Number,value:10},{name:"y",label:"y",type:Q.Number,value:20}]}),gn=e=>{const t={};for(let n=0;n<e.properties.length;n++)t[e.properties[n].label]=e.properties[n].type;return t},mn=e=>{const t={};for(let n=0;n<e.properties.length;n++){let r=e.properties[n].value;const a=e.properties[n].type;a===Q.Number?r=Number(r):a===Q.String&&(r=String(r)),t[e.properties[n].label]=r}return t};var vn={onParentEvent:async(e,t,n,r)=>{const a=r.getState(),i=structuredClone(a),o={...pn(),...i};if(t.name===ln.trigger){const e=mn(o);return r.nextGate(dn.output,{type:Q.JsonObj,value:e})}const s=o.properties.findIndex((e=>e.name===t.name));if(-1!==s){let e=n.data.type===o.properties[s].type;if(!e&&n.data.type===Q.Anything){e=$e(n.data.type)===o.properties[s].type}if(e?(o.properties[s].value=n.data.value,o.properties[s].$$invalidInputType=!1):o.properties[s].$$invalidInputType=!0,r.setState(o),!o.useTriggerPort){const e=mn(o);return r.nextGate(dn.output,{type:Q.JsonObj,value:e})}}},getInputNames:e=>{const t={...pn(),...e},n=t.properties.map((e=>({name:e.name,label:e.label,type:e.type})));return t.useTriggerPort&&n.push({name:ln.trigger,label:ln.trigger,type:Q.Anything}),n},getOutputNames:e=>[{name:dn.output,label:dn.output,type:Q.JsonObj,jsonShape:gn(e)}],getDefaultState:pn};const fn=async e=>{const t=(e,t)=>e.split(t)[1];if(e.startsWith(pe)){const n=t(e,pe);return be("inner","input",n)}if(e.startsWith(ve)){const n=t(e,ve);return be("outer","output",n)}return null},yn=()=>({canvasPosition:{x:0,y:0},canvasZoom:1,inputs:[{name:"input",type:[Q.Anything],index:0}],outputs:[{name:"output",type:[Q.Anything],index:0}],name:"Custom Widget 1",description:"",type:"custom"}),hn=e=>{const t={...yn(),...e},n=t.inputs.map(((e,t)=>({name:be("outer","input",e.name),type:e.type,...e.jsonShape?{jsonShape:e.jsonShape}:void 0,...e.position?{position:e.position}:void 0,label:e.label,isInner:!1,index:t}))),r=t.outputs.map(((e,t)=>({name:be("inner","output",e.name),type:e.type,...e.jsonShape?{jsonShape:e.jsonShape}:void 0,...e.position?{position:e.position}:void 0,label:e.label,isInner:!0,index:n.length+t})));return[...n,...r]};var In={onParentEvent:async(e,t,n,r)=>{const a=r.getState(),i={...yn(),...a},o=hn(i,(r.recipePoolId,r.recipeType,r.thingRecipeId,r.id));for(let e=0;e<o.length;e++){const a=o[e];if(t.name===a.name&&(a.type.includes(Q.Anything)||a.type.includes(n.data.type))){const e=await fn(t.name);e&&await r.nextWidget(e,{type:n.data.type,value:n.data.value})}}},getInputNames:hn,getOutputNames:e=>{const t={...yn(),...e},n=t.outputs.map(((e,t)=>({name:be("outer","output",e.name),type:e.type,...e.jsonShape?{jsonShape:e.jsonShape}:void 0,...e.position?{position:e.position}:void 0,label:e.label,isInner:!1,index:t})));return[...t.inputs.map(((e,t)=>({name:be("inner","input",e.name),type:e.type,...e.jsonShape?{jsonShape:e.jsonShape}:void 0,...e.position?{position:e.position}:void 0,label:e.label,isInner:!0,index:t+n.length}))),...n]},getDefaultState:yn};const Sn=(e,t,n,r,a)=>{const i=4*(t*n.width+e),o=n.data[i],s=n.data[i+1],c=n.data[i+2];return Math.abs(o-r.r)<=a&&Math.abs(s-r.g)<=a&&Math.abs(c-r.b)<=a};var $n,wn,bn,Nn,An,xn,Cn,Pn,En,jn,Dn={getPixelValueAtIndex:(e,t)=>{const n=e.data,r=n[t]||0,a=n[t+1]||0,i=n[t+2]||0;return{avr:(r+a+i)/3,r:r,g:a,b:i}},getBoundingBox:(e,t,n)=>{const r=e.width,a=e.height,i=new Set,o=Number(n.threshold||0),s=isNaN(o)?10:o,c=(n,o)=>{const c=[[n,o]];let u=n,d=n,l=o,p=o;for(;c.length>0;){const n=c.shift();if(!n)continue;const[o,g]=n;o<0||g<0||o>=r||g>=a||i.has(`${o},${g}`)||!Sn(o,g,e,t,s||0)||(i.add(`${o},${g}`),u=Math.min(u,o),d=Math.max(d,o),l=Math.min(l,g),p=Math.max(p,g),c.push([o+1,g],[o-1,g],[o,g+1],[o,g-1]))}return{minX:u,maxX:d,minY:l,maxY:p}},u=[];for(let o=0;o<a;o+=4)for(let a=0;a<r;a+=4)if(!i.has(`${a},${o}`)&&Sn(a,o,e,t,s)){const{minX:e,maxX:t,minY:r,maxY:i}=c(a,o),s=t-e,d=i-r;if(s>=(n.minWidth||1)&&d>=(n.minHeight||1)&&u.push({left:e,top:r,width:s,height:d}),n.maxBoxes&&u.length>=n.maxBoxes)return u}return u},copyImageData:e=>new ImageData(new Uint8ClampedArray(e.data),e.width,e.height),setPixelValueAtIndex:(e,t,n)=>{const r=e.data,a="object"==typeof n,i=a?n.r:n,o=a?n.g:n,s=a?n.b:n;r[t]=i,r[t+1]=o,r[t+2]=s,r[t+3]=255}};!function(e){e.Browser="browser",e.Cloud="cloud",e.Desktop="desktop"}($n||($n={})),function(e){e.Bundle="bundle",e.Group="group"}(wn||(wn={})),function(e){e.Hardware="hardware",e.Virtual="virtual"}(bn||(bn={})),function(e){e.Cloud="cloud",e.Web="web"}(Nn||(Nn={})),function(e){e.Cpu_128M="kmu-cpu-128m",e.Cpu_256M="kmu-cpu-256m",e.Cpu_512M="kmu-cpu-512m",e.Cpu_1024M="kmu-cpu-1024m",e.Cpu_2048M="kmu-cpu-2048m",e.Cpu_4096M="kmu-cpu-4096m"}(An||(An={})),function(e){e.Gateway="gateway",e.Timer="timer"}(xn||(xn={})),function(e){e.InstallInProgress="installation-in-progress"}(Cn||(Cn={})),function(e){e.InstallDependencies="install-dependencies",e.GetInstalledDependencies="get-installed-dep"}(Pn||(Pn={})),function(e){e.Success="success",e.Error="error",e.Pending="pending"}(En||(En={})),function(e){e.NotFound="not-found",e.BadRequest="bad-request",e.Forbidden="forbidden",e.InternalError="internal-error"}(jn||(jn={}));let kn=null;var On=()=>{if(!kn)throw new Error("Required function is not set");return kn};class Tn extends Error{constructor(e,t){super(e),this.name="UserCodeError",t&&(this.stack=t)}}const Ln=(e,t)=>`\n\t\tfunction _user_code_(){\n\t\t\t${t===$n.Browser?"\n\t\t\tvar global = {\n\t\t\t\t__user_code: true\n\t\t\t};\n\t\t\tvar process = {};\n\t\t\tvar console = this.console;\n\t\t\tvar globalThis = global;\n\t\t\tvar require = this.___notSupportedMethod;\n\t\t\t":"\n\t\t\tvar require = this.require;\n\t\t\tvar process = this.kemuProcess;\n\t\t\t"}\n\n\t\t\tvar eval = () => {};\n\t\t\tvar document = {};\n\t\t\tvar navigator = {};\n\t\t\tvar window = this.window;\n\t\t\tvar alert = this.notify.info;\n\t\t\tvar DataType = this.dataTypesEnum;\n\t\t\tvar setInterval = this.setInterval;\n\t\t\tvar setTimeout = this.setTimeout;\n\t\t\tvar addEventListener = this.addEventListener;\n\t\t\tvar removeEventListener = this.removeEventListener;\n\t\t\tvar requestAnimationFrame = this.___notSupportedMethod;\n\t\t\tvar __delay = (ms) => new Promise((resolve, reject) => setTimeout(resolve, ms, reject));\n\n\t\t\tvar Kemu = {\n\t\t\t\tservices: {\n\t\t\t\t\thttp: { ...this.httpWebService },\n\t\t\t\t\tdynamoDb: { ...this.dynamoService },\n\t\t\t\t\tgoogleSheets: {\n\t\t\t\t\t\t...this.googleSheetsService,\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\timage: this.imageHelpers,\n\t\t\t\tvariable: this.variablesManager,\n\n\t\t\t\thelpers: {\n\t\t\t\t\tcryptoJS: this.CryptoJS,\n\t\t\t\t\tjsonp: this.jsonp,\n\t\t\t\t\tdelay: __delay,\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvar sendToPort;\n\n\t\t\t// --- User Methods Start ---\n\t\t\t${e||""};\n\t\t\t// --- User Methods End ---\n\t\t\t\n\t\t\t// Processes the user code asynchronously.\n\t\t\tconst asyncProcessEvent = async (targetPort, sourcePort, event) => {\n\t\t\t\tconst userProcessEvent = typeof processEvent === 'undefined' ? undefined : processEvent;\n\t\t\t\tif(userProcessEvent) {\n\t\t\t\t\ttry{\n\t\t\t\t\t\treturn await userProcessEvent(targetPort, sourcePort, event, sendToPort);\n\t\t\t\t\t}catch(e){\n\t\t\t\t\t\tthis.__errorTracer(e);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/** invoked the very first time the recipe is initialized */\n\t\t\tconst asyncRecipeInit = async (context, logger) => {\n\t\t\t\ttry {\n\t\t\t\t\t${t===$n.Browser?"if(logger) { console = logger; }":""}\n\t\t\t\t\tif(typeof recipeInit === 'function') {\n\t\t\t\t\t\treturn recipeInit(context);\n\t\t\t\t\t}\n\t\t\t\t}catch(e){\n\t\t\t\t\tthis.__errorTracer(e);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/** invoked every time the code is about to be replaced */\n\t\t\tconst asyncOnTerminate = async (context) => {\n\t\t\t\ttry {\n\t\t\t\t\tif(typeof onTerminate === 'function') {\n\t\t\t\t\t\treturn onTerminate(context);\n\t\t\t\t\t}\n\t\t\t\t}catch(e){\n\t\t\t\t\tthis.__errorTracer(e);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/** updates the function that allows widget contexts to send data to the next widget */\n\t\t\tconst setSendToPort = (sendNextFun) => {\n\t\t\t\tsendToPort = sendNextFun;\n\t\t\t}\n\n\t\t\t/** invoked the every time the user code is compiled. */\n\t\t\tconst asyncMainEvent = async (sendNextFun, logger) => {\n\t\t\t\ttry{\n\t\t\t\t\tsetSendToPort(sendNextFun);\n\t\t\t\t\tif(logger) { console = logger; }\n\t\t\t\t\tif(typeof main === 'function'){\n\t\t\t\t\t\treturn main();\n\t\t\t\t\t}\n\t\t\t\t}catch(e){\n\t\t\t\t\tthis.__errorTracer(e);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tasyncProcessEvent: asyncProcessEvent,\n\t\t\t\tmain: asyncMainEvent,\n\t\t\t\trecipeInit: asyncRecipeInit,\n\t\t\t\tsetSendToPortFun: setSendToPort,\n\t\t\t\tonTerminate: asyncOnTerminate,\n\t\t\t\tgetLocalContext: () => global,\n\t\t\t\tgetWidgetInputs: typeof getWidgetInputs === 'undefined' ? undefined : getWidgetInputs,\n\t\t\t\tgetWidgetOutputs: typeof getWidgetOutputs === 'undefined' ? undefined : getWidgetOutputs,\n\t\t\t};\n\t\t}\n\t\t\n\t\treturn function compiler(context){\n\t\t\treturn _user_code_.call(context)\n\t\t}\n\n\t\treturn compiler;\n\t`,Mn=(e,t,n,i)=>{const o=Ln(e,n),s={...t,document:{},__errorTracer:e=>{throw new Tn(e.message,e.stack)},__jest:void 0===globalThis.__jest?void 0:globalThis.__jest,___notSupportedMethod:()=>i?.error("This method is not supported."),console:console,setInterval:()=>i?.error("'setInterval' is not supported. Please use a \"Timer\" widget instead."),setTimeout:t?.setTimeout,imageHelpers:Dn,...n===$n.Cloud?{require:On(),kemuProcess:process.env.KEMU_PROCESS?process.env.KEMU_PROCESS:{}}:{},jsonp:r,CryptoJS:a,window:{addEventListener:t?.addEventListener,removeEventListener:t?.removeEventListener}};try{const e="browser"===(()=>{if(oe)return"browser";if(ce)return"node";if(se)return"worker";throw new Error("Unsupported environment")})()?(e=>e.replace(/[//]{2}[ ]*@kemu-cloud[ \t]*\{[\s\S]*?[//]{2}[ ]*@kemu-cloud[ \t]*\}/gim,""))(o):(e=>e.replace(/[//]{2}[ ]*@kemu-browser[ \t]*\{[\s\S]*?[//]{2}[ ]*@kemu-browser[ \t]*\}/gim,""))(o),t=new Function(e);return{compiledModule:t()(s)}}catch(e){return{error:{name:"CompileError",message:e.message,stack:e.stack}}}},Bn="main",Rn=()=>({pauseExecution:!1,autoPauseOnError:!0,$$eventListeners:{},pages:{[Bn]:{code:"\nconst getWidgetInputs = () => [\n\t{ name: 'Input 1', type: DataType.Number }\n];\n\nconst getWidgetOutputs = () => [\n\t{ name: 'Output 1', type: DataType.Number }\n]\n\nlet counter = 0;\n\nconst processEvent = async (targetPort, sourceWidget, event) => {\n\tif(targetPort.name === 'Input 1'){\n\t\treturn sendToPort('Output 1', {\n\t\t\ttype: DataType.Number,\n\t\t\tvalue: counter++,\n\t\t});\n\t}\n}\n",language:"javascript",name:"My First Script"}},consoleVisible:!1,$$consoleLines:[]}),Wn=(e,t)=>{const n={message:"Unknown Error"};if(e?.stack){const r=e?.stack?.split(":")[0].trim();n.type=r;const a=(e=>{const t=/,[ ]?<anonymous>:([0-9]+:[0-9]+)\)/gm;let n;for(;null!==(n=t.exec(e));){n.index===t.lastIndex&&t.lastIndex++;const e=n[1].split(":");if(2===e.length)return{line:Number(e[0])||0,column:Number(e[1])||0}}return null})(e.stack);a&&(n.line=a.line-(e=>{const t="___user_code_section___";return Ln(t,e).split(t)[0].split("\n").length+2})(t),n.column=a.column)}return e.message&&(n.message=e.message),n},Un=(e,t)=>{const n={...Rn(),...t.getState()},r={...n,...e?{$$error:e}:void 0,...n.autoPauseOnError&&e?{pauseExecution:!0}:void 0};e&&(r.$$consoleLines=[...r.$$consoleLines,{type:"error",text:e.message,timestamp:Date.now(),fileName:Bn}]),t.setState(r)};var Fn,_n;!function(e){e.ServiceCreationLog="service-creation-log"}(Fn=Fn||(Fn={})),function(e){e.Service="service",e.ServiceUI="serviceUI"}(_n=_n||(_n={}));const Gn=new o,zn=(e,t,n)=>{const r=G(e,t);if(!r)throw new Error(`Thing ${t} not found in recipe ${e}`);const a=r.gates[n];if(!a)throw new Error(`Widget ${n} not found in thing ${t}`);return a},Vn=(e,t,n)=>`${t}:${n}:${e}`,Hn=e=>`${e}:new-var`,Jn=async(e,t,n,r,a,i,o)=>{const s={...o},c={thingId:n,recipeId:t,variableName:e,changes:i,ownerId:r,callerWidgetId:a,varDefinition:Object.freeze(s)};if(i.includes("added")){const e=Hn(n);return Gn.emit(e,c)}{const t=Vn(e,n,r);return Gn.emit(t,c)}},qn=(e,t,n,r)=>{const a=zn(e,t,r);a.variablesListener={...a.variablesListener,[n]:0},Xn(e,t)},Kn=(e,t,n,r)=>{const a=zn(e,t,r),i={...a.variablesListener};void 0!==a.variablesListener?.[n]&&(delete i[n],a.variablesListener=i)},Xn=async(e,t)=>{const n=G(e,t);if(!n)throw new Error(`Thing "${t}" not found in recipe "${e}"`);const r={...n.variables},a=Object.keys(r);for(const i of a){const a=r[i],o=Object.keys(a);for(const a of o){!n.gates[a]&&(delete r[i][a],await Jn(i,e,t,a,void 0,["removed"],null))}0===Object.keys(r[i]).length&&delete r[i]}n.variables=r},Yn=(e,t,n)=>{for(const r in t){const a=t[r];if(a.createdByWidgetId===e.id)return a;if(e.type===Ce.variable&&a.ownerType===Ce.variable)return a;if(e.type===Ce.script){const t=a.createdByWidgetId===e.groupId,r=n[a.createdByWidgetId];if(!r)continue;const i=r.groupId===e.groupId;if(t||r.type===Ce.variable&&i)return a}}return null};var Zn=async(e,t,n,r,a,i)=>{const o=G(e,t);if(!o)throw new Error(`Thing ${t} not found in recipe ${e}`);const s={...o.variables};s[r]=s[r]||{};const c=s[r],u=o.gates[n];if(!u)throw new Error(`Widget ${n} not found in thing ${t}`);const d=Object.values(c);let l=!1,p=!1;const g=async a=>Jn(r,e,t,a.createdByWidgetId,n,["value"],a);if(u.type===Ce.variable){l=!0;for(const e of d)e.ownerType===Ce.variable&&e.type===a.type&&(e.value=a.value,p=!0,await g(e))}if(u.type===Ce.script){l=!0;for(const e of d){const t=e.createdByWidgetId===u.groupId,n=o.gates[e.createdByWidgetId],r=n?.type===Ce.variable,i=n?.groupId===u.groupId;(t||r&&i)&&e.type===a.type&&(e.value=a.value,p=!0,await g(e))}}if(!l){l=!0;for(const e of d){e.createdByWidgetId===n&&e.type===a.type&&(e.value=a.value,p=!0,await g(e))}}if(!i?.skipNotifications&&p){const s=Object.values(o.gates);for(const o of s){if(o.id===n&&i?.skipCallerNotification)continue;const s=o.variablesListener?.[r];void 0!==s&&await Ga(o.id,t,e,`${X}${r}`,a)}}},Qn=(e,t,n,r)=>{const a=G(e,t);if(!a)throw new Error(`Thing ${t} not found in recipe ${e}`);if(!r.readerWidgetId&&!r.ownerWidgetId)throw new Error("readerWidgetId or ownerWidgetId must be provided");const i={...a.variables}[n];if(!i)return;if(r.ownerWidgetId){const e=i[r.ownerWidgetId];return e?.value}const o=a.gates[r.readerWidgetId];if(!o)throw new Error(`Widget ${r.readerWidgetId} not found in thing ${t}`);const s=Yn(o,i,a.gates);return s?s.value:null},er=qn,tr=Kn;const nr="setTimeout",rr="variableChanged",ar=e=>{const{recipePoolId:t,thingId:n,scriptWidgetId:r}=e;if(!z(t,n,r))throw new Error(`Widget "${r}" not found in recipe "${t}"`);return{get:(e,a)=>{const i=Qn(t,n,e,{readerWidgetId:r});if(null===i){if(void 0===a)throw new Error(`Variable "${e}" is not defined`);return a}return i},set:async(e,a)=>{await Zn(t,n,r,e,{type:$e(a),value:a})},onValueChange:(a,i)=>{if(!e.setState)return void console.warn("Cannot subscribe to variable changes without a setState function");er(t,n,a,r);const o={...Rn(),...e.getState()};o.$$eventListeners[a]={handler:i,abort:async()=>{tr(t,n,a,r)},name:rr},e.setState(o)}}},ir="__command-compile__";let or;const sr=()=>{console.log("Method not implemented")},cr=(e,t,r)=>{const a=(e,...n)=>{const r={...Rn(),...t.getState()}.$$eventListeners[e];r&&r.handler(n)},i={};return Object.keys(Q).forEach((e=>{i[e]=Q[e]})),{dataTypesEnum:i,notify:{success:e=>{t.getState()?.$$managedUI?.notify?.success(e)},error:e=>{t.getState()?.$$managedUI?.notify?.error(e)},info:e=>{t.getState()?.$$managedUI?.notify?.info(e)}},variablesManager:e.variablesManager?ar({recipePoolId:r.recipePoolId,scriptWidgetId:r.widgetId,thingId:r.thingId,getState:t.getState,setState:t.setState}):{get:sr,set:async()=>sr(),onValueChange:sr},setTimeout:(r,a,i)=>{if(e.withTimers&&t&&t.setState&&t.registerInterrupt){const e=n(),o={...Rn(),...t.getState()};o.$$eventListeners[e]={handler:r,rejectHandler:i,name:nr},t.setState(o),t.registerInterrupt("timeout",e,{timeout:a},void 0,e)}},addEventListener:(e,r)=>{if(t.setState){const i=n(),o={...Rn(),...t.getState()};o.$$eventListeners[i]={handler:r,name:e},t.setState(o),window.addEventListener(e,a.bind(i))}else console.warn(`Cannot remove event listener '${e}' because the widget context is not available.`)},removeEventListener:(e,n)=>{if(t.setState){const r={...Rn(),...t.getState()},a=Object.keys(r.$$eventListeners).find((t=>r.$$eventListeners[t].name===e&&r.$$eventListeners[t].handler===n));t.setState(r),a&&removeEventListener(r.$$eventListeners[a].name,r.$$eventListeners[a].handler)}else console.warn(`Cannot remove event listener '${e}' because the widget context is not available.`)}}},ur=(e,t,n,r)=>{const a={...Rn(),...n.getState()},i=a.pages[Bn].$$compiledCode;if(i)return{compiledModule:i};{const i=cr(e,n,t);return Mn(a.pages[Bn].code,i,n.recipeType,r)}},dr=e=>e.map((e=>({...e,name:e.name.replace("_","")}))),lr=async(e,t)=>{const n={...e};for(const r in e){if(e[r].name===nr){const e=n[r]?.rejectHandler;if("function"==typeof e)try{await e("TIMER_ABORTED")}catch(e){console.log("Error in reject interrupt handler: ",e)}t.cancelInterrupt(r),delete n[r]}}return n},pr=async(e,t,n)=>{let r={...Rn(),...e.getState()};if(void 0!==n){r.pages[Bn]?.$$compiledCode?.onTerminate&&await(r.pages[Bn].$$compiledCode?.onTerminate());let t=await lr(r.$$eventListeners,e);t=await(async e=>{const t={...e};for(const n in e)if(e[n].name===rr){const r=e[n]?.abort;if("function"==typeof r)try{await r()}catch(e){console.log("Error in abort interrupt handler: ",e)}delete t[n]}return t})(t),r.$$eventListeners=t,r.$$error=void 0,r.pages[Bn].$$compiledCode=void 0,r.pages[Bn].code=n,e.setState({...r})}const a=!r.pages[Bn].$$compiledCode,{compiledModule:i,error:o}=ur({variablesManager:!0,withTimers:!0},{recipePoolId:e.recipePoolId,thingId:e.thingRecipeId,widgetId:e.id},{getState:e.getState,setState:e.setState,recipeType:e.recipeType,registerInterrupt:e.registerInterrupt});if(o){console.log("Failed to compile user code");const t=Wn(o,e.recipeType);return Un(t,e),null}if(i){const n=(e=>{const t=(t,n)=>{if(or)try{return or[t](n)}catch(e){return void console.log("Error in custom logger: ",e)}const r={...Rn(),...e.getState()},a=[...r.$$consoleLines||[]];a.push({fileName:Bn,text:n,type:t,timestamp:Date.now()}),a.length>100&&a.splice(0,30),e.setState({...r,$$consoleLines:a})},n={log:e=>{t("log",e)},error:e=>{t("error",e)},warn:e=>{t("warn",e)},info:e=>{t("info",e)}};return n})(e);let o;if(r={...e.getState()},r.pages[Bn].$$compiledCode=i,e.nextGate&&i.setSendToPortFun(e.nextGate),t)try{await i.recipeInit({setState:e.setState,getState:e.getState},n)}catch(t){o=Wn(t,e.recipeType)}if(e.nextGate&&a)try{await i.main(e.nextGate,n)}catch(t){o=Wn(t,e.recipeType)}r.$$lastInputs=i.getWidgetInputs?i.getWidgetInputs():[],r.$$lastOutputs=i.getWidgetOutputs?i.getWidgetOutputs():[],e.setState(r),Un(o,e)}};var gr={onParentEvent:async(e,t,n,r)=>{const a=r.getState(),i={...Rn(),...a};if(!i.pages[Bn])return console.warn("Missing default page");if(i.pauseExecution){if(Object.keys(i.$$eventListeners).length){const e=await lr(i.$$eventListeners,r);r.setState({...i,$$eventListeners:e})}return}if(ye(e?.name||""))return i.$$eventListeners[t.name]?(await i.$$eventListeners[t.name].handler(),i.$$eventListeners[t.name].name===nr&&delete i.$$eventListeners[t.name],void r.setState({...i})):void console.log(`Unknown interrupt id [${t.name}] `);if(t.name.startsWith(X)){const e=t.name.replace(X,""),r=n.data.value,a=i.$$eventListeners[e];return void(a?.handler&&await a.handler(r))}const o=t.name===ir;await pr(r,!1,o?n.data.value:void 0);const s=i.pages[Bn].$$compiledCode;if(e&&e.name!==ir&&s){let a;try{await s.asyncProcessEvent(t,e,n)}catch(e){"UserCodeError"===e.name&&(a=Wn(e,r.recipeType))}Un(a,r)}},getInputNames:(e,t)=>{const n={...Rn(),...e},{compiledModule:r}=ur({},{recipePoolId:t.recipePoolId,thingId:t.thingRecipeId,widgetId:t.widgetId},{getState:()=>n,recipeType:t.recipeType});if(r?.getWidgetInputs){const e=r.getWidgetInputs();return dr(e)}return e.$$lastInputs||[]},getOutputNames:(e,t)=>{const n={...Rn(),...e},{compiledModule:r}=ur({},{recipePoolId:t.recipePoolId,thingId:t.thingRecipeId,widgetId:t.widgetId},{getState:()=>n,recipeType:t.recipeType});if(r?.getWidgetOutputs){const e=r.getWidgetOutputs();return dr(e)}return e.$$lastOutputs||[]},getDefaultState:Rn,initialize:async e=>{const t=e.getState(),n={...Rn(),...t};n.pages[Bn].code&&await pr({getState:e.getState,id:e.widgetThingId,recipePoolId:e.recipePoolId,recipeType:e.recipeType,registerInterrupt:e.registerInterrupt,setState:e.setState,thingRecipeId:e.thingRecipeId,cancelInterrupt:()=>!0},!0,n.pages[Bn].code)}};const mr=async(e,t,n,r)=>{e.startsWith("data:image/")||(e=`data:image/png;base64,${e}`);const a=await vr(e);return((e,t,n,r)=>{const a=r.getContext("2d");if(!a)throw new Error("Failed to get canvas context");const i=e.width,o=e.height;return r.width=t,r.height=n,a.drawImage(e,0,0,i,o,0,0,t,n),a.getImageData(0,0,t,n)})(a,n||a.naturalWidth,r||a.naturalHeight,t)},vr=e=>new Promise(((t,n)=>{const r=new Image;r.onload=()=>t(r),r.onerror=e=>n(e),r.src=e})),fr=Object.freeze({image:"image"}),yr=Object.freeze({base64:"base64"}),hr=()=>({});var Ir={onParentEvent:async(e,t,n,r)=>{const a={...r.getState()};if(t.name===yr.base64){if("string"!=typeof n.data.value)return;if(n.data.type!==Q.String&&n.data.type!==Q.Anything)return;const e=n.data.value;oe&&(a.$$memCanvas&&a.$$memCanvas.getContext||(a.$$memCanvas=xt(320,240)));try{const t=await mr(e,a.$$memCanvas,a.resize?.width,a.resize?.height);return r.setState(a),r.nextGate(fr.image,{type:Q.ImageData,value:t})}catch(e){console.log("[base64ToImageData] Error: ",e)}}},getInputNames:()=>[{name:yr.base64,type:Q.String}],getOutputNames:()=>[{name:fr.image,type:Q.ImageData}],getDefaultState:hr};const Sr=Object.freeze({object:"object",error:"error"}),$r=Object.freeze({string:"string"}),wr=()=>({outputIsArray:!1});var br={onParentEvent:async(e,t,n,r)=>{const a={outputIsArray:!1,...r.getState()};if((n.data.type===Q.String||n.data.type===Q.Anything)&&"string"==typeof n.data.value)try{const e=JSON.parse(n.data.value),t=Array.isArray(e);return t&&!a.outputIsArray?r.setState({...a,outputIsArray:!0}):!t&&a.outputIsArray&&r.setState({...a,outputIsArray:!1}),r.nextGate("object",{type:t?Q.Array:Q.JsonObj,value:e})}catch(e){return r.nextGate("error",{type:Q.Boolean,value:!0})}},getInputNames:()=>[{name:$r.string,type:Q.String}],getOutputNames:e=>[{name:Sr.object,type:[Q.JsonObj,Q.Array],label:e.outputIsArray?"array":Sr.object},{name:Sr.error,type:Q.Boolean}],getDefaultState:wr};const Nr=Object.freeze({string:"string",length:"length"}),Ar=Object.freeze({trigger:"trigger",setText:"setText"}),xr=()=>({text:"",dispatchOnSet:!1});var Cr={onParentEvent:async(e,t,n,r)=>{const a={text:"",dispatchOnSet:!1,...r.getState()};if(t.name===Ar.setText){if(!((n.data.type===Q.String||n.data.type===Q.Anything)&&"string"==typeof n.data.value))return;if("string"==typeof n.data.value&&(a.text=n.data.value,r.setState(a)),!a.dispatchOnSet)return}const i=r.nextGate(Nr.length,{type:Q.Number,value:a.text.length}),o=r.nextGate(Nr.string,{type:Q.String,value:a.text});await Promise.all([i,o])},getInputNames:e=>{const t=[{name:Ar.setText,type:Q.String}];return e.dispatchOnSet||t.push({name:Ar.trigger,type:Q.Anything}),t},getOutputNames:()=>[{name:Nr.string,type:Q.String},{name:Nr.length,type:Q.Number}],getDefaultState:xr};const Pr=Object.freeze({image:"image"}),Er=Object.freeze({image:"image",x:"x",y:"y",width:"width",height:"height"}),jr=()=>({showInputPorts:!1});var Dr={onParentEvent:async(e,t,n,r)=>{const a={showInputPorts:!1,...r.getState()};if("number"==typeof n.data.value)return t.name===Er.x&&(a.cropX=n.data.value),t.name===Er.y&&(a.cropY=n.data.value),t.name===Er.width&&(a.cropWidth=n.data.value),t.name===Er.height&&(a.cropHeight=n.data.value),void r.setState(a);if(t.name===Er.image){if(n.data.type!==Q.ImageData&&n.data.type!==Q.Anything)return;if(!he(n.data.value))return;const e=n.data.value;if(a.$$memCanvas&&a.$$memCanvas.getContext||(oe&&(a.$$memCanvas=xt(320,240),a.$$memCanvasContext=Ct(a.$$memCanvas)),r.setState(a)),!a.$$memCanvas||!a.$$memCanvasContext)return;let t=e;return a.$$memCanvas.width=e.width,a.$$memCanvas.height=e.height,(a.cropX||a.cropY||a.cropWidth||a.cropHeight)&&(t=((e,t,n,r)=>{if(!n)return e;const a=Math.max(r.x||0,0),i=Math.max(r.y||0,0),o=e.width,s=e.height,c=Math.min(Math.ceil(r.width||o),o),u=Math.min(Math.ceil(r.height||s),s);return t.width=e.width,t.height=e.height,n.putImageData(e,0,0),n.drawImage(t,a,i,c,u,0,0,c,u),n.getImageData(0,0,c,u)})(e,a.$$memCanvas,a.$$memCanvasContext,{x:a.cropX,y:a.cropY,width:a.cropWidth,height:a.cropHeight})),r.nextGate(Pr.image,{type:Q.ImageData,value:t})}},getInputNames:e=>{const t=[{name:Er.image,type:[Q.ImageData]}];return e.showInputPorts&&(t.push({name:Er.x,type:Q.Number}),t.push({name:Er.y,type:Q.Number}),t.push({name:Er.width,type:Q.Number}),t.push({name:Er.height,type:Q.Number})),t},getOutputNames:()=>[{name:Pr.image,type:Q.ImageData}],getDefaultState:jr};const kr=Object.freeze({image:"image"}),Or=Object.freeze({image:"image",width:"width",height:"height"}),Tr=()=>({showInputPorts:!1});var Lr={onParentEvent:async(e,t,n,r)=>{const a={showInputPorts:!1,...r.getState()};if("number"==typeof n.data.value)return t.name===Or.width&&(a.width=n.data.value),t.name===Or.height&&(a.height=n.data.value),void r.setState(a);if(t.name===Or.image){if(n.data.type!==Q.ImageData&&n.data.type!==Q.Anything)return;if(!he(n.data.value))return;const e=n.data.value;if(a.$$memCanvas&&a.$$memCanvas.getContext||(a.$$memCanvas=xt(320,240),r.setState(a)),!a.$$memCanvas)return;let t=e;return(a.width||a.height)&&(t=((e,t,n,r)=>{if(!n&&!r)return e;n&&!r?r=n*(e.height/e.width):!n&&r&&(n=r*(e.width/e.height));const a=Math.max(1,n||e.width),i=Math.max(1,r||e.height);t.width=Math.max(e.width,a),t.height=Math.max(e.height,i);const o=Ct(t);if(!o)throw new Error("Failed to get canvas context");return o.putImageData(e,0,0),o.drawImage(t,0,0,e.width,e.height,0,0,a,i),o.getImageData(0,0,a,i)})(e,a.$$memCanvas,a.width,a.height)),r.nextGate(kr.image,{type:Q.ImageData,value:t})}},getInputNames:e=>{const t=[{name:Or.image,type:Q.ImageData}];return e.showInputPorts&&(t.push({name:Or.width,type:Q.Number}),t.push({name:Or.height,type:Q.Number})),t},getOutputNames:()=>[{name:kr.image,type:Q.ImageData}],getDefaultState:Tr};const Mr=Object.freeze({value:"value"}),Br=Object.freeze({trigger:"trigger",setValue:"setValue"}),Rr=()=>({value:0,dispatchOnSet:!1});var Wr={onParentEvent:async(e,t,n,r)=>{const a={value:0,dispatchOnSet:!1,...r.getState()};if(t.name===Br.setValue){const e=n.data.type===Q.Number||n.data.type===Q.Anything||n.data.type===Q.String,t=!isNaN(Number(n.data.value))&&!Array.isArray(n.data.value);if(!e||!t)return;if(a.value=Number(n.data.value),r.setState(a),!a.dispatchOnSet)return}return r.nextGate(Mr.value,{type:Q.Number,value:a.value})},getInputNames:e=>{const t=[{name:Br.setValue,type:Q.Number}];return e.dispatchOnSet||t.push({name:Br.trigger,type:Q.Anything}),t},getOutputNames:()=>[{name:Mr.value,type:Q.Number}],getDefaultState:Rr};const Ur=Object.freeze({image:"image"}),Fr=Object.freeze({image:"image"}),_r=()=>({anchors:[],vertices:[],matrix:[]}),Gr={onParentEvent:async(e,t,n,r)=>{const a={anchors:[],vertices:[],matrix:[],...r.getState()},i=window,o=n.data.type===Q.ImageData;if(i.Speedy&&o){const e=i.Speedy,t=n.data.value;let o,d,l,p=a.$$private?.canvas,g=a.$$private?.context,m={...a};const v=4===a.anchors.length;if(a.$$private?.pipeline)o=a.$$private?.pipeline,d=a.$$private?.source;else{o=e.Pipeline(),d=e.Image.Source();const n=e.Image.Sink();l=e.Transform.PerspectiveWarp(),p?p.width===t.width&&p.height===t.height||(p.width=t.width,p.height=t.height,g=p.getContext("2d")):(c=t.width,u=t.height,p=xt(c,u),g=p.getContext("2d")),d.output().connectTo(l.input()),l.output().connectTo(n.input()),o.init(d,n,l);let r=e.Matrix(3,3,[1,0,0,0,1,0,0,0,1]);if(4===a.anchors.length){const t=e.Matrix(2,4,[(s=a.anchors)[0].x,s[0].y,s[1].x,s[1].y,s[2].x,s[2].y,s[3].x,s[3].y]),n=e.Matrix(2,4,a.vertices.reduce(((e,t)=>e.concat([t.x,t.y])),[])),i=e.Matrix.Zeros(3,3);await e.Matrix.perspective(i,t,n);const o=i.read();r=e.Matrix(3,3,o)}l.transform=r,m={...m,$$private:{...m.$$private,canvas:p,context:g,perspective:l,pipeline:o,source:d}}}let f=t;if(v){const e=await(async(e,t)=>{const n=window,r=e.$$private?.source,a=e.$$private?.pipeline;if(n.Speedy&&r&&a){const e=n.Speedy,i=await createImageBitmap(t),o=await e.load(i);return r.media=o,(await a.run()).image.source}return null})(m,f);e&&(p&&g&&(f=((e,t,n)=>(t.width=e.width,t.height=e.height,n.drawImage(e,0,0),n.getImageData(0,0,e.width,e.height)))(e,p,g)),m.$$private&&r.setState({...m,$$private:{...m.$$private,lastInputImage:t}}))}else m.$$private&&r.setState({...m,$$private:{...m.$$private,lastInputImage:t}});return r.nextGate(Ur.image,{type:Q.ImageData,value:f})}var s,c,u;console.log("Environment not supported")},getInputNames:()=>[{name:Fr.image,type:Q.ImageData}],getOutputNames:()=>[{name:Ur.image,type:Q.ImageData}],getDefaultState:_r,terminate:async e=>{const t=e.getState();t.$$private?.pipeline.release()}},zr=()=>({name:"Default widget bundle",description:"",inputs:[{dataType:[Q.Anything],name:"input"}],outputs:[{dataType:[Q.Anything],name:"output"}]});let Vr;const Hr=()=>{if(!Vr)throw new Error(Be(Me));return Vr};const Jr=async e=>{const t=new s,n=await t.loadAsync(e),r={};for(const e in n.files)if(!n.files[e].dir){const t=await n.file(e);t&&(r[e]=await t.async("uint8array"))}return r},qr={};var Kr=e=>qr[e]||null;const Xr=async(e,t,n)=>{try{const r=Hr(),a=n?r.loadBlobAsString:r.loadBlob;return await a(e,t)}catch(e){return null}},Yr=async e=>{const t=J;try{const n=await Xr(e,t,!0);if(!n)return null;return Function(n)()}catch(e){return null}},Zr=async e=>{const t=q;try{const n=await Xr(e,t,!0);if(!n)return null;return JSON.parse(n)}catch(n){return console.log(`Failed to parse the bundle's state [${e}/${t}] %j`,n),null}},Qr=(e,t)=>`${e.replace(K,"")}_${t}`,ea=(e,t)=>`widget/${e.replace(K,"")}/v/${t}`,ta=async(e,t)=>{const n=Hr(),[r]=await Promise.all([Jr(e),n.createLocation(t)]);for(const e in r)e.startsWith("__MACOSX")||await n.saveBlob(t,e,r[e])},na=(e,t)=>{const n=Qr(e,t),r=Kr(n);return r?{...r}:null},ra=(e,t,n)=>{const r=`${`widget/${e.replace(K,"")}/tmp`}/${t}`;if(n){return Hr().getCacheLocation(r)}return r};var aa=na,ia=async(e,t,n)=>{const r=ra(t,n);await ta(e,r);const a=Yr(r),i=Zr(r),o=Hr(),s=o.getCacheLocation(r),[c,u]=await Promise.all([a,i]);if(!c)return null;let d=u;if(!u){const e=zr(),t=JSON.stringify(e);await o.saveBlob(r,q,fe(t)),d=e}return{cachePath:s,processor:c,storedState:Object.freeze(d)}},oa=(e,t,n)=>{if(n.isTempStorage)return ra(e,t,n.fullStorageRoot);const r=Hr(),a=ea(e,t);return n.fullStorageRoot?r.getCacheLocation(a):a};const sa=()=>zr();var ca={onParentEvent:async(e,t,n,r)=>{const a=r.getState();return a.$$processor?.onParentEvent({sourcePort:e?.name||"",targetPort:t?.name||"",data:n.data},{getState:r.getState,recipeId:r.recipePoolId,recipeType:r.recipeType,setState:r.setState,nextWidget:r.nextGate})},getInputNames:(e,t)=>{const n={...sa(),...e};return n.$$processor?.getInputNames?n.$$processor.getInputNames(e,t):n.inputs.map((e=>({name:e.name,type:e.dataType})))},getOutputNames:(e,t)=>{const n={...sa(),...e};return n.$$processor?.getOutputNames?n.$$processor.getOutputNames(e,t):n.outputs.map((e=>({name:e.name,type:e.dataType})))},getDefaultState:sa,initialize:async(e,t)=>{console.log("Widget bundle initialize",e);let n={...e.getState()},r=n.$$cacheInfo?.widgetThingId||n.collectionInfo?.widgetId||e.widgetThingId;const a=n.$$cacheInfo?.version.toString()||n.collectionInfo?.version.toString()||1;if(n.$$cacheInfo={...n.$$cacheInfo,version:Number(a),widgetThingId:r},!r||!a)throw new Error("Widget bundle state is missing cache id or version");console.log("Loading state from cache");const i=aa(r,a);let o=!i;if(!n.$$processor)if(n.storageUnitId&&!i){const t=await e.getStorageData(n.storageUnitId);if(t){r=e.widgetThingId;const i=await ia(t,r,a);o=!0,i&&(n={...n,$$processor:i.processor,$$cacheInfo:{...n.$$cacheInfo,widgetThingId:r,version:Number(a)}},e.setState(n))}}else if(i){o=!1;const r=n.collectionInfo?{...n.collectionInfo}:void 0;n={...n,...!t.keepCurrentState&&i.storedState?{...i.storedState,...r?{collectionInfo:r}:{}}:{},$$processor:i.processor},e.setState(n)}const s=oa(r,a,{fullStorageRoot:!0,isTempStorage:o});console.log("Invoking bundle initialize with cache: ",s);try{await(n.$$processor?.initialize({cacheLocation:s,getState:e.getState,setState:e.setState}));const t=e.getState();e.setState({...t,$$initializationError:void 0})}catch(t){const n=e.getState();throw e.setState({...n,$$initializationError:t.message||"An error occurred initializing the widget"}),t}},terminate:async e=>{const t={...e.getState()};console.log(`Terminating widget bundle ${t.name} [${t.$$cacheInfo?.widgetThingId||""}]`);const n=t.$$processor;n&&"function"==typeof n.terminate&&await n.terminate({getState:e.getState,setState:e.setState,recipePoolId:e.recipePoolId,widgetId:e.widgetId})}};const ua=Object.freeze({event:"event"}),da="1",la="2",pa="3";var ga={onParentEvent:async(e,t,n,r)=>{const a={...r.getState()};r.setState({...a,$$lastEventType:n.data.type}),await r.nextGate(da,n.data),await r.nextGate(la,n.data),await r.nextGate(pa,n.data)},getInputNames:()=>[{name:ua.event,type:Q.Anything}],getOutputNames:e=>{const t={type:{...e}.$$lastEventType??Q.Anything};return[{name:da,...t},{name:la,...t},{name:pa,...t}]}};const ma=Object.freeze({set:"set",trigger:"trigger"}),va="value";var fa={onParentEvent:async(e,t,n,r)=>{const a=r.getState(),i={name:"myVar",type:Q.String,reactive:!0,defaultValue:"",...a};if(t.name.startsWith(X)){if(!i.reactive)return;if(n.data.type!==i.type)return;return r.nextWidget(va,n.data)}if(t.name!==ma.set){if(t.name===ma.trigger){const e=Qn(r.recipePoolId,r.thingRecipeId,i.name,{ownerWidgetId:r.id}),t=e||i.defaultValue;await r.nextWidget(va,{type:i.type,value:t})}}else await Zn(r.recipePoolId,r.thingRecipeId,r.id,i.name,n.data,{skipCallerNotification:!i.reactive})},getInputNames:e=>{const t={...e};return[{name:ma.set,type:t.type||Q.Anything},{name:ma.trigger,type:Q.Anything}]},getOutputNames:e=>{const t={...e};return[{name:va,type:t.type||Q.Anything}]}};let ya;var ha=e=>{ya=e},Ia=()=>{if(!ya)throw new Error("Hub Connector not set");return ya};const Sa=async(e,t=!1)=>{const n=Ia();let r=e.$$$serviceId;if(!e.service)return console.log("Aborting service initialization, missing property `service` in state."),null;if(!r||t){const t=await n.getCompatibleService(e.service.name,e.service.version,"^");if(!t)return null;r=t.sessionId}return r};var $a={onParentEvent:async(e,t,n,r)=>{const a={dynamicInputs:{},dynamicOutputs:{},customState:{},...r.getState()};if(!e)return;const i=Ia();let o=a.$$$serviceId;if(!o){const e=i.getCachedServices().find((e=>e.name===a.service?.name&&e.version===a.service?.version));if(!e)return;o=e.sessionId,a.$$$serviceId=o,r.setState(a)}const s=a.service?.variants?.find((e=>e.id===a.variantId)),c=s?a.dynamicInputs[s.id]||s?.inputs||[]:a.service?.inputs||[];if(!c?.length)return;if(!s&&a.service?.ignoreParentEvents)return;const u=a.service?.processingTimeoutSec;return i.onParentEvent({recipeId:r.recipePoolId,data:n.data,targetServiceSessionId:o,currentState:a.customState,targetVariantId:a.variantId,target:{portName:t.name,widgetId:r.id,widgetType:r.type},source:e,config:{timeout:u?1e3*u:0,async:a.service?.asyncParentEvents}})},getInputNames:async e=>{const t=e.variantId;if(t&&e.dynamicInputs?.[t])return[...e.dynamicInputs[t]||[]];if(!t)return e.service?.inputs||[];{const n=e.service?.variants?.find((e=>e.id===t));if(n)return n.inputs||[]}return[]},getOutputNames:async e=>{const t=e.variantId;if(t&&e.dynamicOutputs?.[t])return[...e.dynamicOutputs[t]||[]];if(!t)return e.service?.outputs||[];{const n=e.service?.variants?.find((e=>e.id===t));if(n)return n.outputs||[]}return[]},initialize:async e=>{const t={dynamicInputs:{},dynamicOutputs:{},customState:{},...e.getState()},n=Ia(),r=await Sa(t);if(r)try{return await n.initializeServiceInstance({recipeId:e.recipePoolId,sessionId:r,widgetId:e.widgetThingId,recipeType:e.recipeType,variantId:t.variantId})}catch(t){if("FNC_NOT_FOUND"!==t?.errCode){if(!!("string"!=typeof t||!t.match('^Function ".*" not found.$')))throw t;console.warn(`Widget [${e.widgetThingId}] does not have an init function.`)}}else console.log(`Aborting service initialization, "${t.service?.name}" was not found in the current Hub.`)},terminate:async e=>{const t={dynamicInputs:{},dynamicOutputs:{},customState:{},...e.getState()},n=Ia(),r=await Sa(t,!0);if(r)return n.terminateServiceInstance(r,e.widgetId,e.recipePoolId,t.variantId)}};const wa=Object.freeze({Image:"image"}),ba=Object.freeze({Image:"image"}),Na=()=>({filters:[{name:"grayscale",value:.5,id:"d-1"}]});const Aa={input:Ue,counter:Ge,elapsed:He,ifGate:Xe,skipEvent:Qe,between:rt,map:ot,parser:ut,slider:pt,suspend:vt,display:yt,json:St,arrayItem:bt,extractImage:jt,imageConvolution:Lt,firstEvent:Wt,pixelDraw:Vt,randomBetween:Kt,arrayCombine:en,clock:an,multiplication:un,object:vn,widgetGroup:In,script:gr,base64ToImageData:Ir,jsonParse:br,text:Cr,imageCrop:Dr,imageResize:Lr,value:Wr,imageWarp:Gr,widgetBundle:ca,sequence:ga,variable:fa,hubService:$a,imageFilter:{onParentEvent:async(e,t,n,r)=>{const a={filters:[{name:"grayscale",value:.5,id:"d-1"}],...r.getState()};if(t.name===wa.Image&&n.data.type===Q.ImageData){if(!he(n.data.value))return void console.log("ImageFilter: Invalid image data type, aborting process");const e=n.data.value;a.$$memCanvas||(a.$$memCanvas=xt(e.width,e.height)),a.$$context||(a.$$context=a.$$memCanvas.getContext("2d")),a.$$memCanvas.width!==e.width&&(a.$$memCanvas.width=e.width),a.$$memCanvas.height!==e.height&&(a.$$memCanvas.height=e.height),r.setState(a),a.$$context.putImageData(e,0,0),a.filters.length?a.$$context.filter=a.filters.map((e=>`${e.name}(${e.value}${"blur"===e.name?"px":""})`)).join(" "):a.$$context.filter="none",a.$$context.drawImage(a.$$memCanvas,0,0);const t=a.$$context.getImageData(0,0,e.width,e.height);return r.nextWidget(ba.Image,{type:Q.ImageData,value:t})}},getInputNames:()=>[{name:wa.Image,type:Q.ImageData}],getOutputNames:()=>[{name:ba.Image,type:Q.ImageData}],getDefaultState:Na},play:{getInputNames:()=>[],onParentEvent:()=>Promise.resolve(),getOutputNames:()=>[{name:"out",type:Q.Boolean}]}},xa={},Ca=async()=>{if(!Object.keys(xa).length)for(const e in Aa){const t=Aa[e];xa[e]=Object.freeze({...t})}};var Pa=e=>{if(xa[e])return xa[e];throw new Error(Be(Le,e))},Ea=Ca;const ja=new o,Da="invoked";let ka={},Oa={},Ta={},La={};const Ma=(e,t,n)=>`${e}-${t}${n?`-${n}`:""}`;var Ba=(e,t,n,r,a)=>{const i=Ma(e,t,n),o=Ma(e,t),s=Ma(e,t,"produced"),c=Ta[o],u=Date.now();La[o]=u,ka[i]={data:r,sourcePortName:n,...a?{target:{widgetId:a.widgetId,portName:a.portName}}:{}},ja.emit(s,{currentTime:u,prevTime:c,...a?{targetPort:a?.portName}:{}})},Ra=(e,t,n,r,a)=>{const i=Ma(e,t,n),o=Ma(e,t),s=Ma(e,t,Da),c=Ta[o],u=Date.now();Ta[o]=u,Oa[i]={data:r,sourcePortName:n,...a?{source:{widgetId:a.widgetId,portName:a.portName}}:{}},ja.emit(s,{prevTime:c,currentTime:u,targetPort:n,sourceInfo:a})},Wa=()=>{ka={},Oa={},Ta={},La={},ja.clearListeners()};let Ua,Fa,_a;const Ga=async(e,t,n,r,a)=>{const i=G(n,t);if(!i)return;const o=i.gates[e];if(!o||o.disabled)return;const s={...a,timestamp:Date.now()},c=Pa(o.type),u=Ja(e,s,i.recipeId,i.id,i.version,n);if(u&&c.onParentEvent){const t={name:r};return Ua&&await Ua({recipeId:n,blockId:i.recipeId,gateId:e,targetPort:t.name,data:a}),c.onParentEvent(null,t,{originalEvent:s,data:{...s}},u)}},za=async(e,t,n,r,a,i,o,s,c,u)=>{if(!e&&!c)throw new Error("Missing parameter ['sourceGateId']");if(!e&&!u)throw new Error("Missing parameter ['originalEvent']");e&&(u={timestamp:Date.now(),type:Q.Boolean,value:!0});const d=u;if("string"==typeof n){const e=G(r,n);if(!e)return;n=e}const l=n.gates[t];if(!l||l.disabled)return;const p=s.findIndex((e=>e.name===a)),g=Pa(l.type),m=Ja(t,d,n.recipeId,n.id,n.version,r);if(m&&g.onParentEvent&&-1!==p){Ua&&await Ua({recipeId:r,blockId:n.recipeId,gateId:t,targetPort:i.name,data:o,sourceGate:e?"interrupt_widget":c,sourcePort:e?H:a});const u={name:s[p].name,type:s[p].type,...s[p].jsonShape?{jsonShape:s[p].jsonShape}:void 0};return Ra(n.recipeId,t,i.name,o,c?{widgetId:c,portName:a}:void 0),g.onParentEvent(u,i,{originalEvent:d,data:o},m)}},Va=async(e,t,n,r,a,i,o,s)=>{const c=_(s);if(!c)throw new Error(`Failed to find recipe "${s}" in cache`);const u=c.dbInfo.recipeType,d=z(s,a,r);if(!d)return;const l={...n,timestamp:t.timestamp},p=Pa(d.type);let g;g=d.type===Ce.input?p.getOutputNames(d.state,{thingRecipeId:a,thingDbId:i,thingVersion:o,id:r,recipeId:s,recipeType:u,recipePoolId:s}):await p.getOutputNames(d.state,{recipePoolId:s,recipeType:u,thingRecipeId:a,widgetId:r});if(-1!==g.findIndex((t=>t.name===e))){const n=G(s,a);if(!n)return;Ba(a,r,e,l);const i=d.children.length;for(let o=0;o<i;o++){if(Ne(d.children[o]?.sourcePort).portName===e){const i=n.gates[d.children[o].childId];if(i&&!i.disabled){const c=Pa(i.type);let p;const m={recipePoolId:s,recipeType:u,thingRecipeId:a,widgetId:r};p=i.type===Ce.hubService?await c.getInputNames(i.state,m):c.getInputNames(i.state,m);const v=Ne(d.children[o].targetPort),f=p.find((e=>e.name===v.portName));f&&await za(!1,i.id,n,s,e,{name:f.name},d.returnOriginalEvent?t:l,g,d.id,t)}}}}},Ha=async(e,t,n,r)=>{const a=_(r);if(!a)return null;const i=G(r,n);if(!i)return i;const o=i.gates,s=i.gates[t],c=Pa(s.type),u=await c.getInputNames(s.state,{recipePoolId:r,recipeType:a.dbInfo.recipeType,thingRecipeId:n,widgetId:t}),d=u.findIndex((t=>t.name===e));if(-1!==d){const e=((e,t,n)=>{for(const r in n){const a=n[r],i=a.children.length;for(let n=0;n<i;n++){const r=a.children[n],i=Ne(r.targetPort);if(r.childId===e&&i.portName===t)return a}}return null})(t,u[d].name,o);if(e){const t=Pa(e.type);return{getValue:()=>"function"==typeof t.getValue?t.getValue():null}}}return null},Ja=(e,t,n,r,a,i)=>{const o=_(i);if(!o)throw new Error(`Failed to find recipe "${i}" in cache`);const s=z(i,n,e);if(!s)return console.warn(`Gate ${e} not found in block ${n} for recipe ${i}`),null;const c=async(o,s)=>Va(o,t,s,e,n,r,a,i),u={id:e,type:s.type,recipePoolId:i,thingRecipeId:n,recipeType:o.dbInfo.recipeType,returnOriginalEvent:!!s.returnOriginalEvent,registerInterrupt:(t,r,a,o,s)=>ke.createInterrupt(t,i,n,e,r,a,o,s),cancelInterrupt:e=>ke.destroyInterrupt(e),nextWidget:c,nextGate:c,getParentAtPort:t=>Ha(t,e,n,i),getState:()=>Object.freeze({...s.state,...s.type===Ce.input&&{customInputs:[]}}),setState:t=>{if("object"!=typeof t)return void console.warn(`Invalid state type [${typeof t}]. Expected an 'object'`);const r={...t,...s.type===Ce.input&&!t.customInputs&&{customInputs:[]}},a={...s.state};s.state=r,Fa&&Fa({blockId:n,gateId:e,prevState:a,newState:{...r},recipeId:i})}};return u};ke.setInvokeChildGateCb(za);const qa=new o,Ka="invoked",Xa="state",Ya=()=>{ke.destroyAllInterrupts()},Za=async(e,t,n)=>{const r=_(e),a=z(e,t,n);if(a&&r){const i=Pa(a.type);if(i&&"function"==typeof i.terminate){const a=((e,t,n,r)=>Oe(e,t,n,r))(e,r.dbInfo.recipeType,t,n);if(a)try{await i.terminate(a)}catch(e){console.warn(`Error terminating widget "${n}" in thing "${t}". Failing silently: `,e)}}}},Qa=async(e,t,n,r)=>{const a=_(e),i=z(e,t,n);if(i&&a){const o=Pa(i.type);if(o&&"function"==typeof o.initialize){const i=((e,t,n,r)=>Oe(e,t,n,r,!0))(e,a.dbInfo.recipeType,t,n);if(i){const e=o.initialize;try{await e(i,r||{})}catch(e){throw console.warn(`Error initializing widget "${n}" in thing "${t}": `,e),e}}}}},ei=(e,t)=>{const n=_(t);if(n)for(const t in n.blocks){const r=n.blocks[t];for(const t in r.gates)if(t===e)return{widget:r.gates[t],thing:r}}return null},ti=(e,t="",n="")=>`block:${t}:gate:${n||""}:${e}`,ni=e=>{qa.emit(ti(Xa),e),qa.emit(ti(Xa,e.blockId,e.gateId),e)};Ua=async e=>{await qa.emit(ti(Ka),e),await qa.emit(ti(Ka,e.blockId,e.gateId),e)},(e=>{Fa=e})(ni);var ri=async(e,t,n,r,a)=>{const i=V(e,{id:t,authorId:r,version:n,recipeType:a});Wa();const o=_(i);return o&&(o.startedAt=Date.now(),o.retryAttempts=0,o.execCounter=0,o.status=R.STARTING,o.addLog("recipe registered")),i},ai=async e=>{const t=_(e);var n;if(!t)return null;t.addLog("terminating recipe"),Ya();for(const n in t.blocks){const r=t.blocks[n];for(const t in r.gates)await Za(e,n,t)}W[n=e]&&delete W[n]},ii=async(e,t)=>{const n=_(e),r=[];if(n)for(const a in n.blocks){const i=n.blocks[a];if(!t||!Array.isArray(t)||t.includes(a))for(const t in i.gates)try{if(n.dbInfo?.recipeType===$n.Desktop){const e=i.gates[t];if(e.type===Ce.hubService){const r=e.state;if(r?.service?.webOnly){n?.addLog(`skipping initialization of web-only widget "${t}"`);continue}}}await Qa(e,a,t,{keepCurrentState:!0})}catch(e){r.push({widgetId:t,error:e.message})}}return{failed:r,sendToInputWidget:(t,n,r=Y)=>(async(e,t,n,r)=>{const a=_(n),i=G(n,r),o=Date.now();if(i&&a)for(const a in i.gates){const s=i.gates[a];if(s.type===Ce.input&&!s.disabled){const c=s.state.inputName||"";if(c===e){const e=Pa(s.type),u={...t,timestamp:o},d=Ja(a,u,r,i.id,i.version,n);if(d&&e.processEvent){const i={...d,getState:d.getState};Ua&&await Ua({recipeId:n,blockId:r,gateId:a,targetPort:We,data:t}),_a?await _a(r,n,c,t):await e.processEvent(u,i)}}}}})(t,n,e,r)}},oi=e=>{ha(e)},si=(e,t,n,r=!1)=>{const a=ei(t,e);if(a){const{widget:i,thing:o}=a,s={...i.state};i.state=n,r&&ni({blockId:o.recipeId,gateId:t,recipeId:e,newState:{...n},prevState:s})}},ci=(e,t)=>{const n=ei(t,e);return n?n.widget.state:null},ui=async(e,t,n,r,a)=>{const i=ei(t,e);if(i)return Va(n,r,a,t,i.thing.recipeId,i.thing.id,i.thing.version,e)};const di=e=>{try{return JSON.parse(e)}catch(e){return null}},li="undefined"!=typeof window,pi={protocolPrefix:4,protocolVersion:1,jsonLength:4,binaryLength:4,fromServiceId:4,toServiceId:4,sentAt:8},gi={protocolPrefix:4,txtLength:4},mi=Object.values(pi).reduce(((e,t)=>e+t),0),vi=Object.values(gi).reduce(((e,t)=>e+t),0),fi=["width","height","colorSpace"],yi=(e,t)=>{const n={},r=[];let a=0,i=Array.isArray(e)?[]:{};const o=(e,i)=>{const s=(e=>{const t="undefined"!=typeof Buffer&&e instanceof Buffer,n=e instanceof ArrayBuffer,r=e instanceof Uint8ClampedArray,a=e instanceof Uint8Array,i=e instanceof Int8Array;return t?"Buffer":n?"ArrayBuffer":r?"Uint8ClampedArray":a?"Uint8Array":i?"Int8Array":null})(e);if(!s){if(Array.isArray(e)){const t=[];for(let n=0;n<e.length;n++)t[n]=o(e[n],`${i}[${n}]`);return t}if("object"==typeof e){const t={},n=(e=>{const t=e instanceof Int16Array,n=e instanceof Uint16Array,r=e instanceof Int32Array,a=e instanceof Uint32Array,i=e instanceof Float32Array,o=e instanceof Float64Array,s=e instanceof BigInt64Array,c=e instanceof BigUint64Array;return t?"Int16Array":n?"Uint16Array":r?"Int32Array":a?"Uint32Array":i?"Float32Array":o?"Float64Array":s?"BigInt64Array":c?"BigUint64Array":null})(e);if(n)throw new Error(`Unsupported binary type [${n}] at path "${i}"`);for(const n in e)e.hasOwnProperty(n)||fi.includes(n)||console.warn(`Allowing inherited property: ${n} from path: ${i}`),t[n]=o(e[n],`${i.length?`${i}.`:""}${n}`);return t}return e}n[i]={index:a,length:e.byteLength,binaryType:s},"Buffer"===t?r.push(Buffer.from(e)):"ArrayBuffer"===s?r.push(e):r.push(e.buffer),a+=e.byteLength};i=o(e,"");let s=null;if(r.length>1)if("ArrayBuffer"===t){const e=r.reduce(((e,t)=>e+t.byteLength),0),t=new Uint8Array(e);let n=0;for(let e=0;e<r.length;e++)t.set(new Uint8Array(r[e]),n),n+=r[e].byteLength;s=t.buffer}else{s=Buffer.concat(r)}else 1===r.length&&(s=r[0]);return s?{map:n,combinedData:s,sourceCopy:i}:null},hi=(e,t,n)=>{const r=t.match(/(\[\d+\])|([^[\].]+)/g)||[];let a=e;for(let e=0;e<r.length;e++){let t=r[e];const i=t.startsWith("[")&&t.endsWith("]"),o=e===r.length-1;if(i){t=t.slice(1,-1);const i=parseInt(t,10);if(!Array.isArray(a))throw new Error(`Expected an array at key "${r.slice(0,e).join(".")}" but found an object.`);o?a[i]=n:(a[i]||(a[i]=r[e+1].startsWith("[")?[]:{}),a=a[i])}else o?a[t]=n:(a[t]||(a[t]=r[e+1].startsWith("[")?[]:{}),a=a[t])}return e},Ii=(e,t,n)=>{const r="undefined"!=typeof Buffer,a=t instanceof Uint8Array;for(const i in n)if(n.hasOwnProperty(i)){const{index:o,length:s,binaryType:c}=n[i];let u=null;if(r&&t instanceof Buffer)switch(c){case"Buffer":u=t.subarray(o,o+s);break;case"ArrayBuffer":u=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength).slice(o,o+s);break;case"Uint8Array":u=new Uint8Array(t.subarray(o,o+s));break;case"Uint8ClampedArray":u=new Uint8ClampedArray(t.subarray(o,o+s));break;case"Int8Array":u=new Int8Array(t.subarray(o,o+s))}else if(t instanceof ArrayBuffer||t instanceof Uint8Array)switch(c){case"Buffer":if(r){u=Buffer.from(t.slice(o,o+s));break}case"ArrayBuffer":u=a?t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength).slice(o,o+s):t.slice(o,o+s);break;case"Uint8Array":u=a?t.slice(o,o+s):new Uint8Array(t.slice(o,o+s));break;case"Uint8ClampedArray":u=new Uint8ClampedArray(t.slice(o,o+s));break;case"Int8Array":u=new Int8Array(t.slice(o,o+s))}u&&hi(e,i,u)}return e},Si=e=>d(e),$i="KMSG",wi="KCMD",bi=Si("klProtocol");var Ni={encode:(e,t,n)=>{const r={json:e.json},a=yi(r.json,"Buffer"),i=a?.combinedData;a&&(r.jsonBinaryMap=a.map,r.json=a.sourceCopy);const o=i?i.byteLength:0,s=JSON.stringify(r),c=Buffer.from(s),u=c.byteLength,d=pi.protocolPrefix+pi.protocolVersion+pi.jsonLength+pi.binaryLength+pi.fromServiceId+pi.toServiceId+pi.sentAt+u+o,l=Buffer.alloc(d),p=Date.now();let g=0;return l.write($i,g),g+=pi.protocolPrefix,l.writeUInt8(1,g),g+=pi.protocolVersion,l.writeUInt32LE(u,g),g+=pi.jsonLength,l.writeUInt32LE(o,g),g+=pi.binaryLength,l.writeUInt32LE(t,g),g+=pi.fromServiceId,l.writeUInt32LE(n,g),g+=pi.toServiceId,l.writeBigInt64LE(BigInt(p),g),g+=pi.sentAt,c.copy(l,g),g+=u,i&&o&&i.copy(l,g),l},decodeHeader:e=>{let t=0;const n=e.toString("utf-8",t,pi.protocolPrefix);if(t+=pi.protocolPrefix,n!==$i)return null;if(e.byteLength<mi)return bi(`Received a Partial Header with ${e.byteLength} bytes. Waiting for more data.`),{partialHeader:!0,remaining:null};const r=e.readUInt8(t);t+=pi.protocolVersion;const a=e.readUInt32LE(t);t+=pi.jsonLength;const i=e.readUInt32LE(t);t+=pi.binaryLength;const o=e.readUInt32LE(t);t+=pi.fromServiceId;const s=e.readUInt32LE(t);t+=pi.toServiceId;const c=e.readBigInt64LE(t);t+=pi.sentAt;const u=a+i,d=e.subarray(t,t+u),l=e.subarray(0,mi);let p=null;return e.byteLength-mi-a-i>0&&(p=e.subarray(mi+a+i)),{header:{protocolVersion:r,jsonLength:a,binaryLength:i,fromServiceId:o,toServiceId:s,sentAt:new Date(Number(c)),packages:[d],headerPackage:l},remaining:p}},decodeFullKlMessage:e=>{const t=Buffer.concat(e.packages),n=t.subarray(0,e.jsonLength).toString(),r=t.subarray(e.jsonLength,e.jsonLength+e.binaryLength),a=di(n);if(!a?.json)return bi("Invalid JSON in KL message"),null;a.jsonBinaryMap&&r.byteLength&&Ii(a.json,r,a.jsonBinaryMap);const i=Buffer.concat([e.headerPackage,t]);let o=i,s=null;const c=mi+e.jsonLength+e.binaryLength;return i.byteLength>c&&(s=i.subarray(c),o=i.subarray(0,c)),{message:{json:a.json,rawMessage:o},remaining:s}},patchEncodedHeader:(e,t)=>{if(null==t.fromServiceId&&void 0===t.toServiceId)return e;if(e.byteLength<mi)return bi("Invalid Header Size"),e;let n=0;return n+=pi.protocolPrefix,n+=pi.protocolVersion,n+=pi.jsonLength,n+=pi.binaryLength,void 0!==t.fromServiceId&&e.writeUInt32LE(t.fromServiceId,n),n+=pi.fromServiceId,void 0!==t.toServiceId&&e.writeUInt32LE(t.toServiceId,n),e},encodeCommand:e=>{let t=0;const n=Buffer.from(e),r=n.byteLength,a=vi+r,i=Buffer.alloc(a);return i.write(wi,t),t+=gi.protocolPrefix,i.writeUint32LE(r,t),t+=gi.txtLength,n.copy(i,t),i},decodeCommand:e=>{let t=0;if(e.byteLength<vi)return{command:null};const n=e.toString("utf-8",t,gi.protocolPrefix);if(t+=gi.protocolPrefix,n!==wi)return{command:null};const r=e.readUInt32LE(t);t+=gi.txtLength;const a=e.toString("utf-8",t,t+r),i=e.byteLength-vi-r;let o=null;i>0&&(o=e.subarray(vi+r));let s=0;return i<0&&(s=Math.abs(i)),{command:a,remainingData:o,missing:s}}};const Ai="KMSG",xi="KCMD",Ci=Si("klProtocol"),Pi=new TextEncoder;var Ei={encode:(e,t,n)=>{const r={json:e.json},a=yi(e.json,"ArrayBuffer"),i=a?.combinedData;a&&(r.jsonBinaryMap=a.map,r.json=a.sourceCopy);const o=i?i.byteLength:0,s=JSON.stringify(r),c=Pi.encode(s),u=c.byteLength,d=new ArrayBuffer(pi.protocolPrefix+pi.protocolVersion+pi.jsonLength+pi.binaryLength+pi.fromServiceId+pi.toServiceId+pi.sentAt+u+o),l=new DataView(d),p=new Uint8Array(d),g=Date.now();let m=0;for(let e=0;e<4;++e)p[m++]=Ai.charCodeAt(e);return l.setUint8(m,1),m+=pi.protocolVersion,l.setUint32(m,u,!0),m+=pi.jsonLength,l.setUint32(m,o,!0),m+=pi.binaryLength,l.setUint32(m,t,!0),m+=pi.fromServiceId,l.setUint32(m,n,!0),m+=pi.toServiceId,l.setBigInt64(m,BigInt(g),!0),m+=pi.sentAt,p.set(c,m),m+=u,i&&o&&p.set(new Uint8Array(i),m),d},decodeHeader:e=>{const t=new DataView(e);let n=0,r="";for(let e=0;e<pi.protocolPrefix;++e)r+=String.fromCharCode(t.getUint8(n++));if(r!==Ai)return null;if(e.byteLength<mi)return Ci.log(`Received a Partial Header with ${e.byteLength} bytes. Waiting for more data.`),{partialHeader:!0,remaining:null};const a=t.getUint8(n);n+=pi.protocolVersion;const i=t.getUint32(n,!0);n+=pi.jsonLength;const o=t.getUint32(n,!0);n+=pi.binaryLength;const s=t.getUint32(n,!0);n+=pi.fromServiceId;const c=t.getUint32(n,!0);n+=pi.toServiceId;const u=t.getBigInt64(n,!0);n+=pi.sentAt;const d=i+o,l=e.slice(n,n+d),p=new Uint8Array(e,0,mi);let g=null;if(e.byteLength-mi-i-o>0){g=new Uint8Array(e,mi+i+o).slice().buffer}return{header:{protocolVersion:a,jsonLength:i,binaryLength:o,fromServiceId:s,toServiceId:c,sentAt:new Date(Number(u)),packages:[l],headerPackage:p.slice().buffer},remaining:g}},decodeFullKlMessage:e=>{const t=e.packages.reduce(((e,t)=>e+t.byteLength),0),n=new Uint8Array(t);let r,a=0;for(const t of e.packages)r=new Uint8Array(t),n.set(r,a),a+=r.byteLength;const i=(new TextDecoder).decode(n.subarray(0,e.jsonLength)),o=n.subarray(e.jsonLength,e.jsonLength+e.binaryLength),s=di(i);if(!s?.json)return Ci.log("Invalid JSON in KL message"),null;s.jsonBinaryMap&&o.byteLength&&Ii(s.json,o,s.jsonBinaryMap);const c=new Uint8Array(e.headerPackage.byteLength+n.byteLength);c.set(new Uint8Array(e.headerPackage),0),c.set(n,e.headerPackage.byteLength);let u=c,d=null;const l=mi+e.jsonLength+e.binaryLength;return c.byteLength>l&&(d=c.subarray(l),u=c.subarray(0,l)),{message:{json:s.json,...o.length?{binaryData:o.buffer}:{},rawMessage:u.buffer},remaining:d?.buffer??null}},patchEncodedHeader:(e,t)=>{if(null==t.fromServiceId&&void 0===t.toServiceId)return e;if(e.byteLength<mi)return Ci("Invalid Header Size"),e;let n=0;n+=pi.protocolPrefix,n+=pi.protocolVersion,n+=pi.jsonLength,n+=pi.binaryLength;const r=new DataView(e);return void 0!==t.fromServiceId&&r.setUint32(n,t.fromServiceId,!0),n+=pi.fromServiceId,void 0!==t.toServiceId&&r.setUint32(n,t.toServiceId,!0),e},encodeCommand:e=>{let t=0;const n=Pi.encode(e),r=n.byteLength,a=new ArrayBuffer(vi+r),i=new DataView(a),o=new Uint8Array(a);for(let e=0;e<4;++e)o[t++]=xi.charCodeAt(e);return i.setUint32(t,r,!0),t+=gi.txtLength,o.set(n,t),a},decodeCommand:e=>{const t=new DataView(e);let n=0;if(e.byteLength<vi)return{command:null};let r="";for(let e=0;e<gi.protocolPrefix;++e)r+=String.fromCharCode(t.getUint8(n++));if(r!==xi)return{command:null};const a=t.getUint32(n,!0);n+=gi.txtLength;const i=e.byteLength-vi-a,o=new Uint8Array(e,n,Math.min(a,e.byteLength-vi)),s=(new TextDecoder).decode(o);let c=null;i>0&&(c=e.slice(vi+a));let u=0;return i<0&&(u=Math.abs(i)),{command:s,remainingData:c,missing:u}}};let ji=Ni;li&&(ji=Ei);var Di,ki=ji;!function(e){e.FunctionNotFound="FNC_NOT_FOUND"}(Di||(Di={}));let Oi=Math.ceil(Date.now()/1e3);function Ti(e){const t={};let n=console.log;const r={};let a=e||String(Date.now());const i={},o=e=>!i[e],s=(e,t,n,r,a,i)=>{let s=li?new ArrayBuffer(0):Buffer.alloc(0);const c={json:{functionName:e,args:i.success?i.success:[i],messageId:t,type:i.success?"response":"error"}};return o(r)&&(s=ki.encode(c,n,r)),a(s,{msg:c,sourceServiceId:n,targetServiceId:r})};return{setLogger:e=>{n=e},processMessage:(e,a,i,o)=>{if(!o)return!1;const c=o;if(t[c.messageId]){const e=t[c.messageId];return e&&(clearTimeout(e.timer),e.fulfilled||(e.fulfilled=!0,"response"===c.type?e.resolve(c.args):"error"===c.type&&e.reject(c.args[0])),delete t[c.messageId]),!0}if("execute"!==c.type&&n&&n(`No pending execution found for message id "${c.messageId}"`),"execute"===c.type){const t=r[c.functionName];if(t){const n=e=>{s(c.functionName,c.messageId,i.targetServiceId,i.sourceServiceId,a,e)};t({transport:e,args:c.args,reply:n,messageId:c.messageId,sourceServiceId:i.sourceServiceId,send:a})}else{const e=`Function "${c.functionName}" not found.`;n&&n(e),s(c.functionName,c.messageId,i.targetServiceId,i.sourceServiceId,a,{error:e,errCode:"FNC_NOT_FOUND"})}return!0}return!1},execute:async(e,r,i,s,c,u)=>{if(!i){const e="No send buffer function provided.";throw n&&n(e),e}Oi+=1;const d=`${a}-${Oi}-exec-${e.substring(0,10)}`,l={messageId:d,functionName:e,send:i,sourceServiceId:s,targetServiceId:c,args:r||[],fulfilled:!1,resolve:()=>{},reject:()=>{}};l.promise=new Promise(((e,t)=>{l.resolve=e,l.reject=t}));let p=li?new ArrayBuffer(0):Buffer.alloc(0);const g={json:{functionName:e,args:r,messageId:d,type:"execute"}};o(c)&&(p=ki.encode(g,s,c)),t[d]=l,n&&n(`Calling remote function "${e}" with message id "${d}"`);const m="true"===process.env.NO_INVOKE_TIMEOUT;return u?.async?(l.fulfilled=!0,l.resolve([void 0]),delete t[d]):0===u?.timeout||m||(l.timer=setTimeout((()=>{n&&n(`Remote function ${d} timed out`);const r=t[d];r&&!r.fulfilled&&(r.fulfilled=!0,l.reject(`Function ${e} Timed out`)),delete t[d]}),u?.timeout||3e4)),i(p,{sourceServiceId:s,targetServiceId:c,msg:g}),l.promise},sendResponse:s,registerFunction:(e,t)=>{r[e]=t},getTransportSendFunction:e=>{const n=t[e];return n?n.send:null},setServiceName:e=>{a=e},getPendingExecutions:()=>t,rejectAllPending:e=>{Object.keys(t).forEach((n=>{const r=t[n];r&&!r.fulfilled&&(clearTimeout(r.timer),r.fulfilled=!0,r.reject(e),delete t[n])}))},broadcast:(e,t,r,i)=>{Oi+=1;const s=`${a}-${Oi}-multicast-${e.substring(0,10)}`;let c=li?new ArrayBuffer(0):Buffer.alloc(0);const u={json:{functionName:e,args:t,messageId:s,type:"execute"}};let d=o(r[0].serviceId);d&&(c=ki.encode(u,i,r[0].serviceId));for(let t=0;t<r.length;t++)try{const a=r[t];n&&n(`Broadcasting function "${e}" with message id "${s}" to client [${a.serviceId}]`),0!==t&&(d=o(a.serviceId),d&&(c=ki.patchEncodedHeader(c,{toServiceId:a.serviceId}))),a.sendFn(c,{msg:u,sourceServiceId:i,targetServiceId:a.serviceId})}catch(e){n&&n(`Error broadcasting to client at index ${t}`)}},disableServiceEncoding:(e,t)=>{i[e]=t}}}let Li,Mi,Bi,Ri,Wi,Ui=!1;var Fi=()=>{Ui=!0},_i=(e,t)=>{if(!Li)throw new Error("Memory connection not set.");Li.sendBuf(e,t)},Gi=e=>Mi=e,zi=e=>Wi=e,Vi=e=>Bi=e,Hi=e=>Ri=e,Ji=e=>(Li.sendCmd(e),!0);const qi=(e,t=2)=>{const n=(e,r)=>{if("object"==typeof e){const a=Object.keys(e);for(const i of a){const a=e[i];if(a&&"object"==typeof a){const o=a._kemuType;if(void 0!==o){if(o===Q.ImageData){const t=e[i];e[i]=Ae(t)}}else r<t&&n(a,++r)}}}};return n(e,1),e},Ki=Si("klTransmissionManager"),Xi=()=>{const e=(t,n,r,a)=>{let i=n,o=null;const s=t instanceof ArrayBuffer;if(Ki(`RAW: ${t.toString()}`),!i||i.partialHeaderData){let c;if(s?(c=i?.partialHeaderData?new Uint8Array([...new Uint8Array(i.partialHeaderData),...new Uint8Array(t)]).buffer:t,o=Ei.decodeHeader(c)):(c=i?.partialHeaderData?Buffer.concat([i.partialHeaderData,t]):t,o=Ni.decodeHeader(c)),!o){const{command:t,missing:i,remainingData:o}=s?Ei.decodeCommand(c):Ni.decodeCommand(c);return t?a({command:t,complete:!0,rawMessage:c}):Ki(i?`ERROR: Missing ${i} bytes to complete the command. This partial command will be aborted.`:`ERROR: Invalid state, message was decoded without a header or partial header data. Discarding ${c.byteLength} bytes`),o?(Ki(`${o.byteLength} bytes remain after processing command. Re-analyzing...`),e(o,n,r,a)):void 0}if(o.partialHeader)return i={firstPackageAt:Date.now(),partialHeaderData:c},r(i);if(!o.header)return Ki(`ERROR: Invalid state, message was decoded without a header or partial header data. Discarding ${c.byteLength} bytes`);const u=o.header;i={firstPackageAt:Date.now(),header:{...u,totalBytesReceived:u.packages[0].byteLength,totalBytesExpected:u.binaryLength+u.jsonLength,remaining:o.remaining}},r(i)}else i.header&&i.header.totalBytesReceived<i.header.totalBytesExpected&&(i.header.packages.push(t),i.header.totalBytesReceived+=t.byteLength,r(i));if(i.header&&i.header.totalBytesReceived>=i.header.totalBytesExpected){const t=Date.now()-i.header.sentAt.getTime(),n=Date.now()-i.firstPackageAt;Ki(`Received ${i.header.totalBytesReceived} of ${i.header.totalBytesExpected} expected in ${t} ms, elapsed since first package: ${n}ms`);const o=s?Ei.decodeFullKlMessage(i.header):Ni.decodeFullKlMessage(i.header),c=i.header.totalBytesReceived,u=i.header.remaining;r(null),o&&a({klMessage:o.message,complete:!0,sourceServiceId:i.header.fromServiceId,targetServiceId:i.header.toServiceId,rawMessage:o.message.rawMessage});let d=u;if(o?.remaining&&(d=s?u?((e,t)=>{const n=e.byteLength+t.byteLength,r=new ArrayBuffer(n),a=new Uint8Array(e),i=new Uint8Array(t),o=new Uint8Array(r);return o.set(a),o.set(i,a.length),r})(u,o.remaining):o.remaining:u?Buffer.concat([u,o.remaining]):o.remaining),d)return Ki(`${d.byteLength} bytes remaining after processing message with ${c} bytes of data. Re-analyzing...`),e(d,null,r,a)}};return e};Si("ipcClient");Si("kemuWidgetService"),$(process.argv.slice(2));const Yi=e=>d(`runner:${e}`),Zi=Yi("connectionManager"),Qi=Yi("remoteInvoke"),eo=new Ti("kweb");eo.setLogger(Qi);const to=new o,no=new o;let ro,ao=null,io=null;const oo={},so=(e,t,n)=>{const r=`${e}_${t}`,a={contents:n,lastRequestedAt:Date.now(),contentsChecksum:""};return oo[r]=a,a},co=(e,t)=>oo[`${e}_${t}`]||null,uo=async(e,t)=>{if(!ao)return Zi("Hub Link has not been acknowledged. Cannot get services."),null;const n=[{serviceName:e,version:t}];return(await eo.execute(re.GetServiceContents,n,po,ao,0))[0]},lo=async(e,t,n=!1)=>{if(!e||!t)return null;const r=co(e,t);if(!r||n){const n=r||so(e,t);try{const r=await uo(e,t);return r&&(n.contents=r.uiContent,n.contentsChecksum=r.uiContentsChecksum||""),n.contents||null}catch(n){Zi(`Failed to fetch service contents for ${e} v${t}`,n)}}return r?.contents||null},po=_i,go=()=>{Zi("Disconnected from the server"),ao=null,eo.rejectAllPending("Disconnected from the server"),to.emit("disconnected")},mo=()=>{Zi("Connected to the server"),to.emit("connected")},vo=()=>io,fo=(e,t,n,r)=>`${e}_${t}_${n}_${r}`,yo=async()=>{const e=vo();if(e){const t=_(e)?.blocks;if(t){const n={};for(const r in t){const a=t[r];for(const t in a.gates){const r=a.gates[t];if(r.type===Ce.hubService){const t=r.state;if(t.service?.eventEmitter){const r=`${t.service.name}_${t.service.version}`;if(!n[r])try{Zi(`Re-issuing subscription for service ${t.service.name} (${t.service.version})`),n[r]=!0,await Do({listener:{recipeId:e},targetService:{serviceName:t.service.name,version:t.service.version}})}catch(e){Zi(`Failed to re-issue subscription for service ${t.service.name} (${t.service.version})`,e)}}}}}}}},ho=async e=>{const t=e.args[0],n=fo("broadcast",`hub_${t.type}`,(0).toString(),"");await no.emit(n,t)},Io=async e=>{const t=e.args[0];for(const e of t.outputs||[])e.type===Q.ImageData&&he(e.value)&&(e.value=Ae(e.value));const n=vo();if(n){const r=_(n);if(r){const a=async e=>{const n=fo("broadcast",t.source.serviceName,t.source.serviceVersion,e);try{await no.emit(n,t)}catch(t){Zi(`Failed to emit broadcast event for target ${e}`,t)}};await a("app");for(const i in r.blocks){const o=r.blocks[i];for(const r in o.gates){const i=o.gates[r];if(i.disabled)continue;const s=i.state;if(i.type===Ce.hubService&&s.service?.name===t.source.serviceName&&s.service?.version===t.source.serviceVersion&&s.variantId===t.variantId){await a(r);for(const a of t.outputs||[])if(null!==a.value&&void 0!==a.value){const t={type:a.type,value:a.value,timestamp:Date.now()};Zi(`Sending data to output ${a.name} requested by messageId ${e.messageId}`),await ui(n,r,a.name,t,t)}}}}}}},So=async e=>{const t=e.args[0],{finalState:n,recipeId:r,widgetId:a}=t,i=ci(r,a);let o=i;if(n&&o&&i&&(o={...i,customState:n},si(r,a,o,!0)),o?.service)try{const e=fo("setOutputs",o.service.name,o.service.version,a);await no.emit(e,t.outputs)}catch(e){Zi(`Failed to emit setOutputs event for widget ${a}`,e)}for(const n of t.outputs)if(null!==n.value&&void 0!==n.value){if(n.type===Q.ImageData){if(!he(n.value)){Zi(`Invalid ImageData value received for output ${n.name}. Expected an ImageData-like object`);continue}n.value=Ae(n.value)}else n.type===Q.JsonObj&&qi(n.value);const t={type:n.type,value:n.value,timestamp:Date.now()};Zi(`Sending data to output ${n.name} requested by messageId ${e.messageId}`),await ui(r,a,n.name,t,t)}e.reply({success:[]})},$o=async e=>{const t=e.args[0],{newState:n,recipeId:r,widgetId:a}=t,i=ci(r,a);if(i){const t={...i,customState:{...i.customState,...n}};return si(r,a,t,!0),e.reply({success:[]})}},wo=async({args:e,reply:t})=>{const n=e[0],{recipeId:r,widgetId:a,path:i,key:o}=n;Zi(`Received request to set a dependency path for "${o}" on widget "${a}" in recipe "${r}"`);const s=ci(r,a);if(s){const e={...s};e.dependencies=e.dependencies||{},e.dependencies[o]={path:i},si(r,a,e,!0)}return t({success:[]})},bo=async({args:e,reply:t})=>{const n=e[0],{recipeId:r,widgetId:a,key:i}=n;Zi(`Received request to get a dependency path for "${i}" on widget "${a}" in recipe "${r}"`);const o=ci(r,a);if(o){const e=o.dependencies?.[i]?.path;return Zi(`Returning dependency path for "${i}" on widget "${a}": "${e}"`),t({success:[e||null]})}return t({error:"Widget not found",errCode:"WIDGET_NOT_FOUND"})},No=async()=>{if(Zi(`Requesting services on ${(new Date).toISOString()}`),!ao)return Zi("Hub Link has not been acknowledged. Cannot get services."),[];const e=await eo.execute(re.GetServices,[],po,ao,0);ro=e;for(const t of e){if(t.internal)continue;const e=co(t.name,t.version);if(!e||e?.contentsChecksum!==t.uiContentChecksum)try{const n=e||so(t.name,t.version);Zi(`Service ${t.name} v${t.version} contents have changed, fetching new contents`);const r=await uo(t.name,t.version);r&&(n.contents=r.uiContent,n.contentsChecksum=t.uiContentChecksum||"")}catch(e){Zi(`Failed to update service contents for ${t.name} v${t.version}`,e)}}return e},Ao=()=>[...ro||[]],xo=()=>!!ro,Co=async e=>{const{targetServiceSessionId:t}=e;if(!ao)return void Zi("No target service session id provided");Zi(`Forwarding "onParentEvent" to service ${t}`);return await eo.execute(re.OnParentEvent,[e],po,ao,t,e.config)},Po=async e=>{if(!ao)return Zi("Hub Link has not been acknowledged. Cannot get services."),{};const[t]=await eo.execute(re.GetDefaultState,[],po,ao,e);return t},Eo=async(e,t,n,r)=>{if(!ao)return Zi("Hub Link has not been acknowledged. Cannot get services."),null;const[a]=await eo.execute(re.UIEvent,[t,n],po,ao,e,r);return a},jo=(e,t)=>{const n=()=>{t()};return to.on(e,n),()=>to.off(e,n)},Do=async e=>{if(ao)return eo.execute(re.SubscribeToService,[e],po,ao,0);Zi("Hub Link has not been acknowledged. Cannot subscribe to services.")},ko=async e=>{if(ao)return eo.execute(re.UnsubscribeFromService,[e],po,ao,0);Zi("Hub Link has not been acknowledged. Cannot subscribe to services.")},Oo=(e,t,n,r)=>{const a=fo("broadcast",t,n,e);return no.on(a,r)},To=(e,t,n,r)=>{const a=fo("setOutputs",t,n,e);return no.on(a,r)},Lo=async(e,t,n)=>ao?eo.execute(e,t,po,ao,0,n):(Zi("Hub Link has not been acknowledged. Cannot execute function."),null),Mo=async e=>{if(!ao)return void Zi("Hub Link has not been acknowledged. Cannot execute function.");const t=ci(e.recipeId,e.widgetId);if(!t)throw new Error("Widget or recipe pool not found. Cannot initialize service instance.");const n=Object.keys(t.dependencies||{}).reduce(((e,n)=>(e[n]=t.dependencies?.[n]?.path||null,e)),{}),r=[{currentState:t.customState,recipeId:e.recipeId,widgetId:e.widgetId,variantId:e.variantId,recipeType:e.recipeType,currentDependencies:n}],[a]=await eo.execute(re.InitializeInstance,r,po,ao,e.sessionId);if(a){const t=ci(e.recipeId,e.widgetId);if(t){const n={...t,customState:a};si(e.recipeId,e.widgetId,n,!0)}}},Bo=async(e,t,n,r)=>{if(!ao)return void Zi("Hub Link has not been acknowledged. Cannot execute function.");const a=ci(n,t);if(!a)throw new Error("Widget or recipe pool not found. Cannot initialize service instance.");const i=[{currentState:a.customState,recipeId:n,widgetId:t,variantId:r}];await eo.execute(re.TerminateInstance,i,po,ao,e)},Ro=async(e,t,n="^",r)=>{const a=["^","~",">=",">","<=","<","="];if(!a.includes(n))throw new Error(`Invalid compare mode "${n}". Must be one of ${a.join(", ")}`);const i=xo(),o=r||!i?await No():Ao();for(const r of o)if(r.name===e){if(r.version===t)return r;if(c(r.version,`${n}${t}`))return r}return null};var Wo=async()=>{Vi(mo),Hi(go),zi((({json:e,transmission:t})=>{eo.processMessage("websocket",po,t,e)})),eo.registerFunction(re.SetState,$o),eo.registerFunction(re.SetOutputs,So),eo.registerFunction(re.BroadcastEvent,Io),eo.registerFunction(re.HubBroadcastEvent,ho),eo.registerFunction(ae.SetDependencyPath,wo),eo.registerFunction(ae.GetDependencyPath,bo),Gi((e=>{((e,t)=>{const n=ne.SocketAcknowledge,r=ne.IpcAcknowledge,a=e.startsWith(n);if(e===r)return t&&t(),0;if(a){const i=e.split(a?n:r),o=parseInt(i[1]);return t&&t(o),o}})(e,(e=>{e?(Ji((e=>`${ne.AcknowledgeResponse}${e}`)(e)),Zi("Hub Link acknowledged"),ao=e,to.emit("acknowledged"),yo()):Zi("Hub sent ACK request without service id")})),((e,t)=>{e===ne.ServicesListChanged&&(t&&t())})(e,(()=>{Zi("Services list changed"),to.emit("services-changed")}))})),await Fi()},Uo=(e,t)=>{to.on(e,t)},Fo=()=>({getServices:No,getServiceContents:lo,onParentEvent:Co,onCommand:jo,getDefaultState:Po,getCachedServices:Ao,areServicesCached:xo,subscribeToServiceEvents:Do,unsubscribeFromServiceEvents:ko,callProcessorHandler:Eo,onBroadcastEvent:Oo,onSetOutputsEvent:To,executeHubFunction:Lo,initializeServiceInstance:Mo,terminateServiceInstance:Bo,getCompatibleService:Ro}),_o=e=>{io=e},Go=()=>eo;const zo=e=>{try{return JSON.parse(e)}catch(e){return null}},Vo=(e,t)=>{if(e.startsWith(ne.AcknowledgeResponse)){const n=e.split(":"),r=parseInt(n[1]),a=parseInt(n[2]);return t&&t(r,isNaN(a)?void 0:a),!0}return!1},Ho=e=>d(e),Jo=Date.now();let qo=Math.ceil(Jo/1e3);var Ko=()=>qo+=1;const Xo=p(x(),"kemu-user-services"),Yo="KMU-CB-v1";var Zo;!function(e){e.input="input",e.counter="counter",e.play="play",e.elapsed="elapsed",e.ifGate="ifGate",e.skipEvent="skipEvent",e.between="between",e.map="map",e.parser="parser",e.slider="slider",e.suspend="suspend",e.display="display",e.pixelfy="pixelfy",e.json="json",e.arrayItem="arrayItem",e.extractImage="extractImage",e.imageConvolution="imageConvolution",e.firstEvent="firstEvent",e.pixelDraw="pixelDraw",e.randomBetween="randomBetween",e.arrayCombine="arrayCombine",e.clock="clock",e.multiplication="multiplication",e.object="object",e.widgetGroup="widgetGroup",e.script="script",e.base64ToImageData="base64ToImageData",e.jsonParse="jsonParse",e.text="text",e.imageCrop="imageCrop",e.imageResize="imageResize",e.value="value",e.imageWarp="imageWarp",e.widgetBundle="widgetBundle",e.sequence="sequence",e.variable="variable",e.hubService="hubService"}(Zo||(Zo={}));const Qo=e=>({...e,type:Array.isArray(e.type)?e.type.map((e=>Q[e])):Q[e.type]}),es=async e=>{try{return await f(e,"utf-8")}catch(e){return null}},ts=e=>{if(e&&e.startsWith(Yo)){const t=e.slice(9),n=decodeURI(t);return zo(n)}return null},ns=async(e,t,n)=>{let r=[];e.variants?.length&&(r=e.variants.map((e=>({...e,...e.inputs?{inputs:e.inputs.map(Qo)}:{},...e.outputs?{outputs:e.outputs.map(Qo)}:{}}))));const a={...e,path:t,customWidgets:[],...e.inputs?{inputs:e.inputs.map(Qo)}:{inputs:[]},...e.outputs?{outputs:e.outputs.map(Qo)}:{outputs:[]},variants:r,...e.widgetUI&&n?.widgetUIContents?{widgetUIContents:n.widgetUIContents}:{}},i=await(async(e,t,n=console.log)=>{const r=[];if(t.customWidgets?.length)for(const a of t.customWidgets){const t=await es(p(e,a));if(!t){n(`Error loading custom widget file ${a}`);continue}const i=t.startsWith(Yo)?t:`${Yo}${t}`,o=ts(i);if(!o){n(`Custom widget file "${a}" is not a valid Kemu Clipboard item`);continue}const s=Object.values(o).filter((e=>e.type===Zo.widgetGroup&&!e.groupId));if(s.length>1){n(`Custom widget file "${a}" contains more than one top level widgetGroup`);continue}const c=s[0];if(!c){n(`Custom widget file "${a}" does not contain a top level widgetGroup`);continue}const u=c.state,d={name:u.name,color:u.color,description:u.description,contents:i,rootGroupId:c.id,icon:u.icon,protocolVersion:u.protocolVersion||"2"};r.push(d)}return r})(t,e,n?.log);if(i.length?a.customWidgets=i:delete a.customWidgets,a.variants?.length)for(const e of a.variants)if(e.svgIcon)try{const n=await f(p(t,e.svgIcon),"utf-8");e.svgIcon=n}catch(t){n?.log&&n?.log(`Error loading svgIcon for variant ${e.id}: ${t}`)}return a},rs=async e=>{try{return await y(e,h.F_OK),!0}catch{return!1}},as=Ho("serviceManager"),is={};let os=null;const ss=e=>{if(!os)throw new Error('IPC config not set, call "setHubIpcConfig" first.');try{if(e.processor===te.Javascript){as(`Spawning service ${e.name} with sessionId ${e.sessionId}`);const t=l.join(e.path,"processor.js"),n=[`--sessionId=${e.sessionId.toString()}`,`--ipcSpace=${os.appSpace}`,`--ipcId=${os?.id}`,`--recipePath=${os.recipePath||""}`];e.internal&&n.push("--internal=true");const r=N("node",[t,...n]);return r.stdout.on("data",(t=>{as(`[Service ${e.name}] - stdout: ${t}`)})),r.stderr.on("data",(t=>{as(`[Service ${e.name}] - stderr: ${t}`)})),as(`[Service ${e.name}] spawned with PID ${r.pid}`),r}throw`Unsupported processor type ${e.processor}`}catch(t){throw`Error spawning service ${e.name}: ${t}`}},cs=e=>{if(!e?.name)return"Missing name";if(!e?.version)return"Missing version";if(!e?.description)return"Missing description";if(!e?.processor)return"Missing processor";return[te.Javascript,te.Executable,te.Python].includes(e?.processor)?null:"Invalid processor"},us=async(e,t)=>{const n=l.join(e,"manifest.json");if(!w.existsSync(n)){const t=`Missing manifest for service ${e}. Aborting.`;return as(t),{error:t}}const r=await f(n,"utf-8"),a=zo(r),i=cs(a);if(!a||i){const t=`Invalid service manifest [${e}]: ${i}. Aborting.`;return as(t),{error:t}}let o;if(delete a.internal,t?.singleServiceName&&a.name!==t.singleServiceName){return{error:`Skipping service ${a.name} as it does not match the singleServiceName option`}}await Promise.all([(async()=>{if(a.widgetUI)try{o=await f(l.join(e,"widgetUI.js"))}catch(e){const t=`Error loading widgetUI file ${a.name}: ${e}`;return as(t),{error:t}}})(),(async()=>{if(a.svgIcon){const t=await es(l.join(e,a.svgIcon));if(!t){return{error:`Error loading icon for service ${a.name}`}}a.svgIcon=t}})(),(async()=>{if(a.subServices?.length)for(const t of a.subServices){const n=l.join(e,t),{error:r,service:i}=await us(n);r?as(`Error loading sub-service ${t}: ${r}`):i&&(i.info.parentService={name:a.name,version:a.version})}delete a.subServices})(),(async()=>{if(a.variants?.length)for(const t of a.variants)if(t.svgIcon)try{const n=await f(l.join(e,t.svgIcon),"utf-8");t.svgIcon=n}catch(e){as(`Error loading svgIcon for variant ${t.id}: ${e}`)}})()]);const s=Ko(),c=t?.fixedSession||s;as(`Loaded service ${a.name} with sessionId ${c}`);const u=await ns(a,e,{widgetUIContents:o});return ds(u),is[c]={info:{...u,path:e,sessionId:c},status:"loaded",childProcess:null},{service:is[c]}},ds=e=>{e.widgetUIContents?e.uiContentChecksum=(e=>{const t=A("sha256");return t.update(e),t.digest("hex")})(e.widgetUIContents):e.uiContentChecksum=void 0},ls=e=>{try{return e.childProcess=ss(e.info),e.status="started",!0}catch(t){return as(`Service [${e.info.name}] error: ${t}`),e.status="error",e.errorMsg="string"==typeof t?t:JSON.stringify(t),!1}},ps=()=>Object.values(is).filter((e=>"running"===e.status)).map((e=>{const{path:t,...n}=e.info;return{...n}})),gs=(e,t)=>{const n=Object.values(is).find((n=>n.info.name===e&&n.info.version===t));if(!n)return null;if(n.info.internal)throw`Cannot stop internal service ${e}`;if(n.childProcess){as(`Stopping service "${e} (v${t})"`);n.childProcess.kill("SIGINT")||as(`Failed to stop service ${e}`)}return n.status="stopped",as(`Service ${e} stopped`),n},ms=e=>e.info.internal?e.info.path:l.join(e.info.path,"..");var vs={loadServices:async(e,t)=>{if(!await rs(e))return void as(`Failed to load services from "${e}". Directory does not exist.`);const n=w.readdirSync(e,{withFileTypes:!0}).filter((e=>e.isDirectory())).map((e=>e.name));as(`Found ${n.length} services in "${e}"`);for(let r=0;r<n.length;r++){const a=n[r],i=l.join(e,a),{error:o,service:s}=await us(`${i}${t?.internalServices?"":"/dist"}`,t);o&&as(`Failed to load service ${i}. Please check logs`),s&&t?.internalServices&&(s.info.internal=!0)}},launchServices:async e=>{if(as("Initializing services"),!os)throw new Error('IPC config not set, call "setHubIpcConfig" first.');for(const t in is){const n=is[t];e.noSpawningList&&e.noSpawningList.includes(n.info.name)?as(`Service ${n.info.name} is in the noSpawningList. Skipping.`):ls(n)}as("Services initialized")},setServiceStatus:(e,t)=>{const n=is[e];return n?(n.status=t,!0):(as(`Service with serviceId ${e} not found`),!1)},getActiveServices:ps,getMatchingService:(e,t)=>{const n=Object.values(is).filter((e=>"running"===e.status));for(const r of n)if(r.info.name===e){if(r.info.version===t)return r;if(u(r.info.version,t,">="))return r}return null},getServiceBySessionId:e=>is[e]||null,killAllServices:()=>{for(const e in is){const t=is[e];if(t.childProcess)try{as(`Killing service ${t.info.name} with PID ${t.childProcess.pid}`),t.childProcess.kill()}catch(e){as(`Error killing service ${t.info.name}: ${e}`)}}},addDevService:async(e,t,n)=>{const r={info:{...await ns(t,t.path),sessionId:e},status:n,startedAt:new Date,devMode:!0,childProcess:null};is[e]=r,ds(is[e].info)},setServiceManifest:(e,t,n)=>{const r=is[e];if(!r)return as(`Service with sessionId ${e} not found`),!1;const a=cs(t);if(a)return as(`Invalid manifest for service ${r.info.name}: ${a}`),!1;ds(t),r.info={...r.info,...t},n&&(r.status=n)},getMatchingDevService:(e,t,n)=>{const r=Object.values(is).filter((e=>e.devMode));for(const a of r)if(a.info.name===e&&a.status===n&&a.info.version===t)return a;return null},getInternalServices:()=>ps().filter((e=>e.internal)),getAllServices:()=>Object.values(is),stopService:gs,uninstallService:async(e,t)=>{as(`Uninstalling service ${e} v${t}`);const n=gs(e,t);if(!n)return!1;as(`Service ${e} stopped. Removing from disk...`);const r=ms(n),a=Xo;return r.startsWith(a)?(await I(r,{recursive:!0,force:!0}),as(`Service ${e} successfully removed from disk`),(e=>{const t=is[e];delete is[e]})(n.info.sessionId),!0):(as(`Service ${e} is not installed in the user services directory. Aborting.`),!1)},getAllServiceVersions:e=>Object.values(is).filter((t=>t.info.name===e)),setHubIpcConfig:e=>{os={...e}},loadAndLaunch:async(e,t,n)=>{const r=g(e,t),{error:a,service:i}=await us(r);if(a||!i)return{error:a};try{i.info.internal=!!n,i.childProcess=ss(i.info),i.status="started"}catch(e){as(`Error launching service ${i.info.name}: ${e}`),i.status="error",i.errorMsg="string"==typeof e?e:JSON.stringify(e)}return{service:i}},getServiceRootDirectory:ms};var fs={id:"widgets",retry:1500,silent:!0,rawBuffer:!0,appspace:"kemu.",encoding:"hex"};const ys=Object.values({protocolPrefix:4,protocolVersion:1,jsonLength:4,binaryLength:4,fromServiceId:4,toServiceId:4,sentAt:8}).reduce(((e,t)=>e+t),0);v.config={...v.config,...fs};const hs=Ho("ipcServer");let Is,Ss,$s,ws,bs={};const Ns=Xi(),As=e=>{bs[e]&&(hs(`Client disconnected [${e}]`),delete bs[e],Ss&&Ss(e))};var xs=e=>(e?.ipcId&&(v.config.id=e.ipcId),e?.ipcAppSpace&&(v.config.appspace=e.ipcAppSpace),new Promise((e=>{v.serve((()=>{hs("IPC Server Initiated"),v.server.on("data",((e,t)=>{const n=bs[t.id];n?(hs(`IPC Socket [${t.id}] data ${e.byteLength} bytes`),Ns(e,n.activeMessage,(e=>n.activeMessage=e),(e=>{if(!e.complete)return;const n=e=>{t.write(e)};if(e.command)return hs(`Received command from client [${t.id}]: ${e.command}`),void($s&&$s(t.id,e.command,n));e.klMessage&&ws&&ws({send:n,transmission:{sourceServiceId:e.sourceServiceId??-1,targetServiceId:e.targetServiceId??-1,rawMessage:e.rawMessage},json:e.klMessage.json})}))):hs(`Received data from unknown client [${t.id}]. Ignoring.`)})),v.server.on("connect",(e=>{const t=Ko();hs(`New client connected. Registered as "${t}"`),e.id=t,bs[t]={socket:e,activeMessage:null,disconnectHandler:()=>As(t)},e.on("close",bs[t].disconnectHandler),Is&&Is(t)})),v.server.on("disconnect",(e=>{As(e.id)})),v.server.on("error",(e=>{console.log(`IPC Server Error: ${e}`)})),e()})),v.server.start()}))),Cs=e=>{Is=e},Ps=e=>{Ss=e},Es=e=>ws=e,js=(e,t)=>{const n=bs[e];if(!n)return hs(`Cannot send message to unknown client [${e}]`),!1;if(t.length>=ys)return hs("Message is too long to be a command. Use sendMessage instead."),!1;const r=Ni.encodeCommand(t);return n.socket.write(r),!0},Ds=(e,t)=>{const n=bs[e];return!!n&&(delete bs[e],n.socket.id=t,bs[t]=n,n.socket.removeListener("close",n.disconnectHandler),n.disconnectHandler=()=>As(t),n.socket.on("close",n.disconnectHandler),!0)},ks=e=>{$s=e};const Os=Ho("websocketServer"),Ts={},Ls=Xi();let Ms,Bs,Rs,Ws,Us;var Fs=e=>{Us=new C({port:e,maxPayload:104857600}),Us.on("connection",(e=>{const t=Ko();Os(`New client connected. Registered as "${t}"`),e.id=t,Ts[t]={socket:e,activeMessage:null},Ms&&Ms(t),e.on("message",(t=>{if(t instanceof Buffer){const n=Ts[e.id];Ls(t,n.activeMessage,(e=>n.activeMessage=e),(t=>{if(!t.complete)return;const r=t=>{e.send(t),Os(`Writing ${t.byteLength} bytes to socket [${n.socket.id}]: ${t.toString()}`)};if(t.command)return Os(`Received command from client [${n.socket.id}]: ${t.command}`),void(Rs&&Rs(n.socket.id,t.command,r));t.klMessage&&Ws&&Ws({send:r,transmission:{sourceServiceId:t.sourceServiceId??-1,targetServiceId:t.targetServiceId??-1,rawMessage:t.rawMessage},json:t.klMessage.json})}))}})),e.on("close",(()=>{Os(`Client disconnected: ${e.id}`),Bs&&Bs(e.id),delete Ts[e.id]})),e.on("error",(()=>{Os(`Error on client connection: ${e.id}`)}))})),console.log(`WebSocket server is running on port ${e}`)},_s=e=>{Ms=e},Gs=e=>{Bs=e},zs=e=>{Rs=e},Vs=(e,t)=>{const n=Ts[e];if(!n)return Os(`Cannot send message to unknown client [${e}]`),!1;if(t.length>=ys)return Os("Message is too long to be a command. Use sendMessage instead."),!1;const r=Ni.encodeCommand(t);return n.socket.send(r),!0},Hs=e=>Ws=e;const Js=Ho("stopService"),qs=async e=>{const t=e.args[0];if(!t)return e.reply({error:"No service name provided"});const n=vs.getAllServiceVersions(t);Js(`Stopping ${n.length} services with name: ${t}`);for(const e of n)await vs.stopService(e.info.name,e.info.version);const r=n.map((e=>`${e.info.name}@${e.info.version}`));e.reply({success:[r]})},Ks=Ho("removeService"),Xs=async e=>{const t=e.args[0],n=e.args[1];if(!t)return e.reply({error:"No service name provided"});let r=vs.getAllServiceVersions(t);n&&(r=r.filter((e=>e.info.version===n))),Ks(`Removing ${r.length} service(s) with name: ${t}`);for(const e of r)await vs.uninstallService(e.info.name,e.info.version);const a=r.map((e=>`${e.info.name}@${e.info.version}`));e.reply({success:[a]})},Ys=Ho("launchService"),Zs=async e=>{const t=e.args[0],n=e.args[1];if(!t)return e.reply({error:"No service name provided"});if(!n)return e.reply({error:"No service version provided"});const r=`${t}@${n}/dist`;try{Ys(`Loading service ${t}@${n} from ${Xo}`);const{error:a,service:i}=await vs.loadAndLaunch(Xo,r,!1);if(a||!i)return e.reply({error:`Failed to launch service ${t}@${n}: ${a||"error-not-provided"}`});if("error"===i.status)return e.reply({error:`Error launching service: "${i.errorMsg||"unknown-error"}"`});const o=Date.now(),s=3e4,c=async()=>{const r=i.status;return"running"===r?(Ys(`Service ${t}@${n} loaded and started`),e.reply({success:[]})):(Ys(`Service ${t}@${n} not yet started, status: ${r}`),"stopped"===r||"error"===r?e.reply({error:`Error launching service: "${i.errorMsg||"failed to initiate"}"`}):Date.now()-o>s?e.reply({error:"Timeout waiting for service to start"}):(Ys("Retrying in 1 second..."),void setTimeout(c,1e3)))};c()}catch(r){return Ys(`Error loading service ${t}@${n}: ${r?.message||r}`),e.reply({error:r?.message||"There was an error loading the service"})}},Qs=Ho("getMatchingServices"),ec=async e=>{const t=e.args[0],n=[],r=[];Qs(`Checking for matching services: ${t.map((e=>e.name)).join(", ")}`);for(const{name:e,version:a}of t){const t=vs.getMatchingService(e,a);t?n.push({name:e,version:a,installationPath:vs.getServiceRootDirectory(t)}):r.push({name:e,version:a})}Qs(`Found ${n.length} available services and ${r.length} missing services.`),e.reply({success:[{available:n,missing:r}]})},tc=Ho("getServiceContents"),nc=({reply:e,args:t})=>{const[n]=t;tc(`Received GetServiceContents request for service ${n.serviceName} v${n.version}`);const r=vs.getMatchingService(n.serviceName,n.version);if(r){return e({success:[{serviceName:r.info.name,serviceVersion:r.info.version,uiContent:r.info.widgetUIContents,uiContentsChecksum:r.info.uiContentChecksum}]})}tc(`Service ${n.serviceName} v${n.version} not found`),e({error:`Service ${n.serviceName} v${n.version} not found`})},rc=Ho("activeClients");let ac={},ic={};const oc=(e,t)=>`${e}_${t}`,sc=e=>ac[e]||null,cc=(e,t)=>{const n=oc(e,t);return ic[n]||[]},uc=()=>{for(const e in ac){const t=ac[e];if(t.transport===ie.WS){const e=Ni.encodeCommand(ne.ServicesListChanged);t.send(e)}}},dc=(e,t,n,r,a)=>{const i=[];ac[e]={serviceSessionId:e,transport:t,isDevClient:!!a,broadcastSubscriptions:i,send:n,extraInfo:r,addSubscription:t=>{if(!i.some((e=>e.targetService.serviceName===t.serviceName&&e.targetService.version===t.version))){i.push({targetService:t});const r=oc(t.serviceName,t.version);ic[r]=ic[r]||[];return ic[r].some((t=>t.serviceId===e))||ic[r].push({sendFn:n,serviceId:e}),!0}return!1},removeSubscription:t=>{const n=i.findIndex((e=>e.targetService.serviceName===t.serviceName));if(-1!==n){i.splice(n,1);const r=oc(t.serviceName,t.version),a=ic[r]?.findIndex((t=>t.serviceId===e));if(-1!==a&&(ic[r].splice(a,1),!ic[r].length)){const e=vs.getMatchingService(t.serviceName,t.version);if(e?.info.eventEmitter&&"running"===e.status){const t=sc(e.info.sessionId);t?.extraInfo.ipcSocketId&&js(t?.extraInfo.ipcSocketId,ne.BroadcastEnd)}}}},removeAllSubscriptions:()=>{for(const t of i){const n=oc(t.targetService.serviceName,t.targetService.version),r=ic[n].findIndex((t=>t.serviceId===e));-1!==r&&ic[n].splice(r,1)}i.length=0}},t===ie.IPC&&(uc(),pc(e))},lc=()=>{const e=Object.values(ac);for(const t of e)if(t.transport===ie.IPC){const e=t.extraInfo.ipcSocketId,n=vs.getServiceBySessionId(t.serviceSessionId);if(n?.info.eventEmitter){cc(n.info.name,n.info.version).length||e&&js(e,ne.BroadcastEnd)}}},pc=e=>{const t=vs.getServiceBySessionId(e);if(t?.info.eventEmitter){if(cc(t.info.name,t.info.version).length){const t=sc(e);t?.extraInfo.ipcSocketId&&js(t?.extraInfo.ipcSocketId,ne.BroadcastStart)}}},gc=e=>{const t=ac[e];delete ac[e],t.transport===ie.IPC?uc():(t.removeAllSubscriptions(),lc())},mc=Ho("ipc:handleIpcClientCommand"),vc=(e,t,n)=>{!Vo(t,((t,r)=>{if(!t)return void mc(`Ignoring ACK response from IPC service ${e} with no service id`);mc(`Received ACK from IPC service ${t}. Marking as running.`);const a=vs.setServiceStatus(r||t,"running");r&&t&&e!==r&&Ds(e,r),a?dc(r||t,ie.IPC,n,{ipcSocketId:r}):js(e,ne.SendManifest)}))&&mc(`Received unknown command [${t}] from service ${e}`)},fc=Ho("nativeApi"),yc=e=>new Promise(((t,n)=>{j(e,((e,r,a)=>{const i=a.includes("User cancelled")||a.includes("User canceled");if(a&&!i)return n(a);t(r)}))})),hc={chooseDirectoryDialog:async e=>{const t=`\n var app = Application.currentApplication(); \n app.includeStandardAdditions = true; \n var chosenFolder = app.chooseFolder({ \n withPrompt: "${e.args[0].title||"Please select a directory"}" \n }); \n\n chosenFolder.toString();\n `;fc("Showing chooseDirectoryDialog");const n=await yc(`osascript -l JavaScript -e '${t.trim()}'`);return fc(`Chosen directory: ${n}`),e.reply({success:[String(n).trim()]})},chooseFileDialog:async e=>{const t=e.args[0],n=`\n var app = Application.currentApplication(); \n app.includeStandardAdditions = true; \n var chosenFile = app.chooseFile({ \n withPrompt: "${t.title||"Please select a file"}",\n multipleSelectionsAllowed: ${t.allowMultiple?"true":"false"},\n }); \n\n chosenFile.toString();\n `;fc("Showing chooseFileDialog");const r=await yc(`osascript -l JavaScript -e '${n.trim()}'`);return fc(`Chosen file: ${r}`),e.reply({success:[String(r).trim()]})}},Ic={chooseDirectoryDialog:async e=>{e.reply({error:"Not Supported"})},chooseFileDialog:async e=>{e.reply({error:"Not Supported"})}};let Sc;Sc="win32"===E.platform()?Ic:hc;var $c=Sc;const wc=Ho("getUniqueId"),bc=({reply:e,sourceServiceId:t})=>{wc(`Generating unique id for service "${t}"`);return e({success:[D()]})},Nc=m(P(import.meta.url)),Ac=Ho("hub"),xc=new Ti("hub");xc.setLogger(Ac);const Cc=(e,t)=>{const{transmission:n}=t;if(0!==n.targetServiceId){const r=sc(n.targetServiceId);if(!r)return Ac(`Service [${e}] ${n.sourceServiceId} is sending data to an unknown service ["${n.targetServiceId}"]`),!0;r.transport,ie.IPC;const a=t.json?.messageId;return Ac(`Forwarding message from ${n.sourceServiceId} to ${n.targetServiceId}, msgId: ${a}`),r.send(n.rawMessage,{sourceServiceId:n.sourceServiceId,targetServiceId:n.targetServiceId,msg:{json:t.json}}),!0}return!1},Pc=({sourceServiceId:e,args:t})=>{const n=vs.getServiceBySessionId(e);if(n){const r=cc(n.info.name,n.info.version),a=cc(n.info.name,"*");if(!r.length&&!a.length)return;const i=[...r,...a],o=t[0],s={outputs:o.outputs,variantId:o.variantId,source:{serviceName:n.info.name,serviceVersion:n.info.version,sessionId:e}};xc.broadcast(re.BroadcastEvent,[s],i,0)}},Ec=e=>{const{send:t,transmission:n,json:r}=e;Ac(`Raw message Id received from WS: ${r?.messageId}`);Cc(ie.WS,e)||xc.processMessage(ie.WS,t,n,r)},jc=e=>{const t=(n=e,`${ne.SocketAcknowledge}${n}`);var n;Vs(e,t)},Dc=(e,t,n)=>{!Vo(t,(t=>{if(Ac(`Received ACK from WS service ${t}. Marking as running.`),e!==t)throw new Error(`Received ACK from service ${t} but expected ${e}`);dc(t,ie.WS,n,{websocketId:e})}))&&Ac(`Received unknown command [${t}] from service ${e}`)},kc=e=>{Ac(`WS Client ${e} disconnected`),gc(e)},Oc=async({sourceServiceId:e,args:t,transport:n,send:r})=>{if(n!==ie.IPC){var a;Ac(`Received manifest from non IPC service ${e}.`)}else{const n=t[0];if(n.devMode){const t=vs.getMatchingDevService(n.name,n.version,"stopped");if(t){Ac(`Found matching previous service ${t.info.name} (${t.info.version}). Reactivating previous client with session id ${t.info.sessionId}`);const i=sc(t.info.sessionId);if(!i)return void Ac(`Could not find previous client instance for ${t.info.name} (${t.info.version}). Aborting manifest injection`);i.send=r,ac[a=e]?delete ac[a]:rc(`Could not find source client with session id ${a}`),Ds(e,t.info.sessionId);const o=await ns(n,n.path);t.info={...t.info,...o},Ac(`Updating manifest for dev service ${t.info.sessionId}`),vs.setServiceManifest(t.info.sessionId,o,"running"),Ac(`Asking service ${e} to assume previous session id ${t.info.sessionId}`),js(t.info.sessionId,(e=>`${ne.AssumeSession}${e}`)(t.info.sessionId)),(e=>{const t=ac[e];t?t.isDevClient?(t.disconnected=!1,t.transport===ie.IPC&&(uc(),pc(e))):rc(`Client with session id ${e} is not a dev client`):rc(`Could not find source client with session id ${e}`)})(t.info.sessionId)}else{vs.addDevService(e,n,"running");const t=sc(e);t?t.isDevClient=!0:dc(e,ie.IPC,r,{ipcSocketId:e},!0)}return}Ac(`Received manifest from non dev service ${e}. Ignoring...`)}};var Tc=async e=>{Ac("Starting Kemu Hub...");const t=e?.ipc?.appSpace||"kemu.",n=e?.ipc?.id||"widgets";xc.registerFunction(re.GetServiceContents,nc),xc.registerFunction(re.GetServices,(({transport:e,sourceServiceId:t,reply:n})=>{if(Ac(`Received GetServices request from ${e} [${t}]`),e===ie.WS){n({success:vs.getActiveServices().map((e=>{const{widgetUIContents:t,...n}=e;return{...n}}))})}})),xc.registerFunction(re.UnsubscribeFromService,(({transport:e,reply:t,args:n,sourceServiceId:r})=>{if(e===ie.WS){const[e]=n,a=sc(r);if(!a)return t({error:`Session id "${r}" not found`});Ac(`Service ${r} unsubscribing from "${e.targetService.serviceName} (${e.targetService.version})"`),t({success:[]}),a?.removeSubscription({serviceName:e.targetService.serviceName,version:e.targetService.version})}})),xc.registerFunction(re.SubscribeToService,(({transport:e,reply:t,args:n,sourceServiceId:r})=>{if(e===ie.WS){const[e]=n,a=sc(r),i=e.targetService;if(!a)return t({error:`Session id "${r}" not found`});if(Ac(`Service ${r} subscribing to "${i.serviceName} (${i.version})"`),"hub"===i.serviceName)return a.addSubscription(i),void t({success:[]});if(!a.addSubscription(i))return Ac(`Service ${r} already subscribed to "${i.serviceName} (${i.version})", ignoring request.`),t({success:[]});const o=vs.getMatchingService(i.serviceName,i.version);if(!o)return Ac(`Service ${i.serviceName} ${i.version} not active yet`),t({success:[]});if(!o.info.eventEmitter)return Ac(`Service ${i.serviceName} ${i.version} does not have an event emitter, removing subscription`),a.removeSubscription(i),t({error:`Service "${i.serviceName} (${i.version})" does not produce events`});const s=sc(o.info.sessionId);return s?.extraInfo.ipcSocketId&&(Ac(`Sending Broadcast START command to service ${o.info.sessionId}`),js(s?.extraInfo.ipcSocketId,ne.BroadcastStart)),t({success:[]})}})),xc.registerFunction(re.BroadcastEvent,Pc),xc.registerFunction(re.ServiceManifest,Oc),xc.registerFunction("stopService",qs),xc.registerFunction("removeService",Xs),xc.registerFunction("launchService",Zs),xc.registerFunction("getMatchingServices",ec),xc.registerFunction(re.ChooseDirectoryDialog,$c.chooseDirectoryDialog),xc.registerFunction(re.ChooseFileDialog,$c.chooseFileDialog),xc.registerFunction(re.GetUniqueId,bc),Es((e=>{const{send:t,transmission:n,json:r}=e;Ac(`Raw message Id received from IPC: ${r?.messageId}`);Cc(ie.IPC,e)||xc.processMessage(ie.IPC,t,n,r)})),Hs(Ec),_s(jc),zs(Dc),Gs(kc),ks(vc),Cs((e=>{const t=(n=e,`${ne.IpcAcknowledge}${n}`);var n;js(e,t)})),Ps((e=>{Ac(`IPC socket [${e}] disconnected`);const t=sc(e);if(t){Ac(`Found matching service for disconnected socket. SessionId: ${t.serviceSessionId}`);const e=vs.getServiceBySessionId(t.serviceSessionId);vs.setServiceStatus(t.serviceSessionId,"stopped"),e?.devMode?(t.disconnected=!0,uc()):gc(t.serviceSessionId)}})),await xs({ipcAppSpace:t,ipcId:n}),e?.ws?.disabled||await Fs(e?.ws?.port||8080);const r=l.resolve(Nc,"defaultServices"),a=process.env.DEV_SESSION_ID;vs.setHubIpcConfig({recipePath:e?.recipeRootPath,appSpace:t,id:n}),e?.noDefaultServices||await vs.loadServices(r,{fixedSession:a?parseInt(a):void 0,singleServiceName:process.env.DEV_SINGLE_SERVICE_NAME,internalServices:!0}),await rs(Xo)||await S(Xo,{recursive:!0}),null!==e?.servicesInstallPath&&await vs.loadServices(e?.servicesInstallPath||Xo,{internalServices:!1,singleServiceName:process.env.DEV_SINGLE_SERVICE_NAME});const i=process.env.DEV_NO_SPAWN_LIST?.split(",");await vs.launchServices({noSpawningList:i||[]}),Ac("Kemu Hub started")},Lc=e=>{if(e===ie.WS)return{handleWebsocketConnectionEvent:jc,handleWebsocketClientDisconnectionEvent:kc,handleWebsocketMessage:Ec,handleWebsocketClientCommand:Dc,getRemoteInvoke:()=>xc}},Mc=(e=[])=>{let t;const n=new Promise((n=>{const r=()=>{if(vs.getAllServices().every((e=>"running"===e.status))){if(e.every((e=>"running"===vs.getMatchingService(e.name,e.version)?.status)))return n()}t=setTimeout(r,100)};r()}));return n.abort=()=>{t&&clearTimeout(t)},n};let Bc;const Rc=Yi("run"),Wc=Fo(),Uc=1e3,Fc=$(process.argv.slice(2));global.ImageData=L,At({createCanvas:(e,t)=>B(e,t)});const _c={createImageDataLike:(e,t,n,r="srgb")=>{let a;return a=e instanceof Uint8ClampedArray?e:new Uint8ClampedArray(e),{data:a,width:t,height:n,colorSpace:r,_kemuType:Q.ImageData}},loadImageFile:async e=>{const t=await M(e),n=B(t.width,t.height).getContext("2d");n.drawImage(t,0,0,t.width,t.height);return n.getImageData(0,0,t.width,t.height)}};var Gc={start:async n=>{const r=n?.recipePath||Fc.recipePath||process.env.KEMU_EDGE_RECIPE_PATH;if(!r)throw new Error("`recipePath` not provided. Please specify it in the config object, via a command line argument [--recipePath] or as an environment variable [KEMU_EDGE_RECIPE_PATH].");const a=r.endsWith(".json"),i=a?k(r):r,o=a?r:O(i,"recipe.json"),s=(e=>{try{return JSON.parse(e||"")}catch(e){return null}})(await e(T(o),"utf-8"));if(!s)throw new Error("Failed to parse recipe file");await Ea();const c={id:s.id||String(Date.now()),version:1,author:""};(e=>{or=e})(console);const u=Lc(ie.WS),d=(e,t)=>{if(t)u?.handleWebsocketMessage({send:p,transmission:{rawMessage:e,sourceServiceId:t.sourceServiceId,targetServiceId:t.targetServiceId},json:t.msg?.json});else{const t=e instanceof Buffer?e.toString():e;u?.handleWebsocketClientCommand(Uc,t,p)}},l=(Li={instanceServiceId:Uc,sendBuf:d,sendCmd:d,triggerOnCommand:(...e)=>Mi(...e),triggerOnConnected:()=>Bi(),triggerOnDisconnected:()=>Ri(),triggerOnMessageReceived:(...e)=>Wi(...e)},Li);const p=(e,t)=>{if(t)l.triggerOnMessageReceived({send:d,transmission:{rawMessage:e,sourceServiceId:t.sourceServiceId,targetServiceId:t.targetServiceId},json:t.msg.json});else{const t=e instanceof Buffer?e.toString():e;l.triggerOnCommand(t)}},g=Go(),m=u.getRemoteInvoke();g.disableServiceEncoding(0,!0),m.disableServiceEncoding(Uc,!0);const v=Object.values(s.blocks[Y].gates).filter((e=>e.type===Ce.hubService&&e.state.service&&!0!==e.state.service?.webOnly)),f=v.map((e=>{const t=e.state.service;return{name:t.name,version:t.version}})),y=O(i,"services"),h=await t(y).then((()=>!0)).catch((()=>!1));await Tc({recipeRootPath:i,servicesInstallPath:h?O(i,"services"):null,noDefaultServices:!0,ws:{disabled:!0},ipc:{appSpace:"kemu-runner.",id:c.id}}),Rc("Waiting for services to run"),await Mc(f),Rc("All services are running"),oi(Wc);const I=await ri(s,"runner",c.version,c.author,$n.Desktop);return Bc=I,_o(I),await Wo(),new Promise(((e,t)=>{var n;Uo("acknowledged",(async()=>{await Wc.getServices();const{failed:n,sendToInputWidget:r}=await ii(I);if(n.length>0){const e=`Some widgets failed to initialize: ${n.join(", ")}`;return t(e)}Rc("Recipe started"),e({sendToInputWidget:r})})),l.triggerOnConnected(),l.triggerOnCommand((n=Uc,`${ne.SocketAcknowledge}${n}`))}))},terminate:async()=>{Bc&&await ai(Bc)}};void 0===typeof process.env.BLOCKS_INSTALL_DIR&&console.warn("Missing `BLOCKS_INSTALL_DIR` env var");process.env.BLOCKS_INSTALL_DIR;export{Q as DataType,Gc as default,_c as utils};
|
|
1
|
+
import{readFile as e,access as t}from"node:fs/promises";import{nanoid as n}from"nanoid";import r from"jsonp";import a from"crypto-js";import i from"util";import o from"emittery";import"axios";import s from"jszip";import{satisfies as c,compare as u}from"compare-versions";import d from"debug";import l,{join as p,resolve as g,dirname as m}from"path";import v from"node-ipc";import{readFile as f,access as y,constants as h,rm as I,mkdir as S}from"fs/promises";import $ from"minimist";import w,{promises as b}from"fs";import{spawn as N}from"child_process";import{createHash as A}from"crypto";import{homedir as x}from"os";import{WebSocketServer as C}from"ws";import{fileURLToPath as P}from"url";import E from"node:os";import{exec as j}from"node:child_process";import{createId as D}from"@paralleldrive/cuid2";import{dirname as k,join as O,resolve as T}from"node:path";import{ImageData as L,loadImage as M,createCanvas as B}from"@napi-rs/canvas";var R;!function(e){e.STARTING="STARTING",e.PENDING="PENDING",e.RUNNING="RUNNING",e.PAUSED="PAUSED",e.DRAINING="DRAINING",e.STOPPED="STOPPED",e.ERROR="ERROR"}(R=R||(R={}));const W={};let U=0,F="";const _=e=>W[e]?W[e]:null,G=(e,t)=>{const n=_(e);if(!n)return n;return n.blocks[t]||null},z=(e,t,n)=>{const r=G(e,t);if(!r)return r;return r.gates[n]},V=(e,t)=>{let r=n(4);for(;W[r];)r=n(4);const a=(i=e,JSON.parse(JSON.stringify(i)));var i;return a.logs="",a.addLog=e=>{a.logs+=`${(()=>{const e=Date.now();if(e!==U){const t=new Date;U=e,F=t.toJSON()}return F})()}:: ${e}\n`},a.dbInfo={...t},W[r]=a,r},H="interrupt_port",J="main.js",q="state.json",K="{#}",X="$var_",Y="default";var Z,Q,ee,te,ne,re,ae,ie;!function(e){e.Browser="browser",e.Cloud="cloud",e.Desktop="desktop"}(Z||(Z={})),function(e){e[e.Number=0]="Number",e[e.String=1]="String",e[e.ArrayBuffer=2]="ArrayBuffer",e[e.Array=3]="Array",e[e.Boolean=4]="Boolean",e[e.JsonObj=5]="JsonObj",e[e.Anything=6]="Anything",e[e.ImageData=7]="ImageData",e[e.AudioBuffer=8]="AudioBuffer",e[e.Rect=9]="Rect",e[e.Point=10]="Point",e[e.ImageBitmap=11]="ImageBitmap",e[e.BinaryFile=12]="BinaryFile"}(Q||(Q={})),function(e){e.Number="Number",e.String="String",e.ArrayBuffer="ArrayBuffer",e.Array="Array",e.Boolean="Boolean",e.JsonObj="JsonObj",e.Anything="Anything",e.ImageData="ImageData",e.AudioBuffer="AudioBuffer",e.Rect="Rect",e.Point="Point",e.ImageBitmap="ImageBitmap",e.BinaryFile="BinaryFile"}(ee||(ee={})),function(e){e.Javascript="js",e.Python="py",e.Executable="exe"}(te||(te={})),function(e){e.IpcAcknowledge="iack:",e.SocketAcknowledge="sack:",e.AcknowledgeResponse="ackr:",e.ServicesListChanged="update-services",e.SendManifest="send-manifest",e.BroadcastStart="broadcast-start",e.BroadcastEnd="broadcast-end",e.AssumeSession="assume:"}(ne||(ne={})),function(e){e.GetServices="getServices",e.SubscribeToService="subscribeToService",e.UnsubscribeFromService="unsubscribeFromService",e.GetServiceContents="getServiceContents",e.OnParentEvent="onParentEvent",e.GetDefaultState="getDefaultState",e.BroadcastEvent="broadcastEvent",e.HubBroadcastEvent="hubBroadcastEvent",e.ServiceManifest="serviceManifest",e.GetState="getState",e.SetState="setState",e.SetOutputs="setOutputs",e.UIEvent="uiEvent",e.InitializeInstance="initializeInstance",e.TerminateInstance="terminateInstance",e.ChooseDirectoryDialog="chooseDirectoryDialog",e.ChooseFileDialog="chooseFileDialog",e.GetUniqueId="getUniqueId"}(re||(re={})),function(e){e.SetDependencyPath="setDependencyPath",e.GetDependencyPath="getDependencyPath"}(ae||(ae={})),function(e){e.IPC="ipc",e.WS="ws"}(ie||(ie={}));const oe="undefined"!=typeof window&&void 0!==window.document&&void 0!==typeof window.document.createElement,se="object"==typeof self&&self.constructor&&"DedicatedWorkerGlobalScope"===self.constructor.name,ce="undefined"!=typeof process&&null!=process.versions&&null!=process.versions.node,ue="-",de=`inner${ue}`,le=`outer${ue}`,pe=`${le}input${ue}`,ge=`${le}output${ue}`,me=`${de}input${ue}`,ve=`${de}output${ue}`,fe=e=>(new TextEncoder).encode(e),ye=e=>e===H,he=e=>e&&void 0!==e.width&&void 0!==e.height&&void 0!==e.data&&e.data.constructor&&"Uint8ClampedArray"===e.data.constructor.name,Ie=e=>e&&void 0!==e.width&&void 0!==e.height&&void 0!==e.top&&void 0!==e.left&&"number"==typeof e.width&&"number"==typeof e.height&&"number"==typeof e.top&&"number"==typeof e.left,Se=e=>e&&"number"==typeof e.x&&"number"==typeof e.y,$e=e=>"number"==typeof e?Q.Number:"string"==typeof e?Q.String:"boolean"==typeof e?Q.Boolean:Array.isArray(e)?Q.Array:he(e)?Q.ImageData:e&&void 0!==e.duration&&void 0!==e.length&&void 0!==e.numberOfChannels&&void 0!==e.sampleRate&&"function"==typeof e.getChannelData&&"AudioBuffer"===e.constructor.name?Q.AudioBuffer:e&&void 0!==e.byteLength?Q.ArrayBuffer:Ie(e)?Q.Rect:e&&void 0!==e.x&&void 0!==e.y&&"number"==typeof e.x&&"number"==typeof e.y?Q.Point:Q.JsonObj,we=e=>{const t={};let n;n=Array.isArray(e)?e[0]:e;for(const e in n){const r=$e(n[e]);t[e]=r}return t},be=(e,t,n)=>"inner"===e?"input"===t?`${me}${n}`:`${ve}${n}`:"input"===t?`${pe}${n}`:`${ge}${n}`,Ne=e=>{const t=(e||"")?.split("_");if(t.length<3)throw new Error(`Unknown child identifier format [${e}]`);const n=t[0];return{portType:t[1],widgetId:n,portName:t[2]}},Ae=e=>new ImageData(e.data,e.width,e.height,{colorSpace:e.colorSpace});var xe,Ce;!function(e){e.Action="action",e.CustomInput="customInput"}(xe=xe||(xe={})),function(e){e.input="input",e.counter="counter",e.play="play",e.elapsed="elapsed",e.ifGate="ifGate",e.skipEvent="skipEvent",e.between="between",e.map="map",e.parser="parser",e.slider="slider",e.suspend="suspend",e.display="display",e.json="json",e.arrayItem="arrayItem",e.extractImage="extractImage",e.imageConvolution="imageConvolution",e.firstEvent="firstEvent",e.pixelDraw="pixelDraw",e.randomBetween="randomBetween",e.arrayCombine="arrayCombine",e.clock="clock",e.multiplication="multiplication",e.object="object",e.widgetGroup="widgetGroup",e.script="script",e.base64ToImageData="base64ToImageData",e.jsonParse="jsonParse",e.text="text",e.imageCrop="imageCrop",e.imageResize="imageResize",e.value="value",e.imageWarp="imageWarp",e.widgetBundle="widgetBundle",e.sequence="sequence",e.variable="variable",e.hubService="hubService",e.imageFilter="imageFilter"}(Ce=Ce||(Ce={}));const Pe={};let Ee;const je=async e=>{const t=Pe[e],n={name:H,type:Q.Boolean};if(t){const r={name:t.portName},a=t.data||{type:Q.Boolean,value:!0};Ee?(await Ee(!0,t.targetWidgetId,t.thingId,t.recipePoolId,n.name,r,{...a,timestamp:Date.now()},[n]),"timeout"===t.type&&De(e)):console.warn("Interrupt service has not been initialized")}},De=e=>{const t=Pe[e];return!!t&&(t.timerRef&&("interval"===t.type?clearInterval(t.timerRef):"timeout"===t.type&&clearTimeout(t.timerRef)),delete Pe[e],!0)};var ke={interruptHandler:je,createInterrupt:(e,t,r,a,i,o,s,c)=>{if(c&&Pe[c])throw new Error("The given interrupt id already exists");const u=c||n().replace(/_/g,"-");if("interval"===e&&!o.interval)throw new Error(`Invalid interval. Expected a number greater than 0, but got '${o.interval}'`);if("timeout"===e&&!o.timeout)throw new Error(`Invalid timeout. Expected a number greater than 0, but got '${o.timeout}'`);if(Pe[u]={data:s,portName:i,recipePoolId:t,targetWidgetId:a,thingId:r,type:e},"interval"===e)Pe[u].timerRef=setInterval((async()=>await je(u)),o.interval);else{if("timeout"!==e)throw new Error(`Invalid interrupt type '${e}'`);Pe[u].timerRef=setTimeout((async()=>await je(u)),o.timeout)}return u},destroyInterrupt:De,destroyAllInterrupts:()=>{Object.keys(Pe).forEach(De)},setInvokeChildGateCb:e=>{Ee=e}};const Oe=(e,t,n,r,a)=>{const i=z(e,n,r);if(!i)return console.warn(`Gate ${r} not found in block ${n} for recipe ${e}`),null;const o=(t,a,i,o)=>ke.createInterrupt(t,e,n,r,a,i,o),s=()=>Object.freeze({...i.state,...i.type===Ce.input&&{customInputs:[]}}),c=e=>{if("object"!=typeof e)return void console.warn(`Invalid state type [${typeof e}]. Expected an 'object'`);const t={...e,...i.type===Ce.input&&!e.customInputs&&{customInputs:[]}};i.state=t};if(a){return{getState:s,setState:c,registerInterrupt:o,getStorageData:async t=>{const r=((e,t,n)=>{const r=_(e);if(!r)throw new Error(`Recipe [${e} does not exist]`);if(!r.storage)return null;const a=G(e,t);if(!a)throw new Error(`The Thing "${t}" does not exist in recipe ${e}`);if(!(a.storageUnits||[]).includes(n))throw new Error(`The Thing "${t}" has no access to storage unit "${n}"`);return r.storage[n]||null})(e,n,t);return r},recipePoolId:e,recipeType:t,thingRecipeId:n,widgetThingId:r}}return{getState:s,setState:c,recipePoolId:e,widgetId:r}},Te=[10001,"Invalid `sourcePort` parameter"],Le=[10002,"The gate [%s] does not exist. Have you called `loadWidgets` yet?"],Me=[10110,"No storage medium has been loaded, call `loadMedium()` first"],Be=(e,...t)=>JSON.stringify({code:e[0],message:t[0]?i.format(e[1],...t):e[1].replace(/ \[%s\]/g,"")}),Re=()=>({inputName:"",dataType:Q.Anything}),We="output",Ue={processEvent:async(e,t)=>{const n=t.getState(),r={...Re(),...n};if(e.type===r.dataType||r.dataType===Q.Anything)return t.nextWidget(We,{type:e.type,value:e.value});console.error(`Invalid data type: ${e.type} for input: ${r.inputName}. Expected: ${r.dataType}`)},getOutputNames:e=>{const t={...Re(),...e};return[{name:We,type:t.dataType}]},getInputNames:()=>[]},Fe=Object.freeze({in:"in",reset:"reset",increment:"increment"}),_e="output";var Ge={onParentEvent:async(e,t,n,r)=>{if(!e)throw new Error(Be(Te));const a={currentValue:0,increment:1,...r.getState()};let i=a.increment,o=a.currentValue;const s=await r.getParentAtPort(Fe.increment);if(t.name===Fe.increment)return void(n.data.type===Q.Number&&r.setState({...a,increment:Number(n.data.value)}));if(s){const e=s.getValue();null!==e&&(i=e)}if(t.name===Fe.reset)return r.setState({...a,currentValue:0});o+=i,r.setState({currentValue:o,increment:i});const c={type:Q.Number,value:o};return r.nextGate(_e,c)},getInputNames:()=>[{name:Fe.in,type:Q.Anything},{name:Fe.reset,type:Q.Anything},{name:Fe.increment,type:Q.Number}],getOutputNames:()=>[{name:_e,type:Q.Number}]};const ze=Object.freeze({in:"in",reset:"reset"}),Ve="output";var He={onParentEvent:async(e,t,n,r)=>{const a={updatedAt:0,elapsed:0,...r.getState()},i=Date.now(),o=i-(a.updatedAt||i);return t.name===ze.reset?r.setState({...a,updatedAt:i,elapsed:0}):(r.setState({updatedAt:i,elapsed:o}),r.nextGate(Ve,{type:Q.Number,value:o}))},getInputNames:()=>[{name:ze.in,type:Q.Anything},{name:ze.reset,type:Q.Anything}],getOutputNames:()=>[{name:Ve,type:Q.Number}]};const Je=Object.freeze({data:"data",evaluation:"evaluation"}),qe="then",Ke="else";var Xe={onParentEvent:async(e,t,n,r)=>{const a={value:5,condition:"Equal",useDataPort:!1,...r.getState()},i=n.data.value,o=!isNaN(Number(i)),s="string"==typeof i;if(!a.useDataPort&&(n.data.type===Q.Number||n.data.type===Q.String||n.data.type===Q.Anything&&o||n.data.type===Q.Anything&&s)){let e=!1;return("Equal"===a.condition&&n.data.value==a.value||"Not Equal"===a.condition&&n.data.value!==a.value||"Greater"===a.condition&&n.data.value>Number(a.value)||"Less"===a.condition&&n.data.value<Number(a.value)||"Starts With"===a.condition&&String(n.data.value).startsWith(String(a.value))||"Ends With"===a.condition&&String(n.data.value).endsWith(String(a.value))||"Includes"===a.condition&&String(n.data.value).includes(String(a.value))||"Matches"===a.condition&&String(n.data.value).match(String(a.value)))&&(e=!0),e?r.nextGate(qe,n.data):r.nextGate(Ke,n.data)}if((t.name===Je.evaluation&&n.data.type===Q.Number||n.data.type===Q.String||n.data.type===Q.Anything&&(o||s))&&(a.$lastValue=n.data.value,r.setState({...a})),t.name===Je.data){let e=!1;return("Equal"===a.condition&&a.$lastValue==a.value||"Not Equal"===a.condition&&a.$lastValue!==a.value||"Greater"===a.condition&&Number(a.$lastValue)>Number(a.value)||"Less"===a.condition&&Number(a.$lastValue)<Number(a.value)||"Starts With"===a.condition&&String(a.$lastValue).startsWith(String(a.value))||"Ends With"===a.condition&&String(a.$lastValue).endsWith(String(a.value))||"Includes"===a.condition&&String(a.$lastValue).includes(String(a.value))||"Matches"===a.condition&&String(a.$lastValue).match(String(a.value)))&&(e=!0),r.setState({...a,$lastValue:void 0,$lastDataType:n.data.type}),e?r.nextGate(qe,n.data):r.nextGate(Ke,n.data)}},getInputNames:e=>e.useDataPort?[{name:Je.data,type:Q.Anything},{name:Je.evaluation,type:[Q.Number,Q.String]}]:[{name:"in",type:[Q.Number,Q.String]}],getOutputNames:e=>e.$lastDataType?[{name:qe,type:e.$lastDataType},{name:Ke,type:e.$lastDataType}]:[{name:qe,type:[Q.Number,Q.String]},{name:Ke,type:[Q.Number,Q.String]}]};const Ye=Object.freeze({in:"in",reset:"reset"}),Ze="out";var Qe={onParentEvent:async(e,t,n,r)=>{const a={totalCalls:0,callsLimit:1,...r.getState()};return t.name===Ye.reset?r.setState({...a,totalCalls:0}):(a.totalCalls=a.totalCalls+1,a.totalCalls>a.callsLimit?(a.totalCalls=0,r.setState(a),r.nextGate(Ze,n.data)):void r.setState(a))},getInputNames:()=>[{name:Ye.in,type:Q.Anything},{name:Ye.reset,type:Q.Anything}],getOutputNames:()=>[{name:Ze,type:Q.Anything}]};const et=Object.freeze({in:"in"}),tt="then",nt="else";var rt={onParentEvent:async(e,t,n,r)=>{const a={min:1,max:10,...r.getState()};if(n.data.type===Q.Number)return n.data.value>=a.min&&n.data.value<=a.max?r.nextGate(tt,n.data):r.nextGate(nt,n.data)},getInputNames:()=>[{name:et.in,type:Q.Number}],getOutputNames:()=>[{name:tt,type:Q.Number},{name:nt,type:Q.Number}]};const at=Object.freeze({in:"in"}),it="out";var ot={onParentEvent:async(e,t,n,r)=>{const a={clamp:!0,...r.getState()},i=Number(n.data.value);if(void 0!==a.fromMax&&void 0!==a.fromMin&&void 0!==a.toMax&&void 0!==a.toMin&&""!==a.fromMax&&""!==a.fromMin&&""!==a.toMax&&""!==a.toMin&&(n.data.type===Q.Number||n.data.type===Q.Anything&&!isNaN(Number(i)))){let e=((e,t,n,r,a)=>(e-t)*(a-r)/(n-t)+r)(i,Number(a.fromMin),Number(a.fromMax),Number(a.toMin),Number(a.toMax));if(isNaN(e))return;return a.clamp&&(e<Number(a.toMin)&&(e=Number(a.toMin)),e>Number(a.toMax)&&(e=Number(a.toMax))),r.nextGate(it,{type:Q.Number,value:Number(e)})}},getInputNames:()=>[{name:at.in,type:Q.Number}],getOutputNames:()=>[{name:it,type:Q.Number}]};const st=Object.freeze({in:"in"}),ct="out";var ut={onParentEvent:async(e,t,n,r)=>{const a={convertTo:"Integer",floatPlaces:2,...r.getState()};let i=n.data.value;if(n.data.type===Q.Number||n.data.type===Q.Anything||n.data.type===Q.String){if((!isNaN(Number(i))||"string"==typeof i)&&!Array.isArray(i))return"Integer"===a.convertTo?i=parseInt(i):"Decimal"===a.convertTo?i=parseFloat(Number(i).toFixed(a.floatPlaces)):"String"===a.convertTo?i=String(i):"Abs"===a.convertTo?i=Math.abs(Number(i)):"Round"===a.convertTo&&(i=Math.round(Number(i))),r.nextGate(ct,{type:"String"===a.convertTo?Q.String:Q.Number,value:i})}},getInputNames:()=>[{name:st.in,type:Q.Number}],getOutputNames:e=>{const t="String"===e?.convertTo?Q.String:Q.Number;return[{name:ct,type:t}]}};const dt=Object.freeze({in:"in"}),lt="out";var pt={onParentEvent:async(e,t,n,r)=>{const a={currentValue:50,min:0,max:100,...r.getState()};let i=!1;return a.currentValue<a.min&&(a.currentValue=a.min,i=!0),a.currentValue>a.max&&(a.currentValue=a.max,i=!0),i&&r.setState(a),r.nextGate(lt,{type:Q.Number,value:a.currentValue})},getInputNames:()=>[{name:dt.in,type:Q.Anything}],getOutputNames:()=>[{name:lt,type:Q.Number}]};const gt=Object.freeze({in:"in",reset:"reset"}),mt="out";var vt={onParentEvent:async(e,t,n,r)=>{const a={lastCalledAt:0,delayMs:500},i={lastCalledAt:0,delayMs:500,...r.getState()};if(t.name===gt.reset)return r.setState({...i,lastCalledAt:0});const o=Date.now(),s=o-i.lastCalledAt;return i.lastCalledAt===a.lastCalledAt||s>=i.delayMs&&i.delayMs>0?(i.lastCalledAt=o,r.setState(i),r.nextGate(mt,n.data)):void 0},getInputNames:()=>[{name:gt.in,type:Q.Anything},{name:gt.reset,type:Q.Anything}],getOutputNames:()=>[{name:mt,type:Q.Anything}]};const ft="in";var yt={onParentEvent:async()=>{},getInputNames:()=>[{name:ft,type:[Q.ImageData,Q.Number]}],getOutputNames:()=>[]};const ht=()=>({properties:[{label:"property1",name:"property1"}],detectedProperties:{}}),It=(e,t)=>t.split(".").reduce(((e,t)=>null!=e?e[t]:e),e);var St={onParentEvent:async(e,t,n,r)=>{const a={properties:[{label:"property1",name:"property1"}],detectedProperties:{},...r.getState()},i=n?.data?.value,o=Array.isArray(i);if(n.data.type===Q.JsonObj||n.data.type===Q.Rect||n.data.type===Q.Anything||o){let e=!1;for(const t in i){const n=$e(i[t]),r=!!a.detectedProperties[t],o=a.detectedProperties[t]?.type!==n;if(!r||o){const r=n===Q.JsonObj||n===Q.Rect||n===Q.Array;a.detectedProperties[t]={type:n,...r?{shape:we(i[t])}:void 0},e=!0}}if(o&&void 0===a.detectedProperties.length&&(a.detectedProperties.length={type:Q.Number}),e&&r.setState(a),i){const e=[];for(const t of a.properties||[]){const n=It(i,t.label),o=t.label.includes(".");if(void 0!==n){const i=o?$e(n):void 0!==a.detectedProperties[t.label]?.type?a.detectedProperties[t.label].type:Q.Anything;e.push(r.nextGate(t.name,{type:i,value:n}))}}await Promise.allSettled(e)}}},getInputNames:()=>[{name:"in",type:Q.JsonObj}],getOutputNames:e=>{const t={properties:[{label:"property1",name:"property1"}],detectedProperties:{},...e};return t.properties.map((e=>{const n=void 0!==t.detectedProperties[e.label]?t.detectedProperties[e.label]?.type:Q.Anything,r=t.detectedProperties[e.label]?.shape||void 0,a="string"==typeof e;return{name:a?e:e.name,label:a?e:e.label,type:n,jsonShape:r}}))},getDefaultState:ht};const $t="output",wt="noItem";var bt={onParentEvent:async(e,t,n,r)=>{const a={index:0,...r.getState()};let i=a.index;const o=n.data.value,s="string"==typeof n.data.value,c=Array.isArray(n.data.value);if(n.data.type===Q.Anything&&(c||s)||n.data.type===Q.String&&s||n.data.type===Q.Array&&c){i<0&&(i=o.length+i);const e=s?Q.String:$e(o[i]);return e!==a.$$lastDetectedType&&r.setState({...a,$$lastDetectedType:e}),void 0!==o[i]?r.nextGate($t,{value:o[i],type:e}):r.nextGate(wt,{value:!0,type:Q.Boolean})}},getInputNames:()=>[{name:"in",type:[Q.Array,Q.String]}],getOutputNames:e=>[{name:$t,type:e.$$lastDetectedType??Q.Anything},{name:wt,type:Q.Boolean}]};let Nt;const At=e=>{Nt=e},xt=(e,t)=>(()=>{if(!Nt)throw new Error("CanvasManager not set");return Nt})().createCanvas(e,t),Ct=e=>oe?e.getContext("2d",{willReadFrequently:!0}):e.getContext("2d"),Pt=Object.freeze({image:"image",rect:"rect"}),Et="image";var jt={onParentEvent:async(e,t,n,r)=>{const a={offset:{height:0,left:0,top:0,width:0},...r.getState()},i=await r.getParentAtPort(Pt.rect),o=[Q.Anything,Q.Rect,Q.JsonObj];if(t.name!==Pt.rect){if(i){const e=i.getValue();null!==e&&(a.rect={...e},r.setState(a))}if(!oe)return n.data.type===Q.ImageData?r.nextGate(Et,n.data):void 0;if(a.$$canvasFrom&&a.$$canvasFrom.getContext||(a.$$canvasFrom=xt(320,240)),a.$$canvasTo&&a.$$canvasTo.getContext||(a.$$canvasTo=xt(320,240)),(n.data.type===Q.ImageData||n.data.type===Q.Anything&&he(n.data.value))&&!a.$$processing&&a.$$canvasFrom&&a.rect){const e=((e,t,n,r,a)=>{if(r&&r.getContext){const i=r.getContext("2d"),o=n.getContext("2d");if(i&&o){n.width=e.width,n.height=e.height,o.putImageData(e,0,0);const s={...a};a&&(s.height=Number(a.height),s.width=Number(a.width),s.left=Number(a.left),s.top=Number(a.top));const c={top:0,width:0,left:0,height:0,...s};return a&&(Number.isInteger(c.width)||(c.width=t.width*c.width),Number.isInteger(c.height)||(c.height=t.height*c.height),Number.isInteger(c.left)||(c.left=t.left+t.width*c.left),Number.isInteger(c.top)||(c.top=t.top+t.height*c.top)),r.width=t.width+c.width,r.height=t.height+c.height,i.drawImage(n,t.left+c.left,t.top+c.top,t.width+c.width,t.height+c.height,0,0,r.width+c.width,r.height+c.height),i.getImageData(0,0,r.width||1,r.height||1)}}return e})(n.data.value,a.rect,a.$$canvasFrom,a.$$canvasTo,a.offset);return r.nextGate(Et,{type:Q.ImageData,value:e})}}else Ie(n.data.value)&&o.includes(n.data.type)&&r.setState({...a,rect:n.data.value})},getInputNames:()=>[{name:Pt.image,type:Q.ImageData},{name:Pt.rect,type:[Q.Rect,Q.JsonObj]}],getOutputNames:()=>[{name:Et,type:Q.ImageData}]};const Dt=(e,t)=>{const n=Math.round(Math.sqrt(t.length)),r=Math.floor(n/2),a=e.data,i=e.width,o=e.height,s=i,c=o,u=((e,t,n)=>{if(oe)return new ImageData(t,n);return console.warn("Node environment detected. Aborting new ImageData creation"),e})(e,s,c),d=u.data;for(let e=0;e<c;e++)for(let c=0;c<s;c++){const u=e,l=c,p=4*(e*s+c);let g=0,m=0,v=0,f=0;for(let e=0;e<n;e++)for(let s=0;s<n;s++){const c=u+e-r,d=l+s-r;if(c>=0&&c<o&&d>=0&&d<i){const r=4*(c*i+d),o=t[e*n+s];g+=a[r]*o,m+=a[r+1]*o,v+=a[r+2]*o,f+=a[r+3]*o}}d[p]=g,d[p+1]=m,d[p+2]=v,d[p+3]=f+1*(255-f)}return u},kt=[-1,0,1,-2,0,2,1,0,1],Ot=Object.freeze({image:"image"}),Tt="image";var Lt={onParentEvent:async(e,t,n,r)=>{const a=r.getState(),i={matrix:[...kt],...a};if(n.data.type===Q.ImageData||n.data.type===Q.Anything&&he(n.data.value)){const e=Dt(n.data.value,i.matrix);return r.nextGate(Tt,{type:Q.ImageData,value:e})}},getInputNames:()=>[{name:Ot.image,type:Q.ImageData}],getOutputNames:()=>[{name:Tt,type:Q.ImageData}]};const Mt=Object.freeze({output:"output",aborted:"aborted"}),Bt=()=>({inputs:2,matchingOutputs:!0,lastInputIndex:-1,delayMs:500,triggeredAt:0}),Rt=e=>{const t={inputs:2,matchingOutputs:!0,lastInputIndex:-1,delayMs:500,triggeredAt:0,...e},n=Array(t.inputs).fill(0).map(((e,t)=>({name:`input${t+1}`,type:Q.Anything})));return n.push({name:"reset",type:Q.Anything}),n};var Wt={onParentEvent:async(e,t,n,r)=>{const a={inputs:2,matchingOutputs:!0,lastInputIndex:-1,delayMs:500,triggeredAt:0,...r.getState()};if("reset"===t.name)return r.setState({...a,triggeredAt:0});const i=Date.now(),o=i-a.triggeredAt;if(a.triggeredAt&&!(o>=a.delayMs&&a.delayMs>0)&&a.delayMs)return r.nextGate(Mt.aborted,n.data);{a.triggeredAt=i;const e=Rt(a,(r.recipePoolId,r.recipeType,r.thingRecipeId,r.id)).findIndex((e=>e.name===t.name));-1!==e&&(a.lastInputIndex=e),a.matchingOutputs?-1!==e&&await r.nextGate(`output${e+1}`,n.data):await r.nextGate(Mt.output,n.data),r.setState(a)}},getInputNames:Rt,getOutputNames:e=>{const t={inputs:2,matchingOutputs:!0,lastInputIndex:-1,delayMs:500,triggeredAt:0,...e};if(e.matchingOutputs){const e=Array(t.inputs).fill(0).map(((e,t)=>({name:`output${t+1}`,type:Q.Anything})));return e.push({name:Mt.aborted,type:Q.Anything}),e}return[{name:Mt.output,type:Q.Anything},{name:Mt.aborted,type:Q.Anything}]},getDefaultState:Bt};const Ut=(e,t,n,r,a,i)=>{if(a){const o=e.measureText(a),s=o.fontBoundingBoxAscent+o.fontBoundingBoxDescent;e.fillStyle=r,e.fillRect(t,n-i,1.1*o.width,s),e.font=`${i}px Arial`,e.fillStyle="black",e.fillText(a,t,n)}},Ft=(e,t,n,r,a,i,o)=>{e.fillStyle=a,e.fillRect(t,n,r,r),Ut(e,t,n,a,i,o)},_t=(e,t,n,r,a,i)=>{e.beginPath(),e.strokeStyle=r,e.lineWidth=n,e.rect(t.left,t.top,t.width,t.height),e.stroke();const o=n/2;Ut(e,t.left-o,t.top-o,r,a,i)},Gt=Object.freeze({image:"image",pixels:"pixels"}),zt="image";var Vt={onParentEvent:async(e,t,n,r)=>{const a={fontSize:12,color:"#00ff00",size:2,...r.getState()},i=n.data.type===Q.ImageData||n.data.type===Q.Anything&&he(n.data.value);if(t.name===Gt.pixels){const e=((e,t)=>t===Q.Anything&&(he(e)||Se(e)||Ie(e)||Array.isArray(e))||t===Q.Array||t===Q.Rect||t===Q.Point)(n.data.value,n.data.type);if(!e)return;a.$$pixels=n.data.value}if(t.name===Gt.image&&i){const e=n.data.value;a.$$memCanvas&&a.$$memCanvas.getContext||(a.$$memCanvas=xt(e.width||1,e.height||1)),a.$$lastFrame=e}if(a.$$lastFrame&&a.$$pixels&&a.$$memCanvas){const e=(e=>{const{sourceImage:t,pixels:n,memCanvas:r,size:a,color:i,labelProp:o,fontSize:s}=e;if(r){const e=Ct(r);if(e){r.width!==t.width&&(r.width=t.width),r.height!==t.height&&(r.height=t.height),e.putImageData(t,0,0);const c=Array.isArray(n)?n:[n];for(let t=0;t<c.length;t++){const n=c[t],r=o?n[o]:"";Ie(n)?_t(e,n,a,i,r,s):Se(n)&&Ft(e,n.x,n.y,a,i,r,s)}return e.getImageData(0,0,r.width,r.height)}}return t})({sourceImage:a.$$lastFrame,pixels:a.$$pixels||[],memCanvas:a.$$memCanvas,size:a.size,color:a.color,labelProp:a.labelProp,fontSize:a.fontSize});return r.setState({...a,$$lastFrame:void 0,$$pixels:void 0}),r.nextWidget(zt,{type:Q.ImageData,value:e})}r.setState(a)},getInputNames:()=>[{name:Gt.image,type:Q.ImageData},{name:Gt.pixels,type:[Q.Rect,Q.Point,Q.Array]}],getOutputNames:()=>[{name:zt,type:Q.ImageData}]};const Ht=Object.freeze({in:"in"}),Jt="output",qt=e=>{const t=String(e).split(".");return t.length<2?0:t[1].length};var Kt={onParentEvent:async(e,t,n,r)=>{const a={min:1,max:100,...r.getState()},i=!Number.isInteger(a.min),o=!Number.isInteger(a.max),s=i||o;let c=(u=a.min,d=a.max,Math.random()*(d-u)+u);var u,d;if(s){let e=0;if(i&&(e=qt(a.min)),o){const t=qt(a.max);t>e&&(e=t)}c=Number(c.toFixed(e))}else c=Math.floor(c);return r.nextGate(Jt,{type:Q.Number,value:c})},getInputNames:()=>[{name:Ht.in,type:Q.Anything}],getOutputNames:()=>[{name:Jt,type:Q.Number}]};const Xt=Object.freeze({output:"output",totalItems:"totalItems"}),Yt=Object.freeze({trigger:"trigger",clear:"clear"}),Zt=()=>({totalSentItems:-1,totalSentAt:0,$$list:[],$$outputShape:{},totalInputs:1}),Qt=async(e,t)=>t.nextGate(Xt.totalItems,{type:Q.Number,value:e});var en={onParentEvent:async(e,t,n,r)=>{const a={totalSentItems:-1,totalSentAt:0,$$list:[],$$outputShape:{},totalInputs:1,...r.getState()};if(t.name===Yt.clear)return a.$$list=[],a.properties?.autoFilled&&delete a.properties,r.setState(a),Qt(a.$$list.length,r);const i=t.name===Yt.trigger;if(!i)if(Array.isArray(n.data.value))n.data.type!==Q.Array&&n.data.type!==Q.Anything||(a.$$outputShape={...a.$$outputShape,...e?.jsonShape},a.$$list=a.$$list.concat(n.data.value),r.setState({...a}),await Qt(a.$$list.length,r));else{const t=`$$primitive_${Object.keys(a.$$outputShape).length}`;n.data.type===Q.JsonObj?a.$$outputShape={...a.$$outputShape,...e?.jsonShape?e.jsonShape:void 0}:a.$$outputShape={...a.$$outputShape,[t]:n.data.type},a.$$list.push(n.data.value),r.setState({...a}),await Qt(a.$$list.length,r)}if(i){Object.keys(a.$$outputShape).length&&(a.properties={autoFilled:!0,jsonShape:{...a.$$outputShape}});const e=a.$$list.length,t=[...a.$$list];return a.$$list=[],r.setState({...a}),await Qt(e,r),r.nextGate(Xt.output,{type:Q.Array,value:t})}},getInputNames:e=>{const t={totalSentItems:-1,totalSentAt:0,$$list:[],$$outputShape:{},totalInputs:1,...e},n=Array(t.totalInputs||1).fill(0).map(((e,t)=>({name:`array${t+1}`,type:Q.Array})));return n.push({name:Yt.clear,type:Q.Anything},{name:Yt.trigger,type:Q.Anything}),n},getOutputNames:e=>[{name:Xt.output,type:Q.Array,...e.properties?{jsonShape:e.properties?.jsonShape}:void 0},{name:Xt.totalItems,label:"Total Items",type:Q.Number}],getDefaultState:Zt};const tn=Object.freeze({start:"start",stop:"stop"}),nn="output",rn="clock_interrupt";var an={onParentEvent:async(e,t,n,r)=>{const a={enabled:!1,interval:1e3,intervalMode:"ms",...r.getState()};if(ye(e?.name||"")&&t.name===rn)return r.nextGate(nn,{type:Q.Boolean,value:!0});if(t.name===tn.stop&&a.enabled&&a.$$interruptId){r.cancelInterrupt(a.$$interruptId)?(a.enabled=!1,a.$$interruptId=void 0,r.setState(a)):console.warn(`Failed to cancel interrupt [${a.$$interruptId}]`)}else t.name!==tn.start||a.enabled||a.$$interruptId||(a.$$interruptId=r.registerInterrupt("interval",rn,{interval:a.interval}),a.enabled=!0,r.setState(a))},getInputNames:()=>[{name:tn.start,type:Q.Anything},{name:tn.stop,type:Q.Anything}],getOutputNames:()=>[{name:nn,type:Q.Boolean}],initialize:async e=>{const t=e.getState();if(t.enabled&&!t.$$interruptId){const n=e.registerInterrupt("interval",rn,{interval:t.interval});e.setState({...t,$$interruptId:n})}}};const on=Object.freeze({in:"in"}),sn="output",cn=(e,t,n)=>"number"==typeof e?Number((e*t).toFixed(n)):e;var un={onParentEvent:async(e,t,n,r)=>{const a={userProperties:[],factor:2,decimalPoints:2,...r.getState()},i=n.data.type;let o=n.data.value,s=!1;return e?.jsonShape&&(a.detectedInputJson={...a.detectedInputJson,...e?.jsonShape},s=!0),a.detectedInputType||(a.detectedInputType=i,s=!0),n.data.type===Q.Array&&("number"==typeof n.data.value?.[0]?o=((e,t,n)=>{const r=(e||[]).map((e=>cn(e,t,n)));return r})(n.data.value,a.factor,a.decimalPoints):"object"==typeof n.data.value?.[0]&&(o=((e,t,n,r)=>{const a=(e||[]).map((e=>{const a={...e};return Object.keys(a).forEach((e=>{r?.length&&!r?.includes(e)||(a[e]=cn(a[e],t,n))})),a}));return a})(n.data.value,a.factor,a.decimalPoints,a.userProperties))),n.data.type===Q.Number&&(o=cn(n.data.value,a.factor,a.decimalPoints)),s&&r.setState(a),r.nextGate(sn,{type:i,value:o})},getInputNames:()=>[{name:on.in,type:[Q.Array,Q.Number]}],getOutputNames:e=>[{name:sn,type:e.detectedInputType||Q.Number,jsonShape:e.detectedInputJson}]};const dn=Object.freeze({output:"output"}),ln=Object.freeze({trigger:"trigger"}),pn=()=>({useTriggerPort:!0,properties:[{name:"x",label:"x",type:Q.Number,value:10},{name:"y",label:"y",type:Q.Number,value:20}]}),gn=e=>{const t={};for(let n=0;n<e.properties.length;n++)t[e.properties[n].label]=e.properties[n].type;return t},mn=e=>{const t={};for(let n=0;n<e.properties.length;n++){let r=e.properties[n].value;const a=e.properties[n].type;a===Q.Number?r=Number(r):a===Q.String&&(r=String(r)),t[e.properties[n].label]=r}return t};var vn={onParentEvent:async(e,t,n,r)=>{const a=r.getState(),i=structuredClone(a),o={...pn(),...i};if(t.name===ln.trigger){const e=mn(o);return r.nextGate(dn.output,{type:Q.JsonObj,value:e})}const s=o.properties.findIndex((e=>e.name===t.name));if(-1!==s){let e=n.data.type===o.properties[s].type;if(!e&&n.data.type===Q.Anything){e=$e(n.data.type)===o.properties[s].type}if(e?(o.properties[s].value=n.data.value,o.properties[s].$$invalidInputType=!1):o.properties[s].$$invalidInputType=!0,r.setState(o),!o.useTriggerPort){const e=mn(o);return r.nextGate(dn.output,{type:Q.JsonObj,value:e})}}},getInputNames:e=>{const t={...pn(),...e},n=t.properties.map((e=>({name:e.name,label:e.label,type:e.type})));return t.useTriggerPort&&n.push({name:ln.trigger,label:ln.trigger,type:Q.Anything}),n},getOutputNames:e=>[{name:dn.output,label:dn.output,type:Q.JsonObj,jsonShape:gn(e)}],getDefaultState:pn};const fn=async e=>{const t=(e,t)=>e.split(t)[1];if(e.startsWith(pe)){const n=t(e,pe);return be("inner","input",n)}if(e.startsWith(ve)){const n=t(e,ve);return be("outer","output",n)}return null},yn=()=>({canvasPosition:{x:0,y:0},canvasZoom:1,inputs:[{name:"input",type:[Q.Anything],index:0}],outputs:[{name:"output",type:[Q.Anything],index:0}],name:"Custom Widget 1",description:"",type:"custom"}),hn=e=>{const t={...yn(),...e},n=t.inputs.map(((e,t)=>({name:be("outer","input",e.name),type:e.type,...e.jsonShape?{jsonShape:e.jsonShape}:void 0,...e.position?{position:e.position}:void 0,label:e.label,isInner:!1,index:t}))),r=t.outputs.map(((e,t)=>({name:be("inner","output",e.name),type:e.type,...e.jsonShape?{jsonShape:e.jsonShape}:void 0,...e.position?{position:e.position}:void 0,label:e.label,isInner:!0,index:n.length+t})));return[...n,...r]};var In={onParentEvent:async(e,t,n,r)=>{const a=r.getState(),i={...yn(),...a},o=hn(i,(r.recipePoolId,r.recipeType,r.thingRecipeId,r.id));for(let e=0;e<o.length;e++){const a=o[e];if(t.name===a.name&&(a.type.includes(Q.Anything)||a.type.includes(n.data.type))){const e=await fn(t.name);e&&await r.nextWidget(e,{type:n.data.type,value:n.data.value})}}},getInputNames:hn,getOutputNames:e=>{const t={...yn(),...e},n=t.outputs.map(((e,t)=>({name:be("outer","output",e.name),type:e.type,...e.jsonShape?{jsonShape:e.jsonShape}:void 0,...e.position?{position:e.position}:void 0,label:e.label,isInner:!1,index:t})));return[...t.inputs.map(((e,t)=>({name:be("inner","input",e.name),type:e.type,...e.jsonShape?{jsonShape:e.jsonShape}:void 0,...e.position?{position:e.position}:void 0,label:e.label,isInner:!0,index:t+n.length}))),...n]},getDefaultState:yn};const Sn=(e,t,n,r,a)=>{const i=4*(t*n.width+e),o=n.data[i],s=n.data[i+1],c=n.data[i+2];return Math.abs(o-r.r)<=a&&Math.abs(s-r.g)<=a&&Math.abs(c-r.b)<=a};var $n,wn,bn,Nn,An,xn,Cn,Pn,En,jn,Dn={getPixelValueAtIndex:(e,t)=>{const n=e.data,r=n[t]||0,a=n[t+1]||0,i=n[t+2]||0;return{avr:(r+a+i)/3,r:r,g:a,b:i}},getBoundingBox:(e,t,n)=>{const r=e.width,a=e.height,i=new Set,o=Number(n.threshold||0),s=isNaN(o)?10:o,c=(n,o)=>{const c=[[n,o]];let u=n,d=n,l=o,p=o;for(;c.length>0;){const n=c.shift();if(!n)continue;const[o,g]=n;o<0||g<0||o>=r||g>=a||i.has(`${o},${g}`)||!Sn(o,g,e,t,s||0)||(i.add(`${o},${g}`),u=Math.min(u,o),d=Math.max(d,o),l=Math.min(l,g),p=Math.max(p,g),c.push([o+1,g],[o-1,g],[o,g+1],[o,g-1]))}return{minX:u,maxX:d,minY:l,maxY:p}},u=[];for(let o=0;o<a;o+=4)for(let a=0;a<r;a+=4)if(!i.has(`${a},${o}`)&&Sn(a,o,e,t,s)){const{minX:e,maxX:t,minY:r,maxY:i}=c(a,o),s=t-e,d=i-r;if(s>=(n.minWidth||1)&&d>=(n.minHeight||1)&&u.push({left:e,top:r,width:s,height:d}),n.maxBoxes&&u.length>=n.maxBoxes)return u}return u},copyImageData:e=>new ImageData(new Uint8ClampedArray(e.data),e.width,e.height),setPixelValueAtIndex:(e,t,n)=>{const r=e.data,a="object"==typeof n,i=a?n.r:n,o=a?n.g:n,s=a?n.b:n;r[t]=i,r[t+1]=o,r[t+2]=s,r[t+3]=255}};!function(e){e.Browser="browser",e.Cloud="cloud",e.Desktop="desktop"}($n||($n={})),function(e){e.Bundle="bundle",e.Group="group"}(wn||(wn={})),function(e){e.Hardware="hardware",e.Virtual="virtual"}(bn||(bn={})),function(e){e.Cloud="cloud",e.Web="web"}(Nn||(Nn={})),function(e){e.Cpu_128M="kmu-cpu-128m",e.Cpu_256M="kmu-cpu-256m",e.Cpu_512M="kmu-cpu-512m",e.Cpu_1024M="kmu-cpu-1024m",e.Cpu_2048M="kmu-cpu-2048m",e.Cpu_4096M="kmu-cpu-4096m"}(An||(An={})),function(e){e.Gateway="gateway",e.Timer="timer"}(xn||(xn={})),function(e){e.InstallInProgress="installation-in-progress"}(Cn||(Cn={})),function(e){e.InstallDependencies="install-dependencies",e.GetInstalledDependencies="get-installed-dep"}(Pn||(Pn={})),function(e){e.Success="success",e.Error="error",e.Pending="pending"}(En||(En={})),function(e){e.NotFound="not-found",e.BadRequest="bad-request",e.Forbidden="forbidden",e.InternalError="internal-error"}(jn||(jn={}));let kn=null;var On=()=>{if(!kn)throw new Error("Required function is not set");return kn};class Tn extends Error{constructor(e,t){super(e),this.name="UserCodeError",t&&(this.stack=t)}}const Ln=(e,t)=>`\n\t\tfunction _user_code_(){\n\t\t\t${t===$n.Browser?"\n\t\t\tvar global = {\n\t\t\t\t__user_code: true\n\t\t\t};\n\t\t\tvar process = {};\n\t\t\tvar console = this.console;\n\t\t\tvar globalThis = global;\n\t\t\tvar require = this.___notSupportedMethod;\n\t\t\t":"\n\t\t\tvar require = this.require;\n\t\t\tvar process = this.kemuProcess;\n\t\t\t"}\n\n\t\t\tvar eval = () => {};\n\t\t\tvar document = {};\n\t\t\tvar navigator = {};\n\t\t\tvar window = this.window;\n\t\t\tvar alert = this.notify.info;\n\t\t\tvar DataType = this.dataTypesEnum;\n\t\t\tvar setInterval = this.setInterval;\n\t\t\tvar setTimeout = this.setTimeout;\n\t\t\tvar addEventListener = this.addEventListener;\n\t\t\tvar removeEventListener = this.removeEventListener;\n\t\t\tvar requestAnimationFrame = this.___notSupportedMethod;\n\t\t\tvar __delay = (ms) => new Promise((resolve, reject) => setTimeout(resolve, ms, reject));\n\n\t\t\tvar Kemu = {\n\t\t\t\tservices: {\n\t\t\t\t\thttp: { ...this.httpWebService },\n\t\t\t\t\tdynamoDb: { ...this.dynamoService },\n\t\t\t\t\tgoogleSheets: {\n\t\t\t\t\t\t...this.googleSheetsService,\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\timage: this.imageHelpers,\n\t\t\t\tvariable: this.variablesManager,\n\n\t\t\t\thelpers: {\n\t\t\t\t\tcryptoJS: this.CryptoJS,\n\t\t\t\t\tjsonp: this.jsonp,\n\t\t\t\t\tdelay: __delay,\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvar sendToPort;\n\n\t\t\t// --- User Methods Start ---\n\t\t\t${e||""};\n\t\t\t// --- User Methods End ---\n\t\t\t\n\t\t\t// Processes the user code asynchronously.\n\t\t\tconst asyncProcessEvent = async (targetPort, sourcePort, event) => {\n\t\t\t\tconst userProcessEvent = typeof processEvent === 'undefined' ? undefined : processEvent;\n\t\t\t\tif(userProcessEvent) {\n\t\t\t\t\ttry{\n\t\t\t\t\t\treturn await userProcessEvent(targetPort, sourcePort, event, sendToPort);\n\t\t\t\t\t}catch(e){\n\t\t\t\t\t\tthis.__errorTracer(e);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/** invoked the very first time the recipe is initialized */\n\t\t\tconst asyncRecipeInit = async (context, logger) => {\n\t\t\t\ttry {\n\t\t\t\t\t${t===$n.Browser?"if(logger) { console = logger; }":""}\n\t\t\t\t\tif(typeof recipeInit === 'function') {\n\t\t\t\t\t\treturn recipeInit(context);\n\t\t\t\t\t}\n\t\t\t\t}catch(e){\n\t\t\t\t\tthis.__errorTracer(e);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/** invoked every time the code is about to be replaced */\n\t\t\tconst asyncOnTerminate = async (context) => {\n\t\t\t\ttry {\n\t\t\t\t\tif(typeof onTerminate === 'function') {\n\t\t\t\t\t\treturn onTerminate(context);\n\t\t\t\t\t}\n\t\t\t\t}catch(e){\n\t\t\t\t\tthis.__errorTracer(e);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/** updates the function that allows widget contexts to send data to the next widget */\n\t\t\tconst setSendToPort = (sendNextFun) => {\n\t\t\t\tsendToPort = sendNextFun;\n\t\t\t}\n\n\t\t\t/** invoked the every time the user code is compiled. */\n\t\t\tconst asyncMainEvent = async (sendNextFun, logger) => {\n\t\t\t\ttry{\n\t\t\t\t\tsetSendToPort(sendNextFun);\n\t\t\t\t\tif(logger) { console = logger; }\n\t\t\t\t\tif(typeof main === 'function'){\n\t\t\t\t\t\treturn main();\n\t\t\t\t\t}\n\t\t\t\t}catch(e){\n\t\t\t\t\tthis.__errorTracer(e);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tasyncProcessEvent: asyncProcessEvent,\n\t\t\t\tmain: asyncMainEvent,\n\t\t\t\trecipeInit: asyncRecipeInit,\n\t\t\t\tsetSendToPortFun: setSendToPort,\n\t\t\t\tonTerminate: asyncOnTerminate,\n\t\t\t\tgetLocalContext: () => global,\n\t\t\t\tgetWidgetInputs: typeof getWidgetInputs === 'undefined' ? undefined : getWidgetInputs,\n\t\t\t\tgetWidgetOutputs: typeof getWidgetOutputs === 'undefined' ? undefined : getWidgetOutputs,\n\t\t\t};\n\t\t}\n\t\t\n\t\treturn function compiler(context){\n\t\t\treturn _user_code_.call(context)\n\t\t}\n\n\t\treturn compiler;\n\t`,Mn=(e,t,n,i)=>{const o=Ln(e,n),s={...t,document:{},__errorTracer:e=>{throw new Tn(e.message,e.stack)},__jest:void 0===globalThis.__jest?void 0:globalThis.__jest,___notSupportedMethod:()=>i?.error("This method is not supported."),console:console,setInterval:()=>i?.error("'setInterval' is not supported. Please use a \"Timer\" widget instead."),setTimeout:t?.setTimeout,imageHelpers:Dn,...n===$n.Cloud?{require:On(),kemuProcess:process.env.KEMU_PROCESS?process.env.KEMU_PROCESS:{}}:{},jsonp:r,CryptoJS:a,window:{addEventListener:t?.addEventListener,removeEventListener:t?.removeEventListener}};try{const e="browser"===(()=>{if(oe)return"browser";if(ce)return"node";if(se)return"worker";throw new Error("Unsupported environment")})()?(e=>e.replace(/[//]{2}[ ]*@kemu-cloud[ \t]*\{[\s\S]*?[//]{2}[ ]*@kemu-cloud[ \t]*\}/gim,""))(o):(e=>e.replace(/[//]{2}[ ]*@kemu-browser[ \t]*\{[\s\S]*?[//]{2}[ ]*@kemu-browser[ \t]*\}/gim,""))(o),t=new Function(e);return{compiledModule:t()(s)}}catch(e){return{error:{name:"CompileError",message:e.message,stack:e.stack}}}},Bn="main",Rn=()=>({pauseExecution:!1,autoPauseOnError:!0,$$eventListeners:{},pages:{[Bn]:{code:"\nconst getWidgetInputs = () => [\n\t{ name: 'Input 1', type: DataType.Number }\n];\n\nconst getWidgetOutputs = () => [\n\t{ name: 'Output 1', type: DataType.Number }\n]\n\nlet counter = 0;\n\nconst processEvent = async (targetPort, sourceWidget, event) => {\n\tif(targetPort.name === 'Input 1'){\n\t\treturn sendToPort('Output 1', {\n\t\t\ttype: DataType.Number,\n\t\t\tvalue: counter++,\n\t\t});\n\t}\n}\n",language:"javascript",name:"My First Script"}},consoleVisible:!1,$$consoleLines:[]}),Wn=(e,t)=>{const n={message:"Unknown Error"};if(e?.stack){const r=e?.stack?.split(":")[0].trim();n.type=r;const a=(e=>{const t=/,[ ]?<anonymous>:([0-9]+:[0-9]+)\)/gm;let n;for(;null!==(n=t.exec(e));){n.index===t.lastIndex&&t.lastIndex++;const e=n[1].split(":");if(2===e.length)return{line:Number(e[0])||0,column:Number(e[1])||0}}return null})(e.stack);a&&(n.line=a.line-(e=>{const t="___user_code_section___";return Ln(t,e).split(t)[0].split("\n").length+2})(t),n.column=a.column)}return e.message&&(n.message=e.message),n},Un=(e,t)=>{const n={...Rn(),...t.getState()},r={...n,...e?{$$error:e}:void 0,...n.autoPauseOnError&&e?{pauseExecution:!0}:void 0};e&&(r.$$consoleLines=[...r.$$consoleLines,{type:"error",text:e.message,timestamp:Date.now(),fileName:Bn}]),t.setState(r)};var Fn,_n;!function(e){e.ServiceCreationLog="service-creation-log"}(Fn=Fn||(Fn={})),function(e){e.Service="service",e.ServiceUI="serviceUI"}(_n=_n||(_n={}));const Gn=new o,zn=(e,t,n)=>{const r=G(e,t);if(!r)throw new Error(`Thing ${t} not found in recipe ${e}`);const a=r.gates[n];if(!a)throw new Error(`Widget ${n} not found in thing ${t}`);return a},Vn=(e,t,n)=>`${t}:${n}:${e}`,Hn=e=>`${e}:new-var`,Jn=async(e,t,n,r,a,i,o)=>{const s={...o},c={thingId:n,recipeId:t,variableName:e,changes:i,ownerId:r,callerWidgetId:a,varDefinition:Object.freeze(s)};if(i.includes("added")){const e=Hn(n);return Gn.emit(e,c)}{const t=Vn(e,n,r);return Gn.emit(t,c)}},qn=(e,t,n,r)=>{const a=zn(e,t,r);a.variablesListener={...a.variablesListener,[n]:0},Xn(e,t)},Kn=(e,t,n,r)=>{const a=zn(e,t,r),i={...a.variablesListener};void 0!==a.variablesListener?.[n]&&(delete i[n],a.variablesListener=i)},Xn=async(e,t)=>{const n=G(e,t);if(!n)throw new Error(`Thing "${t}" not found in recipe "${e}"`);const r={...n.variables},a=Object.keys(r);for(const i of a){const a=r[i],o=Object.keys(a);for(const a of o){!n.gates[a]&&(delete r[i][a],await Jn(i,e,t,a,void 0,["removed"],null))}0===Object.keys(r[i]).length&&delete r[i]}n.variables=r},Yn=(e,t,n)=>{for(const r in t){const a=t[r];if(a.createdByWidgetId===e.id)return a;if(e.type===Ce.variable&&a.ownerType===Ce.variable)return a;if(e.type===Ce.script){const t=a.createdByWidgetId===e.groupId,r=n[a.createdByWidgetId];if(!r)continue;const i=r.groupId===e.groupId;if(t||r.type===Ce.variable&&i)return a}}return null};var Zn=async(e,t,n,r,a,i)=>{const o=G(e,t);if(!o)throw new Error(`Thing ${t} not found in recipe ${e}`);const s={...o.variables};s[r]=s[r]||{};const c=s[r],u=o.gates[n];if(!u)throw new Error(`Widget ${n} not found in thing ${t}`);const d=Object.values(c);let l=!1,p=!1;const g=async a=>Jn(r,e,t,a.createdByWidgetId,n,["value"],a);if(u.type===Ce.variable){l=!0;for(const e of d)e.ownerType===Ce.variable&&e.type===a.type&&(e.value=a.value,p=!0,await g(e))}if(u.type===Ce.script){l=!0;for(const e of d){const t=e.createdByWidgetId===u.groupId,n=o.gates[e.createdByWidgetId],r=n?.type===Ce.variable,i=n?.groupId===u.groupId;(t||r&&i)&&e.type===a.type&&(e.value=a.value,p=!0,await g(e))}}if(!l){l=!0;for(const e of d){e.createdByWidgetId===n&&e.type===a.type&&(e.value=a.value,p=!0,await g(e))}}if(!i?.skipNotifications&&p){const s=Object.values(o.gates);for(const o of s){if(o.id===n&&i?.skipCallerNotification)continue;const s=o.variablesListener?.[r];void 0!==s&&await Ga(o.id,t,e,`${X}${r}`,a)}}},Qn=(e,t,n,r)=>{const a=G(e,t);if(!a)throw new Error(`Thing ${t} not found in recipe ${e}`);if(!r.readerWidgetId&&!r.ownerWidgetId)throw new Error("readerWidgetId or ownerWidgetId must be provided");const i={...a.variables}[n];if(!i)return;if(r.ownerWidgetId){const e=i[r.ownerWidgetId];return e?.value}const o=a.gates[r.readerWidgetId];if(!o)throw new Error(`Widget ${r.readerWidgetId} not found in thing ${t}`);const s=Yn(o,i,a.gates);return s?s.value:null},er=qn,tr=Kn;const nr="setTimeout",rr="variableChanged",ar=e=>{const{recipePoolId:t,thingId:n,scriptWidgetId:r}=e;if(!z(t,n,r))throw new Error(`Widget "${r}" not found in recipe "${t}"`);return{get:(e,a)=>{const i=Qn(t,n,e,{readerWidgetId:r});if(null===i){if(void 0===a)throw new Error(`Variable "${e}" is not defined`);return a}return i},set:async(e,a)=>{await Zn(t,n,r,e,{type:$e(a),value:a})},onValueChange:(a,i)=>{if(!e.setState)return void console.warn("Cannot subscribe to variable changes without a setState function");er(t,n,a,r);const o={...Rn(),...e.getState()};o.$$eventListeners[a]={handler:i,abort:async()=>{tr(t,n,a,r)},name:rr},e.setState(o)}}},ir="__command-compile__";let or;const sr=()=>{console.log("Method not implemented")},cr=(e,t,r)=>{const a=(e,...n)=>{const r={...Rn(),...t.getState()}.$$eventListeners[e];r&&r.handler(n)},i={};return Object.keys(Q).forEach((e=>{i[e]=Q[e]})),{dataTypesEnum:i,notify:{success:e=>{t.getState()?.$$managedUI?.notify?.success(e)},error:e=>{t.getState()?.$$managedUI?.notify?.error(e)},info:e=>{t.getState()?.$$managedUI?.notify?.info(e)}},variablesManager:e.variablesManager?ar({recipePoolId:r.recipePoolId,scriptWidgetId:r.widgetId,thingId:r.thingId,getState:t.getState,setState:t.setState}):{get:sr,set:async()=>sr(),onValueChange:sr},setTimeout:(r,a,i)=>{if(e.withTimers&&t&&t.setState&&t.registerInterrupt){const e=n(),o={...Rn(),...t.getState()};o.$$eventListeners[e]={handler:r,rejectHandler:i,name:nr},t.setState(o),t.registerInterrupt("timeout",e,{timeout:a},void 0,e)}},addEventListener:(e,r)=>{if(t.setState){const i=n(),o={...Rn(),...t.getState()};o.$$eventListeners[i]={handler:r,name:e},t.setState(o),window.addEventListener(e,a.bind(i))}else console.warn(`Cannot remove event listener '${e}' because the widget context is not available.`)},removeEventListener:(e,n)=>{if(t.setState){const r={...Rn(),...t.getState()},a=Object.keys(r.$$eventListeners).find((t=>r.$$eventListeners[t].name===e&&r.$$eventListeners[t].handler===n));t.setState(r),a&&removeEventListener(r.$$eventListeners[a].name,r.$$eventListeners[a].handler)}else console.warn(`Cannot remove event listener '${e}' because the widget context is not available.`)}}},ur=(e,t,n,r)=>{const a={...Rn(),...n.getState()},i=a.pages[Bn].$$compiledCode;if(i)return{compiledModule:i};{const i=cr(e,n,t);return Mn(a.pages[Bn].code,i,n.recipeType,r)}},dr=e=>e.map((e=>({...e,name:e.name.replace("_","")}))),lr=async(e,t)=>{const n={...e};for(const r in e){if(e[r].name===nr){const e=n[r]?.rejectHandler;if("function"==typeof e)try{await e("TIMER_ABORTED")}catch(e){console.log("Error in reject interrupt handler: ",e)}t.cancelInterrupt(r),delete n[r]}}return n},pr=async(e,t,n)=>{let r={...Rn(),...e.getState()};if(void 0!==n){r.pages[Bn]?.$$compiledCode?.onTerminate&&await(r.pages[Bn].$$compiledCode?.onTerminate());let t=await lr(r.$$eventListeners,e);t=await(async e=>{const t={...e};for(const n in e)if(e[n].name===rr){const r=e[n]?.abort;if("function"==typeof r)try{await r()}catch(e){console.log("Error in abort interrupt handler: ",e)}delete t[n]}return t})(t),r.$$eventListeners=t,r.$$error=void 0,r.pages[Bn].$$compiledCode=void 0,r.pages[Bn].code=n,e.setState({...r})}const a=!r.pages[Bn].$$compiledCode,{compiledModule:i,error:o}=ur({variablesManager:!0,withTimers:!0},{recipePoolId:e.recipePoolId,thingId:e.thingRecipeId,widgetId:e.id},{getState:e.getState,setState:e.setState,recipeType:e.recipeType,registerInterrupt:e.registerInterrupt});if(o){console.log("Failed to compile user code");const t=Wn(o,e.recipeType);return Un(t,e),null}if(i){const n=(e=>{const t=(t,n)=>{if(or)try{return or[t](n)}catch(e){return void console.log("Error in custom logger: ",e)}const r={...Rn(),...e.getState()},a=[...r.$$consoleLines||[]];a.push({fileName:Bn,text:n,type:t,timestamp:Date.now()}),a.length>100&&a.splice(0,30),e.setState({...r,$$consoleLines:a})},n={log:e=>{t("log",e)},error:e=>{t("error",e)},warn:e=>{t("warn",e)},info:e=>{t("info",e)}};return n})(e);let o;if(r={...e.getState()},r.pages[Bn].$$compiledCode=i,e.nextGate&&i.setSendToPortFun(e.nextGate),t)try{await i.recipeInit({setState:e.setState,getState:e.getState},n)}catch(t){o=Wn(t,e.recipeType)}if(e.nextGate&&a)try{await i.main(e.nextGate,n)}catch(t){o=Wn(t,e.recipeType)}r.$$lastInputs=i.getWidgetInputs?i.getWidgetInputs():[],r.$$lastOutputs=i.getWidgetOutputs?i.getWidgetOutputs():[],e.setState(r),Un(o,e)}};var gr={onParentEvent:async(e,t,n,r)=>{const a=r.getState(),i={...Rn(),...a};if(!i.pages[Bn])return console.warn("Missing default page");if(i.pauseExecution){if(Object.keys(i.$$eventListeners).length){const e=await lr(i.$$eventListeners,r);r.setState({...i,$$eventListeners:e})}return}if(ye(e?.name||""))return i.$$eventListeners[t.name]?(await i.$$eventListeners[t.name].handler(),i.$$eventListeners[t.name].name===nr&&delete i.$$eventListeners[t.name],void r.setState({...i})):void console.log(`Unknown interrupt id [${t.name}] `);if(t.name.startsWith(X)){const e=t.name.replace(X,""),r=n.data.value,a=i.$$eventListeners[e];return void(a?.handler&&await a.handler(r))}const o=t.name===ir;await pr(r,!1,o?n.data.value:void 0);const s=i.pages[Bn].$$compiledCode;if(e&&e.name!==ir&&s){let a;try{await s.asyncProcessEvent(t,e,n)}catch(e){"UserCodeError"===e.name&&(a=Wn(e,r.recipeType))}Un(a,r)}},getInputNames:(e,t)=>{const n={...Rn(),...e},{compiledModule:r}=ur({},{recipePoolId:t.recipePoolId,thingId:t.thingRecipeId,widgetId:t.widgetId},{getState:()=>n,recipeType:t.recipeType});if(r?.getWidgetInputs){const e=r.getWidgetInputs();return dr(e)}return e.$$lastInputs||[]},getOutputNames:(e,t)=>{const n={...Rn(),...e},{compiledModule:r}=ur({},{recipePoolId:t.recipePoolId,thingId:t.thingRecipeId,widgetId:t.widgetId},{getState:()=>n,recipeType:t.recipeType});if(r?.getWidgetOutputs){const e=r.getWidgetOutputs();return dr(e)}return e.$$lastOutputs||[]},getDefaultState:Rn,initialize:async e=>{const t=e.getState(),n={...Rn(),...t};n.pages[Bn].code&&await pr({getState:e.getState,id:e.widgetThingId,recipePoolId:e.recipePoolId,recipeType:e.recipeType,registerInterrupt:e.registerInterrupt,setState:e.setState,thingRecipeId:e.thingRecipeId,cancelInterrupt:()=>!0},!0,n.pages[Bn].code)}};const mr=async(e,t,n,r)=>{e.startsWith("data:image/")||(e=`data:image/png;base64,${e}`);const a=await vr(e);return((e,t,n,r)=>{const a=r.getContext("2d");if(!a)throw new Error("Failed to get canvas context");const i=e.width,o=e.height;return r.width=t,r.height=n,a.drawImage(e,0,0,i,o,0,0,t,n),a.getImageData(0,0,t,n)})(a,n||a.naturalWidth,r||a.naturalHeight,t)},vr=e=>new Promise(((t,n)=>{const r=new Image;r.onload=()=>t(r),r.onerror=e=>n(e),r.src=e})),fr=Object.freeze({image:"image"}),yr=Object.freeze({base64:"base64"}),hr=()=>({});var Ir={onParentEvent:async(e,t,n,r)=>{const a={...r.getState()};if(t.name===yr.base64){if("string"!=typeof n.data.value)return;if(n.data.type!==Q.String&&n.data.type!==Q.Anything)return;const e=n.data.value;oe&&(a.$$memCanvas&&a.$$memCanvas.getContext||(a.$$memCanvas=xt(320,240)));try{const t=await mr(e,a.$$memCanvas,a.resize?.width,a.resize?.height);return r.setState(a),r.nextGate(fr.image,{type:Q.ImageData,value:t})}catch(e){console.log("[base64ToImageData] Error: ",e)}}},getInputNames:()=>[{name:yr.base64,type:Q.String}],getOutputNames:()=>[{name:fr.image,type:Q.ImageData}],getDefaultState:hr};const Sr=Object.freeze({object:"object",error:"error"}),$r=Object.freeze({string:"string"}),wr=()=>({outputIsArray:!1});var br={onParentEvent:async(e,t,n,r)=>{const a={outputIsArray:!1,...r.getState()};if((n.data.type===Q.String||n.data.type===Q.Anything)&&"string"==typeof n.data.value)try{const e=JSON.parse(n.data.value),t=Array.isArray(e);return t&&!a.outputIsArray?r.setState({...a,outputIsArray:!0}):!t&&a.outputIsArray&&r.setState({...a,outputIsArray:!1}),r.nextGate("object",{type:t?Q.Array:Q.JsonObj,value:e})}catch(e){return r.nextGate("error",{type:Q.Boolean,value:!0})}},getInputNames:()=>[{name:$r.string,type:Q.String}],getOutputNames:e=>[{name:Sr.object,type:[Q.JsonObj,Q.Array],label:e.outputIsArray?"array":Sr.object},{name:Sr.error,type:Q.Boolean}],getDefaultState:wr};const Nr=Object.freeze({string:"string",length:"length"}),Ar=Object.freeze({trigger:"trigger",setText:"setText"}),xr=()=>({text:"",dispatchOnSet:!1});var Cr={onParentEvent:async(e,t,n,r)=>{const a={text:"",dispatchOnSet:!1,...r.getState()};if(t.name===Ar.setText){if(!((n.data.type===Q.String||n.data.type===Q.Anything)&&"string"==typeof n.data.value))return;if("string"==typeof n.data.value&&(a.text=n.data.value,r.setState(a)),!a.dispatchOnSet)return}const i=r.nextGate(Nr.length,{type:Q.Number,value:a.text.length}),o=r.nextGate(Nr.string,{type:Q.String,value:a.text});await Promise.all([i,o])},getInputNames:e=>{const t=[{name:Ar.setText,type:Q.String}];return e.dispatchOnSet||t.push({name:Ar.trigger,type:Q.Anything}),t},getOutputNames:()=>[{name:Nr.string,type:Q.String},{name:Nr.length,type:Q.Number}],getDefaultState:xr};const Pr=Object.freeze({image:"image"}),Er=Object.freeze({image:"image",x:"x",y:"y",width:"width",height:"height"}),jr=()=>({showInputPorts:!1});var Dr={onParentEvent:async(e,t,n,r)=>{const a={showInputPorts:!1,...r.getState()};if("number"==typeof n.data.value)return t.name===Er.x&&(a.cropX=n.data.value),t.name===Er.y&&(a.cropY=n.data.value),t.name===Er.width&&(a.cropWidth=n.data.value),t.name===Er.height&&(a.cropHeight=n.data.value),void r.setState(a);if(t.name===Er.image){if(n.data.type!==Q.ImageData&&n.data.type!==Q.Anything)return;if(!he(n.data.value))return;const e=n.data.value;if(a.$$memCanvas&&a.$$memCanvas.getContext||(oe&&(a.$$memCanvas=xt(320,240),a.$$memCanvasContext=Ct(a.$$memCanvas)),r.setState(a)),!a.$$memCanvas||!a.$$memCanvasContext)return;let t=e;return a.$$memCanvas.width=e.width,a.$$memCanvas.height=e.height,(a.cropX||a.cropY||a.cropWidth||a.cropHeight)&&(t=((e,t,n,r)=>{if(!n)return e;const a=Math.max(r.x||0,0),i=Math.max(r.y||0,0),o=e.width,s=e.height,c=Math.min(Math.ceil(r.width||o),o),u=Math.min(Math.ceil(r.height||s),s);return t.width=e.width,t.height=e.height,n.putImageData(e,0,0),n.drawImage(t,a,i,c,u,0,0,c,u),n.getImageData(0,0,c,u)})(e,a.$$memCanvas,a.$$memCanvasContext,{x:a.cropX,y:a.cropY,width:a.cropWidth,height:a.cropHeight})),r.nextGate(Pr.image,{type:Q.ImageData,value:t})}},getInputNames:e=>{const t=[{name:Er.image,type:[Q.ImageData]}];return e.showInputPorts&&(t.push({name:Er.x,type:Q.Number}),t.push({name:Er.y,type:Q.Number}),t.push({name:Er.width,type:Q.Number}),t.push({name:Er.height,type:Q.Number})),t},getOutputNames:()=>[{name:Pr.image,type:Q.ImageData}],getDefaultState:jr};const kr=Object.freeze({image:"image"}),Or=Object.freeze({image:"image",width:"width",height:"height"}),Tr=()=>({showInputPorts:!1});var Lr={onParentEvent:async(e,t,n,r)=>{const a={showInputPorts:!1,...r.getState()};if("number"==typeof n.data.value)return t.name===Or.width&&(a.width=n.data.value),t.name===Or.height&&(a.height=n.data.value),void r.setState(a);if(t.name===Or.image){if(n.data.type!==Q.ImageData&&n.data.type!==Q.Anything)return;if(!he(n.data.value))return;const e=n.data.value;if(a.$$memCanvas&&a.$$memCanvas.getContext||(a.$$memCanvas=xt(320,240),r.setState(a)),!a.$$memCanvas)return;let t=e;return(a.width||a.height)&&(t=((e,t,n,r)=>{if(!n&&!r)return e;n&&!r?r=n*(e.height/e.width):!n&&r&&(n=r*(e.width/e.height));const a=Math.max(1,n||e.width),i=Math.max(1,r||e.height);t.width=Math.max(e.width,a),t.height=Math.max(e.height,i);const o=Ct(t);if(!o)throw new Error("Failed to get canvas context");return o.putImageData(e,0,0),o.drawImage(t,0,0,e.width,e.height,0,0,a,i),o.getImageData(0,0,a,i)})(e,a.$$memCanvas,a.width,a.height)),r.nextGate(kr.image,{type:Q.ImageData,value:t})}},getInputNames:e=>{const t=[{name:Or.image,type:Q.ImageData}];return e.showInputPorts&&(t.push({name:Or.width,type:Q.Number}),t.push({name:Or.height,type:Q.Number})),t},getOutputNames:()=>[{name:kr.image,type:Q.ImageData}],getDefaultState:Tr};const Mr=Object.freeze({value:"value"}),Br=Object.freeze({trigger:"trigger",setValue:"setValue"}),Rr=()=>({value:0,dispatchOnSet:!1});var Wr={onParentEvent:async(e,t,n,r)=>{const a={value:0,dispatchOnSet:!1,...r.getState()};if(t.name===Br.setValue){const e=n.data.type===Q.Number||n.data.type===Q.Anything||n.data.type===Q.String,t=!isNaN(Number(n.data.value))&&!Array.isArray(n.data.value);if(!e||!t)return;if(a.value=Number(n.data.value),r.setState(a),!a.dispatchOnSet)return}return r.nextGate(Mr.value,{type:Q.Number,value:a.value})},getInputNames:e=>{const t=[{name:Br.setValue,type:Q.Number}];return e.dispatchOnSet||t.push({name:Br.trigger,type:Q.Anything}),t},getOutputNames:()=>[{name:Mr.value,type:Q.Number}],getDefaultState:Rr};const Ur=Object.freeze({image:"image"}),Fr=Object.freeze({image:"image"}),_r=()=>({anchors:[],vertices:[],matrix:[]}),Gr={onParentEvent:async(e,t,n,r)=>{const a={anchors:[],vertices:[],matrix:[],...r.getState()},i=window,o=n.data.type===Q.ImageData;if(i.Speedy&&o){const e=i.Speedy,t=n.data.value;let o,d,l,p=a.$$private?.canvas,g=a.$$private?.context,m={...a};const v=4===a.anchors.length;if(a.$$private?.pipeline)o=a.$$private?.pipeline,d=a.$$private?.source;else{o=e.Pipeline(),d=e.Image.Source();const n=e.Image.Sink();l=e.Transform.PerspectiveWarp(),p?p.width===t.width&&p.height===t.height||(p.width=t.width,p.height=t.height,g=p.getContext("2d")):(c=t.width,u=t.height,p=xt(c,u),g=p.getContext("2d")),d.output().connectTo(l.input()),l.output().connectTo(n.input()),o.init(d,n,l);let r=e.Matrix(3,3,[1,0,0,0,1,0,0,0,1]);if(4===a.anchors.length){const t=e.Matrix(2,4,[(s=a.anchors)[0].x,s[0].y,s[1].x,s[1].y,s[2].x,s[2].y,s[3].x,s[3].y]),n=e.Matrix(2,4,a.vertices.reduce(((e,t)=>e.concat([t.x,t.y])),[])),i=e.Matrix.Zeros(3,3);await e.Matrix.perspective(i,t,n);const o=i.read();r=e.Matrix(3,3,o)}l.transform=r,m={...m,$$private:{...m.$$private,canvas:p,context:g,perspective:l,pipeline:o,source:d}}}let f=t;if(v){const e=await(async(e,t)=>{const n=window,r=e.$$private?.source,a=e.$$private?.pipeline;if(n.Speedy&&r&&a){const e=n.Speedy,i=await createImageBitmap(t),o=await e.load(i);return r.media=o,(await a.run()).image.source}return null})(m,f);e&&(p&&g&&(f=((e,t,n)=>(t.width=e.width,t.height=e.height,n.drawImage(e,0,0),n.getImageData(0,0,e.width,e.height)))(e,p,g)),m.$$private&&r.setState({...m,$$private:{...m.$$private,lastInputImage:t}}))}else m.$$private&&r.setState({...m,$$private:{...m.$$private,lastInputImage:t}});return r.nextGate(Ur.image,{type:Q.ImageData,value:f})}var s,c,u;console.log("Environment not supported")},getInputNames:()=>[{name:Fr.image,type:Q.ImageData}],getOutputNames:()=>[{name:Ur.image,type:Q.ImageData}],getDefaultState:_r,terminate:async e=>{const t=e.getState();t.$$private?.pipeline.release()}},zr=()=>({name:"Default widget bundle",description:"",inputs:[{dataType:[Q.Anything],name:"input"}],outputs:[{dataType:[Q.Anything],name:"output"}]});let Vr;const Hr=()=>{if(!Vr)throw new Error(Be(Me));return Vr};const Jr=async e=>{const t=new s,n=await t.loadAsync(e),r={};for(const e in n.files)if(!n.files[e].dir){const t=await n.file(e);t&&(r[e]=await t.async("uint8array"))}return r},qr={};var Kr=e=>qr[e]||null;const Xr=async(e,t,n)=>{try{const r=Hr(),a=n?r.loadBlobAsString:r.loadBlob;return await a(e,t)}catch(e){return null}},Yr=async e=>{const t=J;try{const n=await Xr(e,t,!0);if(!n)return null;return Function(n)()}catch(e){return null}},Zr=async e=>{const t=q;try{const n=await Xr(e,t,!0);if(!n)return null;return JSON.parse(n)}catch(n){return console.log(`Failed to parse the bundle's state [${e}/${t}] %j`,n),null}},Qr=(e,t)=>`${e.replace(K,"")}_${t}`,ea=(e,t)=>`widget/${e.replace(K,"")}/v/${t}`,ta=async(e,t)=>{const n=Hr(),[r]=await Promise.all([Jr(e),n.createLocation(t)]);for(const e in r)e.startsWith("__MACOSX")||await n.saveBlob(t,e,r[e])},na=(e,t)=>{const n=Qr(e,t),r=Kr(n);return r?{...r}:null},ra=(e,t,n)=>{const r=`${`widget/${e.replace(K,"")}/tmp`}/${t}`;if(n){return Hr().getCacheLocation(r)}return r};var aa=na,ia=async(e,t,n)=>{const r=ra(t,n);await ta(e,r);const a=Yr(r),i=Zr(r),o=Hr(),s=o.getCacheLocation(r),[c,u]=await Promise.all([a,i]);if(!c)return null;let d=u;if(!u){const e=zr(),t=JSON.stringify(e);await o.saveBlob(r,q,fe(t)),d=e}return{cachePath:s,processor:c,storedState:Object.freeze(d)}},oa=(e,t,n)=>{if(n.isTempStorage)return ra(e,t,n.fullStorageRoot);const r=Hr(),a=ea(e,t);return n.fullStorageRoot?r.getCacheLocation(a):a};const sa=()=>zr();var ca={onParentEvent:async(e,t,n,r)=>{const a=r.getState();return a.$$processor?.onParentEvent({sourcePort:e?.name||"",targetPort:t?.name||"",data:n.data},{getState:r.getState,recipeId:r.recipePoolId,recipeType:r.recipeType,setState:r.setState,nextWidget:r.nextGate})},getInputNames:(e,t)=>{const n={...sa(),...e};return n.$$processor?.getInputNames?n.$$processor.getInputNames(e,t):n.inputs.map((e=>({name:e.name,type:e.dataType})))},getOutputNames:(e,t)=>{const n={...sa(),...e};return n.$$processor?.getOutputNames?n.$$processor.getOutputNames(e,t):n.outputs.map((e=>({name:e.name,type:e.dataType})))},getDefaultState:sa,initialize:async(e,t)=>{console.log("Widget bundle initialize",e);let n={...e.getState()},r=n.$$cacheInfo?.widgetThingId||n.collectionInfo?.widgetId||e.widgetThingId;const a=n.$$cacheInfo?.version.toString()||n.collectionInfo?.version.toString()||1;if(n.$$cacheInfo={...n.$$cacheInfo,version:Number(a),widgetThingId:r},!r||!a)throw new Error("Widget bundle state is missing cache id or version");console.log("Loading state from cache");const i=aa(r,a);let o=!i;if(!n.$$processor)if(n.storageUnitId&&!i){const t=await e.getStorageData(n.storageUnitId);if(t){r=e.widgetThingId;const i=await ia(t,r,a);o=!0,i&&(n={...n,$$processor:i.processor,$$cacheInfo:{...n.$$cacheInfo,widgetThingId:r,version:Number(a)}},e.setState(n))}}else if(i){o=!1;const r=n.collectionInfo?{...n.collectionInfo}:void 0;n={...n,...!t.keepCurrentState&&i.storedState?{...i.storedState,...r?{collectionInfo:r}:{}}:{},$$processor:i.processor},e.setState(n)}const s=oa(r,a,{fullStorageRoot:!0,isTempStorage:o});console.log("Invoking bundle initialize with cache: ",s);try{await(n.$$processor?.initialize({cacheLocation:s,getState:e.getState,setState:e.setState}));const t=e.getState();e.setState({...t,$$initializationError:void 0})}catch(t){const n=e.getState();throw e.setState({...n,$$initializationError:t.message||"An error occurred initializing the widget"}),t}},terminate:async e=>{const t={...e.getState()};console.log(`Terminating widget bundle ${t.name} [${t.$$cacheInfo?.widgetThingId||""}]`);const n=t.$$processor;n&&"function"==typeof n.terminate&&await n.terminate({getState:e.getState,setState:e.setState,recipePoolId:e.recipePoolId,widgetId:e.widgetId})}};const ua=Object.freeze({event:"event"}),da="1",la="2",pa="3";var ga={onParentEvent:async(e,t,n,r)=>{const a={...r.getState()};r.setState({...a,$$lastEventType:n.data.type}),await r.nextGate(da,n.data),await r.nextGate(la,n.data),await r.nextGate(pa,n.data)},getInputNames:()=>[{name:ua.event,type:Q.Anything}],getOutputNames:e=>{const t={type:{...e}.$$lastEventType??Q.Anything};return[{name:da,...t},{name:la,...t},{name:pa,...t}]}};const ma=Object.freeze({set:"set",trigger:"trigger"}),va="value";var fa={onParentEvent:async(e,t,n,r)=>{const a=r.getState(),i={name:"myVar",type:Q.String,reactive:!0,defaultValue:"",...a};if(t.name.startsWith(X)){if(!i.reactive)return;if(n.data.type!==i.type)return;return r.nextWidget(va,n.data)}if(t.name!==ma.set){if(t.name===ma.trigger){const e=Qn(r.recipePoolId,r.thingRecipeId,i.name,{ownerWidgetId:r.id}),t=e||i.defaultValue;await r.nextWidget(va,{type:i.type,value:t})}}else await Zn(r.recipePoolId,r.thingRecipeId,r.id,i.name,n.data,{skipCallerNotification:!i.reactive})},getInputNames:e=>{const t={...e};return[{name:ma.set,type:t.type||Q.Anything},{name:ma.trigger,type:Q.Anything}]},getOutputNames:e=>{const t={...e};return[{name:va,type:t.type||Q.Anything}]}};let ya;var ha=e=>{ya=e},Ia=()=>{if(!ya)throw new Error("Hub Connector not set");return ya};const Sa=async(e,t=!1)=>{const n=Ia();let r=e.$$$serviceId;if(!e.service)return console.log("Aborting service initialization, missing property `service` in state."),null;if(!r||t){const t=await n.getCompatibleService(e.service.name,e.service.version,"^");if(!t)return null;r=t.sessionId}return r};var $a={onParentEvent:async(e,t,n,r)=>{const a={dynamicInputs:{},dynamicOutputs:{},customState:{},...r.getState()};if(!e)return;const i=Ia();let o=a.$$$serviceId;if(!o){const e=i.getCachedServices().find((e=>e.name===a.service?.name&&e.version===a.service?.version));if(!e)return;o=e.sessionId,a.$$$serviceId=o,r.setState(a)}const s=a.service?.variants?.find((e=>e.id===a.variantId)),c=s?a.dynamicInputs[s.id]||s?.inputs||[]:a.service?.inputs||[];if(!c?.length)return;if(!s&&a.service?.ignoreParentEvents)return;const u=a.service?.processingTimeoutSec;return i.onParentEvent({recipeId:r.recipePoolId,data:n.data,targetServiceSessionId:o,currentState:a.customState,targetVariantId:a.variantId,target:{portName:t.name,widgetId:r.id,widgetType:r.type},source:e,config:{timeout:u?1e3*u:0,async:a.service?.asyncParentEvents}})},getInputNames:async e=>{const t=e.variantId;if(t&&e.dynamicInputs?.[t])return[...e.dynamicInputs[t]||[]];if(!t)return e.service?.inputs||[];{const n=e.service?.variants?.find((e=>e.id===t));if(n)return n.inputs||[]}return[]},getOutputNames:async e=>{const t=e.variantId;if(t&&e.dynamicOutputs?.[t])return[...e.dynamicOutputs[t]||[]];if(!t)return e.service?.outputs||[];{const n=e.service?.variants?.find((e=>e.id===t));if(n)return n.outputs||[]}return[]},initialize:async e=>{const t={dynamicInputs:{},dynamicOutputs:{},customState:{},...e.getState()},n=Ia(),r=await Sa(t);if(r)try{return await n.initializeServiceInstance({recipeId:e.recipePoolId,sessionId:r,widgetId:e.widgetThingId,recipeType:e.recipeType,variantId:t.variantId})}catch(t){if("FNC_NOT_FOUND"!==t?.errCode){if(!!("string"!=typeof t||!t.match('^Function ".*" not found.$')))throw t;console.warn(`Widget [${e.widgetThingId}] does not have an init function.`)}}else console.log(`Aborting service initialization, "${t.service?.name}" was not found in the current Hub.`)},terminate:async e=>{const t={dynamicInputs:{},dynamicOutputs:{},customState:{},...e.getState()},n=Ia(),r=await Sa(t,!0);if(r)return n.terminateServiceInstance(r,e.widgetId,e.recipePoolId,t.variantId)}};const wa=Object.freeze({Image:"image"}),ba=Object.freeze({Image:"image"}),Na=()=>({filters:[{name:"grayscale",value:.5,id:"d-1"}]});const Aa={input:Ue,counter:Ge,elapsed:He,ifGate:Xe,skipEvent:Qe,between:rt,map:ot,parser:ut,slider:pt,suspend:vt,display:yt,json:St,arrayItem:bt,extractImage:jt,imageConvolution:Lt,firstEvent:Wt,pixelDraw:Vt,randomBetween:Kt,arrayCombine:en,clock:an,multiplication:un,object:vn,widgetGroup:In,script:gr,base64ToImageData:Ir,jsonParse:br,text:Cr,imageCrop:Dr,imageResize:Lr,value:Wr,imageWarp:Gr,widgetBundle:ca,sequence:ga,variable:fa,hubService:$a,imageFilter:{onParentEvent:async(e,t,n,r)=>{const a={filters:[{name:"grayscale",value:.5,id:"d-1"}],...r.getState()};if(t.name===wa.Image&&n.data.type===Q.ImageData){if(!he(n.data.value))return void console.log("ImageFilter: Invalid image data type, aborting process");const e=n.data.value;a.$$memCanvas||(a.$$memCanvas=xt(e.width,e.height)),a.$$context||(a.$$context=a.$$memCanvas.getContext("2d")),a.$$memCanvas.width!==e.width&&(a.$$memCanvas.width=e.width),a.$$memCanvas.height!==e.height&&(a.$$memCanvas.height=e.height),r.setState(a),a.$$context.putImageData(e,0,0),a.filters.length?a.$$context.filter=a.filters.map((e=>`${e.name}(${e.value}${"blur"===e.name?"px":""})`)).join(" "):a.$$context.filter="none",a.$$context.drawImage(a.$$memCanvas,0,0);const t=a.$$context.getImageData(0,0,e.width,e.height);return r.nextWidget(ba.Image,{type:Q.ImageData,value:t})}},getInputNames:()=>[{name:wa.Image,type:Q.ImageData}],getOutputNames:()=>[{name:ba.Image,type:Q.ImageData}],getDefaultState:Na},play:{getInputNames:()=>[],onParentEvent:()=>Promise.resolve(),getOutputNames:()=>[{name:"out",type:Q.Boolean}]}},xa={},Ca=async()=>{if(!Object.keys(xa).length)for(const e in Aa){const t=Aa[e];xa[e]=Object.freeze({...t})}};var Pa=e=>{if(xa[e])return xa[e];throw new Error(Be(Le,e))},Ea=Ca;const ja=new o,Da="invoked";let ka={},Oa={},Ta={},La={};const Ma=(e,t,n)=>`${e}-${t}${n?`-${n}`:""}`;var Ba=(e,t,n,r,a)=>{const i=Ma(e,t,n),o=Ma(e,t),s=Ma(e,t,"produced"),c=Ta[o],u=Date.now();La[o]=u,ka[i]={data:r,sourcePortName:n,...a?{target:{widgetId:a.widgetId,portName:a.portName}}:{}},ja.emit(s,{currentTime:u,prevTime:c,...a?{targetPort:a?.portName}:{}})},Ra=(e,t,n,r,a)=>{const i=Ma(e,t,n),o=Ma(e,t),s=Ma(e,t,Da),c=Ta[o],u=Date.now();Ta[o]=u,Oa[i]={data:r,sourcePortName:n,...a?{source:{widgetId:a.widgetId,portName:a.portName}}:{}},ja.emit(s,{prevTime:c,currentTime:u,targetPort:n,sourceInfo:a})},Wa=()=>{ka={},Oa={},Ta={},La={},ja.clearListeners()};let Ua,Fa,_a;const Ga=async(e,t,n,r,a)=>{const i=G(n,t);if(!i)return;const o=i.gates[e];if(!o||o.disabled)return;const s={...a,timestamp:Date.now()},c=Pa(o.type),u=Ja(e,s,i.recipeId,i.id,i.version,n);if(u&&c.onParentEvent){const t={name:r};return Ua&&await Ua({recipeId:n,blockId:i.recipeId,gateId:e,targetPort:t.name,data:a}),c.onParentEvent(null,t,{originalEvent:s,data:{...s}},u)}},za=async(e,t,n,r,a,i,o,s,c,u)=>{if(!e&&!c)throw new Error("Missing parameter ['sourceGateId']");if(!e&&!u)throw new Error("Missing parameter ['originalEvent']");e&&(u={timestamp:Date.now(),type:Q.Boolean,value:!0});const d=u;if("string"==typeof n){const e=G(r,n);if(!e)return;n=e}const l=n.gates[t];if(!l||l.disabled)return;const p=s.findIndex((e=>e.name===a)),g=Pa(l.type),m=Ja(t,d,n.recipeId,n.id,n.version,r);if(m&&g.onParentEvent&&-1!==p){Ua&&await Ua({recipeId:r,blockId:n.recipeId,gateId:t,targetPort:i.name,data:o,sourceGate:e?"interrupt_widget":c,sourcePort:e?H:a});const u={name:s[p].name,type:s[p].type,...s[p].jsonShape?{jsonShape:s[p].jsonShape}:void 0};return Ra(n.recipeId,t,i.name,o,c?{widgetId:c,portName:a}:void 0),g.onParentEvent(u,i,{originalEvent:d,data:o},m)}},Va=async(e,t,n,r,a,i,o,s)=>{const c=_(s);if(!c)throw new Error(`Failed to find recipe "${s}" in cache`);const u=c.dbInfo.recipeType,d=z(s,a,r);if(!d)return;const l={...n,timestamp:t.timestamp},p=Pa(d.type);let g;g=d.type===Ce.input?p.getOutputNames(d.state,{thingRecipeId:a,thingDbId:i,thingVersion:o,id:r,recipeId:s,recipeType:u,recipePoolId:s}):await p.getOutputNames(d.state,{recipePoolId:s,recipeType:u,thingRecipeId:a,widgetId:r});if(-1!==g.findIndex((t=>t.name===e))){const n=G(s,a);if(!n)return;Ba(a,r,e,l);const i=d.children.length;for(let o=0;o<i;o++){if(Ne(d.children[o]?.sourcePort).portName===e){const i=n.gates[d.children[o].childId];if(i&&!i.disabled){const c=Pa(i.type);let p;const m={recipePoolId:s,recipeType:u,thingRecipeId:a,widgetId:r};p=i.type===Ce.hubService?await c.getInputNames(i.state,m):c.getInputNames(i.state,m);const v=Ne(d.children[o].targetPort),f=p.find((e=>e.name===v.portName));f&&await za(!1,i.id,n,s,e,{name:f.name},d.returnOriginalEvent?t:l,g,d.id,t)}}}}},Ha=async(e,t,n,r)=>{const a=_(r);if(!a)return null;const i=G(r,n);if(!i)return i;const o=i.gates,s=i.gates[t],c=Pa(s.type),u=await c.getInputNames(s.state,{recipePoolId:r,recipeType:a.dbInfo.recipeType,thingRecipeId:n,widgetId:t}),d=u.findIndex((t=>t.name===e));if(-1!==d){const e=((e,t,n)=>{for(const r in n){const a=n[r],i=a.children.length;for(let n=0;n<i;n++){const r=a.children[n],i=Ne(r.targetPort);if(r.childId===e&&i.portName===t)return a}}return null})(t,u[d].name,o);if(e){const t=Pa(e.type);return{getValue:()=>"function"==typeof t.getValue?t.getValue():null}}}return null},Ja=(e,t,n,r,a,i)=>{const o=_(i);if(!o)throw new Error(`Failed to find recipe "${i}" in cache`);const s=z(i,n,e);if(!s)return console.warn(`Gate ${e} not found in block ${n} for recipe ${i}`),null;const c=async(o,s)=>Va(o,t,s,e,n,r,a,i),u={id:e,type:s.type,recipePoolId:i,thingRecipeId:n,recipeType:o.dbInfo.recipeType,returnOriginalEvent:!!s.returnOriginalEvent,registerInterrupt:(t,r,a,o,s)=>ke.createInterrupt(t,i,n,e,r,a,o,s),cancelInterrupt:e=>ke.destroyInterrupt(e),nextWidget:c,nextGate:c,getParentAtPort:t=>Ha(t,e,n,i),getState:()=>Object.freeze({...s.state,...s.type===Ce.input&&{customInputs:[]}}),setState:t=>{if("object"!=typeof t)return void console.warn(`Invalid state type [${typeof t}]. Expected an 'object'`);const r={...t,...s.type===Ce.input&&!t.customInputs&&{customInputs:[]}},a={...s.state};s.state=r,Fa&&Fa({blockId:n,gateId:e,prevState:a,newState:{...r},recipeId:i})}};return u};ke.setInvokeChildGateCb(za);const qa=new o,Ka="invoked",Xa="state",Ya=()=>{ke.destroyAllInterrupts()},Za=async(e,t,n)=>{const r=_(e),a=z(e,t,n);if(a&&r){const i=Pa(a.type);if(i&&"function"==typeof i.terminate){const a=((e,t,n,r)=>Oe(e,t,n,r))(e,r.dbInfo.recipeType,t,n);if(a)try{await i.terminate(a)}catch(e){console.warn(`Error terminating widget "${n}" in thing "${t}". Failing silently: `,e)}}}},Qa=async(e,t,n,r)=>{const a=_(e),i=z(e,t,n);if(i&&a){const o=Pa(i.type);if(o&&"function"==typeof o.initialize){const i=((e,t,n,r)=>Oe(e,t,n,r,!0))(e,a.dbInfo.recipeType,t,n);if(i){const e=o.initialize;try{await e(i,r||{})}catch(e){throw console.warn(`Error initializing widget "${n}" in thing "${t}": `,e),e}}}}},ei=(e,t)=>{const n=_(t);if(n)for(const t in n.blocks){const r=n.blocks[t];for(const t in r.gates)if(t===e)return{widget:r.gates[t],thing:r}}return null},ti=(e,t="",n="")=>`block:${t}:gate:${n||""}:${e}`,ni=e=>{qa.emit(ti(Xa),e),qa.emit(ti(Xa,e.blockId,e.gateId),e)};Ua=async e=>{await qa.emit(ti(Ka),e),await qa.emit(ti(Ka,e.blockId,e.gateId),e)},(e=>{Fa=e})(ni);var ri=async(e,t,n,r,a)=>{const i=V(e,{id:t,authorId:r,version:n,recipeType:a});Wa();const o=_(i);return o&&(o.startedAt=Date.now(),o.retryAttempts=0,o.execCounter=0,o.status=R.STARTING,o.addLog("recipe registered")),i},ai=async e=>{const t=_(e);var n;if(!t)return null;t.addLog("terminating recipe"),Ya();for(const n in t.blocks){const r=t.blocks[n];for(const t in r.gates)await Za(e,n,t)}W[n=e]&&delete W[n]},ii=async(e,t)=>{const n=_(e),r=[];if(n)for(const a in n.blocks){const i=n.blocks[a];if(!t||!Array.isArray(t)||t.includes(a))for(const t in i.gates)try{if(n.dbInfo?.recipeType===$n.Desktop){const e=i.gates[t];if(e.type===Ce.hubService){const r=e.state;if(r?.service?.webOnly){n?.addLog(`skipping initialization of web-only widget "${t}"`);continue}}}await Qa(e,a,t,{keepCurrentState:!0})}catch(e){r.push({widgetId:t,error:e.message})}}return{failed:r,sendToInputWidget:(t,n,r=Y)=>(async(e,t,n,r)=>{const a=_(n),i=G(n,r),o=Date.now();if(i&&a)for(const a in i.gates){const s=i.gates[a];if(s.type===Ce.input&&!s.disabled){const c=s.state.inputName||"";if(c===e){const e=Pa(s.type),u={...t,timestamp:o},d=Ja(a,u,r,i.id,i.version,n);if(d&&e.processEvent){const i={...d,getState:d.getState};Ua&&await Ua({recipeId:n,blockId:r,gateId:a,targetPort:We,data:t}),_a?await _a(r,n,c,t):await e.processEvent(u,i)}}}}})(t,n,e,r)}},oi=e=>{ha(e)},si=(e,t,n,r=!1)=>{const a=ei(t,e);if(a){const{widget:i,thing:o}=a,s={...i.state};i.state=n,r&&ni({blockId:o.recipeId,gateId:t,recipeId:e,newState:{...n},prevState:s})}},ci=(e,t)=>{const n=ei(t,e);return n?n.widget.state:null},ui=async(e,t,n,r,a)=>{const i=ei(t,e);if(i)return Va(n,r,a,t,i.thing.recipeId,i.thing.id,i.thing.version,e)};const di=e=>{try{return JSON.parse(e)}catch(e){return null}},li="undefined"!=typeof window,pi={protocolPrefix:4,protocolVersion:1,jsonLength:4,binaryLength:4,fromServiceId:4,toServiceId:4,sentAt:8},gi={protocolPrefix:4,txtLength:4},mi=Object.values(pi).reduce(((e,t)=>e+t),0),vi=Object.values(gi).reduce(((e,t)=>e+t),0),fi=["width","height","colorSpace"],yi=(e,t)=>{const n={},r=[];let a=0,i=Array.isArray(e)?[]:{};const o=(e,i)=>{const s=(e=>{const t="undefined"!=typeof Buffer&&e instanceof Buffer,n=e instanceof ArrayBuffer,r=e instanceof Uint8ClampedArray,a=e instanceof Uint8Array,i=e instanceof Int8Array;return t?"Buffer":n?"ArrayBuffer":r?"Uint8ClampedArray":a?"Uint8Array":i?"Int8Array":null})(e);if(!s){if(Array.isArray(e)){const t=[];for(let n=0;n<e.length;n++)t[n]=o(e[n],`${i}[${n}]`);return t}if("object"==typeof e){const t={},n=(e=>{const t=e instanceof Int16Array,n=e instanceof Uint16Array,r=e instanceof Int32Array,a=e instanceof Uint32Array,i=e instanceof Float32Array,o=e instanceof Float64Array,s=e instanceof BigInt64Array,c=e instanceof BigUint64Array;return t?"Int16Array":n?"Uint16Array":r?"Int32Array":a?"Uint32Array":i?"Float32Array":o?"Float64Array":s?"BigInt64Array":c?"BigUint64Array":null})(e);if(n)throw new Error(`Unsupported binary type [${n}] at path "${i}"`);for(const n in e)e.hasOwnProperty(n)||fi.includes(n)||console.warn(`Allowing inherited property: ${n} from path: ${i}`),t[n]=o(e[n],`${i.length?`${i}.`:""}${n}`);return t}return e}n[i]={index:a,length:e.byteLength,binaryType:s},"Buffer"===t?r.push(Buffer.from(e)):"ArrayBuffer"===s?r.push(e):r.push(e.buffer),a+=e.byteLength};i=o(e,"");let s=null;if(r.length>1)if("ArrayBuffer"===t){const e=r.reduce(((e,t)=>e+t.byteLength),0),t=new Uint8Array(e);let n=0;for(let e=0;e<r.length;e++)t.set(new Uint8Array(r[e]),n),n+=r[e].byteLength;s=t.buffer}else{s=Buffer.concat(r)}else 1===r.length&&(s=r[0]);return s?{map:n,combinedData:s,sourceCopy:i}:null},hi=(e,t,n)=>{const r=t.match(/(\[\d+\])|([^[\].]+)/g)||[];let a=e;for(let e=0;e<r.length;e++){let t=r[e];const i=t.startsWith("[")&&t.endsWith("]"),o=e===r.length-1;if(i){t=t.slice(1,-1);const i=parseInt(t,10);if(!Array.isArray(a))throw new Error(`Expected an array at key "${r.slice(0,e).join(".")}" but found an object.`);o?a[i]=n:(a[i]||(a[i]=r[e+1].startsWith("[")?[]:{}),a=a[i])}else o?a[t]=n:(a[t]||(a[t]=r[e+1].startsWith("[")?[]:{}),a=a[t])}return e},Ii=(e,t,n)=>{const r="undefined"!=typeof Buffer,a=t instanceof Uint8Array;for(const i in n)if(n.hasOwnProperty(i)){const{index:o,length:s,binaryType:c}=n[i];let u=null;if(r&&t instanceof Buffer)switch(c){case"Buffer":u=t.subarray(o,o+s);break;case"ArrayBuffer":u=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength).slice(o,o+s);break;case"Uint8Array":u=new Uint8Array(t.subarray(o,o+s));break;case"Uint8ClampedArray":u=new Uint8ClampedArray(t.subarray(o,o+s));break;case"Int8Array":u=new Int8Array(t.subarray(o,o+s))}else if(t instanceof ArrayBuffer||t instanceof Uint8Array)switch(c){case"Buffer":if(r){u=Buffer.from(t.slice(o,o+s));break}case"ArrayBuffer":u=a?t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength).slice(o,o+s):t.slice(o,o+s);break;case"Uint8Array":u=a?t.slice(o,o+s):new Uint8Array(t.slice(o,o+s));break;case"Uint8ClampedArray":u=new Uint8ClampedArray(t.slice(o,o+s));break;case"Int8Array":u=new Int8Array(t.slice(o,o+s))}u&&hi(e,i,u)}return e},Si=e=>d(e),$i="KMSG",wi="KCMD",bi=Si("klProtocol");var Ni={encode:(e,t,n)=>{const r={json:e.json},a=yi(r.json,"Buffer"),i=a?.combinedData;a&&(r.jsonBinaryMap=a.map,r.json=a.sourceCopy);const o=i?i.byteLength:0,s=JSON.stringify(r),c=Buffer.from(s),u=c.byteLength,d=pi.protocolPrefix+pi.protocolVersion+pi.jsonLength+pi.binaryLength+pi.fromServiceId+pi.toServiceId+pi.sentAt+u+o,l=Buffer.alloc(d),p=Date.now();let g=0;return l.write($i,g),g+=pi.protocolPrefix,l.writeUInt8(1,g),g+=pi.protocolVersion,l.writeUInt32LE(u,g),g+=pi.jsonLength,l.writeUInt32LE(o,g),g+=pi.binaryLength,l.writeUInt32LE(t,g),g+=pi.fromServiceId,l.writeUInt32LE(n,g),g+=pi.toServiceId,l.writeBigInt64LE(BigInt(p),g),g+=pi.sentAt,c.copy(l,g),g+=u,i&&o&&i.copy(l,g),l},decodeHeader:e=>{let t=0;const n=e.toString("utf-8",t,pi.protocolPrefix);if(t+=pi.protocolPrefix,n!==$i)return null;if(e.byteLength<mi)return bi(`Received a Partial Header with ${e.byteLength} bytes. Waiting for more data.`),{partialHeader:!0,remaining:null};const r=e.readUInt8(t);t+=pi.protocolVersion;const a=e.readUInt32LE(t);t+=pi.jsonLength;const i=e.readUInt32LE(t);t+=pi.binaryLength;const o=e.readUInt32LE(t);t+=pi.fromServiceId;const s=e.readUInt32LE(t);t+=pi.toServiceId;const c=e.readBigInt64LE(t);t+=pi.sentAt;const u=a+i,d=e.subarray(t,t+u),l=e.subarray(0,mi);let p=null;return e.byteLength-mi-a-i>0&&(p=e.subarray(mi+a+i)),{header:{protocolVersion:r,jsonLength:a,binaryLength:i,fromServiceId:o,toServiceId:s,sentAt:new Date(Number(c)),packages:[d],headerPackage:l},remaining:p}},decodeFullKlMessage:e=>{const t=Buffer.concat(e.packages),n=t.subarray(0,e.jsonLength).toString(),r=t.subarray(e.jsonLength,e.jsonLength+e.binaryLength),a=di(n);if(!a?.json)return bi("Invalid JSON in KL message"),null;a.jsonBinaryMap&&r.byteLength&&Ii(a.json,r,a.jsonBinaryMap);const i=Buffer.concat([e.headerPackage,t]);let o=i,s=null;const c=mi+e.jsonLength+e.binaryLength;return i.byteLength>c&&(s=i.subarray(c),o=i.subarray(0,c)),{message:{json:a.json,rawMessage:o},remaining:s}},patchEncodedHeader:(e,t)=>{if(null==t.fromServiceId&&void 0===t.toServiceId)return e;if(e.byteLength<mi)return bi("Invalid Header Size"),e;let n=0;return n+=pi.protocolPrefix,n+=pi.protocolVersion,n+=pi.jsonLength,n+=pi.binaryLength,void 0!==t.fromServiceId&&e.writeUInt32LE(t.fromServiceId,n),n+=pi.fromServiceId,void 0!==t.toServiceId&&e.writeUInt32LE(t.toServiceId,n),e},encodeCommand:e=>{let t=0;const n=Buffer.from(e),r=n.byteLength,a=vi+r,i=Buffer.alloc(a);return i.write(wi,t),t+=gi.protocolPrefix,i.writeUint32LE(r,t),t+=gi.txtLength,n.copy(i,t),i},decodeCommand:e=>{let t=0;if(e.byteLength<vi)return{command:null};const n=e.toString("utf-8",t,gi.protocolPrefix);if(t+=gi.protocolPrefix,n!==wi)return{command:null};const r=e.readUInt32LE(t);t+=gi.txtLength;const a=e.toString("utf-8",t,t+r),i=e.byteLength-vi-r;let o=null;i>0&&(o=e.subarray(vi+r));let s=0;return i<0&&(s=Math.abs(i)),{command:a,remainingData:o,missing:s}}};const Ai="KMSG",xi="KCMD",Ci=Si("klProtocol"),Pi=new TextEncoder;var Ei={encode:(e,t,n)=>{const r={json:e.json},a=yi(e.json,"ArrayBuffer"),i=a?.combinedData;a&&(r.jsonBinaryMap=a.map,r.json=a.sourceCopy);const o=i?i.byteLength:0,s=JSON.stringify(r),c=Pi.encode(s),u=c.byteLength,d=new ArrayBuffer(pi.protocolPrefix+pi.protocolVersion+pi.jsonLength+pi.binaryLength+pi.fromServiceId+pi.toServiceId+pi.sentAt+u+o),l=new DataView(d),p=new Uint8Array(d),g=Date.now();let m=0;for(let e=0;e<4;++e)p[m++]=Ai.charCodeAt(e);return l.setUint8(m,1),m+=pi.protocolVersion,l.setUint32(m,u,!0),m+=pi.jsonLength,l.setUint32(m,o,!0),m+=pi.binaryLength,l.setUint32(m,t,!0),m+=pi.fromServiceId,l.setUint32(m,n,!0),m+=pi.toServiceId,l.setBigInt64(m,BigInt(g),!0),m+=pi.sentAt,p.set(c,m),m+=u,i&&o&&p.set(new Uint8Array(i),m),d},decodeHeader:e=>{const t=new DataView(e);let n=0,r="";for(let e=0;e<pi.protocolPrefix;++e)r+=String.fromCharCode(t.getUint8(n++));if(r!==Ai)return null;if(e.byteLength<mi)return Ci.log(`Received a Partial Header with ${e.byteLength} bytes. Waiting for more data.`),{partialHeader:!0,remaining:null};const a=t.getUint8(n);n+=pi.protocolVersion;const i=t.getUint32(n,!0);n+=pi.jsonLength;const o=t.getUint32(n,!0);n+=pi.binaryLength;const s=t.getUint32(n,!0);n+=pi.fromServiceId;const c=t.getUint32(n,!0);n+=pi.toServiceId;const u=t.getBigInt64(n,!0);n+=pi.sentAt;const d=i+o,l=e.slice(n,n+d),p=new Uint8Array(e,0,mi);let g=null;if(e.byteLength-mi-i-o>0){g=new Uint8Array(e,mi+i+o).slice().buffer}return{header:{protocolVersion:a,jsonLength:i,binaryLength:o,fromServiceId:s,toServiceId:c,sentAt:new Date(Number(u)),packages:[l],headerPackage:p.slice().buffer},remaining:g}},decodeFullKlMessage:e=>{const t=e.packages.reduce(((e,t)=>e+t.byteLength),0),n=new Uint8Array(t);let r,a=0;for(const t of e.packages)r=new Uint8Array(t),n.set(r,a),a+=r.byteLength;const i=(new TextDecoder).decode(n.subarray(0,e.jsonLength)),o=n.subarray(e.jsonLength,e.jsonLength+e.binaryLength),s=di(i);if(!s?.json)return Ci.log("Invalid JSON in KL message"),null;s.jsonBinaryMap&&o.byteLength&&Ii(s.json,o,s.jsonBinaryMap);const c=new Uint8Array(e.headerPackage.byteLength+n.byteLength);c.set(new Uint8Array(e.headerPackage),0),c.set(n,e.headerPackage.byteLength);let u=c,d=null;const l=mi+e.jsonLength+e.binaryLength;return c.byteLength>l&&(d=c.subarray(l),u=c.subarray(0,l)),{message:{json:s.json,...o.length?{binaryData:o.buffer}:{},rawMessage:u.buffer},remaining:d?.buffer??null}},patchEncodedHeader:(e,t)=>{if(null==t.fromServiceId&&void 0===t.toServiceId)return e;if(e.byteLength<mi)return Ci("Invalid Header Size"),e;let n=0;n+=pi.protocolPrefix,n+=pi.protocolVersion,n+=pi.jsonLength,n+=pi.binaryLength;const r=new DataView(e);return void 0!==t.fromServiceId&&r.setUint32(n,t.fromServiceId,!0),n+=pi.fromServiceId,void 0!==t.toServiceId&&r.setUint32(n,t.toServiceId,!0),e},encodeCommand:e=>{let t=0;const n=Pi.encode(e),r=n.byteLength,a=new ArrayBuffer(vi+r),i=new DataView(a),o=new Uint8Array(a);for(let e=0;e<4;++e)o[t++]=xi.charCodeAt(e);return i.setUint32(t,r,!0),t+=gi.txtLength,o.set(n,t),a},decodeCommand:e=>{const t=new DataView(e);let n=0;if(e.byteLength<vi)return{command:null};let r="";for(let e=0;e<gi.protocolPrefix;++e)r+=String.fromCharCode(t.getUint8(n++));if(r!==xi)return{command:null};const a=t.getUint32(n,!0);n+=gi.txtLength;const i=e.byteLength-vi-a,o=new Uint8Array(e,n,Math.min(a,e.byteLength-vi)),s=(new TextDecoder).decode(o);let c=null;i>0&&(c=e.slice(vi+a));let u=0;return i<0&&(u=Math.abs(i)),{command:s,remainingData:c,missing:u}}};let ji=Ni;li&&(ji=Ei);var Di,ki=ji;!function(e){e.FunctionNotFound="FNC_NOT_FOUND"}(Di||(Di={}));let Oi=Math.ceil(Date.now()/1e3);function Ti(e){const t={};let n=console.log;const r={};let a=e||String(Date.now());const i={},o=e=>!i[e],s=(e,t,n,r,a,i)=>{let s=li?new ArrayBuffer(0):Buffer.alloc(0);const c={json:{functionName:e,args:i.success?i.success:[i],messageId:t,type:i.success?"response":"error"}};return o(r)&&(s=ki.encode(c,n,r)),a(s,{msg:c,sourceServiceId:n,targetServiceId:r})};return{setLogger:e=>{n=e},processMessage:(e,a,i,o)=>{if(!o)return!1;const c=o;if(t[c.messageId]){const e=t[c.messageId];return e&&(clearTimeout(e.timer),e.fulfilled||(e.fulfilled=!0,"response"===c.type?e.resolve(c.args):"error"===c.type&&e.reject(c.args[0])),delete t[c.messageId]),!0}if("execute"!==c.type&&n&&n(`No pending execution found for message id "${c.messageId}"`),"execute"===c.type){const t=r[c.functionName];if(t){const n=e=>{s(c.functionName,c.messageId,i.targetServiceId,i.sourceServiceId,a,e)};t({transport:e,args:c.args,reply:n,messageId:c.messageId,sourceServiceId:i.sourceServiceId,send:a})}else{const e=`Function "${c.functionName}" not found.`;n&&n(e),s(c.functionName,c.messageId,i.targetServiceId,i.sourceServiceId,a,{error:e,errCode:"FNC_NOT_FOUND"})}return!0}return!1},execute:async(e,r,i,s,c,u)=>{if(!i){const e="No send buffer function provided.";throw n&&n(e),e}Oi+=1;const d=`${a}-${Oi}-exec-${e.substring(0,10)}`,l={messageId:d,functionName:e,send:i,sourceServiceId:s,targetServiceId:c,args:r||[],fulfilled:!1,resolve:()=>{},reject:()=>{}};l.promise=new Promise(((e,t)=>{l.resolve=e,l.reject=t}));let p=li?new ArrayBuffer(0):Buffer.alloc(0);const g={json:{functionName:e,args:r,messageId:d,type:"execute"}};o(c)&&(p=ki.encode(g,s,c)),t[d]=l,n&&n(`Calling remote function "${e}" with message id "${d}"`);const m="true"===process.env.NO_INVOKE_TIMEOUT;return u?.async?(l.fulfilled=!0,l.resolve([void 0]),delete t[d]):0===u?.timeout||m||(l.timer=setTimeout((()=>{n&&n(`Remote function ${d} timed out`);const r=t[d];r&&!r.fulfilled&&(r.fulfilled=!0,l.reject(`Function ${e} Timed out`)),delete t[d]}),u?.timeout||3e4)),i(p,{sourceServiceId:s,targetServiceId:c,msg:g}),l.promise},sendResponse:s,registerFunction:(e,t)=>{r[e]=t},getTransportSendFunction:e=>{const n=t[e];return n?n.send:null},setServiceName:e=>{a=e},getPendingExecutions:()=>t,rejectAllPending:e=>{Object.keys(t).forEach((n=>{const r=t[n];r&&!r.fulfilled&&(clearTimeout(r.timer),r.fulfilled=!0,r.reject(e),delete t[n])}))},broadcast:(e,t,r,i)=>{Oi+=1;const s=`${a}-${Oi}-multicast-${e.substring(0,10)}`;let c=li?new ArrayBuffer(0):Buffer.alloc(0);const u={json:{functionName:e,args:t,messageId:s,type:"execute"}};let d=o(r[0].serviceId);d&&(c=ki.encode(u,i,r[0].serviceId));for(let t=0;t<r.length;t++)try{const a=r[t];n&&n(`Broadcasting function "${e}" with message id "${s}" to client [${a.serviceId}]`),0!==t&&(d=o(a.serviceId),d&&(c=ki.patchEncodedHeader(c,{toServiceId:a.serviceId}))),a.sendFn(c,{msg:u,sourceServiceId:i,targetServiceId:a.serviceId})}catch(e){n&&n(`Error broadcasting to client at index ${t}`)}},disableServiceEncoding:(e,t)=>{i[e]=t}}}let Li,Mi,Bi,Ri,Wi,Ui=!1;var Fi=()=>{Ui=!0},_i=(e,t)=>{if(!Li)throw new Error("Memory connection not set.");Li.sendBuf(e,t)},Gi=e=>Mi=e,zi=e=>Wi=e,Vi=e=>Bi=e,Hi=e=>Ri=e,Ji=e=>(Li.sendCmd(e),!0);const qi=(e,t=2)=>{const n=(e,r)=>{if("object"==typeof e){const a=Object.keys(e);for(const i of a){const a=e[i];if(a&&"object"==typeof a){const o=a._kemuType;if(void 0!==o){if(o===Q.ImageData){const t=e[i];e[i]=Ae(t)}}else r<t&&n(a,++r)}}}};return n(e,1),e},Ki=Si("klTransmissionManager"),Xi=()=>{const e=(t,n,r,a)=>{let i=n,o=null;const s=t instanceof ArrayBuffer;if(Ki(`RAW: ${t.toString()}`),!i||i.partialHeaderData){let c;if(s?(c=i?.partialHeaderData?new Uint8Array([...new Uint8Array(i.partialHeaderData),...new Uint8Array(t)]).buffer:t,o=Ei.decodeHeader(c)):(c=i?.partialHeaderData?Buffer.concat([i.partialHeaderData,t]):t,o=Ni.decodeHeader(c)),!o){const{command:t,missing:i,remainingData:o}=s?Ei.decodeCommand(c):Ni.decodeCommand(c);return t?a({command:t,complete:!0,rawMessage:c}):Ki(i?`ERROR: Missing ${i} bytes to complete the command. This partial command will be aborted.`:`ERROR: Invalid state, message was decoded without a header or partial header data. Discarding ${c.byteLength} bytes`),o?(Ki(`${o.byteLength} bytes remain after processing command. Re-analyzing...`),e(o,n,r,a)):void 0}if(o.partialHeader)return i={firstPackageAt:Date.now(),partialHeaderData:c},r(i);if(!o.header)return Ki(`ERROR: Invalid state, message was decoded without a header or partial header data. Discarding ${c.byteLength} bytes`);const u=o.header;i={firstPackageAt:Date.now(),header:{...u,totalBytesReceived:u.packages[0].byteLength,totalBytesExpected:u.binaryLength+u.jsonLength,remaining:o.remaining}},r(i)}else i.header&&i.header.totalBytesReceived<i.header.totalBytesExpected&&(i.header.packages.push(t),i.header.totalBytesReceived+=t.byteLength,r(i));if(i.header&&i.header.totalBytesReceived>=i.header.totalBytesExpected){const t=Date.now()-i.header.sentAt.getTime(),n=Date.now()-i.firstPackageAt;Ki(`Received ${i.header.totalBytesReceived} of ${i.header.totalBytesExpected} expected in ${t} ms, elapsed since first package: ${n}ms`);const o=s?Ei.decodeFullKlMessage(i.header):Ni.decodeFullKlMessage(i.header),c=i.header.totalBytesReceived,u=i.header.remaining;r(null),o&&a({klMessage:o.message,complete:!0,sourceServiceId:i.header.fromServiceId,targetServiceId:i.header.toServiceId,rawMessage:o.message.rawMessage});let d=u;if(o?.remaining&&(d=s?u?((e,t)=>{const n=e.byteLength+t.byteLength,r=new ArrayBuffer(n),a=new Uint8Array(e),i=new Uint8Array(t),o=new Uint8Array(r);return o.set(a),o.set(i,a.length),r})(u,o.remaining):o.remaining:u?Buffer.concat([u,o.remaining]):o.remaining),d)return Ki(`${d.byteLength} bytes remaining after processing message with ${c} bytes of data. Re-analyzing...`),e(d,null,r,a)}};return e};Si("ipcClient");Si("kemuWidgetService"),$(process.argv.slice(2));const Yi=e=>d(`runner:${e}`),Zi=Yi("connectionManager"),Qi=Yi("remoteInvoke"),eo=new Ti("kweb");eo.setLogger(Qi);const to=new o,no=new o;let ro,ao=null,io=null;const oo={},so=(e,t,n)=>{const r=`${e}_${t}`,a={contents:n,lastRequestedAt:Date.now(),contentsChecksum:""};return oo[r]=a,a},co=(e,t)=>oo[`${e}_${t}`]||null,uo=async(e,t)=>{if(!ao)return Zi("Hub Link has not been acknowledged. Cannot get services."),null;const n=[{serviceName:e,version:t}];return(await eo.execute(re.GetServiceContents,n,po,ao,0))[0]},lo=async(e,t,n=!1)=>{if(!e||!t)return null;const r=co(e,t);if(!r||n){const n=r||so(e,t);try{const r=await uo(e,t);return r&&(n.contents=r.uiContent,n.contentsChecksum=r.uiContentsChecksum||""),n.contents||null}catch(n){Zi(`Failed to fetch service contents for ${e} v${t}`,n)}}return r?.contents||null},po=_i,go=()=>{Zi("Disconnected from the server"),ao=null,eo.rejectAllPending("Disconnected from the server"),to.emit("disconnected")},mo=()=>{Zi("Connected to the server"),to.emit("connected")},vo=()=>io,fo=(e,t,n,r)=>`${e}_${t}_${n}_${r}`,yo=async()=>{const e=vo();if(e){const t=_(e)?.blocks;if(t){const n={};for(const r in t){const a=t[r];for(const t in a.gates){const r=a.gates[t];if(r.type===Ce.hubService){const t=r.state;if(t.service?.eventEmitter){const r=`${t.service.name}_${t.service.version}`;if(!n[r])try{Zi(`Re-issuing subscription for service ${t.service.name} (${t.service.version})`),n[r]=!0,await Do({listener:{recipeId:e},targetService:{serviceName:t.service.name,version:t.service.version}})}catch(e){Zi(`Failed to re-issue subscription for service ${t.service.name} (${t.service.version})`,e)}}}}}}}},ho=async e=>{const t=e.args[0],n=fo("broadcast",`hub_${t.type}`,(0).toString(),"");await no.emit(n,t)},Io=async e=>{const t=e.args[0];for(const e of t.outputs||[])e.type===Q.ImageData&&he(e.value)&&(e.value=Ae(e.value));const n=vo();if(n){const r=_(n);if(r){const a=async e=>{const n=fo("broadcast",t.source.serviceName,t.source.serviceVersion,e);try{await no.emit(n,t)}catch(t){Zi(`Failed to emit broadcast event for target ${e}`,t)}};await a("app");for(const i in r.blocks){const o=r.blocks[i];for(const r in o.gates){const i=o.gates[r];if(i.disabled)continue;const s=i.state;if(i.type===Ce.hubService&&s.service?.name===t.source.serviceName&&s.service?.version===t.source.serviceVersion&&s.variantId===t.variantId){await a(r);for(const a of t.outputs||[])if(null!==a.value&&void 0!==a.value){const t={type:a.type,value:a.value,timestamp:Date.now()};Zi(`Sending data to output ${a.name} requested by messageId ${e.messageId}`),await ui(n,r,a.name,t,t)}}}}}}},So=async e=>{const t=e.args[0],{finalState:n,recipeId:r,widgetId:a}=t,i=ci(r,a);let o=i;if(n&&o&&i&&(o={...i,customState:n},si(r,a,o,!0)),o?.service)try{const e=fo("setOutputs",o.service.name,o.service.version,a);await no.emit(e,t.outputs)}catch(e){Zi(`Failed to emit setOutputs event for widget ${a}`,e)}for(const n of t.outputs)if(null!==n.value&&void 0!==n.value){if(n.type===Q.ImageData){if(!he(n.value)){Zi(`Invalid ImageData value received for output ${n.name}. Expected an ImageData-like object`);continue}n.value=Ae(n.value)}else n.type===Q.JsonObj&&qi(n.value);const t={type:n.type,value:n.value,timestamp:Date.now()};Zi(`Sending data to output ${n.name} requested by messageId ${e.messageId}`),await ui(r,a,n.name,t,t)}e.reply({success:[]})},$o=async e=>{const t=e.args[0],{newState:n,recipeId:r,widgetId:a}=t,i=ci(r,a);if(i){const t={...i,customState:{...i.customState,...n}};return si(r,a,t,!0),e.reply({success:[]})}},wo=async({args:e,reply:t})=>{const n=e[0],{recipeId:r,widgetId:a,path:i,key:o}=n;Zi(`Received request to set a dependency path for "${o}" on widget "${a}" in recipe "${r}"`);const s=ci(r,a);if(s){const e={...s};e.dependencies=e.dependencies||{},e.dependencies[o]={path:i},si(r,a,e,!0)}return t({success:[]})},bo=async({args:e,reply:t})=>{const n=e[0],{recipeId:r,widgetId:a,key:i}=n;Zi(`Received request to get a dependency path for "${i}" on widget "${a}" in recipe "${r}"`);const o=ci(r,a);if(o){const e=o.dependencies?.[i]?.path;return Zi(`Returning dependency path for "${i}" on widget "${a}": "${e}"`),t({success:[e||null]})}return t({error:"Widget not found",errCode:"WIDGET_NOT_FOUND"})},No=async()=>{if(Zi(`Requesting services on ${(new Date).toISOString()}`),!ao)return Zi("Hub Link has not been acknowledged. Cannot get services."),[];const e=await eo.execute(re.GetServices,[],po,ao,0);ro=e;for(const t of e){if(t.internal)continue;const e=co(t.name,t.version);if(!e||e?.contentsChecksum!==t.uiContentChecksum)try{const n=e||so(t.name,t.version);Zi(`Service ${t.name} v${t.version} contents have changed, fetching new contents`);const r=await uo(t.name,t.version);r&&(n.contents=r.uiContent,n.contentsChecksum=t.uiContentChecksum||"")}catch(e){Zi(`Failed to update service contents for ${t.name} v${t.version}`,e)}}return e},Ao=()=>[...ro||[]],xo=()=>!!ro,Co=async e=>{const{targetServiceSessionId:t}=e;if(!ao)return void Zi("No target service session id provided");Zi(`Forwarding "onParentEvent" to service ${t}`);return await eo.execute(re.OnParentEvent,[e],po,ao,t,e.config)},Po=async e=>{if(!ao)return Zi("Hub Link has not been acknowledged. Cannot get services."),{};const[t]=await eo.execute(re.GetDefaultState,[],po,ao,e);return t},Eo=async(e,t,n,r)=>{if(!ao)return Zi("Hub Link has not been acknowledged. Cannot get services."),null;const[a]=await eo.execute(re.UIEvent,[t,n],po,ao,e,r);return a},jo=(e,t)=>{const n=()=>{t()};return to.on(e,n),()=>to.off(e,n)},Do=async e=>{if(ao)return eo.execute(re.SubscribeToService,[e],po,ao,0);Zi("Hub Link has not been acknowledged. Cannot subscribe to services.")},ko=async e=>{if(ao)return eo.execute(re.UnsubscribeFromService,[e],po,ao,0);Zi("Hub Link has not been acknowledged. Cannot subscribe to services.")},Oo=(e,t,n,r)=>{const a=fo("broadcast",t,n,e);return no.on(a,r)},To=(e,t,n,r)=>{const a=fo("setOutputs",t,n,e);return no.on(a,r)},Lo=async(e,t,n)=>ao?eo.execute(e,t,po,ao,0,n):(Zi("Hub Link has not been acknowledged. Cannot execute function."),null),Mo=async e=>{if(!ao)return void Zi("Hub Link has not been acknowledged. Cannot execute function.");const t=ci(e.recipeId,e.widgetId);if(!t)throw new Error("Widget or recipe pool not found. Cannot initialize service instance.");const n=Object.keys(t.dependencies||{}).reduce(((e,n)=>(e[n]=t.dependencies?.[n]?.path||null,e)),{}),r=[{currentState:t.customState,recipeId:e.recipeId,widgetId:e.widgetId,variantId:e.variantId,recipeType:e.recipeType,currentDependencies:n}],[a]=await eo.execute(re.InitializeInstance,r,po,ao,e.sessionId);if(a){const t=ci(e.recipeId,e.widgetId);if(t){const n={...t,customState:a};si(e.recipeId,e.widgetId,n,!0)}}},Bo=async(e,t,n,r)=>{if(!ao)return void Zi("Hub Link has not been acknowledged. Cannot execute function.");const a=ci(n,t);if(!a)throw new Error("Widget or recipe pool not found. Cannot initialize service instance.");const i=[{currentState:a.customState,recipeId:n,widgetId:t,variantId:r}];await eo.execute(re.TerminateInstance,i,po,ao,e)},Ro=async(e,t,n="^",r)=>{const a=["^","~",">=",">","<=","<","="];if(!a.includes(n))throw new Error(`Invalid compare mode "${n}". Must be one of ${a.join(", ")}`);const i=xo(),o=r||!i?await No():Ao();for(const r of o)if(r.name===e){if(r.version===t)return r;if(c(r.version,`${n}${t}`))return r}return null};var Wo=async()=>{Vi(mo),Hi(go),zi((({json:e,transmission:t})=>{eo.processMessage("websocket",po,t,e)})),eo.registerFunction(re.SetState,$o),eo.registerFunction(re.SetOutputs,So),eo.registerFunction(re.BroadcastEvent,Io),eo.registerFunction(re.HubBroadcastEvent,ho),eo.registerFunction(ae.SetDependencyPath,wo),eo.registerFunction(ae.GetDependencyPath,bo),Gi((e=>{((e,t)=>{const n=ne.SocketAcknowledge,r=ne.IpcAcknowledge,a=e.startsWith(n);if(e===r)return t&&t(),0;if(a){const i=e.split(a?n:r),o=parseInt(i[1]);return t&&t(o),o}})(e,(e=>{e?(Ji((e=>`${ne.AcknowledgeResponse}${e}`)(e)),Zi("Hub Link acknowledged"),ao=e,to.emit("acknowledged"),yo()):Zi("Hub sent ACK request without service id")})),((e,t)=>{e===ne.ServicesListChanged&&(t&&t())})(e,(()=>{Zi("Services list changed"),to.emit("services-changed")}))})),await Fi()},Uo=(e,t)=>{to.on(e,t)},Fo=()=>({getServices:No,getServiceContents:lo,onParentEvent:Co,onCommand:jo,getDefaultState:Po,getCachedServices:Ao,areServicesCached:xo,subscribeToServiceEvents:Do,unsubscribeFromServiceEvents:ko,callProcessorHandler:Eo,onBroadcastEvent:Oo,onSetOutputsEvent:To,executeHubFunction:Lo,initializeServiceInstance:Mo,terminateServiceInstance:Bo,getCompatibleService:Ro}),_o=e=>{io=e},Go=()=>eo;const zo=e=>{try{return JSON.parse(e)}catch(e){return null}},Vo=(e,t)=>{if(e.startsWith(ne.AcknowledgeResponse)){const n=e.split(":"),r=parseInt(n[1]),a=parseInt(n[2]);return t&&t(r,isNaN(a)?void 0:a),!0}return!1},Ho=e=>d(e),Jo=Date.now();let qo=Math.ceil(Jo/1e3);var Ko=()=>qo+=1;const Xo=p(x(),"kemu-user-services"),Yo="KMU-CB-v1";var Zo;!function(e){e.input="input",e.counter="counter",e.play="play",e.elapsed="elapsed",e.ifGate="ifGate",e.skipEvent="skipEvent",e.between="between",e.map="map",e.parser="parser",e.slider="slider",e.suspend="suspend",e.display="display",e.pixelfy="pixelfy",e.json="json",e.arrayItem="arrayItem",e.extractImage="extractImage",e.imageConvolution="imageConvolution",e.firstEvent="firstEvent",e.pixelDraw="pixelDraw",e.randomBetween="randomBetween",e.arrayCombine="arrayCombine",e.clock="clock",e.multiplication="multiplication",e.object="object",e.widgetGroup="widgetGroup",e.script="script",e.base64ToImageData="base64ToImageData",e.jsonParse="jsonParse",e.text="text",e.imageCrop="imageCrop",e.imageResize="imageResize",e.value="value",e.imageWarp="imageWarp",e.widgetBundle="widgetBundle",e.sequence="sequence",e.variable="variable",e.hubService="hubService"}(Zo||(Zo={}));const Qo=e=>({...e,type:Array.isArray(e.type)?e.type.map((e=>Q[e])):Q[e.type]}),es=async e=>{try{return await f(e,"utf-8")}catch(e){return null}},ts=e=>{if(e&&e.startsWith(Yo)){const t=e.slice(9),n=decodeURI(t);return zo(n)}return null},ns=async(e,t,n)=>{let r=[];e.variants?.length&&(r=e.variants.map((e=>({...e,...e.inputs?{inputs:e.inputs.map(Qo)}:{},...e.outputs?{outputs:e.outputs.map(Qo)}:{}}))));const a={...e,path:t,customWidgets:[],...e.inputs?{inputs:e.inputs.map(Qo)}:{inputs:[]},...e.outputs?{outputs:e.outputs.map(Qo)}:{outputs:[]},variants:r,...e.widgetUI&&n?.widgetUIContents?{widgetUIContents:n.widgetUIContents}:{}},i=await(async(e,t,n=console.log)=>{const r=[];if(t.customWidgets?.length)for(const a of t.customWidgets){const t=await es(p(e,a));if(!t){n(`Error loading custom widget file ${a}`);continue}const i=t.startsWith(Yo)?t:`${Yo}${t}`,o=ts(i);if(!o){n(`Custom widget file "${a}" is not a valid Kemu Clipboard item`);continue}const s=Object.values(o).filter((e=>e.type===Zo.widgetGroup&&!e.groupId));if(s.length>1){n(`Custom widget file "${a}" contains more than one top level widgetGroup`);continue}const c=s[0];if(!c){n(`Custom widget file "${a}" does not contain a top level widgetGroup`);continue}const u=c.state,d={name:u.name,color:u.color,description:u.description,contents:i,rootGroupId:c.id,icon:u.icon,protocolVersion:u.protocolVersion||"2"};r.push(d)}return r})(t,e,n?.log);if(i.length?a.customWidgets=i:delete a.customWidgets,a.variants?.length)for(const e of a.variants)if(e.svgIcon)try{const n=await f(p(t,e.svgIcon),"utf-8");e.svgIcon=n}catch(t){n?.log&&n?.log(`Error loading svgIcon for variant ${e.id}: ${t}`)}return a},rs=async e=>{try{return await y(e,h.F_OK),!0}catch{return!1}},as=Ho("serviceManager"),is={};let os=null;const ss=e=>{if(!os)throw new Error('IPC config not set, call "setHubIpcConfig" first.');try{if(e.processor===te.Javascript){as(`Spawning service ${e.name} with sessionId ${e.sessionId}`);const t=l.join(e.path,"processor.js"),n=[`--sessionId=${e.sessionId.toString()}`,`--ipcSpace=${os.appSpace}`,`--ipcId=${os?.id}`,`--recipePath=${os.recipePath||""}`];e.internal&&n.push("--internal=true");const r=N("node",[t,...n]);return r.stdout.on("data",(t=>{as(`[Service ${e.name}] - stdout: ${t}`)})),r.stderr.on("data",(t=>{as(`[Service ${e.name}] - stderr: ${t}`)})),as(`[Service ${e.name}] spawned with PID ${r.pid}`),r}throw`Unsupported processor type ${e.processor}`}catch(t){throw`Error spawning service ${e.name}: ${t}`}},cs=e=>{if(!e?.name)return"Missing name";if(!e?.version)return"Missing version";if(!e?.description)return"Missing description";if(!e?.processor)return"Missing processor";return[te.Javascript,te.Executable,te.Python].includes(e?.processor)?null:"Invalid processor"},us=async(e,t)=>{const n=l.join(e,"manifest.json");if(!w.existsSync(n)){const t=`Missing manifest for service ${e}. Aborting.`;return as(t),{error:t}}const r=await f(n,"utf-8"),a=zo(r),i=cs(a);if(!a||i){const t=`Invalid service manifest [${e}]: ${i}. Aborting.`;return as(t),{error:t}}let o;if(delete a.internal,t?.singleServiceName&&a.name!==t.singleServiceName){return{error:`Skipping service ${a.name} as it does not match the singleServiceName option`}}await Promise.all([(async()=>{if(a.widgetUI)try{o=await f(l.join(e,"widgetUI.js"))}catch(e){const t=`Error loading widgetUI file ${a.name}: ${e}`;return as(t),{error:t}}})(),(async()=>{if(a.svgIcon){const t=await es(l.join(e,a.svgIcon));if(!t){return{error:`Error loading icon for service ${a.name}`}}a.svgIcon=t}})(),(async()=>{if(a.subServices?.length)for(const t of a.subServices){const n=l.join(e,t),{error:r,service:i}=await us(n);r?as(`Error loading sub-service ${t}: ${r}`):i&&(i.info.parentService={name:a.name,version:a.version})}delete a.subServices})(),(async()=>{if(a.variants?.length)for(const t of a.variants)if(t.svgIcon)try{const n=await f(l.join(e,t.svgIcon),"utf-8");t.svgIcon=n}catch(e){as(`Error loading svgIcon for variant ${t.id}: ${e}`)}})()]);const s=Ko(),c=t?.fixedSession||s;as(`Loaded service ${a.name} with sessionId ${c}`);const u=await ns(a,e,{widgetUIContents:o});return ds(u),is[c]={info:{...u,path:e,sessionId:c},status:"loaded",childProcess:null},{service:is[c]}},ds=e=>{e.widgetUIContents?e.uiContentChecksum=(e=>{const t=A("sha256");return t.update(e),t.digest("hex")})(e.widgetUIContents):e.uiContentChecksum=void 0},ls=e=>{try{return e.childProcess=ss(e.info),e.status="started",!0}catch(t){return as(`Service [${e.info.name}] error: ${t}`),e.status="error",e.errorMsg="string"==typeof t?t:JSON.stringify(t),!1}},ps=()=>Object.values(is).filter((e=>"running"===e.status)).map((e=>{const{path:t,...n}=e.info;return{...n}})),gs=(e,t)=>{const n=Object.values(is).find((n=>n.info.name===e&&n.info.version===t));if(!n)return null;if(n.info.internal)throw`Cannot stop internal service ${e}`;if(n.childProcess){as(`Stopping service "${e} (v${t})"`);n.childProcess.kill("SIGINT")||as(`Failed to stop service ${e}`)}return n.status="stopped",as(`Service ${e} stopped`),n},ms=e=>e.info.internal?e.info.path:l.join(e.info.path,"..");var vs={loadServices:async(e,t)=>{if(!await rs(e))return void as(`Failed to load services from "${e}". Directory does not exist.`);const n=w.readdirSync(e,{withFileTypes:!0}).filter((e=>e.isDirectory())).map((e=>e.name));as(`Found ${n.length} services in "${e}"`);for(let r=0;r<n.length;r++){const a=n[r],i=l.join(e,a),{error:o,service:s}=await us(`${i}${t?.internalServices?"":"/dist"}`,t);o&&as(`Failed to load service ${i}. Please check logs`),s&&t?.internalServices&&(s.info.internal=!0)}},launchServices:async e=>{if(as("Initializing services"),!os)throw new Error('IPC config not set, call "setHubIpcConfig" first.');for(const t in is){const n=is[t];e.noSpawningList&&e.noSpawningList.includes(n.info.name)?as(`Service ${n.info.name} is in the noSpawningList. Skipping.`):ls(n)}as("Services initialized")},setServiceStatus:(e,t)=>{const n=is[e];return n?(n.status=t,!0):(as(`Service with serviceId ${e} not found`),!1)},getActiveServices:ps,getMatchingService:(e,t)=>{const n=Object.values(is).filter((e=>"running"===e.status));for(const r of n)if(r.info.name===e){if(r.info.version===t)return r;if(u(r.info.version,t,">="))return r}return null},getServiceBySessionId:e=>is[e]||null,killAllServices:()=>{for(const e in is){const t=is[e];if(t.childProcess)try{as(`Killing service ${t.info.name} with PID ${t.childProcess.pid}`),t.childProcess.kill()}catch(e){as(`Error killing service ${t.info.name}: ${e}`)}}},addDevService:async(e,t,n)=>{const r={info:{...await ns(t,t.path),sessionId:e},status:n,startedAt:new Date,devMode:!0,childProcess:null};is[e]=r,ds(is[e].info)},setServiceManifest:(e,t,n)=>{const r=is[e];if(!r)return as(`Service with sessionId ${e} not found`),!1;const a=cs(t);if(a)return as(`Invalid manifest for service ${r.info.name}: ${a}`),!1;ds(t),r.info={...r.info,...t},n&&(r.status=n)},getMatchingDevService:(e,t,n)=>{const r=Object.values(is).filter((e=>e.devMode));for(const a of r)if(a.info.name===e&&a.status===n&&a.info.version===t)return a;return null},getInternalServices:()=>ps().filter((e=>e.internal)),getAllServices:()=>Object.values(is),stopService:gs,uninstallService:async(e,t)=>{as(`Uninstalling service ${e} v${t}`);const n=gs(e,t);if(!n)return!1;as(`Service ${e} stopped. Removing from disk...`);const r=ms(n),a=Xo;return r.startsWith(a)?(await I(r,{recursive:!0,force:!0}),as(`Service ${e} successfully removed from disk`),(e=>{const t=is[e];delete is[e]})(n.info.sessionId),!0):(as(`Service ${e} is not installed in the user services directory. Aborting.`),!1)},getAllServiceVersions:e=>Object.values(is).filter((t=>t.info.name===e)),setHubIpcConfig:e=>{os={...e}},loadAndLaunch:async(e,t,n)=>{const r=g(e,t),{error:a,service:i}=await us(r);if(a||!i)return{error:a};try{i.info.internal=!!n,i.childProcess=ss(i.info),i.status="started"}catch(e){as(`Error launching service ${i.info.name}: ${e}`),i.status="error",i.errorMsg="string"==typeof e?e:JSON.stringify(e)}return{service:i}},getServiceRootDirectory:ms};var fs={id:"widgets",retry:1500,silent:!0,rawBuffer:!0,appspace:"kemu.",encoding:"hex"};const ys=Object.values({protocolPrefix:4,protocolVersion:1,jsonLength:4,binaryLength:4,fromServiceId:4,toServiceId:4,sentAt:8}).reduce(((e,t)=>e+t),0);v.config={...v.config,...fs};const hs=Ho("ipcServer");let Is,Ss,$s,ws,bs={};const Ns=Xi(),As=e=>{bs[e]&&(hs(`Client disconnected [${e}]`),delete bs[e],Ss&&Ss(e))};var xs=e=>(e?.ipcId&&(v.config.id=e.ipcId),e?.ipcAppSpace&&(v.config.appspace=e.ipcAppSpace),new Promise((e=>{v.serve((()=>{hs("IPC Server Initiated"),v.server.on("data",((e,t)=>{const n=bs[t.id];n?(hs(`IPC Socket [${t.id}] data ${e.byteLength} bytes`),Ns(e,n.activeMessage,(e=>n.activeMessage=e),(e=>{if(!e.complete)return;const n=e=>{t.write(e)};if(e.command)return hs(`Received command from client [${t.id}]: ${e.command}`),void($s&&$s(t.id,e.command,n));e.klMessage&&ws&&ws({send:n,transmission:{sourceServiceId:e.sourceServiceId??-1,targetServiceId:e.targetServiceId??-1,rawMessage:e.rawMessage},json:e.klMessage.json})}))):hs(`Received data from unknown client [${t.id}]. Ignoring.`)})),v.server.on("connect",(e=>{const t=Ko();hs(`New client connected. Registered as "${t}"`),e.id=t,bs[t]={socket:e,activeMessage:null,disconnectHandler:()=>As(t)},e.on("close",bs[t].disconnectHandler),Is&&Is(t)})),v.server.on("disconnect",(e=>{As(e.id)})),v.server.on("error",(e=>{console.log(`IPC Server Error: ${e}`)})),e()})),v.server.start()}))),Cs=e=>{Is=e},Ps=e=>{Ss=e},Es=e=>ws=e,js=(e,t)=>{const n=bs[e];if(!n)return hs(`Cannot send message to unknown client [${e}]`),!1;if(t.length>=ys)return hs("Message is too long to be a command. Use sendMessage instead."),!1;const r=Ni.encodeCommand(t);return n.socket.write(r),!0},Ds=(e,t)=>{const n=bs[e];return!!n&&(delete bs[e],n.socket.id=t,bs[t]=n,n.socket.removeListener("close",n.disconnectHandler),n.disconnectHandler=()=>As(t),n.socket.on("close",n.disconnectHandler),!0)},ks=e=>{$s=e};const Os=Ho("websocketServer"),Ts={},Ls=Xi();let Ms,Bs,Rs,Ws,Us;var Fs=e=>{Us=new C({port:e,maxPayload:104857600}),Us.on("connection",(e=>{const t=Ko();Os(`New client connected. Registered as "${t}"`),e.id=t,Ts[t]={socket:e,activeMessage:null},Ms&&Ms(t),e.on("message",(t=>{if(t instanceof Buffer){const n=Ts[e.id];Ls(t,n.activeMessage,(e=>n.activeMessage=e),(t=>{if(!t.complete)return;const r=t=>{e.send(t),Os(`Writing ${t.byteLength} bytes to socket [${n.socket.id}]: ${t.toString()}`)};if(t.command)return Os(`Received command from client [${n.socket.id}]: ${t.command}`),void(Rs&&Rs(n.socket.id,t.command,r));t.klMessage&&Ws&&Ws({send:r,transmission:{sourceServiceId:t.sourceServiceId??-1,targetServiceId:t.targetServiceId??-1,rawMessage:t.rawMessage},json:t.klMessage.json})}))}})),e.on("close",(()=>{Os(`Client disconnected: ${e.id}`),Bs&&Bs(e.id),delete Ts[e.id]})),e.on("error",(()=>{Os(`Error on client connection: ${e.id}`)}))})),console.log(`WebSocket server is running on port ${e}`)},_s=e=>{Ms=e},Gs=e=>{Bs=e},zs=e=>{Rs=e},Vs=(e,t)=>{const n=Ts[e];if(!n)return Os(`Cannot send message to unknown client [${e}]`),!1;if(t.length>=ys)return Os("Message is too long to be a command. Use sendMessage instead."),!1;const r=Ni.encodeCommand(t);return n.socket.send(r),!0},Hs=e=>Ws=e;const Js=Ho("stopService"),qs=async e=>{const t=e.args[0];if(!t)return e.reply({error:"No service name provided"});const n=vs.getAllServiceVersions(t);Js(`Stopping ${n.length} services with name: ${t}`);for(const e of n)await vs.stopService(e.info.name,e.info.version);const r=n.map((e=>`${e.info.name}@${e.info.version}`));e.reply({success:[r]})},Ks=Ho("removeService"),Xs=async e=>{const t=e.args[0],n=e.args[1];if(!t)return e.reply({error:"No service name provided"});let r=vs.getAllServiceVersions(t);n&&(r=r.filter((e=>e.info.version===n))),Ks(`Removing ${r.length} service(s) with name: ${t}`);for(const e of r)await vs.uninstallService(e.info.name,e.info.version);const a=r.map((e=>`${e.info.name}@${e.info.version}`));e.reply({success:[a]})},Ys=Ho("launchService"),Zs=async e=>{const t=e.args[0],n=e.args[1];if(!t)return e.reply({error:"No service name provided"});if(!n)return e.reply({error:"No service version provided"});const r=`${t}@${n}/dist`;try{Ys(`Loading service ${t}@${n} from ${Xo}`);const{error:a,service:i}=await vs.loadAndLaunch(Xo,r,!1);if(a||!i)return e.reply({error:`Failed to launch service ${t}@${n}: ${a||"error-not-provided"}`});if("error"===i.status)return e.reply({error:`Error launching service: "${i.errorMsg||"unknown-error"}"`});const o=Date.now(),s=3e4,c=async()=>{const r=i.status;return"running"===r?(Ys(`Service ${t}@${n} loaded and started`),e.reply({success:[]})):(Ys(`Service ${t}@${n} not yet started, status: ${r}`),"stopped"===r||"error"===r?e.reply({error:`Error launching service: "${i.errorMsg||"failed to initiate"}"`}):Date.now()-o>s?e.reply({error:"Timeout waiting for service to start"}):(Ys("Retrying in 1 second..."),void setTimeout(c,1e3)))};c()}catch(r){return Ys(`Error loading service ${t}@${n}: ${r?.message||r}`),e.reply({error:r?.message||"There was an error loading the service"})}},Qs=Ho("getMatchingServices"),ec=async e=>{const t=e.args[0],n=[],r=[];Qs(`Checking for matching services: ${t.map((e=>e.name)).join(", ")}`);for(const{name:e,version:a}of t){const t=vs.getMatchingService(e,a);t?n.push({name:e,version:a,installationPath:vs.getServiceRootDirectory(t)}):r.push({name:e,version:a})}Qs(`Found ${n.length} available services and ${r.length} missing services.`),e.reply({success:[{available:n,missing:r}]})},tc=Ho("getServiceContents"),nc=({reply:e,args:t})=>{const[n]=t;tc(`Received GetServiceContents request for service ${n.serviceName} v${n.version}`);const r=vs.getMatchingService(n.serviceName,n.version);if(r){return e({success:[{serviceName:r.info.name,serviceVersion:r.info.version,uiContent:r.info.widgetUIContents,uiContentsChecksum:r.info.uiContentChecksum}]})}tc(`Service ${n.serviceName} v${n.version} not found`),e({error:`Service ${n.serviceName} v${n.version} not found`})},rc=Ho("activeClients");let ac={},ic={};const oc=(e,t)=>`${e}_${t}`,sc=e=>ac[e]||null,cc=(e,t)=>{const n=oc(e,t);return ic[n]||[]},uc=()=>{for(const e in ac){const t=ac[e];if(t.transport===ie.WS){const e=Ni.encodeCommand(ne.ServicesListChanged);t.send(e)}}},dc=(e,t,n,r,a)=>{const i=[];ac[e]={serviceSessionId:e,transport:t,isDevClient:!!a,broadcastSubscriptions:i,send:n,extraInfo:r,addSubscription:t=>{if(!i.some((e=>e.targetService.serviceName===t.serviceName&&e.targetService.version===t.version))){i.push({targetService:t});const r=oc(t.serviceName,t.version);ic[r]=ic[r]||[];return ic[r].some((t=>t.serviceId===e))||ic[r].push({sendFn:n,serviceId:e}),!0}return!1},removeSubscription:t=>{const n=i.findIndex((e=>e.targetService.serviceName===t.serviceName));if(-1!==n){i.splice(n,1);const r=oc(t.serviceName,t.version),a=ic[r]?.findIndex((t=>t.serviceId===e));if(-1!==a&&(ic[r].splice(a,1),!ic[r].length)){const e=vs.getMatchingService(t.serviceName,t.version);if(e?.info.eventEmitter&&"running"===e.status){const t=sc(e.info.sessionId);t?.extraInfo.ipcSocketId&&js(t?.extraInfo.ipcSocketId,ne.BroadcastEnd)}}}},removeAllSubscriptions:()=>{for(const t of i){const n=oc(t.targetService.serviceName,t.targetService.version),r=ic[n].findIndex((t=>t.serviceId===e));-1!==r&&ic[n].splice(r,1)}i.length=0}},t===ie.IPC&&(uc(),pc(e))},lc=()=>{const e=Object.values(ac);for(const t of e)if(t.transport===ie.IPC){const e=t.extraInfo.ipcSocketId,n=vs.getServiceBySessionId(t.serviceSessionId);if(n?.info.eventEmitter){cc(n.info.name,n.info.version).length||e&&js(e,ne.BroadcastEnd)}}},pc=e=>{const t=vs.getServiceBySessionId(e);if(t?.info.eventEmitter){if(cc(t.info.name,t.info.version).length){const t=sc(e);t?.extraInfo.ipcSocketId&&js(t?.extraInfo.ipcSocketId,ne.BroadcastStart)}}},gc=e=>{const t=ac[e];delete ac[e],t.transport===ie.IPC?uc():(t.removeAllSubscriptions(),lc())},mc=Ho("ipc:handleIpcClientCommand"),vc=(e,t,n)=>{!Vo(t,((t,r)=>{if(!t)return void mc(`Ignoring ACK response from IPC service ${e} with no service id`);mc(`Received ACK from IPC service ${t}. Marking as running.`);const a=vs.setServiceStatus(r||t,"running");r&&t&&e!==r&&Ds(e,r),a?dc(r||t,ie.IPC,n,{ipcSocketId:r}):js(e,ne.SendManifest)}))&&mc(`Received unknown command [${t}] from service ${e}`)},fc=Ho("nativeApi"),yc=e=>new Promise(((t,n)=>{j(e,((e,r,a)=>{const i=a.includes("User cancelled")||a.includes("User canceled");if(a&&!i)return n(a);t(r)}))})),hc={chooseDirectoryDialog:async e=>{const t=`\n var app = Application.currentApplication(); \n app.includeStandardAdditions = true; \n var chosenFolder = app.chooseFolder({ \n withPrompt: "${e.args[0].title||"Please select a directory"}" \n }); \n\n chosenFolder.toString();\n `;fc("Showing chooseDirectoryDialog");const n=await yc(`osascript -l JavaScript -e '${t.trim()}'`);return fc(`Chosen directory: ${n}`),e.reply({success:[String(n).trim()]})},chooseFileDialog:async e=>{const t=e.args[0],n=`\n var app = Application.currentApplication(); \n app.includeStandardAdditions = true; \n var chosenFile = app.chooseFile({ \n withPrompt: "${t.title||"Please select a file"}",\n multipleSelectionsAllowed: ${t.allowMultiple?"true":"false"},\n }); \n\n chosenFile.toString();\n `;fc("Showing chooseFileDialog");const r=await yc(`osascript -l JavaScript -e '${n.trim()}'`);return fc(`Chosen file: ${r}`),e.reply({success:[String(r).trim()]})}},Ic={chooseDirectoryDialog:async e=>{e.reply({error:"Not Supported"})},chooseFileDialog:async e=>{e.reply({error:"Not Supported"})}};let Sc;Sc="win32"===E.platform()?Ic:hc;var $c=Sc;const wc=Ho("getUniqueId"),bc=({reply:e,sourceServiceId:t})=>{wc(`Generating unique id for service "${t}"`);return e({success:[D()]})},Nc=m(P(import.meta.url)),Ac=Ho("hub"),xc=new Ti("hub");xc.setLogger(Ac);const Cc=(e,t)=>{const{transmission:n}=t;if(0!==n.targetServiceId){const r=sc(n.targetServiceId);if(!r)return Ac(`Service [${e}] ${n.sourceServiceId} is sending data to an unknown service ["${n.targetServiceId}"]`),!0;r.transport,ie.IPC;const a=t.json?.messageId;return Ac(`Forwarding message from ${n.sourceServiceId} to ${n.targetServiceId}, msgId: ${a}`),r.send(n.rawMessage,{sourceServiceId:n.sourceServiceId,targetServiceId:n.targetServiceId,msg:{json:t.json}}),!0}return!1},Pc=({sourceServiceId:e,args:t})=>{const n=vs.getServiceBySessionId(e);if(n){const r=cc(n.info.name,n.info.version),a=cc(n.info.name,"*");if(!r.length&&!a.length)return;const i=[...r,...a],o=t[0],s={outputs:o.outputs,variantId:o.variantId,source:{serviceName:n.info.name,serviceVersion:n.info.version,sessionId:e}};xc.broadcast(re.BroadcastEvent,[s],i,0)}},Ec=e=>{const{send:t,transmission:n,json:r}=e;Ac(`Raw message Id received from WS: ${r?.messageId}`);Cc(ie.WS,e)||xc.processMessage(ie.WS,t,n,r)},jc=e=>{const t=(n=e,`${ne.SocketAcknowledge}${n}`);var n;Vs(e,t)},Dc=(e,t,n)=>{!Vo(t,(t=>{if(Ac(`Received ACK from WS service ${t}. Marking as running.`),e!==t)throw new Error(`Received ACK from service ${t} but expected ${e}`);dc(t,ie.WS,n,{websocketId:e})}))&&Ac(`Received unknown command [${t}] from service ${e}`)},kc=e=>{Ac(`WS Client ${e} disconnected`),gc(e)},Oc=async({sourceServiceId:e,args:t,transport:n,send:r})=>{if(n!==ie.IPC){var a;Ac(`Received manifest from non IPC service ${e}.`)}else{const n=t[0];if(n.devMode){const t=vs.getMatchingDevService(n.name,n.version,"stopped");if(t){Ac(`Found matching previous service ${t.info.name} (${t.info.version}). Reactivating previous client with session id ${t.info.sessionId}`);const i=sc(t.info.sessionId);if(!i)return void Ac(`Could not find previous client instance for ${t.info.name} (${t.info.version}). Aborting manifest injection`);i.send=r,ac[a=e]?delete ac[a]:rc(`Could not find source client with session id ${a}`),Ds(e,t.info.sessionId);const o=await ns(n,n.path);t.info={...t.info,...o},Ac(`Updating manifest for dev service ${t.info.sessionId}`),vs.setServiceManifest(t.info.sessionId,o,"running"),Ac(`Asking service ${e} to assume previous session id ${t.info.sessionId}`),js(t.info.sessionId,(e=>`${ne.AssumeSession}${e}`)(t.info.sessionId)),(e=>{const t=ac[e];t?t.isDevClient?(t.disconnected=!1,t.transport===ie.IPC&&(uc(),pc(e))):rc(`Client with session id ${e} is not a dev client`):rc(`Could not find source client with session id ${e}`)})(t.info.sessionId)}else{vs.addDevService(e,n,"running");const t=sc(e);t?t.isDevClient=!0:dc(e,ie.IPC,r,{ipcSocketId:e},!0)}return}Ac(`Received manifest from non dev service ${e}. Ignoring...`)}};var Tc=async e=>{Ac("Starting Kemu Hub...");const t=e?.ipc?.appSpace||"kemu.",n=e?.ipc?.id||"widgets";xc.registerFunction(re.GetServiceContents,nc),xc.registerFunction(re.GetServices,(({transport:e,sourceServiceId:t,reply:n})=>{if(Ac(`Received GetServices request from ${e} [${t}]`),e===ie.WS){n({success:vs.getActiveServices().map((e=>{const{widgetUIContents:t,...n}=e;return{...n}}))})}})),xc.registerFunction(re.UnsubscribeFromService,(({transport:e,reply:t,args:n,sourceServiceId:r})=>{if(e===ie.WS){const[e]=n,a=sc(r);if(!a)return t({error:`Session id "${r}" not found`});Ac(`Service ${r} unsubscribing from "${e.targetService.serviceName} (${e.targetService.version})"`),t({success:[]}),a?.removeSubscription({serviceName:e.targetService.serviceName,version:e.targetService.version})}})),xc.registerFunction(re.SubscribeToService,(({transport:e,reply:t,args:n,sourceServiceId:r})=>{if(e===ie.WS){const[e]=n,a=sc(r),i=e.targetService;if(!a)return t({error:`Session id "${r}" not found`});if(Ac(`Service ${r} subscribing to "${i.serviceName} (${i.version})"`),"hub"===i.serviceName)return a.addSubscription(i),void t({success:[]});if(!a.addSubscription(i))return Ac(`Service ${r} already subscribed to "${i.serviceName} (${i.version})", ignoring request.`),t({success:[]});const o=vs.getMatchingService(i.serviceName,i.version);if(!o)return Ac(`Service ${i.serviceName} ${i.version} not active yet`),t({success:[]});if(!o.info.eventEmitter)return Ac(`Service ${i.serviceName} ${i.version} does not have an event emitter, removing subscription`),a.removeSubscription(i),t({error:`Service "${i.serviceName} (${i.version})" does not produce events`});const s=sc(o.info.sessionId);return s?.extraInfo.ipcSocketId&&(Ac(`Sending Broadcast START command to service ${o.info.sessionId}`),js(s?.extraInfo.ipcSocketId,ne.BroadcastStart)),t({success:[]})}})),xc.registerFunction(re.BroadcastEvent,Pc),xc.registerFunction(re.ServiceManifest,Oc),xc.registerFunction("stopService",qs),xc.registerFunction("removeService",Xs),xc.registerFunction("launchService",Zs),xc.registerFunction("getMatchingServices",ec),xc.registerFunction(re.ChooseDirectoryDialog,$c.chooseDirectoryDialog),xc.registerFunction(re.ChooseFileDialog,$c.chooseFileDialog),xc.registerFunction(re.GetUniqueId,bc),Es((e=>{const{send:t,transmission:n,json:r}=e;Ac(`Raw message Id received from IPC: ${r?.messageId}`);Cc(ie.IPC,e)||xc.processMessage(ie.IPC,t,n,r)})),Hs(Ec),_s(jc),zs(Dc),Gs(kc),ks(vc),Cs((e=>{const t=(n=e,`${ne.IpcAcknowledge}${n}`);var n;js(e,t)})),Ps((e=>{Ac(`IPC socket [${e}] disconnected`);const t=sc(e);if(t){Ac(`Found matching service for disconnected socket. SessionId: ${t.serviceSessionId}`);const e=vs.getServiceBySessionId(t.serviceSessionId);vs.setServiceStatus(t.serviceSessionId,"stopped"),e?.devMode?(t.disconnected=!0,uc()):gc(t.serviceSessionId)}})),await xs({ipcAppSpace:t,ipcId:n}),e?.ws?.disabled||await Fs(e?.ws?.port||8080);const r=l.resolve(Nc,"defaultServices"),a=process.env.DEV_SESSION_ID;vs.setHubIpcConfig({recipePath:e?.recipeRootPath,appSpace:t,id:n}),e?.noDefaultServices||await vs.loadServices(r,{fixedSession:a?parseInt(a):void 0,singleServiceName:process.env.DEV_SINGLE_SERVICE_NAME,internalServices:!0}),await rs(Xo)||await S(Xo,{recursive:!0}),null!==e?.servicesInstallPath&&await vs.loadServices(e?.servicesInstallPath||Xo,{internalServices:!1,singleServiceName:process.env.DEV_SINGLE_SERVICE_NAME});const i=process.env.DEV_NO_SPAWN_LIST?.split(",");await vs.launchServices({noSpawningList:i||[]}),Ac("Kemu Hub started")},Lc=e=>{if(e===ie.WS)return{handleWebsocketConnectionEvent:jc,handleWebsocketClientDisconnectionEvent:kc,handleWebsocketMessage:Ec,handleWebsocketClientCommand:Dc,getRemoteInvoke:()=>xc}},Mc=(e=[])=>{let t;const n=new Promise((n=>{const r=()=>{if(vs.getAllServices().every((e=>"running"===e.status))){if(e.every((e=>"running"===vs.getMatchingService(e.name,e.version)?.status)))return n()}t=setTimeout(r,100)};r()}));return n.abort=()=>{t&&clearTimeout(t)},n};let Bc;const Rc=Yi("run"),Wc=Fo(),Uc=1e3,Fc=$(process.argv.slice(2));global.ImageData=L,At({createCanvas:(e,t)=>B(e,t)});const _c={createImageDataLike:(e,t,n,r="srgb")=>{let a;return a=e instanceof Uint8ClampedArray?e:new Uint8ClampedArray(e),{data:a,width:t,height:n,colorSpace:r,_kemuType:Q.ImageData}},loadImageFile:async e=>{const t=await M(e),n=B(t.width,t.height).getContext("2d");n.drawImage(t,0,0,t.width,t.height);return n.getImageData(0,0,t.width,t.height)}};var Gc={start:async n=>{const r=n?.recipePath||Fc.recipePath||process.env.KEMU_EDGE_RECIPE_PATH;if(!r)throw new Error("`recipePath` not provided. Please specify it in the config object, via a command line argument [--recipePath] or as an environment variable [KEMU_EDGE_RECIPE_PATH].");const a=r.endsWith(".json"),i=a?k(r):r,o=a?r:O(i,"recipe.json"),s=(e=>{try{return JSON.parse(e||"")}catch(e){return null}})(await e(T(o),"utf-8"));if(!s)throw new Error("Failed to parse recipe file");await Ea();const c={id:s.id||String(Date.now()),version:1,author:""};(e=>{or=e})(console);const u=Lc(ie.WS),d=(e,t)=>{if(t)u?.handleWebsocketMessage({send:p,transmission:{rawMessage:e,sourceServiceId:t.sourceServiceId,targetServiceId:t.targetServiceId},json:t.msg?.json});else{const t=e instanceof Buffer?e.toString():e;u?.handleWebsocketClientCommand(Uc,t,p)}},l=(Li={instanceServiceId:Uc,sendBuf:d,sendCmd:d,triggerOnCommand:(...e)=>Mi(...e),triggerOnConnected:()=>Bi(),triggerOnDisconnected:()=>Ri(),triggerOnMessageReceived:(...e)=>Wi(...e)},Li);const p=(e,t)=>{if(t)l.triggerOnMessageReceived({send:d,transmission:{rawMessage:e,sourceServiceId:t.sourceServiceId,targetServiceId:t.targetServiceId},json:t.msg.json});else{const t=e instanceof Buffer?e.toString():e;l.triggerOnCommand(t)}},g=Go(),m=u.getRemoteInvoke();g.disableServiceEncoding(0,!0),m.disableServiceEncoding(Uc,!0);const v=Object.values(s.blocks[Y].gates).filter((e=>e.type===Ce.hubService&&e.state.service&&!0!==e.state.service?.webOnly)),f=v.map((e=>{const t=e.state.service;return{name:t.name,version:t.version}})),y=O(i,"services"),h=await t(y).then((()=>!0)).catch((()=>!1));await Tc({recipeRootPath:i,servicesInstallPath:h?O(i,"services"):null,noDefaultServices:!0,ws:{disabled:!0},ipc:{appSpace:"kemu-runner.",id:c.id}}),Rc("Waiting for services to run"),await Mc(f),Rc("All services are running"),oi(Wc);const I=await ri(s,"runner",c.version,c.author,$n.Desktop);return Bc=I,_o(I),await Wo(),new Promise(((e,t)=>{var n;Uo("acknowledged",(async()=>{await Wc.getServices();const{failed:n,sendToInputWidget:r}=await ii(I);if(n.length>0){const e=`Some widgets failed to initialize: ${n.join(", ")}`;return t(e)}Rc("Recipe started"),e({sendToInputWidget:r})})),l.triggerOnConnected(),l.triggerOnCommand((n=Uc,`${ne.SocketAcknowledge}${n}`))}))},terminate:async()=>{Bc&&await ai(Bc)}};void 0===typeof process.env.BLOCKS_INSTALL_DIR&&console.warn("Missing `BLOCKS_INSTALL_DIR` env var");process.env.BLOCKS_INSTALL_DIR;export{Q as DataType,Gc as default,_c as utils};
|