@16x/webphone-sdk 3.1.8 → 3.1.9

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,57 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.1.9 - 2026-09-24
4
+
5
+ > 同日先发过 `3.8.1`(内容与本文完全相同),按项目版本线改成 3.1.9(3.1.8 的补丁位)重新发布;3.8.1 不再维护。
6
+
7
+
8
+ - **坐席状态接口直接用会话里的那张票**:老平台把 fs token 拼在软电话地址上(`wss://…/api/fs/sip-ws?token=…`),
9
+ 同一个 token 也用于 HTTP 接口的 `Authorization`。`client.setAgentStatus()` 现在把这个地址带给会话来源
10
+ (`SessionProvider.setAgentStatus(request, context?)`,新增可选参数 `AgentStatusContext.wssUrl`),
11
+ 订阅来源可以直接拿它去打 `seat/account/get` 与 `seats/set-status`,**不再单独换一次票**。
12
+ - `createLegacySessionProvider` 的 `setAgentStatus` 按这个顺序取票:
13
+ 会话地址里的 token → 最近见过的那个(退签时会话已经断开)→ `getToken`/`tokenUrl` 重新换票(与旧行为一致)。
14
+ 它自己在 `createSession` 里拼过 WSS 地址时也会记住那张票;`invalidateToken()` 会把它一起清掉。
15
+ - 非破坏性:`setAgentStatus` 的第二个参数是可选的,旧接入方(不传 context、只用 `getToken`/`tokenUrl`)行为不变。
16
+
17
+ ## 4.1.0 - 2026-09-24
18
+
19
+ - 新增 `createLegacySessionProvider`(只在 `@16x/webphone-sdk/legacy` 子入口导出):
20
+ 把老平台「取 token → `POST {host}/openapi/token/v1/seat/account/get` → AES-128-CBC/Pkcs7 解 SIP 密码
21
+ → 拼 WebPhoneSession」以及坐席状态 `POST {host}/openapi/token/v1/seats/set-status` 这一整段交给 SDK,
22
+ 页面只需提供换票口子:`getToken()` 函数或 `tokenUrl` 地址(**两者都不会让 SDK 接触 API SECRET**)。
23
+ AES key/iv 默认用老平台固定值(与旧版 `ccbar.js` 一致),可用 `aesKey`/`aesIv` 覆盖;
24
+ 平台返回的 `iceServers` 原样透传(含 TURN),缺失时才按 `turnIp` 拼 STUN;
25
+ `refreshSession` 等于整条链路重跑(换一次 SIP 密码)。
26
+ - 新增 `decryptSipPassword(cipherText, { key?, iv? })`(同样只在 `/legacy` 导出):
27
+ 解 `seat/account/get` 返回的 `password`/`registerPassword`(AES-128-CBC/Pkcs7、Base64 密文)。
28
+ 服务端(Node 18+)与页面都能用;默认平台内置 key/iv,可覆盖;失败原因在 `error.cause`。
29
+ `createLegacySessionProvider` 内部复用同一个实现。
30
+ - 新增错误码 `LEGACY_PLATFORM_UNREACHABLE`(网络/超时/非 JSON)与 `LEGACY_PLATFORM_REJECTED`
31
+ (平台业务错误,平台的 code 在 `error.serverCode` 上)。
32
+ - 非破坏性:`sessionProvider` 契约与服务端拼会话的用法完全不变。
33
+
34
+ ## 4.0.0 - 2026-09-24
35
+
36
+ **破坏性变更:移除「SDK 自己换会话」这条能力,会话只能由接入方服务端下发。**
37
+
38
+ - 移除 `tokenProvider` 选项与 `baseUrl` 上的会话职责:SDK 不再请求平台会话接口
39
+ (`POST /webphone/v1/sessions`、`/sessions/{id}/refresh`、`DELETE /sessions/{id}`、
40
+ `/capabilities`、`/agents/me/status`)。
41
+ - 删除 `WebPhoneApi`、`TokenManager` 及其公开导出(`TokenProvider`、`TokenRequest`、
42
+ `TokenProviderResult`、`WebPhoneApiOptions`、`RefreshSessionRequest`、`CapabilitiesResponse`)。
43
+ - `sessionProvider` 成为**唯一**会话来源;未提供时构造抛 `CONFIG_INVALID`。
44
+ - `connect({ extension })` 的 `extension` 参数删除(它只用于向平台换取 token):
45
+ 改成 `connect()`,坐席身份由接入方服务端按登录态决定。
46
+ - `sessionProvider.invalidateToken()` 保留:接入方可以在终态失败时清掉自己的服务端缓存。
47
+ - **迁移**:原来用 `tokenProvider` 的接入方,改成在自己服务端拼好 `WebPhoneSession`
48
+ (拿坐席账号 → 解出 SIP 密码 → 拼 WSS 地址),再用 `sessionProvider.createSession` 交给 SDK。
49
+ 参考实现:客户 demo 仓库的 `server/get-session.js`(fs token → 坐席账号 → AES-128-CBC 解密 → 拼 WSS)。
50
+ `docs/api/client.md` 与 `docs-site` 的「会话来源」章节已按新契约重写。
51
+ - 仓库结构:`examples/` 下不再提供前端 demo 与 Node/Go 签发服务(它们只服务于旧流程),
52
+ 只保留 `examples/network-check`(网络预检页);客户包相应缩减为
53
+ `ccbar-sdk-network-check` + `ccbar-sdk-technical-integration-package`。
54
+
3
55
  ## 3.1.8 - 2026-09-23
