@thatopen/services 0.17.0 β 0.18.0
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/built-in/index.d.ts +1043 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +7 -6
- package/docs/builtin/paths.json +16 -0
- package/package.json +2 -1
- package/src/built-in/GISManager/example.ts +326 -0
- package/src/built-in/UIManager/src/app/examples/Sidebar/example.ts +5 -2
- package/src/built-in/UIManager/src/gis-panel/example.ts +163 -0
- package/src/built-in/UIManager/src/gis-properties-panel/example.ts +168 -0
- package/src/built-in/UIManager/src/map-panel/example.ts +189 -0
- package/src/built-in/UIManager/src/models-list/example.ts +61 -2
- package/src/built-in/UIManager/src/settings-panel/example.ts +5 -3
- package/src/built-in/UIManager/src/viewer-toolbar/example.ts +25 -1
- package/src/built-in/index.ts +1051 -0
package/dist/index.cjs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use strict";var St=Object.defineProperty;var Xe=n=>{throw TypeError(n)};var Ot=(n,e,t)=>e in n?St(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var E=(n,e,t)=>Ot(n,typeof e!="symbol"?e+"":e,t),_e=(n,e,t)=>e.has(n)||Xe("Cannot "+t);var u=(n,e,t)=>(_e(n,e,"read from private field"),t?t.call(n):e.get(n)),_=(n,e,t)=>e.has(n)?Xe("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(n):e.set(n,t),T=(n,e,t,s)=>(_e(n,e,"write to private field"),s?s.call(n,t):e.set(n,t),t),a=(n,e,t)=>(_e(n,e,"access private method"),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const P=Object.create(null);P.open="0";P.close="1";P.ping="2";P.pong="3";P.message="4";P.upgrade="5";P.noop="6";const ce=Object.create(null);Object.keys(P).forEach(n=>{ce[P[n]]=n});const Se={type:"error",data:"parser error"},nt=typeof Blob=="function"||typeof Blob<"u"&&Object.prototype.toString.call(Blob)==="[object BlobConstructor]",rt=typeof ArrayBuffer=="function",it=n=>typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView(n):n&&n.buffer instanceof ArrayBuffer,He=({type:n,data:e},t,s)=>nt&&e instanceof Blob?t?s(e):ze(e,s):rt&&(e instanceof ArrayBuffer||it(e))?t?s(e):ze(new Blob([e]),s):s(P[n]+(e||"")),ze=(n,e)=>{const t=new FileReader;return t.onload=function(){const s=t.result.split(",")[1];e("b"+(s||""))},t.readAsDataURL(n)};function Qe(n){return n instanceof Uint8Array?n:n instanceof ArrayBuffer?new Uint8Array(n):new Uint8Array(n.buffer,n.byteOffset,n.byteLength)}let be;function Ct(n,e){if(nt&&n.data instanceof Blob)return n.data.arrayBuffer().then(Qe).then(e);if(rt&&(n.data instanceof ArrayBuffer||it(n.data)))return e(Qe(n.data));He(n,!1,t=>{be||(be=new TextEncoder),e(be.encode(t))})}const Ze="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",ee=typeof Uint8Array>"u"?[]:new Uint8Array(256);for(let n=0;n<Ze.length;n++)ee[Ze.charCodeAt(n)]=n;const Rt=n=>{let e=n.length*.75,t=n.length,s,r=0,i,o,h,f;n[n.length-1]==="="&&(e--,n[n.length-2]==="="&&e--);const m=new ArrayBuffer(e),y=new Uint8Array(m);for(s=0;s<t;s+=4)i=ee[n.charCodeAt(s)],o=ee[n.charCodeAt(s+1)],h=ee[n.charCodeAt(s+2)],f=ee[n.charCodeAt(s+3)],y[r++]=i<<2|o>>4,y[r++]=(o&15)<<4|h>>2,y[r++]=(h&3)<<6|f&63;return m},$t=typeof ArrayBuffer=="function",je=(n,e)=>{if(typeof n!="string")return{type:"message",data:ot(n,e)};const t=n.charAt(0);return t==="b"?{type:"message",data:Nt(n.substring(1),e)}:ce[t]?n.length>1?{type:ce[t],data:n.substring(1)}:{type:ce[t]}:Se},Nt=(n,e)=>{if($t){const t=Rt(n);return ot(t,e)}else return{base64:!0,data:n}},ot=(n,e)=>{switch(e){case"blob":return n instanceof Blob?n:new Blob([n]);case"arraybuffer":default:return n instanceof ArrayBuffer?n:n.buffer}},at="",Pt=(n,e)=>{const t=n.length,s=new Array(t);let r=0;n.forEach((i,o)=>{He(i,!1,h=>{s[o]=h,++r===t&&e(s.join(at))})})},Bt=(n,e)=>{const t=n.split(at),s=[];for(let r=0;r<t.length;r++){const i=je(t[r],e);if(s.push(i),i.type==="error")break}return s};function xt(){return new TransformStream({transform(n,e){Ct(n,t=>{const s=t.length;let r;if(s<126)r=new Uint8Array(1),new DataView(r.buffer).setUint8(0,s);else if(s<65536){r=new Uint8Array(3);const i=new DataView(r.buffer);i.setUint8(0,126),i.setUint16(1,s)}else{r=new Uint8Array(9);const i=new DataView(r.buffer);i.setUint8(0,127),i.setBigUint64(1,BigInt(s))}n.data&&typeof n.data!="string"&&(r[0]|=128),e.enqueue(r),e.enqueue(t)})}})}let Te;function oe(n){return n.reduce((e,t)=>e+t.length,0)}function ae(n,e){if(n[0].length===e)return n.shift();const t=new Uint8Array(e);let s=0;for(let r=0;r<e;r++)t[r]=n[0][s++],s===n[0].length&&(n.shift(),s=0);return n.length&&s<n[0].length&&(n[0]=n[0].slice(s)),t}function It(n,e){Te||(Te=new TextDecoder);const t=[];let s=0,r=-1,i=!1;return new TransformStream({transform(o,h){for(t.push(o);;){if(s===0){if(oe(t)<1)break;const f=ae(t,1);i=(f[0]&128)===128,r=f[0]&127,r<126?s=3:r===126?s=1:s=2}else if(s===1){if(oe(t)<2)break;const f=ae(t,2);r=new DataView(f.buffer,f.byteOffset,f.length).getUint16(0),s=3}else if(s===2){if(oe(t)<8)break;const f=ae(t,8),m=new DataView(f.buffer,f.byteOffset,f.length),y=m.getUint32(0);if(y>Math.pow(2,21)-1){h.enqueue(Se);break}r=y*Math.pow(2,32)+m.getUint32(4),s=3}else{if(oe(t)<r)break;const f=ae(t,r);h.enqueue(je(i?f:Te.decode(f),e)),s=0}if(r===0||r>n){h.enqueue(Se);break}}}})}const ct=4;function w(n){if(n)return Lt(n)}function Lt(n){for(var e in w.prototype)n[e]=w.prototype[e];return n}w.prototype.on=w.prototype.addEventListener=function(n,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+n]=this._callbacks["$"+n]||[]).push(e),this};w.prototype.once=function(n,e){function t(){this.off(n,t),e.apply(this,arguments)}return t.fn=e,this.on(n,t),this};w.prototype.off=w.prototype.removeListener=w.prototype.removeAllListeners=w.prototype.removeEventListener=function(n,e){if(this._callbacks=this._callbacks||{},arguments.length==0)return this._callbacks={},this;var t=this._callbacks["$"+n];if(!t)return this;if(arguments.length==1)return delete this._callbacks["$"+n],this;for(var s,r=0;r<t.length;r++)if(s=t[r],s===e||s.fn===e){t.splice(r,1);break}return t.length===0&&delete this._callbacks["$"+n],this};w.prototype.emit=function(n){this._callbacks=this._callbacks||{};for(var e=new Array(arguments.length-1),t=this._callbacks["$"+n],s=1;s<arguments.length;s++)e[s-1]=arguments[s];if(t){t=t.slice(0);for(var s=0,r=t.length;s<r;++s)t[s].apply(this,e)}return this};w.prototype.emitReserved=w.prototype.emit;w.prototype.listeners=function(n){return this._callbacks=this._callbacks||{},this._callbacks["$"+n]||[]};w.prototype.hasListeners=function(n){return!!this.listeners(n).length};const me=typeof Promise=="function"&&typeof Promise.resolve=="function"?e=>Promise.resolve().then(e):(e,t)=>t(e,0),S=typeof self<"u"?self:typeof window<"u"?window:Function("return this")(),qt="arraybuffer";function ht(n,...e){return e.reduce((t,s)=>(n.hasOwnProperty(s)&&(t[s]=n[s]),t),{})}const Ut=S.setTimeout,Dt=S.clearTimeout;function ge(n,e){e.useNativeTimers?(n.setTimeoutFn=Ut.bind(S),n.clearTimeoutFn=Dt.bind(S)):(n.setTimeoutFn=S.setTimeout.bind(S),n.clearTimeoutFn=S.clearTimeout.bind(S))}const Ft=1.33;function Mt(n){return typeof n=="string"?Ht(n):Math.ceil((n.byteLength||n.size)*Ft)}function Ht(n){let e=0,t=0;for(let s=0,r=n.length;s<r;s++)e=n.charCodeAt(s),e<128?t+=1:e<2048?t+=2:e<55296||e>=57344?t+=3:(s++,t+=4);return t}function ut(){return Date.now().toString(36).substring(3)+Math.random().toString(36).substring(2,5)}function jt(n){let e="";for(let t in n)n.hasOwnProperty(t)&&(e.length&&(e+="&"),e+=encodeURIComponent(t)+"="+encodeURIComponent(n[t]));return e}function Vt(n){let e={},t=n.split("&");for(let s=0,r=t.length;s<r;s++){let i=t[s].split("=");e[decodeURIComponent(i[0])]=decodeURIComponent(i[1])}return e}class Jt extends Error{constructor(e,t,s){super(e),this.description=t,this.context=s,this.type="TransportError"}}class Ve extends w{constructor(e){super(),this.writable=!1,ge(this,e),this.opts=e,this.query=e.query,this.socket=e.socket,this.supportsBinary=!e.forceBase64}onError(e,t,s){return super.emitReserved("error",new Jt(e,t,s)),this}open(){return this.readyState="opening",this.doOpen(),this}close(){return(this.readyState==="opening"||this.readyState==="open")&&(this.doClose(),this.onClose()),this}send(e){this.readyState==="open"&&this.write(e)}onOpen(){this.readyState="open",this.writable=!0,super.emitReserved("open")}onData(e){const t=je(e,this.socket.binaryType);this.onPacket(t)}onPacket(e){super.emitReserved("packet",e)}onClose(e){this.readyState="closed",super.emitReserved("close",e)}pause(e){}createUri(e,t={}){return e+"://"+this._hostname()+this._port()+this.opts.path+this._query(t)}_hostname(){const e=this.opts.hostname;return e.indexOf(":")===-1?e:"["+e+"]"}_port(){return this.opts.port&&(this.opts.secure&&Number(this.opts.port)!==443||!this.opts.secure&&Number(this.opts.port)!==80)?":"+this.opts.port:""}_query(e){const t=jt(e);return t.length?"?"+t:""}}class Gt extends Ve{constructor(){super(...arguments),this._polling=!1}get name(){return"polling"}doOpen(){this._poll()}pause(e){this.readyState="pausing";const t=()=>{this.readyState="paused",e()};if(this._polling||!this.writable){let s=0;this._polling&&(s++,this.once("pollComplete",function(){--s||t()})),this.writable||(s++,this.once("drain",function(){--s||t()}))}else t()}_poll(){this._polling=!0,this.doPoll(),this.emitReserved("poll")}onData(e){const t=s=>{if(this.readyState==="opening"&&s.type==="open"&&this.onOpen(),s.type==="close")return this.onClose({description:"transport closed by the server"}),!1;this.onPacket(s)};Bt(e,this.socket.binaryType).forEach(t),this.readyState!=="closed"&&(this._polling=!1,this.emitReserved("pollComplete"),this.readyState==="open"&&this._poll())}doClose(){const e=()=>{this.write([{type:"close"}])};this.readyState==="open"?e():this.once("open",e)}write(e){this.writable=!1,Pt(e,t=>{this.doWrite(t,()=>{this.writable=!0,this.emitReserved("drain")})})}uri(){const e=this.opts.secure?"https":"http",t=this.query||{};return this.opts.timestampRequests!==!1&&(t[this.opts.timestampParam]=ut()),!this.supportsBinary&&!t.sid&&(t.b64=1),this.createUri(e,t)}}let lt=!1;try{lt=typeof XMLHttpRequest<"u"&&"withCredentials"in new XMLHttpRequest}catch{}const Yt=lt;function Wt(){}class Kt extends Gt{constructor(e){if(super(e),typeof location<"u"){const t=location.protocol==="https:";let s=location.port;s||(s=t?"443":"80"),this.xd=typeof location<"u"&&e.hostname!==location.hostname||s!==e.port}}doWrite(e,t){const s=this.request({method:"POST",data:e});s.on("success",t),s.on("error",(r,i)=>{this.onError("xhr post error",r,i)})}doPoll(){const e=this.request();e.on("data",this.onData.bind(this)),e.on("error",(t,s)=>{this.onError("xhr poll error",t,s)}),this.pollXhr=e}}class N extends w{constructor(e,t,s){super(),this.createRequest=e,ge(this,s),this._opts=s,this._method=s.method||"GET",this._uri=t,this._data=s.data!==void 0?s.data:null,this._create()}_create(){var e;const t=ht(this._opts,"agent","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","autoUnref");t.xdomain=!!this._opts.xd;const s=this._xhr=this.createRequest(t);try{s.open(this._method,this._uri,!0);try{if(this._opts.extraHeaders){s.setDisableHeaderCheck&&s.setDisableHeaderCheck(!0);for(let r in this._opts.extraHeaders)this._opts.extraHeaders.hasOwnProperty(r)&&s.setRequestHeader(r,this._opts.extraHeaders[r])}}catch{}if(this._method==="POST")try{s.setRequestHeader("Content-type","text/plain;charset=UTF-8")}catch{}try{s.setRequestHeader("Accept","*/*")}catch{}(e=this._opts.cookieJar)===null||e===void 0||e.addCookies(s),"withCredentials"in s&&(s.withCredentials=this._opts.withCredentials),this._opts.requestTimeout&&(s.timeout=this._opts.requestTimeout),s.onreadystatechange=()=>{var r;s.readyState===3&&((r=this._opts.cookieJar)===null||r===void 0||r.parseCookies(s.getResponseHeader("set-cookie"))),s.readyState===4&&(s.status===200||s.status===1223?this._onLoad():this.setTimeoutFn(()=>{this._onError(typeof s.status=="number"?s.status:0)},0))},s.send(this._data)}catch(r){this.setTimeoutFn(()=>{this._onError(r)},0);return}typeof document<"u"&&(this._index=N.requestsCount++,N.requests[this._index]=this)}_onError(e){this.emitReserved("error",e,this._xhr),this._cleanup(!0)}_cleanup(e){if(!(typeof this._xhr>"u"||this._xhr===null)){if(this._xhr.onreadystatechange=Wt,e)try{this._xhr.abort()}catch{}typeof document<"u"&&delete N.requests[this._index],this._xhr=null}}_onLoad(){const e=this._xhr.responseText;e!==null&&(this.emitReserved("data",e),this.emitReserved("success"),this._cleanup())}abort(){this._cleanup()}}N.requestsCount=0;N.requests={};if(typeof document<"u"){if(typeof attachEvent=="function")attachEvent("onunload",et);else if(typeof addEventListener=="function"){const n="onpagehide"in S?"pagehide":"unload";addEventListener(n,et,!1)}}function et(){for(let n in N.requests)N.requests.hasOwnProperty(n)&&N.requests[n].abort()}const Xt=function(){const n=ft({xdomain:!1});return n&&n.responseType!==null}();class zt extends Kt{constructor(e){super(e);const t=e&&e.forceBase64;this.supportsBinary=Xt&&!t}request(e={}){return Object.assign(e,{xd:this.xd},this.opts),new N(ft,this.uri(),e)}}function ft(n){const e=n.xdomain;try{if(typeof XMLHttpRequest<"u"&&(!e||Yt))return new XMLHttpRequest}catch{}if(!e)try{return new S[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP")}catch{}}const dt=typeof navigator<"u"&&typeof navigator.product=="string"&&navigator.product.toLowerCase()==="reactnative";class Qt extends Ve{get name(){return"websocket"}doOpen(){const e=this.uri(),t=this.opts.protocols,s=dt?{}:ht(this.opts,"agent","perMessageDeflate","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","localAddress","protocolVersion","origin","maxPayload","family","checkServerIdentity");this.opts.extraHeaders&&(s.headers=this.opts.extraHeaders);try{this.ws=this.createSocket(e,t,s)}catch(r){return this.emitReserved("error",r)}this.ws.binaryType=this.socket.binaryType,this.addEventListeners()}addEventListeners(){this.ws.onopen=()=>{this.opts.autoUnref&&this.ws._socket.unref(),this.onOpen()},this.ws.onclose=e=>this.onClose({description:"websocket connection closed",context:e}),this.ws.onmessage=e=>this.onData(e.data),this.ws.onerror=e=>this.onError("websocket error",e)}write(e){this.writable=!1;for(let t=0;t<e.length;t++){const s=e[t],r=t===e.length-1;He(s,this.supportsBinary,i=>{try{this.doWrite(s,i)}catch{}r&&me(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){typeof this.ws<"u"&&(this.ws.onerror=()=>{},this.ws.close(),this.ws=null)}uri(){const e=this.opts.secure?"wss":"ws",t=this.query||{};return this.opts.timestampRequests&&(t[this.opts.timestampParam]=ut()),this.supportsBinary||(t.b64=1),this.createUri(e,t)}}const Ee=S.WebSocket||S.MozWebSocket;class Zt extends Qt{createSocket(e,t,s){return dt?new Ee(e,t,s):t?new Ee(e,t):new Ee(e)}doWrite(e,t){this.ws.send(t)}}class es extends Ve{get name(){return"webtransport"}doOpen(){try{this._transport=new WebTransport(this.createUri("https"),this.opts.transportOptions[this.name])}catch(e){return this.emitReserved("error",e)}this._transport.closed.then(()=>{this.onClose()}).catch(e=>{this.onError("webtransport error",e)}),this._transport.ready.then(()=>{this._transport.createBidirectionalStream().then(e=>{const t=It(Number.MAX_SAFE_INTEGER,this.socket.binaryType),s=e.readable.pipeThrough(t).getReader(),r=xt();r.readable.pipeTo(e.writable),this._writer=r.writable.getWriter();const i=()=>{s.read().then(({done:h,value:f})=>{h||(this.onPacket(f),i())}).catch(h=>{})};i();const o={type:"open"};this.query.sid&&(o.data=`{"sid":"${this.query.sid}"}`),this._writer.write(o).then(()=>this.onOpen())})})}write(e){this.writable=!1;for(let t=0;t<e.length;t++){const s=e[t],r=t===e.length-1;this._writer.write(s).then(()=>{r&&me(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){var e;(e=this._transport)===null||e===void 0||e.close()}}const ts={websocket:Zt,webtransport:es,polling:zt},ss=/^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,ns=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];function Oe(n){if(n.length>8e3)throw"URI too long";const e=n,t=n.indexOf("["),s=n.indexOf("]");t!=-1&&s!=-1&&(n=n.substring(0,t)+n.substring(t,s).replace(/:/g,";")+n.substring(s,n.length));let r=ss.exec(n||""),i={},o=14;for(;o--;)i[ns[o]]=r[o]||"";return t!=-1&&s!=-1&&(i.source=e,i.host=i.host.substring(1,i.host.length-1).replace(/;/g,":"),i.authority=i.authority.replace("[","").replace("]","").replace(/;/g,":"),i.ipv6uri=!0),i.pathNames=rs(i,i.path),i.queryKey=is(i,i.query),i}function rs(n,e){const t=/\/{2,9}/g,s=e.replace(t,"/").split("/");return(e.slice(0,1)=="/"||e.length===0)&&s.splice(0,1),e.slice(-1)=="/"&&s.splice(s.length-1,1),s}function is(n,e){const t={};return e.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(s,r,i){r&&(t[r]=i)}),t}const Ce=typeof addEventListener=="function"&&typeof removeEventListener=="function",he=[];Ce&&addEventListener("offline",()=>{he.forEach(n=>n())},!1);class M extends w{constructor(e,t){if(super(),this.binaryType=qt,this.writeBuffer=[],this._prevBufferLen=0,this._pingInterval=-1,this._pingTimeout=-1,this._maxPayload=-1,this._pingTimeoutTime=1/0,e&&typeof e=="object"&&(t=e,e=null),e){const s=Oe(e);t.hostname=s.host,t.secure=s.protocol==="https"||s.protocol==="wss",t.port=s.port,s.query&&(t.query=s.query)}else t.host&&(t.hostname=Oe(t.host).host);ge(this,t),this.secure=t.secure!=null?t.secure:typeof location<"u"&&location.protocol==="https:",t.hostname&&!t.port&&(t.port=this.secure?"443":"80"),this.hostname=t.hostname||(typeof location<"u"?location.hostname:"localhost"),this.port=t.port||(typeof location<"u"&&location.port?location.port:this.secure?"443":"80"),this.transports=[],this._transportsByName={},t.transports.forEach(s=>{const r=s.prototype.name;this.transports.push(r),this._transportsByName[r]=s}),this.opts=Object.assign({path:"/engine.io",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:"t",rememberUpgrade:!1,addTrailingSlash:!0,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!1},t),this.opts.path=this.opts.path.replace(/\/$/,"")+(this.opts.addTrailingSlash?"/":""),typeof this.opts.query=="string"&&(this.opts.query=Vt(this.opts.query)),Ce&&(this.opts.closeOnBeforeunload&&(this._beforeunloadEventListener=()=>{this.transport&&(this.transport.removeAllListeners(),this.transport.close())},addEventListener("beforeunload",this._beforeunloadEventListener,!1)),this.hostname!=="localhost"&&(this._offlineEventListener=()=>{this._onClose("transport close",{description:"network connection lost"})},he.push(this._offlineEventListener))),this.opts.withCredentials&&(this._cookieJar=void 0),this._open()}createTransport(e){const t=Object.assign({},this.opts.query);t.EIO=ct,t.transport=e,this.id&&(t.sid=this.id);const s=Object.assign({},this.opts,{query:t,socket:this,hostname:this.hostname,secure:this.secure,port:this.port},this.opts.transportOptions[e]);return new this._transportsByName[e](s)}_open(){if(this.transports.length===0){this.setTimeoutFn(()=>{this.emitReserved("error","No transports available")},0);return}const e=this.opts.rememberUpgrade&&M.priorWebsocketSuccess&&this.transports.indexOf("websocket")!==-1?"websocket":this.transports[0];this.readyState="opening";const t=this.createTransport(e);t.open(),this.setTransport(t)}setTransport(e){this.transport&&this.transport.removeAllListeners(),this.transport=e,e.on("drain",this._onDrain.bind(this)).on("packet",this._onPacket.bind(this)).on("error",this._onError.bind(this)).on("close",t=>this._onClose("transport close",t))}onOpen(){this.readyState="open",M.priorWebsocketSuccess=this.transport.name==="websocket",this.emitReserved("open"),this.flush()}_onPacket(e){if(this.readyState==="opening"||this.readyState==="open"||this.readyState==="closing")switch(this.emitReserved("packet",e),this.emitReserved("heartbeat"),e.type){case"open":this.onHandshake(JSON.parse(e.data));break;case"ping":this._sendPacket("pong"),this.emitReserved("ping"),this.emitReserved("pong"),this._resetPingTimeout();break;case"error":const t=new Error("server error");t.code=e.data,this._onError(t);break;case"message":this.emitReserved("data",e.data),this.emitReserved("message",e.data);break}}onHandshake(e){this.emitReserved("handshake",e),this.id=e.sid,this.transport.query.sid=e.sid,this._pingInterval=e.pingInterval,this._pingTimeout=e.pingTimeout,this._maxPayload=e.maxPayload,this.onOpen(),this.readyState!=="closed"&&this._resetPingTimeout()}_resetPingTimeout(){this.clearTimeoutFn(this._pingTimeoutTimer);const e=this._pingInterval+this._pingTimeout;this._pingTimeoutTime=Date.now()+e,this._pingTimeoutTimer=this.setTimeoutFn(()=>{this._onClose("ping timeout")},e),this.opts.autoUnref&&this._pingTimeoutTimer.unref()}_onDrain(){this.writeBuffer.splice(0,this._prevBufferLen),this._prevBufferLen=0,this.writeBuffer.length===0?this.emitReserved("drain"):this.flush()}flush(){if(this.readyState!=="closed"&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length){const e=this._getWritablePackets();this.transport.send(e),this._prevBufferLen=e.length,this.emitReserved("flush")}}_getWritablePackets(){if(!(this._maxPayload&&this.transport.name==="polling"&&this.writeBuffer.length>1))return this.writeBuffer;let t=1;for(let s=0;s<this.writeBuffer.length;s++){const r=this.writeBuffer[s].data;if(r&&(t+=Mt(r)),s>0&&t>this._maxPayload)return this.writeBuffer.slice(0,s);t+=2}return this.writeBuffer}_hasPingExpired(){if(!this._pingTimeoutTime)return!0;const e=Date.now()>this._pingTimeoutTime;return e&&(this._pingTimeoutTime=0,me(()=>{this._onClose("ping timeout")},this.setTimeoutFn)),e}write(e,t,s){return this._sendPacket("message",e,t,s),this}send(e,t,s){return this._sendPacket("message",e,t,s),this}_sendPacket(e,t,s,r){if(typeof t=="function"&&(r=t,t=void 0),typeof s=="function"&&(r=s,s=null),this.readyState==="closing"||this.readyState==="closed")return;s=s||{},s.compress=s.compress!==!1;const i={type:e,data:t,options:s};this.emitReserved("packetCreate",i),this.writeBuffer.push(i),r&&this.once("flush",r),this.flush()}close(){const e=()=>{this._onClose("forced close"),this.transport.close()},t=()=>{this.off("upgrade",t),this.off("upgradeError",t),e()},s=()=>{this.once("upgrade",t),this.once("upgradeError",t)};return(this.readyState==="opening"||this.readyState==="open")&&(this.readyState="closing",this.writeBuffer.length?this.once("drain",()=>{this.upgrading?s():e()}):this.upgrading?s():e()),this}_onError(e){if(M.priorWebsocketSuccess=!1,this.opts.tryAllTransports&&this.transports.length>1&&this.readyState==="opening")return this.transports.shift(),this._open();this.emitReserved("error",e),this._onClose("transport error",e)}_onClose(e,t){if(this.readyState==="opening"||this.readyState==="open"||this.readyState==="closing"){if(this.clearTimeoutFn(this._pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),Ce&&(this._beforeunloadEventListener&&removeEventListener("beforeunload",this._beforeunloadEventListener,!1),this._offlineEventListener)){const s=he.indexOf(this._offlineEventListener);s!==-1&&he.splice(s,1)}this.readyState="closed",this.id=null,this.emitReserved("close",e,t),this.writeBuffer=[],this._prevBufferLen=0}}}M.protocol=ct;class os extends M{constructor(){super(...arguments),this._upgrades=[]}onOpen(){if(super.onOpen(),this.readyState==="open"&&this.opts.upgrade)for(let e=0;e<this._upgrades.length;e++)this._probe(this._upgrades[e])}_probe(e){let t=this.createTransport(e),s=!1;M.priorWebsocketSuccess=!1;const r=()=>{s||(t.send([{type:"ping",data:"probe"}]),t.once("packet",g=>{if(!s)if(g.type==="pong"&&g.data==="probe"){if(this.upgrading=!0,this.emitReserved("upgrading",t),!t)return;M.priorWebsocketSuccess=t.name==="websocket",this.transport.pause(()=>{s||this.readyState!=="closed"&&(y(),this.setTransport(t),t.send([{type:"upgrade"}]),this.emitReserved("upgrade",t),t=null,this.upgrading=!1,this.flush())})}else{const R=new Error("probe error");R.transport=t.name,this.emitReserved("upgradeError",R)}}))};function i(){s||(s=!0,y(),t.close(),t=null)}const o=g=>{const R=new Error("probe error: "+g);R.transport=t.name,i(),this.emitReserved("upgradeError",R)};function h(){o("transport closed")}function f(){o("socket closed")}function m(g){t&&g.name!==t.name&&i()}const y=()=>{t.removeListener("open",r),t.removeListener("error",o),t.removeListener("close",h),this.off("close",f),this.off("upgrading",m)};t.once("open",r),t.once("error",o),t.once("close",h),this.once("close",f),this.once("upgrading",m),this._upgrades.indexOf("webtransport")!==-1&&e!=="webtransport"?this.setTimeoutFn(()=>{s||t.open()},200):t.open()}onHandshake(e){this._upgrades=this._filterUpgrades(e.upgrades),super.onHandshake(e)}_filterUpgrades(e){const t=[];for(let s=0;s<e.length;s++)~this.transports.indexOf(e[s])&&t.push(e[s]);return t}}let as=class extends os{constructor(e,t={}){const s=typeof e=="object",r=s?{...e}:{...t};(!r.transports||r.transports&&typeof r.transports[0]=="string")&&(r.transports=(r.transports||["polling","websocket","webtransport"]).map(i=>ts[i]).filter(i=>!!i)),super(s?r:e,r)}};function cs(n,e="",t){let s=n;t=t||typeof location<"u"&&location,n==null&&(n=t.protocol+"//"+t.host),typeof n=="string"&&(n.charAt(0)==="/"&&(n.charAt(1)==="/"?n=t.protocol+n:n=t.host+n),/^(https?|wss?):\/\//.test(n)||(typeof t<"u"?n=t.protocol+"//"+n:n="https://"+n),s=Oe(n)),s.port||(/^(http|ws)$/.test(s.protocol)?s.port="80":/^(http|ws)s$/.test(s.protocol)&&(s.port="443")),s.path=s.path||"/";const i=s.host.indexOf(":")!==-1?"["+s.host+"]":s.host;return s.id=s.protocol+"://"+i+":"+s.port+e,s.href=s.protocol+"://"+i+(t&&t.port===s.port?"":":"+s.port),s}const hs=typeof ArrayBuffer=="function",us=n=>typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView(n):n.buffer instanceof ArrayBuffer,pt=Object.prototype.toString,ls=typeof Blob=="function"||typeof Blob<"u"&&pt.call(Blob)==="[object BlobConstructor]",fs=typeof File=="function"||typeof File<"u"&&pt.call(File)==="[object FileConstructor]";function Je(n){return hs&&(n instanceof ArrayBuffer||us(n))||ls&&n instanceof Blob||fs&&n instanceof File}function ue(n,e){if(!n||typeof n!="object")return!1;if(Array.isArray(n)){for(let t=0,s=n.length;t<s;t++)if(ue(n[t]))return!0;return!1}if(Je(n))return!0;if(n.toJSON&&typeof n.toJSON=="function"&&arguments.length===1)return ue(n.toJSON(),!0);for(const t in n)if(Object.prototype.hasOwnProperty.call(n,t)&&ue(n[t]))return!0;return!1}function ds(n){const e=[],t=n.data,s=n;return s.data=Re(t,e),s.attachments=e.length,{packet:s,buffers:e}}function Re(n,e){if(!n)return n;if(Je(n)){const t={_placeholder:!0,num:e.length};return e.push(n),t}else if(Array.isArray(n)){const t=new Array(n.length);for(let s=0;s<n.length;s++)t[s]=Re(n[s],e);return t}else if(typeof n=="object"&&!(n instanceof Date)){const t={};for(const s in n)Object.prototype.hasOwnProperty.call(n,s)&&(t[s]=Re(n[s],e));return t}return n}function ps(n,e){return n.data=$e(n.data,e),delete n.attachments,n}function $e(n,e){if(!n)return n;if(n&&n._placeholder===!0){if(typeof n.num=="number"&&n.num>=0&&n.num<e.length)return e[n.num];throw new Error("illegal attachments")}else if(Array.isArray(n))for(let t=0;t<n.length;t++)n[t]=$e(n[t],e);else if(typeof n=="object")for(const t in n)Object.prototype.hasOwnProperty.call(n,t)&&(n[t]=$e(n[t],e));return n}const ys=["connect","connect_error","disconnect","disconnecting","newListener","removeListener"];var p;(function(n){n[n.CONNECT=0]="CONNECT",n[n.DISCONNECT=1]="DISCONNECT",n[n.EVENT=2]="EVENT",n[n.ACK=3]="ACK",n[n.CONNECT_ERROR=4]="CONNECT_ERROR",n[n.BINARY_EVENT=5]="BINARY_EVENT",n[n.BINARY_ACK=6]="BINARY_ACK"})(p||(p={}));class ms{constructor(e){this.replacer=e}encode(e){return(e.type===p.EVENT||e.type===p.ACK)&&ue(e)?this.encodeAsBinary({type:e.type===p.EVENT?p.BINARY_EVENT:p.BINARY_ACK,nsp:e.nsp,data:e.data,id:e.id}):[this.encodeAsString(e)]}encodeAsString(e){let t=""+e.type;return(e.type===p.BINARY_EVENT||e.type===p.BINARY_ACK)&&(t+=e.attachments+"-"),e.nsp&&e.nsp!=="/"&&(t+=e.nsp+","),e.id!=null&&(t+=e.id),e.data!=null&&(t+=JSON.stringify(e.data,this.replacer)),t}encodeAsBinary(e){const t=ds(e),s=this.encodeAsString(t.packet),r=t.buffers;return r.unshift(s),r}}class Ge extends w{constructor(e){super(),this.opts=Object.assign({reviver:void 0,maxAttachments:10},typeof e=="function"?{reviver:e}:e)}add(e){let t;if(typeof e=="string"){if(this.reconstructor)throw new Error("got plaintext data when reconstructing a packet");t=this.decodeString(e);const s=t.type===p.BINARY_EVENT;s||t.type===p.BINARY_ACK?(t.type=s?p.EVENT:p.ACK,this.reconstructor=new gs(t),t.attachments===0&&super.emitReserved("decoded",t)):super.emitReserved("decoded",t)}else if(Je(e)||e.base64)if(this.reconstructor)t=this.reconstructor.takeBinaryData(e),t&&(this.reconstructor=null,super.emitReserved("decoded",t));else throw new Error("got binary data when not reconstructing a packet");else throw new Error("Unknown type: "+e)}decodeString(e){let t=0;const s={type:Number(e.charAt(0))};if(p[s.type]===void 0)throw new Error("unknown packet type "+s.type);if(s.type===p.BINARY_EVENT||s.type===p.BINARY_ACK){const i=t+1;for(;e.charAt(++t)!=="-"&&t!=e.length;);const o=e.substring(i,t);if(o!=Number(o)||e.charAt(t)!=="-")throw new Error("Illegal attachments");const h=Number(o);if(!ws(h)||h<0)throw new Error("Illegal attachments");if(h>this.opts.maxAttachments)throw new Error("too many attachments");s.attachments=h}if(e.charAt(t+1)==="/"){const i=t+1;for(;++t&&!(e.charAt(t)===","||t===e.length););s.nsp=e.substring(i,t)}else s.nsp="/";const r=e.charAt(t+1);if(r!==""&&Number(r)==r){const i=t+1;for(;++t;){const o=e.charAt(t);if(o==null||Number(o)!=o){--t;break}if(t===e.length)break}s.id=Number(e.substring(i,t+1))}if(e.charAt(++t)){const i=this.tryParse(e.substr(t));if(Ge.isPayloadValid(s.type,i))s.data=i;else throw new Error("invalid payload")}return s}tryParse(e){try{return JSON.parse(e,this.opts.reviver)}catch{return!1}}static isPayloadValid(e,t){switch(e){case p.CONNECT:return tt(t);case p.DISCONNECT:return t===void 0;case p.CONNECT_ERROR:return typeof t=="string"||tt(t);case p.EVENT:case p.BINARY_EVENT:return Array.isArray(t)&&(typeof t[0]=="number"||typeof t[0]=="string"&&ys.indexOf(t[0])===-1);case p.ACK:case p.BINARY_ACK:return Array.isArray(t)}}destroy(){this.reconstructor&&(this.reconstructor.finishedReconstruction(),this.reconstructor=null)}}class gs{constructor(e){this.packet=e,this.buffers=[],this.reconPack=e}takeBinaryData(e){if(this.buffers.push(e),this.buffers.length===this.reconPack.attachments){const t=ps(this.reconPack,this.buffers);return this.finishedReconstruction(),t}return null}finishedReconstruction(){this.reconPack=null,this.buffers=[]}}const ws=Number.isInteger||function(n){return typeof n=="number"&&isFinite(n)&&Math.floor(n)===n};function tt(n){return Object.prototype.toString.call(n)==="[object Object]"}const _s=Object.freeze(Object.defineProperty({__proto__:null,Decoder:Ge,Encoder:ms,get PacketType(){return p}},Symbol.toStringTag,{value:"Module"}));function C(n,e,t){return n.on(e,t),function(){n.off(e,t)}}const bs=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1});class yt extends w{constructor(e,t,s){super(),this.connected=!1,this.recovered=!1,this.receiveBuffer=[],this.sendBuffer=[],this._queue=[],this._queueSeq=0,this.ids=0,this.acks={},this.flags={},this.io=e,this.nsp=t,s&&s.auth&&(this.auth=s.auth),this._opts=Object.assign({},s),this.io._autoConnect&&this.open()}get disconnected(){return!this.connected}subEvents(){if(this.subs)return;const e=this.io;this.subs=[C(e,"open",this.onopen.bind(this)),C(e,"packet",this.onpacket.bind(this)),C(e,"error",this.onerror.bind(this)),C(e,"close",this.onclose.bind(this))]}get active(){return!!this.subs}connect(){return this.connected?this:(this.subEvents(),this.io._reconnecting||this.io.open(),this.io._readyState==="open"&&this.onopen(),this)}open(){return this.connect()}send(...e){return e.unshift("message"),this.emit.apply(this,e),this}emit(e,...t){var s,r,i;if(bs.hasOwnProperty(e))throw new Error('"'+e.toString()+'" is a reserved event name');if(t.unshift(e),this._opts.retries&&!this.flags.fromQueue&&!this.flags.volatile)return this._addToQueue(t),this;const o={type:p.EVENT,data:t};if(o.options={},o.options.compress=this.flags.compress!==!1,typeof t[t.length-1]=="function"){const y=this.ids++,g=t.pop();this._registerAckCallback(y,g),o.id=y}const h=(r=(s=this.io.engine)===null||s===void 0?void 0:s.transport)===null||r===void 0?void 0:r.writable,f=this.connected&&!(!((i=this.io.engine)===null||i===void 0)&&i._hasPingExpired());return this.flags.volatile&&!h||(f?(this.notifyOutgoingListeners(o),this.packet(o)):this.sendBuffer.push(o)),this.flags={},this}_registerAckCallback(e,t){var s;const r=(s=this.flags.timeout)!==null&&s!==void 0?s:this._opts.ackTimeout;if(r===void 0){this.acks[e]=t;return}const i=this.io.setTimeoutFn(()=>{delete this.acks[e];for(let h=0;h<this.sendBuffer.length;h++)this.sendBuffer[h].id===e&&this.sendBuffer.splice(h,1);t.call(this,new Error("operation has timed out"))},r),o=(...h)=>{this.io.clearTimeoutFn(i),t.apply(this,h)};o.withError=!0,this.acks[e]=o}emitWithAck(e,...t){return new Promise((s,r)=>{const i=(o,h)=>o?r(o):s(h);i.withError=!0,t.push(i),this.emit(e,...t)})}_addToQueue(e){let t;typeof e[e.length-1]=="function"&&(t=e.pop());const s={id:this._queueSeq++,tryCount:0,pending:!1,args:e,flags:Object.assign({fromQueue:!0},this.flags)};e.push((r,...i)=>(this._queue[0],r!==null?s.tryCount>this._opts.retries&&(this._queue.shift(),t&&t(r)):(this._queue.shift(),t&&t(null,...i)),s.pending=!1,this._drainQueue())),this._queue.push(s),this._drainQueue()}_drainQueue(e=!1){if(!this.connected||this._queue.length===0)return;const t=this._queue[0];t.pending&&!e||(t.pending=!0,t.tryCount++,this.flags=t.flags,this.emit.apply(this,t.args))}packet(e){e.nsp=this.nsp,this.io._packet(e)}onopen(){typeof this.auth=="function"?this.auth(e=>{this._sendConnectPacket(e)}):this._sendConnectPacket(this.auth)}_sendConnectPacket(e){this.packet({type:p.CONNECT,data:this._pid?Object.assign({pid:this._pid,offset:this._lastOffset},e):e})}onerror(e){this.connected||this.emitReserved("connect_error",e)}onclose(e,t){this.connected=!1,delete this.id,this.emitReserved("disconnect",e,t),this._clearAcks()}_clearAcks(){Object.keys(this.acks).forEach(e=>{if(!this.sendBuffer.some(s=>String(s.id)===e)){const s=this.acks[e];delete this.acks[e],s.withError&&s.call(this,new Error("socket has been disconnected"))}})}onpacket(e){if(e.nsp===this.nsp)switch(e.type){case p.CONNECT:e.data&&e.data.sid?this.onconnect(e.data.sid,e.data.pid):this.emitReserved("connect_error",new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)"));break;case p.EVENT:case p.BINARY_EVENT:this.onevent(e);break;case p.ACK:case p.BINARY_ACK:this.onack(e);break;case p.DISCONNECT:this.ondisconnect();break;case p.CONNECT_ERROR:this.destroy();const s=new Error(e.data.message);s.data=e.data.data,this.emitReserved("connect_error",s);break}}onevent(e){const t=e.data||[];e.id!=null&&t.push(this.ack(e.id)),this.connected?this.emitEvent(t):this.receiveBuffer.push(Object.freeze(t))}emitEvent(e){if(this._anyListeners&&this._anyListeners.length){const t=this._anyListeners.slice();for(const s of t)s.apply(this,e)}super.emit.apply(this,e),this._pid&&e.length&&typeof e[e.length-1]=="string"&&(this._lastOffset=e[e.length-1])}ack(e){const t=this;let s=!1;return function(...r){s||(s=!0,t.packet({type:p.ACK,id:e,data:r}))}}onack(e){const t=this.acks[e.id];typeof t=="function"&&(delete this.acks[e.id],t.withError&&e.data.unshift(null),t.apply(this,e.data))}onconnect(e,t){this.id=e,this.recovered=t&&this._pid===t,this._pid=t,this.connected=!0,this.emitBuffered(),this._drainQueue(!0),this.emitReserved("connect")}emitBuffered(){this.receiveBuffer.forEach(e=>this.emitEvent(e)),this.receiveBuffer=[],this.sendBuffer.forEach(e=>{this.notifyOutgoingListeners(e),this.packet(e)}),this.sendBuffer=[]}ondisconnect(){this.destroy(),this.onclose("io server disconnect")}destroy(){this.subs&&(this.subs.forEach(e=>e()),this.subs=void 0),this.io._destroy(this)}disconnect(){return this.connected&&this.packet({type:p.DISCONNECT}),this.destroy(),this.connected&&this.onclose("io client disconnect"),this}close(){return this.disconnect()}compress(e){return this.flags.compress=e,this}get volatile(){return this.flags.volatile=!0,this}timeout(e){return this.flags.timeout=e,this}onAny(e){return this._anyListeners=this._anyListeners||[],this._anyListeners.push(e),this}prependAny(e){return this._anyListeners=this._anyListeners||[],this._anyListeners.unshift(e),this}offAny(e){if(!this._anyListeners)return this;if(e){const t=this._anyListeners;for(let s=0;s<t.length;s++)if(e===t[s])return t.splice(s,1),this}else this._anyListeners=[];return this}listenersAny(){return this._anyListeners||[]}onAnyOutgoing(e){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.push(e),this}prependAnyOutgoing(e){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.unshift(e),this}offAnyOutgoing(e){if(!this._anyOutgoingListeners)return this;if(e){const t=this._anyOutgoingListeners;for(let s=0;s<t.length;s++)if(e===t[s])return t.splice(s,1),this}else this._anyOutgoingListeners=[];return this}listenersAnyOutgoing(){return this._anyOutgoingListeners||[]}notifyOutgoingListeners(e){if(this._anyOutgoingListeners&&this._anyOutgoingListeners.length){const t=this._anyOutgoingListeners.slice();for(const s of t)s.apply(this,e.data)}}}function Q(n){n=n||{},this.ms=n.min||100,this.max=n.max||1e4,this.factor=n.factor||2,this.jitter=n.jitter>0&&n.jitter<=1?n.jitter:0,this.attempts=0}Q.prototype.duration=function(){var n=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),t=Math.floor(e*this.jitter*n);n=Math.floor(e*10)&1?n+t:n-t}return Math.min(n,this.max)|0};Q.prototype.reset=function(){this.attempts=0};Q.prototype.setMin=function(n){this.ms=n};Q.prototype.setMax=function(n){this.max=n};Q.prototype.setJitter=function(n){this.jitter=n};class Ne extends w{constructor(e,t){var s;super(),this.nsps={},this.subs=[],e&&typeof e=="object"&&(t=e,e=void 0),t=t||{},t.path=t.path||"/socket.io",this.opts=t,ge(this,t),this.reconnection(t.reconnection!==!1),this.reconnectionAttempts(t.reconnectionAttempts||1/0),this.reconnectionDelay(t.reconnectionDelay||1e3),this.reconnectionDelayMax(t.reconnectionDelayMax||5e3),this.randomizationFactor((s=t.randomizationFactor)!==null&&s!==void 0?s:.5),this.backoff=new Q({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(t.timeout==null?2e4:t.timeout),this._readyState="closed",this.uri=e;const r=t.parser||_s;this.encoder=new r.Encoder,this.decoder=new r.Decoder,this._autoConnect=t.autoConnect!==!1,this._autoConnect&&this.open()}reconnection(e){return arguments.length?(this._reconnection=!!e,e||(this.skipReconnect=!0),this):this._reconnection}reconnectionAttempts(e){return e===void 0?this._reconnectionAttempts:(this._reconnectionAttempts=e,this)}reconnectionDelay(e){var t;return e===void 0?this._reconnectionDelay:(this._reconnectionDelay=e,(t=this.backoff)===null||t===void 0||t.setMin(e),this)}randomizationFactor(e){var t;return e===void 0?this._randomizationFactor:(this._randomizationFactor=e,(t=this.backoff)===null||t===void 0||t.setJitter(e),this)}reconnectionDelayMax(e){var t;return e===void 0?this._reconnectionDelayMax:(this._reconnectionDelayMax=e,(t=this.backoff)===null||t===void 0||t.setMax(e),this)}timeout(e){return arguments.length?(this._timeout=e,this):this._timeout}maybeReconnectOnOpen(){!this._reconnecting&&this._reconnection&&this.backoff.attempts===0&&this.reconnect()}open(e){if(~this._readyState.indexOf("open"))return this;this.engine=new as(this.uri,this.opts);const t=this.engine,s=this;this._readyState="opening",this.skipReconnect=!1;const r=C(t,"open",function(){s.onopen(),e&&e()}),i=h=>{this.cleanup(),this._readyState="closed",this.emitReserved("error",h),e?e(h):this.maybeReconnectOnOpen()},o=C(t,"error",i);if(this._timeout!==!1){const h=this._timeout,f=this.setTimeoutFn(()=>{r(),i(new Error("timeout")),t.close()},h);this.opts.autoUnref&&f.unref(),this.subs.push(()=>{this.clearTimeoutFn(f)})}return this.subs.push(r),this.subs.push(o),this}connect(e){return this.open(e)}onopen(){this.cleanup(),this._readyState="open",this.emitReserved("open");const e=this.engine;this.subs.push(C(e,"ping",this.onping.bind(this)),C(e,"data",this.ondata.bind(this)),C(e,"error",this.onerror.bind(this)),C(e,"close",this.onclose.bind(this)),C(this.decoder,"decoded",this.ondecoded.bind(this)))}onping(){this.emitReserved("ping")}ondata(e){try{this.decoder.add(e)}catch(t){this.onclose("parse error",t)}}ondecoded(e){me(()=>{this.emitReserved("packet",e)},this.setTimeoutFn)}onerror(e){this.emitReserved("error",e)}socket(e,t){let s=this.nsps[e];return s?this._autoConnect&&!s.active&&s.connect():(s=new yt(this,e,t),this.nsps[e]=s),s}_destroy(e){const t=Object.keys(this.nsps);for(const s of t)if(this.nsps[s].active)return;this._close()}_packet(e){const t=this.encoder.encode(e);for(let s=0;s<t.length;s++)this.engine.write(t[s],e.options)}cleanup(){this.subs.forEach(e=>e()),this.subs.length=0,this.decoder.destroy()}_close(){this.skipReconnect=!0,this._reconnecting=!1,this.onclose("forced close")}disconnect(){return this._close()}onclose(e,t){var s;this.cleanup(),(s=this.engine)===null||s===void 0||s.close(),this.backoff.reset(),this._readyState="closed",this.emitReserved("close",e,t),this._reconnection&&!this.skipReconnect&&this.reconnect()}reconnect(){if(this._reconnecting||this.skipReconnect)return this;const e=this;if(this.backoff.attempts>=this._reconnectionAttempts)this.backoff.reset(),this.emitReserved("reconnect_failed"),this._reconnecting=!1;else{const t=this.backoff.duration();this._reconnecting=!0;const s=this.setTimeoutFn(()=>{e.skipReconnect||(this.emitReserved("reconnect_attempt",e.backoff.attempts),!e.skipReconnect&&e.open(r=>{r?(e._reconnecting=!1,e.reconnect(),this.emitReserved("reconnect_error",r)):e.onreconnect()}))},t);this.opts.autoUnref&&s.unref(),this.subs.push(()=>{this.clearTimeoutFn(s)})}}onreconnect(){const e=this.backoff.attempts;this._reconnecting=!1,this.backoff.reset(),this.emitReserved("reconnect",e)}}const Z={};function se(n,e){typeof n=="object"&&(e=n,n=void 0),e=e||{};const t=cs(n,e.path||"/socket.io"),s=t.source,r=t.id,i=t.path,o=Z[r]&&i in Z[r].nsps,h=e.forceNew||e["force new connection"]||e.multiplex===!1||o;let f;return h?f=new Ne(s,e):(Z[r]||(Z[r]=new Ne(s,e)),f=Z[r]),t.query&&!e.query&&(e.query=t.queryKey),f.socket(t.path,e)}Object.assign(se,{Manager:Ne,Socket:yt,io:se,connect:se});const Pe=100;function Ts(n){try{const e=JSON.parse(n);if(e&&typeof e=="object"){const t=e;return{message:typeof t.message=="string"?t.message:void 0,code:typeof t.code=="string"?t.code:void 0,details:t.details}}}catch{}return{}}function Es(n){if(!n||typeof n!="object")return;const e=n.retryAfter;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}class we extends Error{constructor(t,s,r,i){const o=Ts(r);super(o.message??`${s||"Request failed"} (${t})`);E(this,"status");E(this,"code");E(this,"details");E(this,"body");E(this,"retryAfter");this.name="RequestError",this.status=t,this.code=o.code,this.details=o.details,this.body=r,this.retryAfter=i??Es(o.details)}}const $="item/folder",d="item",L="processor",vs="npm-registry",B="hidden",ve="FILE",ke="TOOL",Ae="APP",ks=500,st=3e4,As=.25,Ss=n=>new Promise(e=>setTimeout(e,n));function Os(n){var r,i;const e=(i=(r=n.headers)==null?void 0:r.get)==null?void 0:i.call(r,"Retry-After");if(!e)return;const t=Number(e);if(Number.isFinite(t))return Math.max(0,t);const s=Date.parse(e);if(!Number.isNaN(s))return Math.max(0,(s-Date.now())/1e3)}function Cs(n){return n instanceof we?n.status===429||n.status>=500:!0}function Rs(n,e){const t=Math.min(ks*2**e,st),s=t*As*Math.random(),r=n instanceof we&&n.retryAfter!=null?n.retryAfter*1e3:void 0;return r!=null?Math.min(r,st)+s:t+s}var c,Be,l,q,te,le,fe,xe,Ie,mt;const We=class We{constructor(e,t,s){_(this,c);E(this,"apiUrl");E(this,"accessToken");E(this,"wsUrl");E(this,"retries");E(this,"useBearer");E(this,"builtInGlobals",null);E(this,"localServerUrl",null);E(this,"context");const{retries:r=0,useBearer:i=!1,localServerUrl:o}=s||{};let h=t;if(h.charAt(h.length-1)==="/"&&(h=h.slice(0,-1)),this.apiUrl=`${h}/api`,this.accessToken=e,this.wsUrl=`${h}?accessToken=${e}`,this.retries=r,this.useBearer=i,this.context={appId:"",projectId:"",accessToken:e,apiUrl:t},o){let f=o;f.charAt(f.length-1)==="/"&&(f=f.slice(0,-1)),this.localServerUrl=f}}static fromPlatformContext(e){const t=(typeof window<"u"?window.__THATOPEN_CONTEXT__:null)||{appId:"",projectId:"",accessToken:"",apiUrl:""},s=new We(t.accessToken,t.apiUrl,{...e,useBearer:!0});return s.context=t,s}setRetries(e){this.retries=e}setBuiltInGlobals(e){this.builtInGlobals=e}get socketOrigin(){return this.wsUrl.split("?")[0]}async resolveAccessToken(){return this.accessToken}async request(e,t,s){return a(this,c,l).call(this,e,t,s)}async listFiles(e){const{folderId:t,archived:s,projectId:r}=e||{};return t?await a(this,c,l).call(this,"GET",`${$}/${t}/items`,{query:{itemType:ve,archived:s}}):await a(this,c,l).call(this,"GET",`${d}`,{query:{itemType:ve,archived:s,...r&&{projectId:r}}})}async getFile(e,t){return await a(this,c,Ie).call(this,e,t)}async createFile(e){return await a(this,c,fe).call(this,e,ve)}async updateFile(e,t){return await a(this,c,xe).call(this,e,t)}async archiveFile(e){return await a(this,c,l).call(this,"DELETE",`${d}/${e}`)}async recoverFile(e){return await a(this,c,l).call(this,"PUT",`${d}/${e}/recover`)}async downloadFile(e,t){return await a(this,c,le).call(this,e,t)}async getFileVersionMetadata(e,t,s){const{withDraft:r}=s||{};return await a(this,c,l).call(this,"GET",`${d}/${encodeURIComponent(e)}/version/${encodeURIComponent(t)}/metadata`,{query:{...r&&{withDraft:"true"}}})}async updateFileVersionMetadata(e,t,s){return await a(this,c,l).call(this,"PUT",`${d}/${encodeURIComponent(e)}/version/${encodeURIComponent(t)}/metadata`,{body:JSON.stringify({metadata:s}),contentType:"application/json"})}async deleteFileVersionMetadata(e,t){return await a(this,c,l).call(this,"DELETE",`${d}/${encodeURIComponent(e)}/version/${encodeURIComponent(t)}/metadata`)}async getFileVersionMetadataBatch(e,t){const{withDraft:s}=t||{};return await a(this,c,te).call(this,e,async r=>(await a(this,c,l).call(this,"POST",`${d}/batch/version-metadata`,{body:JSON.stringify({entries:r,...s!==void 0&&{withDraft:s}}),contentType:"application/json"})).results)}async listFolders(e){const{archived:t,parentFolderId:s,projectId:r}=e||{};return await a(this,c,l).call(this,"GET",$,{query:{parentFolderId:s,archived:t,...r&&{projectId:r}}})}async getFolder(e){return await a(this,c,l).call(this,"GET",`${$}/${e}`)}async getFoldersBatch(e){return await a(this,c,te).call(this,e,async t=>(await a(this,c,l).call(this,"POST",`${d}/batch/folders`,{body:JSON.stringify({folderIds:t}),contentType:"application/json"})).results)}async createFolder(e,t,s){return await a(this,c,l).call(this,"POST",$,{body:JSON.stringify({name:e,...t&&{parentId:t},...s&&{projectId:s}}),contentType:"application/json"})}async updateFolder(e,t){const{name:s}=t;return await a(this,c,l).call(this,"PUT",`${$}/${e}`,{body:JSON.stringify({name:s}),contentType:"application/json"})}async archiveFolder(e){return await a(this,c,l).call(this,"DELETE",`${$}/${e}`)}async recoverFolder(e){return await a(this,c,l).call(this,"PUT",`${$}/${e}/recover`)}async downloadFolder(e){return await a(this,c,q).call(this,`${$}/${e}/download`)}async listComponents(e){const{folderId:t,ShowVersions:s,projectId:r}=e||{};return t?await a(this,c,l).call(this,"GET",`${$}/${t}/items`,{query:{itemType:ke,...s&&{ShowVersions:s}}}):await a(this,c,l).call(this,"GET",`${d}`,{query:{itemType:ke,...s&&{ShowVersions:s},...r&&{projectId:r}}})}async getComponent(e,t){return await a(this,c,Ie).call(this,e,t)}async createComponent(e){const{componentProps:t}=e;return await a(this,c,fe).call(this,e,ke,t)}async updateComponent(e,t){const{componentProps:s}=t;return await a(this,c,xe).call(this,e,t,s)}async downloadComponent(e,t){return await a(this,c,le).call(this,e,t)}async downloadComponentBundle(e,t){const{versionTag:s,withDraft:r}=t||{};return await a(this,c,q).call(this,`${d}/${e}/download/bundle`,{query:{...s&&{versionTag:s},...r&&{withDraft:r}}})}async archiveComponent(e){return await a(this,c,l).call(this,"DELETE",`${d}/${e}`)}async recoverComponent(e){return await a(this,c,l).call(this,"PUT",`${d}/${e}/recover`)}async getBuiltInComponent(e){return await(await a(this,c,q).call(this,`built-in/${e}/bundle`)).text()}async initBuiltInComponent(e,t,s){const r=await this.getBuiltInComponent(e.uuid),i=s??this.builtInGlobals??(typeof window<"u"?window.ThatOpenCompany:{})??{},o=Object.keys(i),h=o.map(g=>i[g]),m=new Function(...o,`${r}
|
|
2
|
-
return main;`)(...h),y=(m==null?void 0:m.componentDefinition)??m;t.get(y)}async initBuiltInComponents(e,...t){await Promise.all(t.map(s=>this.initBuiltInComponent(s,e)))}async setup(e,...t){var o,h;const s=e.OBC,r=e.BUI;if(!(s!=null&&s.Components))throw new Error("globals.OBC must include Components");if(!(r!=null&&r.Manager))throw new Error("globals.BUI must include Manager");const i=new s.Components;return r.Manager.init(),this.setBuiltInGlobals(e),await this.initBuiltInComponents(i,...t),i.init(),(h=(o=this.context.appEventOrchestrator)==null?void 0:o.appLoaded)==null||h.call(o),{components:i}}throwError(e,t){var s,r;(r=(s=this.context.appEventOrchestrator)==null?void 0:s.appError)==null||r.call(s,e,t)}async listApps(e){const{folderId:t,ShowVersions:s,projectId:r}=e||{};return t?await a(this,c,l).call(this,"GET",`${$}/${t}/items`,{query:{itemType:Ae,...s&&{ShowVersions:s}}}):await a(this,c,l).call(this,"GET",`${d}`,{query:{itemType:Ae,...s&&{ShowVersions:s},...r&&{projectId:r}}})}async createApp(e){const{appProps:t}=e;return await a(this,c,fe).call(this,e,Ae,t)}async downloadApp(e,t){return await a(this,c,le).call(this,e,t)}async downloadAppBundle(e,t){const{versionTag:s,withDraft:r}=t||{};return await a(this,c,q).call(this,`${d}/${e}/download/bundle`,{query:{...s&&{versionTag:s},...r&&{withDraft:r}}})}async archiveApp(e){return await a(this,c,l).call(this,"DELETE",`${d}/${e}`)}async getNpmCredentials(){return await a(this,c,l).call(this,"GET",`${vs}/credentials`)}async executeComponent(e,t,s){if(this.localServerUrl){const r=`${this.localServerUrl}/api/${L}/${e}/execute`,i=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!i.ok){const o=await i.text().catch(()=>"");throw new Error(`Local server request failed: ${i.status} - ${o}`)}return await i.json()}return await a(this,c,l).call(this,"POST",`${L}/${e}/execute`,{body:JSON.stringify(t),query:{...s&&{versionTag:s}},contentType:"application/json"})}async abortExecution(e){if(this.localServerUrl){const t=`${this.localServerUrl}/api/${L}/progress/${e}/abort`,s=await fetch(t,{method:"POST"});if(!s.ok){const r=await s.text().catch(()=>"");throw new Error(`Local server request failed: ${s.status} - ${r}`)}return await s.json()}return await a(this,c,l).call(this,"POST",`${L}/progress/${e}/abort`)}async listExecutions(e,t){if(this.localServerUrl){const s=t?`?projectId=${encodeURIComponent(t)}`:"",r=`${this.localServerUrl}/api/${L}/${e}/progress${s}`,i=await fetch(r);if(!i.ok){const o=await i.text().catch(()=>"");throw new Error(`Local server request failed: ${i.status} - ${o}`)}return await i.json()}return await a(this,c,l).call(this,"GET",`${L}/${e}/progress`,{query:{...t&&{projectId:t}}})}async getExecution(e){if(this.localServerUrl){const t=`${this.localServerUrl}/api/${L}/progress/${e}`,s=await fetch(t);if(!s.ok){const r=await s.text().catch(()=>"");throw new Error(`Local server request failed: ${s.status} - ${r}`)}return await s.json()}return await a(this,c,l).call(this,"GET",`${L}/progress/${e}`)}async onExecutionProgress(e,t){const s=this.localServerUrl?`${this.localServerUrl}?accessToken=${this.accessToken}`:this.wsUrl,r=await se(s,{...this.localServerUrl&&{transports:["websocket"]}});r.on("connect",function(){r.emit("executionSubscription",JSON.stringify({executionId:e})),r.on("execution",i=>{t(i)})}),r.on("connect_error",function(i){console.log(i)})}async createHiddenFile(e,t,s){const r=new FormData;return r.append("file",e),r.append("parentItemId",t),s!=null&&r.append("tag",s),await a(this,c,l).call(this,"POST",`${d}/${B}`,{body:r})}async createHiddenFilesBatch(e,t,s){const r=new FormData;for(const i of e)r.append("files",i);return r.append("parentItemId",t),s!=null&&r.append("tag",s),await a(this,c,l).call(this,"POST",`${d}/${B}/batch`,{body:r})}async deleteHiddenFile(e){return await a(this,c,l).call(this,"DELETE",`${d}/${B}/${e}`)}async getHiddenFile(e){return await a(this,c,l).call(this,"GET",`${d}/${B}/${e}`)}async downloadHiddenFile(e){return await a(this,c,q).call(this,`${d}/${B}/${e}/download`)}async getHiddenFileSignedUrl(e,t){return await a(this,c,l).call(this,"GET",`${d}/${B}/${e}/signed-url`,{...t!=null&&{query:{expiresIn:t}}})}async getHiddenFileSignedUrlsBatch(e,t){return await a(this,c,te).call(this,e,async s=>(await a(this,c,l).call(this,"POST",`${d}/${B}/signed-url/batch`,{body:JSON.stringify({hiddenFileIds:s,...t!=null&&{expiresIn:t}}),contentType:"application/json"})).results)}async getHiddenFilesByParent(e,t){return await a(this,c,l).call(this,"GET",`${d}/${e}/${B}`,{...t!=null&&{query:{tag:t}}})}async deleteHiddenFilesByParent(e){return await a(this,c,l).call(this,"DELETE",`${d}/${e}/${B}`)}async uploadItemIcon(e,t){const s=new FormData;return s.append("icon",t),await a(this,c,l).call(this,"PUT",`${d}/${e}/icon`,{body:s})}async getItemIcon(e){return await a(this,c,q).call(this,`${d}/${e}/icon`)}async removeItemIcon(e){return await a(this,c,l).call(this,"DELETE",`${d}/${e}/icon`)}async updateItem(e,t){return await a(this,c,l).call(this,"PUT",`${d}/${e}`,{body:JSON.stringify(t),contentType:"application/json"})}async createVersion(e,t,s,r,i){const o=new FormData;return o.append("file",t),o.append("versionTag",s),r&&o.append("extraProps",JSON.stringify(r)),i&&o.append("metadata",JSON.stringify(i)),await a(this,c,l).call(this,"POST",`${d}/${e}/version`,{body:o})}async listVersions(e,t={}){return await a(this,c,l).call(this,"GET",`${d}/${encodeURIComponent(e)}/versions`,{query:t})}async listVersionsBatch(e,t={}){const{archived:s}=t;return await a(this,c,te).call(this,e,async r=>(await a(this,c,l).call(this,"POST",`${d}/batch/versions`,{body:JSON.stringify({itemIds:r,...s!==void 0&&{archived:s}}),contentType:"application/json"})).results)}async archiveVersion(e,t){return await a(this,c,l).call(this,"PUT",`${d}/${encodeURIComponent(e)}/version/${encodeURIComponent(t)}/archive`)}async recoverVersion(e,t){return await a(this,c,l).call(this,"PUT",`${d}/${encodeURIComponent(e)}/version/${encodeURIComponent(t)}/recover`)}async deleteVersion(e,t){return await a(this,c,l).call(this,"DELETE",`${d}/${encodeURIComponent(e)}/version/${encodeURIComponent(t)}`)}};c=new WeakSet,Be=function(e){return`${this.apiUrl}/${e}`},l=async function(e,t,s){const{body:r,query:i,contentType:o,retries:h,responseType:f,retryAttempt:m}=s||{},y=a(this,c,Be).call(this,t),g=a(this,c,mt).call(this,i),R=await this.resolveAccessToken(),At={...g,...this.useBearer?{}:{accessToken:R}};try{const O=await fetch(y+"?"+new URLSearchParams(At).toString(),{method:e,headers:{Accept:"application/json",...o&&{"Content-Type":o},...this.useBearer&&{Authorization:`Bearer ${R}`}},...r&&{body:r}});if(!O.ok){const j=await O.text().then(ie=>ie).catch(()=>"");throw new we(O.status,O.statusText,j,Os(O))}return f==="blob"?await O.blob():O.json().then(j=>j).catch(()=>{})}catch(O){const j=h??this.retries;if(j>0&&Cs(O)){const ie=m??0;return await Ss(Rs(O,ie)),await a(this,c,l).call(this,e,t,{...s,retries:j-1,retryAttempt:ie+1})}throw O}},q=async function(e,t){const{query:s}=t||{},r=a(this,c,Be).call(this,e),i=await this.resolveAccessToken(),o={...s,...this.useBearer?{}:{accessToken:i}};return await fetch(r+"?"+new URLSearchParams(o).toString(),{method:"GET",...this.useBearer&&{headers:{Authorization:`Bearer ${i}`}}})},te=async function(e,t){if(!e.length)return[];const s=[];for(let i=0;i<e.length;i+=Pe)s.push(e.slice(i,i+Pe));return(await Promise.all(s.map(t))).flat()},le=async function(e,t){const{versionTag:s,withDraft:r}=t||{};return await a(this,c,q).call(this,`${d}/${e}/download`,{query:{...s&&{versionTag:s},...r&&{withDraft:r}}})},fe=async function(e,t,s){const{name:r,versionTag:i,parentFolderId:o,projectId:h,file:f,metadata:m}=e,y=new FormData;return y.append("file",f),y.append("name",r),y.append("versionTag",i),y.append("itemType",t),o&&y.append("folderId",o),h&&y.append("projectId",h),s&&y.append("extraProps",JSON.stringify(s)),m&&y.append("metadata",JSON.stringify(m)),await a(this,c,l).call(this,"POST",d,{body:y})},xe=async function(e,t,s){const{name:r,versionTag:i,parentFolderId:o,file:h,metadata:f}=t;let m,y;if(h){const g=new FormData;g.append("file",h),i&&g.append("versionTag",i),s&&g.append("extraProps",JSON.stringify(s)),f&&g.append("metadata",JSON.stringify(f)),y=await a(this,c,l).call(this,"POST",`${d}/${e}/version`,{body:g})}if(r||o){const g={...r&&{name:r},...o&&{folderId:o}},R=JSON.stringify(g);m=await a(this,c,l).call(this,"PUT",`${d}/${e}`,{body:R,contentType:"application/json"})}return{item:m,version:y}},Ie=async function(e,t){const{showVersions:s=!1}=t||{};return await a(this,c,l).call(this,"GET",`${d}/${e}`,{query:{showVersions:s}})},mt=function(e){return e&&Object.entries(e).filter(([,t])=>t!==void 0).reduce((t,[s,r])=>(t[s]=r,t),{})};let ye=We;function gt(){if(typeof window>"u"||window.parent===window)throw new Error("client.channel only works inside a That Open app, which runs in an iframe of the platform.");return{post:n=>window.parent.postMessage(n,"*"),listen:n=>{const e=t=>{t.source===window.parent&&n(t.data)};return window.addEventListener("message",e),()=>window.removeEventListener("message",e)}}}const Le="channel:",$s=1e4;function de(n){try{n()}catch(e){console.error("[channel] a listener threw:",e)}}var x,k,A,Y,W,K,v,qe,Ue,G;class Ye{constructor(e,t){_(this,v);_(this,x,!1);_(this,k,[]);_(this,A,[]);_(this,Y,new Set);_(this,W,new Set);_(this,K,new Set);this.transport=e,this.controls=t}get joined(){return u(this,x)}get peers(){return u(this,k)}join(){return u(this,x)?Promise.resolve():a(this,v,qe).call(this,"joined",this.controls.join)}leave(){return!u(this,x)&&!u(this,A).some(e=>e.want==="joined")?Promise.resolve():a(this,v,qe).call(this,"left",this.controls.leave)}onChange(e){return u(this,Y).add(e),()=>void u(this,Y).delete(e)}onPeerJoined(e){return u(this,W).add(e),()=>void u(this,W).delete(e)}onPeerLeft(e){return u(this,K).add(e),()=>void u(this,K).delete(e)}applyJoined(){T(this,x,!0),a(this,v,Ue).call(this,"joined"),a(this,v,G).call(this)}applyLeft(){T(this,x,!1),T(this,k,[]),a(this,v,Ue).call(this,"left"),a(this,v,G).call(this)}applyPeers(e){T(this,k,e),a(this,v,G).call(this)}applyPeerJoined(e){!u(this,x)||u(this,k).some(t=>t.from===e.from)||(T(this,k,[...u(this,k),e]),u(this,W).forEach(t=>de(()=>t(e))),a(this,v,G).call(this))}applyPeerLeft(e){const t=u(this,k).find(s=>s.from===e);t&&(T(this,k,u(this,k).filter(s=>s.from!==e)),u(this,K).forEach(s=>de(()=>s(t))),a(this,v,G).call(this))}failPending(e){const t=u(this,A);return T(this,A,[]),t.forEach(s=>{clearTimeout(s.timer),s.reject(e)}),t.length>0}post(e){this.transport.post(e)}}x=new WeakMap,k=new WeakMap,A=new WeakMap,Y=new WeakMap,W=new WeakMap,K=new WeakMap,v=new WeakSet,qe=function(e,t){return new Promise((s,r)=>{const i={want:e,resolve:s,reject:r,timer:setTimeout(()=>{T(this,A,u(this,A).filter(o=>o!==i)),r(new Error(`The platform did not confirm ${e==="joined"?"joining":"leaving"} in time.`))},$s)};u(this,A).push(i),this.transport.post({type:"APP_CHANNEL_CONTROL",...t})})},Ue=function(e){const t=u(this,A).filter(s=>s.want===e);T(this,A,u(this,A).filter(s=>s.want!==e)),t.forEach(s=>{clearTimeout(s.timer),s.resolve()})},G=function(){u(this,Y).forEach(e=>de(e))};var X;class wt extends Ye{constructor(t){super(t,{join:{action:"joinCollab"},leave:{action:"leaveCollab"}});_(this,X,new Map)}on(t,s){const r=u(this,X).get(t)??new Set;return r.add(s),u(this,X).set(t,r),()=>void r.delete(s)}send(t,s){if(t.startsWith(Le))throw new Error(`Message types starting with '${Le}' are reserved.`);this.joined&&this.post({type:"APP_CHANNEL_PUBLISH",message:{type:t,payload:s}})}accepts(t){return t===void 0||t==="collab"}async handle(t){const s=u(this,X).get(t.type);if(!(s!=null&&s.size))return{handled:!1};const r=bt(t);return s.forEach(i=>de(()=>i(t.payload,r))),{handled:!0}}}X=new WeakMap;var U;class _t extends Ye{constructor(t,s){super(t,{join:{action:"joinExternal",kind:s},leave:{action:"leaveExternal",kind:s}});_(this,U,new Map);this.kind=s}on(t,s){if(u(this,U).has(t))throw new Error(`"${t}" already has a handler in this room. Remove it first.`);return u(this,U).set(t,s),()=>void u(this,U).delete(t)}accepts(t,s){return t!==void 0&&t!=="external"?!1:this.kind===void 0||t===void 0||this.kind===s}get hasHandlers(){return u(this,U).size>0}async handle(t){const s=u(this,U).get(t.type);if(!s)return{handled:!1};try{return{handled:!0,value:await s(t.payload,bt(t))}}catch(r){return{handled:!0,error:r instanceof Error?r.message:String(r)}}}}U=new WeakMap;function bt(n){return{from:n.from,at:n.at,requestId:n.requestId,kind:n.kind}}function Ns(n){const e=n;if((e==null?void 0:e.type)!=="THATOPEN_CHANNEL_MESSAGE")return null;const t=e.message;return!t||typeof t.type!="string"?null:{type:t.type,requestId:typeof t.requestId=="string"?t.requestId:void 0,payload:t.payload,at:typeof t.at=="number"?t.at:Date.now(),from:typeof t.from=="string"?t.from:"",scope:t.scope==="collab"||t.scope==="external"?t.scope:void 0,kind:typeof t.kind=="string"?t.kind:void 0}}var H,ne,I,D,F,b,De,pe,Et,vt,kt,Fe;class Tt{constructor(e){_(this,b);_(this,H);_(this,ne);_(this,I);_(this,D,new Map);_(this,F,new Set);T(this,H,e),T(this,ne,e.listen(t=>void a(this,b,Et).call(this,t)))}collab(){return u(this,I)??T(this,I,new wt(u(this,H))),u(this,I)}external(e){const t=e??"";let s=u(this,D).get(t);return s||(s=new _t(u(this,H),e),u(this,D).set(t,s)),s}dispose(){u(this,ne).call(this)}}H=new WeakMap,ne=new WeakMap,I=new WeakMap,D=new WeakMap,F=new WeakMap,b=new WeakSet,De=function(){return[...u(this,I)?[u(this,I)]:[],...u(this,D).values()]},pe=function(e,t){if(e==="collab")return u(this,I);if(e==="external")return u(this,D).get(typeof t=="string"?t:"")},Et=async function(e){const t=Ns(e);if(t){if(t.type.startsWith(Le)){a(this,b,vt).call(this,t);return}await a(this,b,kt).call(this,t)}},vt=function(e){var s,r,i;const t=e.payload??{};switch(e.type){case"channel:joined":(s=a(this,b,pe).call(this,t.scope,t.kind))==null||s.applyJoined();break;case"channel:left":(r=a(this,b,pe).call(this,t.scope,t.kind))==null||r.applyLeft();break;case"channel:peers":(i=a(this,b,pe).call(this,t.scope,t.kind))==null||i.applyPeers(t.peers??[]);break;case"channel:peer-joined":case"channel:peer-left":{if(!t.from)break;const o=t.scope==="collab"?[u(this,I)]:[...u(this,D).values()].filter(h=>h.accepts("external",t.kind));for(const h of o)e.type==="channel:peer-joined"?h==null||h.applyPeerJoined({from:t.from,kind:t.kind}):h==null||h.applyPeerLeft(t.from);break}case"channel:error":{const o=new Error(String(e.payload));a(this,b,De).call(this).map(f=>f.failPending(o)).some(Boolean)||console.error("[channel] error:",e.payload);break}}},kt=async function(e){const t=a(this,b,De).call(this).filter(i=>i.accepts(e.scope,e.kind));let s=!1;for(const i of t){const o=await i.handle(e);o.handled&&(s=!0,e.requestId&&a(this,b,Fe).call(this,e.requestId,o))}e.requestId&&e.scope==="external"&&t.length>0&&!s&&a(this,b,Fe).call(this,e.requestId,{handled:!0,error:`No handler for "${e.type}".`})},Fe=function(e,t){u(this,F).has(e)||(u(this,F).add(e),u(this,F).size>500&&u(this,F).delete(u(this,F).values().next().value),u(this,H).post({type:"APP_CHANNEL_PUBLISH",message:{type:t.error===void 0?"reply":"reply-error",requestId:e,payload:t.error===void 0?t.value:{error:t.error}}}))};const V="project",J="notifications";var z,re;const Ke=class Ke extends ye{constructor(t,s,r){super(typeof t=="string"?t:"",s,{...r,useBearer:!0});_(this,z);_(this,re);typeof t=="function"&&T(this,z,t)}async resolveAccessToken(){return u(this,z)?await u(this,z).call(this):super.resolveAccessToken()}static fromPlatformContext(t){const s=(typeof window<"u"?window.__THATOPEN_CONTEXT__:null)||{appId:"",projectId:"",accessToken:"",apiUrl:""},r=new Ke(s.accessToken,s.apiUrl,t);return r.context=s,r}get channel(){return u(this,re)??T(this,re,new Tt(gt())),u(this,re)}async getProject(t){return await this.request("GET",`${V}/${t}`)}async getProjectData(t){return await this.request("GET",`${V}/${t}/data`)}async getAvatar(t){return await this.request("GET",`account/${t}/avatar`,{responseType:"blob"})}async checkPermission(t){return await this.request("GET",`${V}/permissions/check`,{query:t})}async checkPermissionBatch(t){return(await this.request("POST",`${V}/permissions/check/batch`,{body:JSON.stringify({checks:t}),contentType:"application/json"})).results}async getNotifications(t){return await this.request("GET",J,{query:{...(t==null?void 0:t.cursor)!==void 0&&{cursor:t.cursor},...(t==null?void 0:t.limit)!==void 0&&{limit:String(t.limit)}}})}async getUnreadNotificationCount(){return(await this.request("GET",`${J}/unread-count`)).count}async markNotificationsRead(t){return await this.request("POST",`${J}/mark-read`,{body:JSON.stringify({ids:t}),contentType:"application/json"})}async markAllNotificationsRead(){return await this.request("POST",`${J}/mark-all-read`)}async getNotificationSubscriptions(){return await this.request("GET",`${J}/subscriptions`)}async unsubscribeFromAutomation(t){return await this.request("DELETE",`${J}/subscriptions/${t}`)}async subscribeToAutomation(t,s,r){return await this.request("POST",`${V}/${t}/events/hooks/${s}/subscription`,{body:JSON.stringify(r??{}),contentType:"application/json"})}async updateAutomationSubscription(t,s,r){return await this.request("PATCH",`${V}/${t}/events/hooks/${s}/subscription`,{body:JSON.stringify(r),contentType:"application/json"})}async onNotification(t){const s=await this.resolveAccessToken(),r=se(`${this.socketOrigin}/notifications?accessToken=${encodeURIComponent(s)}`,{transports:["websocket"]});return r.on("notification.created",i=>t({type:"created",id:i==null?void 0:i.id})),r.on("notification.read",i=>t({type:"read",id:i==null?void 0:i.id})),r.on("notifications.allRead",i=>t({type:"allRead",batch:i==null?void 0:i.batch})),()=>r.disconnect()}};z=new WeakMap,re=new WeakMap;let Me=Ke;const Ps={MAX_FIELDS:200,MAX_KEY_LENGTH:50,MAX_VALUE_LENGTH:50},Bs={uuid:"a3f82c1d-5b74-4e9a-bc30-d7e12f894a61"},xs={uuid:"2c9f4e8d-3a1b-4c5e-9d7f-0a2b6c8e1d3f"},Is={uuid:"b0b5e2a2-0b3a-4a6b-8b1c-0b1c4a6b8b1c"},Ls={uuid:"3f9c1a7e-6b2d-4e18-9a5c-7d0e2f4b6c81"},qs={uuid:"2c4ae432-fc24-43e9-9783-0c960c674e96"},Us={uuid:"6f3a9c2e-8b1d-4e6a-9c3f-1d7b5a8e2c4f"},Ds={uuid:"69af63aa-19ba-4fc7-b17b-75647bac1d76"},Fs={uuid:"234f1416-528d-452a-9cc9-a16c5239b2eb"};exports.CDEManager=Bs;exports.ChannelClient=Tt;exports.ChannelRoom=Ye;exports.ClashesManager=xs;exports.CollabRoom=wt;exports.EngineServicesClient=ye;exports.ExternalRoom=_t;exports.FileList=Is;exports.GitHistoryManager=Ls;exports.HelloWorld=qs;exports.METADATA_LIMITS=Ps;exports.PlatformClient=Me;exports.ProjectManager=Us;exports.RequestError=we;exports.STORAGE_BATCH_MAX=Pe;exports.TopicsManager=Ds;exports.UIManager=Fs;exports.windowTransport=gt;
|
|
2
|
+
return main;`)(...h),y=(m==null?void 0:m.componentDefinition)??m;t.get(y)}async initBuiltInComponents(e,...t){await Promise.all(t.map(s=>this.initBuiltInComponent(s,e)))}async setup(e,...t){var o,h;const s=e.OBC,r=e.BUI;if(!(s!=null&&s.Components))throw new Error("globals.OBC must include Components");if(!(r!=null&&r.Manager))throw new Error("globals.BUI must include Manager");const i=new s.Components;return r.Manager.init(),this.setBuiltInGlobals(e),await this.initBuiltInComponents(i,...t),i.init(),(h=(o=this.context.appEventOrchestrator)==null?void 0:o.appLoaded)==null||h.call(o),{components:i}}throwError(e,t){var s,r;(r=(s=this.context.appEventOrchestrator)==null?void 0:s.appError)==null||r.call(s,e,t)}async listApps(e){const{folderId:t,ShowVersions:s,projectId:r}=e||{};return t?await a(this,c,l).call(this,"GET",`${$}/${t}/items`,{query:{itemType:Ae,...s&&{ShowVersions:s}}}):await a(this,c,l).call(this,"GET",`${d}`,{query:{itemType:Ae,...s&&{ShowVersions:s},...r&&{projectId:r}}})}async createApp(e){const{appProps:t}=e;return await a(this,c,fe).call(this,e,Ae,t)}async downloadApp(e,t){return await a(this,c,le).call(this,e,t)}async downloadAppBundle(e,t){const{versionTag:s,withDraft:r}=t||{};return await a(this,c,q).call(this,`${d}/${e}/download/bundle`,{query:{...s&&{versionTag:s},...r&&{withDraft:r}}})}async archiveApp(e){return await a(this,c,l).call(this,"DELETE",`${d}/${e}`)}async getNpmCredentials(){return await a(this,c,l).call(this,"GET",`${vs}/credentials`)}async executeComponent(e,t,s){if(this.localServerUrl){const r=`${this.localServerUrl}/api/${L}/${e}/execute`,i=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!i.ok){const o=await i.text().catch(()=>"");throw new Error(`Local server request failed: ${i.status} - ${o}`)}return await i.json()}return await a(this,c,l).call(this,"POST",`${L}/${e}/execute`,{body:JSON.stringify(t),query:{...s&&{versionTag:s}},contentType:"application/json"})}async abortExecution(e){if(this.localServerUrl){const t=`${this.localServerUrl}/api/${L}/progress/${e}/abort`,s=await fetch(t,{method:"POST"});if(!s.ok){const r=await s.text().catch(()=>"");throw new Error(`Local server request failed: ${s.status} - ${r}`)}return await s.json()}return await a(this,c,l).call(this,"POST",`${L}/progress/${e}/abort`)}async listExecutions(e,t){if(this.localServerUrl){const s=t?`?projectId=${encodeURIComponent(t)}`:"",r=`${this.localServerUrl}/api/${L}/${e}/progress${s}`,i=await fetch(r);if(!i.ok){const o=await i.text().catch(()=>"");throw new Error(`Local server request failed: ${i.status} - ${o}`)}return await i.json()}return await a(this,c,l).call(this,"GET",`${L}/${e}/progress`,{query:{...t&&{projectId:t}}})}async getExecution(e){if(this.localServerUrl){const t=`${this.localServerUrl}/api/${L}/progress/${e}`,s=await fetch(t);if(!s.ok){const r=await s.text().catch(()=>"");throw new Error(`Local server request failed: ${s.status} - ${r}`)}return await s.json()}return await a(this,c,l).call(this,"GET",`${L}/progress/${e}`)}async onExecutionProgress(e,t){const s=this.localServerUrl?`${this.localServerUrl}?accessToken=${this.accessToken}`:this.wsUrl,r=await se(s,{...this.localServerUrl&&{transports:["websocket"]}});r.on("connect",function(){r.emit("executionSubscription",JSON.stringify({executionId:e})),r.on("execution",i=>{t(i)})}),r.on("connect_error",function(i){console.log(i)})}async createHiddenFile(e,t,s){const r=new FormData;return r.append("file",e),r.append("parentItemId",t),s!=null&&r.append("tag",s),await a(this,c,l).call(this,"POST",`${d}/${B}`,{body:r})}async createHiddenFilesBatch(e,t,s){const r=new FormData;for(const i of e)r.append("files",i);return r.append("parentItemId",t),s!=null&&r.append("tag",s),await a(this,c,l).call(this,"POST",`${d}/${B}/batch`,{body:r})}async deleteHiddenFile(e){return await a(this,c,l).call(this,"DELETE",`${d}/${B}/${e}`)}async getHiddenFile(e){return await a(this,c,l).call(this,"GET",`${d}/${B}/${e}`)}async downloadHiddenFile(e){return await a(this,c,q).call(this,`${d}/${B}/${e}/download`)}async getHiddenFileSignedUrl(e,t){return await a(this,c,l).call(this,"GET",`${d}/${B}/${e}/signed-url`,{...t!=null&&{query:{expiresIn:t}}})}async getHiddenFileSignedUrlsBatch(e,t){return await a(this,c,te).call(this,e,async s=>(await a(this,c,l).call(this,"POST",`${d}/${B}/signed-url/batch`,{body:JSON.stringify({hiddenFileIds:s,...t!=null&&{expiresIn:t}}),contentType:"application/json"})).results)}async getHiddenFilesByParent(e,t){return await a(this,c,l).call(this,"GET",`${d}/${e}/${B}`,{...t!=null&&{query:{tag:t}}})}async deleteHiddenFilesByParent(e){return await a(this,c,l).call(this,"DELETE",`${d}/${e}/${B}`)}async uploadItemIcon(e,t){const s=new FormData;return s.append("icon",t),await a(this,c,l).call(this,"PUT",`${d}/${e}/icon`,{body:s})}async getItemIcon(e){return await a(this,c,q).call(this,`${d}/${e}/icon`)}async removeItemIcon(e){return await a(this,c,l).call(this,"DELETE",`${d}/${e}/icon`)}async updateItem(e,t){return await a(this,c,l).call(this,"PUT",`${d}/${e}`,{body:JSON.stringify(t),contentType:"application/json"})}async createVersion(e,t,s,r,i){const o=new FormData;return o.append("file",t),o.append("versionTag",s),r&&o.append("extraProps",JSON.stringify(r)),i&&o.append("metadata",JSON.stringify(i)),await a(this,c,l).call(this,"POST",`${d}/${e}/version`,{body:o})}async listVersions(e,t={}){return await a(this,c,l).call(this,"GET",`${d}/${encodeURIComponent(e)}/versions`,{query:t})}async listVersionsBatch(e,t={}){const{archived:s}=t;return await a(this,c,te).call(this,e,async r=>(await a(this,c,l).call(this,"POST",`${d}/batch/versions`,{body:JSON.stringify({itemIds:r,...s!==void 0&&{archived:s}}),contentType:"application/json"})).results)}async archiveVersion(e,t){return await a(this,c,l).call(this,"PUT",`${d}/${encodeURIComponent(e)}/version/${encodeURIComponent(t)}/archive`)}async recoverVersion(e,t){return await a(this,c,l).call(this,"PUT",`${d}/${encodeURIComponent(e)}/version/${encodeURIComponent(t)}/recover`)}async deleteVersion(e,t){return await a(this,c,l).call(this,"DELETE",`${d}/${encodeURIComponent(e)}/version/${encodeURIComponent(t)}`)}};c=new WeakSet,Be=function(e){return`${this.apiUrl}/${e}`},l=async function(e,t,s){const{body:r,query:i,contentType:o,retries:h,responseType:f,retryAttempt:m}=s||{},y=a(this,c,Be).call(this,t),g=a(this,c,mt).call(this,i),R=await this.resolveAccessToken(),At={...g,...this.useBearer?{}:{accessToken:R}};try{const O=await fetch(y+"?"+new URLSearchParams(At).toString(),{method:e,headers:{Accept:"application/json",...o&&{"Content-Type":o},...this.useBearer&&{Authorization:`Bearer ${R}`}},...r&&{body:r}});if(!O.ok){const j=await O.text().then(ie=>ie).catch(()=>"");throw new we(O.status,O.statusText,j,Os(O))}return f==="blob"?await O.blob():O.json().then(j=>j).catch(()=>{})}catch(O){const j=h??this.retries;if(j>0&&Cs(O)){const ie=m??0;return await Ss(Rs(O,ie)),await a(this,c,l).call(this,e,t,{...s,retries:j-1,retryAttempt:ie+1})}throw O}},q=async function(e,t){const{query:s}=t||{},r=a(this,c,Be).call(this,e),i=await this.resolveAccessToken(),o={...s,...this.useBearer?{}:{accessToken:i}};return await fetch(r+"?"+new URLSearchParams(o).toString(),{method:"GET",...this.useBearer&&{headers:{Authorization:`Bearer ${i}`}}})},te=async function(e,t){if(!e.length)return[];const s=[];for(let i=0;i<e.length;i+=Pe)s.push(e.slice(i,i+Pe));return(await Promise.all(s.map(t))).flat()},le=async function(e,t){const{versionTag:s,withDraft:r}=t||{};return await a(this,c,q).call(this,`${d}/${e}/download`,{query:{...s&&{versionTag:s},...r&&{withDraft:r}}})},fe=async function(e,t,s){const{name:r,versionTag:i,parentFolderId:o,projectId:h,file:f,metadata:m}=e,y=new FormData;return y.append("file",f),y.append("name",r),y.append("versionTag",i),y.append("itemType",t),o&&y.append("folderId",o),h&&y.append("projectId",h),s&&y.append("extraProps",JSON.stringify(s)),m&&y.append("metadata",JSON.stringify(m)),await a(this,c,l).call(this,"POST",d,{body:y})},xe=async function(e,t,s){const{name:r,versionTag:i,parentFolderId:o,file:h,metadata:f}=t;let m,y;if(h){const g=new FormData;g.append("file",h),i&&g.append("versionTag",i),s&&g.append("extraProps",JSON.stringify(s)),f&&g.append("metadata",JSON.stringify(f)),y=await a(this,c,l).call(this,"POST",`${d}/${e}/version`,{body:g})}if(r||o){const g={...r&&{name:r},...o&&{folderId:o}},R=JSON.stringify(g);m=await a(this,c,l).call(this,"PUT",`${d}/${e}`,{body:R,contentType:"application/json"})}return{item:m,version:y}},Ie=async function(e,t){const{showVersions:s=!1}=t||{};return await a(this,c,l).call(this,"GET",`${d}/${e}`,{query:{showVersions:s}})},mt=function(e){return e&&Object.entries(e).filter(([,t])=>t!==void 0).reduce((t,[s,r])=>(t[s]=r,t),{})};let ye=We;function gt(){if(typeof window>"u"||window.parent===window)throw new Error("client.channel only works inside a That Open app, which runs in an iframe of the platform.");return{post:n=>window.parent.postMessage(n,"*"),listen:n=>{const e=t=>{t.source===window.parent&&n(t.data)};return window.addEventListener("message",e),()=>window.removeEventListener("message",e)}}}const Le="channel:",$s=1e4;function de(n){try{n()}catch(e){console.error("[channel] a listener threw:",e)}}var x,k,A,Y,W,K,v,qe,Ue,G;class Ye{constructor(e,t){_(this,v);_(this,x,!1);_(this,k,[]);_(this,A,[]);_(this,Y,new Set);_(this,W,new Set);_(this,K,new Set);this.transport=e,this.controls=t}get joined(){return u(this,x)}get peers(){return u(this,k)}join(){return u(this,x)?Promise.resolve():a(this,v,qe).call(this,"joined",this.controls.join)}leave(){return!u(this,x)&&!u(this,A).some(e=>e.want==="joined")?Promise.resolve():a(this,v,qe).call(this,"left",this.controls.leave)}onChange(e){return u(this,Y).add(e),()=>void u(this,Y).delete(e)}onPeerJoined(e){return u(this,W).add(e),()=>void u(this,W).delete(e)}onPeerLeft(e){return u(this,K).add(e),()=>void u(this,K).delete(e)}applyJoined(){T(this,x,!0),a(this,v,Ue).call(this,"joined"),a(this,v,G).call(this)}applyLeft(){T(this,x,!1),T(this,k,[]),a(this,v,Ue).call(this,"left"),a(this,v,G).call(this)}applyPeers(e){T(this,k,e),a(this,v,G).call(this)}applyPeerJoined(e){!u(this,x)||u(this,k).some(t=>t.from===e.from)||(T(this,k,[...u(this,k),e]),u(this,W).forEach(t=>de(()=>t(e))),a(this,v,G).call(this))}applyPeerLeft(e){const t=u(this,k).find(s=>s.from===e);t&&(T(this,k,u(this,k).filter(s=>s.from!==e)),u(this,K).forEach(s=>de(()=>s(t))),a(this,v,G).call(this))}failPending(e){const t=u(this,A);return T(this,A,[]),t.forEach(s=>{clearTimeout(s.timer),s.reject(e)}),t.length>0}post(e){this.transport.post(e)}}x=new WeakMap,k=new WeakMap,A=new WeakMap,Y=new WeakMap,W=new WeakMap,K=new WeakMap,v=new WeakSet,qe=function(e,t){return new Promise((s,r)=>{const i={want:e,resolve:s,reject:r,timer:setTimeout(()=>{T(this,A,u(this,A).filter(o=>o!==i)),r(new Error(`The platform did not confirm ${e==="joined"?"joining":"leaving"} in time.`))},$s)};u(this,A).push(i),this.transport.post({type:"APP_CHANNEL_CONTROL",...t})})},Ue=function(e){const t=u(this,A).filter(s=>s.want===e);T(this,A,u(this,A).filter(s=>s.want!==e)),t.forEach(s=>{clearTimeout(s.timer),s.resolve()})},G=function(){u(this,Y).forEach(e=>de(e))};var X;class wt extends Ye{constructor(t){super(t,{join:{action:"joinCollab"},leave:{action:"leaveCollab"}});_(this,X,new Map)}on(t,s){const r=u(this,X).get(t)??new Set;return r.add(s),u(this,X).set(t,r),()=>void r.delete(s)}send(t,s){if(t.startsWith(Le))throw new Error(`Message types starting with '${Le}' are reserved.`);this.joined&&this.post({type:"APP_CHANNEL_PUBLISH",message:{type:t,payload:s}})}accepts(t){return t===void 0||t==="collab"}async handle(t){const s=u(this,X).get(t.type);if(!(s!=null&&s.size))return{handled:!1};const r=bt(t);return s.forEach(i=>de(()=>i(t.payload,r))),{handled:!0}}}X=new WeakMap;var U;class _t extends Ye{constructor(t,s){super(t,{join:{action:"joinExternal",kind:s},leave:{action:"leaveExternal",kind:s}});_(this,U,new Map);this.kind=s}on(t,s){if(u(this,U).has(t))throw new Error(`"${t}" already has a handler in this room. Remove it first.`);return u(this,U).set(t,s),()=>void u(this,U).delete(t)}accepts(t,s){return t!==void 0&&t!=="external"?!1:this.kind===void 0||t===void 0||this.kind===s}get hasHandlers(){return u(this,U).size>0}async handle(t){const s=u(this,U).get(t.type);if(!s)return{handled:!1};try{return{handled:!0,value:await s(t.payload,bt(t))}}catch(r){return{handled:!0,error:r instanceof Error?r.message:String(r)}}}}U=new WeakMap;function bt(n){return{from:n.from,at:n.at,requestId:n.requestId,kind:n.kind}}function Ns(n){const e=n;if((e==null?void 0:e.type)!=="THATOPEN_CHANNEL_MESSAGE")return null;const t=e.message;return!t||typeof t.type!="string"?null:{type:t.type,requestId:typeof t.requestId=="string"?t.requestId:void 0,payload:t.payload,at:typeof t.at=="number"?t.at:Date.now(),from:typeof t.from=="string"?t.from:"",scope:t.scope==="collab"||t.scope==="external"?t.scope:void 0,kind:typeof t.kind=="string"?t.kind:void 0}}var H,ne,I,D,F,b,De,pe,Et,vt,kt,Fe;class Tt{constructor(e){_(this,b);_(this,H);_(this,ne);_(this,I);_(this,D,new Map);_(this,F,new Set);T(this,H,e),T(this,ne,e.listen(t=>void a(this,b,Et).call(this,t)))}collab(){return u(this,I)??T(this,I,new wt(u(this,H))),u(this,I)}external(e){const t=e??"";let s=u(this,D).get(t);return s||(s=new _t(u(this,H),e),u(this,D).set(t,s)),s}dispose(){u(this,ne).call(this)}}H=new WeakMap,ne=new WeakMap,I=new WeakMap,D=new WeakMap,F=new WeakMap,b=new WeakSet,De=function(){return[...u(this,I)?[u(this,I)]:[],...u(this,D).values()]},pe=function(e,t){if(e==="collab")return u(this,I);if(e==="external")return u(this,D).get(typeof t=="string"?t:"")},Et=async function(e){const t=Ns(e);if(t){if(t.type.startsWith(Le)){a(this,b,vt).call(this,t);return}await a(this,b,kt).call(this,t)}},vt=function(e){var s,r,i;const t=e.payload??{};switch(e.type){case"channel:joined":(s=a(this,b,pe).call(this,t.scope,t.kind))==null||s.applyJoined();break;case"channel:left":(r=a(this,b,pe).call(this,t.scope,t.kind))==null||r.applyLeft();break;case"channel:peers":(i=a(this,b,pe).call(this,t.scope,t.kind))==null||i.applyPeers(t.peers??[]);break;case"channel:peer-joined":case"channel:peer-left":{if(!t.from)break;const o=t.scope==="collab"?[u(this,I)]:[...u(this,D).values()].filter(h=>h.accepts("external",t.kind));for(const h of o)e.type==="channel:peer-joined"?h==null||h.applyPeerJoined({from:t.from,kind:t.kind}):h==null||h.applyPeerLeft(t.from);break}case"channel:error":{const o=new Error(String(e.payload));a(this,b,De).call(this).map(f=>f.failPending(o)).some(Boolean)||console.error("[channel] error:",e.payload);break}}},kt=async function(e){const t=a(this,b,De).call(this).filter(i=>i.accepts(e.scope,e.kind));let s=!1;for(const i of t){const o=await i.handle(e);o.handled&&(s=!0,e.requestId&&a(this,b,Fe).call(this,e.requestId,o))}e.requestId&&e.scope==="external"&&t.length>0&&!s&&a(this,b,Fe).call(this,e.requestId,{handled:!0,error:`No handler for "${e.type}".`})},Fe=function(e,t){u(this,F).has(e)||(u(this,F).add(e),u(this,F).size>500&&u(this,F).delete(u(this,F).values().next().value),u(this,H).post({type:"APP_CHANNEL_PUBLISH",message:{type:t.error===void 0?"reply":"reply-error",requestId:e,payload:t.error===void 0?t.value:{error:t.error}}}))};const V="project",J="notifications";var z,re;const Ke=class Ke extends ye{constructor(t,s,r){super(typeof t=="string"?t:"",s,{...r,useBearer:!0});_(this,z);_(this,re);typeof t=="function"&&T(this,z,t)}async resolveAccessToken(){return u(this,z)?await u(this,z).call(this):super.resolveAccessToken()}static fromPlatformContext(t){const s=(typeof window<"u"?window.__THATOPEN_CONTEXT__:null)||{appId:"",projectId:"",accessToken:"",apiUrl:""},r=new Ke(s.accessToken,s.apiUrl,t);return r.context=s,r}get channel(){return u(this,re)??T(this,re,new Tt(gt())),u(this,re)}async getProject(t){return await this.request("GET",`${V}/${t}`)}async getProjectData(t){return await this.request("GET",`${V}/${t}/data`)}async getAvatar(t){return await this.request("GET",`account/${t}/avatar`,{responseType:"blob"})}async checkPermission(t){return await this.request("GET",`${V}/permissions/check`,{query:t})}async checkPermissionBatch(t){return(await this.request("POST",`${V}/permissions/check/batch`,{body:JSON.stringify({checks:t}),contentType:"application/json"})).results}async getNotifications(t){return await this.request("GET",J,{query:{...(t==null?void 0:t.cursor)!==void 0&&{cursor:t.cursor},...(t==null?void 0:t.limit)!==void 0&&{limit:String(t.limit)}}})}async getUnreadNotificationCount(){return(await this.request("GET",`${J}/unread-count`)).count}async markNotificationsRead(t){return await this.request("POST",`${J}/mark-read`,{body:JSON.stringify({ids:t}),contentType:"application/json"})}async markAllNotificationsRead(){return await this.request("POST",`${J}/mark-all-read`)}async getNotificationSubscriptions(){return await this.request("GET",`${J}/subscriptions`)}async unsubscribeFromAutomation(t){return await this.request("DELETE",`${J}/subscriptions/${t}`)}async subscribeToAutomation(t,s,r){return await this.request("POST",`${V}/${t}/events/hooks/${s}/subscription`,{body:JSON.stringify(r??{}),contentType:"application/json"})}async updateAutomationSubscription(t,s,r){return await this.request("PATCH",`${V}/${t}/events/hooks/${s}/subscription`,{body:JSON.stringify(r),contentType:"application/json"})}async onNotification(t){const s=await this.resolveAccessToken(),r=se(`${this.socketOrigin}/notifications?accessToken=${encodeURIComponent(s)}`,{transports:["websocket"]});return r.on("notification.created",i=>t({type:"created",id:i==null?void 0:i.id})),r.on("notification.read",i=>t({type:"read",id:i==null?void 0:i.id})),r.on("notifications.allRead",i=>t({type:"allRead",batch:i==null?void 0:i.batch})),()=>r.disconnect()}};z=new WeakMap,re=new WeakMap;let Me=Ke;const Ps={MAX_FIELDS:200,MAX_KEY_LENGTH:50,MAX_VALUE_LENGTH:50},Bs={uuid:"a3f82c1d-5b74-4e9a-bc30-d7e12f894a61"},xs={uuid:"2c9f4e8d-3a1b-4c5e-9d7f-0a2b6c8e1d3f"},Is={uuid:"b0b5e2a2-0b3a-4a6b-8b1c-0b1c4a6b8b1c"},Ls={uuid:"d8f3a1c2-6b4e-4f9a-8c1d-2e7b5a9f3c60"},qs={uuid:"3f9c1a7e-6b2d-4e18-9a5c-7d0e2f4b6c81"},Us={uuid:"2c4ae432-fc24-43e9-9783-0c960c674e96"},Ds={uuid:"6f3a9c2e-8b1d-4e6a-9c3f-1d7b5a8e2c4f"},Fs={uuid:"69af63aa-19ba-4fc7-b17b-75647bac1d76"},Ms={uuid:"234f1416-528d-452a-9cc9-a16c5239b2eb"};exports.CDEManager=Bs;exports.ChannelClient=Tt;exports.ChannelRoom=Ye;exports.ClashesManager=xs;exports.CollabRoom=wt;exports.EngineServicesClient=ye;exports.ExternalRoom=_t;exports.FileList=Is;exports.GISManager=Ls;exports.GitHistoryManager=qs;exports.HelloWorld=Us;exports.METADATA_LIMITS=Ps;exports.PlatformClient=Me;exports.ProjectManager=Ds;exports.RequestError=we;exports.STORAGE_BATCH_MAX=Pe;exports.TopicsManager=Fs;exports.UIManager=Ms;exports.windowTransport=gt;
|
package/dist/index.es.js
CHANGED
|
@@ -4049,7 +4049,7 @@ const xs = {
|
|
|
4049
4049
|
MAX_FIELDS: 200,
|
|
4050
4050
|
MAX_KEY_LENGTH: 50,
|
|
4051
4051
|
MAX_VALUE_LENGTH: 50
|
|
4052
|
-
}, Is = { uuid: "a3f82c1d-5b74-4e9a-bc30-d7e12f894a61" }, Ls = { uuid: "2c9f4e8d-3a1b-4c5e-9d7f-0a2b6c8e1d3f" }, qs = { uuid: "b0b5e2a2-0b3a-4a6b-8b1c-0b1c4a6b8b1c" }, Us = { uuid: "3f9c1a7e-6b2d-4e18-9a5c-7d0e2f4b6c81" },
|
|
4052
|
+
}, Is = { uuid: "a3f82c1d-5b74-4e9a-bc30-d7e12f894a61" }, Ls = { uuid: "2c9f4e8d-3a1b-4c5e-9d7f-0a2b6c8e1d3f" }, qs = { uuid: "b0b5e2a2-0b3a-4a6b-8b1c-0b1c4a6b8b1c" }, Us = { uuid: "d8f3a1c2-6b4e-4f9a-8c1d-2e7b5a9f3c60" }, Ds = { uuid: "3f9c1a7e-6b2d-4e18-9a5c-7d0e2f4b6c81" }, Fs = { uuid: "2c4ae432-fc24-43e9-9783-0c960c674e96" }, Ms = { uuid: "6f3a9c2e-8b1d-4e6a-9c3f-1d7b5a8e2c4f" }, Hs = { uuid: "69af63aa-19ba-4fc7-b17b-75647bac1d76" }, js = { uuid: "234f1416-528d-452a-9cc9-a16c5239b2eb" };
|
|
4053
4053
|
export {
|
|
4054
4054
|
Is as CDEManager,
|
|
4055
4055
|
Ns as ChannelClient,
|
|
@@ -4059,14 +4059,15 @@ export {
|
|
|
4059
4059
|
Ce as EngineServicesClient,
|
|
4060
4060
|
Rs as ExternalRoom,
|
|
4061
4061
|
qs as FileList,
|
|
4062
|
-
Us as
|
|
4063
|
-
Ds as
|
|
4062
|
+
Us as GISManager,
|
|
4063
|
+
Ds as GitHistoryManager,
|
|
4064
|
+
Fs as HelloWorld,
|
|
4064
4065
|
xs as METADATA_LIMITS,
|
|
4065
4066
|
tt as PlatformClient,
|
|
4066
|
-
|
|
4067
|
+
Ms as ProjectManager,
|
|
4067
4068
|
Ve as RequestError,
|
|
4068
4069
|
Ze as STORAGE_BATCH_MAX,
|
|
4069
|
-
|
|
4070
|
-
|
|
4070
|
+
Hs as TopicsManager,
|
|
4071
|
+
js as UIManager,
|
|
4071
4072
|
Ss as windowTransport
|
|
4072
4073
|
};
|
package/docs/builtin/paths.json
CHANGED
|
@@ -39,6 +39,10 @@
|
|
|
39
39
|
"path": "src/built-in/ClashesManager/example.ts",
|
|
40
40
|
"description": "ClashesManager β Structural engineers and BIM coordinators routinely detect geometric clashes between disciplines β structural steel penetrating ductwork, pipes clashing with slabs β and need to track the status of each issue through resolution without leaving their BIM environment."
|
|
41
41
|
},
|
|
42
|
+
{
|
|
43
|
+
"path": "src/built-in/GISManager/example.ts",
|
|
44
|
+
"description": "GISManager β Georeferenced BIM projects need their surroundings: the real terrain and buildings around the model, and the project's GIS layers (parcels, networks, boundaries) drawn at the right place in the 3D scene and on a 2D map."
|
|
45
|
+
},
|
|
42
46
|
{
|
|
43
47
|
"path": "src/built-in/ProjectManager/example.ts",
|
|
44
48
|
"description": "ProjectManager β Project-level configuration and data β GIS origin, georeferencing, app settings, and other project-scoped concerns β need a single canonical place to live. Without it, every builtin that needs to persist something at the project level (not per-file, not per-user) ends up inventing its own file, its own save/load pattern, and its own place to put it."
|
|
@@ -87,10 +91,22 @@
|
|
|
87
91
|
"path": "src/built-in/UIManager/src/clashes-panel/example.ts",
|
|
88
92
|
"description": "clashes-panel β BIM coordinators need a dedicated review environment where they can see all detected clashes, filter by status, navigate to each issue in the 3D viewer, and mark items as resolved β without writing any UI code themselves."
|
|
89
93
|
},
|
|
94
|
+
{
|
|
95
|
+
"path": "src/built-in/UIManager/src/gis-panel/example.ts",
|
|
96
|
+
"description": "gis-panel β A georeferenced project is much easier to review with its real surroundings around the model, and with the GIS layers of the site (networks, parcels, boundaries) switched on and off from a list. Streaming the terrain and buildings needs a Cesium Ion token and a way to load and unload them, and fine-tuning their position needs a few controls."
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"path": "src/built-in/UIManager/src/gis-properties-panel/example.ts",
|
|
100
|
+
"description": "gis-properties-panel β A GIS feature (a pipe, a parcel, a manhole) is useless without its attributes: diameter, material, owner, installation date. Users want to click a feature, in the 3D view or on the map, and read them."
|
|
101
|
+
},
|
|
90
102
|
{
|
|
91
103
|
"path": "src/built-in/UIManager/src/git-history-panel/example.ts",
|
|
92
104
|
"description": "git-history-panel β `top-git-history` is a GitKraken-style commit timeline for the **revit-flow** feature. It lists the commits pushed by the Revit add-in (newest first) and, when you click a commit, drives the shared 3D viewer to color that commit's changed elements β created green, modified blue, deleted red β on the loaded baseline model."
|
|
93
105
|
},
|
|
106
|
+
{
|
|
107
|
+
"path": "src/built-in/UIManager/src/map-panel/example.ts",
|
|
108
|
+
"description": "map-panel β In a large site, the 3D camera alone is a poor way to get oriented: users want a plan view to see where they are, where the GIS features are, and to jump somewhere else with a click."
|
|
109
|
+
},
|
|
94
110
|
{
|
|
95
111
|
"path": "src/built-in/UIManager/src/models-list/example.ts",
|
|
96
112
|
"description": "top-models-list β top-models-list is the project's 3D-viewable-files tree: it mirrors the real storage folder structure, converts IFC to fragments, and loads `.frag`/`.potree`/`.splat` models into the 3D scene. Its loaders are PLUGGABLE β the panel owns the UI and the orchestration (progress, refresh, association), but the HOST decides how each extra file format is loaded, so you can teach it new formats without forking the built-in."
|
package/package.json
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"access": "public"
|
|
16
16
|
},
|
|
17
17
|
"private": false,
|
|
18
|
-
"version": "0.
|
|
18
|
+
"version": "0.18.0",
|
|
19
19
|
"main": "dist/index.cjs.js",
|
|
20
20
|
"module": "dist/index.es.js",
|
|
21
21
|
"types": "dist/index.d.ts",
|
|
@@ -73,6 +73,7 @@
|
|
|
73
73
|
"vitest": "^4.1.4"
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
|
+
"@types/geojson": "7946.0.16",
|
|
76
77
|
"dotenv": "^16.4.5",
|
|
77
78
|
"socket.io": "^4.8.0",
|
|
78
79
|
"socket.io-client": "^4.8.0"
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
/* MD
|
|
2
|
+
## GISManager
|
|
3
|
+
---
|
|
4
|
+
Georeferenced BIM projects need their surroundings: the real terrain and
|
|
5
|
+
buildings around the model, and the project's GIS layers (parcels, networks,
|
|
6
|
+
boundaries) drawn at the right place in the 3D scene and on a 2D map.
|
|
7
|
+
|
|
8
|
+
GISManager is the component that owns all of that. It streams Cesium Ion 3D
|
|
9
|
+
Tiles (Google Photorealistic 3D Tiles by default) around the project origin,
|
|
10
|
+
loads vector layers (shapefile zip or GeoJSON) declared in the project's
|
|
11
|
+
layer manifest, and renders a 2D minimap with markers.
|
|
12
|
+
|
|
13
|
+
This tutorial covers initializing the manager from the platform client;
|
|
14
|
+
enabling the 3D tiles; the layer manifest and how heights, styles and
|
|
15
|
+
coordinate systems are read; selecting and focusing features; and the 2D
|
|
16
|
+
minimap with its markers. The recommended UI is provided by `top-gis-panel`,
|
|
17
|
+
`top-map-panel` and `top-gis-properties-panel`.
|
|
18
|
+
|
|
19
|
+
GISManager reads the project origin from `ProjectManager`, so initialize
|
|
20
|
+
`ProjectManager` first.
|
|
21
|
+
|
|
22
|
+
### π Importing our libraries
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import * as OBC from "@thatopen/components";
|
|
26
|
+
import * as OBF from "@thatopen/components-front";
|
|
27
|
+
import * as BUI from "@thatopen/ui";
|
|
28
|
+
import * as THREE from "three";
|
|
29
|
+
import * as FRAGS from "@thatopen/fragments";
|
|
30
|
+
import { PlatformClient, GISManager, ProjectManager } from "@thatopen/services";
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
/* MD
|
|
34
|
+
### π Initializing GISManager
|
|
35
|
+
Both components are set up through the platform client.
|
|
36
|
+
`client.setup(...)` resolves the shared `OBC.Components` instance.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
const client = PlatformClient.fromPlatformContext();
|
|
40
|
+
|
|
41
|
+
const { components } = (await client.setup(
|
|
42
|
+
{ OBC, OBF, BUI, THREE, FRAGS },
|
|
43
|
+
{ uuid: ProjectManager.uuid },
|
|
44
|
+
{ uuid: GISManager.uuid },
|
|
45
|
+
)) as { components: OBC.Components };
|
|
46
|
+
|
|
47
|
+
await components.get(ProjectManager).init(client);
|
|
48
|
+
|
|
49
|
+
const gis = components.get(GISManager);
|
|
50
|
+
|
|
51
|
+
/* MD
|
|
52
|
+
`init(client)` restores the project origin from `ProjectManager` and reads
|
|
53
|
+
the project's layer manifest (see below). It never throws: with no project or
|
|
54
|
+
no stored file the manager just keeps its defaults, and an empty layer list.
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
await gis.init(client);
|
|
58
|
+
console.log("layers:", gis.vectorLayersConfig);
|
|
59
|
+
|
|
60
|
+
/* MD
|
|
61
|
+
### π 3D tiles
|
|
62
|
+
Streaming the tiles needs a Cesium Ion token. The component does not persist
|
|
63
|
+
the token anywhere: your application provides it (from its own settings, or
|
|
64
|
+
typed by the user in `top-gis-panel`) before enabling the tiles.
|
|
65
|
+
|
|
66
|
+
`enableTiles()` resolves once the first tiles are loaded and rejects with a
|
|
67
|
+
readable message if the token is invalid or has no access to the tileset (the
|
|
68
|
+
same message is also fired through `onLoadError`).
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
gis.onLoadError.add((message) => console.warn("GIS tiles:", message));
|
|
72
|
+
|
|
73
|
+
gis.apiToken = "<your Cesium Ion token>";
|
|
74
|
+
await gis.enableTiles();
|
|
75
|
+
|
|
76
|
+
/* MD
|
|
77
|
+
`onStateChanged` fires whenever the token, origin, tiles visibility, tiles
|
|
78
|
+
offset or tiles opacity change, with a plain snapshot of all of them.
|
|
79
|
+
`setTilesOpacity(0.5)` makes the tiles see-through (1 = opaque), which lets
|
|
80
|
+
you see vector layers that run underground. `disableTiles()` unloads
|
|
81
|
+
everything.
|
|
82
|
+
|
|
83
|
+
On hosts whose engine supports the deferred postproduction pipeline, the
|
|
84
|
+
tiles and the vector layers are drawn through an occlusion pass, which is what
|
|
85
|
+
makes the see-through effect possible. On other hosts they are added to the
|
|
86
|
+
scene directly and stay opaque. You do not need to do anything for this: the
|
|
87
|
+
component detects it.
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
gis.onStateChanged.add((state) => console.log("tiles visible:", state.tilesVisible));
|
|
91
|
+
gis.setTilesOpacity(0.6);
|
|
92
|
+
|
|
93
|
+
/* MD
|
|
94
|
+
A small East/North/Up correction (in metres) can be applied to the tiles to
|
|
95
|
+
compensate for the tileset's own positioning error. Persist it with
|
|
96
|
+
`saveTilesOffset()`; it is stored in the same file as the layer manifest and
|
|
97
|
+
restored by `init`.
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
gis.onOffsetSaveComplete.add((success) => console.log("offset saved:", success));
|
|
101
|
+
gis.setTilesOffset(0.5, -0.3, 0);
|
|
102
|
+
gis.saveTilesOffset();
|
|
103
|
+
|
|
104
|
+
/* MD
|
|
105
|
+
### ποΈ The layer manifest
|
|
106
|
+
The vector layers of a project are declared in one JSON file,
|
|
107
|
+
`{GISManager.uuid}.json`, stored loose in the project's `__project_data`
|
|
108
|
+
folder. `init(client)` reads it into `gis.vectorLayersConfig`; it only holds
|
|
109
|
+
metadata (the geometry stays in the layer's own file, referenced by `fileId`
|
|
110
|
+
and downloaded when the layer is loaded).
|
|
111
|
+
|
|
112
|
+
There is no user interface to register layers yet: the manifest is written by
|
|
113
|
+
your application (or by hand). The component only reads it, and rewrites it
|
|
114
|
+
(keeping `layers` as they are) when the tiles offset is saved.
|
|
115
|
+
|
|
116
|
+
Each entry of `layers` has:
|
|
117
|
+
|
|
118
|
+
- `id` β unique id, used by every API below.
|
|
119
|
+
- `name` β display name (shown by the panels).
|
|
120
|
+
- `fileId` β id of the layer's file in the project.
|
|
121
|
+
- `type` β `"shapefile"` (a zip with the `.shp`, `.dbf`, `.prj`β¦ files) or
|
|
122
|
+
`"geojson"`. If it is missing or unrecognised the downloaded bytes decide:
|
|
123
|
+
a zip signature means shapefile, a leading `{` means GeoJSON.
|
|
124
|
+
- `style` β `stroke` (CSS colour), `stroke-width` (pixels), `fill` (CSS
|
|
125
|
+
colour, polygons) and `fill-opacity` (0 to 1). All optional.
|
|
126
|
+
- `height` β optional, how features get their height (next section).
|
|
127
|
+
|
|
128
|
+
Here is a complete manifest with a points layer whose vertices carry their
|
|
129
|
+
own height, and a lines layer whose heights come from its attributes:
|
|
130
|
+
|
|
131
|
+
```json
|
|
132
|
+
{
|
|
133
|
+
"layers": [
|
|
134
|
+
{
|
|
135
|
+
"id": "manholes",
|
|
136
|
+
"name": "Manholes",
|
|
137
|
+
"fileId": "<file id of manholes.zip>",
|
|
138
|
+
"type": "shapefile",
|
|
139
|
+
"style": { "stroke": "#ffb300", "stroke-width": 6 },
|
|
140
|
+
"height": { "source": "geometry" }
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"id": "pipes",
|
|
144
|
+
"name": "Pipes",
|
|
145
|
+
"fileId": "<file id of pipes.geojson>",
|
|
146
|
+
"type": "geojson",
|
|
147
|
+
"style": { "stroke": "#1e88e5", "stroke-width": 3 },
|
|
148
|
+
"height": {
|
|
149
|
+
"source": "attributes",
|
|
150
|
+
"startProperty": "z_start",
|
|
151
|
+
"endProperty": "z_end",
|
|
152
|
+
"startDepthProperty": "depth_start",
|
|
153
|
+
"endDepthProperty": "depth_end",
|
|
154
|
+
"nodeLayers": ["manholes"],
|
|
155
|
+
"nodeSnapDistance": 0.5
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
],
|
|
159
|
+
"tilesOffset": { "east": 0.5, "north": -0.3, "up": 0 }
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Once `init` has read it, every layer can be loaded and unloaded by id.
|
|
164
|
+
`loadVectorLayer` downloads and parses the file; it never throws, failures
|
|
165
|
+
are reported through `onVectorLayerError`.
|
|
166
|
+
*/
|
|
167
|
+
|
|
168
|
+
gis.onLayersLoaded.add((layers) => console.log("manifest read:", layers.length, "layers"));
|
|
169
|
+
gis.onVectorLayerError.add(({ id, message }) => console.warn(`Layer ${id}:`, message));
|
|
170
|
+
|
|
171
|
+
await gis.loadVectorLayer("manholes");
|
|
172
|
+
await gis.loadVectorLayer("pipes");
|
|
173
|
+
|
|
174
|
+
console.log("loaded:", gis.vectorLayers.isLayerLoaded("pipes"));
|
|
175
|
+
|
|
176
|
+
gis.unloadVectorLayer("manholes");
|
|
177
|
+
|
|
178
|
+
/* MD
|
|
179
|
+
### π Layer heights
|
|
180
|
+
The `height` option of a layer decides at what height its features are drawn:
|
|
181
|
+
|
|
182
|
+
- **No `height`** β the layer is drawn flat, at the origin's height.
|
|
183
|
+
- **`{ "source": "geometry" }`** β every vertex is placed at its own Z (the
|
|
184
|
+
third GeoJSON coordinate). If any vertex of the layer has no Z, the whole
|
|
185
|
+
layer is drawn flat instead (with a console warning).
|
|
186
|
+
- **`{ "source": "attributes", β¦ }`** β for line features only (other
|
|
187
|
+
geometry types are drawn flat). A line gets a height at its first vertex
|
|
188
|
+
and at its last one, and the vertices in between are interpolated along
|
|
189
|
+
the line. Each end is resolved in this order:
|
|
190
|
+
1. its own height property (`startProperty` / `endProperty`);
|
|
191
|
+
2. otherwise the surface height of the nearest node minus its depth
|
|
192
|
+
property (`startDepthProperty` / `endDepthProperty`). Nodes are the
|
|
193
|
+
points with a Z found in the layers listed in `nodeLayers`, and
|
|
194
|
+
"nearest" means within `nodeSnapDistance` metres (0.5 by default) of
|
|
195
|
+
the line end;
|
|
196
|
+
3. otherwise the height resolved for the other end (the line is drawn
|
|
197
|
+
level);
|
|
198
|
+
4. otherwise the surface height of the nearest node.
|
|
199
|
+
|
|
200
|
+
A property counts as missing when it is not a finite number or is exactly
|
|
201
|
+
`0`. Rules 1 and 2 are tried on both ends before rule 3 is applied, so a
|
|
202
|
+
copied height never comes from another copy. A line for which no rule can
|
|
203
|
+
give a height to both ends is not drawn (one console warning per layer
|
|
204
|
+
summarizes how many).
|
|
205
|
+
|
|
206
|
+
All heights are orthometric (the usual survey heights above the geoid). The
|
|
207
|
+
component adds the project's geoid undulation, taken from the `ProjectManager`
|
|
208
|
+
CRS, to place them in the scene, and re-places the loaded layers if it changes.
|
|
209
|
+
*/
|
|
210
|
+
|
|
211
|
+
/* MD
|
|
212
|
+
### π§ GeoJSON coordinate systems
|
|
213
|
+
Shapefiles are read with their `.prj`. For GeoJSON layers, the coordinate
|
|
214
|
+
system comes from the legacy `crs` member of the file:
|
|
215
|
+
|
|
216
|
+
- Longitude/latitude (`CRS84`, or `EPSG:4326`) is read as it is.
|
|
217
|
+
- `EPSG:3857` and the UTM zones (`EPSG:326xx`, `327xx`, `258xx` and `269xx`)
|
|
218
|
+
are reprojected to longitude/latitude when the layer loads.
|
|
219
|
+
- Any other declared CRS is rejected, and so are projected coordinates in a
|
|
220
|
+
file that declares no `crs`.
|
|
221
|
+
|
|
222
|
+
A rejected layer is not loaded, and the reason (for example `Unsupported CRS
|
|
223
|
+
"EPSG:2154"β¦`) is delivered through `onVectorLayerError`, which is what the
|
|
224
|
+
GIS panel shows as a toast.
|
|
225
|
+
*/
|
|
226
|
+
|
|
227
|
+
/* MD
|
|
228
|
+
### π±οΈ Selection and focus
|
|
229
|
+
Clicking a feature in the 3D view selects it. `onFeatureSelected` delivers
|
|
230
|
+
the selection (`layerId`, `layerName`, `featureIndex`, `geometryType` and the
|
|
231
|
+
feature's `properties`), or `null` when the selection is cleared. The current
|
|
232
|
+
selection can also be read at any time from `gis.vectorLayers.selection`.
|
|
233
|
+
|
|
234
|
+
Your application can select a feature too, optionally flying the camera to
|
|
235
|
+
it. `onFocusRequested` fires with the bounding sphere the camera is sent to,
|
|
236
|
+
which is how the 2D map follows.
|
|
237
|
+
*/
|
|
238
|
+
|
|
239
|
+
gis.onFeatureSelected.add((selection) => {
|
|
240
|
+
if (!selection) return console.log("selection cleared");
|
|
241
|
+
console.log(selection.layerName, selection.geometryType, selection.properties);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
gis.onFocusRequested.add(({ layerId, featureIndex, sphere }) => {
|
|
245
|
+
console.log("focusing", layerId, featureIndex, "radius:", sphere.radius);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
gis.selectVectorFeature("pipes", 0, { focus: true });
|
|
249
|
+
gis.vectorLayers.clearSelection();
|
|
250
|
+
|
|
251
|
+
/* MD
|
|
252
|
+
### πΊοΈ The 2D minimap
|
|
253
|
+
`gis.minimap` renders a top-down, north-up image of the 3D tiles that
|
|
254
|
+
`top-map-panel` draws together with the vector layers, the camera and the
|
|
255
|
+
markers.
|
|
256
|
+
|
|
257
|
+
`captureMap()` takes the picture. The 3D tiles must be loaded (without them
|
|
258
|
+
the image is empty). The captured area is the bounding box of all the
|
|
259
|
+
manifest's layers, whether they are displayed or not; with no usable layers it
|
|
260
|
+
is a square of `2 * halfExtent` metres (250 by default) centred on the origin.
|
|
261
|
+
The image has a fixed side of `resolution` pixels (2048 by default, limited by
|
|
262
|
+
the GPU), so the larger the area, the coarser the map.
|
|
263
|
+
*/
|
|
264
|
+
|
|
265
|
+
gis.minimap.onCaptured.add((capture) => console.log("map captured:", capture.size, "px"));
|
|
266
|
+
|
|
267
|
+
gis.minimap.halfExtent = 400;
|
|
268
|
+
gis.minimap.resolution = 4096;
|
|
269
|
+
const capture = await gis.minimap.captureMap();
|
|
270
|
+
document.body.appendChild(capture.image);
|
|
271
|
+
|
|
272
|
+
/* MD
|
|
273
|
+
`worldToMap` converts a scene position into normalized image coordinates
|
|
274
|
+
(0 to 1, origin at the top-left), and `mapToWorld` does the opposite for a
|
|
275
|
+
horizontal plane at a given height. Both return `null` until a map has been
|
|
276
|
+
captured.
|
|
277
|
+
*/
|
|
278
|
+
|
|
279
|
+
const point = gis.vectorLayers.geoToWorld(gis.latitude, gis.longitude, gis.height);
|
|
280
|
+
const onMap = gis.minimap.worldToMap(point);
|
|
281
|
+
console.log("origin on the map:", onMap);
|
|
282
|
+
console.log("back to the scene:", onMap && gis.minimap.mapToWorld(onMap.x, onMap.y, point.y));
|
|
283
|
+
|
|
284
|
+
/* MD
|
|
285
|
+
### π Minimap markers
|
|
286
|
+
Markers are HTML elements drawn over the map by `top-map-panel`. They live in
|
|
287
|
+
the minimap, not in the panel, so they survive the panel being recreated.
|
|
288
|
+
|
|
289
|
+
A marker has an `id`, a scene `position` (read on every redraw, so changing
|
|
290
|
+
it moves the marker), an optional `label` and an optional `createElement`
|
|
291
|
+
factory. Without the factory the panel draws a default badge with the label
|
|
292
|
+
and reports its clicks through `onMarkerClicked`. With it, the marker is your
|
|
293
|
+
own element and it owns its click behaviour. It is a factory and not an
|
|
294
|
+
element because each panel needs its own DOM node.
|
|
295
|
+
|
|
296
|
+
`geoToWorld(lat, lon, height)` turns a geographic position into a scene
|
|
297
|
+
position.
|
|
298
|
+
*/
|
|
299
|
+
|
|
300
|
+
gis.minimap.onMarkersChanged.add(({ kind, id }) => console.log("markers:", kind, id));
|
|
301
|
+
gis.minimap.onMarkerClicked.add((id) => console.log("clicked:", id));
|
|
302
|
+
|
|
303
|
+
gis.minimap.addMarker({
|
|
304
|
+
id: "site-office",
|
|
305
|
+
label: "Site office",
|
|
306
|
+
position: gis.vectorLayers.geoToWorld(gis.latitude, gis.longitude, gis.height),
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
gis.minimap.addMarker({
|
|
310
|
+
id: "crane",
|
|
311
|
+
position: new THREE.Vector3(-20, 0, 35),
|
|
312
|
+
createElement: () => {
|
|
313
|
+
const pin = document.createElement("div");
|
|
314
|
+
pin.textContent = "ποΈ";
|
|
315
|
+
pin.style.fontSize = "1.4rem";
|
|
316
|
+
pin.style.cursor = "pointer";
|
|
317
|
+
pin.onclick = () => console.log("crane clicked");
|
|
318
|
+
return pin;
|
|
319
|
+
},
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
gis.minimap.updateMarker("site-office", { label: "Main office" });
|
|
323
|
+
console.log("markers:", [...gis.minimap.markers.keys()]);
|
|
324
|
+
|
|
325
|
+
gis.minimap.removeMarker("crane");
|
|
326
|
+
gis.minimap.clearMarkers();
|