{"version":3,"sources":["../src/utils/simple-event-emitter.ts","../src/utils/sse-stream.ts","../src/enums/call-event-name.enum.ts","../src/enums/client-event-name.enum.ts","../src/enums/call-state.enum.ts","../src/constants/api-endpoints.ts","../src/constants/ice-servers.ts","../src/call.ts","../src/firetell-client.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type Listener<T = any> = (event: T) => void;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EventMap = Record<string, any>;\n\nexport class SimpleEventEmitter<Events extends EventMap = EventMap> {\n  private listeners: Map<string, Listener[]> = new Map();\n\n  public on<K extends string & keyof Events>(event: K, listener: Listener<Events[K]>): void;\n  public on(event: string, listener: Listener): void;\n  public on(event: string, listener: Listener): void {\n    if (!this.listeners.has(event)) {\n      this.listeners.set(event, []);\n    }\n    this.listeners.get(event)!.push(listener as Listener);\n  }\n\n  /**\n   * Subscribe to an event for a single emission only.\n   * The listener is automatically removed after first invocation.\n   */\n  public once<K extends string & keyof Events>(event: K, listener: Listener<Events[K]>): void;\n  public once(event: string, listener: Listener): void;\n  public once(event: string, listener: Listener): void {\n    const wrapper: Listener = (data) => {\n      this.off(event, wrapper);\n      listener(data);\n    };\n    this.on(event, wrapper);\n  }\n\n  public off<K extends string & keyof Events>(event: K, listener: Listener<Events[K]>): void;\n  public off(event: string, listener: Listener): void;\n  public off(event: string, listener: Listener): void {\n    const arr = this.listeners.get(event);\n    if (!arr) return;\n    this.listeners.set(event, arr.filter(l => l !== listener));\n  }\n\n  public emit<K extends string & keyof Events>(event: K, data?: Events[K]): void;\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  public emit(event: string, data?: any): void;\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  public emit(event: string, data?: any): void {\n    const arr = this.listeners.get(event);\n    if (!arr) return;\n    // Iterate over a copy to avoid issues if listeners modify the array\n    [...arr].forEach(listener => listener(data));\n  }\n\n  public offAll(): void {\n    this.listeners.clear();\n  }\n}\n","export interface SseMessageEvent {\n  event: string;\n  data: any;\n  id?: string;\n  raw?: string;\n}\n\nexport interface SseStreamConfig {\n  url: string;\n  token?: string;\n  headers?: Record<string, string>;\n  withCredentials?: boolean;\n  maxReconnectDelay?: number;\n  initialReconnectDelay?: number;\n  onOpen?: () => void;\n  onMessage?: (event: SseMessageEvent) => void;\n  onError?: (error: unknown) => void;\n  onConnectionStateChange?: (state: \"connecting\" | \"connected\" | \"disconnected\") => void;\n}\n\n/**\n * Lightweight, zero-dependency SSE Stream Client with Authorization Bearer header support.\n * Uses fetch() + ReadableStream on modern browsers and Node.js (18+),\n * with graceful fallback to EventSource (?token=...) for legacy environments.\n */\nexport class SseStreamClient {\n  private config: SseStreamConfig;\n  private abortController: AbortController | null = null;\n  private nativeEventSource: EventSource | null = null;\n  private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n  private reconnectDelay: number;\n  private isExplicitlyClosed: boolean = false;\n  private _connected: boolean = false;\n\n  constructor(config: SseStreamConfig) {\n    this.config = config;\n    this.reconnectDelay = config.initialReconnectDelay || 3000;\n  }\n\n  public get isConnected(): boolean {\n    return this._connected;\n  }\n\n  /**\n   * Start or restart the SSE connection stream\n   */\n  public connect(): void {\n    this.isExplicitlyClosed = false;\n    this.cleanup();\n    this.config.onConnectionStateChange?.(\"connecting\");\n\n    // Prefer fetch with ReadableStream (supports Authorization: Bearer header)\n    if (typeof fetch !== \"undefined\" && typeof ReadableStream !== \"undefined\") {\n      void this.connectViaFetch();\n    } else if (typeof EventSource !== \"undefined\") {\n      this.connectViaEventSource();\n    } else {\n      console.warn(\"SseStreamClient: Neither fetch streams nor EventSource is available in this environment.\");\n      this.config.onConnectionStateChange?.(\"disconnected\");\n    }\n  }\n\n  private async connectViaFetch(): Promise<void> {\n    this.abortController = new AbortController();\n    const signal = this.abortController.signal;\n\n    try {\n      const headers: Record<string, string> = {\n        Accept: \"text/event-stream\",\n        \"Cache-Control\": \"no-cache\",\n        ...(this.config.token ? { Authorization: `Bearer ${this.config.token}` } : {}),\n        ...(this.config.headers || {}),\n      };\n\n      const response = await fetch(this.config.url, {\n        method: \"GET\",\n        headers,\n        signal,\n      });\n\n      if (!response.ok) {\n        throw new Error(`SSE stream connection failed: HTTP ${response.status} ${response.statusText}`);\n      }\n\n      if (!response.body) {\n        throw new Error(\"SSE response body is not readable\");\n      }\n\n      this._connected = true;\n      this.reconnectDelay = this.config.initialReconnectDelay || 3000;\n      this.config.onOpen?.();\n      this.config.onConnectionStateChange?.(\"connected\");\n\n      const reader = response.body.getReader();\n      const decoder = new TextDecoder(\"utf-8\");\n      let buffer = \"\";\n\n      while (true) {\n        const { value, done } = await reader.read();\n        if (done) break;\n\n        buffer += decoder.decode(value, { stream: true });\n        const lines = buffer.split(/\\r?\\n/);\n        buffer = lines.pop() || \"\"; // retain incomplete line in buffer\n\n        let currentEvent = \"message\";\n        let currentData = \"\";\n        let currentId = \"\";\n\n        for (const line of lines) {\n          const trimmed = line.trim();\n          if (!trimmed) {\n            // End of an SSE event block (empty line \\n\\n)\n            if (currentData) {\n              let parsedData: any = currentData;\n              try {\n                parsedData = JSON.parse(currentData);\n              } catch {\n                // Keep string if not valid JSON\n              }\n              this.config.onMessage?.({\n                event: currentEvent,\n                data: parsedData,\n                id: currentId || undefined,\n                raw: currentData,\n              });\n              currentEvent = \"message\";\n              currentData = \"\";\n              currentId = \"\";\n            }\n            continue;\n          }\n\n          if (trimmed.startsWith(\":\")) {\n            // Comment / keep-alive ping line\n            continue;\n          }\n\n          if (trimmed.startsWith(\"event:\")) {\n            currentEvent = trimmed.slice(6).trim();\n          } else if (trimmed.startsWith(\"data:\")) {\n            const dataPart = trimmed.slice(5).trim();\n            currentData = currentData ? `${currentData}\\n${dataPart}` : dataPart;\n          } else if (trimmed.startsWith(\"id:\")) {\n            currentId = trimmed.slice(3).trim();\n          }\n        }\n      }\n\n      // Stream completed normally (server closed connection)\n      this._connected = false;\n      if (!this.isExplicitlyClosed) {\n        this.scheduleReconnect();\n      }\n    } catch (error: any) {\n      this._connected = false;\n      if (signal.aborted || this.isExplicitlyClosed) {\n        return;\n      }\n      this.config.onError?.(error);\n      this.scheduleReconnect();\n    }\n  }\n\n  private connectViaEventSource(): void {\n    try {\n      const url = new URL(this.config.url, typeof window !== \"undefined\" ? window.location.href : \"http://localhost\");\n      if (this.config.token) {\n        url.searchParams.set(\"token\", this.config.token);\n      }\n\n      this.nativeEventSource = new EventSource(url.toString(), {\n        withCredentials: this.config.withCredentials || false,\n      });\n\n      this.nativeEventSource.onopen = () => {\n        this._connected = true;\n        this.reconnectDelay = this.config.initialReconnectDelay || 3000;\n        this.config.onOpen?.();\n        this.config.onConnectionStateChange?.(\"connected\");\n      };\n\n      this.nativeEventSource.onmessage = (e: MessageEvent) => {\n        let parsedData: any = e.data;\n        try {\n          parsedData = JSON.parse(e.data);\n        } catch {\n          // Keep raw string if not JSON\n        }\n        this.config.onMessage?.({\n          event: parsedData?.event || e.type || \"message\",\n          data: parsedData,\n          raw: typeof e.data === \"string\" ? e.data : undefined,\n        });\n      };\n\n      this.nativeEventSource.onerror = (err) => {\n        this._connected = false;\n        if (this.isExplicitlyClosed) return;\n        this.config.onError?.(err);\n        this.config.onConnectionStateChange?.(\"disconnected\");\n      };\n    } catch (err) {\n      this._connected = false;\n      this.config.onError?.(err);\n      this.scheduleReconnect();\n    }\n  }\n\n  private scheduleReconnect(): void {\n    if (this.isExplicitlyClosed) return;\n    this.cleanup();\n    this.config.onConnectionStateChange?.(\"disconnected\");\n\n    const maxDelay = this.config.maxReconnectDelay || 60000;\n    const currentDelay = this.reconnectDelay;\n    const jitter = Math.random() * 1000;\n    const nextDelay = Math.min(currentDelay + jitter, maxDelay);\n\n    this.reconnectDelay = Math.min(this.reconnectDelay * 2, maxDelay);\n\n    this.config.onConnectionStateChange?.(\"connecting\");\n    this.reconnectTimer = setTimeout(() => {\n      this.reconnectTimer = null;\n      if (!this.isExplicitlyClosed) {\n        this.connect();\n      }\n    }, nextDelay);\n  }\n\n  /**\n   * Stop the SSE connection and cancel reconnect timers\n   */\n  public close(): void {\n    this.isExplicitlyClosed = true;\n    this._connected = false;\n    this.cleanup();\n    this.config.onConnectionStateChange?.(\"disconnected\");\n  }\n\n  private cleanup(): void {\n    if (this.abortController) {\n      this.abortController.abort();\n      this.abortController = null;\n    }\n    if (this.nativeEventSource) {\n      this.nativeEventSource.close();\n      this.nativeEventSource = null;\n    }\n    if (this.reconnectTimer) {\n      clearTimeout(this.reconnectTimer);\n      this.reconnectTimer = null;\n    }\n  }\n}\n","export enum ECallEventName {\n    MEDIA_STATE = \"mediaState\",\n    STATE = \"state\",\n    LOCAL_STREAM = \"localStream\",\n    REMOTE_STREAM = \"remoteStream\",\n    MUTE = \"mute\",\n    CAMERA = \"camera\",\n    SCREEN_SHARE = \"screenShare\",\n    TRANSCRIPTION = \"transcription\",\n    TRANSCRIPTION_STARTED = \"transcription.started\",\n    TRANSCRIPTION_DIALOGUE = \"transcription.dialogue\",\n    TRANSCRIPTION_COMPLETED = \"transcription.completed\",\n    RECORDING = \"recording\",\n    RECORDING_STARTED = \"recording.started\",\n    RECORDING_COMPLETED = \"recording.completed\",\n}","export enum EClientEventName {\n    SESSION = \"session\",\n    ERROR = \"error\",\n    CALL_RING = \"call.ring\",\n    CALL_OFFER = \"call.offer\",\n    CALL_OFFERED = \"call.offered\",\n    CALL_CREATED = \"call.created\",\n    CALL_STARTED = \"call.started\",\n    CALL_ANSWERED = \"call.answered\",\n    CALL_ENDED = \"call.ended\",\n    CALL_CANCELED = \"call.canceled\",\n    CALL_HELD = \"call.held\",\n    CALL_UNHELD = \"call.unheld\",\n    CALL_TRANSFERRED = \"call.transferred\",\n    CALL_MUTE = \"call.mute\",\n    AGENT_STATE = \"agent.state\",\n    AGENT_STATE_FORCED = \"agent.state.forced\",\n    AGENT_CREATED = \"agent.created\",\n    AGENT_UPDATED = \"agent.updated\",\n    AGENT_DELETED = \"agent.deleted\",\n    RECONNECTED = \"reconnected\",\n    CONTACT_CREATED = \"contact.created\",\n    CONTACT_UPDATED = \"contact.updated\",\n    CONTACT_DELETED = \"contact.deleted\",\n    TEAM_CREATED = \"team.created\",\n    TEAM_UPDATED = \"team.updated\",\n    TEAM_DELETED = \"team.deleted\",\n    TEAM_ASSIGNED = \"team.assigned\",\n    TEAM_UNASSIGNED = \"team.unassigned\",\n    CONNECTION_STATE = \"connection.state\",\n    CALL_RECORDING_READY = \"call.recording.ready\",\n}","export enum ECallState {\n  'INITIATED' = 'INITIATED',\n  'TRYING' = 'TRYING',\n  'RINGING' = 'RINGING',\n  'ANSWERED' = 'ANSWERED',\n  'ACTIVE' = 'ACTIVE',\n  'ONHOLD' = 'ONHOLD',\n  'ENDED' = 'ENDED',\n  'ERROR' = 'ERROR',\n  'CANCEL' = 'CANCEL',\n  'NONE' = 'NONE',\n}\n","/**\n * API endpoint paths used by the SDK.\n * All paths are relative to the workspace base URL.\n */\nexport const API_ENDPOINTS = {\n  /** Workspace metadata (WS servers, ICE servers) */\n  WORKSPACE_METADATA: \"/api/v1\",\n  /** Agent login (username/password → JWT) */\n  AUTH_LOGIN: \"/api/v1/auth/login\",\n  /** REST Make Call Endpoint */\n  MAKE_CALL: \"/api/v1/call-center/calls\",\n  /** SSE Realtime Events Stream Endpoint */\n  EVENT_STREAM: \"/stream\",\n  /** Supervision Endpoints */\n  SUPERVISION: (callId: string, mode: string) => `/api/v1/call-center/calls/${callId}/${mode}`,\n  /** Stop Supervision Endpoint */\n  SUPERVISION_STOP: (callId: string) => `/api/v1/call-center/calls/${callId}/supervision`,\n  /** Call Transfer Endpoint */\n  TRANSFER: (callId: string) => `/api/v1/call-center/calls/${callId}/transfer`,\n  /** Agent Accessible Phone Numbers (DIDs) Endpoint */\n  PHONE_NUMBERS: \"/api/v1/call-center/phone-numbers\",\n} as const;\n","/**\n * Fallback ICE (STUN) servers used when workspace metadata is unavailable\n */\nexport const DEFAULT_ICE_SERVERS: RTCIceServer[] = [\n  {\n    urls: [\n      \"stun:stun.l.google.com:19302\",\n      \"stun:stun1.l.google.com:19302\",\n    ],\n  },\n  {\n    urls: [\"stun:stun.cloudflare.com:3478\"],\n  },\n];\n","import { ECallEventName } from \"./enums/call-event-name.enum\";\nimport { EClientEventName } from \"./enums/client-event-name.enum\";\nimport { ECallState } from \"./enums/call-state.enum\";\nimport { CallOptions } from \"./interfaces/call-options.interface\";\nimport {\n  ITranscriptionStartedEvent,\n  ITranscriptionDialogueEvent,\n  ITranscriptionCompletedEvent,\n} from \"./interfaces/transcription.interface\";\nimport {\n  ICallRecordingStartedEvent,\n  ICallRecordingCompletedEvent,\n} from \"./interfaces/recording.interface\";\nimport { SimpleEventEmitter, SseStreamClient, SseMessageEvent } from \"./utils\";\nimport { FiretellClient } from \"./firetell-client\";\nimport { DEFAULT_ICE_SERVERS, API_ENDPOINTS } from \"./constants\";\n\n/** Event-based Native WebSocket message shape */\nexport interface IWsEventMessage {\n  event: string;\n  data?: Record<string, unknown>;\n}\n\nexport class Call extends SimpleEventEmitter {\n  public callId: string | null = null;\n  public from: string;\n  public from_name: string;\n  public from_avatar: string | null = null;\n  public get avatar(): string | null {\n    return this.from_avatar;\n  }\n  public to: string;\n  public active: boolean = false;\n  private client: FiretellClient | null;\n  private ws: WebSocket | null = null;\n  private callSseClient: SseStreamClient | null = null;\n  private state: ECallState = ECallState.NONE;\n  private peerConnection: RTCPeerConnection;\n  public remoteDescription: RTCSessionDescriptionInit | null = null;\n  private localStream: MediaStream | null = null;\n  private remoteStream: MediaStream | null = null;\n  public isVideo: boolean | MediaTrackConstraints;\n  public isMuted: boolean = false;\n  public isCameraOff: boolean = false;\n  public isScreenSharing: boolean = false;\n  private _cameraTrack: MediaStreamTrack | null = null;\n  private _screenStream: MediaStream | null = null;\n  public isTransfer: boolean;\n  public transferReason?: string;\n  public isInternal: boolean;\n  private _destroying: boolean = false;\n  private currentRemoteSetupRole: string | null = null;\n\n  constructor(client: FiretellClient, options: CallOptions = {}) {\n    super();\n    if (!(client instanceof FiretellClient))\n      throw new Error(\"Missing or invalid client instance\");\n    this.client = client;\n    this.to = options.to || \"\";\n    this.from = options.from || \"\";\n    this.from_name = options.from_name || \"\";\n    this.from_avatar = options.from_avatar || null;\n    this.isVideo = options.isVideo || false;\n    this.isTransfer = options.isTransfer || false;\n    this.transferReason = options.transferReason;\n    this.isInternal = options.isInternal || false;\n    this.peerConnection = new RTCPeerConnection({\n      iceServers: this.client?.iceServers?.length\n        ? this.client.iceServers\n        : DEFAULT_ICE_SERVERS,\n    });\n  }\n\n  /**\n   * Open dedicated Native WebSocket signaling connection for this call session\n   * and authenticate with call_token within 3s.\n   */\n  public async connectSignaling(wsUrl: string, callToken: string): Promise<void> {\n    return new Promise((resolve, reject) => {\n      try {\n        this.ws = new WebSocket(wsUrl);\n\n        const authTimeout = setTimeout(() => {\n          if (this.ws && this.ws.readyState !== WebSocket.CLOSED) {\n            this.ws.close();\n            this.ws = null;\n          }\n          reject(new Error(\"Call WebSocket authentication timed out after 3s\"));\n        }, 3000);\n\n        this.ws.onopen = () => {\n          // Send session.connect with call_token\n          this.sendWsEvent(\"session.connect\", { call_token: callToken });\n        };\n\n        this.ws.onmessage = (event: MessageEvent) => {\n          try {\n            const parsed = JSON.parse(event.data) as IWsEventMessage;\n            this._handleWsMessage(parsed, () => {\n              clearTimeout(authTimeout);\n              resolve();\n            });\n          } catch (err) {\n            console.error(\"Call.connectSignaling::JSON parse error:\", err);\n          }\n        };\n\n        this.ws.onerror = (err) => {\n          clearTimeout(authTimeout);\n          this.emit(ECallEventName.STATE, { state: ECallState.ERROR, reason: \"WebSocket error\" });\n          reject(err);\n        };\n\n        this.ws.onclose = () => {\n          clearTimeout(authTimeout);\n          this.ws = null;\n          if (this.active && !this._destroying) {\n            this.destroy(false);\n          }\n        };\n      } catch (err) {\n        reject(err);\n      }\n    });\n  }\n\n  /**\n   * Helper to send JSON event message over this call's WebSocket\n   */\n  public sendWsEvent(event: string, data?: Record<string, unknown>): void {\n    if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n      this.ws.send(JSON.stringify({ event, data }));\n    }\n  }\n\n  /**\n   * Helper to extract a valid RTCSessionDescriptionInit from WS event data.\n   * Handles object formats { type, sdp }, nested { sdp: { type, sdp } }, or raw SDP strings.\n   */\n  private _extractSdpInit(data: unknown): RTCSessionDescriptionInit | null {\n    if (!data || typeof data !== \"object\") return null;\n    const obj = data as Record<string, unknown>;\n\n    if (obj.sdp && typeof obj.sdp === \"object\") {\n      const sdpObj = obj.sdp as Record<string, unknown>;\n      if (typeof sdpObj.sdp === \"string\") {\n        return {\n          type: (sdpObj.type as RTCSessionDescriptionInit[\"type\"]) || \"answer\",\n          sdp: sdpObj.sdp,\n        };\n      }\n    }\n\n    if (typeof obj.sdp === \"string\") {\n      return {\n        type: (obj.type as RTCSessionDescriptionInit[\"type\"]) || \"answer\",\n        sdp: obj.sdp,\n      };\n    }\n\n    if (typeof obj.type === \"string\" && typeof obj.sdp === \"string\") {\n      return {\n        type: obj.type as RTCSessionDescriptionInit[\"type\"],\n        sdp: obj.sdp,\n      };\n    }\n\n    return null;\n  }\n\n  /**\n   * Process incoming WebSocket signaling messages for this call\n   */\n  private _handleWsMessage(msg: IWsEventMessage, onConnectSuccess: () => void): void {\n    const { event, data } = msg;\n\n    switch (event) {\n      case \"session.connected\": {\n        onConnectSuccess();\n        break;\n      }\n      case \"session.error\": {\n        console.error(\"Call.handleWsMessage::session.error:\", data);\n        this.emit(ECallEventName.STATE, {\n          state: ECallState.ERROR,\n          reason: (data?.message as string) || \"Session error\",\n        });\n        break;\n      }\n      case \"call.offer\": {\n        if (data) {\n          const sdpInit = this._extractSdpInit(data);\n          if (sdpInit) {\n            this.remoteDescription = sdpInit;\n            void this.setRemoteDescription(this.remoteDescription);\n          }\n          if (data.from) this.from = (data.from as { number?: string })?.number || String(data.from);\n          if (data.from_name) this.from_name = String(data.from_name);\n          if (data.from_avatar !== undefined) this.from_avatar = (data.from_avatar as string) || null;\n          if (data.is_video !== undefined) {\n            this.isVideo = Boolean(data.is_video);\n          } else if (sdpInit?.sdp) {\n            this.isVideo = /m=video [1-9]/.test(sdpInit.sdp);\n          }\n          if (data.is_transfer !== undefined) this.isTransfer = Boolean(data.is_transfer);\n          if (data.transfer_reason !== undefined) this.transferReason = String(data.transfer_reason);\n        }\n        this.state = ECallState.RINGING;\n        this.emit(ECallEventName.STATE, { state: ECallState.RINGING, data });\n        if (this.client) {\n          this.client.events.emit(EClientEventName.CALL_OFFER, this);\n        }\n        break;\n      }\n      case \"call.answered\": {\n        const sdpInit = this._extractSdpInit(data);\n        if (sdpInit) {\n          void this.setRemoteDescription(sdpInit);\n        }\n        this.state = ECallState.ACTIVE;\n        this.active = true;\n        this.emit(ECallEventName.STATE, { state: ECallState.ANSWERED, data });\n        break;\n      }\n      case \"call.held\": {\n        const sdpInit = this._extractSdpInit(data);\n        if (sdpInit) {\n          void this.setRemoteDescription(sdpInit);\n        }\n        this.state = ECallState.ONHOLD;\n        this.emit(ECallEventName.STATE, { state: ECallState.ONHOLD, data });\n        break;\n      }\n      case \"call.unheld\": {\n        const sdpInit = this._extractSdpInit(data);\n        if (sdpInit) {\n          void this.setRemoteDescription(sdpInit);\n        }\n        this.state = ECallState.ACTIVE;\n        this.emit(ECallEventName.STATE, { state: ECallState.ACTIVE, data });\n        break;\n      }\n      case \"call.camera\": {\n        this.emit(ECallEventName.CAMERA, {\n          enabled: Boolean(data?.enabled),\n          remote: true,\n          data,\n        });\n        break;\n      }\n      case \"call.screen_share\": {\n        this.emit(ECallEventName.SCREEN_SHARE, {\n          sharing: Boolean(data?.sharing),\n          remote: true,\n          data,\n        });\n        break;\n      }\n      case \"call.ended\":\n      case \"call.rejected\":\n      case \"call.canceled\": {\n        this.state = ECallState.ENDED;\n        const reason = (data?.reason as string) || event;\n        this.emit(ECallEventName.STATE, {\n          state: ECallState.ENDED,\n          reason,\n          data,\n        });\n        if (this.client) {\n          const clientEvent =\n            event === \"call.canceled\"\n              ? EClientEventName.CALL_CANCELED\n              : EClientEventName.CALL_ENDED;\n          this.client.events.emit(clientEvent, {\n            call: this,\n            call_id: this.callId,\n            event,\n            reason,\n            data,\n          });\n        }\n        this.destroy(false);\n        break;\n      }\n      case \"call.sdp\": {\n        const sdpInit = this._extractSdpInit(data);\n        if (sdpInit) {\n          void this.setRemoteDescription(sdpInit);\n        }\n        break;\n      }\n      case \"call.state\": {\n        const sdpInit = this._extractSdpInit(data);\n        if (sdpInit) {\n          void this.setRemoteDescription(sdpInit);\n        }\n        if (data?.state) {\n          const nextState = (data.state as ECallState) || ECallState.RINGING;\n          this.state = nextState === ECallState.ANSWERED ? ECallState.ACTIVE : nextState;\n        }\n        this.emit(ECallEventName.STATE, data || {});\n        break;\n      }\n    }\n  }\n\n  /**\n   * Register a callback for all transcription events on this call (started, dialogue, completed).\n   */\n  public onTranscription(\n    listener: (event: {\n      type: \"started\" | \"dialogue\" | \"completed\";\n      data:\n        | ITranscriptionStartedEvent\n        | ITranscriptionDialogueEvent\n        | ITranscriptionCompletedEvent;\n    }) => void\n  ): () => void {\n    this.on(ECallEventName.TRANSCRIPTION, listener);\n    return () => this.off(ECallEventName.TRANSCRIPTION, listener);\n  }\n\n  /**\n   * Register a callback for real-time speech dialogue transcription chunks.\n   */\n  public onDialogue(\n    listener: (dialogue: ITranscriptionDialogueEvent) => void\n  ): () => void {\n    this.on(ECallEventName.TRANSCRIPTION_DIALOGUE, listener);\n    return () => this.off(ECallEventName.TRANSCRIPTION_DIALOGUE, listener);\n  }\n\n  /**\n   * Register a callback for active call recording events (started, completed).\n   */\n  public onRecording(\n    listener: (event: {\n      type: \"started\" | \"completed\";\n      data: ICallRecordingStartedEvent | ICallRecordingCompletedEvent;\n    }) => void\n  ): () => void {\n    this.on(ECallEventName.RECORDING, listener);\n    return () => this.off(ECallEventName.RECORDING, listener);\n  }\n\n  /**\n   * Connect dedicated per-call Server-Sent Events (SSE) stream for live transcription and telemetry.\n   * Subscribes to `/stream?call_id=<callId>` using the call session token.\n   */\n  public connectCallEventStream(callToken?: string): void {\n    if (!this.client || !this.callId) return;\n\n    // Prevent opening multiple SSE streams for the same call session\n    if (this.callSseClient) return;\n\n    try {\n      const sseUrl = `${this.client.getBaseUrl()}${API_ENDPOINTS.EVENT_STREAM}?call_id=${encodeURIComponent(\n        this.callId\n      )}`;\n      const token = callToken || this.client.getJwt();\n\n      this.callSseClient = new SseStreamClient({\n        url: sseUrl,\n        token,\n        onMessage: (msg: SseMessageEvent) => {\n          this._handleSseMessage(msg);\n        },\n        onError: (err) => {\n          console.warn(`Call[${this.callId}] SSE stream warning:`, err);\n        },\n      });\n\n      this.callSseClient.connect();\n    } catch (err) {\n      console.warn(`Call[${this.callId}] SSE connection failed:`, err);\n    }\n  }\n\n  /**\n   * Process incoming Server-Sent Events for this specific call session.\n   */\n  private _handleSseMessage(msg: SseMessageEvent): void {\n    const { event, data } = msg;\n    let payload = data;\n    if (typeof payload === \"string\") {\n      try {\n        payload = JSON.parse(payload);\n      } catch {\n        // use raw string\n      }\n    }\n    const d = (payload?.data || payload) || {};\n\n    switch (event) {\n      case \"call.transcription.started\":\n      case \"transcription.started\": {\n        const item = d as ITranscriptionStartedEvent;\n        this.emit(ECallEventName.TRANSCRIPTION_STARTED, item);\n        this.emit(ECallEventName.TRANSCRIPTION, { type: \"started\", data: item });\n        break;\n      }\n      case \"call.transcription.dialogue\":\n      case \"transcription.dialogue\": {\n        const item = d as ITranscriptionDialogueEvent;\n        this.emit(ECallEventName.TRANSCRIPTION_DIALOGUE, item);\n        this.emit(ECallEventName.TRANSCRIPTION, { type: \"dialogue\", data: item });\n        break;\n      }\n      case \"call.transcription.completed\":\n      case \"transcription.completed\": {\n        const item = d as ITranscriptionCompletedEvent;\n        this.emit(ECallEventName.TRANSCRIPTION_COMPLETED, item);\n        this.emit(ECallEventName.TRANSCRIPTION, { type: \"completed\", data: item });\n        break;\n      }\n      case \"call.recording.started\":\n      case \"recording.started\": {\n        const item = d as ICallRecordingStartedEvent;\n        this.emit(ECallEventName.RECORDING_STARTED, item);\n        this.emit(ECallEventName.RECORDING, { type: \"started\", data: item });\n        break;\n      }\n      case \"call.recording.completed\":\n      case \"recording.completed\": {\n        const item = d as ICallRecordingCompletedEvent;\n        this.emit(ECallEventName.RECORDING_COMPLETED, item);\n        this.emit(ECallEventName.RECORDING, { type: \"completed\", data: item });\n        break;\n      }\n      default: {\n        this.emit(event, d);\n        break;\n      }\n    }\n  }\n\n  /**\n   * Start an outbound call.\n   * Initiates REST call creation, connects dedicated WS signaling,\n   * gathers full ICE candidates, and sends call.offer.\n   */\n  public async start(): Promise<void> {\n    if (!this.client) throw new Error(\"Client is not attached to Call\");\n    this.active = true;\n    this.state = ECallState.INITIATED;\n    try {\n      await this._setupWebrtcMedia({ video: this.isVideo, audio: true });\n      const offer = await this.peerConnection.createOffer();\n      await this.peerConnection.setLocalDescription(offer);\n\n      // Wait for all ICE candidates to be gathered (Full ICE, not Trickle)\n      const sdp = await this._getSDPFull();\n      const res = await this.client.initiateCallRest(this.to, this.from, Boolean(this.isVideo));\n      this.callId = res.call_id;\n\n      // Connect dedicated WS for this call session\n      await this.connectSignaling(res.ws_url, res.call_token);\n\n      // Connect dedicated SSE stream for this call session\n      this.connectCallEventStream(res.call_token);\n\n      // Send call.offer over WebSocket\n      this.sendWsEvent(\"call.offer\", { sdp: sdp.sdp });\n      this.active = true;\n    } catch (error: unknown) {\n      this.active = false;\n      this.state = ECallState.ERROR;\n      this.destroy(false);\n      throw error instanceof Error ? error : new Error(String(error));\n    }\n  }\n\n  /**\n   * Join an existing call session (e.g. Supervision: Listen, Whisper, Barge)\n   * using a pre-generated call_token and ws_url.\n   */\n  public async joinSession(\n    wsUrl: string,\n    callToken: string,\n    mode: \"listen\" | \"whisper\" | \"barge\" = \"listen\"\n  ): Promise<void> {\n    this.active = true;\n    this.state = ECallState.INITIATED;\n    try {\n      const isListenMode = mode === \"listen\";\n      // In listen (silent monitor) mode: do NOT request microphone permission / getUserMedia.\n      // Use WebRTC recvonly transceiver so browser shows no active microphone indicator.\n      await this._setupWebrtcMedia({\n        video: Boolean(this.isVideo),\n        audio: isListenMode ? false : true,\n      });\n      const offer = await this.peerConnection.createOffer();\n      await this.peerConnection.setLocalDescription(offer);\n\n      const sdp = await this._getSDPFull();\n      await this.connectSignaling(wsUrl, callToken);\n\n      // Connect dedicated SSE stream for this call session\n      this.connectCallEventStream(callToken);\n\n      this.sendWsEvent(\"call.offer\", { sdp: sdp.sdp });\n      this.active = true;\n    } catch (error: unknown) {\n      this.active = false;\n      this.state = ECallState.ERROR;\n      this.destroy(false);\n      throw error instanceof Error ? error : new Error(String(error));\n    }\n  }\n\n  /**\n   * Hang up this call\n   */\n  public async hangup(): Promise<void> {\n    if (!this.active) return;\n    this.active = false;\n    if (this.callId && this.ws && this.ws.readyState === WebSocket.OPEN) {\n      this.sendWsEvent(\"call.hangup\", {});\n    }\n    this.destroy(false);\n  }\n\n  /**\n   * Accept an incoming call.\n   * Sets up WebRTC media, sets remote description, creates answer,\n   * gathers full ICE, then sends call.answer over WebSocket.\n   */\n  public async accept(): Promise<void> {\n    if (!this.callId) throw new Error(\"callId is missing\");\n    if (!this.remoteDescription) throw new Error(\"remoteDescription is missing\");\n    // Ensure isVideo is accurately detected from remote offer SDP if not explicitly set\n    if (!this.isVideo && this.remoteDescription?.sdp) {\n      this.isVideo = /m=video [1-9]/.test(this.remoteDescription.sdp);\n    }\n    try {\n      await this._setupWebrtcMedia({ video: this.isVideo, audio: true });\n      await this.setRemoteDescription(this.remoteDescription);\n      const answer = await this.peerConnection.createAnswer();\n      await this.peerConnection.setLocalDescription(answer);\n      const sdp = await this._getSDPFull();\n\n      this.sendWsEvent(\"call.answer\", {\n        sdp: sdp.sdp,\n      });\n\n      // Connect dedicated per-call SSE stream for live transcription and telemetry\n      this.connectCallEventStream();\n\n      this.active = true;\n      this.state = ECallState.ANSWERED;\n    } catch (error: unknown) {\n      this.active = false;\n      this.state = ECallState.ERROR;\n      this.destroy(false);\n      throw error instanceof Error ? error : new Error(String(error));\n    }\n  }\n\n  /**\n   * Reject an incoming call\n   */\n  public async reject(): Promise<void> {\n    if (this.callId && this.ws && this.ws.readyState === WebSocket.OPEN) {\n      this.sendWsEvent(\"call.reject\", {});\n    }\n    this.destroy(false);\n  }\n\n  /**\n   * Transfer the call to another target.\n   * Target can be: extension number (e.g. \"100\"), agent username,\n   * team ID (te_...), or SIP account ID (si_...).\n   * @param target Transfer target identifier\n   * @param reason Optional transfer reason\n   */\n  public async transfer(\n    target: string,\n    reason?: string\n  ): Promise<void> {\n    if (!this.active) {\n      throw new Error(\"Cannot transfer: call is not active\");\n    }\n    if (!target) {\n      throw new Error(\"Target is required for call transfer\");\n    }\n    if (!this.callId) return;\n    if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n      this.sendWsEvent(\"call.transfer\", {\n        target,\n        reason: reason || undefined,\n      });\n    }\n    this.active = false;\n    this._cleanupPeerConnection();\n    if (this.client && this.callId) {\n      this.client.activeCalls.delete(this.callId);\n    }\n    this.state = ECallState.ENDED;\n    this.emit(ECallEventName.STATE, { state: ECallState.ENDED, reason: \"Transferred\" });\n  }\n\n  /**\n   * Send a DTMF tone\n   * @param digit Single digit: 0-9, *, #, A-D\n   * @param duration Duration in ms (default: 250)\n   */\n  public async sendDTMF(digit: string, duration?: number): Promise<void> {\n    if (!this.active) {\n      throw new Error(\"Cannot send DTMF: call is not active\");\n    }\n    if (!this.callId) return;\n    this.sendWsEvent(\"call.dtmf\", {\n      digit,\n      duration: duration || 250,\n    });\n  }\n\n  /**\n   * Mute the microphone.\n   * Stops local audio tracks and notifies the server.\n   */\n  public async mute(): Promise<void> {\n    if (!this.active) {\n      throw new Error(\"Cannot mute: call is not active\");\n    }\n    if (!this.callId) return;\n    if (this.localStream) {\n      this.localStream.getAudioTracks().forEach((track) => {\n        track.enabled = false;\n      });\n    }\n    this.isMuted = true;\n    this.sendWsEvent(\"call.mute\", { muted: true });\n    this.emit(ECallEventName.MUTE, { muted: true });\n  }\n\n  /**\n   * Unmute the microphone.\n   * Resumes local audio tracks and notifies the server.\n   */\n  public async unmute(): Promise<void> {\n    if (!this.active) {\n      throw new Error(\"Cannot unmute: call is not active\");\n    }\n    if (!this.callId) return;\n    if (this.localStream) {\n      this.localStream.getAudioTracks().forEach((track) => {\n        track.enabled = true;\n      });\n    }\n    this.isMuted = false;\n    this.sendWsEvent(\"call.mute\", { muted: false });\n    this.emit(ECallEventName.MUTE, { muted: false });\n  }\n\n  /**\n   * Toggle mute state\n   */\n  public async toggleMute(): Promise<void> {\n    if (this.isMuted) {\n      await this.unmute();\n    } else {\n      await this.mute();\n    }\n  }\n\n  /**\n   * Mute / disable local camera video track.\n   * Remote party will receive black frames / paused stream.\n   */\n  public async muteVideo(): Promise<void> {\n    if (!this.active) {\n      throw new Error(\"Cannot mute video: call is not active\");\n    }\n    if (this.localStream) {\n      this.localStream.getVideoTracks().forEach((track) => {\n        track.enabled = false;\n      });\n    }\n    this.isCameraOff = true;\n    if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n      this.sendWsEvent(\"call.camera\", { enabled: false });\n    }\n    this.emit(ECallEventName.CAMERA, { enabled: false, remote: false });\n  }\n\n  /**\n   * Unmute / enable local camera video track.\n   */\n  public async unmuteVideo(): Promise<void> {\n    if (!this.active) {\n      throw new Error(\"Cannot unmute video: call is not active\");\n    }\n    if (this.localStream) {\n      this.localStream.getVideoTracks().forEach((track) => {\n        track.enabled = true;\n      });\n    }\n    this.isCameraOff = false;\n    if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n      this.sendWsEvent(\"call.camera\", { enabled: true });\n    }\n    this.emit(ECallEventName.CAMERA, { enabled: true, remote: false });\n  }\n\n  /**\n   * Toggle camera mute state\n   */\n  public async toggleCamera(): Promise<void> {\n    if (this.isCameraOff) {\n      await this.unmuteVideo();\n    } else {\n      await this.muteVideo();\n    }\n  }\n\n  /**\n   * Start sharing screen via navigator.mediaDevices.getDisplayMedia.\n   * Replaces the active video track on RTCRtpSender without renegotiating SDP.\n   */\n  public async startScreenShare(): Promise<void> {\n    if (!this.active) {\n      throw new Error(\"Cannot start screen share: call is not active\");\n    }\n    if (!this.isVideo) {\n      throw new Error(\"Screen sharing is only available on video calls\");\n    }\n    if (this.isScreenSharing) return;\n\n    if (!navigator?.mediaDevices?.getDisplayMedia) {\n      throw new Error(\"getDisplayMedia is not supported in this browser\");\n    }\n\n    try {\n      const screenStream = await navigator.mediaDevices.getDisplayMedia({\n        video: true,\n        audio: false,\n      });\n      const screenTrack = screenStream.getVideoTracks()[0];\n      if (!screenTrack) {\n        throw new Error(\"No video track found in display media stream\");\n      }\n\n      const videoSender = this.peerConnection\n        ?.getSenders()\n        .find((s) => s.track && s.track.kind === \"video\");\n\n      if (!videoSender) {\n        screenStream.getTracks().forEach((t) => t.stop());\n        throw new Error(\"No active video sender found in peer connection\");\n      }\n\n      // Save original camera track\n      this._cameraTrack = videoSender.track;\n      this._screenStream = screenStream;\n\n      // Replace track on RTCRtpSender seamlessly\n      await videoSender.replaceTrack(screenTrack);\n\n      // Replace video track in localStream so preview shows screen share\n      if (this.localStream) {\n        const oldTrack = this.localStream.getVideoTracks()[0];\n        if (oldTrack) {\n          this.localStream.removeTrack(oldTrack);\n        }\n        this.localStream.addTrack(screenTrack);\n        this.emit(ECallEventName.LOCAL_STREAM, this.localStream);\n      }\n\n      this.isScreenSharing = true;\n\n      // Native browser \"Stop sharing\" hook\n      screenTrack.onended = () => {\n        void this.stopScreenShare();\n      };\n\n      if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n        this.sendWsEvent(\"call.screen_share\", { sharing: true });\n      }\n      this.emit(ECallEventName.SCREEN_SHARE, { sharing: true, remote: false });\n    } catch (err: unknown) {\n      if (this._screenStream) {\n        this._screenStream.getTracks().forEach((t) => t.stop());\n        this._screenStream = null;\n      }\n      this.isScreenSharing = false;\n      throw err instanceof Error ? err : new Error(String(err));\n    }\n  }\n\n  /**\n   * Stop sharing screen and restore original camera video track.\n   */\n  public async stopScreenShare(): Promise<void> {\n    if (!this.isScreenSharing) return;\n\n    try {\n      const videoSender = this.peerConnection\n        ?.getSenders()\n        .find((s) => s.track && s.track.kind === \"video\");\n\n      // Stop screen stream tracks\n      if (this._screenStream) {\n        this._screenStream.getTracks().forEach((t) => t.stop());\n        this._screenStream = null;\n      }\n\n      // Restore camera track if available\n      if (videoSender && this._cameraTrack) {\n        await videoSender.replaceTrack(this._cameraTrack);\n\n        if (this.localStream) {\n          const oldTrack = this.localStream.getVideoTracks()[0];\n          if (oldTrack) {\n            this.localStream.removeTrack(oldTrack);\n          }\n          this.localStream.addTrack(this._cameraTrack);\n          this.emit(ECallEventName.LOCAL_STREAM, this.localStream);\n        }\n      }\n\n      this.isScreenSharing = false;\n      this._cameraTrack = null;\n\n      if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n        this.sendWsEvent(\"call.screen_share\", { sharing: false });\n      }\n      this.emit(ECallEventName.SCREEN_SHARE, { sharing: false, remote: false });\n    } catch (err: unknown) {\n      this.isScreenSharing = false;\n      this._cameraTrack = null;\n      throw err instanceof Error ? err : new Error(String(err));\n    }\n  }\n\n  /**\n   * Toggle screen sharing state\n   */\n  public async toggleScreenShare(): Promise<void> {\n    if (this.isScreenSharing) {\n      await this.stopScreenShare();\n    } else {\n      await this.startScreenShare();\n    }\n  }\n\n  /**\n   * Put the call on hold\n   */\n  public async onhold(): Promise<void> {\n    if (!this.callId) return;\n    this.peerConnection.getTransceivers().forEach((t) => {\n      if (t.sender.track) {\n        t.direction = \"sendonly\";\n      }\n    });\n\n    const offer = await this.peerConnection.createOffer();\n    await this.peerConnection.setLocalDescription(offer);\n    const sdp = await this._getSDPFull();\n    this.sendWsEvent(\"call.hold\", { sdp: sdp.sdp });\n    this.state = ECallState.ONHOLD;\n    this.emit(ECallEventName.STATE, { state: ECallState.ONHOLD });\n  }\n\n  /**\n   * Resume a held call\n   */\n  public async unhold(): Promise<void> {\n    if (this.state !== ECallState.ONHOLD) {\n      throw new Error(\"Call is not on hold\");\n    }\n    if (!this.callId) return;\n    this.peerConnection.getTransceivers().forEach((t) => {\n      if (t.sender.track) {\n        t.direction = \"sendrecv\";\n      }\n    });\n\n    const offer = await this.peerConnection.createOffer();\n    await this.peerConnection.setLocalDescription(offer);\n    const sdp = await this._getSDPFull();\n    this.sendWsEvent(\"call.unhold\", { sdp: sdp.sdp });\n    this.state = ECallState.ACTIVE;\n    this.emit(ECallEventName.STATE, { state: ECallState.ACTIVE });\n  }\n\n  /**\n   * Update call signaling state from server notification\n   */\n  public setSignalState(state: ECallState, params: Record<string, unknown>): void {\n    this.state = state === ECallState.ANSWERED ? ECallState.ACTIVE : state;\n    this.emit(ECallEventName.STATE, params);\n  }\n\n  /**\n   * Get current call state\n   */\n  public get callState(): ECallState {\n    return this.state;\n  }\n\n  /**\n   * Whether the call is currently on hold\n   */\n  public get isHold(): boolean {\n    return this.state === ECallState.ONHOLD;\n  }\n\n  /**\n   * Destroy/cleanup this call instance.\n   * Closes WebRTC PeerConnection, stops local/remote media tracks,\n   * closes dedicated WebSocket connection, and clears event listeners.\n   * @param sendHangup Whether to send call.hangup event to server (default: true, set to false for transfers)\n   */\n  public async destroy(sendHangup: boolean = true): Promise<void> {\n    if (this._destroying) return;\n    this._destroying = true;\n\n    if (sendHangup && this.active && this.callId && this.ws && this.ws.readyState === WebSocket.OPEN) {\n      this.sendWsEvent(\"call.hangup\", {});\n    }\n    this.active = false;\n\n    // Close dedicated Call WebSocket\n    if (this.ws) {\n      try {\n        this.ws.close();\n      } catch {\n        // Ignore WebSocket close errors during cleanup\n      }\n      this.ws = null;\n    }\n\n    // Close dedicated Call SSE Stream\n    if (this.callSseClient) {\n      try {\n        this.callSseClient.close();\n      } catch {\n        // Ignore SSE close errors during cleanup\n      }\n      this.callSseClient = null;\n    }\n\n    if (this.client && this.callId) {\n      this.client.activeCalls.delete(this.callId);\n    }\n    this.client = null;\n\n    this._cleanupPeerConnection();\n\n    if (this.state !== ECallState.ENDED && this.state !== ECallState.ERROR) {\n      this.state = ECallState.ENDED;\n      this.emit(ECallEventName.STATE, { state: ECallState.ENDED, reason: \"Local Hangup\" });\n    }\n\n    this.offAll();\n  }\n\n  /**\n   * Set the remote SDP description on the peer connection\n   */\n  public async setRemoteDescription(\n    sdp: RTCSessionDescriptionInit\n  ): Promise<void> {\n    try {\n      if (sdp.type === \"answer\" && this.peerConnection.signalingState === \"stable\") {\n        return;\n      }\n\n      let sdpText = sdp.sdp || \"\";\n\n      // Extract DTLS setup role (active/passive/actpass) from SDP\n      const setupMatch = sdpText.match(/a=setup:(active|passive|actpass)/);\n\n      if (setupMatch) {\n        if (!this.currentRemoteSetupRole) {\n          // Record initial established DTLS role from server (must be 'active' or 'passive')\n          if (setupMatch[1] === \"active\" || setupMatch[1] === \"passive\") {\n            this.currentRemoteSetupRole = setupMatch[1];\n          }\n        } else if (\n          (setupMatch[1] === \"active\" || setupMatch[1] === \"passive\") &&\n          setupMatch[1] !== this.currentRemoteSetupRole\n        ) {\n          // Preserve established DTLS role during renegotiation (hold/unhold) to prevent 'Failed to set SSL role for the transport'\n          sdpText = sdpText.replace(\n            /a=setup:(active|passive|actpass)/g,\n            `a=setup:${this.currentRemoteSetupRole}`\n          );\n        }\n      }\n\n      const finalSdp: RTCSessionDescriptionInit = {\n        type: sdp.type,\n        sdp: sdpText,\n      };\n\n      await this.peerConnection.setRemoteDescription(\n        new RTCSessionDescription(finalSdp)\n      );\n    } catch (error) {\n      console.error(\"setRemoteDescription:\", error);\n    }\n  }\n\n  /**\n   * Setup WebRTC media (getUserMedia + peerConnection)\n   */\n  private async _setupWebrtcMedia(\n    constraints: MediaStreamConstraints\n  ): Promise<boolean> {\n    try {\n      this._cleanupPeerConnection();\n      this.peerConnection = new RTCPeerConnection({\n        iceServers: this.client?.iceServers?.length\n          ? this.client.iceServers\n          : DEFAULT_ICE_SERVERS,\n      });\n\n      this.peerConnection.oniceconnectionstatechange = () => {\n        this.emit(\n          ECallEventName.MEDIA_STATE,\n          this.peerConnection.iceConnectionState\n        );\n      };\n\n      // Process remote stream\n      this.peerConnection.ontrack = (event) => {\n        let remoteStream = event.streams && event.streams[0];\n        if (!remoteStream) {\n          if (!this.remoteStream) {\n            this.remoteStream = new MediaStream();\n          }\n          this.remoteStream.addTrack(event.track);\n          remoteStream = this.remoteStream;\n        } else {\n          this.remoteStream = remoteStream;\n        }\n        this.emit(ECallEventName.REMOTE_STREAM, remoteStream);\n      };\n\n      if (constraints.audio || constraints.video) {\n        this.localStream = await navigator.mediaDevices.getUserMedia(constraints);\n\n        // Add local tracks to peer connection\n        this.localStream.getTracks().forEach((track) =>\n          this.peerConnection.addTrack(track, this.localStream!)\n        );\n        this.emit(ECallEventName.LOCAL_STREAM, this.localStream);\n      } else {\n        // Receive-only mode (e.g. Listen / Silent Monitor): NO microphone requested!\n        this.peerConnection.addTransceiver(\"audio\", { direction: \"recvonly\" });\n      }\n\n      return true;\n    } catch (error: unknown) {\n      throw error instanceof Error ? error : new Error(String(error));\n    }\n  }\n\n  /**\n   * Wait for ICE candidates to be gathered and return full SDP.\n   * Firetell media servers do not support Trickle ICE.\n   */\n  private async _getSDPFull(): Promise<RTCSessionDescription> {\n    return new Promise((resolve, reject) => {\n      const pc = this.peerConnection;\n\n      let isFinished = false;\n      let timeoutTimer: ReturnType<typeof setTimeout> | null = null;\n      let fallbackTimer: ReturnType<typeof setTimeout> | null = null;\n\n      const finish = () => {\n        if (isFinished) return;\n        isFinished = true;\n        if (pc) {\n          pc.onicecandidate = null;\n          pc.onicegatheringstatechange = null;\n        }\n        if (timeoutTimer) clearTimeout(timeoutTimer);\n        if (fallbackTimer) clearTimeout(fallbackTimer);\n\n        if (pc && pc.localDescription) {\n          resolve(pc.localDescription);\n        } else {\n          reject(new Error(\"No local description after ICE gathering\"));\n        }\n      };\n\n      // Check if ICE gathering is already complete\n      if (pc.iceGatheringState === \"complete\") {\n        finish();\n        return;\n      }\n\n      // Hard safety timeout of 6 seconds\n      timeoutTimer = setTimeout(() => {\n        if (pc.localDescription) {\n          finish();\n        } else {\n          if (pc) {\n            pc.onicecandidate = null;\n            pc.onicegatheringstatechange = null;\n          }\n          reject(new Error(\"ICE gathering timed out after 6s\"));\n        }\n      }, 6000);\n\n      // Fallback: If 3 seconds pass and STUN Public IP candidate (typ srflx) or Relay (typ relay) is present\n      fallbackTimer = setTimeout(() => {\n        if (\n          pc.localDescription &&\n          (/typ srflx/.test(pc.localDescription.sdp) || /typ relay/.test(pc.localDescription.sdp))\n        ) {\n          finish();\n        }\n      }, 3000);\n\n      pc.onicecandidate = (event) => {\n        if (!event.candidate) {\n          // ICE gathering complete (null candidate signals end)\n          finish();\n        }\n      };\n\n      pc.onicegatheringstatechange = () => {\n        if (pc.iceGatheringState === \"complete\") {\n          finish();\n        }\n      };\n    });\n  }\n\n  /**\n   * Cleanup the peer connection and streams\n   */\n  private _cleanupPeerConnection(): void {\n    this.isMuted = false;\n    this.currentRemoteSetupRole = null;\n    if (this.peerConnection) {\n      this.peerConnection.onicecandidate = null;\n      this.peerConnection.oniceconnectionstatechange = null;\n      this.peerConnection.onicegatheringstatechange = null;\n      this.peerConnection.onconnectionstatechange = null;\n      this.peerConnection.ontrack = null;\n      this.peerConnection.close();\n    }\n    if (this._screenStream) {\n      this._screenStream.getTracks().forEach((track) => track.stop());\n      this._screenStream = null;\n    }\n    this._cameraTrack = null;\n    this.isCameraOff = false;\n    this.isScreenSharing = false;\n    if (this.localStream) {\n      this.localStream.getTracks().forEach((track) => track.stop());\n      this.localStream = null;\n      this.emit(ECallEventName.LOCAL_STREAM, null);\n    }\n    if (this.remoteStream) {\n      this.remoteStream = null;\n      this.emit(ECallEventName.REMOTE_STREAM, null);\n    }\n  }\n}\n","import { SimpleEventEmitter, SseStreamClient, SseMessageEvent } from \"./utils\";\nimport { Call } from \"./call\";\nimport { ISession } from \"./interfaces/session.interface\";\nimport { ECallState } from \"./enums/call-state.enum\";\nimport { ECallEventName } from \"./enums/call-event-name.enum\";\nimport { EClientEventName } from \"./enums/client-event-name.enum\";\nimport { EStorageKey } from \"./enums/storage-key.enum\";\nimport { CallOptions } from \"./interfaces/call-options.interface\";\nimport { IJwtPayload } from \"./interfaces/jwt-payload.interface\";\nimport { IClientPhoneNumbersResponse } from \"./interfaces/phone-number.interface\";\nimport { API_ENDPOINTS } from \"./constants/api-endpoints\";\nimport { DEFAULT_ICE_SERVERS } from \"./constants/ice-servers\";\n\ndeclare const __SDK_VERSION__: string;\nexport const SDK_VERSION = typeof __SDK_VERSION__ !== \"undefined\" ? __SDK_VERSION__ : \"1.0.1\";\n\n/** Params for a call.ring notification */\nexport interface ICallRingParams {\n  call_id: string;\n  call_token: string;\n  ws_url?: string;\n  from?: {\n    number: string;\n    name?: string;\n    avatar?: string | null;\n  };\n  to?: {\n    number: string;\n    name?: string;\n  };\n  is_transfer?: boolean;\n  transfer_reason?: string;\n  is_video?: boolean;\n  timestamp?: string;\n}\n\n/** Params for a call.offer (incoming call) notification */\ninterface ICallOfferParams {\n  call_id: string;\n  from: string;\n  from_name?: string;\n  from_avatar?: string | null;\n  to: string;\n  sdp: RTCSessionDescriptionInit;\n  is_transfer?: boolean;\n  transfer_reason?: string;\n  is_video?: boolean;\n}\n\n/** Response from REST Make Call API */\nexport interface IMakeCallResponse {\n  call_id: string;\n  status: string;\n  call_token: string;\n  ws_url: string;\n  expires_in: number;\n}\n\n/** Response from REST Supervision API */\nexport interface ISupervisionResponse {\n  call_id: string;\n  mode: \"listen\" | \"whisper\" | \"barge\";\n  supervisor: string;\n  status: string;\n  call_token: string;\n  ws_url: string;\n  expires_in: number;\n}\n\nexport class FiretellClient {\n  public static readonly VERSION = SDK_VERSION;\n  public readonly sdkVersion = SDK_VERSION;\n  private baseUrl = \"\";\n  private jwt: string = \"\";\n  private jwtPayload: IJwtPayload | null = null;\n  private wsServers: string[] = [];\n  public iceServers: RTCIceServer[] = DEFAULT_ICE_SERVERS;\n  private session: ISession | null = null;\n  private isReconnecting: boolean = false;\n  private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n  private reconnectDelay = 3000;\n  private webRTCChecked: boolean = false;\n  private sseClient: SseStreamClient | null = null;\n  private knownCallStates = new Map<string, { status: string; weight: number; timestamp: number }>();\n\n  /**\n   * Event emitter for client events\n   * @events session, incomingCall, error, reconnected, workspace.agent.state\n   */\n  public events = new SimpleEventEmitter();\n  public isWebRTCSupport: boolean = false;\n  public connected: boolean = false;\n\n  /**\n   * Promise that resolves when the client is fully initialized\n   */\n  public readonly ready: Promise<ISession>;\n  private _resolveReady!: (session: ISession) => void;\n  private _rejectReady!: (error: Error) => void;\n\n  /**\n   * Current active calls Map<call_id, Call>\n   */\n  public readonly activeCalls = new Map<string, Call>();\n\n  /**\n   * FiretellClient constructor\n   * @param jwt Json Web Token\n   * @param domain Workspace API domain\n   */\n  constructor(jwt: string, domain: string) {\n    if (!jwt) throw new Error(\"jwt is required in constructor\");\n    const payload = this._parseJwt(jwt);\n    if (!payload) throw new Error(\"Invalid JWT\");\n    this.jwt = jwt;\n    this.jwtPayload = payload;\n    this.ready = new Promise<ISession>((resolve, reject) => {\n      this._resolveReady = resolve;\n      this._rejectReady = reject;\n    });\n    this.baseUrl = this._checkWorkspaceDomain(domain);\n    this._fetchWorkspaceMetadata();\n  }\n\n  private _checkWorkspaceDomain(domain: string): string {\n    if (!domain) throw new Error(\"Workspace domain is required\");\n    if (domain.endsWith(\"/\")) {\n      domain = domain.slice(0, -1);\n    }\n    const domainRegex = /^(https?:\\/\\/)?([^\\s/$.?#].[^\\s]*)$/;\n    if (!domainRegex.test(domain)) throw new Error(\"Invalid workspace domain\");\n    if (!domain.startsWith(\"https://\") && !domain.startsWith(\"http://\")) {\n      domain = `https://${domain}`;\n    }\n    return domain;\n  }\n\n  private async _fetchWorkspaceMetadata(): Promise<void> {\n    try {\n      const response = await fetch(`${this.baseUrl}${API_ENDPOINTS.WORKSPACE_METADATA}`, {\n        headers: {\n          \"Content-Type\": \"application/json\",\n          Authorization: `Bearer ${this.jwt}`,\n        },\n        method: \"GET\",\n      });\n      if (!response.ok) {\n        throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n      }\n      const data = (await response.json()) as {\n        ws_servers: string[];\n        ice_servers: RTCIceServer[];\n      };\n      this.wsServers = data.ws_servers || [];\n      this.iceServers = data.ice_servers && data.ice_servers.length ? data.ice_servers : DEFAULT_ICE_SERVERS;\n\n      // Start SSE Realtime Events stream for background presence & workspace updates\n      this._initEventStream();\n\n      // Mark session ready\n      const dummySession: ISession = {\n        session_id: `ses_${Date.now()}`,\n        username: this.jwtPayload?.sub || \"\",\n        display_name: this.jwtPayload?.sub || \"\",\n        domain: this.jwtPayload?.domain || \"\",\n        expires_at: (this.jwtPayload?.exp || 0) * 1000,\n      };\n      this.session = dummySession;\n      this.events.emit(EClientEventName.SESSION, dummySession);\n      this._resolveReady(dummySession);\n    } catch (error) {\n      console.error(\n        \"fetchWorkspaceMetadata::Error fetching workspace config:\",\n        error\n      );\n      this._rejectReady(\n        error instanceof Error\n          ? error\n          : new Error(\"Failed to fetch workspace metadata\")\n      );\n    }\n  }\n\n  /**\n   * Connect to Server-Sent Events (SSE) Realtime Event Stream\n   * using SseStreamClient with Authorization Bearer header.\n   */\n  private _initEventStream(): void {\n    try {\n      const sseUrl = `${this.baseUrl}${API_ENDPOINTS.EVENT_STREAM}`;\n\n      const CALL_STATE_WEIGHT: Record<string, number> = {\n        created: 1,\n        initiated: 1,\n        pending: 1,\n        started: 2,\n        ringing: 2,\n        progress: 2,\n        answered: 3,\n        active: 3,\n        held: 3,\n        ended: 4,\n        completed: 4,\n        canceled: 4,\n        missed: 4,\n        failed: 4,\n        busy: 4,\n        rejected: 4,\n      };\n\n      const seenEventSignatures = new Map<string, number>();\n\n      const isDuplicateEvent = (payload: any): boolean => {\n        if (!payload || typeof payload !== \"object\") return false;\n        const eventName = payload.event || \"\";\n        const callId =\n          payload.data?.call_id ||\n          payload.data?.id ||\n          payload.call_id ||\n          payload.id ||\n          \"\";\n        const status = payload.data?.status || payload.status || \"\";\n        const timestamp = payload.timestamp || payload.data?.timestamp || \"\";\n\n        let sig = \"\";\n        if (eventName && callId) {\n          sig = `${eventName}:${callId}:${status || timestamp}`;\n        } else if (payload.id || payload.event_id) {\n          sig = `${eventName}:${payload.id || payload.event_id}`;\n        } else {\n          return false;\n        }\n\n        const now = Date.now();\n        if (seenEventSignatures.size > 100) {\n          for (const [k, ts] of seenEventSignatures.entries()) {\n            if (now - ts > 5000) seenEventSignatures.delete(k);\n          }\n        }\n\n        const lastSeen = seenEventSignatures.get(sig);\n        if (lastSeen && now - lastSeen < 3000) {\n          return true; // Duplicate event\n        }\n        seenEventSignatures.set(sig, now);\n        return false;\n      };\n\n      const guardCallState = (eventName: string, payload: any): void => {\n        if (!payload || typeof payload !== \"object\") return;\n        const callId =\n          payload.data?.call_id ||\n          payload.data?.id ||\n          payload.call_id ||\n          payload.id;\n        if (!callId) return;\n\n        const rawStatus = (payload.data?.status || payload.status || \"\").toLowerCase();\n        let eventWeight = CALL_STATE_WEIGHT[rawStatus] || 0;\n\n        if (eventName === \"call.created\" && eventWeight < 1) eventWeight = 1;\n        else if ((eventName === \"call.started\" || eventName === \"call.ring\") && eventWeight < 2) eventWeight = 2;\n        else if (eventName === \"call.answered\" && eventWeight < 3) eventWeight = 3;\n        else if ((eventName === \"call.ended\" || eventName === \"call.canceled\") && eventWeight < 4) eventWeight = 4;\n\n        const now = Date.now();\n        if (this.knownCallStates.size > 200) {\n          for (const [k, v] of this.knownCallStates.entries()) {\n            if (now - v.timestamp > 600000) this.knownCallStates.delete(k);\n          }\n        }\n\n        const existing = this.knownCallStates.get(callId);\n        if (existing && eventWeight < existing.weight) {\n          // Late or out-of-order event arriving after higher-ranked state:\n          // Preserve the higher status in payload to prevent UI state regression\n          if (payload.data && typeof payload.data === \"object\") {\n            payload.data.status = existing.status;\n            payload.data.is_late_event = true;\n          }\n          if (payload.status) {\n            payload.status = existing.status;\n          }\n          return;\n        }\n\n        const newStatus = rawStatus || (\n          eventWeight === 1 ? \"created\" :\n          eventWeight === 2 ? \"started\" :\n          eventWeight === 3 ? \"active\" :\n          eventWeight === 4 ? \"ended\" : \"created\"\n        );\n\n        this.knownCallStates.set(callId, {\n          status: newStatus,\n          weight: Math.max(existing?.weight || 0, eventWeight),\n          timestamp: now,\n        });\n      };\n\n      const handleIncomingSseEvent = (msg: SseMessageEvent) => {\n        const { event, data } = msg;\n        if (isDuplicateEvent(data)) return;\n        guardCallState(event, data);\n\n        switch (event) {\n          case \"call.ring\": {\n            const ringData = (data || {}) as ICallRingParams;\n            this.events.emit(EClientEventName.CALL_RING, ringData);\n            if (ringData.call_token) {\n              const wsUrl =\n                ringData.ws_url ||\n                this.wsServers[0] ||\n                `wss://${this.baseUrl.replace(/^https?:\\/\\//, \"\")}/ws`;\n              this.createCallSession(ringData.call_token, wsUrl, ringData.call_id, {\n                to: ringData.to?.number || \"\",\n                from: ringData.from?.number || \"\",\n                from_name: ringData.from?.name || \"\",\n                from_avatar: ringData.from?.avatar || null,\n                isVideo: Boolean(ringData.is_video),\n                isTransfer: ringData.is_transfer || false,\n                transferReason: ringData.transfer_reason,\n              }).catch((err) =>\n                console.error(\"Error connecting call WebSocket from SSE ring:\", err)\n              );\n            }\n            break;\n          }\n          case \"call.answered\": {\n            const payload = data;\n            const callId = payload?.data?.call_id || payload?.data?.id || payload?.call_id || payload?.id;\n            if (callId) {\n              const call = this.activeCalls.get(callId);\n              if (call && call.callState !== ECallState.ACTIVE) {\n                call.emit(ECallEventName.STATE, {\n                  state: ECallState.ACTIVE,\n                  reason: \"Answered\",\n                  data: payload?.data || payload,\n                });\n              }\n            }\n            this.events.emit(EClientEventName.CALL_ANSWERED, payload);\n            break;\n          }\n          case \"call.canceled\": {\n            const callId = data?.data?.call_id || data?.data?.id || data?.call_id || data?.id;\n            if (callId) {\n              const call = this.activeCalls.get(callId);\n              if (call) {\n                call.emit(ECallEventName.STATE, {\n                  state: ECallState.ENDED,\n                  reason: data?.data?.hangup_cause || data?.reason || \"Canceled\",\n                  data: data?.data || data,\n                });\n                call.destroy(false);\n              }\n              this.activeCalls.delete(callId);\n            }\n            this.events.emit(EClientEventName.CALL_CANCELED, data);\n            break;\n          }\n          case \"call.ended\": {\n            const callId = data?.data?.call_id || data?.data?.id || data?.call_id || data?.id;\n            if (callId) {\n              const call = this.activeCalls.get(callId);\n              if (call) {\n                call.emit(ECallEventName.STATE, {\n                  state: ECallState.ENDED,\n                  reason: data?.data?.hangup_cause || data?.reason || \"Call Ended\",\n                  data: data?.data || data,\n                });\n                call.destroy(false);\n              }\n              this.activeCalls.delete(callId);\n            }\n            this.events.emit(EClientEventName.CALL_ENDED, data);\n            break;\n          }\n          case \"system.error\": {\n            console.error(\"SSE system error received:\", data);\n            if (data?.code === \"SSE_LIMIT_EXCEEDED\") {\n              this.sseClient?.close();\n              this.session = null;\n              this.events.emit(\"error\", new Error(data.message || \"SSE connection limit exceeded\"));\n              this.events.emit(EClientEventName.SESSION, null);\n            }\n            break;\n          }\n          case \"call.created\": {\n            this.events.emit(EClientEventName.CALL_CREATED, data);\n            break;\n          }\n          case \"call.started\": {\n            this.events.emit(EClientEventName.CALL_STARTED, data);\n            break;\n          }\n          case \"agent.state\": {\n            this.events.emit(EClientEventName.AGENT_STATE, data);\n            break;\n          }\n          case \"agent.state.forced\": {\n            this.events.emit(EClientEventName.AGENT_STATE_FORCED, data);\n            break;\n          }\n          case \"agent.created\": {\n            this.events.emit(EClientEventName.AGENT_CREATED, data);\n            break;\n          }\n          case \"agent.updated\": {\n            this.events.emit(EClientEventName.AGENT_UPDATED, data);\n            break;\n          }\n          case \"agent.deleted\": {\n            this.events.emit(EClientEventName.AGENT_DELETED, data);\n            break;\n          }\n          case \"contact.created\": {\n            this.events.emit(EClientEventName.CONTACT_CREATED, data);\n            break;\n          }\n          case \"contact.updated\": {\n            this.events.emit(EClientEventName.CONTACT_UPDATED, data);\n            break;\n          }\n          case \"contact.deleted\": {\n            this.events.emit(EClientEventName.CONTACT_DELETED, data);\n            break;\n          }\n          case \"team.created\": {\n            this.events.emit(EClientEventName.TEAM_CREATED, data);\n            break;\n          }\n          case \"team.updated\": {\n            this.events.emit(EClientEventName.TEAM_UPDATED, data);\n            break;\n          }\n          case \"team.deleted\": {\n            this.events.emit(EClientEventName.TEAM_DELETED, data);\n            break;\n          }\n          case \"team.assigned\": {\n            this.events.emit(EClientEventName.TEAM_ASSIGNED, data);\n            break;\n          }\n          case \"team.unassigned\": {\n            this.events.emit(EClientEventName.TEAM_UNASSIGNED, data);\n            break;\n          }\n          case \"call.recording.ready\": {\n            this.events.emit(EClientEventName.CALL_RECORDING_READY, data);\n            break;\n          }\n          default: {\n            if (event !== \"system.ping\") {\n              this.events.emit(event, data);\n            }\n            break;\n          }\n        }\n      };\n\n      if (this.sseClient) {\n        this.sseClient.close();\n        this.sseClient = null;\n      }\n\n      this.sseClient = new SseStreamClient({\n        url: sseUrl,\n        token: this.jwt,\n        onOpen: () => {\n          this.connected = true;\n        },\n        onMessage: handleIncomingSseEvent,\n        onConnectionStateChange: (state) => {\n          this.connected = state === \"connected\";\n          this.events.emit(EClientEventName.CONNECTION_STATE, state);\n        },\n        onError: (err) => {\n          console.warn(\"SSE Stream Client error:\", err);\n        },\n      });\n\n      this.sseClient.connect();\n    } catch (err) {\n      console.warn(\"SseStreamClient initialization skipped or unsupported:\", err);\n    }\n  }\n\n  /**\n   * Call REST API POST /v1/call-center/calls to initiate call creation\n   */\n  public async initiateCallRest(\n    to: string,\n    from?: string,\n    isVideo?: boolean\n  ): Promise<IMakeCallResponse> {\n    const response = await fetch(`${this.baseUrl}${API_ENDPOINTS.MAKE_CALL}`, {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n        Authorization: `Bearer ${this.jwt}`,\n      },\n      body: JSON.stringify({\n        to,\n        from,\n        type: isVideo ? \"video\" : \"audio\",\n      }),\n    });\n\n    if (!response.ok) {\n      const errData = await response.json().catch(() => ({}));\n      throw new Error(errData.message || `HTTP ${response.status}: Failed to make call`);\n    }\n\n    return (await response.json()) as IMakeCallResponse;\n  }\n\n  /**\n   * Helper to create a Call instance and connect its dedicated per-call WebSocket\n   */\n  public async createCallSession(\n    callToken: string,\n    wsUrl: string,\n    callId: string,\n    options: import(\"./interfaces/call-options.interface\").CallOptions\n  ): Promise<Call> {\n    const call = new Call(this, options);\n    call.callId = callId;\n    this.activeCalls.set(callId, call);\n    await call.connectSignaling(wsUrl, callToken);\n    call.connectCallEventStream(callToken);\n    return call;\n  }\n\n  /**\n   * Initiate a new outbound call via REST API, then open native WebSocket per call.\n   * @param call Call instance\n   * @param sdp RTCSessionDescription (full SDP)\n   */\n  public async makeCall(\n    call: Call,\n    sdp: RTCSessionDescription\n  ): Promise<string> {\n    if (!(call instanceof Call)) {\n      throw new Error(\"Missing or invalid call instance\");\n    }\n    if (!sdp) {\n      throw new Error(\"Missing or invalid sdp\");\n    }\n    const res = await this.initiateCallRest(call.to, call.from, Boolean(call.isVideo));\n    call.callId = res.call_id;\n    this.activeCalls.set(res.call_id, call);\n    await call.connectSignaling(res.ws_url, res.call_token);\n    call.connectCallEventStream(res.call_token);\n    call.sendWsEvent(\"call.offer\", { sdp: sdp.sdp });\n    return res.call_id;\n  }\n\n  /**\n   * Initiate Call Supervision (listen / whisper / barge) via REST API.\n   */\n  private async _superviseCall(\n    callId: string,\n    mode: \"listen\" | \"whisper\" | \"barge\"\n  ): Promise<ISupervisionResponse> {\n    const url = `${this.baseUrl}${API_ENDPOINTS.SUPERVISION(callId, mode)}`;\n    const response = await fetch(url, {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n        Authorization: `Bearer ${this.jwt}`,\n      },\n    });\n\n    if (!response.ok) {\n      const errData = await response.json().catch(() => ({}));\n      throw new Error(errData.message || `HTTP ${response.status}: Failed to supervise call`);\n    }\n\n    return (await response.json()) as ISupervisionResponse;\n  }\n\n  /**\n   * Helper to start supervision (listen / whisper / barge) and automatically\n   * establish the WebRTC audio session.\n   */\n  public async startSupervision(\n    callId: string,\n    mode: \"listen\" | \"whisper\" | \"barge\",\n    options?: CallOptions\n  ): Promise<Call> {\n    const res = await this._superviseCall(callId, mode);\n    if (!res.ws_url) {\n      throw new Error(\"Server did not return ws_url for supervision session\");\n    }\n    const call = new Call(this, options);\n    call.callId = res.call_id;\n    this.activeCalls.set(res.call_id, call);\n    await call.joinSession(res.ws_url, res.call_token, mode);\n    return call;\n  }\n\n  /**\n   * Helper to stop an active call supervision session.\n   * Closes WebRTC call session and calls the REST API DELETE /api/v1/call-center/calls/:call_id/supervision.\n   */\n  public async stopSupervision(callId: string): Promise<void> {\n    // 1. Destroy and cleanup active supervision Call session if present\n    const call = this.activeCalls.get(callId);\n    if (call) {\n      call.destroy();\n      this.activeCalls.delete(callId);\n    }\n\n    // 2. Call REST API DELETE /api/v1/call-center/calls/:call_id/supervision\n    const url = `${this.baseUrl}${API_ENDPOINTS.SUPERVISION_STOP(callId)}`;\n    const response = await fetch(url, {\n      method: \"DELETE\",\n      headers: {\n        Authorization: `Bearer ${this.jwt}`,\n      },\n    });\n\n    if (!response.ok) {\n      const errData = await response.json().catch(() => ({}));\n      throw new Error(\n        errData.message || `HTTP ${response.status}: Failed to stop supervision`\n      );\n    }\n  }\n\n  /**\n   * Send Call Transfer request via WebSocket or REST API fallback.\n   * Target can be: extension number, agent username, team ID (te_...), or SIP account ID (si_...).\n   */\n  public async sendTransfer(\n    callId: string,\n    target: string,\n    reason?: string\n  ): Promise<void> {\n    const call = this.activeCalls.get(callId);\n    if (call) {\n      await call.transfer(target, reason);\n      return;\n    }\n\n    const url = `${this.baseUrl}${API_ENDPOINTS.TRANSFER(callId)}`;\n    const response = await fetch(url, {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n        Authorization: `Bearer ${this.jwt}`,\n      },\n      body: JSON.stringify({\n        target,\n        reason: reason || undefined,\n      }),\n    });\n\n    if (!response.ok) {\n      const errData = await response.json().catch(() => ({}));\n      throw new Error(errData.message || `HTTP ${response.status}: Failed to transfer call`);\n    }\n\n    this.activeCalls.delete(callId);\n  }\n\n  /**\n   * Send login with username, password, domain.\n   */\n  public async login(\n    username: string,\n    password: string,\n    domain: string\n  ): Promise<void> {\n    if (!username || !password) {\n      throw new Error(\"Username and password are required\");\n    }\n    if (!domain) {\n      throw new Error(\"domain is required\");\n    }\n\n    const response = await fetch(`${this.baseUrl}${API_ENDPOINTS.AUTH_LOGIN}`, {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      },\n      body: JSON.stringify({ username, password, domain }),\n    });\n    const data = await response.json();\n    if (data.error) {\n      throw new Error(data.error);\n    }\n\n    this.jwt = data.access_token;\n    const payload = this._parseJwt(this.jwt);\n    if (!payload) throw new Error(\"Invalid JWT received from login\");\n    this.jwtPayload = payload;\n\n    // Re-initialize SSE event stream\n    if (this.sseClient) {\n      this.sseClient.close();\n      this.sseClient = null;\n    }\n    this._initEventStream();\n  }\n\n  /**\n   * Fetch phone numbers (DIDs) accessible by the authenticated agent/team.\n   * Calls GET /api/v1/call-center/phone-numbers using the agent's JWT.\n   */\n  public async getPhoneNumbers(options?: {\n    page?: number;\n    limit?: number;\n  }): Promise<IClientPhoneNumbersResponse> {\n    const page = options?.page || 1;\n    const limit = options?.limit || 100;\n    const url = `${this.baseUrl}${API_ENDPOINTS.PHONE_NUMBERS}?page=${page}&limit=${limit}`;\n    const response = await fetch(url, {\n      method: \"GET\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n        Authorization: `Bearer ${this.jwt}`,\n      },\n    });\n\n    if (!response.ok) {\n      const err = (await response.json().catch(() => ({}))) as { message?: string };\n      throw new Error(err.message || `HTTP ${response.status}: Failed to fetch phone numbers`);\n    }\n\n    return (await response.json()) as IClientPhoneNumbersResponse;\n  }\n\n  public getSessionInfo(): ISession | null {\n    return this.session;\n  }\n\n  public getJwtPayload(): IJwtPayload | null {\n    return this.jwtPayload;\n  }\n\n  public getBaseUrl(): string {\n    return this.baseUrl;\n  }\n\n  public getJwt(): string {\n    return this.jwt;\n  }\n\n  /**\n   * Helper to generate or retrieve a unique, persistent Device ID for browser environment.\n   * Uses localStorage when available, or falls back to random UUID.\n   * @param storageKey Key to store device ID in localStorage (default: \"firetell_device_id\")\n   * @returns Persistent unique device ID string\n   */\n  public static getOrCreateDeviceId(storageKey: string = EStorageKey.DEVICE_ID): string {\n    if (typeof window !== \"undefined\" && typeof localStorage !== \"undefined\") {\n      try {\n        const existingId = localStorage.getItem(storageKey);\n        if (existingId && existingId.trim().length > 0) {\n          return existingId;\n        }\n      } catch {\n        // Handle private browsing or restricted storage\n      }\n    }\n\n    let newDeviceId: string;\n    if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n      newDeviceId = `web_${crypto.randomUUID()}`;\n    } else {\n      const rand = Math.random().toString(36).substring(2, 11) + Math.random().toString(36).substring(2, 11);\n      newDeviceId = `web_${Date.now().toString(36)}_${rand}`;\n    }\n\n    if (typeof window !== \"undefined\" && typeof localStorage !== \"undefined\") {\n      try {\n        localStorage.setItem(storageKey, newDeviceId);\n      } catch {\n        // Ignore quota errors\n      }\n    }\n\n    return newDeviceId;\n  }\n\n  /**\n   * Helper instance method to get or generate persistent browser Device ID.\n   * @param storageKey Custom key for localStorage (default: \"firetell_device_id\")\n   */\n  public getDeviceId(storageKey?: string): string {\n    return FiretellClient.getOrCreateDeviceId(storageKey);\n  }\n\n  private _cleanupSession(): void {\n    this.session = null;\n    this.events.emit(EClientEventName.SESSION, null);\n    this.events.offAll();\n    if (this.reconnectTimer) {\n      clearTimeout(this.reconnectTimer);\n      this.reconnectTimer = null;\n    }\n    this.reconnectDelay = 3000;\n    if (this.sseClient) {\n      this.sseClient.close();\n      this.sseClient = null;\n    }\n    this.knownCallStates.clear();\n  }\n\n  private _isVideoCall(sdp: RTCSessionDescriptionInit): boolean {\n    return /m=video/.test(sdp.sdp || \"\");\n  }\n\n  private _checkWebRTCSupport(): boolean {\n    const hasRTCPeerConnection = typeof window !== \"undefined\" && !!window.RTCPeerConnection;\n    const hasGetUserMedia =\n      typeof navigator !== \"undefined\" &&\n      !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia);\n    if (!hasRTCPeerConnection || !hasGetUserMedia) {\n      const errorMsg = \"WebRTC is not supported in this environment.\";\n      console.error(errorMsg);\n      this.events.emit(EClientEventName.ERROR, {\n        code: 606,\n        message: errorMsg,\n      });\n      return false;\n    }\n    return true;\n  }\n\n  private _handleIncomingCall(params: ICallOfferParams): void {\n    const { call_id, from, from_name, from_avatar, to, sdp, is_transfer, transfer_reason, is_video } = params;\n    const call = new Call(this, {\n      from,\n      from_name,\n      from_avatar,\n      to: to || this.getSessionInfo()?.username || \"\",\n      isVideo: is_video !== undefined ? is_video : this._isVideoCall(sdp),\n      isTransfer: is_transfer || false,\n      transferReason: transfer_reason,\n    });\n    call.callId = call_id;\n    call.remoteDescription = sdp;\n\n    this.activeCalls.set(call_id, call);\n    this.events.emit(EClientEventName.CALL_OFFER, call);\n  }\n\n  public logout(): void {\n    this.activeCalls.forEach((call) => call.destroy());\n    this.activeCalls.clear();\n    this._cleanupSession();\n  }\n\n  public destroy(): void {\n    this.activeCalls.forEach((call) => call.destroy());\n    this.activeCalls.clear();\n    if (this.reconnectTimer) {\n      clearTimeout(this.reconnectTimer);\n      this.reconnectTimer = null;\n    }\n    this.reconnectDelay = 3000;\n    if (this.sseClient) {\n      this.sseClient.close();\n      this.sseClient = null;\n    }\n    this.knownCallStates.clear();\n    this.session = null;\n    this.jwtPayload = null;\n    this.jwt = \"\";\n    this.events.offAll();\n  }\n\n  private _parseJwt(jwt: string): IJwtPayload | null {\n    try {\n      const parts = jwt.split(\".\");\n      if (parts.length < 2) return null;\n\n      const base64 = parts[1]\n        .replace(/-/g, \"+\")\n        .replace(/_/g, \"/\")\n        .padEnd(parts[1].length + ((4 - (parts[1].length % 4)) % 4), \"=\");\n\n      let jsonString: string;\n      if (typeof window === \"undefined\") {\n        jsonString = Buffer.from(base64, \"base64\").toString(\"utf-8\");\n      } else {\n        const binary = atob(base64);\n        const bytes = new Uint8Array(binary.length);\n        for (let i = 0; i < binary.length; i++) {\n          bytes[i] = binary.charCodeAt(i);\n        }\n        const decoder = new TextDecoder(\"utf-8\");\n        jsonString = decoder.decode(bytes);\n      }\n\n      const decoded: IJwtPayload = JSON.parse(jsonString);\n      if (decoded.sub && decoded.domain) {\n        return decoded;\n      }\n      return null;\n    } catch {\n      return null;\n    }\n  }\n}"],"mappings":"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","names":["ECallEventName","EClientEventName","ECallState"]}