4
56
 
5
57
  - **修 3.1.7 引入的回归:来电会被立刻拒掉(对端收到 480)。**
package/README.md CHANGED
@@ -10,7 +10,7 @@ npm install @16x/webphone-sdk
10
10
 
11
11
  公开包地址:[https://www.npmjs.com/package/@16x/webphone-sdk](https://www.npmjs.com/package/@16x/webphone-sdk)。任何人都可以直接安装,不需要 token。
12
12
 
13
- 浏览器只应接收客户服务端签发的短期 WebPhone Access Token。不要把 `appSecret`、固定 SIP 密码或 TURN 密码写入前端代码、示例、日志或构建产物。客户从安装到首通的完整路径见 `docs/quick-start.md`,PC/H5 选择见 `docs/guides/mobile-h5.md`。
13
+ 浏览器只应接收客户服务端下发的会话(已含短期 WSS ticket 与 SIP 凭证)。不要把 `appSecret`、AES 密钥、固定 SIP 密码或 TURN 密码写入前端代码、示例、日志或构建产物。客户从安装到首通的完整路径见 `docs/quick-start.md`,PC/H5 选择见 `docs/guides/mobile-h5.md`。
14
14
 
15
15
  ## Core 快速开始
16
16
 
@@ -19,11 +19,13 @@ import { CCBarClient } from '@16x/webphone-sdk';
19
19
 
20
20
  const client = new CCBarClient({
21
21
  platform: 'web',
22
- tokenProvider: async () => {
23
- // 你们自己的签发接口:返回 { accessToken, expiresAt? },签名密钥留在服务端
24
- const response = await fetch('/get-token', { method: 'POST', credentials: 'include' });
25
- if (!response.ok) throw new Error('获取外呼凭证失败');
26
- return response.json();
22
+ sessionProvider: {
23
+ // 你们自己的会话接口:返回一份 WebPhoneSession,签名与解密都留在服务端
24
+ createSession: async () => {
25
+ const response = await fetch('/get-session', { method: 'POST', credentials: 'include' });
26
+ if (!response.ok) throw new Error('获取会话失败');
27
+ return response.json();
28
+ },
27
29
  },
28
30
  });
29
31
 
@@ -51,7 +53,7 @@ await client.dispose();
51
53
  - `CCBarClient.getDiagnostics` 脱敏诊断报告
52
54
  - `CCBarCall.mute/unmute/hold/resume/sendDtmf/transfer/hangup`
53
55
 
54
- 构造参数里几个按需用的:`sessionProvider`(3.1.0+,自建/旧平台直接给会话,见下一节)、
56
+ 构造参数里几个按需用的:`sessionProvider`(**必填**,4.0.0 起唯一会话来源,见下一节)、
55
57
  `sipKeepaliveSeconds`(3.1.1+,默认 25 秒重发 REGISTER 撑住 NAT/代理上的长连接,`0` 关闭)、
56
58
  `sharedWorker`(多标签页入口)、`baseUrl`、`maxConcurrentCalls`。
57
59
 
@@ -60,10 +62,10 @@ INVITE,预收集候选才能做到「点完就出局」。
60
62
 
61
63
  PC Web 支持完整 Core 通话能力。移动 H5 首期仅承诺受支持系统浏览器中的前台单路外呼;来电、保持、转接、后台和锁屏通话不在承诺范围内。
62
64
 
63
- ## 自定义会话来源(自建 / 旧平台)
65
+ ## 会话来源(sessionProvider)
64
66
 
65
- 平台不提供 `/webphone/v1/sessions`(自建网关,或老的 `token/fs` + `seat/account/get` 那一套)时,
66
- 用 `sessionProvider` 把会话直接交给 SDK,`tokenProvider` 与 `sessionProvider` 二选一:
67
+ 会话由接入方在自己的服务端拼好后交给 SDK:**4.0.0 起这是唯一的会话来源**(3.x 的 `tokenProvider`
68
+ 以及 SDK 自己请求平台会话接口的能力已移除,迁移方式见 `CHANGELOG.md` 的 4.0.0 条目)。
67
69
 
68
70
  ```ts
69
71
  const client = new CCBarClient({
@@ -108,10 +110,12 @@ import { CCBarSDK } from '@16x/webphone-sdk/legacy';
108
110
 
109
111
  const legacy = new CCBarSDK({
110
112
  platform: 'web',
111
- tokenProvider: async () => fetch('/get-token', {
112
- method: 'POST',
113
- credentials: 'include',
114
- }).then(response => response.json()),
113
+ sessionProvider: {
114
+ createSession: async () => fetch('/get-session', {
115
+ method: 'POST',
116
+ credentials: 'include',
117
+ }).then(response => response.json()),
118
+ },
115
119
  });
116
120
 
117
121
  await legacy.login();
@@ -120,6 +124,49 @@ await legacy.hangup();
120
124
  await legacy.signOut();
121
125
  ```
122
126
 
127
+ ### `createLegacySessionProvider`:老平台的会话来源
128
+
129
+ 老平台(`token/fs` + `seat/account/get` 这一套)可以把「取 token → 取坐席账号 → 解 SIP 密码 → 拼会话」
130
+ 整段交给 SDK,页面只提供换票口子:
131
+
132
+ ```ts
133
+ import { createLegacySessionProvider } from '@16x/webphone-sdk/legacy';
134
+
135
+ const client = new CCBarClient({
136
+ sessionProvider: createLegacySessionProvider({
137
+ host: 'https://vxapi.yundianlab.com',
138
+ // 取 token 二选一:给函数,或给地址让 SDK 去 POST(都是你们自己的接口)
139
+ getToken: () => fetch('/get-token', { method: 'POST' }).then(response => response.json()),
140
+ // tokenUrl: '/get-token',
141
+ }),
142
+ });
143
+ ```
144
+
145
+ - **SDK 不碰 API SECRET**:`/openapi/v1/token/fs` 的加签始终在你们服务端,SDK 只拿结果;
146
+ - **AES key 会随包下发**:老平台那把 16 字节 key/iv 是固定值(旧版 `ccbar.js` 里同样是硬编码),
147
+ 可用 `aesKey` / `aesIv` 覆盖;介意的话就走服务端拼会话(见下一节);
148
+ - 坐席状态:`client.setAgentStatus(...)` 打到 `{host}/openapi/token/v1/seats/set-status`,
149
+ 其中 `extension` 传的是**坐席账号**(`username`,可能带企业前缀);
150
+ - **浏览器直连网关**:需要网关放行 CORS 与调用方 IP(`seat/account/get` 有 IP 白名单),部署前先确认;
151
+ - 取票与 SIP 密码都按有效期提前换(`refreshBufferSeconds`,默认 180 秒)。
152
+
153
+ ### `decryptSipPassword`:解 `seat/account/get` 返回的 `password`
154
+
155
+ `password`(或 `registerPassword`)是 **AES-128-CBC/Pkcs7 的密文、Base64 编码**,
156
+ SDK 把解密单独导出,服务端(Node 18+)与页面都能用:
157
+
158
+ ```ts
159
+ import { decryptSipPassword } from '@16x/webphone-sdk/legacy';
160
+
161
+ const password = await decryptSipPassword(data.password); // 明文 SIP 密码
162
+ // 环境用的是别的 key/iv 时:await decryptSipPassword(data.password, { key, iv })
163
+ ```
164
+
165
+ - key/iv 各 16 字节,**默认是平台内置固定值**(与旧版 `ccbar.js` 一致),可用 `key`/`iv` 覆盖;
166
+ - 失败抛 `CCBarError`,可读原因在 `error.cause`(密文为空 / 不是合法 Base64 / 解密失败);
167
+ - 依赖 WebCrypto:浏览器需安全上下文(https / localhost),Node 需 18+;
168
+ - `createLegacySessionProvider` 内部用的就是它。
169
+
123
170
  旧方法映射如下:
124
171
 
125
172
  | Legacy | Core |
@@ -137,8 +184,8 @@ await legacy.signOut();
137
184
  `insideCall(number)` 会使用 `type: 'extension'` 标记 SIP 呼叫(INVITE 上带 `X-XCall-Destination-Type: extension`),
138
185
  浏览器不拼接客户前缀;后端按当前会话租户解析分机并路由到同租户坐席。普通 `dial()` 不传 type,继续按外呼处理。
139
186
 
140
- 对接**旧平台**时注意:那套网关只认「企业前缀 + 分机号」,`type: 'extension'` 这个头它不解析,
141
- 所以需要自己拼好前缀再拨(`dial({ destination: \`${prefix}${number}\` })`),
187
+ 注意:如果你们的网关只认「企业前缀 + 分机号」,`type: 'extension'` 这个头它不解析,
188
+ 就需要自己拼好前缀再拨(`dial({ destination: \`${prefix}${number}\` })`),
142
189
  具体见客户示例仓库的 `prefixExtension()`。
143
190
 
144
191
  `setBu()` 不会伪造 `busy`。该方法抛出 `DeprecatedError`,因为忙碌状态应由通话状态或服务端状态策略驱动。所有 Legacy 方法仅在开发构建中各警告一次,生产构建不输出弃用日志。`signOut()` 是终态操作;如需保留实例以便重新连接,请直接使用 Core 的 `disconnect()`。
@@ -146,7 +193,7 @@ await legacy.signOut();
146
193
  ## 版本与更新记录
147
194
 
148
195
  当前版本见 `package.json`,每个版本改了什么见 [CHANGELOG.md](./CHANGELOG.md)。
149
- 最近几个版本:3.1.0 新增 `sessionProvider`;3.1.1 新增 SIP 保活;3.1.2 拨号带 ICE 候选池。
196
+ 最近几个版本:4.0.0 移除 `tokenProvider`(只保留 `sessionProvider`,破坏性变更);3.1.0 新增 `sessionProvider`;3.1.1 新增 SIP 保活;3.1.2 拨号带 ICE 候选池。
150
197
 
151
198
  ## 开发与验收
152
199
 
@@ -0,0 +1 @@
1
+ const e=require("./SharedWorkerProtocol-39dch6xL.cjs"),t=require("./Diagnostics-DkKlZQnY.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;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`,`held`,()=>this.options.session.hold())}async resume(e){this.assertNotDisposed(),this.assertOwner(e),this.assertHoldCapability(),this.assertState(`held`),this.assertCapability(`hold`),await this.startPendingOperation(`resume`,`active`,()=>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.transitionIfAllowed(`held`,t,e);break;case`unhold`:this.transitionIfAllowed(`active`,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))}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,n){if(this.pendingOperation!==void 0)throw this.operationError();return new Promise((r,i)=>{let a={kind:e,nextState:t,resolve:r,reject:i};this.pendingOperation=a,a.timer=setTimeout(()=>this.timeoutPendingOperation(a),l);let o;try{o=n()}catch(e){this.rejectPendingOperation(e);return}o.then(()=>this.resolvePendingOperation(a),e=>this.rejectPendingOperation(e,a))})}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.transitionTo(e.nextState),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 h=`X-User-Data`,g=/[^\x20-\x7E]/,ee=`userdata 只能是可见 ASCII(不能有换行/制表/中文):换行会构成 SIP 头注入;要传中文或 JSON 请调用方先 encodeURIComponent / base64,再在平台侧解回来`;function te(t){if(typeof t!=`string`)return[];let n=t.trim();if(n===``)return[];if(g.test(n))throw new e.i(`CALL_INVALID_USERDATA`,`call`,!1,{cause:ee});return[`${h}: ${n}`]}var _=class{events=new v;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=te(t.userdata);this.requireCapability(n,`outbound`);let o=this.callLimit(n);if(this.options.platform===`mobile-web`&&this.calls.size+this.pendingDialCount>=o)throw this.capabilityError();if(this.calls.size+this.pendingDialCount>=o||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 s=m(),c;try{c=await this.holdActiveCallForNewCall(),this.assertGeneration(r,s);let e;try{e=this.options.sip.dial(i,this.dialOptions(s,n,t.type,a))}catch(e){throw this.dialError(e,s)}this.assertGeneration(r,s);let o;try{o=new u({id:s,destination:i,platform:this.options.platform,capabilities:this.effectiveCapabilities(n),session:e,onStateChanged:(e,t)=>this.handleStateChanged(o,e,t),onError:e=>this.events.emit(`error`,{error:e}),onDisposed:()=>this.handleDisposed(o)})}catch(e){throw this.dialError(e,s)}if(!this.isCurrentGeneration(r))throw o.dispose(),this.callOperationError(o.id);this.calls.set(o.id,o),this.callSessions.set(o.id,e),this.options.onCallCreated?.(o.id,e);try{o.beginOutbound()}catch(e){throw o.dispose(),this.calls.delete(o.id),this.callSessions.delete(o.id),this.dialError(e,o.id)}if(!this.isCurrentGeneration(r))throw o.dispose(),this.calls.delete(o.id),this.callSessions.delete(o.id),this.callOperationError(o.id);return this.events.emit(`call.created`,{callId:o.id,state:o.state}),o}catch(e){if(this.isCurrentGeneration(r)&&c!==void 0&&this.isManagedCall(c)&&c.state===`held`)try{await c.resume()}catch(t){throw this.compensationError(c.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}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:y(n)}):this.events.emit(`call.failed`,{callId:e.id,error:b(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}):new e.i(`CALL_OPERATION_NOT_ALLOWED`,`call`,!1,{callId:n,cause:t})}},v=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 y(e){if(typeof e!=`object`||!e||!(`reason`in e))return`ended`;let t=e.reason;return typeof t==`string`&&t!==``?t:`ended`}function b(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});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});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 x=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`&&S(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(ne(n))}catch(e){this.pending.forEach(t=>{clearTimeout(t.timer),t.reject(e)}),this.pending.clear()}}};function S(e){return typeof e==`object`&&!!e&&`state`in e&&(e.state===`connected`||e.state===`reconnecting`)}function ne(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?.status===void 0?{}:{status:n.status}})}function C(t={}){if((t.enabled??`auto`)===!1)return{mode:`single-tab`,reason:`disabled`};let n=t.locationHref??T(),r=w(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(!ie(r,n))return i(`SharedWorker URL must be same-origin`);let a=t.workerCtor??re();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??ae(),c=new x(o.port),l={version:1,type:`attach`,requestId:oe(),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 w(e,t=T()){try{return t===void 0?void 0:new URL(e??`./shared-worker.js`,t).toString()}catch{return}}function T(){return typeof location>`u`?void 0:location.href}function re(){if(typeof SharedWorker==`function`)return SharedWorker}function ie(e,t){if(t===void 0)return!0;try{return new URL(e,t).origin===new URL(t).origin}catch{return!1}}function ae(){return`tab-${typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID():Math.random().toString(36).slice(2)}`}function oe(){return`attach-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}var E=class{mediaDevices;createAudioElement;outputCapability;outputDeviceId;outputGeneration=0;outputTail;constructor(e={}){this.mediaDevices=e.mediaDevices===null?void 0:e.mediaDevices??D(),this.createAudioElement=e.createAudioElement}async requestPermission(e={}){let t=this.requireMediaDevices(),n;try{n=await t.getUserMedia({audio:e})}catch(e){throw A(e)}O(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 j(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 M(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 k(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 D(){return globalThis.navigator?.mediaDevices}function O(e){let t;try{t=e.getTracks()}catch{return}t.forEach(e=>{try{e.stop()}catch{}})}function k(t){let n=N(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 A(t){let n=N(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 j(t){let n=N(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 M(t){let n=N(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 N(e){if(typeof e!=`object`||!e||!(`name`in e))return;let t=e.name;return typeof t==`string`?t:void 0}var P=class{createAudioElement;bindings=new Map;audioOwners=new Map;trackOwners=new Map;generations=new Map;pendingPlays=new Map;constructor(e=F){this.createAudioElement=e}async bind(t,n){let r=this.bindings.get(t);if(r?.stream===n)return;let i=I(t,n),a;try{a=this.createAudioElement()}catch(n){throw L(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 L(i,this.trackOwners),new e.i(`CALL_OPERATION_NOT_ALLOWED`,`call`,!1,{callId:t});try{a.autoplay=!0,a.playsInline=!0}catch(n){throw L(i,this.trackOwners),new e.i(`SDK_INTERNAL_ERROR`,`internal`,!1,{callId:t,cause:n})}try{a.srcObject=n}catch(n){throw L(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),z(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 F(){if(typeof document>`u`)throw new e.i(`CAPABILITY_NOT_SUPPORTED`,`capability`,!1);return document.createElement(`audio`)}function I(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 R(n),new e.i(`SDK_INTERNAL_ERROR`,`internal`,!1,{callId:t,cause:r??i})}}}function L(e,t){e.forEach(e=>{(t.get(e)??0)===0&&z(e)})}function R(e){try{[...new Set(e.getTracks())].filter(e=>e.kind===`audio`).forEach(z)}catch{}}function z(e){try{e.stop()}catch{}}var B=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 E(t),this.remoteAudio=new P(e.createAudioElement),this.getActiveCall=e.getActiveCall,this.createRemoteStream=e.createRemoteStream??se}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=V(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)||q(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 G(s),new e.i(`SDK_INTERNAL_ERROR`,`internal`,!1,{callId:n.callId,cause:t})}let l;try{l=s.getAudioTracks()}catch(t){throw K(c),new e.i(`SDK_INTERNAL_ERROR`,`internal`,!1,{callId:n.callId,cause:t})}let u=l[0];if(u===void 0)throw K(c),new e.i(`MEDIA_DEVICE_NOT_FOUND`,`media`,!1,{callId:n.callId});if(!this.canCommitInputSwitch(n,r,i,a,o))throw K(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),K(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),K(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),q(a)),c.forEach(e=>{e!==u&&q(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 V(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 G(e){try{K(e.getTracks())}catch{}}function K(e){e.forEach(q)}function q(e){try{e.stop()}catch{}}function se(e){if(typeof MediaStream<`u`)try{return new MediaStream([e])}catch{return}}function ce(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 B({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||!J(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(!J(t)||typeof t.getMediaRegistration!=`function`)return;let n=t.getMediaRegistration();if(le(n)&&r.get(e)?.peerConnection!==n.peerConnection){r.set(e,n);try{d.registerCallMedia(e,n)}catch{r.delete(e)}}}}function J(e){return typeof e==`object`&&!!e}function le(e){return typeof e==`object`&&!!e&&`peerConnection`in e&&typeof e.peerConnection==`object`&&e.peerConnection!==null}var ue=1e3,de=3e4;function fe(e,t=Math.random){let n=Math.min(de,ue*2**Math.max(0,Math.floor(e))),r=Math.min(1,Math.max(0,t()));return Math.round(n*(1+r*.2))}var pe=class{recover;random;isOnline;onAttempt;attempt=0;pendingTimer;running=!1;online=!0;generation=0;disposed=!1;restartAfterRun=!1;constructor(e){this.recover=e.recover,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=fe(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}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)}},me=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=[];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?Y(X(n.sessionProvider)):Y(n.api),this.suppliedSip=n.sip===void 0?void 0:_e(n.sip),this.mediaBridge=ce(()=>this.getActiveMediaContext()),this.media=this.mediaBridge.publicMedia,this.reconnect=new pe({recover:()=>this.recoverConnection(),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`}:C({...n.sharedWorker,...n.sharedWorkerHost??{}})}static async checkSupport(){let e=typeof navigator<`u`&&navigator.mediaDevices!==void 0,t=typeof WebSocket<`u`,n=ge(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.api.invalidateToken?.(),this.connectOperation!==void 0)return this.connectOperation;if(this.state===`connected`)return Promise.resolve();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(e){this.assertNotDisposed();let t=this.session?.transport.wssUrl;await this.api.setAgentStatus({status:e,reason:``},t===void 0?void 0:{wssUrl:t}),this.disposed||this.events.emit(`agent.statusChanged`,{status:e})}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??xe(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.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 _({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){ve(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 n,this.terminalReleaseOperations.delete(t)}catch(n){try{await this.mediaBridge.releaseCall(t),this.terminalReleaseOperations.delete(t)}catch(t){e??=t??n}}if(e!==void 0)throw 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`)&&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.reconnect.cancel()}}}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(){this.disposed||this.intentionalDisconnect||this.hasNonTerminalCalls()||(await this.awaitMediaReleaseBarriers(),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-Dr8HbLl-.cjs")),Promise.resolve().then(()=>require("./JsSipAdapter-BN9BAFHr.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(),n=()=>this.reconnect.notifyOffline();e.addEventListener(`online`,t),e.addEventListener(`offline`,n),this.networkUnsubscribers=[()=>e.removeEventListener(`online`,t),()=>e.removeEventListener(`offline`,n)]}detachNetworkListeners(){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:he(e),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 he(e){if(e===void 0)return{configured:!1,serverCount:0,stunServerCount:0,turnServerCount:0};let t=0,n=0;return e.iceServers.forEach(e=>{let r=e.urls.map(e=>e.toLowerCase());r.some(e=>e.startsWith(`stun:`))&&(t+=1),r.some(e=>e.startsWith(`turn:`)||e.startsWith(`turns:`))&&(n+=1)}),{configured:e.iceServers.length>0,serverCount:e.iceServers.length,stunServerCount:t,turnServerCount:n}}function ge(e){return e===``?`unknown`:/iPhone|iPad|Android/i.test(e)?`mobile-web`:`web`}function Y(t){if(typeof t!=`object`||!t)throw new e.i(`CONFIG_INVALID`,`configuration`,!1);return t}function X(n){let r={createSession:e=>n.createSession(e),refreshSession:e=>n.refreshSession===void 0?n.createSession({sdkVersion:t.r,platform:`web`}):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 _e(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,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`:!1}function ve(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 ye=[`outbound`,`inbound`,`mute`,`hold`,`dtmf`,`blind_transfer`,`device_selection`],be=[`outbound`,`mute`,`dtmf`];function xe(e){return e===`mobile-web`?be:ye}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,"d",{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,"l",{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return me}}),Object.defineProperty(exports,"u",{enumerable:!0,get:function(){return r}});