@nnepoch/dtc-sdk 3.0.15 → 3.0.16

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.
@@ -106,4 +106,4 @@ onmessage = async (event) => {
106
106
  }
107
107
  };
108
108
  postMessage({ type: 'ready' });\n`}var U=class extends Error{constructor(e,t,n){super(t),this.code=e,this.details=n,this.name=`BusinessProgramRuntimeError`}},Ln=class{constructor(e,t=Rn){this.host=e,this.workerFactory=t,this.loaded=new Map,this.active=new Map,this.activeProgramLocks=new Map}async load(e){if(this.loaded.has(e.capsuleHash))return{loaded:!1};if(!/^[a-f0-9]{64}$/.test(e.capsuleHash))throw new U(`PROGRAM_HASH_INVALID`,`capsuleHash must be a SHA-256 hex string.`);if(await zn(e),await Vn(Bn(e))!==e.capsuleHash)throw new U(`PROGRAM_HASH_INVALID`,`Business Program capsuleHash mismatch.`);return this.validatePermissions(e.manifest),this.loaded.set(e.capsuleHash,{manifest:structuredClone(e.manifest),bundle:e.bundle,data:structuredClone(e.data)}),{loaded:!0}}async start(e,t){if(this.active.has(e.executionId))throw new U(`PROGRAM_EXECUTION_EXISTS`,`Execution "${e.executionId}" already exists.`);let n=this.loaded.get(e.capsuleHash);if(!n)throw new U(`PROGRAM_NOT_LOADED`,`Business Program capsule is not loaded.`);let r=this.activeProgramLocks.get(n.manifest.programId);if(r)throw new U(`PROGRAM_LOCK_CONFLICT`,`Business Program "${n.manifest.programId}" is already running.`,{executionId:r});let i;try{i=this.workerFactory(In(n.bundle))}catch(e){throw new U(`PROGRAM_WORKER_UNAVAILABLE`,`Business Program Worker could not be created. Check the page CSP worker-src policy.`,qn(e))}let a={};Object.assign(a,{request:e,program:n,worker:i,onEvent:t,timeout:setTimeout(()=>{this.finishExecution(a,`failed`,`Business Program execution timed out.`)},n.manifest.limits.timeoutMs),sdkCallCount:0,totalDelayMs:0,emittedEventCount:0,pendingDelays:new Set,streams:new Map,nextStreamId:1,terminal:!1}),this.active.set(e.executionId,a),this.activeProgramLocks.set(n.manifest.programId,e.executionId);try{return await this.waitForWorkerReady(a),i.postMessage({type:`start`,inputs:structuredClone(e.inputs),data:structuredClone(n.data)}),this.emit(a,{type:`started`},!1,`running`),{executionId:e.executionId,state:`running`}}catch(e){throw this.finishExecution(a,`failed`,e instanceof Error?e.message:String(e)),e}}cancel(e){let t=this.active.get(e.executionId);return t&&this.finishExecution(t,`cancelled`,e.reason??`Business Program cancelled.`),{executionId:e.executionId,state:`cancelled`}}cancelAll(e=`Business Program runtime disposed.`){for(let t of[...this.active.values()])this.finishExecution(t,`cancelled`,e)}validatePermissions(e){let t=new Set;for(let n of e.permissions.methods){let e=`${n.module}\u0000${n.method}\u0000${n.mode}`;if(t.has(e))throw new U(`PROGRAM_PERMISSION_INVALID`,`Business Program permissions must be unique.`);t.add(e);let r=this.host.getMethodMetadata(n.module,n.method);if(!r)throw new U(`PROGRAM_PERMISSION_INVALID`,`Business Program method "${n.module}.${n.method}" is not exposed.`);if(n.mode===`query`&&(r.responseMode!==`single`||r.sideEffects.some(e=>e!==`read`)))throw new U(`PROGRAM_PERMISSION_INVALID`,`Query permission requires a read-only single method: ${n.module}.${n.method}.`);if(n.mode===`stage`&&r.responseMode!==`single`)throw new U(`PROGRAM_PERMISSION_INVALID`,`Stage permission requires responseMode=single: ${n.module}.${n.method}.`);if(n.mode===`stream`&&r.responseMode!==`stream`)throw new U(`PROGRAM_PERMISSION_INVALID`,`Stream permission requires responseMode=stream: ${n.module}.${n.method}.`)}}waitForWorkerReady(e){return new Promise((t,n)=>{let r=setTimeout(()=>n(new U(`PROGRAM_WORKER_UNAVAILABLE`,`Business Program Worker did not become ready in 5 seconds.`)),5e3);e.worker.onmessage=n=>{G(n.data)?.type===`ready`&&(clearTimeout(r),e.worker.onmessage=t=>{this.handleWorkerMessage(e,t.data)},e.worker.onerror=t=>{this.finishExecution(e,`failed`,t.message||`Business Program Worker failed.`)},t())},e.worker.onerror=e=>{clearTimeout(r),n(new U(`PROGRAM_WORKER_ERROR`,e.message||`Business Program Worker failed.`))}})}async handleWorkerMessage(e,t){if(e.terminal)return;let n=G(t);if(!(!n||typeof n.type!=`string`)){if(n.type===`host-request`&&typeof n.id==`string`&&typeof n.operation==`string`){try{let t=await this.handleHostRequest(e,n.operation,n.payload);if(e.terminal)return;e.worker.postMessage({type:`host-response`,id:n.id,ok:!0,result:t})}catch(t){if(e.terminal)return;e.worker.postMessage({type:`host-response`,id:n.id,ok:!1,error:qn(t)})}return}if(n.type===`emit`){let t=G(n.event);this.emit(e,{type:t?.type===`action`?`action`:`progress`,phase:typeof t?.phase==`string`?t.phase:void 0,message:typeof t?.message==`string`?t.message:void 0,data:t?.data},!1,`running`);return}if(n.type===`complete`){this.finishExecution(e,`completed`,void 0,n.result);return}if(n.type===`fail`){let t=G(n.error);this.finishExecution(e,`failed`,typeof t?.message==`string`?t.message:`Business Program failed.`,t?.details)}}}async handleHostRequest(e,t,n){if(t===`query`){let t=Wn(n);this.requirePermission(e.program.manifest,t,`query`),this.incrementSdkCalls(e,1);let r=await this.host.invoke(t);if(!r.ok)throw new U(r.error.code,r.error.message,r.error.details);return r.data}if(t===`execute-stage`)return this.executeStage(e,n);if(t===`open-stream`)return this.openStream(e,n);if(t===`stream-next`)return this.nextStreamEvent(e,n);if(t===`close-stream`)return this.closeStream(e,n);if(t===`delay`){let t=G(n)?.delayMs;if(!Number.isInteger(t)||t<0)throw new U(`PROGRAM_REQUEST_INVALID`,`delayMs must be a non-negative integer.`);return await this.controlledDelay(e,t),null}throw new U(`PROGRAM_REQUEST_INVALID`,`Unsupported host operation "${t}".`)}async executeStage(e,t){let n=G(t)?.actions;if(!Array.isArray(n)||n.length===0||n.length>e.program.manifest.limits.maxStageActions)throw new U(`PROGRAM_STAGE_INVALID`,`Program stage action count is invalid.`);let r=Kn(n),i=r.filter(e=>e.type===`invoke`);for(let t of i)this.requirePermission(e.program.manifest,Gn(t),`stage`);this.incrementSdkCalls(e,i.length);let a=this.host.validateActions({actions:i.map(e=>({id:e.id,...Gn(e),responseMode:`single`}))});if(!a.ok)throw new U(a.error.code,a.error.message,a.error.details);let o=a.data.items.find(e=>!e.valid);if(!a.data.valid||o)throw new U(o?.error?.code??`INVALID_PAYLOAD`,o?.error?.message??`Business Program stage preflight failed.`,o?.error?.details);let s=[],c={};for(let[t,n]of r.entries()){if(e.terminal)throw new U(`PROGRAM_CANCELLED`,`Business Program execution is no longer active.`);if(n.type===`delay`)await this.controlledDelay(e,n.delayMs);else{let e=await this.host.invoke(Gn(n));if(!e.ok)return{state:`failed`,completedActionIds:s,skippedActionIds:r.slice(t+1).map(e=>e.id),results:c,failedAction:{id:n.id,...e.error}};n.saveAs&&(c[n.saveAs]=e.data)}s.push(n.id)}return{state:`completed`,completedActionIds:s,skippedActionIds:[],results:c}}async openStream(e,t){let n=Wn(t);this.requirePermission(e.program.manifest,n,`stream`),this.incrementSdkCalls(e,1);let r=`${e.request.executionId}:stream:${e.nextStreamId++}`,i={streamId:r,requestId:``,events:[],waiters:[],terminal:!1};e.streams.set(r,i);let a=await this.host.startStream({...n,streamId:r},t=>{this.pushStreamEvent(e,i,t)});if(!a.ok)throw e.streams.delete(r),new U(a.error.code,a.error.message,a.error.details);return i.requestId=a.data.requestId,a.data}nextStreamEvent(e,t){let n=this.requireProgramStream(e,t),r=n.events.shift();return r?(r.terminal&&e.streams.delete(n.streamId),Promise.resolve(r)):n.terminal?(e.streams.delete(n.streamId),Promise.reject(new U(`PROGRAM_STREAM_CLOSED`,`Stream "${n.streamId}" is closed.`))):new Promise((e,t)=>{n.waiters.push({resolve:e,reject:t})})}async closeStream(e,t){let n=this.requireProgramStream(e,t),r=G(t)?.reason,i=await this.host.closeStream({streamId:n.streamId,reason:typeof r==`string`?r:`Business Program closed stream.`});if(!i.ok)throw new U(i.error.code,i.error.message,i.error.details);return this.disposeProgramStream(e,n,`Business Program closed stream.`,!1),{streamId:n.streamId,closed:!0}}requireProgramStream(e,t){let n=G(t)?.streamId,r=typeof n==`string`?e.streams.get(n):void 0;if(!r)throw new U(`PROGRAM_STREAM_NOT_FOUND`,`Business Program stream does not exist.`);return r}pushStreamEvent(e,t,n){if(e.terminal||!e.streams.has(t.streamId))return;t.terminal=n.terminal;let r=t.waiters.shift();r?(r.resolve(n),n.terminal&&e.streams.delete(t.streamId)):t.events.push(n)}disposeProgramStream(e,t,n,r=!0){e.streams.delete(t.streamId),t.terminal=!0;for(let e of t.waiters.splice(0))e.reject(new U(`PROGRAM_CANCELLED`,n));r&&this.host.closeStream({streamId:t.streamId,reason:n})}async controlledDelay(e,t){if(e.terminal)throw new U(`PROGRAM_CANCELLED`,`Business Program execution is no longer active.`);if(e.totalDelayMs+=t,e.totalDelayMs>e.program.manifest.limits.maxTotalDelayMs)throw new U(`PROGRAM_LIMIT_EXCEEDED`,`Business Program total delay limit exceeded.`);await new Promise((n,r)=>{let i={};i.reject=r,i.timer=setTimeout(()=>{e.pendingDelays.delete(i),n()},t),e.pendingDelays.add(i)})}requirePermission(e,t,n){if(!e.permissions.methods.some(e=>e.module===t.moduleName&&e.method===t.methodName&&e.mode===n))throw new U(`PROGRAM_PERMISSION_DENIED`,`Business Program cannot use ${t.moduleName}.${t.methodName} as ${n}.`)}incrementSdkCalls(e,t){if(e.sdkCallCount+=t,e.sdkCallCount>e.program.manifest.limits.maxSdkCalls)throw new U(`PROGRAM_LIMIT_EXCEEDED`,`Business Program SDK call limit exceeded.`)}emit(e,t,n,r){if(e.emittedEventCount+=1,e.emittedEventCount>e.program.manifest.limits.maxEventCount){this.finishExecution(e,`failed`,`Business Program event limit exceeded.`);return}e.onEvent({executionId:e.request.executionId,traceId:e.request.traceId,event:t,terminal:n,state:r})}finishExecution(e,t,n,r){if(!e.terminal){e.terminal=!0,clearTimeout(e.timeout);for(let t of e.pendingDelays)clearTimeout(t.timer),t.reject(new U(`PROGRAM_CANCELLED`,n??`Business Program stopped.`));e.pendingDelays.clear();for(let r of[...e.streams.values()])this.disposeProgramStream(e,r,n??`Business Program ${t}.`);e.worker.terminate(),this.active.delete(e.request.executionId),this.activeProgramLocks.get(e.program.manifest.programId)===e.request.executionId&&this.activeProgramLocks.delete(e.program.manifest.programId),e.onEvent({executionId:e.request.executionId,traceId:e.request.traceId,event:{type:t,message:n,data:r},terminal:!0,state:t})}}};function Rn(e){let t=URL.createObjectURL(new Blob([e],{type:`text/javascript`}));try{return new Worker(t)}finally{URL.revokeObjectURL(t)}}async function zn(e){if(await Vn(e.bundle)!==e.manifest.entry.sha256)throw new U(`PROGRAM_HASH_INVALID`,`Business Program entry sha256 mismatch.`);for(let t of e.manifest.data){let n=e.data[t.name];if(typeof n!=`string`||await Vn(n)!==t.sha256)throw new U(`PROGRAM_HASH_INVALID`,`Business Program data "${t.name}" sha256 mismatch.`)}}function Bn(e){return JSON.stringify(e.manifest)+e.bundle+e.manifest.data.map(t=>e.data[t.name]??``).join(``)}async function Vn(e){let t=new TextEncoder().encode(e);if(typeof crypto<`u`&&crypto.subtle){let e=await crypto.subtle.digest(`SHA-256`,t);return Un(new Uint8Array(e))}return Un(Hn(t))}function Hn(e){let t=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),n=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),r=Math.ceil((e.length+9)/64)*64,i=new Uint8Array(r);i.set(e),i[e.length]=128;let a=e.length*8,o=new DataView(i.buffer);o.setUint32(r-8,Math.floor(a/4294967296)),o.setUint32(r-4,a>>>0);let s=new Uint32Array(64);for(let e=0;e<r;e+=64){for(let t=0;t<16;t+=1)s[t]=o.getUint32(e+t*4);for(let e=16;e<64;e+=1){let t=W(s[e-15],7)^W(s[e-15],18)^s[e-15]>>>3,n=W(s[e-2],17)^W(s[e-2],19)^s[e-2]>>>10;s[e]=s[e-16]+t+s[e-7]+n>>>0}let[r,i,a,c,l,u,d,f]=n;for(let e=0;e<64;e+=1){let n=W(l,6)^W(l,11)^W(l,25),o=l&u^~l&d,p=f+n+o+t[e]+s[e]>>>0,m=(W(r,2)^W(r,13)^W(r,22))+(r&i^r&a^i&a)>>>0;f=d,d=u,u=l,l=c+p>>>0,c=a,a=i,i=r,r=p+m>>>0}n[0]=n[0]+r>>>0,n[1]=n[1]+i>>>0,n[2]=n[2]+a>>>0,n[3]=n[3]+c>>>0,n[4]=n[4]+l>>>0,n[5]=n[5]+u>>>0,n[6]=n[6]+d>>>0,n[7]=n[7]+f>>>0}let c=new Uint8Array(32),l=new DataView(c.buffer);return n.forEach((e,t)=>l.setUint32(t*4,e)),c}function W(e,t){return e>>>t|e<<32-t}function Un(e){return Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)}function Wn(e){let t=G(e);if(!t||typeof t.module!=`string`||typeof t.method!=`string`)throw new U(`PROGRAM_REQUEST_INVALID`,`SDK request requires module and method.`);return{moduleName:t.module,methodName:t.method,payload:t.payload}}function Gn(e){return{moduleName:e.module,methodName:e.method,payload:e.payload}}function Kn(e){let t=new Map,n=new Set;for(let r of e){if(!r||typeof r.id!=`string`||!r.id||t.has(r.id))throw new U(`PROGRAM_STAGE_INVALID`,`Program stage action IDs must be unique.`);if(r.type!==`invoke`&&r.type!==`delay`)throw new U(`PROGRAM_STAGE_INVALID`,`Unsupported Program stage action type.`);if(r.type===`invoke`){if(!r.module||!r.method||r.responseMode!==`single`)throw new U(`PROGRAM_STAGE_INVALID`,`Invoke action "${r.id}" is invalid.`);if(r.saveAs&&(n.has(r.saveAs)||!/^[A-Za-z][A-Za-z0-9-]*$/.test(r.saveAs)))throw new U(`PROGRAM_STAGE_INVALID`,`saveAs "${r.saveAs}" is invalid or duplicated.`);r.saveAs&&n.add(r.saveAs)}else if(!Number.isInteger(r.delayMs)||r.delayMs<0)throw new U(`PROGRAM_STAGE_INVALID`,`Delay action "${r.id}" is invalid.`);t.set(r.id,r)}for(let n of e)for(let e of n.dependsOn??[])if(!t.has(e)||e===n.id)throw new U(`PROGRAM_STAGE_INVALID`,`Action "${n.id}" has an invalid dependency.`);let r=[],i=new Set;for(;r.length<e.length;){let t=e.find(e=>!i.has(e.id)&&(e.dependsOn??[]).every(e=>i.has(e)));if(!t)throw new U(`PROGRAM_STAGE_INVALID`,`Program stage dependency graph contains a cycle.`);r.push(t),i.add(t.id)}return r}function G(e){return typeof e==`object`&&e?e:void 0}function qn(e){return e instanceof U?{name:e.name,message:e.message,code:e.code,details:e.details}:e instanceof Error?{name:e.name,message:e.message}:{name:`Error`,message:String(e)}}function Jn(){return typeof crypto<`u`&&typeof crypto.randomUUID==`function`?`sdk3_${crypto.randomUUID()}`:`sdk3_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,10)}`}function K(e){return{ok:!0,data:e,ts:Date.now()}}function q(e,t,n){return{ok:!1,error:{code:e,message:t,moduleName:n?.moduleName,methodName:n?.methodName,details:n?.details},ts:Date.now()}}function Yn(){return typeof document>`u`?void 0:document.title}function Xn(){return typeof window>`u`?void 0:window.location.href}function Zn(e){return e.runtimeName??e.engineConfig?.sceneName??Yn()??e.engineConfig?.engineUuid}function Qn(e){if(e)return{sceneName:e.sceneName,engineUuid:e.engineUuid,mapType:e.mapType,operationType:e.operationType,viewMode:e.viewMode,centerIP:e.centerIP,signalingServer:e.signalingServer,codec:e.codec}}function $n(e){return typeof e==`object`&&!!e}function er(e){return $n(e)&&Object.keys(e).length===0}function tr(e){return $n(e)&&e.ok===!1&&typeof e.ts==`number`}function nr(e){return new Promise(t=>{setTimeout(t,e)})}function rr(e,t){let n=t?.fields.filter(e=>e.required)??[];if(n.length!==0)return $n(e)?n.find(t=>e[t.name]===void 0):n[0]}function ir(e){return e instanceof p?e.toJSON():e instanceof Error?{name:e.name,message:e.message}:e}function ar(e){if(typeof e!=`object`&&typeof e!=`function`||e===null)return!1;let t=e;return typeof t.then==`function`&&typeof t.cancel==`function`&&typeof t.requestId==`string`}function or(e){if(!(!$n(e)||typeof e.id!=`string`))return{parentId:typeof e.parentId==`string`?e.parentId:``,id:e.id}}function sr(e){if(typeof e!=`string`)return e;try{return JSON.parse(e)}catch{return}}function cr(e){let t=e.response,n=sr(t?.param??t?.params??e.param??e.params);return $n(n)&&n.status===`finished`}function lr(e,t={},n={}){let r=t.bridgeId??Jn(),i=kn(t.expose),a=new Map,o=!1,s=()=>{o=!0},c=()=>{o=!1};e.on(e.Events.WebRtcConnected,s),e.on(e.Events.WebRtcDisconnected,c),e.on(e.Events.WebRtcFailed,c);function l(){return{bridgeId:r,connected:o,runtimeName:Zn(t),title:Yn(),pageUrl:Xn(),sdkVersion:t.sdkVersion,metadata:t.metadata,engine:Qn(t.engineConfig)}}function u(e){return On(e)?An(e,i)?e:q(`API_NOT_EXPOSED`,`API module "${e}" is not exposed by agentBridge.expose.`,{moduleName:e}):q(`API_NOT_FOUND`,`API module "${e}" does not exist.`,{moduleName:e})}function d(t,n){if(!jn(t,n,i))return q(`API_NOT_EXPOSED`,`API method "${t}.${n}" is not exposed.`,{moduleName:t,methodName:n});let r=e[t];return!$n(r)||typeof r[n]!=`function`?q(`API_NOT_FOUND`,`API method "${t}.${n}" does not exist.`,{moduleName:t,methodName:n}):r}function f(e,t=!0){let n=u(e.moduleName);if(typeof n!=`string`)return n;let r=d(n,e.methodName);if(tr(r))return r;let a=Pn(n,e.methodName,i);if(!a)return q(`METHOD_SCHEMA_NOT_FOUND`,`Schema for "${n}.${e.methodName}" is not available.`,{moduleName:n,methodName:e.methodName});let o=l();if(!o.connected)return q(`SDK_NOT_READY`,`DTCEngine is not connected yet.`,{moduleName:n,methodName:e.methodName,details:o});if(t&&a.payloadKind===`none`&&e.payload!==void 0&&!er(e.payload))return q(`INVALID_PAYLOAD`,`API method "${n}.${e.methodName}" does not accept payload.`,{moduleName:n,methodName:e.methodName,details:e.payload});let s=t?rr(e.payload,a):void 0;if(s)return q(`INVALID_PAYLOAD`,`Missing required payload field "${s.name}".`,{moduleName:n,methodName:e.methodName,details:{field:s.name}});let c=r[e.methodName];return typeof c==`function`?{resolvedModule:n,resolvedMethod:r,methodRef:c,schema:a}:q(`API_NOT_FOUND`,`API method "${n}.${e.methodName}" does not exist.`,{moduleName:n,methodName:e.methodName})}function h(e){return{type:e.type,requestId:e.requestId,response:e.response,...e.error?{error:{name:e.error.name,message:e.error.message}}:{}}}function g(e,t,n){let r=e.request.streamId;a.get(r)===e&&(a.delete(r),e.onEvent({streamId:r,requestId:e.promise.requestId,moduleName:e.request.moduleName,methodName:e.request.methodName,event:{type:`cancel`,requestId:e.promise.requestId,error:{name:`StreamClosedError`,message:n}},terminal:!0,terminalReason:t}),e.promise.cancel(n))}function _(e,t){let n=a.get(e);if(!n)return;let r=n.request.moduleName===`PathPatrol`&&n.request.methodName===`add`&&cr(t),i=r||t.type===`done`||t.type===`error`||t.type===`cancel`,o=r?`finished`:t.type===`done`?`completed`:t.type===`error`?`error`:t.type===`cancel`?`cancelled`:void 0;n.onEvent({streamId:e,requestId:t.requestId||n.promise.requestId,moduleName:n.request.moduleName,methodName:n.request.methodName,event:h(t),terminal:i,terminalReason:o}),i&&(a.delete(e),r&&t.type!==`done`&&n.promise.cancel(`PathPatrol.add reported status=finished`))}function ee(e){let t=or(e);if(t)for(let e of[...a.values()]){let n=or(e.request.payload);e.request.moduleName===`PathPatrol`&&e.request.methodName===`add`&&n?.id===t.id&&n.parentId===t.parentId&&g(e,`stopped`,`Matching PathPatrol.stop succeeded`)}}function te(e=`Agent bridge disconnected`){for(let t of[...a.values()])g(t,`bridge-disconnected`,e)}let v,ne=new Ln({getMethodMetadata(e,t){if(!On(e)||!An(e,i))return;let n=Nn(e,i).find(e=>e.methodName===t);return n?{responseMode:n.responseMode,sideEffects:n.sideEffects}:void 0},validateActions(e){return v.validateActions(e)},invoke(e){return v.invoke(e)},startStream(e,t){return v.startStream(e,t)},closeStream(e){return v.closeStream(e)}},n.businessProgramWorkerFactory);return v={getSnapshot:l,dispose(){te(`Agent bridge runtime disposed`),ne.cancelAll(`Agent bridge runtime disposed`),e.off(e.Events.WebRtcConnected,s),e.off(e.Events.WebRtcDisconnected,c),e.off(e.Events.WebRtcFailed,c)},closeAllStreams:te,cancelAllPrograms(e){ne.cancelAll(e)},listModules(){return Mn(i)},listMethods(e){let t=u(e);return typeof t==`string`?K(Nn(t,i)):t},getMethodSchema(e,t){let n=u(e);if(typeof n!=`string`)return n;if(!jn(n,t,i))return q(`API_NOT_EXPOSED`,`API method "${n}.${t}" is not exposed.`,{moduleName:n,methodName:t});let r=Pn(n,t,i);return r?K(r):q(`METHOD_SCHEMA_NOT_FOUND`,`Schema for "${n}.${t}" is not available.`,{moduleName:n,methodName:t})},validateActions(e){let t=e.actions.map(e=>{let t=f(e,!1);if(tr(t))return{id:e.id,valid:!1,error:t.error};if(t.schema.responseMode!==e.responseMode)return{id:e.id,valid:!1,error:{code:`STREAM_INVOKE_REQUIRED`,message:`API method "${t.resolvedModule}.${e.methodName}" is ${t.schema.responseMode}, not ${e.responseMode}.`,moduleName:t.resolvedModule,methodName:e.methodName,details:{expected:e.responseMode,actual:t.schema.responseMode}}};let n=Fn(t.resolvedModule,e.methodName,i);if(!n)return{id:e.id,valid:!1,error:{code:`METHOD_SCHEMA_NOT_FOUND`,message:`Validation schema for "${t.resolvedModule}.${e.methodName}" is not available.`,moduleName:t.resolvedModule,methodName:e.methodName}};try{return m(n,t.schema.payloadKind===`none`?void 0:e.payload,t.resolvedModule,e.methodName),{id:e.id,valid:!0}}catch(n){return{id:e.id,valid:!1,error:{code:`INVALID_PAYLOAD`,message:n instanceof Error?n.message:String(n),moduleName:t.resolvedModule,methodName:e.methodName,details:ir(n)}}}});return K({valid:t.every(e=>e.valid),items:t})},async invoke(e){let n=f(e);if(tr(n))return n;let{resolvedModule:r,resolvedMethod:i,methodRef:a,schema:o}=n;if(o.responseMode===`stream`)return q(`STREAM_INVOKE_REQUIRED`,`API method "${r}.${e.methodName}" requires a streaming invoke.`,{moduleName:r,methodName:e.methodName,details:{responseMode:o.responseMode,tool:`sdk3_invoke_stream`}});if(t.mockInvoke===!0)return await nr(100),K({success:!0,code:`MOCK_OK`,message:`mock invoke success`,data:null});try{let t=o.payloadKind===`none`||e.payload===void 0?await a.call(i):await a.call(i,e.payload);return r===`PathPatrol`&&e.methodName===`stop`&&(!$n(t)||t.success!==!1)&&ee(e.payload),K(t)}catch(t){return t instanceof p?q(`INVALID_PAYLOAD`,t.message,{moduleName:r,methodName:e.methodName,details:t.toJSON()}):q(`API_EXECUTION_FAILED`,`API method "${r}.${e.methodName}" failed.`,{moduleName:r,methodName:e.methodName,details:ir(t)})}},async startStream(e,t){if(a.has(e.streamId))return q(`INVALID_PAYLOAD`,`Stream "${e.streamId}" already exists.`,{moduleName:e.moduleName,methodName:e.methodName});let n=f(e);if(tr(n))return n;let{resolvedModule:r,resolvedMethod:i,methodRef:o,schema:s}=n;if(s.responseMode!==`stream`)return q(`API_NOT_STREAMING`,`API method "${r}.${e.methodName}" is not streaming.`,{moduleName:r,methodName:e.methodName});try{let n,c=[],l=!1,u=t=>{if(!l){c.push(t);return}_(e.streamId,t)};if(n=s.payloadKind===`none`||e.payload===void 0?o.call(i,u):o.call(i,e.payload,u),!ar(n))return q(`API_NOT_STREAMING`,`API method "${r}.${e.methodName}" did not return a stream handle.`,{moduleName:r,methodName:e.methodName});let d={request:e,promise:n,onEvent:t};a.set(e.streamId,d),l=!0,n.catch(()=>void 0),c.forEach(t=>_(e.streamId,t));let f=c.find(e=>e.type===`error`);return f?q(`INVALID_PAYLOAD`,f.error?.message??`API method "${r}.${e.methodName}" failed before stream start.`,{moduleName:r,methodName:e.methodName,details:ir(f.error)}):K({streamId:e.streamId,requestId:n.requestId})}catch(t){return q(`API_EXECUTION_FAILED`,`API method "${r}.${e.methodName}" failed to start a stream.`,{moduleName:r,methodName:e.methodName,details:ir(t)})}},async closeStream(e){let t=a.get(e.streamId);return t?(g(t,`cancelled`,e.reason?.trim()||`Stream closed by MCP client`),K({streamId:e.streamId,closed:!0})):K({streamId:e.streamId,closed:!1})},async loadProgram(e){try{return K(await ne.load(e))}catch(e){return q(`PROGRAM_INVALID`,e instanceof Error?e.message:String(e),{details:ur(e)})}},async startProgram(e,t){if(!o)return q(`SDK_NOT_READY`,`SDK runtime is not connected.`);try{return K(await ne.start(e,t))}catch(e){return q(`PROGRAM_EXECUTION_FAILED`,e instanceof Error?e.message:String(e),{details:ur(e)})}},async cancelProgram(e){try{return K(ne.cancel(e))}catch(e){return q(`PROGRAM_EXECUTION_FAILED`,e instanceof Error?e.message:String(e),{details:ur(e)})}}},v}function ur(e){return e instanceof U?{code:e.code,message:e.message,details:e.details}:ir(e)}function dr(){return typeof globalThis<`u`&&typeof globalThis.location?.href==`string`?globalThis.location?.href??``:``}function fr(){return typeof globalThis<`u`&&typeof globalThis.navigator?.userAgent==`string`?globalThis.navigator?.userAgent??``:``}const pr=l.z.string().min(1),mr=[`bs`,`cs`],hr=l.z.custom(e=>typeof e==`object`&&!!e,`dom must be a valid HTMLDivElement`),gr={centerHeartbeatIntervalMs:5e3,centerHeartbeatTimeoutMs:5e4},J={runMode:`RunMode/`,centerIP:`CenterIP/`,privateKey:`PrivateKey/`,showProgressBar:`showProgressBar/`},_r=l.z.object({centerIP:pr.optional(),signalingServer:pr.optional(),sceneName:pr.optional(),token:pr.optional(),dom:hr.optional(),showProgressBar:l.z.boolean().optional().default(!0),codec:l.z.string().optional().default(`H264`),viewMode:l.z.enum(mr).optional().default(`bs`),turnServer:l.z.string().optional(),turnUser:l.z.string().optional(),turnPwd:l.z.string().optional(),privateKey:l.z.string().optional(),engineUuid:l.z.string().optional(),mapType:l.z.string().optional().default(`web`),operationType:l.z.string().optional().default(`viewer`),freeCheckInterval:l.z.number().int().min(0).optional().default(0),initialSettings:l.z.record(l.z.unknown()).optional().default({}),logger:l.z.enum([`silent`,`error`,`warn`,`info`,`debug`]).optional().default(`info`),includeStack:l.z.enum([`silent`,`error`,`warn`,`info`,`debug`]).optional().default(`warn`),pixelStreamingLogger:l.z.enum([`silent`,`error`,`warn`,`info`,`debug`]).optional().default(`warn`),centerHeartbeatIntervalMs:l.z.never().optional(),centerHeartbeatTimeoutMs:l.z.never().optional()}).strict().superRefine((e,t)=>{!e.centerIP&&!e.signalingServer&&t.addIssue({code:l.z.ZodIssueCode.custom,path:[`centerIP`],message:`one of centerIP, signalingServer is required`}),e.sceneName||t.addIssue({code:l.z.ZodIssueCode.custom,path:[`sceneName`],message:`sceneName is required`}),e.token||t.addIssue({code:l.z.ZodIssueCode.custom,path:[`token`],message:`token is required`}),e.dom||t.addIssue({code:l.z.ZodIssueCode.custom,path:[`dom`],message:`dom is required`})});function vr(e){let t={};return e.split(` `).forEach(e=>{if(e.startsWith(J.runMode)){t.viewMode=e.slice(J.runMode.length);return}if(e.startsWith(J.centerIP)){t.centerIP=e.slice(J.centerIP.length);return}if(e.startsWith(J.privateKey)){t.privateKey=e.slice(J.privateKey.length);return}if(e.startsWith(J.showProgressBar)){let n=e.slice(J.showProgressBar.length);n===`true`?t.showProgressBar=!0:n===`false`&&(t.showProgressBar=!1)}}),t}function yr(e){let t=fr()||void 0;if(!t)return e;let n=vr(t);return Object.keys(n).length===0?e:{...e,...n}}function br(e){let t=yr(e),n=_r.safeParse(t);if(!n.success)throw new p(`Core`,`DTCEngine.constructor`,n.error.issues.map(e=>({field:e.path.length>0?e.path.join(`.`):`<root>`,reason:e.message,code:e.code})));let r=n.data;return{centerIP:r.centerIP??``,signalingServer:r.signalingServer,sceneName:r.sceneName??``,token:r.token??``,dom:r.dom,showProgressBar:r.showProgressBar,codec:r.codec,viewMode:r.viewMode,turnServer:r.turnServer,turnUser:r.turnUser,turnPwd:r.turnPwd,privateKey:r.privateKey??``,engineUuid:r.engineUuid,mapType:r.mapType,operationType:r.operationType,freeCheckInterval:r.freeCheckInterval,initialSettings:r.initialSettings,logger:r.logger,includeStack:r.includeStack,pixelStreamingLogger:r.pixelStreamingLogger,centerHeartbeatIntervalMs:gr.centerHeartbeatIntervalMs,centerHeartbeatTimeoutMs:gr.centerHeartbeatTimeoutMs}}const xr=[`token`,`privatekey`,`authorization`,`cookie`,`set-cookie`],Sr={enabled:!1,endpoint:``,apiKey:``,app:{name:`@nnepoch/dtc-sdk`,version:`0.1.0`,environment:`production`},batching:{enabled:!0,itemLimit:20,sendTimeoutMs:3e4},retry:{maxAttempts:2},failure:{disableAfterConsecutiveFailures:5,warningIntervalMs:3e4},redactKeys:xr},Cr=l.z.object({enabled:l.z.boolean().default(!1),endpoint:l.z.string().optional(),apiKey:l.z.string().optional(),app:l.z.object({name:l.z.string().min(1).default(`@nnepoch/dtc-sdk`),version:l.z.string().min(1).default(`0.1.0`),environment:l.z.string().min(1).default(`production`)}).default({name:`@nnepoch/dtc-sdk`,version:`0.1.0`,environment:`production`}),batching:l.z.object({enabled:l.z.boolean().default(!0),itemLimit:l.z.number().int().min(1).default(20),sendTimeoutMs:l.z.number().int().min(200).default(3e3)}).default({enabled:!0,itemLimit:20,sendTimeoutMs:3e3}),retry:l.z.object({maxAttempts:l.z.number().int().min(1).max(5).default(2)}).default({maxAttempts:2}),failure:l.z.object({disableAfterConsecutiveFailures:l.z.number().int().min(1).default(5),warningIntervalMs:l.z.number().int().min(1e3).default(3e4)}).default({disableAfterConsecutiveFailures:5,warningIntervalMs:3e4}),redactKeys:l.z.array(l.z.string().min(1)).default(xr)}).superRefine((e,t)=>{let n=typeof e.endpoint==`string`?e.endpoint.trim():``,r=n.length>0;if(e.enabled&&!r){t.addIssue({code:l.z.ZodIssueCode.custom,path:[`endpoint`],message:`qos reporting enabled requires endpoint`});return}e.enabled&&r&&!l.z.string().url().safeParse(n).success&&t.addIssue({code:l.z.ZodIssueCode.custom,path:[`endpoint`],message:`qos reporting endpoint must be a valid url`})});function wr(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Tr(e,t){let n={...e};return Object.entries(t).forEach(([e,t])=>{if(t!==void 0){if(wr(t)&&wr(n[e])){n[e]=Tr(n[e],t);return}n[e]=t}}),n}function Er(){let e=wr(globalThis.__ENGINE3_INTERNAL_QOS_REPORTING__)?{...globalThis.__ENGINE3_INTERNAL_QOS_REPORTING__}:{};typeof e.endpoint==`string`&&e.endpoint.trim().length===0&&delete e.endpoint,typeof e.apiKey==`string`&&e.apiKey.trim().length===0&&delete e.apiKey;let t=Tr(Sr,e);return Cr.parse(t)}function Dr(e,t){let n=e.toLowerCase();return t.some(e=>n.includes(e.toLowerCase()))}function Or(e){if(typeof e==`string`)return e;if(e===void 0)return`undefined`;if(e===null)return`null`;if(typeof e==`number`||typeof e==`boolean`||typeof e==`bigint`)return String(e);try{return JSON.stringify(e)}catch{return String(e)}}function kr(e,t){let n=new WeakSet,r=(e,i)=>{if(i&&Dr(i,t.redactKeys))return`[REDACTED]`;if(e===null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`)return e;if(typeof e==`bigint`)return e.toString();if(e===void 0)return`undefined`;if(typeof e==`function`||typeof e==`symbol`)return String(e);if(e instanceof Date)return e.toISOString();if(e instanceof Error)return{name:e.name,message:e.message,stack:e.stack};if(Array.isArray(e))return e.map(e=>r(e));if(typeof e==`object`&&e){if(n.has(e))return`[CIRCULAR]`;n.add(e);let t=Object.entries(e),i={};return t.forEach(([e,t])=>{i[e]=r(t,e)}),i}return Or(e)};return r(e)}function Ar(e){let t=e.toLowerCase();return t.includes(`auth`)?`auth`:t.includes(`center`)?`center`:t.includes(`sessionadapter`)||t.includes(`webrtc`)||t.includes(`pixelstreaming`)?`webrtc`:t.includes(`enginestatus`)||t.includes(`stream`)?`media`:t.includes(`requestbridge`)||t.includes(`camera`)||t.includes(`scene`)||t.includes(`model`)||t.includes(`poi`)||t.includes(`weather`)||t.includes(`timeline`)||t.includes(`popup`)||t.includes(`animation`)?`ue_api`:`session`}function jr(e){if(typeof e!=`string`)return;let t=e.trim();return t.length>0?t:void 0}function Mr(e){return e.trim().replace(/\s+/g,`_`).slice(0,64)}function Nr(e){if(!wr(e))return;let t=jr(e.code)??jr(e.errorCode)??jr(e.status);if(t)return Mr(t);let n=e.error;if(wr(n)){let e=jr(n.code)??jr(n.errorCode)??jr(n.status);if(e)return Mr(e)}}var Pr=class{constructor(e,t){this.config=e,this.deps=t}async send(e){let t=typeof AbortController<`u`?new AbortController:void 0,n=t?setTimeout(()=>{t.abort()},this.config.batching.sendTimeoutMs):void 0;try{let n=await this.deps.fetchImpl(this.config.endpoint??``,{method:`POST`,headers:{"Content-Type":`application/json`,...this.config.apiKey?{"x-api-key":this.config.apiKey}:{}},body:JSON.stringify(e),signal:t?.signal});if(!n.ok)throw Error(`qos reporting request failed: ${n.status}`)}finally{n&&clearTimeout(n)}}};function Fr(){return typeof fetch==`function`}var Ir=class{constructor(e,t,n,r,i={}){if(this.config=e,this.session=t,this.runtime=n,this.onWarning=r,this.queue=[],this.flushing=!1,this.consecutiveFailures=0,this.lastWarningAt=0,this.disabledByFailure=!1,this.warnCount=0,this.errorCount=0,this.errorByStage={},this.errorCodeCounts=new Map,this.now=i.now??Date.now,this.setTimeoutImpl=i.setTimeoutImpl??setTimeout,this.clearTimeoutImpl=i.clearTimeoutImpl??clearTimeout,!e.enabled){this.enabled=!1,this.transport=void 0;return}if(this.enabled=!0,i.createTransport){this.transport=i.createTransport(e);return}if(!Fr()){this.transport=void 0,this.warnLimited(`qos reporting skipped: fetch unavailable`);return}this.transport=new Pr(e,{fetchImpl:fetch})}startSession(e){this.resetWarnErrorSummary(),this.recordEvent({eventName:`session_start`,stage:`session`,status:`start`,attrs:e})}endSession(e){this.recordEvent({eventName:`session_end`,stage:`session`,status:`end`,attrs:e,metrics:{summary:this.getWarnErrorSummary()}}),this.flush()}recordEvent(e){if(!this.enabled||!this.transport||this.disabledByFailure)return;let t=e.attrs?kr(e.attrs,this.config):void 0,n=e.metrics?kr(e.metrics,this.config):void 0;if(this.queue.push({eventName:e.eventName,stage:e.stage,status:e.status,ts:e.ts??this.now(),level:e.level??(e.status===`failed`?`error`:`info`),durationMs:e.durationMs,errorCode:e.errorCode,errorMessage:e.errorMessage,attrs:t,metrics:n}),!this.config.batching.enabled||this.queue.length>=this.config.batching.itemLimit){this.flush();return}this.flushTimer||=this.setTimeoutImpl(()=>{this.flushTimer=void 0,this.flush()},this.config.batching.sendTimeoutMs)}recordLogSignal(e){if(e.level===`warn`){this.warnCount+=1;return}this.errorCount+=1;let t=Ar(e.moduleName);this.errorByStage[t]=(this.errorByStage[t]??0)+1;let n=Nr(e.meta)??`UNKNOWN`;this.errorCodeCounts.set(n,(this.errorCodeCounts.get(n)??0)+1)}getWarnErrorSummary(){let e=Array.from(this.errorCodeCounts.entries()).sort((e,t)=>t[1]-e[1]).map(([e,t])=>({code:e,count:t}));return{logWarnCount:this.warnCount,logErrorCount:this.errorCount,logErrorByStage:{...this.errorByStage},logErrorTopCodes:e}}async flush(){if(this.flushing||this.queue.length===0||!this.transport||this.disabledByFailure)return;this.flushing=!0,this.flushTimer&&=(this.clearTimeoutImpl(this.flushTimer),void 0);let e=this.config.batching.enabled?this.config.batching.itemLimit:this.queue.length,t=this.queue.splice(0,e),n={schemaVersion:`1.0.0`,source:`enginesdk3`,sdkVersion:this.config.app.version,sentAt:this.now(),session:this.session,context:this.runtime,events:t};try{await this.sendWithRetry(n),this.consecutiveFailures=0}catch(e){this.onFailure(e,`send qos payload failed`)}finally{this.flushing=!1,this.queue.length>0&&!this.disabledByFailure&&this.flush()}}async sendWithRetry(e){let t=Math.max(1,this.config.retry.maxAttempts),n;for(let r=1;r<=t;r+=1)try{await this.transport?.send(e);return}catch(e){n=e}throw n instanceof Error?n:Error(String(n))}onFailure(e,t){this.consecutiveFailures+=1,this.warnLimited(t,{consecutiveFailures:this.consecutiveFailures,error:e instanceof Error?`${e.name}: ${e.message}`:String(e)}),this.consecutiveFailures>=this.config.failure.disableAfterConsecutiveFailures&&(this.disabledByFailure=!0,this.warnLimited(`qos reporting disabled after repeated failures`))}warnLimited(e,t){let n=this.now();n-this.lastWarningAt<this.config.failure.warningIntervalMs||(this.lastWarningAt=n,this.onWarning(e,t))}resetWarnErrorSummary(){this.warnCount=0,this.errorCount=0,this.errorByStage={},this.errorCodeCounts.clear()}},Lr=class{constructor(){this.listeners=new Map,this.debugMode=!1}on(e,t){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),this.debugMode&&console.log(`[EventBus] Subscribed to "${String(e)}"`)}off(e,t){let n=this.listeners.get(e);n&&(n.delete(t),n.size===0&&this.listeners.delete(e)),this.debugMode&&console.log(`[EventBus] Unsubscribed from "${String(e)}"`)}emit(e,t){let n=this.listeners.get(e);this.debugMode&&console.log(`[EventBus] Emitting "${String(e)}"`,t),!(!n||n.size===0)&&n.forEach(n=>{try{n(t)}catch(t){console.error(`[EventBus] Error in handler for "${String(e)}":`,t)}})}once(e,t){let n=r=>{this.off(e,n),t(r)};this.on(e,n)}removeAllListeners(e){e===void 0?(this.listeners.clear(),this.debugMode&&console.log(`[EventBus] Removed all listeners`)):(this.listeners.delete(e),this.debugMode&&console.log(`[EventBus] Removed all listeners for "${String(e)}"`))}listenerCount(e){return this.listeners.get(e)?.size??0}eventNames(){return Array.from(this.listeners.keys())}setDebugMode(e){this.debugMode=e}};const Rr=[`webRtcConnected`,`webRtcDisconnected`,`webRtcConnecting`,`webRtcFailed`,`statsReceived`,`subscribeFailed`,`streamerAssigned`];var zr=class{constructor(){this.mode=`bs`,this.forwardEvents=[...Rr,`streamLoading`]}applyInitialSettings(e){return{[d.Flags.KeyboardInput]:!0,[d.Flags.MouseInput]:!0,[d.Flags.TouchInput]:!0,[d.Flags.GamepadInput]:!0,[d.Flags.XRControllerInput]:!0,[d.Flags.HoveringMouseMode]:!0,[d.Flags.AutoPlayVideo]:!0,[d.Flags.MatchViewportResolution]:!0,[d.Flags.StartVideoMuted]:!0,[d.NumericParameters.MaxReconnectAttempts]:0,...e}}onBeforeConnect(e){e.info(`session connect preparing for bs mode`)}onAfterConnect(e){e.info(`session connect triggered for bs mode`)}},Br=class{constructor(){this.mode=`cs`,this.forwardEvents=Rr}applyInitialSettings(e){return{[d.Flags.KeyboardInput]:!0,[d.Flags.MouseInput]:!1,[d.Flags.TouchInput]:!1,[d.Flags.GamepadInput]:!1,[d.Flags.XRControllerInput]:!1,[d.Flags.HoveringMouseMode]:!0,[d.Flags.AutoPlayVideo]:!0,[d.Flags.MatchViewportResolution]:!0,[d.Flags.StartVideoMuted]:!0,[d.NumericParameters.MaxReconnectAttempts]:0,...e}}onBeforeConnect(e){e.info(`session connect preparing for cs mode`)}onAfterConnect(e){e.info(`session connect triggered for cs mode`)}};function Vr(e){return e===`cs`?new Br:new zr}var Hr=class{constructor(e,t,n=_){this.logger=n,this.streamerAssignedListeners=new Set,this.handlePoiCursorResponse=e=>{try{let t=JSON.parse(e);if(t.uuid!==`POICursor`)return;this.setVideoCursor(t.param===`pointer`?`pointer`:`default`)}catch{}},this.videoElementParent=t,this.modeStrategy=Vr(e.viewMode);let r=this.modeStrategy.applyInitialSettings(e.initialSettings??{});this.psConfig=new d.Config({initialSettings:{...r}}),t?.classList?.add(`fixed-size`),t&&getComputedStyle(t).position===`static`&&(t.style.position=`relative`),this.stream=new d.PixelStreaming(this.psConfig,t?{videoElementParent:t}:void 0),this.stream.addResponseEventListener(`enginesdk_poi_cursor_listener`,this.handlePoiCursorResponse),this.setupStreamerAssignedListener(),this.logger.info(`session initialized`,{hasVideoParent:!!t,viewMode:this.modeStrategy.mode})}connect(){this.modeStrategy.onBeforeConnect(this.logger),this.logger.info(`connect`),this.stream.connect(),this.modeStrategy.onAfterConnect(this.logger)}reconnect(){this.logger.info(`reconnect`),this.stream.reconnect()}disconnect(){this.logger.info(`disconnect`),this.setVideoCursor(`default`),this.stream.disconnect()}beginPointEditorMouseInput(){let e=[d.Flags.MouseInput,d.Flags.HoveringMouseMode],t=e.map(e=>this.psConfig.isFlagEnabled(e));e.forEach(e=>this.psConfig.setFlagEnabled(e,!0));let n=!1;return()=>{n||(n=!0,e.forEach((e,n)=>this.psConfig.setFlagEnabled(e,t[n])))}}setSignallingUrlBuilder(e){this.logger.info(`setSignallingUrlBuilder configured`),this.stream.setSignallingUrlBuilder(e)}emitUIInteraction(e){let t=this.stream.emitUIInteraction(e);return t?this.logger.debug(`emitUIInteraction sent`):this.logger.warn(`emitUIInteraction failed`),t}emitCommand(e){let t=this.stream.emitCommand(e);return t?this.logger.debug(`emitCommand sent`):this.logger.warn(`emitCommand failed`),t}addResponseEventListener(e,t){this.logger.debug(`addResponseEventListener`,{name:e}),this.stream.addResponseEventListener(e,t)}removeResponseEventListener(e){this.logger.debug(`removeResponseEventListener`,{name:e}),this.stream.removeResponseEventListener(e)}addEventListener(e,t){if(this.logger.debug(`addEventListener`,{event:e}),e===`streamerAssigned`){this.streamerAssignedListeners.add(t);return}this.stream.addEventListener(e,t)}removeEventListener(e,t){if(this.logger.debug(`removeEventListener`,{event:e}),e===`streamerAssigned`){this.streamerAssignedListeners.delete(t);return}this.stream.removeEventListener(e,t)}getForwardEvents(){return this.modeStrategy.forwardEvents}getViewMode(){return this.modeStrategy.mode}isReconnecting(){return this.stream.isReconnecting()}setVideoCursor(e){this.videoElementParent&&(this.videoElementParent.style.cursor=e,this.videoElementParent.querySelectorAll(`video`).forEach(t=>{t.style.cursor=e}))}setupStreamerAssignedListener(){try{let e=this.stream.webRtcController?.protocol;if(!e||typeof e.addListener!=`function`){this.logger.warn(`webRtcController.protocol not available, streamerAssigned listener not registered`);return}e.addListener(`streamerAssigned`,e=>{if(this.logger.info(`streamerAssigned received`,{streamerId:e.streamerId}),e.streamerId)try{this.psConfig.setOptionSettingValue(d.OptionParameters.StreamerId,e.streamerId),this.logger.info(`StreamerId configured`,{streamerId:e.streamerId})}catch(t){this.logger.error(`Failed to set StreamerId`,{streamerId:e.streamerId,error:t instanceof Error?t.message:String(t)})}else this.logger.warn(`streamerAssigned received without streamerId`,{msg:e});this.streamerAssignedListeners.forEach(t=>{try{t(e)}catch(e){this.logger.error(`streamerAssigned listener error`,{error:e instanceof Error?e.message:String(e)})}})}),this.logger.debug(`streamerAssigned listener registered`)}catch(e){this.logger.error(`Failed to setup streamerAssigned listener`,{error:e instanceof Error?e.message:String(e)})}}};const Y={SignallingBootstrapFailed:`SIGNALLING_BOOTSTRAP_FAILED`,CenterUnavailable:`CENTER_UNAVAILABLE`,CenterProtocolInvalid:`CENTER_PROTOCOL_INVALID`,ConnectResultFailed:`CONNECT_RESULT_FAILED`,ServiceAllocationFailed:`SERVICE_ALLOCATION_FAILED`,ResourceWaiting:`RESOURCE_WAITING`,AuthorizeFailed:`AUTHORIZE_FAILED`,TokenInvalid:`TOKEN_INVALID`,TokenExpired:`TOKEN_EXPIRED`,SignallingUrlMissing:`SIGNALLING_URL_MISSING`,HeartbeatTimeout:`HEARTBEAT_TIMEOUT`,CenterDisconnected:`CENTER_DISCONNECTED`};var X=class extends Error{constructor(e,t,n,r){super(t),this.code=e,this.retryable=n,this.details=r,this.name=`SDKAuthError`}toErrorInfo(){return{code:this.code,message:this.message,retryable:this.retryable}}};function Ur(e){return e instanceof X?e:e instanceof Error?new X(Y.CenterUnavailable,e.message,!0,{cause:e.message}):new X(Y.CenterUnavailable,String(e),!0)}var Wr=class{constructor(e,t=_,n){this.config=e,this.logger=t,this.authEvents=n,this.textEncoder=new TextEncoder,this.connectId=``,this.events=new c.EventEmitter,this.manualClose=!1}on(e,t){this.events.on(e,t)}off(e,t){this.events.off(e,t)}isConnected(){return this.socket?.readyState===WebSocket.OPEN}getConnectId(){return this.connectId}async connect(){if(this.isConnected())return;this.disposeSocket(),this.connectId=this.generateConnectId();let e=this.buildCenterWsUrl(this.connectId),t=this.defaultWebSocketFactory;return this.logger.info(`center connecting`,{wsUrl:e}),this.manualClose=!1,this.closeReasonError=void 0,new Promise((n,r)=>{try{let i=t(e);this.socket=i,i.onopen=()=>{this.startHeartbeatLoops(),this.sendHeartbeat(),this.logger.info(`center connected`),i.binaryType=`arraybuffer`,n()},i.onmessage=e=>{this.handleIncomingData(e.data)},i.onerror=()=>{},i.onclose=()=>{this.stopHeartbeatLoops(),this.socket=void 0;let e=this.closeReasonError??new X(Y.CenterDisconnected,`Center websocket disconnected`,!0);this.manualClose||(this.events.emit(`disconnected`,e),r(e)),this.closeReasonError=void 0}}catch(e){this.authEvents.emit(`progress`,{kind:`loading`,message:y.ServiceUrlInValid,key:`ServiceUrlInValid`,isClose:!0}),r(new X(Y.CenterUnavailable,`Failed to create center websocket: ${e instanceof Error?e.message:String(e)}`,!0,{cause:e instanceof Error?e.message:String(e)}))}})}disconnect(){this.manualClose=!0,this.closeReasonError=void 0,this.disposeSocket()}sendApiData(e,t,n){if(!this.socket||this.socket.readyState!==WebSocket.OPEN)throw new X(Y.CenterDisconnected,`Center websocket is not connected`,!0);let r={projectKey:this.config.sceneName,cls:`WebAPI`,method:e,param:t,fn:n},i=JSON.stringify(r),a=this.textEncoder.encode(i),o=new Uint8Array(a.length+1);o.set(a),this.socket.send(o.buffer),e!==`Heart`&&this.logger.debug(`center send`,{method:e,callbackName:n})}defaultWebSocketFactory(e){if(typeof WebSocket>`u`)throw Error(`WebSocket is not available in current runtime.`);return new WebSocket(e)}startHeartbeatLoops(){this.stopHeartbeatLoops(),this.heartbeatTimer=setInterval(()=>{try{this.isConnected()&&this.sendHeartbeat()}catch(e){this.logger.warn(`send heartbeat failed`,{error:e instanceof Error?e.message:String(e)})}},this.config.centerHeartbeatIntervalMs)}sendHeartbeat(){this.sendApiData(`Heart`),this.armHeartbeatTimeout()}stopHeartbeatLoops(){this.heartbeatTimer&&=(clearInterval(this.heartbeatTimer),void 0),this.clearHeartbeatTimeout()}armHeartbeatTimeout(){this.heartbeatTimeoutTimer||=setTimeout(()=>{this.heartbeatTimeoutTimer=void 0;let e=new X(Y.HeartbeatTimeout,`Center heartbeat timed out after ${this.config.centerHeartbeatTimeoutMs}ms`,!0);this.closeReasonError=e,this.events.emit(`heartbeatTimeout`,e),this.socket?.close()},this.config.centerHeartbeatTimeoutMs)}clearHeartbeatTimeout(){this.heartbeatTimeoutTimer&&=(clearTimeout(this.heartbeatTimeoutTimer),void 0)}disposeSocket(){this.stopHeartbeatLoops(),this.socket&&=(this.socket.onopen=null,this.socket.onmessage=null,this.socket.onerror=null,this.socket.onclose=null,this.socket.close(),void 0)}async handleIncomingData(e){this.clearHeartbeatTimeout();let t=await this.decodeToBytes(e);if(!t)return;let n;try{n=(0,f.inflate)(t,{to:`string`})}catch{this.logger.warn(`center message inflate failed`);return}if(!n)return;let r;try{r=JSON.parse(n)}catch{this.logger.warn(`center message parse failed`);return}if(!r.fn){this.logger.warn(`center message missing fn`);return}r.fn!==`Heart`&&this.events.emit(`message`,r)}async decodeToBytes(e){if(e instanceof ArrayBuffer)return new Uint8Array(e);if(ArrayBuffer.isView(e))return new Uint8Array(e.buffer,e.byteOffset,e.byteLength);if(typeof Blob<`u`&&e instanceof Blob){let t=await e.arrayBuffer();return new Uint8Array(t)}return typeof e==`string`?this.textEncoder.encode(e):(this.logger.warn(`unsupported center message format`),null)}buildCenterWsUrl(e){return`${this.config.centerIP.replace(/^https:/i,`wss:`).replace(/^http:/i,`ws:`).replace(/\/+$/,``)}/${[this.config.mapType,e,this.config.sceneName,this.config.token,this.config.operationType].map(e=>encodeURIComponent(e)).join(`/`)}`}generateConnectId(){return`w_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,10)}`}};function Gr(e,t,n){let r=e.endsWith(`/`)?e:`${e}/`,i=new URL(`api/v1/allocate`,r);return i.searchParams.set(`token`,t),i.searchParams.set(`proj`,n),i.toString()}function Kr(e){if(typeof e.signalingAddress==`string`&&e.signalingAddress.trim().length>0)return e.signalingAddress.trim();if(typeof e.signallingAddress==`string`&&e.signallingAddress.trim().length>0)return e.signallingAddress.trim()}function qr(e,t){return new X(Y.SignallingBootstrapFailed,`Signalling allocate request timed out after ${t}ms`,!0,{endpoint:e,timeoutMs:t})}async function Jr(e,t=_){if(typeof fetch!=`function`)throw new X(Y.SignallingBootstrapFailed,`Fetch API is not available for signalling allocation`,!1);let n=Gr(e.signalingServer,e.token,e.proj),r=e.timeoutMs??15e3,i=typeof AbortController==`function`?new AbortController:void 0,a=!1,o,s=i?void 0:new Promise((e,t)=>{o=t}),c;c=setTimeout(()=>{if(a=!0,i){i.abort();return}o?.(qr(n,r))},r);try{let e=fetch(n,{method:`GET`,...i?{signal:i.signal}:{}}),r=i?await e:await Promise.race([e,s]);if(!r.ok)throw new X(Y.SignallingBootstrapFailed,`Signalling allocate request failed with status ${r.status}`,!0,{endpoint:n,status:r.status});let a;try{a=await r.json()}catch(e){throw new X(Y.SignallingBootstrapFailed,`Signalling allocate response is not valid JSON`,!1,{endpoint:n,cause:e instanceof Error?e.message:String(e)})}let o=Kr(a);if(!o)throw new X(Y.SignallingUrlMissing,`Signalling allocate response missing signalingAddress`,!1,a);return t.info(`signalling allocate resolved url`,{endpoint:n}),o}catch(e){throw a?qr(n,r):e instanceof X?e:new X(Y.SignallingBootstrapFailed,e instanceof Error?e.message:`Signalling allocate request failed`,!0,{endpoint:n,cause:e})}finally{c!==void 0&&clearTimeout(c)}}var Yr=class{constructor(e,t,n=_){this.config=e,this.session=t,this.logger=n,this.events=new c.EventEmitter,this.handleWebRtcDisconnected=()=>{this.recoverFromWebRtcDisconnection()},this.nextOperationId=0,this.phase=`idle`,this.stopRequested=!1,this.reconnecting=!1,this.snapshot={state:`idle`,reconnecting:!1,updatedAt:Date.now()},this.centerClient=new Wr(e,n,this.events),this.centerClient.on(`heartbeatTimeout`,e=>{this.logger.warn(`center heartbeat timeout`,{message:e.message}),this.handleCenterInterruption(e)}),this.centerClient.on(`disconnected`,e=>{this.logger.warn(`center disconnected`,{message:e.message}),this.handleCenterInterruption(e)}),this.centerClient.on(`message`,e=>{this.handleCenterMessage(e)}),this.session.addEventListener(`webRtcDisconnected`,this.handleWebRtcDisconnected)}on(e,t){this.events.on(e,t)}off(e,t){this.events.off(e,t)}getSnapshot(){return{...this.snapshot,reconnecting:this.reconnecting||this.session.isReconnecting()}}start(){return this.runningFlow?this.runningFlow.promise:this.startFlow({route:this.shouldUseDirectSignallingBootstrap()?`direct`:`center`,reconnecting:!1,disconnectSession:!1,resolveOnStop:!0})}reconnect(){return this.startFlow({route:this.shouldUseDirectSignallingBootstrap()?`direct`:`center`,reconnecting:!0,disconnectSession:!0,resolveOnStop:!0})}reconnectSignalling(){let e=this.signallingAllocationSource;return e?this.startFlow({route:`signalling`,reconnecting:!0,disconnectSession:!0,resolveOnStop:!1,signallingSource:e}):this.reconnect()}startFlow(e){if(this.runningFlow)return e.reconnecting&&(this.reconnecting=!0),e.disconnectSession&&this.session.disconnect(),this.runningFlow.promise;e.disconnectSession&&this.session.disconnect(),this.stopRequested=!1,this.reconnecting=e.reconnecting;let t=this.advanceOperation(),n=this.createRunningFlow(t,e.resolveOnStop);return this.runningFlow=n,this.phase=e.route===`signalling`?`settling`:`starting`,n.promise=this.decorateRunningFlow(n),(e.route===`center`||e.route===`direct`)&&this.prepareAuthBootstrap(t),this.runFlowRoute(e,t),n.promise}runFlowRoute(e,t){switch(e.route){case`center`:this.runCenterFlow(t);return;case`direct`:this.runDirectFlow(t);return;case`signalling`:this.runSignallingFlow(e.signallingSource,t);return}}prepareAuthBootstrap(e){this.centerClient.disconnect(),this.clearRunningContext(),this.pendingCenterInterruption=void 0,this.updateSnapshot(`centerConnecting`,{lastError:void 0,signallingUrl:void 0,engineToken:void 0,webToken:void 0}),this.isCurrentOperation(e)}runCenterFlow(e){this.runAuthFlowOnce(e)}runDirectFlow(e){this.startDirectSignallingBootstrap(e).catch(t=>{this.rejectActiveFlow(t,e)})}runSignallingFlow(e,t){if(!e){this.rejectActiveFlow(new X(Y.SignallingBootstrapFailed,`Signalling bootstrap source is missing`,!1),t);return}this.signallingAllocationSource=e,this.resolveAndConnectSignalling(e,t).catch(e=>{this.rejectActiveFlow(e,t)})}disconnect(){let e=this.runningFlow;this.advanceOperation(),this.runningFlow=void 0,this.reconnecting=!1,this.stopRequested=!0,this.pendingCenterInterruption=void 0,this.phase=`idle`;let t=new X(Y.CenterDisconnected,`Auth workflow disconnected by user`,!0);e&&(e.stopRequested=!0,e.reject?.(t),e.resolve=void 0,e.reject=void 0),this.centerClient.disconnect(),this.session.disconnect(),this.updateSnapshot(`idle`,{webToken:void 0,engineToken:void 0,signallingUrl:void 0,lastError:void 0}),e&&(e.stopSnapshot=this.getSnapshot())}disconnectAndWait(){let e=this.runningFlow?.promise;return this.disconnect(),e?e.then(()=>void 0,()=>void 0):Promise.resolve()}runAuthFlowOnce(e){this.isCurrentOperation(e)&&this.centerClient.connect().then(()=>{this.isCurrentOperation(e)&&(this.updateSnapshot(`centerConnected`),this.expectMessage(`ConnectResult`))}).catch(t=>{this.rejectActiveFlow(t,e)})}shouldUseDirectSignallingBootstrap(){return!!this.config.signalingServer}async startDirectSignallingBootstrap(e){if(!this.isCurrentOperation(e))return;this.setPhase(`settling`,e);let t=this.resolveDirectSignallingAllocationSource();this.signallingAllocationSource=t,await this.resolveAndConnectSignalling(t,e)}resolveDirectSignallingAllocationSource(){if(this.config.signalingServer)return{signalingServer:this.config.signalingServer,token:this.config.token,proj:this.config.sceneName};throw new X(Y.SignallingBootstrapFailed,`No signalling bootstrap source configured`,!1)}handleCenterMessage(e){switch(e.fn){case`ConnectResult`:this.emitCenterEvent(`ConnectResult`,e),this.handleConnectResult(e);return;case`EngineServiceInit`:this.emitCenterEvent(`EngineServiceInit`,e),this.handleEngineServiceInit(e);return;case`TokenAuthorize`:this.emitCenterEvent(`TokenAuthorize`,e),this.handleTokenAuthorize(e);return;case`CenterCloseMessage`:this.emitCenterEvent(`CenterCloseMessage`,e),this.handleCenterCloseMessage(e);return;case`EngineSocketClose`:this.emitCenterEvent(`EngineSocketClose`,e),this.handleEngineSocketClose(e);return;case`TokenWillExpired`:this.emitCenterEvent(`TokenWillExpired`,e),this.handleTokenWillExpired(e);return;case`Offer`:case`Answer`:case`IceCandidate`:this.logger.debug(`center message ignored by current change scope`,{fn:e.fn});return;default:this.logger.debug(`unhandled center message`,{fn:e.fn})}}handleConnectResult(e){if(this.isExpecting(`ConnectResult`))try{if(e.success===!1){this.logger.warn(`connect result failed`,{status:e.status??``,message:e.message??``});return}let t=this.parseValues(e),n=t.webToken;if(!n)throw new X(Y.ConnectResultFailed,`ConnectResult missing webToken`,!0,e);this.connectResult=t,this.emitCenterEvent(`Connect`,e),this.emitLoadingProgress(y.EngineIniting,`EngineIniting`),this.updateSnapshot(`serviceAllocating`,{webToken:n}),this.centerClient.sendApiData(`GetServiceInfo`,this.config.privateKey||void 0),this.expectMessage(`EngineServiceInit`)}catch(e){this.rejectActiveFlow(e)}}handleEngineServiceInit(e){if(this.isExpecting(`EngineServiceInit`))try{if(e.success===!1){let t=e.message??``;this.emitWaitingProgress(t),this.config.viewMode!==`cs`&&this.emitCenterEvent(`EngineServiceInitWait`,e),this.updateSnapshot(`waiting`);return}let t=this.parseValues(e),n=t.token;if(!n)throw new X(Y.ServiceAllocationFailed,`EngineServiceInit missing engine token`,!0,e);this.serviceInfo=t,this.emitLoadingProgress(y.EngineTockenChecking,`EngineTockenChecking`),this.updateSnapshot(`authorizing`,{engineToken:n});let r=JSON.stringify({engineToken:n,webUuid:this.centerClient.getConnectId(),webToken:this.snapshot.webToken});this.centerClient.sendApiData(`AuthorizeToken`,r,`TokenAuthorize`),this.expectMessage(`TokenAuthorize`)}catch(e){this.rejectActiveFlow(e)}}handleTokenAuthorize(e){if(!this.isExpecting(`TokenAuthorize`))return;if(e.success===!1){this.logger.warn(`token authorize failed, wait center close message`,{status:e.status??``,message:e.message??``});return}let t=this.runningFlow?.operationId;t!==void 0&&this.handleTokenAuthorizeSuccess(e,t).catch(e=>{this.rejectActiveFlow(e,t)})}async handleTokenAuthorizeSuccess(e,t){if(!this.isCurrentOperation(t))return;this.setPhase(`settling`,t);let n=(this.tryParseValues(e)??{}).signalingServer?.trim();if(!n)throw new X(Y.SignallingUrlMissing,`TokenAuthorize missing signalingServer`,!1,e);let r=this.snapshot.engineToken;if(!r)throw new X(Y.ServiceAllocationFailed,`Engine token is missing before signaling allocation`,!1,e);let i={signalingServer:n,token:r,proj:this.config.sceneName};this.signallingAllocationSource=i,await this.resolveAndConnectSignalling(i,t)}async resolveAndConnectSignalling(e,t){let n=await Jr(e,this.logger);if(!this.isCurrentOperation(t)){this.logger.debug(`ignore stale signalling allocation result`,{operationId:t});return}this.connectWithSignallingUrl(n,t)}connectWithSignallingUrl(e,t){if(!this.isCurrentOperation(t)){this.logger.debug(`ignore stale signalling connect result`,{operationId:t});return}if(!e)throw new X(Y.SignallingUrlMissing,`Signalling url is missing before connect`,!1);this.session.setSignallingUrlBuilder(()=>{let e=this.snapshot.signallingUrl;if(!e)throw new X(Y.SignallingUrlMissing,`Signalling url not ready before connect`,!1);return e}),this.emitLoadingProgress(y.EngineConnectioning,`EngineConnectioning`),this.updateSnapshot(`webrtcConnecting`,{signallingUrl:e}),this.session.connect(),this.setPhase(`connected`,t),this.updateSnapshot(`connected`),this.completeRunningFlow(this.getSnapshot(),t)}handleCenterCloseMessage(e){let t=e.message??`CenterCloseMessage received`;if(e.status===`TokenInValid`){this.emitLoadingProgress(y.TokenInValid,`TokenInValid`);let n=new X(Y.TokenInvalid,t,!1,e);this.rejectActiveFlow(n)||this.publishFailure(n),this.centerClient.disconnect();return}if(e.status===`TokenExpired`){this.emitLoadingProgress(y.TokenExpired,`TokenExpired`);let n=new X(Y.TokenExpired,t,!1,e);this.rejectActiveFlow(n)||this.publishFailure(n),this.centerClient.disconnect();return}this.emitLoadingProgress(y.EngineTokenCheckFail,`EngineTokenCheckFail`);let n=new X(Y.AuthorizeFailed,t,!1,e);this.rejectActiveFlow(n)||this.publishFailure(n)}handleEngineSocketClose(e){let t=this.snapshot.engineToken,n=this.extractEngineSocketCloseToken(e.values);if(!t||!n||t!==n){this.logger.debug(`ignore EngineSocketClose for non-current session`,{currentToken:t,closedToken:n});return}let r=new X(Y.CenterDisconnected,e.message??`Engine socket closed`,!0,e);this.emitLoadingProgress(y.EngineClose,`EngineClose`),this.handleCenterInterruption(r)}handleTokenWillExpired(e){this.logger.warn(`token will expire soon`,{message:e.message??``}),this.emitTokenWillExpireProgress(e.message??``)}expectMessage(e){this.expectedCenterFn=e}isExpecting(e){return this.expectedCenterFn===e&&this.hasActiveRunningFlow()}advanceOperation(){return this.nextOperationId+=1,this.nextOperationId}isCurrentOperation(e){return this.runningFlow?.operationId===e}setPhase(e,t){return this.isCurrentOperation(t)?(this.phase=e,!0):!1}createRunningFlow(e,t=!1){let n=()=>void 0,r=()=>void 0;return{operationId:e,promise:new Promise((e,t)=>{n=e,r=t}),resolve:n,reject:r,stopRequested:!1,resolveOnStop:t}}decorateRunningFlow(e){return e.promise.then(t=>e.stopRequested?e.stopSnapshot??this.getSnapshot():(this.reconnecting=!1,this.events.emit(`connected`,t),t)).catch(t=>{if(e.stopRequested){if(e.resolveOnStop)return e.stopSnapshot??this.getSnapshot();throw Ur(t)}let n=Ur(t);throw this.isCurrentOperation(e.operationId)&&(this.updateSnapshot(`failed`,{lastError:n.toErrorInfo()}),this.events.emit(`failed`,this.getSnapshot())),n}).finally(()=>{if(!this.isCurrentOperation(e.operationId))return;let t=e.stopRequested||this.stopRequested;this.setPhase(this.snapshot.state===`connected`?`connected`:`idle`,e.operationId),this.runningFlow=void 0,this.reconnecting=!1,this.stopRequested=!1,this.flushPendingCenterInterruption(t,e.operationId)})}completeRunningFlow(e,t){if(!this.isCurrentOperation(t)){this.logger.debug(`ignore stale auth flow completion`,{operationId:t});return}let n=this.runningFlow;this.clearRunningContext(t),n?.resolve?.(e),n&&(n.resolve=void 0,n.reject=void 0)}rejectActiveFlow(e,t){let n=Ur(e),r=this.runningFlow;if(!r||t!==void 0&&r.operationId!==t)return this.logger.debug(`ignore stale auth flow failure`,{operationId:t,currentOperationId:r?.operationId,code:n.code,message:n.message}),!1;let i=r.reject;return i?(this.clearRunningContext(r.operationId),r.resolve=void 0,r.reject=void 0,i(n),!0):(this.logger.debug(`ignore auth flow failure without active deferred`,{operationId:r.operationId,code:n.code,message:n.message}),!1)}publishFailure(e){this.updateSnapshot(`failed`,{lastError:e.toErrorInfo()}),this.events.emit(`failed`,this.getSnapshot())}hasActiveRunningFlow(){return!!this.runningFlow?.reject}clearRunningContext(e){e!==void 0&&!this.isCurrentOperation(e)||(this.expectedCenterFn=void 0,this.connectResult=void 0,this.serviceInfo=void 0)}isWaitingMessage(e){return[`坐席已满`,`服务已满`,`排队`,`没有服务资源`,`资源`].some(t=>e.includes(t))}parseValues(e){if(!e.values)return{};try{return JSON.parse(e.values)}catch(t){throw new X(Y.CenterProtocolInvalid,`Invalid center values json for ${e.fn}`,!1,{envelope:e,cause:t instanceof Error?t.message:String(t)})}}tryParseValues(e){if(e.values)try{return JSON.parse(e.values)}catch(t){this.logger.warn(`center values parse failed, fallback to empty payload`,{fn:e.fn,cause:t instanceof Error?t.message:String(t)});return}}extractEngineSocketCloseToken(e){if(!e)return;let t=e.trim();if(t){try{let e=JSON.parse(t);if(typeof e==`string`)return e;if(e&&typeof e.token==`string`&&e.token.trim().length>0)return e.token}catch{}return t}}handleCenterInterruption(e){let t=this.decideCenterInterruption();switch(t.kind){case`ignore`:return;case`reject`:this.rejectActiveFlow(e,t.operationId);return;case`defer`:this.deferCenterInterruption(e,t.operationId);return;case`recover`:this.recoverFromCenterInterruption(e);return}}decideCenterInterruption(){if(this.isTerminalSnapshot())return{kind:`ignore`};let e=this.runningFlow;return e?this.phase===`settling`?{kind:`defer`,operationId:e.operationId}:this.hasActiveRunningFlow()?{kind:`reject`,operationId:e.operationId}:{kind:`defer`,operationId:e.operationId}:{kind:`recover`}}isTerminalSnapshot(){return this.isTerminalSnapshotState(this.snapshot.state)}deferCenterInterruption(e,t){if(this.isCurrentOperation(t)){if(this.pendingCenterInterruption){this.logger.debug(`center interruption already deferred during flow settlement`,{currentCode:this.pendingCenterInterruption.error.code,incomingCode:e.code});return}this.pendingCenterInterruption={operationId:t,error:e},this.logger.debug(`defer center interruption until current flow settles`,{operationId:t,code:e.code,message:e.message})}}flushPendingCenterInterruption(e,t){let n=this.pendingCenterInterruption;if(!(!n||n.operationId!==t)){if(this.pendingCenterInterruption=void 0,e||this.snapshot.state===`idle`||this.snapshot.state===`failed`||this.runningFlow){this.logger.debug(`drop deferred center interruption`,{skip:e,state:this.snapshot.state,code:n.error.code,operationId:t});return}this.recoverFromCenterInterruption(n.error)}}recoverFromWebRtcDisconnection(){let e=this.snapshot.state;if(this.shouldIgnoreWebRtcDisconnection(e)){this.logger.debug(`ignore WebRTC disconnection for current workflow state`,{stopRequested:this.stopRequested,reconnecting:this.reconnecting,hasRunningPromise:!!this.runningFlow,state:e});return}this.logger.warn(`WebRTC disconnected, reconnect signalling`,{state:e}),this.reconnectSignalling().catch(e=>{let t=Ur(e);this.publishFailure(t)})}shouldIgnoreWebRtcDisconnection(e){return this.stopRequested||this.reconnecting||!!this.runningFlow||this.isTerminalSnapshotState(e)}isTerminalSnapshotState(e){return e===`idle`||e===`failed`}recoverFromCenterInterruption(e){this.logger.warn(`center interruption detected, start reconnect`,{state:this.snapshot.state,code:e.code,message:e.message}),this.emitCenterEvent(`UnConnect`,{code:e.code,message:e.message}),this.emitLoadingProgress(y.SerriceError,`SerriceError`),this.reconnect().catch(e=>{let t=Ur(e);this.publishFailure(t)})}updateSnapshot(e,t){this.snapshot={...this.snapshot,...t,state:e,reconnecting:this.reconnecting||this.session.isReconnecting(),updatedAt:Date.now()},this.events.emit(`stateChanged`,this.getSnapshot())}emitLoadingProgress(e,t,n=!0){this.events.emit(`progress`,{kind:`loading`,message:e,key:t,isClose:n})}emitTokenWillExpireProgress(e,t=!0){this.events.emit(`progress`,{kind:`tokenWillExpire`,message:e,key:`TokenWillExpired`,isClose:t})}emitCenterEvent(e,t){this.events.emit(`centerEvent`,{eventName:e,payload:t})}emitWaitingProgress(e){if(this.config.viewMode!==`cs`){if(e.includes(`云渲染服务坐席已满`)||e.includes(`坐席已满`)||e.includes(`当前服务已满`)){this.emitLoadingProgress(e,`EngineWaiting`);return}e.includes(`没有服务资源`)&&this.emitLoadingProgress(y.SerriceUnAvaible,`SerriceUnAvaible`)}}};function Xr(e){return typeof e==`object`&&!!e}var Zr=class{constructor(e,t=_,n={},r={}){this.session=e,this.logger=t,this.hooks=n,this.pending=new Map,this.sendRetries=new Map,this.listenerName=`enginesdk3_response_listener`,this.disconnectEvents=[`webRtcDisconnected`,`webRtcFailed`],this.onResponse=this.handleResponse.bind(this),this.onSessionDisconnected=()=>{this.cleanupPendingOnDisconnect()},this.retryOptions={enabled:r.enabled??!0,intervalMs:r.intervalMs??250,maxWaitMs:r.maxWaitMs??15e3},this.logger.debug(`register response listener`,{listenerName:this.listenerName}),this.session.addResponseEventListener(this.listenerName,this.onResponse),this.disconnectEvents.forEach(e=>{this.session.addEventListener(e,this.onSessionDisconnected)})}sendRequest(e,t,n){let{requestId:r,envelope:i}=this.createRequestEnvelope(e,t,n),a,o,s=new Promise((e,t)=>{a=e,o=t}),c={mode:`single`,module:e,method:t,sentAt:Date.now(),resolve:a,reject:o};return this.pending.set(r,c),this.handleSendAttempt(r,i,c,!1),s}sendStreamRequest(e,t,n,r){let{requestId:i,envelope:a}=this.createRequestEnvelope(e,t,n),o=r??(()=>void 0),s,c,l=new Promise((e,t)=>{s=e,c=t});Object.defineProperty(l,"requestId",{value:i,enumerable:!0}),l.cancel=e=>{this.cancelStreamRequest(i,e)};let u={mode:`stream`,module:e,method:t,sentAt:Date.now(),callback:o,isDone:e=>this.defaultStreamDonePredicate(e),resolve:s,reject:e=>c(e)};return this.pending.set(i,u),this.handleSendAttempt(i,a,u,!0),l}sendPendingRequest(e,t,n){if(this.logger.debug(`emit ${n.mode} request`,{requestId:e,module:n.module,method:n.method}),!this.session.emitUIInteraction(t)){let t=Error(`Failed to send ${n.mode} request: ${n.module}.${n.method}`);return this.logger.error(`emit request failed`,{requestId:e,module:n.module,method:n.method}),t}this.hooks.onRequestSent?.({requestId:e,module:n.module,method:n.method})}handleSendAttempt(e,t,n,r){let i=this.sendPendingRequest(e,t,n);if(i){if(!this.retryOptions.enabled){this.settlePendingFailure(e,n,i,{notifyStream:r});return}this.logger.warn(`emit request failed, will retry until transport ready`,{requestId:e,module:n.module,method:n.method,error:i.message}),this.scheduleSendRetry(e,t,n,r,i)}}scheduleSendRetry(e,t,n,r,i){let a=this.sendRetries.get(e);if(a){a.lastError=i,a.timer===void 0&&(a.timer=setTimeout(()=>this.runSendRetry(a),this.retryOptions.intervalMs));return}let o={requestId:e,envelope:t,pending:n,notifyStream:r,queuedAt:Date.now(),lastError:i};this.sendRetries.set(e,o),o.timer=setTimeout(()=>this.runSendRetry(o),this.retryOptions.intervalMs)}runSendRetry(e){if(e.timer=void 0,this.sendRetries.get(e.requestId)!==e)return;let t=Date.now()-e.queuedAt;if(t>=this.retryOptions.maxWaitMs){this.sendRetries.delete(e.requestId);let{module:n,method:r,mode:i}=e.pending,a=Error(`Failed to send ${i} request: ${n}.${r} after retrying for ${t}ms (${e.lastError.message})`);this.logger.error(`send retry gave up`,{requestId:e.requestId,module:n,method:r,error:a.message}),this.settlePendingFailure(e.requestId,e.pending,a,{notifyStream:e.notifyStream});return}let n=this.sendPendingRequest(e.requestId,e.envelope,e.pending);if(!n){this.sendRetries.delete(e.requestId),this.logger.info(`request sent after transport ready retry`,{requestId:e.requestId,module:e.pending.module,method:e.pending.method});return}e.lastError=n,this.logger.debug(`send retry attempt failed, will retry again`,{requestId:e.requestId,module:e.pending.module,method:e.pending.method,error:n.message}),e.timer=setTimeout(()=>this.runSendRetry(e),this.retryOptions.intervalMs)}clearSendRetry(e){let t=this.sendRetries.get(e);t&&(t.timer!==void 0&&clearTimeout(t.timer),this.sendRetries.delete(e))}settlePendingFailure(e,t,n,r={}){this.pending.get(e)===t&&(this.pending.delete(e),this.clearSendRetry(e),t.mode===`stream`&&r.notifyStream&&this.emitStreamCallback(t,{type:`error`,requestId:e,response:r.response,error:n}),t.reject(n))}handleResponse(e){let t;try{t=JSON.parse(e)}catch(e){this.logger.warn(`response parse failed`,{error:h(e)});return}let n=t.requestId??t.uuid;if(!n){this.logger.warn(`response missing requestId`);return}t.requestId=n,t.param!==void 0&&t.params===void 0&&(t.params=t.param);let r=this.pending.get(n);if(!r){this.logger.debug(`response ignored, no pending request`,{requestId:n});return}if(r.mode===`single`){this.pending.delete(n),this.resolveSingleResponse(t,r);return}this.resolveStreamResponse(t,r)}createRequestEnvelope(e,t,n){let r=`r_${Date.now()}_${Math.random().toString(16).slice(2,10)}`;return{requestId:r,envelope:{AssemblyName:`EngineApi`,fn:r,ClassName:e,FunctionName:t,Value:JSON.stringify(n),ts:Date.now()}}}defaultStreamDonePredicate(e){if(typeof e.code==`string`){let t=e.code.trim().toUpperCase();if(t===`DONE`||t===`STREAM_DONE`)return!0}return!!this.hasDoneFlag(e)}hasDoneFlag(e){return[e,e.data].some(e=>Xr(e)?e.done===!0||e.isEnd===!0:!1)}resolveSingleResponse(e,t){if(e.success||!e.success&&e.errorMsg!=null){this.emitResponseReceivedHook(e,t),this.logger.info(`response success`,{requestId:e.requestId,code:e.code}),t.resolve(e);return}this.logger.warn(`response failed`,{requestId:e.requestId,code:``,message:e.errorMsg}),t.reject(Error(` ${e.errorMsg}`))}resolveStreamResponse(e,t){if(!e.success){let n=Error(` ${e.errorMsg??e.message}`);this.logger.warn(`stream response failed`,{requestId:e.requestId,code:e.code,message:e.errorMsg??e.message}),this.settlePendingFailure(e.requestId,t,n,{response:e,notifyStream:!0});return}if(this.emitResponseReceivedHook(e,t),t.isDone(e)){this.pending.delete(e.requestId);let n=this.emitStreamCallback(t,this.createStreamResponseEvent(`done`,e));if(n){t.reject(n);return}this.logger.info(`stream request done`,{requestId:e.requestId,code:e.code}),t.resolve(e);return}let n=this.emitStreamCallback(t,this.createStreamResponseEvent(`data`,e));n&&this.settlePendingFailure(e.requestId,t,n)}createStreamResponseEvent(e,t){return{...t,type:e,requestId:t.requestId,response:t,data:t.data,params:t.params,param:t.params??t.param,errorMsg:t.errorMsg}}emitResponseReceivedHook(e,t){this.hooks.onResponseReceived?.({requestId:e.requestId,module:t.module,method:t.method,durationMs:Math.max(0,Date.now()-t.sentAt),code:e.code})}emitStreamCallback(e,t){try{e.callback(t);return}catch(e){let n=e instanceof Error?e:Error(String(e));return this.logger.warn(`stream callback failed`,{requestId:t.requestId,type:t.type,error:n.message}),n}}cancelStreamRequest(e,t){let n=this.pending.get(e);if(!n||n.mode!==`stream`)return;this.pending.delete(e),this.clearSendRetry(e);let r=t?.trim()||`Stream request cancelled by client`,i=Error(r);this.logger.info(`stream request cancelled`,{requestId:e,module:n.module,method:n.method}),this.emitStreamCallback(n,{type:`cancel`,requestId:e,error:i}),n.reject(i)}cleanupPendingOnDisconnect(){if(this.sendRetries.forEach(e=>{e.timer!==void 0&&clearTimeout(e.timer)}),this.sendRetries.clear(),this.pending.size===0)return;let e=Error(`Session disconnected before request completed`);this.pending.forEach((t,n)=>{t.mode===`single`||this.emitStreamCallback(t,{type:`error`,requestId:n,error:e}),t.reject(e),this.logger.warn(`pending request cleared on disconnect`,{requestId:n,mode:t.mode})}),this.pending.clear()}};function Qr(e){return typeof e==`object`&&!!e}function Z(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function $r(e){if(!Qr(e))return;let t=e.data;if(!Qr(t))return;let n=t.aggregatedStats;if(Qr(n))return n}function ei(e,t,n){if(e===void 0||t===void 0)return{packetLossRate:void 0,next:n};let r={packetsLost:e,packetsReceived:t};if(!n)return{packetLossRate:void 0,next:r};let i=e-n.packetsLost,a=t-n.packetsReceived;if(i<0||a<0)return{packetLossRate:void 0,next:r};let o=i+a;if(o<=0)return{packetLossRate:void 0,next:r};let s=i/o;return{packetLossRate:Math.max(0,Math.min(1,s)),next:r}}function ti(e){let t=e.getActiveCandidatePair;if(typeof t!=`function`)return;let n=t.call(e);if(!Qr(n))return;let r=Z(n.currentRoundTripTime);return r===void 0?void 0:r*1e3}function ni(e,t){let n=$r(e);if(!n)return;let r=Qr(n.inboundVideoStats)?n.inboundVideoStats:{},i=Z(r.bitrate),a=ei(Z(r.packetsLost),Z(r.packetsReceived),t);return{aggregatedStats:n,inboundVideoStats:r,metrics:{fps:Z(r.framesPerSecond),bitrateKbps:i===void 0?void 0:i/1e3,packetLossRate:a.packetLossRate,jitterMs:(()=>{let e=Z(r.jitter);return e===void 0?void 0:e*1e3})(),rttMs:ti(n),frameWidth:Z(r.frameWidth),frameHeight:Z(r.frameHeight)},packetCounters:a.next}}function ri(){return{CameraHeight:`-`,FPS:`-`,Width:`-`,Height:`-`,runTime:`-`,bytePerSecond:`-`,lostPacketsRate:`-`,delayTime:`-`,Codec:`-`}}function ii(e){if(typeof e==`string`)return e;if(typeof e==`number`||typeof e==`boolean`)return String(e)}function ai(e){if(e<=0||!Number.isFinite(e))return`00:00:00`;let t=Math.floor(e/1e3);return[Math.floor(t/3600),Math.floor(t%3600/60),t%60].map(e=>String(e).padStart(2,`0`)).join(`:`)}var oi=class{constructor(e,t,n=_,r){this.session=e,this.onStatus=t,this.logger=n,this.onSample=r,this.connected=!1,this.status=ri(),this.onWebRtcConnected=()=>{this.connected=!0,this.firstStatsTimestampMs=void 0,this.lastStatsTimestamp=void 0,this.packetCounters=void 0,this.logger.info(`engine status collector started`)},this.onWebRtcDisconnected=()=>{this.pause(`webRtcDisconnected`)},this.onWebRtcFailed=()=>{this.pause(`webRtcFailed`)},this.onWebRtcConnecting=()=>{this.pause(`webRtcConnecting`)},this.onStatsReceived=e=>{if(!this.connected)return;let t=ni(e,this.packetCounters);t&&(this.packetCounters=t.packetCounters,this.status=this.patchByStats(this.status,t),this.onSample?.(this.extractMediaSample(t)),this.emit())},this.session.addEventListener(`webRtcConnected`,this.onWebRtcConnected),this.session.addEventListener(`webRtcDisconnected`,this.onWebRtcDisconnected),this.session.addEventListener(`webRtcFailed`,this.onWebRtcFailed),this.session.addEventListener(`webRtcConnecting`,this.onWebRtcConnecting),this.session.addEventListener(`statsReceived`,this.onStatsReceived)}stop(){this.pause(`manualStop`)}dispose(){this.stop(),this.session.removeEventListener(`webRtcConnected`,this.onWebRtcConnected),this.session.removeEventListener(`webRtcDisconnected`,this.onWebRtcDisconnected),this.session.removeEventListener(`webRtcFailed`,this.onWebRtcFailed),this.session.removeEventListener(`webRtcConnecting`,this.onWebRtcConnecting),this.session.removeEventListener(`statsReceived`,this.onStatsReceived)}pause(e){this.connected&&(this.connected=!1,this.lastStatsTimestamp=void 0,this.packetCounters=void 0,this.logger.info(`engine status collector paused`,{reason:e}))}patchByStats(e,t){let n=t.aggregatedStats,r=t.inboundVideoStats,i={...e},a=t.metrics.frameWidth;a!==void 0&&(i.Width=String(a));let o=t.metrics.frameHeight;o!==void 0&&(i.Height=String(o));let s=t.metrics.fps;s!==void 0&&(i.FPS=String(s));let c=t.metrics.bitrateKbps;c!==void 0&&(i.bytePerSecond=`${Math.round(c)} kb/s`),i.lostPacketsRate=t.metrics.packetLossRate===void 0?`-`:`${(t.metrics.packetLossRate*100).toFixed(2)}%`;let l=Z(r.timestamp);if(l!==void 0){if(this.lastStatsTimestamp!==void 0){let e=l-this.lastStatsTimestamp;i.delayTime=`${Math.max(0,1e3-e).toFixed(2)} ms`}this.lastStatsTimestamp=l}this.firstStatsTimestampMs===void 0&&(this.firstStatsTimestampMs=Date.now()),i.runTime=ii(n.sessionStats?.runTime)??ai(Date.now()-this.firstStatsTimestampMs);let u=ii(r.codecId),d=u?this.getCodecMimeType(n,u):void 0;return d&&(i.Codec=d),i}extractMediaSample(e){return{...e.metrics,bitrateKbps:e.metrics.bitrateKbps===void 0?void 0:Math.round(e.metrics.bitrateKbps)}}getCodecMimeType(e,t){let n=e.codecs;if(!n)return;let r;(n instanceof Map||typeof n.get==`function`)&&(r=n.get(t));let i=r?.mimeType;return typeof i==`string`&&i.length>0?i:void 0}emit(){this.onStatus({...this.status})}};const si=[`Normal`,`Mild`,`Moderate`,`Severe`];function ci(e){return si.indexOf(e)}function li(e,t){return ci(e)>=ci(t)?e:t}function ui(e,t){let n=ci(t);return e.filter(e=>ci(e)>=n).length}function di(e){return e===`Severe`?`Moderate`:e===`Moderate`?`Mild`:`Normal`}function fi(e){return e===void 0?`Normal`:e>=.1?`Severe`:e>=.06?`Moderate`:e>=.03?`Mild`:`Normal`}function pi(e){return e===void 0?`Normal`:e>=240?`Severe`:e>=180?`Moderate`:e>=120?`Mild`:`Normal`}function mi(e){return e===void 0?`Normal`:e>=80?`Severe`:e>=50?`Moderate`:e>=25?`Mild`:`Normal`}function hi(e){return e===void 0?`Normal`:e<=12?`Severe`:e<=20?`Moderate`:e<=28?`Mild`:`Normal`}function gi(e){let t=fi(e.packetLossRate),n=li(pi(e.rttMs),mi(e.jitterMs)),r=[t,n,hi(e.fps)],i=[t,n];return r.some(e=>e===`Severe`)?`Severe`:ui(r,`Moderate`)>=2||ui(i,`Moderate`)>=1&&ui(r,`Mild`)>=2?`Moderate`:ui(r,`Mild`)>=2||ui(i,`Moderate`)>=1?`Mild`:`Normal`}function _i(e,t,n,r,i=e){return{measuredLevel:t,outcome:n,reason:r,degradeStreak:i.degradeStreak,recoverStreak:i.recoverStreak}}const vi=[{evaluate(e,t){if(!(e.connected&&e.metrics.connected))return _i(e,t,`hold`,`session not connected, skip adaptation`)}},{evaluate(e,t){if(e.actionInFlight)return _i(e,t,`hold`,`action in flight`)}},{evaluate(e,t){if(!(e.now>=e.cooldownUntil))return _i(e,t,`skip_cooldown`,`cooldown until ${e.cooldownUntil}`)}},{evaluate(e,t){if(ci(t)<=ci(e.stableLevel))return;let n=e.degradeStreak+1,r=t===`Severe`?1:2;return n<r?_i(e,t,`skip_hysteresis`,`degrade streak ${n}/${r}`,{degradeStreak:n,recoverStreak:0}):{measuredLevel:t,outcome:`downgrade`,targetLevel:t,reason:`measured ${t}`,degradeStreak:0,recoverStreak:0}}},{evaluate(e,t){if(t!==`Normal`||e.stableLevel===`Normal`)return;let n=e.recoverStreak+1;if(n<4)return _i(e,t,`skip_hysteresis`,`recover streak ${n}/4`,{degradeStreak:0,recoverStreak:n});let r=di(e.stableLevel);return{measuredLevel:t,outcome:`recover`,targetLevel:r,reason:`recover to ${r}`,degradeStreak:0,recoverStreak:0}}},{evaluate(e,t){return _i(e,t,`hold`,`no transition`,{degradeStreak:0,recoverStreak:t===`Normal`?e.recoverStreak:0})}}];function yi(e){let t=gi(e.metrics);for(let n of vi){let r=n.evaluate(e,t);if(r)return r}return _i(e,t,`hold`,`no transition`)}const bi={Normal:{bitrate:12e6,fps:60,width:1920,height:1080},Mild:{bitrate:8e6,fps:45,width:1600,height:900},Moderate:{bitrate:4e6,fps:30,width:1280,height:720},Severe:{bitrate:2e6,fps:20,width:960,height:540}};function xi(e){let t=e.filter(e=>typeof e==`number`&&Number.isFinite(e));if(t.length!==0)return t.reduce((e,t)=>e+t,0)/t.length}var Si=class{constructor(e){this.metricsWindow=[],this.traces=[],this.connected=!1,this.mode=`auto`,this.currentLevel=`Normal`,this.stableLevel=`Normal`,this.diagnosticsVisible=!1,this.degradeStreak=0,this.recoverStreak=0,this.cooldownUntil=0,this.actionInFlight=!1,this.lastAppliedProfileKey=``,this.transitionGeneration=0,this.onStatsReceived=e=>{this.handleStatsReceived(e)},this.onWebRtcConnected=()=>{this.connected=!0,this.metricsWindow.length=0,this.degradeStreak=0,this.recoverStreak=0,this.cooldownUntil=0,this.actionInFlight=!1,this.packetCounters=void 0,this.lastMetrics=void 0,this.currentLevel=`Normal`,this.stableLevel=`Normal`,this.lastAppliedProfileKey=``,this.transitionGeneration+=1,this.logger.info(`network adaptation received webRtcConnected`),this.pushTrace({outcome:`hold`,reason:`webrtc connected, resume adaptation`}),this.emitDiagnosticsSnapshot()},this.onWebRtcConnecting=()=>{this.handleConnectionInterrupted(`webRtcConnecting`)},this.onWebRtcDisconnected=()=>{this.handleConnectionInterrupted(`webRtcDisconnected`)},this.onWebRtcFailed=()=>{this.handleConnectionInterrupted(`webRtcFailed`)},this.session=e.session,this.screen=e.screen,this.logger=e.logger??_,this.onStateChange=e.onStateChange,this.onAction=e.onAction,this.onDiagnostics=e.onDiagnostics}start(){this.session.addEventListener(`statsReceived`,this.onStatsReceived),this.session.addEventListener(`webRtcConnected`,this.onWebRtcConnected),this.session.addEventListener(`webRtcConnecting`,this.onWebRtcConnecting),this.session.addEventListener(`webRtcDisconnected`,this.onWebRtcDisconnected),this.session.addEventListener(`webRtcFailed`,this.onWebRtcFailed)}dispose(){this.session.removeEventListener(`statsReceived`,this.onStatsReceived),this.session.removeEventListener(`webRtcConnected`,this.onWebRtcConnected),this.session.removeEventListener(`webRtcConnecting`,this.onWebRtcConnecting),this.session.removeEventListener(`webRtcDisconnected`,this.onWebRtcDisconnected),this.session.removeEventListener(`webRtcFailed`,this.onWebRtcFailed)}setMode(e){this.mode!==e&&(this.mode=e,this.pushTrace({outcome:`manual`,reason:`mode switched to ${e}`}),this.emitDiagnosticsSnapshot(),e===`auto`&&this.lastMetrics&&this.evaluateAutoStrategy(this.lastMetrics))}setManualLevel(e){this.setMode(`manual`),this.transitionToLevel(e,`manual`,`manual override to ${e}`,!0)}setDiagnosticsVisible(e){this.diagnosticsVisible=e,this.emitDiagnosticsSnapshot()}getDiagnosticsSnapshot(){return{ts:Date.now(),visible:this.diagnosticsVisible,mode:this.mode,currentLevel:this.currentLevel,connected:this.connected,lastMetrics:this.lastMetrics,lastAction:this.lastAction,traces:[...this.traces]}}handleStatsReceived(e){let t=ni(e,this.packetCounters);if(!t)return;this.packetCounters=t.packetCounters;let n={ts:Date.now(),connected:this.connected,...t.metrics};this.lastMetrics=this.pushMetrics(n),this.emitDiagnosticsSnapshot(),this.mode!==`manual`&&this.evaluateAutoStrategy(this.lastMetrics)}handleConnectionInterrupted(e){this.connected=!1,this.logger.warn(`network adaptation connection interrupted`,{source:e}),this.metricsWindow.length=0,this.recoverStreak=0,this.degradeStreak=0,this.cooldownUntil=0,this.actionInFlight=!1,this.packetCounters=void 0,this.transitionGeneration+=1,this.pushTrace({outcome:`hold`,reason:`${e}; session disconnected, pause adaptation`}),this.emitDiagnosticsSnapshot()}pushMetrics(e){return this.metricsWindow.push(e),this.metricsWindow.length>5&&this.metricsWindow.shift(),{ts:e.ts,connected:e.connected,fps:xi(this.metricsWindow.map(e=>e.fps)),bitrateKbps:xi(this.metricsWindow.map(e=>e.bitrateKbps)),packetLossRate:xi(this.metricsWindow.map(e=>e.packetLossRate)),jitterMs:xi(this.metricsWindow.map(e=>e.jitterMs)),rttMs:xi(this.metricsWindow.map(e=>e.rttMs)),frameWidth:xi(this.metricsWindow.map(e=>e.frameWidth)),frameHeight:xi(this.metricsWindow.map(e=>e.frameHeight))}}evaluateAutoStrategy(e){let t=yi({connected:this.connected,metrics:e,currentLevel:this.currentLevel,stableLevel:this.stableLevel,mode:this.mode,actionInFlight:this.actionInFlight,cooldownUntil:this.cooldownUntil,now:Date.now(),degradeStreak:this.degradeStreak,recoverStreak:this.recoverStreak});this.applyStrategyDecision(t,e)}applyStrategyDecision(e,t){if(this.degradeStreak=e.degradeStreak,this.recoverStreak=e.recoverStreak,e.outcome===`downgrade`||e.outcome===`recover`){this.transitionToLevel(e.targetLevel??e.measuredLevel,e.outcome,e.reason,!1,t);return}this.pushTrace({measuredLevel:e.measuredLevel,currentLevel:this.currentLevel,mode:this.mode,metrics:t,outcome:e.outcome,reason:e.reason})}transitionToLevel(e,t,n,r,i=this.lastMetrics){if(console.log(`transitionToLevel`,e,t,n,r,i),!r&&e===this.stableLevel){this.pushTrace({measuredLevel:gi(i??{ts:Date.now(),connected:!1}),currentLevel:this.currentLevel,mode:this.mode,metrics:i,outcome:`hold`,reason:`target level equals current level`});return}let a=this.transitionGeneration;this.actionInFlight=!0,this.runTransition(e,t,n,a,i).finally(()=>{a===this.transitionGeneration&&(this.actionInFlight=!1)})}async runTransition(e,t,n,r,i=this.lastMetrics){if(r!==this.transitionGeneration){this.logger.info(`network adaptation transition ignored before start`,{targetLevel:e,reason:n});return}let a=this.currentLevel,o=this.stableLevel,s=gi(i??{ts:Date.now(),connected:!1});t===`recover`&&this.currentLevel!==`Recovering`&&(this.currentLevel=`Recovering`,this.onStateChange?.({from:a,to:`Recovering`,mode:this.mode,reason:`enter recovering before ${e}`,ts:Date.now(),metrics:i}));let c=await this.applyLevelProfile(e,n);if(r!==this.transitionGeneration){this.logger.info(`network adaptation transition discarded after action (stale generation)`,{targetLevel:e,reason:n}),this.pushTrace({measuredLevel:s,currentLevel:this.currentLevel,mode:this.mode,targetLevel:e,metrics:i,outcome:`hold`,reason:`${n}; stale transition discarded`}),this.emitDiagnosticsSnapshot();return}if(this.lastAction=c,this.onAction?.(c),!c.success){this.logger.warn(`network adaptation transition not committed due to action failure`,{targetLevel:e,reason:n});let t=this.currentLevel;this.currentLevel=o,t!==this.currentLevel&&this.onStateChange?.({from:t,to:this.currentLevel,mode:this.mode,reason:`${n}; action failed rollback`,ts:Date.now(),metrics:i}),this.pushTrace({measuredLevel:s,currentLevel:t,mode:this.mode,targetLevel:e,metrics:i,outcome:`hold`,reason:`${n}; action failed, keep ${o}`}),this.emitDiagnosticsSnapshot();return}let l=this.currentLevel;this.stableLevel=e,this.currentLevel=e,this.cooldownUntil=Date.now()+6e3,this.onStateChange?.({from:l,to:e,mode:this.mode,reason:n,ts:Date.now(),metrics:i}),this.pushTrace({measuredLevel:s,currentLevel:l,mode:this.mode,targetLevel:e,metrics:i,outcome:t,reason:n}),this.emitDiagnosticsSnapshot()}async applyLevelProfile(e,t){let n=bi[e],r=`${n.bitrate}-${n.fps}-${n.width}x${n.height}`;if(r===this.lastAppliedProfileKey)return{level:e,mode:this.mode,success:!0,skipped:!0,reason:`${t}; profile already applied`,ts:Date.now(),steps:[]};let i=[];i.push(await this.runActionStep(`SetSceneRenderBitrate`,{bitrate:n.bitrate})),i.push(await this.runActionStep(`SetSceneFPS`,{fps:n.fps})),i.push(await this.runActionStep(`SetScreenResolution`,{width:n.width,height:n.height}));let a=i.every(e=>e.success);return a&&(this.lastAppliedProfileKey=r),{level:e,mode:this.mode,success:a,skipped:!1,reason:t,ts:Date.now(),steps:i}}async runActionStep(e,t){try{return this.logger.info(`network adaptation action success`,{type:e,payload:t}),{type:e,payload:t,success:!0}}catch(n){let r=n instanceof Error?n.message:String(n);return this.logger.warn(`network adaptation action failed`,{type:e,payload:t,error:r}),{type:e,payload:t,success:!1,error:r}}}pushTrace(e){let t={ts:Date.now(),mode:e.mode??this.mode,currentLevel:e.currentLevel??this.currentLevel,measuredLevel:e.measuredLevel??gi(this.lastMetrics??{ts:Date.now(),connected:this.connected}),targetLevel:e.targetLevel,outcome:e.outcome,reason:e.reason,metrics:e.metrics};this.traces.unshift(t),this.traces.length>30&&(this.traces.length=30),this.emitDiagnosticsSnapshot()}emitDiagnosticsSnapshot(){this.onDiagnostics?.(this.getDiagnosticsSnapshot())}},Ci=class{constructor(e){this.visible=!1,this.onKeyDown=e=>{e.ctrlKey&&e.altKey&&e.code===`KeyD`&&(e.preventDefault(),this.toggle())},this.options=e,this.logger=e.logger??_,typeof window<`u`&&window.addEventListener(`keydown`,this.onKeyDown)}dispose(){typeof window<`u`&&window.removeEventListener(`keydown`,this.onKeyDown),this.root?.remove(),this.root=void 0}update(e){this.snapshot=e,this.visible&&(this.ensureRoot(),this.render())}setVisible(e){this.visible!==e&&(this.visible=e,this.ensureRoot(),this.root&&(this.root.style.display=e?`block`:`none`),e&&this.render(),this.options.onVisibilityChange?.(e))}toggle(){this.setVisible(!this.visible)}ensureRoot(){if(this.root||typeof document>`u`||!document.body)return;let e=document.createElement(`div`);e.id=`enginesdk3-network-diagnostics-panel`,e.style.position=`fixed`,e.style.right=`16px`,e.style.bottom=`16px`,e.style.zIndex=`2147483647`,e.style.width=`360px`,e.style.maxWidth=`calc(100vw - 32px)`,e.style.maxHeight=`70vh`,e.style.overflow=`auto`,e.style.padding=`12px`,e.style.borderRadius=`8px`,e.style.boxShadow=`0 6px 24px rgba(0, 0, 0, 0.35)`,e.style.background=`rgba(12, 17, 24, 0.94)`,e.style.color=`#e8f0ff`,e.style.fontFamily=`Menlo, Consolas, Monaco, monospace`,e.style.fontSize=`12px`,e.style.lineHeight=`1.4`,e.style.display=this.visible?`block`:`none`;let t=document.createElement(`div`);t.style.display=`flex`,t.style.justifyContent=`space-between`,t.style.alignItems=`center`,t.style.marginBottom=`8px`;let n=document.createElement(`strong`);n.textContent=`Network Diagnostics`,t.appendChild(n),this.levelLabel=document.createElement(`span`),this.levelLabel.style.color=`#7ee787`,this.levelLabel.textContent=`Normal`,t.appendChild(this.levelLabel),e.appendChild(t);let r=document.createElement(`div`);r.style.display=`flex`,r.style.alignItems=`center`,r.style.gap=`8px`,r.style.marginBottom=`8px`;let i=document.createElement(`span`);i.textContent=`Mode`,r.appendChild(i),this.modeSelect=document.createElement(`select`),this.modeSelect.style.flex=`1`,this.modeSelect.innerHTML=`<option value="auto">Auto</option><option value="manual">Manual</option>`,this.modeSelect.onchange=()=>{let e=this.modeSelect?.value===`manual`?`manual`:`auto`;this.options.onModeChange(e)},r.appendChild(this.modeSelect),e.appendChild(r);let a=document.createElement(`div`);a.style.display=`flex`,a.style.alignItems=`center`,a.style.gap=`8px`,a.style.marginBottom=`8px`;let o=document.createElement(`span`);o.textContent=`Manual Level`,a.appendChild(o),this.levelSelect=document.createElement(`select`),this.levelSelect.style.flex=`1`,this.levelSelect.innerHTML=[`<option value="Normal">Normal</option>`,`<option value="Mild">Mild</option>`,`<option value="Moderate">Moderate</option>`,`<option value="Severe">Severe</option>`].join(``),this.levelSelect.onchange=()=>{let e=this.levelSelect?.value??`Normal`;this.options.onManualLevelChange(e)},a.appendChild(this.levelSelect),e.appendChild(a),this.metricsPre=document.createElement(`pre`),this.metricsPre.style.margin=`0 0 8px 0`,this.metricsPre.style.padding=`8px`,this.metricsPre.style.background=`rgba(255, 255, 255, 0.06)`,this.metricsPre.style.borderRadius=`6px`,this.metricsPre.style.whiteSpace=`pre-wrap`,this.metricsPre.style.wordBreak=`break-word`,e.appendChild(this.metricsPre);let s=document.createElement(`div`);s.style.marginBottom=`6px`,s.textContent=`Recent Decisions`,e.appendChild(s),this.traceList=document.createElement(`div`),this.traceList.style.display=`flex`,this.traceList.style.flexDirection=`column`,this.traceList.style.gap=`4px`,e.appendChild(this.traceList),document.body.appendChild(e),this.root=e,this.logger.info(`network diagnostics panel ready`)}render(){!this.root||!this.snapshot||(this.levelLabel&&(this.levelLabel.textContent=this.snapshot.currentLevel,this.levelLabel.style.color=this.snapshot.currentLevel===`Severe`?`#ff7b72`:`#7ee787`),this.modeSelect&&(this.modeSelect.value=this.snapshot.mode),this.levelSelect&&(this.levelSelect.disabled=this.snapshot.mode!==`manual`),this.metricsPre&&(this.metricsPre.textContent=this.buildMetricsText(this.snapshot)),this.traceList&&(this.traceList.innerHTML=``,this.snapshot.traces.slice(0,10).forEach(e=>{let t=document.createElement(`div`);t.style.padding=`6px`,t.style.borderRadius=`6px`,t.style.background=`rgba(255, 255, 255, 0.04)`,t.textContent=`${new Date(e.ts).toLocaleTimeString()} | ${e.outcome} | ${e.reason}`,this.traceList?.appendChild(t)})))}buildMetricsText(e){let t=e.lastMetrics;if(!t)return`No metrics yet`;let n=t.packetLossRate===void 0?`-`:`${(t.packetLossRate*100).toFixed(2)}%`;return[`connected: ${e.connected}`,`mode: ${e.mode}`,`level: ${e.currentLevel}`,`fps: ${t.fps?.toFixed(2)??`-`}`,`bitrate(kbps): ${t.bitrateKbps?.toFixed(2)??`-`}`,`packetLoss: ${n}`,`rtt(ms): ${t.rttMs?.toFixed(2)??`-`}`,`jitter(ms): ${t.jitterMs?.toFixed(2)??`-`}`,`resolution: ${t.frameWidth??`-`}x${t.frameHeight??`-`}`,`lastAction: ${e.lastAction?`${e.lastAction.level} (${e.lastAction.success?`ok`:`fail`})`:`-`}`].join(`
109
- `)}},wi=class{constructor(e){this.disconnected=!1,this.hasEverConnected=!1,this.authWorkflow=e.authWorkflow,this.logger=e.logger}async connect(){if(this.disconnected)throw Error(`Cannot connect after disconnect. Use restart() instead.`);this.logger.info(`Starting connection flow`);try{let e=await this.authWorkflow.start();return this.logger.info(`Connection established`,{engineToken:e.engineToken?.substring(0,16)+`...`}),e}catch(e){throw this.logger.error(`Connection failed`,{error:e}),e}}async disconnect(){return this.disconnected?(this.logger.info(`Already disconnected, skipping`),this.disconnectPromise||Promise.resolve()):(this.logger.info(`Disconnecting...`),this.disconnected=!0,this.disconnectPromise=(async()=>{try{await this.authWorkflow.disconnectAndWait(),this.logger.info(`Disconnected successfully`)}catch(e){throw this.logger.error(`Error during disconnect`,{error:e}),e}})(),this.disconnectPromise)}async prepareConnectAfterDisconnect(){this.disconnectPromise&&await this.disconnectPromise,this.disconnected=!1,this.disconnectPromise=void 0,this.hasEverConnected=!1}async restart(){return this.logger.info(`Restarting connection...`),await this.disconnect(),await this.prepareConnectAfterDisconnect(),this.connect()}getStatus(){return{disconnected:this.disconnected,hasEverConnected:this.hasEverConnected}}hasConnectedBefore(){return this.hasEverConnected}markConnected(){this.hasEverConnected=!0}},Q=class extends Error{constructor(e,t,n,r){super(t),this.code=e,this.moduleName=n,this.dependencyName=r,this.name=`ApiRegistryError`}};function Ti(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Ei(e,t){return Ti(e)&&typeof e[t]==`function`}function Di(e){if(!Ti(e))throw new Q(`CONTEXT_INVALID`,`API registry context must be an object`);let t=[[`bridge`,e.bridge,`sendRequest`],[`authWorkflow`,e.authWorkflow,`getSnapshot`],[`connectionLifecycle`,e.connectionLifecycle,`connect`],[`createLogger`,e.createLogger,void 0]];for(let[e,n,r]of t)if(!(r?Ei(n,r):typeof n==`function`||n!=null))throw new Q(`CONTEXT_INVALID`,`API registry context dependency '${e}'${r?` with ${r}()`:``} is required`,void 0,e)}function Oi(e){if(!Ti(e))throw new Q(`REGISTRY_INVALID`,`API registry must be a non-null object`);let t=Object.keys(e).find(e=>!pn.includes(e));if(t)throw new Q(`REGISTRY_UNKNOWN_MODULE`,`API registry contains unknown module '${t}'`,t);let n=pn.find(t=>!(t in e));if(n)throw new Q(`REGISTRY_INCOMPLETE`,`API registry is missing module '${n}'`,n);for(let t of pn)if(typeof e[t]!=`function`)throw new Q(`FACTORY_INVALID`,`API registry factory for '${t}' must be a function`,t)}function ki(e,t,n,r){let i;try{i=t[r](n)}catch(e){throw new Q(`FACTORY_FAILED`,`API registry factory for '${r}' failed: ${e instanceof Error?e.message:String(e)}`,r,void 0)}if(i==null)throw new Q(`FACTORY_EMPTY_RESULT`,`API registry factory for '${r}' returned ${i===null?`null`:`undefined`}`,r);e[r]=i}function Ai(e,t=fn){if(Di(e),Oi(t),typeof t.Popup==`function`&&(e.popupManager===null||e.popupManager===void 0))throw new Q(`CONTEXT_INVALID`,`API registry context dependency 'popupManager' is required by the Popup module`,`Popup`,`popupManager`);let n={};return pn.forEach(r=>{ki(n,t,e,r)}),n}const ji=.78;var $=class extends Error{constructor(e,t,n,r){super(t),this.code=e,this.buildingId=n,this.floorId=r,this.name=`BuildingFloorError`}};function Mi(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Ni(e){return Mi(e)&&typeof e.x==`number`&&Number.isFinite(e.x)&&typeof e.y==`number`&&Number.isFinite(e.y)&&typeof e.z==`number`&&Number.isFinite(e.z)}function Pi(e){return{position:Fi(e.position),target:Fi(e.target),fov:e.fov,time:e.time}}function Fi(e){return new S(e.x,e.y,e.z,e.ePSGType)}var Ii=class{constructor(e,t){this.dependencies=e,this.buildings=new Map,this.logger=t?.logger??_}async register(e){let t=Array.isArray(e)?e:[e],n=this.normalizeRegistrations(t),r=await Promise.all(n.map(async e=>({definition:e,positions:await this.measureFloorPositions(e)})));this.assertBuildingsRemainAvailable(n),r.forEach(({definition:e,positions:t})=>{this.buildings.set(e.buildingId,{definition:e,originalPositions:t,explodedDistances:new Map,visibleFloorIds:e.floors.map(e=>e.id),transitionId:0,status:`overview`,activeMoves:new Set})});let i=n.map(e=>e.buildingId);return this.logger.info(`building floors registered`,{buildingIds:i}),{buildingIds:i}}async switchTo(e){let t=this.requireBuilding(e.buildingId),n=t.definition.floors.findIndex(t=>t.id===e.floorId);if(n<0)throw new $(`FLOOR_NOT_FOUND`,`Floor "${e.floorId}" is not registered for building "${e.buildingId}".`,e.buildingId,e.floorId);let r=t.definition.floors[n];return this.transition(t,{floorId:r.id,visibleFloorIds:t.definition.floors.slice(0,n+1).map(e=>e.id),hiddenFloorIds:t.definition.floors.slice(n+1).map(e=>e.id),viewPoint:r.viewPoint,objectIds:r.objects??[],overview:!1,focus:e.focus===!0})}async showOverview(e){let t=this.requireBuilding(e.buildingId);return this.transition(t,{visibleFloorIds:t.definition.floors.map(e=>e.id),hiddenFloorIds:[],viewPoint:t.definition.overview.viewPoint,objectIds:t.definition.overview.objects??[],overview:!0,focus:e.focus===!0})}async cancel(e){let t=this.requireBuilding(e.buildingId);t.transitionId+=1,await this.stopActiveTransition(t),t.currentFloorId=void 0,t.status=`cancelled`,this.logger.info(`building floor transition cancelled`,{buildingId:e.buildingId})}getState(e){let t=this.requireBuilding(e.buildingId);return{buildingId:t.definition.buildingId,status:t.status,currentFloorId:t.currentFloorId,visibleFloorIds:[...t.visibleFloorIds],transitionId:t.transitionId}}normalizeRegistrations(e){if(e.length===0)throw new $(`INVALID_REGISTRATION`,`At least one building is required.`);let t=new Set;return e.map(e=>{let n=this.requireNonEmptyString(e?.buildingId,`buildingId`),r=this.requireNonEmptyString(e?.parentId,`parentId`,n);if(t.has(n))throw new $(`INVALID_REGISTRATION`,`Building "${n}" is duplicated in the registration batch.`,n);if(this.buildings.has(n))throw new $(`BUILDING_ALREADY_REGISTERED`,`Building "${n}" is already registered.`,n);if(t.add(n),!Array.isArray(e.floors)||e.floors.length===0)throw new $(`INVALID_REGISTRATION`,`Building "${n}" must contain at least one floor.`,n);let i=new Set,a=e.floors.map((e,t)=>{let r=this.normalizeFloor(e,n,t);if(i.has(r.id))throw new $(`INVALID_REGISTRATION`,`Floor "${r.id}" is duplicated in building "${n}".`,n,r.id);return i.add(r.id),r}),o=e.overview??{},s=o.objects??[];if(!Array.isArray(s)||s.some(e=>typeof e!=`string`||e.trim()===``))throw new $(`INVALID_REGISTRATION`,`Building "${n}" overview objects must contain non-empty IDs.`,n);return o.viewPoint&&this.validateViewPoint(o.viewPoint,n,`overview`),{buildingId:n,parentId:r,floors:a,overview:{objects:[...s],viewPoint:o.viewPoint?Pi(o.viewPoint):void 0}}})}normalizeFloor(e,t,n){let r=typeof e==`string`?{id:e}:e;if(!Mi(r))throw new $(`INVALID_REGISTRATION`,`Floor at index ${n} in building "${t}" must be a string or object.`,t);let i=this.requireNonEmptyString(r.id,`floors[${n}].id`,t),a=r.viewPoint;return a!==void 0&&this.validateViewPoint(a,t,i),{id:i,viewPoint:a?Pi(a):void 0,objects:this.normalizeObjectIds(r.objects,t,i)}}normalizeObjectIds(e,t,n){if(e!==void 0){if(!Array.isArray(e)||e.some(e=>typeof e!=`string`||e.trim()===``))throw new $(`INVALID_REGISTRATION`,`Objects for "${t}@${n}" must contain non-empty IDs.`,t,n);return[...e]}}validateViewPoint(e,t,n){if(!Mi(e)||!Ni(e.position)||!Ni(e.target))throw new $(`INVALID_REGISTRATION`,`View point for "${t}@${n}" requires valid position and target vectors.`,t,n);if(e.fov!==void 0&&(!Number.isFinite(e.fov)||e.fov<10||e.fov>150))throw new $(`INVALID_REGISTRATION`,`View point fov for "${t}@${n}" must be between 10 and 150.`,t,n);if(e.time!==void 0&&(!Number.isFinite(e.time)||e.time<0))throw new $(`INVALID_REGISTRATION`,`View point time for "${t}@${n}" must be a non-negative number.`,t,n)}requireNonEmptyString(e,t,n){if(typeof e!=`string`||e.trim()===``)throw new $(`INVALID_REGISTRATION`,`${t} must be a non-empty string.`,n);return e}assertBuildingsRemainAvailable(e){let t=e.find(e=>this.buildings.has(e.buildingId));if(t)throw new $(`BUILDING_ALREADY_REGISTERED`,`Building "${t.buildingId}" was registered while its model information was loading.`,t.buildingId)}async measureFloorPositions(e){let t=await Promise.all(e.floors.map(async t=>{let n=await this.dependencies.model.getModelInfo({parentId:e.parentId,id:t.id});return[t.id,this.extractPosition(n,e.buildingId,t.id)]}));return new Map(t)}extractPosition(e,t,n){let r=e,i=e.params??e.data??r.param;if(Mi(i)&&(`param`in i||`params`in i)&&(i=i.param??i.params),typeof i==`string`)try{i=JSON.parse(i)}catch{i=void 0}let a=Mi(i)?i.position:void 0;if(!Ni(a))throw new $(`MODEL_INFO_INVALID`,`Model information for "${t}@${n}" does not contain a valid position.`,t,n);return{x:a.x,y:a.y,z:a.z,ePSGType:typeof a.ePSGType==`string`&&a.ePSGType!==``?a.ePSGType:`0000`}}requireBuilding(e){let t=this.buildings.get(e);if(!t)throw new $(`BUILDING_NOT_REGISTERED`,`Building "${e}" is not registered.`,e);return t}async transition(e,t){let n=e.transitionId+1;if(e.transitionId=n,await this.stopActiveTransition(e),n!==e.transitionId)return this.createResult(e,t,`cancelled`,`none`);e.status=`switching`;let r=t.visibleFloorIds.filter(t=>e.explodedDistances.has(t)),i=t.hiddenFloorIds.filter(t=>!e.explodedDistances.has(t)),a=t.hiddenFloorIds.filter(t=>e.explodedDistances.has(t));try{let r=this.getAccessoryObjectIds(e.definition);if(r.length>0&&(await this.dependencies.model.setVisible({id:r,visible:!1}),n!==e.transitionId)||t.visibleFloorIds.length>0&&(await this.dependencies.model.setVisible({parentId:e.definition.parentId,id:t.visibleFloorIds,visible:!0}),n!==e.transitionId))return this.createResult(e,t,`cancelled`,`none`);a.length>0&&await this.dependencies.model.setVisible({parentId:e.definition.parentId,id:a,visible:!1})}catch(t){throw n===e.transitionId&&(e.status=`cancelled`),t}return n===e.transitionId?new Promise((a,o)=>{let s={id:n,timers:new Set,pendingActions:new Set,settled:!1,resolve:a,reject:o};e.activeTransition=s,r.forEach((t,n)=>{this.schedule(e,s,n*105,async()=>{let n=e.originalPositions.get(t),r=this.getHideOffset(e),i=Math.max(r*.035,.5),a=e.explodedDistances.get(t)??r;e.activeMoves.add(t),await this.dependencies.modelTransform.startMoveByNodes({parentId:e.definition.parentId,id:t,nodes:[this.positionAtZ(n,n.z-i),this.positionAtZ(n,n.z)],speed:this.getMotionSpeed(a+i*2),linear:6,isLookAtTarget:!1,needDirection:!1})})}),[...i].reverse().forEach((t,n)=>{this.schedule(e,s,n*105,async()=>{let r=e.originalPositions.get(t),i=this.getHideOffset(e),a=Math.max(i*.045,.6),o=i*(1+.24*n);e.explodedDistances.set(t,o),e.activeMoves.add(t),await this.dependencies.modelTransform.startMoveByNodes({parentId:e.definition.parentId,id:t,nodes:[this.positionAtZ(r,r.z-a),this.positionAtZ(r,r.z+o)],speed:this.getMotionSpeed(o+a*2),linear:5,isLookAtTarget:!1,needDirection:!1})})});let c=Math.max(this.getBatchDurationMs(r.length),this.getBatchDurationMs(i.length));this.scheduleCompletion(e,s,c,t)}):this.createResult(e,t,`cancelled`,`none`)}schedule(e,t,n,r){let i=setTimeout(()=>{if(t.timers.delete(i),t.settled||t.id!==e.transitionId)return;let n=Promise.resolve().then(()=>{if(!(t.settled||t.id!==e.transitionId))return r()});t.pendingActions.add(n),n.then(()=>{t.pendingActions.delete(n)}).catch(r=>{t.pendingActions.delete(n),this.failTransition(e,t,r)})},n);t.timers.add(i)}scheduleCompletion(e,t,n,r){let i=setTimeout(()=>{t.timers.delete(i),!(t.settled||t.id!==e.transitionId)&&Promise.all([...t.pendingActions]).then(()=>this.completeTransition(e,t,r)).catch(n=>{this.failTransition(e,t,n)})},n);t.timers.add(i)}async completeTransition(e,t,n){if(!(t.settled||t.id!==e.transitionId))try{if(n.hiddenFloorIds.length>0&&(await this.dependencies.model.setVisible({parentId:e.definition.parentId,id:n.hiddenFloorIds,visible:!1}),t.settled||t.id!==e.transitionId)||(n.visibleFloorIds.forEach(t=>e.explodedDistances.delete(t)),e.activeMoves.clear(),e.visibleFloorIds=[...n.visibleFloorIds],e.currentFloorId=n.floorId,e.status=n.overview?`overview`:`floor`,n.objectIds.length>0&&(await this.dependencies.model.setVisible({id:n.objectIds,visible:!0}),t.settled||t.id!==e.transitionId)))return;let r=await this.focusTarget(e,n);if(t.settled||t.id!==e.transitionId)return;this.settleTransition(e,t,this.createResult(e,n,`completed`,r))}catch(n){this.failTransition(e,t,n)}}async focusTarget(e,t){return t.focus?t.viewPoint?(await this.dependencies.camera.flyToTarget({point:t.viewPoint.position,target:t.viewPoint.target,fov:t.viewPoint.fov,time:t.viewPoint.time??.2}),`viewPoint`):(await this.dependencies.camera.lookAt({parentId:e.definition.parentId,id:t.visibleFloorIds,time:.2,isRotate:!1,isHighlight:!1}),`bounds`):`none`}failTransition(e,t,n){t.settled||(t.settled=!0,t.timers.forEach(e=>clearTimeout(e)),t.timers.clear(),e.activeTransition===t&&(e.activeTransition=void 0),e.status===`switching`&&(e.currentFloorId=void 0,e.status=`cancelled`),this.stopActiveMoves(e),this.logger.warn(`building floor transition failed`,{buildingId:e.definition.buildingId,error:n}),t.reject(n))}settleTransition(e,t,n){t.settled||(t.settled=!0,t.timers.forEach(e=>clearTimeout(e)),t.timers.clear(),e.activeTransition===t&&(e.activeTransition=void 0),t.resolve(n))}async stopActiveTransition(e){let t=e.activeTransition;t&&this.settleTransition(e,t,{buildingId:e.definition.buildingId,status:`cancelled`,visibleFloorIds:[...e.visibleFloorIds],focusMode:`none`,completion:`estimated`}),await this.stopActiveMoves(e)}async stopActiveMoves(e){let t=[...e.activeMoves];e.activeMoves.clear(),t.forEach(t=>{this.dependencies.modelTransform.endMove({parentId:e.definition.parentId,id:t}).catch(n=>{this.logger.warn(`failed to stop building floor move`,{buildingId:e.definition.buildingId,floorId:t,error:n})})}),await Promise.resolve()}createResult(e,t,n,r){return{buildingId:e.definition.buildingId,floorId:t.floorId,status:n,visibleFloorIds:n===`completed`?[...t.visibleFloorIds]:[...e.visibleFloorIds],focusMode:r,completion:`estimated`}}getHideOffset(e){let t=[...e.originalPositions.values()].map(e=>e.z);return t.length<2?2e3:Math.max(Math.max(...t)-Math.min(...t),1)*2.2}getAccessoryObjectIds(e){let t=new Set(e.overview.objects??[]);return e.floors.forEach(e=>{e.objects?.forEach(e=>t.add(e))}),[...t]}getBatchDurationMs(e){return e===0?0:(e-1)*105+ji*1e3}getMotionSpeed(e){return Math.max(e/ji,1)}positionAtZ(e,t){return{x:e.x,y:e.y,z:t,ePSGType:e.ePSGType}}},Li=class{bind(e){this.lifecycle=e}connect(){return this.getLifecycle().connect()}disconnect(){return this.getLifecycle().disconnect()}reconnect(){return this.getLifecycle().reconnect()}getLifecycle(){if(!this.lifecycle)throw Error(`Connection lifecycle is not bound`);return this.lifecycle}};function Ri(e){return`${e}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,10)}`}var zi=class{withConfig(e){return this.userConfig=e,this}withOptions(e){return this.videoElementParent=e?.videoElementParent,this}build(){if(!this.userConfig)throw Error(`Config must be set via withConfig() before calling build()`);let e=br(this.userConfig),t=Ri(`sess`),n=Ri(`trace`);ne(e.pixelStreamingLogger);let r=new ce(e.logger,void 0,{includeStack:e.includeStack}),i=r.child(`QoS`),a=Er(),o=new Ir(a,{sessionId:t,traceId:n,runMode:e.viewMode,viewMode:e.viewMode},{appId:e.sceneName,env:a.app.environment,pageUrl:dr(),userAgent:fr()},(e,t)=>{i.warn(e,t)});r.setReporter(o);let s=new Lr,c=r.child(`Core`);c.info(`engine init`,{logLevel:r.level,qosReportingEnabled:a.enabled}),o.startSession({engineUuid:e.engineUuid??``});let l=new Hr(e,e.dom||this.videoElementParent,r.child(`SessionAdapter`)),u=new Yr(e,l,r.child(`AuthWorkflow`)),d=new Zr(l,r.child(`RequestBridge`),{onRequestSent:({requestId:e,module:t,method:n})=>{o.recordEvent({eventName:`ue_request_sent`,stage:`ue_api`,status:`start`,attrs:{requestId:e,apiName:`${t}.${n}`,module:t,method:n}})},onResponseReceived:({requestId:e,module:t,method:n,durationMs:r,code:i})=>{o.recordEvent({eventName:`ue_response_received`,stage:`ue_api`,status:`success`,durationMs:r,attrs:{requestId:e,apiName:`${t}.${n}`,module:t,method:n},metrics:{ueApiRttMs:r,code:i}})}}),f=new wi({authWorkflow:u,logger:r.child(`ConnectionManager`)}),p=new Li,m=new le({enabled:e.showProgressBar,hostElement:e.dom,emit:e=>{s.emit(`LoadingProgress`,e)},logger:r.child(`LoadingProgress`)}),h=new oi(l,e=>{s.emit(`EngineStatus`,e)},r.child(`EngineStatus`),e=>{o.recordEvent({eventName:`media_stats_sample`,stage:`media`,status:`update`,metrics:e})}),g=new en({getEngineConfig:()=>e,on:(e,t)=>s.on(e,t),off:(e,t)=>s.off(e,t)}),_=Ai({bridge:d,authWorkflow:u,connectionLifecycle:p,createLogger:e=>r.child(e),popupManager:g,videoElementParent:e.dom||this.videoElementParent,beginPointEditorMouseInput:()=>l.beginPointEditorMouseInput()}),ee=new Ii({model:_.Model,modelTransform:_.ModelTransform,camera:_.Camera},{logger:r.child(`BuildingFloor`)}),te={},v=new Si({session:l,screen:_.Screen,logger:r.child(`NetworkAdaptation`),onStateChange:e=>{c.info(`network level changed`,e),s.emit(`networkLevelChanged`,e)},onAction:e=>{(e.success?c.info.bind(c):c.warn.bind(c))(`network adaptation action executed`,e),s.emit(`networkActionExecuted`,e)},onDiagnostics:e=>{s.emit(`networkDiagnosticsUpdated`,e),te.current?.update(e)}}),re=new Ci({logger:r.child(`NetworkDiagnosticsPanel`),onModeChange:e=>{c.info(`network mode changed`,{mode:e}),s.emit(`networkModeChanged`,{mode:e}),v.setMode(e)},onManualLevelChange:e=>{c.info(`network manual level set`,{level:e}),v.setManualLevel(e)},onVisibilityChange:e=>{c.info(`network diagnostics visibility changed`,{visible:e}),v.setDiagnosticsVisible(e),s.emit(`networkDiagnosticsVisibilityChanged`,{visible:e})}});return te.current=re,{config:e,qosMonitor:o,loggerManager:r,eventBus:s,session:l,authWorkflow:u,bridge:d,connectionManager:f,connectionLifecycle:p,loadingProgress:m,engineStatus:h,networkAdaptation:v,networkDiagnosticsPanel:re,popupManager:g,buildingFloor:ee,apiFacade:_,sessionId:t,traceId:n}}};const Bi={centerConnecting:`authConnecting`,waiting:`authWaiting`,authorizing:`authAuthorizing`,connected:`authConnected`,failed:`authFailed`};var Vi=class{constructor(e,t){this.Events={WebRtcConnected:`webRtcConnected`,WebOnConnect:`webRtcConnected`,MapLoaded:`OnApiDataChannelStarted`,WebRtcDisconnected:`webRtcDisconnected`,WebOnDisconnect:`webRtcDisconnected`,DataChannelDisconnet:`webRtcDisconnected`,WebRtcConnecting:`webRtcConnecting`,WebRtcFailed:`webRtcFailed`,StatsReceived:`statsReceived`,EngineStatus:`EngineStatus`,StreamLoading:`streamLoading`,LoadingProgress:`LoadingProgress`,CenterConnected:`Connect`,CenterDisconnected:`UnConnect`,ConnectResult:`ConnectResult`,CenterCloseMessage:`CenterCloseMessage`,TokenAuthorize:`TokenAuthorize`,EngineServiceInit:`EngineServiceInit`,EngineServiceInitWait:`EngineServiceInitWait`,EngineSocketClose:`EngineSocketClose`,TokenWillExpired:`TokenWillExpired`,AuthStateChanged:`authStateChanged`,AuthConnecting:`authConnecting`,AuthWaiting:`authWaiting`,AuthAuthorizing:`authAuthorizing`,AuthConnected:`authConnected`,AuthFailed:`authFailed`,SessionModeReady:`sessionModeReady`,SessionModeFailed:`sessionModeFailed`,SceneConfig:`SceneConfig`,ModelClick:`ModelClick`,ModelUpdate:`ModelUpdate`,CameraHeight:`CameraHeight`,LeftClick:`MouseLeftButtonClick`,LeftDoubleClick:`MouseLeftButtonDoubleClick`,LeftLongPressed:`MouseLeftButtonLongPressed`,RightClick:`MouseRightButtonClick`,RightDoubleClick:`MouseRightButtonDoubleClick`,RightLongPressed:`MouseRightButtonLongPressed`,ModelTrigger:`ModelTrigger`,SyncPops:`SyncPops`,NetworkLevelChanged:`networkLevelChanged`,NetworkActionExecuted:`networkActionExecuted`,NetworkModeChanged:`networkModeChanged`,NetworkDiagnosticsVisibilityChanged:`networkDiagnosticsVisibilityChanged`,NetworkDiagnosticsUpdated:`networkDiagnosticsUpdated`,LoadMQTTDataFinished:`LoadMQTTDataFinished`,LoadMQTTDataProgress:`LoadMQTTDataProgress`,TrainsVisible:`TrainsVisible`,TrainsInfo:`TrainsInfo`},this.Enums={DlssQuality:C,FilterMode:Ve,GizmoType:We,LayerEnum:Re,ModelTransformType:Be,ScreenRenderBitratePreset:w,Season:ze,TrainBehavior:He,UIPopState:Ue,VideoCodeType:Le},this.uePushResponseListenerName=`enginesdk3_ue_push_listener`,this.uePushResponseHandler=this.handleUePushResponse.bind(this);let n=new zi().withConfig(e).withOptions({videoElementParent:t?.videoElementParent}).build();this.resolvedConfig=n.config,this.agentBridgeOptions=t?.agentBridge,this.eventBus=n.eventBus,this.qosMonitor=n.qosMonitor,this.session=n.session,this.authWorkflow=n.authWorkflow,this.connectionManager=n.connectionManager,this.loadingProgressController=n.loadingProgress,this.engineStatusCollector=n.engineStatus,this.networkAdaptation=n.networkAdaptation,this.networkDiagnosticsPanel=n.networkDiagnosticsPanel,this.popupManager=n.popupManager,n.connectionLifecycle.bind({connect:this.connect.bind(this),disconnect:()=>this.disconnectAndWait(),reconnect:this.restart.bind(this)});let r=n.loggerManager.child(`Core`),i=this.resolvedConfig;this.uePushEventNames=new Set([this.Events.MapLoaded,this.Events.ModelClick,this.Events.ModelUpdate,this.Events.CameraHeight,this.Events.LeftClick,this.Events.LeftDoubleClick,this.Events.LeftLongPressed,this.Events.RightClick,this.Events.RightDoubleClick,this.Events.RightLongPressed,this.Events.SceneConfig,this.Events.ModelTrigger,this.Events.SyncPops,this.Events.LoadMQTTDataFinished,this.Events.LoadMQTTDataProgress,this.Events.NetworkDiagnosticsUpdated,this.Events.TrainsVisible,this.Events.TrainsInfo]),this.session.addResponseEventListener(this.uePushResponseListenerName,this.uePushResponseHandler),i.viewMode===`cs`?this.loadingProgressController.show(y.SourcePreparing,`SourcePreparing`):this.loadingProgressController.show(y.EngineIniting,`EngineIniting`),this.mountApiFacade(n.apiFacade),this.BuildingFloor=n.buildingFloor,this.networkAdaptation.start(),this.networkDiagnosticsPanel.update(this.networkAdaptation.getDiagnosticsSnapshot()),this.initializeOptionalRuntimeExtensions(),this.setupEventListeners(r),this.bootstrapPromise=this.startAuthFlowWithQos().catch(e=>(r.error(`auto auth bootstrap failed`,{error:h(e)}),this.authWorkflow.getSnapshot()))}setupEventListeners(e){this.session.getForwardEvents().forEach(t=>{this.session.addEventListener(t,n=>{(t===`webRtcConnecting`||t===`webRtcDisconnected`||t===`webRtcFailed`)&&(this.PointEditor.cancelPlacement(),this.GizmosTool.resetRuntime()),t===`webRtcConnected`&&(this.connectionManager.markConnected(),this.loadingProgressController.show(y.EngineConnectionSuccess,`EngineConnectionSuccess`,!1)),(t===`webRtcDisconnected`||t===`subscribeFailed`)&&this.loadingProgressController.show(y.EngineClose,`EngineClose`,!0),t===`streamerAssigned`&&(this.connectionManager.hasConnectedBefore()?(this.loadingProgressController.show(y.EngineConnectionSuccess,`EngineConnectionSuccess`,!1),e.info(`streamerAssigned during reconnect, showing success progress`)):e.info(`streamerAssigned during initial connect, skip progress (will show on webRtcConnected)`)),this.handleSessionForwardEventForQos(t),e.debug(`forward event`,{eventName:t}),this.eventBus.emit(t,n)})}),this.authWorkflow.on(`stateChanged`,t=>{this.handleAuthStateForQos(t.state),e.debug(`auth state changed`,{state:t.state}),this.eventBus.emit(this.Events.AuthStateChanged,t);let n=Bi[t.state];n&&this.eventBus.emit(n,t)}),this.authWorkflow.on(`progress`,e=>{this.handleProgressNotice(e)}),this.authWorkflow.on(`centerEvent`,({eventName:e,payload:t})=>{this.handleCenterEventForQos(e),this.eventBus.emit(e,t)}),this.authWorkflow.on(`failed`,t=>{let n=this.durationFrom(this.authStartedAt);this.authStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`auth_failed`,stage:`auth`,status:`failed`,durationMs:n,errorCode:t.lastError?.code,errorMessage:t.lastError?.message}),e.error(`auth workflow failed`,{error:t.lastError?JSON.stringify(t.lastError):`unknown`}),this.eventBus.emit(this.Events.SessionModeFailed,{mode:this.session.getViewMode(),snapshot:t})}),this.authWorkflow.on(`connected`,e=>{let t=this.durationFrom(this.authStartedAt);this.authStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`auth_success`,stage:`auth`,status:`success`,durationMs:t}),this.eventBus.emit(this.Events.SessionModeReady,{mode:this.session.getViewMode(),snapshot:e})})}on(e,t){this.eventBus.on(e,t)}off(e,t){this.eventBus.off(e,t)}whenReady(){return this.bootstrapPromise}setNetworkAdaptationMode(e){this.handleNetworkModeChange(e)}setNetworkManualLevel(e){this.handleNetworkModeChange(`manual`),this.networkAdaptation.setManualLevel(e)}getNetworkDiagnosticsSnapshot(){return this.latestNetworkDiagnostics??this.networkAdaptation.getDiagnosticsSnapshot()}async disconnectAndWait(){this.connectionManager.getStatus().disconnected||(this.qosMonitor.endSession({reason:`disconnect`}),this.stopRuntimeForLifecycle({disconnectAuth:!1,removeListener:!0}),await this.connectionManager.disconnect())}disconnect(){this.disconnectAndWait()}async connect(){return this.connectionManager.getStatus().disconnected?(await this.connectionManager.prepareConnectAfterDisconnect(),this.session.addResponseEventListener(this.uePushResponseListenerName,this.uePushResponseHandler),this.initializeOptionalRuntimeExtensions(),this.qosMonitor.startSession({reason:`connect`}),this.startAuthFlowWithQos()):this.authWorkflow.getSnapshot()}async restart(){return this.qosMonitor.endSession({reason:`restart`}),this.stopRuntimeForLifecycle({disconnectAuth:!1,stopAgentBridge:!1,removeListener:!0}),this.session.addResponseEventListener(this.uePushResponseListenerName,this.uePushResponseHandler),this.initializeOptionalRuntimeExtensions(),this.qosMonitor.startSession({reason:`restart`}),this.authStartedAt=Date.now(),this.centerConnectStartedAt=void 0,this.webrtcConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`auth_start`,stage:`auth`,status:`start`}),this.connectionManager.restart()}startAuthFlowWithQos(){return this.authStartedAt=Date.now(),this.centerConnectStartedAt=void 0,this.webrtcConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`auth_start`,stage:`auth`,status:`start`}),this.connectionManager.connect()}handleSessionForwardEventForQos(e){if(e===`webRtcConnecting`){this.webrtcConnectStartedAt===void 0&&(this.webrtcConnectStartedAt=Date.now(),this.qosMonitor.recordEvent({eventName:`webrtc_connect_start`,stage:`webrtc`,status:`start`}));return}if(e===`webRtcConnected`){let e=this.durationFrom(this.webrtcConnectStartedAt);this.webrtcConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`webrtc_connected`,stage:`webrtc`,status:`success`,durationMs:e}),this.qosMonitor.recordEvent({eventName:`first_frame_rendered`,stage:`media`,status:`success`,durationMs:e});return}(e===`webRtcDisconnected`||e===`webRtcFailed`)&&(this.webrtcConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`webrtc_disconnected`,stage:`webrtc`,status:`failed`,attrs:{reason:e}}))}handleAuthStateForQos(e){if(e===`centerConnecting`){this.centerConnectStartedAt=Date.now(),this.qosMonitor.recordEvent({eventName:`center_connect_start`,stage:`center`,status:`start`});return}if(e===`centerConnected`){let e=this.durationFrom(this.centerConnectStartedAt);this.centerConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`center_connected`,stage:`center`,status:`success`,durationMs:e});return}e===`webrtcConnecting`&&this.webrtcConnectStartedAt===void 0&&(this.webrtcConnectStartedAt=Date.now(),this.qosMonitor.recordEvent({eventName:`webrtc_connect_start`,stage:`webrtc`,status:`start`}))}handleCenterEventForQos(e){if(this.qosMonitor.recordEvent({eventName:`center_message_received`,stage:`center`,status:`update`,attrs:{fn:e}}),e===this.Events.CenterDisconnected){this.qosMonitor.recordEvent({eventName:`center_disconnected`,stage:`center`,status:`failed`,attrs:{reason:e}});return}if(e===this.Events.CenterConnected&&this.centerConnectStartedAt!==void 0){let e=this.durationFrom(this.centerConnectStartedAt);this.centerConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`center_connected`,stage:`center`,status:`success`,durationMs:e})}}durationFrom(e){if(e===void 0)return;let t=Date.now()-e;return Number.isFinite(t)&&t>=0?t:void 0}handleProgressNotice(e){if(e.kind===`tokenWillExpire`){this.loadingProgressController.showTokenWillExpire(e.message,e.key,e.isClose);return}this.loadingProgressController.show(e.message,e.key,e.isClose)}handleNetworkModeChange(e){this.networkAdaptation.setMode(e);let t={mode:e,ts:Date.now(),diagnostics:this.networkAdaptation.getDiagnosticsSnapshot()};this.eventBus.emit(this.Events.NetworkModeChanged,t)}mountApiFacade(e){let t=this;Object.keys(e).forEach(n=>{this.setApiModule(t,e,n)})}setApiModule(e,t,n){e[n]=t[n]}initializeOptionalRuntimeExtensions(){if(this.agentBridge||!this.agentBridgeOptions?.enabled)return;let e={...this.agentBridgeOptions,serverUrl:this.agentBridgeOptions.serverUrl??`ws://127.0.0.1:8787/sdk3-bridge`},t=lr(this,{runtimeName:e.runtimeName,expose:e.expose,metadata:e.metadata,engineConfig:this.resolvedConfig,getAuthSnapshot:()=>this.authWorkflow.getSnapshot(),mockInvoke:e.mockInvoke});this.agentBridge=new he(t,e),this.agentBridge.start()}stopRuntimeForLifecycle(e){this.PointEditor.cancelPlacement(),this.GizmosTool.resetRuntime(),e?.stopAgentBridge!==!1&&(this.agentBridge?.stop(`disconnect`),this.agentBridge=void 0),e?.removeListener!==!1&&this.session.removeResponseEventListener(this.uePushResponseListenerName),this.engineStatusCollector.stop(),e?.disconnectAuth!==!1&&this.authWorkflow.disconnect(),this.loadingProgressController.dispose(),this.qosMonitor.flush()}handleUePushResponse(e){let t=e,n;try{if(t=JSON.parse(e),typeof t==`object`&&t){let e=t,r=e.uuid??e.fn;typeof r==`string`&&r.length>0&&(n=r)}}catch{}if(n===`PointEditorGizmoEnded`){this.GizmosTool.finishFromEngine();return}!n&&this.uePushEventNames.has(e)&&(n=e),!(!n||!this.uePushEventNames.has(n))&&this.eventBus.emit(n,t)}getEngineConfig(){return this.resolvedConfig}};exports.AGENT_BRIDGE_API_METADATA=En,exports.API_MODULE_KEYS=pn,exports.AgentRuntimeBridge=he,exports.Animation=Nt,exports.ApiRegistryError=Q,exports.BuildingFloor=Ii,exports.BuildingFloorError=$,exports.Camera=Pt,exports.Connect=Ft,exports.DTCEngine=Vi,exports.Dlss=It,exports.DlssQuality=C,exports.FilterMode=Ve,exports.GizmoType=We,exports.GizmosTool=je,exports.HeatMap=Lt,exports.HighLighterEffect=Rt,exports.Layer=Vt,exports.LayerEnum=Re,exports.Model=Ht,exports.ModelPOI=Ut,exports.ModelTransform=Wt,exports.ModelTransformType=Be,exports.Navigation=Gt,exports.PathPatrol=Kt,exports.PendingValidationSchemaMap=jt,exports.PointEditor=Qt,exports.PointIcon=Yt,exports.Popup=nn,exports.SDKValidationError=p,exports.Scene=an,exports.Screen=rn,exports.ScreenRenderBitratePreset=w,exports.ScreenRenderBitratePresetOptions=Fe,exports.Season=ze,exports.SpatialQuery=on,exports.TimeLine=sn,exports.TrainBehavior=He,exports.TrainSimulate=cn,exports.UIPOI=ln,exports.VideoCodeType=Le,exports.WeatherSystem=dn,exports.WebView=un,exports.apiRegistry=fn,exports.createAgentBridgeMetadata=Dn,exports.createApiFacade=Ai,exports.createBridgeRuntime=lr,exports.getAgentBridgeMethodSchema=Pn,exports.isAgentBridgeMethodExposed=jn,exports.isAgentBridgeModuleExposed=An,exports.isAgentBridgeModuleName=On,exports.listAgentBridgeMethods=Nn,exports.listAgentBridgeModules=Mn,exports.resolveAgentBridgeExposeConfig=kn;
109
+ `)}},wi=class{constructor(e){this.disconnected=!1,this.hasEverConnected=!1,this.authWorkflow=e.authWorkflow,this.logger=e.logger}async connect(){if(this.disconnected)throw Error(`Cannot connect after disconnect. Use restart() instead.`);this.logger.info(`Starting connection flow`);try{let e=await this.authWorkflow.start();return this.logger.info(`Connection established`,{engineToken:e.engineToken?.substring(0,16)+`...`}),e}catch(e){throw this.logger.error(`Connection failed`,{error:e}),e}}async disconnect(){return this.disconnected?(this.logger.info(`Already disconnected, skipping`),this.disconnectPromise||Promise.resolve()):(this.logger.info(`Disconnecting...`),this.disconnected=!0,this.disconnectPromise=(async()=>{try{await this.authWorkflow.disconnectAndWait(),this.logger.info(`Disconnected successfully`)}catch(e){throw this.logger.error(`Error during disconnect`,{error:e}),e}})(),this.disconnectPromise)}async prepareConnectAfterDisconnect(){this.disconnectPromise&&await this.disconnectPromise,this.disconnected=!1,this.disconnectPromise=void 0,this.hasEverConnected=!1}async restart(){return this.logger.info(`Restarting connection...`),await this.disconnect(),await this.prepareConnectAfterDisconnect(),this.connect()}getStatus(){return{disconnected:this.disconnected,hasEverConnected:this.hasEverConnected}}hasConnectedBefore(){return this.hasEverConnected}markConnected(){this.hasEverConnected=!0}},Q=class extends Error{constructor(e,t,n,r){super(t),this.code=e,this.moduleName=n,this.dependencyName=r,this.name=`ApiRegistryError`}};function Ti(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Ei(e,t){return Ti(e)&&typeof e[t]==`function`}function Di(e){if(!Ti(e))throw new Q(`CONTEXT_INVALID`,`API registry context must be an object`);let t=[[`bridge`,e.bridge,`sendRequest`],[`authWorkflow`,e.authWorkflow,`getSnapshot`],[`connectionLifecycle`,e.connectionLifecycle,`connect`],[`createLogger`,e.createLogger,void 0]];for(let[e,n,r]of t)if(!(r?Ei(n,r):typeof n==`function`||n!=null))throw new Q(`CONTEXT_INVALID`,`API registry context dependency '${e}'${r?` with ${r}()`:``} is required`,void 0,e)}function Oi(e){if(!Ti(e))throw new Q(`REGISTRY_INVALID`,`API registry must be a non-null object`);let t=Object.keys(e).find(e=>!pn.includes(e));if(t)throw new Q(`REGISTRY_UNKNOWN_MODULE`,`API registry contains unknown module '${t}'`,t);let n=pn.find(t=>!(t in e));if(n)throw new Q(`REGISTRY_INCOMPLETE`,`API registry is missing module '${n}'`,n);for(let t of pn)if(typeof e[t]!=`function`)throw new Q(`FACTORY_INVALID`,`API registry factory for '${t}' must be a function`,t)}function ki(e,t,n,r){let i;try{i=t[r](n)}catch(e){throw new Q(`FACTORY_FAILED`,`API registry factory for '${r}' failed: ${e instanceof Error?e.message:String(e)}`,r,void 0)}if(i==null)throw new Q(`FACTORY_EMPTY_RESULT`,`API registry factory for '${r}' returned ${i===null?`null`:`undefined`}`,r);e[r]=i}function Ai(e,t=fn){if(Di(e),Oi(t),typeof t.Popup==`function`&&(e.popupManager===null||e.popupManager===void 0))throw new Q(`CONTEXT_INVALID`,`API registry context dependency 'popupManager' is required by the Popup module`,`Popup`,`popupManager`);let n={};return pn.forEach(r=>{ki(n,t,e,r)}),n}const ji=.78;var $=class extends Error{constructor(e,t,n,r){super(t),this.code=e,this.buildingId=n,this.floorId=r,this.name=`BuildingFloorError`}};function Mi(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Ni(e){return Mi(e)&&typeof e.x==`number`&&Number.isFinite(e.x)&&typeof e.y==`number`&&Number.isFinite(e.y)&&typeof e.z==`number`&&Number.isFinite(e.z)}function Pi(e){return{position:Fi(e.position),target:Fi(e.target),fov:e.fov,time:e.time}}function Fi(e){return new S(e.x,e.y,e.z,e.ePSGType)}var Ii=class{constructor(e,t){this.dependencies=e,this.buildings=new Map,this.logger=t?.logger??_}async register(e){let t=Array.isArray(e)?e:[e],n=this.normalizeRegistrations(t),r=await Promise.all(n.map(async e=>({definition:e,positions:await this.measureFloorPositions(e)})));this.assertBuildingsRemainAvailable(n),r.forEach(({definition:e,positions:t})=>{this.buildings.set(e.buildingId,{definition:e,originalPositions:t,explodedDistances:new Map,visibleFloorIds:e.floors.map(e=>e.id),transitionId:0,status:`overview`,activeMoves:new Set})});let i=n.map(e=>e.buildingId);return this.logger.info(`building floors registered`,{buildingIds:i}),{buildingIds:i}}async switchTo(e){let t=this.requireBuilding(e.buildingId),n=t.definition.floors.findIndex(t=>t.id===e.floorId);if(n<0)throw new $(`FLOOR_NOT_FOUND`,`Floor "${e.floorId}" is not registered for building "${e.buildingId}".`,e.buildingId,e.floorId);let r=t.definition.floors[n];return this.transition(t,{floorId:r.id,visibleFloorIds:t.definition.floors.slice(0,n+1).map(e=>e.id),hiddenFloorIds:t.definition.floors.slice(n+1).map(e=>e.id),viewPoint:r.viewPoint,objectIds:r.objects??[],showLayers:r.showLayers??[],hideLayers:r.hideLayers??[],overview:!1,focus:e.focus===!0})}async showOverview(e){let t=this.requireBuilding(e.buildingId);return this.transition(t,{visibleFloorIds:t.definition.floors.map(e=>e.id),hiddenFloorIds:[],viewPoint:t.definition.overview.viewPoint,objectIds:t.definition.overview.objects??[],showLayers:t.definition.overview.showLayers??[],hideLayers:t.definition.overview.hideLayers??[],overview:!0,focus:e.focus===!0})}async cancel(e){let t=this.requireBuilding(e.buildingId);t.transitionId+=1,await this.stopActiveTransition(t),t.currentFloorId=void 0,t.status=`cancelled`,this.logger.info(`building floor transition cancelled`,{buildingId:e.buildingId})}getState(e){let t=this.requireBuilding(e.buildingId);return{buildingId:t.definition.buildingId,status:t.status,currentFloorId:t.currentFloorId,visibleFloorIds:[...t.visibleFloorIds],transitionId:t.transitionId}}normalizeRegistrations(e){if(e.length===0)throw new $(`INVALID_REGISTRATION`,`At least one building is required.`);let t=new Set;return e.map(e=>{let n=this.requireNonEmptyString(e?.buildingId,`buildingId`),r=this.requireNonEmptyString(e?.parentId,`parentId`,n);if(t.has(n))throw new $(`INVALID_REGISTRATION`,`Building "${n}" is duplicated in the registration batch.`,n);if(this.buildings.has(n))throw new $(`BUILDING_ALREADY_REGISTERED`,`Building "${n}" is already registered.`,n);if(t.add(n),!Array.isArray(e.floors)||e.floors.length===0)throw new $(`INVALID_REGISTRATION`,`Building "${n}" must contain at least one floor.`,n);let i=new Set,a=e.floors.map((e,t)=>{let r=this.normalizeFloor(e,n,t);if(i.has(r.id))throw new $(`INVALID_REGISTRATION`,`Floor "${r.id}" is duplicated in building "${n}".`,n,r.id);return i.add(r.id),r}),o=e.overview??{},s=o.objects??[];if(!Array.isArray(s)||s.some(e=>typeof e!=`string`||e.trim()===``))throw new $(`INVALID_REGISTRATION`,`Building "${n}" overview objects must contain non-empty IDs.`,n);return o.viewPoint&&this.validateViewPoint(o.viewPoint,n,`overview`),{buildingId:n,parentId:r,floors:a,overview:{objects:[...s],showLayers:this.normalizeObjectIds(o.showLayers,n,`overview`,`showLayers`),hideLayers:this.normalizeObjectIds(o.hideLayers,n,`overview`,`hideLayers`),viewPoint:o.viewPoint?Pi(o.viewPoint):void 0}}})}normalizeFloor(e,t,n){let r=typeof e==`string`?{id:e}:e;if(!Mi(r))throw new $(`INVALID_REGISTRATION`,`Floor at index ${n} in building "${t}" must be a string or object.`,t);let i=this.requireNonEmptyString(r.id,`floors[${n}].id`,t),a=r.viewPoint;return a!==void 0&&this.validateViewPoint(a,t,i),{id:i,viewPoint:a?Pi(a):void 0,objects:this.normalizeObjectIds(r.objects,t,i),showLayers:this.normalizeObjectIds(r.showLayers,t,i,`showLayers`),hideLayers:this.normalizeObjectIds(r.hideLayers,t,i,`hideLayers`)}}normalizeObjectIds(e,t,n,r=`Objects`){if(e!==void 0){if(!Array.isArray(e)||e.some(e=>typeof e!=`string`||e.trim()===``))throw new $(`INVALID_REGISTRATION`,`${r} for "${t}@${n}" must contain non-empty IDs.`,t,n);return[...e]}}validateViewPoint(e,t,n){if(!Mi(e)||!Ni(e.position)||!Ni(e.target))throw new $(`INVALID_REGISTRATION`,`View point for "${t}@${n}" requires valid position and target vectors.`,t,n);if(e.fov!==void 0&&(!Number.isFinite(e.fov)||e.fov<10||e.fov>150))throw new $(`INVALID_REGISTRATION`,`View point fov for "${t}@${n}" must be between 10 and 150.`,t,n);if(e.time!==void 0&&(!Number.isFinite(e.time)||e.time<0))throw new $(`INVALID_REGISTRATION`,`View point time for "${t}@${n}" must be a non-negative number.`,t,n)}requireNonEmptyString(e,t,n){if(typeof e!=`string`||e.trim()===``)throw new $(`INVALID_REGISTRATION`,`${t} must be a non-empty string.`,n);return e}assertBuildingsRemainAvailable(e){let t=e.find(e=>this.buildings.has(e.buildingId));if(t)throw new $(`BUILDING_ALREADY_REGISTERED`,`Building "${t.buildingId}" was registered while its model information was loading.`,t.buildingId)}async measureFloorPositions(e){let t=await Promise.all(e.floors.map(async t=>{let n=await this.dependencies.model.getModelInfo({parentId:e.parentId,id:t.id});return[t.id,this.extractPosition(n,e.buildingId,t.id)]}));return new Map(t)}extractPosition(e,t,n){let r=e,i=e.params??e.data??r.param;if(Mi(i)&&(`param`in i||`params`in i)&&(i=i.param??i.params),typeof i==`string`)try{i=JSON.parse(i)}catch{i=void 0}let a=Mi(i)?i.position:void 0;if(!Ni(a))throw new $(`MODEL_INFO_INVALID`,`Model information for "${t}@${n}" does not contain a valid position.`,t,n);return{x:a.x,y:a.y,z:a.z,ePSGType:typeof a.ePSGType==`string`&&a.ePSGType!==``?a.ePSGType:`0000`}}requireBuilding(e){let t=this.buildings.get(e);if(!t)throw new $(`BUILDING_NOT_REGISTERED`,`Building "${e}" is not registered.`,e);return t}async transition(e,t){let n=e.transitionId+1;if(e.transitionId=n,await this.stopActiveTransition(e),n!==e.transitionId)return this.createResult(e,t,`cancelled`,`none`);e.status=`switching`;let r=t.visibleFloorIds.filter(t=>e.explodedDistances.has(t)),i=t.hiddenFloorIds.filter(t=>!e.explodedDistances.has(t)),a=t.hiddenFloorIds.filter(t=>e.explodedDistances.has(t));try{let r=this.getAccessoryObjectIds(e.definition).filter(e=>!t.showLayers.includes(e));if(r.length>0&&(await this.dependencies.model.setVisible({id:r,visible:!1}),n!==e.transitionId))return this.createResult(e,t,`cancelled`,`none`);for(let[r,i]of[[t.showLayers,!0],[t.hideLayers,!1]])if(r.length!==0&&(await this.dependencies.model.setVisible({id:r,visible:i}),n!==e.transitionId))return this.createResult(e,t,`cancelled`,`none`);if(t.visibleFloorIds.length>0&&(await this.dependencies.model.setVisible({parentId:e.definition.parentId,id:t.visibleFloorIds,visible:!0}),n!==e.transitionId))return this.createResult(e,t,`cancelled`,`none`);a.length>0&&await this.dependencies.model.setVisible({parentId:e.definition.parentId,id:a,visible:!1})}catch(t){throw n===e.transitionId&&(e.status=`cancelled`),t}return n===e.transitionId?new Promise((a,o)=>{let s={id:n,timers:new Set,pendingActions:new Set,settled:!1,resolve:a,reject:o};e.activeTransition=s,r.forEach((t,n)=>{this.schedule(e,s,n*105,async()=>{let n=e.originalPositions.get(t),r=this.getHideOffset(e),i=Math.max(r*.035,.5),a=e.explodedDistances.get(t)??r;e.activeMoves.add(t),await this.dependencies.modelTransform.startMoveByNodes({parentId:e.definition.parentId,id:t,nodes:[this.positionAtZ(n,n.z-i),this.positionAtZ(n,n.z)],speed:this.getMotionSpeed(a+i*2),linear:6,isLookAtTarget:!1,needDirection:!1})})}),[...i].reverse().forEach((t,n)=>{this.schedule(e,s,n*105,async()=>{let r=e.originalPositions.get(t),i=this.getHideOffset(e),a=Math.max(i*.045,.6),o=i*(1+.24*n);e.explodedDistances.set(t,o),e.activeMoves.add(t),await this.dependencies.modelTransform.startMoveByNodes({parentId:e.definition.parentId,id:t,nodes:[this.positionAtZ(r,r.z-a),this.positionAtZ(r,r.z+o)],speed:this.getMotionSpeed(o+a*2),linear:5,isLookAtTarget:!1,needDirection:!1})})});let c=Math.max(this.getBatchDurationMs(r.length),this.getBatchDurationMs(i.length));this.scheduleCompletion(e,s,c,t)}):this.createResult(e,t,`cancelled`,`none`)}schedule(e,t,n,r){let i=setTimeout(()=>{if(t.timers.delete(i),t.settled||t.id!==e.transitionId)return;let n=Promise.resolve().then(()=>{if(!(t.settled||t.id!==e.transitionId))return r()});t.pendingActions.add(n),n.then(()=>{t.pendingActions.delete(n)}).catch(r=>{t.pendingActions.delete(n),this.failTransition(e,t,r)})},n);t.timers.add(i)}scheduleCompletion(e,t,n,r){let i=setTimeout(()=>{t.timers.delete(i),!(t.settled||t.id!==e.transitionId)&&Promise.all([...t.pendingActions]).then(()=>this.completeTransition(e,t,r)).catch(n=>{this.failTransition(e,t,n)})},n);t.timers.add(i)}async completeTransition(e,t,n){if(!(t.settled||t.id!==e.transitionId))try{if(n.hiddenFloorIds.length>0&&(await this.dependencies.model.setVisible({parentId:e.definition.parentId,id:n.hiddenFloorIds,visible:!1}),t.settled||t.id!==e.transitionId))return;n.visibleFloorIds.forEach(t=>e.explodedDistances.delete(t)),e.activeMoves.clear(),e.visibleFloorIds=[...n.visibleFloorIds],e.currentFloorId=n.floorId,e.status=n.overview?`overview`:`floor`;let r=n.objectIds.filter(e=>!n.hideLayers.includes(e));if(r.length>0&&(await this.dependencies.model.setVisible({id:r,visible:!0}),t.settled||t.id!==e.transitionId))return;let i=await this.focusTarget(e,n);if(t.settled||t.id!==e.transitionId)return;this.settleTransition(e,t,this.createResult(e,n,`completed`,i))}catch(n){this.failTransition(e,t,n)}}async focusTarget(e,t){return t.focus?t.viewPoint?(await this.dependencies.camera.flyToTarget({point:t.viewPoint.position,target:t.viewPoint.target,fov:t.viewPoint.fov,time:t.viewPoint.time??.2}),`viewPoint`):(await this.dependencies.camera.lookAt({parentId:e.definition.parentId,id:t.visibleFloorIds,time:.2,isRotate:!1,isHighlight:!1}),`bounds`):`none`}failTransition(e,t,n){t.settled||(t.settled=!0,t.timers.forEach(e=>clearTimeout(e)),t.timers.clear(),e.activeTransition===t&&(e.activeTransition=void 0),e.status===`switching`&&(e.currentFloorId=void 0,e.status=`cancelled`),this.stopActiveMoves(e),this.logger.warn(`building floor transition failed`,{buildingId:e.definition.buildingId,error:n}),t.reject(n))}settleTransition(e,t,n){t.settled||(t.settled=!0,t.timers.forEach(e=>clearTimeout(e)),t.timers.clear(),e.activeTransition===t&&(e.activeTransition=void 0),t.resolve(n))}async stopActiveTransition(e){let t=e.activeTransition;t&&this.settleTransition(e,t,{buildingId:e.definition.buildingId,status:`cancelled`,visibleFloorIds:[...e.visibleFloorIds],focusMode:`none`,completion:`estimated`}),await this.stopActiveMoves(e)}async stopActiveMoves(e){let t=[...e.activeMoves];e.activeMoves.clear(),t.forEach(t=>{this.dependencies.modelTransform.endMove({parentId:e.definition.parentId,id:t}).catch(n=>{this.logger.warn(`failed to stop building floor move`,{buildingId:e.definition.buildingId,floorId:t,error:n})})}),await Promise.resolve()}createResult(e,t,n,r){return{buildingId:e.definition.buildingId,floorId:t.floorId,status:n,visibleFloorIds:n===`completed`?[...t.visibleFloorIds]:[...e.visibleFloorIds],focusMode:r,completion:`estimated`}}getHideOffset(e){let t=[...e.originalPositions.values()].map(e=>e.z);return t.length<2?2e3:Math.max(Math.max(...t)-Math.min(...t),1)*2.2}getAccessoryObjectIds(e){let t=new Set(e.overview.objects??[]);return e.floors.forEach(e=>{e.objects?.forEach(e=>t.add(e))}),[...t]}getBatchDurationMs(e){return e===0?0:(e-1)*105+ji*1e3}getMotionSpeed(e){return Math.max(e/ji,1)}positionAtZ(e,t){return{x:e.x,y:e.y,z:t,ePSGType:e.ePSGType}}},Li=class{bind(e){this.lifecycle=e}connect(){return this.getLifecycle().connect()}disconnect(){return this.getLifecycle().disconnect()}reconnect(){return this.getLifecycle().reconnect()}getLifecycle(){if(!this.lifecycle)throw Error(`Connection lifecycle is not bound`);return this.lifecycle}};function Ri(e){return`${e}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,10)}`}var zi=class{withConfig(e){return this.userConfig=e,this}withOptions(e){return this.videoElementParent=e?.videoElementParent,this}build(){if(!this.userConfig)throw Error(`Config must be set via withConfig() before calling build()`);let e=br(this.userConfig),t=Ri(`sess`),n=Ri(`trace`);ne(e.pixelStreamingLogger);let r=new ce(e.logger,void 0,{includeStack:e.includeStack}),i=r.child(`QoS`),a=Er(),o=new Ir(a,{sessionId:t,traceId:n,runMode:e.viewMode,viewMode:e.viewMode},{appId:e.sceneName,env:a.app.environment,pageUrl:dr(),userAgent:fr()},(e,t)=>{i.warn(e,t)});r.setReporter(o);let s=new Lr,c=r.child(`Core`);c.info(`engine init`,{logLevel:r.level,qosReportingEnabled:a.enabled}),o.startSession({engineUuid:e.engineUuid??``});let l=new Hr(e,e.dom||this.videoElementParent,r.child(`SessionAdapter`)),u=new Yr(e,l,r.child(`AuthWorkflow`)),d=new Zr(l,r.child(`RequestBridge`),{onRequestSent:({requestId:e,module:t,method:n})=>{o.recordEvent({eventName:`ue_request_sent`,stage:`ue_api`,status:`start`,attrs:{requestId:e,apiName:`${t}.${n}`,module:t,method:n}})},onResponseReceived:({requestId:e,module:t,method:n,durationMs:r,code:i})=>{o.recordEvent({eventName:`ue_response_received`,stage:`ue_api`,status:`success`,durationMs:r,attrs:{requestId:e,apiName:`${t}.${n}`,module:t,method:n},metrics:{ueApiRttMs:r,code:i}})}}),f=new wi({authWorkflow:u,logger:r.child(`ConnectionManager`)}),p=new Li,m=new le({enabled:e.showProgressBar,hostElement:e.dom,emit:e=>{s.emit(`LoadingProgress`,e)},logger:r.child(`LoadingProgress`)}),h=new oi(l,e=>{s.emit(`EngineStatus`,e)},r.child(`EngineStatus`),e=>{o.recordEvent({eventName:`media_stats_sample`,stage:`media`,status:`update`,metrics:e})}),g=new en({getEngineConfig:()=>e,on:(e,t)=>s.on(e,t),off:(e,t)=>s.off(e,t)}),_=Ai({bridge:d,authWorkflow:u,connectionLifecycle:p,createLogger:e=>r.child(e),popupManager:g,videoElementParent:e.dom||this.videoElementParent,beginPointEditorMouseInput:()=>l.beginPointEditorMouseInput()}),ee=new Ii({model:_.Model,modelTransform:_.ModelTransform,camera:_.Camera},{logger:r.child(`BuildingFloor`)}),te={},v=new Si({session:l,screen:_.Screen,logger:r.child(`NetworkAdaptation`),onStateChange:e=>{c.info(`network level changed`,e),s.emit(`networkLevelChanged`,e)},onAction:e=>{(e.success?c.info.bind(c):c.warn.bind(c))(`network adaptation action executed`,e),s.emit(`networkActionExecuted`,e)},onDiagnostics:e=>{s.emit(`networkDiagnosticsUpdated`,e),te.current?.update(e)}}),re=new Ci({logger:r.child(`NetworkDiagnosticsPanel`),onModeChange:e=>{c.info(`network mode changed`,{mode:e}),s.emit(`networkModeChanged`,{mode:e}),v.setMode(e)},onManualLevelChange:e=>{c.info(`network manual level set`,{level:e}),v.setManualLevel(e)},onVisibilityChange:e=>{c.info(`network diagnostics visibility changed`,{visible:e}),v.setDiagnosticsVisible(e),s.emit(`networkDiagnosticsVisibilityChanged`,{visible:e})}});return te.current=re,{config:e,qosMonitor:o,loggerManager:r,eventBus:s,session:l,authWorkflow:u,bridge:d,connectionManager:f,connectionLifecycle:p,loadingProgress:m,engineStatus:h,networkAdaptation:v,networkDiagnosticsPanel:re,popupManager:g,buildingFloor:ee,apiFacade:_,sessionId:t,traceId:n}}};const Bi={centerConnecting:`authConnecting`,waiting:`authWaiting`,authorizing:`authAuthorizing`,connected:`authConnected`,failed:`authFailed`};var Vi=class{constructor(e,t){this.Events={WebRtcConnected:`webRtcConnected`,WebOnConnect:`webRtcConnected`,MapLoaded:`OnApiDataChannelStarted`,WebRtcDisconnected:`webRtcDisconnected`,WebOnDisconnect:`webRtcDisconnected`,DataChannelDisconnet:`webRtcDisconnected`,WebRtcConnecting:`webRtcConnecting`,WebRtcFailed:`webRtcFailed`,StatsReceived:`statsReceived`,EngineStatus:`EngineStatus`,StreamLoading:`streamLoading`,LoadingProgress:`LoadingProgress`,CenterConnected:`Connect`,CenterDisconnected:`UnConnect`,ConnectResult:`ConnectResult`,CenterCloseMessage:`CenterCloseMessage`,TokenAuthorize:`TokenAuthorize`,EngineServiceInit:`EngineServiceInit`,EngineServiceInitWait:`EngineServiceInitWait`,EngineSocketClose:`EngineSocketClose`,TokenWillExpired:`TokenWillExpired`,AuthStateChanged:`authStateChanged`,AuthConnecting:`authConnecting`,AuthWaiting:`authWaiting`,AuthAuthorizing:`authAuthorizing`,AuthConnected:`authConnected`,AuthFailed:`authFailed`,SessionModeReady:`sessionModeReady`,SessionModeFailed:`sessionModeFailed`,SceneConfig:`SceneConfig`,ModelClick:`ModelClick`,ModelUpdate:`ModelUpdate`,CameraHeight:`CameraHeight`,LeftClick:`MouseLeftButtonClick`,LeftDoubleClick:`MouseLeftButtonDoubleClick`,LeftLongPressed:`MouseLeftButtonLongPressed`,RightClick:`MouseRightButtonClick`,RightDoubleClick:`MouseRightButtonDoubleClick`,RightLongPressed:`MouseRightButtonLongPressed`,ModelTrigger:`ModelTrigger`,SyncPops:`SyncPops`,NetworkLevelChanged:`networkLevelChanged`,NetworkActionExecuted:`networkActionExecuted`,NetworkModeChanged:`networkModeChanged`,NetworkDiagnosticsVisibilityChanged:`networkDiagnosticsVisibilityChanged`,NetworkDiagnosticsUpdated:`networkDiagnosticsUpdated`,LoadMQTTDataFinished:`LoadMQTTDataFinished`,LoadMQTTDataProgress:`LoadMQTTDataProgress`,TrainsVisible:`TrainsVisible`,TrainsInfo:`TrainsInfo`},this.Enums={DlssQuality:C,FilterMode:Ve,GizmoType:We,LayerEnum:Re,ModelTransformType:Be,ScreenRenderBitratePreset:w,Season:ze,TrainBehavior:He,UIPopState:Ue,VideoCodeType:Le},this.uePushResponseListenerName=`enginesdk3_ue_push_listener`,this.uePushResponseHandler=this.handleUePushResponse.bind(this);let n=new zi().withConfig(e).withOptions({videoElementParent:t?.videoElementParent}).build();this.resolvedConfig=n.config,this.agentBridgeOptions=t?.agentBridge,this.eventBus=n.eventBus,this.qosMonitor=n.qosMonitor,this.session=n.session,this.authWorkflow=n.authWorkflow,this.connectionManager=n.connectionManager,this.loadingProgressController=n.loadingProgress,this.engineStatusCollector=n.engineStatus,this.networkAdaptation=n.networkAdaptation,this.networkDiagnosticsPanel=n.networkDiagnosticsPanel,this.popupManager=n.popupManager,n.connectionLifecycle.bind({connect:this.connect.bind(this),disconnect:()=>this.disconnectAndWait(),reconnect:this.restart.bind(this)});let r=n.loggerManager.child(`Core`),i=this.resolvedConfig;this.uePushEventNames=new Set([this.Events.MapLoaded,this.Events.ModelClick,this.Events.ModelUpdate,this.Events.CameraHeight,this.Events.LeftClick,this.Events.LeftDoubleClick,this.Events.LeftLongPressed,this.Events.RightClick,this.Events.RightDoubleClick,this.Events.RightLongPressed,this.Events.SceneConfig,this.Events.ModelTrigger,this.Events.SyncPops,this.Events.LoadMQTTDataFinished,this.Events.LoadMQTTDataProgress,this.Events.NetworkDiagnosticsUpdated,this.Events.TrainsVisible,this.Events.TrainsInfo]),this.session.addResponseEventListener(this.uePushResponseListenerName,this.uePushResponseHandler),i.viewMode===`cs`?this.loadingProgressController.show(y.SourcePreparing,`SourcePreparing`):this.loadingProgressController.show(y.EngineIniting,`EngineIniting`),this.mountApiFacade(n.apiFacade),this.BuildingFloor=n.buildingFloor,this.networkAdaptation.start(),this.networkDiagnosticsPanel.update(this.networkAdaptation.getDiagnosticsSnapshot()),this.initializeOptionalRuntimeExtensions(),this.setupEventListeners(r),this.bootstrapPromise=this.startAuthFlowWithQos().catch(e=>(r.error(`auto auth bootstrap failed`,{error:h(e)}),this.authWorkflow.getSnapshot()))}setupEventListeners(e){this.session.getForwardEvents().forEach(t=>{this.session.addEventListener(t,n=>{(t===`webRtcConnecting`||t===`webRtcDisconnected`||t===`webRtcFailed`)&&(this.PointEditor.cancelPlacement(),this.GizmosTool.resetRuntime()),t===`webRtcConnected`&&(this.connectionManager.markConnected(),this.loadingProgressController.show(y.EngineConnectionSuccess,`EngineConnectionSuccess`,!1)),(t===`webRtcDisconnected`||t===`subscribeFailed`)&&this.loadingProgressController.show(y.EngineClose,`EngineClose`,!0),t===`streamerAssigned`&&(this.connectionManager.hasConnectedBefore()?(this.loadingProgressController.show(y.EngineConnectionSuccess,`EngineConnectionSuccess`,!1),e.info(`streamerAssigned during reconnect, showing success progress`)):e.info(`streamerAssigned during initial connect, skip progress (will show on webRtcConnected)`)),this.handleSessionForwardEventForQos(t),e.debug(`forward event`,{eventName:t}),this.eventBus.emit(t,n)})}),this.authWorkflow.on(`stateChanged`,t=>{this.handleAuthStateForQos(t.state),e.debug(`auth state changed`,{state:t.state}),this.eventBus.emit(this.Events.AuthStateChanged,t);let n=Bi[t.state];n&&this.eventBus.emit(n,t)}),this.authWorkflow.on(`progress`,e=>{this.handleProgressNotice(e)}),this.authWorkflow.on(`centerEvent`,({eventName:e,payload:t})=>{this.handleCenterEventForQos(e),this.eventBus.emit(e,t)}),this.authWorkflow.on(`failed`,t=>{let n=this.durationFrom(this.authStartedAt);this.authStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`auth_failed`,stage:`auth`,status:`failed`,durationMs:n,errorCode:t.lastError?.code,errorMessage:t.lastError?.message}),e.error(`auth workflow failed`,{error:t.lastError?JSON.stringify(t.lastError):`unknown`}),this.eventBus.emit(this.Events.SessionModeFailed,{mode:this.session.getViewMode(),snapshot:t})}),this.authWorkflow.on(`connected`,e=>{let t=this.durationFrom(this.authStartedAt);this.authStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`auth_success`,stage:`auth`,status:`success`,durationMs:t}),this.eventBus.emit(this.Events.SessionModeReady,{mode:this.session.getViewMode(),snapshot:e})})}on(e,t){this.eventBus.on(e,t)}off(e,t){this.eventBus.off(e,t)}whenReady(){return this.bootstrapPromise}setNetworkAdaptationMode(e){this.handleNetworkModeChange(e)}setNetworkManualLevel(e){this.handleNetworkModeChange(`manual`),this.networkAdaptation.setManualLevel(e)}getNetworkDiagnosticsSnapshot(){return this.latestNetworkDiagnostics??this.networkAdaptation.getDiagnosticsSnapshot()}async disconnectAndWait(){this.connectionManager.getStatus().disconnected||(this.qosMonitor.endSession({reason:`disconnect`}),this.stopRuntimeForLifecycle({disconnectAuth:!1,removeListener:!0}),await this.connectionManager.disconnect())}disconnect(){this.disconnectAndWait()}async connect(){return this.connectionManager.getStatus().disconnected?(await this.connectionManager.prepareConnectAfterDisconnect(),this.session.addResponseEventListener(this.uePushResponseListenerName,this.uePushResponseHandler),this.initializeOptionalRuntimeExtensions(),this.qosMonitor.startSession({reason:`connect`}),this.startAuthFlowWithQos()):this.authWorkflow.getSnapshot()}async restart(){return this.qosMonitor.endSession({reason:`restart`}),this.stopRuntimeForLifecycle({disconnectAuth:!1,stopAgentBridge:!1,removeListener:!0}),this.session.addResponseEventListener(this.uePushResponseListenerName,this.uePushResponseHandler),this.initializeOptionalRuntimeExtensions(),this.qosMonitor.startSession({reason:`restart`}),this.authStartedAt=Date.now(),this.centerConnectStartedAt=void 0,this.webrtcConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`auth_start`,stage:`auth`,status:`start`}),this.connectionManager.restart()}startAuthFlowWithQos(){return this.authStartedAt=Date.now(),this.centerConnectStartedAt=void 0,this.webrtcConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`auth_start`,stage:`auth`,status:`start`}),this.connectionManager.connect()}handleSessionForwardEventForQos(e){if(e===`webRtcConnecting`){this.webrtcConnectStartedAt===void 0&&(this.webrtcConnectStartedAt=Date.now(),this.qosMonitor.recordEvent({eventName:`webrtc_connect_start`,stage:`webrtc`,status:`start`}));return}if(e===`webRtcConnected`){let e=this.durationFrom(this.webrtcConnectStartedAt);this.webrtcConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`webrtc_connected`,stage:`webrtc`,status:`success`,durationMs:e}),this.qosMonitor.recordEvent({eventName:`first_frame_rendered`,stage:`media`,status:`success`,durationMs:e});return}(e===`webRtcDisconnected`||e===`webRtcFailed`)&&(this.webrtcConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`webrtc_disconnected`,stage:`webrtc`,status:`failed`,attrs:{reason:e}}))}handleAuthStateForQos(e){if(e===`centerConnecting`){this.centerConnectStartedAt=Date.now(),this.qosMonitor.recordEvent({eventName:`center_connect_start`,stage:`center`,status:`start`});return}if(e===`centerConnected`){let e=this.durationFrom(this.centerConnectStartedAt);this.centerConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`center_connected`,stage:`center`,status:`success`,durationMs:e});return}e===`webrtcConnecting`&&this.webrtcConnectStartedAt===void 0&&(this.webrtcConnectStartedAt=Date.now(),this.qosMonitor.recordEvent({eventName:`webrtc_connect_start`,stage:`webrtc`,status:`start`}))}handleCenterEventForQos(e){if(this.qosMonitor.recordEvent({eventName:`center_message_received`,stage:`center`,status:`update`,attrs:{fn:e}}),e===this.Events.CenterDisconnected){this.qosMonitor.recordEvent({eventName:`center_disconnected`,stage:`center`,status:`failed`,attrs:{reason:e}});return}if(e===this.Events.CenterConnected&&this.centerConnectStartedAt!==void 0){let e=this.durationFrom(this.centerConnectStartedAt);this.centerConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`center_connected`,stage:`center`,status:`success`,durationMs:e})}}durationFrom(e){if(e===void 0)return;let t=Date.now()-e;return Number.isFinite(t)&&t>=0?t:void 0}handleProgressNotice(e){if(e.kind===`tokenWillExpire`){this.loadingProgressController.showTokenWillExpire(e.message,e.key,e.isClose);return}this.loadingProgressController.show(e.message,e.key,e.isClose)}handleNetworkModeChange(e){this.networkAdaptation.setMode(e);let t={mode:e,ts:Date.now(),diagnostics:this.networkAdaptation.getDiagnosticsSnapshot()};this.eventBus.emit(this.Events.NetworkModeChanged,t)}mountApiFacade(e){let t=this;Object.keys(e).forEach(n=>{this.setApiModule(t,e,n)})}setApiModule(e,t,n){e[n]=t[n]}initializeOptionalRuntimeExtensions(){if(this.agentBridge||!this.agentBridgeOptions?.enabled)return;let e={...this.agentBridgeOptions,serverUrl:this.agentBridgeOptions.serverUrl??`ws://127.0.0.1:8787/sdk3-bridge`},t=lr(this,{runtimeName:e.runtimeName,expose:e.expose,metadata:e.metadata,engineConfig:this.resolvedConfig,getAuthSnapshot:()=>this.authWorkflow.getSnapshot(),mockInvoke:e.mockInvoke});this.agentBridge=new he(t,e),this.agentBridge.start()}stopRuntimeForLifecycle(e){this.PointEditor.cancelPlacement(),this.GizmosTool.resetRuntime(),e?.stopAgentBridge!==!1&&(this.agentBridge?.stop(`disconnect`),this.agentBridge=void 0),e?.removeListener!==!1&&this.session.removeResponseEventListener(this.uePushResponseListenerName),this.engineStatusCollector.stop(),e?.disconnectAuth!==!1&&this.authWorkflow.disconnect(),this.loadingProgressController.dispose(),this.qosMonitor.flush()}handleUePushResponse(e){let t=e,n;try{if(t=JSON.parse(e),typeof t==`object`&&t){let e=t,r=e.uuid??e.fn;typeof r==`string`&&r.length>0&&(n=r)}}catch{}if(n===`PointEditorGizmoEnded`){this.GizmosTool.finishFromEngine();return}!n&&this.uePushEventNames.has(e)&&(n=e),!(!n||!this.uePushEventNames.has(n))&&this.eventBus.emit(n,t)}getEngineConfig(){return this.resolvedConfig}};exports.AGENT_BRIDGE_API_METADATA=En,exports.API_MODULE_KEYS=pn,exports.AgentRuntimeBridge=he,exports.Animation=Nt,exports.ApiRegistryError=Q,exports.BuildingFloor=Ii,exports.BuildingFloorError=$,exports.Camera=Pt,exports.Connect=Ft,exports.DTCEngine=Vi,exports.Dlss=It,exports.DlssQuality=C,exports.FilterMode=Ve,exports.GizmoType=We,exports.GizmosTool=je,exports.HeatMap=Lt,exports.HighLighterEffect=Rt,exports.Layer=Vt,exports.LayerEnum=Re,exports.Model=Ht,exports.ModelPOI=Ut,exports.ModelTransform=Wt,exports.ModelTransformType=Be,exports.Navigation=Gt,exports.PathPatrol=Kt,exports.PendingValidationSchemaMap=jt,exports.PointEditor=Qt,exports.PointIcon=Yt,exports.Popup=nn,exports.SDKValidationError=p,exports.Scene=an,exports.Screen=rn,exports.ScreenRenderBitratePreset=w,exports.ScreenRenderBitratePresetOptions=Fe,exports.Season=ze,exports.SpatialQuery=on,exports.TimeLine=sn,exports.TrainBehavior=He,exports.TrainSimulate=cn,exports.UIPOI=ln,exports.VideoCodeType=Le,exports.WeatherSystem=dn,exports.WebView=un,exports.apiRegistry=fn,exports.createAgentBridgeMetadata=Dn,exports.createApiFacade=Ai,exports.createBridgeRuntime=lr,exports.getAgentBridgeMethodSchema=Pn,exports.isAgentBridgeMethodExposed=jn,exports.isAgentBridgeModuleExposed=An,exports.isAgentBridgeModuleName=On,exports.listAgentBridgeMethods=Nn,exports.listAgentBridgeModules=Mn,exports.resolveAgentBridgeExposeConfig=kn;
@@ -2356,6 +2356,10 @@ interface BuildingFloorItem {
2356
2356
  viewPoint?: BuildingFloorViewPoint;
2357
2357
  /** 切换到该楼层后显示的附属对象。 */
2358
2358
  objects?: string[];
2359
+ /** 切层动画开始前显示的对象 ID;不限定于楼层父节点。 */
2360
+ showLayers?: string[];
2361
+ /** 切层动画开始前隐藏的对象 ID;与 objects/showLayers 重复时隐藏优先。 */
2362
+ hideLayers?: string[];
2359
2363
  }
