@16x/webphone-sdk 3.1.15 → 3.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.1.17
4
+
5
+ 修复平台抖动后 dial 永久不可自愈(CALL_NOT_CONNECTED)——与主线 3.2.8 同源修复:
6
+
7
+ - `ReconnectManager` 新增 `isRecovered` 校验:recover() 成功返回不再被当作连接已恢复,未恢复按失败继续退避。
8
+ - `recoverInvalidSession` 重建失败不再 `reconnect.cancel()` 永久取消重连循环(事故主根因),保持封顶退避重试。
9
+ - `recoverConnection` 在会话被清空后改走 `performConnect` 全新建会话;在途通话超过 120s 宽限后强制终态(终态事件不可达时)。
10
+ - 媒体释放屏障增加 5s 超时,防止永不 settle 的释放操作锁死重连。
11
+
12
+ ## 3.1.16 - 2026-10-08
13
+
14
+ - 修正客户专属发布版本号与 npm dist-tag 对齐;此版本运行时代码与 3.1.15 相同。
15
+
3
16
  ## 3.1.15 - 2026-10-08
4
17
 
5
18
  - 回移 3.2.6–3.2.7 的 ICE 改进:增加 ICE gathering 3 秒兜底、按 URL 探测 ICE 服务,并将探测结果区分为可用、不可用和未知。
@@ -1,5 +1,5 @@
1
1
  import { i as e, t } from "./SharedWorkerProtocol-CffZrUXg.js";
2
- import { r as n, t as r } from "./Diagnostics-DLU1_Np2.js";
2
+ import { r as n, t as r } from "./Diagnostics-B6xGNl8M.js";
3
3
  //#region src/events/TypedEventBus.ts
4
4
  var i = class {
5
5
  handlers = /* @__PURE__ */ new Map();
@@ -608,6 +608,27 @@ var v = class {
608
608
  }).then(() => void 0);
609
609
  return this.disposeOperation = n, n;
610
610
  }
611
+ async forceTerminateCalls(e = 5e3) {
612
+ if (this.disposed) return;
613
+ let t = [...this.calls.values()];
614
+ for (let n of t) {
615
+ if (this.disposed) return;
616
+ if (this.calls.get(n.id) === n) {
617
+ try {
618
+ await Promise.race([n.hangup().catch(() => void 0), new Promise((t) => setTimeout(t, Math.max(0, e)))]);
619
+ } catch {}
620
+ try {
621
+ n.dispose();
622
+ } catch {}
623
+ if (this.calls.get(n.id) === n) {
624
+ this.calls.delete(n.id), this.callSessions.delete(n.id), this.callOwners.delete(n.id), this.ownerLostCalls.delete(n.id), this.activeCallId === n.id && (this.activeCallId = null);
625
+ try {
626
+ await this.notifyCallTerminal(n.id);
627
+ } catch {}
628
+ }
629
+ }
630
+ }
631
+ }
611
632
  updateSession(e) {
612
633
  this.disposed || (this.incomingSessionSnapshot = e);
613
634
  }
