@microtronics/studio-cli 1.2.1-rc.0 → 1.2.1
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/dist/main.js +1 -1
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -2195,7 +2195,7 @@ ${p0}
|
|
|
2195
2195
|
`).forEach(v=>{this.onConsole(v)}),x=""}for(let F=r.length-1;F>=0;F--)Date.now()>r[F].start+XB&&r.splice(F,1)}}isHex(x){return/^[a-fA-F0-9]*$/.test(x)}onConsole(x){if(!(x[0]===""&&x[1]==="#"&&x.length<10)){if(x[0]===""&&x[1]==="."&&x.length<10050){let[A,e]=x.substr(2).split("=");if(A.length>1&&A.length<50){["~~","~h","~g","~i","~r","~s"].includes(A)||(this.emit("#watch",{key:A,value:e,date:new Date}),this.logger.debug(`#watch ${A} = ${e}`));return}}this.formatConsoleLine(x)}}process_x01(x,A){if(x.length<11)return;let e=x.substr(1,4);if(!this.isHex(e))return;let r=x.substr(-5,4);if(!this.isHex(r))return;let t=parseInt(e,16),i=parseInt(r,16),n=65535&(A<0?0:t-A),F=65535&i-t-x.length;if(n&&this.onConsole(`?console - x01 ${n} characters lost`),A=i,F){this.onConsole(`?console - x01 ${F} characters lost (dropped "${x}")`);return}this.onConsole(x[0]+x.slice(5,-5))}dispose(){this.atHandler.off("data",this.dataHandler),this.removeAllListeners()}};function QA(x){return parseInt(x.slice(6),16)}function fA(x){return"400000"+x.toString(16).toUpperCase().padStart(10,"0")}function s8(x){return x?new Uint8Array(x):null}function Cn(x){return{...x,data:s8(x.data)}}function Ui(x){return{...x,data:s8(x.data)}}var ZB=/^400000[0-9A-F]{10}$/;function uF(x,A){if(!ZB.test(A))throw new Error(`MemoryStorage: uto_data row for tag ${x} has non-canonical stamp "${A}"; expected 16-char uppercase hex output of stamp40ToDbHex ("400000" + 10 hex digits)`)}var xC=class a8{constructor(){A0(this,"metadata",new Map),A0(this,"utoData",new Map),A0(this,"changeRequests",[]),A0(this,"files",new Map)}async getMetadataValue(A){return this.metadata.get(A)??null}async setMetadataValue(A,e){this.metadata.set(A,e)}async deleteMetadataValue(A){this.metadata.delete(A)}async getUtoDataTags(){return[...this.utoData.keys()]}async getLatestStampForTag(A){let e=this.utoData.get(A);return!e||e.size===0?null:[...e.keys()].sort().at(-1)}async getRowForTag(A){let e=await this.getLatestStampForTag(A);return e===null?null:Cn(this.utoData.get(A).get(e))}async replaceUtoRow(A){uF(A.tag,A.stamp),this.utoData.set(A.tag,new Map([[A.stamp,Cn(A)]]))}async insertHistoricRows(A){for(let e of A){uF(e.tag,e.stamp);let r=this.utoData.get(e.tag);r||(r=new Map,this.utoData.set(e.tag,r)),r.has(e.stamp)||r.set(e.stamp,Cn(e))}}async getHistoricRows(A,e){let r=this.utoData.get(A);if(!r)return[];let t=[...r.values()];if(e.fromStamp!==void 0){let n=e.fromStamp;t=t.filter(F=>F.stamp>=n)}if(e.untilStamp!==void 0){let n=e.untilStamp;t=t.filter(F=>F.stamp<=n)}t.sort((n,F)=>e.order==="desc"?F.stamp.localeCompare(n.stamp):n.stamp.localeCompare(F.stamp));let i=e.offset??0;return t.slice(i,i+e.limit).map(Cn)}async getUtoChangeRequests(){return[...this.changeRequests].sort((A,e)=>A.tag-e.tag||A.stamp.localeCompare(e.stamp)).map(A=>({...A}))}async insertUtoChangeRequests(A){for(let e of A)this.changeRequests.push({tag:e.tag,stamp:fA(e.stamp40),user:e.user??"",json:e.json})}async clearUtoChangeRequests(){this.changeRequests=[]}async getFiles(){return[...this.files.values()].map(Ui)}async getFile(A){let e=this.files.get(A);return e?Ui(e):null}async upsertFile(A){this.files.set(A.filename,Ui(A))}async deleteFile(A){this.files.delete(A)}toJSON(){let A=[];for(let e of this.utoData.values())for(let r of e.values())A.push({tag:r.tag,stamp:r.stamp,flags:r.flags,site_related:r.site_related,data:r.data?gn(r.data):null});return{metadata:Object.fromEntries(this.metadata),utoData:A,changeRequests:this.changeRequests.map(e=>({...e})),files:[...this.files.values()].map(e=>({filename:e.filename,stamp:e.stamp,crc:e.crc,size:e.size,flags:e.flags,flags_int:e.flags_int,data:e.data?gn(e.data):null}))}}static fromJSON(A){let e=new a8;for(let[r,t]of Object.entries(A.metadata??{}))e.metadata.set(r,t);for(let r of A.utoData??[]){let t=e.utoData.get(r.tag);t||(t=new Map,e.utoData.set(r.tag,t)),t.set(r.stamp,{tag:r.tag,stamp:r.stamp,flags:r.flags,site_related:r.site_related,data:r.data?ts(r.data,`uto_data.data of tag ${r.tag}`):null})}e.changeRequests=(A.changeRequests??[]).map(r=>({...r}));for(let r of A.files??[])e.files.set(r.filename,{filename:r.filename,stamp:r.stamp,crc:r.crc,size:r.size,flags:r.flags,flags_int:r.flags_int,data:r.data?ts(r.data,`files.data of "${r.filename}"`):null});return e}},AC=new Set(["link","unknown"]);function _t(x){return AC.has(x)}var o8=-2;function Ce(x){return x.index===o8}var eC=65535,DF={configa:4294928218,configb:4294928219,configc:4294928220};function ys(x){let A=x.toLowerCase();if(A==="histdata"||A==="histdata0")return"histdata0";let e=/^rm2mconfig([0-9a-c])$/.exec(A);return e?`config${e[1]}`:x}function wn(x){let A=ys(x.trim()).toLowerCase();return Object.prototype.hasOwnProperty.call(DF,A)?DF[A]:z0.containerIdToTag(A,!1)}function yt(x){return wn(x.name)}function rC(x,A){let e=x.byNameOrAlias(A);return wn(e?e.name:A)}function F8(x){return Number.isInteger(x)&&x>=0&&x<=eC}var tC={u8:"u8",s8:"s8",u16:"u16",s16:"s16",u32:"u32",s32:"s32",s64:"s64",f32:"f32",f64:"f64",floatm16:"floatm16",stamp4:"stamp4",stamp:"stamp",stamp8:"stamp8",datetime:"datetime",ufm8:"ufm8",link:"link",string:"string",float:"f32",float32:"f32",float64:"f64",char:"string",bint:"s8",wint:"s16",dint:"s32",qint:"s64",byte:"u8",word:"u16",dword:"u32",time_span:"s64"};function nC(x){return x===void 0?"unknown":tC[x.toLowerCase()]??"unknown"}var iC={u8:1,s8:1,u16:2,s16:2,floatm16:2,u32:4,s32:4,f32:4,stamp4:4,stamp:5,stamp8:8,datetime:8,ufm8:1,link:0,unknown:0,s64:8,f64:8},sC=new Set(["name","alias","title","index","byteofs","type","max","decpl","vscale","vofs","units","editmask","view","edit","default","bitmask"]),ks="name",aC="type";function oC(x){let A=x.indexOf("=");return{key:x.slice(0,A).trim().toLowerCase(),value:x.slice(A+1).trim()}}function FC(x){return/^config[0-9]$/.test(x)||/^config[A-C]$/i.test(x)?"config":/^histdata[0-9]$/.test(x)?"histdata":"other"}function sr(x,A){let e=x.get(A);if(e===void 0)return;let r=parseInt(e,10);return Number.isNaN(r)?void 0:r}function vC(x){let A=x.get("bitmask");if(A===void 0)return;let e=A.startsWith("$")?A.slice(1):A,r=parseInt(e,16);return Number.isNaN(r)?void 0:r}var lC=/^(.*?)%(config[0-9a-fA-F])%(.+)$/;function v8(x){let A=lC.exec(x);if(!A)return{};let e=A[1],r=e===""?NaN:Number(e);return{ref:{container:A[2],field:A[3]},prefixValue:Number.isFinite(r)?r:void 0}}function cC(x){let A=x.get("vscale");if(A===void 0)return{value:1};let e=v8(A);if(e.ref)return{value:e.prefixValue??1,ref:e.ref};let r=Number(A);return Number.isFinite(r)?{value:r}:{value:1}}function fC(x){let A=x.get("vofs");if(A===void 0)return{value:0};let e=v8(A);if(e.ref)return{value:e.prefixValue??0,ref:e.ref};let r=Number(A);return Number.isFinite(r)?{value:r}:{value:0}}function EC(x,A){return x==="string"?A??0:iC[x]}function BC(x){let A={};for(let[e,r]of x)sC.has(e)||(A[e]=r);return A}function CC(x,A,e){let r=nC(x.get(aC)),t=sr(x,"max"),i=EC(r,t),n=A.fields[A.fields.length-1],v=sr(x,"byteofs")??(n?n.byteofs+n.size:A.kind==="histdata"?1:0),E=A.fields.length,u=x.get(ks)??(A.kind==="histdata"?`ch${E}`:`field${E}`),D=cC(x),m=fC(x),w=sr(x,"index");return{name:u,alias:x.get("alias"),title:x.get("title"),index:w,sortIndex:w??e,byteofs:v,type:r,size:i,max:t,decpl:sr(x,"decpl"),vscale:D.value,vofs:m.value,vscaleRef:D.ref,vofsRef:m.ref,units:x.get("units"),editmask:x.get("editmask"),view:sr(x,"view"),edit:sr(x,"edit"),default:x.get("default"),bitmask:vC(x),attrs:BC(x)}}function dC(){return{name:"",kind:"other",fields:[],recordSize:0}}function uC(x,A,e){switch(A){case ks:{let r=ys(e);x.name=r,x.kind=FC(r);break}case"alias":x.alias=e;break;case"title":x.title=e;break;case"upload":x.upload=parseInt(e,10);break;case"download":x.download=parseInt(e,10);break;case"edit":x.edit=parseInt(e,10);break;default:break}}function DC(x){if(!x.name)throw new Error("?dde.table-without-name");x.recordSize=x.fields.filter(A=>!_t(A.type)).reduce((A,e)=>Math.max(A,e.byteofs+e.size),0),x.fields.sort((A,e)=>A.sortIndex-e.sortIndex)}function pC(x){if(x==="*")return{keyBytes:[],matchAll:!0};let A=x.slice(0,2).toLowerCase()==="0x"?x.slice(2):x;A.length%2!==0&&(A=`0${A}`);let e=[];for(let r=0;r<A.length;r+=2){let t=parseInt(A.slice(r,r+2),16);e.push(Number.isNaN(t)?0:t)}return{keyBytes:e,matchAll:!1}}function bC(x){return x.toLowerCase()==="histdata28"?"applog0":ys(x)}function mC(x){let{keyBytes:A,matchAll:e}=pC(x.get("key")??"00");return{source:x.get("source")??"",target:bC(x.get("target")??""),key:A[0]??0,keyBytes:A,matchAll:e,keepraw:sr(x,"keepraw")}}function hC(x,A){return{containers:x,splits:A,byNameOrAlias(e){let r=e.toLowerCase();return x.find(t=>t.name.toLowerCase()===r||(t.alias??"").toLowerCase()===r)??null}}}function jC(x,A){switch(A){case"<table>":return x.container=dC(),x.expectName=!0,!0;case"</table>":return x.container&&(DC(x.container),x.containers.push(x.container)),x.container=null,!0;case"<field>":return x.field=new Map,!0;case"</field>":return x.container&&x.field&&x.container.fields.push(CC(x.field,x.container,x.line)),x.field=null,!0;case"<split>":return x.split=new Map,!0;case"</split>":return x.split&&x.splits.push(mC(x.split)),x.split=null,!0;default:return!1}}function gC(x,A){let{key:e,value:r}=oC(A);if(x.split)x.split.set(e,r);else if(x.field)x.field.set(e,r);else if(x.container){if(x.expectName&&e!==ks)throw new Error(`?dde.first-table-attr-not-name."${e}"`);x.expectName=!1,uC(x.container,e,r)}}function yC(x){let A={containers:[],splits:[],container:null,field:null,split:null,expectName:!1,line:0};for(let[e,r]of x.replace(/\r\n/g,`
|
|
2196
2196
|
`).replace(/\r/g,`
|
|
2197
2197
|
`).split(`
|
|
2198
|
-
`).entries()){A.line=e;let t=r.trim();t===""||t.startsWith("//")||jC(A,t)||t.includes("=")&&gC(A,t)}return hC(A.containers,A.splits)}var l8=null,kC=4;function Kr(x){let A=new Date(x),e=(r,t)=>r.toString().padStart(t,"0");return e(A.getUTCFullYear(),4)+e(A.getUTCMonth()+1,2)+e(A.getUTCDate(),2)+e(A.getUTCHours(),2)+e(A.getUTCMinutes(),2)+e(A.getUTCSeconds(),2)+e(A.getUTCMilliseconds(),3)}function Vr(x){let A=x.trim();if(A==="*")return l8;if(!/^\d{4,17}$/.test(A))throw new Error(`?apiStamp.invalid-input."${x}"`);let e=(u,D,m)=>{let w=A.slice(u,u+D);return parseInt(w.length?w.padEnd(D,"0"):m,10)},r=parseInt(A.slice(0,kC),10),t=A.length>=6?e(4,2,"01"):1,i=A.length>=8?e(6,2,"01"):1,n=e(8,2,"00"),F=e(10,2,"00"),v=e(12,2,"00"),E=e(14,3,"000");return Date.UTC(r,t-1,i,n,F,v,E)}var St="NAN",wC="%HEX%",_C=65535,ws=class extends Error{constructor(x){super(`?ddeCodec.unknown-alias."${x}"`),A0(this,"alias",x),this.name="DdeUnknownAliasError"}};function In(x){return(x.alias??x.name).toLowerCase()}function Mn(x){return x==="string"}function _s(x){return x==="stamp"||x==="stamp4"||x==="stamp8"||x==="datetime"}function c8(x){return(x.editmask??"").toUpperCase()===wC}function SC(x,A){return A===void 0||!Number.isFinite(x)?x:Ss(x,A)}function Ss(x,A){if(!Number.isFinite(x))return x;let e=10**A;return Math.sign(x)*Math.round(Math.abs(x)*e)/e}function $C(x,A){if(!Number.isFinite(x)||x===0)return x;let e=Math.abs(x),r=Math.floor(Math.log10(e));return 10**(r+1)<=e?r+=1:10**r>e&&(r-=1),Ss(x,A-1-r)}function TC(x){return x==="floatm16"||x==="f32"||x==="f64"}function PC(x,A){if(!Number.isFinite(A))return A;let e=x.decpl??(TC(x.type)?9:0),r=Ss(A,e),t=x.type==="floatm16"?3:x.type==="f32"?7:15;return $C(r,t)}function _n(x,A){let e=BigInt.asUintN(64,BigInt(Math.trunc(x))),r=BigInt.asUintN(64,BigInt(Math.trunc(A))),t=0n,i=1n;for(;r!==0n;)r&1n&&(e&1n&&(t|=i),i<<=1n),e>>=1n,r>>=1n;return Number(t)}function f8(x,A,e){let r=BigInt.asUintN(64,BigInt(Math.trunc(x))),t=BigInt.asUintN(64,BigInt(Math.trunc(A))),i=BigInt.asUintN(64,BigInt(Math.trunc(e))),n=1n;for(;i!==0n;)i&1n&&(r=t&1n?r|n:r&~n,t>>=1n),i>>=1n,n<<=1n;return Number(r)}var qC=new Set(["u8","s8","u16","s16","u32","s32","s64","ufm8"]);function Sn(x){return!!x.bitmask&&qC.has(x.type)}var E8=255,B8=254,C8=253,d8=252,u8=251,NC=207,$s=65535,$n=65534,Ts=65533,Ps=65532,qs=65531;function IC(x){switch(x){case E8:return $s;case B8:return $n;case C8:return Ts;case d8:return Ps;case u8:return qs;default:return x<=31?x:x>NC?$n:(x&15|16)<<(x>>4)-1}}function MC(x){switch(x){case $s:return E8;case $n:return B8;case Ts:return C8;case Ps:return d8;case qs:return u8;default:{if(x<=31)return x;let A=1,e=x;for(;(e&65504)>0;)e>>=1,A++;return A<<4|e&15}}}var Tn=1023,os=31,D8=127,Hi=8388607,LC=255,Fs=15,RC=-14,pF=15;function p8(x){let A=(x&Tn)<<13,e=(x&31744)>>10;if(e===os)return m8(1024-(x&Tn));e!==0&&(e=e-Fs+4+D8);let r=(A|e<<23)>>>0;x&32768&&(r=(r|2147483648)>>>0);let t=new DataView(new ArrayBuffer(4));return t.setUint32(0,r),t.getFloat32(0)}function b8(x){if(typeof x=="string"||Number.isNaN(x))return _C;let A=new DataView(new ArrayBuffer(4));A.setFloat32(0,x);let e=A.getUint32(0),r=e>>>16&32768,t=(e&Hi)+4096,i=(t>Hi?1:0)+(e>>>23&LC),n=(t&Hi)>>>13;return i!==0&&(i=i-D8-4,i<RC?(n=0,i=0):i>pF?(n=Tn,i=pF+Fs):i=i+Fs),r|i<<10|n}var OC=["OF","UF","OL","SC"],vs={u8:{NAN:255,OF:254,UF:253,OL:252,SC:251},u16:{NAN:65535,OF:65534,UF:65533,OL:65532,SC:65531},u32:{NAN:4294967295,OF:4294967294,UF:4294967293,OL:4294967292,SC:4294967291},s8:{NAN:127,OF:126,UF:-126,OL:-127,SC:-128},s16:{NAN:32767,OF:32766,UF:-32766,OL:-32767,SC:-32768},s32:{NAN:2147483647,OF:2147483646,UF:-2147483646,OL:-2147483647,SC:-2147483648},s64:{NAN:0x7fffffffffffffffn,OF:0x7ffffffffffffffen,UF:-0x7ffffffffffffffen,OL:-0x7fffffffffffffffn,SC:-0x8000000000000000n},ufm8:{NAN:$s,OF:$n,UF:Ts,OL:Ps,SC:qs}},GC={NAN:65535,OF:65534,UF:65533,OL:65532,SC:65531},Wx={NAN:1,OF:2,UF:3,OL:4,SC:5},UC=new Set(["u8","u16","u32","ufm8"]);function HC(x){let A=Math.floor(x),e=x-A;return e<.5?A:e>.5?A+1:A%2===0?A:A+1}function Ns(x){let A=x.replace(/,/g,"").trim();if(!/^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/.test(A))return null;let e=Number(A);return Number.isFinite(e)?e:null}function Is(x,A,e){switch(x){case"u8":return A.getUint8(e);case"s8":return A.getInt8(e);case"u16":return A.getUint16(e,!1);case"s16":return A.getInt16(e,!1);case"u32":return A.getUint32(e,!1);case"s32":return A.getInt32(e,!1);case"s64":return Number(A.getBigInt64(e,!1));case"f32":return A.getFloat32(e,!1);case"f64":return A.getFloat64(e,!1);case"floatm16":return p8(A.getUint16(e,!1));case"ufm8":return IC(A.getUint8(e));default:throw new Error(`?ddeCodec.non-numeric-type."${x}"`)}}function m8(x){switch(x){case Wx.OF:return"OF";case Wx.UF:return"UF";case Wx.OL:return"OL";case Wx.SC:return"SC";default:return St}}var bF=[["NAN",Wx.NAN],["OF",Wx.OF],["UF",Wx.UF],["OL",Wx.OL],["SC",Wx.SC]];function JC(x,A){let e=x.getUint32(A,!1);if((e&2139095040)!==2139095040)return 0;let r=e&8388607;return r===0?Wx.NAN:(r=r&4194304?8388608-r:r&255,r===0?Wx.NAN:r)}function KC(x,A){let e=x.getBigUint64(A,!1);if((e&0x7ff0000000000000n)!==0x7ff0000000000000n)return 0;let r=Number(e&0xffn);return r===0?Wx.NAN:r}function zC(x,A){if(x.type==="s64"){let t=A.getBigInt64(x.byteofs,!1);Sn(x)&&(t=BigInt(_n(Number(t),x.bitmask)));let i=vs.s64;return bF.find(([n])=>t===BigInt(i[n]))?.[1]??0}let e=vs[x.type];if(!e)return 0;let r=Is(x.type,A,x.byteofs);return Sn(x)&&(r=_n(r,x.bitmask)),bF.find(([t])=>r===e[t])?.[1]??0}function h8(x,A){switch(x.type){case"floatm16":{let e=A.getUint16(x.byteofs,!1);return(e>>10&os)===os?1024-(e&Tn):0}case"f32":return JC(A,x.byteofs);case"f64":return KC(A,x.byteofs);default:return zC(x,A)}}function j8(x,A){let e=Is(x.type,A,x.byteofs);return typeof e=="string"||Number.isNaN(e)?NaN:(Sn(x)&&(e=_n(e,x.bitmask)),e*x.vscale+x.vofs)}function VC(x,A){let e=h8(x,A);if(e!==0)return m8(e);let r=j8(x,A);return Number.isNaN(r)?St:PC(x,r)}function WC(x,A){if(x.byteofs+x.size>A.byteLength)return null;if(Mn(x.type)||_s(x.type))return NaN;let e=new DataView(A.buffer,A.byteOffset,A.byteLength);return h8(x,e)!==0?NaN:j8(x,e)}function XC(x,A){if(c8(x)){let e="";for(let r=0;r<x.size;r++)e+=A.getUint8(x.byteofs+r).toString(16).padStart(2,"0");return e.toUpperCase()}return z0.cp1252Unpack(A,x.byteofs,x.size)}var g8=25569,y8=864e5;function YC(x){return(x-g8)*y8}function QC(x){return x/y8+g8}function ZC(x,A){if(x.type==="datetime")return Kr(YC(A.getFloat64(x.byteofs,!1)));if(x.type==="stamp8"){let r=A.getBigUint64(x.byteofs,!1),t=Number(r&0xffffffffffn);return Kr(z0.stamp40ToMS(t))}let e=A.getUint32(x.byteofs,!1)*256;return x.size>=5&&(e+=A.getUint8(x.byteofs+4)),Kr(z0.stamp40ToMS(e))}var xd=new Set(["u8","s8","u16","s16","u32","s32","s64","ufm8"]);function Ad(x,A){return/^[+-]?\d+$/.test(x)?parseInt(x,10):/^\$[0-9a-fA-F]+$/.test(x)?parseInt(x.slice(1),16):A}function ed(x){let A=x.default;if(A===void 0)return;if(Mn(x.type))return A;let e=A.trim();if(e===""||e.toUpperCase()===St)return St;if(xd.has(x.type))return Ad(e,0);let r=Ns(e);return r!==null?r:A}function rd(x,A,e){return x.byteofs+x.size>e?ed(x):Mn(x.type)?XC(x,A):_s(x.type)?ZC(x,A):VC(x,A)}function ls(x,A){let e=new DataView(A.buffer,A.byteOffset,A.byteLength),r={};for(let t of x.fields)Ce(t)||_t(t.type)||(r[In(t)]=rd(t,e,A.byteLength));return r}function td(x,A){if(typeof A=="number")return Number.isFinite(A)?{kind:"value",physical:A}:{kind:"sentinel",state:"NAN"};if(typeof A=="string"){if(A.toUpperCase()===St||A==="")return{kind:"sentinel",state:"NAN"};let e=OC.find(t=>t===A);if(e)return{kind:"sentinel",state:e};if("OUS".includes(A[0]))return{kind:"skip"};let r=Ns(A);return r!==null?{kind:"value",physical:r}:mF(x)}return mF(x)}function mF(x){let A=x.default;return A!==void 0&&A.startsWith("%")?{kind:"sentinel",state:"NAN"}:{kind:"value",physical:(A!==void 0?Ns(A):null)??0}}function cs(x,A,e){switch(x.type){case"floatm16":return A.setUint16(x.byteofs,GC[e],!1);case"f32":return A.setUint32(x.byteofs,(2139095040|Wx[e])>>>0,!1);case"f64":return A.setBigUint64(x.byteofs,0x7ff0000000000000n|BigInt(Wx[e]),!1);default:break}let r=vs[x.type]?.[e];if(r===void 0)throw new Error(`?ddeCodec.non-numeric-type."${x.type}"`);if(x.type==="s64")return A.setBigInt64(x.byteofs,BigInt(r),!1);k8(x,A,Number(r))}function nd(x,A,e){if(x.vscale===0)return;let r=(e-x.vofs)/x.vscale;switch(x.type){case"f32":return A.setFloat32(x.byteofs,r,!1);case"f64":return A.setFloat64(x.byteofs,r,!1);case"floatm16":return A.setUint16(x.byteofs,b8(r),!1);default:break}if(Number.isNaN(r))return cs(x,A,"NAN");if(!Number.isFinite(r))return cs(x,A,"OF");let t=r;UC.has(x.type)&&t<0&&(t=0),k8(x,A,HC(t))}function k8(x,A,e){if(Sn(x)){let r=Is(x.type,A,x.byteofs);e=f8(r,e,x.bitmask)}id(x.type,A,x.byteofs,e)}function id(x,A,e,r){switch(x){case"u8":return A.setUint8(e,r);case"s8":return A.setInt8(e,r);case"u16":return A.setUint16(e,r,!1);case"s16":return A.setInt16(e,r,!1);case"u32":return A.setUint32(e,r,!1);case"s32":return A.setInt32(e,r,!1);case"s64":return A.setBigInt64(e,BigInt(r),!1);case"ufm8":return A.setUint8(e,MC(r));default:throw new Error(`?ddeCodec.non-numeric-type."${x}"`)}}function sd(x,A,e){let r=String(e);if(c8(x)){let t=r.trim();if(t.length%2!==0||t.length>x.size*2)throw new Error(`?ddeCodec.invalid-hex."${In(x)}"`);for(let i=0;i<x.size;i++){let n=i*2<t.length?parseInt(t.substr(i*2,2),16):0;A.setUint8(x.byteofs+i,n)}return}z0.cp1252Pack(A,x.byteofs,x.size,r)}function ad(x,A,e){let r=Vr(String(e));if(r===null)throw new Error(`?ddeCodec.unbounded-stamp."${In(x)}"`);if(x.type==="datetime"){A.setFloat64(x.byteofs,QC(r),!1);return}let t=z0.msToStamp40(r);if(x.type==="stamp8"){A.setBigUint64(x.byteofs,BigInt(t),!1);return}A.setUint32(x.byteofs,Math.trunc(t/256),!1),x.size>=5&&A.setUint8(x.byteofs+4,t&255)}function od(x,A,e){if(Mn(x.type))return sd(x,A,e);if(_s(x.type))return ad(x,A,e);let r=td(x,e);switch(r.kind){case"skip":return;case"sentinel":return cs(x,A,r.state);case"value":return nd(x,A,r.physical)}}function fs(x,A,e){let r=e?new Uint8Array(e):new Uint8Array(x.recordSize),t=new DataView(r.buffer,r.byteOffset,r.byteLength),i=new Map(x.fields.filter(n=>!Ce(n)&&!_t(n.type)).map(n=>[In(n),n]));for(let[n,F]of Object.entries(A)){let v=i.get(n.toLowerCase());if(!v)throw new ws(n);od(v,t,F)}return r}var hF=99,Fd=256,Me=class extends Error{constructor(x){super(`?ddeMapper.unknown-container."${x}"`),A0(this,"container",x),this.name="DdeUnknownContainerError"}},$t=class extends Error{constructor(x,A){let e=A?`${x}.${A}`:x;super(`?ddeMapper.write-forbidden."${e}"`),A0(this,"container",x),A0(this,"field",A),this.name="DdeWriteForbiddenError"}},Ms=class extends Error{constructor(x){super(`?ddeMapper.unknown-field."${x}"`),A0(this,"field",x),this.name="DdeUnknownFieldError"}};function Ji(x){return(x.alias??x.name).toLowerCase()}var vd=class{constructor(x,A,e=qt){A0(this,"model",x),A0(this,"storage",A),A0(this,"timeSource",e)}async readContainer(x){let A=this.model.byNameOrAlias(x);if(!A)return null;let e=yt(A);if(e===null)return null;let r=await this.storage.getRowForTag(e);if(!r||!r.data)return null;let t=ls(await this.resolveScaleRefs(A),r.data);return delete t.stamp,{stamp:this.rowStamp(r),...t}}async writeContainer(x,A){let e=this.model.byNameOrAlias(x);if(!e)throw new Me(x);let r=yt(e);if(r===null)throw new Me(x);if(e.edit===hF)throw new $t(e.name);let{stamp:t,...i}=A;this.assertFieldsWritable(e,i);let n=await this.storage.getRowForTag(r),F=fs(await this.resolveScaleRefs(e),i,n?.data??null),v=z0.msToStamp40(this.recordStampMs(t)??this.timeSource.nowMs()),E=fA(v);return await this.storage.replaceUtoRow({tag:r,stamp:E,flags:n?.flags??0,site_related:n?.site_related??0,data:F}),{tag:r,stampHex:E,stamp40:v,data:F,devicePushable:F8(r)&&e.download!==0,upload:e.upload,download:e.download}}async seedContainer(x,A){let e=this.model.byNameOrAlias(x);if(!e)throw new Me(x);let r=yt(e);if(r===null)throw new Me(x);let{stamp:t,...i}=A,n=fs(await this.resolveScaleRefs(e),i,null),F=z0.msToStamp40(this.recordStampMs(t)??this.timeSource.nowMs());await this.storage.replaceUtoRow({tag:r,stamp:fA(F),flags:0,site_related:0,data:n})}recordStampMs(x){if(typeof x!="string")return null;try{return Vr(x)}catch{return null}}async readTimeseries(x,A){let e=this.model.byNameOrAlias(x);if(!e)throw new Me(x);let r=this.model.splits.find(E=>E.target.toLowerCase()===e.name.toLowerCase());if(!r)throw new Me(x);let t=Math.abs(A.count),i=A.offset??0,n=this.buildSelectSet(e,A.select),F=await this.resolveScaleRefs(e);return(await this.collectMatched(F,r,i+t,{fromStamp:this.boundHex(A.fromMs),untilStamp:this.boundHex(A.untilMs),order:A.count<0?"desc":"asc",selectSet:n})).slice(i,i+t)}matchesSplit(x,A){return x.length===0?!1:A.matchAll?!0:x.length<A.keyBytes.length?!1:A.keyBytes.every((e,r)=>x[r]===e)}async collectMatched(x,A,e,r){let t=[];if(e<=0)return t;let i=Math.max(e,Fd);for(let n=0;;n+=i){let F=await this.storage.getHistoricRows(26623,{fromStamp:r.fromStamp,untilStamp:r.untilStamp,order:r.order,limit:i,offset:n});for(let v of F)if(v.data&&this.matchesSplit(v.data,A)&&(t.push(this.recordFromRow(x,v,r.selectSet)),t.length>=e))return t;if(F.length<i)return t}}async readTimeseriesEdge(x,A,e){return(await this.readTimeseries(x,{count:A==="youngest"?-1:1,select:e}))[0]??null}recordFromRow(x,A,e){let r=ls(x,A.data),t={stamp:this.rowStamp(A)};for(let[i,n]of Object.entries(r))i!=="stamp"&&(!e||e.has(i))&&(t[i]=n);return t}rowStamp(x){return Kr(z0.stamp40ToMS(QA(x.stamp)))}boundHex(x){if(x!=null)return fA(z0.msToStamp40(x))}async resolveScaleRefs(x){if(!x.fields.some(r=>r.vscaleRef||r.vofsRef))return x;let A=new Map,e=[];for(let r of x.fields){if(!r.vscaleRef&&!r.vofsRef){e.push(r);continue}e.push({...r,vscale:r.vscaleRef?await this.resolveRef(r.vscaleRef,A,r.vscale):r.vscale,vofs:r.vofsRef?await this.resolveRef(r.vofsRef,A,r.vofs):r.vofs})}return{...x,fields:e}}async resolveRef(x,A,e){if(!/^config[0-9a-f]$/i.test(x.container))return e;let r=this.referencedField(x);if(!r)return e;let t=x.container.toLowerCase();A.has(t)||A.set(t,await this.referencedRecordData(x.container));let i=A.get(t);if(!i)return e;let n=WC(r,i);return n===null?e:n}referencedField(x){let A=x.field.toLowerCase();return this.model.byNameOrAlias(x.container)?.fields.find(r=>Ji(r)===A||r.name.toLowerCase()===A)??null}async referencedRecordData(x){let A=this.model.byNameOrAlias(x);if(!A)return null;let e=yt(A);return e===null?null:(await this.storage.getRowForTag(e))?.data??null}assertFieldsWritable(x,A){let e=new Map(x.fields.filter(r=>!Ce(r)&&!_t(r.type)).map(r=>[Ji(r),r]));for(let r of Object.keys(A)){let t=e.get(r.toLowerCase());if(t&&t.edit===hF)throw new $t(x.name,t.name)}}buildSelectSet(x,A){if(!A||A.length===0)return null;let e=new Set(x.fields.filter(t=>!Ce(t)&&!_t(t.type)).map(t=>Ji(t))),r=new Set;for(let t of A){let i=t.toLowerCase();if(i!=="stamp"){if(!e.has(i))throw new Ms(t);r.add(i)}}return r}},ld=new Set(["$titles","$meta"]);function cd(x){let A=x;if(typeof x=="string")try{A=JSON.parse(x)}catch{return null}return typeof A!="object"||A===null||Array.isArray(A)?null:A}function Es(x,A){let e=A.toLowerCase();if(ld.has(e))return null;let r=x[e];if(typeof r!="object"||r===null)return null;let t=new Map;for(let[i,n]of Object.entries(r)){if(typeof n!="object"||n===null)continue;let F=n.alias;typeof F=="string"&&F.length>0&&t.set(i.toLowerCase(),F)}return t}function w8(x,A){let e={};for(let[r,t]of Object.entries(x)){if(r==="stamp"){e[r]=t;continue}let i=A?.get(r.toLowerCase());e[i??r]=t}return e}function Nt(x,A){if(!x)return null;let e=Es(x,A.name);return e||(A.alias?Es(x,A.alias):null)}var fd=require("events"),O0="[OfflineSyncManager]",Ed=500,Bd="site_info",Cd=new Set(["local-data-interface.json"]);function Ox(x){if(x?.aborted)throw x.reason??new DOMException("The operation was aborted.","AbortError")}function dd(x){let A=kn(x);return!!(x&2)||A!==0&&A!==65}function jF(x){return x.filter(A=>(A.filename===Jr||A.filename===hs)&&A.outcome==="download").map(A=>A.filename)}var rr="skip-equal",Hr="skip-device-readonly",Ki="delete",Ne="error",zi="upload",Vi="uploading-utos",gF="downloading-utos",dn="fetching-device-state",Wi="uploading-files",un="downloading-files",yF="executing-change-requests",kF="executed",ud="error",Xi="skip-old-stamp",Dd=class extends fd.EventEmitter{constructor(x,A,e){super(),A0(this,"utoMaster",x),A0(this,"storage",A),A0(this,"logger",e)}emitProgress(x,A,e,r,t){let i={phase:x,item:A,completed:e,total:r,...t};this.emit("progress",i)}async uploadHistoricTag(x,A,e,r,t){try{let i=await this.storage.getRowForTag(x),n=0,F=async v=>{let E=v.filter(u=>u.stamp40>e).map(u=>({tag:x,stamp:fA(u.stamp40),flags:i?.flags??0,site_related:i?.site_related??0,data:u.data}));await this.storage.insertHistoricRows(E),n+=E.length};return await this.utoMaster.requestHistoricUtos(x,e,t,void 0,Ed,F),this.logger?.info(`${O0} historic upload tag=0x${x.toString(16)} +${n} records`),{tag:x,sTag:A.sTag,historic:!0,outcome:"upload",dbStamp40:e,deviceStamp40:r,recordsAppended:n}}catch(i){return this.logger?.error(`${O0} historic upload error tag=0x${x.toString(16)}: ${i}`),{tag:x,sTag:A.sTag,historic:!0,outcome:"error",dbStamp40:e,deviceStamp40:r}}}async uploadSingleTag(x,A,e,r){try{let t=await this.utoMaster.requestUto(x,0);if(!t)return this.logger?.info(`${O0} single upload tag=0x${x.toString(16)} \u2014 device returned no data (skip)`),{tag:x,sTag:A.sTag,historic:!1,outcome:rr,dbStamp40:e,deviceStamp40:r};let i=await this.storage.getRowForTag(x);return await this.storage.replaceUtoRow({tag:x,stamp:fA(t.stamp),flags:i?.flags??0,site_related:i?.site_related??0,data:t.data?new Uint8Array(t.data.buffer.slice(t.data.byteOffset,t.data.byteOffset+t.data.byteLength)):null}),this.logger?.info(`${O0} single upload tag=0x${x.toString(16)}`),{tag:x,sTag:A.sTag,historic:!1,outcome:"upload",dbStamp40:e,deviceStamp40:r}}catch(t){return this.logger?.error(`${O0} single upload error tag=0x${x.toString(16)}: ${JSON.stringify(t)}`),{tag:x,sTag:A.sTag,historic:!1,outcome:"error",dbStamp40:e,deviceStamp40:r}}}async uploadUtoTags(x,A,e,r){let t=x.length;this.emitProgress(Vi,null,0,t);let i=0;for(let n of x){Ox(r);let F=A.get(n),{tagInfo:v,dbStamp40:E,deviceStamp40:u}=F;if(this.emitProgress(Vi,v?.sTag??`0x${n.toString(16)}`,i,t),!v||u===null)e.set(n,{tag:n,sTag:"?",historic:!1,outcome:"unknown-tag",dbStamp40:E,deviceStamp40:u});else if(!(!v.flags.up||u<=E)){let D=v.sTag,m=i,w=v.historic?await this.uploadHistoricTag(n,v,E,u,j=>{this.emitProgress(Vi,D,m,t,{recordsReceived:j})}):await this.uploadSingleTag(n,v,E,u);e.set(n,w)}++i}}async pullFileFromDevice(x,A,e,r,t,i){let n=A.stamp;try{let F=await this.utoMaster.requestFile(x,E=>{this.emitProgress(Wi,x,i,t,{bytesTransferred:E})}),v=ms(F);if(v!==A.crc32)throw new Error(`crc32 mismatch: expected 0x${A.crc32.toString(16)}, got 0x${v.toString(16)}`);return await this.storage.upsertFile({filename:x,stamp:fA(n),crc:A.crc32,size:F.byteLength,flags:A._flags,flags_int:r,data:F}),{filename:x,outcome:zi,dbStamp40:e,deviceStamp40:n}}catch(F){return this.logger?.error(`${O0} file upload error ${x}: ${JSON.stringify(F)}`),{filename:x,outcome:Ne,dbStamp40:e,deviceStamp40:n}}}async autoSyncUploadFile(x,A,e,r,t,i,n,F){let v=A.stamp;if(v>r)return this.fileContentMatches(A,e)?this.convergeFileStamp(x,A,e,r):i?this.pullFileFromDevice(x,A,r,t,n,F):void 0;if(v===r&&this.fileContentMatches(A,e))return{filename:x,outcome:rr,dbStamp40:r,deviceStamp40:v}}async convergeFileStamp(x,A,e,r){let t=A.stamp;try{return await this.storage.upsertFile({filename:x,stamp:fA(t),crc:A.crc32,size:A.size,flags:A._flags,flags_int:e.flags_int,data:e.data}),{filename:x,outcome:rr,dbStamp40:r,deviceStamp40:t}}catch(i){return this.logger?.error(`${O0} file upload error ${x}: ${JSON.stringify(i)}`),{filename:x,outcome:Ne,dbStamp40:r,deviceStamp40:t}}}async mirrorUploadFile(x,A,e,r,t,i,n){let F=A.stamp;if(F!==r||!this.fileContentMatches(A,e))return t?this.pullFileFromDevice(x,A,r,e.flags_int,i,n):{filename:x,outcome:Hr,dbStamp40:r,deviceStamp40:F}}async decideFileUpload(x,A,e,r){let t=await this.storage.getFile(x),i=!!(A._flags&1);if(!t)return i?this.pullFileFromDevice(x,A,0,16,e,r):void 0;let n=QA(t.stamp);return A._flags&8?this.autoSyncUploadFile(x,A,t,n,t.flags_int,i,e,r):this.decideNonSystemUpload(x,A,t,n,i,e,r)}pullIfReadable(x,A,e,r,t,i,n){return x?this.pullFileFromDevice(A,e,r,t,i,n):void 0}async decideNonSystemUpload(x,A,e,r,t,i,n){let F=e.flags_int;if(!(F&2))return F&4?this.pullIfReadable(t,x,A,r,F,i,n):this.decideUploadBySyncLogic(x,A,e,r,t,i,n)}async decideUploadBySyncLogic(x,A,e,r,t,i,n){let F=e.flags_int,v=kn(F);if(v===65)return this.fileContentMatches(A,e)?this.convergeFileStamp(x,A,e,r):this.pullIfReadable(t,x,A,r,F,i,n);if(v===1)return this.autoSyncUploadFile(x,A,e,r,F,t,i,n);if(v===97)return A.stamp>r?this.pullIfReadable(t,x,A,r,F,i,n):void 0;if(v!==33)return this.mirrorUploadFile(x,A,e,r,t,i,n)}async uploadFiles(x,A,e,r){let t=Object.entries(x),i=t.length;this.emitProgress(Wi,null,0,i);let n=0;for(let[F,v]of t){if(Ox(r),!(F===hs||F===Jr&&!e)){let u=await this.decideFileUpload(F,v,i,n);u&&A.set(F,u)}this.emitProgress(Wi,F,++n,i)}}fileContentMatches(x,A){return A!==null&&x.crc32===A.crc&&x.size===A.size}async downloadSingleTag(x,A,e,r){try{let t=await this.storage.getRowForTag(x);return t?.data&&await this.utoMaster.sendUTOCmdExt(3,x,t.data,e),{tag:x,sTag:A.sTag,historic:!1,outcome:"download",dbStamp40:e,deviceStamp40:r}}catch(t){return this.logger?.error(`${O0} download error tag=0x${x.toString(16)}: ${t}`),{tag:x,sTag:A.sTag,historic:!1,outcome:"error",dbStamp40:e,deviceStamp40:r}}}async processDownloadTag(x,A,e,r,t){if(e===r&&!t.has(x)){let i=A.flags.up?rr:"skip-db-readonly";t.set(x,{tag:x,sTag:A.sTag,historic:!1,outcome:i,dbStamp40:e,deviceStamp40:r});return}if(e>r){let i=A.flags.down?await this.downloadSingleTag(x,A,e,r):{tag:x,sTag:A.sTag,historic:!1,outcome:Hr,dbStamp40:e,deviceStamp40:r};t.set(x,i)}}async downloadUtoTags(x,A,e,r){let t=x.length;this.emitProgress(gF,null,0,t);let i=0;for(let n of x){Ox(r);let{tagInfo:F,dbStamp40:v,deviceStamp40:E}=A.get(n);F&&E!==null&&!F.historic&&await this.processDownloadTag(n,F,v,E,e),this.emitProgress(gF,F?.sTag??`0x${n.toString(16)}`,++i,t)}}async sendFileToDevice(x,A,e,r,t){let i=x.data.byteLength,n=F=>{if(F!==null){let v=Math.round(i*parseInt(F,10)/100);this.emitProgress(un,x.filename,t,r,{bytesTransferred:v,bytesTotal:i})}};this.utoMaster.on("installing",n);try{return await this.utoMaster.sendFile(0,x.data,z0.stamp40ToMS(A),x.filename),{filename:x.filename,outcome:"download",dbStamp40:A,deviceStamp40:e}}catch(F){return this.logger?.error(`${O0} file download error ${x.filename}: ${F}`),{filename:x.filename,outcome:"error",dbStamp40:A,deviceStamp40:e}}finally{this.utoMaster.removeListener("installing",n)}}async processDownloadFile(x,A,e,r,t=!1){if(!x.data)return;let i=A?.stamp??0,n=QA(x.stamp);if(A!==void 0&&this.fileContentMatches(A,x))return n===i?void 0:{filename:x.filename,outcome:rr,dbStamp40:n,deviceStamp40:i};if(!(!t&&n<i))return!t&&A!==void 0&&!(A._flags&2)?{filename:x.filename,outcome:Hr,dbStamp40:n,deviceStamp40:i}:this.sendFileToDevice(x,n,i,e,r)}async isAppInDevPhase(){let x=await this.storage.getMetadataValue(Bd);if(!x)return!1;try{return JSON.parse(x).app?.phase==="dev"}catch(A){return this.logger?.error(`${O0} corrupt site_info metadata: ${A}`),!1}}async downloadFiles(x,A,e,r){let t=await this.storage.getFiles(),i=t.filter(D=>D.flags&8),n=t.filter(D=>!(D.flags&8)),F=[...i,...n].filter(D=>D.filename),v=Object.entries(x).filter(([,D])=>D._flags&4).map(([D])=>D),E=F.length;this.emitProgress(un,null,0,E);let u=0;for(let D of F){if(Ox(r),e&&D.filename===Jr){this.emitProgress(un,D.filename,++u,E);continue}let m=D.filename===Jr&&!e,w=await this.decideFileDownload(D,x[D.filename],A.get(D.filename),v,m,E,u);w&&A.set(D.filename,w),this.emitProgress(un,D.filename,++u,E)}}async decideFileDownload(x,A,e,r,t,i,n){return A!==void 0?this.decideDownloadExisting(x,A,e,t,i,n):this.decideDownloadMissing(x,r,i,n)}async decideDownloadExisting(x,A,e,r,t,i){if(A._flags&4)return;if(x.flags&8)return e?void 0:this.processDownloadFile(x,A,t,i,r);let n=x.flags_int;if(n&8)return this.handleDeviceDelete(x,A,e);if(!e&&!(n&4))return this.pushToDevice(x,A,t,i)}async pushToDevice(x,A,e,r){let t=A.stamp,i=QA(x.stamp),n=this.wantDownloadPush(x,A,i,t);if(n==="match")return{filename:x.filename,outcome:rr,dbStamp40:i,deviceStamp40:t};if(n!=="none"&&!(i===0||!x.data||x.data.byteLength===0))return A._flags&2?this.sendFileToDevice(x,i,t,e,r):{filename:x.filename,outcome:Hr,dbStamp40:i,deviceStamp40:t}}wantDownloadPush(x,A,e,r){let t=x.flags_int;if(t&2)return"push";let i=this.fileContentMatches(A,x),n=kn(t);return n===33||n===1&&e>=r?i?"match":"push":n===97&&e>r?"push":"none"}async handleDeviceDelete(x,A,e){let r=A.stamp,t=QA(x.stamp);if(!(e&&(e.outcome===zi||e.outcome===Ne))){if(!(A._flags&2))return{filename:x.filename,outcome:Hr,dbStamp40:t,deviceStamp40:r};try{return await this.utoMaster.deleteFile(x.filename),await this.storage.deleteFile(x.filename),{filename:x.filename,outcome:Ki,dbStamp40:t,deviceStamp40:r}}catch(i){return this.logger?.error(`${O0} file delete error ${x.filename}: ${JSON.stringify(i)}`),{filename:x.filename,outcome:Ne,dbStamp40:t,deviceStamp40:r}}}}async decideDownloadMissing(x,A,e,r){let t=x.flags_int,i=QA(x.stamp);if(t&8)try{return await this.storage.deleteFile(x.filename),{filename:x.filename,outcome:Ki,dbStamp40:i,deviceStamp40:null}}catch(n){return this.logger?.error(`${O0} file delete error ${x.filename}: ${JSON.stringify(n)}`),{filename:x.filename,outcome:Ne,dbStamp40:i,deviceStamp40:null}}if(!(x.flags&12)&&dd(t)&&x.flags&2&&this.hasMatchingNode(x.filename,A)&&x.data)return this.sendFileToDevice(x,i,0,e,r)}hasMatchingNode(x,A){return A.some(e=>e.slice(0,-1)===x.slice(0,e.length-1))}async reconcileFileState(x){try{await this.reconcileFileStateUnguarded(x)}catch(A){if(x?.aborted)throw A;this.logger?.error(`${O0} file-state reconciliation failed: ${JSON.stringify(A)}`)}}async reconcileFileStateUnguarded(x){let A=await this.utoMaster.requestFileList(),e=new Set(Object.keys(A)),r=await this.storage.getFiles(),t=new Map(r.map(i=>[i.filename,i]));for(let[i,n]of Object.entries(A))Ox(x),await this.reconcileDeviceFile(i,n,t.get(i)??null);for(let i of r)Ox(x),e.has(i.filename)||await this.dropRowMissingFromDevice(i)}async reconcileDeviceFile(x,A,e){let r=!!((A._flags|(e?.flags??0))&8);if(e?.data&&!this.fileContentMatches(A,e)){this.logger?.info(`${O0} reconcile keep ${x}: row holds undeployed content`);return}if(!e?.data&&!r)return;let t={filename:x,stamp:fA(A.stamp),crc:A.crc32,size:A.size,flags:A._flags,flags_int:e?.flags_int??16,data:this.keepBlob(x,r)?e?.data??null:null};e&&this.fileRowMatches(e,t)||await this.storage.upsertFile(t)}keepBlob(x,A){return!A||Cd.has(x)}fileRowMatches(x,A){return x.stamp===A.stamp&&x.crc===A.crc&&x.size===A.size&&x.flags===A.flags&&x.flags_int===A.flags_int&&(x.data??null)===A.data}async dropRowMissingFromDevice(x){try{await this.storage.deleteFile(x.filename)}catch(A){this.logger?.error(`${O0} reconcile delete error ${x.filename}: ${JSON.stringify(A)}`)}}async validateDevice(x){Ox(x),this.emitProgress("validating",null,0,1);let A=await this.utoMaster.requestDeviceInfo();if(!A)throw new Error(`${O0} requestDeviceInfo returned null`);let e=await this.storage.getMetadataValue("device_id");if(e===null){if(!A.serialNumber)throw new Error(`${O0} DB metadata missing device_id and connected device has no serialNumber`);if(!this.storage.setMetadataValue)throw new Error(`${O0} DB metadata missing device_id`);await this.storage.setMetadataValue("device_id",A.serialNumber),e=A.serialNumber}if(e.toUpperCase()!==A.serialNumber.toUpperCase())throw new Error(`${O0} DB device_id "${e}" does not match connected device "${A.serialNumber}"`);return this.emitProgress("validating",null,1,1),A}buildTagMap(x){let A=new Map;for(let e=0;e<x.utos.length;e++){let r=x.utos[e];A.set(r.wTag,{index:e,flags:{up:r.flags.up,down:r.flags.down,setValue:!!r.flags.setValue},historic:r.flags.historic,sTag:r.sTag})}return A}async resolveDbTags(x){let A=await this.storage.getUtoDataTags(),e=new Set(A);for(let[r,t]of x)t.historic&&!e.has(r)&&A.push(r);return A}async buildTagStampCache(x,A,e){let r=new Map;for(let t of x){let i=A.get(t),n=await this.storage.getLatestStampForTag(t),F=n?QA(n):0,v=i&&i.index<e.stamps.length?e.stamps[i.index]:null;r.set(t,{dbStamp40:F,deviceStamp40:v,tagInfo:i})}return r}async executeChangeRequests(x,A,e,r,t,i){let n=await this.storage.getUtoChangeRequests(),F=this.groupChangeRequests(n),v=F.size;if(this.emitProgress(yF,null,0,v),v===0)return;let E=new Set,u=0;for(let[D,m]of F){Ox(i);let w=x.get(D),j=w?.sTag??`0x${D.toString(16)}`;this.emitProgress(yF,j,u,v),await this.executeChangeRequestTag(D,j,w,m,A,r,t,E),++u}E.size>0&&await this.repullExecutedTags(E,x,e,i)}groupChangeRequests(x){let A=new Map;for(let e of x){let r=A.get(e.tag)??[];r.push({stamp40:QA(e.stamp),user:e.user,json:e.json}),A.set(e.tag,r)}return A}async executeChangeRequestTag(x,A,e,r,t,i,n,F){if(!e){this.pushChangeResults(n,x,A,r,"unknown-tag");return}if(!e.flags.setValue){this.pushChangeResults(n,x,A,r,"skip-unsupported");return}let v=e.index<t.stamps.length?t.stamps[e.index]:0,E=r.filter(D=>D.stamp40<=v),u=r.filter(D=>D.stamp40>v);this.pushChangeResults(n,x,A,E,Xi),u.length>0&&await this.coalesceAndSend(x,A,e,u,i,n,F)}async coalesceAndSend(x,A,e,r,t,i,n){let F=await this.storage.getRowForTag(x);if(t.get(x)?.outcome===Ne||!F||!F.data){this.pushChangeResults(i,x,A,r,"error");return}let v=this.resolveSetObject(F.data,r,A);if(v===null){this.pushChangeResults(i,x,A,r,"error");return}if(Object.keys(v).length===0){this.pushChangeResults(i,x,A,r,"skip-no-change");return}let E=r[r.length-1].stamp40,u=await this.utoMaster.sendSetValue(x,JSON.stringify(v),E);u.outcome==="ok"||u.outcome==="stamp"?(n.add(x),this.pushChangeResults(i,x,A,r,kF,u.resultCode)):u.outcome==="denied"?(this.logger?.warn(`${O0} change-request denied ${A} (result=${u.resultCode}) \u2014 server will retry`),this.pushChangeResults(i,x,A,r,"denied",u.resultCode)):(this.logger?.error(`${O0} change-request error ${A} (result=${u.resultCode})`),this.pushChangeResults(i,x,A,r,"error",u.resultCode))}resolveSetObject(x,A,e){try{let r=JSON.parse(z0.cp1252Unpack(x,0,x.byteLength));return this.buildSetObject(r,A,e)}catch(r){return this.logger?.error(`${O0} change-request unparseable uto_data ${e}: ${r}`),null}}buildSetObject(x,A,e){let r={};for(let t of A){let i=JSON.parse(t.json);if(!this.isPlainRecord(i))throw new Error(`change-request JSON is not an object on ${e}`);for(let[n,F]of Object.entries(i)){let v=this.resolveChangeField(x[n],F,n,e);v.apply&&(r[n]=v.value,x[n]=v.value)}}return r}resolveChangeField(x,A,e,r){if(this.isBitwiseOp(A)){let{op:t,val:i}=A;return this.resolveBitwiseOp(x,t,i,e,r)}return x===A?{apply:!1}:{apply:!0,value:A}}resolveBitwiseOp(x,A,e,r,t){return A!=="|"&&A!=="&"?(this.logger?.warn(`${O0} change-request unknown op "${A}" on ${t}.${r} \u2014 skipped`),{apply:!1}):typeof e!="number"?(this.logger?.warn(`${O0} change-request op "${A}" with non-number val on ${t}.${r} \u2014 skipped`),{apply:!1}):x===void 0?A==="|"?{apply:!0,value:e}:{apply:!1}:typeof x!="number"?(this.logger?.warn(`${O0} change-request op "${A}" on non-number ${t}.${r} \u2014 skipped`),{apply:!1}):{apply:!0,value:A==="|"?x|e:x&e}}isBitwiseOp(x){return this.isPlainRecord(x)&&"op"in x}isPlainRecord(x){return typeof x=="object"&&x!==null&&!Array.isArray(x)}pushChangeResults(x,A,e,r,t,i){for(let n of r)x.push({tag:A,sTag:e,stamp40:n.stamp40,user:n.user,outcome:t,resultCode:i})}async repullExecutedTags(x,A,e,r){let t=null;try{t=await this.utoMaster.requestStamps()}catch(i){this.logger?.warn(`${O0} change-request STAMPS re-fetch failed \u2014 using per-tag stamps: ${i}`)}for(let i of x)Ox(r),await this.repullExecutedTag(i,A,t,e)}async repullExecutedTag(x,A,e,r){try{let t=await this.utoMaster.requestUto(x,0);if(!t){this.logger?.info(`${O0} change-request re-pull tag=0x${x.toString(16)} \u2014 device returned no data (E_EOD), DB row unchanged`);return}let i=await this.storage.getRowForTag(x),n=t.stamp;await this.storage.replaceUtoRow({tag:x,stamp:fA(n),flags:i?.flags??0,site_related:i?.site_related??0,data:t.data?new Uint8Array(t.data.buffer.slice(t.data.byteOffset,t.data.byteOffset+t.data.byteLength)):null});let F=r.get(x);if(F){let v=A.get(x),E=e&&v&&v.index<e.stamps.length?e.stamps[v.index]:n;F.dbStamp40=n,F.deviceStamp40=E}this.logger?.info(`${O0} change-request re-pull tag=0x${x.toString(16)} \u2192 stamp ${n}`)}catch(t){this.logger?.error(`${O0} change-request re-pull error tag=0x${x.toString(16)}: ${t}`)}}aggregateResult(x,A,e){let r=[...x.values()],t=[...A.values()],i=jF(t);return{tags:r,files:t,changeRequests:e,requiresReconnectSync:i.length>0,rebootFilesDeployed:i,totalTagsUploaded:r.filter(n=>n.outcome==="upload"&&!n.historic).length,totalTagsDownloaded:r.filter(n=>n.outcome==="download").length,totalTagsSkipped:r.filter(n=>n.outcome===rr||n.outcome==="skip-db-readonly"||n.outcome===Hr).length,totalHistoricRecordsAppended:r.reduce((n,F)=>n+(F.recordsAppended??0),0),totalFilesUploaded:t.filter(n=>n.outcome===zi).length,totalFilesDownloaded:t.filter(n=>n.outcome==="download").length,totalFilesDeleted:t.filter(n=>n.outcome===Ki).length,totalChangeRequestsExecuted:e.filter(n=>n.outcome===kF).length,totalErrors:r.filter(n=>n.outcome===Ne).length+t.filter(n=>n.outcome===Ne).length+e.filter(n=>n.outcome===ud).length}}async sync(x){let{signal:A}=x??{},e=await this.validateDevice(A);Ox(A),this.emitProgress(dn,null,0,3);let r=this.buildTagMap(e),t=await this.utoMaster.requestStamps();if(!t)throw new Error(`${O0} requestStamps returned null`);this.emitProgress(dn,"stamps",1,3);let i=await this.utoMaster.requestFileList();this.emitProgress(dn,"file-list",2,3);let n=await this.resolveDbTags(r);this.emitProgress(dn,"db-tags",3,3);let F=await this.buildTagStampCache(n,r,t),v=new Map,E=new Map,u=[],D=await this.isAppInDevPhase();return Ox(A),await this.uploadUtoTags(n,F,v,A),Ox(A),await this.uploadFiles(i,E,D,A),Ox(A),await this.executeChangeRequests(r,t,F,v,u,A),Ox(A),await this.downloadUtoTags(n,F,v,A),Ox(A),await this.downloadFiles(i,E,D,A),Ox(A),jF([...E.values()]).length===0&&await this.reconcileFileState(A),this.emitProgress("complete",null,0,0),this.aggregateResult(v,E,u)}async executeAdHocChangeRequest(x,A){let e=await this.utoMaster.requestDeviceInfo();if(!e)throw new Error(`${O0} requestDeviceInfo returned null`);let r=this.buildTagMap(e),t=await this.utoMaster.requestStamps();if(!t)throw new Error(`${O0} requestStamps returned null`);let i=r.get(x),n=i?.sTag??`0x${x.toString(16)}`,F=A.map(m=>({stamp40:m.stamp40,user:"",json:m.json})).sort((m,w)=>m.stamp40-w.stamp40),v=new Map,E=[],u=new Set;return await this.executeChangeRequestTag(x,n,i,F,t,v,E,u),u.size>0&&await this.repullExecutedTags(u,r,new Map,void 0),E.find(m=>m.outcome!==Xi)?.outcome??Xi}},pd=require("events"),bd=require("events"),md=require("events"),hd=5e3,Ls=class _8 extends md.EventEmitter{constructor(A=ZA){super(),A0(this,"logger",A),A0(this,"ws",null),A0(this,"bridgeTransport",null),A0(this,"bridgeSignal"),A0(this,"bridgeResolve",null),A0(this,"bridgeReject",null),A0(this,"serverMessageCount",0),A0(this,"settled",!1),A0(this,"abortHandler",null),A0(this,"connectTimeout"),A0(this,"writeQueue",[]),A0(this,"isProcessingQueue",!1),A0(this,"queueAborted",!1),A0(this,"queueDrainPromise",Promise.resolve()),A0(this,"transportUnsubscribe",null)}static buildSyncUrl(A,e){return`wss://${A}/uto/1/sync/${e}`}resetBridgeState(){this.serverMessageCount=0,this.settled=!1,this.abortHandler=null,this.connectTimeout=void 0,this.writeQueue=[],this.isProcessingQueue=!1,this.queueAborted=!1,this.queueDrainPromise=Promise.resolve(),this.bridgeResolve=null,this.bridgeReject=null,this.bridgeTransport=null,this.bridgeSignal=void 0,this.transportUnsubscribe=null}async processWriteQueue(){if(!this.isProcessingQueue){for(this.isProcessingQueue=!0;this.writeQueue.length>0&&!this.queueAborted;){let A=this.writeQueue.shift();try{await t8(this.bridgeTransport,A)}catch(e){let r=e instanceof Error?e.message:String(e);this.logger.error(`Error writing to transport: ${r}`)}}this.isProcessingQueue=!1}}cleanup(){this.transportUnsubscribe&&(this.transportUnsubscribe(),this.transportUnsubscribe=null),this.abortHandler&&this.bridgeSignal&&(this.bridgeSignal.removeEventListener("abort",this.abortHandler),this.abortHandler=null),this.connectTimeout!==void 0&&(clearTimeout(this.connectTimeout),this.connectTimeout=void 0),this.ws=null}settle(A,e){this.settled||(this.settled=!0,this.cleanup(),A==="resolve"?this.bridgeResolve?.({serverMessageCount:this.serverMessageCount}):this.bridgeReject?.(e))}attachWebSocketHandlers(A,e){let r=t=>{A.readyState===WebSocket.OPEN&&!this.bridgeSignal?.aborted&&!this.settled&&A.send(t)};this.abortHandler=()=>{this.logger.info("WebSocket bridge aborted"),this.queueAborted=!0,this.writeQueue.length=0,(A.readyState===WebSocket.OPEN||A.readyState===WebSocket.CONNECTING)&&A.close(),this.settle("reject",new Error("Operation aborted"))},this.bridgeSignal&&this.bridgeSignal.addEventListener("abort",this.abortHandler),A.onopen=()=>{this.connectTimeout!==void 0&&(clearTimeout(this.connectTimeout),this.connectTimeout=void 0),this.logger.info(`WebSocket connected to ${e}`),this.transportUnsubscribe=this.bridgeTransport.onData(r),this.emit("wsConnected")},A.onmessage=t=>{this.serverMessageCount++,this.emit("serverMessage",this.serverMessageCount),!(this.bridgeSignal?.aborted||this.settled)&&(this.writeQueue.push(t.data),this.isProcessingQueue||(this.queueDrainPromise=this.processWriteQueue()))},A.onclose=t=>{this.logger.info(`WebSocket closed (server=${e}, code=${t.code}, messages=${this.serverMessageCount})`),this.emit("wsClosed",t.code,t.reason),this.queueDrainPromise.then(()=>this.settle("resolve")).catch(()=>this.settle("resolve"))},A.onerror=t=>{this.logger.error(`WebSocket error (server=${e})`),this.emit("wsError",t),this.queueAborted=!0,this.writeQueue.length=0,this.settle("reject",new Error("WebSocket error"))}}async bridge(A,e,r,t){return new Promise((i,n)=>{if(t?.aborted){n(new Error("Operation aborted"));return}this.resetBridgeState(),this.bridgeTransport=A,this.bridgeSignal=t,this.bridgeResolve=i,this.bridgeReject=n;let F=_8.buildSyncUrl(e,r);this.logger.info(`Opening WebSocket: ${F}`);let v=new WebSocket(F);v.binaryType="arraybuffer",this.ws=v,this.connectTimeout=setTimeout(()=>{v.readyState===WebSocket.CONNECTING&&(this.logger.error("WebSocket connection timeout"),v.close(),this.settle("reject",new Error("WebSocket connection timeout")))},hd),this.attachWebSocketHandlers(v,e)})}close(){this.ws&&this.ws.readyState===WebSocket.OPEN&&this.ws.close()}},S8="https://lic.mydatanet.at/api/2/";async function $8(x,A=S8){let e=`${A}devices/${x}/assignment`,r=await fetch(e);if(!r.ok)throw new Error(`Failed to get device assignment: ${r.status} ${r.statusText}`);return r.json()}var T8=class extends bd.EventEmitter{constructor(x=ZA){super(),A0(this,"logger",x)}async execute(x,A,e,r){let t=e;t||(this.logger.info("[LegacySync] No serverUrl provided, resolving via device assignment..."),this.emit("syncPhase",{phase:"resolving-server"}),t=(await $8(A)).server_url,this.logger.info("[LegacySync] Resolved server URL: "+t)),this.logger.info("[LegacySync] Starting legacy sync (server="+t+")");let i=new Ls(this.logger);i.on("wsConnected",()=>this.emit("wsConnected")),i.on("wsClosed",(F,v)=>this.emit("wsClosed",F,v)),i.on("wsError",F=>this.emit("wsError",F)),i.on("serverMessage",F=>this.emit("serverMessage",F));let n=await i.bridge(x,t,A,r);return this.logger.info("[LegacySync] Legacy sync completed (serverMessages="+n.serverMessageCount+")"),{serverMessageCount:n.serverMessageCount}}},jd=require("events"),P8="Operation aborted";function gd(x){return x instanceof Error?x.message:String(x)}function Yi(x){if(x?.aborted)throw new Error(P8)}var q8=class extends jd.EventEmitter{constructor(x,A=ZA){super(),A0(this,"atHandler",x),A0(this,"logger",A)}async execute(x,A,e,r){this.logger.info("Starting debug-enabled sync");let t=[{name:"mnt",queryServer:n=>this.atHandler.queryMntServerConfig(n),initiateSync:n=>this.atHandler.initiateMntSync(n)},{name:"mdn",queryServer:n=>this.atHandler.queryMdnServerConfig(n),initiateSync:n=>this.atHandler.initiateMdnSync(n)}],i={};for(let n of t)try{i[n.name]=await this.runSyncPhase(n,x,A,r)}catch(F){if(r?.aborted)throw new Error(P8);let v=`${n.name.toUpperCase()} sync phase failed: ${gd(F)}`;throw this.logger.error(v),new Error(v)}return this.logger.info(`Debug sync completed (mntMessages=${i.mnt}, mdnMessages=${i.mdn})`),{mntServerMessageCount:i.mnt,mdnServerMessageCount:i.mdn}}async runSyncPhase(x,A,e,r){Yi(r);let t=x.name.toUpperCase();this.emit("syncPhase",{phase:x.name}),this.logger.info(`Phase: Querying ${t} server configuration`);let i=await x.queryServer(r);this.logger.info(`${t} server domain: ${i}`),Yi(r),await x.initiateSync(r),Yi(r);let n=await this.syncWithServer(A,i,e,r);return this.logger.info(`${t} phase completed (serverMessages=${n.serverMessageCount})`),n.serverMessageCount}async syncWithServer(x,A,e,r){let t=new Ls(this.logger),i=!1;t.on("wsConnected",()=>this.emit("wsConnected"));let n=this.atHandler.createConCloseMonitor(()=>{i=!0,this.logger.info("Device initiated close (+CONCLOSE), closing WebSocket"),t.close()});try{let F=await t.bridge(x,A,e,r);return i?this.logger.info("Connection closed by device (+CONCLOSE)"):(this.logger.info("Connection closed by server, sending +CONCLOSE to device"),await this.atHandler.sendConnectionClose(r)),F}finally{n()}}},yd=class extends pd.EventEmitter{constructor(x,A,e=ZA){super(),A0(this,"syncTransport",x),A0(this,"logger",e),A0(this,"atHandler"),this.atHandler=A??null}async sync(x){let A=this.atHandler?"debug":"legacy";this.emit("syncStart",{mode:A});try{if(this.atHandler)try{return this.emit("syncPhase",{phase:"debug-sync"}),await this.syncWithDebug(x)}catch(e){return this.logger.warn("[SyncManager] Debug sync failed, falling back to legacy sync: "+(e instanceof Error?e.message:String(e))),this.emit("syncPhase",{phase:"debug-fallback-legacy"}),await this.syncLegacy(x)}return this.emit("syncPhase",{phase:"legacy"}),await this.syncLegacy(x)}catch(e){throw this.emit("syncError",e),e}}async syncLegacy(x){let A=new T8(this.logger);A.on("syncPhase",t=>this.emit("syncPhase",t));let r={mode:"legacy",serverMessageCount:(await A.execute(this.syncTransport,x.serialNumber,x.serverUrl,x.signal)).serverMessageCount};return this.emit("syncComplete",r),r}async syncWithDebug(x){let A=new q8(this.atHandler,this.logger);A.on("syncPhase",t=>this.emit("syncPhase",t));let e=await A.execute(this.syncTransport,x.serialNumber,x.serverUrl??"",x.signal),r={mode:"debug",serverMessageCount:e.mntServerMessageCount+e.mdnServerMessageCount,mntServerMessageCount:e.mntServerMessageCount,mdnServerMessageCount:e.mdnServerMessageCount};return this.emit("syncComplete",r),r}dispose(){}},kd=require("events"),_x={MNT_CFG:"at+mntcfg?",MDN_CFG:"at+mdncfg?",MNT_SYNC:"at+mntsync",MDN_SYNC:"at+mdnsync",CON_CLOSE:"at+conclose",APP_GET_METADATA:"AT+APP=GETMETADATA",APP_GET_DATAVALUE:"AT+APP=GETDATAVALUE",APP_TRIG_MEASURE:"AT+APP=TRIGMEASURE",APP_TRIG_MEASURE_TEST:"AT+APP=TRIGMEASURE=?",ATI:"ati",RM2M_STATE:"at+rm2mstate?",TX:"at+tx",TX_MAINTENANCE:"at+tx=4",TX_GSM_POSITION:"at+tx=1",TX_MODE_TRIGGERED:"at+txmode=0",TX_MODE_WAKEUP:"at+txmode=1",TX_MODE_ONLINE:"at+txmode=2",COMPANION_CERT:"AT+COMPCERT",COMPANION_CERT_TEST:"AT+COMPCERT=?"},K0={OK:"OK",ERROR:"ERROR",SYNC_START:"+SYNC START",MEASURED:"+MEASURED",CON_CLOSE:"+CONCLOSE",MNT_CFG_PREFIX:"+MNTCFG",MDN_CFG_PREFIX:"+MDNCFG",RM2M_STATE:"+RM2MSTATE",ERROR_PIN_REQUIRED:"ERROR PIN REQUIRED",ERROR_NO_DATA:"ERROR NO DATA",COMPCERT_ERROR:/\+COMPCERT ERROR:\s*(\d+)/},Vx=1e4,N8=9e4,I8=/(?:ERROR PIN REQUIRED|ERROR NO DATA|ERROR|OK)\r\n/;function M8(){return{buffer:"",closedByDevice:!1,reset(){this.buffer="",this.closedByDevice=!1}}}var tr="Operation aborted",Hx=class extends Error{constructor(x="AT command handler was disposed"){super(x),this.name="AtHandlerDisposedError"}},Rs=class extends Error{constructor(x="Device returned ERROR response"){super(x),this.name="AtDeviceError"}},wd=class extends kd.EventEmitter{constructor(x,A=ZA){super(),A0(this,"transport",x),A0(this,"logger",A),A0(this,"mutex",new gs("AtCommandHandler")),A0(this,"bufferState",M8()),A0(this,"responseCallback",null),A0(this,"decoder",new TextDecoder),A0(this,"dataHandler"),A0(this,"disposeTransportListener"),A0(this,"isDisposed",!1),A0(this,"activeAbort",null),A0(this,"session"),this.dataHandler=e=>this.handleIncomingData(e),this.disposeTransportListener=this.transport.onData(this.dataHandler),this.session={sendAndWait:(e,r,t=Vx,i)=>this.executeSendAndWait(e,r,t,i),sendRaw:(e,r=Vx)=>this.executeSendRaw(e,r),queryMntServerConfig:e=>this.executeQueryConfig(_x.MNT_CFG,K0.MNT_CFG_PREFIX,e),queryMdnServerConfig:e=>this.executeQueryConfig(_x.MDN_CFG,K0.MDN_CFG_PREFIX,e),initiateMntSync:e=>this.executeInitiateMntSync(e),initiateMdnSync:e=>this.executeInitiateMdnSync(e),sendCompanionCert:(e,r)=>this.executeSendCompanionCert(e,r),queryCompanionCertSupport:e=>this.executeQueryCompanionCertSupport(e),sendConnectionClose:e=>this.executeSendConnectionClose(e)}}get isBusy(){return this.mutex.islocked}get disposed(){return this.isDisposed}async withAtLock(x){await this.mutex.requestLock();try{if(this.isDisposed)throw new Hx;return await x(this.session)}finally{this.mutex.unlock()}}handleIncomingData(x){let A=this.decoder.decode(x);this.bufferState.buffer+=A,this.emit("data",A),this.responseCallback&&this.responseCallback(this.bufferState.buffer),!this.responseCallback&&this.bufferState.buffer.length>1e3&&(this.bufferState.buffer=this.bufferState.buffer.slice(-500))}encodeCommand(x){let A=new Uint8Array(x.length+2);for(let e=0;e<x.length;e++)A[e]=x.charCodeAt(e);return A[x.length]=10,A[x.length+1]=13,A.buffer}makeCleanup(x,A,e){return()=>{this.responseCallback=null,this.activeAbort=null,clearTimeout(x),A&&e&&A.removeEventListener("abort",e)}}makeResponseChecker(x,A,e,r){let t=x instanceof RegExp;return i=>{if(x!==K0.ERROR&&i.includes(K0.ERROR)){A(),r(new Rs);return}let n=!1,F=i;if(t){let v=i.match(x);v&&(n=!0,F=v[0])}else n=i.includes(x);if(n){A(),e(F);return}i.length>500&&(this.bufferState.buffer=this.bufferState.buffer.slice(-250))}}executeSendAndWait(x,A,e,r){return new Promise((t,i)=>{if(this.isDisposed){i(new Hx);return}if(r?.aborted){i(new Error(tr));return}x&&(this.bufferState.buffer="");let F=A instanceof RegExp?A.source:A,v={cleanup:()=>{}},E=setTimeout(()=>{v.cleanup(),i(new Error(`Timeout waiting for response: ${F}`))},e),u=()=>{v.cleanup(),i(new Error(tr))};v.cleanup=this.makeCleanup(E,r,u),r&&r.addEventListener("abort",u);let D=this.makeResponseChecker(A,v.cleanup,t,i);this.responseCallback=D,this.activeAbort=()=>{v.cleanup(),i(new Hx)},!x&&this.bufferState.buffer&&D(this.bufferState.buffer),x&&(this.logger.info("TX: "+x),this.transport.write(this.encodeCommand(x)).catch(m=>{v.cleanup(),i(m)}))})}executeSendRaw(x,A){return new Promise((e,r)=>{if(this.isDisposed){r(new Hx);return}this.bufferState.buffer="";let t=setTimeout(()=>{i(),r(new Error(`Timeout waiting for raw AT response to: ${x}`))},A),i=this.makeCleanup(t);this.activeAbort=()=>{i(),r(new Hx)},this.responseCallback=n=>{I8.test(n)&&(i(),this.logger.info("RX: "+n.trim()),e(n))},this.logger.info("TX: "+x),this.transport.write(this.encodeCommand(x)).catch(n=>{i(),r(n)})})}executeQueryConfig(x,A,e){return new Promise((r,t)=>{if(this.isDisposed){t(new Hx);return}if(e?.aborted){t(new Error(tr));return}this.bufferState.buffer="";let i={cleanup:()=>{}},n=setTimeout(()=>{i.cleanup(),this.logger.error(`Timeout waiting for ${A} server config`),t(new Error(`Timeout waiting for ${A} response \u2014 server configuration not available`))},Vx),F=()=>{i.cleanup(),t(new Error(tr))};i.cleanup=this.makeCleanup(n,e,F),e&&e.addEventListener("abort",F);let v=new RegExp(`\\${A}:\\s*<?([^,>\\s]+)>?`);this.activeAbort=()=>{i.cleanup(),t(new Hx)},this.responseCallback=E=>{let u=E.match(v);if(u){i.cleanup();let D=u[1].trim();this.logger.info(`Server config ${A}: ${D}`),r(D);return}E.length>500&&(this.bufferState.buffer=this.bufferState.buffer.slice(-250))},this.logger.info("TX: "+x),this.transport.write(this.encodeCommand(x)).catch(E=>{i.cleanup(),this.logger.error(`Failed to send ${A} command: `+(E instanceof Error?E.message:String(E))),t(E)})})}async sendAndWait(x,A,e=Vx,r){return this.withAtLock(t=>t.sendAndWait(x,A,e,r))}async sendRaw(x,A=Vx){return this.withAtLock(e=>e.sendRaw(x,A))}async queryMntServerConfig(x){return this.withAtLock(A=>A.queryMntServerConfig(x))}async queryMdnServerConfig(x){return this.withAtLock(A=>A.queryMdnServerConfig(x))}async initiateMntSync(x){return this.withAtLock(A=>A.initiateMntSync(x))}async initiateMdnSync(x){return this.withAtLock(A=>A.initiateMdnSync(x))}async sendCompanionCert(x,A){return this.withAtLock(e=>e.sendCompanionCert(x,A))}async executeInitiateMntSync(x){this.logger.info("Initiating MNT sync"),await this.executeSendAndWait(_x.MNT_SYNC,K0.OK,Vx,x)}async executeInitiateMdnSync(x){this.logger.info("Initiating MDN sync");try{await this.executeSendAndWait(_x.MDN_SYNC,K0.OK,Vx,x),await this.executeSendAndWait(null,K0.SYNC_START,Vx,x)}catch(A){this.logger.error("Failed to initiate MDN sync: "+(A instanceof Error?A.message:String(A)))}}async executeSendCompanionCert(x,A){if(this.isDisposed)throw new Hx;if(A?.aborted)throw new Error(tr);let e=x.replace(/-/g,"+").replace(/_/g,"/")+"=".repeat((4-x.length%4)%4),r=e.length,t=await this.executeSendAndWait(`${_x.COMPANION_CERT}=${r}`,K0.OK,Vx,A),i=parseInt(t.match(/(\d+)/)[1],10),n=0;for(;n<r;){let F=Math.min(i,r-n),v=e.slice(n,n+F);await this.executeSendAndWait(`${_x.COMPANION_CERT}=${F},${n},${v}`,K0.OK,Vx,A),n+=F}return this.executeCompanionCertFinalize(r,A)}executeCompanionCertFinalize(x,A){return new Promise((e,r)=>{if(this.isDisposed){r(new Hx);return}if(A?.aborted){r(new Error(tr));return}this.bufferState.buffer="";let t={cleanup:()=>{}},i=setTimeout(()=>{t.cleanup(),r(new Error("Timeout waiting for AT+COMPCERT finalize response"))},Vx),n=()=>{t.cleanup(),r(new Error(tr))};t.cleanup=this.makeCleanup(i,A,n),A&&A.addEventListener("abort",n),this.activeAbort=()=>{t.cleanup(),r(new Hx)},this.responseCallback=v=>{let E=v.match(K0.COMPCERT_ERROR);if(E){t.cleanup(),e({success:!1,errorCode:parseInt(E[1],10)});return}if(v.includes(K0.OK)){t.cleanup(),e({success:!0});return}v.length>500&&(this.bufferState.buffer=this.bufferState.buffer.slice(-250))};let F=`${_x.COMPANION_CERT}=0,${x}`;this.logger.info("TX: "+F),this.transport.write(this.encodeCommand(F)).catch(v=>{t.cleanup(),r(v)})})}async queryCompanionCertSupport(x){return this.withAtLock(A=>A.queryCompanionCertSupport(x))}async executeQueryCompanionCertSupport(x){try{return await this.executeSendAndWait(_x.COMPANION_CERT_TEST,K0.OK,Vx,x),!0}catch(A){if(A instanceof Hx)throw A;return!1}}async sendConnectionClose(x){return this.withAtLock(A=>A.sendConnectionClose(x))}async executeSendConnectionClose(x){try{await this.executeSendAndWait(_x.CON_CLOSE,K0.CON_CLOSE,Vx,x)}catch(A){this.logger.error("Failed to receive +CONCLOSE response: "+(A instanceof Error?A.message:String(A)))}}createConCloseMonitor(x){let A="",e=r=>{A+=r,A.includes(K0.CON_CLOSE)&&(A="",this.bufferState.closedByDevice=!0,x()),A.length>1e3&&(A=A.slice(-500))};return this.on("data",e),()=>{this.off("data",e)}}dispose(){this.isDisposed||(this.isDisposed=!0,this.activeAbort?.(),this.disposeTransportListener(),this.responseCallback=null,this.activeAbort=null,this.removeAllListeners())}},L8=(x=>(x[x.FORMAT=1]="FORMAT",x[x.SIGNATURE=2]="SIGNATURE",x[x.EXPIRED=3]="EXPIRED",x[x.NO_MDN_PUBKEY=4]="NO_MDN_PUBKEY",x[x.BUSY=5]="BUSY",x[x.INTERNAL=6]="INTERNAL",x))(L8||{}),_d=require("events"),Qi="requesting-cert",Zi="cert-revoked",R8=class Bs extends _d.EventEmitter{constructor(){super(...arguments),A0(this,"utoMaster",null)}async authenticate(A){let e=A.logger??yn,{signal:r,atHandler:t}=A,i=()=>{if(r?.aborted)throw new Error("Operation aborted")};try{this.emitPhase("checking-cert"),i();let n=await this.loadOrGenerateKeypair(A.storage),F=await A.storage.getCertificate(A.apiConfig.apiHost);(F===null||!bs(F.notAfter))&&(e.info("Companion cert missing or near expiry \u2014 requesting new cert"),this.emitPhase(Qi),i(),F=await this.requestAndStoreCert(n,A)),this.utoMaster=new n8(A.utoTransport,e,A.timeSource),this.emitPhase("cert-presenting"),i();let v=F;F=await t.withAtLock(async D=>{let m=await this.presentCertWithRefresh(D,v,n,A);return await D.initiateMdnSync(r),m}),this.emitPhase("ecs-handshake"),i(),await this.utoMaster.init();let E=await this.utoMaster.initiateEcsHandshake({companionPublicKey:n.publicKey,companionPrivateKey:n.privateKey,signal:r});if(!E.success)return this.fail("ecs-handshake",`ECS handshake failed (code ${E.resultCode})`);this.emitPhase("connected");let u=this.utoMaster;return this.utoMaster=null,{success:!0,utoMaster:u}}catch(n){return this.handleError(n)}}dispose(){this.utoMaster=null,this.removeAllListeners()}async loadOrGenerateKeypair(A){let e=await A.getKeypair();if(e!==null)return e;let r=await rs();return await A.saveKeypair(r),r}static async fetchCertOrThrowRevoked(A,e){try{return await zF(e.apiConfig,{publicKey:A.publicKey,subject:e.subject})}catch(r){throw r instanceof wt&&(r.httpStatus===401||r.httpStatus===404)?(await e.storage.clearCertificate(e.apiConfig.apiHost),new xs(Zi,`Companion cert revoked or session expired (HTTP ${r.httpStatus})`,{httpStatus:r.httpStatus,apiCode:r.code})):r}}async requestAndStoreCert(A,e){let r=await Bs.fetchCertOrThrowRevoked(A,e),t={base64Url:r.certificateBase64Url,notAfter:r.notAfter};return await e.storage.saveCertificate(t,e.apiConfig.apiHost),t}static async refreshCertificate(A){let e=await A.storage.getKeypair(),r=e!==null?e:await(async()=>{let n=await rs();return await A.storage.saveKeypair(n),n})(),t=await Bs.fetchCertOrThrowRevoked(r,A),i={base64Url:t.certificateBase64Url,notAfter:t.notAfter};return await A.storage.saveCertificate(i,A.apiConfig.apiHost),i}static async clearCredentials(A,e){await A.clearCertificate(e)}async presentCertWithRefresh(A,e,r,t){let i=await A.sendCompanionCert(e.base64Url,t.signal);if(i.success||i.errorCode===3&&((t.logger??yn).info("Device reported EXPIRED \u2014 refreshing cert and retrying"),this.emitPhase(Qi),e=await this.requestAndStoreCert(r,t),i=await A.sendCompanionCert(e.base64Url,t.signal),i.success))return e;throw new xs("cert-presenting",`AT+COMPCERT rejected (code ${i.errorCode??"?"})`,{certErrorCode:i.errorCode})}emitPhase(A){this.emit("phase",A)}fail(A,e){return this.emit("phase","error"),{success:!1,phase:A,error:e}}handleError(A){return A instanceof xs?(this.emit("phase",A.phase===Zi?Zi:"error"),{success:!1,phase:A.phase,error:A.message,certErrorCode:A.certErrorCode,httpStatus:A.httpStatus,apiCode:A.apiCode}):(this.emit("phase","error"),A instanceof wt?{success:!1,phase:Qi,error:A.message,httpStatus:A.httpStatus,apiCode:A.code}:{success:!1,phase:"error",error:A instanceof Error?A.message:String(A)})}};A0(R8,"encodePublicKeyBase64Url",ps);var Sd=R8,xs=class extends Error{constructor(x,A,e={}){super(A),A0(this,"phase",x),A0(this,"extra",e),this.name="AuthError"}get certErrorCode(){return this.extra.certErrorCode}get httpStatus(){return this.extra.httpStatus}get apiCode(){return this.extra.apiCode}},O8=(x=>(x.CERT_FORMAT="cert_format",x.CERT_SIGNATURE="cert_signature",x.CERT_EXPIRED="cert_expired",x.NO_MDN_PUBKEY="no_mdn_pubkey",x.DEVICE_BUSY="device_busy",x.DEVICE_INTERNAL="device_internal",x.ECS_FAILURE="ecs_failure",x.CERT_REVOKED="cert_revoked",x.SESSION_EXPIRED="session_expired",x.ABORTED="aborted",x.UNKNOWN="unknown",x))(O8||{}),$d={cert_format:"companion_auth.error.cert_format",cert_signature:"companion_auth.error.cert_signature",cert_expired:"companion_auth.error.cert_expired",no_mdn_pubkey:"companion_auth.error.no_mdn_pubkey",device_busy:"companion_auth.error.device_busy",device_internal:"companion_auth.error.device_internal",ecs_failure:"companion_auth.error.ecs_failure",cert_revoked:"companion_auth.error.cert_revoked",session_expired:"companion_auth.error.session_expired",aborted:"companion_auth.error.aborted",unknown:"companion_auth.error.unknown"};function Td(x){if(x.certErrorCode!==void 0)switch(x.certErrorCode){case 1:return"cert_format";case 2:return"cert_signature";case 3:return"cert_expired";case 4:return"no_mdn_pubkey";case 5:return"device_busy";case 6:return"device_internal"}return x.phase==="cert-revoked"?x.httpStatus===401?"session_expired":"cert_revoked":x.phase==="ecs-handshake"?"ecs_failure":x.error==="Operation aborted"?"aborted":"unknown"}var Pd=require("events");function G8(x){let A=x.replace(/\r\nOK\r\n$/,"").trim();return A?A.split("\f").map(e=>{let r=e.split(" ");return r.length<4?null:{name:r[0],scale:parseFloat(r[1]),offset:parseFloat(r[2]),unit:r[3]}}).filter(e=>e!==null):[]}function U8(x){let A=x.replace(/^\+[^\r\n]*\r\n/gm,"").replace(/\r\nOK\r\n$/,"").trim();return A?A.split("\f"):[]}function H8(x,A,e){let r=parseFloat(x);return isNaN(r)?x:parseFloat(Number(r*A+e).toFixed(3)).toString()}function Cs(x,A){return x.map((e,r)=>({name:e.name,displayValue:H8(A[r]??"",e.scale,e.offset),unit:e.unit}))}var qd=2e3,J8=class extends Pd.EventEmitter{constructor(x,A=ZA){super(),A0(this,"atHandler",x),A0(this,"logger",A),A0(this,"datapoints",[]),A0(this,"values",[]),A0(this,"polling",!1),A0(this,"pollTimer",null),A0(this,"fetchInProgress",!1),A0(this,"fetchPromise",null)}async checkSupport(){this.logger.info("Checking local data support");let x=await this.atHandler.sendRaw(_x.APP_GET_METADATA),A=x.includes(K0.OK)?{supported:!0,pinRequired:!1}:x.includes(K0.ERROR_PIN_REQUIRED)?{supported:!0,pinRequired:!0}:x.includes(K0.ERROR_NO_DATA)?{supported:!1,pinRequired:!1}:x.includes(K0.ERROR)?{supported:!1,pinRequired:!1}:{supported:!1,pinRequired:!1};return this.logger.info("Local data support: "+JSON.stringify(A)),A}async fetchMetadata(x){this.logger.info("Fetching metadata"+(x?" (with PIN)":""));let A=x?`${_x.APP_GET_METADATA}=${x}`:_x.APP_GET_METADATA,e=await this.atHandler.sendRaw(A);if(this.logger.debug("Metadata response: "+e),e.includes(K0.ERROR_PIN_REQUIRED))return this.logger.warn("PIN required/invalid for metadata"),null;if(e.includes(K0.ERROR_NO_DATA))return this.logger.warn("No data available from device"),this.datapoints=[],this.values=[],this.emit("metadata",[]),this.emit("error","No local data available from device"),[];if(e.includes(K0.OK)){let r=G8(e);return this.logger.info("Parsed "+r.length+" datapoints"),this.datapoints=r,this.values=new Array(r.length).fill(""),this.emit("metadata",r),r}return e.includes(K0.ERROR)?(this.logger.error("Metadata fetch error: "+e),this.emit("error","Device returned error during metadata fetch"),[]):[]}async fetchValues(x){return this.readValues(A=>this.atHandler.sendRaw(A),x)}async readValues(x,A){try{this.logger.debug("Fetching values");let e=A?`${_x.APP_GET_DATAVALUE}=${A}`:_x.APP_GET_DATAVALUE,r=await x(e);if(r.includes(K0.OK)){let t=U8(r);return this.logger.debug("Values: "+t.join(", ")),this.values=t,this.emit("values",t),this.emit("displayValues",Cs(this.datapoints,t)),t}return[]}catch(e){return this.logger.warn("Value fetch error: "+(e instanceof Error?e.message:String(e))),[]}}async checkMeasurementTriggerSupport(){this.logger.info("Checking measurement trigger support");try{let A=(await this.atHandler.sendRaw(_x.APP_TRIG_MEASURE_TEST)).includes(K0.OK);return this.logger.info("Measurement trigger support: "+A),A}catch(x){if(x instanceof Hx)throw x;return this.logger.warn("Measurement trigger probe failed: "+(x instanceof Error?x.message:String(x))),!1}}async triggerMeasurement(x={}){let{pin:A,timeoutMs:e=N8,signal:r}=x;return this.logger.info("Triggering measurement"),this.atHandler.withAtLock(async t=>{let i=await t.sendRaw(_x.APP_TRIG_MEASURE);if(this.logger.debug("Trigger measurement response: "+i),!i.includes(K0.OK))return this.logger.warn("Measurement trigger rejected: "+i.trim()),{outcome:"rejected",values:[],response:i};this.emit("measurementTriggered");try{let n=await t.sendAndWait(null,K0.MEASURED,e,r);return this.emit("measurementCompleted"),{outcome:"measured",values:await this.readValues(v=>t.sendRaw(v),A),response:n}}catch(n){if(n instanceof Hx)throw n;let F="timeout";return n instanceof Rs?F="error":r?.aborted&&(F="aborted"),this.logger.warn(`Measurement ${F} while waiting for ${K0.MEASURED}: `+(n instanceof Error?n.message:String(n))),this.emit("measurementFailed",F),{outcome:F,values:[],response:i}}})}async startPolling(x,A=qd){if(this.polling){this.logger.warn("Polling already active \u2014 ignoring startPolling call");return}this.logger.info("Starting polling every "+A+" ms"),this.polling=!0,this.fetchInProgress=!1,this.emit("pollingStarted"),this.fetchPromise=this.fetchValues(x),await this.fetchPromise,this.fetchPromise=null,this.polling&&(this.pollTimer=setInterval(()=>{this.fetchInProgress||(this.fetchInProgress=!0,this.fetchPromise=this.fetchValues(x).finally(()=>{this.fetchInProgress=!1,this.fetchPromise=null}))},A))}async stopPolling(){this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null),this.polling&&(this.logger.info("Polling stopped"),this.polling=!1,this.emit("pollingStopped")),this.fetchPromise&&await this.fetchPromise}getSnapshot(){return{datapoints:[...this.datapoints],values:[...this.values],isPolling:this.polling}}getDisplayValues(){return Cs(this.datapoints,this.values)}dispose(){this.stopPolling(),this.datapoints=[],this.values=[],this.removeAllListeners()}};async function Nd(x,A,e){let r=i=>{if(i instanceof Hx)throw i},t=new J8(x);try{let i=await x.queryMdnServerConfig(e).catch(D=>(r(D),!1)),n=await t.checkSupport().catch(D=>(r(D),{supported:!1,pinRequired:!1})),F=n.supported?await t.checkMeasurementTriggerSupport().catch(D=>(r(D),!1)):!1,v=n.supported?{pinRequired:n.pinRequired,canTriggerMeasurement:F}:!1,E=!1,u=!1;if(i){let[D,m]=await Promise.all([x.queryCompanionCertSupport(e).catch(w=>(r(w),!1)),A?.getCertificate(i)]);E=D,u=m!=null&&bs(m.notAfter)}return{hostname:i,localData:v,secureConnection:E,validCert:u}}finally{t.dispose()}}var Id=require("events"),Md={0:"trigger",1:"wakeup",2:"online"},Ld={0:["2G","","GSM"],1:["2G","Compact","GSM-COMPACT"],2:["3G","","UTRAN"],3:["2G","EDGE","GSM-EGPRS"],4:["3G","HSDPA","UTRAN-HSDPA"],5:["3G","HSUPA","UTRAN-HSUPA"],6:["3G","HSPA+","UTRAN-HSXPA"],7:["4G","","EUTRAN"],8:["4G","LTE-M","LTE-CATM1"],9:["4G","NB-IoT","LTE-CATNB1"],100:["WiFi","","WIFI"],101:["LAN","Ethernet","ETHERNET"],102:["Local","Wireless","WIRELESS"],103:["Local","Wired","WIRED"]},Rd={"NO SCRIPT":"none","SCRIPT ERROR":"error","SCRIPT OK":"ok"},Tx={FAILED:1,ACTIVE:2,STARTED:4,RETRY:8,WAKEUPABLE:16,EXTSIM:32,DISABLED:64,WAKEUP:256,POSUPDATE_ACTIVE:512},Od=Tx.FAILED|Tx.ACTIVE|Tx.STARTED|Tx.RETRY|Tx.WAKEUPABLE|Tx.EXTSIM|Tx.DISABLED|Tx.WAKEUP|Tx.POSUPDATE_ACTIVE,wF=`${K0.RM2M_STATE}: `;function K8(x=0){let A=(x&Tx.WAKEUPABLE)!==0,e="offline",r=A;return x&Tx.POSUPDATE_ACTIVE?(e="locating",r=!1):x&Tx.RETRY?(e="retry",r=!1):x&Tx.STARTED?(e="dialing",r=!1):x&Tx.ACTIVE?(e="active",r=!1):x&Tx.FAILED?(e="failed",r=A):x&Tx.DISABLED&&(e="disabled",r=!1),{signal:e,simType:(x&Tx.EXTSIM)!==0?"external":"internal",wakeupable:r,unknownFlags:x&~Od}}function Gd(x){if(x===void 0)return null;let A=parseInt(x,10);return isNaN(A)?x:Md[A]??x}function Ud(x){if(x===void 0)return null;let A=parseInt(x,10);return isNaN(A)?null:Ld[A]??["unknown",`itf#${x}`,`itf#${x}`]}function Hd(x){if(x.length===0)return null;let A=x.join(",");return Rd[A]??A}function z8(x){let A=x.split(","),[e,r,t,i,...n]=A;if(!e||!/^-?\d+$/.test(e)||!r||!/^\d+$/.test(r))return null;let F=parseInt(r,10),v=Ud(i),E=i!==void 0?parseInt(i,10):NaN;return{stamp:new Date,rssi:E>=101?null:parseInt(e,10),state:F,uplinkState:K8(F),uplinkMode:Gd(t),uplinkInterface:v?v[0]:null,uplinkInterfaceExtended:v?v[1]:null,uplinkInterfaceTechnical:v?v[2]:null,scriptState:Hd(n)}}function V8(x){let A=x.indexOf(wF);if(A===-1)return null;let e=x.substring(A+wF.length),r=e.search(/\r?\n/);if(r===-1)return null;let t=e.substring(0,r).trim();return t?z8(t):null}var Jd=5e3,Kd=class extends Id.EventEmitter{constructor(x,A=yn){super(),A0(this,"atHandler"),A0(this,"logger"),A0(this,"lastState",null),A0(this,"pollingTimer",null),A0(this,"polling",!1),A0(this,"fetchInProgress",!1),A0(this,"fetchPromise",null),this.atHandler=x,this.logger=A}async fetchState(){try{let x=await this.atHandler.sendRaw(_x.RM2M_STATE),A=V8(x);return A?(this.lastState=A,this.emit("state",A),this.logger.debug("RM2M state fetched successfully")):this.logger.warn("Failed to parse RM2M state response"),A}catch(x){let A=x instanceof Error?x.message:String(x);return this.logger.error(`Failed to fetch RM2M state: ${A}`),this.emit("error",A),null}}startPolling(x=Jd){if(this.polling){this.logger.debug("Polling already active, ignoring startPolling call");return}this.logger.info(`Starting RM2M state polling every ${x}ms`),this.polling=!0,this.fetchInProgress=!1,this.emit("pollingStarted"),this.runGuardedFetch(),this.pollingTimer=setInterval(()=>this.runGuardedFetch(),x)}runGuardedFetch(){this.fetchInProgress||(this.fetchInProgress=!0,this.fetchPromise=this.fetchState().finally(()=>{this.fetchInProgress=!1,this.fetchPromise=null}))}async stopPolling(){this.pollingTimer&&(clearInterval(this.pollingTimer),this.pollingTimer=null),this.polling&&(this.logger.info("RM2M state polling stopped"),this.polling=!1,this.emit("pollingStopped")),this.fetchPromise&&await this.fetchPromise}getLastState(){return this.lastState?{...this.lastState,uplinkState:{...this.lastState.uplinkState}}:null}get isPolling(){return this.polling}dispose(){this.stopPolling(),this.lastState=null,this.removeAllListeners()}},zd=require("events"),W8=class extends zd.EventEmitter{constructor(){super(...arguments),A0(this,"serialNumber",""),A0(this,"serverUrl",""),A0(this,"deviceId",""),A0(this,"rssi",null),A0(this,"hasDebugSupport",!1),A0(this,"connectionState","disconnected"),A0(this,"connectionError",""),A0(this,"mtuSize",23)}get isConnected(){return this.connectionState==="connected"}setConnected(x){this.serialNumber=x.serialNumber,this.deviceId=x.deviceId,this.serverUrl=x.serverUrl??this.serverUrl,this.hasDebugSupport=x.hasDebugSupport??!1,this.mtuSize=x.mtuSize??23,this.rssi=x.rssi??null,this.connectionState="connected",this.connectionError="",this.emit("connected",this.snapshot()),this.emit("stateChange",this.snapshot())}setDisconnected(){this.connectionState="disconnected",this.rssi=null,this.emit("disconnected"),this.emit("stateChange",this.snapshot())}setError(x){this.connectionError=x,this.connectionState="disconnected",this.emit("error",x),this.emit("stateChange",this.snapshot())}setConnectionState(x){this.connectionState=x,this.emit("stateChange",this.snapshot())}updateRssi(x){this.rssi=x,this.emit("rssiUpdate",x)}reset(){this.serialNumber="",this.serverUrl="",this.deviceId="",this.rssi=null,this.hasDebugSupport=!1,this.connectionState="disconnected",this.connectionError="",this.mtuSize=23,this.emit("reset"),this.emit("stateChange",this.snapshot())}snapshot(){return{serialNumber:this.serialNumber,serverUrl:this.serverUrl,deviceId:this.deviceId,rssi:this.rssi,hasDebugSupport:this.hasDebugSupport,connectionState:this.connectionState,connectionError:this.connectionError,mtuSize:this.mtuSize,isConnected:this.isConnected}}},Vd=require("events"),X8={maxDuration:6e4,initialDelay:1e3,maxDelay:1e4,maxGattRetries:3},Wd=class extends Vd.EventEmitter{constructor(x=ZA,A){super(),A0(this,"logger",x),A0(this,"state"),A0(this,"transports",null),A0(this,"transportFactory",null),A0(this,"disconnectFn",null),A0(this,"reconnectOptions"),A0(this,"reconnectAbortController",null),this.state=new W8,this.reconnectOptions={...X8,...A}}async connect(x,A,e){this.transportFactory=x,this.disconnectFn=A,this.state.setConnectionState("connecting");try{return this.transports=await x(),this.state.setConnected(e),this.logger.info(`Connected to device ${e.serialNumber}`),this.transports}catch(r){let t=r instanceof Error?r.message:String(r);throw this.state.setError(t),this.logger.error(`Connection failed: ${t}`),r}}async disconnect(){if(this.stopReconnect(),this.disconnectFn)try{await this.disconnectFn()}catch(x){this.logger.warn(`Disconnect error: ${x}`)}this.transports=null,this.state.setDisconnected(),this.logger.info("Disconnected from device")}async reconnect(){if(!this.transportFactory||!this.disconnectFn)return this.logger.error("Cannot reconnect: no transport factory"),!1;this.state.setConnectionState("reconnecting"),this.reconnectAbortController=new AbortController;let{signal:x}=this.reconnectAbortController,A=Date.now(),e=this.reconnectOptions.initialDelay;for(;Date.now()-A<this.reconnectOptions.maxDuration;){if(x.aborted||(this.logger.info(`Reconnecting in ${e}ms...`),await this.sleep(e,x),x.aborted))return!1;try{return this.transports=await this.transportFactory(),this.state.setConnectionState("connected"),this.state.connectionError="",this.logger.info("Reconnected successfully"),this.emit("reconnected"),!0}catch(r){this.logger.warn(`Reconnect attempt failed: ${r}`),e=Math.min(e*2,this.reconnectOptions.maxDelay)}}return this.state.setError("Reconnect timeout exceeded"),this.logger.error("Reconnect failed: timeout exceeded"),this.emit("reconnectFailed"),!1}stopReconnect(){this.reconnectAbortController?.abort(),this.reconnectAbortController=null}getTransports(){return this.transports}sleep(x,A){return new Promise(e=>{let r=setTimeout(e,x);A?.addEventListener("abort",()=>{clearTimeout(r),e()},{once:!0})})}},Xd={configurationNumber:1,utoInterface:0,utoEndpoint:1,utoSize:64*1024,debugInterface:1,debugEndpoint:2,debugSize:1024},Yd={service:"BC300000-0FA0-4ED4-860A-CF95434B5A4E",txCharacteristic:"BC30E1FF-0FA0-4ED4-860A-CF95434B5A4E",rxCharacteristic:"BC30E1FE-0FA0-4ED4-860A-CF95434B5A4E",txDebugCharacteristic:"BC30E201-0FA0-4ED4-860A-CF95434B5A4E",rxDebugCharacteristic:"BC30E200-0FA0-4ED4-860A-CF95434B5A4E"},Qd=590,Zd=3e4,S0=class extends Error{constructor(x){super(x),this.name="ApiBadRequestError"}},EA=class extends Error{constructor(x){super(x),this.name="ApiNotFoundError"}},Ln=class extends Error{constructor(x){super(x),this.name="ApiForbiddenError"}},Os=class extends Error{constructor(x){super(x),this.name="ApiMethodNotAllowedError"}};function BA(x){try{return decodeURIComponent(x)}catch{throw new S0("malformed url encoding")}}var xu=2e3,Au=2136;function Gs(x){if(x.length===0)return!0;if(!/^\d{4,17}$/.test(x))return!1;let A=Number(x.slice(0,4));return A>=xu&&A<=Au}function Wr(x){if(x)for(let A of["stamp","from","until"]){let e=x[A];if(typeof e=="string"&&!(A==="until"&&e==="*")&&!(A!=="stamp"&&e.trim().length===0)&&!Gs(e))throw new S0(`attribute '${A}' is not valid`)}}function eu(x){return typeof x.setMetadataValue=="function"?x:null}function ru(x){return typeof x.insertUtoChangeRequests=="function"?x:null}function Us(){return{lastIssuedStamp40:0,tagMutexTails:new Map}}async function tu(x){return{status:200,body:x.ctx.siteInfo}}async function nu(x){let{blueprint:A}=x.ctx;if(!A)throw new EA("blueprint unavailable");return{status:200,body:A}}async function iu(x){let{me:A}=x.ctx;if(A==null)throw new EA("no profile stored");return{status:200,body:A}}function Y8(x,A,e,r){let t=x.push;t&&(async()=>{try{await t.container(A,e,r)}catch(i){x.logger?.error(`[localApi] device push for tag ${A} failed:`,i)}})()}async function su(x,A,e){let r=x.push;if(!r)return null;try{return await r.adHocChangeRequest(A,e)}catch(t){return x.logger?.error(`[localApi] change request for tag ${A} failed:`,t),null}}var au=1024;function It(x){let A=x.indexOf(0),e=A<0?x:x.subarray(0,A);try{let r=new TextDecoder("utf-8").decode(e),t=JSON.parse(r);return typeof t!="object"||t===null||Array.isArray(t)?null:t}catch{return null}}function Q8(x,A=0){let e=new TextEncoder().encode(x),r=Math.max(au,A,e.length+1),t=new Uint8Array(r);return t.set(e,0),t}var Hs=26432,Fr={aberrant:1,service:2,standby:4,commissioned:8,offline:16,commissioning:65536,online:131072},Z8=Object.keys(Fr),Mt=["standby","commissioned","offline","commissioning","online"],ds=Mt.reduce((x,A)=>x|Fr[A],0)>>>0;function xv(x){let A=0;for(let e of Z8)x[e]===!0&&(A|=Fr[e]);return A>>>0}function Js(x,A){let e={};for(let r of Z8)x&Fr[r]?e[r]=!0:typeof A?.[r]=="boolean"&&(e[r]=!1);return e}async function Av(x,A){let e=A.device;if(!e)return!1;let r=await x.getRowForTag(Hs);if(!r?.data)return!1;let t=It(r.data);if(!t)return!1;let i=!1;if(typeof t.lifecycleFlags=="number"){let n=Js(t.lifecycleFlags,e.lifecycle_flags);JSON.stringify(e.lifecycle_flags)!==JSON.stringify(n)&&(e.lifecycle_flags=n,i=!0)}return typeof t.lifecycleState=="string"&&e.lifecycle_state!==t.lifecycleState&&(e.lifecycle_state=t.lifecycleState,i=!0),i}var ou=new Set([...Mt,"service","lifecycle_state"]);function Fu(x,A){let e=Math.max(z0.msToStamp40((x.timeSource??qt).nowMs()),A.lastIssuedStamp40+1);return A.lastIssuedStamp40=e+1,e}async function vu(x){let A=Eu(x.request.body??null);if(!A)throw new S0("invalid or missing request body");lu(A);let e=x.ctx,r=e.siteInfo.lifecycle_flags;if(!fu(r))throw new S0("this site does not support lifecycle flags!");let t=xv(r),i=t;for(let E of Mt){let u=A[E];typeof u=="boolean"&&(i=u?i|Fr[E]:i&~Fr[E])}if(i>>>=0,i===t)return{status:204,body:""};let n=Fu(e,x.session),F=[{json:JSON.stringify({lifecycleFlags:{op:"&",val:~ds>>>0}}),stamp40:n},{json:JSON.stringify({lifecycleFlags:{op:"|",val:i&ds}}),stamp40:n+1}],v=ru(e.storage);return v&&await v.insertUtoChangeRequests(F.map(E=>({tag:Hs,stamp40:E.stamp40,json:E.json}))),e.siteInfo.lifecycle_flags=Js(i,r),await ev(e),cu(e,F),{status:204,body:""}}function lu(x){let A=[];for(let[e,r]of Object.entries(x))ou.has(e)?(e==="lifecycle_state"?typeof r!="string":typeof r!="boolean")&&A.push(`"${e}" is not valid`):A.push(`"${e}" is not an allowed lifecycle property`);if(A.length>0)throw new S0(`validation errors: ${A.join(", ")}`);if(Object.keys(x).some(e=>!Mt.includes(e)))throw new S0("invalid parameters")}async function cu(x,A){try{let e=await su(x,Hs,A);e==="executed"?await Av(x.storage,x.siteInfo)&&await ev(x):e!==null&&x.logger?.warn(`[localApi] lifecycle change request not applied by the device (outcome=${e})`)}catch(e){x.logger?.error("[localApi] lifecycle device-mirror refresh failed:",e)}}async function ev(x){await eu(x.storage)?.setMetadataValue("site_info",JSON.stringify(x.siteInfo))}function fu(x){return typeof x=="object"&&x!==null&&!Array.isArray(x)}function Eu(x){if(!x)return null;let A;try{A=JSON.parse(x)}catch{return null}return typeof A!="object"||A===null||Array.isArray(A)?null:A}function rv(x){if(x!=null){if(Array.isArray(x)&&x.every(A=>typeof A=="string"))return x;throw new S0('"select" must be an array')}}function Bu(x){if(x!=null){if(Array.isArray(x)&&x.every(A=>typeof A=="string"))return x;throw new S0("invalid parameter, select must be an array")}}function Cu(x,A){let e=new Map;if(A){for(let[r,t]of A)e.set(t,r);return e}for(let r of x?.fields??[]){if(Ce(r))continue;let t=r.alias??r.name;e.set(t,t.toLowerCase())}return e}function du(x){let A=new Map;for(let e of x.fields){if(Ce(e))continue;let r=(e.alias??e.name).toLowerCase();A.set(e.name,r),e.alias&&A.set(e.alias,r)}return A}function uu(x){let A=new Set;for(let e of x.fields)Ce(e)||A.add((e.alias??e.name).toLowerCase());return A.add("stamp"),A}function Du(x,A,e){if(!e)return null;let r=Cu(x,A),t=new Set,i=[];for(let n of e){if(n==="stamp")continue;let F=r.get(n);F?t.add(F):i.push(n)}if(i.length>0)throw tv(i);return t}function pu(x,A){let e=du(x),r=[],t=[],i=!1;for(let n of A){if(n==="stamp"){i=!0,r.push("stamp");continue}let F=e.get(n);F?r.push(F):t.push(n)}if(t.length>0)throw tv(t);return i||r.unshift("stamp"),r}function bu(x,A){if(A===void 0)return;let e=uu(x),r=A.map(i=>i.toLowerCase()),t=r.filter(i=>!e.has(i));if(t.length>0)throw new S0(`unknown field name(s): ${t.join(",")}`);return r.includes("stamp")?r:["stamp",...r]}function mu(x,A){if(!A)return x;let e={};for(let[r,t]of Object.entries(x))(r==="stamp"||A.has(r))&&(e[r]=t);return e}function Ks(x,A){if(!A)return x;let e={};for(let r of A)e[r]=r in x?x[r]:null;return e}function tv(x){return new S0(`Fields [\`${x.join("`, `")}\`] do not exist in this container`)}function Rn(x,A){return x.containers.find(e=>e.name===A||e.alias===A)??null}async function hu(x){let A=x.ctx,e=BA(x.params[1]),r=Rn(A.model,e);if(!r)throw new S0("container does not exist");let t=await A.mapper.readContainer(e);if(!t)throw new EA(`no data for container "${e}"`);let i=gu(A,r,t,ju(x));return{status:200,body:nv(A,e,i)}}function ju(x){let A=x.query.json??{};return rv(A.select)}function gu(x,A,e,r){let t=Du(A,Nt(x.blueprint??null,A),r);return mu(e,t)}function nv(x,A,e){let r=x.model.byNameOrAlias(A);return r?w8(e,Nt(x.blueprint??null,r)):e}async function yu(x){let A=x.ctx,e=BA(x.params[1]),r=A.model.byNameOrAlias(e);if(!r)throw new EA(`unknown container "${e}"`);let t=await A.mapper.readContainer(e);if(!t)throw new EA(`unknown container "${e}"`);let i=x.query.json??{},n=Bu(i.select),F=bu(r,n);return{status:200,body:Ks(t,F)}}async function ku(x){let A=BA(x.params[1]);return iv(x,A,"canonical")}async function wu(x){let A=BA(x.params[1]);if(!x.ctx.model.byNameOrAlias(A))throw new EA(`unknown container "${A}"`);return iv(x,A,"legacy")}async function iv(x,A,e){let r=qu(x);if(!r)throw new S0("invalid or missing request body");Wr(r);let{stamp:t,...i}=r;if(e==="canonical"&&t!==void 0&&typeof t!="string")throw new S0("value(s) of field(s) stamp are not valid");let n=x.ctx;if(e==="canonical"&&!Rn(n.model,A))throw new S0("container does not exist");let F=n.model.byNameOrAlias(A);if(F?.kind==="histdata")throw new EA(`unknown container "${A}"`);let v=e==="canonical"?$u(n,F,i):Tu(F,i);try{let E=e==="canonical"&&t!==void 0?{...v,stamp:t}:v,u=await n.mapper.writeContainer(A,E);return u.devicePushable&&Y8(n,u.tag,u.data,u.stamp40),{status:204,body:""}}catch(E){throw _u(E,A,e,n,F)}}function _u(x,A,e,r,t){if(x instanceof $t){let i=x.field?Su(r,t,x.field,e):void 0;return e==="canonical"?i?new S0(`no permission to modify container field \`${i}\``):new S0(`no permission to modify container \`${A}\``):i?new Ln(`unknown field name(s): ${i}`):new Os(`no permission to modify '${A}'`)}return x}function Su(x,A,e,r){if(!A)return e;let t=A.fields.find(n=>n.name===e||n.name.toLowerCase()===e||(n.alias??n.name).toLowerCase()===e);return t?r==="legacy"?(t.alias??t.name).toLowerCase():Nt(x.blueprint??null,A)?.get(e)??t.alias??t.name:e}function $u(x,A,e){if(!A)return e;let r=Nt(x.blueprint??null,A),t=new Map;if(r)for(let[i,n]of r)t.set(n,i);else for(let i of A.fields){let n=i.alias??i.name;t.set(n,n.toLowerCase()),t.set(n.toLowerCase(),n.toLowerCase())}return sv(A,t,e,i=>new S0(`unknown field name(s): ${i}`))}function Tu(x,A){if(!x)return A;let e=new Map;for(let r of x.fields){let t=r.alias??r.name;e.set(t.toLowerCase(),t.toLowerCase()),e.set(t,t.toLowerCase())}return sv(x,e,A,r=>new Ln(`unknown field name(s): ${r}`))}var Pu=new Set(["stamp","stamp4","stamp8","datetime"]);function sv(x,A,e,r){let t=new Map(x.fields.map(v=>[(v.alias??v.name).toLowerCase(),v])),i={},n=[],F=[];for(let[v,E]of Object.entries(e)){let u=A.get(v);if(!u){n.push(v);continue}let D=t.get(u);if(D&&Pu.has(D.type)&&!(typeof E=="string"&&Gs(E))){F.push(v);continue}i[u]=E}if(n.length>0)throw r(n.join(","));if(F.length>0)throw new S0(`value(s) of field(s) ${F.join(",")} are not valid`);return i}function qu(x){let A=x.query.json,e=A!=null&&typeof A=="object"&&!Array.isArray(A)?A:void 0,r=x.request.body;if(!r)return e?{...e}:null;let t=Nu(r);if(t===void 0)throw new S0("request supplied data which is not json formatted");return typeof t!="object"||t===null||Array.isArray(t)?null:{...e,...t}}function Nu(x){try{return JSON.parse(x)}catch{return}}var av="x-mt-backfill",ov="pending";async function zs(x,A,e){let r=x.push?.backfill;if(!(!r||A===void 0||A===null||e===null))try{return await r.call(x.push,{fromMs:e})==="pending"?{[av]:ov}:void 0}catch(t){x.logger?.error("[localApi] historic backfill check failed:",t);return}}var Iu=1e3,Dn=1e3,Fv="20000101",vv="*";async function Mu(x){let A=x.query.json??{};Cv(A,["from","until","count","offset","select"]),Wr(A);let e=x.ctx,r=BA(x.params[1]),{mapperSelect:t,order:i}=cv(e,r,A.select);fv(e,r);let n=Pn(A.from,Fv,"from"),F=Pn(A.until,vv,"until");Ev(n,F),F!==null&&(F=Ru(F));let v=Ou(A.count),E=Bv(A.offset),u=await zs(e,A.from,n);return{status:200,body:(await e.mapper.readTimeseries(r,{fromMs:n,untilMs:F,count:v,offset:E,select:t})).map(m=>lv(x,e,r,Ks(m,i))),headers:u}}async function Lu(x){let A=x.query.json??{};Cv(A,["from","until","offset","select"]),Wr(A);let e=x.ctx,r=BA(x.params[1]),t=x.params[2],{mapperSelect:i,order:n}=cv(e,r,A.select);fv(e,r);let F=Pn(A.from,Fv,"from"),v=Pn(A.until,vv,"until");Ev(F,v);let E=Bv(A.offset),u=await zs(e,A.from,F),m=(await e.mapper.readTimeseries(r,{fromMs:F,untilMs:v,count:t==="youngest"?-1:1,offset:E,select:i}))[0];return m?{status:200,body:lv(x,e,r,Ks(m,n)),headers:u}:{status:204,body:JSON.stringify("no timeseries recordData found"),headers:u}}function lv(x,A,e,r){return x.apiVersion==="1"?r:nv(A,e,r)}function cv(x,A,e){let r=rv(e);if(!r)return{mapperSelect:void 0,order:null};let t=Rn(x.model,A);if(!t)return{mapperSelect:r,order:null};let i=pu(t,r),n=i.filter(F=>F!=="stamp");return{mapperSelect:n.length>0?n:void 0,order:i}}function fv(x,A){if(!Rn(x.model,A))throw new S0("timeseries does not exist")}function Pn(x,A,e){let t=x==null||typeof x=="string"&&x.trim()===""?A:String(x);if(t==="*")return null;try{return Vr(t)}catch{throw new S0(`attribute '${e}' is not valid`)}}function Ev(x,A){if(x!==null&&A!==null&&x>A)throw new S0('E_BAD_REQUEST "from" value must be older than "until"')}function Ru(x){let A=z0.msToStamp40(x);return z0.stamp40ToMS(A)>=x&&(A-=1),z0.stamp40ToMS(A)}function Ou(x){if(x==null||x==="")return Iu;let A=Number(x);if(!Number.isInteger(A))throw new S0('"count" must be an integer');if(A===0)throw new S0("`count` cannot be 0");if(A<-Dn)throw new S0(`"count" must be greater than or equal to -${Dn}`);if(A>Dn)throw new S0(`"count" must be less than or equal to ${Dn}`);return A}function Bv(x){if(x==null||x==="")return 0;let A=Number(x);if(!Number.isInteger(A))throw new S0('"offset" must be an integer');if(A<0)throw new S0('"offset" must be greater than or equal to 0');return A}function Cv(x,A){for(let e of Object.keys(x))if(!A.includes(e))throw new S0(`"${e}" is not allowed`)}var Gu=1e5,Uu="20000101",Hu="*";async function Ju(x){let e=`histdata${x.params[1]?Number(x.params[1]):0}`,r=x.ctx,t=r.model.byNameOrAlias(e);if(!t)throw new EA(`unknown container "${e}"`);let i=x.query.json??{};Wr(i);let{fromMs:n,untilMs:F}=Vu(i);Wu(n,F);let v=Xu(i),E=Yu(i),u=dv(t,i.select)??["stamp"],D=qn(i.from)?await zs(r,i.from,n):void 0,m=u.filter(S=>S!=="stamp");return{status:200,body:(await r.mapper.readTimeseries(e,{fromMs:n,untilMs:F,count:v,offset:E,select:m.length>0?m:void 0})).map(S=>u.map(P=>P==="stamp"?S.stamp:S[P]??null)),headers:D}}async function Ku(x){let e=`histdata${x.params[1]?Number(x.params[1]):0}`,r=x.params[2],t=x.ctx,i=t.model.byNameOrAlias(e);if(!i)throw new EA(`unknown container "${e}"`);let n=x.query.json??{};Wr(n);let F=dv(i,n.select)??["stamp"],v=zu(n),E=F.filter(m=>m!=="stamp"),D=(await t.mapper.readTimeseries(e,{fromMs:null,untilMs:v??null,count:v!==void 0||r==="youngest"?-1:1,select:E.length>0?E:void 0}))[0];return D?{status:200,body:[F.map(m=>m==="stamp"?D.stamp:D[m]??null)]}:{status:200,body:[]}}function zu(x){if(!(!qn(x.until)||x.until==="*"))try{return Vr(String(x.until))??void 0}catch{throw new S0("from or until value invalid")}}function Vu(x){let A=qn(x.from),e=qn(x.until);if((!A||!e)&&!Vs(x.count))throw new S0("missing or invalid parameters (from and until and/or count)");return{fromMs:_F(A?x.from:Uu),untilMs:_F(e?x.until:Hu)}}function Wu(x,A){if(x!==null&&A!==null&&x>A)throw new S0('"from" value must be older than "until"')}function _F(x){let A=String(x);try{return Vr(A)}catch{throw new S0(`invalid stamp "${A}"`)}}function Xu(x){if(!Vs(x.count))return Gu;if(typeof x.count!="number")throw new S0("invalid parameter count");return x.count}function Yu(x){let A=x.offset;if(A==null||A==="")return 0;if(typeof A!="number"||A<0)throw new S0("invalid parameter offset");return A}function dv(x,A){if(A==null)return;if(!Array.isArray(A))throw new S0("invalid parameter, select must be an array");let e=A.map(F=>String(F).toLowerCase()),r=e.filter(F=>F.includes(" "));if(r.length>0)throw new S0(`aggregation suffix not allowed: ${r.join(",")}`);let t=e.includes("stamp")?e:["stamp",...e],i=new Set(x.fields.filter(F=>!Ce(F)).map(F=>(F.alias??F.name).toLowerCase()));i.add("stamp");let n=t.filter(F=>!i.has(F));if(n.length>0)throw new S0(`invalid channel(s) ${n.join(",")}`);return t}function Vs(x){return!!x}function qn(x){return typeof x=="string"?x.trim().length>0:Vs(x)}var Qu="device_id";function Zu(x){return async A=>(await On(A),{status:200,body:await AD(A.ctx,x)})}async function On(x){let A=BA(x.params[0]),e=await xD(x.ctx);if(!e||e.toLowerCase()!==A.toLowerCase())throw new EA(`unknown device "${A}"`)}async function xD(x){return x.deviceId||x.siteInfo.device?.device_id||x.storage.getMetadataValue(Qu)}async function AD(x,A){let e=await x.storage.getRowForTag(A);if(!e||!e.data)return{};let r=It(e.data);return r?(typeof r.pipAppVer=="number"&&(r.pipAppVer=`${r.pipAppVer}.0.0`),r.stamp=Kr(z0.stamp40ToMS(QA(e.stamp))),r):{}}function Ws(x,A,e){let t=(x.tagMutexTails.get(A)??Promise.resolve()).then(e);return x.tagMutexTails.set(A,t.catch(()=>{})),t}function eD(x){return async A=>{await On(A);let e=nD(A.request.body??null);if(!e)throw new S0("invalid or missing request body");return Ws(A.session,x,async()=>{let r=await A.ctx.storage.getRowForTag(x),t=r?.data?It(r.data)??{}:{};return await Xs(A.ctx,x,r,{...t,...e}),{status:204,body:""}})}}function rD(x){return async A=>(await On(A),Ws(A.session,x,async()=>{let e=await A.ctx.storage.getRowForTag(x);return!e||!e.data?{status:204,body:""}:(await Xs(A.ctx,x,e,{}),{status:204,body:""})}))}function tD(x){return async A=>{await On(A);let e=BA(A.params[1]);return Ws(A.session,x,async()=>{let r=await A.ctx.storage.getRowForTag(x);if(!r||!r.data)return{status:204,body:""};let t=It(r.data)??{},i=e.toLowerCase();for(let n of Object.keys(t))n.toLowerCase()===i&&delete t[n];return await Xs(A.ctx,x,r,t),{status:204,body:""}})}}function nD(x){if(!x)return null;let A;try{A=JSON.parse(x)}catch{return null}return typeof A!="object"||A===null||Array.isArray(A)?null:A}async function Xs(x,A,e,r){let t=Q8(JSON.stringify(r),e?.data?.length??0),i=z0.msToStamp40((x.timeSource??qt).nowMs());await x.storage.replaceUtoRow({tag:A,stamp:fA(i),flags:e?.flags??0,site_related:e?.site_related??0,data:t}),Y8(x,A,t,i)}var uv={"content-type":"application/json"},iD=[{method:"GET",pattern:/^\/api\/1\/me$/,handler:iu,checksUid:!1},{method:"GET",pattern:/^\/api\/[12]\/sites\/([^/]+)$/,handler:tu,checksUid:!0},{method:"GET",pattern:/^\/api\/[12]\/sites\/([^/]+)\/blueprint$/,handler:nu,checksUid:!0},{method:"POST",pattern:/^\/api\/1\/sites\/([^/]+)\/cn-set-lifecycle$/,handler:vu,checksUid:!0},{method:"GET",pattern:/^\/api\/[12]\/sites\/([^/]+)\/timeseries\/([^/]+)\/(oldest|youngest)$/,handler:Lu,checksUid:!0},{method:"GET",pattern:/^\/api\/[12]\/sites\/([^/]+)\/timeseries\/([^/]+)$/,handler:Mu,checksUid:!0},{method:"GET",pattern:/^\/api\/[12]\/sites\/([^/]+)\/containers\/([^/]+)$/,handler:hu,checksUid:!0},{method:"PUT",pattern:/^\/api\/[12]\/sites\/([^/]+)\/containers\/([^/]+)$/,handler:ku,checksUid:!0},{method:"GET",pattern:/^\/api\/1\/sites\/([^/]+)\/histdata(\d)?\/(oldest|youngest)$/,handler:Ku,checksUid:!0},{method:"GET",pattern:/^\/api\/1\/sites\/([^/]+)\/histdata(\d)?$/,handler:Ju,checksUid:!0},{method:"GET",pattern:/^\/api\/1\/sites\/([^/]+)\/(config[0-9a-c]|config[A-C])$/,handler:yu,checksUid:!0},{method:"PUT",pattern:/^\/api\/1\/sites\/([^/]+)\/(config[0-9a-c]|config[A-C])$/,handler:wu,checksUid:!0},...sD()];function sD(){let x={"sys-otp":26432,"sys-flash":26433,"app-otp":26434,"app-flash":26435,"app-state":26436,"sys-info":26437,"app-info":26438},A={"sys-flash":26433,"app-flash":26435},e=Object.entries(x).map(([t,i])=>({method:"GET",pattern:new RegExp(`^/api/1/devices/([^/]+)/${t}$`),handler:Zu(i),checksUid:!1})),r=Object.entries(A).flatMap(([t,i])=>[{method:"PUT",pattern:new RegExp(`^/api/1/devices/([^/]+)/${t}$`),handler:eD(i),checksUid:!1},{method:"DELETE",pattern:new RegExp(`^/api/1/devices/([^/]+)/${t}$`),handler:rD(i),checksUid:!1},{method:"DELETE",pattern:new RegExp(`^/api/1/devices/([^/]+)/${t}/([^/]+)$`),handler:tD(i),checksUid:!1}]);return[...e,...r]}var aD=/^\/api\/([12])\/customers\/([^/]+)\/sites\/(.*)$/;function oD(x){let A=Us();return e=>Dv(x,e,A)}async function Dv(x,A,e=Us()){try{let[r,t]=lD(A.path),i=cD(t),n=vD(r,x);if(n===null)return or(404,"E_NOT_FOUND","unknown customer");let F=A.method.toUpperCase();for(let v of iD){if(v.method!==F)continue;let E=v.pattern.exec(n);if(!E)continue;let u=E.slice(1);if(v.checksUid&&!FD(x,u[0]))return or(404,"E_NOT_FOUND","unknown site");let D=/^\/api\/([12])\//.exec(n)?.[1]??"1",m=await v.handler({request:A,params:u,query:i,ctx:x,session:e,apiVersion:D});return BD(m)}return or(404,"E_NOT_FOUND","not found")}catch(r){return bv(r)}}function FD(x,A){return x.allowAnySiteUid===!0||A!==void 0&&BA(A)===x.siteUid}function vD(x,A){let e=aD.exec(x);if(!e)return x;let r=BA(e[2]).toLowerCase();return(A.siteInfo.customer_id??"").toLowerCase()===r||(A.siteInfo.customer_uid??"").toLowerCase()===r?`/api/${e[1]}/sites/${e[3]}`:null}function lD(x){let A=x.indexOf("?");return A<0?[x,""]:[x.slice(0,A),x.slice(A+1)]}function cD(x){let A={params:{}};if(!x)return A;for(let e of x.split("&"))e&&fD(A,e);return A}function fD(x,A){let e=A.indexOf("="),r=BA(e<0?A:A.slice(0,e)),t=e<0?"":BA(A.slice(e+1));r==="json"?x.json=ED(t):x.params[r]=t}function ED(x){try{return JSON.parse(x)}catch{throw new S0("request supplied data which is not json formatted ")}}function BD(x){let A=typeof x.body=="string"?x.body:JSON.stringify(x.body);return{status:x.status,headers:{...uv,...x.headers},body:A}}function pv(x,A){return{status:x,headers:{...uv},body:JSON.stringify(A)}}function bv(x){return x instanceof S0||x instanceof Ms||x instanceof ws?or(400,"E_BAD_REQUEST",x.message):x instanceof Ln||x instanceof $t?or(403,"E_FORBIDDEN",x.message):x instanceof Os?or(405,"E_METHOD_NOT_ALLOWED",x.message):x instanceof EA||x instanceof Me?or(404,"E_NOT_FOUND",x.message):pv(500,{err:x instanceof Error?x.message:String(x)})}function or(x,A,e){return pv(x,{err:`${A} ${e}`})}function CD(x,A){let e=A.apmId??"local",r=A.version??1;return{uid:A.siteUid,name:A.name??A.siteUid,customer_id:e,customer_uid:e,app:{apmid:e,version:String(r)},device:{device_id:A.deviceId,lifecycle_flags:{}},lifecycle_flags:{},containers:x.containers.map(t=>({name:t.name,alias:t.alias??t.name,kind:t.kind}))}}});var Ab={};Bf(Ab,{default:()=>Dc,deviceExitCode:()=>uc,program:()=>DA});module.exports=Cf(Ab);var J0=require("commander"),Qt=U0(require("chalk"));var gi={name:"@microtronics/studio-cli",version:"1.2.1-rc.0",description:"Microtronics Studio CLI Tool",main:"./out/api.js",typings:"./out/studio-cli.d.ts",bin:{"studio-cli":"studio-cli"},publishConfig:{access:"public"},scripts:{compile:"npm run build:registryApiTypings && tsc","build:cli":"node build.mjs","build:exe":"node build-exe.mjs",api:"api-extractor run --local --verbose",build:"npm run compile && npm run api && npm run build:cli","watch:build":"npm run compile -- --watch",test:"cross-env STUDIO_ENV=lucky mocha","test-ci":"cross-env STUDIO_ENV=lucky mocha --reporter mocha-junit-reporter","watch:test":"npm run test -- --watch",prepublishOnly:"npm run build","build:registryApiTypings":"npx openapi-typescript https://api.registry.lucky.ci.microtronics.com/v1/openapi.yaml -o ./src/typings/registry.ts"},author:"Microtronics",license:"ISC",dependencies:{"@gera2ld/tarjs":"^0.3.1",ajv:"^8.17.1","ajv-formats":"^3.0.1","ajv-keywords":"^5.1.0",chalk:"^5.4.1",commander:"^12.1.0","cross-fetch":"^4.0.0","deepmerge-ts":"^7.1.5",dotenv:"^16.4.7","file-type-checker":"^1.1.2",glob:"^11.0.1","iconv-lite":"^0.6.3","image-dimensions":"^2.3.0",ini:"^5.0.0",minimatch:"^10.0.1","openapi-fetch":"^0.13.0",pako:"^2.1.0",semver:"^7.7.2","sql.js":"^1.14.2","tinytar-fix":"^0.1.1","update-notifier":"^7.3.1",usb:"^2.14.0",uuid:"^9.0.1","vscode-uri":"^3.0.8",yaml:"^2.6.1"},engines:{node:">= 22"},devDependencies:{"@microsoft/api-extractor":"^7.47.11","@microtronics/device-master":"bitbucket:microtronics-core/device-master#v4.1.0","@types/chai":"^4.3.6","@types/chai-as-promised":"^7.1.5","@types/ini":"^4.1.1","@types/mocha":"^10.0.9","@types/node":"^22.9.1","@types/semver":"^7.5.6","@types/sql.js":"^1.4.11","@types/update-notifier":"^6.0.8","@types/vscode":"^1.86.2","@yao-pkg/pkg":"^6.22.0",chai:"^4.3.8","chai-as-promised":"^7.1.2","cross-env":"^7.0.3",esbuild:"^0.27.3","extract-zip":"^2.0.1",mocha:"^10.8.2","mocha-junit-reporter":"^2.2.1","openapi-typescript":"^7.6.0","pawncc-wasm":"bitbucket:microtronics-core/pawncc-wasm#v1.1.1",resedit:"^3.0.2",tar:"^7.5.7","ts-node":"^10.9.2",typescript:"^5.6.3"},mocha:{require:["ts-node/register"],"watch-files":"src/**",spec:"./test/**/*.spec.ts",recursive:!0},files:["out/api.js","out/studio-cli.d.ts","dist/main.js","dist/studio-cli.d.ts","studio-cli","CHANGELOG.md"]};var yA=U0(require("node:fs/promises"));var bt=require("vscode-uri"),Ya=require("glob"),le={readFile(x){return yA.default.readFile(x.fsPath)},async rm(x){if(await this.stat(x))return yA.default.rm(x.fsPath,{recursive:!0})},async stat(x){try{let A=await yA.default.stat(x.fsPath),e=(A.isDirectory()?2:0)|(A.isFile()?1:0)|(A.isSymbolicLink()?64:0);return{ctime:A.ctimeMs,mtime:A.mtimeMs,permissions:void 0,size:A.size,type:e}}catch{return null}},async writeFile(x,A){typeof A=="string"&&(A=new TextEncoder().encode(A));let e=bt.Utils.dirname(x);return await yA.default.mkdir(e.fsPath,{recursive:!0}),yA.default.writeFile(x.fsPath,A,{flag:"w"})},async findFiles(x,A,e){let r={ignore:e,nodir:!0,absolute:!0,dot:!0,cwd:x.fsPath};return(await(0,Ya.glob)(A,r)).map(i=>{let n=i.replace(/\\/g,"/");return bt.URI.parse(`file:///${n}`)})},async copy(x,A){let e=await yA.default.stat(x.fsPath);return await yA.default.mkdir(bt.Utils.dirname(A).fsPath,{recursive:!0}),e.isDirectory()?yA.default.cp(x.fsPath,A.fsPath,{force:!0,recursive:!0}):yA.default.copyFile(x.fsPath,A.fsPath)},async mkdir(x){await yA.default.mkdir(x.fsPath,{recursive:!0})}};var xt=require("vscode-uri");var ue=require("vscode-uri");var qr=require("vscode-uri");var uf=new Uint32Array([0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117]);function sn(x,A=0){let e=~~A^-1;for(let r=0;r<x.length;r++)e=e>>>8^uf[(e^x[r])&255];return(e^-1)>>>0}var cb=new Uint8Array([0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64]),fb=new Uint8Array([0,192,193,1,195,3,2,194,198,6,7,199,5,197,196,4,204,12,13,205,15,207,206,14,10,202,203,11,201,9,8,200,216,24,25,217,27,219,218,26,30,222,223,31,221,29,28,220,20,212,213,21,215,23,22,214,210,18,19,211,17,209,208,16,240,48,49,241,51,243,242,50,54,246,247,55,245,53,52,244,60,252,253,61,255,63,62,254,250,58,59,251,57,249,248,56,40,232,233,41,235,43,42,234,238,46,47,239,45,237,236,44,228,36,37,229,39,231,230,38,34,226,227,35,225,33,32,224,160,96,97,161,99,163,162,98,102,166,167,103,165,101,100,164,108,172,173,109,175,111,110,174,170,106,107,171,105,169,168,104,120,184,185,121,187,123,122,186,190,126,127,191,125,189,188,124,180,116,117,181,119,183,182,118,114,178,179,115,177,113,112,176,80,144,145,81,147,83,82,146,150,86,87,151,85,149,148,84,156,92,93,157,95,159,158,94,90,154,155,91,153,89,88,152,136,72,73,137,75,139,138,74,78,142,143,79,141,77,76,140,68,132,133,69,135,71,70,134,130,66,67,131,65,129,128,64]);var j0;(w=>{function x(j,S){let[P,N]=S,{line:R,col:O}=j.linePos(P);return{line:Number(R)-1,startCharacter:O-1,endCharacter:O+(N-P)}}w.yamlRangeToLineInformation=x;let A=new TextEncoder;function e(j){return sn(A.encode(j)).toString(16)}w.generateHashForLibraryName=e;function r(j){return sn(A.encode(j)).toString(16)}w.generateHashForFilePath=r;function t(j){return sn(j).toString(16).toUpperCase().padStart(8,"0")}w.generateCRC32ForFileContent=t;function i(j){try{let S=null;return j?.type==="Buffer"?S=Uint8Array.from(j.data):S=j,new TextDecoder("utf8").decode(S)}catch{return""}}w.convertBlobToString=i;function n(j=""){return j.replace(/\r\n|\n\r|\r/g,`
|
|
2198
|
+
`).entries()){A.line=e;let t=r.trim();t===""||t.startsWith("//")||jC(A,t)||t.includes("=")&&gC(A,t)}return hC(A.containers,A.splits)}var l8=null,kC=4;function Kr(x){let A=new Date(x),e=(r,t)=>r.toString().padStart(t,"0");return e(A.getUTCFullYear(),4)+e(A.getUTCMonth()+1,2)+e(A.getUTCDate(),2)+e(A.getUTCHours(),2)+e(A.getUTCMinutes(),2)+e(A.getUTCSeconds(),2)+e(A.getUTCMilliseconds(),3)}function Vr(x){let A=x.trim();if(A==="*")return l8;if(!/^\d{4,17}$/.test(A))throw new Error(`?apiStamp.invalid-input."${x}"`);let e=(u,D,m)=>{let w=A.slice(u,u+D);return parseInt(w.length?w.padEnd(D,"0"):m,10)},r=parseInt(A.slice(0,kC),10),t=A.length>=6?e(4,2,"01"):1,i=A.length>=8?e(6,2,"01"):1,n=e(8,2,"00"),F=e(10,2,"00"),v=e(12,2,"00"),E=e(14,3,"000");return Date.UTC(r,t-1,i,n,F,v,E)}var St="NAN",wC="%HEX%",_C=65535,ws=class extends Error{constructor(x){super(`?ddeCodec.unknown-alias."${x}"`),A0(this,"alias",x),this.name="DdeUnknownAliasError"}};function In(x){return(x.alias??x.name).toLowerCase()}function Mn(x){return x==="string"}function _s(x){return x==="stamp"||x==="stamp4"||x==="stamp8"||x==="datetime"}function c8(x){return(x.editmask??"").toUpperCase()===wC}function SC(x,A){return A===void 0||!Number.isFinite(x)?x:Ss(x,A)}function Ss(x,A){if(!Number.isFinite(x))return x;let e=10**A;return Math.sign(x)*Math.round(Math.abs(x)*e)/e}function $C(x,A){if(!Number.isFinite(x)||x===0)return x;let e=Math.abs(x),r=Math.floor(Math.log10(e));return 10**(r+1)<=e?r+=1:10**r>e&&(r-=1),Ss(x,A-1-r)}function TC(x){return x==="floatm16"||x==="f32"||x==="f64"}function PC(x,A){if(!Number.isFinite(A))return A;let e=x.decpl??(TC(x.type)?9:0),r=Ss(A,e),t=x.type==="floatm16"?3:x.type==="f32"?7:15;return $C(r,t)}function _n(x,A){let e=BigInt.asUintN(64,BigInt(Math.trunc(x))),r=BigInt.asUintN(64,BigInt(Math.trunc(A))),t=0n,i=1n;for(;r!==0n;)r&1n&&(e&1n&&(t|=i),i<<=1n),e>>=1n,r>>=1n;return Number(t)}function f8(x,A,e){let r=BigInt.asUintN(64,BigInt(Math.trunc(x))),t=BigInt.asUintN(64,BigInt(Math.trunc(A))),i=BigInt.asUintN(64,BigInt(Math.trunc(e))),n=1n;for(;i!==0n;)i&1n&&(r=t&1n?r|n:r&~n,t>>=1n),i>>=1n,n<<=1n;return Number(r)}var qC=new Set(["u8","s8","u16","s16","u32","s32","s64","ufm8"]);function Sn(x){return!!x.bitmask&&qC.has(x.type)}var E8=255,B8=254,C8=253,d8=252,u8=251,NC=207,$s=65535,$n=65534,Ts=65533,Ps=65532,qs=65531;function IC(x){switch(x){case E8:return $s;case B8:return $n;case C8:return Ts;case d8:return Ps;case u8:return qs;default:return x<=31?x:x>NC?$n:(x&15|16)<<(x>>4)-1}}function MC(x){switch(x){case $s:return E8;case $n:return B8;case Ts:return C8;case Ps:return d8;case qs:return u8;default:{if(x<=31)return x;let A=1,e=x;for(;(e&65504)>0;)e>>=1,A++;return A<<4|e&15}}}var Tn=1023,os=31,D8=127,Hi=8388607,LC=255,Fs=15,RC=-14,pF=15;function p8(x){let A=(x&Tn)<<13,e=(x&31744)>>10;if(e===os)return m8(1024-(x&Tn));e!==0&&(e=e-Fs+4+D8);let r=(A|e<<23)>>>0;x&32768&&(r=(r|2147483648)>>>0);let t=new DataView(new ArrayBuffer(4));return t.setUint32(0,r),t.getFloat32(0)}function b8(x){if(typeof x=="string"||Number.isNaN(x))return _C;let A=new DataView(new ArrayBuffer(4));A.setFloat32(0,x);let e=A.getUint32(0),r=e>>>16&32768,t=(e&Hi)+4096,i=(t>Hi?1:0)+(e>>>23&LC),n=(t&Hi)>>>13;return i!==0&&(i=i-D8-4,i<RC?(n=0,i=0):i>pF?(n=Tn,i=pF+Fs):i=i+Fs),r|i<<10|n}var OC=["OF","UF","OL","SC"],vs={u8:{NAN:255,OF:254,UF:253,OL:252,SC:251},u16:{NAN:65535,OF:65534,UF:65533,OL:65532,SC:65531},u32:{NAN:4294967295,OF:4294967294,UF:4294967293,OL:4294967292,SC:4294967291},s8:{NAN:127,OF:126,UF:-126,OL:-127,SC:-128},s16:{NAN:32767,OF:32766,UF:-32766,OL:-32767,SC:-32768},s32:{NAN:2147483647,OF:2147483646,UF:-2147483646,OL:-2147483647,SC:-2147483648},s64:{NAN:0x7fffffffffffffffn,OF:0x7ffffffffffffffen,UF:-0x7ffffffffffffffen,OL:-0x7fffffffffffffffn,SC:-0x8000000000000000n},ufm8:{NAN:$s,OF:$n,UF:Ts,OL:Ps,SC:qs}},GC={NAN:65535,OF:65534,UF:65533,OL:65532,SC:65531},Wx={NAN:1,OF:2,UF:3,OL:4,SC:5},UC=new Set(["u8","u16","u32","ufm8"]);function HC(x){let A=Math.floor(x),e=x-A;return e<.5?A:e>.5?A+1:A%2===0?A:A+1}function Ns(x){let A=x.replace(/,/g,"").trim();if(!/^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/.test(A))return null;let e=Number(A);return Number.isFinite(e)?e:null}function Is(x,A,e){switch(x){case"u8":return A.getUint8(e);case"s8":return A.getInt8(e);case"u16":return A.getUint16(e,!1);case"s16":return A.getInt16(e,!1);case"u32":return A.getUint32(e,!1);case"s32":return A.getInt32(e,!1);case"s64":return Number(A.getBigInt64(e,!1));case"f32":return A.getFloat32(e,!1);case"f64":return A.getFloat64(e,!1);case"floatm16":return p8(A.getUint16(e,!1));case"ufm8":return IC(A.getUint8(e));default:throw new Error(`?ddeCodec.non-numeric-type."${x}"`)}}function m8(x){switch(x){case Wx.OF:return"OF";case Wx.UF:return"UF";case Wx.OL:return"OL";case Wx.SC:return"SC";default:return St}}var bF=[["NAN",Wx.NAN],["OF",Wx.OF],["UF",Wx.UF],["OL",Wx.OL],["SC",Wx.SC]];function JC(x,A){let e=x.getUint32(A,!1);if((e&2139095040)!==2139095040)return 0;let r=e&8388607;return r===0?Wx.NAN:(r=r&4194304?8388608-r:r&255,r===0?Wx.NAN:r)}function KC(x,A){let e=x.getBigUint64(A,!1);if((e&0x7ff0000000000000n)!==0x7ff0000000000000n)return 0;let r=Number(e&0xffn);return r===0?Wx.NAN:r}function zC(x,A){if(x.type==="s64"){let t=A.getBigInt64(x.byteofs,!1);Sn(x)&&(t=BigInt(_n(Number(t),x.bitmask)));let i=vs.s64;return bF.find(([n])=>t===BigInt(i[n]))?.[1]??0}let e=vs[x.type];if(!e)return 0;let r=Is(x.type,A,x.byteofs);return Sn(x)&&(r=_n(r,x.bitmask)),bF.find(([t])=>r===e[t])?.[1]??0}function h8(x,A){switch(x.type){case"floatm16":{let e=A.getUint16(x.byteofs,!1);return(e>>10&os)===os?1024-(e&Tn):0}case"f32":return JC(A,x.byteofs);case"f64":return KC(A,x.byteofs);default:return zC(x,A)}}function j8(x,A){let e=Is(x.type,A,x.byteofs);return typeof e=="string"||Number.isNaN(e)?NaN:(Sn(x)&&(e=_n(e,x.bitmask)),e*x.vscale+x.vofs)}function VC(x,A){let e=h8(x,A);if(e!==0)return m8(e);let r=j8(x,A);return Number.isNaN(r)?St:PC(x,r)}function WC(x,A){if(x.byteofs+x.size>A.byteLength)return null;if(Mn(x.type)||_s(x.type))return NaN;let e=new DataView(A.buffer,A.byteOffset,A.byteLength);return h8(x,e)!==0?NaN:j8(x,e)}function XC(x,A){if(c8(x)){let e="";for(let r=0;r<x.size;r++)e+=A.getUint8(x.byteofs+r).toString(16).padStart(2,"0");return e.toUpperCase()}return z0.cp1252Unpack(A,x.byteofs,x.size)}var g8=25569,y8=864e5;function YC(x){return(x-g8)*y8}function QC(x){return x/y8+g8}function ZC(x,A){if(x.type==="datetime")return Kr(YC(A.getFloat64(x.byteofs,!1)));if(x.type==="stamp8"){let r=A.getBigUint64(x.byteofs,!1),t=Number(r&0xffffffffffn);return Kr(z0.stamp40ToMS(t))}let e=A.getUint32(x.byteofs,!1)*256;return x.size>=5&&(e+=A.getUint8(x.byteofs+4)),Kr(z0.stamp40ToMS(e))}var xd=new Set(["u8","s8","u16","s16","u32","s32","s64","ufm8"]);function Ad(x,A){return/^[+-]?\d+$/.test(x)?parseInt(x,10):/^\$[0-9a-fA-F]+$/.test(x)?parseInt(x.slice(1),16):A}function ed(x){let A=x.default;if(A===void 0)return;if(Mn(x.type))return A;let e=A.trim();if(e===""||e.toUpperCase()===St)return St;if(xd.has(x.type))return Ad(e,0);let r=Ns(e);return r!==null?r:A}function rd(x,A,e){return x.byteofs+x.size>e?ed(x):Mn(x.type)?XC(x,A):_s(x.type)?ZC(x,A):VC(x,A)}function ls(x,A){let e=new DataView(A.buffer,A.byteOffset,A.byteLength),r={};for(let t of x.fields)Ce(t)||_t(t.type)||(r[In(t)]=rd(t,e,A.byteLength));return r}function td(x,A){if(typeof A=="number")return Number.isFinite(A)?{kind:"value",physical:A}:{kind:"sentinel",state:"NAN"};if(typeof A=="string"){if(A.toUpperCase()===St||A==="")return{kind:"sentinel",state:"NAN"};let e=OC.find(t=>t===A);if(e)return{kind:"sentinel",state:e};if("OUS".includes(A[0]))return{kind:"skip"};let r=Ns(A);return r!==null?{kind:"value",physical:r}:mF(x)}return mF(x)}function mF(x){let A=x.default;return A!==void 0&&A.startsWith("%")?{kind:"sentinel",state:"NAN"}:{kind:"value",physical:(A!==void 0?Ns(A):null)??0}}function cs(x,A,e){switch(x.type){case"floatm16":return A.setUint16(x.byteofs,GC[e],!1);case"f32":return A.setUint32(x.byteofs,(2139095040|Wx[e])>>>0,!1);case"f64":return A.setBigUint64(x.byteofs,0x7ff0000000000000n|BigInt(Wx[e]),!1);default:break}let r=vs[x.type]?.[e];if(r===void 0)throw new Error(`?ddeCodec.non-numeric-type."${x.type}"`);if(x.type==="s64")return A.setBigInt64(x.byteofs,BigInt(r),!1);k8(x,A,Number(r))}function nd(x,A,e){if(x.vscale===0)return;let r=(e-x.vofs)/x.vscale;switch(x.type){case"f32":return A.setFloat32(x.byteofs,r,!1);case"f64":return A.setFloat64(x.byteofs,r,!1);case"floatm16":return A.setUint16(x.byteofs,b8(r),!1);default:break}if(Number.isNaN(r))return cs(x,A,"NAN");if(!Number.isFinite(r))return cs(x,A,"OF");let t=r;UC.has(x.type)&&t<0&&(t=0),k8(x,A,HC(t))}function k8(x,A,e){if(Sn(x)){let r=Is(x.type,A,x.byteofs);e=f8(r,e,x.bitmask)}id(x.type,A,x.byteofs,e)}function id(x,A,e,r){switch(x){case"u8":return A.setUint8(e,r);case"s8":return A.setInt8(e,r);case"u16":return A.setUint16(e,r,!1);case"s16":return A.setInt16(e,r,!1);case"u32":return A.setUint32(e,r,!1);case"s32":return A.setInt32(e,r,!1);case"s64":return A.setBigInt64(e,BigInt(r),!1);case"ufm8":return A.setUint8(e,MC(r));default:throw new Error(`?ddeCodec.non-numeric-type."${x}"`)}}function sd(x,A,e){let r=String(e);if(c8(x)){let t=r.trim();if(t.length%2!==0||t.length>x.size*2)throw new Error(`?ddeCodec.invalid-hex."${In(x)}"`);for(let i=0;i<x.size;i++){let n=i*2<t.length?parseInt(t.substr(i*2,2),16):0;A.setUint8(x.byteofs+i,n)}return}z0.cp1252Pack(A,x.byteofs,x.size,r)}function ad(x,A,e){let r=Vr(String(e));if(r===null)throw new Error(`?ddeCodec.unbounded-stamp."${In(x)}"`);if(x.type==="datetime"){A.setFloat64(x.byteofs,QC(r),!1);return}let t=z0.msToStamp40(r);if(x.type==="stamp8"){A.setBigUint64(x.byteofs,BigInt(t),!1);return}A.setUint32(x.byteofs,Math.trunc(t/256),!1),x.size>=5&&A.setUint8(x.byteofs+4,t&255)}function od(x,A,e){if(Mn(x.type))return sd(x,A,e);if(_s(x.type))return ad(x,A,e);let r=td(x,e);switch(r.kind){case"skip":return;case"sentinel":return cs(x,A,r.state);case"value":return nd(x,A,r.physical)}}function fs(x,A,e){let r=e?new Uint8Array(e):new Uint8Array(x.recordSize),t=new DataView(r.buffer,r.byteOffset,r.byteLength),i=new Map(x.fields.filter(n=>!Ce(n)&&!_t(n.type)).map(n=>[In(n),n]));for(let[n,F]of Object.entries(A)){let v=i.get(n.toLowerCase());if(!v)throw new ws(n);od(v,t,F)}return r}var hF=99,Fd=256,Me=class extends Error{constructor(x){super(`?ddeMapper.unknown-container."${x}"`),A0(this,"container",x),this.name="DdeUnknownContainerError"}},$t=class extends Error{constructor(x,A){let e=A?`${x}.${A}`:x;super(`?ddeMapper.write-forbidden."${e}"`),A0(this,"container",x),A0(this,"field",A),this.name="DdeWriteForbiddenError"}},Ms=class extends Error{constructor(x){super(`?ddeMapper.unknown-field."${x}"`),A0(this,"field",x),this.name="DdeUnknownFieldError"}};function Ji(x){return(x.alias??x.name).toLowerCase()}var vd=class{constructor(x,A,e=qt){A0(this,"model",x),A0(this,"storage",A),A0(this,"timeSource",e)}async readContainer(x){let A=this.model.byNameOrAlias(x);if(!A)return null;let e=yt(A);if(e===null)return null;let r=await this.storage.getRowForTag(e);if(!r||!r.data)return null;let t=ls(await this.resolveScaleRefs(A),r.data);return delete t.stamp,{stamp:this.rowStamp(r),...t}}async writeContainer(x,A){let e=this.model.byNameOrAlias(x);if(!e)throw new Me(x);let r=yt(e);if(r===null)throw new Me(x);if(e.edit===hF)throw new $t(e.name);let{stamp:t,...i}=A;this.assertFieldsWritable(e,i);let n=await this.storage.getRowForTag(r),F=fs(await this.resolveScaleRefs(e),i,n?.data??null),v=z0.msToStamp40(this.recordStampMs(t)??this.timeSource.nowMs()),E=fA(v);return await this.storage.replaceUtoRow({tag:r,stamp:E,flags:n?.flags??0,site_related:n?.site_related??0,data:F}),{tag:r,stampHex:E,stamp40:v,data:F,devicePushable:F8(r)&&e.download!==0,upload:e.upload,download:e.download}}async seedContainer(x,A){let e=this.model.byNameOrAlias(x);if(!e)throw new Me(x);let r=yt(e);if(r===null)throw new Me(x);let{stamp:t,...i}=A,n=fs(await this.resolveScaleRefs(e),i,null),F=z0.msToStamp40(this.recordStampMs(t)??this.timeSource.nowMs());await this.storage.replaceUtoRow({tag:r,stamp:fA(F),flags:0,site_related:0,data:n})}recordStampMs(x){if(typeof x!="string")return null;try{return Vr(x)}catch{return null}}async readTimeseries(x,A){let e=this.model.byNameOrAlias(x);if(!e)throw new Me(x);let r=this.model.splits.find(E=>E.target.toLowerCase()===e.name.toLowerCase());if(!r)throw new Me(x);let t=Math.abs(A.count),i=A.offset??0,n=this.buildSelectSet(e,A.select),F=await this.resolveScaleRefs(e);return(await this.collectMatched(F,r,i+t,{fromStamp:this.boundHex(A.fromMs),untilStamp:this.boundHex(A.untilMs),order:A.count<0?"desc":"asc",selectSet:n})).slice(i,i+t)}matchesSplit(x,A){return x.length===0?!1:A.matchAll?!0:x.length<A.keyBytes.length?!1:A.keyBytes.every((e,r)=>x[r]===e)}async collectMatched(x,A,e,r){let t=[];if(e<=0)return t;let i=Math.max(e,Fd);for(let n=0;;n+=i){let F=await this.storage.getHistoricRows(26623,{fromStamp:r.fromStamp,untilStamp:r.untilStamp,order:r.order,limit:i,offset:n});for(let v of F)if(v.data&&this.matchesSplit(v.data,A)&&(t.push(this.recordFromRow(x,v,r.selectSet)),t.length>=e))return t;if(F.length<i)return t}}async readTimeseriesEdge(x,A,e){return(await this.readTimeseries(x,{count:A==="youngest"?-1:1,select:e}))[0]??null}recordFromRow(x,A,e){let r=ls(x,A.data),t={stamp:this.rowStamp(A)};for(let[i,n]of Object.entries(r))i!=="stamp"&&(!e||e.has(i))&&(t[i]=n);return t}rowStamp(x){return Kr(z0.stamp40ToMS(QA(x.stamp)))}boundHex(x){if(x!=null)return fA(z0.msToStamp40(x))}async resolveScaleRefs(x){if(!x.fields.some(r=>r.vscaleRef||r.vofsRef))return x;let A=new Map,e=[];for(let r of x.fields){if(!r.vscaleRef&&!r.vofsRef){e.push(r);continue}e.push({...r,vscale:r.vscaleRef?await this.resolveRef(r.vscaleRef,A,r.vscale):r.vscale,vofs:r.vofsRef?await this.resolveRef(r.vofsRef,A,r.vofs):r.vofs})}return{...x,fields:e}}async resolveRef(x,A,e){if(!/^config[0-9a-f]$/i.test(x.container))return e;let r=this.referencedField(x);if(!r)return e;let t=x.container.toLowerCase();A.has(t)||A.set(t,await this.referencedRecordData(x.container));let i=A.get(t);if(!i)return e;let n=WC(r,i);return n===null?e:n}referencedField(x){let A=x.field.toLowerCase();return this.model.byNameOrAlias(x.container)?.fields.find(r=>Ji(r)===A||r.name.toLowerCase()===A)??null}async referencedRecordData(x){let A=this.model.byNameOrAlias(x);if(!A)return null;let e=yt(A);return e===null?null:(await this.storage.getRowForTag(e))?.data??null}assertFieldsWritable(x,A){let e=new Map(x.fields.filter(r=>!Ce(r)&&!_t(r.type)).map(r=>[Ji(r),r]));for(let r of Object.keys(A)){let t=e.get(r.toLowerCase());if(t&&t.edit===hF)throw new $t(x.name,t.name)}}buildSelectSet(x,A){if(!A||A.length===0)return null;let e=new Set(x.fields.filter(t=>!Ce(t)&&!_t(t.type)).map(t=>Ji(t))),r=new Set;for(let t of A){let i=t.toLowerCase();if(i!=="stamp"){if(!e.has(i))throw new Ms(t);r.add(i)}}return r}},ld=new Set(["$titles","$meta"]);function cd(x){let A=x;if(typeof x=="string")try{A=JSON.parse(x)}catch{return null}return typeof A!="object"||A===null||Array.isArray(A)?null:A}function Es(x,A){let e=A.toLowerCase();if(ld.has(e))return null;let r=x[e];if(typeof r!="object"||r===null)return null;let t=new Map;for(let[i,n]of Object.entries(r)){if(typeof n!="object"||n===null)continue;let F=n.alias;typeof F=="string"&&F.length>0&&t.set(i.toLowerCase(),F)}return t}function w8(x,A){let e={};for(let[r,t]of Object.entries(x)){if(r==="stamp"){e[r]=t;continue}let i=A?.get(r.toLowerCase());e[i??r]=t}return e}function Nt(x,A){if(!x)return null;let e=Es(x,A.name);return e||(A.alias?Es(x,A.alias):null)}var fd=require("events"),O0="[OfflineSyncManager]",Ed=500,Bd="site_info",Cd=new Set(["local-data-interface.json"]);function Ox(x){if(x?.aborted)throw x.reason??new DOMException("The operation was aborted.","AbortError")}function dd(x){let A=kn(x);return!!(x&2)||A!==0&&A!==65}function jF(x){return x.filter(A=>(A.filename===Jr||A.filename===hs)&&A.outcome==="download").map(A=>A.filename)}var rr="skip-equal",Hr="skip-device-readonly",Ki="delete",Ne="error",zi="upload",Vi="uploading-utos",gF="downloading-utos",dn="fetching-device-state",Wi="uploading-files",un="downloading-files",yF="executing-change-requests",kF="executed",ud="error",Xi="skip-old-stamp",Dd=class extends fd.EventEmitter{constructor(x,A,e){super(),A0(this,"utoMaster",x),A0(this,"storage",A),A0(this,"logger",e)}emitProgress(x,A,e,r,t){let i={phase:x,item:A,completed:e,total:r,...t};this.emit("progress",i)}async uploadHistoricTag(x,A,e,r,t){try{let i=await this.storage.getRowForTag(x),n=0,F=async v=>{let E=v.filter(u=>u.stamp40>e).map(u=>({tag:x,stamp:fA(u.stamp40),flags:i?.flags??0,site_related:i?.site_related??0,data:u.data}));await this.storage.insertHistoricRows(E),n+=E.length};return await this.utoMaster.requestHistoricUtos(x,e,t,void 0,Ed,F),this.logger?.info(`${O0} historic upload tag=0x${x.toString(16)} +${n} records`),{tag:x,sTag:A.sTag,historic:!0,outcome:"upload",dbStamp40:e,deviceStamp40:r,recordsAppended:n}}catch(i){return this.logger?.error(`${O0} historic upload error tag=0x${x.toString(16)}: ${i}`),{tag:x,sTag:A.sTag,historic:!0,outcome:"error",dbStamp40:e,deviceStamp40:r}}}async uploadSingleTag(x,A,e,r){try{let t=await this.utoMaster.requestUto(x,0);if(!t)return this.logger?.info(`${O0} single upload tag=0x${x.toString(16)} \u2014 device returned no data (skip)`),{tag:x,sTag:A.sTag,historic:!1,outcome:rr,dbStamp40:e,deviceStamp40:r};let i=await this.storage.getRowForTag(x);return await this.storage.replaceUtoRow({tag:x,stamp:fA(t.stamp),flags:i?.flags??0,site_related:i?.site_related??0,data:t.data?new Uint8Array(t.data.buffer.slice(t.data.byteOffset,t.data.byteOffset+t.data.byteLength)):null}),this.logger?.info(`${O0} single upload tag=0x${x.toString(16)}`),{tag:x,sTag:A.sTag,historic:!1,outcome:"upload",dbStamp40:e,deviceStamp40:r}}catch(t){return this.logger?.error(`${O0} single upload error tag=0x${x.toString(16)}: ${JSON.stringify(t)}`),{tag:x,sTag:A.sTag,historic:!1,outcome:"error",dbStamp40:e,deviceStamp40:r}}}async uploadUtoTags(x,A,e,r){let t=x.length;this.emitProgress(Vi,null,0,t);let i=0;for(let n of x){Ox(r);let F=A.get(n),{tagInfo:v,dbStamp40:E,deviceStamp40:u}=F;if(this.emitProgress(Vi,v?.sTag??`0x${n.toString(16)}`,i,t),!v||u===null)e.set(n,{tag:n,sTag:"?",historic:!1,outcome:"unknown-tag",dbStamp40:E,deviceStamp40:u});else if(!(!v.flags.up||u<=E)){let D=v.sTag,m=i,w=v.historic?await this.uploadHistoricTag(n,v,E,u,j=>{this.emitProgress(Vi,D,m,t,{recordsReceived:j})}):await this.uploadSingleTag(n,v,E,u);e.set(n,w)}++i}}async pullFileFromDevice(x,A,e,r,t,i){let n=A.stamp;try{let F=await this.utoMaster.requestFile(x,E=>{this.emitProgress(Wi,x,i,t,{bytesTransferred:E})}),v=ms(F);if(v!==A.crc32)throw new Error(`crc32 mismatch: expected 0x${A.crc32.toString(16)}, got 0x${v.toString(16)}`);return await this.storage.upsertFile({filename:x,stamp:fA(n),crc:A.crc32,size:F.byteLength,flags:A._flags,flags_int:r,data:F}),{filename:x,outcome:zi,dbStamp40:e,deviceStamp40:n}}catch(F){return this.logger?.error(`${O0} file upload error ${x}: ${JSON.stringify(F)}`),{filename:x,outcome:Ne,dbStamp40:e,deviceStamp40:n}}}async autoSyncUploadFile(x,A,e,r,t,i,n,F){let v=A.stamp;if(v>r)return this.fileContentMatches(A,e)?this.convergeFileStamp(x,A,e,r):i?this.pullFileFromDevice(x,A,r,t,n,F):void 0;if(v===r&&this.fileContentMatches(A,e))return{filename:x,outcome:rr,dbStamp40:r,deviceStamp40:v}}async convergeFileStamp(x,A,e,r){let t=A.stamp;try{return await this.storage.upsertFile({filename:x,stamp:fA(t),crc:A.crc32,size:A.size,flags:A._flags,flags_int:e.flags_int,data:e.data}),{filename:x,outcome:rr,dbStamp40:r,deviceStamp40:t}}catch(i){return this.logger?.error(`${O0} file upload error ${x}: ${JSON.stringify(i)}`),{filename:x,outcome:Ne,dbStamp40:r,deviceStamp40:t}}}async mirrorUploadFile(x,A,e,r,t,i,n){let F=A.stamp;if(F!==r||!this.fileContentMatches(A,e))return t?this.pullFileFromDevice(x,A,r,e.flags_int,i,n):{filename:x,outcome:Hr,dbStamp40:r,deviceStamp40:F}}async decideFileUpload(x,A,e,r){let t=await this.storage.getFile(x),i=!!(A._flags&1);if(!t)return i?this.pullFileFromDevice(x,A,0,16,e,r):void 0;let n=QA(t.stamp);return A._flags&8?this.autoSyncUploadFile(x,A,t,n,t.flags_int,i,e,r):this.decideNonSystemUpload(x,A,t,n,i,e,r)}pullIfReadable(x,A,e,r,t,i,n){return x?this.pullFileFromDevice(A,e,r,t,i,n):void 0}async decideNonSystemUpload(x,A,e,r,t,i,n){let F=e.flags_int;if(!(F&2))return F&4?this.pullIfReadable(t,x,A,r,F,i,n):this.decideUploadBySyncLogic(x,A,e,r,t,i,n)}async decideUploadBySyncLogic(x,A,e,r,t,i,n){let F=e.flags_int,v=kn(F);if(v===65)return this.fileContentMatches(A,e)?this.convergeFileStamp(x,A,e,r):this.pullIfReadable(t,x,A,r,F,i,n);if(v===1)return this.autoSyncUploadFile(x,A,e,r,F,t,i,n);if(v===97)return A.stamp>r?this.pullIfReadable(t,x,A,r,F,i,n):void 0;if(v!==33)return this.mirrorUploadFile(x,A,e,r,t,i,n)}async uploadFiles(x,A,e,r){let t=Object.entries(x),i=t.length;this.emitProgress(Wi,null,0,i);let n=0;for(let[F,v]of t){if(Ox(r),!(F===hs||F===Jr&&!e)){let u=await this.decideFileUpload(F,v,i,n);u&&A.set(F,u)}this.emitProgress(Wi,F,++n,i)}}fileContentMatches(x,A){return A!==null&&x.crc32===A.crc&&x.size===A.size}async downloadSingleTag(x,A,e,r){try{let t=await this.storage.getRowForTag(x);return t?.data&&await this.utoMaster.sendUTOCmdExt(3,x,t.data,e),{tag:x,sTag:A.sTag,historic:!1,outcome:"download",dbStamp40:e,deviceStamp40:r}}catch(t){return this.logger?.error(`${O0} download error tag=0x${x.toString(16)}: ${t}`),{tag:x,sTag:A.sTag,historic:!1,outcome:"error",dbStamp40:e,deviceStamp40:r}}}async processDownloadTag(x,A,e,r,t){if(e===r&&!t.has(x)){let i=A.flags.up?rr:"skip-db-readonly";t.set(x,{tag:x,sTag:A.sTag,historic:!1,outcome:i,dbStamp40:e,deviceStamp40:r});return}if(e>r){let i=A.flags.down?await this.downloadSingleTag(x,A,e,r):{tag:x,sTag:A.sTag,historic:!1,outcome:Hr,dbStamp40:e,deviceStamp40:r};t.set(x,i)}}async downloadUtoTags(x,A,e,r){let t=x.length;this.emitProgress(gF,null,0,t);let i=0;for(let n of x){Ox(r);let{tagInfo:F,dbStamp40:v,deviceStamp40:E}=A.get(n);F&&E!==null&&!F.historic&&await this.processDownloadTag(n,F,v,E,e),this.emitProgress(gF,F?.sTag??`0x${n.toString(16)}`,++i,t)}}async sendFileToDevice(x,A,e,r,t){let i=x.data.byteLength,n=F=>{if(F!==null){let v=Math.round(i*parseInt(F,10)/100);this.emitProgress(un,x.filename,t,r,{bytesTransferred:v,bytesTotal:i})}};this.utoMaster.on("installing",n);try{return await this.utoMaster.sendFile(0,x.data,z0.stamp40ToMS(A),x.filename),{filename:x.filename,outcome:"download",dbStamp40:A,deviceStamp40:e}}catch(F){return this.logger?.error(`${O0} file download error ${x.filename}: ${F}`),{filename:x.filename,outcome:"error",dbStamp40:A,deviceStamp40:e}}finally{this.utoMaster.removeListener("installing",n)}}async processDownloadFile(x,A,e,r,t=!1){if(!x.data)return;let i=A?.stamp??0,n=QA(x.stamp);if(A!==void 0&&this.fileContentMatches(A,x))return n===i?void 0:{filename:x.filename,outcome:rr,dbStamp40:n,deviceStamp40:i};if(!(!t&&n<i))return!t&&A!==void 0&&!(A._flags&2)?{filename:x.filename,outcome:Hr,dbStamp40:n,deviceStamp40:i}:this.sendFileToDevice(x,n,i,e,r)}async isAppInDevPhase(){let x=await this.storage.getMetadataValue(Bd);if(!x)return!1;try{return JSON.parse(x).app?.phase==="dev"}catch(A){return this.logger?.error(`${O0} corrupt site_info metadata: ${A}`),!1}}async downloadFiles(x,A,e,r){let t=await this.storage.getFiles(),i=t.filter(D=>D.flags&8),n=t.filter(D=>!(D.flags&8)),F=[...i,...n].filter(D=>D.filename),v=Object.entries(x).filter(([,D])=>D._flags&4).map(([D])=>D),E=F.length;this.emitProgress(un,null,0,E);let u=0;for(let D of F){if(Ox(r),e&&D.filename===Jr){this.emitProgress(un,D.filename,++u,E);continue}let m=D.filename===Jr&&!e,w=await this.decideFileDownload(D,x[D.filename],A.get(D.filename),v,m,E,u);w&&A.set(D.filename,w),this.emitProgress(un,D.filename,++u,E)}}async decideFileDownload(x,A,e,r,t,i,n){return A!==void 0?this.decideDownloadExisting(x,A,e,t,i,n):this.decideDownloadMissing(x,r,i,n)}async decideDownloadExisting(x,A,e,r,t,i){if(A._flags&4)return;if(x.flags&8)return e?void 0:this.processDownloadFile(x,A,t,i,r);let n=x.flags_int;if(n&8)return this.handleDeviceDelete(x,A,e);if(!e&&!(n&4))return this.pushToDevice(x,A,t,i)}async pushToDevice(x,A,e,r){let t=A.stamp,i=QA(x.stamp),n=this.wantDownloadPush(x,A,i,t);if(n==="match")return{filename:x.filename,outcome:rr,dbStamp40:i,deviceStamp40:t};if(n!=="none"&&!(i===0||!x.data||x.data.byteLength===0))return A._flags&2?this.sendFileToDevice(x,i,t,e,r):{filename:x.filename,outcome:Hr,dbStamp40:i,deviceStamp40:t}}wantDownloadPush(x,A,e,r){let t=x.flags_int;if(t&2)return"push";let i=this.fileContentMatches(A,x),n=kn(t);return n===33||n===1&&e>=r?i?"match":"push":n===97&&e>r?"push":"none"}async handleDeviceDelete(x,A,e){let r=A.stamp,t=QA(x.stamp);if(!(e&&(e.outcome===zi||e.outcome===Ne))){if(!(A._flags&2))return{filename:x.filename,outcome:Hr,dbStamp40:t,deviceStamp40:r};try{return await this.utoMaster.deleteFile(x.filename),await this.storage.deleteFile(x.filename),{filename:x.filename,outcome:Ki,dbStamp40:t,deviceStamp40:r}}catch(i){return this.logger?.error(`${O0} file delete error ${x.filename}: ${JSON.stringify(i)}`),{filename:x.filename,outcome:Ne,dbStamp40:t,deviceStamp40:r}}}}async decideDownloadMissing(x,A,e,r){let t=x.flags_int,i=QA(x.stamp);if(t&8)try{return await this.storage.deleteFile(x.filename),{filename:x.filename,outcome:Ki,dbStamp40:i,deviceStamp40:null}}catch(n){return this.logger?.error(`${O0} file delete error ${x.filename}: ${JSON.stringify(n)}`),{filename:x.filename,outcome:Ne,dbStamp40:i,deviceStamp40:null}}if(!(x.flags&12)&&dd(t)&&x.flags&2&&this.hasMatchingNode(x.filename,A)&&x.data)return this.sendFileToDevice(x,i,0,e,r)}hasMatchingNode(x,A){return A.some(e=>e.slice(0,-1)===x.slice(0,e.length-1))}async reconcileFileState(x){try{await this.reconcileFileStateUnguarded(x)}catch(A){if(x?.aborted)throw A;this.logger?.error(`${O0} file-state reconciliation failed: ${JSON.stringify(A)}`)}}async reconcileFileStateUnguarded(x){let A=await this.utoMaster.requestFileList(),e=new Set(Object.keys(A)),r=await this.storage.getFiles(),t=new Map(r.map(i=>[i.filename,i]));for(let[i,n]of Object.entries(A))Ox(x),await this.reconcileDeviceFile(i,n,t.get(i)??null);for(let i of r)Ox(x),e.has(i.filename)||await this.dropRowMissingFromDevice(i)}async reconcileDeviceFile(x,A,e){let r=!!((A._flags|(e?.flags??0))&8);if(e?.data&&!this.fileContentMatches(A,e)){this.logger?.info(`${O0} reconcile keep ${x}: row holds undeployed content`);return}if(!e?.data&&!r)return;let t={filename:x,stamp:fA(A.stamp),crc:A.crc32,size:A.size,flags:A._flags,flags_int:e?.flags_int??16,data:this.keepBlob(x,r)?e?.data??null:null};e&&this.fileRowMatches(e,t)||await this.storage.upsertFile(t)}keepBlob(x,A){return!A||Cd.has(x)}fileRowMatches(x,A){return x.stamp===A.stamp&&x.crc===A.crc&&x.size===A.size&&x.flags===A.flags&&x.flags_int===A.flags_int&&(x.data??null)===A.data}async dropRowMissingFromDevice(x){try{await this.storage.deleteFile(x.filename)}catch(A){this.logger?.error(`${O0} reconcile delete error ${x.filename}: ${JSON.stringify(A)}`)}}async validateDevice(x){Ox(x),this.emitProgress("validating",null,0,1);let A=await this.utoMaster.requestDeviceInfo();if(!A)throw new Error(`${O0} requestDeviceInfo returned null`);let e=await this.storage.getMetadataValue("device_id");if(e===null){if(!A.serialNumber)throw new Error(`${O0} DB metadata missing device_id and connected device has no serialNumber`);if(!this.storage.setMetadataValue)throw new Error(`${O0} DB metadata missing device_id`);await this.storage.setMetadataValue("device_id",A.serialNumber),e=A.serialNumber}if(e.toUpperCase()!==A.serialNumber.toUpperCase())throw new Error(`${O0} DB device_id "${e}" does not match connected device "${A.serialNumber}"`);return this.emitProgress("validating",null,1,1),A}buildTagMap(x){let A=new Map;for(let e=0;e<x.utos.length;e++){let r=x.utos[e];A.set(r.wTag,{index:e,flags:{up:r.flags.up,down:r.flags.down,setValue:!!r.flags.setValue},historic:r.flags.historic,sTag:r.sTag})}return A}async resolveDbTags(x){let A=await this.storage.getUtoDataTags(),e=new Set(A);for(let[r,t]of x)t.historic&&!e.has(r)&&A.push(r);return A}async buildTagStampCache(x,A,e){let r=new Map;for(let t of x){let i=A.get(t),n=await this.storage.getLatestStampForTag(t),F=n?QA(n):0,v=i&&i.index<e.stamps.length?e.stamps[i.index]:null;r.set(t,{dbStamp40:F,deviceStamp40:v,tagInfo:i})}return r}async executeChangeRequests(x,A,e,r,t,i){let n=await this.storage.getUtoChangeRequests(),F=this.groupChangeRequests(n),v=F.size;if(this.emitProgress(yF,null,0,v),v===0)return;let E=new Set,u=0;for(let[D,m]of F){Ox(i);let w=x.get(D),j=w?.sTag??`0x${D.toString(16)}`;this.emitProgress(yF,j,u,v),await this.executeChangeRequestTag(D,j,w,m,A,r,t,E),++u}E.size>0&&await this.repullExecutedTags(E,x,e,i)}groupChangeRequests(x){let A=new Map;for(let e of x){let r=A.get(e.tag)??[];r.push({stamp40:QA(e.stamp),user:e.user,json:e.json}),A.set(e.tag,r)}return A}async executeChangeRequestTag(x,A,e,r,t,i,n,F){if(!e){this.pushChangeResults(n,x,A,r,"unknown-tag");return}if(!e.flags.setValue){this.pushChangeResults(n,x,A,r,"skip-unsupported");return}let v=e.index<t.stamps.length?t.stamps[e.index]:0,E=r.filter(D=>D.stamp40<=v),u=r.filter(D=>D.stamp40>v);this.pushChangeResults(n,x,A,E,Xi),u.length>0&&await this.coalesceAndSend(x,A,e,u,i,n,F)}async coalesceAndSend(x,A,e,r,t,i,n){let F=await this.storage.getRowForTag(x);if(t.get(x)?.outcome===Ne||!F||!F.data){this.pushChangeResults(i,x,A,r,"error");return}let v=this.resolveSetObject(F.data,r,A);if(v===null){this.pushChangeResults(i,x,A,r,"error");return}if(Object.keys(v).length===0){this.pushChangeResults(i,x,A,r,"skip-no-change");return}let E=r[r.length-1].stamp40,u=await this.utoMaster.sendSetValue(x,JSON.stringify(v),E);u.outcome==="ok"||u.outcome==="stamp"?(n.add(x),this.pushChangeResults(i,x,A,r,kF,u.resultCode)):u.outcome==="denied"?(this.logger?.warn(`${O0} change-request denied ${A} (result=${u.resultCode}) \u2014 server will retry`),this.pushChangeResults(i,x,A,r,"denied",u.resultCode)):(this.logger?.error(`${O0} change-request error ${A} (result=${u.resultCode})`),this.pushChangeResults(i,x,A,r,"error",u.resultCode))}resolveSetObject(x,A,e){try{let r=JSON.parse(z0.cp1252Unpack(x,0,x.byteLength));return this.buildSetObject(r,A,e)}catch(r){return this.logger?.error(`${O0} change-request unparseable uto_data ${e}: ${r}`),null}}buildSetObject(x,A,e){let r={};for(let t of A){let i=JSON.parse(t.json);if(!this.isPlainRecord(i))throw new Error(`change-request JSON is not an object on ${e}`);for(let[n,F]of Object.entries(i)){let v=this.resolveChangeField(x[n],F,n,e);v.apply&&(r[n]=v.value,x[n]=v.value)}}return r}resolveChangeField(x,A,e,r){if(this.isBitwiseOp(A)){let{op:t,val:i}=A;return this.resolveBitwiseOp(x,t,i,e,r)}return x===A?{apply:!1}:{apply:!0,value:A}}resolveBitwiseOp(x,A,e,r,t){return A!=="|"&&A!=="&"?(this.logger?.warn(`${O0} change-request unknown op "${A}" on ${t}.${r} \u2014 skipped`),{apply:!1}):typeof e!="number"?(this.logger?.warn(`${O0} change-request op "${A}" with non-number val on ${t}.${r} \u2014 skipped`),{apply:!1}):x===void 0?A==="|"?{apply:!0,value:e}:{apply:!1}:typeof x!="number"?(this.logger?.warn(`${O0} change-request op "${A}" on non-number ${t}.${r} \u2014 skipped`),{apply:!1}):{apply:!0,value:A==="|"?x|e:x&e}}isBitwiseOp(x){return this.isPlainRecord(x)&&"op"in x}isPlainRecord(x){return typeof x=="object"&&x!==null&&!Array.isArray(x)}pushChangeResults(x,A,e,r,t,i){for(let n of r)x.push({tag:A,sTag:e,stamp40:n.stamp40,user:n.user,outcome:t,resultCode:i})}async repullExecutedTags(x,A,e,r){let t=null;try{t=await this.utoMaster.requestStamps()}catch(i){this.logger?.warn(`${O0} change-request STAMPS re-fetch failed \u2014 using per-tag stamps: ${i}`)}for(let i of x)Ox(r),await this.repullExecutedTag(i,A,t,e)}async repullExecutedTag(x,A,e,r){try{let t=await this.utoMaster.requestUto(x,0);if(!t){this.logger?.info(`${O0} change-request re-pull tag=0x${x.toString(16)} \u2014 device returned no data (E_EOD), DB row unchanged`);return}let i=await this.storage.getRowForTag(x),n=t.stamp;await this.storage.replaceUtoRow({tag:x,stamp:fA(n),flags:i?.flags??0,site_related:i?.site_related??0,data:t.data?new Uint8Array(t.data.buffer.slice(t.data.byteOffset,t.data.byteOffset+t.data.byteLength)):null});let F=r.get(x);if(F){let v=A.get(x),E=e&&v&&v.index<e.stamps.length?e.stamps[v.index]:n;F.dbStamp40=n,F.deviceStamp40=E}this.logger?.info(`${O0} change-request re-pull tag=0x${x.toString(16)} \u2192 stamp ${n}`)}catch(t){this.logger?.error(`${O0} change-request re-pull error tag=0x${x.toString(16)}: ${t}`)}}aggregateResult(x,A,e){let r=[...x.values()],t=[...A.values()],i=jF(t);return{tags:r,files:t,changeRequests:e,requiresReconnectSync:i.length>0,rebootFilesDeployed:i,totalTagsUploaded:r.filter(n=>n.outcome==="upload"&&!n.historic).length,totalTagsDownloaded:r.filter(n=>n.outcome==="download").length,totalTagsSkipped:r.filter(n=>n.outcome===rr||n.outcome==="skip-db-readonly"||n.outcome===Hr).length,totalHistoricRecordsAppended:r.reduce((n,F)=>n+(F.recordsAppended??0),0),totalFilesUploaded:t.filter(n=>n.outcome===zi).length,totalFilesDownloaded:t.filter(n=>n.outcome==="download").length,totalFilesDeleted:t.filter(n=>n.outcome===Ki).length,totalChangeRequestsExecuted:e.filter(n=>n.outcome===kF).length,totalErrors:r.filter(n=>n.outcome===Ne).length+t.filter(n=>n.outcome===Ne).length+e.filter(n=>n.outcome===ud).length}}async sync(x){let{signal:A}=x??{},e=await this.validateDevice(A);Ox(A),this.emitProgress(dn,null,0,3);let r=this.buildTagMap(e),t=await this.utoMaster.requestStamps();if(!t)throw new Error(`${O0} requestStamps returned null`);this.emitProgress(dn,"stamps",1,3);let i=await this.utoMaster.requestFileList();this.emitProgress(dn,"file-list",2,3);let n=await this.resolveDbTags(r);this.emitProgress(dn,"db-tags",3,3);let F=await this.buildTagStampCache(n,r,t),v=new Map,E=new Map,u=[],D=await this.isAppInDevPhase();return Ox(A),await this.uploadUtoTags(n,F,v,A),Ox(A),await this.uploadFiles(i,E,D,A),Ox(A),await this.executeChangeRequests(r,t,F,v,u,A),Ox(A),await this.downloadUtoTags(n,F,v,A),Ox(A),await this.downloadFiles(i,E,D,A),Ox(A),jF([...E.values()]).length===0&&await this.reconcileFileState(A),this.emitProgress("complete",null,0,0),this.aggregateResult(v,E,u)}async executeAdHocChangeRequest(x,A){let e=await this.utoMaster.requestDeviceInfo();if(!e)throw new Error(`${O0} requestDeviceInfo returned null`);let r=this.buildTagMap(e),t=await this.utoMaster.requestStamps();if(!t)throw new Error(`${O0} requestStamps returned null`);let i=r.get(x),n=i?.sTag??`0x${x.toString(16)}`,F=A.map(m=>({stamp40:m.stamp40,user:"",json:m.json})).sort((m,w)=>m.stamp40-w.stamp40),v=new Map,E=[],u=new Set;return await this.executeChangeRequestTag(x,n,i,F,t,v,E,u),u.size>0&&await this.repullExecutedTags(u,r,new Map,void 0),E.find(m=>m.outcome!==Xi)?.outcome??Xi}},pd=require("events"),bd=require("events"),md=require("events"),hd=5e3,Ls=class _8 extends md.EventEmitter{constructor(A=ZA){super(),A0(this,"logger",A),A0(this,"ws",null),A0(this,"bridgeTransport",null),A0(this,"bridgeSignal"),A0(this,"bridgeResolve",null),A0(this,"bridgeReject",null),A0(this,"serverMessageCount",0),A0(this,"settled",!1),A0(this,"abortHandler",null),A0(this,"connectTimeout"),A0(this,"writeQueue",[]),A0(this,"isProcessingQueue",!1),A0(this,"queueAborted",!1),A0(this,"queueDrainPromise",Promise.resolve()),A0(this,"transportUnsubscribe",null)}static buildSyncUrl(A,e){return`wss://${A}/uto/1/sync/${e}`}resetBridgeState(){this.serverMessageCount=0,this.settled=!1,this.abortHandler=null,this.connectTimeout=void 0,this.writeQueue=[],this.isProcessingQueue=!1,this.queueAborted=!1,this.queueDrainPromise=Promise.resolve(),this.bridgeResolve=null,this.bridgeReject=null,this.bridgeTransport=null,this.bridgeSignal=void 0,this.transportUnsubscribe=null}async processWriteQueue(){if(!this.isProcessingQueue){for(this.isProcessingQueue=!0;this.writeQueue.length>0&&!this.queueAborted;){let A=this.writeQueue.shift();try{await t8(this.bridgeTransport,A)}catch(e){let r=e instanceof Error?e.message:String(e);this.logger.error(`Error writing to transport: ${r}`)}}this.isProcessingQueue=!1}}cleanup(){this.transportUnsubscribe&&(this.transportUnsubscribe(),this.transportUnsubscribe=null),this.abortHandler&&this.bridgeSignal&&(this.bridgeSignal.removeEventListener("abort",this.abortHandler),this.abortHandler=null),this.connectTimeout!==void 0&&(clearTimeout(this.connectTimeout),this.connectTimeout=void 0),this.ws=null}settle(A,e){this.settled||(this.settled=!0,this.cleanup(),A==="resolve"?this.bridgeResolve?.({serverMessageCount:this.serverMessageCount}):this.bridgeReject?.(e))}attachWebSocketHandlers(A,e){let r=t=>{A.readyState===WebSocket.OPEN&&!this.bridgeSignal?.aborted&&!this.settled&&A.send(t)};this.abortHandler=()=>{this.logger.info("WebSocket bridge aborted"),this.queueAborted=!0,this.writeQueue.length=0,(A.readyState===WebSocket.OPEN||A.readyState===WebSocket.CONNECTING)&&A.close(),this.settle("reject",new Error("Operation aborted"))},this.bridgeSignal&&this.bridgeSignal.addEventListener("abort",this.abortHandler),A.onopen=()=>{this.connectTimeout!==void 0&&(clearTimeout(this.connectTimeout),this.connectTimeout=void 0),this.logger.info(`WebSocket connected to ${e}`),this.transportUnsubscribe=this.bridgeTransport.onData(r),this.emit("wsConnected")},A.onmessage=t=>{this.serverMessageCount++,this.emit("serverMessage",this.serverMessageCount),!(this.bridgeSignal?.aborted||this.settled)&&(this.writeQueue.push(t.data),this.isProcessingQueue||(this.queueDrainPromise=this.processWriteQueue()))},A.onclose=t=>{this.logger.info(`WebSocket closed (server=${e}, code=${t.code}, messages=${this.serverMessageCount})`),this.emit("wsClosed",t.code,t.reason),this.queueDrainPromise.then(()=>this.settle("resolve")).catch(()=>this.settle("resolve"))},A.onerror=t=>{this.logger.error(`WebSocket error (server=${e})`),this.emit("wsError",t),this.queueAborted=!0,this.writeQueue.length=0,this.settle("reject",new Error("WebSocket error"))}}async bridge(A,e,r,t){return new Promise((i,n)=>{if(t?.aborted){n(new Error("Operation aborted"));return}this.resetBridgeState(),this.bridgeTransport=A,this.bridgeSignal=t,this.bridgeResolve=i,this.bridgeReject=n;let F=_8.buildSyncUrl(e,r);this.logger.info(`Opening WebSocket: ${F}`);let v=new WebSocket(F);v.binaryType="arraybuffer",this.ws=v,this.connectTimeout=setTimeout(()=>{v.readyState===WebSocket.CONNECTING&&(this.logger.error("WebSocket connection timeout"),v.close(),this.settle("reject",new Error("WebSocket connection timeout")))},hd),this.attachWebSocketHandlers(v,e)})}close(){this.ws&&this.ws.readyState===WebSocket.OPEN&&this.ws.close()}},S8="https://lic.mydatanet.at/api/2/";async function $8(x,A=S8){let e=`${A}devices/${x}/assignment`,r=await fetch(e);if(!r.ok)throw new Error(`Failed to get device assignment: ${r.status} ${r.statusText}`);return r.json()}var T8=class extends bd.EventEmitter{constructor(x=ZA){super(),A0(this,"logger",x)}async execute(x,A,e,r){let t=e;t||(this.logger.info("[LegacySync] No serverUrl provided, resolving via device assignment..."),this.emit("syncPhase",{phase:"resolving-server"}),t=(await $8(A)).server_url,this.logger.info("[LegacySync] Resolved server URL: "+t)),this.logger.info("[LegacySync] Starting legacy sync (server="+t+")");let i=new Ls(this.logger);i.on("wsConnected",()=>this.emit("wsConnected")),i.on("wsClosed",(F,v)=>this.emit("wsClosed",F,v)),i.on("wsError",F=>this.emit("wsError",F)),i.on("serverMessage",F=>this.emit("serverMessage",F));let n=await i.bridge(x,t,A,r);return this.logger.info("[LegacySync] Legacy sync completed (serverMessages="+n.serverMessageCount+")"),{serverMessageCount:n.serverMessageCount}}},jd=require("events"),P8="Operation aborted";function gd(x){return x instanceof Error?x.message:String(x)}function Yi(x){if(x?.aborted)throw new Error(P8)}var q8=class extends jd.EventEmitter{constructor(x,A=ZA){super(),A0(this,"atHandler",x),A0(this,"logger",A)}async execute(x,A,e,r){this.logger.info("Starting debug-enabled sync");let t=[{name:"mnt",queryServer:n=>this.atHandler.queryMntServerConfig(n),initiateSync:n=>this.atHandler.initiateMntSync(n)},{name:"mdn",queryServer:n=>this.atHandler.queryMdnServerConfig(n),initiateSync:n=>this.atHandler.initiateMdnSync(n)}],i={};for(let n of t)try{i[n.name]=await this.runSyncPhase(n,x,A,r)}catch(F){if(r?.aborted)throw new Error(P8);let v=`${n.name.toUpperCase()} sync phase failed: ${gd(F)}`;throw this.logger.error(v),new Error(v)}return this.logger.info(`Debug sync completed (mntMessages=${i.mnt}, mdnMessages=${i.mdn})`),{mntServerMessageCount:i.mnt,mdnServerMessageCount:i.mdn}}async runSyncPhase(x,A,e,r){Yi(r);let t=x.name.toUpperCase();this.emit("syncPhase",{phase:x.name}),this.logger.info(`Phase: Querying ${t} server configuration`);let i=await x.queryServer(r);this.logger.info(`${t} server domain: ${i}`),Yi(r),await x.initiateSync(r),Yi(r);let n=await this.syncWithServer(A,i,e,r);return this.logger.info(`${t} phase completed (serverMessages=${n.serverMessageCount})`),n.serverMessageCount}async syncWithServer(x,A,e,r){let t=new Ls(this.logger),i=!1;t.on("wsConnected",()=>this.emit("wsConnected"));let n=this.atHandler.createConCloseMonitor(()=>{i=!0,this.logger.info("Device initiated close (+CONCLOSE), closing WebSocket"),t.close()});try{let F=await t.bridge(x,A,e,r);return i?this.logger.info("Connection closed by device (+CONCLOSE)"):(this.logger.info("Connection closed by server, sending +CONCLOSE to device"),await this.atHandler.sendConnectionClose(r)),F}finally{n()}}},yd=class extends pd.EventEmitter{constructor(x,A,e=ZA){super(),A0(this,"syncTransport",x),A0(this,"logger",e),A0(this,"atHandler"),this.atHandler=A??null}async sync(x){let A=this.atHandler?"debug":"legacy";this.emit("syncStart",{mode:A});try{if(this.atHandler)try{return this.emit("syncPhase",{phase:"debug-sync"}),await this.syncWithDebug(x)}catch(e){return this.logger.warn("[SyncManager] Debug sync failed, falling back to legacy sync: "+(e instanceof Error?e.message:String(e))),this.emit("syncPhase",{phase:"debug-fallback-legacy"}),await this.syncLegacy(x)}return this.emit("syncPhase",{phase:"legacy"}),await this.syncLegacy(x)}catch(e){throw this.emit("syncError",e),e}}async syncLegacy(x){let A=new T8(this.logger);A.on("syncPhase",t=>this.emit("syncPhase",t));let r={mode:"legacy",serverMessageCount:(await A.execute(this.syncTransport,x.serialNumber,x.serverUrl,x.signal)).serverMessageCount};return this.emit("syncComplete",r),r}async syncWithDebug(x){let A=new q8(this.atHandler,this.logger);A.on("syncPhase",t=>this.emit("syncPhase",t));let e=await A.execute(this.syncTransport,x.serialNumber,x.serverUrl??"",x.signal),r={mode:"debug",serverMessageCount:e.mntServerMessageCount+e.mdnServerMessageCount,mntServerMessageCount:e.mntServerMessageCount,mdnServerMessageCount:e.mdnServerMessageCount};return this.emit("syncComplete",r),r}dispose(){}},kd=require("events"),_x={MNT_CFG:"at+mntcfg?",MDN_CFG:"at+mdncfg?",MNT_SYNC:"at+mntsync",MDN_SYNC:"at+mdnsync",CON_CLOSE:"at+conclose",APP_GET_METADATA:"AT+APP=GETMETADATA",APP_GET_DATAVALUE:"AT+APP=GETDATAVALUE",APP_TRIG_MEASURE:"AT+APP=TRIGMEASURE",APP_TRIG_MEASURE_TEST:"AT+APP=TRIGMEASURE=?",ATI:"ati",RM2M_STATE:"at+rm2mstate?",TX:"at+tx",TX_MAINTENANCE:"at+tx=4",TX_GSM_POSITION:"at+tx=1",TX_MODE_TRIGGERED:"at+txmode=0",TX_MODE_WAKEUP:"at+txmode=1",TX_MODE_ONLINE:"at+txmode=2",COMPANION_CERT:"AT+COMPCERT",COMPANION_CERT_TEST:"AT+COMPCERT=?"},K0={OK:"OK",ERROR:"ERROR",SYNC_START:"+SYNC START",MEASURED:"+MEASURED",CON_CLOSE:"+CONCLOSE",MNT_CFG_PREFIX:"+MNTCFG",MDN_CFG_PREFIX:"+MDNCFG",RM2M_STATE:"+RM2MSTATE",ERROR_PIN_REQUIRED:"ERROR PIN REQUIRED",ERROR_NO_DATA:"ERROR NO DATA",COMPCERT_ERROR:/\+COMPCERT ERROR:\s*(\d+)/},Vx=1e4,N8=9e4,I8=/(?:ERROR PIN REQUIRED|ERROR NO DATA|ERROR|OK)\r\n/;function M8(){return{buffer:"",closedByDevice:!1,reset(){this.buffer="",this.closedByDevice=!1}}}var tr="Operation aborted",Hx=class extends Error{constructor(x="AT command handler was disposed"){super(x),this.name="AtHandlerDisposedError"}},Rs=class extends Error{constructor(x="Device returned ERROR response"){super(x),this.name="AtDeviceError"}},wd=class extends kd.EventEmitter{constructor(x,A=ZA){super(),A0(this,"transport",x),A0(this,"logger",A),A0(this,"mutex",new gs("AtCommandHandler")),A0(this,"bufferState",M8()),A0(this,"responseCallback",null),A0(this,"decoder",new TextDecoder),A0(this,"dataHandler"),A0(this,"disposeTransportListener"),A0(this,"isDisposed",!1),A0(this,"activeAbort",null),A0(this,"session"),this.dataHandler=e=>this.handleIncomingData(e),this.disposeTransportListener=this.transport.onData(this.dataHandler),this.session={sendAndWait:(e,r,t=Vx,i)=>this.executeSendAndWait(e,r,t,i),sendRaw:(e,r=Vx)=>this.executeSendRaw(e,r),queryMntServerConfig:e=>this.executeQueryConfig(_x.MNT_CFG,K0.MNT_CFG_PREFIX,e),queryMdnServerConfig:e=>this.executeQueryConfig(_x.MDN_CFG,K0.MDN_CFG_PREFIX,e),initiateMntSync:e=>this.executeInitiateMntSync(e),initiateMdnSync:e=>this.executeInitiateMdnSync(e),sendCompanionCert:(e,r)=>this.executeSendCompanionCert(e,r),queryCompanionCertSupport:e=>this.executeQueryCompanionCertSupport(e),sendConnectionClose:e=>this.executeSendConnectionClose(e)}}get isBusy(){return this.mutex.islocked}get disposed(){return this.isDisposed}async withAtLock(x){await this.mutex.requestLock();try{if(this.isDisposed)throw new Hx;return await x(this.session)}finally{this.mutex.unlock()}}handleIncomingData(x){let A=this.decoder.decode(x);this.bufferState.buffer+=A,this.emit("data",A),this.responseCallback&&this.responseCallback(this.bufferState.buffer),!this.responseCallback&&this.bufferState.buffer.length>1e3&&(this.bufferState.buffer=this.bufferState.buffer.slice(-500))}encodeCommand(x){let A=new Uint8Array(x.length+2);for(let e=0;e<x.length;e++)A[e]=x.charCodeAt(e);return A[x.length]=10,A[x.length+1]=13,A.buffer}makeCleanup(x,A,e){return()=>{this.responseCallback=null,this.activeAbort=null,clearTimeout(x),A&&e&&A.removeEventListener("abort",e)}}makeResponseChecker(x,A,e,r){let t=x instanceof RegExp;return i=>{if(x!==K0.ERROR&&i.includes(K0.ERROR)){A(),r(new Rs);return}let n=!1,F=i;if(t){let v=i.match(x);v&&(n=!0,F=v[0])}else n=i.includes(x);if(n){A(),e(F);return}i.length>500&&(this.bufferState.buffer=this.bufferState.buffer.slice(-250))}}executeSendAndWait(x,A,e,r){return new Promise((t,i)=>{if(this.isDisposed){i(new Hx);return}if(r?.aborted){i(new Error(tr));return}x&&(this.bufferState.buffer="");let F=A instanceof RegExp?A.source:A,v={cleanup:()=>{}},E=setTimeout(()=>{v.cleanup(),i(new Error(`Timeout waiting for response: ${F}`))},e),u=()=>{v.cleanup(),i(new Error(tr))};v.cleanup=this.makeCleanup(E,r,u),r&&r.addEventListener("abort",u);let D=this.makeResponseChecker(A,v.cleanup,t,i);this.responseCallback=D,this.activeAbort=()=>{v.cleanup(),i(new Hx)},!x&&this.bufferState.buffer&&D(this.bufferState.buffer),x&&(this.logger.info("TX: "+x),this.transport.write(this.encodeCommand(x)).catch(m=>{v.cleanup(),i(m)}))})}executeSendRaw(x,A){return new Promise((e,r)=>{if(this.isDisposed){r(new Hx);return}this.bufferState.buffer="";let t=setTimeout(()=>{i(),r(new Error(`Timeout waiting for raw AT response to: ${x}`))},A),i=this.makeCleanup(t);this.activeAbort=()=>{i(),r(new Hx)},this.responseCallback=n=>{I8.test(n)&&(i(),this.logger.info("RX: "+n.trim()),e(n))},this.logger.info("TX: "+x),this.transport.write(this.encodeCommand(x)).catch(n=>{i(),r(n)})})}executeQueryConfig(x,A,e){return new Promise((r,t)=>{if(this.isDisposed){t(new Hx);return}if(e?.aborted){t(new Error(tr));return}this.bufferState.buffer="";let i={cleanup:()=>{}},n=setTimeout(()=>{i.cleanup(),this.logger.error(`Timeout waiting for ${A} server config`),t(new Error(`Timeout waiting for ${A} response \u2014 server configuration not available`))},Vx),F=()=>{i.cleanup(),t(new Error(tr))};i.cleanup=this.makeCleanup(n,e,F),e&&e.addEventListener("abort",F);let v=new RegExp(`\\${A}:\\s*<?([^,>\\s]+)>?`);this.activeAbort=()=>{i.cleanup(),t(new Hx)},this.responseCallback=E=>{let u=E.match(v);if(u){i.cleanup();let D=u[1].trim();this.logger.info(`Server config ${A}: ${D}`),r(D);return}E.length>500&&(this.bufferState.buffer=this.bufferState.buffer.slice(-250))},this.logger.info("TX: "+x),this.transport.write(this.encodeCommand(x)).catch(E=>{i.cleanup(),this.logger.error(`Failed to send ${A} command: `+(E instanceof Error?E.message:String(E))),t(E)})})}async sendAndWait(x,A,e=Vx,r){return this.withAtLock(t=>t.sendAndWait(x,A,e,r))}async sendRaw(x,A=Vx){return this.withAtLock(e=>e.sendRaw(x,A))}async queryMntServerConfig(x){return this.withAtLock(A=>A.queryMntServerConfig(x))}async queryMdnServerConfig(x){return this.withAtLock(A=>A.queryMdnServerConfig(x))}async initiateMntSync(x){return this.withAtLock(A=>A.initiateMntSync(x))}async initiateMdnSync(x){return this.withAtLock(A=>A.initiateMdnSync(x))}async sendCompanionCert(x,A){return this.withAtLock(e=>e.sendCompanionCert(x,A))}async executeInitiateMntSync(x){this.logger.info("Initiating MNT sync"),await this.executeSendAndWait(_x.MNT_SYNC,K0.OK,Vx,x)}async executeInitiateMdnSync(x){this.logger.info("Initiating MDN sync");try{await this.executeSendAndWait(_x.MDN_SYNC,K0.OK,Vx,x),await this.executeSendAndWait(null,K0.SYNC_START,Vx,x)}catch(A){this.logger.error("Failed to initiate MDN sync: "+(A instanceof Error?A.message:String(A)))}}async executeSendCompanionCert(x,A){if(this.isDisposed)throw new Hx;if(A?.aborted)throw new Error(tr);let e=x.replace(/-/g,"+").replace(/_/g,"/")+"=".repeat((4-x.length%4)%4),r=e.length,t=await this.executeSendAndWait(`${_x.COMPANION_CERT}=${r}`,K0.OK,Vx,A),i=parseInt(t.match(/(\d+)/)[1],10),n=0;for(;n<r;){let F=Math.min(i,r-n),v=e.slice(n,n+F);await this.executeSendAndWait(`${_x.COMPANION_CERT}=${F},${n},${v}`,K0.OK,Vx,A),n+=F}return this.executeCompanionCertFinalize(r,A)}executeCompanionCertFinalize(x,A){return new Promise((e,r)=>{if(this.isDisposed){r(new Hx);return}if(A?.aborted){r(new Error(tr));return}this.bufferState.buffer="";let t={cleanup:()=>{}},i=setTimeout(()=>{t.cleanup(),r(new Error("Timeout waiting for AT+COMPCERT finalize response"))},Vx),n=()=>{t.cleanup(),r(new Error(tr))};t.cleanup=this.makeCleanup(i,A,n),A&&A.addEventListener("abort",n),this.activeAbort=()=>{t.cleanup(),r(new Hx)},this.responseCallback=v=>{let E=v.match(K0.COMPCERT_ERROR);if(E){t.cleanup(),e({success:!1,errorCode:parseInt(E[1],10)});return}if(v.includes(K0.OK)){t.cleanup(),e({success:!0});return}v.length>500&&(this.bufferState.buffer=this.bufferState.buffer.slice(-250))};let F=`${_x.COMPANION_CERT}=0,${x}`;this.logger.info("TX: "+F),this.transport.write(this.encodeCommand(F)).catch(v=>{t.cleanup(),r(v)})})}async queryCompanionCertSupport(x){return this.withAtLock(A=>A.queryCompanionCertSupport(x))}async executeQueryCompanionCertSupport(x){try{return await this.executeSendAndWait(_x.COMPANION_CERT_TEST,K0.OK,Vx,x),!0}catch(A){if(A instanceof Hx)throw A;return!1}}async sendConnectionClose(x){return this.withAtLock(A=>A.sendConnectionClose(x))}async executeSendConnectionClose(x){try{await this.executeSendAndWait(_x.CON_CLOSE,K0.CON_CLOSE,Vx,x)}catch(A){this.logger.error("Failed to receive +CONCLOSE response: "+(A instanceof Error?A.message:String(A)))}}createConCloseMonitor(x){let A="",e=r=>{A+=r,A.includes(K0.CON_CLOSE)&&(A="",this.bufferState.closedByDevice=!0,x()),A.length>1e3&&(A=A.slice(-500))};return this.on("data",e),()=>{this.off("data",e)}}dispose(){this.isDisposed||(this.isDisposed=!0,this.activeAbort?.(),this.disposeTransportListener(),this.responseCallback=null,this.activeAbort=null,this.removeAllListeners())}},L8=(x=>(x[x.FORMAT=1]="FORMAT",x[x.SIGNATURE=2]="SIGNATURE",x[x.EXPIRED=3]="EXPIRED",x[x.NO_MDN_PUBKEY=4]="NO_MDN_PUBKEY",x[x.BUSY=5]="BUSY",x[x.INTERNAL=6]="INTERNAL",x))(L8||{}),_d=require("events"),Qi="requesting-cert",Zi="cert-revoked",R8=class Bs extends _d.EventEmitter{constructor(){super(...arguments),A0(this,"utoMaster",null)}async authenticate(A){let e=A.logger??yn,{signal:r,atHandler:t}=A,i=()=>{if(r?.aborted)throw new Error("Operation aborted")};try{this.emitPhase("checking-cert"),i();let n=await this.loadOrGenerateKeypair(A.storage),F=await A.storage.getCertificate(A.apiConfig.apiHost);(F===null||!bs(F.notAfter))&&(e.info("Companion cert missing or near expiry \u2014 requesting new cert"),this.emitPhase(Qi),i(),F=await this.requestAndStoreCert(n,A)),this.utoMaster=new n8(A.utoTransport,e,A.timeSource),this.emitPhase("cert-presenting"),i();let v=F;F=await t.withAtLock(async D=>{let m=await this.presentCertWithRefresh(D,v,n,A);return await D.initiateMdnSync(r),m}),this.emitPhase("ecs-handshake"),i(),await this.utoMaster.init();let E=await this.utoMaster.initiateEcsHandshake({companionPublicKey:n.publicKey,companionPrivateKey:n.privateKey,signal:r});if(!E.success)return this.fail("ecs-handshake",`ECS handshake failed (code ${E.resultCode})`);this.emitPhase("connected");let u=this.utoMaster;return this.utoMaster=null,{success:!0,utoMaster:u}}catch(n){return this.handleError(n)}}dispose(){this.utoMaster=null,this.removeAllListeners()}async loadOrGenerateKeypair(A){let e=await A.getKeypair();if(e!==null)return e;let r=await rs();return await A.saveKeypair(r),r}static async fetchCertOrThrowRevoked(A,e){try{return await zF(e.apiConfig,{publicKey:A.publicKey,subject:e.subject})}catch(r){throw r instanceof wt&&(r.httpStatus===401||r.httpStatus===404)?(await e.storage.clearCertificate(e.apiConfig.apiHost),new xs(Zi,`Companion cert revoked or session expired (HTTP ${r.httpStatus})`,{httpStatus:r.httpStatus,apiCode:r.code})):r}}async requestAndStoreCert(A,e){let r=await Bs.fetchCertOrThrowRevoked(A,e),t={base64Url:r.certificateBase64Url,notAfter:r.notAfter};return await e.storage.saveCertificate(t,e.apiConfig.apiHost),t}static async refreshCertificate(A){let e=await A.storage.getKeypair(),r=e!==null?e:await(async()=>{let n=await rs();return await A.storage.saveKeypair(n),n})(),t=await Bs.fetchCertOrThrowRevoked(r,A),i={base64Url:t.certificateBase64Url,notAfter:t.notAfter};return await A.storage.saveCertificate(i,A.apiConfig.apiHost),i}static async clearCredentials(A,e){await A.clearCertificate(e)}async presentCertWithRefresh(A,e,r,t){let i=await A.sendCompanionCert(e.base64Url,t.signal);if(i.success||i.errorCode===3&&((t.logger??yn).info("Device reported EXPIRED \u2014 refreshing cert and retrying"),this.emitPhase(Qi),e=await this.requestAndStoreCert(r,t),i=await A.sendCompanionCert(e.base64Url,t.signal),i.success))return e;throw new xs("cert-presenting",`AT+COMPCERT rejected (code ${i.errorCode??"?"})`,{certErrorCode:i.errorCode})}emitPhase(A){this.emit("phase",A)}fail(A,e){return this.emit("phase","error"),{success:!1,phase:A,error:e}}handleError(A){return A instanceof xs?(this.emit("phase",A.phase===Zi?Zi:"error"),{success:!1,phase:A.phase,error:A.message,certErrorCode:A.certErrorCode,httpStatus:A.httpStatus,apiCode:A.apiCode}):(this.emit("phase","error"),A instanceof wt?{success:!1,phase:Qi,error:A.message,httpStatus:A.httpStatus,apiCode:A.code}:{success:!1,phase:"error",error:A instanceof Error?A.message:String(A)})}};A0(R8,"encodePublicKeyBase64Url",ps);var Sd=R8,xs=class extends Error{constructor(x,A,e={}){super(A),A0(this,"phase",x),A0(this,"extra",e),this.name="AuthError"}get certErrorCode(){return this.extra.certErrorCode}get httpStatus(){return this.extra.httpStatus}get apiCode(){return this.extra.apiCode}},O8=(x=>(x.CERT_FORMAT="cert_format",x.CERT_SIGNATURE="cert_signature",x.CERT_EXPIRED="cert_expired",x.NO_MDN_PUBKEY="no_mdn_pubkey",x.DEVICE_BUSY="device_busy",x.DEVICE_INTERNAL="device_internal",x.ECS_FAILURE="ecs_failure",x.CERT_REVOKED="cert_revoked",x.SESSION_EXPIRED="session_expired",x.ABORTED="aborted",x.UNKNOWN="unknown",x))(O8||{}),$d={cert_format:"companion_auth.error.cert_format",cert_signature:"companion_auth.error.cert_signature",cert_expired:"companion_auth.error.cert_expired",no_mdn_pubkey:"companion_auth.error.no_mdn_pubkey",device_busy:"companion_auth.error.device_busy",device_internal:"companion_auth.error.device_internal",ecs_failure:"companion_auth.error.ecs_failure",cert_revoked:"companion_auth.error.cert_revoked",session_expired:"companion_auth.error.session_expired",aborted:"companion_auth.error.aborted",unknown:"companion_auth.error.unknown"};function Td(x){if(x.certErrorCode!==void 0)switch(x.certErrorCode){case 1:return"cert_format";case 2:return"cert_signature";case 3:return"cert_expired";case 4:return"no_mdn_pubkey";case 5:return"device_busy";case 6:return"device_internal"}return x.phase==="cert-revoked"?x.httpStatus===401?"session_expired":"cert_revoked":x.phase==="ecs-handshake"?"ecs_failure":x.error==="Operation aborted"?"aborted":"unknown"}var Pd=require("events");function G8(x){let A=x.replace(/\r\nOK\r\n$/,"").trim();return A?A.split("\f").map(e=>{let r=e.split(" ");return r.length<4?null:{name:r[0],scale:parseFloat(r[1]),offset:parseFloat(r[2]),unit:r[3]}}).filter(e=>e!==null):[]}function U8(x){let A=x.replace(/^\+[^\r\n]*\r\n/gm,"").replace(/\r\nOK\r\n$/,"").trim();return A?A.split("\f"):[]}function H8(x,A,e){let r=parseFloat(x);return isNaN(r)?x:parseFloat(Number(r*A+e).toFixed(3)).toString()}function Cs(x,A){return x.map((e,r)=>({name:e.name,displayValue:H8(A[r]??"",e.scale,e.offset),unit:e.unit}))}var qd=2e3,J8=class extends Pd.EventEmitter{constructor(x,A=ZA){super(),A0(this,"atHandler",x),A0(this,"logger",A),A0(this,"datapoints",[]),A0(this,"values",[]),A0(this,"polling",!1),A0(this,"pollTimer",null),A0(this,"fetchInProgress",!1),A0(this,"fetchPromise",null)}async checkSupport(){this.logger.info("Checking local data support");let x=await this.atHandler.sendRaw(_x.APP_GET_METADATA),A=x.includes(K0.OK)?{supported:!0,pinRequired:!1}:x.includes(K0.ERROR_PIN_REQUIRED)?{supported:!0,pinRequired:!0}:x.includes(K0.ERROR_NO_DATA)?{supported:!1,pinRequired:!1}:x.includes(K0.ERROR)?{supported:!1,pinRequired:!1}:{supported:!1,pinRequired:!1};return this.logger.info("Local data support: "+JSON.stringify(A)),A}async fetchMetadata(x){this.logger.info("Fetching metadata"+(x?" (with PIN)":""));let A=x?`${_x.APP_GET_METADATA}=${x}`:_x.APP_GET_METADATA,e=await this.atHandler.sendRaw(A);if(this.logger.debug("Metadata response: "+e),e.includes(K0.ERROR_PIN_REQUIRED))return this.logger.warn("PIN required/invalid for metadata"),null;if(e.includes(K0.ERROR_NO_DATA))return this.logger.warn("No data available from device"),this.datapoints=[],this.values=[],this.emit("metadata",[]),this.emit("error","No local data available from device"),[];if(e.includes(K0.OK)){let r=G8(e);return this.logger.info("Parsed "+r.length+" datapoints"),this.datapoints=r,this.values=new Array(r.length).fill(""),this.emit("metadata",r),r}return e.includes(K0.ERROR)?(this.logger.error("Metadata fetch error: "+e),this.emit("error","Device returned error during metadata fetch"),[]):[]}async fetchValues(x){return this.readValues(A=>this.atHandler.sendRaw(A),x)}async readValues(x,A){try{this.logger.debug("Fetching values");let e=A?`${_x.APP_GET_DATAVALUE}=${A}`:_x.APP_GET_DATAVALUE,r=await x(e);if(r.includes(K0.OK)){let t=U8(r);return this.logger.debug("Values: "+t.join(", ")),this.values=t,this.emit("values",t),this.emit("displayValues",Cs(this.datapoints,t)),t}return[]}catch(e){return this.logger.warn("Value fetch error: "+(e instanceof Error?e.message:String(e))),[]}}async checkMeasurementTriggerSupport(){this.logger.info("Checking measurement trigger support");try{let A=(await this.atHandler.sendRaw(_x.APP_TRIG_MEASURE_TEST)).includes(K0.OK);return this.logger.info("Measurement trigger support: "+A),A}catch(x){if(x instanceof Hx)throw x;return this.logger.warn("Measurement trigger probe failed: "+(x instanceof Error?x.message:String(x))),!1}}async triggerMeasurement(x={}){let{pin:A,timeoutMs:e=N8,signal:r}=x;return this.logger.info("Triggering measurement"),this.atHandler.withAtLock(async t=>{let i=await t.sendRaw(_x.APP_TRIG_MEASURE);if(this.logger.debug("Trigger measurement response: "+i),!i.includes(K0.OK))return this.logger.warn("Measurement trigger rejected: "+i.trim()),{outcome:"rejected",values:[],response:i};this.emit("measurementTriggered");try{let n=await t.sendAndWait(null,K0.MEASURED,e,r);return this.emit("measurementCompleted"),{outcome:"measured",values:await this.readValues(v=>t.sendRaw(v),A),response:n}}catch(n){if(n instanceof Hx)throw n;let F="timeout";return n instanceof Rs?F="error":r?.aborted&&(F="aborted"),this.logger.warn(`Measurement ${F} while waiting for ${K0.MEASURED}: `+(n instanceof Error?n.message:String(n))),this.emit("measurementFailed",F),{outcome:F,values:[],response:i}}})}async startPolling(x,A=qd){if(this.polling){this.logger.warn("Polling already active \u2014 ignoring startPolling call");return}this.logger.info("Starting polling every "+A+" ms"),this.polling=!0,this.fetchInProgress=!1,this.emit("pollingStarted"),this.fetchPromise=this.fetchValues(x),await this.fetchPromise,this.fetchPromise=null,this.polling&&(this.pollTimer=setInterval(()=>{this.fetchInProgress||(this.fetchInProgress=!0,this.fetchPromise=this.fetchValues(x).finally(()=>{this.fetchInProgress=!1,this.fetchPromise=null}))},A))}async stopPolling(){this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null),this.polling&&(this.logger.info("Polling stopped"),this.polling=!1,this.emit("pollingStopped")),this.fetchPromise&&await this.fetchPromise}getSnapshot(){return{datapoints:[...this.datapoints],values:[...this.values],isPolling:this.polling}}getDisplayValues(){return Cs(this.datapoints,this.values)}dispose(){this.stopPolling(),this.datapoints=[],this.values=[],this.removeAllListeners()}};async function Nd(x,A,e){let r=i=>{if(i instanceof Hx)throw i},t=new J8(x);try{let i=await x.queryMdnServerConfig(e).catch(D=>(r(D),!1)),n=await t.checkSupport().catch(D=>(r(D),{supported:!1,pinRequired:!1})),F=n.supported?await t.checkMeasurementTriggerSupport().catch(D=>(r(D),!1)):!1,v=n.supported?{pinRequired:n.pinRequired,canTriggerMeasurement:F}:!1,E=!1,u=!1;if(i){let[D,m]=await Promise.all([x.queryCompanionCertSupport(e).catch(w=>(r(w),!1)),A?.getCertificate(i)]);E=D,u=m!=null&&bs(m.notAfter)}return{hostname:i,localData:v,secureConnection:E,validCert:u}}finally{t.dispose()}}var Id=require("events"),Md={0:"trigger",1:"wakeup",2:"online"},Ld={0:["2G","","GSM"],1:["2G","Compact","GSM-COMPACT"],2:["3G","","UTRAN"],3:["2G","EDGE","GSM-EGPRS"],4:["3G","HSDPA","UTRAN-HSDPA"],5:["3G","HSUPA","UTRAN-HSUPA"],6:["3G","HSPA+","UTRAN-HSXPA"],7:["4G","","EUTRAN"],8:["4G","LTE-M","LTE-CATM1"],9:["4G","NB-IoT","LTE-CATNB1"],100:["WiFi","","WIFI"],101:["LAN","Ethernet","ETHERNET"],102:["Local","Wireless","WIRELESS"],103:["Local","Wired","WIRED"]},Rd={"NO SCRIPT":"none","SCRIPT ERROR":"error","SCRIPT OK":"ok"},Tx={FAILED:1,ACTIVE:2,STARTED:4,RETRY:8,WAKEUPABLE:16,EXTSIM:32,DISABLED:64,WAKEUP:256,POSUPDATE_ACTIVE:512},Od=Tx.FAILED|Tx.ACTIVE|Tx.STARTED|Tx.RETRY|Tx.WAKEUPABLE|Tx.EXTSIM|Tx.DISABLED|Tx.WAKEUP|Tx.POSUPDATE_ACTIVE,wF=`${K0.RM2M_STATE}: `;function K8(x=0){let A=(x&Tx.WAKEUPABLE)!==0,e="offline",r=A;return x&Tx.POSUPDATE_ACTIVE?(e="locating",r=!1):x&Tx.RETRY?(e="retry",r=!1):x&Tx.STARTED?(e="dialing",r=!1):x&Tx.ACTIVE?(e="active",r=!1):x&Tx.FAILED?(e="failed",r=A):x&Tx.DISABLED&&(e="disabled",r=!1),{signal:e,simType:(x&Tx.EXTSIM)!==0?"external":"internal",wakeupable:r,unknownFlags:x&~Od}}function Gd(x){if(x===void 0)return null;let A=parseInt(x,10);return isNaN(A)?x:Md[A]??x}function Ud(x){if(x===void 0)return null;let A=parseInt(x,10);return isNaN(A)?null:Ld[A]??["unknown",`itf#${x}`,`itf#${x}`]}function Hd(x){if(x.length===0)return null;let A=x.join(",");return Rd[A]??A}function z8(x){let A=x.split(","),[e,r,t,i,...n]=A;if(!e||!/^-?\d+$/.test(e)||!r||!/^\d+$/.test(r))return null;let F=parseInt(r,10),v=Ud(i),E=i!==void 0?parseInt(i,10):NaN;return{stamp:new Date,rssi:E>=101?null:parseInt(e,10),state:F,uplinkState:K8(F),uplinkMode:Gd(t),uplinkInterface:v?v[0]:null,uplinkInterfaceExtended:v?v[1]:null,uplinkInterfaceTechnical:v?v[2]:null,scriptState:Hd(n)}}function V8(x){let A=x.indexOf(wF);if(A===-1)return null;let e=x.substring(A+wF.length),r=e.search(/\r?\n/);if(r===-1)return null;let t=e.substring(0,r).trim();return t?z8(t):null}var Jd=5e3,Kd=class extends Id.EventEmitter{constructor(x,A=yn){super(),A0(this,"atHandler"),A0(this,"logger"),A0(this,"lastState",null),A0(this,"pollingTimer",null),A0(this,"polling",!1),A0(this,"fetchInProgress",!1),A0(this,"fetchPromise",null),this.atHandler=x,this.logger=A}async fetchState(){try{let x=await this.atHandler.sendRaw(_x.RM2M_STATE),A=V8(x);return A?(this.lastState=A,this.emit("state",A),this.logger.debug("RM2M state fetched successfully")):this.logger.warn("Failed to parse RM2M state response"),A}catch(x){let A=x instanceof Error?x.message:String(x);return this.logger.error(`Failed to fetch RM2M state: ${A}`),this.emit("error",A),null}}startPolling(x=Jd){if(this.polling){this.logger.debug("Polling already active, ignoring startPolling call");return}this.logger.info(`Starting RM2M state polling every ${x}ms`),this.polling=!0,this.fetchInProgress=!1,this.emit("pollingStarted"),this.runGuardedFetch(),this.pollingTimer=setInterval(()=>this.runGuardedFetch(),x)}runGuardedFetch(){this.fetchInProgress||(this.fetchInProgress=!0,this.fetchPromise=this.fetchState().finally(()=>{this.fetchInProgress=!1,this.fetchPromise=null}))}async stopPolling(){this.pollingTimer&&(clearInterval(this.pollingTimer),this.pollingTimer=null),this.polling&&(this.logger.info("RM2M state polling stopped"),this.polling=!1,this.emit("pollingStopped")),this.fetchPromise&&await this.fetchPromise}getLastState(){return this.lastState?{...this.lastState,uplinkState:{...this.lastState.uplinkState}}:null}get isPolling(){return this.polling}dispose(){this.stopPolling(),this.lastState=null,this.removeAllListeners()}},zd=require("events"),W8=class extends zd.EventEmitter{constructor(){super(...arguments),A0(this,"serialNumber",""),A0(this,"serverUrl",""),A0(this,"deviceId",""),A0(this,"rssi",null),A0(this,"hasDebugSupport",!1),A0(this,"connectionState","disconnected"),A0(this,"connectionError",""),A0(this,"mtuSize",23)}get isConnected(){return this.connectionState==="connected"}setConnected(x){this.serialNumber=x.serialNumber,this.deviceId=x.deviceId,this.serverUrl=x.serverUrl??this.serverUrl,this.hasDebugSupport=x.hasDebugSupport??!1,this.mtuSize=x.mtuSize??23,this.rssi=x.rssi??null,this.connectionState="connected",this.connectionError="",this.emit("connected",this.snapshot()),this.emit("stateChange",this.snapshot())}setDisconnected(){this.connectionState="disconnected",this.rssi=null,this.emit("disconnected"),this.emit("stateChange",this.snapshot())}setError(x){this.connectionError=x,this.connectionState="disconnected",this.emit("error",x),this.emit("stateChange",this.snapshot())}setConnectionState(x){this.connectionState=x,this.emit("stateChange",this.snapshot())}updateRssi(x){this.rssi=x,this.emit("rssiUpdate",x)}reset(){this.serialNumber="",this.serverUrl="",this.deviceId="",this.rssi=null,this.hasDebugSupport=!1,this.connectionState="disconnected",this.connectionError="",this.mtuSize=23,this.emit("reset"),this.emit("stateChange",this.snapshot())}snapshot(){return{serialNumber:this.serialNumber,serverUrl:this.serverUrl,deviceId:this.deviceId,rssi:this.rssi,hasDebugSupport:this.hasDebugSupport,connectionState:this.connectionState,connectionError:this.connectionError,mtuSize:this.mtuSize,isConnected:this.isConnected}}},Vd=require("events"),X8={maxDuration:6e4,initialDelay:1e3,maxDelay:1e4,maxGattRetries:3},Wd=class extends Vd.EventEmitter{constructor(x=ZA,A){super(),A0(this,"logger",x),A0(this,"state"),A0(this,"transports",null),A0(this,"transportFactory",null),A0(this,"disconnectFn",null),A0(this,"reconnectOptions"),A0(this,"reconnectAbortController",null),this.state=new W8,this.reconnectOptions={...X8,...A}}async connect(x,A,e){this.transportFactory=x,this.disconnectFn=A,this.state.setConnectionState("connecting");try{return this.transports=await x(),this.state.setConnected(e),this.logger.info(`Connected to device ${e.serialNumber}`),this.transports}catch(r){let t=r instanceof Error?r.message:String(r);throw this.state.setError(t),this.logger.error(`Connection failed: ${t}`),r}}async disconnect(){if(this.stopReconnect(),this.disconnectFn)try{await this.disconnectFn()}catch(x){this.logger.warn(`Disconnect error: ${x}`)}this.transports=null,this.state.setDisconnected(),this.logger.info("Disconnected from device")}async reconnect(){if(!this.transportFactory||!this.disconnectFn)return this.logger.error("Cannot reconnect: no transport factory"),!1;this.state.setConnectionState("reconnecting"),this.reconnectAbortController=new AbortController;let{signal:x}=this.reconnectAbortController,A=Date.now(),e=this.reconnectOptions.initialDelay;for(;Date.now()-A<this.reconnectOptions.maxDuration;){if(x.aborted||(this.logger.info(`Reconnecting in ${e}ms...`),await this.sleep(e,x),x.aborted))return!1;try{return this.transports=await this.transportFactory(),this.state.setConnectionState("connected"),this.state.connectionError="",this.logger.info("Reconnected successfully"),this.emit("reconnected"),!0}catch(r){this.logger.warn(`Reconnect attempt failed: ${r}`),e=Math.min(e*2,this.reconnectOptions.maxDelay)}}return this.state.setError("Reconnect timeout exceeded"),this.logger.error("Reconnect failed: timeout exceeded"),this.emit("reconnectFailed"),!1}stopReconnect(){this.reconnectAbortController?.abort(),this.reconnectAbortController=null}getTransports(){return this.transports}sleep(x,A){return new Promise(e=>{let r=setTimeout(e,x);A?.addEventListener("abort",()=>{clearTimeout(r),e()},{once:!0})})}},Xd={configurationNumber:1,utoInterface:0,utoEndpoint:1,utoSize:64*1024,debugInterface:1,debugEndpoint:2,debugSize:1024},Yd={service:"BC300000-0FA0-4ED4-860A-CF95434B5A4E",txCharacteristic:"BC30E1FF-0FA0-4ED4-860A-CF95434B5A4E",rxCharacteristic:"BC30E1FE-0FA0-4ED4-860A-CF95434B5A4E",txDebugCharacteristic:"BC30E201-0FA0-4ED4-860A-CF95434B5A4E",rxDebugCharacteristic:"BC30E200-0FA0-4ED4-860A-CF95434B5A4E"},Qd=590,Zd=3e4,S0=class extends Error{constructor(x){super(x),this.name="ApiBadRequestError"}},EA=class extends Error{constructor(x){super(x),this.name="ApiNotFoundError"}},Ln=class extends Error{constructor(x){super(x),this.name="ApiForbiddenError"}},Os=class extends Error{constructor(x){super(x),this.name="ApiMethodNotAllowedError"}};function BA(x){try{return decodeURIComponent(x)}catch{throw new S0("malformed url encoding")}}var xu=2e3,Au=2136;function Gs(x){if(x.length===0)return!0;if(!/^\d{4,17}$/.test(x))return!1;let A=Number(x.slice(0,4));return A>=xu&&A<=Au}function Wr(x){if(x)for(let A of["stamp","from","until"]){let e=x[A];if(typeof e=="string"&&!(A==="until"&&e==="*")&&!(A!=="stamp"&&e.trim().length===0)&&!Gs(e))throw new S0(`attribute '${A}' is not valid`)}}function eu(x){return typeof x.setMetadataValue=="function"?x:null}function ru(x){return typeof x.insertUtoChangeRequests=="function"?x:null}function Us(){return{lastIssuedStamp40:0,tagMutexTails:new Map}}async function tu(x){return{status:200,body:x.ctx.siteInfo}}async function nu(x){let{blueprint:A}=x.ctx;if(!A)throw new EA("blueprint unavailable");return{status:200,body:A}}async function iu(x){let{me:A}=x.ctx;if(A==null)throw new EA("no profile stored");return{status:200,body:A}}function Y8(x,A,e,r){let t=x.push;t&&(async()=>{try{await t.container(A,e,r)}catch(i){x.logger?.error(`[localApi] device push for tag ${A} failed:`,i)}})()}async function su(x,A,e){let r=x.push;if(!r)return null;try{return await r.adHocChangeRequest(A,e)}catch(t){return x.logger?.error(`[localApi] change request for tag ${A} failed:`,t),null}}var au=1024;function It(x){let A=x.indexOf(0),e=A<0?x:x.subarray(0,A);try{let r=new TextDecoder("utf-8").decode(e),t=JSON.parse(r);return typeof t!="object"||t===null||Array.isArray(t)?null:t}catch{return null}}function Q8(x,A=0){let e=new TextEncoder().encode(x),r=Math.max(au,A,e.length+1),t=new Uint8Array(r);return t.set(e,0),t}var Hs=26432,Fr={aberrant:1,service:2,standby:4,commissioned:8,offline:16,commissioning:65536,online:131072},Z8=Object.keys(Fr),Mt=["standby","commissioned","offline","commissioning","online"],ds=Mt.reduce((x,A)=>x|Fr[A],0)>>>0;function xv(x){let A=0;for(let e of Z8)x[e]===!0&&(A|=Fr[e]);return A>>>0}function Js(x,A){let e={};for(let r of Z8)x&Fr[r]?e[r]=!0:typeof A?.[r]=="boolean"&&(e[r]=!1);return e}async function Av(x,A){let e=A.device;if(!e)return!1;let r=await x.getRowForTag(Hs);if(!r?.data)return!1;let t=It(r.data);if(!t)return!1;let i=!1;if(typeof t.lifecycleFlags=="number"){let n=Js(t.lifecycleFlags,e.lifecycle_flags);JSON.stringify(e.lifecycle_flags)!==JSON.stringify(n)&&(e.lifecycle_flags=n,i=!0)}return typeof t.lifecycleState=="string"&&e.lifecycle_state!==t.lifecycleState&&(e.lifecycle_state=t.lifecycleState,i=!0),i}var ou=new Set([...Mt,"service","lifecycle_state"]);function Fu(x,A){let e=Math.max(z0.msToStamp40((x.timeSource??qt).nowMs()),A.lastIssuedStamp40+1);return A.lastIssuedStamp40=e+1,e}async function vu(x){let A=Eu(x.request.body??null);if(!A)throw new S0("invalid or missing request body");lu(A);let e=x.ctx,r=e.siteInfo.lifecycle_flags;if(!fu(r))throw new S0("this site does not support lifecycle flags!");let t=xv(r),i=t;for(let E of Mt){let u=A[E];typeof u=="boolean"&&(i=u?i|Fr[E]:i&~Fr[E])}if(i>>>=0,i===t)return{status:204,body:""};let n=Fu(e,x.session),F=[{json:JSON.stringify({lifecycleFlags:{op:"&",val:~ds>>>0}}),stamp40:n},{json:JSON.stringify({lifecycleFlags:{op:"|",val:i&ds}}),stamp40:n+1}],v=ru(e.storage);return v&&await v.insertUtoChangeRequests(F.map(E=>({tag:Hs,stamp40:E.stamp40,json:E.json}))),e.siteInfo.lifecycle_flags=Js(i,r),await ev(e),cu(e,F),{status:204,body:""}}function lu(x){let A=[];for(let[e,r]of Object.entries(x))ou.has(e)?(e==="lifecycle_state"?typeof r!="string":typeof r!="boolean")&&A.push(`"${e}" is not valid`):A.push(`"${e}" is not an allowed lifecycle property`);if(A.length>0)throw new S0(`validation errors: ${A.join(", ")}`);if(Object.keys(x).some(e=>!Mt.includes(e)))throw new S0("invalid parameters")}async function cu(x,A){try{let e=await su(x,Hs,A);e==="executed"?await Av(x.storage,x.siteInfo)&&await ev(x):e!==null&&x.logger?.warn(`[localApi] lifecycle change request not applied by the device (outcome=${e})`)}catch(e){x.logger?.error("[localApi] lifecycle device-mirror refresh failed:",e)}}async function ev(x){await eu(x.storage)?.setMetadataValue("site_info",JSON.stringify(x.siteInfo))}function fu(x){return typeof x=="object"&&x!==null&&!Array.isArray(x)}function Eu(x){if(!x)return null;let A;try{A=JSON.parse(x)}catch{return null}return typeof A!="object"||A===null||Array.isArray(A)?null:A}function rv(x){if(x!=null){if(Array.isArray(x)&&x.every(A=>typeof A=="string"))return x;throw new S0('"select" must be an array')}}function Bu(x){if(x!=null){if(Array.isArray(x)&&x.every(A=>typeof A=="string"))return x;throw new S0("invalid parameter, select must be an array")}}function Cu(x,A){let e=new Map;if(A){for(let[r,t]of A)e.set(t,r);return e}for(let r of x?.fields??[]){if(Ce(r))continue;let t=r.alias??r.name;e.set(t,t.toLowerCase())}return e}function du(x){let A=new Map;for(let e of x.fields){if(Ce(e))continue;let r=(e.alias??e.name).toLowerCase();A.set(e.name,r),e.alias&&A.set(e.alias,r)}return A}function uu(x){let A=new Set;for(let e of x.fields)Ce(e)||A.add((e.alias??e.name).toLowerCase());return A.add("stamp"),A}function Du(x,A,e){if(!e)return null;let r=Cu(x,A),t=new Set,i=[];for(let n of e){if(n==="stamp")continue;let F=r.get(n);F?t.add(F):i.push(n)}if(i.length>0)throw tv(i);return t}function pu(x,A){let e=du(x),r=[],t=[],i=!1;for(let n of A){if(n==="stamp"){i=!0,r.push("stamp");continue}let F=e.get(n);F?r.push(F):t.push(n)}if(t.length>0)throw tv(t);return i||r.unshift("stamp"),r}function bu(x,A){if(A===void 0)return;let e=uu(x),r=A.map(i=>i.toLowerCase()),t=r.filter(i=>!e.has(i));if(t.length>0)throw new S0(`unknown field name(s): ${t.join(",")}`);return r.includes("stamp")?r:["stamp",...r]}function mu(x,A){if(!A)return x;let e={};for(let[r,t]of Object.entries(x))(r==="stamp"||A.has(r))&&(e[r]=t);return e}function Ks(x,A){if(!A)return x;let e={};for(let r of A)e[r]=r in x?x[r]:null;return e}function tv(x){return new S0(`Fields [\`${x.join("`, `")}\`] do not exist in this container`)}function Rn(x,A){return x.containers.find(e=>e.name===A||e.alias===A)??null}async function hu(x){let A=x.ctx,e=BA(x.params[1]),r=Rn(A.model,e);if(!r)throw new S0("container does not exist");let t=await A.mapper.readContainer(e);if(!t)throw new EA(`no data for container "${e}"`);let i=gu(A,r,t,ju(x));return{status:200,body:nv(A,e,i)}}function ju(x){let A=x.query.json??{};return rv(A.select)}function gu(x,A,e,r){let t=Du(A,Nt(x.blueprint??null,A),r);return mu(e,t)}function nv(x,A,e){let r=x.model.byNameOrAlias(A);return r?w8(e,Nt(x.blueprint??null,r)):e}async function yu(x){let A=x.ctx,e=BA(x.params[1]),r=A.model.byNameOrAlias(e);if(!r)throw new EA(`unknown container "${e}"`);let t=await A.mapper.readContainer(e);if(!t)throw new EA(`unknown container "${e}"`);let i=x.query.json??{},n=Bu(i.select),F=bu(r,n);return{status:200,body:Ks(t,F)}}async function ku(x){let A=BA(x.params[1]);return iv(x,A,"canonical")}async function wu(x){let A=BA(x.params[1]);if(!x.ctx.model.byNameOrAlias(A))throw new EA(`unknown container "${A}"`);return iv(x,A,"legacy")}async function iv(x,A,e){let r=qu(x);if(!r)throw new S0("invalid or missing request body");Wr(r);let{stamp:t,...i}=r;if(e==="canonical"&&t!==void 0&&typeof t!="string")throw new S0("value(s) of field(s) stamp are not valid");let n=x.ctx;if(e==="canonical"&&!Rn(n.model,A))throw new S0("container does not exist");let F=n.model.byNameOrAlias(A);if(F?.kind==="histdata")throw new EA(`unknown container "${A}"`);let v=e==="canonical"?$u(n,F,i):Tu(F,i);try{let E=e==="canonical"&&t!==void 0?{...v,stamp:t}:v,u=await n.mapper.writeContainer(A,E);return u.devicePushable&&Y8(n,u.tag,u.data,u.stamp40),{status:204,body:""}}catch(E){throw _u(E,A,e,n,F)}}function _u(x,A,e,r,t){if(x instanceof $t){let i=x.field?Su(r,t,x.field,e):void 0;return e==="canonical"?i?new S0(`no permission to modify container field \`${i}\``):new S0(`no permission to modify container \`${A}\``):i?new Ln(`unknown field name(s): ${i}`):new Os(`no permission to modify '${A}'`)}return x}function Su(x,A,e,r){if(!A)return e;let t=A.fields.find(n=>n.name===e||n.name.toLowerCase()===e||(n.alias??n.name).toLowerCase()===e);return t?r==="legacy"?(t.alias??t.name).toLowerCase():Nt(x.blueprint??null,A)?.get(e)??t.alias??t.name:e}function $u(x,A,e){if(!A)return e;let r=Nt(x.blueprint??null,A),t=new Map;if(r)for(let[i,n]of r)t.set(n,i);else for(let i of A.fields){let n=i.alias??i.name;t.set(n,n.toLowerCase()),t.set(n.toLowerCase(),n.toLowerCase())}return sv(A,t,e,i=>new S0(`unknown field name(s): ${i}`))}function Tu(x,A){if(!x)return A;let e=new Map;for(let r of x.fields){let t=r.alias??r.name;e.set(t.toLowerCase(),t.toLowerCase()),e.set(t,t.toLowerCase())}return sv(x,e,A,r=>new Ln(`unknown field name(s): ${r}`))}var Pu=new Set(["stamp","stamp4","stamp8","datetime"]);function sv(x,A,e,r){let t=new Map(x.fields.map(v=>[(v.alias??v.name).toLowerCase(),v])),i={},n=[],F=[];for(let[v,E]of Object.entries(e)){let u=A.get(v);if(!u){n.push(v);continue}let D=t.get(u);if(D&&Pu.has(D.type)&&!(typeof E=="string"&&Gs(E))){F.push(v);continue}i[u]=E}if(n.length>0)throw r(n.join(","));if(F.length>0)throw new S0(`value(s) of field(s) ${F.join(",")} are not valid`);return i}function qu(x){let A=x.query.json,e=A!=null&&typeof A=="object"&&!Array.isArray(A)?A:void 0,r=x.request.body;if(!r)return e?{...e}:null;let t=Nu(r);if(t===void 0)throw new S0("request supplied data which is not json formatted");return typeof t!="object"||t===null||Array.isArray(t)?null:{...e,...t}}function Nu(x){try{return JSON.parse(x)}catch{return}}var av="x-mt-backfill",ov="pending";async function zs(x,A,e){let r=x.push?.backfill;if(!(!r||A===void 0||A===null||e===null))try{return await r.call(x.push,{fromMs:e})==="pending"?{[av]:ov}:void 0}catch(t){x.logger?.error("[localApi] historic backfill check failed:",t);return}}var Iu=1e3,Dn=1e3,Fv="20000101",vv="*";async function Mu(x){let A=x.query.json??{};Cv(A,["from","until","count","offset","select"]),Wr(A);let e=x.ctx,r=BA(x.params[1]),{mapperSelect:t,order:i}=cv(e,r,A.select);fv(e,r);let n=Pn(A.from,Fv,"from"),F=Pn(A.until,vv,"until");Ev(n,F),F!==null&&(F=Ru(F));let v=Ou(A.count),E=Bv(A.offset),u=await zs(e,A.from,n);return{status:200,body:(await e.mapper.readTimeseries(r,{fromMs:n,untilMs:F,count:v,offset:E,select:t})).map(m=>lv(x,e,r,Ks(m,i))),headers:u}}async function Lu(x){let A=x.query.json??{};Cv(A,["from","until","offset","select"]),Wr(A);let e=x.ctx,r=BA(x.params[1]),t=x.params[2],{mapperSelect:i,order:n}=cv(e,r,A.select);fv(e,r);let F=Pn(A.from,Fv,"from"),v=Pn(A.until,vv,"until");Ev(F,v);let E=Bv(A.offset),u=await zs(e,A.from,F),m=(await e.mapper.readTimeseries(r,{fromMs:F,untilMs:v,count:t==="youngest"?-1:1,offset:E,select:i}))[0];return m?{status:200,body:lv(x,e,r,Ks(m,n)),headers:u}:{status:204,body:JSON.stringify("no timeseries recordData found"),headers:u}}function lv(x,A,e,r){return x.apiVersion==="1"?r:nv(A,e,r)}function cv(x,A,e){let r=rv(e);if(!r)return{mapperSelect:void 0,order:null};let t=Rn(x.model,A);if(!t)return{mapperSelect:r,order:null};let i=pu(t,r),n=i.filter(F=>F!=="stamp");return{mapperSelect:n.length>0?n:void 0,order:i}}function fv(x,A){if(!Rn(x.model,A))throw new S0("timeseries does not exist")}function Pn(x,A,e){let t=x==null||typeof x=="string"&&x.trim()===""?A:String(x);if(t==="*")return null;try{return Vr(t)}catch{throw new S0(`attribute '${e}' is not valid`)}}function Ev(x,A){if(x!==null&&A!==null&&x>A)throw new S0('E_BAD_REQUEST "from" value must be older than "until"')}function Ru(x){let A=z0.msToStamp40(x);return z0.stamp40ToMS(A)>=x&&(A-=1),z0.stamp40ToMS(A)}function Ou(x){if(x==null||x==="")return Iu;let A=Number(x);if(!Number.isInteger(A))throw new S0('"count" must be an integer');if(A===0)throw new S0("`count` cannot be 0");if(A<-Dn)throw new S0(`"count" must be greater than or equal to -${Dn}`);if(A>Dn)throw new S0(`"count" must be less than or equal to ${Dn}`);return A}function Bv(x){if(x==null||x==="")return 0;let A=Number(x);if(!Number.isInteger(A))throw new S0('"offset" must be an integer');if(A<0)throw new S0('"offset" must be greater than or equal to 0');return A}function Cv(x,A){for(let e of Object.keys(x))if(!A.includes(e))throw new S0(`"${e}" is not allowed`)}var Gu=1e5,Uu="20000101",Hu="*";async function Ju(x){let e=`histdata${x.params[1]?Number(x.params[1]):0}`,r=x.ctx,t=r.model.byNameOrAlias(e);if(!t)throw new EA(`unknown container "${e}"`);let i=x.query.json??{};Wr(i);let{fromMs:n,untilMs:F}=Vu(i);Wu(n,F);let v=Xu(i),E=Yu(i),u=dv(t,i.select)??["stamp"],D=qn(i.from)?await zs(r,i.from,n):void 0,m=u.filter(S=>S!=="stamp");return{status:200,body:(await r.mapper.readTimeseries(e,{fromMs:n,untilMs:F,count:v,offset:E,select:m.length>0?m:void 0})).map(S=>u.map(P=>P==="stamp"?S.stamp:S[P]??null)),headers:D}}async function Ku(x){let e=`histdata${x.params[1]?Number(x.params[1]):0}`,r=x.params[2],t=x.ctx,i=t.model.byNameOrAlias(e);if(!i)throw new EA(`unknown container "${e}"`);let n=x.query.json??{};Wr(n);let F=dv(i,n.select)??["stamp"],v=zu(n),E=F.filter(m=>m!=="stamp"),D=(await t.mapper.readTimeseries(e,{fromMs:null,untilMs:v??null,count:v!==void 0||r==="youngest"?-1:1,select:E.length>0?E:void 0}))[0];return D?{status:200,body:[F.map(m=>m==="stamp"?D.stamp:D[m]??null)]}:{status:200,body:[]}}function zu(x){if(!(!qn(x.until)||x.until==="*"))try{return Vr(String(x.until))??void 0}catch{throw new S0("from or until value invalid")}}function Vu(x){let A=qn(x.from),e=qn(x.until);if((!A||!e)&&!Vs(x.count))throw new S0("missing or invalid parameters (from and until and/or count)");return{fromMs:_F(A?x.from:Uu),untilMs:_F(e?x.until:Hu)}}function Wu(x,A){if(x!==null&&A!==null&&x>A)throw new S0('"from" value must be older than "until"')}function _F(x){let A=String(x);try{return Vr(A)}catch{throw new S0(`invalid stamp "${A}"`)}}function Xu(x){if(!Vs(x.count))return Gu;if(typeof x.count!="number")throw new S0("invalid parameter count");return x.count}function Yu(x){let A=x.offset;if(A==null||A==="")return 0;if(typeof A!="number"||A<0)throw new S0("invalid parameter offset");return A}function dv(x,A){if(A==null)return;if(!Array.isArray(A))throw new S0("invalid parameter, select must be an array");let e=A.map(F=>String(F).toLowerCase()),r=e.filter(F=>F.includes(" "));if(r.length>0)throw new S0(`aggregation suffix not allowed: ${r.join(",")}`);let t=e.includes("stamp")?e:["stamp",...e],i=new Set(x.fields.filter(F=>!Ce(F)).map(F=>(F.alias??F.name).toLowerCase()));i.add("stamp");let n=t.filter(F=>!i.has(F));if(n.length>0)throw new S0(`invalid channel(s) ${n.join(",")}`);return t}function Vs(x){return!!x}function qn(x){return typeof x=="string"?x.trim().length>0:Vs(x)}var Qu="device_id";function Zu(x){return async A=>(await On(A),{status:200,body:await AD(A.ctx,x)})}async function On(x){let A=BA(x.params[0]),e=await xD(x.ctx);if(!e||e.toLowerCase()!==A.toLowerCase())throw new EA(`unknown device "${A}"`)}async function xD(x){return x.deviceId||x.siteInfo.device?.device_id||x.storage.getMetadataValue(Qu)}async function AD(x,A){let e=await x.storage.getRowForTag(A);if(!e||!e.data)return{};let r=It(e.data);return r?(typeof r.pipAppVer=="number"&&(r.pipAppVer=`${r.pipAppVer}.0.0`),r.stamp=Kr(z0.stamp40ToMS(QA(e.stamp))),r):{}}function Ws(x,A,e){let t=(x.tagMutexTails.get(A)??Promise.resolve()).then(e);return x.tagMutexTails.set(A,t.catch(()=>{})),t}function eD(x){return async A=>{await On(A);let e=nD(A.request.body??null);if(!e)throw new S0("invalid or missing request body");return Ws(A.session,x,async()=>{let r=await A.ctx.storage.getRowForTag(x),t=r?.data?It(r.data)??{}:{};return await Xs(A.ctx,x,r,{...t,...e}),{status:204,body:""}})}}function rD(x){return async A=>(await On(A),Ws(A.session,x,async()=>{let e=await A.ctx.storage.getRowForTag(x);return!e||!e.data?{status:204,body:""}:(await Xs(A.ctx,x,e,{}),{status:204,body:""})}))}function tD(x){return async A=>{await On(A);let e=BA(A.params[1]);return Ws(A.session,x,async()=>{let r=await A.ctx.storage.getRowForTag(x);if(!r||!r.data)return{status:204,body:""};let t=It(r.data)??{},i=e.toLowerCase();for(let n of Object.keys(t))n.toLowerCase()===i&&delete t[n];return await Xs(A.ctx,x,r,t),{status:204,body:""}})}}function nD(x){if(!x)return null;let A;try{A=JSON.parse(x)}catch{return null}return typeof A!="object"||A===null||Array.isArray(A)?null:A}async function Xs(x,A,e,r){let t=Q8(JSON.stringify(r),e?.data?.length??0),i=z0.msToStamp40((x.timeSource??qt).nowMs());await x.storage.replaceUtoRow({tag:A,stamp:fA(i),flags:e?.flags??0,site_related:e?.site_related??0,data:t}),Y8(x,A,t,i)}var uv={"content-type":"application/json"},iD=[{method:"GET",pattern:/^\/api\/1\/me$/,handler:iu,checksUid:!1},{method:"GET",pattern:/^\/api\/[12]\/sites\/([^/]+)$/,handler:tu,checksUid:!0},{method:"GET",pattern:/^\/api\/[12]\/sites\/([^/]+)\/blueprint$/,handler:nu,checksUid:!0},{method:"POST",pattern:/^\/api\/1\/sites\/([^/]+)\/cn-set-lifecycle$/,handler:vu,checksUid:!0},{method:"GET",pattern:/^\/api\/[12]\/sites\/([^/]+)\/timeseries\/([^/]+)\/(oldest|youngest)$/,handler:Lu,checksUid:!0},{method:"GET",pattern:/^\/api\/[12]\/sites\/([^/]+)\/timeseries\/([^/]+)$/,handler:Mu,checksUid:!0},{method:"GET",pattern:/^\/api\/[12]\/sites\/([^/]+)\/containers\/([^/]+)$/,handler:hu,checksUid:!0},{method:"PUT",pattern:/^\/api\/[12]\/sites\/([^/]+)\/containers\/([^/]+)$/,handler:ku,checksUid:!0},{method:"GET",pattern:/^\/api\/1\/sites\/([^/]+)\/histdata(\d)?\/(oldest|youngest)$/,handler:Ku,checksUid:!0},{method:"GET",pattern:/^\/api\/1\/sites\/([^/]+)\/histdata(\d)?$/,handler:Ju,checksUid:!0},{method:"GET",pattern:/^\/api\/1\/sites\/([^/]+)\/(config[0-9a-c]|config[A-C])$/,handler:yu,checksUid:!0},{method:"PUT",pattern:/^\/api\/1\/sites\/([^/]+)\/(config[0-9a-c]|config[A-C])$/,handler:wu,checksUid:!0},...sD()];function sD(){let x={"sys-otp":26432,"sys-flash":26433,"app-otp":26434,"app-flash":26435,"app-state":26436,"sys-info":26437,"app-info":26438},A={"sys-flash":26433,"app-flash":26435},e=Object.entries(x).map(([t,i])=>({method:"GET",pattern:new RegExp(`^/api/1/devices/([^/]+)/${t}$`),handler:Zu(i),checksUid:!1})),r=Object.entries(A).flatMap(([t,i])=>[{method:"PUT",pattern:new RegExp(`^/api/1/devices/([^/]+)/${t}$`),handler:eD(i),checksUid:!1},{method:"DELETE",pattern:new RegExp(`^/api/1/devices/([^/]+)/${t}$`),handler:rD(i),checksUid:!1},{method:"DELETE",pattern:new RegExp(`^/api/1/devices/([^/]+)/${t}/([^/]+)$`),handler:tD(i),checksUid:!1}]);return[...e,...r]}var aD=/^\/api\/([12])\/customers\/([^/]+)\/sites\/(.*)$/;function oD(x){let A=Us();return e=>Dv(x,e,A)}async function Dv(x,A,e=Us()){try{let[r,t]=lD(A.path),i=cD(t),n=vD(r,x);if(n===null)return or(404,"E_NOT_FOUND","unknown customer");let F=A.method.toUpperCase();for(let v of iD){if(v.method!==F)continue;let E=v.pattern.exec(n);if(!E)continue;let u=E.slice(1);if(v.checksUid&&!FD(x,u[0]))return or(404,"E_NOT_FOUND","unknown site");let D=/^\/api\/([12])\//.exec(n)?.[1]??"1",m=await v.handler({request:A,params:u,query:i,ctx:x,session:e,apiVersion:D});return BD(m)}return or(404,"E_NOT_FOUND","not found")}catch(r){return bv(r)}}function FD(x,A){return x.allowAnySiteUid===!0||A!==void 0&&BA(A)===x.siteUid}function vD(x,A){let e=aD.exec(x);if(!e)return x;let r=BA(e[2]).toLowerCase();return(A.siteInfo.customer_id??"").toLowerCase()===r||(A.siteInfo.customer_uid??"").toLowerCase()===r?`/api/${e[1]}/sites/${e[3]}`:null}function lD(x){let A=x.indexOf("?");return A<0?[x,""]:[x.slice(0,A),x.slice(A+1)]}function cD(x){let A={params:{}};if(!x)return A;for(let e of x.split("&"))e&&fD(A,e);return A}function fD(x,A){let e=A.indexOf("="),r=BA(e<0?A:A.slice(0,e)),t=e<0?"":BA(A.slice(e+1));r==="json"?x.json=ED(t):x.params[r]=t}function ED(x){try{return JSON.parse(x)}catch{throw new S0("request supplied data which is not json formatted ")}}function BD(x){let A=typeof x.body=="string"?x.body:JSON.stringify(x.body);return{status:x.status,headers:{...uv,...x.headers},body:A}}function pv(x,A){return{status:x,headers:{...uv},body:JSON.stringify(A)}}function bv(x){return x instanceof S0||x instanceof Ms||x instanceof ws?or(400,"E_BAD_REQUEST",x.message):x instanceof Ln||x instanceof $t?or(403,"E_FORBIDDEN",x.message):x instanceof Os?or(405,"E_METHOD_NOT_ALLOWED",x.message):x instanceof EA||x instanceof Me?or(404,"E_NOT_FOUND",x.message):pv(500,{err:x instanceof Error?x.message:String(x)})}function or(x,A,e){return pv(x,{err:`${A} ${e}`})}function CD(x,A){let e=A.apmId??"local",r=A.version??1;return{uid:A.siteUid,name:A.name??A.siteUid,customer_id:e,customer_uid:e,app:{apmid:e,version:String(r)},device:{device_id:A.deviceId,lifecycle_flags:{}},lifecycle_flags:{},containers:x.containers.map(t=>({name:t.name,alias:t.alias??t.name,kind:t.kind}))}}});var Ab={};Bf(Ab,{default:()=>Dc,deviceExitCode:()=>uc,program:()=>DA});module.exports=Cf(Ab);var J0=require("commander"),Qt=U0(require("chalk"));var gi={name:"@microtronics/studio-cli",version:"1.2.1",description:"Microtronics Studio CLI Tool",main:"./out/api.js",typings:"./out/studio-cli.d.ts",bin:{"studio-cli":"studio-cli"},publishConfig:{access:"public"},scripts:{compile:"npm run build:registryApiTypings && tsc","build:cli":"node build.mjs","build:exe":"node build-exe.mjs",api:"api-extractor run --local --verbose",build:"npm run compile && npm run api && npm run build:cli","watch:build":"npm run compile -- --watch",test:"cross-env STUDIO_ENV=lucky mocha","test-ci":"cross-env STUDIO_ENV=lucky mocha --reporter mocha-junit-reporter","watch:test":"npm run test -- --watch",prepublishOnly:"npm run build","build:registryApiTypings":"npx openapi-typescript https://api.registry.lucky.ci.microtronics.com/v1/openapi.yaml -o ./src/typings/registry.ts"},author:"Microtronics",license:"ISC",dependencies:{"@gera2ld/tarjs":"^0.3.1",ajv:"^8.17.1","ajv-formats":"^3.0.1","ajv-keywords":"^5.1.0",chalk:"^5.4.1",commander:"^12.1.0","cross-fetch":"^4.0.0","deepmerge-ts":"^7.1.5",dotenv:"^16.4.7","file-type-checker":"^1.1.2",glob:"^11.0.1","iconv-lite":"^0.6.3","image-dimensions":"^2.3.0",ini:"^5.0.0",minimatch:"^10.0.1","openapi-fetch":"^0.13.0",pako:"^2.1.0",semver:"^7.7.2","sql.js":"^1.14.2","tinytar-fix":"^0.1.1","update-notifier":"^7.3.1",usb:"^2.14.0",uuid:"^9.0.1","vscode-uri":"^3.0.8",yaml:"^2.6.1"},engines:{node:">= 22"},devDependencies:{"@microsoft/api-extractor":"^7.47.11","@microtronics/device-master":"bitbucket:microtronics-core/device-master#v4.1.0","@types/chai":"^4.3.6","@types/chai-as-promised":"^7.1.5","@types/ini":"^4.1.1","@types/mocha":"^10.0.9","@types/node":"^22.9.1","@types/semver":"^7.5.6","@types/sql.js":"^1.4.11","@types/update-notifier":"^6.0.8","@types/vscode":"^1.86.2","@yao-pkg/pkg":"^6.22.0",chai:"^4.3.8","chai-as-promised":"^7.1.2","cross-env":"^7.0.3",esbuild:"^0.27.3","extract-zip":"^2.0.1",mocha:"^10.8.2","mocha-junit-reporter":"^2.2.1","openapi-typescript":"^7.6.0","pawncc-wasm":"bitbucket:microtronics-core/pawncc-wasm#v1.1.1",resedit:"^3.0.2",tar:"^7.5.7","ts-node":"^10.9.2",typescript:"^5.6.3"},mocha:{require:["ts-node/register"],"watch-files":"src/**",spec:"./test/**/*.spec.ts",recursive:!0},files:["out/api.js","out/studio-cli.d.ts","dist/main.js","dist/studio-cli.d.ts","studio-cli","CHANGELOG.md"]};var yA=U0(require("node:fs/promises"));var bt=require("vscode-uri"),Ya=require("glob"),le={readFile(x){return yA.default.readFile(x.fsPath)},async rm(x){if(await this.stat(x))return yA.default.rm(x.fsPath,{recursive:!0})},async stat(x){try{let A=await yA.default.stat(x.fsPath),e=(A.isDirectory()?2:0)|(A.isFile()?1:0)|(A.isSymbolicLink()?64:0);return{ctime:A.ctimeMs,mtime:A.mtimeMs,permissions:void 0,size:A.size,type:e}}catch{return null}},async writeFile(x,A){typeof A=="string"&&(A=new TextEncoder().encode(A));let e=bt.Utils.dirname(x);return await yA.default.mkdir(e.fsPath,{recursive:!0}),yA.default.writeFile(x.fsPath,A,{flag:"w"})},async findFiles(x,A,e){let r={ignore:e,nodir:!0,absolute:!0,dot:!0,cwd:x.fsPath};return(await(0,Ya.glob)(A,r)).map(i=>{let n=i.replace(/\\/g,"/");return bt.URI.parse(`file:///${n}`)})},async copy(x,A){let e=await yA.default.stat(x.fsPath);return await yA.default.mkdir(bt.Utils.dirname(A).fsPath,{recursive:!0}),e.isDirectory()?yA.default.cp(x.fsPath,A.fsPath,{force:!0,recursive:!0}):yA.default.copyFile(x.fsPath,A.fsPath)},async mkdir(x){await yA.default.mkdir(x.fsPath,{recursive:!0})}};var xt=require("vscode-uri");var ue=require("vscode-uri");var qr=require("vscode-uri");var uf=new Uint32Array([0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117]);function sn(x,A=0){let e=~~A^-1;for(let r=0;r<x.length;r++)e=e>>>8^uf[(e^x[r])&255];return(e^-1)>>>0}var cb=new Uint8Array([0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64,0,193,129,64,1,192,128,65,0,193,129,64,1,192,128,65,1,192,128,65,0,193,129,64]),fb=new Uint8Array([0,192,193,1,195,3,2,194,198,6,7,199,5,197,196,4,204,12,13,205,15,207,206,14,10,202,203,11,201,9,8,200,216,24,25,217,27,219,218,26,30,222,223,31,221,29,28,220,20,212,213,21,215,23,22,214,210,18,19,211,17,209,208,16,240,48,49,241,51,243,242,50,54,246,247,55,245,53,52,244,60,252,253,61,255,63,62,254,250,58,59,251,57,249,248,56,40,232,233,41,235,43,42,234,238,46,47,239,45,237,236,44,228,36,37,229,39,231,230,38,34,226,227,35,225,33,32,224,160,96,97,161,99,163,162,98,102,166,167,103,165,101,100,164,108,172,173,109,175,111,110,174,170,106,107,171,105,169,168,104,120,184,185,121,187,123,122,186,190,126,127,191,125,189,188,124,180,116,117,181,119,183,182,118,114,178,179,115,177,113,112,176,80,144,145,81,147,83,82,146,150,86,87,151,85,149,148,84,156,92,93,157,95,159,158,94,90,154,155,91,153,89,88,152,136,72,73,137,75,139,138,74,78,142,143,79,141,77,76,140,68,132,133,69,135,71,70,134,130,66,67,131,65,129,128,64]);var j0;(w=>{function x(j,S){let[P,N]=S,{line:R,col:O}=j.linePos(P);return{line:Number(R)-1,startCharacter:O-1,endCharacter:O+(N-P)}}w.yamlRangeToLineInformation=x;let A=new TextEncoder;function e(j){return sn(A.encode(j)).toString(16)}w.generateHashForLibraryName=e;function r(j){return sn(A.encode(j)).toString(16)}w.generateHashForFilePath=r;function t(j){return sn(j).toString(16).toUpperCase().padStart(8,"0")}w.generateCRC32ForFileContent=t;function i(j){try{let S=null;return j?.type==="Buffer"?S=Uint8Array.from(j.data):S=j,new TextDecoder("utf8").decode(S)}catch{return""}}w.convertBlobToString=i;function n(j=""){return j.replace(/\r\n|\n\r|\r/g,`
|
|
2199
2199
|
`)}w.normalizeLF=n;function F(j){try{let S=i(j);return n(S).split(`
|
|
2200
2200
|
`)}catch{return[]}}w.convertBlobToStringArray=F,w.isNumeric=j=>!Array.isArray(j)&&j-parseFloat(j)+1>=0;function E(j){let S="",P=j.byteLength;for(let N=0;N<P;N++)S+=String.fromCharCode(j[N]);return btoa(S)}w.bufferToBase64=E;function u(j,S){let P=`${j}`.match(/\{\d*(index)(\+\d*)?}/g);if(P){let N=j;return P.forEach(R=>{let O=R.replace(/\+0$/,""),e0=O.match(/index/)?.[0];if(e0){let I=O.slice(1,-1).split(e0)[1],k=parseInt(I)||0;N=N.replace(R,`${S+k}`)}}),N}else return j}w.patchValueWithArrayInfo=u;let D={};function m(j,S,P){let N=D[j];N&&clearTimeout(N.timer),D[j]={timer:setTimeout(()=>{delete D[j],P()},S),handler:P}}w.defer=m})(j0||={});var Bo=require("image-dimensions"),Co=require("file-type-checker");var Ib=require("cross-fetch/polyfill"),co=U0(require("openapi-fetch"));var Pe=require("vscode-uri");var px=require("vscode-uri");var KA=U0(require("semver"));var Rx="dist/",Qa="dde/",yi="dlo/",ki=".studio/",Za="dfiles/",t0;(v=>{v.fileNames={projectSettings:"studio.json",mainAmx:"main.amx",mainAmxReport:"main.xml",ddeXml:"dde.xml",ddeOpenApi:"main.yaml",historyJson:"history.json",mainDDE:"main.dde",autoInc:"auto.inc",defaultInc:"default.inc",autoUplinkInc:"app-uplink.inc",autoDdeInc:"X-dde.inc",mainDdeInc:"main-dde.inc",autoLocalDataInc:"auto-local-data.inc",legacyAutoInc:"legacy-auto.inc",legacyAutoDdeInc:"legacy-auto-dde.inc",legacyAutoUplinkInc:"legacy-auto-uplink.inc",reportTemplate:"mdn_report_template.json",dloCfg:"dlo.cfg",devMirror:"mirror.json",devDeviceLog:"device.jsonl"};let A=`${ki}auto/`,e=`${ki}dev/`,r=`${A}dlo/`,t=`${A}dde/`;v.filePaths={studio:{initFile:`${A}.init`,auto:{path:A,dlo:{path:r,autoInc:`${r}${v.fileNames.autoInc}`,defaultInc:`${r}${v.fileNames.defaultInc}`,autoUplinkInc:`${r}${v.fileNames.autoUplinkInc}`,autoLocalDataInc:`${r}${v.fileNames.autoLocalDataInc}`,autoDdeInc:`${r}${v.fileNames.autoDdeInc}`,mainDdeInc:`${r}${v.fileNames.mainDdeInc}`,legacyAutoInc:`${r}${v.fileNames.legacyAutoInc}`,legacyAutoDdeInc:`${r}${v.fileNames.legacyAutoDdeInc}`,legacyAutoUplinkInc:`${r}${v.fileNames.legacyAutoUplinkInc}`,cfg:`${r}${v.fileNames.dloCfg}`},dde:{path:t,historyJson:`${t}${v.fileNames.historyJson}`}},libdeps:`${ki}libdeps/`,dev:{path:e,mirror:`${e}${v.fileNames.devMirror}`,deviceLog:`${e}${v.fileNames.devDeviceLog}`}},dist:{path:Rx,dloPath:`${Rx}dlo/`,mainAmxPath:`${Rx}dlo/${v.fileNames.mainAmx}`,mainAmxReportPath:`${Rx}dlo/${v.fileNames.mainAmxReport}`,ddeXmlPath:`${Rx}dde/${v.fileNames.ddeXml}`,ddeApiPath:`${Rx}api/`,ddeApi:`${Rx}api/${v.fileNames.ddeOpenApi}`,historyJson:`${Rx}dde/${v.fileNames.historyJson}`,povPath:`${Rx}pov`,povDetailsPath:`${Rx}pov/details`,dfilesPath:`${Rx}dfiles`,dfilesProperties:`${Rx}dfiles/properties.json`,bloPath:`${Rx}blo`,reportTemplate:`${Rx}/${v.fileNames.reportTemplate}`,definesTs:`${Rx}defines.ts`,definesAppTs:`${Rx}defines.app.ts`},dlo:{path:yi,mainDLO:`${yi}main.dlo`,mainINI:`${yi}main.ini`},dde:{path:Qa,mainDDE:`${Qa}main.dde`},dfiles:{path:Za,mainDFILES:`${Za}/main.dfiles`},appIni:"app.ini",defaultsIni:"defaults.ini"},v.readme=E=>`# ${E} README
|
|
2201
2201
|
|