2360
2364
  /** 楼层既可使用节点 ID,也可使用带固定视角的对象。 */
2361
2365
  type BuildingFloorInput = string | BuildingFloorItem;
@@ -2363,6 +2367,10 @@ type BuildingFloorInput = string | BuildingFloorItem;
2363
2367
  interface BuildingFloorOverview {
2364
2368
  /** 仅在整栋视图中显示的附属对象。 */
2365
2369
  objects?: string[];
2370
+ /** 恢复整栋视图时,在动画开始前显示的对象 ID。 */
2371
+ showLayers?: string[];
2372
+ /** 恢复整栋视图时,在动画开始前隐藏的对象 ID;隐藏优先。 */
2373
+ hideLayers?: string[];
2366
2374
  /** 整栋视图的可选固定视角。 */
2367
2375
  viewPoint?: BuildingFloorViewPoint;
2368
2376
  }
@@ -3676,37 +3684,37 @@ declare class Camera extends BaseApi {
3676
3684
  declare class Scene extends BaseApi {
3677
3685
  constructor(bridge: ApiBridge, runtimeOptions?: BaseApiRuntimeOptions);
3678
3686
  /**
3679
- * 获取当前引擎服务支持的场景名称列表。
3680
- * @param callback - 可选回调函数。
3681
- * @returns Promise 形式的接口响应。
3687
+ * 获取当前引擎服务支持的场景名称列表。
3688
+ * @param callback - 可选回调函数。
3689
+ * @returns Promise 形式的接口响应。
3682
3690
  * @agentSideEffects read
3683
3691
  * @agentPreconditions DTCEngine 已完成鉴权并建立 WebRTC 连接
3684
3692
  * @agentRiskLevel low
3685
3693
  * @agentExample {}
3686
- * @example
3687
- * ```ts
3688
- * dtcEngine.Scene.getAllSceneName((data) => {
3689
- * console.log(data);
3690
- * });
3691
- * ```
3692
- */
3694
+ * @example
3695
+ * ```ts
3696
+ dtcEngine.Scene.getAllSceneName((data) => {
3697
+ console.log(data);
3698
+ });
3699
+ * ```
3700
+ */
3693
3701
  getAllSceneName(callback?: ApiCallback<ApiResponseEnvelope<unknown>>): Promise<ApiResponseEnvelope<unknown>>;
3694
3702
  /**
3695
- * 按场景名称切换场景。
3696
- * @param payload - 场景切换参数。
3697
- * @param callback - 可选回调函数。
3698
- * @returns Promise 形式的接口响应。
3703
+ * 按场景名称切换场景。
3704
+ * @param payload - 场景切换参数。
3705
+ * @param callback - 可选回调函数。
3706
+ * @returns Promise 形式的接口响应。
3699
3707
  * @agentSideEffects write
3700
3708
  * @agentPreconditions DTCEngine 已完成鉴权并建立 WebRTC 连接
3701
3709
  * @agentRiskLevel low
3702
3710
  * @agentExample { sceneName: 'TestScene' }
3703
- * @example
3704
- * ```ts
3705
- * dtcEngine.Scene.switchSceneByName({ sceneName: 'TestScene' }, (result) => {
3706
- * console.log(result);
3707
- * });
3708
- * ```
3709
- */
3711
+ * @example
3712
+ * ```ts
3713
+ dtcEngine.Scene.switchSceneByName({ sceneName: 'TestScene' }, (result) => {
3714
+ console.log(result);
3715
+ });
3716
+ * ```
3717
+ */
3710
3718
  switchSceneByName(payload: SceneSwitchRequest, callback?: ApiCallback<ApiResponseEnvelope<unknown>>): Promise<ApiResponseEnvelope<unknown>>;
3711
3719
  /**
3712
3720
  * 获取当前正在运行的场景名称。
@@ -2356,6 +2356,10 @@ interface BuildingFloorItem {
2356
2356
  viewPoint?: BuildingFloorViewPoint;
2357
2357
  /** 切换到该楼层后显示的附属对象。 */
2358
2358
  objects?: string[];
2359
+ /** 切层动画开始前显示的对象 ID;不限定于楼层父节点。 */
2360
+ showLayers?: string[];
2361
+ /** 切层动画开始前隐藏的对象 ID;与 objects/showLayers 重复时隐藏优先。 */
2362
+ hideLayers?: string[];
2359
2363
  }
2360
2364
  /** 楼层既可使用节点 ID,也可使用带固定视角的对象。 */
2361
2365
  type BuildingFloorInput = string | BuildingFloorItem;
@@ -2363,6 +2367,10 @@ type BuildingFloorInput = string | BuildingFloorItem;
2363
2367
  interface BuildingFloorOverview {
2364
2368
  /** 仅在整栋视图中显示的附属对象。 */
2365
2369
  objects?: string[];
2370
+ /** 恢复整栋视图时,在动画开始前显示的对象 ID。 */
2371
+ showLayers?: string[];
2372
+ /** 恢复整栋视图时,在动画开始前隐藏的对象 ID;隐藏优先。 */
2373
+ hideLayers?: string[];
2366
2374
  /** 整栋视图的可选固定视角。 */
2367
2375
  viewPoint?: BuildingFloorViewPoint;
2368
2376
  }
@@ -3676,37 +3684,37 @@ declare class Camera extends BaseApi {
3676
3684
  declare class Scene extends BaseApi {
3677
3685
  constructor(bridge: ApiBridge, runtimeOptions?: BaseApiRuntimeOptions);
3678
3686
  /**
3679
- * 获取当前引擎服务支持的场景名称列表。
3680
- * @param callback - 可选回调函数。
3681
- * @returns Promise 形式的接口响应。
3687
+ * 获取当前引擎服务支持的场景名称列表。
3688
+ * @param callback - 可选回调函数。
3689
+ * @returns Promise 形式的接口响应。
3682
3690
  * @agentSideEffects read
3683
3691
  * @agentPreconditions DTCEngine 已完成鉴权并建立 WebRTC 连接
3684
3692
  * @agentRiskLevel low
3685
3693
  * @agentExample {}
3686
- * @example
3687
- * ```ts
3688
- * dtcEngine.Scene.getAllSceneName((data) => {
3689
- * console.log(data);
3690
- * });
3691
- * ```
3692
- */
3694
+ * @example
3695
+ * ```ts
3696
+ dtcEngine.Scene.getAllSceneName((data) => {
3697
+ console.log(data);
3698
+ });
3699
+ * ```
3700
+ */
3693
3701
  getAllSceneName(callback?: ApiCallback<ApiResponseEnvelope<unknown>>): Promise<ApiResponseEnvelope<unknown>>;
3694
3702
  /**
3695
- * 按场景名称切换场景。
3696
- * @param payload - 场景切换参数。
3697
- * @param callback - 可选回调函数。
3698
- * @returns Promise 形式的接口响应。
3703
+ * 按场景名称切换场景。
3704
+ * @param payload - 场景切换参数。
3705
+ * @param callback - 可选回调函数。
3706
+ * @returns Promise 形式的接口响应。
3699
3707
  * @agentSideEffects write
3700
3708
  * @agentPreconditions DTCEngine 已完成鉴权并建立 WebRTC 连接
3701
3709
  * @agentRiskLevel low
3702
3710
  * @agentExample { sceneName: 'TestScene' }
3703
- * @example
3704
- * ```ts
3705
- * dtcEngine.Scene.switchSceneByName({ sceneName: 'TestScene' }, (result) => {
3706
- * console.log(result);
3707
- * });
3708
- * ```
3709
- */
3711
+ * @example
3712
+ * ```ts
3713
+ dtcEngine.Scene.switchSceneByName({ sceneName: 'TestScene' }, (result) => {
3714
+ console.log(result);
3715
+ });
3716
+ * ```
3717
+ */
3710
3718
  switchSceneByName(payload: SceneSwitchRequest, callback?: ApiCallback<ApiResponseEnvelope<unknown>>): Promise<ApiResponseEnvelope<unknown>>;
3711
3719
  /**
3712
3720
  * 获取当前正在运行的场景名称。