@@ -1926,6 +1947,7 @@ function Ee(e, t = Math.random) {
1926
1947
  //#region src/reconnect/ReconnectManager.ts
1927
1948
  var De = class {
1928
1949
  recover;
1950
+ isRecovered;
1929
1951
  random;
1930
1952
  isOnline;
1931
1953
  onAttempt;
@@ -1937,7 +1959,7 @@ var De = class {
1937
1959
  disposed = !1;
1938
1960
  restartAfterRun = !1;
1939
1961
  constructor(e) {
1940
- this.recover = e.recover, this.random = e.random ?? Math.random, this.isOnline = e.isOnline ?? (() => !0), this.onAttempt = e.onAttempt;
1962
+ this.recover = e.recover, this.isRecovered = e.isRecovered, this.random = e.random ?? Math.random, this.isOnline = e.isOnline ?? (() => !0), this.onAttempt = e.onAttempt;
1941
1963
  }
1942
1964
  start() {
1943
1965
  if (this.disposed || !this.online || !this.isOnline() || this.pendingTimer !== void 0 || this.running) return;
@@ -1975,7 +1997,7 @@ var De = class {
1975
1997
  } finally {
1976
1998
  this.running = !1;
1977
1999
  }
1978
- this.restartAfterRun ? (this.restartAfterRun = !1, this.isCurrent(this.generation) && this.start()) : t && this.isCurrent(e) && this.start();
2000
+ !t && this.isCurrent(e) && this.isRecovered !== void 0 && !this.isRecovered() && (this.attempt += 1, t = !0), this.restartAfterRun ? (this.restartAfterRun = !1, this.isCurrent(this.generation) && this.start()) : t && this.isCurrent(e) && this.start();
1979
2001
  }
1980
2002
  isCurrent(e) {
1981
2003
  return !this.disposed && this.online && e === this.generation && this.isOnline();
@@ -1983,7 +2005,7 @@ var De = class {
1983
2005
  clearPendingTimer() {
1984
2006
  this.pendingTimer !== void 0 && (clearTimeout(this.pendingTimer), this.pendingTimer = void 0);
1985
2007
  }
1986
- }, Oe = class t {
2008
+ }, Oe = 12e4, ke = 5e3, Ae = class t {
1987
2009
  media;
1988
2010
  options;
1989
2011
  api;
@@ -2014,6 +2036,7 @@ var De = class {
2014
2036
  sipUnsubscribe;
2015
2037
  networkUnsubscribers = [];
2016
2038
  networkProbeTimer;
2039
+ stuckCallsSince;
2017
2040
  sessionDeleteOperations = /* @__PURE__ */ new Map();
2018
2041
  deletedSessions = /* @__PURE__ */ new Set();
2019
2042
  ownedSessionIds = /* @__PURE__ */ new Set();
@@ -2021,8 +2044,9 @@ var De = class {
2021
2044
  sharedWorkerSelection;
2022
2045
  constructor(t) {
2023
2046
  if (this.options = t, t.api === void 0 && t.sessionProvider === void 0) throw new e("CONFIG_INVALID", "configuration", !1, { cause: "CCBarClient 需要 sessionProvider" });
2024
- this.api = t.api === void 0 ? J(X(t.sessionProvider)) : J(t.api), this.suppliedSip = t.sip === void 0 ? void 0 : je(t.sip), this.mediaBridge = Se(() => this.getActiveMediaContext()), this.media = this.mediaBridge.publicMedia, this.reconnect = new De({
2047
+ this.api = t.api === void 0 ? J(Ne(t.sessionProvider)) : J(t.api), this.suppliedSip = t.sip === void 0 ? void 0 : X(t.sip), this.mediaBridge = Se(() => this.getActiveMediaContext()), this.media = this.mediaBridge.publicMedia, this.reconnect = new De({
2025
2048
  recover: () => this.recoverConnection(),
2049
+ isRecovered: () => this.state === "connected",
2026
2050
  onAttempt: (e) => {
2027
2051
  this.disposed || this.events.emit("connection.reconnecting", { attempt: e });
2028
2052
  }
@@ -2039,7 +2063,7 @@ var De = class {
2039
2063
  });
2040
2064
  }
2041
2065
  static async checkSupport() {
2042
- let e = typeof navigator < "u" && navigator.mediaDevices !== void 0, t = typeof WebSocket < "u", n = Ae(typeof navigator < "u" ? navigator.userAgent : "");
2066
+ let e = typeof navigator < "u" && navigator.mediaDevices !== void 0, t = typeof WebSocket < "u", n = Me(typeof navigator < "u" ? navigator.userAgent : "");
2043
2067
  return {
2044
2068
  supported: e && t,
2045
2069
  platform: n,
@@ -2147,7 +2171,7 @@ var De = class {
2147
2171
  sdkVersion: n,
2148
2172
  platform: a === "mobile-web" ? "mobile_web" : "web",
2149
2173
  ...this.options.locale === void 0 ? {} : { locale: this.options.locale },
2150
- requestedCapabilities: [...this.options.requestedCapabilities ?? Fe(a)]
2174
+ requestedCapabilities: [...this.options.requestedCapabilities ?? Le(a)]
2151
2175
  }), this.ownedSessionIds.add(t.sessionId), this.assertGeneration(e), r = await this.getSip(), this.assertGeneration(e), this.session = t;
2152
2176
  let o = this.callManager ?? this.createCallManager(r, t, a);
2153
2177
  this.callManager === void 0 && (i = o), o.updateSession(t), this.callManager = o, this.attachSipListener(r), this.attachNetworkListeners(), await r.connect(t), this.assertGeneration(e), this.setConnectionState("connected"), this.events.emit("connection.registered", { registered: !0 }), this.scheduleRefresh(t);
@@ -2171,7 +2195,7 @@ var De = class {
2171
2195
  } catch (t) {
2172
2196
  $(t) || (e ??= t);
2173
2197
  }
2174
- this.reconnect.cancel(), this.clearRefreshTimer(), this.intentionalDisconnect = !0, this.detachNetworkListeners(), this.detachSipListener(), this.detachManagerListeners();
2198
+ this.reconnect.cancel(), this.stuckCallsSince = void 0, this.clearRefreshTimer(), this.intentionalDisconnect = !0, this.detachNetworkListeners(), this.detachSipListener(), this.detachManagerListeners();
2175
2199
  let r = this.callManager, i = this.sip;
2176
2200
  this.callManager = void 0;
2177
2201
  try {
@@ -2253,7 +2277,7 @@ var De = class {
2253
2277
  try {
2254
2278
  await this.media.releaseAll();
2255
2279
  } catch (t) {
2256
- Me(t) || (e ??= t);
2280
+ Pe(t) || (e ??= t);
2257
2281
  }
2258
2282
  try {
2259
2283
  await this.mediaBridge.dispose();
@@ -2275,16 +2299,31 @@ var De = class {
2275
2299
  async awaitMediaReleaseBarriers() {
2276
2300
  let e;
2277
2301
  for (let [t, n] of [...this.terminalReleaseOperations]) try {
2278
- await n, this.terminalReleaseOperations.delete(t);
2302
+ await this.withBarrierTimeout(n, t), this.terminalReleaseOperations.delete(t);
2279
2303
  } catch (n) {
2280
2304
  try {
2281
- await this.mediaBridge.releaseCall(t), this.terminalReleaseOperations.delete(t);
2305
+ await this.withBarrierTimeout(this.mediaBridge.releaseCall(t), t), this.terminalReleaseOperations.delete(t);
2282
2306
  } catch (t) {
2283
2307
  e ??= t ?? n;
2284
2308
  }
2285
2309
  }
2286
2310
  if (e !== void 0) throw e;
2287
2311
  }
2312
+ withBarrierTimeout(t, n, r = ke) {
2313
+ return new Promise((i, a) => {
2314
+ let o = setTimeout(() => {
2315
+ a(new e("SDK_INTERNAL_ERROR", "internal", !0, {
2316
+ callId: n,
2317
+ cause: "media release barrier timeout"
2318
+ }));
2319
+ }, Math.max(0, r));
2320
+ t.then((e) => {
2321
+ clearTimeout(o), i(e);
2322
+ }, (e) => {
2323
+ clearTimeout(o), a(e);
2324
+ });
2325
+ });
2326
+ }
2288
2327
  detachSipListener() {
2289
2328
  let e = this.sipUnsubscribe;
2290
2329
  this.sipUnsubscribe = void 0;
@@ -2394,7 +2433,7 @@ var De = class {
2394
2433
  if (!this.disposed) try {
2395
2434
  await this.performConnect(this.lifecycleGeneration);
2396
2435
  } catch {
2397
- this.reconnect.cancel();
2436
+ this.disposed || this.reconnect.start();
2398
2437
  }
2399
2438
  }
2400
2439
  }
@@ -2406,7 +2445,18 @@ var De = class {
2406
2445
  }, n);
2407
2446
  }
2408
2447
  async recoverConnection() {
2409
- this.disposed || this.intentionalDisconnect || this.hasNonTerminalCalls() || (await this.awaitMediaReleaseBarriers(), await this.refreshAndRebuild());
2448
+ if (!(this.disposed || this.intentionalDisconnect)) {
2449
+ if (this.hasNonTerminalCalls()) {
2450
+ let e = Date.now();
2451
+ if (this.stuckCallsSince === void 0 && (this.stuckCallsSince = e), e - this.stuckCallsSince < Oe) return;
2452
+ this.stuckCallsSince = void 0, await this.callManager?.forceTerminateCalls();
2453
+ } else this.stuckCallsSince = void 0;
2454
+ if (await this.awaitMediaReleaseBarriers(), this.session === void 0) {
2455
+ await this.performConnect(this.lifecycleGeneration);
2456
+ return;
2457
+ }
2458
+ await this.refreshAndRebuild();
2459
+ }
2410
2460
  }
2411
2461
  async getSip() {
2412
2462
  if (this.sip !== void 0) return this.sip;
@@ -2466,7 +2516,7 @@ var De = class {
2466
2516
  destination: e.destination
2467
2517
  })),
2468
2518
  permission: this.support?.hasMediaDevices === !1 ? "unsupported" : "unknown",
2469
- ice: ke(e, this.sip?.iceQualitySnapshot?.()),
2519
+ ice: je(e, this.sip?.iceQualitySnapshot?.()),
2470
2520
  wss: {
2471
2521
  configured: e !== void 0,
2472
2522
  secure: e?.transport.wssUrl.toLowerCase().startsWith("wss://") ?? !1,
@@ -2583,7 +2633,7 @@ var De = class {
2583
2633
  return new e("SDK_ALREADY_DISPOSED", "internal", !1);
2584
2634
  }
2585
2635
  };
2586
- function ke(e, t) {
2636
+ function je(e, t) {
2587
2637
  if (e === void 0) return {
2588
2638
  configured: !1,
2589
2639
  serverCount: 0,
@@ -2603,7 +2653,7 @@ function ke(e, t) {
2603
2653
  turnServerCount: r
2604
2654
  };
2605
2655
  }
2606
- function Ae(e) {
2656
+ function Me(e) {
2607
2657
  return e === "" ? "unknown" : /iPhone|iPad|Android/i.test(e) ? "mobile-web" : "web";
2608
2658
  }
2609
2659
  function J(t) {
@@ -2622,7 +2672,7 @@ async function Y(e) {
2622
2672
  }
2623
2673
  };
2624
2674
  }
2625
- function X(t) {
2675
+ function Ne(t) {
2626
2676
  let r = {
2627
2677
  createSession: async (e) => Y(await t.createSession(e)),
2628
2678
  refreshSession: async (e) => Y(t.refreshSession === void 0 ? await t.createSession({
@@ -2636,7 +2686,7 @@ function X(t) {
2636
2686
  }, i = t.invalidateToken;
2637
2687
  return i !== void 0 && (r.invalidateToken = () => i()), r;
2638
2688
  }
2639
- function je(t) {
2689
+ function X(t) {
2640
2690
  if (typeof t != "object" || !t) throw new e("CONFIG_INVALID", "configuration", !1);
2641
2691
  return t;
2642
2692
  }
@@ -2656,13 +2706,13 @@ function Z(t, n, r, i, a) {
2656
2706
  function Q(t) {
2657
2707
  return t instanceof e ? t.status !== void 0 && t.status >= 400 && t.status < 500 || t.serverCode === "SESSION_NOT_FOUND" || t.serverCode === "SESSION_EXPIRED" || t.serverCode === "TOKEN_INVALID" || t.serverCode === "TOKEN_EXPIRED" || t.code === "AUTH_TOKEN_UNAVAILABLE" || t.code === "AUTH_TOKEN_EXPIRED" || t.code === "AUTH_TOKEN_REJECTED" : !1;
2658
2708
  }
2659
- function Me(t) {
2709
+ function Pe(t) {
2660
2710
  return t instanceof e && t.code === "SDK_ALREADY_DISPOSED";
2661
2711
  }
2662
2712
  function $(t) {
2663
2713
  return t instanceof e && (t.code === "SDK_ALREADY_DISPOSED" || t.code === "CALL_NOT_CONNECTED");
2664
2714
  }
2665
- var Ne = [
2715
+ var Fe = [
2666
2716
  "outbound",
2667
2717
  "inbound",
2668
2718
  "mute",
@@ -2670,13 +2720,13 @@ var Ne = [
2670
2720
  "dtmf",
2671
2721
  "blind_transfer",
2672
2722
  "device_selection"
2673
- ], Pe = [
2723
+ ], Ie = [
2674
2724
  "outbound",
2675
2725
  "mute",
2676
2726
  "dtmf"
2677
2727
  ];
2678
- function Fe(e) {
2679
- return e === "mobile-web" ? Pe : Ne;
2728
+ function Le(e) {
2729
+ return e === "mobile-web" ? Ie : Fe;
2680
2730
  }
2681
2731
  //#endregion
2682
- export { v as a, s as c, a as d, i as f, x as i, o as l, w as n, f as o, T as r, c as s, Oe as t, l as u };
2732
+ export { v as a, s as c, a as d, i as f, x as i, o as l, w as n, f as o, T as r, c as s, Ae as t, l as u };
@@ -0,0 +1 @@
1
+ const e=require("./SharedWorkerProtocol-C-4KpECM.cjs"),t=require("./Diagnostics-CK0ai_sy.cjs");var n=class{handlers=new Map;on(e,t){let n=this.handlers.get(e)??new Set;n.add(t),this.handlers.set(e,n);let r=!0;return()=>{r&&(r=!1,n.delete(t))}}off(e,t){this.handlers.get(e)?.delete(t)}emit(e,t){[...this.handlers.get(e)??[]].forEach(e=>{try{e(t)}catch{}})}listenerCount(){return[...this.handlers.values()].reduce((e,t)=>e+t.size,0)}clear(){this.handlers.clear()}},r={new:new Set([`dialing`,`ringing`,`failed`]),dialing:new Set([`ringing`,`connecting`,`ended`,`failed`]),ringing:new Set([`connecting`,`ended`,`failed`]),connecting:new Set([`active`,`ended`,`failed`]),active:new Set([`held`,`ended`,`failed`]),held:new Set([`active`,`ended`,`failed`]),ended:new Set,failed:new Set},i=(e,t)=>r[e].has(t);function a(e,t){if(!i(e,t))throw new o(e,t);return t}var o=class extends e.i{constructor(e,t){super(`CALL_OPERATION_NOT_ALLOWED`,`call`,!1,{cause:{from:e,to:t}})}},s=a,c=[`progress`,`accepted`,`confirmed`,`ended`,`failed`,`hold`,`unhold`,`mediaConnected`],l=3e4,u=class{options;currentState=`new`;sessionUnsubscribers=[];capabilities;disposed=!1;pendingOperation;localHeld=!1;remoteHeld=!1;incomingOperation;ownerTabId;ownerLost=!1;id;destination;platform;constructor(t){this.options=t,this.id=t.id,this.destination=t.destination,this.platform=t.platform,this.capabilities=t.capabilities??new Set;try{c.forEach(e=>{this.sessionUnsubscribers.push(t.session.on(e,t=>this.handleSessionEvent(e,t)))})}catch(n){this.cleanupSessionListeners();try{t.session.terminate()}catch{}throw new e.i(`CALL_OPERATION_NOT_ALLOWED`,`call`,!1,{callId:this.id,cause:n})}}get state(){return this.currentState}getResourceCounts(){return{timers:this.pendingOperation?.timer===void 0?0:1,listeners:this.sessionUnsubscribers.length}}async mute(e){this.assertNotDisposed(),this.assertOwner(e),this.assertMediaControlAllowed(),this.assertCapability(`mute`),this.invoke(()=>this.options.session.mute())}async unmute(e){this.assertNotDisposed(),this.assertOwner(e),this.assertMediaControlAllowed(),this.assertCapability(`mute`),this.invoke(()=>this.options.session.unmute())}async answer(e,t){this.assertNotDisposed(),this.assertOwner(t),this.assertIncomingCall(),this.assertCapability(`inbound`),this.assertIncomingOperationAvailable(),this.incomingOperation=`answer`;try{this.options.session.answer(e)}catch(e){throw this.incomingOperation=void 0,this.finishFailedIncomingOperation(e),this.operationError(e)}this.transitionIfAllowed(`connecting`,void 0,`accepted`)}async reject(e={},t){this.assertNotDisposed(),this.assertOwner(t),this.assertIncomingCall(),this.assertIncomingOperationAvailable(),this.incomingOperation=`reject`;let n;try{this.options.session.terminate()}catch(e){n=e}finally{this.incomingOperation=void 0,this.transitionIfStillRinging(`ended`,{reason:e.reason?.trim()||`rejected`})}if(n!==void 0)throw this.operationError(n)}async hold(e){this.assertNotDisposed(),this.assertOwner(e),this.assertHoldCapability(),this.assertState(`active`),this.assertCapability(`hold`),await this.startPendingOperation(`hold`,()=>this.options.session.hold())}async resume(e){if(this.assertNotDisposed(),this.assertOwner(e),this.assertHoldCapability(),this.assertState(`held`),this.assertCapability(`hold`),this.remoteHeld&&!this.localHeld)throw this.operationError({reason:`remote_hold_active`});await this.startPendingOperation(`resume`,()=>this.options.session.unhold())}async sendDtmf(e,t){if(this.assertNotDisposed(),this.assertOwner(t),!/^[0-9A-D*#]$/.test(e))throw this.operationError();this.assertState(`active`),this.assertCapability(`dtmf`),this.invoke(()=>this.options.session.sendDtmf(e))}async transfer(e,t){if(this.assertNotDisposed(),this.assertOwner(t),this.assertTransferCapability(),this.assertState(`active`),this.assertCapability(`blind_transfer`),!f(e)||e.target.trim()===``)throw this.operationError();this.invoke(()=>this.options.session.refer(e.target.trim()))}async hangup(e){if(this.assertNotDisposed(),this.assertOwner(e),d(this.currentState))throw this.operationError();try{this.options.session.terminate(),d(this.currentState)||this.transitionTo(`ended`)}catch(e){throw this.operationError(e)}}beginOutbound(){this.assertNotDisposed(),this.assertCapability(`outbound`),this.transitionTo(`dialing`)}beginIncoming(){this.assertNotDisposed(),this.transitionTo(`ringing`)}setOwnerTabId(e){this.ownerTabId=e,this.ownerLost=!1}clearOwnerTabId(e={}){this.ownerTabId=void 0,this.ownerLost=e.lost===!0}getOwnerTabId(){return this.ownerTabId}assertOwnerForManager(e){this.assertOwner(e)}canBeReclaimed(){return this.currentState===`new`||this.currentState===`dialing`||this.currentState===`ringing`}dispose(){if(!this.disposed){if(this.rejectPendingOperation(),this.incomingOperation=void 0,this.disposed=!0,!d(this.currentState))try{this.options.session.terminate()}catch(e){this.reportOperationError(e)}this.cleanupSessionListeners();try{this.options.onDisposed?.()}catch{}}}handleSessionEvent(e,t){if((e===`accepted`||e===`confirmed`||e===`ended`||e===`failed`)&&(this.incomingOperation=void 0),!(this.disposed||d(this.currentState)))switch(e){case`progress`:this.transitionIfAllowed(`ringing`,t,e);break;case`accepted`:this.transitionIfAllowed(`connecting`,t,e);break;case`confirmed`:this.transitionToActive(t);break;case`mediaConnected`:this.currentState===`connecting`&&this.transitionTo(`active`,t);break;case`hold`:this.updateHoldState(!0,t,e);break;case`unhold`:this.updateHoldState(!1,t,e);break;case`ended`:this.transitionIfAllowed(`ended`,t,e);break;case`failed`:this.transitionIfAllowed(`failed`,t,e)}}transitionToActive(e){this.currentState!==`active`&&((this.currentState===`dialing`||this.currentState===`ringing`)&&this.transitionTo(`connecting`,e),this.transitionIfAllowed(`active`,e,`confirmed`))}transitionIfAllowed(e,t,n){this.currentState!==e&&(i(this.currentState,e)?this.transitionTo(e,t):this.reportIllegalTransition(e,n))}updateHoldState(e,t,n){let r=typeof t==`object`&&t?t.originator:void 0;r===`remote`?this.remoteHeld=e:r===`both`?(this.localHeld=e,this.remoteHeld=e):this.localHeld=e;let i=this.localHeld||this.remoteHeld?`held`:`active`;this.transitionIfAllowed(i,t,n)}transitionIfStillRinging(e,t){this.currentState===`ringing`&&this.transitionTo(e,t)}transitionTo(e,t){if(this.currentState===e)return;if(!i(this.currentState,e))throw this.operationError();let n=this.currentState;this.currentState=e,d(e)&&this.rejectPendingOperation();try{this.options.onStateChanged?.({callId:this.id,from:n,to:e},t)}catch{}finally{d(e)&&this.dispose()}}startPendingOperation(e,t){if(this.pendingOperation!==void 0)throw this.operationError({reason:`pending_operation_in_progress`,operation:this.pendingOperation.kind});return new Promise((n,r)=>{let i={kind:e,resolve:n,reject:r};this.pendingOperation=i,i.timer=setTimeout(()=>this.timeoutPendingOperation(i),l);let a;try{a=t()}catch(e){this.rejectPendingOperation(e);return}a.then(()=>this.resolvePendingOperation(i),e=>this.rejectPendingOperation(e,i))})}resolvePendingOperation(e){if(this.pendingOperation===e){if(this.clearPendingTimer(e),this.pendingOperation=void 0,this.disposed||d(this.currentState)){e.reject(this.operationError());return}try{this.localHeld=e.kind===`hold`;let t=this.localHeld||this.remoteHeld?`held`:`active`;this.transitionTo(t),e.resolve()}catch(t){e.reject(this.operationError(t))}}}rejectPendingOperation(e,t){let n=this.pendingOperation;n===void 0||t!==void 0&&n!==t||(this.clearPendingTimer(n),this.pendingOperation=void 0,n.reject(this.operationError(e)))}timeoutPendingOperation(e){this.pendingOperation===e&&(this.rejectPendingOperation(Error(`${e.kind} operation timed out`),e),this.dispose())}clearPendingTimer(e){e.timer!==void 0&&(clearTimeout(e.timer),e.timer=void 0)}reportIllegalTransition(e,t){this.reportOperationError({event:t,from:this.currentState,to:e})}reportOperationError(t){let n=t instanceof e.i&&t.callId===this.id?t:this.operationError(t);try{this.options.onError?.(n)}catch{}}finishFailedIncomingOperation(e){this.reportOperationError(e);try{this.options.session.terminate()}catch(t){e={operation:e,cleanup:t}}this.transitionIfStillRinging(`ended`,{reason:`incoming_operation_failed`,cause:e})}cleanupSessionListeners(){this.sessionUnsubscribers.splice(0).forEach(e=>{try{e()}catch{}})}assertState(e){if(this.currentState!==e)throw this.operationError()}assertMediaControlAllowed(){if(this.currentState!==`active`&&this.currentState!==`held`)throw this.operationError()}assertHoldCapability(){if(this.platform===`mobile-web`)throw this.capabilityError()}assertTransferCapability(){if(this.platform===`mobile-web`)throw this.capabilityError()}assertIncomingCall(){if(this.options.incoming!==!0||this.currentState!==`ringing`)throw this.operationError()}assertIncomingOperationAvailable(){if(this.incomingOperation!==void 0)throw this.operationError()}assertCapability(e){if(!this.capabilities.has(e))throw this.capabilityError()}invoke(e){try{e()}catch(e){throw this.operationError(e)}}assertNotDisposed(){if(this.disposed)throw this.operationError()}assertOwner(e){if(e!==void 0&&(this.ownerLost||this.ownerTabId!==void 0&&this.ownerTabId!==e))throw this.operationError()}capabilityError(){return new e.i(`CAPABILITY_NOT_SUPPORTED`,`capability`,!1,{callId:this.id})}operationError(t){return new e.i(`CALL_OPERATION_NOT_ALLOWED`,`call`,!1,{callId:this.id,cause:t})}};function d(e){return e===`ended`||e===`failed`}function f(e){return typeof e==`object`&&!!e&&e.type===`blind`&&typeof e.target==`string`}var p=0;function m(){return p+=1,`call_${Date.now().toString(36)}_${p.toString(36)}`}var ee=`X-User-Data`,te=/[^\x20-\x7E]/,ne=`userdata 只能是可见 ASCII(不能有换行/制表/中文):换行会构成 SIP 头注入;要传中文或 JSON 请调用方先 encodeURIComponent / base64,再在平台侧解回来`;function re(t){if(typeof t!=`string`)return[];let n=t.trim();if(n===``)return[];if(te.test(n))throw new e.i(`CALL_INVALID_USERDATA`,`call`,!1,{cause:ne});return[`${ee}: ${n}`]}var h=class{events=new g;calls=new Map;options;incomingUnsubscribe;activeCallId=null;incomingSessionSnapshot;callSessions=new Map;callOwners=new Map;ownerLostCalls=new Set;pendingDialCount=0;pendingDestinations=new Set;activeOperationPromise=Promise.resolve();operationGeneration=0;automaticActiveTransition;disposed=!1;terminalNotified=new Set;terminalOperations=new Map;disposeOperation;constructor(t){this.options=t,this.incomingSessionSnapshot=t.session;try{this.incomingUnsubscribe=t.sip.onIncoming(e=>this.handleIncoming(e))}catch(t){throw new e.i(`SDK_INTERNAL_ERROR`,`internal`,!1,{cause:t})}}on(e,t){return this.disposed?()=>void 0:this.events.on(e,t)}async dial(t,n){this.assertNotDisposed();let r=this.operationGeneration,i=t.destination.trim();if(i===``)throw new e.i(`CALL_INVALID_DESTINATION`,`call`,!1);let a=/^\+?\d{3,20}$/.test(i),o=/^sips?:[^\s<>@]+(?:@[^\s<>@]+)?$/i.test(i);if(!a&&!o)throw new e.i(`CALL_INVALID_DESTINATION`,`call`,!1);let s=re(t.userdata);this.requireCapability(n,`outbound`);let c=this.callLimit(n);if(this.options.platform===`mobile-web`&&this.calls.size+this.pendingDialCount>=c)throw this.capabilityError();if(this.calls.size+this.pendingDialCount>=c||this.pendingDestinations.has(i)||[...this.calls.values()].some(e=>e.destination===i))throw new e.i(`CALL_ALREADY_EXISTS`,`call`,!1);this.pendingDialCount+=1,this.pendingDestinations.add(i);let l=m(),d;try{d=await this.holdActiveCallForNewCall(),this.assertGeneration(r,l);let e;try{e=this.options.sip.dial(i,this.dialOptions(l,n,t.type,s))}catch(e){throw this.dialError(e,l)}this.assertGeneration(r,l);let a;try{a=new u({id:l,destination:i,platform:this.options.platform,capabilities:this.effectiveCapabilities(n),session:e,onStateChanged:(e,t)=>this.handleStateChanged(a,e,t),onError:e=>this.events.emit(`error`,{error:e}),onDisposed:()=>this.handleDisposed(a)})}catch(e){throw this.dialError(e,l)}if(!this.isCurrentGeneration(r))throw a.dispose(),this.callOperationError(a.id);this.calls.set(a.id,a),this.callSessions.set(a.id,e),this.options.onCallCreated?.(a.id,e);try{a.beginOutbound()}catch(e){throw a.dispose(),this.calls.delete(a.id),this.callSessions.delete(a.id),this.dialError(e,a.id)}if(!this.isCurrentGeneration(r))throw a.dispose(),this.calls.delete(a.id),this.callSessions.delete(a.id),this.callOperationError(a.id);return this.events.emit(`call.created`,{callId:a.id,state:a.state}),a}catch(e){if(this.isCurrentGeneration(r)&&d!==void 0&&this.isManagedCall(d)&&d.state===`held`)try{await d.resume()}catch(t){throw this.compensationError(d.id,void 0,e,t)}throw e}finally{--this.pendingDialCount,this.pendingDestinations.delete(i)}}async answer(e,t,n,r){this.assertNotDisposed();let i=this.requireCall(e);if(this.options.platform===`mobile-web`&&t.policy.mobileIncomingEnabled!==!0)throw this.capabilityError(e);let a={iceServers:t.iceServers,pcConfig:{iceServers:t.iceServers},...n===void 0?{}:{mediaConstraints:n}};await i.answer(a,r)}async reject(e,t,n){this.assertNotDisposed(),await this.requireCall(e).reject(t,n)}getCalls(){return[...this.calls.values()]}hasNonTerminalCalls(){return this.calls.size>0}getResourceCounts(){let e=[...this.calls.values()].map(e=>e.getResourceCounts());return{timers:e.reduce((e,t)=>e+t.timers,0),listeners:this.events.listenerCount()+e.reduce((e,t)=>e+t.listeners,0),terminalRecords:this.terminalNotified.size+this.terminalOperations.size}}getActiveCall(){return this.activeCallId===null?void 0:this.calls.get(this.activeCallId)}async setActiveCall(e,t){this.assertNotDisposed(),this.requireCall(e).assertOwnerForManager(t),await this.enqueueActiveOperation(t=>this.switchActiveCall(e,t))}async claimCall(e,t){this.assertNotDisposed();let n=t.trim();if(n===``)throw this.callOperationError(e);let r=this.requireCall(e),i=this.callOwners.get(e);if(i!==n){if(i!==void 0||this.ownerLostCalls.has(e)&&!r.canBeReclaimed())throw this.callOperationError(e);this.ownerLostCalls.delete(e),this.callOwners.set(e,n),r.setOwnerTabId(n),this.emitOwnershipChanged({callId:e,state:`owned`,ownerTabId:n})}}async releaseCall(e,t){this.assertNotDisposed();let n=this.requireCall(e);if(this.callOwners.get(e)!==t)throw this.callOperationError(e);this.callOwners.delete(e);let r=!n.canBeReclaimed();r?this.ownerLostCalls.add(e):this.ownerLostCalls.delete(e),n.clearOwnerTabId({lost:r}),this.emitOwnershipChanged({callId:e,state:r?`owner-lost`:`released`})}getCallOwner(e){return this.callOwners.get(e)}releaseOwnedCalls(e){for(let[t,n]of[...this.callOwners.entries()]){if(n!==e)continue;let r=this.calls.get(t);if(r===void 0){this.callOwners.delete(t),this.ownerLostCalls.delete(t);continue}this.callOwners.delete(t);let i=!r.canBeReclaimed();i?this.ownerLostCalls.add(t):this.ownerLostCalls.delete(t),r.clearOwnerTabId({lost:i}),this.emitOwnershipChanged({callId:t,state:i?`owner-lost`:`released`})}}dispose(e={}){if(this.disposeOperation!==void 0)return this.disposeOperation;this.disposed=!0,this.operationGeneration+=1,this.automaticActiveTransition=void 0,this.activeOperationPromise=Promise.resolve(),this.events.clear();try{this.incomingUnsubscribe()}catch{}this.activeCallId=null;let t=[...this.calls.values()];this.calls.clear(),this.callSessions.clear(),this.callOwners.clear(),this.ownerLostCalls.clear();let n=Promise.all(t.map(async t=>{let n;try{e.terminateCalls===!0&&t.state!==`ended`&&t.state!==`failed`?await t.hangup():t.dispose()}catch(e){n=e,t.dispose()}try{await this.notifyCallTerminal(t.id)}catch(e){n??=e}if(n!==void 0)throw n})).finally(()=>{this.terminalNotified.clear(),this.terminalOperations.clear()}).then(()=>void 0);return this.disposeOperation=n,n}async forceTerminateCalls(e=5e3){if(this.disposed)return;let t=[...this.calls.values()];for(let n of t){if(this.disposed)return;if(this.calls.get(n.id)===n){try{await Promise.race([n.hangup().catch(()=>void 0),new Promise(t=>setTimeout(t,Math.max(0,e)))])}catch{}try{n.dispose()}catch{}if(this.calls.get(n.id)===n){this.calls.delete(n.id),this.callSessions.delete(n.id),this.callOwners.delete(n.id),this.ownerLostCalls.delete(n.id),this.activeCallId===n.id&&(this.activeCallId=null);try{await this.notifyCallTerminal(n.id)}catch{}}}}}updateSession(e){this.disposed||(this.incomingSessionSnapshot=e)}async switchActiveCall(e,t){this.assertGeneration(t,e);let n=this.requireCall(e),r=this.getActiveCall();if(r?.id===n.id)return;if(n.state!==`held`&&n.state!==`active`)throw this.callOperationError(e);let i=n.state===`held`;try{if(r!==void 0&&await r.hold(),this.assertGeneration(t,n.id),n.state===`held`&&await n.resume(),this.assertGeneration(t,n.id),!this.isManagedCall(n)||n.state!==`active`)throw this.callOperationError(n.id);this.commitActive(n,t)}catch(a){if(!this.isCurrentGeneration(t))throw this.callOperationError(n.id,a);if(r===void 0)throw this.callOperationError(e,a);try{let e=n.state===`active`;i&&e&&this.isManagedCall(n)&&await n.hold(),this.assertGeneration(t,n.id),r.state===`held`&&this.isManagedCall(r)&&await r.resume(),this.assertGeneration(t,r.id),r.state===`active`&&this.isManagedCall(r)&&this.commitActive(r,t)}catch(e){throw this.compensationError(r.id,n.id,a,e)}throw this.isManagedCall(r)&&r.state===`active`&&this.commitActive(r,t),this.callOperationError(n.id,{operation:a,restoredCallId:r.id})}}handleStateChanged(e,t,n){if(this.disposed)return;let r=this.callSessions.get(e.id);if(r!==void 0&&this.options.onCallStateChanged?.(e.id,r),this.events.emit(`call.stateChanged`,t),t.to===`active`&&this.activeCallId!==e.id){let t=this.getActiveCall();if(this.options.autoHoldPreviousCall===!0&&t!==void 0&&t.id!==e.id&&t.state===`active`){let n=this.operationGeneration;this.enqueueActiveOperation(n=>this.switchAutomaticActiveCall(t,e,n)).catch(e=>{this.isCurrentGeneration(n)&&this.events.emit(`error`,{error:e})})}else this.commitActive(e)}t.to===`held`&&this.activeCallId===e.id&&this.automaticActiveTransition?.previous.id!==e.id&&(this.activeCallId=null,this.events.emit(`call.activeChanged`,{callId:null})),(t.to===`ended`||t.to===`failed`)&&(this.calls.delete(e.id),this.callSessions.delete(e.id),this.callOwners.delete(e.id),this.ownerLostCalls.delete(e.id),this.activeCallId===e.id&&this.automaticActiveTransition?.previous.id!==e.id&&(this.activeCallId=null,this.events.emit(`call.activeChanged`,{callId:null})),this.notifyCallTerminal(e.id),t.to===`ended`?this.events.emit(`call.ended`,{callId:e.id,reason:_(n)}):this.events.emit(`call.failed`,{callId:e.id,error:v(n,e.id)}))}async switchAutomaticActiveCall(e,t,n){this.automaticActiveTransition={previous:e,target:t};let r;try{if(this.assertGeneration(n,t.id),!this.isManagedCall(t)||t.state!==`active`)return;if(!this.isManagedCall(e)||e.state!==`active`){this.commitActive(t,n);return}if(await e.hold(),this.assertGeneration(n,t.id),!this.isManagedCall(e)){this.isManagedCall(t)&&t.state===`active`&&this.commitActive(t,n);return}if(!this.isManagedCall(t)||t.state!==`active`)r=Error(`target call is no longer active`);else{this.commitActive(t,n);return}}catch(e){r=e}finally{this.automaticActiveTransition?.target.id===t.id&&(this.automaticActiveTransition=void 0)}if(!this.isCurrentGeneration(n))return;if(!this.isManagedCall(e)){this.isManagedCall(t)&&t.state===`active`&&this.commitActive(t,n);return}let i=await this.restoreAutomaticActiveCall(e,t,r,n);if(this.isCurrentGeneration(n)){if(i.error!==void 0)throw i.error;if(!this.isManagedCall(e)){this.isManagedCall(t)&&t.state===`active`&&this.commitActive(t,n);return}throw this.callOperationError(t.id,{operation:r,restoredCallId:e.id})}}async restoreAutomaticActiveCall(e,t,n,r){if(!this.isCurrentGeneration(r))return{};if(!this.isManagedCall(e))return this.isManagedCall(t)&&t.state===`active`&&this.commitActive(t,r),{};let i;try{this.isManagedCall(t)&&t.state===`active`&&await t.hold(),this.assertGeneration(r,t.id),this.isManagedCall(e)&&e.state===`held`&&await e.resume(),this.assertGeneration(r,e.id)}catch(e){i=e}return this.isCurrentGeneration(r)?this.isManagedCall(e)?i===void 0?(e.state===`active`&&this.commitActive(e,r),{}):{error:this.compensationError(e.id,t.id,n,i)}:(this.isManagedCall(t)&&t.state===`active`&&this.commitActive(t,r),{}):{}}handleDisposed(e){this.disposed||(this.calls.delete(e.id),this.callSessions.delete(e.id),this.callOwners.delete(e.id),this.ownerLostCalls.delete(e.id),this.notifyCallTerminal(e.id),this.activeCallId===e.id&&(this.activeCallId=null,this.events.emit(`call.activeChanged`,{callId:null})))}commitActive(e,t=this.operationGeneration){this.isCurrentGeneration(t)&&this.isManagedCall(e)&&e.state===`active`&&this.activeCallId!==e.id&&(this.activeCallId=e.id,this.events.emit(`call.activeChanged`,{callId:e.id}))}handleIncoming(t){if(this.disposed)return;let n=m(),r=this.incomingSessionSnapshot;if(r===void 0||!r.policy.incomingEnabled||!this.effectiveCapabilities(r).has(`inbound`)){this.terminateUnsupportedIncoming(t),this.events.emit(`error`,{error:this.capabilityError(n)});return}let i=t.from??t.id;if(this.calls.size+this.pendingDialCount>=this.callLimit(r)){this.terminateUnsupportedIncoming(t),this.events.emit(`error`,{error:new e.i(`CALL_ALREADY_EXISTS`,`call`,!1,{callId:n})});return}let a;try{a=new u({id:n,destination:i,platform:this.options.platform,incoming:!0,capabilities:this.effectiveCapabilities(r),session:t,onStateChanged:(e,t)=>this.handleStateChanged(a,e,t),onError:e=>this.events.emit(`error`,{error:e}),onDisposed:()=>this.handleDisposed(a)})}catch(e){this.events.emit(`error`,{error:this.callOperationError(n,e)});return}this.calls.set(a.id,a),this.callSessions.set(a.id,t),this.options.onCallCreated?.(a.id,t);try{a.beginIncoming(),this.events.emit(`call.incoming`,{callId:a.id,from:i})}catch(e){a.dispose(),this.events.emit(`error`,{error:this.callOperationError(a.id,e)})}}terminateUnsupportedIncoming(e){try{e.terminate()}catch{}}async holdActiveCallForNewCall(){if(this.options.autoHoldPreviousCall!==!0)return;let e=this.getActiveCall();if(e!==void 0&&e.state===`active`)return await e.hold(),e}enqueueActiveOperation(e){let t=this.operationGeneration,n=()=>this.isCurrentGeneration(t)?e(t):Promise.reject(this.callOperationError(``)),r=this.activeOperationPromise.then(n,n);return this.activeOperationPromise=r.catch(()=>void 0),r}isManagedCall(e){return!this.disposed&&this.calls.get(e.id)===e&&e.state!==`ended`&&e.state!==`failed`}isCurrentGeneration(e){return!this.disposed&&this.operationGeneration===e}assertGeneration(e,t){if(!this.isCurrentGeneration(e))throw this.callOperationError(t??``)}effectiveCapabilities(e){let t=new Set(e.capabilities);return this.options.platform===`mobile-web`&&(t.delete(`hold`),t.delete(`blind_transfer`),e.policy.mobileIncomingEnabled!==!0&&t.delete(`inbound`)),t}requireCapability(e,t,n){if(!this.effectiveCapabilities(e).has(t))throw this.capabilityError(n)}requireCall(e){let t=this.calls.get(e);if(t===void 0)throw this.callOperationError(e);return t}emitOwnershipChanged(e){this.events.emit(`call.ownershipChanged`,e)}notifyCallTerminal(e){let t=this.terminalOperations.get(e);if(t!==void 0)return t;if(this.terminalNotified.has(e))return Promise.resolve();this.terminalNotified.add(e);let n;try{n=this.options.onCallTerminal?.(e)}catch(t){this.events.emit(`error`,{error:this.callOperationError(e,t)});let n=Promise.reject(this.callOperationError(e,t));return this.terminalOperations.set(e,n),n.catch(()=>void 0).finally(()=>this.pruneTerminalRecord(e,n)),n}let r=Promise.resolve(n).catch(t=>{throw this.events.emit(`error`,{error:this.callOperationError(e,t)}),t});return this.terminalOperations.set(e,r),r.catch(()=>void 0).finally(()=>this.pruneTerminalRecord(e,r)),r}pruneTerminalRecord(e,t){this.terminalOperations.get(e)===t&&this.terminalOperations.delete(e),this.calls.has(e)||this.terminalNotified.delete(e)}assertNotDisposed(){if(this.disposed)throw new e.i(`SDK_ALREADY_DISPOSED`,`internal`,!1)}callOperationError(t,n){return new e.i(`CALL_OPERATION_NOT_ALLOWED`,`call`,!1,{callId:t,cause:n})}capabilityError(t){return new e.i(`CAPABILITY_NOT_SUPPORTED`,`capability`,!1,{callId:t})}compensationError(e,t,n,r){return this.callOperationError(e,{operation:n,rollback:r,originalCallId:e,targetCallId:t})}callLimit(e){let t=this.options.platform===`mobile-web`?1:2,n=this.options.maxConcurrentCalls??t;return Math.min(t,Math.max(1,n),Math.max(1,e.policy.maxConcurrentCalls))}dialOptions(e,t,n,r=[]){return{iceServers:t.iceServers,extraHeaders:[`X-XCall-Call-ID: ${e}`,`X-XCall-Session-ID: ${t.sessionId}`,...r],...n===void 0?{}:{type:n}}}dialError(t,n){return t instanceof e.i?new e.i(t.code,t.category,t.retryable,{requestId:t.requestId,callId:n,cause:t.cause??t,serverCode:t.serverCode,platformCode:t.platformCode,status:t.status}):new e.i(`CALL_OPERATION_NOT_ALLOWED`,`call`,!1,{callId:n,cause:t})}},g=class{handlers=new Map;on(e,t){let n=this.handlers.get(e)??new Set,r=t;n.add(r),this.handlers.set(e,n);let i=!0;return()=>{i&&(i=!1,n.delete(r))}}emit(e,t){let n=this.handlers.get(e);n!==void 0&&[...n].forEach(e=>{try{e(t)}catch{}})}listenerCount(){return[...this.handlers.values()].reduce((e,t)=>e+t.size,0)}clear(){this.handlers.clear()}};function _(e){if(typeof e!=`object`||!e||!(`reason`in e))return`ended`;let t=e.reason;return typeof t==`string`&&t!==``?t:`ended`}function v(t,n){if(t instanceof e.i)return new e.i(t.code,t.category,t.retryable,{requestId:t.requestId,callId:n,cause:t.cause??t,serverCode:t.serverCode,platformCode:t.platformCode,status:t.status});if(typeof t==`object`&&t&&`error`in t){let r=t.error;if(r instanceof e.i)return new e.i(r.code,r.category,r.retryable,{requestId:r.requestId,callId:n,cause:r.cause??r,serverCode:r.serverCode,platformCode:r.platformCode,status:r.status});if(r instanceof Error)return new e.i(`CALL_OPERATION_NOT_ALLOWED`,`call`,!1,{callId:n,cause:r})}return new e.i(`CALL_OPERATION_NOT_ALLOWED`,`call`,!1,{callId:n,cause:t})}var ie=`q7X4p6MvK1z8Lb3A`,ae=`W9e2T4mN0aQ7Ru6C`,oe=16,se=`�`;function ce(e){for(let t of e){let e=t.codePointAt(0)??0;if(e===127||e<32&&e!==9)return!0}return!1}async function y(t,n={}){let r=String(t??``).replace(/\s+/g,``);if(!r)throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,!1,{cause:`解密的密文为空:坐席账号里没有 password/registerPassword`});let i=n.subtle??globalThis.crypto?.subtle;if(i===void 0)throw new e.i(`CONFIG_INVALID`,`configuration`,!1,{cause:`需要 WebCrypto 才能解 SIP 密码:请在安全上下文(https / localhost)或 Node 18+ 里运行`});let a=b(r);if(a===void 0)throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,!1,{cause:`密文不是合法的 Base64:确认取的是 password/registerPassword 原值,没有被截断或转义`});let o=await i.importKey(`raw`,x(n.key??ie),`AES-CBC`,!1,[`decrypt`]);try{let e=await i.decrypt({name:`AES-CBC`,iv:x(n.iv??ae)},o,a);return new TextDecoder(`utf-8`).decode(e).trim()}catch(t){throw new e.i(`LEGACY_PLATFORM_REJECTED`,`auth`,!1,{cause:`SIP 密码解密失败(检查 key/iv 与该环境是否一致):${t instanceof Error?t.message:String(t)}`})}}async function le(e,t={}){let n=String(e??``).replace(/\s+/g,``);if(ue(n))try{let e=await y(n,t);return de(e)?e:void 0}catch{return}}function ue(e){let t=b(e);return t!==void 0&&t.byteLength>0&&t.byteLength%oe===0}function de(e){return e.length===0||e.includes(se)?!1:!ce(e)}function b(e){if(e.length!==0&&e.length%4==0&&/^[A-Za-z0-9+/]+={0,2}$/.test(e))try{let t=atob(e),n=new Uint8Array(new ArrayBuffer(t.length));for(let e=0;e<t.length;e+=1)n[e]=t.charCodeAt(e);return n}catch{return}}function x(e){let t=new TextEncoder().encode(e),n=new Uint8Array(new ArrayBuffer(t.byteLength));return n.set(t),n}var fe=class{port;timeoutMs;pending=new Map;eventHandlers=new Set;closed=!1;lifecycleState=`connected`;constructor(e,t={}){this.port=e,this.timeoutMs=t.timeoutMs??15e3,this.port.onmessage=e=>this.handleMessage(e.data),this.port.start()}request(t){return this.closed?Promise.reject(new e.i(`SDK_ALREADY_DISPOSED`,`internal`,!1)):this.pending.has(t.requestId)?Promise.reject(new e.i(`SDK_INTERNAL_ERROR`,`internal`,!1,{requestId:t.requestId})):this.lifecycleState===`reconnecting`&&t.type===`command`&&(t.command===`dial`||t.command===`answer`)?Promise.reject(new e.i(`CALL_OPERATION_NOT_ALLOWED`,`call`,!0,{callId:t.payload?.callId})):new Promise((n,r)=>{let i=setTimeout(()=>{this.pending.delete(t.requestId),r(new e.i(`NETWORK_TIMEOUT`,`network`,!0,{requestId:t.requestId}))},this.timeoutMs);this.pending.set(t.requestId,{resolve:e=>n(e),reject:r,timer:i}),this.port.postMessage(t)})}onEvent(e){return this.closed?()=>void 0:(this.eventHandlers.add(e),()=>this.eventHandlers.delete(e))}getLifecycleState(){return this.lifecycleState}close(){this.closed||(this.closed=!0,this.pending.forEach(t=>{clearTimeout(t.timer),t.reject(new e.i(`SDK_ALREADY_DISPOSED`,`internal`,!1))}),this.pending.clear(),this.eventHandlers.clear(),this.port.close())}handleMessage(t){try{let n=e.t(t);if(n.type===`event`){n.event===`connection.stateChanged`&&pe(n.payload)&&(this.lifecycleState=n.payload.state),this.eventHandlers.forEach(e=>e(n));return}if(n.type!==`response`)return;let r=this.pending.get(n.requestId);if(r===void 0)return;this.pending.delete(n.requestId),clearTimeout(r.timer),n.ok?r.resolve(n.result):r.reject(me(n))}catch(e){this.pending.forEach(t=>{clearTimeout(t.timer),t.reject(e)}),this.pending.clear()}}};function pe(e){return typeof e==`object`&&!!e&&`state`in e&&(e.state===`connected`||e.state===`reconnecting`)}function me(t){let n=t.error;return new e.i(n?.code??`SDK_INTERNAL_ERROR`,n?.category??`internal`,n?.retryable??!1,{requestId:t.requestId,...n?.message===void 0?{}:{cause:n.message},...n?.serverCode===void 0?{}:{serverCode:n.serverCode},...n?.platformCode===void 0?{}:{platformCode:n.platformCode},...n?.status===void 0?{}:{status:n.status}})}function S(t={}){if((t.enabled??`auto`)===!1)return{mode:`single-tab`,reason:`disabled`};let n=t.locationHref??w(),r=C(t.url,n),i=n=>{if(t.fallback===`error`)throw new e.i(`CONFIG_INVALID`,`configuration`,!1,{cause:n});return{mode:`single-tab`,reason:n}};if(r===void 0)return i(`SharedWorker URL is unavailable`);if(!E(r,n))return i(`SharedWorker URL must be same-origin`);let a=t.workerCtor??T();if(a===void 0)return i(`SharedWorker is not supported`);let o;try{o=new a(r,t.name===void 0?void 0:{name:t.name})}catch(e){return i(`SharedWorker construction failed: ${e instanceof Error?e.message:String(e)}`)}let s=t.tabId??D(),c=new fe(o.port),l={version:1,type:`attach`,requestId:O(),tabId:s},u=c.request(l).then(()=>void 0).catch(e=>{throw c.close(),e});return{mode:`shared`,worker:o,client:c,tabId:s,workerUrl:r,ready:u}}function C(e,t=w()){try{return t===void 0?void 0:new URL(e??`./shared-worker.js`,t).toString()}catch{return}}function w(){return typeof location>`u`?void 0:location.href}function T(){if(typeof SharedWorker==`function`)return SharedWorker}function E(e,t){if(t===void 0)return!0;try{return new URL(e,t).origin===new URL(t).origin}catch{return!1}}function D(){return`tab-${typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID():Math.random().toString(36).slice(2)}`}function O(){return`attach-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}var k=class{mediaDevices;createAudioElement;outputCapability;outputDeviceId;outputGeneration=0;outputTail;constructor(e={}){this.mediaDevices=e.mediaDevices===null?void 0:e.mediaDevices??A(),this.createAudioElement=e.createAudioElement}async requestPermission(e={}){let t=this.requireMediaDevices(),n;try{n=await t.getUserMedia({audio:e})}catch(e){throw N(e)}j(n)}async getDevices(){if(this.mediaDevices===void 0)return[];try{return(await this.mediaDevices.enumerateDevices()).filter(e=>e.kind===`audioinput`||e.kind===`audiooutput`&&this.supportsOutputSelection())}catch(e){throw P(e)}}getCapabilities(){return{input:this.mediaDevices!==void 0,output:this.supportsOutputSelection()}}supportsOutputSelection(){if(this.outputCapability!==void 0)return this.outputCapability;let e=this.createAudioElementSafely();return this.outputCapability=e!==void 0&&typeof e.setSinkId==`function`,this.outputCapability}async setOutputDevice(t,n){if(!this.supportsOutputSelection())throw new e.i(`CAPABILITY_NOT_SUPPORTED`,`capability`,!1);this.outputDeviceId=t;let r=++this.outputGeneration;n!==void 0&&await this.enqueueOutput(async()=>{r===this.outputGeneration&&await this.applyOutputDevice(t,n)})}async applyConfiguredOutputDevice(e){if(this.outputDeviceId===void 0||e===void 0)return;let t=this.outputDeviceId,n=this.outputGeneration;await this.enqueueOutput(async()=>{n===this.outputGeneration&&await this.applyOutputDevice(t,e)})}getOutputDeviceId(){return this.outputDeviceId}async applyOutputDevice(t,n){let r=n;if(typeof r.setSinkId!=`function`)throw new e.i(`CAPABILITY_NOT_SUPPORTED`,`capability`,!1);try{await r.setSinkId(t)}catch(e){throw F(e)}}enqueueOutput(e){let t=this.outputTail,n=t===void 0?e():t.then(e,e),r=n.catch(()=>void 0);return this.outputTail=r,r.then(()=>{this.outputTail===r&&(this.outputTail=void 0)}),n}async openInputStream(e){let t=this.requireMediaDevices();try{return await t.getUserMedia({audio:{deviceId:{exact:e}}})}catch(e){throw M(e)}}requireMediaDevices(){if(this.mediaDevices===void 0)throw new e.i(`CAPABILITY_NOT_SUPPORTED`,`capability`,!1);return this.mediaDevices}createAudioElementSafely(){if(this.createAudioElement!==void 0)try{return this.createAudioElement()}catch{return}if(typeof document<`u`)try{return document.createElement(`audio`)}catch{return}}};function A(){return globalThis.navigator?.mediaDevices}function j(e){let t;try{t=e.getTracks()}catch{return}t.forEach(e=>{try{e.stop()}catch{}})}function M(t){let n=I(t);return n===`NotFoundError`||n===`OverconstrainedError`?new e.i(`MEDIA_DEVICE_NOT_FOUND`,`media`,!1,{cause:t}):n===`NotReadableError`||n===`AbortError`?new e.i(`MEDIA_DEVICE_IN_USE`,`media`,!0,{cause:t}):n===`NotAllowedError`||n===`SecurityError`?new e.i(`MEDIA_PERMISSION_DENIED`,`media`,!1,{cause:t}):new e.i(`SDK_INTERNAL_ERROR`,`internal`,!1,{cause:t})}function N(t){let n=I(t);return n===`NotFoundError`||n===`OverconstrainedError`?new e.i(`MEDIA_DEVICE_NOT_FOUND`,`media`,!1,{cause:t}):n===`NotReadableError`||n===`AbortError`?new e.i(`MEDIA_DEVICE_IN_USE`,`media`,!0,{cause:t}):n===`NotAllowedError`||n===`SecurityError`?new e.i(`MEDIA_PERMISSION_DENIED`,`media`,!1,{cause:t}):new e.i(`SDK_INTERNAL_ERROR`,`internal`,!1,{cause:t})}function P(t){let n=I(t);return n===`NotFoundError`?new e.i(`MEDIA_DEVICE_NOT_FOUND`,`media`,!1,{cause:t}):n===`NotAllowedError`||n===`SecurityError`?new e.i(`MEDIA_PERMISSION_DENIED`,`media`,!1,{cause:t}):n===`AbortError`||n===`NotReadableError`?new e.i(`MEDIA_DEVICE_IN_USE`,`media`,!0,{cause:t}):new e.i(`SDK_INTERNAL_ERROR`,`internal`,!1,{cause:t})}function F(t){let n=I(t);return n===`NotFoundError`?new e.i(`MEDIA_DEVICE_NOT_FOUND`,`media`,!1,{cause:t}):n===`NotAllowedError`||n===`SecurityError`?new e.i(`MEDIA_PERMISSION_DENIED`,`media`,!1,{cause:t}):n===`AbortError`||n===`NotReadableError`?new e.i(`MEDIA_DEVICE_IN_USE`,`media`,!0,{cause:t}):new e.i(`SDK_INTERNAL_ERROR`,`internal`,!1,{cause:t})}function I(e){if(typeof e!=`object`||!e||!(`name`in e))return;let t=e.name;return typeof t==`string`?t:void 0}var L=class{createAudioElement;bindings=new Map;audioOwners=new Map;trackOwners=new Map;generations=new Map;pendingPlays=new Map;constructor(e=R){this.createAudioElement=e}async bind(t,n){let r=this.bindings.get(t);if(r?.stream===n)return;let i=z(t,n),a;try{a=this.createAudioElement()}catch(n){throw B(i,this.trackOwners),new e.i(`CAPABILITY_NOT_SUPPORTED`,`capability`,!1,{callId:t,cause:n})}let o=this.audioOwners.get(a);if(o!==void 0&&o!==t)throw B(i,this.trackOwners),new e.i(`CALL_OPERATION_NOT_ALLOWED`,`call`,!1,{callId:t});try{a.autoplay=!0,a.playsInline=!0}catch(n){throw B(i,this.trackOwners),new e.i(`SDK_INTERNAL_ERROR`,`internal`,!1,{callId:t,cause:n})}try{a.srcObject=n}catch(n){throw B(i,this.trackOwners),new e.i(`SDK_INTERNAL_ERROR`,`internal`,!1,{callId:t,cause:n})}this.acquireTracks(i),r!==void 0&&this.releaseBinding(r,r.audio!==a);let s=this.nextGeneration(t);this.audioOwners.set(a,t);let c={callId:t,audio:a,stream:n,tracks:i,generation:s};this.bindings.set(t,c),this.beginPlay(t);try{await a.play()}catch(n){if(!this.isCurrent(t,s))return;throw new e.i(`MEDIA_PLAYBACK_BLOCKED`,`media`,!1,{callId:t,cause:n})}finally{this.finishPlay(t)}this.isCurrent(t,s)}async play(t){let n=this.bindings.get(t);if(n===void 0)throw new e.i(`CALL_OPERATION_NOT_ALLOWED`,`call`,!1,{callId:t});let r=n.generation;this.beginPlay(t);try{await n.audio.play()}catch(n){if(!this.isCurrent(t,r))return;throw new e.i(`MEDIA_PLAYBACK_BLOCKED`,`media`,!1,{callId:t,cause:n})}finally{this.finishPlay(t)}this.isCurrent(t,r)}getAudioElement(e){return this.bindings.get(e)?.audio}getResourceCounts(){return{tracks:this.trackOwners.size,audioElements:this.audioOwners.size}}release(e){this.nextGeneration(e);let t=this.bindings.get(e);t!==void 0&&this.releaseBinding(t),this.cleanupGeneration(e)}releaseAll(){[...this.bindings.keys()].forEach(e=>this.release(e))}releaseBinding(e,t=!0){if(this.bindings.get(e.callId)===e&&this.bindings.delete(e.callId),this.audioOwners.get(e.audio)===e.callId&&this.audioOwners.delete(e.audio),t)try{e.audio.srcObject=null}catch{}e.tracks.forEach(e=>this.releaseTrack(e))}acquireTracks(e){e.forEach(e=>this.trackOwners.set(e,(this.trackOwners.get(e)??0)+1))}releaseTrack(e){let t=this.trackOwners.get(e);if(t===void 0||t<=1){this.trackOwners.delete(e),V(e);return}this.trackOwners.set(e,t-1)}beginPlay(e){this.pendingPlays.set(e,(this.pendingPlays.get(e)??0)+1)}finishPlay(e){let t=this.pendingPlays.get(e)??0;t<=1?this.pendingPlays.delete(e):this.pendingPlays.set(e,t-1),this.cleanupGeneration(e)}nextGeneration(e){let t=(this.generations.get(e)??0)+1;return this.generations.set(e,t),t}cleanupGeneration(e){!this.bindings.has(e)&&!this.pendingPlays.has(e)&&this.generations.delete(e)}isCurrent(e,t){return this.generations.get(e)===t&&this.bindings.get(e)?.generation===t}};function R(){if(typeof document>`u`)throw new e.i(`CAPABILITY_NOT_SUPPORTED`,`capability`,!1);return document.createElement(`audio`)}function z(t,n){try{return[...new Set(n.getAudioTracks())].filter(e=>e.kind===`audio`)}catch(r){try{return[...new Set(n.getTracks())].filter(e=>e.kind===`audio`)}catch(i){throw he(n),new e.i(`SDK_INTERNAL_ERROR`,`internal`,!1,{callId:t,cause:r??i})}}}function B(e,t){e.forEach(e=>{(t.get(e)??0)===0&&V(e)})}function he(e){try{[...new Set(e.getTracks())].filter(e=>e.kind===`audio`).forEach(V)}catch{}}function V(e){try{e.stop()}catch{}}var ge=class{deviceManager;remoteAudio;getActiveCall;createRemoteStream;calls=new Map;resources=new Set;inputOperations=new Map;senderQueues=new Map;releaseOperations=new Map;callReleaseOperations=new Map;releaseErrors=new WeakMap;releaseAllOperation;disposeOperation;disposing=!1;disposed=!1;constructor(e={}){let t={mediaDevices:e.mediaDevices,createAudioElement:e.createAudioElement};this.deviceManager=new k(t),this.remoteAudio=new L(e.createAudioElement),this.getActiveCall=e.getActiveCall,this.createRemoteStream=e.createRemoteStream??ye}requestPermission(e){return this.assertNotDisposed(),this.deviceManager.requestPermission(e)}getDevices(){return this.assertNotDisposed(),this.deviceManager.getDevices()}getCapabilities(){return this.assertNotDisposed(),this.deviceManager.getCapabilities()}supportsOutputSelection(){return this.assertNotDisposed(),this.deviceManager.supportsOutputSelection()}registerCallMedia(e,t){this.assertNotDisposed();let n=this.calls.get(e);n!==void 0&&this.releaseResource(n).catch(e=>{this.releaseErrors.set(n,e)});let r=_e(t)?t:{peerConnection:t},i={callId:e,peerConnection:r.peerConnection,senders:new Map,localTracks:new Set,pendingTracks:new Set,generation:1,released:!1,peerClosed:!1};if(this.captureSenders(i,r.getSenderKind),this.resources.add(i),r.localTracks?.forEach(e=>{e.kind===`audio`&&i.localTracks.add(e)}),this.calls.set(e,i),r.trackSource!==void 0)try{i.trackSourceUnsubscribe=r.trackSource.onTrack(e=>this.handleTrackEvent(i,e))}catch{}return async()=>{let e=this.releaseOperations.get(i);if(e!==void 0)await e;else if(this.releaseErrors.has(i))throw this.releaseErrors.get(i);else await this.releaseResource(i);let t=this.releaseErrors.get(i);if(t!==void 0)throw t}}async setInputDevice(e,t){this.assertNotDisposed();let n=t??this.getActiveCall?.();this.assertActiveCall(n),this.assertDeviceSelectionCapability(n);let r=this.ensureCallMedia(n),i=(this.inputOperations.get(n.callId)??Promise.resolve()).then(()=>this.performInputSwitch(e,n,r),()=>this.performInputSwitch(e,n,r));this.inputOperations.set(n.callId,i);try{await i}finally{this.inputOperations.get(n.callId)===i&&this.inputOperations.delete(n.callId)}}setOutputDevice(e,t){this.assertNotDisposed();let n=t??this.getActiveCall?.()?.callId,r=n===void 0?void 0:this.remoteAudio.getAudioElement(n);return this.deviceManager.setOutputDevice(e,r)}async bindRemoteTrack(e,t){this.assertNotDisposed();let n;try{await this.remoteAudio.bind(e,t)}catch(e){n=e}let r;try{await this.deviceManager.applyConfiguredOutputDevice(this.remoteAudio.getAudioElement(e))}catch(e){r=e}if(n!==void 0)throw n;if(r!==void 0)throw r}playRemoteAudio(e){return this.assertNotDisposed(),this.remoteAudio.play(e)}getResourceCounts(){let e=new Set;this.resources.forEach(t=>{t.localTracks.forEach(t=>e.add(t)),t.pendingTracks.forEach(t=>e.add(t))});let t=this.remoteAudio.getResourceCounts();return{listeners:[...this.resources].filter(e=>e.trackSourceUnsubscribe!==void 0).length,tracks:e.size+t.tracks,peerConnections:this.resources.size,audioElements:t.audioElements}}releaseResource(t){let n=this.releaseOperations.get(t);if(n!==void 0)return n;if(!this.resources.has(t))return Promise.resolve();let r=t.callId;this.remoteAudio.release(r),this.releaseErrors.delete(t),this.calls.get(r)===t&&this.calls.delete(r),t.generation+=1,t.released=!0,this.unsubscribeTrackSource(t);let i=new Set([...t.localTracks,...t.pendingTracks]),a=[...t.senders.values()].filter(e=>e.audio).map(e=>({senderResource:e,promise:this.enqueueSender(t,e,()=>W(e.sender),!0)})),o=Promise.all(a.map(async e=>{try{return await e.promise,{senderResource:e.senderResource,cause:void 0}}catch(t){return{senderResource:e.senderResource,cause:t}}})).then(async n=>{let a=new Set,o=[];if(n.forEach(e=>{if(e.cause!==void 0){o.push(e.cause);let t=H(e.senderResource.sender);t?.kind===`audio`&&a.add(t);return}let t=H(e.senderResource.sender);t?.kind===`audio`&&i.add(t)}),i.forEach(e=>{a.has(e)||K(e)}),o.length>0)throw t.localTracks.clear(),t.pendingTracks.clear(),a.forEach(e=>t.localTracks.add(e)),new e.i(`SDK_INTERNAL_ERROR`,`internal`,!0,{callId:r,cause:o[0]});if(!t.peerClosed&&t.peerConnection.close!==void 0)try{await t.peerConnection.close(),t.peerClosed=!0}catch(n){let i=[...t.senders.values()].map(e=>H(e.sender)).find(e=>e?.kind===`audio`);throw t.localTracks.clear(),t.pendingTracks.clear(),i!=null&&t.localTracks.add(i),new e.i(`SDK_INTERNAL_ERROR`,`internal`,!0,{callId:r,cause:n})}t.localTracks.clear(),t.pendingTracks.clear(),t.senders.clear(),this.resources.delete(t),this.releaseUnusedSenderQueues()}).catch(e=>{throw this.releaseErrors.set(t,e),this.calls.get(r)===void 0&&this.calls.set(r,t),e}).finally(()=>{this.releaseOperations.get(t)===o&&this.releaseOperations.delete(t)});return this.releaseOperations.set(t,o),o}releaseCall(e){let t=this.callReleaseOperations.get(e);if(t!==void 0)return t;let n=[...this.resources].filter(t=>t.callId===e);if(n.length===0)return Promise.resolve();let r=Promise.all(n.map(async e=>{try{return await this.releaseResource(e),{cause:void 0}}catch(e){return{cause:e}}})).then(e=>{let t=e.find(e=>e.cause!==void 0)?.cause;if(t!==void 0)throw t}).finally(()=>{this.callReleaseOperations.get(e)===r&&this.callReleaseOperations.delete(e)});return this.callReleaseOperations.set(e,r),r}releaseAll(){if(this.releaseAllOperation!==void 0)return this.releaseAllOperation;this.remoteAudio.releaseAll();let e=new Set([...this.resources].map(e=>e.callId)),t=Promise.all([...e].map(async e=>{try{return await this.releaseCall(e),{cause:void 0}}catch(e){return{cause:e}}})).then(e=>{let t=e.find(e=>e.cause!==void 0)?.cause;if(t!==void 0)throw t}).finally(()=>{this.releaseAllOperation===t&&(this.releaseAllOperation=void 0)});return this.releaseAllOperation=t,t}dispose(){if(this.disposeOperation!==void 0)return this.disposeOperation;this.disposing=!0;let e=this.releaseAll(),t=this.waitForInputOperations(),n=Promise.allSettled([e,t]).then(e=>{let t=e.find(e=>e.status===`rejected`);if(t?.status===`rejected`)throw t.reason;this.inputOperations.clear(),this.disposed=!0,this.disposing=!1}).finally(()=>{this.disposeOperation===n&&!this.disposed&&(this.disposeOperation=void 0),!this.disposed&&this.disposeOperation===void 0&&(this.disposing=!1)});return this.disposeOperation=n,n}async waitForInputOperations(){let e=[...this.inputOperations.values()];e.length!==0&&await Promise.allSettled(e)}async performInputSwitch(t,n,r){if(this.assertActiveCall(n),this.assertDeviceSelectionCapability(n),!this.isCurrentResource(r)||n.peerConnection!==r.peerConnection)throw this.callOperationError(n.callId);let i=this.findAudioSender(r),a=H(i.sender),o=r.generation,s=await this.deviceManager.openInputStream(t),c;try{c=s.getTracks()}catch(t){throw ve(s),new e.i(`SDK_INTERNAL_ERROR`,`internal`,!1,{callId:n.callId,cause:t})}let l;try{l=s.getAudioTracks()}catch(t){throw G(c),new e.i(`SDK_INTERNAL_ERROR`,`internal`,!1,{callId:n.callId,cause:t})}let u=l[0];if(u===void 0)throw G(c),new e.i(`MEDIA_DEVICE_NOT_FOUND`,`media`,!1,{callId:n.callId});if(!this.canCommitInputSwitch(n,r,i,a,o))throw G(c),this.callOperationError(n.callId);c.forEach(e=>r.pendingTracks.add(e)),r.pendingTracks.add(u);try{await this.enqueueSender(r,i,()=>i.sender.replaceTrack(u))}catch(t){throw r.released?this.callOperationError(n.callId):(r.released||(c.forEach(e=>r.pendingTracks.delete(e)),r.pendingTracks.delete(u),await this.rollbackSender(r,i,a,u),G(c)),new e.i(`MEDIA_DEVICE_IN_USE`,`media`,!0,{callId:n.callId,cause:t}))}if(!this.canCommitInputSwitch(n,r,i,u,o)){if(!r.released)try{await this.enqueueSender(r,i,()=>H(i.sender)===u?W(i.sender):Promise.resolve()),c.forEach(e=>r.pendingTracks.delete(e)),r.pendingTracks.delete(u),G(c)}catch(t){throw new e.i(`SDK_INTERNAL_ERROR`,`internal`,!0,{callId:n.callId,cause:t})}throw this.callOperationError(n.callId)}c.forEach(e=>r.pendingTracks.delete(e)),r.pendingTracks.delete(u),r.localTracks.add(u),a!==null&&a!==u&&(r.localTracks.delete(a),K(a)),c.forEach(e=>{e!==u&&K(e)})}ensureCallMedia(e){let t=this.calls.get(e.callId);if(t!==void 0&&t.peerConnection===e.peerConnection)return t;if(e.peerConnection===void 0)throw this.capabilityError(e.callId);this.registerCallMedia(e.callId,e.peerConnection);let n=this.calls.get(e.callId);if(n===void 0)throw this.callOperationError(e.callId);return n}captureSenders(t,n){let r;try{r=t.peerConnection.getSenders()}catch(n){throw new e.i(`SDK_INTERNAL_ERROR`,`internal`,!1,{callId:t.callId,cause:n})}r.forEach(r=>{let i=H(r),a;try{a=n?.(r)??r.senderKind??r.kind}catch(n){throw new e.i(`SDK_INTERNAL_ERROR`,`internal`,!1,{callId:t.callId,cause:n})}t.senders.set(r,{sender:r,audio:a===`audio`||a===void 0&&i?.kind===`audio`,queue:this.senderQueues.get(r)??this.createSenderQueue(r)}),i?.kind===`audio`&&t.localTracks.add(i)})}findAudioSender(e){let t=[...e.senders.values()].find(e=>e.audio&&(H(e.sender)?.kind===`audio`||H(e.sender)===null));if(t===void 0)throw this.capabilityError(e.callId);return t}handleTrackEvent(e,t){if(!this.isCurrentResource(e)||t.track.kind!==`audio`)return;let n=t.streams[0]??this.createRemoteStream(t.track);n!==void 0&&this.bindRemoteTrack(e.callId,n).catch(()=>void 0)}canCommitInputSwitch(e,t,n,r,i){if(this.disposed||!this.isCurrentResource(t,i)||e.state!==`active`||e.peerConnection!==t.peerConnection||!t.senders.has(n.sender))return!1;try{if(!t.peerConnection.getSenders().includes(n.sender))return!1}catch{return!1}return H(n.sender)===r}enqueueSender(e,t,n,r=!1){t.queue.pending+=1;let i=t.queue.chain.then(async()=>{if(e.released&&!r)throw this.callOperationError(e.callId);return n()},async()=>{if(e.released&&!r)throw this.callOperationError(e.callId);return n()}),a=i.finally(()=>{--t.queue.pending});return t.queue.chain=a.catch(()=>void 0),i}createSenderQueue(e){let t={chain:Promise.resolve(),pending:0};return this.senderQueues.set(e,t),t}releaseUnusedSenderQueues(){let e=new Set;this.resources.forEach(t=>t.senders.forEach(t=>e.add(t.sender))),this.senderQueues.forEach((t,n)=>{t.pending===0&&!e.has(n)&&this.senderQueues.delete(n)})}async rollbackSender(e,t,n,r){e.released||H(t.sender)!==r||await this.enqueueSender(e,t,()=>t.sender.replaceTrack(n)).catch(()=>void 0)}isCurrentResource(e,t=e.generation){return!this.disposed&&this.calls.get(e.callId)===e&&e.generation===t}unsubscribeTrackSource(e){let t=e.trackSourceUnsubscribe;if(e.trackSourceUnsubscribe=void 0,t!==void 0)try{t()}catch{}}assertActiveCall(t){if(t===void 0||t.state!==`active`)throw new e.i(`CALL_OPERATION_NOT_ALLOWED`,`call`,!1,{callId:t?.callId})}assertDeviceSelectionCapability(e){if(e.capabilities===void 0||!e.capabilities.has(`device_selection`))throw this.capabilityError(e.callId)}capabilityError(t){return new e.i(`CAPABILITY_NOT_SUPPORTED`,`capability`,!1,{callId:t})}callOperationError(t){return new e.i(`CALL_OPERATION_NOT_ALLOWED`,`call`,!1,{callId:t})}assertNotDisposed(){if(this.disposed||this.disposing)throw new e.i(`SDK_ALREADY_DISPOSED`,`internal`,!1)}};function _e(e){return`peerConnection`in e}function H(e){try{return e.track}catch{return null}}function U(e){return typeof e==`object`&&!!e&&e.name===`InvalidStateError`}function W(e){try{return e.replaceTrack(null).catch(e=>{if(!U(e))throw e})}catch(e){return U(e)?Promise.resolve():Promise.reject(e)}}function ve(e){try{G(e.getTracks())}catch{}}function G(e){e.forEach(K)}function K(e){try{e.stop()}catch{}}function ye(e){if(typeof MediaStream<`u`)try{return new MediaStream([e])}catch{return}}function be(t,n={}){let r=new Map,i=new Map,a=new Set,o=n.ownershipRequired===!0,s=!1,c=!1,l,u=()=>t(),d=new ge({getActiveCall:u});return{publicMedia:{requestPermission:()=>(f(),d.requestPermission()),getDevices:()=>(f(),d.getDevices()),getCapabilities:()=>(f(),d.getCapabilities()),supportsOutputSelection:()=>(f(),d.supportsOutputSelection()),setInputDevice:e=>(f(),d.setInputDevice(e,u())),setOutputDevice:e=>(f(),d.setOutputDevice(e)),playRemoteAudio:e=>(f(),d.playRemoteAudio(e)),releaseAll:()=>(f(),d.releaseAll())},registerCall(e,t){s||c||!q(t)||(i.set(e,t),(!o||a.has(e))&&p(e,t))},async setCallOwnership(e,t){if(s)return;if(t!==`owned`){a.delete(e),await d.releaseCall(e),r.delete(e);return}a.add(e);let n=i.get(e);n!==void 0&&p(e,n)},contextFor(e,t,n){let i=r.get(e);if(i!==void 0)return{callId:e,state:t,capabilities:n,peerConnection:i.peerConnection}},async releaseCall(e){s||(await d.releaseCall(e),r.delete(e),i.delete(e),a.delete(e))},releaseAll:async()=>{await d.releaseAll(),r.clear(),i.clear(),a.clear()},getResourceCounts:()=>d.getResourceCounts(),dispose:()=>{if(l!==void 0)return l;c=!0;let e=d.dispose().then(()=>{s=!0,c=!1,r.clear(),i.clear(),a.clear()}).finally(()=>{l===e&&!s&&(l=void 0,c=!1)});return l=e,e}};function f(){if(s)throw new e.i(`SDK_ALREADY_DISPOSED`,`internal`,!1)}function p(e,t){if(!q(t)||typeof t.getMediaRegistration!=`function`)return;let n=t.getMediaRegistration();if(xe(n)&&r.get(e)?.peerConnection!==n.peerConnection){r.set(e,n);try{d.registerCallMedia(e,n)}catch{r.delete(e)}}}}function q(e){return typeof e==`object`&&!!e}function xe(e){return typeof e==`object`&&!!e&&`peerConnection`in e&&typeof e.peerConnection==`object`&&e.peerConnection!==null}var Se=1e3,Ce=3e4;function we(e,t=Math.random){let n=Math.min(Ce,Se*2**Math.max(0,Math.floor(e))),r=Math.min(1,Math.max(0,t()));return Math.round(n*(1+r*.2))}var Te=class{recover;isRecovered;random;isOnline;onAttempt;attempt=0;pendingTimer;running=!1;online=!0;generation=0;disposed=!1;restartAfterRun=!1;constructor(e){this.recover=e.recover,this.isRecovered=e.isRecovered,this.random=e.random??Math.random,this.isOnline=e.isOnline??(()=>!0),this.onAttempt=e.onAttempt}start(){if(this.disposed||!this.online||!this.isOnline()||this.pendingTimer!==void 0||this.running)return;let e=this.generation,t=we(this.attempt,this.random);this.pendingTimer=setTimeout(()=>{this.pendingTimer=void 0,this.run(e)},t)}notifyOffline(){this.disposed||(this.online=!1,this.generation+=1,this.clearPendingTimer(),this.restartAfterRun=!1)}notifyOnline(){this.disposed||(this.online=!0,this.running&&(this.restartAfterRun=!0),this.start())}cancel(){this.disposed||(this.generation+=1,this.clearPendingTimer(),this.attempt=0,this.restartAfterRun=!1)}dispose(){this.disposed||(this.disposed=!0,this.generation+=1,this.clearPendingTimer(),this.restartAfterRun=!1)}getTimerCount(){return this.pendingTimer===void 0?0:1}async run(e){if(this.disposed||!this.online||e!==this.generation||this.running)return;this.running=!0;try{this.onAttempt?.(this.attempt)}catch{}let t=!1;try{await this.recover(),this.isCurrent(e)&&(this.attempt=0)}catch{this.isCurrent(e)&&(this.attempt+=1,t=!0)}finally{this.running=!1}!t&&this.isCurrent(e)&&this.isRecovered!==void 0&&!this.isRecovered()&&(this.attempt+=1,t=!0),this.restartAfterRun?(this.restartAfterRun=!1,this.isCurrent(this.generation)&&this.start()):t&&this.isCurrent(e)&&this.start()}isCurrent(e){return!this.disposed&&this.online&&e===this.generation&&this.isOnline()}clearPendingTimer(){this.pendingTimer!==void 0&&(clearTimeout(this.pendingTimer),this.pendingTimer=void 0)}},Ee=12e4,De=5e3,Oe=class r{media;options;api;suppliedSip;sip;events=new n;mediaBridge;reconnect;diagnostics;callManager;session;state=`idle`;initialized=!1;disposed=!1;intentionalDisconnect=!1;deferredRebuild=!1;sessionRecoveryPending=!1;detectedPlatform;support;acceptingEvents=!0;connectOperation;disconnectOperation;refreshOperation;disposeOperation;refreshTimer;lifecycleGeneration=0;managerUnsubscribers=[];sipUnsubscribe;networkUnsubscribers=[];networkProbeTimer;stuckCallsSince;sessionDeleteOperations=new Map;deletedSessions=new Set;ownedSessionIds=new Set;terminalReleaseOperations=new Map;sharedWorkerSelection;constructor(n){if(this.options=n,n.api===void 0&&n.sessionProvider===void 0)throw new e.i(`CONFIG_INVALID`,`configuration`,!1,{cause:`CCBarClient 需要 sessionProvider`});this.api=n.api===void 0?J(X(n.sessionProvider)):J(n.api),this.suppliedSip=n.sip===void 0?void 0:je(n.sip),this.mediaBridge=be(()=>this.getActiveMediaContext()),this.media=this.mediaBridge.publicMedia,this.reconnect=new Te({recover:()=>this.recoverConnection(),isRecovered:()=>this.state===`connected`,onAttempt:e=>{this.disposed||this.events.emit(`connection.reconnecting`,{attempt:e})}}),this.diagnostics=new t.t({getSnapshot:()=>this.createDiagnosticsSnapshot(),getPermission:()=>this.readMicrophonePermission(),getDeviceNames:async()=>(await this.media.getDevices()).map(e=>e.label).filter(e=>e!==``)}),this.sharedWorkerSelection=n.sharedWorker===void 0?{mode:`single-tab`,reason:`disabled`}:S({...n.sharedWorker,...n.sharedWorkerHost??{}})}static async checkSupport(){let e=typeof navigator<`u`&&navigator.mediaDevices!==void 0,t=typeof WebSocket<`u`,n=Ae(typeof navigator<`u`?navigator.userAgent:``);return{supported:e&&t,platform:n,hasMediaDevices:e,hasWebSocket:t,...e&&t?{}:{reason:`当前运行环境缺少 WebPhone 所需的浏览器能力`}}}async initialize(){if(this.assertNotDisposed(),this.initialized)return;let e=await r.checkSupport();this.support=e,this.options.platform===void 0&&(e.platform===`web`||e.platform===`mobile-web`)&&(this.detectedPlatform=e.platform),await this.awaitSharedWorkerReady(),this.assertNotDisposed(),this.initialized=!0}connect(){if(this.assertNotDisposed(),this.connectOperation!==void 0)return this.connectOperation;if(this.state===`connected`)return Promise.resolve();this.api.invalidateToken?.();let e=this.lifecycleGeneration,t=this.performConnect(e).finally(()=>{this.connectOperation===t&&(this.connectOperation=void 0)});return this.connectOperation=t,t}disconnect(){if(this.assertNotDisposed(),this.disconnectOperation!==void 0)return this.disconnectOperation;if(this.state===`idle`&&this.connectOperation===void 0||this.state===`disconnected`&&this.connectOperation===void 0)return Promise.resolve();this.lifecycleGeneration+=1,this.acceptingEvents=!1;let e=this.performDisconnect().finally(()=>{this.disconnectOperation===e&&(this.disconnectOperation=void 0)});return this.disconnectOperation=e,e}dispose(){if(this.disposeOperation!==void 0)return this.disposeOperation;this.disposed=!0,this.lifecycleGeneration+=1,this.intentionalDisconnect=!0,this.acceptingEvents=!1,this.reconnect.dispose(),this.clearRefreshTimer(),this.detachNetworkListeners(),this.releaseSharedWorker(),this.state=`disconnected`,this.diagnostics.log(`info`,`connection.stateChanged`,{state:`disconnected`}),this.detachSipListener(),this.detachManagerListeners();let e=!1,t=this.performDispose().then(()=>{e=!0}).finally(()=>{this.disposeOperation===t&&!e&&(this.disposeOperation=void 0)});return this.disposeOperation=t,t}recover(){return this.assertNotDisposed(),this.recoverConnection()}dial(t){this.assertConnected();let n=this.callManager,r=this.session;if(n===void 0||r===void 0)throw new e.i(`CALL_NOT_CONNECTED`,`call`,!1);return n.dial(t,r)}answer(t,n){this.assertConnected();let r=this.callManager,i=this.session;if(r===void 0||i===void 0)throw new e.i(`CALL_NOT_CONNECTED`,`call`,!1);return r.answer(t,i,n)}setActiveCall(t){this.assertConnected();let n=this.callManager;if(n===void 0)throw new e.i(`CALL_NOT_CONNECTED`,`call`,!1);return n.setActiveCall(t)}getCalls(){return this.callManager?.getCalls()??[]}getActiveCall(){return this.callManager?.getActiveCall()}getAgent(){return this.session?.agent}getSharedWorkerState(){let e=this.sharedWorkerSelection;return e.mode===`shared`?{mode:`shared`,tabId:e.tabId}:{mode:`single-tab`,reason:e.reason}}getDiagnostics(e={}){return this.diagnostics.getReport(e)}async setAgentStatus(t){if(this.assertNotDisposed(),t!==`available`&&t!==`offline`&&t!==`break`)throw new e.i(`CONFIG_INVALID`,`configuration`,!1,{cause:`Unsupported agent status: ${String(t)}`});let n=this.session?.transport.wssUrl;await this.api.setAgentStatus({status:t,reason:``},n===void 0?void 0:{wssUrl:n}),this.disposed||this.events.emit(`agent.statusChanged`,{status:t})}on(e,t){return this.disposed?()=>void 0:this.events.on(e,t)}off(e,t){this.events.off(e,t)}async performConnect(e){let n,r,i;try{await this.initialize(),this.assertGeneration(e);let a=this.resolvePlatform();this.intentionalDisconnect=!1,this.acceptingEvents=!0,this.setConnectionState(`connecting`),n=await this.api.createSession({sdkVersion:t.r,platform:a===`mobile-web`?`mobile_web`:`web`,...this.options.locale===void 0?{}:{locale:this.options.locale},requestedCapabilities:[...this.options.requestedCapabilities??Fe(a)]}),this.ownedSessionIds.add(n.sessionId),this.assertGeneration(e),r=await this.getSip(),this.assertGeneration(e),this.session=n;let o=this.callManager??this.createCallManager(r,n,a);this.callManager===void 0&&(i=o),o.updateSession(n),this.callManager=o,this.attachSipListener(r),this.attachNetworkListeners(),await r.connect(n),this.assertGeneration(e),this.setConnectionState(`connected`),this.events.emit(`connection.registered`,{registered:!0}),this.scheduleRefresh(n)}catch(t){if(await this.rollbackConnect(n,r,i),this.disposed)throw this.disposedError();if(e!==this.lifecycleGeneration)throw t;let a=Z(t,`REGISTRATION_FAILED`,`registration`,!0);throw this.setConnectionState(`failed`),this.events.emit(`connection.failed`,{error:a}),a}}async performDisconnect(){let e,t=this.connectOperation;if(t!==void 0)try{await t}catch(t){$(t)||(e??=t)}let n=this.refreshOperation;if(n!==void 0)try{await n}catch(t){$(t)||(e??=t)}this.reconnect.cancel(),this.stuckCallsSince=void 0,this.clearRefreshTimer(),this.intentionalDisconnect=!0,this.detachNetworkListeners(),this.detachSipListener(),this.detachManagerListeners();let r=this.callManager,i=this.sip;this.callManager=void 0;try{await r?.dispose({terminateCalls:!0})}catch(t){e??=t}try{await this.awaitMediaReleaseBarriers()}catch(t){e??=t}try{i!==void 0&&await i.disconnect()}catch(t){e??=t}this.session=void 0;try{await this.deleteOwnedSessions()}catch(t){e??=t}if(this.pruneDeletedSessionTombstones(),this.disposed||(this.acceptingEvents=!0,this.setConnectionState(`disconnected`)),e!==void 0)throw e}createCallManager(e,t,n){let r=new h({sip:e,platform:n,session:t,maxConcurrentCalls:this.options.maxConcurrentCalls,autoHoldPreviousCall:this.options.autoHoldPreviousCall,onCallCreated:(e,t)=>this.handleCallCreated(e,t),onCallStateChanged:(e,t)=>this.handleCallStateChanged(e,t),onCallTerminal:e=>this.handleCallTerminal(e)});return this.bindManagerEvents(r),r}async rollbackConnect(e,t,n){if(n!==void 0){this.detachManagerListeners(),this.callManager===n&&(this.callManager=void 0);try{await n.dispose({terminateCalls:!0})}catch{}}if(t!==void 0){this.detachSipListener();try{await t.disconnect()}catch{}}if(this.session===e&&(this.session=void 0),e!==void 0)try{await this.deleteSession(e.sessionId)}catch{}}async performDispose(){let e,t=[this.connectOperation,this.disconnectOperation,this.refreshOperation].filter(e=>e!==void 0);for(let n of t)try{await n}catch(t){$(t)||(e??=t)}let n=this.callManager;this.callManager=void 0;try{await n?.dispose({terminateCalls:!0})}catch(t){e??=t}try{await this.awaitMediaReleaseBarriers()}catch(t){e??=t}try{await this.media.releaseAll()}catch(t){Me(t)||(e??=t)}try{await this.mediaBridge.dispose()}catch(t){e??=t}try{await this.sip?.dispose()}catch(t){e??=t}try{await this.deleteOwnedSessions()}catch(t){e??=t}if(this.pruneDeletedSessionTombstones(),this.session=void 0,this.sipUnsubscribe=void 0,this.events.clear(),e!==void 0)throw e}async awaitMediaReleaseBarriers(){let e;for(let[t,n]of[...this.terminalReleaseOperations])try{await this.withBarrierTimeout(n,t),this.terminalReleaseOperations.delete(t)}catch(n){try{await this.withBarrierTimeout(this.mediaBridge.releaseCall(t),t),this.terminalReleaseOperations.delete(t)}catch(t){e??=t??n}}if(e!==void 0)throw e}withBarrierTimeout(t,n,r=De){return new Promise((i,a)=>{let o=setTimeout(()=>{a(new e.i(`SDK_INTERNAL_ERROR`,`internal`,!0,{callId:n,cause:`media release barrier timeout`}))},Math.max(0,r));t.then(e=>{clearTimeout(o),i(e)},e=>{clearTimeout(o),a(e)})})}detachSipListener(){let e=this.sipUnsubscribe;this.sipUnsubscribe=void 0;try{e?.()}catch{}}detachManagerListeners(){this.managerUnsubscribers.splice(0).forEach(e=>{try{e()}catch{}})}bindManagerEvents(e){[`call.created`,`call.incoming`,`call.stateChanged`,`call.activeChanged`,`call.ended`,`call.failed`,`error`].forEach(t=>{let n=e.on(t,e=>{this.acceptingEvents&&!this.disposed&&(this.diagnostics.log(t===`error`||t===`call.failed`?`error`:`info`,String(t),e),this.events.emit(t,e))});this.managerUnsubscribers.push(n)})}handleCallCreated(e,t){this.acceptingEvents&&!this.disposed&&this.mediaBridge.registerCall(e,t)}handleCallStateChanged(e,t){this.acceptingEvents&&!this.disposed&&this.mediaBridge.registerCall(e,t)}handleCallTerminal(e){let t=this.startTerminalRelease(e);return this.deferredRebuild&&!this.hasNonTerminalCalls()&&this.startDeferredRecovery(),t}startTerminalRelease(e){let t=this.terminalReleaseOperations.get(e);if(t!==void 0)return t;let n=this.mediaBridge.releaseCall(e).then(()=>{this.terminalReleaseOperations.get(e)===n&&this.terminalReleaseOperations.delete(e)}).catch(t=>{throw this.acceptingEvents&&!this.disposed&&this.events.emit(`error`,{error:Z(t,`SDK_INTERNAL_ERROR`,`internal`,!0,e)}),t});return this.terminalReleaseOperations.set(e,n),n}async startDeferredRecovery(){try{if(await this.awaitMediaReleaseBarriers(),this.deferredRebuild&&!this.hasNonTerminalCalls()&&!this.disposed){if(this.sessionRecoveryPending){this.recoverInvalidSession();return}this.deferredRebuild=!1,this.clearRefreshTimer(),this.reconnect.start()}}catch{!this.disposed&&!this.sessionRecoveryPending&&this.reconnect.start()}}async refreshAndRebuild(){if(this.refreshOperation!==void 0)return this.refreshOperation;let e=this.performRefreshAndRebuild().finally(()=>{this.refreshOperation===e&&(this.refreshOperation=void 0),this.sessionRecoveryPending&&!this.hasNonTerminalCalls()&&!this.disposed&&this.recoverInvalidSession()});return this.refreshOperation=e,e}async performRefreshAndRebuild(){if(this.disposed||this.session===void 0)return;let e=this.lifecycleGeneration,t=this.session;try{let n=await this.api.refreshSession(t.sessionId);if(!this.isCurrentGeneration(e)||this.session!==t)return;if(this.session=n,this.callManager?.updateSession(n),this.events.emit(`token.refreshed`,{expiresAt:n.expiresAt}),this.hasNonTerminalCalls()){this.deferredRebuild=!0,this.scheduleRefresh(n);return}let r=await this.getSip();if(!this.isCurrentGeneration(e))return;await r.connect(n),this.isCurrentGeneration(e)&&(this.deferredRebuild=!1,this.setConnectionState(`connected`),this.scheduleRefresh(n))}catch(n){if(!this.isCurrentGeneration(e))return;throw this.handleRefreshFailure(t,n),n}}handleRefreshFailure(e,t){if(this.disposed)return;let n=Z(t,`NETWORK_OFFLINE`,`network`,!0);if(this.events.emit(`token.expiring`,{expiresAt:e.expiresAt}),this.events.emit(`error`,{error:n}),Q(t)){this.clearRefreshTimer(),this.reconnect.cancel(),this.deletedSessions.add(e.sessionId),this.sessionRecoveryPending=!0,this.deferredRebuild=!0,(n.code===`AUTH_TOKEN_UNAVAILABLE`||n.code===`AUTH_TOKEN_EXPIRED`||n.code===`AUTH_TOKEN_REJECTED`)&&this.api.invalidateToken?.();return}this.deferredRebuild=!0,this.hasNonTerminalCalls()||this.reconnect.start()}async recoverInvalidSession(){if(!(!this.sessionRecoveryPending||this.disposed||this.hasNonTerminalCalls())){this.sessionRecoveryPending=!1,this.deferredRebuild=!1;try{await this.performDisconnect()}catch(e){this.disposed||this.events.emit(`error`,{error:Z(e,`SDK_INTERNAL_ERROR`,`internal`,!0)});return}if(!this.disposed)try{await this.performConnect(this.lifecycleGeneration)}catch{this.disposed||this.reconnect.start()}}}scheduleRefresh(e){this.clearRefreshTimer();let t=e.expiresAt*1e3-Date.now()-6e4,n=Math.max(1e3,t);this.refreshTimer=setTimeout(()=>{this.refreshTimer=void 0,this.refreshAndRebuild().catch(()=>void 0)},n)}async recoverConnection(){if(!(this.disposed||this.intentionalDisconnect)){if(this.hasNonTerminalCalls()){let e=Date.now();if(this.stuckCallsSince===void 0&&(this.stuckCallsSince=e),e-this.stuckCallsSince<Ee)return;this.stuckCallsSince=void 0,await this.callManager?.forceTerminateCalls()}else this.stuckCallsSince=void 0;if(await this.awaitMediaReleaseBarriers(),this.session===void 0){await this.performConnect(this.lifecycleGeneration);return}await this.refreshAndRebuild()}}async getSip(){if(this.sip!==void 0)return this.sip;if(this.suppliedSip!==void 0)return this.sip=this.suppliedSip,this.sip;let[e,t]=await Promise.all([Promise.resolve().then(()=>require("./createJsSipFactory-B1ORbJiP.cjs")),Promise.resolve().then(()=>require("./JsSipAdapter-l97xq1ao.cjs"))]);return this.sip=new t.JsSipAdapter(e.createJsSipFactory(),this.options.baseUrl,this.options.sipKeepaliveSeconds,this.options.agentTerminal,this.options.sipSessionTimers??!1),this.sip}attachSipListener(e){this.sipUnsubscribe===void 0&&e.onConnectionStateChanged!==void 0&&(this.sipUnsubscribe=e.onConnectionStateChanged((e,t)=>{if(!(this.disposed||this.intentionalDisconnect||!this.acceptingEvents)){if(e===`registered`){this.setConnectionState(`connected`);return}this.state===`connected`&&(this.setConnectionState(`reconnecting`),this.reconnect.start(),t!==void 0&&this.events.emit(`error`,{error:Z(t,`SIP_WS_UNAVAILABLE`,`registration`,!0)}))}}))}attachNetworkListeners(){if(this.networkUnsubscribers.length>0||typeof window>`u`)return;let e=window,t=()=>{this.reconnect.notifyOnline(),this.scheduleIceReassessment()},n=()=>this.reconnect.notifyOffline(),r=()=>this.scheduleIceReassessment();e.addEventListener(`online`,t),e.addEventListener(`offline`,n);let i=(typeof navigator>`u`?void 0:navigator)?.connection;i?.addEventListener(`change`,r),this.networkUnsubscribers=[()=>e.removeEventListener(`online`,t),()=>e.removeEventListener(`offline`,n),...i===void 0?[]:[()=>i.removeEventListener(`change`,r)]]}scheduleIceReassessment(){this.networkProbeTimer!==void 0&&clearTimeout(this.networkProbeTimer),this.networkProbeTimer=setTimeout(()=>{this.networkProbeTimer=void 0,!this.disposed&&this.state===`connected`&&this.sip?.reassessIceServers?.(`network-online`)},2e3)}detachNetworkListeners(){this.networkProbeTimer!==void 0&&clearTimeout(this.networkProbeTimer),this.networkProbeTimer=void 0,this.networkUnsubscribers.splice(0).forEach(e=>e())}getActiveMediaContext(){let e=this.callManager?.getActiveCall();return e===void 0?void 0:this.mediaBridge.contextFor(e.id,e.state,new Set(this.session?.capabilities??[]))}hasNonTerminalCalls(){return this.callManager?.hasNonTerminalCalls()??!1}clearRefreshTimer(){this.refreshTimer!==void 0&&(clearTimeout(this.refreshTimer),this.refreshTimer=void 0)}createDiagnosticsSnapshot(){let e=this.session;return{connectionState:this.state,calls:this.getCalls().map(e=>({callId:e.id,state:e.state,destination:e.destination})),permission:this.support?.hasMediaDevices===!1?`unsupported`:`unknown`,ice:ke(e,this.sip?.iceQualitySnapshot?.()),wss:{configured:e!==void 0,secure:e?.transport.wssUrl.toLowerCase().startsWith(`wss://`)??!1,state:this.state},resources:this.getDiagnosticsResourceCounts()}}getDiagnosticsResourceCounts(){let e=this.mediaBridge.getResourceCounts(),t=this.callManager?.getResourceCounts()??{timers:0,listeners:0},n=this.sip?.getResourceCounts?.(),r=(this.callManager===void 0?0:1)+(this.sipUnsubscribe===void 0?0:1),i=this.session!==void 0&&this.state!==`idle`&&this.state!==`disconnected`;return{timers:(this.refreshTimer===void 0?0:1)+this.reconnect.getTimerCount()+t.timers,listeners:this.events.listenerCount()+t.listeners+e.listeners+this.networkUnsubscribers.length+(n?.listeners??r),tracks:e.tracks,peerConnections:e.peerConnections,audioElements:e.audioElements,webSockets:n?.webSockets??+!!i,deletedSessions:this.deletedSessions.size}}async readMicrophonePermission(){if(typeof navigator>`u`||navigator.mediaDevices===void 0)return`unsupported`;if(navigator.permissions===void 0)return`unknown`;try{return(await navigator.permissions.query({name:`microphone`})).state}catch{return`unknown`}}deleteSession(e){if(this.deletedSessions.has(e))return Promise.resolve();let t=this.sessionDeleteOperations.get(e);if(t!==void 0)return t;let n=this.api.deleteSession(e).then(()=>{this.deletedSessions.add(e)}).catch(t=>{if(Q(t)){this.deletedSessions.add(e);return}throw t}).finally(()=>{this.sessionDeleteOperations.get(e)===n&&this.sessionDeleteOperations.delete(e)});return this.sessionDeleteOperations.set(e,n),n}pruneDeletedSessionTombstones(){for(let e of[...this.deletedSessions])!this.ownedSessionIds.has(e)&&!this.sessionDeleteOperations.has(e)&&this.deletedSessions.delete(e)}async deleteOwnedSessions(){let e;for(let t of[...this.ownedSessionIds])try{await this.deleteSession(t),this.ownedSessionIds.delete(t)}catch(t){e??=t}if(e!==void 0)throw e}resolvePlatform(){let t=this.options.platform??this.detectedPlatform;if(t===void 0)throw new e.i(`CONFIG_INVALID`,`configuration`,!1,{cause:this.support?.platform??`unknown`});return t}setConnectionState(e){this.state===e||this.disposed||(this.state=e,this.diagnostics.log(`info`,`connection.stateChanged`,{state:e}),this.events.emit(`connection.stateChanged`,{state:e===`disconnected`||e===`idle`?`offline`:e}))}assertConnected(){if(this.assertNotDisposed(),this.state!==`connected`||this.callManager===void 0||this.session===void 0)throw new e.i(`CALL_NOT_CONNECTED`,`call`,!1)}assertGeneration(t){if(this.disposed)throw this.disposedError();if(t!==this.lifecycleGeneration)throw new e.i(`CALL_NOT_CONNECTED`,`call`,!1)}isCurrentGeneration(e){return!this.disposed&&e===this.lifecycleGeneration}async awaitSharedWorkerReady(){let e=this.sharedWorkerSelection;if(e.mode===`shared`)try{await e.ready}catch(e){if(this.disposed)return;if(this.options.sharedWorker?.fallback===`error`)throw e;this.sharedWorkerSelection={mode:`single-tab`,reason:e instanceof Error?e.message:`SharedWorker attach failed`}}}releaseSharedWorker(){let e=this.sharedWorkerSelection;if(this.sharedWorkerSelection={mode:`single-tab`,reason:`disposed`},e.mode===`shared`){try{e.client.request({version:1,type:`detach`,requestId:`detach-${e.tabId}`,tabId:e.tabId}).catch(()=>void 0)}catch{}e.client.close()}}assertNotDisposed(){if(this.disposed)throw this.disposedError()}disposedError(){return new e.i(`SDK_ALREADY_DISPOSED`,`internal`,!1)}};function ke(e,t){if(e===void 0)return{configured:!1,serverCount:0,stunServerCount:0,turnServerCount:0,...t?{probe:t}:{}};let n=0,r=0;return e.iceServers.forEach(e=>{let t=e.urls.map(e=>e.toLowerCase());t.some(e=>e.startsWith(`stun:`))&&(n+=1),t.some(e=>e.startsWith(`turn:`)||e.startsWith(`turns:`))&&(r+=1)}),{...t?{probe:t}:{},configured:e.iceServers.length>0,serverCount:e.iceServers.length,stunServerCount:n,turnServerCount:r}}function Ae(e){return e===``?`unknown`:/iPhone|iPad|Android/i.test(e)?`mobile-web`:`web`}function J(t){if(typeof t!=`object`||!t)throw new e.i(`CONFIG_INVALID`,`configuration`,!1);return t}async function Y(e){let t=e.sip?.registerTicket;if(typeof t!=`string`||t===``)return e;let n=await le(t);return n===void 0||n===t?e:{...e,sip:{...e.sip,registerTicket:n}}}function X(n){let r={createSession:async e=>Y(await n.createSession(e)),refreshSession:async e=>Y(n.refreshSession===void 0?await n.createSession({sdkVersion:t.r,platform:`web`}):await n.refreshSession(e)),deleteSession:async e=>{n.deleteSession!==void 0&&await n.deleteSession(e)},setAgentStatus:(t,r)=>n.setAgentStatus===void 0?Promise.reject(new e.i(`CAPABILITY_NOT_SUPPORTED`,`capability`,!1,{cause:`当前会话来源不支持坐席状态设置(sessionProvider.setAgentStatus 未提供)`})):n.setAgentStatus(t,r)},i=n.invalidateToken;return i!==void 0&&(r.invalidateToken=()=>i()),r}function je(t){if(typeof t!=`object`||!t)throw new e.i(`CONFIG_INVALID`,`configuration`,!1);return t}function Z(t,n,r,i,a){return t instanceof e.i?new e.i(t.code,t.category,t.retryable,{requestId:t.requestId,callId:a??t.callId,cause:t.cause??t,serverCode:t.serverCode,platformCode:t.platformCode,status:t.status}):new e.i(n,r,i,{callId:a,cause:t})}function Q(t){return t instanceof e.i?t.status!==void 0&&t.status>=400&&t.status<500||t.serverCode===`SESSION_NOT_FOUND`||t.serverCode===`SESSION_EXPIRED`||t.serverCode===`TOKEN_INVALID`||t.serverCode===`TOKEN_EXPIRED`||t.code===`AUTH_TOKEN_UNAVAILABLE`||t.code===`AUTH_TOKEN_EXPIRED`||t.code===`AUTH_TOKEN_REJECTED`:!1}function Me(t){return t instanceof e.i&&t.code===`SDK_ALREADY_DISPOSED`}function $(t){return t instanceof e.i&&(t.code===`SDK_ALREADY_DISPOSED`||t.code===`CALL_NOT_CONNECTED`)}var Ne=[`outbound`,`inbound`,`mute`,`hold`,`dtmf`,`blind_transfer`,`device_selection`],Pe=[`outbound`,`mute`,`dtmf`];function Fe(e){return e===`mobile-web`?Pe:Ne}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,"d",{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,"f",{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,"l",{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return Oe}}),Object.defineProperty(exports,"u",{enumerable:!0,get:function(){return s}});
@@ -1,6 +1,6 @@
1
1
  import { n as e, t } from "./redact-DB3CMbsK.js";
2
2
  //#region src/version.ts
3
- var n = "3.1.15", r = class {
3
+ var n = "3.1.17", r = class {
4
4
  capacity;
5
5
  entries = [];
6
6
  constructor(e) {
@@ -1 +1 @@
1
- const e=require("./redact-Bq26pObO.cjs");var t=`3.1.15`,n=class{capacity;entries=[];constructor(e){if(this.capacity=e,!Number.isInteger(e)||e<=0)throw RangeError(`RingBuffer capacity must be a positive integer`)}push(e){this.entries.length===this.capacity&&this.entries.shift(),this.entries.push(e)}toArray(){return[...this.entries]}},r=`@16x/webphone-sdk`,i=200,a=class{dependencies;logs=new n(i);now;constructor(e){this.dependencies=e,this.now=e.now??(()=>new Date)}log(t,n,r){this.logs.push({timestamp:this.now().toISOString(),level:t,message:e.t(n),...r===void 0?{}:{context:e.n(r)}})}async getReport(n={}){let i=n.includeRecentLogs!==!1,a=n.includeDeviceNames===!0,u=n.maskPhoneNumbers!==!1,d=this.dependencies.getSnapshot(),f=this.dependencies.getPermission===void 0?d.permission:await o(this.dependencies.getPermission,d.permission),p=a?await s(this.dependencies.getDeviceNames):void 0,m=l(c(this.dependencies.getUserAgent)),h={generatedAt:this.now().toISOString(),sdk:{name:r,version:t},browser:m.browser,os:m.os,...d,permission:f,recentLogs:i?this.logs.toArray():[],...p===void 0?{}:{deviceNames:p}};return e.n(h,{maskPhoneNumbers:u})}};async function o(e,t){try{return await e()}catch{return t}}async function s(e){if(e===void 0)return[];try{return[...await e()]}catch{return[]}}function c(e){if(e!==void 0)try{return e()}catch{return``}return typeof navigator>`u`?``:navigator.userAgent}function l(e){return{browser:u(e),os:d(e)}}function u(e){for(let[t,n]of[[`Edge`,/Edg\/([\d.]+)/],[`Chrome`,/(?:Chrome|CriOS)\/([\d.]+)/],[`Firefox`,/(?:Firefox|FxiOS)\/([\d.]+)/],[`Safari`,/Version\/([\d.]+).*Safari/]]){let r=e.match(n);if(r?.[1]!==void 0)return{name:t,version:r[1]}}return{name:`unknown`,version:``}}function d(e){let t=e.match(/(?:iPhone|iPad).*OS ([\d_]+)/);if(t?.[1]!==void 0)return{name:`iOS`,version:t[1].replaceAll(`_`,`.`)};let n=e.match(/Android ([\d.]+)/);if(n?.[1]!==void 0)return{name:`Android`,version:n[1]};let r=e.match(/Windows NT ([\d.]+)/);if(r?.[1]!==void 0)return{name:`Windows`,version:r[1]};let i=e.match(/Mac OS X ([\d_]+)/);return i?.[1]===void 0?/Linux/.test(e)?{name:`Linux`,version:``}:{name:`unknown`,version:``}:{name:`macOS`,version:i[1].replaceAll(`_`,`.`)}}Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return a}});
1
+ const e=require("./redact-Bq26pObO.cjs");var t=`3.1.17`,n=class{capacity;entries=[];constructor(e){if(this.capacity=e,!Number.isInteger(e)||e<=0)throw RangeError(`RingBuffer capacity must be a positive integer`)}push(e){this.entries.length===this.capacity&&this.entries.shift(),this.entries.push(e)}toArray(){return[...this.entries]}},r=`@16x/webphone-sdk`,i=200,a=class{dependencies;logs=new n(i);now;constructor(e){this.dependencies=e,this.now=e.now??(()=>new Date)}log(t,n,r){this.logs.push({timestamp:this.now().toISOString(),level:t,message:e.t(n),...r===void 0?{}:{context:e.n(r)}})}async getReport(n={}){let i=n.includeRecentLogs!==!1,a=n.includeDeviceNames===!0,u=n.maskPhoneNumbers!==!1,d=this.dependencies.getSnapshot(),f=this.dependencies.getPermission===void 0?d.permission:await o(this.dependencies.getPermission,d.permission),p=a?await s(this.dependencies.getDeviceNames):void 0,m=l(c(this.dependencies.getUserAgent)),h={generatedAt:this.now().toISOString(),sdk:{name:r,version:t},browser:m.browser,os:m.os,...d,permission:f,recentLogs:i?this.logs.toArray():[],...p===void 0?{}:{deviceNames:p}};return e.n(h,{maskPhoneNumbers:u})}};async function o(e,t){try{return await e()}catch{return t}}async function s(e){if(e===void 0)return[];try{return[...await e()]}catch{return[]}}function c(e){if(e!==void 0)try{return e()}catch{return``}return typeof navigator>`u`?``:navigator.userAgent}function l(e){return{browser:u(e),os:d(e)}}function u(e){for(let[t,n]of[[`Edge`,/Edg\/([\d.]+)/],[`Chrome`,/(?:Chrome|CriOS)\/([\d.]+)/],[`Firefox`,/(?:Firefox|FxiOS)\/([\d.]+)/],[`Safari`,/Version\/([\d.]+).*Safari/]]){let r=e.match(n);if(r?.[1]!==void 0)return{name:t,version:r[1]}}return{name:`unknown`,version:``}}function d(e){let t=e.match(/(?:iPhone|iPad).*OS ([\d_]+)/);if(t?.[1]!==void 0)return{name:`iOS`,version:t[1].replaceAll(`_`,`.`)};let n=e.match(/Android ([\d.]+)/);if(n?.[1]!==void 0)return{name:`Android`,version:n[1]};let r=e.match(/Windows NT ([\d.]+)/);if(r?.[1]!==void 0)return{name:`Windows`,version:r[1]};let i=e.match(/Mac OS X ([\d_]+)/);return i?.[1]===void 0?/Linux/.test(e)?{name:`Linux`,version:``}:{name:`unknown`,version:``}:{name:`macOS`,version:i[1].replaceAll(`_`,`.`)}}Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return a}});
@@ -91,6 +91,7 @@ export declare class CCBarClient {
91
91
  private sipUnsubscribe?;
92
92
  private networkUnsubscribers;
93
93
  private networkProbeTimer?;
94
+ private stuckCallsSince;
94
95
  private readonly sessionDeleteOperations;
95
96
  private readonly deletedSessions;
96
97
  private readonly ownedSessionIds;
@@ -120,6 +121,8 @@ export declare class CCBarClient {
120
121
  private rollbackConnect;
121
122
  private performDispose;
122
123
  private awaitMediaReleaseBarriers;
124
+ /** 屏障等待限时:释放操作永不 settle 时不能挂起恢复流程(会锁死 ReconnectManager.running)。 */
125
+ private withBarrierTimeout;
123
126
  private detachSipListener;
124
127
  private detachManagerListeners;
125
128
  private bindManagerEvents;
@@ -72,6 +72,11 @@ export declare class CallManager {
72
72
  dispose(options?: {
73
73
  readonly terminateCalls?: boolean;
74
74
  }): Promise<void>;
75
+ /**
76
+ * 恢复路径专用:传输已断、终态事件不可达时强制清空在途通话(不置 disposed)。
77
+ * 每通 hangup 限时,超时/异常则 dispose 兜底;事件未触达时手动摘除记录并补发终态通知。
78
+ */
79
+ forceTerminateCalls(hangupTimeoutMs?: number): Promise<void>;
75
80
  updateSession(session: WebPhoneSession): void;
76
81
  private switchActiveCall;
77
82
  private handleStateChanged;
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../Diagnostics-Djp1V_JV.cjs"),t=require("../redact-Bq26pObO.cjs");require("../createJsSipFactory-B1ORbJiP.cjs"),exports.Diagnostics=e.t,exports.RingBuffer=e.n,exports.diagnosticsVersion=e.r,exports.redactText=t.t,exports.redactValue=t.n;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../Diagnostics-CK0ai_sy.cjs"),t=require("../redact-Bq26pObO.cjs");require("../createJsSipFactory-B1ORbJiP.cjs"),exports.Diagnostics=e.t,exports.RingBuffer=e.n,exports.diagnosticsVersion=e.r,exports.redactText=t.t,exports.redactValue=t.n;
@@ -1,3 +1,3 @@
1
- import { n as e, r as t, t as n } from "../Diagnostics-DLU1_Np2.js";
1
+ import { n as e, r as t, t as n } from "../Diagnostics-B6xGNl8M.js";
2
2
  import { n as r, t as i } from "../redact-DB3CMbsK.js";
3
3
  export { n as Diagnostics, e as RingBuffer, t as diagnosticsVersion, i as redactText, r as redactValue };
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./SharedWorkerProtocol-C-4KpECM.cjs"),t=require("./CCBarClient-DBQefPRJ.cjs"),n=require("./Diagnostics-Djp1V_JV.cjs"),r=require("./redact-Bq26pObO.cjs");require("./diagnostics/index.cjs"),require("./createJsSipFactory-B1ORbJiP.cjs");function i(e){if(e.code!==`OK`)throw TypeError(`Unexpected session response code: ${e.code}`);if(e.data===void 0||e.data===null)throw TypeError(`Unexpected session response: missing data`);return e.data}function a(e={}){return{version:`0.1.0`,options:e}}var o=`0.1.0`;exports.CCBarCall=t.o,exports.CCBarClient=t.t,exports.CCBarError=e.i,exports.CallManager=t.a,exports.CallStateError=t.s,exports.Diagnostics=n.t,exports.RingBuffer=n.n,exports.TypedEventBus=t.f,exports.assertCallTransition=t.c,exports.canTransition=t.l,exports.createSdk=a,exports.createSharedWorkerSelection=t.n,exports.diagnosticsVersion=n.r,exports.parseSessionResponse=i,exports.redactText=r.t,exports.redactValue=r.n,exports.resolveWorkerUrl=t.r,exports.transition=t.u,exports.transitions=t.d,exports.version=o;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./SharedWorkerProtocol-C-4KpECM.cjs"),t=require("./CCBarClient-GQ3yxDur.cjs"),n=require("./Diagnostics-CK0ai_sy.cjs"),r=require("./redact-Bq26pObO.cjs");require("./diagnostics/index.cjs"),require("./createJsSipFactory-B1ORbJiP.cjs");function i(e){if(e.code!==`OK`)throw TypeError(`Unexpected session response code: ${e.code}`);if(e.data===void 0||e.data===null)throw TypeError(`Unexpected session response: missing data`);return e.data}function a(e={}){return{version:`0.1.0`,options:e}}var o=`0.1.0`;exports.CCBarCall=t.o,exports.CCBarClient=t.t,exports.CCBarError=e.i,exports.CallManager=t.a,exports.CallStateError=t.s,exports.Diagnostics=n.t,exports.RingBuffer=n.n,exports.TypedEventBus=t.f,exports.assertCallTransition=t.c,exports.canTransition=t.l,exports.createSdk=a,exports.createSharedWorkerSelection=t.n,exports.diagnosticsVersion=n.r,exports.parseSessionResponse=i,exports.redactText=r.t,exports.redactValue=r.n,exports.resolveWorkerUrl=t.r,exports.transition=t.u,exports.transitions=t.d,exports.version=o;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { i as e } from "./SharedWorkerProtocol-CffZrUXg.js";
2
- import { a as t, c as n, d as r, f as i, l as a, n as o, o as s, r as c, s as l, t as u, u as d } from "./CCBarClient-AX6m4-Vg.js";
3
- import { n as f, r as p, t as m } from "./Diagnostics-DLU1_Np2.js";
2
+ import { a as t, c as n, d as r, f as i, l as a, n as o, o as s, r as c, s as l, t as u, u as d } from "./CCBarClient-C2sC86Xi.js";
3
+ import { n as f, r as p, t as m } from "./Diagnostics-B6xGNl8M.js";
4
4
  import { n as h, t as g } from "./redact-DB3CMbsK.js";
5
5
  import "./diagnostics/index.js";
6
6
  //#region src/api/contracts.ts