From e1ceb2c8819f248ef8c7485ed7119abd96e3648e Mon Sep 17 00:00:00 2001 From: Roger Urscheler Date: Fri, 10 Jan 2020 14:58:46 -0500 Subject: [PATCH] Upload version 1.2.7604 --- circuit.js | 1114 ++++++++++++++++++++++++++++++++++-------------- circuit.min.js | 6 +- package.json | 6 +- 3 files changed, 806 insertions(+), 320 deletions(-) diff --git a/circuit.js b/circuit.js index b423dc9..fc962e6 100644 --- a/circuit.js +++ b/circuit.js @@ -30,10 +30,10 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * @version: 1.2.7402 + * @version: 1.2.7604 */ -var Circuit = {}; Object.defineProperty(Circuit, 'version', { value: '1.2.7402'}); +var Circuit = {}; Object.defineProperty(Circuit, 'version', { value: '1.2.7604'}); // Define external globals for JSHint /*global Buffer, process, require*/ @@ -598,8 +598,8 @@ var Circuit = (function (circuit) { // Returns set of symbols that is used for url regular expressions function getUrlSymbols() { - var urlSymbolLast = '\\w@\'^=$%&\\/~+!\\(\\)\\{\\}\\-\\|'; - var urlSymbol = urlSymbolLast + '.,?:\\[\\]'; + var urlSymbolLast = '\\w@\'^=$%&\\/~+\\{\\}\\-\\|'; + var urlSymbol = urlSymbolLast + '.,?!:\\[\\]\\(\\)'; return '(?:[' + urlSymbol + '#]*[' + urlSymbolLast + '#])?'; } var URL_SYMBOLS = getUrlSymbols(); @@ -3613,6 +3613,7 @@ var Circuit = (function (circuit) { NOT_CONNECTED: 'NOT_CONNECTED', // Not connected to a thirdparty provider ALREADY_CONNECTED: 'ALREADY_CONNECTED', // Already connected to a thirdparty provider INVALID_ITEMIDS: 'INVALID_ITEMIDS', + INVALID_SITEID: 'INVALID_SITEID', TOO_MANY_REQUESTS: 'TOO_MANY_REQUESTS' // The server rejected the request due to its rate limit (too many requests per second) }, @@ -3678,6 +3679,13 @@ var Circuit = (function (circuit) { DESCENDING: 'DESCENDING' }, + TimeRange: { + ONE_HOUR: 3600000, + ONE_DAY: 86400000, + ONE_WEEK: 7 * 86400000, + ONE_MONTH: 30 * 86400000 + }, + /////////////////////////////////////////////////////////////////////////// // Conversation Action /////////////////////////////////////////////////////////////////////////// @@ -3809,6 +3817,7 @@ var Circuit = (function (circuit) { SPACE_INFO: 'SPACE_INFO', SPACE_DETAILS: 'SPACE_DETAILS', SPACE_PINNED_TOPICS: 'SPACE_PINNED_TOPICS', + SPACE_ACTIVE_POLLS: 'SPACE_ACTIVE_POLLS', // Selector panel settings CONVERSATION_FAVORITES: 'CONVERSATION_FAVORITES' }, @@ -3819,6 +3828,7 @@ var Circuit = (function (circuit) { SPACE_INFO: true, SPACE_DETAILS: true, SPACE_PINNED_TOPICS: true, + SPACE_ACTIVE_POLLS: true, CONVERSATION_FAVORITES: true }, @@ -5032,7 +5042,14 @@ var Circuit = (function (circuit) { MODERATE_CONVERSATIONS: 'MODERATE_CONVERSATIONS', ORGANIZE_CONVERSATIONS: 'ORGANIZE_CONVERSATIONS', SEARCH_CONVERSATIONS: 'SEARCH_CONVERSATIONS', - USER_TO_USER: 'USER_TO_USER' + USER_TO_USER: 'USER_TO_USER', + READ_SPACE: 'READ_SPACE', + WRITE_SPACE: 'WRITE_SPACE', + MANAGE_SPACE: 'MANAGE_SPACE', + CREATE_SPACE_CONTENT: 'CREATE_SPACE_CONTENT', + DELETE_SPACE_CONTENT: 'DELETE_SPACE_CONTENT', + UPDATE_SPACE_CONTENT: 'UPDATE_SPACE_CONTENT', + ORGANIZE_SPACE: 'ORGANIZE_SPACE' }, OAuthGrantTypes: { @@ -5224,6 +5241,8 @@ var Circuit = (function (circuit) { ADD_LDAP_CONFIGURATION_FOR_PHONE: 'ADD_LDAP_CONFIGURATION_FOR_PHONE', GET_LDAP_CONFIGURATION_FOR_PHONE: 'GET_LDAP_CONFIGURATION_FOR_PHONE', VALIDATE_TRANSFER_TARGET: 'VALIDATE_TRANSFER_TARGET', + ADD_PHONE_ONLY_USER: 'ADD_PHONE_ONLY_USER', + ADD_SHARED_DEVICE: 'ADD_SHARED_DEVICE', // MediaServer Application Framework CREATE_APPLICATION_FRAMEWORK_CONFIGURATION: 'CREATE_APPLICATION_FRAMEWORK_CONFIGURATION', @@ -5728,6 +5747,15 @@ var Circuit = (function (circuit) { AZUREAD: 'AZUREAD' }, + MsGraphDataTypes: { + FILE: 'file', + FOLDER: 'folder', + DRIVE: 'drive', + SITE: 'site', + CONTENT: 'content', + SUBSITES: 'subsites' + }, + /////////////////////////////////////////////////////////////////////////// // Guest Action /////////////////////////////////////////////////////////////////////////// @@ -6092,6 +6120,8 @@ var Circuit = (function (circuit) { GET_ITEMS_BY_IDS: 'GET_ITEMS_BY_IDS', CREATE_TOPIC: 'CREATE_TOPIC', CREATE_POLL: 'CREATE_POLL', + VOTE_POLL_OPTIONS: 'VOTE_POLL_OPTIONS', + GET_POLL_OPTION_VOTERS: 'GET_POLL_OPTION_VOTERS', CREATE_REPLY: 'CREATE_REPLY', UPDATE_TOPIC: 'UPDATE_TOPIC', UPDATE_POLL: 'UPDATE_POLL', @@ -6104,6 +6134,7 @@ var Circuit = (function (circuit) { UNFLAG: 'UNFLAG', GET_FLAGGED_ITEMS_COUNT: 'GET_FLAGGED_ITEMS_COUNT', GET_FLAGGED_ITEMS: 'GET_FLAGGED_ITEMS', + GET_SPACE_ITEMS_BY_IDS_WITH_TOPIC_AND_SPACE_ID: 'GET_SPACE_ITEMS_BY_IDS_WITH_TOPIC_AND_SPACE_ID', PIN_TOPIC: 'PIN_TOPIC', UNPIN_TOPIC: 'UNPIN_TOPIC', GET_PINNED_TOPICS: 'GET_PINNED_TOPICS', @@ -6461,7 +6492,6 @@ var Circuit = (function (circuit) { CMR_CONTROL_PANEL: 'CMR_CONTROL_PANEL', CONFERENCE_POLL: 'CONFERENCE_POLL', DARK_MODE: 'DARK_MODE', - DETAILED_CALL_STATISTICS: 'DETAILED_CALL_STATISTICS', DISABLE_CALL_KIT: 'DISABLE_CALL_KIT', ENHANCED_AUTOMATED_ATTENDANT: 'ENHANCED_AUTOMATED_ATTENDANT', FAVORITE_A_SPACE: 'FAVORITE_A_SPACE', @@ -6488,18 +6518,19 @@ var Circuit = (function (circuit) { SHAREPOINT: 'SHAREPOINT', SIMULCAST: 'SIMULCAST', SPACES: 'SPACES', + SPACES_CODE_FORMAT: 'SPACES_CODE_FORMAT', SPACES_FILTER_AND_LABELS: 'SPACES_FILTER_AND_LABELS', - SPACES_FLAGGING: 'SPACES_FLAGGING', SPACES_HASHTAGS: 'SPACES_HASHTAGS', + SPACES_PAGES: 'SPACES_PAGES', SPACES_POLLING: 'SPACES_POLLING', + SPACES_QUESTIONS: 'SPACES_QUESTIONS', STARTED_MEETING_SUMMARY: 'STARTED_MEETING_SUMMARY', TEAMS: 'TEAMS', TENANT_ADMIN_USER_TABLE_ENHANCEMENT: 'TENANT_ADMIN_USER_TABLE_ENHANCEMENT', TRANSCRIPTION_AND_TRANSLATION: 'TRANSCRIPTION_AND_TRANSLATION', UCAAS_PHONES_LDAP_SETTINGS: 'UCAAS_PHONES_LDAP_SETTINGS', + UCAAS_SHARED_TRUNKS: 'UCAAS_SHARED_TRUNKS', UNIFIED_CONVERSATION_CREATION: 'UNIFIED_CONVERSATION_CREATION', - UNIFIED_PLAN_SDP: 'UNIFIED_PLAN_SDP', - VIDEO_POINTER: 'VIDEO_POINTER', WEBRTC_DEBUG_LOGGING: 'WEBRTC_DEBUG_LOGGING', WEBRTC_ICE_OPTIMIZATION: 'WEBRTC_ICE_OPTIMIZATION' }, @@ -6522,6 +6553,7 @@ var Circuit = (function (circuit) { AvatarBadgeType: { COMMUNITY: 'COMMUNITY', EVENT: 'EVENT', + EXPERT: 'EXPERT', SKYPE: 'SKYPE' }, @@ -6902,7 +6934,7 @@ var Circuit = (function (circuit) { // RTC_SESSION case Constants.ContentType.RTC_SESSION: evtName = 'RTCSession.' + event.rtcSession.type; - switch (event.rtcSession.type) { + switch (event.rtcSession.type) { // NOSONAR case Constants.RTCSessionEventType.SESSION_STARTED: evtData = event.rtcSession.sessionStarted; break; @@ -7193,10 +7225,10 @@ var Circuit = (function (circuit) { evtData = event.space.unflagged; break; case Constants.SpaceEventType.LIKED: - evtData = event.space.likedEvent; + evtData = event.space.liked; break; case Constants.SpaceEventType.UNLIKED: - evtData = event.space.unlikedEvent; + evtData = event.space.unliked; break; case Constants.SpaceEventType.BASIC_SEARCH_RESULT: evtData = event.space.basicSearchResult; @@ -9013,6 +9045,7 @@ var Circuit = (function (circuit) { // Imports var logger = circuit.logger; + var Utils = circuit.Utils; var MAX_BUFFERED_AMOUNT = 64 * 1024; @@ -9056,6 +9089,12 @@ var Circuit = (function (circuit) { } }); + var RtpStatsConfig = { + COLLECTION_INTERVAL: 5000, + DELAY_UPON_ANSWER: Utils.isMobile() ? 0 : 5000, + DELAY_RTT_PROCESSING: 3 // googRTT takes few seconds to settle, so skip 3 stat collection cycles + }; + ///////////////////////////////////////////////////////////////////////////////// // Helper functions ///////////////////////////////////////////////////////////////////////////////// @@ -9321,7 +9360,7 @@ var Circuit = (function (circuit) { {autoGainControl: !!config.enableAudioAGC}, {echoCancellation: true} ]; - return useNewSyntax ? { advanced: options } : { optional: options}; + return useNewSyntax ? { advanced: options } : { optional: options }; }; var getDefaultAudioOptions = function (config) { @@ -9344,14 +9383,18 @@ var Circuit = (function (circuit) { }; var getDefaultVideoOptionsNewConstraint = function (config) { + var options; if (config && config.videoResolution) { - var options = { + options = { aspectRatio: { min: 1.77, max: 1.78 }, frameRate: { min: 24, max: 30 } }; if (config.minFrameRate) { options.frameRate.min = Math.min(config.minFrameRate, options.frameRate.max); } + if (config.sourceId) { + options.deviceId = { exact: config.sourceId }; + } switch (config.videoResolution) { case VideoResolutionLevel.VIDEO_1080: // Full HD @@ -9372,12 +9415,21 @@ var Circuit = (function (circuit) { return options; } // return video in 16:9 aspect ratio by default - return { + options = { aspectRatio: { min: 1.77, max: 1.78 } }; + if (config.sourceId) { + // If resolution is not set, deviceId is optional + options.deviceId = config.sourceId; + } + return options; }; var getDefaultVideoOptions = function (config) { + if (circuit.WebRTCAdapter.useNewConstraintSyntax) { + return getDefaultVideoOptionsNewConstraint(config); + } + var options = { mandatory: { // set video in 16:9 aspect ratio by default @@ -9389,35 +9441,43 @@ var Circuit = (function (circuit) { ] }; - if (config && config.videoResolution) { - // FrameRate - options.mandatory.minFrameRate = 24; - options.mandatory.maxFrameRate = 30; - if (config.minFrameRate) { - options.mandatory.minFrameRate = Math.min(config.minFrameRate, options.mandatory.maxFrameRate); - } - switch (config.videoResolution) { - case VideoResolutionLevel.VIDEO_1080: - // Full HD - options.mandatory.minWidth = 1920; - options.mandatory.maxWidth = 1920; - options.mandatory.minHeight = 1080; - options.mandatory.maxHeight = 1080; - break; - case VideoResolutionLevel.VIDEO_720: - // HD - options.mandatory.minWidth = 1280; - options.mandatory.maxWidth = 1280; - options.mandatory.minHeight = 720; - options.mandatory.maxHeight = 720; - break; - case VideoResolutionLevel.VIDEO_480: - // SD - options.mandatory.minWidth = 854; - options.mandatory.maxWidth = 854; - options.mandatory.minHeight = 480; - options.mandatory.maxHeight = 480; - break; + if (config) { + if (config.videoResolution) { + // FrameRate + options.mandatory.minFrameRate = 24; + options.mandatory.maxFrameRate = 30; + if (config.minFrameRate) { + options.mandatory.minFrameRate = Math.min(config.minFrameRate, options.mandatory.maxFrameRate); + } + if (config.sourceId) { + options.mandatory.sourceId = config.sourceId; + } + switch (config.videoResolution) { + case VideoResolutionLevel.VIDEO_1080: + // Full HD + options.mandatory.minWidth = 1920; + options.mandatory.maxWidth = 1920; + options.mandatory.minHeight = 1080; + options.mandatory.maxHeight = 1080; + break; + case VideoResolutionLevel.VIDEO_720: + // HD + options.mandatory.minWidth = 1280; + options.mandatory.maxWidth = 1280; + options.mandatory.minHeight = 720; + options.mandatory.maxHeight = 720; + break; + case VideoResolutionLevel.VIDEO_480: + // SD + options.mandatory.minWidth = 853; + options.mandatory.maxWidth = 854; + options.mandatory.minHeight = 480; + options.mandatory.maxHeight = 480; + break; + } + } else if (config.sourceId) { + // If resolution is not set, sourceId is optional + options.optional.push({ sourceId: config.sourceId }); } } @@ -9941,21 +10001,7 @@ var Circuit = (function (circuit) { } return audio; }, - getVideoOptions: function (config) { - var video; - if (circuit.WebRTCAdapter.useNewConstraintSyntax) { - video = getDefaultVideoOptionsNewConstraint(config); - if (config && config.sourceId) { - video.deviceId = {exact: config.sourceId}; - } - } else { - video = getDefaultVideoOptions(config); - if (config && config.sourceId) { - video.optional.push({sourceId: config.sourceId}); - } - } - return video; - }, + getVideoOptions: getDefaultVideoOptions, getDesktopOptions: function (streamId, screenConstraint) { screenConstraint = screenConstraint || {}; var fr = screenConstraint.frameRate || {}; @@ -10213,6 +10259,7 @@ var Circuit = (function (circuit) { enabled: true, browser: 'firefox', unifiedPlanEnabled: useUnifiedPlan, + useNewConstraintSyntax: true, MediaStream: MediaStream, PeerConnection: function (configuration, constraints, dataOptions) { var pc = new PeerConnection(configuration); @@ -10396,15 +10443,7 @@ var Circuit = (function (circuit) { delete audio.optional; return audio; }, - getVideoOptions: function (config) { - var video = getDefaultVideoOptionsNewConstraint(config); - if (config && config.sourceId) { - video.deviceId = config.sourceId; - } - video.advanced = video.optional; - delete video.optional; - return video; - }, + getVideoOptions: getDefaultVideoOptions, getDesktopOptions: function (streamId, screenConstraint) { screenConstraint = screenConstraint || {}; var fr = screenConstraint.frameRate || {}; @@ -10628,6 +10667,7 @@ var Circuit = (function (circuit) { enabled: true, browser: 'safari', unifiedPlanEnabled: true, + useNewConstraintSyntax: true, useReducedAudioConstraints: true, MediaStream: MediaStream, PeerConnection: function (config, constraints, dataOptions) { @@ -10740,13 +10780,7 @@ var Circuit = (function (circuit) { } return audio; }, - getVideoOptions: function (config) { - var video = getDefaultVideoOptionsNewConstraint(config); - if (config && config.sourceId) { - video.deviceId = {exact: config.sourceId}; - } - return video; - }, + getVideoOptions: getDefaultVideoOptions, getDesktopOptions: function (streamId, screenConstraint) { screenConstraint = screenConstraint || {}; var fr = screenConstraint.frameRate || {}; @@ -10939,7 +10973,13 @@ var Circuit = (function (circuit) { } }; }, - setEncodingParameters: function () {}, + setEncodingParameters: function (rtpTransceiver, maxBitrate) { + if (!rtpTransceiver || !rtpTransceiver.sender || !maxBitrate) { + return; + } + rtpTransceiver.sender.maxBitrate = maxBitrate; + logger.debug('[WebRTCAdapter]: Applied maxBitrate {' + maxBitrate + '} to RtpSender mid=' + rtpTransceiver.mid); + }, audioOutputSelectionSupported: false, groupPeerConnectionsSupported: false, getMediaSourcesSupported: false, @@ -11120,6 +11160,7 @@ var Circuit = (function (circuit) { enabled: true, browser: 'cordovaios', unifiedPlanEnabled: false, + useNewConstraintSyntax: true, MediaStream: cordova.plugins.iosrtc.MediaStream, PeerConnection: function (config, constraints) { var pc = new cordova.plugins.iosrtc.RTCPeerConnection(config, constraints); @@ -11219,6 +11260,7 @@ var Circuit = (function (circuit) { getAudioOptions: function (config) { var audio = getDefaultAudioOptions(config); if (config && config.sourceId) { + // Cordova doesn't support exact (mandatory) deviceId audio.deviceId = config.sourceId; } return audio; @@ -11226,6 +11268,7 @@ var Circuit = (function (circuit) { getVideoOptions: function (config) { var video = getDefaultVideoOptions(config); if (config && config.sourceId) { + // Cordova doesn't support exact (mandatory) deviceId video.deviceId = config.sourceId; } return video; @@ -11425,6 +11468,8 @@ var Circuit = (function (circuit) { circuit.Enums.VideoResolutionLevel = VideoResolutionLevel; circuit.Enums.RtpQualityLevel = RtpQualityLevel; + circuit.RtpStatsConfig = RtpStatsConfig; + return circuit; })(Circuit || {}); //eslint-disable-line no-use-before-define @@ -14427,6 +14472,7 @@ var Circuit = (function (circuit) { curr.isMeetingGuest = participant.isMeetingGuest; curr.rtcSupportedFeatures = participant.rtcSupportedFeatures; curr.flags = participant.flags; + curr.videoPointerTo = participant.videoPointerTo; if (participant.participantType === Constants.RTCParticipantType.TELEPHONY) { curr.displayName = participant.displayName; curr.firstName = participant.firstName; @@ -15287,6 +15333,13 @@ var Circuit = (function (circuit) { // Display feature selected for CMR this.screenEnabledFeature = null; + // Previous media features state before changing + this.previousScreenFeaturesState = { + ToggleWhiteboard: false, + ToggleScreenShare: false, + ToggleConferencePoll: false + }; + // Is conference poll enabled for the call this.pollEnabled = false; // Object that contains conference poll data @@ -15961,6 +16014,8 @@ var Circuit = (function (circuit) { var Utils = circuit.Utils; var TemasysAdapter = circuit.TemasysAdapter; + var PERMISSION_DENIED_BY_SYSTEM = 'permission denied by system'; + /////////////////////////////////////////////////////////////////////////////////////// // Controller for Screen Sharing /////////////////////////////////////////////////////////////////////////////////////// @@ -15994,10 +16049,13 @@ var Circuit = (function (circuit) { }) .catch(function (error) { if (error.name === 'NotAllowedError') { - // 'NotAllowedError' is returned if the user cancels the screen/window selection - // In this case we shouldn't show an error message, that's why we're mapping it to CHOOSE_DESKTOP_MEDIA_CANCELLED - errorCb(Constants.ReturnCode.CHOOSE_DESKTOP_MEDIA_CANCELLED); - return; + // 'NotAllowedError' is returned if the user cancels the screen/window selection or the OS denied access, + // the message property contains more information + if (!error.message || error.message.toLowerCase() !== PERMISSION_DENIED_BY_SYSTEM) { + // In this case we shouldn't show an error message, that's why we're mapping it to CHOOSE_DESKTOP_MEDIA_CANCELLED + errorCb(Constants.ReturnCode.CHOOSE_DESKTOP_MEDIA_CANCELLED); + return; + } } errorCb(error); }); @@ -16206,8 +16264,9 @@ var Circuit = (function (circuit) { // Imports var logger = circuit.logger; - var Utils = circuit.Utils; var RtpQualityLevel = circuit.Enums.RtpQualityLevel; + var RtpStatsConfig = circuit.RtpStatsConfig; + var Utils = circuit.Utils; var _isMobile = Utils.isMobile(); @@ -16277,12 +16336,6 @@ var Circuit = (function (circuit) { } }); - var RtpStatsConfig = { - COLLECTION_INTERVAL: 5000, - DELAY_UPON_ANSWER: _isMobile ? 0 : 5000, - DELAY_RTT_PROCESSING: 3 // googRTT takes few seconds to settle, so skip 3 stat collection cycles - }; - var CallStats = Object.freeze({ audioOutputLevel: 'aol', bytesReceived: 'or', @@ -16434,11 +16487,7 @@ var Circuit = (function (circuit) { info.hAddr = res.stat('ipAddress'); // ANS-51833: In some cases of VPN connected calls, selected candidate is host // but, backend needs srflx host address for the QoS bandwidth calculations - // get srflx address if there any otherwise default to host address. info.sAddr = getAddrByNetworkIdForQosReport(m, candidate, 'srflx'); - if (!info.sAddr) { - info.sAddr = info.hAddr; - } } else { if (type === 'srflx') { info.sAddr = candidate.address; @@ -17287,6 +17336,10 @@ var Circuit = (function (circuit) { return _savedRTPStats; }; + this.getStreamQualityData = function () { + return null; + }; + this.setTransmitVideoParams = function () {}; } @@ -17299,7 +17352,6 @@ var Circuit = (function (circuit) { // Exports circuit.CallStats = CallStats; circuit.CallStatsHandler = CallStatsHandler; - circuit.RtpStatsConfig = RtpStatsConfig; return circuit; })(Circuit || {}); //eslint-disable-line no-use-before-define @@ -17309,11 +17361,12 @@ var Circuit = (function (circuit) { 'use strict'; // Imports + var Constants = circuit.Constants; var logger = circuit.logger; + var RtpQualityLevel = circuit.Enums.RtpQualityLevel; + var RtpStatsConfig = circuit.RtpStatsConfig; var Utils = circuit.Utils; var VideoResolutionLevel = circuit.Enums.VideoResolutionLevel; - var RtpQualityLevel = circuit.Enums.RtpQualityLevel; - var Constants = circuit.Constants; var _isMobile = Utils.isMobile(); @@ -17327,18 +17380,20 @@ var Circuit = (function (circuit) { id: Constants.AudioQualityParam.JITTER, StatName: 'jr', StatText: 'googJitterReceived', - Threshold: [50, 100, 200], + Threshold: [50, 300, 500], ThresholdType: ThresholdType.MAX, RecurrenceThreshold: _isMobile ? 2 : 3, + StreamQualityThreshold: 25, reportIssues: true }, GOOG_RTT: { id: Constants.AudioQualityParam.RTT, StatName: 'rtt', StatText: 'googRtt', - Threshold: [300, 400, 500], + Threshold: [300, 600, 800], ThresholdType: ThresholdType.MAX, RecurrenceThreshold: _isMobile ? 2 : 3, + StreamQualityThreshold: 25, reportIssues: true }, PACKET_LOSS_RECV: { @@ -17348,6 +17403,7 @@ var Circuit = (function (circuit) { Threshold: [0.05, 0.2, 0.3], ThresholdType: ThresholdType.MAX, RecurrenceThreshold: _isMobile ? 2 : 3, + StreamQualityThreshold: 3, reportIssues: true }, PACKET_LOSS_SEND: { @@ -17391,7 +17447,7 @@ var Circuit = (function (circuit) { id: Constants.VideoQualityParam.RTT, StatName: 'rtt', StatText: 'googRtt', - Threshold: [300, 400, 500], + Threshold: [300, 600, 800], ThresholdType: ThresholdType.MAX, RecurrenceThreshold: _isMobile ? 2 : 3 }, @@ -17401,6 +17457,7 @@ var Circuit = (function (circuit) { StatText: 'packetLossRecv', Threshold: [0.05, 0.2, 0.3], ThresholdType: ThresholdType.MAX, + StreamQualityThreshold: 0.1, RecurrenceThreshold: _isMobile ? 2 : 3 }, PACKET_LOSS_SEND: { @@ -17414,7 +17471,7 @@ var Circuit = (function (circuit) { }); // Dynamic, depends on the "desired" resolution - var RTPHDVideoStatType = Object.freeze({ + var RTPHDVideoStatType = JSON.stringify({ FRAME_HEIGHT_SENT: { id: Constants.VideoQualityParam.FRAME_HEIGHT_SENT, StatName: 'fhs', @@ -17457,11 +17514,11 @@ var Circuit = (function (circuit) { } }); - var RtpStatsConfig = { - COLLECTION_INTERVAL: 5000, - DELAY_UPON_ANSWER: _isMobile ? 0 : 5000, - DELAY_RTT_PROCESSING: 3 // googRTT takes few seconds to settle, so skip 3 stat collection cycles - }; + var SsrcContents = Object.freeze({ + AUDIO: 'audio', + VIDEO: 'video', + SCREEN: 'screen' + }); var CallStats = Object.freeze({ audioOutputLevel: 'aol', @@ -17534,17 +17591,21 @@ var Circuit = (function (circuit) { var browserInfo = Utils.getBrowserInfo(); - function CallStatsHandlerUnified(peerConnections) { + function CallStatsHandlerUnified(peerConnections, isDirectCall) { // NOSONAR if (!Array.isArray(peerConnections)) { throw new Error('peerConnections must be an array'); } ///////////////////////////////////////////////////////////////////////////// - // Internal Variables + // Constants ///////////////////////////////////////////////////////////////////////////// var LOG_SKIP_COUNTER = 6; // If there's no issues, log stats every 30 seconds var MAX_VIOLATIONS = 20; // Only log the violations up to this limit + var STREAM_QUALITY_SUMMARY_ITERATIONS = 6; + ///////////////////////////////////////////////////////////////////////////// + // Internal Variables + ///////////////////////////////////////////////////////////////////////////// var _peerConnections = peerConnections.filter(function (pc) { return pc; }); if (!peerConnections.length) { throw new Error('Cannot create CallStatsHandler object without at least one peer connection'); @@ -17552,6 +17613,7 @@ var Circuit = (function (circuit) { var _nics = circuit.WebRTCAdapter.getNetmaskMap(); + var _isDirectCall = !!isDirectCall; var _options = {}; var _rtpStatsDelayUponAnsTimer = null; @@ -17566,12 +17628,19 @@ var Circuit = (function (circuit) { var _qosCollected; var _qualityIssueDetected = false; var _lowQualityVideoTracks = {}; + var _streamQualityData = null; + var _tmpStreamQualityData = { + audio: null + }; + + var _streamQualityStatsToCheck = [ + RTPAudioStatType.GOOG_JITTER_RECEIVED, + RTPAudioStatType.PACKET_LOSS_RECV, + RTPAudioStatType.GOOG_RTT + ]; // Create copy of HD stat object so we can modify thresholds depending on video resolution - var _rtpHDVideoStatType = {}; - Object.keys(RTPHDVideoStatType).forEach(function (key) { - _rtpHDVideoStatType[key] = Object.assign({}, RTPHDVideoStatType[key]); - }); + var _rtpHDVideoStatType = JSON.parse(RTPHDVideoStatType); var _that = this; @@ -17596,7 +17665,7 @@ var Circuit = (function (circuit) { function getAddrByNetworkIdForQosReport(parsedMLine, selectedCandidate, type) { var addr; - // Find corresponding address based on the type and networkid + // Find corresponding address based on the type and network-id parsedMLine.a.some(function (a) { if (a.field === 'candidate' && a.value) { var candidate = new circuit.IceCandidate(a.value); @@ -17653,11 +17722,7 @@ var Circuit = (function (circuit) { info.hAddr = res.stat('ipAddress'); // ANS-51833: In some cases of VPN connected calls, selected candidate is host // but, backend needs srflx host address for the QoS bandwidth calculations - // get srflx address if there any otherwise default to host address. info.sAddr = getAddrByNetworkIdForQosReport(m, candidate, 'srflx'); - if (!info.sAddr) { - info.sAddr = info.hAddr; - } } else { if (type === 'srflx') { info.sAddr = candidate.address; @@ -17735,17 +17800,6 @@ var Circuit = (function (circuit) { } else { getChannelInfo(channelInfo, res); } - // Find the media types that use this channel - channelInfo.mediaTypes = []; - ['audio', 'video'].forEach(function (m) { - ['transmit', 'receive'].forEach(function (direction) { - Object.keys(formattedStats[m][direction]).forEach(function (ssrc) { - if (formattedStats[m][direction][ssrc].channelId === channelId && !channelInfo.mediaTypes.includes(m)) { - channelInfo.mediaTypes.push(m); - } - }); - }); - }); } formattedStats.channelInfo[channelId] = channelInfo; } @@ -17756,7 +17810,7 @@ var Circuit = (function (circuit) { var commonData = { id: res.id, ssrc: ssrc, - content: res.stat('googContentType'), + content: res.stat('googContentType'), // 'realtime' or 'screen' channelId: res.stat('transportId'), trackId: res.stat('googTrackId') }; @@ -17767,29 +17821,32 @@ var Circuit = (function (circuit) { formattedStats.audio.transmit[ssrc] = commonData; } statsPtr = formattedStats.audio.transmit[ssrc]; + statsPtr.content = SsrcContents.AUDIO; } else if (res.stat('audioOutputLevel')) { if (!formattedStats.audio.receive[ssrc]) { formattedStats.audio.receive[ssrc] = commonData; } statsPtr = formattedStats.audio.receive[ssrc]; + statsPtr.content = SsrcContents.AUDIO; } else if (res.stat('googFrameHeightSent')) { if (!formattedStats.video.transmit[ssrc]) { formattedStats.video.transmit[ssrc] = commonData; } - if (browserInfo.firefox && res.stat('mid') === pc.getScreenShareMediaId()) { - // In FF we don't have googContentType, so we need to do it ourselves - commonData.content = 'screen'; + if (browserInfo.firefox) { + // In FF we don't have googContentType, but it provides the 'mid' attribute, which we can use to identify + // the screen ssrc + commonData.content = res.stat('mid') === pc.getScreenShareMediaId() ? SsrcContents.SCREEN : SsrcContents.VIDEO; + } else if (commonData.content !== SsrcContents.SCREEN) { + // googContentType has 'screen' if screen is being transmitted. If not, mark it as video + commonData.content = SsrcContents.VIDEO; } statsPtr = formattedStats.video.transmit[ssrc]; } else if (res.stat('googFrameHeightReceived')) { if (!formattedStats.video.receive[ssrc]) { formattedStats.video.receive[ssrc] = commonData; } - if (pc.desktopRemoteSsrc.includes(commonData.ssrc)) { - // It's tricky to find out which SSRC is sending the screen. - // We need to resort to checking SDP contents - commonData.content = 'screen'; - } + // Check if this ssrc is listed under the screenshare m-line, otherwise consider it a video ssrc + commonData.content = pc.desktopRemoteSsrc.includes(commonData.ssrc) ? SsrcContents.SCREEN : SsrcContents.VIDEO; statsPtr = formattedStats.video.receive[ssrc]; } @@ -17879,6 +17936,18 @@ var Circuit = (function (circuit) { parsedLocalSdp = parsedLocalSdp || circuit.sdpParser.parse(pc.localDescription && pc.localDescription.sdp); info.candidate = getIceCandidateInfo(local, parsedLocalSdp); } + // Analyze what kind of media is trafficking through this channel. + // For optimization, we're only checking if it's receiving audio (we're assuming it's also transmitting) + // and if it's transmitting video (not screen) + var audioReceive = formattedStats.audio.receive; + info.isAudioChannel = info.isAudioChannel || Object.values(audioReceive).some(function (audioChannel) { + return audioChannel.channelId === channelId; + }); + var videoSend = formattedStats.video.transmit; + info.isVideoSendChannel = info.isVideoSendChannel || Object.values(videoSend).some(function (videoChannel) { + return videoChannel.channelId === channelId && + videoChannel.content === SsrcContents.VIDEO && !_lowQualityVideoTracks[videoChannel.trackId]; + }); } }); } @@ -17931,7 +18000,8 @@ var Circuit = (function (circuit) { return getPcStats(mainPc, 'AUDIO/VIDEO/SCREEN', mainPc.startTime, includeQosData) .then(function (stats) { if (stats) { - ['audio', 'video'].forEach(function (media) { + // Associate each SSRC to their channels + [SsrcContents.AUDIO, SsrcContents.VIDEO].forEach(function (media) { if (stats[media]) { ['transmit', 'receive'].forEach(function (direction) { Object.keys(stats[media][direction]).forEach(function (ssrc) { @@ -18192,22 +18262,22 @@ var Circuit = (function (circuit) { var savedStats = _savedRTPStats[trackId] || {}; var audioIssues = _audioIssues[trackId] || {}; var send = statsReport.audio.transmit[trackId]; - send.media = 'audio'; - // * Packet loss if (send) { + send.media = SsrcContents.AUDIO; + // Packet loss var statType = RTPAudioStatType.PACKET_LOSS_SEND; var currentPL = calculatePLSent(send, savedStats); if (send.pl && send.ps) { issueCounter(audioIssues, statType, currentPL >= statType.Threshold[0] ? currentPL : -1, statsReport.startTime, send, savedStats); } - analyzeCallQuality(statsReport, statType, 'audio', currentPL); + analyzeCallQuality(statsReport, statType, SsrcContents.AUDIO, currentPL); var packetsSent = (send.ps || 0) - (savedStats.ps || 0); issueCounter(audioIssues, RTPAudioStatType.NO_PACKETS_SEND, packetsSent > 0 ? -1 : true, statsReport.startTime, send, savedStats); - // * Echo likelihood + // Echo likelihood statType = RTPAudioStatType.ECHO_LIKELIHOOD; calculateAverageAndMax(send, savedStats, RTPAudioStatType.ECHO_LIKELIHOOD.StatName); var statValue = send[statType.StatName] || 0; @@ -18225,32 +18295,34 @@ var Circuit = (function (circuit) { var savedStats = _savedRTPStats[trackId] || {}; var audioIssues = _audioIssues[trackId] || {}; var rcv = statsReport.audio.receive[trackId]; - rcv.media = 'audio'; - var statType = RTPAudioStatType.PACKET_LOSS_RECV; + if (rcv) { + rcv.media = SsrcContents.AUDIO; var currentPL = calculatePLReceived(rcv, savedStats); if (rcv.pl && rcv.pr) { issueCounter(audioIssues, statType, currentPL >= statType.Threshold[0] ? currentPL : -1, statsReport.startTime, rcv, savedStats); } - analyzeCallQuality(statsReport, statType, 'audio', currentPL); + analyzeCallQuality(statsReport, statType, SsrcContents.AUDIO, currentPL); - // * Packets received - check if we're receiving packets. If not, assume that either we + // Packets received - check if we're receiving packets. If not, assume that either we // lost connection or the other peer stopped responding if (!_options.sendOnlyStream) { issueCounter(audioIssues, RTPAudioStatType.NO_PACKETS_RECV, rcv.pr > savedStats.pr ? -1 : true, statsReport.startTime, rcv, savedStats); } - // * Jitter received + // Jitter received statType = RTPAudioStatType.GOOG_JITTER_RECEIVED; var statValue; calculateAverageAndMax(rcv, savedStats, RTPAudioStatType.GOOG_JITTER_RECEIVED.StatName); statValue = rcv[statType.StatName]; - analyzeCallQuality(statsReport, statType, 'audio', statValue); + analyzeCallQuality(statsReport, statType, SsrcContents.AUDIO, statValue); issueCounter(audioIssues, statType, statValue && statValue >= statType.Threshold[0] ? statValue : -1, statsReport.startTime, rcv, savedStats); + + statsReport.quality.audio.trackId = trackId; } _savedRTPStats[trackId] = rcv; _audioIssues[trackId] = audioIssues; @@ -18266,32 +18338,26 @@ var Circuit = (function (circuit) { } function getHDVideoResolutionInfo(statsReport, fhs, fws) { + var videoInfo = {}; if (fhs >= 0 && fws >= 0) { - statsReport.quality.videoInfo = { - resolution: { - height: fhs, - width: fws - } + videoInfo.resolution = { + height: fhs, + width: fws }; - var hdVideo = null; - switch (fhs) { + var height = Math.min(fhs, fws); + switch (height) { case 1080: - hdVideo = VideoResolutionLevel.VIDEO_1080; + videoInfo.hdVideo = VideoResolutionLevel.VIDEO_1080; break; case 720: - hdVideo = VideoResolutionLevel.VIDEO_720; + videoInfo.hdVideo = VideoResolutionLevel.VIDEO_720; break; case 480: - hdVideo = VideoResolutionLevel.VIDEO_480; + videoInfo.hdVideo = VideoResolutionLevel.VIDEO_480; break; } - if (hdVideo) { - statsReport.quality.videoInfo.hdVideo = hdVideo; - } - } else { - // This client doesn't support fhs and/or fws - statsReport.quality.videoInfo = {}; } + statsReport.quality.videoInfo = videoInfo; } function processTransmitVideoRTPStats(statsReport) { @@ -18299,7 +18365,7 @@ var Circuit = (function (circuit) { var savedStats = _savedRTPStats[trackId] || {}; var videoIssues = _videoIssues[trackId] || {}; var send = statsReport.video.transmit[trackId]; - send.media = 'video'; + send.media = SsrcContents.VIDEO; // Packet loss var statType = RTPVideoStatType.PACKET_LOSS_SEND; @@ -18309,18 +18375,23 @@ var Circuit = (function (circuit) { issueCounter(videoIssues, statType, currentPL >= statType.Threshold[0] ? currentPL : -1, statsReport.startTime, send, savedStats); } - analyzeCallQuality(statsReport, statType, 'video', currentPL); - analyzeCallQuality(statsReport, _rtpHDVideoStatType.FRAME_HEIGHT_SENT, 'video', send.fhs); - analyzeCallQuality(statsReport, _rtpHDVideoStatType.FRAME_WIDTH_SENT, 'video', send.fws); - analyzeCallQuality(statsReport, _rtpHDVideoStatType.FRAME_RATE_SENT, 'video', send.frs); - if (statsReport.video.bw) { - analyzeCallQuality(statsReport, _rtpHDVideoStatType.TRANSMIT_BIT_RATE, 'video', statsReport.video.bw.tbr); - analyzeCallQuality(statsReport, _rtpHDVideoStatType.AVAIL_SEND_BW, 'video', statsReport.video.bw.abw); + if (send.content === SsrcContents.VIDEO) { + // Only analyze quality if video (not screen) is being transmitted + analyzeCallQuality(statsReport, statType, SsrcContents.VIDEO, currentPL); + + // Handle portrait and landscape videos + var width = Math.max(send.fws, send.fhs) || send.fws; + var height = Math.min(send.fws, send.fhs) || send.fhs; + analyzeCallQuality(statsReport, _rtpHDVideoStatType.FRAME_HEIGHT_SENT, SsrcContents.VIDEO, height); + analyzeCallQuality(statsReport, _rtpHDVideoStatType.FRAME_WIDTH_SENT, SsrcContents.VIDEO, width); + analyzeCallQuality(statsReport, _rtpHDVideoStatType.FRAME_RATE_SENT, SsrcContents.VIDEO, send.frs); + if (statsReport.video.bw) { + analyzeCallQuality(statsReport, _rtpHDVideoStatType.TRANSMIT_BIT_RATE, SsrcContents.VIDEO, statsReport.video.bw.tbr); + analyzeCallQuality(statsReport, _rtpHDVideoStatType.AVAIL_SEND_BW, SsrcContents.VIDEO, statsReport.video.bw.abw); + } + getHDVideoResolutionInfo(statsReport, send.fhs, send.fws); } - getHDVideoResolutionInfo(statsReport, send.fhs, send.fws); - statsReport.video.isActive = true; } - _savedRTPStats[trackId] = send; _videoIssues[trackId] = videoIssues; }); @@ -18331,8 +18402,7 @@ var Circuit = (function (circuit) { var savedStats = _savedRTPStats[trackId] || {}; var videoIssues = _videoIssues[trackId] || {}; var rcv = statsReport.video.receive[trackId]; - rcv.media = 'video'; - + rcv.media = SsrcContents.VIDEO; // Packet loss var statType = RTPVideoStatType.PACKET_LOSS_RECV; if (rcv && rcv.pr) { @@ -18341,8 +18411,6 @@ var Circuit = (function (circuit) { issueCounter(videoIssues, statType, currentPL >= statType.Threshold[0] ? currentPL : -1, statsReport.startTime, rcv, savedStats); } - analyzeCallQuality(statsReport, statType, 'video', currentPL); - statsReport.video.isActive = true; // Mark video as active, because we can have inbound ssrc's but no packets are received } _savedRTPStats[trackId] = rcv; _videoIssues[trackId] = videoIssues; @@ -18354,7 +18422,7 @@ var Circuit = (function (circuit) { return; } _savedRTPStats.bw = statsReport.video.bw || {}; - _savedRTPStats.bw.media = 'video'; + _savedRTPStats.bw.media = SsrcContents.VIDEO; processTransmitVideoRTPStats(statsReport); processReceiveVideoRTPStats(statsReport); @@ -18370,15 +18438,15 @@ var Circuit = (function (circuit) { issueCounter(issues, statType, channelInfo.rtt >= statType.Threshold[0] ? channelInfo.rtt : -1, statsReport.startTime, channelInfo, saved); - var media = channelInfo.mediaTypes || (saved && saved.mediaTypes) || []; - // The same channel can be used for audio and video, so we analyze RTT just once (since it's - // the same for both) - if (media.includes('audio')) { + // Only analyze RTT if the channel has audio or is transmitting video. + // After data is saved the first time, isAudioChannel and isVideoSendChannel properties are only in saved object. + saved = saved || channelInfo; + if (saved.isAudioChannel) { statType = RTPAudioStatType.GOOG_RTT; - analyzeCallQuality(statsReport, statType, 'audio', channelInfo.rtt); - } else if (media.includes('video') && statsReport.video.isActive) { + analyzeCallQuality(statsReport, statType, SsrcContents.AUDIO, channelInfo.rtt); + } else if (saved.isVideoSendChannel) { statType = RTPVideoStatType.GOOG_RTT; - analyzeCallQuality(statsReport, statType, 'video', channelInfo.rtt); + analyzeCallQuality(statsReport, statType, SsrcContents.VIDEO, channelInfo.rtt); } _channelIssues[channelId] = issues; }); @@ -18434,28 +18502,34 @@ var Circuit = (function (circuit) { } } - if (!_savedRTPStats.quality || (statsReport.quality.level !== _savedRTPStats.quality.level)) { + var oldLevel = _savedRTPStats.quality && _savedRTPStats.quality.level; + + // Stats must be saved before raisting onNetworkQuality event + _savedRTPStats.quality = { + level: statsReport.quality.level, + audio: statsReport.quality.audio, + video: statsReport.quality.video + }; + if (statsReport.quality.videoInfo) { + _savedRTPStats.quality.videoInfo = statsReport.quality.videoInfo; + } + + if (statsReport.quality.level !== oldLevel) { // Log the overall and quality level for all stats var log = '[CallStatsHandlerUnified]: calculateOverallQuality:'; - ['audio', 'video'].forEach(function (media) { + [SsrcContents.AUDIO, SsrcContents.VIDEO].forEach(function (media) { log += '\n' + media + ':'; var logRef = statsReport.quality[media]; Object.keys(logRef).forEach(function (k) { - log += ' ' + k + '=' + logRef[k].qualityLevel.levelName + '[' + logRef[k].value + ']'; + if (k !== 'trackId') { + log += ' ' + k + '=' + logRef[k].qualityLevel.levelName + '[' + logRef[k].value + ']'; + } }); }); log += '\nOverall: ' + statsReport.quality.level.levelName; logger.debug(log); _that.onNetworkQuality && _that.onNetworkQuality(statsReport.quality); } - _savedRTPStats.quality = { - level: statsReport.quality.level, - audio: statsReport.quality.audio, - video: statsReport.quality.video - }; - if (statsReport.quality.videoInfo) { - _savedRTPStats.quality.videoInfo = statsReport.quality.videoInfo; - } } function processQualityIssues(statsReport) { @@ -18501,6 +18575,7 @@ var Circuit = (function (circuit) { processRttStats(statsReport); foundQualityIssues = processQualityIssues(statsReport); saveChannelInfo(statsReport); + collectClvStats(statsReport.quality, SsrcContents.AUDIO); if (!foundQualityIssues && _qualityIssueDetected) { // Since there are no issues we can clear the threshold exceeded error @@ -18529,14 +18604,18 @@ var Circuit = (function (circuit) { } function stopCollectingRTPStats() { + logger.debug('[CallStatsHandlerUnified]: stopCollectingRTPStats ', _streamQualityData); + var promise = getRTPStatsForClientDiagnostics(true); + // Probably there are not yet averaged data so write them also + writeClvStats(SsrcContents.AUDIO); if (_rtpStatsDelayUponAnsTimer) { - logger.debug('[CallStatsHandlerUnified]: cancel collecting RTPStats '); + logger.debug('[CallStatsHandlerUnified]: Cancel collecting RTP stats '); window.clearTimeout(_rtpStatsDelayUponAnsTimer); _rtpStatsDelayUponAnsTimer = null; } else if (_rtpStatsCollectionTimer) { - logger.debug('[CallStatsHandlerUnified]: stop collecting RTPStats'); + logger.debug('[CallStatsHandlerUnified]: Stop collecting RTP stats'); window.clearInterval(_rtpStatsCollectionTimer); _rtpStatsCollectionTimer = null; @@ -18580,6 +18659,91 @@ var Circuit = (function (circuit) { return report; } + function getOldStreamQualityValue(media, stat) { + var data = _streamQualityData[media].qualityData; + return (data && data.length && data[data.length - 1][stat.StatName]) || 0; + } + + function getStreamQualityDataAverage(media) { + var qualityData = _tmpStreamQualityData[media]; + _tmpStreamQualityData[media] = null; + + if (!qualityData || !qualityData.count) { + return null; + } + + var count = qualityData.count; + delete qualityData.count; + + _streamQualityStatsToCheck.forEach(function (stat) { + var value = qualityData[stat.StatName]; + if (stat.StatName === RTPAudioStatType.PACKET_LOSS_RECV.StatName) { + value *= 100; + } + qualityData[stat.StatName] = Math.round(value / count); + }); + qualityData.timestamp = Date.now(); + return qualityData; + } + + function writeClvStats(media) { + var data = getStreamQualityDataAverage(media); + if (data) { + _streamQualityStatsToCheck.some(function (stat) { + var threshold = stat.StreamQualityThreshold; + var newValue = data[stat.StatName] || 0; + var oldValue = getOldStreamQualityValue(media, stat); + // Write initial data or if threshold exceeded + if (_streamQualityData[media].qualityData.length === 0 || Math.abs(oldValue - newValue) > threshold) { + logger.debug('[CallStatsHandlerUnified]: Writing into clientStreamQualityData - ', data); + _streamQualityData[media].qualityData.push(data); + return true; + } + return false; + }); + } + } + + function writeTmpClvStats(quality, media) { + var qualityData = _tmpStreamQualityData[media]; + if (!qualityData) { + qualityData = {count: 0}; + _streamQualityStatsToCheck.forEach(function (stat) { + qualityData[stat.StatName] = 0; + }); + _tmpStreamQualityData[media] = qualityData; + } + + _streamQualityStatsToCheck.forEach(function (stat) { + var value = (quality[media][stat.id] && quality[media][stat.id].value) || 0; + qualityData[stat.StatName] += value; + }); + qualityData.count++; + + if (_streamQualityData[media].qualityData.length === 0) { + // write initial dataType + writeClvStats(media); + } + } + + function collectClvStats(quality, media) { + // Only collect for direct calls. In Group Calls CLV retrieves this information from the MediaServer + if (!_isDirectCall) { + return; + } + + _streamQualityData = _streamQualityData || {}; + _streamQualityData[media] = _streamQualityData[media] || {qualityData: []}; + + _streamQualityData[media].trackId = quality[media].trackId; + + if (_tmpStreamQualityData[media] && _tmpStreamQualityData[media].count >= STREAM_QUALITY_SUMMARY_ITERATIONS) { + writeClvStats(media); + } else { + writeTmpClvStats(quality, media); + } + } + ///////////////////////////////////////////////////////////////////////////// // Public interfaces ///////////////////////////////////////////////////////////////////////////// @@ -18606,24 +18770,30 @@ var Circuit = (function (circuit) { return _savedRTPStats; }; + this.getStreamQualityData = function () { + return _streamQualityData; + }; + this.setTransmitVideoParams = function (params) { - params = params || {}; + if (!params) { + return; + } - if (params.mediaConstraints.hdVideo) { + if (params.mediaConstraints && params.mediaConstraints.hdVideo) { var resolution = params.mediaConstraints.videoResolution || VideoResolutionLevel.VIDEO_1080; - var height = 0, width = 0; + var height, width; switch (resolution) { case VideoResolutionLevel.VIDEO_1080: - width = 1920; height = 1080; + width = 1920; break; case VideoResolutionLevel.VIDEO_720: - width = 1280; height = 720; + width = 1280; break; default: - width = 854; height = 480; + width = 853; break; } _rtpHDVideoStatType.FRAME_RATE_SENT.Threshold = [20, 8, 3]; @@ -18633,15 +18803,20 @@ var Circuit = (function (circuit) { _rtpHDVideoStatType.FRAME_WIDTH_SENT.Threshold = [ 0.9 * width, 0.75 * width, 0.5 * width ]; - _rtpHDVideoStatType.AVAIL_SEND_BW.Threshold = _rtpHDVideoStatType.TRANSMIT_BIT_RATE.Threshold = [ - 0.9 * (params.bitRates.maxBitRate || 0) * 1024, - (params.bitRates.minBitRate || 0) * 1024, - ((params.bitRates.minBitRate && params.bitRates.minBitRate - 1) || 0) * 1024 - ]; + + var maxBitRate = (params.bitRates.maxBitRate || 0) * 1000; + var minBitRate = (params.bitRates.minBitRate || 0) * 1000; + var highThreshold = maxBitRate * 0.75; + if (highThreshold < minBitRate) { + // Min and max are too close. Use maxBitRate as threshold. + highThreshold = maxBitRate; + } + _rtpHDVideoStatType.AVAIL_SEND_BW.Threshold = [highThreshold, minBitRate, 0.5 * minBitRate]; + _rtpHDVideoStatType.TRANSMIT_BIT_RATE.Threshold = _rtpHDVideoStatType.AVAIL_SEND_BW.Threshold; } if (params.trackConstraints) { - // Find the low bandwidth/quality video sender(s): we don't report stats for them + // Find the low bandwidth/quality video sender(s). We don't report stats for them. Object.keys(params.trackConstraints).forEach(function (id) { var track = params.trackConstraints[id]; if (track.quality === Constants.VideoQuality.LOW) { @@ -18721,9 +18896,6 @@ var Circuit = (function (circuit) { // Timeout before raising onIceDisconnected event var ICE_DISCONNECT_DELAY = 1000; - // Maximum bandwidth to use with AS parameter - var MAX_BANDWIDTH = 10000; - var DEFAULT_VIDEO_CODEC = VideoCodecs.VP8; var DEGRADATION_MODE = Object.freeze({ @@ -18751,7 +18923,7 @@ var Circuit = (function (circuit) { maxBw: 2000 }, '720p': { - maxBw: 1536 + maxBw: 1500 }, '480p': { maxBw: 512 @@ -18912,6 +19084,9 @@ var Circuit = (function (circuit) { screen: 2 }; + // Maximum bandwidth to use with AS parameter on remote SDP for Chrome WebRTC implementation + var MAX_BANDWIDTH = Utils.isMobile() ? 2000 : 10000; + /////////////////////////////////////////////////////////////////////////// // Local variables /////////////////////////////////////////////////////////////////////////// @@ -19450,9 +19625,7 @@ var Circuit = (function (circuit) { } function updateVideoResolutionInMediaConstraints(resolution) { - if (resolution === VideoResolutionLevel.VIDEO_480 && _mediaConstraints.hdVideo && - _mediaConstraints.videoResolution !== resolution) { - logger.debug('[RtcSessionController]: Downgrading video from HD to SD. Resolution: ', resolution); + if (!resolution) { _mediaConstraints.hdVideo = false; } _mediaConstraints.videoResolution = resolution; @@ -19615,7 +19788,7 @@ var Circuit = (function (circuit) { function createCallStatsHandler(pcList) { if (WebRTCAdapter.unifiedPlanEnabled && circuit.CallStatsHandlerUnified) { - return new circuit.CallStatsHandlerUnified(pcList); + return new circuit.CallStatsHandlerUnified(pcList, _isDirectCall); } return new circuit.CallStatsHandler(pcList); } @@ -20174,10 +20347,15 @@ var Circuit = (function (circuit) { }); } - function sendQosAvailable(qos, isRenegotiation, lastSavedStats) { + function sendQosAvailable(qos, isRenegotiation, lastSavedStats, streamQualityData) { // Invoke onQosAvailable event handler logger.debug('[RtcSessionController]: send QosAvailable event'); - sendEvent(_that.onQosAvailable, {qos: qos, renegotiationInProgress: isRenegotiation, lastSavedStats: lastSavedStats}); + sendEvent(_that.onQosAvailable, { + qos: qos, + renegotiationInProgress: isRenegotiation, + lastSavedStats: lastSavedStats, + streamQualityData: streamQualityData + }); } ///////////////////////////////////////////////////////////////////////////// @@ -21208,7 +21386,10 @@ var Circuit = (function (circuit) { } else { mediaType = 'video'; } - if (WebRTCAdapter.unifiedPlanEnabled && _browser.chrome) { + + var isChromeWebRTC = WebRTCAdapter.unifiedPlanEnabled && (_browser.chrome || _isMobile); + if (isChromeWebRTC) { + // https://bugs.chromium.org/p/webrtc/issues/detail?id=10641 // https://bugs.chromium.org/p/chromium/issues/detail?id=1001080 // Chrome requires some upper limit for it max bandwidth as it fail when availableOutgoingBitrate is // around 50 mbps. Please note that this setting has nothing to do with the sent video stream, which @@ -21227,7 +21408,7 @@ var Circuit = (function (circuit) { var desktopMlineIndex, desktopXGoogle; if (_pc.desktopPeerConnection) { var desktopMode = _mediaConstraints.hdDesktop ? 'hdScreenShare' : 'screenShare'; - maxBw = WebRTCAdapter.unifiedPlanEnabled && _browser.chrome ? MAX_BANDWIDTH : RtcSessionController.sdpParameters[desktopMode].maxBw; + maxBw = isChromeWebRTC ? MAX_BANDWIDTH : RtcSessionController.sdpParameters[desktopMode].maxBw; desktopXGoogle = RtcSessionController.xGoogle[desktopMode]; // Set bandwidth and xgoogle parameters only on the screenshare m-line @@ -22177,7 +22358,7 @@ var Circuit = (function (circuit) { if (publishQos && qosRequired && qos) { // By the time the qos available, the _renegotiationInProgress flag is already cleared, // that's why we need to pass this isRenegotiation parameter around - sendQosAvailable(qos, isRenegotiation, callStats.getLastSavedStats()); + sendQosAvailable(qos, isRenegotiation, callStats.getLastSavedStats(), callStats.getStreamQualityData()); } if (!isRenegotiation) { _that.onQosAvailable = null; @@ -22973,11 +23154,8 @@ var Circuit = (function (circuit) { _isMockedCall = true; }; - // The following API is being provided exclusively to allow access to the RTCPeerConnection - // object to the Selenium testing framework for E2E automation test scenarios. - // This API SHALL NOT be used by the EVO/IMP client itself. this.getCurrentPeerConnection = function () { - return _pc.mainPeerConnection; + return _pc && _pc.mainPeerConnection; }; this.getNumberOfExtraVideoChannels = function () { @@ -24280,6 +24458,8 @@ var Circuit = (function (circuit) { var SP133_API_VERSION = 2090184; // 2.9.184-x var SP134_API_VERSION = 2090187; // 2.9.187-x var SP135_API_VERSION = 2090189; // 2.9.189-x + var SP136_API_VERSION = 2090190; // 2.9.190-x + var SP137_API_VERSION = 2090192; // 2.9.192-x var NOP = function () {}; @@ -24884,12 +25064,12 @@ var Circuit = (function (circuit) { this.unsubscribeAll = _connHandler.unsubscribeAll; - this.isSpacesFavoritesSupported = function () { - return _clientApiVersion > SP132_API_VERSION; + this.isHardPhoneOnlySupported = function () { + return _clientApiVersion > SP137_API_VERSION; }; - this.isSharepointSupported = function () { - return _clientApiVersion > SP133_API_VERSION; + this.isSpacesFavoritesSupported = function () { + return _clientApiVersion > SP132_API_VERSION; }; this.isPinVideoSupported = function () { @@ -24936,6 +25116,30 @@ var Circuit = (function (circuit) { return _clientApiVersion > SP135_API_VERSION; }; + this.isSpaceLikeEventingSupported = function () { + return _clientApiVersion > SP135_API_VERSION; + }; + + this.isSharepointSupported = function () { + return _clientApiVersion > SP136_API_VERSION; + }; + + this.isSpacesQuestionsSupported = function () { + return _clientApiVersion > SP136_API_VERSION; + }; + + this.isSpaceFlaggedItemsByIdsSupported = function () { + return _clientApiVersion > SP136_API_VERSION; + }; + + this.isSpacesPagesSupported = function () { + return _clientApiVersion > SP137_API_VERSION; + }; + + this.isSpaceScopesSupported = function () { + return _clientApiVersion > SP137_API_VERSION; + }; + /////////////////////////////////////////////////////////////////////////////// // Public User related Interfaces /////////////////////////////////////////////////////////////////////////////// @@ -28873,7 +29077,7 @@ var Circuit = (function (circuit) { }); }; - this.submitQOSData = function (qosData, cb) { + this.submitQOSData = function (qosData, streamQualityData, cb) { cb = cb || NOP; logger.debug('[ClientApiHandler]: submitQOSData...'); var request = { @@ -28883,6 +29087,9 @@ var Circuit = (function (circuit) { dataSets: qosData } }; + if (streamQualityData && _clientApiVersion > SP137_API_VERSION) { + request.submitQOSData.clientStreamQuality = streamQualityData; + } sendRequest(Constants.ContentType.INSTRUMENTATION, request, function (err, rsp) { if (isResponseValid(err, rsp, cb)) { cb(null); @@ -29067,6 +29274,45 @@ var Circuit = (function (circuit) { }, null, keysToOmitFromResponse, tenantContext); }; + this.addPhoneOnlyUser = function (data, cb, tenantContext) { + cb = cb || NOP; + logger.debug('[ClientApiHandler]: AddPhoneOnlyUser...'); + var request = { + type: Constants.AdministrationActionType.ADD_PHONE_ONLY_USER, + addPhoneOnlyUser: { + emailAddress: data.emailAddress || undefined, + lastName: data.lastName, + firstName: data.firstName, + locale: data.locale, + packageId: data.packageId + } + }; + sendRequest(Constants.ContentType.ADMINISTRATION, request, function (err, rsp) { + if (isResponseValid(err, rsp, cb)) { + cb(null, rsp.administration.addPhoneOnlyUserResult.user); + } + }, null, null, tenantContext); + }; + + this.addSharedDevice = function (data, cb, tenantContext) { + cb = cb || NOP; + logger.debug('[ClientApiHandler]: addSharedDevice...'); + var request = { + type: Constants.AdministrationActionType.ADD_SHARED_DEVICE, + addSharedDevice: { + name: data.name, + location: data.location || undefined, + locale: data.locale || undefined, + packageId: data.packageId + } + }; + sendRequest(Constants.ContentType.ADMINISTRATION, request, function (err, rsp) { + if (isResponseValid(err, rsp, cb)) { + cb(null, rsp.administration.addSharedDeviceResult.user); + } + }, null, null, tenantContext); + }; + this.deleteUser = function (id, cb, tenantContext) { cb = cb || NOP; logger.debug('[ClientApiHandler]: deleteUser...'); @@ -30763,6 +31009,29 @@ var Circuit = (function (circuit) { }, null, null, tenantContext); }; + this.findOpenscapeSitesByITSP = function (itspId, cb, tenantContext) { + cb = cb || NOP; + logger.debug('[ClientApiHandler]: findOpenscapeSitesByITSP...'); + + if (!itspId) { + logger.warn('[ClientApiHandler]: No ITSP id was provided'); + sendAsyncResp(cb, Constants.ReturnCode.INVALID_MESSAGE); + return; + } + var request = { + type: Constants.AdministrationActionType.FIND_OPENSCAPE_SITES_BY_ITSP, + findOpenscapeSitesByITSP: { + itspid: itspId + } + }; + + sendRequest(Constants.ContentType.ADMINISTRATION, request, function (err, rsp) { + if (isResponseValid(err, rsp, cb)) { + cb(null, rsp.administration.findOpenscapeSitesByITSPResult.siteList || []); + } + }, null, null, tenantContext); + }; + this.getPickupGroupMemberDNs = function (cb, tenantContext) { cb = cb || NOP; logger.debug('[ClientApiHandler]: getPickupGroupMemberDNs...'); @@ -32044,6 +32313,12 @@ var Circuit = (function (circuit) { cb = cb || NOP; logger.debug('[ClientApiHandler]: getFolderItems for ', data.provider); + if ((data.provider === Constants.ThirdPartyConnectorType.MS_SHAREPOINT) && !_self.isSharepointSupported()) { + logger.warn('[ClientApiHandler]: The getFolderItems operation for Sharepoint is not supported by the backend'); + sendAsyncResp(cb, Constants.ReturnCode.OPERATION_NOT_SUPPORTED); + return; + } + var request; switch (data.provider) { @@ -32062,12 +32337,16 @@ var Circuit = (function (circuit) { case Constants.ThirdPartyConnectorType.GOOGLE_DRIVE: case Constants.ThirdPartyConnectorType.ONE_DRIVE: case Constants.ThirdPartyConnectorType.SYNCPLICITY: + case Constants.ThirdPartyConnectorType.MS_SHAREPOINT: request = { type: Constants.ThirdPartyConnectorsActionType.GET_FOLDER_ITEMS_WITH_CURSOR, getFolderItemsWithCursor: { type: data.provider, syncpointId: data.syncpointId || undefined, id: data.folderId, + siteId: data.siteId || undefined, + folderType: data.folderType || undefined, + contentType: data.contentType || undefined, cursor: data.indexCursor, pageSize: data.pageSize, accessToken: data.accessToken || undefined @@ -32161,6 +32440,12 @@ var Circuit = (function (circuit) { var itemsData = requestData.itemsData; logger.debug('[ClientApiHandler]: shareFolderItems ' + provider + '...'); + if ((provider === Constants.ThirdPartyConnectorType.MS_SHAREPOINT) && !_self.isSharepointSupported()) { + logger.warn('[ClientApiHandler]: The shareFolderItems operation for Sharepoint is not supported by the backend'); + sendAsyncResp(cb, Constants.ReturnCode.OPERATION_NOT_SUPPORTED); + return; + } + var request; switch (provider) { case Constants.ThirdPartyConnectorType.BOX: @@ -32169,6 +32454,7 @@ var Circuit = (function (circuit) { case Constants.ThirdPartyConnectorType.GOOGLE_DRIVE: case Constants.ThirdPartyConnectorType.ONE_DRIVE: case Constants.ThirdPartyConnectorType.SYNCPLICITY: + case Constants.ThirdPartyConnectorType.MS_SHAREPOINT: request = { type: Constants.ThirdPartyConnectorsActionType.SHARE_FOLDER_ITEMS, shareFolderItems: { @@ -33088,6 +33374,12 @@ var Circuit = (function (circuit) { cb = cb || NOP; logger.debug('[ClientApiHandler]: getNCAData...'); + if (!timestamp) { + logger.warn('[ClientApiHandler]: Missing timestamp'); + sendAsyncResp(cb, Constants.ReturnCode.INVALID_MESSAGE); + return; + } + var keysToOmitFromResponse = [ 'response.space.getNCADataResult.getTopicWithRepliesResult.topic.topic.subject', 'response.space.getNCADataResult.getTopicWithRepliesResult.topic.content', @@ -33104,7 +33396,7 @@ var Circuit = (function (circuit) { var request = { type: Constants.SpaceActionType.GET_NCA_DATA, getNCAData: { - timestamp: timestamp || undefined, + timestamp: timestamp, spaceId: spaceId || undefined, topicId: topicId || undefined } @@ -33874,6 +34166,7 @@ var Circuit = (function (circuit) { 'response.space.getTopicWithRepliesResult.topic.content', 'response.space.getTopicWithRepliesResult.topic.contentTags', 'response.space.getTopicWithRepliesResult.topic.tags', + 'response.space.getTopicWithRepliesResult.topic.poll.options.[].text', 'response.space.getTopicWithRepliesResult.replies.[].content', 'response.space.getTopicWithRepliesResult.replies.[].attachments', 'response.space.getTopicWithRepliesResult.replies.[].contentTags', @@ -33904,6 +34197,36 @@ var Circuit = (function (circuit) { }, null, keysToOmitFromResponse); }; + + this.getOpenSpacePolls = function (spaceId, pagePointer, pageSize, cb) { + cb = cb || NOP; + logger.debug('[ClientApiHandler]: getOpenSpacePolls...'); + + if (!checkSpacesPollingSupported('getOpenSpacePolls', cb)) { + return; + } + + var keysToOmitFromResponse = [ + 'response.space.getOpenPollsResult.openPolls.[].subject' + ]; + + var request = { + type: Constants.SpaceActionType.GET_OPEN_POLLS, + getOpenPolls: { + spaceId: spaceId, + searchPointer: pagePointer || undefined, + numberOfResults: pageSize || undefined + } + }; + sendRequest(Constants.ContentType.SPACE, request, function (err, rsp) { + if (rsp && rsp.code === Constants.ReturnCode.NO_RESULT) { + cb(null, {openPolls: [], hasMore: false}); + } else if (isResponseValid(err, rsp, cb)) { + cb(null, rsp.space.getOpenPollsResult); + } + }, null, keysToOmitFromResponse); + }; + this.getSpaceReplies = function (topicId, timestamp, numberOfResults, direction, cb) { cb = cb || NOP; logger.debug('[ClientApiHandler]: getSpaceReplies...'); @@ -34321,6 +34644,66 @@ var Circuit = (function (circuit) { }, null, keysToOmitFromResponse); }; + this.voteSpacePoll = function (itemId, optionIds, cb) { + cb = cb || NOP; + logger.debug('[ClientApiHandler]: voteSpacePoll...'); + + if (!checkSpacesPollingSupported('voteSpacePoll', cb)) { + return; + } + + var keysToOmitFromResponse = [ + 'response.space.votePollOptionsResult.item.content', + 'response.space.votePollOptionsResult.item.attachments', + 'response.space.votePollOptionsResult.item.contentTags', + 'response.space.votePollOptionsResult.item.sharedItems.[].containerName', + 'response.space.votePollOptionsResult.item.sharedItems.[].topicSubject', + 'response.space.votePollOptionsResult.item.poll.options.[].text' + ]; + + var request = { + type: Constants.SpaceActionType.VOTE_POLL_OPTIONS, + votePollOptions: { + itemId: itemId, + optionIds: optionIds + } + }; + + sendRequest(Constants.ContentType.SPACE, request, function (err, rsp) { + if (isResponseValid(err, rsp, cb)) { + rsp.space.votePollOptionsResult.item.sanitized = _hasLastRequestBeenSanitized; + cb(null, rsp.space.votePollOptionsResult.item); + } + }, null, keysToOmitFromResponse); + }; + + this.getSpacePollOptionVoters = function (itemId, optionId, data, cb) { + cb = cb || NOP; + logger.debug('[ClientApiHandler]: getSpacePollOptionVoters...'); + + if (!checkSpacesPollingSupported('getSpacePollOptionVoters', cb)) { + return; + } + + var request = { + type: Constants.SpaceActionType.GET_POLL_OPTION_VOTERS, + getPollOptionVoters: { + itemId: itemId, + optionId: optionId, + searchPointer: (data && data.searchPointer) || undefined, + numberOfResults: (data && data.numberOfResults) || undefined + } + }; + + sendRequest(Constants.ContentType.SPACE, request, function (err, rsp) { + if (rsp && rsp.code === Constants.ReturnCode.NO_RESULT) { + cb(null, {participants: [], hasMore: false}); + } else if (isResponseValid(err, rsp, cb)) { + cb(null, rsp.space.getPollOptionVotersResult); + } + }); + }; + this.getSpaceLikes = function (itemId, pagePointer, pageSize, cb) { cb = cb || NOP; logger.debug('[ClientApiHandler]: getSpaceLikes...'); @@ -34401,10 +34784,21 @@ var Circuit = (function (circuit) { logger.debug('[ClientApiHandler]: getFlaggedSpaceItems...'); var keysToOmitFromResponse = [ - 'response.space.getFlaggedItemsResult.items.[].content', - 'response.space.getFlaggedItemsResult.items.[].attachments', - 'response.space.getFlaggedItemsResult.items.[].contentTags', - 'response.space.getFlaggedItemsResult.items.[].tags' + 'response.space.getFlaggedItemsResult.items.[].space.name', + 'response.space.getFlaggedItemsResult.items.[].space.description', + 'response.space.getFlaggedItemsResult.items.[].space.tags', + 'response.space.getFlaggedItemsResult.items.[].parentTopic.topic.subject', + 'response.space.getFlaggedItemsResult.items.[].parentTopic.content', + 'response.space.getFlaggedItemsResult.items.[].parentTopic.poll.subject', + 'response.space.getFlaggedItemsResult.items.[].item.poll.subject', + 'response.space.getFlaggedItemsResult.items.[].item.topic.subject', + 'response.space.getFlaggedItemsResult.items.[].item.topic.content', + 'response.space.getFlaggedItemsResult.items.[].item.content', + 'response.space.getFlaggedItemsResult.items.[].item.attachments', + 'response.space.getFlaggedItemsResult.items.[].item.contentTags', + 'response.space.getFlaggedItemsResult.items.[].item.tags', + 'response.space.getFlaggedItemsResult.items.[].item.sharedItems.[].containerName', + 'response.space.getFlaggedItemsResult.items.[].item.sharedItems.[].topicSubject' ]; var request = { @@ -34425,6 +34819,47 @@ var Circuit = (function (circuit) { }, null, keysToOmitFromResponse); }; + this.getFlaggedSpaceItemsByIds = function (itemIds, cb) { + cb = cb || NOP; + logger.debug('[ClientApiHandler]: getFlaggedSpaceItemsByIds...'); + + if (!_self.isSpaceFlaggedItemsByIdsSupported()) { + logger.warn('[ClientApiHandler]: The getFlaggedSpaceItemsByIds operation is not supported by the backend'); + sendAsyncResp(cb, Constants.ReturnCode.OPERATION_NOT_SUPPORTED); + return; + } + + var keysToOmitFromResponse = [ + 'response.space.getSpaceItemsByIdsWithTopicAndSpaceIdResult.items.[].space.name', + 'response.space.getSpaceItemsByIdsWithTopicAndSpaceIdResult.items.[].space.description', + 'response.space.getSpaceItemsByIdsWithTopicAndSpaceIdResult.items.[].space.tags', + 'response.space.getSpaceItemsByIdsWithTopicAndSpaceIdResult.items.[].parentTopic.topic.subject', + 'response.space.getSpaceItemsByIdsWithTopicAndSpaceIdResult.items.[].parentTopic.content', + 'response.space.getSpaceItemsByIdsWithTopicAndSpaceIdResult.items.[].parentTopic.poll.subject', + 'response.space.getSpaceItemsByIdsWithTopicAndSpaceIdResult.items.[].item.poll.subject', + 'response.space.getSpaceItemsByIdsWithTopicAndSpaceIdResult.items.[].item.topic.subject', + 'response.space.getSpaceItemsByIdsWithTopicAndSpaceIdResult.items.[].item.topic.content', + 'response.space.getSpaceItemsByIdsWithTopicAndSpaceIdResult.items.[].item.content', + 'response.space.getSpaceItemsByIdsWithTopicAndSpaceIdResult.items.[].item.attachments', + 'response.space.getSpaceItemsByIdsWithTopicAndSpaceIdResult.items.[].item.contentTags', + 'response.space.getSpaceItemsByIdsWithTopicAndSpaceIdResult.items.[].item.tags', + 'response.space.getSpaceItemsByIdsWithTopicAndSpaceIdResult.items.[].item.sharedItems.[].containerName', + 'response.space.getSpaceItemsByIdsWithTopicAndSpaceIdResult.items.[].item.sharedItems.[].topicSubject' + ]; + + var request = { + type: Constants.SpaceActionType.GET_SPACE_ITEMS_BY_IDS_WITH_TOPIC_AND_SPACE_ID, + getSpaceItemsByIdsWithTopicAndSpaceId: { + itemIds: itemIds + } + }; + sendRequest(Constants.ContentType.SPACE, request, function (err, rsp) { + if (isResponseValid(err, rsp, cb, true)) { + cb(null, rsp.space.getSpaceItemsByIdsWithTopicAndSpaceIdResult); + } + }, null, keysToOmitFromResponse); + }; + this.flagSpaceItem = function (itemId, cb) { cb = cb || NOP; logger.debug('[ClientApiHandler]: flagSpaceItem...'); @@ -35115,7 +35550,9 @@ var Circuit = (function (circuit) { CLICK_TO_ANSWER_REQUEST: 'CLICK_TO_ANSWER_REQUEST', CLICK_TO_ANSWER_RESPONSE: 'CLICK_TO_ANSWER_RESPONSE', START_CONFERENCE_REQUEST: 'START_CONFERENCE_REQUEST', - START_CONFERENCE_RESPONSE: 'START_CONFERENCE_RESPONSE' + START_CONFERENCE_RESPONSE: 'START_CONFERENCE_RESPONSE', + NAVIGATE_REQUEST: 'NAVIGATE_REQUEST', + NAVIGATE_REQUEST_RESPONSE: 'NAVIGATE_REQUEST_RESPONSE' }); var ContactCardResponseCode = Object.freeze({ @@ -35131,7 +35568,8 @@ var Circuit = (function (circuit) { MUTE_DEVICE_FAILED: 'MUTE_DEVICE_FAILED', CONVERSATION_NAVIGATE_FAILED: 'CONVERSATION_NAVIGATE_FAILED', JOIN_CONFERENCE_FAILED: 'JOIN_CONFERENCE_FAILED', - START_CONFERENCE_FAILED: 'START_CONFERENCE_FAILED' + START_CONFERENCE_FAILED: 'START_CONFERENCE_FAILED', + NAVIGATE_REQUEST_FAILED: 'NAVIGATE_REQUEST_FAILED' }); var MeetingPointMessage = Object.freeze({ @@ -40108,7 +40546,8 @@ var Circuit = (function (circuit) { /////////////////////////////////////////////////////////////////////////////////////// // ExtensionSvc Implementation /////////////////////////////////////////////////////////////////////////////////////// - function ExtensionSvcImpl($rootScope, $timeout, $window, $q, LogSvc, PubSubSvc, PopupSvc, RegistrationSvc) { + // eslint-disable-next-line max-params + function ExtensionSvcImpl($rootScope, $timeout, $window, $q, LogSvc, PubSubSvc, PopupSvc, RegistrationSvc) { // NOSONAR LogSvc.debug('New Service: ExtensionSvc'); /////////////////////////////////////////////////////////////////////////////////////// @@ -40120,6 +40559,9 @@ var Circuit = (function (circuit) { var UNIVERGEBLUE_HOSTNAME = 'teams.univergeblue.com'; var BLUEBETA_HOSTNAME = 'bluebeta.circuit.com'; + var CHROME_URL = 'https://chrome.google.com/webstore/detail/'; + var EDGE_URL = 'https://microsoftedge.microsoft.com/addons/category/Edge-Extensions'; + // This defines the minimum extension version supported by the webclient. // Update this as old extension versions no longer work with the webclient. var MIN_EXTENSION_VERSION_STR = '1.2.1600'; @@ -40182,7 +40624,13 @@ var Circuit = (function (circuit) { } function getExtensionInstallUrl() { - var url = 'https://chrome.google.com/webstore/detail/'; + var url = $rootScope.browser.subType === 'edge' ? EDGE_URL : CHROME_URL; + + if ($rootScope.browser.subType === 'edge') { + LogSvc.info('[ExtensionSvc]: Set URL to Edge extension webstore link'); + // TODO: Complete URL with extension ID once available + return url; + } if ($rootScope.siemensAGUser) { url += 'siemens-circuit-by-unify/mnkbplodbhpkiphfeldjmaoickanlanc'; @@ -40202,7 +40650,7 @@ var Circuit = (function (circuit) { } function init() { - $rootScope.isChromeExtRunning = _self.isExtensionRunning(); + $rootScope.isBrowserExtRunning = _self.isExtensionRunning(); } function invokeHandlerApi(apiName, params, cb) { @@ -40272,7 +40720,7 @@ var Circuit = (function (circuit) { _extensionVersion = evt.data.version; validateExtensionVersion(); if (_extensionVersionSupported) { - $rootScope.isChromeExtRunning = true; + $rootScope.isBrowserExtRunning = true; LogSvc.setExtensionVersion(_extensionVersion); LogSvc.debug('[ExtensionSvc]: Publish /chromeExt/initialized event'); PubSubSvc.publish('/chromeExt/initialized'); @@ -40282,7 +40730,7 @@ var Circuit = (function (circuit) { _extConnHandler.addEventListener('extensionUnregistered', function () { $rootScope.$apply(function () { - $rootScope.isChromeExtRunning = false; + $rootScope.isBrowserExtRunning = false; LogSvc.debug('[ExtensionSvc]: Publish /chromeExt/unregistered event'); PubSubSvc.publish('/chromeExt/unregistered'); }); @@ -41946,6 +42394,7 @@ var Circuit = (function (circuit) { * * @class */ + // eslint-disable-next-line max-params function CircuitCallControlSvcImpl( $rootScope, $timeout, @@ -41958,7 +42407,7 @@ var Circuit = (function (circuit) { ConversationSvc, NotificationSvc, InstrumentationSvc, - DeviceDiagnosticSvc) { + DeviceDiagnosticSvc) { // NOSONAR // The following imports need to be defined inside CircuitCallControlSvcImpl due to JS-SDK var Conversation = circuit.Conversation; @@ -42742,7 +43191,7 @@ var Circuit = (function (circuit) { userId: apiParticipant.userId, firstName: apiParticipant.firstName, lastName: apiParticipant.lastName, - displayName: apiParticipant.displayName, + displayName: apiParticipant.userDisplayName, location: apiParticipant.location, userType: apiParticipant.participantType === Constants.RTCParticipantType.MEETING_POINT ? Constants.UserType.MEETING_POINT : Constants.UserType.REGULAR }); @@ -42765,6 +43214,7 @@ var Circuit = (function (circuit) { // Create a derived object var participant = RtcParticipant.createFromUser(user, Enums.ParticipantState.Active); + participant.apiDisplayName = apiParticipant.userDisplayName || apiParticipant.phoneNumber; participant.streamId = apiParticipant.videoStreamId || ''; participant.screenStreamId = apiParticipant.screenStreamId || ''; participant.mediaType = Proto.getMediaType(apiParticipant.mediaTypes || mediaType); @@ -42775,6 +43225,7 @@ var Circuit = (function (circuit) { participant.isMeetingGuest = apiParticipant.isMeetingGuest; participant.rtcSupportedFeatures = apiParticipant.rtcSupportedFeatures || []; participant.flags = apiParticipant.flags || []; + participant.videoPointerTo = apiParticipant.videoPointerTo; return participant; } @@ -43191,8 +43642,12 @@ var Circuit = (function (circuit) { // now we have to reset it sessionCtrl.dontReuseAudioStream = false; } + PubSubSvc.publish('/call/changeMediaType/completed', [call, err]); cb(err); }; + + PubSubSvc.publish('/call/changeMediaType/started', [call, data]); + sessionCtrl.dontReuseAudioStream = data.dontReuseAudioStream; var onSdp = function (evt) { sessionCtrl.onSessionDescription = null; @@ -44201,7 +44656,7 @@ var Circuit = (function (circuit) { if (recording.starter.userId === $rootScope.localUser.userId) { recording.starter.res = 'res_StartedRecording_You'; } else { - recording.starter.name = recording.starter.firstName || recording.starter.displayName; + recording.starter.name = recording.starter.displayName; recording.starter.res = recording.starter.name ? 'res_StartedRecording_Other' : 'res_StartedRecording'; } } @@ -44587,7 +45042,7 @@ var Circuit = (function (circuit) { LogSvc.info('[CircuitCallControlSvc]: QoS already submitted for call Id:', call.callId); return; } - InstrumentationSvc.sendQOSData(call, call.lastMediaType, event.qos, event.lastSavedStats); + InstrumentationSvc.sendQOSData(call, call.lastMediaType, event.qos, event.lastSavedStats, event.streamQualityData); } if (event.renegotiationInProgress) { @@ -45780,11 +46235,15 @@ var Circuit = (function (circuit) { } function addRemoveMedia(callId, mediaToChange, logMethodName, options) { + mediaToChange = mediaToChange || {}; logMethodName = logMethodName || 'addRemoveMedia'; + options = options || {}; + var logTopic = '[CircuitCallControlSvc]: ' + logMethodName + ': '; var localCall = findLocalCallByCallId(callId); var incomingCall = null; var currentMediaType = {}; + if (!localCall) { incomingCall = getIncomingCall(callId); if (!incomingCall || incomingCall.callId !== callId) { @@ -45794,16 +46253,22 @@ var Circuit = (function (circuit) { currentMediaType = incomingCall.mediaType; } else { currentMediaType = localCall.localMediaType; + if (typeof mediaToChange.desktop === 'boolean' && localCall.videoPointerTo) { + // Disable video pointer when enabling/disabling screenshare + mediaToChange.video = false; + options.videoPointerTo = null; + } } LogSvc.debug(logTopic, mediaToChange); var data = { callId: callId, - dontReuseAudioStream: !!(options && options.dontReuseAudioStream), + dontReuseAudioStream: !!(options.dontReuseAudioStream), mediaType: Object.assign({}, currentMediaType, mediaToChange), - videoPointerTo: (options && options.videoPointerTo) || null + videoPointerTo: options.videoPointerTo || null }; + // When adding/removing video or screenshare we need to reset the corresponding HD settings, so // they are properly initialized in adjustMediaTypeConstraints(). if (typeof mediaToChange.video === 'boolean' && typeof mediaToChange.hdVideo !== 'boolean') { @@ -45863,7 +46328,7 @@ var Circuit = (function (circuit) { LogSvc.debug('[CircuitCallControlSvc]: Number of call features enabled for CMRs', featureCounter); if (enabled) { - if (featureCounter >= 2) { + if (featureCounter >= 2 && call.previousScreenFeaturesState[featureName] !== featuresStates[featureName]) { call.screenEnabledFeature = featureName; LogSvc.debug('[CircuitCallControlSvc]: Selected feature to show on invited CMR:', call.screenEnabledFeature); } @@ -45882,6 +46347,7 @@ var Circuit = (function (circuit) { return false; }); } + call.previousScreenFeaturesState = featuresStates; // The following code is for backward compatibility with old CMRs (lower then 1.2.5400) // Latest versions of CMR inform Inviter about selectedFeature as soon as the one is changed @@ -46719,7 +47185,7 @@ var Circuit = (function (circuit) { mediaType.desktop = mediaType.desktop || localCall.localMediaType.desktop; localCall.mediaType = mediaType; localCall.activeClient = null; - if (mediaType.desktop !== localCall.lastMediaType.desktop) { + if (mediaType.desktop !== localCall.previousScreenFeaturesState.ToggleScreenShare) { var isScreenSharingEnabled = localCall.hasRemoteScreenShare() || localCall.hasLocalScreenShare(); updateScreenEnabledFeature(localCall, ScreenDisplayAction.ToggleScreenShare.name, isScreenSharingEnabled); } @@ -46742,7 +47208,9 @@ var Circuit = (function (circuit) { var oldPcState = callParticipant.pcState; var oldVideoStream = callParticipant.videoStream; - if (callParticipant.streamId !== normalizedParticipant.streamId || !callParticipant.hasSameMediaType(normalizedParticipant)) { + if (callParticipant.streamId !== normalizedParticipant.streamId || + callParticipant.screenStreamId !== normalizedParticipant.screenStreamId || + !callParticipant.hasSameMediaType(normalizedParticipant)) { mediaParticipantUpdate = true; } @@ -46995,13 +47463,19 @@ var Circuit = (function (circuit) { } var joinDataWrapper = evt.userEnteredStage ? { userEnteredStage: evt.userEnteredStage } : null; + var participant = localCall.getParticipant(normalizedParticipant.userId); LogSvc.debug('[CircuitCallControlSvc]: Publish /call/participant/joined event'); - PubSubSvc.publish('/call/participant/joined', [localCall, localCall.getParticipant(normalizedParticipant.userId), joinDataWrapper]); + PubSubSvc.publish('/call/participant/joined', [localCall, participant, joinDataWrapper]); simulateActiveSpeakers(); // Update the call's media type localCall.updateMediaType(); + // If recorded user joined call, update recording info + if (!localCall.isTestCall && localCall.recording.recordingUserId === participant.userId) { + localCall.recording.recordingUser = participant; + } + publishCallState(localCall); }); @@ -47184,7 +47658,9 @@ var Circuit = (function (circuit) { // Remove the leaving participant removeCallParticipant(localCall, userId, evt.cause); var isScreenSharingEnabled = localCall.hasRemoteScreenShare() || localCall.hasLocalScreenShare(); - updateScreenEnabledFeature(localCall, ScreenDisplayAction.ToggleScreenShare.name, isScreenSharingEnabled); + if (isScreenSharingEnabled !== localCall.previousScreenFeaturesState.ToggleScreenShare) { + updateScreenEnabledFeature(localCall, ScreenDisplayAction.ToggleScreenShare.name, isScreenSharingEnabled); + } if (localCall.isDirectUpgradedToConf && localCall.participants.length === 0) { leaveCall(localCall, null, Enums.CallClientTerminatedReason.ENDED_BY_ANOTHER_USER); } @@ -47726,6 +48202,8 @@ var Circuit = (function (circuit) { LogSvc.debug('[CircuitCallControlSvc]: Ignore UPDATED event, can not find participant to update for userId: ', userId); return; } + var startVideoPointer = !callParticipant.videoPointerTo && evt.participant.videoPointerTo + && $rootScope.localUser.userId === evt.participant.videoPointerTo; var normalizedParticipant = normalizeApiParticipant(evt.participant); var pState = normalizedParticipant.muted ? Enums.ParticipantState.Muted : Enums.ParticipantState.Active; @@ -47740,11 +48218,9 @@ var Circuit = (function (circuit) { lookupParticipant(updatedParticipant, localCall); if (mediaUpdate) { - var mediaTypeDesktop = localCall.mediaType.desktop; // Update the call's media type localCall.updateMediaType(); - - if (mediaTypeDesktop !== localCall.mediaType.desktop) { + if (localCall.previousScreenFeaturesState.ToggleScreenShare !== localCall.mediaType.desktop) { var isScreenSharingEnabled = localCall.hasRemoteScreenShare() || localCall.hasLocalScreenShare(); updateScreenEnabledFeature(localCall, ScreenDisplayAction.ToggleScreenShare.name, isScreenSharingEnabled); } @@ -47755,7 +48231,7 @@ var Circuit = (function (circuit) { } } - if (mediaUpdate || mutedUpdate) { + if (mediaUpdate || mutedUpdate || startVideoPointer) { LogSvc.debug('[CircuitCallControlSvc]: Publish /call/participant/updated event'); PubSubSvc.publish('/call/participant/updated', [localCall.callId, updatedParticipant, oldMediaType]); } @@ -48208,7 +48684,14 @@ var Circuit = (function (circuit) { LogSvc.debug('[CircuitCallControlSvc]: Ignore event as the user has other calls'); return; } - + if (evt.callingUserId === $rootScope.localUser.userId) { + LogSvc.debug('[CircuitCallControlSvc]: Ignore event as the calling user is the local user'); + return; + } + if (_callToPickup && _callToPickup.pickupSession === evt.rtcSessionId) { + LogSvc.debug('[CircuitCallControlSvc]: Ignore event for call that is already notified'); + return; + } $rootScope.$apply(function () { UserSvc.getUsersByIds([evt.callingUserId, evt.calledUserId], function (err, users) { if (err) { @@ -48234,8 +48717,7 @@ var Circuit = (function (circuit) { rtcSessionId: evt.rtcSessionId, convId: evt.rtcSessionId, type: Constants.ConversationType.DIRECT, - peerUser: callingUser, - participants: [] + participants: [{userId: callingUser.userId}] }; conversation = ConversationSvc.createConversationAsGuest(conversation); } @@ -48246,10 +48728,6 @@ var Circuit = (function (circuit) { _callToPickup.setRedirectingUser(null, null, calledUser.displayName, calledUser.userId, RedirectionTypes.CallPickupNotification); _callToPickup.pickUpFromUser = calledUser; _callToPickup.pickupSession = evt.rtcSessionId; - if (conversation.isTemporary) { - conversation.peerUser = callingUser; - _callToPickup.setPeerUser('', callingUser.displayName, callingUser.userId); - } conversation.call = _callToPickup; publishConversationUpdate(conversation); presentIncomingCall(conversation, callingUser.userId, true); @@ -48986,6 +49464,12 @@ var Circuit = (function (circuit) { } }; + if (localCall.videoPointerTo) { + // Disable video pointer + changeMediaData.mediaType.video = false; + changeMediaData.videoPointerTo = null; + } + changeMediaType(changeMediaData, function (err) { if (err) { LogSvc.warn('[CircuitCallControlSvc]: AddScreenShare failed: ', err); @@ -49593,7 +50077,9 @@ var Circuit = (function (circuit) { * * @param {String} callId The call ID of call for which video will be toggled. * @param {boolean} hdVideo Turn the HD video on/off. - * @param {Function} cb A callback function replying with an error + * @param {Function} cb A callback function replying with an error (1st parameter). If the desired video resolution is not supported, + * it will attempt to use a lower resolution defined in Circuit.Enums.VideoResolutionLevel. If successful, + * 'res_ToggleVideoResolutionNotSupported' is returned as a warning (2nd parameter). * @param {VideoResolutionLevel} videoResolution Desired HD resolution. Defaults to max HD resolution supported by camera. */ this.changeHDVideo = function (callId, hdVideo, cb, videoResolution) { @@ -49621,7 +50107,7 @@ var Circuit = (function (circuit) { if (localCall.localMediaType.hdVideo === hdVideo) { LogSvc.debug('[CircuitCallControlSvc]: changeHDVideo - No changes'); - cb(); + cb(null, null); return; } @@ -49643,7 +50129,11 @@ var Circuit = (function (circuit) { LogSvc.warn('[CircuitCallControlSvc]: changeHDVideo failed: ', err); cb('res_ToggleVideoFailed'); } else { - cb(); + var warning = null; + if (videoResolution && videoResolution !== localCall.localMediaType.videoResolution) { + warning = 'res_ToggleVideoResolutionNotSupported'; + } + cb(null, warning); } }); }; @@ -49653,7 +50143,9 @@ var Circuit = (function (circuit) { * * @param {String} callId The call ID of call for which video will be toggled. * @param {String} newResolution New HD video resolution. - * @param {Function} cb A callback function replying with an error + * @param {Function} cb A callback function replying with an error (1st parameter). If the new resolution is not supported, + * it will attempt to use a lower resolution defined in Circuit.Enums.VideoResolutionLevel. If successful, + * 'res_ToggleVideoResolutionNotSupported' is returned as a warning (2nd parameter). */ this.changeVideoResolution = function (callId, newResolution, cb) { cb = cb || function () {}; @@ -49663,9 +50155,9 @@ var Circuit = (function (circuit) { cb('No active call'); return; } - if (!localCall.localMediaType.video && !localCall.localMediaType.hdVideo) { + if (!localCall.localMediaType.video || !localCall.localMediaType.hdVideo) { LogSvc.warn('[CircuitCallControlSvc]: changeVideoResolution - Local call has no HD video'); - cb('No video'); + cb('No HD video'); return; } @@ -49678,7 +50170,7 @@ var Circuit = (function (circuit) { if (localCall.localMediaType.videoResolution === newResolution) { LogSvc.debug('[CircuitCallControlSvc]: changeVideoResolution - No changes'); - cb(); + cb(null, null); return; } @@ -49695,7 +50187,7 @@ var Circuit = (function (circuit) { LogSvc.warn('[CircuitCallControlSvc]: changeVideoResolution failed: ', err); cb('res_ToggleVideoFailed'); } else { - cb(); + cb(null, localCall.localMediaType.videoResolution !== newResolution ? 'res_ToggleVideoResolutionNotSupported' : null); } }); }; @@ -51085,7 +51577,7 @@ var Circuit = (function (circuit) { if (p.mediaType && p.mediaType.desktop) { // All users can take picture from screenshare - return !!(call.isDirect || (p.streams && p.streams.desktop)); + return !!((call.isDirect && p.streamId) || (p.streams && p.streams.desktop)); } // Only IC users can take picture from video @@ -51392,7 +51884,6 @@ var Circuit = (function (circuit) { var call = findLocalCallByCallId(callId); if (call && call.sessionCtrl) { var stats = call.sessionCtrl.getLastSavedStats(); - if (stats.quality) { return stats.quality; } @@ -51458,6 +51949,7 @@ var Circuit = (function (circuit) { * * @class */ + // eslint-disable-next-line max-params function CstaSvcImpl( $rootScope, $timeout, @@ -51466,8 +51958,7 @@ var Circuit = (function (circuit) { CircuitCallControlSvc, AtcRegistrationSvc, UserSvc, - ConversationSvc, - UserProfileSvc) { + UserProfileSvc) { // NOSONAR LogSvc.debug('New Service: CstaSvc'); @@ -51820,7 +52311,7 @@ var Circuit = (function (circuit) { return; } var originalPartnerChanged = atcCallInfo.originalPartnerDisplay && atcCallInfo.originalPartnerDisplay.fqn && - atcCallInfo.originalPartnerDisplay.fqn !== atcCallInfo.peerFQN && + (atcCallInfo.originalPartnerDisplay.fqn !== atcCallInfo.peerFQN || !remoteCall.peerUser.displayName) && !(remoteCall.pickedUp && remoteCall.direction === CallDirection.INCOMING); var partner = { @@ -54166,13 +54657,11 @@ var Circuit = (function (circuit) { return; } call.atcCallInfo.setServicesPermitted(event.servicesPermitted); - if (!call.atcCallInfo.peerFQN) { - display = getDisplayInfo(event.failingDevice || event.calledDevice); - if (display) { - // Update partner's display information if presented - call.atcCallInfo.setPartnerDisplay(display); - setCallPeerUser(call, call.atcCallInfo.peerDn, call.atcCallInfo.peerFQN, call.atcCallInfo.peerName); - } + display = getDisplayInfo(event.failingDevice || event.calledDevice); + if (display) { + // Update partner's display information if presented + call.atcCallInfo.setPartnerDisplay(display); + setCallPeerUser(call, call.atcCallInfo.peerDn, call.atcCallInfo.peerFQN, call.atcCallInfo.peerName); } switch (event.cause) { case 'busy': @@ -58866,7 +59355,6 @@ var Circuit = (function (circuit) { this.CircuitCallControlSvc, this.AtcRegistrationSvc, this.SdkHelperSvc, // UserSvc - this.SdkHelperSvc, // ConversationSvc this.SdkHelperSvc); // UserProfileSvc this.CallControlSvc = new circuit.CallControlSvcImpl( @@ -59103,8 +59591,8 @@ var Circuit = (function (circuit) { // changed in the future. circuit.ExtensionConnHandlerSingleton.getInstance(); - // Except for Safari, disable unifiedPlanEnabled for the SDK until end of 2019 to honor deprecation rule. - Circuit.WebRTCAdapter.unifiedPlanEnabled = !!browserInfo.safari; + // Except for Safari and FF, disable unifiedPlanEnabled for the SDK until end of 2019 to honor deprecation rule. + Circuit.WebRTCAdapter.unifiedPlanEnabled = !!(browserInfo.safari || browserInfo.firefox); /** * This is the main class of the Circuit module and is the entry point for all APIs. @@ -59734,7 +60222,8 @@ var Circuit = (function (circuit) { Constants.GetStuffType.SUPPORT_CONVERSATION_ID, Constants.GetStuffType.TELEPHONY_CONVERSATION_ID, Constants.GetStuffType.ACCOUNTS, - Constants.GetStuffType.PRESENCE_STATE + Constants.GetStuffType.PRESENCE_STATE, + Constants.GetStuffType.TENANT ]; _clientApiHandler.getStuff(types, function (err, stuff) { if (apiError(err, reject, true)) { return; } @@ -59742,6 +60231,7 @@ var Circuit = (function (circuit) { _supportConvId = stuff.supportConvId; publicizeUser(stuff.user) .then(function (user) { + user.secId = stuff.tenant.secId; _self.loggedOnUser = user; _services.SdkHelperSvc.setLocalUser(user); resolve(); @@ -62856,10 +63346,8 @@ var Circuit = (function (circuit) { // Publicize functions // Constants and helper function to build the random avatars - var DEFAULT_AVATAR = '/content/images/icon-general-default-avatar'; - var DEFAULT_OPEN_CONV_AVATAR = '/content/images/icon-general-openconvo-avatar'; - var DEFAULT_LARGE_CONV_AVATAR = '/content/images/icon-general-large-conference'; - var DEFAULT_GROUP_CONV_AVATAR = '/content/images/icon-general-emptyconvo-avatar'; + var DEFAULT_AVATAR = 'content/images/icon-general-default-avatar'; + var DEFAULT_GROUP_CONV_AVATAR = 'content/images/icon-general-default-group-avatar'; var COLORS = ['-blue', '-green', '-orange', '-yellow']; function getColor(convId) { @@ -62950,15 +63438,17 @@ var Circuit = (function (circuit) { return Promise.resolve(); } // Add avatar and avatarLarge attributes + var domain = fullDomain(); if (user.smallImageUri && user.largeImageUri) { - user.avatar = fullDomain() + 'fileapi/' + user.userId + '_s.jpg?fileid=' + user.smallImageUri; - user.avatarLarge = fullDomain() + 'fileapi/' + user.userId + '_b.jpg?fileid=' + user.largeImageUri; + user.avatar = domain + 'fileapi/' + user.userId + '_s.jpg?fileid=' + user.smallImageUri; + user.avatarLarge = domain + 'fileapi/' + user.userId + '_b.jpg?fileid=' + user.largeImageUri; user.hasAvatar = true; } else { // User does not have a profile picture. Let's assign a random one. var color = getColor(user.userId); - user.avatar = 'https://' + _self.domain + DEFAULT_AVATAR + color + '.png'; - user.avatarLarge = 'https://' + _self.domain + DEFAULT_AVATAR + color + '-XL.png'; + user.avatar = domain + DEFAULT_AVATAR + color + '.png'; + user.avatarLarge = domain + DEFAULT_AVATAR + color + '-XL.png'; + user.hasAvatar = false; } // Remove user attributes not exposed to SDK @@ -63124,22 +63614,16 @@ var Circuit = (function (circuit) { if (conv.type !== Constants.ConversationType.DIRECT) { // Add avatar and avatarLarge attributes + var domain = fullDomain(); if (!conv.conversationAvatar || !conv.conversationAvatar.smallPictureId || !conv.conversationAvatar.largePictureId) { // Conversation does not have an avatar - if (conv.type === Constants.ConversationType.OPEN) { - var color = conv.isDraft ? '-grey' : getColor(conv.convId); - conv.avatar = 'https://' + _self.domain + DEFAULT_OPEN_CONV_AVATAR + color + '.png'; - conv.avatarLarge = 'https://' + _self.domain + DEFAULT_OPEN_CONV_AVATAR + color + '-XL.png'; - } else if (conv.type === Constants.ConversationType.LARGE) { - conv.avatar = 'https://' + _self.domain + DEFAULT_LARGE_CONV_AVATAR + '.png'; - conv.avatarLarge = 'https://' + _self.domain + DEFAULT_LARGE_CONV_AVATAR + '-XL.png'; - } else { - conv.avatar = 'https://' + _self.domain + DEFAULT_GROUP_CONV_AVATAR + '.png'; - conv.avatarLarge = 'https://' + _self.domain + DEFAULT_GROUP_CONV_AVATAR + '-XL.png'; - } + var color = conv.isDraft ? '' : getColor(conv.convId); + conv.avatar = domain + DEFAULT_GROUP_CONV_AVATAR + color + '.png'; + conv.avatarLarge = domain + DEFAULT_GROUP_CONV_AVATAR + color + '-XL.png'; + conv.hasConversationAvatar = false; } else { - conv.avatar = fullDomain() + 'avatar?convId=' + conv.convId + '&type=small&fileid=' + conv.conversationAvatar.smallPictureId; - conv.avatarLarge = fullDomain() + 'avatar?convId=' + conv.convId + '&type=large&fileid=' + conv.conversationAvatar.largePictureId; + conv.avatar = domain + 'avatar?convId=' + conv.convId + '&type=small&fileid=' + conv.conversationAvatar.smallPictureId; + conv.avatarLarge = domain + 'avatar?convId=' + conv.convId + '&type=large&fileid=' + conv.conversationAvatar.largePictureId; conv.hasConversationAvatar = true; } // Transform OPEN to COMMUNITY @@ -63157,15 +63641,17 @@ var Circuit = (function (circuit) { return Promise.resolve(); } // Add avatar and avatarLarge attributes + var domain = fullDomain(); if (participant.smallImageUri && participant.largeImageUri) { - participant.avatar = fullDomain() + 'fileapi/' + participant.userId + '_s.jpg?fileid=' + participant.smallImageUri; - participant.avatarLarge = fullDomain() + 'fileapi/' + participant.userId + '_b.jpg?fileid=' + participant.largeImageUri; + participant.avatar = domain + 'fileapi/' + participant.userId + '_s.jpg?fileid=' + participant.smallImageUri; + participant.avatarLarge = domain + 'fileapi/' + participant.userId + '_b.jpg?fileid=' + participant.largeImageUri; participant.hasAvatar = true; } else { // User does not have a profile picture. Let's assign a random one. var color = getColor(participant.userId); - participant.avatar = 'https://' + _self.domain + DEFAULT_AVATAR + color + '.png'; - participant.avatarLarge = 'https://' + _self.domain + DEFAULT_AVATAR + color + '-XL.png'; + participant.avatar = domain + DEFAULT_AVATAR + color + '.png'; + participant.avatarLarge = domain + DEFAULT_AVATAR + color + '-XL.png'; + participant.hasAvatar = false; } // Remove participat attributes not exposed to SDK diff --git a/circuit.min.js b/circuit.min.js index 8d99fa0..b296062 100644 --- a/circuit.min.js +++ b/circuit.min.js @@ -30,13 +30,13 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * @version: 1.2.7402 + * @version: 1.2.7604 */ -var Circuit = {}; Object.defineProperty(Circuit, 'version', { value: '1.2.7402'}); +var Circuit = {}; Object.defineProperty(Circuit, 'version', { value: '1.2.7604'}); -var global=Function("return this")(),window=global.window||global,navigator=global.navigator||window.navigator||{},document=window.document,WebSocket=global.WebSocket,XMLHttpRequest=global.XMLHttpRequest,Promise=global.Promise,Circuit=function(be){"use strict";var Ue=be.Enums.ConnectionState,Le=be.Enums.ConversationType,Me=be.Constants,we=be.logger,Ge=be.PrivateData,He=be.Enums.Targets,ke=be.Enums.VideoResolutionLevel,Ve=be.Utils,Fe="tHuMbNaIl___",Be="CALL_RECORDING,CALLS,MENTION_EVENT,READ_CONVERSATIONS,READ_USER,READ_USER_PROFILE,WRITE_CONVERSATIONS,WRITE_USER_PROFILE";!function(e,t){if(e.location.hash||e.location.search){var n=Object.assign({},Ve.parseQS(e.location.hash),Ve.parseQS(e.location.search));if(n.state)try{Object.assign(n,JSON.parse(n.state))}catch(e){we.error("Could not decode state parameter")}if(n.display&&"popup"===n.display&&n.redirect_uri===e.location.origin+e.location.pathname&&e.document.addEventListener("DOMContentLoaded",function(){e.document.body.innerHTML="Redirecting, please wait..."}),n.callback){var i=n.callback;if(i in t)try{delete n.callback,t[i](n)}catch(e){}}n.display&&"popup"===n.display&&function(){if(window.frameElement&&window.parent)window.parent.document.body.removeChild(window.frameElement);else try{window.close()}catch(e){}}()}}(window,window.opener||window.parent);var t=Ve.getBrowserInfo();return be.ExtensionConnHandlerSingleton.getInstance(),Circuit.WebRTCAdapter.unifiedPlanEnabled=!!t.safari,be.Client=function(e){be.BaseEventTarget.call(this,be.logger);var l=this,t=be.Enums.ConnectionState.Disconnected,c=Ve.shallowCopy(e)||{};c.domain=c.domain||"circuitsandbox.net",c.emoticonMode=c.emoticonMode||"standard",h(e);var s,d,n,i,r,o,a,u="node"===window.navigator.platform,C="iOS"===window.navigator.platform||"Android"===window.navigator.platform,E=/]*)>([^;]*)((?:[^;]*;)*(?:displayNumber=(\d*)))?(?:;.*)*/,i=n.exec(e);i?(C.localUser.isOsBizCTIEnabled&&i[1]&&(i[1]=i[1].replace(/\/.*/,"")),t.fqn=i[1]||"",t.name=i[2]||"",t.dn=i[4]||i[1]||ne):(i=(n=/N([^;]*)/).exec(e))?(t.fqn=i[1]||"",t.dn=i[1]||ne):(t.fqn=e,t.dn=e)}return E.debug("[CstaSvc]: Retrieved partner display: ",t),t}function Ne(e){se();for(var t=u.getPhoneCalls(),n=[],i=0;i":r+=n?v.osmoFQN:v.osmoFQN+";epid="+v.epid;break;case Ot.Cell:if(!v.cell)return E.error("[CstaSvc]: Cell phone is not configured"),null;r+=v.cell;break;case Ot.Desk:r+=v.onsFQN,i&&v.osmoDeviceList&&(r="N<"+r+"/"+v.osmoDeviceList[0]+">");break;case Ot.VM:r=v.vm;break;case Ot.Other:t?r+=t:r=v.vm;break;default:return E.error("[CstaSvc]: Invalid target: "+e),null}return r}function Ue(e,t,n){return!(!C.localUser.isOsBizCTIEnabled||"connected"!==e||_e(t)!==Ot.Desk||_e(n)!==Ot.WebRTC)&&(E.debug("[CstaSvc]: DSS call move from desk to client"),!0)}function Le(e){return Object.assign(v,o.getAtcRegistrationData()),!(!{subscriber:C.localUser.cstaNumber}.subscriber||!v)||(e&&e("There is no registered user."),!1)}function Me(i,r,e){var t=N.genCstaRequest(i);if(!t)return E.error("[CstaSvc]: Failed to build CSTA request: "+i.request),void(r&&r("Failed to send the request"));if(Y===Ct.Registered){var n={content:{type:ut.CSTA,phoneNumber:C.localUser.cstaNumber,CSTA:t},destUserId:C.localUser.associatedTelephonyUserID};e&&(n.keysToOmitFromLogging=e.map(function(e){return"content.CSTA."+e})),_.sendAtcRequest(n,function(t,n){C.$apply(function(){if(t)E.warn("[CstaSvc]: ",t),r&&r(t);else{var e=N.parseResponse(i.request,n.CSTA);e||""===e?e.error?("Operation Error"===e.errorCategory&&"invalidConnectionID"===e.errorValue&&"busy"!==i.reason&&"AcceptCall"!==i.request&&"DeflectCall"!==i.request&&De(),r&&r(e.errorCategory+" - "+e.errorValue)):r&&r(null,e):r&&r("Failed to parse response from server")}})})}else r&&r("Client is not registered with ATC")}function we(e,t){t.transferredCall&&!t.seamlessHandover&&(L[e]={newCallId:t.transferredCall.cID,failedCallId:function(e){var t,n=(parseInt(e.substring(0,2),16)+2).toString(16).toUpperCase(),i=e.substring(2);return t=n.length<2?"0"+n+i:n+i,E.debug("[CstaSvc]: FailedCallId to be tracked: "+t),t}(t.transferredCall.cID),timeout:d(function(){delete L[e]},n)})}function Ge(e,t){return!(!e||!Le())&&((t===Ot.Other||e.atcCallInfo.position!==t)&&(!!function(){var e=Ze();v&&v.vm&&e.push(Ot.VM);return e.push(Ot.Other),e}().includes(t)||(E.error("[CstaSvc]: isTargetAllowed invoked with invalid target: "+t),!1)))}function He(){C.localUser.isOsBizCTIEnabled||(E.debug("[CstaSvc]: Synchronize the selected routing option"),f.updateRoutingOption(C.localUser.selectedRoutingOption))}function ke(){var e=!w,t=!(!v||!v.cell);E.debug("[CstaSvc]: Publish /csta/deviceChange event. desk="+e+", cell="+t),T.publish("/csta/deviceChange")}function Ve(){return C.localUser.isOsBizCTIEnabled?v.onsFQN:C.localUser.isOSV?Pt.normalizeDn(C.localUser.cstaNumber):C.localUser.cstaNumber}function Fe(e){var t=u.findOsBizFirstCall(),n=u.findOsBizSecondCall();if(t&&n){if(t.atcCallInfo.getCstaCallId()===e)return E.debug("[CstaSvc]: First local call with callId: ",e),E.debug("[CstaSvc]: Second local call with callId: ",n.atcCallInfo.getCstaCallId()),u.moveOsBizCalls(t,n),!0;if(n.atcCallInfo.getCstaCallId()===e)return E.debug("[CstaSvc]: Second local call with callId: ",e),E.debug("[CstaSvc]: First local call with callId: ",t.atcCallInfo.getCstaCallId()),u.moveOsBizCalls(n,t),!0}else if(!t&&!n){var i=de();if(i&&i.atcCallInfo&&i.atcCallInfo.getCstaCallId()===e){E.debug("[CstaSvc]: Remote call with callId: ",e);var r=pe();if(r){E.debug("[CstaSvc]: Second remote call with callId: ",r.atcCallInfo.getCstaCallId());var o=i.atcCallInfo;return i.atcCallInfo=r.atcCallInfo,i.setPeerUser(i.atcCallInfo.peerDn,i.atcCallInfo.peerName),r.atcCallInfo=o,delete P[i.atcCallInfo.getCstaCallId()],ue((P[o.getCstaCallId()]=r).atcCallInfo.getCstaCallId()),!0}}}return!1}function Be(t,n){return Object.values(P).some(function(e){return e.atcCallInfo.pickUp&&(C.localUser.isOSV?e.atcCallInfo.peerFQN===t:e.atcCallInfo.peerName===n)})}function xe(e){E.debug("[CstaSvc]: New pickup call for: ",e.calledDisplay.displayName);var t=Ie(e.callId);t.atcCallInfo.pickUp=!0,t.atcCallInfo.setPosition(Ot.Other),t.atcCallInfo.setPartnerDisplay(e.callingDisplay),P[e.callId]=t,e.event?(t.atcCallInfo.setServicesPermitted(e.event.servicesPermitted),t.atcCallInfo.setCstaConnection(e.event.connection)):e.callingUserId&&(t.pickupSession=e.callId,t.peerGtcUserId=e.callingUserId,t.setRedirectingUser(e.calledDisplay.dn,e.calledDisplay.fqn,e.calledDisplay.name,e.calledUserId,mt.CallPickupNotification)),t.setCstaState(Rt.Ringing),t.direction=pt.INCOMING,t.atcCallInfo.setOriginalPartnerDisplay(e.calledDisplay),re(t,t.atcCallInfo.peerDn,t.atcCallInfo.peerFQN,t.atcCallInfo.peerName,function(){e.callingUserId?ot(t):oe(t,e.calledDisplay.dn,e.calledDisplay.fqn,e.calledDisplay.name,mt.CallPickupNotification,function(){ot(t)})})}function We(e){var t,n,i=Ne(e.connection.cID);if(i)i.direction===pt.OUTGOING&&I.test(e.cause)?(oe(i,(t=ge(e.divertingDevice)).dn,t.fqn,t.name,mt.CallForward),n=ge(e.newDestination),i.setPeerUser(n.dn,n.name),i.atcCallInfo.setOriginalPartnerDisplay(t)):C.localUser.isOsBizCTIEnabled&&i.direction===pt.INCOMING&&i.isOsBizSecondCall&&fe(e.divertingDevice)&&Fe(e.connection.cID)&&E.debug("[CstaSvc]: Second call was diverted and released");else if("distributed"===e.cause&&fe(e.divertingDevice)&&_e(e.newDestination)===Ot.Desk)E.debug("[CstaSvc]: Ignore Diverted event with cause = distributed and newDestination = desk");else{if(i=P[e.connection.cID]){if(i.atcCallInfo.masterParallelHgCall)return void E.debug("[CstaSvc]: Ignore Diverted event for master parallel hunt group")}else i=Ie(e.connection.cID);if("null"===e.localConnectionInfo&&fe(e.divertingDevice)){if(fe(e.newDestination)){if(fe(e.newDestination)&&(_e(e.newDestination)===Ot.WebRTC&&(H={cID:e.connection.cID,dID:e.newDestination}),i)){if(i.pickupNotification)return;if("redirected"===e.cause&&e.lastRedirectionDevice&&!fe(e.lastRedirectionDevice)){var r=ge(e.lastRedirectionDevice);oe(i,r.dn,r.fqn,r.name,mt.CallForward),P[e.connection.cID]=i}if(C.localUser.isOsBizCTIEnabled&&"park"===e.cause&&_e(e.newDestination)!==_e(e.divertingDevice))return i.setRedirectionType(mt.Dss),void(P[e.connection.cID]=i);if(i.forwarded)return;if(i.checkCstaState(Rt.Ringing)&&_e(e.newDestination)===i.atcCallInfo.getPosition())return E.debug("[CstaSvc]: new destination has the same position as the current alerting position. Ignore event"),void(H={});i.atcCallInfo.setIgnoreCall(!0),E.debug("[CstaSvc]: Publish /atccall/info event"),T.publish("/atccall/info",[i])}}else{if((function(e){return!!e&&ge(e).dn===v.vm}(e.newDestination)||_e(e.connection.dID)===Ot.WebRTC||C.localUser.isOsBizCTIEnabled)&&i.atcCallInfo.setIgnoreCall(!0),i.setCstaState(Rt.Idle),i.direction=pt.INCOMING,i.atcCallInfo.setMissedReason(gt.CANCELLED),I.test(e.cause)){P[e.connection.cID]=i;var o=ge(e.callingDevice);E.debug("[CstaSvc]: Update partner display to ",o),i.atcCallInfo.setPartnerDisplay(o),re(i,i.atcCallInfo.peerDn,i.atcCallInfo.peerFQN,i.atcCallInfo.peerName)}E.debug("[CstaSvc]: Publish /atccall/info event"),T.publish("/atccall/info",[i])}i&&!i.isHandoverInProgress&&ue(e.connection.cID)}else if(!fe(e.divertingDevice)&&i){var a=ge(e.divertingDevice);if(a&&i.atcCallInfo.setOriginalPartnerDisplay(a),i.direction===pt.OUTGOING&&I.test(e.cause))return oe(i,(t=ge(e.divertingDevice)).dn,t.fqn,t.name,mt.CallForward),n=ge(e.newDestination),void i.setPeerUser(n.dn,n.name);i.atcCallInfo.setMissedReason(gt.CANCELLED),E.debug("[CstaSvc]: Publish /atccall/info event"),T.publish("/atccall/info",[i])}}}function Ye(e,t){k&&k.newCallId===t&&(e.direction=k.direction,e.setRedirectingUser(k.redirectingUser.phoneNumber,k.redirectingUser.fqNumber,k.redirectingUser.displayName,k.redirectingUser.userId,k.redirectingUser.redirectionType),e.atcCallInfo.transferCb=k.transferCb,delete k.transferCb,k={})}function Ke(e){return C.localUser.isOsBizCTIEnabled?{cID:e.getCstaCallId(),dID:v.onsFQN}:e.getCstaConnection()}function qe(e){var t,n,i,r,o;if(fe(e.queue)){t=e.queuedConnection,n=e.callingDevice,E.debug("[CstaSvc]: LocalConnection: ",t),E.debug("[CstaSvc]: Partner Device ID: ",n),i=_e(t.dID,e.epid);var a=ge(n);if(r=t.cID,!(o=P[r])){if("noAvailableAgents"===e.cause)return void E.debug("[CstaSvc]: Cause=noAvailableAgents. Ignore Queued event");if(C.localUser.isOsBizCTIEnabled&&(!C.localUser.pbxCampOnSupported||!C.circuitLabs.OSBIZ_EXTENDED_TELEPHONY)&&("multipleQueuing"===e.cause||"keyOperation"===e.cause||"campOn"===e.cause))return void E.debug("[CstaSvc]: CampOn is not supported. Ignore this event.");o=Ie(r),P[r]=o,E.debug("[CstaSvc]: Created new Remote Call object for callID= ",r)}if(o.atcCallInfo.setPosition(i),o.atcCallInfo.setPartnerDisplay(a),re(o,o.atcCallInfo.peerDn,o.atcCallInfo.peerFQN,o.atcCallInfo.peerName),o.setCstaState(Rt.Parked),o.atcCallInfo.setCstaConnection(t),C.localUser.isOsBizCTIEnabled&&C.circuitLabs.OSBIZ_EXTENDED_TELEPHONY&&C.localUser.pbxCampOnSupported&&("campOn"===e.cause||"keyOperation"===e.cause))if(h&&i===Ot.WebRTC){if(E.debug("[CstaSvc]: Cause=campOn. A local call is established and user receives new incoming call"),i===Ot.WebRTC)return void $e(o,e.servicesPermitted)}else Object.values(P).find(function(e){return e.isEstablished})&&i===Ot.Desk?(E.debug("[CstaSvc]: Cause=campOn. A remote call is established and user receives new incoming call"),m.call=o,E.debug("[CstaSvc]: Publish /conversation/update event. convId = ",m.convId),T.publish("/conversation/update",[m]),E.debug("[CstaSvc]: Publish /call/remote/incoming event"),T.publish("/call/remote/incoming",[o]),o.direction=pt.INCOMING,o.setCstaState(Rt.Ringing)):D&&(E.debug("[CstaSvc]: Cause=campOn. A call is ringing and user receives new incoming call. Do not display yet."),o.setCstaState(Rt.Ringing),o.direction=pt.INCOMING,o.atcCallInfo.setQueuedIncomingCall(!0))}else{if(!C.localUser.isOsBizCTIEnabled||!fe(e.callingDevice)||"campOn"!==e.cause)return void E.debug("[CstaSvc]: ONS DN is not the queue device. Ignore Queued event.");if(i=_e(e.callingDevice),r=e.queuedConnection.cID,!(o=i===Ot.WebRTC?Ne(r):P[r]))return void E.debug("[CstaSvc]: Call not found for callID= ",r);o.atcCallInfo.setOutgoingCallCampedOn(),o.isRemote&&o.checkCstaState(Rt.Busy)&&o.setCstaState(Rt.Delivered)}o.atcCallInfo.setServicesPermitted(e.servicesPermitted),E.debug("[CstaSvc]: Publish /atccall/info event"),T.publish("/atccall/info",[o])}function je(e){var t,n,i,r=e.failedConnection.cID;if("fail"===e.localConnectionInfo&&fe(e.failingDevice)){if((t=P[r])&&t.atcCallInfo&&t.atcCallInfo.masterParallelHgCall)return void E.debug("[CstaSvc]: Ignore Failed event for master parallel hunt group");switch(fe(e.callingDevice)&&(n=ge(e.calledDevice)).dn!==ne&&t&&!t.pickedUp&&n.fqn!==Pt.cleanPhoneNumber(t.atcCallInfo.peerFQN)&&(re(t,n.dn,n.fqn,n.name),t.atcCallInfo.setPartnerDisplay(n)),e.cause){case"blocked":U[r]&&E.debug("[CstaSvc]: Received Failed event for transfer, waiting for ConnectionCleared event"),C.localUser.isOSV||(i=_e(e.failedConnection.dID),(t=i===Ot.WebRTC?Ne(r):P[r])&&t.isHandoverInProgress&&(E.debug("[CstaSvc]: Received Failed event from non OSV PBX while handover is in progress"),t.clearAtcHandoverInProgress(),E.debug("[CstaSvc]: Publish /atccall/moveFailed event"),T.publish("/atccall/moveFailed")),C.localUser.isOsBizCTIEnabled&&t&&t.isRemote&&t.atcCallInfo&&t.atcCallInfo.setServicesPermitted(e.servicesPermitted));break;case"doNotDisturb":(t=P[r])?(E.debug("[CstaSvc]: Publish /atccall/info event"),T.publish("/atccall/info",[t])):E.warn("[CstaSvc]: DND call does not exist. Ignore Failed event");break;case"reorderTone":(t=P[r])?(t.atcCallInfo.setMissedReason(gt.REORDER_TONE),E.debug("[CstaSvc]: Publish /atccall/info event"),T.publish("/atccall/info",[t])):E.warn("[CstaSvc]: Outgoing call failed with reorder tone");break;case"busy":(t=P[r])?(t.atcCallInfo.setMissedReason(gt.BUSY),t.checkCstaState(Rt.Offered)&&t.setCstaState(Rt.Failed),t.atcCallInfo.clearOutgoingCallCampedOn(),E.debug("[CstaSvc]: Publish /atccall/info event"),T.publish("/atccall/info",[t])):E.warn("[CstaSvc]: Busy call does not exist. Ignore Failed event");break;case"destNotObtainable":(t=Ne(r)||P[r])&&d(function(){t.isPresent()&&function(e,t){var n=e.isOsBizSecondCall?u.findOsBizFirstCall():pe();if(e&&n&&Le(t)){return Me({request:"ReconnectCall",heldCall:Ke(n.atcCallInfo),activeCall:Ke(e.atcCallInfo)},t)}t&&t()}(t)},R)}}else if("connected"===e.localConnectionInfo&&fe(e.callingDevice)){if((t=Ne(r))&&t.atcCallInfo.getCstaCallId()===r||(t=P[r]),!t)return void E.warn("[CstaSvc]: Could not find call corresponding to handle FailedEvent Event.");switch(t.atcCallInfo.setServicesPermitted(e.servicesPermitted),t.atcCallInfo.peerFQN||(n=ge(e.failingDevice||e.calledDevice))&&(t.atcCallInfo.setPartnerDisplay(n),re(t,t.atcCallInfo.peerDn,t.atcCallInfo.peerFQN,t.atcCallInfo.peerName)),e.cause){case"busy":t.isRemote&&(t.setCstaState(Rt.Busy),t.atcCallInfo.setMissedReason(gt.BUSY));break;case"reorderTone":t.atcCallInfo.setMissedReason(gt.REORDER_TONE);break;case"blocked":t.atcCallInfo.setMissedReason(gt.DECLINED);break;case"destOutOfOrder":t.atcCallInfo.setMissedReason(gt.DEST_OUT_OF_ORDER);break;default:t.atcCallInfo.setMissedReason(gt.DEFAULT)}E.debug("[CstaSvc]: Publish /atccall/info event"),T.publish("/atccall/info",[t])}}function Qe(e){if(ee)return E.warn("[CstaSvc]: Queue new forwarding request until loop detected timer expires"),void(te=e);Date.now()-$PreferredDevice");var i={activateForward:n,forwardDN:e,forwardingType:"forwardNoAns"};f.setForwarding(i,t)},this.setRoutingOptionReroutingNumber=function(e,t){var n=!!(e=e||""),i={activateForward:n,forwardDN:e=n?"N<"+Pt.cleanPhoneNumber(e)+">PreferredDevice":"",forwardingType:"preferredDevice"};f.setForwarding(i,t)},this.getForwardingData=function(){return v.forwardList},this.getForwardingImmediate=function(){var e=v.forwardList.find(function(e){return me(e.forwardingType)&&e.forwardDN!==v.vm});return{status:!(!e||!e.forwardStatus),forwardDN:e&&e.forwardDN}},this.getForwardingVMStatus=function(){return v.forwardList.some(function(e){return me(e.forwardingType)&&e.forwardDN===v.vm&&e.forwardStatus})},this.setVoicemail=function(e,t,n){if(Le(n))if(t=t||j,C.localUser.pbxCallForwardToVoiceMailSupported&&C.localUser.voicemailPBXEnabled)if(E.debug("[CstaSvc]: Set voice mail duration to: ",t),e!==C.localUser.voicemailActive||e&&j!==t){var i={request:"SetForwarding",device:Ve(),voicemailActive:e,voicemailRingDuration:e?t:void 0};Qe(function(){Me(i,function(e){e?n&&n(e):(j=t,n&&n(null))})})}else n&&n(null);else n&&n("Cannot configure VM on PBX")},this.setRoutingTimers=function(t,n){if(Le(n))if(C.localUser.ringDurationEnabled){if(E.debug("[CstaSvc]: Set routing timers to: ",t),Q!==t.mainRingDuration||z!==t.cellRingDuration||X!==t.clientRingDuration||!C.localUser.routeToCell){var e={request:"SetForwarding",device:Ve(),mainRingDuration:t.mainRingDuration||void 0,clientRingDuration:t.clientRingDuration||void 0,cellRingDuration:t.cellRingDuration||void 0,routeToCell:!0};Qe(function(){Me(e,function(e){e?n&&n(e):(Q=t.mainRingDuration||Q,X=t.clientRingDuration||X,z=t.cellRingDuration||z,n&&n(null))})})}}else E.debug("[CstaSvc]: Cannot set routing timers"),n&&n("Cannot configure routing timers on PBX")},this.startCall=function(t,e,n,i){Le(i)&&(t?C.localUser.isOsBizCTIEnabled&&t.isHolding()&&t.isRemote?v.supportedFeatures&&v.supportedFeatures.includes("zhOs")?(E.debug("[CstaSvc]: OSBiz supports exlussive hold for remote call. Send MakeCall"),f.makeCall(e,n,i)):f.retrieve(t,function(e){e?i&&i("res_MakeCallFailed"):f.consultationCall(t,n,i)}):f.consultationCall(t,n,i):f.makeCall(e,n,i))},this.getHuntGroupList=function(){return ie},this},ct}((Circuit=function(vt){"use strict";var _t=vt.AtcCallInfo,gt=vt.Enums.AtcMessage,Nt=vt.BusyHandlingOptions,mt=vt.ClientApiHandlerSingleton,ht=vt.Constants,Ot=vt.DefaultAvatars,Dt=vt.Enums,Pt=vt.LocalCall,yt=vt.Proto,bt=vt.Enums.RedirectionTypes,Ut=vt.RemoteCall,Lt=vt.RoutingOptions,Mt=vt.RtcParticipant,wt=vt.RtcSessionController,Gt=vt.ScreenSharingController,Ht=vt.Enums.ScreenDisplayAction,kt=vt.Enums.ScreenFeaturesByPriority,Vt=vt.sdpParser,Ft=vt.UserToUserHandlerSingleton,Bt=vt.Utils,xt=vt.WebRTCAdapter,Wt=Object.values(vt.Enums.VideoResolutionLevel);return vt.CircuitCallControlSvcImpl=function(g,A,a,e,N,m,h,T,O,p,s,u){var c=vt.Conversation,l=vt.UserProfile;m.debug("New Service: CircuitCallControlSvc"),wt.isCMR=g.isCMR;var o=Bt.isMobile(),R=!!e.cordova,d=3200,t=6e4,C=2e3,E=5e3,S=500,f=this,D=mt.getInstance(),r=Ft.getInstance(),I=[],v=null,_=null,P=[],y=null,b=!1,U=!1,L={},M=[],w=null,n=!1,G=!1,H={},k=null,V=null,F=null,B=null,x=null,W=null;function Y(e){return O.getConversationAsGuestById(e)||O.getConversationFromCache(e)}function K(){if(V){var e=1e3*(V.ttl||0);e=Math.max(e-t,0),V.expirationTimestamp=Date.now()+e}}function q(e){if(e.audio=!!e.audio,e.video=!!e.video,e.desktop=!!e.desktop,g.isCMR)return e.hdVideo=e.video,e.minFrameRate=30,e.desktop=!1,void(e.hdDesktop=!1);if(e.video||(e.hdVideo=!1),e.desktop||(e.hdDesktop=!1),!vt.isSDK&&(e.video||e.hdDesktop)){var t=!(!o&&g.localUser.isICMixedUser&&!g.isICMode);e.video&&(e.hdVideo=!!(g.localUser.canUseHDVideo&&("boolean"==typeof e.hdVideo?e.hdVideo:t))),e.desktop&&(e.hdDesktop=!!(g.localUser.canUseHDScreenShare&&("boolean"==typeof e.hdDesktop?e.hdDesktop:t)))}}function j(o){return new N(function(n,i){var e=V&&V.expirationTimestamp||0;if(Date.now()=E)&&O.updateLastCallTime(r),ee(r)}w&&!v&&(a.cancel(w),w=null),n||(m.debug("[CircuitCallControlSvc]: Publish /call/ended event. Replaced=",i),h.publish("/call/ended",[e,i]),e.ratingEvent&&Qe(e.ratingEvent))}}function re(e){return v&&v.callId===e?v:_&&_.callId===e?_:null}function oe(e){var t;for(t=0;t(e.vrsOverloadLevel||0)&&(e.vrsOverloadLevel=n,m.debug("[CircuitCallControlSvc]: Publish /call/vrsOverloadLevelChanged event. userId =",t.userId+", level = "+n),h.publish("/call/vrsOverloadLevelChanged",[e,t]))}function He(n,i,e,t){var r=n.addParticipant(i,e,t);return r&&(Me(n,r),we(n,r),Ge(n,r),i.noData&&!i.reqPending&&(m.debug("[CircuitCallControlSvc]: Get user data for added participant. userId: ",i.userId),T.getUserById(i.userId,function(e,t){t&&(m.debug("[CircuitCallControlSvc]: Successfully retrieved participant data. userId: ",i.userId),n.isPresent()&&n.hasParticipant(i.userId)&&(i.firstName=t.firstName,i.lastName=t.lastName,i.displayName=t.displayName,m.debug("[CircuitCallControlSvc]: Publish /call/participant/updated event. userId =",i.userId),h.publish("/call/participant/updated",[n.callId,i])))}))),r}function ke(e,t,n){var i=e.updateParticipant(t,n);return i&&(Me(e,i),we(e,i),Ge(e,i)),i}function Ve(e,t,n){var i=Dt.ParticipantState.Terminated;switch(n){case ht.RTCSessionParticipantLeftCause.CONNECTION_LOST:case ht.RTCSessionParticipantLeftCause.STREAM_LOST:i=Dt.ParticipantState.ConnectionLost;break;case ht.RTCSessionParticipantLeftCause.REMOVED:i=Dt.ParticipantState.Removed;break;case ht.RTCSessionParticipantLeftCause.USER_LEFT_STAGE:i=Dt.ParticipantState.OffStage}e.setParticipantState(t,i);var r=e.removeParticipant(t);if(!e.hasOtherParticipants()){if(!e.conferenceCall)return m.debug("[CircuitCallControlSvc]: Publish /group/terminated event"),h.publish("/group/terminated",[e]),void ye(e,null,Dt.CallClientTerminatedReason.NO_USERS_LEFT,!0);e.setState(Dt.CallState.Waiting)}if(r){e.updateMediaType(),!e.isRemote&&r.isCMP&&r.isMeetingPointInvitee&&!X(e.participants)&&(e.setMeetingPointInviteState(!1),f.enableRemoteAudio(e.callId)),e.conferenceCall&&(m.debug("[CircuitCallControlSvc]: Publish /conference/participant/left event"),h.publish("/conference/participant/left",[e,n]));var o=n?{leftCause:n}:null;m.debug("[CircuitCallControlSvc]: Publish /call/participant/removed event"),h.publish("/call/participant/removed",[e.callId,r,o])}te(e)}function Fe(t,e){t&&e&&e.state&&e.state!==ht.RecordingInfoState.INITIAL&&(e.recordingMediaTypes&&e.recordingMediaTypes.includes(ht.RecordingMediaType.TEXT)&&(t.transcription.state=e.state,m.debug("[CircuitCallControlSvc]: Publish /call/transcription/info event"),h.publish("/call/transcription/info",[t])),e.recordingMediaTypes&&!e.recordingMediaTypes.includes(ht.RealtimeMediaType.AUDIO)&&!e.recordingMediaTypes.includes(ht.RealtimeMediaType.VIDEO)||(function(e,t){e.recordingMediaTypes=t.recordingMediaTypes,e.state!==t.state?(e.notifyByCurtain=t.state===ht.RecordingInfoState.START_PENDING||t.state===ht.RecordingInfoState.STARTED&&e.state===ht.RecordingInfoState.START_PENDING,e.notifyByUser=!e.notifyByCurtain||t.state===ht.RecordingInfoState.START_PENDING&&e.state!==ht.RecordingInfoState.STARTED):(e.notifyByCurtain=!1,e.notifyByUser=!1);e.state=t.state,e.duration=t.duration||e.duration,e.reason=t.reason,e.recordingUserId=null,e.recordingUser=null,t.state===ht.RecordingInfoState.STARTED&&(e.resumeTime=Date.now(),t.layout&&t.layout.layoutMapping&&t.layout.layoutMapping.length&&t.layout.layoutName===ht.RecordingVideoLayoutName.SINGLE_VIDEO&&(e.recordingUserId=t.layout.layoutMapping[0].tileContent));t.starter&&t.starter.userId&&t.starter.userId!==e.starter.userId&&(e.starter=t.starter,e.starter.userId===g.localUser.userId?e.starter.res="res_StartedRecording_You":(e.starter.name=e.starter.firstName||e.starter.displayName,e.starter.res=e.starter.name?"res_StartedRecording_Other":"res_StartedRecording"))}(t.recording,e),t.recording.recordingUserId&&(t.recording.recordingUserId===g.localUser.userId?t.recording.recordingUser=g.localUser:t.participants.some(function(e){return e.userId===t.recording.recordingUserId&&(t.recording.recordingUser=e,!0)})),m.debug("[CircuitCallControlSvc]: Publish /call/recording/info event"),h.publish("/call/recording/info",[t])))}function Be(e){v&&void 0!==e&&v.attendeeCount!==e&&(v.attendeeCount=e,v.updateCallState(),m.debug("[CircuitCallControlSvc]: Publish /call/attendeeCountChanged"),h.publish("/call/attendeeCountChanged",[v.callId,v.attendeeCount]))}function xe(i,e){return new N(function(t,n){i&&!i.screenShareEventHandler?i.isVdi?t({}):(i.screenShareEventHandler=Gt.getScreen(function(e){A(function(){i.screenShareEventHandler=null,i.rejectGetScreenPromise=null,t(e||{})},0)},function(e){A(function(){i.screenShareEventHandler=null,i.rejectGetScreenPromise=null,e===ht.ReturnCode.CHOOSE_DESKTOP_MEDIA_CANCELLED?n(e):n("res_AccessToDesktopFailed")},0)},e),i.rejectGetScreenPromise=function(e){m.warn("[CircuitCallControlSvc]: Cancelling getScreen promise for call ID: ",i.callId),n(e)}):n("res_ErrorMsgInternal")})}function We(r){return new N(function(n,t){function i(){m.debug("[CircuitCallControlSvc]: Terminate ICE candidates collection test"),e.onSessionDescription=null,e.onRtcError=null,e.terminate()}var e=new wt({disableTrickleIce:!0,isDirectCall:!0,candidatesCollectionTest:!0});r&&(e.setTurnUris(r.turnServer),e.setTurnCredentials(r)),e.disableRemoteVideo(),e.onSessionDescription=function(e){var t=vt.sdpParser.getIceCandidates(e.sdp.sdp);m.debug("[CircuitCallControlSvc]: testIceCandidates - candidates: ",t),i(),n({turnServers:r&&r.turnServer||[],candidates:t})},e.onRtcError=function(e){m.error("[CircuitCallControlSvc]: Error collecting candidates. ",e.error),i(),t(e.error)},m.debug("[CircuitCallControlSvc]: testIceCandidates - Start collection"),e.start({audio:!1})})}function Ye(e,t){if(e&&e.replaces){var n=oe(e.replaces.callId);n&&(g.localUser.userId===n.screenOwnerId&&(e.restartScreenControlSession=!0,e.screenControllerId=n.screenControllerId),t&&ye(n,null,Dt.CallClientTerminatedReason.CALL_MOVED_TO_ANOTHER_CONV)),m.debug("[CircuitCallControlSvc]: Publish /call/moved event"),h.publish("/call/moved",[e.replaces.callId,e.callId]),e.replaces=null,te(e)}}function Ke(e){return!(!g.isCMR&&(e&&e.isDirect||Bt.isMobile()))}function qe(){return xt.unifiedPlanEnabled||"firefox"===xt.browser}function je(e){return!!Wt.includes(e)||(m.error("[CircuitCallControlSvc]: Invalid video resolution: ",e),!1)}function Qe(e){m.debug("[CircuitCallControlSvc]: Publish /call/showRatingDialog event"),h.publish("/call/showRatingDialog",[e])}function Xe(e,t){if(m.debug("[CircuitCallControlSvc]: handleRtcError: ",t.error),"res_RemoteControlSessionStopped"===t.error)return Ae(e.callId),void h.publish("/screenControl/terminated",[e]);(h.publish("/call/rtcError",[e,t.error]),e.checkState([Dt.CallState.Ringing,Dt.CallState.Answering]))?Pe(e,{type:!g.isCMR||"res_AccessToMediaInputDevicesFailed"!==t.error&&"res_AccessToAudioInputDeviceFailed"!==t.error?ht.InviteRejectCause.BUSY:ht.InviteRejectCause.TEMPORARILY_UNAVAILABLE}):e.sameAs(v)&&("res_CallMediaFailed"===t.error?(e.setDisconnectCause(ht.DisconnectCause.NEGOTIATION_FAILED),f.endCallWithCauseCode(e.callId,Dt.CallClientTerminatedReason.ICE_TIMED_OUT)):"res_CallMediaDisconnected"===t.error?(e.setDisconnectCause(ht.DisconnectCause.STREAM_LOST),f.endCallWithCauseCode(e.callId,Dt.CallClientTerminatedReason.LOST_MEDIA_STREAM),D.pingServer()):e.isEstablished()||f.endCall(e.callId))}function ze(e){var t=e&&e.sessionCtrl;t?(t.onIceCandidate=function(t,e){m.debug("[CircuitCallControlSvc]: RtcSessionController - onIceCandidate");var n={rtcSessionId:t.callId,userId:g.localUser.userId,origin:e.origin,candidates:e.candidates.map(JSON.stringify.bind(JSON))};e.isAudioVideo&&(t.sdpOrigin=e.origin);var i=u.createActionInfo(t,ht.RtcDiagnosticsAction.ICE_CANDIDATES);i&&(i.data=n.candidates,i.isEndOfCandidates=e.endOfCandidates);D.sendIceCandidates(n,function(e){u.finishActionInfo(t,i),e&&m.warn("Failed to send ICE candidate: ",e)})}.bind(null,e),t.onSdpConnected=function(t){m.debug("[CircuitCallControlSvc]: RtcSessionController - onSdpConnected"),g.$apply(function(){m.debug("[CircuitCallControlSvc]: Publish /call/sdpConnected event"),h.publish("/call/sdpConnected",[t]);var e=u.createActionInfo(t,ht.RtcDiagnosticsAction.SDP_CONNECTED);u.finishActionInfo(t,e),t.isTelephonyCall?(t.state.established||t.setState(Dt.CallState.Waiting),t.updateCallState()):t.setState(t.isDirect||t.hasOtherParticipants()?Dt.CallState.Active:Dt.CallState.Waiting),te(t),u.finishDeviceDiagnostics(t),u.sendCallConnected(t)})}.bind(null,e),t.onIceConnected=function(e,t){m.debug("[CircuitCallControlSvc]: RtcSessionController - onIceConnected. pcType:",t.pcType),g.$apply(function(){"audio/video"===t.pcType?(e.isEstablished()&&e.disconnectCause&&e.disconnectCause.cause===ht.DisconnectCause.STREAM_LOST&&(e.disconnectCause=null),ne(e,"connected")):"screen control"===t.pcType&&_e(e,e.screenOwnerId,e.screenControllerId,!0)})}.bind(null,e),t.onIceDisconnected=function(e,t){m.debug("[CircuitCallControlSvc]: RtcSessionController - onIceDisconnected. pcType:",t.pcType),g.$apply(function(){"audio/video"===t.pcType&&e.isEstablished()&&!e.isHeld()?(e.setDisconnectCause(ht.DisconnectCause.STREAM_LOST),ne(e,"disconnected")):"screen control"===t.pcType&&(Ne(e.callId),_e(e,null,null,!0))})}.bind(null,e),t.onRemoteVideoAdded=function(){m.debug("[CircuitCallControlSvc]: RtcSessionController - onRemoteVideoAdded")}.bind(null,e),t.onRemoteVideoRemoved=function(){m.debug("[CircuitCallControlSvc]: RtcSessionController - onRemoteVideoRemoved")}.bind(null,e),t.onRemoteStreamUpdated=function(e){m.debug("[CircuitCallControlSvc]: RtcSessionController - onRemoteStreamUpdated"),g.$apply(function(){m.debug("[CircuitCallControlSvc]: Publish /call/remoteStreamUpdated event"),h.publish("/call/remoteStreamUpdated",[e])})}.bind(null,e),t.onDTMFToneChange=function(e,t){m.debug("[CircuitCallControlSvc]: RtcSessionController - onDTMFToneChange"),g.$apply(function(){t.tone?(m.debug("[CircuitCallControlSvc]: Sent DTMF Digit"),h.publish("/call/singleDigitSent",[e,t.tone])):""===t.tone&&(m.info("[CircuitCallControlSvc]: Digits played completely"),h.publish("/call/digitsSent",[e]))})}.bind(null,e),t.onRtcError=function(e,t){g.$apply(function(){Xe(e,t)})}.bind(null,e),t.onRtcWarning=function(e,t){m.debug("[CircuitCallControlSvc]: RtcSessionController - onRtcWarning"),g.$apply(function(){h.publish("/call/rtcWarning",[e,t.warning])})}.bind(null,e),t.onLocalStreamEnded=function(t,e){m.debug("[CircuitCallControlSvc]: RtcSessionController - onStreamEnded"),e.isDesktop&&v.hasLocalScreenShare()?(m.debug("[CircuitCallControlSvc]: Screenshare stream ended, remove screenshare or terminate the call"),v.isEstablished()?f.removeScreenShare(v.callId):f.endCall(v.callId)):f.renegotiateMedia(t.callId,function(e){e&&g.$apply(function(){m.debug("[CircuitCallControlSvc]: Publish /call/localStreamEnded event"),h.publish("/call/localStreamEnded",[t])})})}.bind(null,e),t.onQosAvailable=function(e,t){m.debug("[CircuitCallControlSvc]: RtcSessionController - onQosAvailable"),t.renegotiationInProgress&&(e.terminateReason=Dt.CallClientTerminatedReason.MEDIA_RENEGOTIATION);if(e.sessionCtrl){if(e.qosSubmitted)return void m.info("[CircuitCallControlSvc]: QoS already submitted for call Id:",e.callId);s.sendQOSData(e,e.lastMediaType,t.qos,t.lastSavedStats)}t.renegotiationInProgress&&(e.terminateReason=null,e.updateMediaDevices())}.bind(null,e),t.onStatsThresholdExceeded=function(e,t){n||(m.debug("[CircuitCallControlSvc]: RtcSessionController - onStatsThresholdExceeded. Cleared: ",!(!t||!t.cleared)),g.$apply(function(){t&&t.cleared?h.publish("/call/rtp/threshholdExceeded/cleared",[e.callId]):h.publish("/call/rtp/threshholdExceeded/detected",[e.callId])}))}.bind(null,e),t.onStatsNoOutgoingPackets=function(e){m.debug("[CircuitCallControlSvc]: RtcSessionController - onStatsNoOutgoingPackets. Publish /call/rtp/noOutgoingPackets event"),g.$apply(function(){h.publish("/call/rtp/noOutgoingPackets",[e.callId])})}.bind(null,e),t.onNetworkQuality=function(n,i){if(!i||!i.quality)return;g.$apply(function(){var e=null;if(xt.unifiedPlanEnabled)e=i.quality.level,n.networkQuality=e,m.debug("[CircuitCallControlSvc]: Publish /call/network/quality event for quality=",e);else{var t=i.quality;e={userId:g.localUser.userId,audio:{qualityLevel:t.qualityLevel.value,currentPlSend:t.currentPlSend,currentPlReceive:t.currentPlReceive,firstTimeLowQuality:t.firstTimeLowQuality}},m.debug("[CircuitCallControlSvc]: Publish legacy /call/network/quality event for quality=",e.audio.qualityLevel)}h.publish("/call/network/quality",[n.callId,e])})}.bind(null,e),t.onGetUserMediaException=function(e,t){m.debug("[CircuitCallControlSvc]: RtcSessionController - onGetUserMediaException. Publish /call/getUserMediaException event"),g.$apply(function(){h.publish("/call/getUserMediaException",[e,t.info])})}.bind(null,e)):m.error("[CircuitCallControlSvc]: Failed to get RtcSessionController for given call. ",e)}function Je(e){try{m.debug("[CircuitCallControlSvc]: Received RTCSession.ACTIVE_SPEAKER");var t=re(e.sessionId);if(!t)return void m.warn("[CircuitCallControlSvc]: Unexpected event. There is no local call");if(t.isDirect||t.participants.length<2)return void m.debug("[CircuitCallControlSvc]: Ignore RTC.ACTIVE_SPEAKER event for 1-2-1 calls");var n=[];if(e.first&&n.push(e.first),e.second&&n.push(e.second),e.third&&n.push(e.third),!t.setActiveSpeakers(n))return;m.debug("[CircuitCallControlSvc]: Publish /call/participants/activeSpeakers event"),h.publish("/call/participants/activeSpeakers",[t.callId,n])}catch(e){m.error("[CircuitCallControlSvc]: Exception handling RTC.ACTIVE_SPEAKER event. ",e)}}function $e(t){if(m.debug("[CircuitCallControlSvc]: Processing active session for convId = ",t.convId),t.participants&&0!==t.participants.length){var e=O.getConversationByRtcSession(t.rtcSessionId);if(e&&(e.hasJoined||e.isTemporary)&&(t.turnServers&&Ce(t.rtcSessionId,t.turnServers),!Ue(t.rtcSessionId))){var n,i=!1;if(t.participants.some(function(e){return e.userId===g.localUser.userId&&((n=e).clientId===D.clientId&&(i=!0),!0)}),e.call){var r=e.call;return r.isRemote&&e.isTemporary&&n?(e.call.setState(Dt.CallState.ActiveRemote),r.setActiveClient(n),Le(r),void(r.mediaType=yt.getMediaType(t.mediaTypes))):void m.debug("[CircuitCallControlSvc]: Conversation already has an associated call")}if(e.type!==ht.ConversationType.DIRECT||t.hosted||n){if(i){var o=function(e){e&&m.warn("[CircuitCallControlSvc] Lost session could not be terminated. Session Id=",t.rtcSessionId)},a={disconnectCause:ht.DisconnectCause.CONNECTION_LOST,disconnectReason:ht.DisconnectReason.CALL_LOST};if(e.type===ht.ConversationType.DIRECT)return void D.terminateRtcCall(t.rtcSessionId,a,o);D.leaveRtcCall(t.rtcSessionId,a,o)}me(e,n,t,t.rtcSessionId,function(e){n&&Ze(e,t)})}}}else m.warn("[CircuitCallControlSvc]: The active session does not have participants. rtcSessionId = ",t.rtcSessionId)}function Ze(t,e){t&&t.isTelephonyCall&&e&&e.participants&&e.participants.length<=2&&e.participants.some(function(e){return e.participantType===ht.RTCParticipantType.TELEPHONY&&(de(t,e.phoneNumber,null,e.userDisplayName),!0)})}function et(e){var t=!1;return re(e.rtcSessionId)&&e.participants&&(t=e.participants.some(function(e){return e.userId===g.localUser.userId&&e.clientId===D.clientId})),t}function tt(){return D.injectHasActiveCall(f.hasActiveCall),new N(function(s,c){G||g.isSessionGuest?(m.debug("[CircuitCallControlSvc]: Initialize active RTC sessions"),D.getActiveSessions(function(t,n){g.$apply(function(){t&&m.error("[CircuitCallControlSvc]: Error getting active sessions: ",t),n=n||[],Bt.emptyArray(P);for(var e=I.length-1;0<=e;e--)I[e].isRemote&&(I[e].guestToken?P.push(I[e]):ie(I[e]));var i=null,r=!1,o=!1,a=[];n.forEach(function(t){var n=re(t.rtcSessionId);if(n){if(et(t))return r=r||n===v,o=o||n===_,m.info("[CircuitCallControlSvc]: Found localCall in active sessions. Trigger media renegotiation."),void f.renegotiateMedia(n.callId,function(e){n.screenOwnerId===g.localUser.userId&&(e||t.screenOwnerId!==g.localUser.userId?(m.debug("[CircuitCallControlSvc]: There was a renegotiation error or remote control has been terminated on backend"),Ae(n.callId)):(m.debug("[CircuitCallControlSvc]: Starting a screen control session."),fe(n.callId,t.screenControllerId,function(e){e?m.error("[CircuitCallControlSvc]: Could not start the screen control session"):m.debug("[CircuitCallControlSvc]: Successfully started the screen control session.")}))),e?_e(n,null,null,!0):_e(n,t.screenOwnerId,t.screenControllerId,!0),h.publish("/call/sessionInitialized",[n])});ie(n,Dt.CallClientTerminatedReason.LOST_WEBSOCKET_CONNECTION)}(i=O.getConversationByRtcSession(t.rtcSessionId))&&i.hasJoined?$e(t):t.invitedGuests&&t.invitedGuests.includes(g.localUser.userId)?(m.info("[CircuitCallControlSvc]: Local user is invited as guest to this session"),a.push(O.createConversationAsGuestFromSummary(t.convId))):i||(m.info("[CircuitCallControlSvc]: Conversation associated with session is not cached. Need to get it."),a.push(O.getConversationPromise(t.convId)))}),h.publish("/activeSessions/received"),_&&!o&&ie(_,Dt.CallClientTerminatedReason.LOST_WEBSOCKET_CONNECTION),v&&!r&&ie(v,Dt.CallClientTerminatedReason.LOST_WEBSOCKET_CONNECTION),0t){c.warn("[DeviceDiagnosticSvc]: Stored device diagnostics exceeded max size. Discard old data.");var i="",r=n.length-a;d.some(function(e,t){return(i+=JSON.stringify(e)).length>r&&(c.warn("[DeviceDiagnosticSvc]: Number of discarded records: ",t+1),d.splice(0,t+1),n=JSON.stringify(d),!0)})}o.setString(o.keys.RTC_CLIENT_INFOS,n)}else o.removeItem(o.keys.RTC_CLIENT_INFOS)}function C(e){e&&e.joinDelayTimer&&(n.cancel(e.joinDelayTimer),e.joinDelayTimer=null)}function E(e){return!(!e||!e.deviceDiagnostics)&&(e.deviceDiagnostics.data.actionInfo.some(function(e){return!e.complete})||!e.deviceDiagnostics.iceGatheringFinished)}function T(e){if(e&&e.deviceDiagnostics){c.debug("[DeviceDiagnosticSvc]: Force finish device diagnostics");var t=e.deviceDiagnostics;C(t),t.joinDelayed&&I(e),p(e)}}function p(e){e&&e.deviceDiagnostics&&(c.debug("[DeviceDiagnosticSvc]: Clear device diagnostics"),C(e.deviceDiagnostics),delete e.deviceDiagnostics)}function S(e){u&&(c.debug("[DeviceDiagnosticSvc]: Store device diagnostics to send when client reconnects"),d.push(e),r())}function I(e){if(e&&e.deviceDiagnostics){var t={sdpOrigin:e.sdpOrigin||null,userId:s.localUser.userId,convId:e.convId,clientInfoType:f.RtcClientInfoType.DEVICE_DIAGNOSTICS,reason:f.RtcClientInfoReason.JOIN_DELAY,timestamp:Date.now(),sessionId:e.callId,deviceDiagnostics:_.shallowCopy(e.deviceDiagnostics.data)};e.instanceId&&(t.instanceId=e.instanceId),p(e),c.debug("[DeviceDiagnosticSvc]: Sending device diagnostics..."),l.sendClientInfo([t],function(e){e&&(c.debug("[DeviceDiagnosticSvc]: Failed to send device diagnostics. ",e),v.isOfflineFailure(e)&&S(t))})}else c.debug("[DeviceDiagnosticSvc]: sendDeviceDiagnostics - Nothing to send")}function A(e){if(!e||!e.label||"string"!=typeof e.label)return"";var t=e.label;return t.startsWith("res_")?s.i18n.localize(t)||"":t}return u&&e.subscribe("/conversations/loadComplete",function(){c.debug("[DeviceDiagnosticSvc]: Received /conversations/loadComplete event"),function(){if(0=T)||a.warn("[ExtensionSvc]: The installed extension version ("+R+") is not supported. Minimum version is "+t)),f&&(i.isChromeExtRunning=!0,a.setExtensionVersion(R),a.debug("[ExtensionSvc]: Publish /chromeExt/initialized event"),s.publish("/chromeExt/initialized"))})}),A.addEventListener("extensionUnregistered",function(){i.$apply(function(){i.isChromeExtRunning=!1,a.debug("[ExtensionSvc]: Publish /chromeExt/unregistered event"),s.publish("/chromeExt/unregistered")})});var m=function(t,n){i.$apply(function(){var e=n.data&&n.data.data;a.debug("[ExtensionSvc]: Publish "+t+" event: ",e),s.publish(t,[e])})};A.addEventListener("headsetAppLaunched",m.bind(null,"/chromeExt/headsetAppLaunched")),A.addEventListener("headsetAppUninstalled",m.bind(null,"/chromeExt/headsetAppUninstalled")),A.addEventListener("webRTCIPHandlingPolicyChanged",m.bind(null,"/chromeExt/webRTCIPHandlingPolicyChanged"))}return this.isExtensionRunning=function(){return A&&A.isExtensionRunning()&&f},this.getExtensionVersion=function(){return R},this.isExtensionVersionSupported=function(){return f},this.installExtension=function(i){return new e(function(e,t){if(I.isExtensionRunning())e();else{if(!c)return a.error("[ExtensionSvc]: installExtension API requires PopupSvc"),void t(S.INTERNAL_ERROR);var n=N(i);if(n)t(n);else{c.confirm({message:"res_ActionInstallExtensionText",title:"res_ActionInstallExtensionTitle",yesLabel:"res_ActionInstall",noLabel:"res_Close",backdrop:!0}).result.then(function(){I.inlineInstallation(i).then(e).catch(t)}).catch(function(){t(S.USER_CANCELLED_INSTALL)})}}})},this.inlineInstallation=function(r){return new e(function(e,t){var n=N(r);if(n)t(n);else{var i=_();a.debug("[ExtensionSvc]: Open store link for ",i),o.open(i),e()}})},this.addEventListener=function(e,t){A&&A.addEventListener(e,t)},this.exchangeGetConnectionStatus=function(e,t){return g("exchangeGetConnectionStatus",[e],t)},this.exchangeConnect=function(e,t){return g("exchangeConnect",[e],t)},this.exchangeSearchContacts=function(e,t,n,i){return g("exchangeSearchContacts",[e,t,n],i)},this.exchangeGetCapabilities=function(e){return g("exchangeGetCapabilities",[],e)},this.exchangeAutodiscoverGetServer=function(e,t){return g("exchangeAutodiscoverGetServer",[e],t)},this.exchangeResolveContact=function(e,t,n){return g("exchangeResolveContact",[e,t],n)},this.exchangeGetContact=function(e,t,n){return g("exchangeGetContact",[e,t],n)},this.exchangeDisconnect=function(e){return g("exchangeDisconnect",[],e)},this.exchangeOnRenewedToken=function(e,t,n,i){return g("exchangeOnRenewedToken",[e,t,n],i)},this.storeExchCredentials=function(e,t){return g("exchangeStoreCredentials",[e],t)},this.getStoredCredentials=function(e,t){return g("getStoredCredentials",[e],t)},this.getAllPersonalContacts=function(e,t){return g("getAllPersonalContacts",[e],t)},this.syncAllPersonalContacts=function(e,t,n){return g("syncAllPersonalContacts",[e,t],n)},this.exchangeCancelReqCallback=function(e){return g("exchangeCancelReqCallback",[e])},this.getAppointments=function(e,t,n,i,r){return g("getAppointments",[e,t,n,i],r)},this.supportsGetAppointments=function(){return!(!i.localUser||!i.localUser.msExchangeEnabled)&&(!!I.isExtensionRunning()||!(!i.browser||!i.browser.chrome))},this.supportsExchangeAutodiscover=function(){return I.isExtensionRunning()},this.supportsExchangeAutodiscoverSvc=function(){return I.isExtensionRunning()},this.supportsExchangeAutodiscoverGetServer=function(){return R===p||1023300<=y.convertVersionToNumber(R)},this.supportsOOO=function(){return R===p||1022800<=y.convertVersionToNumber(R)},this.supportsUserAvailability=function(){return R===p||1025800<=y.convertVersionToNumber(R)},this.getOooMsg=function(e,t,n,i){I.supportsOOO()||i&&i(null,{response:O.ExchangeConnResponse.UNSUPPORTED_METHOD}),g("getOooMsg",[e,t,n],i)},this.getUserAvailability=function(e,t,n){I.supportsUserAvailability()||n&&n(null,{response:O.ExchangeConnResponse.UNSUPPORTED_METHOD}),g("getUserAvailability",[e,t],n)},this.launchHeadsetIntegrationApp=function(e,t,n){return g("launchHeadsetIntegrationApp",[e,t],n)},this.getHeadsetIntegrationAppStatus=function(e,t){return g("getHeadsetIntegrationAppStatus",[e],t)},this.restartHeadsetApp=function(e,t){return g("restartHeadsetApp",[e],t)},this.supportsPolicySettings=function(){return R===p||1023300<=y.convertVersionToNumber(R)},this.setIPHandlingPolicy=function(e,t,n){h.isElectron?(v.send("set-ip-handling-policy",e),n&&n(null)):g("setIPHandlingPolicy",[e,t],n)},this.getIPHandlingPolicy=function(n){"function"==typeof n&&(h.isElectron?(v.send("get-ip-handling-policy"),v.once("get-ip-handling-policy-response",function(e,t){i.$apply(function(){n(null,{value:t||null})})})):g("getIPHandlingPolicy",[],n))},this.bringToFront=function(e){h.isElectron?v.send("focus-window"):g("bringToFront",[],e)},this.getFileFromExtension=function(e,t,n){return g("getFile",[e,t],n)},i.isChromeExtRunning=I.isExtensionRunning(),this},h}((Circuit=function(e){"use strict";var u=e.BaseCall,C=e.Utils;return e.PubSubSvcImpl=function(n){n.debug("New Service: PubSubSvc");var i={},r={},o={},a=[];function s(e,t){try{null==t?t=[]:Array.isArray(t)||(t=[t]),e.apply(null,t)}catch(e){n.error(e)}}function c(e,t,n){e[t]&&e[t].slice(0).forEach(function(e){s(e,n)})}function l(e,t,n){e[t]?e[t].includes(n)||e[t].push(n):e[t]=[n]}function d(e,t,n){if(e[t]){var i=e[t].indexOf(n);0<=i&&e[t].splice(i,1)}}return this.publish=function(e,t){(i[e]||r[e]||o[e]||a.length)&&(n.debug("[PubSubSvc]: Publishing "+e+" event"),c(i,e,t),function(e,t){r[e]&&(null==t?t=[]:Array.isArray(t)||(t=[t]),t=t.map(function(e){if(e&&"object"==typeof e){if(e.isConversationObject)return C.trimConvForMobile(e);if(e instanceof u)return C.trimCallForMobile(e)}return e}),r[e].slice(0).forEach(function(e){s(e,t)}))}(e,t),c(o,e,t),function(e,t){(t=t?Array.prototype.slice.call(t):[]).unshift(e),a.slice(0).forEach(function(e){s(e,t)})}(e,t),delete o[e])},this.subscribe=function(e,t){l(i,e,t)},this.unsubscribe=function(e,t){d(i,e,t)},this.subscribeOnce=function(e,t){l(o,e,t)},this.unsubscribeOnce=function(e,t){d(o,e,t)},this.subscribeMobile=function(e,t){l(r,e,t)},this.unsubscribeMobile=function(e,t){d(r,e,t)},this.subscribeAll=function(e){!function(e){a.includes(e)||a.push(e)}(e)},this.unsubscribeAll=function(e){!function(e){var t=a.indexOf(e);0<=t&&a.splice(t,1)}(e)},this.resetSubscriptions=function(){i={},r={},o={},a=[]},this},e}((Circuit=function(e){"use strict";var t=e.Utils,n={ACCESSIBILITY:"125328",AGC:"89415",DEVICE_ACCESS:"48742",JABRA:"112718",LOGIN:"37428",MODERATION:"93154",PLANTRONICS:"115017",SHORTCUTS:t.isMacOs?"144499":"144490",TELEPHONY:"103733"};return e.UtilSvcImpl=function(n,i,r,o){o.debug("New Service: UtilSvc");var a=this;return this.promisify=function(t,r){return function(){var e=Array.prototype.slice.call(arguments);return new i(function(n,i){e.push(function(e){if(e)i(e);else{var t=Array.prototype.slice.call(arguments);switch(t.shift(),t.length){case 0:n();break;case 1:n(t[0]);break;default:n(t)}}}),t.apply(r,e)})}},this.getFaqUrl=function(e){if(n.localUser){if(n.localUser.faqUrl&&t.DEFAULT_FAQ_URL!==n.localUser.faqUrl)return n.localUser.faqUrl+(e||"");if(n.localUser.helpUrl&&t.DEFAULT_HELP_URL!==n.localUser.helpUrl)return n.localUser.helpUrl}return"HELP"===e?t.DEFAULT_HELP_URL:t.DEFAULT_FAQ_URL+(e?"?articleId="+e:"")},this.isPartnerAdmin=function(e){return!(!n.localUser||!n.localUser.isPartnerAdmin)||(o.debug("[UtilSvc]: Cannot invoke request. Local user is not a partner admin."),e&&r(function(){e("Not partner admin")}),!1)},this.isTenantAdmin=function(e,t){return!!n.localUser&&(t&&t.tenantId!==n.localUser.tenantId?a.isPartnerAdmin(e):!!n.localUser.isTenantAdmin||(o.warn("[UtilSvc]: Local user is not a tenant admin"),e&&r(function(){e("Not tenant admin")}),!1))},this.hasOAuthAppChangeRights=function(){return!!n.localUser&&(!!n.localUser.hasDeveloperConsoleAccess||(o.warn("[UtilSvc]: Local user does not have rights for accessing the developer console"),!1))},this.hasOAuthAppViewRights=function(){return!!n.localUser&&(!!n.localUser.canViewDeveloperConsole||(o.warn("[UtilSvc]: Local user does not have rights for viewing the developer console."),!1))},this},e.Enums=e.Enums||{},e.Enums.FaqArticle=n,e}((Circuit=function(R){"use strict";var f=Object.freeze({Idle:"Idle",Active:"Active"});return R.Enums=R.Enums||{},R.Enums.IdleState=f,R.SdkHelperSvcImpl=function(i,e,r,o){var a,t=R.Enums.ConnectionState,n=R.Constants,s=R.Conversation,c=R.UserProfile,l=R.Utils,d=this,u={},C=null,E=R.ClientApiHandlerSingleton.getInstance(),T=[];function p(){return null}function S(){if(!i.localUser||!i.localUser.accounts||!i.localUser.accounts[0])return!1;var e=i.localUser,t=i.localUser.accounts[0],n=e.callerId;return t.telephonyConfiguration?(e.phoneNumber=t.telephonyConfiguration.phoneNumber||null,e.isATC?(e.callerId=t.telephonyConfiguration.phoneNumber,e.cstaNumber=l.cleanPhoneNumber(t.telephonyConfiguration.phoneNumber),e.registerNumber=e.cstaNumber,e.isRegisterTC=!0):e.isSTC?(e.callerId=t.telephonyConfiguration.phoneNumber,e.registerNumber=l.cleanPhoneNumber(t.telephonyConfiguration.phoneNumber),e.cstaNumber=null,e.isRegisterTC=!0):(e.callerId=t.telephonyConfiguration.callerId||e.phoneNumber||C,e.cstaNumber=null,e.registerNumber=null,e.isRegisterTC=!1)):(e.phoneNumber=null,e.callerId=C,e.cstaNumber=null,e.registerNumber=null,e.isRegisterTC=!1),n!==e.callerId}function I(){return new Promise(function(n,i){E.getTelephonyData(function(e,t){e?i(e):(C=t.defaultCallerId||null,n(t))})})}function A(){return new Promise(function(n,i){E.getTelephonyConversationId(function(e,t){e||!t?i("Telephony conversation not found"):d.getConversationById(t,null,function(e,t){e||!t?i(e||"Error retrieving telephony conversation"):((a=t).isTelephonyConv=!0,n(t))})})})}return o.subscribe("/telephony/data",function(e){var t=!1;C!==e.defaultCallerId&&(C=e.defaultCallerId,l.updateTelephonyNumbers(i.localUser,e.defaultCallerId)&&(t=!0)),i.localUser.telephonyAvailable!==e.telephonyAvailableForUser&&(i.localUser.telephonyAvailable=e.telephonyAvailableForUser,t=!0),t&&o.publish("/localUser/update",[i.localUser])}),E.on("Account.TELEPHONY_CONFIGURATION_UPDATED",function(e){if(e.configuration&&i.localUser){var t=i.localUser.accounts&&i.localUser.accounts[0];t&&(t.telephonyConfiguration=e.configuration,d.telephonyConfigChanged(),o.publish("/localUser/update",[i.localUser]))}}),this.addConversationToCache=function(e){e&&e.convId&&(u[e.convId]=s.extend(e))},this.setLocalUser=function(e){e&&(e.canUseHDVideo=e.hasPermission(Circuit.Enums.SystemPermission.HD_VIDEO),e.canUseHDScreenShare=e.hasPermission(Circuit.Enums.SystemPermission.HD_SCREENSHARE),i.localUser=e,c.syncTelephonyConfig(e),S())},this.telephonyConfigChanged=function(){S(),c.syncTelephonyConfig(i.localUser)},this.getConversationPromise=function(t){return new Promise(function(n,i){if(t){var e=u[t];e?n(e):d.getConversationById(t,null,function(e,t){e||!t?i("Conversation not found"):n(t)})}else i()})},this.getConversationById=function(e,t,i){"function"==typeof i&&E.getConversationById(e,function(e,t){var n=s.extend(t);n&&(u[t.convId]=n),i(e,n)})},this.getConversationByRtcSession=function(e){for(var t in r.debug("[SdkHelperSvc]: getConversationByRtcSession - rtcSessionId = ",e),u)if(u.hasOwnProperty(t)&&u[t].rtcSessionId===e)return u[t];return null},this.getConversationFromCache=function(e){return r.debug("[SdkHelperSvc]: getConversationFromCache - convId = ",e),u[e]||null},this.getConversationAsGuestById=function(t){return T.find(function(e){return e.convId===t})},this.getTelephonyData=I,this.getTelephonyConversationPromise=function(){return a?Promise.resolve(a):A()},this.getTelephonyConversation=function(t){if("function"==typeof t){if(a)return void window.setTimeout(function(){t(null,a)});I().then(S).then(A).then(function(e){t(null,e)}).catch(t)}},this.getCachedTelephonyConversation=function(){return a},this.isConversationsLoadComplete=function(){return!!i.localUser},this.updateLastCallTime=function(){},this.createConversationAsGuest=function(n){var e=s.extend({convId:n.convId,type:n.type,topic:n.topic,rtcSessionId:n.rtcSessionId,creatorId:n.creatorId,participants:[{userId:i.localUser.userId}],creatorTenantId:n.creatorTenantId||i.localUser.tenantId,isTemporary:!0,creationTime:n.creationTime||Date.now()});return T.some(function(e,t){return e.convId===n.convId&&(T.splice(t,1),!0)}),T.push(e),r.debug("[SDK]: Created temporary (as guest) conversation for session:",e.rtcSessionId),setTimeout(function(){n.isExtended?(r.debug("[SDK]: Publish /conversation/navigate/reload event"),o.publish("/conversation/navigate/reload",[e])):(r.debug("[SDK]: Publish /conversation/new event"),o.publish("/conversation/new",[e]))}),e},this.createConversationAsGuestFromSummary=function(e){return new Promise(function(n,i){e?E.getConversationSummary(e,null,function(e,t){e?i("[SDK] getConversationSummary request failed"):n(d.createConversationAsGuest(t))}):i("convId is required")})},this.sendQOSData=function(e,t,n){r.debug("[SdkHelperSvc]: sendQOSData - call stats: ",n)},this.state=function(){switch(E.getConnState()){case t.Disconnected:return"Disconnected";case t.Connecting:return"Connecting";case t.Reconnecting:return"Reconnecting";case t.Connected:return"Registered";default:return""}},this.isRegistered=function(){return E.getConnState()===t.Connected},this.getSetting=function(){return null},this.getUserIdleState=function(){return f.Active},this.isAutoSnoozeOn=!1,this.setPresenceWithLocation=function(){},this.startAutoSnooze=function(){},this.cancelAutoSnooze=function(){},this.snooze=function(){},this.resume=function(){},this.getUserFromCache=p,this.getUser=p,this.getUserById=function(e,t){t&&t(n.ReturnCode.NO_RESULT)},this.addUsersToCache=function(){},this.startReverseLookUp=function(e,t){t&&t(null)},this},R}((Circuit=function(t){"use strict";return t.Enums.SystemPermission=t.Constants.SystemPermission,t.Enums.DeviceType=t.Constants.DeviceType,t.Enums.CallStateName={},Object.getOwnPropertyNames(t.Enums.CallState).forEach(function(e){t.Enums.CallStateName[e]=e}),t.Enums.ConversationItemType=t.Constants.ConversationItemType,t.Enums.ConversationType={DIRECT:"DIRECT",GROUP:"GROUP",LARGE:"LARGE",COMMUNITY:"COMMUNITY"},t.Enums.PresenceState=t.Constants.PresenceState,t.Enums.RTCItemType=t.Constants.RTCItemType,t.Enums.RTCParticipantType=t.Constants.RTCParticipantType,t.Enums.SystemItemType=t.Constants.SystemItemType,t.Enums.TextItemContentType=t.Constants.TextItemContentType,t.Enums.UserBusyHandlingOptions=t.Constants.UserBusyHandlingOptions,t.Enums.UserType=t.Constants.UserType,t.Enums.UserState=t.Constants.UserState,t.Enums.SearchDirection=t.Constants.SearchDirection,t.Enums.ParticipantCriteria=t.Constants.GetConversationParticipantCriteria,t.Enums.ConversationParticipantType=t.Constants.ConversationParticipantType,t.Enums.RetrieveAction=t.Constants.RetrieveAction,t.Enums.RecordingInfoState=t.Constants.RecordingInfoState,t.Enums.RecordingInfoState=t.Constants.RecordingInfoState,t.Enums.SearchScope=t.Constants.SearchScope,t.Enums.SearchStatusCode=t.Constants.SearchStatusCode,t.Enums.SessionClosedReason=t.Constants.SessionClosedReason,t.Enums.GetAccountsFilterCriteria=t.Constants.GetAccountsFilterCriteria,t.Enums.AccountStatus=t.Constants.AccountStatus,t.Enums.GetAccountsSorting=t.Constants.GetAccountsSorting,t.Enums.SortOrder=t.Constants.SortOrder,t.Enums.SearchContext=t.Constants.SearchContext,t.Enums.Locale=t.Constants.Locale,t.Enums.VideoResolution={VGA:"VGA",HD:"HD",FHD:"FHD",NONE:"NONE"},t.Enums.FormControlType=t.Constants.CPaaSFormMetaDataControlType,t.Enums.RecordingVideoLayoutName=t.Constants.RecordingVideoLayoutName,t.Enums.JournalFilter=t.Constants.JournalFilter,t}((Circuit=function(e){"use strict";var t;return e.ExtensionConnHandlerSingleton={getInstance:function(){return t||(t=new e.ExtensionConnHandler),t}},e}((Circuit=function(p){"use strict";var e=p.BaseEventTarget,S=p.ChromeExtension,I=p.logger,A=p.Utils;function R(){R.parent.constructor.call(this,I);var o,a,s=5e3,c=65e3,r=this,l={},d=0,n=!1,e=window.BgExchangeConnectorHandler;if(p.isElectron){if(e){a=e.getInstance();var u=function(e){e.data&&e.data.keysToOmitFromLogging&&(e.keysToOmitFromLogging=e.data.keysToOmitFromLogging.map(function(e){return"data."+e}),delete e.data.keysToOmitFromLogging),t(e)};o=Object.create(I,{sendResponse:{value:function(e,t,n){var i={type:S.BgMsgType.RESPONSE,reqId:e,suppressLog:!!n,data:t};u(i)}},sendInternalEvent:{value:function(e){I.error("[ExtensionConnHandler]: Unexpected internal event: ",e)}},sendExchangeConnEvent:{value:function(e,t){var n={type:S.BgMsgType.EVENT,target:S.BgTarget.EXCHANGE_CONNECTOR,suppressLog:!!t,data:e};u(n)}}});var i="exchange";window.chrome={storage:{local:{set:function(e,t){window.localStorage.setItem(i,JSON.stringify(e,function(e,t){if("string"!=typeof e||"$"!==e.charAt(0))return t})),t&&t()},get:function(e,t){t&&t(JSON.parse(window.localStorage.getItem(i)))},clear:function(e){window.localStorage.removeItem(i),e&&e()}}},runtime:{},windows:{create:function(){}},permissions:{contains:function(e,t){t(!0)}}}}setTimeout(function(){I.info("[ExtensionConnHandler]: Raise extensionInitialized"),n=!0;var e=r.createEvent("extensionInitialized");e.data={version:"electron"},r.dispatch(e)},1e3)}function C(e,t){I.info("[ExtensionConnHandler]: Dispatching event: ",e);var n=r.createEvent(e);n.data=t,r.dispatch(n)}function E(e,t,n,i){return e?r.isExtensionRunning()?function(e,t,n,i){e.type===S.BgMsgType.REQUEST&&(e.reqId=function(e,t){e=e||function(){};var n=++d,i=window.setTimeout(function(){l[n]&&(I.error("[ExtensionConnHandler]: Timeout waiting for response. reqId:",n),delete l[n],e(S.ResponseError.TIMEOUT))},t||s);return l[n]={cb:e,timer:i},n}(t,n));i||I.msgSend("[ExtensionConnHandler]: ",e);if(e.suppressLog=i,p.isElectron&&a&&e.type===S.BgMsgType.REQUEST&&e.target===S.BgTarget.EXCHANGE_CONNECTOR)return window.setTimeout(function(){a.onWebClientMsg(o,e,p.__server)},0),e.reqId;var r=new CustomEvent(S.DOMEvent.TO_EXTENSION,{detail:JSON.stringify(e)});try{document&&document.dispatchEvent(r)}catch(e){return I.warning("[ExtensionConnHandler]: Error sending message: "+r,e),!1}return e.reqId}(e,t,n,i):(I.info("[ExtensionConnHandler]: Chrome extension is not running"),t&&window.setTimeout(function(){t("Extension not running")},0),!1):(I.error("[ExtensionConnHandler]: Cannot send message. Invalid message."),t&&window.setTimeout(function(){t("Invalid message")},0),!1)}function T(){I.warning("[ExtensionConnHandler]: The content script has unregistered itself. Chrome extension is no longer running."),n=!1,I.info("[ExtensionConnHandler]: Dispatching event: extensionUnregistered");var e=r.createEvent("extensionUnregistered");r.dispatch(e)}function t(e){if(e.target!==S.BgTarget.LOG)switch(e.suppressLog||I.msgRcvd("[ExtensionConnHandler]: ",e),e.type){case S.BgMsgType.REQUEST:case S.BgMsgType.EVENT:!function(e){switch(e.target){case S.BgTarget.INTERNAL:switch(e.data.type){case S.BgInternalMsgType.INIT_MSG:I.info("[ExtensionConnHandler]: Received INIT_MSG. Send an INIT_MSG_ACK to the extension."),n=!0,E({target:S.BgTarget.INTERNAL,data:{type:S.BgInternalMsgType.INIT_MSG_ACK}}),C("extensionInitialized",e.data);break;case S.BgInternalMsgType.EXTENSION_DISCONNECTED:I.warning("[ExtensionConnHandler]: Received EXTENSION_DISCONNECTED from ansible-content"),T();break;default:I.warning("[ExtensionConnHandler]: Received unknown INTERNAL msg type:",e.data.type)}break;case S.BgTarget.HEADSET_APP:switch(e.data.type){case S.BgHeadsetAppMsgType.HEADSET_APP_LAUNCHED:C("headsetAppLaunched",e.data);break;case S.BgHeadsetAppMsgType.HEADSET_APP_UNINSTALLED:C("headsetAppUninstalled",e.data);break;default:I.warning("[ExtensionConnHandler]: Received unknown HEADSET_APP msg type:",e.data.type)}break;case S.BgTarget.PRIVACY_SETTINGS:e.data.type===S.BgPrivacySettingsMsgType.IP_HANDLING_POLICY_CHANGED?C("webRTCIPHandlingPolicyChanged",e.data):I.warning("[ExtensionConnHandler]: Received unknown PRIVACY_SETTINGS msg type:",e.data.type);break;default:e.suppressLog||I.info("[ExtensionConnHandler]: Dispatching event:",e.target);var t=r.createEvent(e.target);t.data=e.data,t.suppressLog=e.suppressLog,e.reqId&&e.type===S.BgMsgType.REQUEST&&(t.reqId=e.reqId),r.dispatch(t)}}(e);break;case S.BgMsgType.RESPONSE:!function(e){if(l[e.reqId]){var t=l[e.reqId];t.timer&&window.clearTimeout(t.timer),delete l[e.reqId],e.data&&e.data.error?(t.cb(e.data.error),e.data.error===S.ResponseError.UNREGISTERED&&T()):t.cb(null,e.data),e.suppressLog||I.debug("[ExtensionConnHandler]: Remaining callbacks pending:",Object.keys(l).length)}else I.info("[ExtensionConnHandler]: No registered callback for reqId =",e.reqId)}(e);break;default:I.msgRcvd("[ExtensionConnHandler]: Unexpected message type: ",e.type)}else I.logMsg(e.data.log.level,e.data.log.messages)}this.isExtensionRunning=function(){return n},this.getScreenShareUserMedia=function(e){E({target:S.BgTarget.SCREEN_SHARE,type:S.BgMsgType.REQUEST,data:{type:S.BgScreenShareMsgType.CHOOSE_DESKTOP_MEDIA}},e)},this.exchangeConnect=function(e,t){E({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{method:S.BgExchangeMsgType.CONNECT,object:{settings:e}},keysToOmitFromLogging:["data.object.settings.exchInfo"]},t,18e4)},this.exchangeDisconnect=function(e){E({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{method:S.BgExchangeMsgType.DISCONNECT,object:{}}},e,c)},this.exchangeGetConnectionStatus=function(e,t){E({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.GET_CONNECTION_STATUS},keysToOmitFromLogging:["data.key"]},t,c)},this.exchangeGetCapabilities=function(e){E({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{method:S.BgExchangeMsgType.GET_CAPABILITIES}},e,c)},this.exchangeAutodiscoverGetServer=function(e,t){E({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{method:S.BgExchangeMsgType.AUTODISCOVER_GET_SERVER,object:{settings:e}},keysToOmitFromLogging:["data.object.settings.exchInfo"]},t,c)},this.exchangeCancelReqCallback=function(e){return I.debug("[ExtensionConnHandler]: Unregistering callback for reqId:",e),function(e){return!(!e||!l[e])&&(delete l[e],!0)}(e)},this.exchangeSearchContacts=function(e,t,n,i){return E({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.SEARCH_CONTACTS,object:{searchString:t,resultCount:n}},keysToOmitFromLogging:["data.key"]},i,c)},this.exchangeResolveContact=function(e,t,n){E({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.RESOLVE_CONTACT,object:t},keysToOmitFromLogging:["data.key"]},n,c)},this.exchangeGetContact=function(e,t,n){E({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.GET_CONTACT,object:{email:t}},keysToOmitFromLogging:["data.key"]},n,c)},this.exchangeOnRenewedToken=function(e,t,n,i){E({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.RESPONSE,data:{key:e,method:S.BgExchangeMsgType.ON_RENEWED_TOKEN,object:{reqId:t,token:n}},keysToOmitFromLogging:["data.key","data.object.token"]},i,c)},this.exchangeStoreCredentials=function(e,t){E({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{method:S.BgExchangeMsgType.STORE_EXCH_CREDENTIALS,object:e},keysToOmitFromLogging:["data.object"]},t,c)},this.getAllPersonalContacts=function(e,t){E({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.GET_ALL_PERSONAL_CONTACTS},keysToOmitFromLogging:["data.key"]},t,c)},this.getAppointments=function(e,t,n,i,r){E({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.GET_APPOINTMENTS,startDate:t,endDate:n,resCount:i},keysToOmitFromLogging:["data.key"]},r,c)},this.syncAllPersonalContacts=function(e,t,n){E({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.SYNC_ALL_PERSONAL_CONTACTS,syncState:t},keysToOmitFromLogging:["data.key","data.syncState"]},n,c)},this.getStoredCredentials=function(e,t){E({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.GET_STORED_CREDENTIALS},keysToOmitFromLogging:["data.key"]},t,c)},this.getOooMsg=function(e,t,n,i){E({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.GET_OOO_MSG,fromEmail:t,email:n},keysToOmitFromLogging:["data.key"]},i,c)},this.getUserAvailability=function(e,t,n){E({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.GET_USER_AVAILABILITY,email:t},keysToOmitFromLogging:["data.key","data.email"]},n,c)},this.getHeadsetIntegrationAppStatus=function(e,t){"function"==typeof t&&(p.isElectron?window.setTimeout(function(){I.debug("[ExtensionConnHandler]: Return status INSTALLED for desktop app"),t(null,{status:S.HeadsetAppStatus.INSTALLED})},0):E({target:S.BgTarget.HEADSET_APP,type:S.BgMsgType.REQUEST,data:{type:S.BgHeadsetAppMsgType.GET_HEADSET_APP_STATUS,appId:e}},t))},this.launchHeadsetIntegrationApp=function(e,t,n){E({target:S.BgTarget.HEADSET_APP,type:S.BgMsgType.REQUEST,data:{type:S.BgHeadsetAppMsgType.LAUNCH_HEADSET_APP,appId:e,localizedStrings:t}},n,18e4)},this.restartHeadsetApp=function(e,t){E({target:S.BgTarget.HEADSET_APP,type:S.BgMsgType.REQUEST,data:{type:S.BgHeadsetAppMsgType.RESTART_HEADSET_APP,appId:e}},t)},this.setIPHandlingPolicy=function(e,t,n){E({target:S.BgTarget.PRIVACY_SETTINGS,type:S.BgMsgType.REQUEST,data:{type:S.BgPrivacySettingsMsgType.SET_IP_HANDLING_POLICY,policy:e,localizedStrings:t}},n,18e4)},this.getIPHandlingPolicy=function(e){E({target:S.BgTarget.PRIVACY_SETTINGS,type:S.BgMsgType.REQUEST,data:{type:S.BgPrivacySettingsMsgType.GET_IP_HANDLING_POLICY}},e)},this.bringToFront=function(e){E({target:S.BgTarget.INTERNAL,type:S.BgMsgType.REQUEST,data:{type:S.BgInternalMsgType.BRING_TO_FRONT}},e)},this.getFile=function(e,t,n){E({target:S.BgTarget.INTERNAL,type:S.BgMsgType.REQUEST,data:{type:S.BgInternalMsgType.GET_FILE,name:e,lang:t}},n)},A.getBrowserInfo().chrome&&document&&document.addEventListener(S.DOMEvent.FROM_EXTENSION,function(e){if(e&&e.detail)try{t(JSON.parse(e.detail))}catch(e){I.error("[ExtensionConnHandler]: Error parsing JSON object. ",e)}})}return A.inherit(R,e),R.prototype.name="ExtensionConnHandler",p.ExtensionConnHandler=R,p}((Circuit=function(e){"use strict";var l=Circuit.logger;return e.CstaParser=function(){function r(e){var t=null;return e&&e.extn&&e.extn.pDa&&e.extn.pDa.prvt&&(t=e.extn.pDa.prvt.zEpid),t}function n(t){t&&Object.keys(t).forEach(function(e){t[e]=""===t[e]||"true"===t[e]})}function o(e){if(!e)return{};var t={};return e.sP&&(t.rSP=e.sP,n(t.rSP.cCSs)),e.extn&&e.extn.pDa&&e.extn.pDa.prvt&&void 0!==e.extn.pDa.prvt.zxSP&&(t.eSP=e.extn.pDa.prvt.zxSP,n(t.eSP)),t}function i(e){return{forwardingType:e.fTe,forwardStatus:"true"===e.fS,forwardDN:e.fDNN}}function a(e){return{name:e.zgNM,pilotDn:e.zgDN,available:"false"===e.zMB}}function s(e){if(e.extn&&e.extn.pDa&&e.extn.pDa.prvt){var t=[];if(e.extn.pDa.prvt.zeMBSL)return Array.isArray(e.extn.pDa.prvt.zeMBSL.zeMBS)?e.extn.pDa.prvt.zeMBSL.zeMBS.forEach(function(e){t.push(a(e))}):t.push(a(e.extn.pDa.prvt.zeMBSL.zeMBS)),t}return null}function c(e){return{recordId:e.rID,callID:e.cID,recordType:e.rTp,createdTime:e.cTm,result:e.res,callDuration:e.cDr,callingDevice:e.clDv||"",calledDevice:e.cldDv||"",answeringDevice:e.aDv||""}}this.genCstaRequest=function(e){try{switch(e.request){case"AlternateCall":return function(e){return{ACl:{hC:{cID:e.heldCall.cID,dID:e.heldCall.dID},atC:{cID:e.activeCall.cID,dID:e.activeCall.dID}}}}(e);case"ConferenceCall":return function(e){return{CoC:{hC:{cID:e.heldCall.cID,dID:e.heldCall.dID},atC:{cID:e.activeCall.cID,dID:e.activeCall.dID}}}}(e);case"AnswerCall":return function(e){return{AnC:{cTBAd:{cID:e.callToBeAnswered.cID,dID:e.callToBeAnswered.dID}}}}(e);case"CallBackCallRelated":return function(e){return{CB:{cC:{cID:e.callBackConnection.cID,dID:e.callBackConnection.dID}}}}(e);case"CallBackNonCallRelated":return function(e){return{CBNC:{orD:e.orD,tD:e.tD}}}(e);case"CancelCallBack":return function(e){return{CCB:{orD:e.orD,tD:e.tD}}}(e);case"ClearConnection":return function(e){return{CCn:{coTBC:{cID:e.connectionToBeCleared.cID,dID:e.connectionToBeCleared.dID},rsn:e.reason}}}(e);case"ConsultationCall":return function(e){return{CnC:{cnD:e.consultedDevice||void 0,eCl:{cID:e.existingCall.cID,dID:e.existingCall.dID}}}}(e);case"DeflectCall":return function(e){var t={cTBD:{cID:e.callToBeDiverted.cID,dID:e.callToBeDiverted.dID},nD:e.newDestination};e.autoAnswer&&(t.extn={pDa:{prvt:{zdT:"Auto-Answer"}}});return{DCl:t}}(e);case"GenerateDigits":return function(e){return{GD:{cTSD:{cID:e.connectionToSendDigits.cID,dID:e.connectionToSendDigits.dID},cTS:e.charactersToSend}}}(e);case"GetDoNotDisturb":return function(e){return{GDND:{dvc:e.device}}}(e);case"GetForwarding":return function(e){return{GF:{dvc:e.device}}}(e);case"GetMessageWaitingIndicator":return function(e){return{GMWI:{dvc:e.device}}}(e);case"HoldCall":return function(e){var t={cTBH:{cID:e.callToBeHeld.cID,dID:e.callToBeHeld.dID}};e.holdOptions&&(t.extn={zhOs:e.holdOptions});return{HC:t}}(e);case"ReconnectCall":return function(e){return{RC:{hC:{cID:e.heldCall.cID,dID:e.heldCall.dID},atC:{cID:e.activeCall.cID||void 0,dID:e.activeCall.dID||void 0}}}}(e);case"RetrieveCall":return function(e){return{RCl:{cTBRd:{cID:e.callToBeRetrieved.cID,dID:e.callToBeRetrieved.dID}}}}(e);case"SetBusy":return function(e){return{zSBN:{dvc:e.device,zbO:e.busyState}}}(e);case"SetDoNotDisturb":return function(e){return{SDND:{dvc:e.device,dNDO:e.doNotDisturbOn}}}(e);case"SetForwarding":return function(e){var t={SF:{dvc:e.device,aF:e.activateForward,fDNN:e.forwardDN,fTe:e.forwardingType,riC:e.ringCount}},n={};void 0!==e.staticOndActive?n={zsOA:!0===e.staticOndActive?"true":"false",zsOD:e.staticOndDN||""}:void 0!==e.voicemailActive||void 0!==e.voicemailRingDuration?n={zvMA:"boolean"==typeof e.voicemailActive?e.voicemailActive.toString():void 0,zvMRD:e.voicemailRingDuration?e.voicemailRingDuration.toString():void 0}:(void 0!==e.mainRingDuration&&(n.zmRD=e.mainRingDuration.toString()||""),void 0!==e.clientRingDuration&&(n.zcRD=e.clientRingDuration.toString()||""),void 0!==e.cellRingDuration&&(n.zcpRD=e.cellRingDuration.toString()||""),void 0!==e.alternativeNumber&&(n.zcPN=e.alternativeNumber),void 0!==e.routeToCell&&(n.zrTCN=e.routeToCell?"true":"false"));0n&&(i=i*n/r,r=n):t"),Me(m.onGetUserMediaException,{info:t}))},function(e){var t,n=e&&e.name||"Unspecified";if(o.videoResolution&&(n===an||n===sn))return Jt.warn("[RtcSessionController]: Failed to access local media with HD constraints: ",p.video),o.videoResolution=a.shift(),me(o.videoResolution),p.video=_.getVideoOptions(o),void l();Jt.warn("[RtcSessionController]: Failed to access local media: ",n),E&&(window.clearTimeout(E),E=null),t=dn.includes(n)?Y.video?"res_AccessToMediaInputDevicesFailedPermissionDenied":"res_AccessToAudioInputDeviceFailedPermissionDenied":n===cn||n===ln?Y.video?"res_AccessToMediaInputDevicesFailedInUse":"res_AccessToAudioInputDeviceFailedInUse":Y.video?"res_AccessToMediaInputDevicesFailed":"res_AccessToAudioInputDeviceFailed",u(t)})};l(),Jt.debug("[RtcSessionController]: Requested access to Local Media")})}catch(e){Jt.error("[RtcSessionController]: Exception while handling getUserMedia: ",e),E&&(window.clearTimeout(E),E=null),u(Y.video?"res_AccessToMediaInputDevicesFailed":"res_AccessToAudioInputDeviceFailed")}}function Ne(t,n,i){Jt.debug("[RtcSessionController]: getUserMediaDesktop()");try{var e={audio:!1},r=he();e.video=_.getDesktopOptions(i.streamId||i.screenType,r),Jt.info("[RtcSessionController]: Calling getUserMedia - constraints = ",e),_.getUserMedia(e,function(e){if(Jt.info("[RtcSessionController]: User has granted access for screen capture. Stream Id:",_.getStreamId(e)),se)return Jt.info("[RtcSessionController]: Session already terminated. Stop desktop MediaStream: ",_.getStreamId(e)),void ct(e);i&&(Z=i.isScreenControlled,ee=Z,function(e){Jt.debug("[RtcSessionController]: send ScreenSharePointerStatus event"),Me(m.onScreenSharePointerStatus,{isSupported:!(!e||!e.isSupported),isEnabled:!(!e||!e.isEnabled)})}(i.pointer),te=i),e.oninactive=Re.bind(null,e,!0),ut(e,u),t()},function(e){var t=e&&e.name||"Unspecified";Jt.warn("[RtcSessionController]: Failed to access local media: ",t),dn.includes(t)?n(Xt.ReturnCode.CHOOSE_DESKTOP_MEDIA_CANCELLED):n("res_AccessToDesktopFailed")}),Jt.debug("[RtcSessionController]: Requested access for screen capture")}catch(e){Jt.error("[RtcSessionController]: Exception while handling getUserMedia: ",e),n("res_AccessToDesktopFailed")}}function me(e){e===tn.VIDEO_480&&Y.hdVideo&&Y.videoResolution!==e&&(Jt.debug("[RtcSessionController]: Downgrading video from HD to SD. Resolution: ",e),Y.hdVideo=!1),Y.videoResolution=e}function he(){var e=Y.hdDesktop?"hdScreenShare":"screenShare",t={frameRate:{min:fn.sdpParameters[e].minFrameRate,max:fn.sdpParameters[e].maxFrameRate}};return Y.remoteControlEnabled&&(t.frameRate.min=Math.max(t.frameRate.min,fn.sdpParameters.rcScreenShare.minFrameRate),t.frameRate.max=Math.max(t.frameRate.max,fn.sdpParameters.rcScreenShare.maxFrameRate)),t}function Oe(e){if(e){if(c)return!0}else if(y)return!0;var t={};A&&(t.rtcpMuxPolicy=fn.sdpParameters.rtcpMuxPolicy),C.length&&!re?(t.iceServers=[{urls:C,credential:E.password,username:E.username}],fn.allowOnlyRelayCandidates&&(t.iceTransportPolicy="relay")):(re||Jt.warn("[RtcSessionController]: No TURN server(s) provided."),t.iceServers=[]);var n=!!re;re=!1,fn.webRTCIPHandlingPolicy&&Jt.info("[RtcSessionController]: webRTCIPHandlingPolicy is set to ",fn.webRTCIPHandlingPolicy),Jt.debug("[RtcSessionController]: Creating RtcPeerConnections. config: ",t);var i={optional:[{DtlsSrtpKeyAgreement:!0},{googImprovedWifiBwe:!0},{googHighBitrate:!0},{googVeryHighBitrate:!0},{googDscp:!0}]};Jt.debug("[RtcSessionController]: Creating peer connections. constraints:",i),h?(Jt.debug("[RtcSessionController]: Set number of extra video channels for direct calls to 0"),s=0):D?(Jt.debug("[RtcSessionController]: Set number of extra video channels for mobile clients to 0"),s=0):ne&&ie?(Jt.debug("[RtcSessionController]: Set number of extra video channels for guests in large conference to 0."),s=0):Ae||!z&&!J?(s="number"==typeof fn.maxVideoExtraChannels?(s=Math.max(fn.maxVideoExtraChannels,0),Math.min(s,Sn)):In,Jt.info("[RtcSessionController]: Set number of extra video channels to ",s)):(Jt.debug("[RtcSessionController]: Remote video is disabled. Set number of extra video channels to 0."),s=0);var r=s;Y.video&&J&&_.unifiedPlanEnabled&&!Ae&&(Jt.debug("[RtcSessionController]: Local video is enabled and we only allow remote screenshare. We need to setup an extra sendonly video channel."),r=1);var o,a={extraVideoChannels:r,createDesktopPc:!fn.disableDesktopPc&&!h&&(!z||Y.desktop||J),onlyRemoteScreenShare:J};Jt.debug("[RtcSessionController]: Creating peer connections. options:",a);try{e||($=[]),(o=_.unifiedPlanEnabled?new jt.RtcPeerConnectionsUnified(t,a):new jt.RtcPeerConnections(t,i,a)).connectionBypassed=n,Jt.debug("[RtcSessionController]: Created audio/video peer connections. Connection bypassed: ",n)}catch(e){return Jt.error("[RtcSessionController]: Failed to create peer connections.",e),!1}return e?c=o:(d=[y=o,b],l=ye([y]),De(y,l)),!0}function De(e,t){e&&(e.onicecandidate=function(e,t){if(!e||!d.includes(e))return void Je("Received icecandidate event for old PC");var n,i=qe(e,"sdpStatus");if(t.candidate){if(!t.candidate.candidate)return void ze("Ignore empty candidate for mid "+t.candidate.sdpMid);var r=new zt(t.candidate.candidate);if("udp"!==r.transport)return void ze("Ignore non UDP candidate");if(e===y&&"relay"===r.typ&&(e.hasRelayCandidates=!0),ze("New ICE candidate: ",t.candidate),Ze(e)){if(n=e.localDescription,!Ze(e,n.type))return;var o={candidate:t.candidate.candidate,sdpMid:t.candidate.sdpMid,sdpMLineIndex:t.candidate.sdpMLineIndex};!function(e,t){var n=Ye(e=e||y);if(!n)return!1;if(fn.allowAllIceCandidatesScreenShare||t.sdpMid!==y.getScreenShareMediaId()||n.hasRelayRtpCandidate||n.sendAllCandidates)return!0;var i=new zt(t.candidate);if(i.isTcpTlsRelay())return i.isRtp()&&(Jt.info("[RtcSessionController]: Found local relay candidate for TURN over TCP/TLS. Remove queued candidates."),n.hasRelayRtpCandidate=!0,delete n.queuedCandidates,n.relayRtpCandidateTimeout&&(window.clearTimeout(n.relayRtpCandidateTimeout),delete n.relayRtpCandidateTimeout)),!0;"udp"===i.transport&&(n.queuedCandidates||(n.queuedCandidates=[],Jt.debug("[RtcSessionController]: Start timer to wait for relay candidate for TURN over TCP/TLS."),n.relayRtpCandidateTimeout=window.setTimeout(function(){Jt.info("[RtcSessionController]: Timer expired. Stop waiting for relay candidate for TURN over TCP/TLS and send all pending candidates."),delete n.relayRtpCandidateTimeout,n.queuedCandidates&&(we(n.queuedCandidates,e),delete n.queuedCandidates),n.sendAllCandidates=!0},un)),n.queuedCandidates.push(t),Jt.debug("[RtcSessionController]: Queue candidate in case there is no TURN over TCP/TLS relay candidate"));return!1}(e,o)||(i!==nn.None&&i!==nn.OfferPending&&i!==nn.AnswerPending?function(e,t){var n=Ye(t);if(!n)return;n.pendingCandidates||(n.pendingCandidates=[],Jt.debug("[RtcSessionController]: Start timer to collect candidates before send."),n.collectCandidatesTimeout=window.setTimeout(function(){Jt.debug("[RtcSessionController]: Timer expired. Send all pending candidates."),delete n.collectCandidatesTimeout,n.pendingCandidates&&(we(n.pendingCandidates,t),delete n.pendingCandidates)},on));n.pendingCandidates.push(e)}(o,e):ze("Ignore ICE candidate in state ",i))}}else if(ze("End of candidates. PC: ",be(e)),e.endOfCandidates=!0,e!==b&&nt()){if(!(n=e.localDescription))return void $e("End of candidates, but cannot access pc.localDescription");Ze(e,n.type)&&i!==nn.None&&i!==nn.OfferPending&&i!==nn.AnswerPending?function(e){var t=Ye(e);if(!t)return;var n=[];t.pendingCandidates&&(Jt.info("[RtcSessionController]: Send all pending candidates."),n=t.pendingCandidates);t.queuedCandidates&&(Jt.info("[RtcSessionController]: There was no relay candidate for TURN over TCP/TLS. Send all queued candidates."),Array.prototype.push.apply(n,t.queuedCandidates));n.push({candidate:"a=end-of-candidates\r\n"}),Xe(e),we(n,e)}(e):He(e,n)}qe(e,"candidatesTimer")&&Ze(e)&&(i===nn.OfferPending||i===nn.AnswerPending)&&(n=e.localDescription,He(e,n))}.bind(null,e),e.oniceconnectionstatechange=Ue.bind(null,e),e.onaddstream=function(e,t){if(ze("Added Remote Stream"),I)return void ze("Renegotiation is in progress. Ignore AddStream event.");Et([t.stream]),Ve()}.bind(null,e),e.onremovestream=function(e,t){Je("Removed Remote Stream"),function(e){if(!e)return;var n=!1,i=O?_.getVideoTrackId(e):_.getVideoStreamTrackId(e);i&&w.some(function(e,t){return e.streamId===i&&(w.splice(t,1),n=!0)});var t=O?_.getAudioTrackId(e):_.getAudioStreamTrackId(e);G&&G.streamId===t&&(n=!(G=null));n&&We()}(t.stream),Ve()}.bind(null,e)),t&&(t.onThresholdExceeded=function(e){Me(m.onStatsThresholdExceeded,{cleared:e})},t.onNoOutgoingPackets=function(){Me(m.onStatsNoOutgoingPackets,{})},t.onNetworkQuality=function(e){Me(m.onNetworkQuality,{quality:e})})}function Pe(e,t){e&&(e.onicecandidate=null,e.oniceconnectionstatechange=null,e.onaddstream=null,e.onremovestream=null),t&&(t.onThresholdExceeded=null,t.onNoOutgoingPackets=null,t.onNetworkQuality=null)}function ye(e){return _.unifiedPlanEnabled&&jt.CallStatsHandlerUnified?new jt.CallStatsHandlerUnified(e):new jt.CallStatsHandler(e)}function be(e){return e===y?"audio/video":"screen control"}function Ue(e){if(e&&d.includes(e)){var t=be(e);switch(ze("Connection state change ("+t+"): ",e.iceConnectionState),!C.length||e!==y||e.connectionBypassed||"completed"!==e.iceConnectionState&&"failed"!==e.iceConnectionState||e.hasRelayCandidates||Je("[RtcSessionController]: No relay candidates were collected, please check connectivity to the TURN servers"),qe(e,"sdpStatus")){case nn.Connected:switch(e.iceConnectionState){case"connected":case"completed":Ge(e,t);break;case"disconnected":e.connectionBypassed||function(e,t){if(e.iceDisconnectTimeout)return;e.iceDisconnectTimeout=window.setTimeout(function(){delete e.iceDisconnectTimeout,"disconnected"===e.iceConnectionState&&(Jt.debug("[RtcSessionController]: send IceDisconnected event pcType:",t),Me(m.onIceDisconnected,{pcType:t}))},Cn)}(e,t);break;case"failed":e.connectionBypassed||(_t(nn.Disconnected,e),$e("[RtcSessionController]: ICE connection has failed"),e!==b&&ft("res_CallMediaDisconnected"))}break;case nn.AnswerReceived:case nn.PrAnswerReceived:case nn.AnswerApplied:case nn.AnswerSent:switch(e.iceConnectionState){case"connected":case"completed":e.connected=!0,tt(e)&&(Qe(e),_t(nn.Connected,e),Ge(e,t));break;case"failed":Qe(e),Rt(e)}}}else Je("Received iceconnectionstatechange event for old PC")}function Le(e,t){ze("RTCDTMFSender - ontonechange",t.tone?"":": finished"),function(e){Jt.debug("[RtcSessionController]: send DTMFToneChanged event"),Me(m.onDTMFToneChange,{tone:e})}(t.tone)}function Me(e,t){if("function"==typeof e)try{e(t||{})}catch(e){Jt.error(e)}}function we(e,t){var n=Ye(t);if(n&&e){var i=n.sentIceCandidates,r=!1;if(0<(e=e.filter(function(e){if(e.candidate.startsWith("a=end-of-candidates"))return r=!0;var t=e.candidate,n=i.some(function(e){return e.equals(t)});return n?Je("Ignore duplicate ICE candidate: ",e.candidate):i.push(new zt(t)),!n})).length){Jt.debug("[RtcSessionController]: Send IceCandidate event");var o={origin:function(e){if(!e)return"";var t=qe(e,"localOrigin");if(!t){var n=e.localDescription;n&&(t=Zt.getOrigin(n.sdp),Ke(e,"localOrigin",t))}return t}(t),candidates:e,endOfCandidates:r,isAudioVideo:"audio/video"===be(t)};Me(m.onIceCandidate,o),it(t)}}}function Ge(e,t){e.iceDisconnectTimeout&&(window.clearTimeout(e.iceDisconnectTimeout),delete e.iceDisconnectTimeout),Jt.debug("[RtcSessionController]: send IceConnected event pcType:",t),Me(m.onIceConnected,{pcType:t})}function He(e,t){if(e){je(e);var n=qe(e,"sdpStatus");"offer"===t.type?n===nn.OfferPending&&ke(e,nn.OfferSent):n===nn.AnswerPending&&ke(e,nn.AnswerSent)}else Je("Cannot send local description for non existing pc.")}function ke(e,t){if(e){var n;if(Jt.info("[RtcSessionController]: sendSessionDescription - PC: ",be(e)),e===b){var i=b.localDescription;n={type:i.type,parsedSdp:Zt.parse(i.sdp)}}else{var r=e.localDescription,o=Zt.parse(r.sdp);if("answer"===r.type){Jt.info("[RtcSessionController]: sendSessionDescription - Processing answer SDP");var a=qe(y,"disabledRemoteOfferMLines");!y.desktopPeerConnection&&a.get(N.video)&&(o.m.splice(N.video,0,a.get(N.video)),a.remove(N.video))}if(e.desktopPeerConnection){Jt.info("[RtcSessionController]: sendSessionDescription - Adjust screenshare m-line");var s=Zt.findMediaLineIndex(o,e.getScreenShareMediaId());if(0<=s){var c=o.m[s];if(c){c={m:[c]};var l=!h&&!fn.allowAllIceCandidatesScreenShare;Jt.info("[RtcSessionController]: Remove UDP video candidates for screenshare: ",l);var d=Ze(y,r.type)&&!y.endOfCandidates;Zt.validateIceCandidates(c,l,d)}}else Jt.warn("[RtcSessionController]: Could not find screenshare m-line: no ICE validation was made.")}n={type:r.type,parsedSdp:o}}var u=Ze(e,n.type),C=n.parsedSdp;C=Zt.removeAudioLevelAttr(C),C=Zt.fixTrickleIceOption(C,u),u?nt()&&(C=Zt.addEndOfCandidatesLine(C)):C=Zt.removeEndOfCandidatesLine(C),y.restoreAudioConnectionMode&&Zt.setConnectionMode(C,"audio",y.restoreAudioConnectionMode);var E=!D||v.canReceiveHdVideo?"maxBw":"maxBwMobile";(E=fn.sdpParameters.receiveVideo[E])&&Zt.setVideoBandwidth(C,E,!0);var T=le||de;if(0!==Zt.iceTotalCandidatesCount(C)||T)if(Zt.validateIceCandidates(C,!1,Se)||u&&!nt()||le){if(u&&!nt()){var p=Ye(e);p&&(p.sentIceCandidates=Zt.getIceCandidates(C))}var S={type:n.type,sdp:Zt.stringify(C)};if(e===y&&e.desktopPeerConnection&&(S.screen=y.getScreenShareMediaId(),P[g])){var I=function(e){var t,n=P[e];n&&n.getVideoTracks().length&&(t=_.getVideoStreamTrackId(n));return t}(g);Jt.info("[RtcSessionController]: Video streamId is ",I);var A=null;O&&I&&(A=_.unifiedPlanEnabled?function(e){var t,n=P[e];if(n){var i=n.getVideoTracks()[0];i&&(t=y&&y.getMediaId(i))}return t}(g):Zt.getMediaIds(C)[I]),S.video=A||I,Kt()&&(S.videoSenderConfiguration=y.getAvailableVideoSenders(Ie))}Jt.debug("[RtcSessionController]: send SessionDescription event"),le=!1,Me(m.onSessionDescription,{sdp:S}),_t(t,e)}else Jt.error("[RtcSessionController]: Failure: SDP contains at least one m line without IceCandidates"),ft();else if(u){var R=ht();Jt.debug("[RtcSessionController]: No ICE candidates collected yet. Waiting "+R+" more milliseconds.");var f=window.setTimeout(function(){Ke(e,"candidatesTimer",null),ft("res_RestartBrowser")},R);Ke(e,"candidatesTimer",f)}else ft("res_RestartBrowser")}else Je("Cannot send Session Description for non existing pc.")}function Ve(){Jt.debug("[RtcSessionController]: send RemoteStreamUpdated event"),Me(m.onRemoteStreamUpdated,{})}function Fe(e){Jt.debug("[RtcSessionController]: send Error event"),Me(m.onRtcError,{error:e})}function Be(e){"function"==typeof m.onRtcError&&window.setTimeout(function(){Fe(e)},0)}function xe(){Jt.debug("[RtcSessionController]: send MediaUpdate event"),Me(m.onMediaUpdate,{})}function We(){Jt.debug("[RtcSessionController]: send RemoteStreams event"),Me(m.onRemoteStreams,{audio:G,video:w})}function Ye(e){return e?e===y?a.main:e===b?a.screenControl:null:null}function Ke(e,t,n){e&&(e===y?a.main[t]=n:a.screenControl[t]=n)}function qe(e,t){return e?e===y?a.main[t]:a.screenControl[t]:null}function je(e){var t=qe(e,"candidatesTimer");t&&(window.clearTimeout(t),Ke(e,"candidatesTimer",null))}function Qe(e){var t=qe(e,"connectedTimer");t&&(window.clearTimeout(t),Ke(e,"connectedTimer",null))}function Xe(e){var t=Ye(e);t&&(t.collectCandidatesTimeout&&(window.clearTimeout(t.collectCandidatesTimeout),delete t.collectCandidatesTimeout),t.relayRtpCandidateTimeout&&(window.clearTimeout(t.relayRtpCandidateTimeout),delete t.relayRtpCandidateTimeout),t.sentIceCandidates=[],t.pendingCandidates&&delete t.pendingCandidates,t.queuedCandidates&&delete t.queuedCandidates,t.hasRelayRtpCandidate=!1,t.sendAllCandidates=!1)}function ze(e,t){Jt.debug("[RtcSessionController]["+o+"]: "+e,t)}function Je(e,t){Jt.warn("[RtcSessionController]["+o+"]: "+e,t)}function $e(e,t){Jt.error("[RtcSessionController]["+o+"]: "+e,t)}function Ze(e,t){return!!e&&(t?"offer"===t&&qe(e,"trickleIceForOffer")||"answer"===t&&qe(e,"trickleIceForAnswer"):qe(e,"trickleIceForOffer")||qe(e,"trickleIceForAnswer"))}function et(e,t){var n=t&&Zt.isTrickleIceOption(t);return n&&Jt.debug("[RtcSessionController]: SDP "+e+" indicates support for Trickle-ICE."),!!n}function tt(e){return e&&e===b?b.connected:!y||y.connected}function nt(){return(!y||y.endOfCandidates)&&(!b||b.endOfCandidates)}function it(t){if(t=t||y)if(Qe(t),tt(t))_t(nn.Connected,t);else{var e=X?r:i;Jt.debug("[RtcSessionController]: Starting ICE CONNECTED timer");var n=window.setTimeout(function(){Ke(t,"connectedTimer",null);var e=qe(t,"sdpStatus");if("connected"===t.iceConnectionState||"completed"===t.iceConnectionState)return Jt.debug("[RtcSessionController]: Missed iceConnectionState=connected event but media is connected"),t.connected=!0,_t(nn.Connected,t),void Ge(t,be(t));e!==nn.AnswerSent&&e!==nn.AnswerReceived&&e!==nn.AnswerApplied||tt(t)||(X?_t(nn.Connected,t):(Jt.warn("[RtcSessionController]: Timed out waiting for connected state."),Rt(t)))},e);Ke(t,"connectedTimer",n)}else Je("Terminating waitConnectedState for non existing pc.")}function rt(){c&&(Jt.debug("[RtcSessionController]: Closing the pre-allocated peer connection"),Ke(y,"nextPcLocalSdpSetAt",0),ot(c),c=null)}function ot(e,t){Pe(e,t),e&&(e.iceDisconnectTimeout&&(window.clearTimeout(e.iceDisconnectTimeout),delete e.iceDisconnectTimeout),_.closePc(e))}function at(e){if(!e)return!1;var t=e.getLocalStreams();if(!en.isEmptyArray(t))return!0;Jt.debug("[RtcSessionController]: Add local streams to "+(e===y?"existing":"next")+" peer connection");try{P[g]&&e.addStream(P[g],yt(),Ie),Jt.debug("[RtcSessionController]: Added local audio/video stream"),P[u]&&(P[u].isScreen=!0,e.addStream(P[u],yt(),Ie),Jt.debug("[RtcSessionController]: Added local screenshare stream"))}catch(e){return Jt.error("[RtcSessionController]: Failed to add Local Streams ",e),!1}return!0}function st(){Jt.debug("[RtcSessionController]: Remove local streams from existing PeerConnections");try{[y].forEach(function(n){n&&n.getLocalStreams().forEach(function(e,t){e&&(n.removeStream(e),Jt.debug("[RtcSessionController]: Removed PeerConnection Stream #",t))})})}catch(e){return Jt.error("[RtcSessionController]: Failed to remove Local Streams ",e),!1}return!0}function ct(e){e&&(e.oninactive=null,0"),M=n[1],Jt.debug("[RtcSessionController]: Set local desktop stream to ",_.getStreamId(M)||""),Jt.debug("[RtcSessionController]: send LocalVideoStream event"),Me(m.onLocalVideoStream,{stream:M||t,videoStream:t,desktopStream:M}),xe())}function ut(e,t){if(t===g||t===u){if(P[t]!==e){var n,i,r;if(P[t]&&ct(P[t]),P[t]=e,t===g&&Y.video){if(Y.hdVideo){if(Y.videoResolution){var o=fn.sdpParameters.hdVideo[Y.videoResolution];n=o&&o.maxBw}i="hdVideo",r=Xt.VideoQuality.HIGH}else i="video",r=Xt.VideoQuality.NORMAL;n||(n=fn.sdpParameters[i].maxBw)}else t===u&&Y.desktop&&(i=Y.hdDesktop?"hdScreenShare":"screenShare",n=fn.sdpParameters[i].maxBw,Y.remoteControlEnabled&&(n=Math.max(n,fn.sdpParameters.rcScreenShare.maxBw)));if(e&&0(T.minBitRate||0)&&(T=E,Jt.debug("[RtcSessionController]: Using X-Google parameters from screenshare: ",T))}Zt.setXGoogle(t,T),C&&E&&!_.unifiedPlanEnabled&&Zt.setXGoogle(t,E,C)}if(Zt.setOpusParameters(t,fn.sdpParameters.audio),V!==(V=!!Zt.isHold(t)&&("offer"===n||!F&&Y.audio))&&(V?Jt.info("[RtcSessionController]: The client has been held"):Jt.info("[RtcSessionController]: The client has been retrieved")),A){var S=t.m[0];if(S&&"audio"===S.media)S.a.some(function(e){return"mid"===e.field})||(pe=pe||"audio",Jt.debug("[RtcSessionController]: Adding a=mid:"+pe+" to SBC's answer SDP"),S.a.push({field:"mid",value:pe}))}var I=qe(e,"sdpStatus");return"offer"!==n||I!==nn.Connected||F||V||(w.length&&!s?(Jt.debug("[RtcSessionController]: send RemoteVideoRemoved event"),Me(m.onRemoteVideoRemoved,{})):!w.length&&s&&(Jt.debug("[RtcSessionController]: send RemoteVideoAdded event"),Me(m.onRemoteVideoAdded,{}))),F||"answer"===n&&a||(H={audio:!0,video:s}),Se=h&&"offer"===n&&Zt.isMultiplexEnabled(t),t}function ht(){var e=fn.candidatesTimeout||rn;return 0=r.Threshold[0]?o:-1,c.startTime,i,t),P(c,r,"audio",o);var a=(i.ps||0)-(t.ps||0);O(n,K.NO_PACKETS_SEND,!(0=r.Threshold[0]?s:-1,c.startTime,i,t)}l[e]=i,C[e]=n})}(e),function(s){Object.keys(s.audio.receive).forEach(function(e){var t=l[e]||{},n=C[e]||{},i=s.audio.receive[e];i.media="audio";var r=K.PACKET_LOSS_RECV;if(i){var o,a=m(i,t);i.pl&&i.pr&&O(n,r,a>=r.Threshold[0]?a:-1,s.startTime,i,t),P(s,r,"audio",a),c.sendOnlyStream||O(n,K.NO_PACKETS_RECV,!(i.pr>t.pr)||-1,s.startTime,i,t),r=K.GOOG_JITTER_RECEIVED,h(i,t,K.GOOG_JITTER_RECEIVED.StatName),o=i[r.StatName],P(s,r,"audio",o),O(n,r,o&&o>=r.Threshold[0]?o:-1,s.startTime,i,t)}l[e]=i,C[e]=n})}(e))}function b(a){Object.keys(a.video.transmit).forEach(function(e){var t=l[e]||{},n=E[e]||{},i=a.video.transmit[e];i.media="video";var r=q.PACKET_LOSS_SEND;if(i&&!S[i.trackId]){var o=N(i,t);i.pl&&i.ps&&O(n,r,o>=r.Threshold[0]?o:-1,a.startTime,i,t),P(a,r,"video",o),P(a,I.FRAME_HEIGHT_SENT,"video",i.fhs),P(a,I.FRAME_WIDTH_SENT,"video",i.fws),P(a,I.FRAME_RATE_SENT,"video",i.frs),a.video.bw&&(P(a,I.TRANSMIT_BIT_RATE,"video",a.video.bw.tbr),P(a,I.AVAIL_SEND_BW,"video",a.video.bw.abw)),function(e,t,n){if(0<=t&&0<=n){e.quality.videoInfo={resolution:{height:t,width:n}};var i=null;switch(t){case 1080:i=B.VIDEO_1080;break;case 720:i=B.VIDEO_720;break;case 480:i=B.VIDEO_480}i&&(e.quality.videoInfo.hdVideo=i)}else e.quality.videoInfo={}}(a,i.fhs,i.fws),a.video.isActive=!0}l[e]=i,E[e]=n})}function U(e){e&&e.video&&(l.bw=e.video.bw||{},l.bw.media="video",b(e),function(a){Object.keys(a.video.receive).forEach(function(e){var t=l[e]||{},n=E[e]||{},i=a.video.receive[e];i.media="video";var r=q.PACKET_LOSS_RECV;if(i&&i.pr){var o=m(i,t);i.pl&&O(n,r,o>=r.Threshold[0]?o:-1,a.startTime,i,t),P(a,r,"video",o),a.video.isActive=!0}l[e]=i,E[e]=n})}(e))}function L(e){!function(i){i.quality.level=x.RTP_QUALITY_HIGH;var r=0,o=-1;if(Object.keys(x).some(function(e){var t=x[e];if(t!==x.RTP_QUALITY_HIGH){var n=i.quality[t.value]||[];if(0=i.Threshold[0]?n.rtt:-1,a.startTime,n,t);var o=n.mediaTypes||t&&t.mediaTypes||[];o.includes("audio")?(i=K.GOOG_RTT,P(a,i,"audio",n.rtt)):o.includes("video")&&a.video.isActive&&(i=q.GOOG_RTT,P(a,i,"video",n.rtt)),T[e]=r})}(e),t=L(e),function(n){Object.keys(n.channelInfo).forEach(function(e){var t=s[e]||{};s[e]=Object.assign(t,n.channelInfo[e])})}(e),!t&&p&&(V.debug("[CallStatsHandlerUnified]: processRTPStats - No quality issues detected. Clear threshold exceeded error."),p=!1,A.onThresholdExceeded&&A.onThresholdExceeded(!0)),!p&&a%n!=0||function(i){var r,o;function a(e){return void 0===e||e<0?"n/a":e}Object.keys(i.channelInfo).forEach(function(n){var e=i.channelInfo[n];r="[CallStatsHandlerUnified]: statsReport: channelRtt="+(0<=e.rtt?e.rtt:"n/a"),Object.keys(i.audio.receive).forEach(function(e){var t=i.audio.receive[e];t.channelId===n&&(r+="\n audioReceive: id="+t.id+" pl="+a(t.pl)+" pr="+a(t.pr)+" or="+a(t.or)+" jr="+a(t.jr))}),Object.keys(i.audio.transmit).forEach(function(e){var t=i.audio.transmit[e];t.channelId===n&&(r+="\n audioTransmit: id="+t.id+" pl="+a(t.pl)+" ps="+a(t.ps)+" os="+a(t.os))}),Object.keys(i.video.receive).forEach(function(e){var t=i.video.receive[e];t.channelId===n&&(r+="\n videoReceive: id="+t.id+" pl="+a(t.pl)+" pr="+a(t.pr)+" or="+a(t.or)+" fwr="+t.fwr+" fhr="+t.fhr+" frd="+t.frd+" frr="+t.frr)}),Object.keys(i.video.transmit).forEach(function(e){var t=i.video.transmit[e];t.channelId===n&&(r+="\n videoTransmit: id="+t.id+" pl="+a(t.pl)+" ps="+a(t.ps)+" os="+a(t.os)+" fws="+t.fws+" fhs="+t.fhs+" frs="+t.frs+" abw="+(i.video.bw&&i.video.bw.abw||"N/A"))}),V.debug(r)}),r="[CallStatsHandlerUnified]: statsReport:\n",[C,E,T].forEach(function(n,e){switch(0=t.statObj.RecurrenceThreshold?t.reported?(delete n[e],V.debug("[CallStatsHandlerUnified]: issueCounter cleared=",e)):(t.reported=!0,t.counter=0,(r=r||{})[e]=!0):t.reported&&((r=r||{})[e]=!0)})}),r}this.start=function(){t||o||(V.debug("[CallStatsHandlerUnified]: Waiting to start collecting RTPstats"),t=window.setTimeout(function(){V.info("[CallStatsHandlerUnified]: Start collecting RTPStats"),t=null,a=0,w(),o=window.setInterval(function(){w()},Q.COLLECTION_INTERVAL)},Q.DELAY_UPON_ANSWER))},this.stop=function(){return function(){var e=g(!0);return t?(V.debug("[CallStatsHandlerUnified]: cancel collecting RTPStats "),window.clearTimeout(t),t=null):o&&(V.debug("[CallStatsHandlerUnified]: stop collecting RTPStats"),window.clearInterval(o),o=null,l&&V.debug("[CallStatsHandlerUnified]: savedRTPStats =",l),A.onThresholdExceeded&&A.onThresholdExceeded(!0),p=!1),e}()},this.onThresholdExceeded=null,this.onNoOutgoingPackets=null,this.onNetworkQuality=null,this.setOptions=function(e){e&&(c=e)},this.getLastSavedStats=function(){return l.channelInfo=s,l},this.setTransmitVideoParams=function(t){if((t=t||{}).mediaConstraints.hdVideo){var e=0,n=0;switch(t.mediaConstraints.videoResolution||B.VIDEO_1080){case B.VIDEO_1080:n=1920,e=1080;break;case B.VIDEO_720:n=1280,e=720;break;default:n=854,e=480}I.FRAME_RATE_SENT.Threshold=[20,8,3],I.FRAME_HEIGHT_SENT.Threshold=[.9*e,.75*e,.5*e],I.FRAME_WIDTH_SENT.Threshold=[.9*n,.75*n,.5*n],I.AVAIL_SEND_BW.Threshold=I.TRANSMIT_BIT_RATE.Threshold=[.9*(t.bitRates.maxBitRate||0)*1024,1024*(t.bitRates.minBitRate||0),1024*(t.bitRates.minBitRate&&t.bitRates.minBitRate-1||0)]}t.trackConstraints&&Object.keys(t.trackConstraints).forEach(function(e){t.trackConstraints[e].quality===W.VideoQuality.LOW&&(S[e]=!0)})}}return t.overridePromise=function(e){void 0===k&&(k=e)},H.CallStatsHandlerUnified=t,H}((Circuit=function(P){"use strict";var l,y=P.logger,i=P.Utils,b=P.Enums.RtpQualityLevel,e=i.isMobile(),U=Object.freeze({GOOG_JITTER_RECEIVED:{StatName:"jr",StatText:"googJitterReceived",Threshold:50,RecurrenceThreshold:e?2:3,reportIssues:!0},GOOG_RTT:{StatName:"rtt",StatText:"googRtt",Threshold:300,RecurrenceThreshold:e?2:3,reportIssues:!0},PACKET_LOSS_RECV:{StatName:"",StatText:"packetLossRecv",Threshold:.05,RecurrenceThreshold:e?2:3,reportIssues:!0},PACKET_LOSS_SEND:{StatName:"",StatText:"packetLossSend",Threshold:.05,RecurrenceThreshold:e?0:3,reportIssues:!0},NO_PACKETS_RECV:{StatName:"",StatText:"noPacketsReceived",Threshold:0,RecurrenceThreshold:e?2:3,reportIssues:!0},ECHO_LIKELIHOOD:{StatName:"ecmax",StatText:"googResidualEchoLikelihoodRecentMax",Threshold:.5,RecurrenceThreshold:e?2:3,reportIssues:!1}}),L=Object.freeze({GOOG_RTT:{StatName:"rtt",StatText:"googRtt",Threshold:300,RecurrenceThreshold:e?2:3},PACKET_LOSS_RECV:{StatName:"",StatText:"packetLossRecv",Threshold:.05,RecurrenceThreshold:e?2:3},PACKET_LOSS_SEND:{StatName:"",StatText:"packetLossSend",Threshold:.05,RecurrenceThreshold:e?0:3}}),M={COLLECTION_INTERVAL:5e3,DELAY_UPON_ANSWER:e?0:5e3,DELAY_RTT_PROCESSING:3},d=Object.freeze({audioOutputLevel:"aol",bytesReceived:"or",bytesSent:"os",googAvailableSendBandwidth:"abw",googResidualEchoLikelihoodRecentMax:"ecmax",googFrameHeightReceived:"fhr",googFrameHeightSent:"fhs",googFrameWidthReceived:"fwr",googFrameWidthSent:"fws",googFrameRateDecoded:"frd",googFrameRateSent:"frs",googFrameRateReceived:"frr",googJitterReceived:"jr",googRtt:"rtt",googTransmitBitrate:"tbr",packetsLost:"pl",packetsReceived:"pr",packetsSent:"ps"});void 0!==window.Promise&&(l=window.Promise);var u=i.getBrowserInfo();function C(e){switch(e){case"local":return"host";case"stun":case"serverreflexive":return"srflx";case"peerreflexive":return"prflx";case"relayed":return"relay";default:return e}}function E(e,n,i){var r;return e.a.some(function(e){if("candidate"===e.field&&e.value){var t=new P.IceCandidate(e.value);if(t.typ===i&&t["network-id"]===n["network-id"])return r=t.address,!0}return!1}),r}function T(e){var t=i.parseIpWithPort(e.stat("googLocalAddress"))||{},n=i.parseIpWithPort(e.stat("googRemoteAddress"))||{};return{ipl:t.ipAddress,ptl:t.port,ipr:n.ipAddress,ptr:n.port,lct:C(e.stat("googLocalCandidateType")),rct:C(e.stat("googRemoteCandidateType")),tt:e.stat("googTransportType")}}function o(e,t,r,n,i){if(!t||!r)return null;var o={startTime:e,pcType:n,audio:{},video:{}},a={audio:{},video:{}},s={},c=t.result?t.result():t;if(!Array.isArray(c))return null;if(c.forEach(function(t){if(t){var n=null;switch(t.type){case"googCandidatePair":"true"===t.stat("googActiveConnection")&&function(e,t,n,i){"Channel-audio-1"===e.stat("googChannelId")?(t.audio.rtt=parseInt(e.stat("googRtt"),10),i&&(n.audio.local=e.stat("localCandidateId"),u.firefox?n.audio.remote=e.stat("remoteCandidateId"):t.audio.channelInfo=T(e))):(t.video.rtt=parseInt(e.stat("googRtt"),10),i&&(n.video.local=e.stat("localCandidateId"),u.firefox?n.video.remote=e.stat("remoteCandidateId"):t.video.channelInfo=T(e)))}(t,o,a,i);break;case"ssrc":n=function(e,t){var n=null,i={id:e.id,ssrc:e.stat("ssrc"),timestamp:e.timestamp};return e.stat("audioInputLevel")?(t.audio.transmit||(t.audio.transmit=i),n=t.audio.transmit):e.stat("audioOutputLevel")?(t.audio.receive||(t.audio.receive=i),n=t.audio.receive):e.stat("googFrameHeightSent")?(t.video.transmit||(t.video.transmit=i),n=t.video.transmit):e.stat("googFrameHeightReceived")&&(t.video.receive||(t.video.receive=i),n=t.video.receive),n}(t,o);break;case"VideoBwe":o.video.bw||(o.video.bw={id:t.id}),n=o.video.bw;break;case"localcandidate":case"remotecandidate":s[t.id]=t}if(t.names&&n)(t.names()||[]).forEach(function(e){d[e]&&(n[d[e]]=parseFloat(t.stat(e)))}),n.en=t.stat("googCodecName")}}),i){var l;["audio","video"].forEach(function(e){var t=o[e]||{},n=s[a[e].local];if(n){if(!t.channelInfo){var i=s[a[e].remote];t.channelInfo=function(e,t){return{ipl:e&&e.stat("ipAddress"),ptl:e&&e.stat("portNumber"),ipr:t&&t.stat("ipAddress"),ptr:t&&t.stat("portNumber"),lct:e&&C(e.stat("candidateType")),rct:t&&C(t.stat("candidateType")),tt:e&&e.stat("transport")}}(n,i)}t.channelInfo.ni=n.stat("networkType"),l=l||P.sdpParser.parse(r.localDescription&&r.localDescription.sdp),t.channelInfo.candidate=function(i,e,t){var r,o,a={};if(!i||!e||!t)return a;var s=C(i.stat("candidateType"));return"prflx"===s?o=i.stat("ipAddress"):r=String(i.stat("portNumber")),("string"==typeof e?P.sdpParser.parse(e):e).m.some(function(n){return n.media===t&&(n.a.some(function(e){if("candidate"!==e.field)return!1;if(e.value){var t;if(r&&0<=e.value.indexOf(r)&&(t=new P.IceCandidate(e.value),String(t.port)===r&&s===t.typ))return a.value=e.value,"host"===s?(a.hAddr=i.stat("ipAddress"),a.sAddr=E(n,t,"srflx"),a.sAddr||(a.sAddr=a.hAddr)):(a.sAddr="srflx"===s?t.address:t.raddr,a.hAddr=E(n,t,"host"),"relay"===s&&(a.tt=t.getRelayClientTransportType())),!0;if(o&&0<=e.value.indexOf("srflx")&&"srflx"===(t=t||new P.IceCandidate(e.value)).typ&&String(t.address)===o)return a.sAddr=o,a.hAddr=E(n,t,"host"),!0}return!1}),!0)}),a}(n,l,e)}})}return o}function w(t,n,i,r){return t.getStats?t.getStats().catch(function(e){y.warn("[CallStatsHandler]: getStats["+n+"] failed with err = ",e)}).then(function(e){return e?e=o(i,e,t,n,r):y.warn("[CallStatsHandler]: getStats["+n+"] did not return a response"),e}):l.resolve()}function t(e){if(!Array.isArray(e))throw new Error("peerConnections must be an array");var t=6,u=20,r=e.filter(function(e){return e});if(!e.length)throw new Error("Cannot create CallStatsHandler object without at least one peer connection");var d,C,E,T,p,o,S={},n=null,i=null,I=0,A=[],R=[],f=[],v=[],_=[],g=this;function a(e){var n=[],i=!o;return o=o||i,r.forEach(function(t){t&&(e||"completed"===t.iceConnectionState||"connected"===t.iceConnectionState?(t.mainPeerConnection&&(n.push(w(t.mainPeerConnection,"AUDIO/VIDEO",t.startTime,i)),t.groupPeerConnections.forEach(function(e){n.push(w(e,"AUX_VIDEO",t.startTime,i))})),t.desktopPeerConnection&&n.push(w(t.desktopPeerConnection,"SCREEN_SHARE",t.startTime,i))):y.warn("[CallStatsHandler]: Do not collect stats. pc.iceConnectionState = ",t.iceConnectionState))}),new l(function(t){l.all(n).then(function(e){(e=e&&e.filter(function(e,t){return e&&(e.audio&&!e.audio.channelInfo&&R[t]&&(e.audio.channelInfo=R[t]),e.video&&!e.video.channelInfo&&f[t]&&(e.video.channelInfo=f[t])),e}))&&e.length?t(e):t()})})}function N(e,t){var n=0,i=0;return t&&(n=t.pl||0,i=t.ps||0),(e.pl-n)/(e.ps-i||-1)}function m(e,t){var n=0,i=0;return t&&(n=t.pl||0,i=t.pr||0),(e.pl-n)/(e.pr-i+e.pl-n||-1)}function h(e,t,n){var i=n+"Sum",r=n+"Count",o=n+"Max";t?(void 0!==t[i]?(e[i]=t[i]+(e[n]||0),++t[r],e[r]=t[r]):(e[i]=e[n]||0,e[r]=1),void 0!==t[o]?e[o]=Math.max(t[o],e[n]||0):e[o]=e[n]||0):(e[i]=e[o]=e[n]||0,e[r]=1)}function O(e,t,n,i,r,o){var a;t.reportIssues?a=e[t.StatText]||{}:a={counter:(e[t.StatText]||{}).counter};var s=t.StatText+"LastViStart",c=t.StatText+"Violations",l=t.StatText+"ViCounter";if(r[s]=o&&o[s],r[c]=o&&o[c],r[l]=o&&o[l]||0,-1===n){if(r[s]){var d=r[c];d=d?d+",":"",r[c]=d+"("+r[s]+","+parseInt((Date.now()-i)/1e3,10)+")",r[l]++,delete r[s]}a.reported?a.counter++:a.counter&&(delete e[t.StatText],y.debug("[CallStatsHandler]: issueCounter cleared=",t.StatText))}else a.reported?(a.counter=0,a.value=n):a.counter?(a.counter++,a.value=n):(e[t.StatText]={statObj:t,counter:1,value:n},r[l]s.audio.receive.pr)||-1,e.startTime,e.audio,s.audio);var c,l=U.GOOG_JITTER_RECEIVED;r&&(h(r,s.audio&&s.audio.receive,U.GOOG_JITTER_RECEIVED.StatName),O(o,l,(c=r[l.StatName])&&c>=l.Threshold?c:-1,e.startTime,e.audio,s.audio)),l=U.PACKET_LOSS_SEND,i&&i.pl&&i.ps&&O(o,l,(n=N(i,s.audio&&s.audio.transmit))>=l.Threshold?n:-1,e.startTime,e.audio,s.audio),l=U.PACKET_LOSS_RECV,r&&r.pl&&r.pr&&O(o,l,(n=m(r,s.audio&&s.audio.receive))>=l.Threshold?n:-1,e.startTime,e.audio,s.audio),e.audio&&M.DELAY_RTT_PROCESSING=l.Threshold?e.audio.rtt:-1,e.startTime,e.audio,s.audio)),l=U.ECHO_LIKELIHOOD,i&&(h(i,s.audio&&s.audio.transmit,U.ECHO_LIKELIHOOD.StatName),O(o,l,(c=i[l.StatName])&&c>=l.Threshold?c:-1,e.startTime,e.audio,s.audio)),i=e.video&&e.video.transmit,r=e.video&&e.video.receive,l=L.PACKET_LOSS_SEND,i&&i.pl&&i.ps&&O(a,l,(n=N(i,s.video&&s.video.transmit))>=l.Threshold?n:-1,e.startTime,e.video,s.video),l=L.PACKET_LOSS_RECV,r&&r.pl&&r.pr&&O(a,l,(n=m(r,s.video&&s.video.receive))>=l.Threshold?n:-1,e.startTime,e.video,s.video),(i||r)&&M.DELAY_RTT_PROCESSING=l.Threshold?e.video.rtt:-1,e.startTime,e.video,s.video)),e.audio&&e.audio.channelInfo&&(R[t]=e.audio.channelInfo),e.video&&e.video.channelInfo&&(f[t]=e.video.channelInfo),A[t]=e,v[t]=o,_[t]=a;var d=D(o),u=D(a);(d||u)&&(C=!0,p||(u=u||"none",p=!0,(d=d||"none").noPacketsReceived?y.warn("[CallStatsHandler]: processRTPStats - No packets received from remote peer"):(y.warn("[CallStatsHandler]: processRTPStats - Quality issues detected",[{audio:d},{video:u}]),g.onThresholdExceeded&&g.onThresholdExceeded())))}),!C&&p&&(y.debug("[CallStatsHandler]: processRTPStats - No quality issues detected. Clear threshold exceeded error."),p=!1,g.onThresholdExceeded&&g.onThresholdExceeded(!0)),!p&&I%t!=0||A.forEach(function(e,t){!function(e,t){var i,n,r;function o(e){return void 0===e||e<0?"n/a":e}e&&(e.audio||e.video)&&(i="[CallStatsHandler]: statsReport: audioRtt="+(e.audio&&e.audio.rtt||"n/a")+" videoRtt="+((e.video.receive||e.video.transmit)&&e.video&&e.video.rtt||"n/a"),e.audio&&((n=e.audio.receive)&&n.id&&(i+="\n audioReceive: id="+n.id+" pl="+o(n.pl)+" pr="+o(n.pr)+" or="+o(n.or)+" jr="+o(n.jr)),(n=e.audio.transmit)&&n.id&&(i+="\n audioTransmit: id="+n.id+" pl="+o(n.pl)+" ps="+o(n.ps)+" os="+o(n.os))),e.video&&((n=e.video.receive)&&n.id&&(i+="\n videoReceive: id="+n.id+" pl="+o(n.pl)+" pr="+o(n.pr)+" or="+o(n.or)+" fwr="+n.fwr+" fhr="+n.fhr+" frd="+n.frd+" frr="+n.frr),(n=e.video.transmit)&&n.id&&(i+="\n videoTransmit: id="+n.id+" pl="+o(n.pl)+" ps="+o(n.ps)+" os="+o(n.os)+" fws="+n.fws+" fhs="+n.fhs+" frs="+n.frs+" abw="+n.abw)),y.debug(i)),t&&t.length&&(i="[CallStatsHandler]: statsReport:\n",t.forEach(function(t,e){i+=0===e?" Audio issues=":"\n Video issues=";var n=Object.keys(t);n.length?(r=!0,n.forEach(function(e){i+=" "+e+"="+t[e].value+" count="+t[e].counter})):i+=" none"}),r&&y.info(i))}(e,[v[t],_[t]])}),I++}}function c(){P.isElectron&&y.debug("[CallStatsHandler]: Get RTP stats for local call(s)"),a().then(function(e){e?(P.isElectron&&y.debug("[CallStatsHandler]: Process RTP stats for local call(s)"),s(e),function(e){if(!e||!e.length)return y.debug("[CallStatsHandler]: processNetworkIndication - No stats for network indication.");E||(E=[],C=b.RTP_QUALITY_HIGH,T=!(d={noPacketsSeq:0,qualityLevelSeq:0}));e.forEach(function(e,t){var n=0,i=0,r=e.audio&&e.audio.transmit,o=e.audio&&e.audio.receive,a=!0,s=!0,c=E[t]||{};!r||isNaN(r.pl)||isNaN(r.ps)||(n=N(r,c.audio&&c.audio.transmit)||0,c.audio&&c.audio.transmit&&c.audio.transmit.ps&&(a=r.ps!==c.audio.transmit.ps),a||y.warn("[CallStatsHandler]: processNetworkIndication - No packets sent to remote peer")),!o||isNaN(o.pl)||isNaN(o.pr)||(i=m(o,c.audio&&c.audio.receive)||0,c.audio&&c.audio.receive&&c.audio.receive.pr&&(s=o.pr!==c.audio.receive.pr),s||S.sendOnlyStream||y.warn("[CallStatsHandler]: processNetworkIndication - No packets received from remote peer"));var l={currentPlSend:n,currentPlReceive:i};a?(d.noPacketsSeq=0,l.qualityLevel=b.getLevel(Math.max(n,i))):(d.noPacketsSeq++,1=t.statObj.RecurrenceThreshold?t.reported?(delete n[e],y.debug("[CallStatsHandler]: issueCounter cleared=",e)):(t.reported=!0,t.counter=0,(i=i||{})[e]=!0):t.reported&&((i=i||{})[e]=!0)}),i}this.start=function(){n||i?(y.debug("[CallStatsHandler]: Restart collecting RTPStats"),E=C=d=null,T=!1):(y.debug("[CallStatsHandler]: Waiting to start collecting RTPstats"),n=window.setTimeout(function(){y.info("[CallStatsHandler]: Start collecting RTPStats"),n=null,I=0,c(),i=window.setInterval(function(){c()},M.COLLECTION_INTERVAL)},M.DELAY_UPON_ANSWER))},this.stop=function(){return new l(function(t){a(!0).then(function(e){t(e)}),n?(y.debug("[CallStatsHandler]: cancel collecting RTPStats "),window.clearTimeout(n),n=null):i&&(y.debug("[CallStatsHandler]: stop collecting RTPStats"),window.clearInterval(i),E=C=d=i=null,T=!1,A&&y.debug("[CallStatsHandler]: savedRTPStats =",A),g.onThresholdExceeded&&g.onThresholdExceeded(!0),p=!1)})},this.onThresholdExceeded=null,this.onNoOutgoingPackets=null,this.onNetworkQuality=null,this.setOptions=function(e){e&&(S=e)},this.getLastSavedStats=function(){return A},this.setTransmitVideoParams=function(){}}return t.overridePromise=function(e){void 0===l&&(l=e)},P.CallStats=d,P.CallStatsHandler=t,P.RtpStatsConfig=M,P}((Circuit=function(d){"use strict";var u=d.AppMessagingHandlerSingleton,C=d.ChromeExtension,E=d.Constants,T=d.logger,p=d.Utils,S=d.TemasysAdapter,e=function(){var i=u?u.getInstance():null,e={getScreen:function(e,t){t&&t("NOT_SUPPORTED")},setControllingScreen:function(e,t){t&&t("NOT_SUPPORTED")},unregEvtHandlers:function(){},isScreensharingAvailable:function(){return!1},isFirefoxLegacy:function(){return!1},installExtension:function(){},injectExtensionSvc:function(){},injectTemasysSvc:function(){}},t=p.getBrowserInfo();function n(t,n){navigator.mediaDevices.getDisplayMedia({video:!0}).then(function(e){t({mediaStream:e})}).catch(function(e){"NotAllowedError"!==e.name?n(e):n(E.ReturnCode.CHOOSE_DESKTOP_MEDIA_CANCELLED)})}if(d.isElectron)e.getScreen=function(i,r,e){var t=require("electron").ipcRenderer;t.once("screenshare-chooser",function(e,t,n){"share"===t?(T.info("[ScreenSharingController]: Got screen share stream. Stream id: ",n.display.streamId),i&&i({screenIndex:n.display.screenIndex,streamId:n.display.streamId,pointer:n.pointer,screenControlSupported:n.screenControlSupported})):"cancel"===t&&(T.info("[ScreenSharingController]: User canceled screen share"),r&&r(E.ReturnCode.CHOOSE_DESKTOP_MEDIA_CANCELLED))}),T.info("[ScreenSharingController]: Request screen in Electron"),t.send("screenshare-chooser","open",e)},e.isScreensharingAvailable=function(){return!0},e.setControllingScreen=function(){require("electron").ipcRenderer.send("screenshare-chooser","setControllingScreen")};else if(d.isVdiApp)e.getScreen=function(t,n){i.sendInternalMessage({method:"showwindow"}),window.setTimeout(function(){chrome.desktopCapture.chooseDesktopMedia(["screen"],null,function(e){i.sendInternalMessage({method:"minimizewindow"}),e?t&&t({streamId:e}):n&&n(E.ReturnCode.CHOOSE_DESKTOP_MEDIA_CANCELLED)})},0)},e.isScreensharingAvailable=function(){return!0};else if(t.chrome)if(navigator.mediaDevices.getDisplayMedia)e.getScreen=n,e.isScreensharingAvailable=function(){return!0};else{var r,o,a,s=function(e){e&&e===o&&r&&o&&(r.removeEventListener(C.BgTarget.SCREEN_SHARE,o),o=null)},c=function(e,t){return r?(s(o),o=function(e,t,n){var i=n.data;switch(n.suppressLog||T.info("[ScreenSharingController]: Received screenshare event from extension - ",i.type),i.type){case C.BgScreenShareMsgType.CHOOSE_DESKTOP_MEDIA_DONE:T.info("[ScreenSharingController]: CHOOSE_DESKTOP_MEDIA done. Stream Id:",i.streamId),s(o),e&&e({streamId:i.streamId});break;case C.BgScreenShareMsgType.CHOOSE_DESKTOP_MEDIA_CANCELLED:T.info("[ScreenSharingController]: CHOOSE_DESKTOP_MEDIA cancelled"),s(o),t(E.ReturnCode.CHOOSE_DESKTOP_MEDIA_CANCELLED)}}.bind(null,e,t),r.addEventListener(C.BgTarget.SCREEN_SHARE,o),o):null};e.getScreen=function(e,t){var n=null;return a&&a.isExtensionRunning()?(n=c(e,t),r.getScreenShareUserMedia(function(e){e&&(T.warn("[ScreenSharingController]: Error starting screen share using chrome extension: ",e),s(n),t("res_AccessToExtensionFailed"))})):t("res_AccessToExtensionFailed"),n},e.isScreensharingAvailable=function(){return!!a&&a.isExtensionRunning()},e.installExtension=function(){a&&(T.debug("[ScreenSharingController]: Install Chrome extension"),a.installExtension(!0).then(function(){T.info("[ScreenSharingController]: Chrome extension was successfully installed")}).catch(function(e){T.warn("[ScreenSharingController]: Failed to install Chrome extension. ",e)}))},e.injectExtensionSvc=function(e,t){a=e,r=t},e.unregEvtHandlers=s}else if(t.msie){var l;e.getScreen=function(e,t){S&&S.isScreensharingAvailable()?e&&e():t&&t("NOT_AVAILABLE")},e.isScreensharingAvailable=function(){return!!S&&S.isScreensharingAvailable()},e.installExtension=function(){l&&l.showPopup()},e.injectTemasysSvc=function(e){l=e}}else t.firefox?(navigator.mediaDevices.getDisplayMedia?e.getScreen=n:(e.getScreen=function(e){e&&e()},e.isFirefoxLegacy=function(){return!0}),e.isScreensharingAvailable=function(){return!0}):"Android"!==window.navigator.platform&&"iOS"!==window.navigator.platform||(e.getScreen=function(e){e&&e()},e.isScreensharingAvailable=function(){return!0});return e}();return d.ScreenSharingController=e,d}((Circuit=function(w){"use strict";var G=w.logger,e=w.BaseCall,H=w.Enums.CallState,k=w.Constants,t=w.Enums.CstaCallState,V=w.Constants.IncomingVideoContentType,n=w.Enums.ParticipantState,F=w.Constants.RealtimeMediaType,B=w.Utils,i=Object.freeze({SERVER_ENDED_PRFX:"SERVER_ENDED:"}),r=Object.freeze({CLIENT_ENDED_PRFX:"CLIENT_ENDED:",ANOTHER_CLIENT_ANSWERED:"ANOTHER_CLIENT_ANSWERED",ANOTHER_CLIENT_REJECTED:"ANOTHER_CLIENT_REJECTED",ANOTHER_CLIENT_PULLED_CALL:"ANOTHER_CLIENT_PULLED_CALL",CALL_MOVED_TO_ANOTHER_CONV:"CALL_MOVED_TO_ANOTHER_CONV",CALLER_LEFT_CONFERENCE:"CALLER_LEFT_CONFERENCE",ENDED_BY_ANOTHER_USER:"ENDED_BY_ANOTHER_USER",LOST_WEBSOCKET_CONNECTION:"LOST_WEBSOCKET_CONNECTION",NO_USERS_LEFT:"NO_USERS_LEFT",REQUEST_TO_SERVER_FAILED:"REQUEST_TO_SERVER_FAILED",RTC_SESSION_START_FAILED:"RTC_SESSION_START_FAILED",SET_REMOTE_SDP_FAILED:"SET_REMOTE_SDP_FAILED",USER_ENDED:"USER_ENDED",LOST_MEDIA_STREAM:"LOST_MEDIA_STREAM",ICE_TIMED_OUT:"ICE_TIMED_OUT",USER_LOGGED_OUT:"USER_LOGGED_OUT",PAGE_UNLOADED:"PAGE_UNLOADED",DISCONNECTED:"WS_DISCONNECTED",FAILED_TO_SEND:"WS_FAILED_TO_SEND",REQUEST_TIMEOUT:"WS_REQUEST_TIMEOUT",MEDIA_RENEGOTIATION:"MEDIA_RENEGOTIATION"}),x=B.isMobile();function W(e,t){var o=w.WebRTCAdapter;t=t||{};var a=w.RtcSessionController;if(!e||!e.rtcSessionId)throw new Error("Cannot create LocalCall object without a valid conversation");W.parent.constructor.call(this,e,!1);var s=this,r=null,n=!1,i=null,c=!1,l=!1,d=!1,u=!1,C=!1,E=!1,T=!1,p=!1,S=null,I=null,A=null,R=null,f=!1,v=[],_=[],g=[],N="",m="",h=!1,O={},D=null;function P(){r?(G.debug("[LocalCall]: RtcSessionController - onMediaUpdate: callId =",s.callId),s.activeMediaType=r.getActiveMediaType(),G.debug("[LocalCall]: Set active media type to ",s.activeMediaType),s.localMediaType=r.getMediaConstraints(),G.debug("[LocalCall]: Set local media type to ",s.localMediaType),s.updateMediaType(),s.updateCallState(),L(F.VIDEO),L(F.DESKTOP_SHARING)):G.debug("[LocalCall]: session controller not available - onMediaUpdate: callId =",s.callId)}function y(e){G.debug("[LocalCall]: RtcSessionController - onLocalVideoStream: callId =",s.callId),s.localVideoStream=e.stream,s.localStreams.desktop=e.desktopStream,s.localStreams.video=e.videoStream,N="",G.debug("[LocalCall]: Set local video stream to ",e.videoStream&&e.videoStream.id||""),G.debug("[LocalCall]: Set local desktop stream to ",e.desktopStream&&e.desktopStream.id||"")}function b(e){G.debug("[LocalCall]: RtcSessionController - onScreenSharePointerStatus",e),s.pointer={isSupported:e.isSupported,isEnabled:e.isEnabled}}function U(e){G.debug("[LocalCall]: RtcSessionController - onRemoteStreams: callId =",s.callId),s.remoteAudioStream=e.audio&&e.audio.stream||null,m="",G.debug("[LocalCall]: Set remote audio stream to",s.remoteAudioStream&&s.remoteAudioStream.id||""),s.remoteVideoStreams=e.video||[],G.debug("[LocalCall]: Set remote video streams to",e.video||""),s.participants.forEach(function(e){s.setParticipantRemoteVideoStream(e)}),s.checkForActiveRemoteVideo()}function L(e){var t=r.getAvailableVideoReceivers(e),n=[],i=O[e]||[];t.forEach(function(t){var e=i.find(function(e){return e.id===t.id});e||((e=t).pinnedUser=null,e.quality=k.VideoQuality.NORMAL,e.disabled=!1),n.push(e)}),O[e]=n,G.debug("[LocalCall] Updated video receiver configuration for media type "+e+" is ",n)}function M(){var n=[];return Object.keys(O).forEach(function(e){var t=O[e];t&&((d||e===F.VIDEO&&u)&&(t=JSON.parse(JSON.stringify(t))).forEach(function(e){e.disabled=!0}),Array.prototype.push.apply(n,t))}),n}Object.defineProperties(this,{sessionCtrl:{get:function(){return r},enumerable:!0,configurable:!1},isVdi:{get:function(){return!(!r||!r.isRemoteController)},enumerable:!0,configurable:!1},locallyMuted:{get:function(){return!(!r||!r.isMuted())},enumerable:!0,configurable:!1},remoteVideoDisabled:{get:function(){return d},enumerable:!0,configurable:!1},remoteVideoScreenOnlyAllowed:{get:function(){return u},enumerable:!0,configurable:!1},remoteAudioDisabled:{get:function(){return C},enumerable:!0,configurable:!1},isMocked:{get:function(){return T},enumerable:!0,configurable:!1},isMeetingPointInvited:{get:function(){return p},enumerable:!0,configurable:!1},hasActiveRemoteScreenShareOnly:{get:function(){return l},enumerable:!0,configurable:!1},ringAllAllowed:{get:function(){return!!(this.peerUsers&&0this.RTP_QUALITY_LOW.threshold?this.RTP_QUALITY_LOW:e>this.RTP_QUALITY_MEDIUM.threshold?this.RTP_QUALITY_MEDIUM:this.RTP_QUALITY_HIGH}}),v=function(e){if(e)try{e.oninactive=null;var t=function(e){return"function"==typeof e.getTracks?e.getTracks():e.getAudioTracks().concat(e.getVideoTracks())}(e);t.length&&t[0].stop?t.forEach(function(e){e.stop(),R.debug("[WebRTCAdapter]: Media track has been stopped:",e.label)}):e.stop&&e.stop(),R.info("[WebRTCAdapter]: Media stream has been stopped. Stream ID:",e.id)}catch(e){R.error("[WebRTCAdapter]: Failed to stop media stream. ",e)}},_=function(e){if(e)try{var t=e.getVideoTracks();t?t.forEach(function(e){e.stop&&"video"===e.kind&&!e.remote&&e.stop()}):R.info("[WebRTCAdapter]: No video tracks to be changed")}catch(e){R.error("[WebRTCAdapter]: Failed to disable local video tracks. ",e)}},g=function(e){try{e.close(),R.debug("[WebRTCAdapter]: RTCPeerConnection has been closed")}catch(e){R.error(e)}},N=function(){return!!navigator.mediaDevices&&"function"==typeof navigator.mediaDevices.enumerateDevices&&"undefined"!=typeof HTMLMediaElement&&"function"==typeof HTMLMediaElement.prototype.setSinkId},l=[],d=null,u=null,m=function(e){if("function"==typeof e){var i,r,o;if(R.debug("[WebRTCAdapter]: Get audio output, microphone and camera devices"),!navigator.mediaDevices||!navigator.mediaDevices.enumerateDevices)return i=[{kind:"audio",id:"default",label:"",facing:""}],o=[{kind:"video",id:"default",label:"",facing:""}],void window.setTimeout(function(){e(i,o,null)},0);if(0Date.now())return R.debug("[WebRTCAdapter]: Return cached devices"),i=u.audioSources,r=u.audioOutputs,o=u.videoSources,void window.setTimeout(function(){e(i,o,r)},0);var t=function(t,n,i){a();var e=l;l=[],e.forEach(function(e){try{e(t||[],n||[],i||null)}catch(e){}})}.bind(null);l.push(e),R.debug("[WebRTCAdapter]: Invoke MediaDevices.enumerateDevices()"),a(),d=window.setTimeout(function(){d=null,l.length&&(u?(R.error("[WebRTCAdapter]: MediaDevices.enumerateDevices timed out. Return cached devices."),i=u.audioSources,r=u.audioOutputs,o=u.videoSources):R.error("[WebRTCAdapter]: MediaDevices.enumerateDevices timed out. Device cache is empty, no devices available!"),t(i,o,r),t=null)},3e3),navigator.mediaDevices.enumerateDevices().then(function(e){e=e||[],i=[],r=[],o=[],R.info("[WebRTCAdapter]: MediaDevices.enumerateDevices returned "+e.length+" device(s)"),e.forEach(function(e){var t={id:e.deviceId,groupId:e.groupId,kind:e.kind,label:e.label};if(t.label){var n=t.label.match(/(.*)\s\(.*:.*\)/);t.label=n&&n[1]||t.label}switch(I.isElectron&&("default"!==t.id||t.label||(t.label="res_DefaultDeviceLabel")),t.kind){case"audioinput":i.push(t);break;case"audiooutput":r.push(t);break;case"videoinput":o.push(t)}}),0!==r.length&&N()||(r=null),R.debug("[WebRTCAdapter]: Update DeviceInfos cache"),u={audioSources:i,audioOutputs:r,videoSources:o},i.length?!i.some(function(e){return e.label})||o.length&&!o.some(function(e){return e.label})?(R.debug("[WebRTCAdapter]: User hasn't authorized access to audio and/or video input devices yet"),u.validTimestamp=0):u.validTimestamp=Date.now()+6e4:u.validTimestamp=0,t&&t(i,o,r)}).catch(function(e){R.error("[WebRTCAdapter]: Failed to enumerate devices. ",e),t&&t()})}},h=function(){R.debug("[WebRTCAdapter]: Cleared device info cache"),u=null},O=function(e){if(e&&e.iceServers){var n=[];e.iceServers.forEach(function(t){t.url?n.push(t):t.urls&&t.urls.forEach(function(e){n.push({url:e,credential:t.credential,username:t.username})})}),e.iceServers=n}},D=function(e,t){var n=[{autoGainControl:!!(e=e||{}).enableAudioAGC},{echoCancellation:!0}];return t?{advanced:n}:{optional:n}},P=function(e){return{optional:[{echoCancellation:!0},{googEchoCancellation:!0},{googEchoCancellation2:!0},{autoGainControl:!!(e=e||{}).enableAudioAGC},{googAutoGainControl:!!e.enableAudioAGC},{googAutoGainControl2:!!e.enableAudioAGC},{noiseSuppression:!0},{googNoiseSuppression:!0},{googNoiseSuppression2:!0},{googHighpassFilter:!0}]}},y=function(e){if(e&&e.videoResolution){var t={aspectRatio:{min:1.77,max:1.78},frameRate:{min:24,max:30}};switch(e.minFrameRate&&(t.frameRate.min=Math.min(e.minFrameRate,t.frameRate.max)),e.videoResolution){case c.VIDEO_1080:t.width={min:1920},t.height={min:1080};break;case c.VIDEO_720:t.width={min:1280},t.height={min:720};break;case c.VIDEO_480:t.width={min:854},t.height={min:480}}return t}return{aspectRatio:{min:1.77,max:1.78}}},b=function(e){var t={mandatory:{minAspectRatio:1.77,maxAspectRatio:1.78},optional:[{googNoiseReduction:!0}]};if(e&&e.videoResolution)switch(t.mandatory.minFrameRate=24,t.mandatory.maxFrameRate=30,e.minFrameRate&&(t.mandatory.minFrameRate=Math.min(e.minFrameRate,t.mandatory.maxFrameRate)),e.videoResolution){case c.VIDEO_1080:t.mandatory.minWidth=1920,t.mandatory.maxWidth=1920,t.mandatory.minHeight=1080,t.mandatory.maxHeight=1080;break;case c.VIDEO_720:t.mandatory.minWidth=1280,t.mandatory.maxWidth=1280,t.mandatory.minHeight=720,t.mandatory.maxHeight=720;break;case c.VIDEO_480:t.mandatory.minWidth=854,t.mandatory.maxWidth=854,t.mandatory.minHeight=480,t.mandatory.maxHeight=480}return t},U=function(e,t){var n=e&&e.getAudioTracks();return!(!n||!n[0])&&(n[0].enabled=!!t,!0)},L=function(a,s,c){if(c=c||function(){},R.debug("[WebRTCAdapter]: Attach sinkId to audio element"),a)return s&&s.length?void(void 0!==a.sinkId&&I.WebRTCAdapter?(R.debug("[WebRTCAdapter]: Get media sources to find available device"),I.WebRTCAdapter.getMediaSources(function(e,t,n){var i=I.Utils.selectMediaDevice(n,s),r=i&&i.id||"";if(R.debug("[WebRTCAdapter]: Found audio output device to attach as sinkId. deviceId = ",r||"NONE"),a.sinkId===r)return R.debug("[WebRTCAdapter]: Audio output device is already attached to element"),void c();r||R.warn("[WebRTCAdapter]: A previously selected output device could not be found. Fallback to browser's default. Device not found: ",a.sinkId);var o=window.setTimeout(function(){o=null,R.error("[WebRTCAdapter]: Timed out attaching audio output device: ",r||""),c("timed out")},3e3);a.setSinkId(r).then(function(){o&&(window.clearTimeout(o),R.debug("[WebRTCAdapter]: Success, audio output device attached: ",r||""),c())}).catch(function(e){if(o){window.clearTimeout(o);var t=(e=e||{}).message||"unknown error";"SecurityError"===e.name&&(t="You need to use HTTPS for selecting audio output device."),R.error("[WebRTCAdapter]: Failed to attach output device. Device Id:"+r+" - ",t),c(t)}}),R.debug("[WebRTCAdapter]: setSinkId has been invoked")})):c("setSinkId not available")):(R.debug("[WebRTCAdapter]: There is no audio output device selected"),void c());c("Invalid parameters")},M=function(e){var t={offerToReceiveAudio:1,offerToReceiveVideo:1};return e&&(e.mandatory&&(e.mandatory.hasOwnProperty("OfferToReceiveAudio")&&(t.offerToReceiveAudio=e.mandatory.OfferToReceiveAudio?1:0),e.mandatory.hasOwnProperty("OfferToReceiveVideo")&&(t.offerToReceiveVideo=e.mandatory.OfferToReceiveVideo?1:0)),e.optional&&e.optional.some(function(e){return!!e.hasOwnProperty("VoiceActivityDetection")&&(t.voiceActivityDetection=!!e.VoiceActivityDetection,!0)})),t},w=function(r,o,a,s,c){function e(t){var e=function(e,t,n,i){if(!e||!e[t])return e;var r=e[t];if(r.mandatory){var o=r.mandatory[n];if(o){var a=(e=Object.create(e))[t];a.optional=a.optional||[];var s={};s[n]=o,a.optional.push(s),delete a.mandatory}}else{var c=r[i];c&&c.exact&&((e=Object.create(e))[t][i]=c.exact)}return e}(a,"audio","sourceId","deviceId");if(e!==a){R.warn("[WebRTCAdapter]: First getUserMedia attempt with required audio sourceId/deviceId failed. Falling back to optional.");var n=function(e){s(e,t)},i=r.apply(o,[e,n,c]);i&&i.then&&i.then(n).catch(c)}else c&&c(t)}var t=r.apply(o,[a,s,e]);t&&t.then&&t.then(s).catch(e)},G=function(t,n,i,r,o){var a=null,s=I.isElectron?1:3,c=0;function l(e){R.warn("[WebRTCAdapter]: Get user media failed: ",e&&e.name||e),a&&window.clearTimeout(a),a=null,o&&o(e),o=r=null}!function e(){R.info("[WebRTCAdapter]: Get user media attempt #:",c),a=null,c!==s?(++c,w(t,n,i,function(e,t){!function(e,t){R.info("[WebRTCAdapter]: Get user media succeeded"),r?r(e,t):v(e),o=r=null}(e,t),a&&window.clearTimeout(a),a=null},l),a=window.setTimeout(e,1e4)):l("Timeout")}()},H=function(e,t){if(e&&t&&t.isScreenControlled)if(R.info("[WebRTCAdapter]: Data channel will be created for supporting screen control"),t.isScreenOwner){var n=(new Date).toISOString(),i=t.screenControlChannelName+"_"+n,r=e.createDataChannel(i,o);s(r,!0),e.ondatachannel=null}else e.ondatachannel=function(e){s(e.channel,!1),this.dataChannel=e.channel,this.sendDataMessage=function(e){if(this.dataChannel&&"open"===this.dataChannel.readyState){var t;return e&&"object"==typeof e?(t=JSON.stringify(e),this.dataChannel.bufferedAmount+t.length=l&&(e+=d-(Date.now()-O[0])),c.info("[CONN]: Start throttle timeout with delay = ",e),P=window.setTimeout(function(){P=null,function(){c.info("[CONN]: Dequeue throttled messages. Number of queued messages = ",D.length),W();var e=0;for(;0=l&&W(),O.length=C?c.error("[CONN]: Throttling queue is full. Drop the message."):(D.push(e),c.info("[CONN]: Queued message #",D.length))}(e),Y())),!0):(c.error("[CONN]: Data is missing. Cannot send message."),!1)},this.injectHasActiveCall=function(e){y="function"==typeof e?e:null}},q.Enums=q.Enums||{},q.Enums.ConnectionState=X,q}((Circuit=function(e){"use strict";var n=e.Utils,i=Object.freeze({TLS:{name:"tls",start:0,end:11e6},TCP:{name:"tcp",start:12e6,end:31e6},UDP:{name:"udp",start:35e6,end:6e7}}),t=Object.freeze({VP8:"VP8",VP9:"VP9",H264:"H264"});function d(e){if(e){var t=(e=e.replace(/(a=)*candidate:([^\r]+)(\r\n)*/i,"$2")).split(" ");if(t.length<7)throw new Error("Invalid candidate: "+e);this.foundation=parseInt(t[0],10),this.componentId=parseInt(t[1],10),this.transport=t[2].toLowerCase(),this.priority=parseInt(t[3],10),this.address=t[4],this.port=parseInt(t[5],10),this.typ=t[7],this.optional=[];for(var n=8;n=e.start&&n<=e.end&&(t=e.name,!0)})}return t},d.prototype.getValue=function(){for(var e=this.foundation+" "+this.componentId+" "+this.transport+" "+this.priority+" "+this.address+" "+this.port+" typ "+this.typ,t=0;t|<]*(?:shortcut|abbr)="(\S*)"[^/?>]*\/?)>/gi;function n(e,t,n){var i=r.EMOTICON_MAPPING[n];return i?String.fromCodePoint(i):""}return r.standardizeEmoticon=function(e){return e?e.replace(t,n):""},r.removeMentionHtml=function(e){var i=0;return e.replace(/()|(<\/span>)/gi,function(e,t,n){return t?t.match(/class="mention"/i)?"":(i++,t):n&&i?(i--,n):""})},e}((Circuit=function(a){"use strict";a.__server="",a.__domain="",a.isElectron=!(a.isSDK||"undefined"==typeof process||!process.versions||!process.versions.electron);var t,c=a.logger,l=a.Emoticons,d=a.Emoji;if(a.isElectron){var e=(t=require("electron").remote).getCurrentWindow();a.__server=e._domain||"",a.__sotelUser=!!e._sotelUser,a.productName=e._productName||"Circuit",a.productBrand=e._productBrand||""}else a.productName="string"==typeof __productName?__productName:"Circuit",a.productBrand="string"==typeof __productBrand?__productBrand:"";"undefined"!=typeof Skype&&(a.SkypeSDK=Skype,Skype=null);var u="https://",C="circuit://",E=/<(img[^>|<]*(?:shortcut|abbr)="(\S*)"[^/?>]*\/?)>/gi,T=a.Utils||{};var n="(?:[\\w@'^=$%&\\/~+!\\(\\)\\{\\}\\-\\|.,?:\\[\\]#]*[\\w@'^=$%&\\/~+!\\(\\)\\{\\}\\-\\|#])?",i=["items","parents","peerUsers","previousMembers"];T.trimCallForMobile=function(e){var t;return e&&(t=T.flattenObj(e)),t},T.trimConvForMobile=function(e){var t;return e&&(t=T.flattenObj(e),i.forEach(function(e){delete t[e]}),t.call=T.trimCallForMobile(e.call)),t},T.isPromise=function(e){return!(!e||"function"!=typeof e.then)},T.convertVersionToNumber=function(e){if("string"!=typeof e)return 0;var t=e.split("."),n=parseInt(t[0],10)||0,i=parseInt(t[1],10)||0;i=Math.min(i,99);var r=parseInt(t[2],10)||0;return(r=Math.min(r,9999))+1e4*i+1e6*n},T.trimTextWithEmoticonsBeforeMatch=function(e,t,n){for(var i=e.indexOf(t),r=e.slice(i),o=e.slice(0,i),a=String.fromCharCode(17),s=String.fromCharCode(18),c=o.replace(E,function(e,t){return a+t+s}),l=!0,d=c.length-1,u=c.length-1,C=u;o.length-1-d<=n&&0<=u;)18===c.charCodeAt(u)?(c=c.replaceAt(u,">"),l=!1):17===c.charCodeAt(u)&&(c=c.replaceAt(u,"<"),l=!0),C=u,u--,l&&d--;return(o=0/i)||0<=e.search(/<[^>]*?style=[^>]*?mso-[^<]+?>/i)||0<=e.search(/]*?Microsoft/i)},T.isXCodeDoc=function(e){return 0<=e.search(/]*?Cocoa[^<]+?>/)},T.isYourCircuitDomain=function(){var e=a.isElectron?a.__server:window.location.host;return-1!==["eu.yourcircuit.com","na.yourcircuit.com"].indexOf(e)},T.isIntegrationsSupported=function(){var e=a.isElectron?a.__server.split(":")[0]:window.location.hostname;return["tandi.circuitsandbox.net","adfs01.circuitsandbox.net","circuitsandbox.net","beta.circuit.com","eu.yourcircuit.com","na.yourcircuit.com","circuitdev.unify.com"].includes(e)},T.sanitizer=null,T.sanitize=function(t){if(!t||!T.sanitizer)return t||"";try{t=(t=(t=(t=t.replace(/style="background-color: rgb\(212, 239, 181\);"/gi,'class="rich-text-highlight"')).replace(/<[^>]+background-color: rgb\(212, 239, 181\);.*?>/gi,function(e){return e.includes("class=")?e.replace(/class=".*?"/gi,function(e){return e.includes("rich-text-highlight")?e:e.replace(/[^=]\s*(.*)/gi,function(e){return e.slice(0,-1)+" rich-text-highlight"})}):e.replace(">",function(e){return' class="rich-text-highlight" '+e})})).replace(/]*class="(emoticon-icon|emojione-icon))[^>]*>/gi,"")).replace(/]*>([\s\S]*?)<\/title>/gi,""),t=(t=(t=(t=(t=l?l.normalizeEmoticonHtml(t):t).replace(/]*>|<\/font>/gi,"")).replace(/(<\s*hr\s*><\s*\/hr\s*>|<\s*hr\s*>)/gi,"
")).replace(/(\r|\n)+(?=[^<]*?>)/gi," ")).replace(/\r\n|\r|\n/g,"
"),"function"==typeof T.sanitizer&&(t=T.sanitizer(t));var e=t.split(/<\/?div.*?>|<\/?p.*?>/g).filter(function(e){return!!e}),n=e.length,i="";if(1(?![\s\S]*
)(?=(<[^/][^>]*><\/[^>]*>)*$|(<\/[^>]*>)*$|$)/i,s=0;s)|()|())*(
|)(<\/span>|<\/b>|<\/i>)*/g,"
"),!o||o.endsWith("")||o.endsWith("")||a.test(o)||(i+="
"),i+=r,o=r;else i=e[0];t=i}catch(e){return c.error("[Utils]: Error sanitizing content. ",e),c.error("[Utils]: Unexpected content: ",t),""}return t||""},T.sanitizeSymbols=function(e){return T.isMobile()&&"undefined"!=typeof he?e&&he.encode(e,{allowUnsafeSymbols:!0,decimal:!0}):e},T.convertSymbolCodes=function(e){return T.isMobile()?e&&e.replace(d.HTML_ENTITY_REGEX,function(e){return function(e){var t=e.replace(/[&#;]/g,"");if(!/^[0-9]+$/.test(t)||55296<=t&&t<=57343||1114111>>10&1023|55296),t=56320|1023&t),n+=String.fromCharCode(t)}(e)}):e},T.retrieveTextOnly=function(e,t){if(!e||"PLAIN"===t)return e;e=(e=(e=(e=(e=e.replace(Circuit.Emoticons.HTML_REGEX,"")).replace(/&#\d+;/g,"")).replace(/.*?>/g,"")).replace(T.URL_PATTERN,"")).replace(T.PSEUDO_URL_PATTERN,"");var n=document.createElement("div");return n.innerHTML=e.replace(/<(br[/]?|\/li|hr[/]?)>/gi," "),n.textContent.trim()},T.toPlainText=function(e,t){if(!e||t&&"RICH"!==t)return e;l&&(e=e.replace(l.HTML_REGEX,function(e,t){return l.isEmoticonContent(e)?t:e}));var n=document.createElement("div");return n.innerHTML=e.replace(/<(br[/]?|\/li|hr[/]?)>/gi," "),n.textContent},T.toPlainTextWithEmoticonHtml=function(e,t){if(!e||t&&"RICH"!==t)return e;var n=String.fromCharCode(17),i=String.fromCharCode(18);e=e.replace(l.HTML_REGEX,function(e,t){return l.isEmoticonContent(e)?n+t+i:e}),e=d.convertEmojis(e);var r=String.fromCharCode(19),o=String.fromCharCode(20);e=e.replace(d.HTML_REGEX,function(e,t){return d.isEmojiContent(e)?r+t+o:e});var a=document.createElement("div");a.innerHTML=e.replace(/<(br[/]?|\/li|hr[/]?)>/gi," ");var s=T.textToHtmlEscaped(a.textContent,!0);return(s=s.replace(/\x11([^\x11\x12]*)\x12/gim,function(e,t){return l.getHtmlFromShortcut(t,!1,!0,!0)})).replace(/\x13([^\x13\x14]*)\x14/gim,function(e,t){return d.convertEmojis(t.replace(/&/g,"&"))})},T.truncateFileName=function(e){return!e||e.length<=22?e:e.substring(0,10)+" ..."+e.substring(e.length-8,e.length)},T.convertItemText=function(e,t,n){return e?n?T.toPlainTextWithEmoticonHtml(e,t):T.toPlainText(e,t):""},T.createMentionedUsersArray=function(e,n){for(var t=[],i=//g,r=i.exec(e);null!==r;){var o=T.ABBR_PATTERN.exec(r[0]);o=o&&o[1],-1===t.indexOf(o)&&t.push(o),r=i.exec(e)}return n&&(t=t.filter(function(t){return n.some(function(e){return e.userId===t})})),t},T.DEFAULT_HELP_URL="https://www.circuit.com/support",T.DEFAULT_FAQ_URL="https://www.circuit.com/unifyportalfaqdetail",T.SEPARATORS_PATTERN="!-/:-@[-^{-~\\s",T.NUMERIC_PATTERN="^[0-9]*$",T.NUMERIC_SIGN_PATTERN="^[*+]?[0-9]*$",T.ALPHANUMERIC_PATTERN="^[a-zA-Z0-9_]*$",T.URL_SEPARATORS_PATTERN=/(?=[.,;!]?\s+|[.,;!]$)/,T.URL_PATTERN=new RegExp("(http|ftp|https|circuit):\\/\\/[\\w-]+?((\\.|:)[\\w-]+?)*?"+n,"gim"),T.EXACT_URL_PATTERN=new RegExp("^"+T.URL_PATTERN.source+"$","i"),T.PSEUDO_URL_PATTERN=new RegExp("www\\.+[\\w-]+?(\\.[\\w-]+?)+?"+n,"gim"),T.PROTOCOL_PATTERN=/^(?:http|https|ftp):\/\//,T.TABBABLE_ELEMENTS_PATTERN="a[href], area[href], input:not([disabled]):not([tabindex='-1']), button:not([disabled]):not([tabindex='-1']),select:not([disabled]):not([tabindex='-1']), textarea:not([disabled]):not([tabindex='-1']), iframe, object, embed, *[tabindex]:not([tabindex='-1']), *[contenteditable=true]",T.RICH_TEXT_LINK_CLASS="text-linkDarkGreen",T.ABBR_PATTERN=/abbr=["'](.*?)["']/,T.SPACE_HASHTAGS_PATTERN=/]*class=["']hashtag["'][^>]*>/gim,T.SPACE_HASHTAG_PATTERN=/^([a-zA-Z\u0080-\u009f\u00a1-\uffff0-9_]+)$/g,T.EMAIL_ADDRESS_INCLUDED_PATTERN=/[\w*+\-$?^{!#%&'/=`|}~]+?(?:\.[\w*+\-$?^{!#%&'/=`|}~]+?)*?@[a-z\d-]+?(?:\.[a-z\d-]{2,})+/gim,T.EMAIL_ADDRESS_PATTERN=new RegExp("^"+T.EMAIL_ADDRESS_INCLUDED_PATTERN.source+"$","i"),a.isElectron&&t&&(T.SSO_EMAIL_DOMAINS_MAPPING=t.getGlobal("constants").SSO_EMAIL_DOMAINS_MAPPING||[],T.SSO_PATTERN="[_a-z0-9-]+?@(("+T.SSO_EMAIL_DOMAINS_MAPPING.join(")|(")+"))",T.SSO_EMAIL_ADDRESS_PATTERN=new RegExp(T.SSO_PATTERN,"i")),T.CIRCUIT_CONVERSATION_HASH_PATTERN=/#\/(conversation|open|muted)\/[0-9\-a-z]+?(\?((user=(\d)+?)|(item=([0-9\-a-z])+?(&user=(\d)+?)?)))?$/gim,T.CIRCUIT_SPACE_HASH_PATTERN=/#\/space\/[0-9\-a-z]+?(\?topic=[0-9\-a-z]+?(&reply=[0-9\-a-z]+?)?)?$/gim,T.CIRCUIT_LINKS_HASH_PATTERN=/#\/(profile|phone|user|search)\/[0-9\-a-z]+?$/gim,T.CIRCUIT_HASH_TAG_SEARCH_PATTERN=/#\/search\/[a-zA-Z\u0080-\u009f\u00a1-\uffff0-9_]+/gim,T.CIRCUIT_EMAIL_HASH_PATTERN=new RegExp("#\\/email\\/"+T.EMAIL_ADDRESS_INCLUDED_PATTERN.source+"$","gim"),T.PHONE_PATTERN=/^(\+\s*)?\d+(\s*\(\s*\d+\s*\)\s*\d+)?((\s*-?\s*\d+)*|(\s*\.\s*\d+)*)$/,T.GNF_PHONE_PATTERN=/^((\+)|(\+\s*\d+(\s*\(\s*\d+\s*\)\s*\d+)?((\s*-?\s*\d+)*|(\s*\.\s*\d+)*)))$/,T.PHONE_PAC=/^([#*]+[#*()\-\s+\d]*)$/,T.PHONE_DIAL_PATTERN=/^([#*()\\/\-.\s+\d,]*)$/,T.PHONE_DIAL_WITH_PIN_PATTERN=/^([#*()\\/\-.\s+\d]*)(,+[,\d#*]+)$/,T.PHONE_WITH_EXTENSION_PATTERN=/^([#*()\\/\-.\s+\d]*)(\s*(x|X|ext\.)\s*\d+)$/,T.TIME_PATTERN=/^((([0-1]?[0-9]|2[0-3]):[0-5][0-9]\s*)|((0?[1-9]|1[0-2]):[0-5][0-9]\s*(PM|AM)))$/,T.IPV4_ADDRESS_PATTERN=/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/,T.TCP_PORT_NUMBERS_PATTERN=/^(0|([1-9]\d{0,3}|[1-5]\d{4}|[6][0-5][0-5]([0-2]\d|[3][0-5])))$/,T.FQDN_PATTERN=/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])$/,T.matchPhonePattern=function(e){return e&&"string"==typeof e?e.match(T.PHONE_PATTERN):null},T.matchUrlPattern=function(e){return e&&"string"==typeof e?e.match(T.URL_PATTERN)||e.match(T.PSEUDO_URL_PATTERN):null},T.matchEmailPattern=function(e){return e&&"string"==typeof e?e.match(T.EMAIL_ADDRESS_INCLUDED_PATTERN):null},T.getEmails=function(e){var t=e&&e.split(/[;,]\s*|\s+/i);return(t=t&&t.map(function(e){var t=e.match(T.EMAIL_ADDRESS_INCLUDED_PATTERN);return t&&t[0]}).filter(function(e){return!!e}))||[]},T.getTags=function(e){return e&&e.split(/[;,]\s*/i).reduce(function(e,t){var n=t.trim();return n.length&&e.push(n),e},[])},T.matchNames=function(e,t,n){if(!e||"string"!=typeof e||!t)return!1;var i=new RegExp("^"+RegExp.escape(t),n||"i");return i.test(e)||e.split(" ").some(function(e){return i.test(e)})},T.matchIpOrFqdnPattern=function(e){return e&&"string"==typeof e?e.match(T.IPV4_ADDRESS_PATTERN)||e.match(T.FQDN_PATTERN):null},T.compareStrings=function(e,t){return"string"==typeof e&&"string"==typeof t&&new RegExp("^"+RegExp.escape(e)+"$","i").test(t)},T.rstring=function(){return Math.floor(1e9*Math.random()).toString()},T.randomNumber=function(e,t){return Math.floor(Math.random()*(t-e+1))+e},T.randomBoolean=function(){return Math.random()<.5},T.createTransactionId=function(){for(var e=[],t="0123456789abcdef",n=0;n<36;n++)e[n]=t.substr(Math.floor(16*Math.random()),1);return e[14]="4",e[19]=t.substr(e[19]?3:8,1),e[8]=e[13]=e[18]=e[23]="-",e.join("")},T.getLegalRegion=function(e){switch(e){case"europe":var t=(navigator.language||navigator.browserLanguage).split("-");return"de"===T.lastArrayElement(t).toLowerCase()?"de":"uk";case"americas":case"apac":default:return"us"}},T.getBrowserInfo=function(){if("iOS"===window.navigator.platform)return{ios:!0,type:"ios"};if("Android"===window.navigator.platform)return{android:!0,type:"android"};if("node"===window.navigator.platform)return{node:!0,type:"node"};if(Circuit.isElectron)return{chrome:!0,type:"chrome",version:process.versions.chrome};if(window.cordova&&"ios"===window.cordova.platformId)return{cordovaios:!0,type:"cordovaios"};var e,t={},n=navigator.userAgent.toLowerCase(),i=/(msie|trident)(?: |.*rv:)([\d.]+)/.exec(n)||/(opera|opr)\/(?:.*version\/|)([\d.]+)/.exec(n)||/(firefox)\/([\d.]+)/.exec(n)||/(edge)\/([\d.]+)/.exec(n)||/(edg)\/([\d.]+)/.exec(n)||/(chrome)\/([\d.]+)/.exec(n)||/version\/([\d.]+).*(safari)/.exec(n)||/(phantomjs)\/([\d.]+)/.exec(n)||[],r=i[1]||"",o=i[2]||0;if("safari"===o)r=i[2],o=i[1];else switch(r){case"trident":r="msie";break;case"opr":r="opera";break;case"edg":r="chrome",e="edge"}return t[r]=!0,t.type=r,t.version=o,e&&(t.subType=e),t};var r=[{s:"Windows 10",r:/(Windows.* 10|Windows 10.0|Windows[ _]NT.* 10.0)/},{s:"Windows 8.1",r:/(Windows.* 8.1|Windows[ _]NT.* 6.3)/},{s:"Windows 8",r:/(Windows.* 8|Windows[ _]NT.* 6.2)/},{s:"Windows 7",r:/(Windows.* 7|Windows[ _]NT.* 6.1)/},{s:"Windows Vista",r:/(Windows.* Vista|Windows[ _]NT.* 6.0)/},{s:"Windows Server 2003",r:/(Windows Server 2003|Windows[ _]NT.* 5.2)/},{s:"Windows XP",r:/(Windows[ _]NT.* 5.1|Windows XP)/},{s:"Windows 2000",r:/(Windows[ _]NT.* 5.0|Windows 2000)/},{s:"Windows ME",r:/(Win 9x 4.90|Windows ME)/},{s:"Windows 98",r:/(Windows 98|Win98)/},{s:"Windows 95",r:/(Windows 95|Win95|Windows_95)/},{s:"Windows NT 4.0",r:/(Windows NT 4.0|WinNT4.0|WinNT|Windows NT)/},{s:"Windows CE",r:/Windows CE/},{s:"Windows 3.11",r:/Windows 3.11|Win16/},{s:"Android",r:/Android/},{s:"Open BSD",r:/Open BSD|OpenBSD/},{s:"Sun OS",r:/Sun OS|SunOS/},{s:"Linux",r:/(Linux|X11)/},{s:"iOS",r:/(iOS|iPhone|iPad|iPod)/},{s:"Mac OS X",r:/Mac OS X/},{s:"Mac OS",r:/(Mac OS|MacPPC|MacIntel|Mac_PowerPC|Macintosh|Darwin)/},{s:"QNX",r:/QNX/},{s:"UNIX",r:/UNIX/},{s:"BeOS",r:/BeOS/},{s:"OS/2",r:/OS\/2/},{s:"Search Bot",r:/(Search Bot|nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/}];function o(e){if(!e)return"";var t=document.createElement("div"),n=document.createElement("div");e=e.replace(/\$/gm,"$$$$");var i=0;return e=e.replace(/()|(<\/span>)/gi,function(e,t,n){return t?t.match(/class="mention"/i)?e.replace(/.*abbr="(.*?)".*?>/gi,''):t.match(/class="hashtag"/i)?e.replace(/.*abbr="(.*?)".*?>/gi,''):(i++,t):n?i?(i--,n):"":""}),T.isMobile()||(e=d.convertEmojis(e)),t.innerHTML=e,function e(t,n){if(!t||!t.childNodes||!t.childNodes.length)return t;var i;for(var r=0,o=t.childNodes.length;r";return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">").replace(/\r\n|\r|\n/gm,n)},T.escapedHtmlToText=function(e){return e?e.replace(/&/g,"&").replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/ /g," ").replace(//g,"\r\n"):""},T.stripParenthesis=function(e){for(var t=(e=e.trim()).match(/\(/g)||[],n=e.match(/\)/g)||[],i=0;"("===e[i];)i++;return e.slice(i,e.length-Math.abs(t.length-i-n.length))},T.linkifyText=function(e,t){t||(e=e.replace(/\xA0| |\x0A|\x0D/gim," "));for(var a=String.fromCharCode(17),s=String.fromCharCode(18),c=String.fromCharCode(19),n=function(e){var t="",n="",i=p(),r=T.getCircuitRelativeLink(i,e);if(!r){var o=!0;if((r=e).startsWith(C))new RegExp(i.replace(u,"")+"\\/guest\\?token=","i").exec(e)?r=e.replace(C,u):o=!1;else T.PROTOCOL_PATTERN.exec(e)||(r="http://"+r);t=o?" target="+c+"_blank"+c:"",n=" rel="+c+"noopener noreferrer"+c}return a+"a href="+c+r+c+t+n+s+e+a+"/a"+s},i=e.split(T.URL_SEPARATORS_PATTERN),r=0;r").replace(/\x13/gi,"'")},T.linkifyContent=function(e,t){if(!e)return"";return 5e4t.clientHeight}return!1},T.isDescendantOrEqual=function(e,t){if(e===t)return!0;for(var n=e;n;)if((n=n.parentElement)===t)return!0;return!1},T.isSupportedImage=function(e){return/^image\/(jpeg|gif|bmp|png)$/i.test(e)},T.isVideoSupportedByBrowser=function(e){return/^video\/(quicktime|mp4|webm)$/i.test(e)},T.shallowCopy=function(e){if(!e||"object"!=typeof e)return e;if(Array.isArray(e))return e.slice();var t=T.flattenObj(e),n={};for(var i in t)t.hasOwnProperty(i)&&(n[i]=t[i]);return n},T.normalizeLocaleProto=function(e){var t;return e&&5<=e.length&&(t=e.replace(/-/g,"_").toUpperCase()),t},T.normalizeLocale=function(e){var t;return e&&5<=e.length&&(t=e.substr(0,2).toLowerCase()+e.substr(2,e.length-2).replace(/_/g,"-")),t},T.getLocalTime=function(e){var t=new Date;return null==e||t.setTime(t.getTime()+60*(t.getTimezoneOffset()-e)*1e3),t.getTime()},T.delayOrTimestamp=function(e,t){return 0e.length&&t.startsWith(e)){var r=t.slice(e.length),o=r.match(T.CIRCUIT_CONVERSATION_HASH_PATTERN);return o?o[0].replace(/\/(muted|open)/gim,"/conversation"):(o=r.match(T.CIRCUIT_SPACE_HASH_PATTERN))?o[0]:(o=r.match(T.CIRCUIT_LINKS_HASH_PATTERN)||r.match(T.CIRCUIT_EMAIL_HASH_PATTERN)||r.match(T.CIRCUIT_HASH_TAG_SEARCH_PATTERN))&&o[0]}return""},T.isCircuitLink=function(e,t){return!!T.getCircuitRelativeLink(e,t)},T.throttle=function(n,i,r){var o,a,s,c=null,l=0;r=r||{};function d(){l=!1===r.leading?0:Date.now(),c=null,s=n.apply(o,a),o=a=null}return function(){var e=Date.now();l||!1!==r.leading||(l=e);var t=i-(e-l);return o=this,a=arguments,t<=0?(c&&(window.clearTimeout(c),c=null),l=e,s=n.apply(o,a),o=a=null):c||!1===r.trailing||(c=window.setTimeout(d,t)),s}},T.hasEmptyPrototype=function(e){return!(!e||"object"!=typeof e)&&T.isEmptyObject(Object.getPrototypeOf(e))},T.compareElements=function(e,t){if(e===t)return!0;if(!e||!t)return!1;if("object"!=typeof e||"object"!=typeof t)return!1;if(e instanceof Array&&t instanceof Array){if(e.length!==t.length)return!1;var i=t.slice();return e.every(function(n){return i.some(function(e,t){return!!T.compareElements(n,e)&&(i.splice(t,1),!0)})})}if(!T.hasEmptyPrototype(e)||!T.hasEmptyPrototype(t))return!1;for(var n in e)if(e.hasOwnProperty(n)&&0!==n.indexOf("$$")&&!T.compareElements(e[n],t[n]))return!1;return!0},T.copyToClipboard=function(e,t,n){var i,r,o,a,s;if(e)try{r=document.createRange(),i=window.getSelection(),a=document.body.style.overflow,s=this.getBrowserInfo().msie,o=n?document.createElement("textarea"):document.createElement("div"),n||(e=e.replace(/\r\n/gi,"
")),o.style.backgroundColor="#fff",o.style.font="normal normal 15px Calibri, sans-serif",o.style["white-space"]="pre-wrap",n?(o.value=e,o.setAttribute("readonly",""),o.style.position="absolute",o.style.left="-9999px",document.body.appendChild(o),i.removeAllRanges(),o.select(),o.setSelectionRange(0,e.length)):(o.innerHTML=e,document.body.appendChild(o),r.selectNode(o),i.removeAllRanges(),i.addRange(r)),s&&(document.body.style.overflow="hidden"),document.execCommand("copy")?t&&t():t&&t("Failed to copy")}catch(e){c.error("[Utils]: Copy to clipboard failed"),t&&t("Internal error")}finally{i&&("function"!=typeof i.removeRange||n?i.removeAllRanges():i.removeRange(r)),s&&(document.body.style.overflow=a),o&&document.body.removeChild(o)}},T.toCamelCase=function(e){if(!e||"string"!=typeof e)return"";for(var t=e.toLowerCase().split(/[_-]/),n=1;n=e.length||n<0||t===n)){for(var i=e.length;i<=n;i++)e.push(void 0);e.splice(n,0,e.splice(t,1)[0])}},T.emptyArray=function(e){if(e.length)for(;0>>0,r=arguments[1],o=0;o>>0,r=arguments[1],o=0;o]*)>([^;]*)((?:[^;]*;)*(?:displayNumber=(\d*)))?(?:;.*)*/,i=n.exec(e);i?(E.localUser.isOsBizCTIEnabled&&i[1]&&(i[1]=i[1].replace(/\/.*/,"")),t.fqn=i[1]||"",t.name=i[2]||"",t.dn=i[4]||i[1]||te):(i=(n=/N([^;]*)/).exec(e))?(t.fqn=i[1]||"",t.dn=i[1]||te):(t.fqn=e,t.dn=e)}return C.debug("[CstaSvc]: Retrieved partner display: ",t),t}function ge(e){ae();for(var t=u.getPhoneCalls(),n=[],i=0;i":r+=n?v.osmoFQN:v.osmoFQN+";epid="+v.epid;break;case ht.Cell:if(!v.cell)return C.error("[CstaSvc]: Cell phone is not configured"),null;r+=v.cell;break;case ht.Desk:r+=v.onsFQN,i&&v.osmoDeviceList&&(r="N<"+r+"/"+v.osmoDeviceList[0]+">");break;case ht.VM:r=v.vm;break;case ht.Other:t?r+=t:r=v.vm;break;default:return C.error("[CstaSvc]: Invalid target: "+e),null}return r}function be(e,t,n){return!(!E.localUser.isOsBizCTIEnabled||"connected"!==e||ve(t)!==ht.Desk||ve(n)!==ht.WebRTC)&&(C.debug("[CstaSvc]: DSS call move from desk to client"),!0)}function Ue(e){return Object.assign(v,o.getAtcRegistrationData()),!(!{subscriber:E.localUser.cstaNumber}.subscriber||!v)||(e&&e("There is no registered user."),!1)}function Le(i,r,e){var t=N.genCstaRequest(i);if(!t)return C.error("[CstaSvc]: Failed to build CSTA request: "+i.request),void(r&&r("Failed to send the request"));if(Y===ut.Registered){var n={content:{type:dt.CSTA,phoneNumber:E.localUser.cstaNumber,CSTA:t},destUserId:E.localUser.associatedTelephonyUserID};e&&(n.keysToOmitFromLogging=e.map(function(e){return"content.CSTA."+e})),_.sendAtcRequest(n,function(t,n){E.$apply(function(){if(t)C.warn("[CstaSvc]: ",t),r&&r(t);else{var e=N.parseResponse(i.request,n.CSTA);e||""===e?e.error?("Operation Error"===e.errorCategory&&"invalidConnectionID"===e.errorValue&&"busy"!==i.reason&&"AcceptCall"!==i.request&&"DeflectCall"!==i.request&&Oe(),r&&r(e.errorCategory+" - "+e.errorValue)):r&&r(null,e):r&&r("Failed to parse response from server")}})})}else r&&r("Client is not registered with ATC")}function Me(e,t){t.transferredCall&&!t.seamlessHandover&&(L[e]={newCallId:t.transferredCall.cID,failedCallId:function(e){var t,n=(parseInt(e.substring(0,2),16)+2).toString(16).toUpperCase(),i=e.substring(2);return t=n.length<2?"0"+n+i:n+i,C.debug("[CstaSvc]: FailedCallId to be tracked: "+t),t}(t.transferredCall.cID),timeout:d(function(){delete L[e]},n)})}function we(e,t){return!(!e||!Ue())&&((t===ht.Other||e.atcCallInfo.position!==t)&&(!!function(){var e=$e();v&&v.vm&&e.push(ht.VM);return e.push(ht.Other),e}().includes(t)||(C.error("[CstaSvc]: isTargetAllowed invoked with invalid target: "+t),!1)))}function Ge(){E.localUser.isOsBizCTIEnabled||(C.debug("[CstaSvc]: Synchronize the selected routing option"),f.updateRoutingOption(E.localUser.selectedRoutingOption))}function He(){var e=!w,t=!(!v||!v.cell);C.debug("[CstaSvc]: Publish /csta/deviceChange event. desk="+e+", cell="+t),T.publish("/csta/deviceChange")}function ke(){return E.localUser.isOsBizCTIEnabled?v.onsFQN:E.localUser.isOSV?Dt.normalizeDn(E.localUser.cstaNumber):E.localUser.cstaNumber}function Ve(e){var t=u.findOsBizFirstCall(),n=u.findOsBizSecondCall();if(t&&n){if(t.atcCallInfo.getCstaCallId()===e)return C.debug("[CstaSvc]: First local call with callId: ",e),C.debug("[CstaSvc]: Second local call with callId: ",n.atcCallInfo.getCstaCallId()),u.moveOsBizCalls(t,n),!0;if(n.atcCallInfo.getCstaCallId()===e)return C.debug("[CstaSvc]: Second local call with callId: ",e),C.debug("[CstaSvc]: First local call with callId: ",t.atcCallInfo.getCstaCallId()),u.moveOsBizCalls(n,t),!0}else if(!t&&!n){var i=le();if(i&&i.atcCallInfo&&i.atcCallInfo.getCstaCallId()===e){C.debug("[CstaSvc]: Remote call with callId: ",e);var r=Te();if(r){C.debug("[CstaSvc]: Second remote call with callId: ",r.atcCallInfo.getCstaCallId());var o=i.atcCallInfo;return i.atcCallInfo=r.atcCallInfo,i.setPeerUser(i.atcCallInfo.peerDn,i.atcCallInfo.peerName),r.atcCallInfo=o,delete P[i.atcCallInfo.getCstaCallId()],de((P[o.getCstaCallId()]=r).atcCallInfo.getCstaCallId()),!0}}}return!1}function Fe(t,n){return Object.values(P).some(function(e){return e.atcCallInfo.pickUp&&(E.localUser.isOSV?e.atcCallInfo.peerFQN===t:e.atcCallInfo.peerName===n)})}function Be(e){C.debug("[CstaSvc]: New pickup call for: ",e.calledDisplay.displayName);var t=Se(e.callId);t.atcCallInfo.pickUp=!0,t.atcCallInfo.setPosition(ht.Other),t.atcCallInfo.setPartnerDisplay(e.callingDisplay),P[e.callId]=t,e.event?(t.atcCallInfo.setServicesPermitted(e.event.servicesPermitted),t.atcCallInfo.setCstaConnection(e.event.connection)):e.callingUserId&&(t.pickupSession=e.callId,t.peerGtcUserId=e.callingUserId,t.setRedirectingUser(e.calledDisplay.dn,e.calledDisplay.fqn,e.calledDisplay.name,e.calledUserId,Nt.CallPickupNotification)),t.setCstaState(At.Ringing),t.direction=Tt.INCOMING,t.atcCallInfo.setOriginalPartnerDisplay(e.calledDisplay),ie(t,t.atcCallInfo.peerDn,t.atcCallInfo.peerFQN,t.atcCallInfo.peerName,function(){e.callingUserId?rt(t):re(t,e.calledDisplay.dn,e.calledDisplay.fqn,e.calledDisplay.name,Nt.CallPickupNotification,function(){rt(t)})})}function xe(e){var t,n,i=ge(e.connection.cID);if(i)i.direction===Tt.OUTGOING&&I.test(e.cause)?(re(i,(t=_e(e.divertingDevice)).dn,t.fqn,t.name,Nt.CallForward),n=_e(e.newDestination),i.setPeerUser(n.dn,n.name),i.atcCallInfo.setOriginalPartnerDisplay(t)):E.localUser.isOsBizCTIEnabled&&i.direction===Tt.INCOMING&&i.isOsBizSecondCall&&Re(e.divertingDevice)&&Ve(e.connection.cID)&&C.debug("[CstaSvc]: Second call was diverted and released");else if("distributed"===e.cause&&Re(e.divertingDevice)&&ve(e.newDestination)===ht.Desk)C.debug("[CstaSvc]: Ignore Diverted event with cause = distributed and newDestination = desk");else{if(i=P[e.connection.cID]){if(i.atcCallInfo.masterParallelHgCall)return void C.debug("[CstaSvc]: Ignore Diverted event for master parallel hunt group")}else i=Se(e.connection.cID);if("null"===e.localConnectionInfo&&Re(e.divertingDevice)){if(Re(e.newDestination)){if(Re(e.newDestination)&&(ve(e.newDestination)===ht.WebRTC&&(H={cID:e.connection.cID,dID:e.newDestination}),i)){if(i.pickupNotification)return;if("redirected"===e.cause&&e.lastRedirectionDevice&&!Re(e.lastRedirectionDevice)){var r=_e(e.lastRedirectionDevice);re(i,r.dn,r.fqn,r.name,Nt.CallForward),P[e.connection.cID]=i}if(E.localUser.isOsBizCTIEnabled&&"park"===e.cause&&ve(e.newDestination)!==ve(e.divertingDevice))return i.setRedirectionType(Nt.Dss),void(P[e.connection.cID]=i);if(i.forwarded)return;if(i.checkCstaState(At.Ringing)&&ve(e.newDestination)===i.atcCallInfo.getPosition())return C.debug("[CstaSvc]: new destination has the same position as the current alerting position. Ignore event"),void(H={});i.atcCallInfo.setIgnoreCall(!0),C.debug("[CstaSvc]: Publish /atccall/info event"),T.publish("/atccall/info",[i])}}else{if((function(e){return!!e&&_e(e).dn===v.vm}(e.newDestination)||ve(e.connection.dID)===ht.WebRTC||E.localUser.isOsBizCTIEnabled)&&i.atcCallInfo.setIgnoreCall(!0),i.setCstaState(At.Idle),i.direction=Tt.INCOMING,i.atcCallInfo.setMissedReason(_t.CANCELLED),I.test(e.cause)){P[e.connection.cID]=i;var o=_e(e.callingDevice);C.debug("[CstaSvc]: Update partner display to ",o),i.atcCallInfo.setPartnerDisplay(o),ie(i,i.atcCallInfo.peerDn,i.atcCallInfo.peerFQN,i.atcCallInfo.peerName)}C.debug("[CstaSvc]: Publish /atccall/info event"),T.publish("/atccall/info",[i])}i&&!i.isHandoverInProgress&&de(e.connection.cID)}else if(!Re(e.divertingDevice)&&i){var a=_e(e.divertingDevice);if(a&&i.atcCallInfo.setOriginalPartnerDisplay(a),i.direction===Tt.OUTGOING&&I.test(e.cause))return re(i,(t=_e(e.divertingDevice)).dn,t.fqn,t.name,Nt.CallForward),n=_e(e.newDestination),void i.setPeerUser(n.dn,n.name);i.atcCallInfo.setMissedReason(_t.CANCELLED),C.debug("[CstaSvc]: Publish /atccall/info event"),T.publish("/atccall/info",[i])}}}function We(e,t){k&&k.newCallId===t&&(e.direction=k.direction,e.setRedirectingUser(k.redirectingUser.phoneNumber,k.redirectingUser.fqNumber,k.redirectingUser.displayName,k.redirectingUser.userId,k.redirectingUser.redirectionType),e.atcCallInfo.transferCb=k.transferCb,delete k.transferCb,k={})}function Ye(e){return E.localUser.isOsBizCTIEnabled?{cID:e.getCstaCallId(),dID:v.onsFQN}:e.getCstaConnection()}function Ke(e){var t,n,i,r,o;if(Re(e.queue)){t=e.queuedConnection,n=e.callingDevice,C.debug("[CstaSvc]: LocalConnection: ",t),C.debug("[CstaSvc]: Partner Device ID: ",n),i=ve(t.dID,e.epid);var a=_e(n);if(r=t.cID,!(o=P[r])){if("noAvailableAgents"===e.cause)return void C.debug("[CstaSvc]: Cause=noAvailableAgents. Ignore Queued event");if(E.localUser.isOsBizCTIEnabled&&(!E.localUser.pbxCampOnSupported||!E.circuitLabs.OSBIZ_EXTENDED_TELEPHONY)&&("multipleQueuing"===e.cause||"keyOperation"===e.cause||"campOn"===e.cause))return void C.debug("[CstaSvc]: CampOn is not supported. Ignore this event.");o=Se(r),P[r]=o,C.debug("[CstaSvc]: Created new Remote Call object for callID= ",r)}if(o.atcCallInfo.setPosition(i),o.atcCallInfo.setPartnerDisplay(a),ie(o,o.atcCallInfo.peerDn,o.atcCallInfo.peerFQN,o.atcCallInfo.peerName),o.setCstaState(At.Parked),o.atcCallInfo.setCstaConnection(t),E.localUser.isOsBizCTIEnabled&&E.circuitLabs.OSBIZ_EXTENDED_TELEPHONY&&E.localUser.pbxCampOnSupported&&("campOn"===e.cause||"keyOperation"===e.cause))if(h&&i===ht.WebRTC){if(C.debug("[CstaSvc]: Cause=campOn. A local call is established and user receives new incoming call"),i===ht.WebRTC)return void Je(o,e.servicesPermitted)}else Object.values(P).find(function(e){return e.isEstablished})&&i===ht.Desk?(C.debug("[CstaSvc]: Cause=campOn. A remote call is established and user receives new incoming call"),m.call=o,C.debug("[CstaSvc]: Publish /conversation/update event. convId = ",m.convId),T.publish("/conversation/update",[m]),C.debug("[CstaSvc]: Publish /call/remote/incoming event"),T.publish("/call/remote/incoming",[o]),o.direction=Tt.INCOMING,o.setCstaState(At.Ringing)):D&&(C.debug("[CstaSvc]: Cause=campOn. A call is ringing and user receives new incoming call. Do not display yet."),o.setCstaState(At.Ringing),o.direction=Tt.INCOMING,o.atcCallInfo.setQueuedIncomingCall(!0))}else{if(!E.localUser.isOsBizCTIEnabled||!Re(e.callingDevice)||"campOn"!==e.cause)return void C.debug("[CstaSvc]: ONS DN is not the queue device. Ignore Queued event.");if(i=ve(e.callingDevice),r=e.queuedConnection.cID,!(o=i===ht.WebRTC?ge(r):P[r]))return void C.debug("[CstaSvc]: Call not found for callID= ",r);o.atcCallInfo.setOutgoingCallCampedOn(),o.isRemote&&o.checkCstaState(At.Busy)&&o.setCstaState(At.Delivered)}o.atcCallInfo.setServicesPermitted(e.servicesPermitted),C.debug("[CstaSvc]: Publish /atccall/info event"),T.publish("/atccall/info",[o])}function qe(e){var t,n,i,r=e.failedConnection.cID;if("fail"===e.localConnectionInfo&&Re(e.failingDevice)){if((t=P[r])&&t.atcCallInfo&&t.atcCallInfo.masterParallelHgCall)return void C.debug("[CstaSvc]: Ignore Failed event for master parallel hunt group");switch(Re(e.callingDevice)&&(n=_e(e.calledDevice)).dn!==te&&t&&!t.pickedUp&&n.fqn!==Dt.cleanPhoneNumber(t.atcCallInfo.peerFQN)&&(ie(t,n.dn,n.fqn,n.name),t.atcCallInfo.setPartnerDisplay(n)),e.cause){case"blocked":U[r]&&C.debug("[CstaSvc]: Received Failed event for transfer, waiting for ConnectionCleared event"),E.localUser.isOSV||(i=ve(e.failedConnection.dID),(t=i===ht.WebRTC?ge(r):P[r])&&t.isHandoverInProgress&&(C.debug("[CstaSvc]: Received Failed event from non OSV PBX while handover is in progress"),t.clearAtcHandoverInProgress(),C.debug("[CstaSvc]: Publish /atccall/moveFailed event"),T.publish("/atccall/moveFailed")),E.localUser.isOsBizCTIEnabled&&t&&t.isRemote&&t.atcCallInfo&&t.atcCallInfo.setServicesPermitted(e.servicesPermitted));break;case"doNotDisturb":(t=P[r])?(C.debug("[CstaSvc]: Publish /atccall/info event"),T.publish("/atccall/info",[t])):C.warn("[CstaSvc]: DND call does not exist. Ignore Failed event");break;case"reorderTone":(t=P[r])?(t.atcCallInfo.setMissedReason(_t.REORDER_TONE),C.debug("[CstaSvc]: Publish /atccall/info event"),T.publish("/atccall/info",[t])):C.warn("[CstaSvc]: Outgoing call failed with reorder tone");break;case"busy":(t=P[r])?(t.atcCallInfo.setMissedReason(_t.BUSY),t.checkCstaState(At.Offered)&&t.setCstaState(At.Failed),t.atcCallInfo.clearOutgoingCallCampedOn(),C.debug("[CstaSvc]: Publish /atccall/info event"),T.publish("/atccall/info",[t])):C.warn("[CstaSvc]: Busy call does not exist. Ignore Failed event");break;case"destNotObtainable":(t=ge(r)||P[r])&&d(function(){t.isPresent()&&function(e,t){var n=e.isOsBizSecondCall?u.findOsBizFirstCall():Te();if(e&&n&&Ue(t)){return Le({request:"ReconnectCall",heldCall:Ye(n.atcCallInfo),activeCall:Ye(e.atcCallInfo)},t)}t&&t()}(t)},R)}}else if("connected"===e.localConnectionInfo&&Re(e.callingDevice)){if((t=ge(r))&&t.atcCallInfo.getCstaCallId()===r||(t=P[r]),!t)return void C.warn("[CstaSvc]: Could not find call corresponding to handle FailedEvent Event.");switch(t.atcCallInfo.setServicesPermitted(e.servicesPermitted),(n=_e(e.failingDevice||e.calledDevice))&&(t.atcCallInfo.setPartnerDisplay(n),ie(t,t.atcCallInfo.peerDn,t.atcCallInfo.peerFQN,t.atcCallInfo.peerName)),e.cause){case"busy":t.isRemote&&(t.setCstaState(At.Busy),t.atcCallInfo.setMissedReason(_t.BUSY));break;case"reorderTone":t.atcCallInfo.setMissedReason(_t.REORDER_TONE);break;case"blocked":t.atcCallInfo.setMissedReason(_t.DECLINED);break;case"destOutOfOrder":t.atcCallInfo.setMissedReason(_t.DEST_OUT_OF_ORDER);break;default:t.atcCallInfo.setMissedReason(_t.DEFAULT)}C.debug("[CstaSvc]: Publish /atccall/info event"),T.publish("/atccall/info",[t])}}function je(e){if(Z)return C.warn("[CstaSvc]: Queue new forwarding request until loop detected timer expires"),void(ee=e);Date.now()-JPreferredDevice");var i={activateForward:n,forwardDN:e,forwardingType:"forwardNoAns"};f.setForwarding(i,t)},this.setRoutingOptionReroutingNumber=function(e,t){var n=!!(e=e||""),i={activateForward:n,forwardDN:e=n?"N<"+Dt.cleanPhoneNumber(e)+">PreferredDevice":"",forwardingType:"preferredDevice"};f.setForwarding(i,t)},this.getForwardingData=function(){return v.forwardList},this.getForwardingImmediate=function(){var e=v.forwardList.find(function(e){return Ne(e.forwardingType)&&e.forwardDN!==v.vm});return{status:!(!e||!e.forwardStatus),forwardDN:e&&e.forwardDN}},this.getForwardingVMStatus=function(){return v.forwardList.some(function(e){return Ne(e.forwardingType)&&e.forwardDN===v.vm&&e.forwardStatus})},this.setVoicemail=function(e,t,n){if(Ue(n))if(t=t||q,E.localUser.pbxCallForwardToVoiceMailSupported&&E.localUser.voicemailPBXEnabled)if(C.debug("[CstaSvc]: Set voice mail duration to: ",t),e!==E.localUser.voicemailActive||e&&q!==t){var i={request:"SetForwarding",device:ke(),voicemailActive:e,voicemailRingDuration:e?t:void 0};je(function(){Le(i,function(e){e?n&&n(e):(q=t,n&&n(null))})})}else n&&n(null);else n&&n("Cannot configure VM on PBX")},this.setRoutingTimers=function(t,n){if(Ue(n))if(E.localUser.ringDurationEnabled){if(C.debug("[CstaSvc]: Set routing timers to: ",t),j!==t.mainRingDuration||X!==t.cellRingDuration||Q!==t.clientRingDuration||!E.localUser.routeToCell){var e={request:"SetForwarding",device:ke(),mainRingDuration:t.mainRingDuration||void 0,clientRingDuration:t.clientRingDuration||void 0,cellRingDuration:t.cellRingDuration||void 0,routeToCell:!0};je(function(){Le(e,function(e){e?n&&n(e):(j=t.mainRingDuration||j,Q=t.clientRingDuration||Q,X=t.cellRingDuration||X,n&&n(null))})})}}else C.debug("[CstaSvc]: Cannot set routing timers"),n&&n("Cannot configure routing timers on PBX")},this.startCall=function(t,e,n,i){Ue(i)&&(t?E.localUser.isOsBizCTIEnabled&&t.isHolding()&&t.isRemote?v.supportedFeatures&&v.supportedFeatures.includes("zhOs")?(C.debug("[CstaSvc]: OSBiz supports exlussive hold for remote call. Send MakeCall"),f.makeCall(e,n,i)):f.retrieve(t,function(e){e?i&&i("res_MakeCallFailed"):f.consultationCall(t,n,i)}):f.consultationCall(t,n,i):f.makeCall(e,n,i))},this.getHuntGroupList=function(){return ne},this},st}((Circuit=function(vt){"use strict";var _t=vt.AtcCallInfo,gt=vt.Enums.AtcMessage,Nt=vt.BusyHandlingOptions,mt=vt.ClientApiHandlerSingleton,ht=vt.Constants,Ot=vt.DefaultAvatars,Dt=vt.Enums,Pt=vt.LocalCall,yt=vt.Proto,bt=vt.Enums.RedirectionTypes,Ut=vt.RemoteCall,Lt=vt.RoutingOptions,Mt=vt.RtcParticipant,wt=vt.RtcSessionController,Gt=vt.ScreenSharingController,Ht=vt.Enums.ScreenDisplayAction,kt=vt.Enums.ScreenFeaturesByPriority,Vt=vt.sdpParser,Ft=vt.UserToUserHandlerSingleton,Bt=vt.Utils,xt=vt.WebRTCAdapter,Wt=Object.values(vt.Enums.VideoResolutionLevel);return vt.CircuitCallControlSvcImpl=function(g,A,a,e,N,m,h,T,O,p,s,u){var c=vt.Conversation,l=vt.UserProfile;m.debug("New Service: CircuitCallControlSvc"),wt.isCMR=g.isCMR;var o=Bt.isMobile(),R=!!e.cordova,d=3200,t=6e4,E=2e3,C=5e3,S=500,f=this,D=mt.getInstance(),r=Ft.getInstance(),I=[],v=null,_=null,P=[],y=null,b=!1,U=!1,L={},M=[],w=null,n=!1,G=!1,H={},k=null,V=null,F=null,B=null,x=null,W=null;function Y(e){return O.getConversationAsGuestById(e)||O.getConversationFromCache(e)}function K(){if(V){var e=1e3*(V.ttl||0);e=Math.max(e-t,0),V.expirationTimestamp=Date.now()+e}}function q(e){if(e.audio=!!e.audio,e.video=!!e.video,e.desktop=!!e.desktop,g.isCMR)return e.hdVideo=e.video,e.minFrameRate=30,e.desktop=!1,void(e.hdDesktop=!1);if(e.video||(e.hdVideo=!1),e.desktop||(e.hdDesktop=!1),!vt.isSDK&&(e.video||e.hdDesktop)){var t=!(!o&&g.localUser.isICMixedUser&&!g.isICMode);e.video&&(e.hdVideo=!!(g.localUser.canUseHDVideo&&("boolean"==typeof e.hdVideo?e.hdVideo:t))),e.desktop&&(e.hdDesktop=!!(g.localUser.canUseHDScreenShare&&("boolean"==typeof e.hdDesktop?e.hdDesktop:t)))}}function j(o){return new N(function(n,i){var e=V&&V.expirationTimestamp||0;if(Date.now()=C)&&O.updateLastCallTime(r),ee(r)}w&&!v&&(a.cancel(w),w=null),n||(m.debug("[CircuitCallControlSvc]: Publish /call/ended event. Replaced=",i),h.publish("/call/ended",[e,i]),e.ratingEvent&&Qe(e.ratingEvent))}}function re(e){return v&&v.callId===e?v:_&&_.callId===e?_:null}function oe(e){var t;for(t=0;t(e.vrsOverloadLevel||0)&&(e.vrsOverloadLevel=n,m.debug("[CircuitCallControlSvc]: Publish /call/vrsOverloadLevelChanged event. userId =",t.userId+", level = "+n),h.publish("/call/vrsOverloadLevelChanged",[e,t]))}function He(n,i,e,t){var r=n.addParticipant(i,e,t);return r&&(Me(n,r),we(n,r),Ge(n,r),i.noData&&!i.reqPending&&(m.debug("[CircuitCallControlSvc]: Get user data for added participant. userId: ",i.userId),T.getUserById(i.userId,function(e,t){t&&(m.debug("[CircuitCallControlSvc]: Successfully retrieved participant data. userId: ",i.userId),n.isPresent()&&n.hasParticipant(i.userId)&&(i.firstName=t.firstName,i.lastName=t.lastName,i.displayName=t.displayName,m.debug("[CircuitCallControlSvc]: Publish /call/participant/updated event. userId =",i.userId),h.publish("/call/participant/updated",[n.callId,i])))}))),r}function ke(e,t,n){var i=e.updateParticipant(t,n);return i&&(Me(e,i),we(e,i),Ge(e,i)),i}function Ve(e,t,n){var i=Dt.ParticipantState.Terminated;switch(n){case ht.RTCSessionParticipantLeftCause.CONNECTION_LOST:case ht.RTCSessionParticipantLeftCause.STREAM_LOST:i=Dt.ParticipantState.ConnectionLost;break;case ht.RTCSessionParticipantLeftCause.REMOVED:i=Dt.ParticipantState.Removed;break;case ht.RTCSessionParticipantLeftCause.USER_LEFT_STAGE:i=Dt.ParticipantState.OffStage}e.setParticipantState(t,i);var r=e.removeParticipant(t);if(!e.hasOtherParticipants()){if(!e.conferenceCall)return m.debug("[CircuitCallControlSvc]: Publish /group/terminated event"),h.publish("/group/terminated",[e]),void ye(e,null,Dt.CallClientTerminatedReason.NO_USERS_LEFT,!0);e.setState(Dt.CallState.Waiting)}if(r){e.updateMediaType(),!e.isRemote&&r.isCMP&&r.isMeetingPointInvitee&&!X(e.participants)&&(e.setMeetingPointInviteState(!1),f.enableRemoteAudio(e.callId)),e.conferenceCall&&(m.debug("[CircuitCallControlSvc]: Publish /conference/participant/left event"),h.publish("/conference/participant/left",[e,n]));var o=n?{leftCause:n}:null;m.debug("[CircuitCallControlSvc]: Publish /call/participant/removed event"),h.publish("/call/participant/removed",[e.callId,r,o])}te(e)}function Fe(t,e){t&&e&&e.state&&e.state!==ht.RecordingInfoState.INITIAL&&(e.recordingMediaTypes&&e.recordingMediaTypes.includes(ht.RecordingMediaType.TEXT)&&(t.transcription.state=e.state,m.debug("[CircuitCallControlSvc]: Publish /call/transcription/info event"),h.publish("/call/transcription/info",[t])),e.recordingMediaTypes&&!e.recordingMediaTypes.includes(ht.RealtimeMediaType.AUDIO)&&!e.recordingMediaTypes.includes(ht.RealtimeMediaType.VIDEO)||(function(e,t){e.recordingMediaTypes=t.recordingMediaTypes,e.state!==t.state?(e.notifyByCurtain=t.state===ht.RecordingInfoState.START_PENDING||t.state===ht.RecordingInfoState.STARTED&&e.state===ht.RecordingInfoState.START_PENDING,e.notifyByUser=!e.notifyByCurtain||t.state===ht.RecordingInfoState.START_PENDING&&e.state!==ht.RecordingInfoState.STARTED):(e.notifyByCurtain=!1,e.notifyByUser=!1);e.state=t.state,e.duration=t.duration||e.duration,e.reason=t.reason,e.recordingUserId=null,e.recordingUser=null,t.state===ht.RecordingInfoState.STARTED&&(e.resumeTime=Date.now(),t.layout&&t.layout.layoutMapping&&t.layout.layoutMapping.length&&t.layout.layoutName===ht.RecordingVideoLayoutName.SINGLE_VIDEO&&(e.recordingUserId=t.layout.layoutMapping[0].tileContent));t.starter&&t.starter.userId&&t.starter.userId!==e.starter.userId&&(e.starter=t.starter,e.starter.userId===g.localUser.userId?e.starter.res="res_StartedRecording_You":(e.starter.name=e.starter.displayName,e.starter.res=e.starter.name?"res_StartedRecording_Other":"res_StartedRecording"))}(t.recording,e),t.recording.recordingUserId&&(t.recording.recordingUserId===g.localUser.userId?t.recording.recordingUser=g.localUser:t.participants.some(function(e){return e.userId===t.recording.recordingUserId&&(t.recording.recordingUser=e,!0)})),m.debug("[CircuitCallControlSvc]: Publish /call/recording/info event"),h.publish("/call/recording/info",[t])))}function Be(e){v&&void 0!==e&&v.attendeeCount!==e&&(v.attendeeCount=e,v.updateCallState(),m.debug("[CircuitCallControlSvc]: Publish /call/attendeeCountChanged"),h.publish("/call/attendeeCountChanged",[v.callId,v.attendeeCount]))}function xe(i,e){return new N(function(t,n){i&&!i.screenShareEventHandler?i.isVdi?t({}):(i.screenShareEventHandler=Gt.getScreen(function(e){A(function(){i.screenShareEventHandler=null,i.rejectGetScreenPromise=null,t(e||{})},0)},function(e){A(function(){i.screenShareEventHandler=null,i.rejectGetScreenPromise=null,e===ht.ReturnCode.CHOOSE_DESKTOP_MEDIA_CANCELLED?n(e):n("res_AccessToDesktopFailed")},0)},e),i.rejectGetScreenPromise=function(e){m.warn("[CircuitCallControlSvc]: Cancelling getScreen promise for call ID: ",i.callId),n(e)}):n("res_ErrorMsgInternal")})}function We(r){return new N(function(n,t){function i(){m.debug("[CircuitCallControlSvc]: Terminate ICE candidates collection test"),e.onSessionDescription=null,e.onRtcError=null,e.terminate()}var e=new wt({disableTrickleIce:!0,isDirectCall:!0,candidatesCollectionTest:!0});r&&(e.setTurnUris(r.turnServer),e.setTurnCredentials(r)),e.disableRemoteVideo(),e.onSessionDescription=function(e){var t=vt.sdpParser.getIceCandidates(e.sdp.sdp);m.debug("[CircuitCallControlSvc]: testIceCandidates - candidates: ",t),i(),n({turnServers:r&&r.turnServer||[],candidates:t})},e.onRtcError=function(e){m.error("[CircuitCallControlSvc]: Error collecting candidates. ",e.error),i(),t(e.error)},m.debug("[CircuitCallControlSvc]: testIceCandidates - Start collection"),e.start({audio:!1})})}function Ye(e,t){if(e&&e.replaces){var n=oe(e.replaces.callId);n&&(g.localUser.userId===n.screenOwnerId&&(e.restartScreenControlSession=!0,e.screenControllerId=n.screenControllerId),t&&ye(n,null,Dt.CallClientTerminatedReason.CALL_MOVED_TO_ANOTHER_CONV)),m.debug("[CircuitCallControlSvc]: Publish /call/moved event"),h.publish("/call/moved",[e.replaces.callId,e.callId]),e.replaces=null,te(e)}}function Ke(e){return!(!g.isCMR&&(e&&e.isDirect||Bt.isMobile()))}function qe(){return xt.unifiedPlanEnabled||"firefox"===xt.browser}function je(e){return!!Wt.includes(e)||(m.error("[CircuitCallControlSvc]: Invalid video resolution: ",e),!1)}function Qe(e){m.debug("[CircuitCallControlSvc]: Publish /call/showRatingDialog event"),h.publish("/call/showRatingDialog",[e])}function Xe(e,t){if(m.debug("[CircuitCallControlSvc]: handleRtcError: ",t.error),"res_RemoteControlSessionStopped"===t.error)return Ae(e.callId),void h.publish("/screenControl/terminated",[e]);(h.publish("/call/rtcError",[e,t.error]),e.checkState([Dt.CallState.Ringing,Dt.CallState.Answering]))?Pe(e,{type:!g.isCMR||"res_AccessToMediaInputDevicesFailed"!==t.error&&"res_AccessToAudioInputDeviceFailed"!==t.error?ht.InviteRejectCause.BUSY:ht.InviteRejectCause.TEMPORARILY_UNAVAILABLE}):e.sameAs(v)&&("res_CallMediaFailed"===t.error?(e.setDisconnectCause(ht.DisconnectCause.NEGOTIATION_FAILED),f.endCallWithCauseCode(e.callId,Dt.CallClientTerminatedReason.ICE_TIMED_OUT)):"res_CallMediaDisconnected"===t.error?(e.setDisconnectCause(ht.DisconnectCause.STREAM_LOST),f.endCallWithCauseCode(e.callId,Dt.CallClientTerminatedReason.LOST_MEDIA_STREAM),D.pingServer()):e.isEstablished()||f.endCall(e.callId))}function ze(e){var t=e&&e.sessionCtrl;t?(t.onIceCandidate=function(t,e){m.debug("[CircuitCallControlSvc]: RtcSessionController - onIceCandidate");var n={rtcSessionId:t.callId,userId:g.localUser.userId,origin:e.origin,candidates:e.candidates.map(JSON.stringify.bind(JSON))};e.isAudioVideo&&(t.sdpOrigin=e.origin);var i=u.createActionInfo(t,ht.RtcDiagnosticsAction.ICE_CANDIDATES);i&&(i.data=n.candidates,i.isEndOfCandidates=e.endOfCandidates);D.sendIceCandidates(n,function(e){u.finishActionInfo(t,i),e&&m.warn("Failed to send ICE candidate: ",e)})}.bind(null,e),t.onSdpConnected=function(t){m.debug("[CircuitCallControlSvc]: RtcSessionController - onSdpConnected"),g.$apply(function(){m.debug("[CircuitCallControlSvc]: Publish /call/sdpConnected event"),h.publish("/call/sdpConnected",[t]);var e=u.createActionInfo(t,ht.RtcDiagnosticsAction.SDP_CONNECTED);u.finishActionInfo(t,e),t.isTelephonyCall?(t.state.established||t.setState(Dt.CallState.Waiting),t.updateCallState()):t.setState(t.isDirect||t.hasOtherParticipants()?Dt.CallState.Active:Dt.CallState.Waiting),te(t),u.finishDeviceDiagnostics(t),u.sendCallConnected(t)})}.bind(null,e),t.onIceConnected=function(e,t){m.debug("[CircuitCallControlSvc]: RtcSessionController - onIceConnected. pcType:",t.pcType),g.$apply(function(){"audio/video"===t.pcType?(e.isEstablished()&&e.disconnectCause&&e.disconnectCause.cause===ht.DisconnectCause.STREAM_LOST&&(e.disconnectCause=null),ne(e,"connected")):"screen control"===t.pcType&&_e(e,e.screenOwnerId,e.screenControllerId,!0)})}.bind(null,e),t.onIceDisconnected=function(e,t){m.debug("[CircuitCallControlSvc]: RtcSessionController - onIceDisconnected. pcType:",t.pcType),g.$apply(function(){"audio/video"===t.pcType&&e.isEstablished()&&!e.isHeld()?(e.setDisconnectCause(ht.DisconnectCause.STREAM_LOST),ne(e,"disconnected")):"screen control"===t.pcType&&(Ne(e.callId),_e(e,null,null,!0))})}.bind(null,e),t.onRemoteVideoAdded=function(){m.debug("[CircuitCallControlSvc]: RtcSessionController - onRemoteVideoAdded")}.bind(null,e),t.onRemoteVideoRemoved=function(){m.debug("[CircuitCallControlSvc]: RtcSessionController - onRemoteVideoRemoved")}.bind(null,e),t.onRemoteStreamUpdated=function(e){m.debug("[CircuitCallControlSvc]: RtcSessionController - onRemoteStreamUpdated"),g.$apply(function(){m.debug("[CircuitCallControlSvc]: Publish /call/remoteStreamUpdated event"),h.publish("/call/remoteStreamUpdated",[e])})}.bind(null,e),t.onDTMFToneChange=function(e,t){m.debug("[CircuitCallControlSvc]: RtcSessionController - onDTMFToneChange"),g.$apply(function(){t.tone?(m.debug("[CircuitCallControlSvc]: Sent DTMF Digit"),h.publish("/call/singleDigitSent",[e,t.tone])):""===t.tone&&(m.info("[CircuitCallControlSvc]: Digits played completely"),h.publish("/call/digitsSent",[e]))})}.bind(null,e),t.onRtcError=function(e,t){g.$apply(function(){Xe(e,t)})}.bind(null,e),t.onRtcWarning=function(e,t){m.debug("[CircuitCallControlSvc]: RtcSessionController - onRtcWarning"),g.$apply(function(){h.publish("/call/rtcWarning",[e,t.warning])})}.bind(null,e),t.onLocalStreamEnded=function(t,e){m.debug("[CircuitCallControlSvc]: RtcSessionController - onStreamEnded"),e.isDesktop&&v.hasLocalScreenShare()?(m.debug("[CircuitCallControlSvc]: Screenshare stream ended, remove screenshare or terminate the call"),v.isEstablished()?f.removeScreenShare(v.callId):f.endCall(v.callId)):f.renegotiateMedia(t.callId,function(e){e&&g.$apply(function(){m.debug("[CircuitCallControlSvc]: Publish /call/localStreamEnded event"),h.publish("/call/localStreamEnded",[t])})})}.bind(null,e),t.onQosAvailable=function(e,t){m.debug("[CircuitCallControlSvc]: RtcSessionController - onQosAvailable"),t.renegotiationInProgress&&(e.terminateReason=Dt.CallClientTerminatedReason.MEDIA_RENEGOTIATION);if(e.sessionCtrl){if(e.qosSubmitted)return void m.info("[CircuitCallControlSvc]: QoS already submitted for call Id:",e.callId);s.sendQOSData(e,e.lastMediaType,t.qos,t.lastSavedStats,t.streamQualityData)}t.renegotiationInProgress&&(e.terminateReason=null,e.updateMediaDevices())}.bind(null,e),t.onStatsThresholdExceeded=function(e,t){n||(m.debug("[CircuitCallControlSvc]: RtcSessionController - onStatsThresholdExceeded. Cleared: ",!(!t||!t.cleared)),g.$apply(function(){t&&t.cleared?h.publish("/call/rtp/threshholdExceeded/cleared",[e.callId]):h.publish("/call/rtp/threshholdExceeded/detected",[e.callId])}))}.bind(null,e),t.onStatsNoOutgoingPackets=function(e){m.debug("[CircuitCallControlSvc]: RtcSessionController - onStatsNoOutgoingPackets. Publish /call/rtp/noOutgoingPackets event"),g.$apply(function(){h.publish("/call/rtp/noOutgoingPackets",[e.callId])})}.bind(null,e),t.onNetworkQuality=function(n,i){if(!i||!i.quality)return;g.$apply(function(){var e=null;if(xt.unifiedPlanEnabled)e=i.quality.level,n.networkQuality=e,m.debug("[CircuitCallControlSvc]: Publish /call/network/quality event for quality=",e);else{var t=i.quality;e={userId:g.localUser.userId,audio:{qualityLevel:t.qualityLevel.value,currentPlSend:t.currentPlSend,currentPlReceive:t.currentPlReceive,firstTimeLowQuality:t.firstTimeLowQuality}},m.debug("[CircuitCallControlSvc]: Publish legacy /call/network/quality event for quality=",e.audio.qualityLevel)}h.publish("/call/network/quality",[n.callId,e])})}.bind(null,e),t.onGetUserMediaException=function(e,t){m.debug("[CircuitCallControlSvc]: RtcSessionController - onGetUserMediaException. Publish /call/getUserMediaException event"),g.$apply(function(){h.publish("/call/getUserMediaException",[e,t.info])})}.bind(null,e)):m.error("[CircuitCallControlSvc]: Failed to get RtcSessionController for given call. ",e)}function Je(e){try{m.debug("[CircuitCallControlSvc]: Received RTCSession.ACTIVE_SPEAKER");var t=re(e.sessionId);if(!t)return void m.warn("[CircuitCallControlSvc]: Unexpected event. There is no local call");if(t.isDirect||t.participants.length<2)return void m.debug("[CircuitCallControlSvc]: Ignore RTC.ACTIVE_SPEAKER event for 1-2-1 calls");var n=[];if(e.first&&n.push(e.first),e.second&&n.push(e.second),e.third&&n.push(e.third),!t.setActiveSpeakers(n))return;m.debug("[CircuitCallControlSvc]: Publish /call/participants/activeSpeakers event"),h.publish("/call/participants/activeSpeakers",[t.callId,n])}catch(e){m.error("[CircuitCallControlSvc]: Exception handling RTC.ACTIVE_SPEAKER event. ",e)}}function $e(t){if(m.debug("[CircuitCallControlSvc]: Processing active session for convId = ",t.convId),t.participants&&0!==t.participants.length){var e=O.getConversationByRtcSession(t.rtcSessionId);if(e&&(e.hasJoined||e.isTemporary)&&(t.turnServers&&Ee(t.rtcSessionId,t.turnServers),!Ue(t.rtcSessionId))){var n,i=!1;if(t.participants.some(function(e){return e.userId===g.localUser.userId&&((n=e).clientId===D.clientId&&(i=!0),!0)}),e.call){var r=e.call;return r.isRemote&&e.isTemporary&&n?(e.call.setState(Dt.CallState.ActiveRemote),r.setActiveClient(n),Le(r),void(r.mediaType=yt.getMediaType(t.mediaTypes))):void m.debug("[CircuitCallControlSvc]: Conversation already has an associated call")}if(e.type!==ht.ConversationType.DIRECT||t.hosted||n){if(i){var o=function(e){e&&m.warn("[CircuitCallControlSvc] Lost session could not be terminated. Session Id=",t.rtcSessionId)},a={disconnectCause:ht.DisconnectCause.CONNECTION_LOST,disconnectReason:ht.DisconnectReason.CALL_LOST};if(e.type===ht.ConversationType.DIRECT)return void D.terminateRtcCall(t.rtcSessionId,a,o);D.leaveRtcCall(t.rtcSessionId,a,o)}me(e,n,t,t.rtcSessionId,function(e){n&&Ze(e,t)})}}}else m.warn("[CircuitCallControlSvc]: The active session does not have participants. rtcSessionId = ",t.rtcSessionId)}function Ze(t,e){t&&t.isTelephonyCall&&e&&e.participants&&e.participants.length<=2&&e.participants.some(function(e){return e.participantType===ht.RTCParticipantType.TELEPHONY&&(de(t,e.phoneNumber,null,e.userDisplayName),!0)})}function et(e){var t=!1;return re(e.rtcSessionId)&&e.participants&&(t=e.participants.some(function(e){return e.userId===g.localUser.userId&&e.clientId===D.clientId})),t}function tt(){return D.injectHasActiveCall(f.hasActiveCall),new N(function(s,c){G||g.isSessionGuest?(m.debug("[CircuitCallControlSvc]: Initialize active RTC sessions"),D.getActiveSessions(function(t,n){g.$apply(function(){t&&m.error("[CircuitCallControlSvc]: Error getting active sessions: ",t),n=n||[],Bt.emptyArray(P);for(var e=I.length-1;0<=e;e--)I[e].isRemote&&(I[e].guestToken?P.push(I[e]):ie(I[e]));var i=null,r=!1,o=!1,a=[];n.forEach(function(t){var n=re(t.rtcSessionId);if(n){if(et(t))return r=r||n===v,o=o||n===_,m.info("[CircuitCallControlSvc]: Found localCall in active sessions. Trigger media renegotiation."),void f.renegotiateMedia(n.callId,function(e){n.screenOwnerId===g.localUser.userId&&(e||t.screenOwnerId!==g.localUser.userId?(m.debug("[CircuitCallControlSvc]: There was a renegotiation error or remote control has been terminated on backend"),Ae(n.callId)):(m.debug("[CircuitCallControlSvc]: Starting a screen control session."),fe(n.callId,t.screenControllerId,function(e){e?m.error("[CircuitCallControlSvc]: Could not start the screen control session"):m.debug("[CircuitCallControlSvc]: Successfully started the screen control session.")}))),e?_e(n,null,null,!0):_e(n,t.screenOwnerId,t.screenControllerId,!0),h.publish("/call/sessionInitialized",[n])});ie(n,Dt.CallClientTerminatedReason.LOST_WEBSOCKET_CONNECTION)}(i=O.getConversationByRtcSession(t.rtcSessionId))&&i.hasJoined?$e(t):t.invitedGuests&&t.invitedGuests.includes(g.localUser.userId)?(m.info("[CircuitCallControlSvc]: Local user is invited as guest to this session"),a.push(O.createConversationAsGuestFromSummary(t.convId))):i||(m.info("[CircuitCallControlSvc]: Conversation associated with session is not cached. Need to get it."),a.push(O.getConversationPromise(t.convId)))}),h.publish("/activeSessions/received"),_&&!o&&ie(_,Dt.CallClientTerminatedReason.LOST_WEBSOCKET_CONNECTION),v&&!r&&ie(v,Dt.CallClientTerminatedReason.LOST_WEBSOCKET_CONNECTION),0t){c.warn("[DeviceDiagnosticSvc]: Stored device diagnostics exceeded max size. Discard old data.");var i="",r=n.length-a;d.some(function(e,t){return(i+=JSON.stringify(e)).length>r&&(c.warn("[DeviceDiagnosticSvc]: Number of discarded records: ",t+1),d.splice(0,t+1),n=JSON.stringify(d),!0)})}o.setString(o.keys.RTC_CLIENT_INFOS,n)}else o.removeItem(o.keys.RTC_CLIENT_INFOS)}function E(e){e&&e.joinDelayTimer&&(n.cancel(e.joinDelayTimer),e.joinDelayTimer=null)}function C(e){return!(!e||!e.deviceDiagnostics)&&(e.deviceDiagnostics.data.actionInfo.some(function(e){return!e.complete})||!e.deviceDiagnostics.iceGatheringFinished)}function T(e){if(e&&e.deviceDiagnostics){c.debug("[DeviceDiagnosticSvc]: Force finish device diagnostics");var t=e.deviceDiagnostics;E(t),t.joinDelayed&&I(e),p(e)}}function p(e){e&&e.deviceDiagnostics&&(c.debug("[DeviceDiagnosticSvc]: Clear device diagnostics"),E(e.deviceDiagnostics),delete e.deviceDiagnostics)}function S(e){u&&(c.debug("[DeviceDiagnosticSvc]: Store device diagnostics to send when client reconnects"),d.push(e),r())}function I(e){if(e&&e.deviceDiagnostics){var t={sdpOrigin:e.sdpOrigin||null,userId:s.localUser.userId,convId:e.convId,clientInfoType:f.RtcClientInfoType.DEVICE_DIAGNOSTICS,reason:f.RtcClientInfoReason.JOIN_DELAY,timestamp:Date.now(),sessionId:e.callId,deviceDiagnostics:_.shallowCopy(e.deviceDiagnostics.data)};e.instanceId&&(t.instanceId=e.instanceId),p(e),c.debug("[DeviceDiagnosticSvc]: Sending device diagnostics..."),l.sendClientInfo([t],function(e){e&&(c.debug("[DeviceDiagnosticSvc]: Failed to send device diagnostics. ",e),v.isOfflineFailure(e)&&S(t))})}else c.debug("[DeviceDiagnosticSvc]: sendDeviceDiagnostics - Nothing to send")}function A(e){if(!e||!e.label||"string"!=typeof e.label)return"";var t=e.label;return t.startsWith("res_")?s.i18n.localize(t)||"":t}return u&&e.subscribe("/conversations/loadComplete",function(){c.debug("[DeviceDiagnosticSvc]: Received /conversations/loadComplete event"),function(){if(0=S)||a.warn("[ExtensionSvc]: The installed extension version ("+v+") is not supported. Minimum version is "+t)),_&&(i.isBrowserExtRunning=!0,a.setExtensionVersion(v),a.debug("[ExtensionSvc]: Publish /chromeExt/initialized event"),s.publish("/chromeExt/initialized"))})}),f.addEventListener("extensionUnregistered",function(){i.$apply(function(){i.isBrowserExtRunning=!1,a.debug("[ExtensionSvc]: Publish /chromeExt/unregistered event"),s.publish("/chromeExt/unregistered")})});var O=function(t,n){i.$apply(function(){var e=n.data&&n.data.data;a.debug("[ExtensionSvc]: Publish "+t+" event: ",e),s.publish(t,[e])})};f.addEventListener("headsetAppLaunched",O.bind(null,"/chromeExt/headsetAppLaunched")),f.addEventListener("headsetAppUninstalled",O.bind(null,"/chromeExt/headsetAppUninstalled")),f.addEventListener("webRTCIPHandlingPolicyChanged",O.bind(null,"/chromeExt/webRTCIPHandlingPolicyChanged"))}return this.isExtensionRunning=function(){return f&&f.isExtensionRunning()&&_},this.getExtensionVersion=function(){return v},this.isExtensionVersionSupported=function(){return _},this.installExtension=function(i){return new e(function(e,t){if(R.isExtensionRunning())e();else{if(!c)return a.error("[ExtensionSvc]: installExtension API requires PopupSvc"),void t(A.INTERNAL_ERROR);var n=h(i);if(n)t(n);else{c.confirm({message:"res_ActionInstallExtensionText",title:"res_ActionInstallExtensionTitle",yesLabel:"res_ActionInstall",noLabel:"res_Close",backdrop:!0}).result.then(function(){R.inlineInstallation(i).then(e).catch(t)}).catch(function(){t(A.USER_CANCELLED_INSTALL)})}}})},this.inlineInstallation=function(r){return new e(function(e,t){var n=h(r);if(n)t(n);else{var i=N();a.debug("[ExtensionSvc]: Open store link for ",i),o.open(i),e()}})},this.addEventListener=function(e,t){f&&f.addEventListener(e,t)},this.exchangeGetConnectionStatus=function(e,t){return m("exchangeGetConnectionStatus",[e],t)},this.exchangeConnect=function(e,t){return m("exchangeConnect",[e],t)},this.exchangeSearchContacts=function(e,t,n,i){return m("exchangeSearchContacts",[e,t,n],i)},this.exchangeGetCapabilities=function(e){return m("exchangeGetCapabilities",[],e)},this.exchangeAutodiscoverGetServer=function(e,t){return m("exchangeAutodiscoverGetServer",[e],t)},this.exchangeResolveContact=function(e,t,n){return m("exchangeResolveContact",[e,t],n)},this.exchangeGetContact=function(e,t,n){return m("exchangeGetContact",[e,t],n)},this.exchangeDisconnect=function(e){return m("exchangeDisconnect",[],e)},this.exchangeOnRenewedToken=function(e,t,n,i){return m("exchangeOnRenewedToken",[e,t,n],i)},this.storeExchCredentials=function(e,t){return m("exchangeStoreCredentials",[e],t)},this.getStoredCredentials=function(e,t){return m("getStoredCredentials",[e],t)},this.getAllPersonalContacts=function(e,t){return m("getAllPersonalContacts",[e],t)},this.syncAllPersonalContacts=function(e,t,n){return m("syncAllPersonalContacts",[e,t],n)},this.exchangeCancelReqCallback=function(e){return m("exchangeCancelReqCallback",[e])},this.getAppointments=function(e,t,n,i,r){return m("getAppointments",[e,t,n,i],r)},this.supportsGetAppointments=function(){return!(!i.localUser||!i.localUser.msExchangeEnabled)&&(!!R.isExtensionRunning()||!(!i.browser||!i.browser.chrome))},this.supportsExchangeAutodiscover=function(){return R.isExtensionRunning()},this.supportsExchangeAutodiscoverSvc=function(){return R.isExtensionRunning()},this.supportsExchangeAutodiscoverGetServer=function(){return v===I||1023300<=U.convertVersionToNumber(v)},this.supportsOOO=function(){return v===I||1022800<=U.convertVersionToNumber(v)},this.supportsUserAvailability=function(){return v===I||1025800<=U.convertVersionToNumber(v)},this.getOooMsg=function(e,t,n,i){R.supportsOOO()||i&&i(null,{response:P.ExchangeConnResponse.UNSUPPORTED_METHOD}),m("getOooMsg",[e,t,n],i)},this.getUserAvailability=function(e,t,n){R.supportsUserAvailability()||n&&n(null,{response:P.ExchangeConnResponse.UNSUPPORTED_METHOD}),m("getUserAvailability",[e,t],n)},this.launchHeadsetIntegrationApp=function(e,t,n){return m("launchHeadsetIntegrationApp",[e,t],n)},this.getHeadsetIntegrationAppStatus=function(e,t){return m("getHeadsetIntegrationAppStatus",[e],t)},this.restartHeadsetApp=function(e,t){return m("restartHeadsetApp",[e],t)},this.supportsPolicySettings=function(){return v===I||1023300<=U.convertVersionToNumber(v)},this.setIPHandlingPolicy=function(e,t,n){D.isElectron?(g.send("set-ip-handling-policy",e),n&&n(null)):m("setIPHandlingPolicy",[e,t],n)},this.getIPHandlingPolicy=function(n){"function"==typeof n&&(D.isElectron?(g.send("get-ip-handling-policy"),g.once("get-ip-handling-policy-response",function(e,t){i.$apply(function(){n(null,{value:t||null})})})):m("getIPHandlingPolicy",[],n))},this.bringToFront=function(e){D.isElectron?g.send("focus-window"):m("bringToFront",[],e)},this.getFileFromExtension=function(e,t,n){return m("getFile",[e,t],n)},i.isBrowserExtRunning=R.isExtensionRunning(),this},D}((Circuit=function(e){"use strict";var u=e.BaseCall,E=e.Utils;return e.PubSubSvcImpl=function(n){n.debug("New Service: PubSubSvc");var i={},r={},o={},a=[];function s(e,t){try{null==t?t=[]:Array.isArray(t)||(t=[t]),e.apply(null,t)}catch(e){n.error(e)}}function c(e,t,n){e[t]&&e[t].slice(0).forEach(function(e){s(e,n)})}function l(e,t,n){e[t]?e[t].includes(n)||e[t].push(n):e[t]=[n]}function d(e,t,n){if(e[t]){var i=e[t].indexOf(n);0<=i&&e[t].splice(i,1)}}return this.publish=function(e,t){(i[e]||r[e]||o[e]||a.length)&&(n.debug("[PubSubSvc]: Publishing "+e+" event"),c(i,e,t),function(e,t){r[e]&&(null==t?t=[]:Array.isArray(t)||(t=[t]),t=t.map(function(e){if(e&&"object"==typeof e){if(e.isConversationObject)return E.trimConvForMobile(e);if(e instanceof u)return E.trimCallForMobile(e)}return e}),r[e].slice(0).forEach(function(e){s(e,t)}))}(e,t),c(o,e,t),function(e,t){(t=t?Array.prototype.slice.call(t):[]).unshift(e),a.slice(0).forEach(function(e){s(e,t)})}(e,t),delete o[e])},this.subscribe=function(e,t){l(i,e,t)},this.unsubscribe=function(e,t){d(i,e,t)},this.subscribeOnce=function(e,t){l(o,e,t)},this.unsubscribeOnce=function(e,t){d(o,e,t)},this.subscribeMobile=function(e,t){l(r,e,t)},this.unsubscribeMobile=function(e,t){d(r,e,t)},this.subscribeAll=function(e){!function(e){a.includes(e)||a.push(e)}(e)},this.unsubscribeAll=function(e){!function(e){var t=a.indexOf(e);0<=t&&a.splice(t,1)}(e)},this.resetSubscriptions=function(){i={},r={},o={},a=[]},this},e}((Circuit=function(e){"use strict";var t=e.Utils,n={ACCESSIBILITY:"125328",AGC:"89415",DEVICE_ACCESS:"48742",JABRA:"112718",LOGIN:"37428",MODERATION:"93154",PLANTRONICS:"115017",SHORTCUTS:t.isMacOs?"144499":"144490",TELEPHONY:"103733"};return e.UtilSvcImpl=function(n,i,r,o){o.debug("New Service: UtilSvc");var a=this;return this.promisify=function(t,r){return function(){var e=Array.prototype.slice.call(arguments);return new i(function(n,i){e.push(function(e){if(e)i(e);else{var t=Array.prototype.slice.call(arguments);switch(t.shift(),t.length){case 0:n();break;case 1:n(t[0]);break;default:n(t)}}}),t.apply(r,e)})}},this.getFaqUrl=function(e){if(n.localUser){if(n.localUser.faqUrl&&t.DEFAULT_FAQ_URL!==n.localUser.faqUrl)return n.localUser.faqUrl+(e||"");if(n.localUser.helpUrl&&t.DEFAULT_HELP_URL!==n.localUser.helpUrl)return n.localUser.helpUrl}return"HELP"===e?t.DEFAULT_HELP_URL:t.DEFAULT_FAQ_URL+(e?"?articleId="+e:"")},this.isPartnerAdmin=function(e){return!(!n.localUser||!n.localUser.isPartnerAdmin)||(o.debug("[UtilSvc]: Cannot invoke request. Local user is not a partner admin."),e&&r(function(){e("Not partner admin")}),!1)},this.isTenantAdmin=function(e,t){return!!n.localUser&&(t&&t.tenantId!==n.localUser.tenantId?a.isPartnerAdmin(e):!!n.localUser.isTenantAdmin||(o.warn("[UtilSvc]: Local user is not a tenant admin"),e&&r(function(){e("Not tenant admin")}),!1))},this.hasOAuthAppChangeRights=function(){return!!n.localUser&&(!!n.localUser.hasDeveloperConsoleAccess||(o.warn("[UtilSvc]: Local user does not have rights for accessing the developer console"),!1))},this.hasOAuthAppViewRights=function(){return!!n.localUser&&(!!n.localUser.canViewDeveloperConsole||(o.warn("[UtilSvc]: Local user does not have rights for viewing the developer console."),!1))},this},e.Enums=e.Enums||{},e.Enums.FaqArticle=n,e}((Circuit=function(R){"use strict";var f=Object.freeze({Idle:"Idle",Active:"Active"});return R.Enums=R.Enums||{},R.Enums.IdleState=f,R.SdkHelperSvcImpl=function(i,e,r,o){var a,t=R.Enums.ConnectionState,n=R.Constants,s=R.Conversation,c=R.UserProfile,l=R.Utils,d=this,u={},E=null,C=R.ClientApiHandlerSingleton.getInstance(),T=[];function p(){return null}function S(){if(!i.localUser||!i.localUser.accounts||!i.localUser.accounts[0])return!1;var e=i.localUser,t=i.localUser.accounts[0],n=e.callerId;return t.telephonyConfiguration?(e.phoneNumber=t.telephonyConfiguration.phoneNumber||null,e.isATC?(e.callerId=t.telephonyConfiguration.phoneNumber,e.cstaNumber=l.cleanPhoneNumber(t.telephonyConfiguration.phoneNumber),e.registerNumber=e.cstaNumber,e.isRegisterTC=!0):e.isSTC?(e.callerId=t.telephonyConfiguration.phoneNumber,e.registerNumber=l.cleanPhoneNumber(t.telephonyConfiguration.phoneNumber),e.cstaNumber=null,e.isRegisterTC=!0):(e.callerId=t.telephonyConfiguration.callerId||e.phoneNumber||E,e.cstaNumber=null,e.registerNumber=null,e.isRegisterTC=!1)):(e.phoneNumber=null,e.callerId=E,e.cstaNumber=null,e.registerNumber=null,e.isRegisterTC=!1),n!==e.callerId}function I(){return new Promise(function(n,i){C.getTelephonyData(function(e,t){e?i(e):(E=t.defaultCallerId||null,n(t))})})}function A(){return new Promise(function(n,i){C.getTelephonyConversationId(function(e,t){e||!t?i("Telephony conversation not found"):d.getConversationById(t,null,function(e,t){e||!t?i(e||"Error retrieving telephony conversation"):((a=t).isTelephonyConv=!0,n(t))})})})}return o.subscribe("/telephony/data",function(e){var t=!1;E!==e.defaultCallerId&&(E=e.defaultCallerId,l.updateTelephonyNumbers(i.localUser,e.defaultCallerId)&&(t=!0)),i.localUser.telephonyAvailable!==e.telephonyAvailableForUser&&(i.localUser.telephonyAvailable=e.telephonyAvailableForUser,t=!0),t&&o.publish("/localUser/update",[i.localUser])}),C.on("Account.TELEPHONY_CONFIGURATION_UPDATED",function(e){if(e.configuration&&i.localUser){var t=i.localUser.accounts&&i.localUser.accounts[0];t&&(t.telephonyConfiguration=e.configuration,d.telephonyConfigChanged(),o.publish("/localUser/update",[i.localUser]))}}),this.addConversationToCache=function(e){e&&e.convId&&(u[e.convId]=s.extend(e))},this.setLocalUser=function(e){e&&(e.canUseHDVideo=e.hasPermission(Circuit.Enums.SystemPermission.HD_VIDEO),e.canUseHDScreenShare=e.hasPermission(Circuit.Enums.SystemPermission.HD_SCREENSHARE),i.localUser=e,c.syncTelephonyConfig(e),S())},this.telephonyConfigChanged=function(){S(),c.syncTelephonyConfig(i.localUser)},this.getConversationPromise=function(t){return new Promise(function(n,i){if(t){var e=u[t];e?n(e):d.getConversationById(t,null,function(e,t){e||!t?i("Conversation not found"):n(t)})}else i()})},this.getConversationById=function(e,t,i){"function"==typeof i&&C.getConversationById(e,function(e,t){var n=s.extend(t);n&&(u[t.convId]=n),i(e,n)})},this.getConversationByRtcSession=function(e){for(var t in r.debug("[SdkHelperSvc]: getConversationByRtcSession - rtcSessionId = ",e),u)if(u.hasOwnProperty(t)&&u[t].rtcSessionId===e)return u[t];return null},this.getConversationFromCache=function(e){return r.debug("[SdkHelperSvc]: getConversationFromCache - convId = ",e),u[e]||null},this.getConversationAsGuestById=function(t){return T.find(function(e){return e.convId===t})},this.getTelephonyData=I,this.getTelephonyConversationPromise=function(){return a?Promise.resolve(a):A()},this.getTelephonyConversation=function(t){if("function"==typeof t){if(a)return void window.setTimeout(function(){t(null,a)});I().then(S).then(A).then(function(e){t(null,e)}).catch(t)}},this.getCachedTelephonyConversation=function(){return a},this.isConversationsLoadComplete=function(){return!!i.localUser},this.updateLastCallTime=function(){},this.createConversationAsGuest=function(n){var e=s.extend({convId:n.convId,type:n.type,topic:n.topic,rtcSessionId:n.rtcSessionId,creatorId:n.creatorId,participants:[{userId:i.localUser.userId}],creatorTenantId:n.creatorTenantId||i.localUser.tenantId,isTemporary:!0,creationTime:n.creationTime||Date.now()});return T.some(function(e,t){return e.convId===n.convId&&(T.splice(t,1),!0)}),T.push(e),r.debug("[SDK]: Created temporary (as guest) conversation for session:",e.rtcSessionId),setTimeout(function(){n.isExtended?(r.debug("[SDK]: Publish /conversation/navigate/reload event"),o.publish("/conversation/navigate/reload",[e])):(r.debug("[SDK]: Publish /conversation/new event"),o.publish("/conversation/new",[e]))}),e},this.createConversationAsGuestFromSummary=function(e){return new Promise(function(n,i){e?C.getConversationSummary(e,null,function(e,t){e?i("[SDK] getConversationSummary request failed"):n(d.createConversationAsGuest(t))}):i("convId is required")})},this.sendQOSData=function(e,t,n){r.debug("[SdkHelperSvc]: sendQOSData - call stats: ",n)},this.state=function(){switch(C.getConnState()){case t.Disconnected:return"Disconnected";case t.Connecting:return"Connecting";case t.Reconnecting:return"Reconnecting";case t.Connected:return"Registered";default:return""}},this.isRegistered=function(){return C.getConnState()===t.Connected},this.getSetting=function(){return null},this.getUserIdleState=function(){return f.Active},this.isAutoSnoozeOn=!1,this.setPresenceWithLocation=function(){},this.startAutoSnooze=function(){},this.cancelAutoSnooze=function(){},this.snooze=function(){},this.resume=function(){},this.getUserFromCache=p,this.getUser=p,this.getUserById=function(e,t){t&&t(n.ReturnCode.NO_RESULT)},this.addUsersToCache=function(){},this.startReverseLookUp=function(e,t){t&&t(null)},this},R}((Circuit=function(t){"use strict";return t.Enums.SystemPermission=t.Constants.SystemPermission,t.Enums.DeviceType=t.Constants.DeviceType,t.Enums.CallStateName={},Object.getOwnPropertyNames(t.Enums.CallState).forEach(function(e){t.Enums.CallStateName[e]=e}),t.Enums.ConversationItemType=t.Constants.ConversationItemType,t.Enums.ConversationType={DIRECT:"DIRECT",GROUP:"GROUP",LARGE:"LARGE",COMMUNITY:"COMMUNITY"},t.Enums.PresenceState=t.Constants.PresenceState,t.Enums.RTCItemType=t.Constants.RTCItemType,t.Enums.RTCParticipantType=t.Constants.RTCParticipantType,t.Enums.SystemItemType=t.Constants.SystemItemType,t.Enums.TextItemContentType=t.Constants.TextItemContentType,t.Enums.UserBusyHandlingOptions=t.Constants.UserBusyHandlingOptions,t.Enums.UserType=t.Constants.UserType,t.Enums.UserState=t.Constants.UserState,t.Enums.SearchDirection=t.Constants.SearchDirection,t.Enums.ParticipantCriteria=t.Constants.GetConversationParticipantCriteria,t.Enums.ConversationParticipantType=t.Constants.ConversationParticipantType,t.Enums.RetrieveAction=t.Constants.RetrieveAction,t.Enums.RecordingInfoState=t.Constants.RecordingInfoState,t.Enums.RecordingInfoState=t.Constants.RecordingInfoState,t.Enums.SearchScope=t.Constants.SearchScope,t.Enums.SearchStatusCode=t.Constants.SearchStatusCode,t.Enums.SessionClosedReason=t.Constants.SessionClosedReason,t.Enums.GetAccountsFilterCriteria=t.Constants.GetAccountsFilterCriteria,t.Enums.AccountStatus=t.Constants.AccountStatus,t.Enums.GetAccountsSorting=t.Constants.GetAccountsSorting,t.Enums.SortOrder=t.Constants.SortOrder,t.Enums.SearchContext=t.Constants.SearchContext,t.Enums.Locale=t.Constants.Locale,t.Enums.VideoResolution={VGA:"VGA",HD:"HD",FHD:"FHD",NONE:"NONE"},t.Enums.FormControlType=t.Constants.CPaaSFormMetaDataControlType,t.Enums.RecordingVideoLayoutName=t.Constants.RecordingVideoLayoutName,t.Enums.JournalFilter=t.Constants.JournalFilter,t}((Circuit=function(e){"use strict";var t;return e.ExtensionConnHandlerSingleton={getInstance:function(){return t||(t=new e.ExtensionConnHandler),t}},e}((Circuit=function(p){"use strict";var e=p.BaseEventTarget,S=p.ChromeExtension,I=p.logger,A=p.Utils;function R(){R.parent.constructor.call(this,I);var o,a,s=5e3,c=65e3,r=this,l={},d=0,n=!1,e=window.BgExchangeConnectorHandler;if(p.isElectron){if(e){a=e.getInstance();var u=function(e){e.data&&e.data.keysToOmitFromLogging&&(e.keysToOmitFromLogging=e.data.keysToOmitFromLogging.map(function(e){return"data."+e}),delete e.data.keysToOmitFromLogging),t(e)};o=Object.create(I,{sendResponse:{value:function(e,t,n){var i={type:S.BgMsgType.RESPONSE,reqId:e,suppressLog:!!n,data:t};u(i)}},sendInternalEvent:{value:function(e){I.error("[ExtensionConnHandler]: Unexpected internal event: ",e)}},sendExchangeConnEvent:{value:function(e,t){var n={type:S.BgMsgType.EVENT,target:S.BgTarget.EXCHANGE_CONNECTOR,suppressLog:!!t,data:e};u(n)}}});var i="exchange";window.chrome={storage:{local:{set:function(e,t){window.localStorage.setItem(i,JSON.stringify(e,function(e,t){if("string"!=typeof e||"$"!==e.charAt(0))return t})),t&&t()},get:function(e,t){t&&t(JSON.parse(window.localStorage.getItem(i)))},clear:function(e){window.localStorage.removeItem(i),e&&e()}}},runtime:{},windows:{create:function(){}},permissions:{contains:function(e,t){t(!0)}}}}setTimeout(function(){I.info("[ExtensionConnHandler]: Raise extensionInitialized"),n=!0;var e=r.createEvent("extensionInitialized");e.data={version:"electron"},r.dispatch(e)},1e3)}function E(e,t){I.info("[ExtensionConnHandler]: Dispatching event: ",e);var n=r.createEvent(e);n.data=t,r.dispatch(n)}function C(e,t,n,i){return e?r.isExtensionRunning()?function(e,t,n,i){e.type===S.BgMsgType.REQUEST&&(e.reqId=function(e,t){e=e||function(){};var n=++d,i=window.setTimeout(function(){l[n]&&(I.error("[ExtensionConnHandler]: Timeout waiting for response. reqId:",n),delete l[n],e(S.ResponseError.TIMEOUT))},t||s);return l[n]={cb:e,timer:i},n}(t,n));i||I.msgSend("[ExtensionConnHandler]: ",e);if(e.suppressLog=i,p.isElectron&&a&&e.type===S.BgMsgType.REQUEST&&e.target===S.BgTarget.EXCHANGE_CONNECTOR)return window.setTimeout(function(){a.onWebClientMsg(o,e,p.__server)},0),e.reqId;var r=new CustomEvent(S.DOMEvent.TO_EXTENSION,{detail:JSON.stringify(e)});try{document&&document.dispatchEvent(r)}catch(e){return I.warning("[ExtensionConnHandler]: Error sending message: "+r,e),!1}return e.reqId}(e,t,n,i):(I.info("[ExtensionConnHandler]: Chrome extension is not running"),t&&window.setTimeout(function(){t("Extension not running")},0),!1):(I.error("[ExtensionConnHandler]: Cannot send message. Invalid message."),t&&window.setTimeout(function(){t("Invalid message")},0),!1)}function T(){I.warning("[ExtensionConnHandler]: The content script has unregistered itself. Chrome extension is no longer running."),n=!1,I.info("[ExtensionConnHandler]: Dispatching event: extensionUnregistered");var e=r.createEvent("extensionUnregistered");r.dispatch(e)}function t(e){if(e.target!==S.BgTarget.LOG)switch(e.suppressLog||I.msgRcvd("[ExtensionConnHandler]: ",e),e.type){case S.BgMsgType.REQUEST:case S.BgMsgType.EVENT:!function(e){switch(e.target){case S.BgTarget.INTERNAL:switch(e.data.type){case S.BgInternalMsgType.INIT_MSG:I.info("[ExtensionConnHandler]: Received INIT_MSG. Send an INIT_MSG_ACK to the extension."),n=!0,C({target:S.BgTarget.INTERNAL,data:{type:S.BgInternalMsgType.INIT_MSG_ACK}}),E("extensionInitialized",e.data);break;case S.BgInternalMsgType.EXTENSION_DISCONNECTED:I.warning("[ExtensionConnHandler]: Received EXTENSION_DISCONNECTED from ansible-content"),T();break;default:I.warning("[ExtensionConnHandler]: Received unknown INTERNAL msg type:",e.data.type)}break;case S.BgTarget.HEADSET_APP:switch(e.data.type){case S.BgHeadsetAppMsgType.HEADSET_APP_LAUNCHED:E("headsetAppLaunched",e.data);break;case S.BgHeadsetAppMsgType.HEADSET_APP_UNINSTALLED:E("headsetAppUninstalled",e.data);break;default:I.warning("[ExtensionConnHandler]: Received unknown HEADSET_APP msg type:",e.data.type)}break;case S.BgTarget.PRIVACY_SETTINGS:e.data.type===S.BgPrivacySettingsMsgType.IP_HANDLING_POLICY_CHANGED?E("webRTCIPHandlingPolicyChanged",e.data):I.warning("[ExtensionConnHandler]: Received unknown PRIVACY_SETTINGS msg type:",e.data.type);break;default:e.suppressLog||I.info("[ExtensionConnHandler]: Dispatching event:",e.target);var t=r.createEvent(e.target);t.data=e.data,t.suppressLog=e.suppressLog,e.reqId&&e.type===S.BgMsgType.REQUEST&&(t.reqId=e.reqId),r.dispatch(t)}}(e);break;case S.BgMsgType.RESPONSE:!function(e){if(l[e.reqId]){var t=l[e.reqId];t.timer&&window.clearTimeout(t.timer),delete l[e.reqId],e.data&&e.data.error?(t.cb(e.data.error),e.data.error===S.ResponseError.UNREGISTERED&&T()):t.cb(null,e.data),e.suppressLog||I.debug("[ExtensionConnHandler]: Remaining callbacks pending:",Object.keys(l).length)}else I.info("[ExtensionConnHandler]: No registered callback for reqId =",e.reqId)}(e);break;default:I.msgRcvd("[ExtensionConnHandler]: Unexpected message type: ",e.type)}else I.logMsg(e.data.log.level,e.data.log.messages)}this.isExtensionRunning=function(){return n},this.getScreenShareUserMedia=function(e){C({target:S.BgTarget.SCREEN_SHARE,type:S.BgMsgType.REQUEST,data:{type:S.BgScreenShareMsgType.CHOOSE_DESKTOP_MEDIA}},e)},this.exchangeConnect=function(e,t){C({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{method:S.BgExchangeMsgType.CONNECT,object:{settings:e}},keysToOmitFromLogging:["data.object.settings.exchInfo"]},t,18e4)},this.exchangeDisconnect=function(e){C({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{method:S.BgExchangeMsgType.DISCONNECT,object:{}}},e,c)},this.exchangeGetConnectionStatus=function(e,t){C({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.GET_CONNECTION_STATUS},keysToOmitFromLogging:["data.key"]},t,c)},this.exchangeGetCapabilities=function(e){C({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{method:S.BgExchangeMsgType.GET_CAPABILITIES}},e,c)},this.exchangeAutodiscoverGetServer=function(e,t){C({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{method:S.BgExchangeMsgType.AUTODISCOVER_GET_SERVER,object:{settings:e}},keysToOmitFromLogging:["data.object.settings.exchInfo"]},t,c)},this.exchangeCancelReqCallback=function(e){return I.debug("[ExtensionConnHandler]: Unregistering callback for reqId:",e),function(e){return!(!e||!l[e])&&(delete l[e],!0)}(e)},this.exchangeSearchContacts=function(e,t,n,i){return C({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.SEARCH_CONTACTS,object:{searchString:t,resultCount:n}},keysToOmitFromLogging:["data.key"]},i,c)},this.exchangeResolveContact=function(e,t,n){C({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.RESOLVE_CONTACT,object:t},keysToOmitFromLogging:["data.key"]},n,c)},this.exchangeGetContact=function(e,t,n){C({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.GET_CONTACT,object:{email:t}},keysToOmitFromLogging:["data.key"]},n,c)},this.exchangeOnRenewedToken=function(e,t,n,i){C({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.RESPONSE,data:{key:e,method:S.BgExchangeMsgType.ON_RENEWED_TOKEN,object:{reqId:t,token:n}},keysToOmitFromLogging:["data.key","data.object.token"]},i,c)},this.exchangeStoreCredentials=function(e,t){C({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{method:S.BgExchangeMsgType.STORE_EXCH_CREDENTIALS,object:e},keysToOmitFromLogging:["data.object"]},t,c)},this.getAllPersonalContacts=function(e,t){C({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.GET_ALL_PERSONAL_CONTACTS},keysToOmitFromLogging:["data.key"]},t,c)},this.getAppointments=function(e,t,n,i,r){C({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.GET_APPOINTMENTS,startDate:t,endDate:n,resCount:i},keysToOmitFromLogging:["data.key"]},r,c)},this.syncAllPersonalContacts=function(e,t,n){C({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.SYNC_ALL_PERSONAL_CONTACTS,syncState:t},keysToOmitFromLogging:["data.key","data.syncState"]},n,c)},this.getStoredCredentials=function(e,t){C({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.GET_STORED_CREDENTIALS},keysToOmitFromLogging:["data.key"]},t,c)},this.getOooMsg=function(e,t,n,i){C({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.GET_OOO_MSG,fromEmail:t,email:n},keysToOmitFromLogging:["data.key"]},i,c)},this.getUserAvailability=function(e,t,n){C({target:S.BgTarget.EXCHANGE_CONNECTOR,type:S.BgMsgType.REQUEST,data:{key:e,method:S.BgExchangeMsgType.GET_USER_AVAILABILITY,email:t},keysToOmitFromLogging:["data.key","data.email"]},n,c)},this.getHeadsetIntegrationAppStatus=function(e,t){"function"==typeof t&&(p.isElectron?window.setTimeout(function(){I.debug("[ExtensionConnHandler]: Return status INSTALLED for desktop app"),t(null,{status:S.HeadsetAppStatus.INSTALLED})},0):C({target:S.BgTarget.HEADSET_APP,type:S.BgMsgType.REQUEST,data:{type:S.BgHeadsetAppMsgType.GET_HEADSET_APP_STATUS,appId:e}},t))},this.launchHeadsetIntegrationApp=function(e,t,n){C({target:S.BgTarget.HEADSET_APP,type:S.BgMsgType.REQUEST,data:{type:S.BgHeadsetAppMsgType.LAUNCH_HEADSET_APP,appId:e,localizedStrings:t}},n,18e4)},this.restartHeadsetApp=function(e,t){C({target:S.BgTarget.HEADSET_APP,type:S.BgMsgType.REQUEST,data:{type:S.BgHeadsetAppMsgType.RESTART_HEADSET_APP,appId:e}},t)},this.setIPHandlingPolicy=function(e,t,n){C({target:S.BgTarget.PRIVACY_SETTINGS,type:S.BgMsgType.REQUEST,data:{type:S.BgPrivacySettingsMsgType.SET_IP_HANDLING_POLICY,policy:e,localizedStrings:t}},n,18e4)},this.getIPHandlingPolicy=function(e){C({target:S.BgTarget.PRIVACY_SETTINGS,type:S.BgMsgType.REQUEST,data:{type:S.BgPrivacySettingsMsgType.GET_IP_HANDLING_POLICY}},e)},this.bringToFront=function(e){C({target:S.BgTarget.INTERNAL,type:S.BgMsgType.REQUEST,data:{type:S.BgInternalMsgType.BRING_TO_FRONT}},e)},this.getFile=function(e,t,n){C({target:S.BgTarget.INTERNAL,type:S.BgMsgType.REQUEST,data:{type:S.BgInternalMsgType.GET_FILE,name:e,lang:t}},n)},A.getBrowserInfo().chrome&&document&&document.addEventListener(S.DOMEvent.FROM_EXTENSION,function(e){if(e&&e.detail)try{t(JSON.parse(e.detail))}catch(e){I.error("[ExtensionConnHandler]: Error parsing JSON object. ",e)}})}return A.inherit(R,e),R.prototype.name="ExtensionConnHandler",p.ExtensionConnHandler=R,p}((Circuit=function(e){"use strict";var l=Circuit.logger;return e.CstaParser=function(){function r(e){var t=null;return e&&e.extn&&e.extn.pDa&&e.extn.pDa.prvt&&(t=e.extn.pDa.prvt.zEpid),t}function n(t){t&&Object.keys(t).forEach(function(e){t[e]=""===t[e]||"true"===t[e]})}function o(e){if(!e)return{};var t={};return e.sP&&(t.rSP=e.sP,n(t.rSP.cCSs)),e.extn&&e.extn.pDa&&e.extn.pDa.prvt&&void 0!==e.extn.pDa.prvt.zxSP&&(t.eSP=e.extn.pDa.prvt.zxSP,n(t.eSP)),t}function i(e){return{forwardingType:e.fTe,forwardStatus:"true"===e.fS,forwardDN:e.fDNN}}function a(e){return{name:e.zgNM,pilotDn:e.zgDN,available:"false"===e.zMB}}function s(e){if(e.extn&&e.extn.pDa&&e.extn.pDa.prvt){var t=[];if(e.extn.pDa.prvt.zeMBSL)return Array.isArray(e.extn.pDa.prvt.zeMBSL.zeMBS)?e.extn.pDa.prvt.zeMBSL.zeMBS.forEach(function(e){t.push(a(e))}):t.push(a(e.extn.pDa.prvt.zeMBSL.zeMBS)),t}return null}function c(e){return{recordId:e.rID,callID:e.cID,recordType:e.rTp,createdTime:e.cTm,result:e.res,callDuration:e.cDr,callingDevice:e.clDv||"",calledDevice:e.cldDv||"",answeringDevice:e.aDv||""}}this.genCstaRequest=function(e){try{switch(e.request){case"AlternateCall":return function(e){return{ACl:{hC:{cID:e.heldCall.cID,dID:e.heldCall.dID},atC:{cID:e.activeCall.cID,dID:e.activeCall.dID}}}}(e);case"ConferenceCall":return function(e){return{CoC:{hC:{cID:e.heldCall.cID,dID:e.heldCall.dID},atC:{cID:e.activeCall.cID,dID:e.activeCall.dID}}}}(e);case"AnswerCall":return function(e){return{AnC:{cTBAd:{cID:e.callToBeAnswered.cID,dID:e.callToBeAnswered.dID}}}}(e);case"CallBackCallRelated":return function(e){return{CB:{cC:{cID:e.callBackConnection.cID,dID:e.callBackConnection.dID}}}}(e);case"CallBackNonCallRelated":return function(e){return{CBNC:{orD:e.orD,tD:e.tD}}}(e);case"CancelCallBack":return function(e){return{CCB:{orD:e.orD,tD:e.tD}}}(e);case"ClearConnection":return function(e){return{CCn:{coTBC:{cID:e.connectionToBeCleared.cID,dID:e.connectionToBeCleared.dID},rsn:e.reason}}}(e);case"ConsultationCall":return function(e){return{CnC:{cnD:e.consultedDevice||void 0,eCl:{cID:e.existingCall.cID,dID:e.existingCall.dID}}}}(e);case"DeflectCall":return function(e){var t={cTBD:{cID:e.callToBeDiverted.cID,dID:e.callToBeDiverted.dID},nD:e.newDestination};e.autoAnswer&&(t.extn={pDa:{prvt:{zdT:"Auto-Answer"}}});return{DCl:t}}(e);case"GenerateDigits":return function(e){return{GD:{cTSD:{cID:e.connectionToSendDigits.cID,dID:e.connectionToSendDigits.dID},cTS:e.charactersToSend}}}(e);case"GetDoNotDisturb":return function(e){return{GDND:{dvc:e.device}}}(e);case"GetForwarding":return function(e){return{GF:{dvc:e.device}}}(e);case"GetMessageWaitingIndicator":return function(e){return{GMWI:{dvc:e.device}}}(e);case"HoldCall":return function(e){var t={cTBH:{cID:e.callToBeHeld.cID,dID:e.callToBeHeld.dID}};e.holdOptions&&(t.extn={zhOs:e.holdOptions});return{HC:t}}(e);case"ReconnectCall":return function(e){return{RC:{hC:{cID:e.heldCall.cID,dID:e.heldCall.dID},atC:{cID:e.activeCall.cID||void 0,dID:e.activeCall.dID||void 0}}}}(e);case"RetrieveCall":return function(e){return{RCl:{cTBRd:{cID:e.callToBeRetrieved.cID,dID:e.callToBeRetrieved.dID}}}}(e);case"SetBusy":return function(e){return{zSBN:{dvc:e.device,zbO:e.busyState}}}(e);case"SetDoNotDisturb":return function(e){return{SDND:{dvc:e.device,dNDO:e.doNotDisturbOn}}}(e);case"SetForwarding":return function(e){var t={SF:{dvc:e.device,aF:e.activateForward,fDNN:e.forwardDN,fTe:e.forwardingType,riC:e.ringCount}},n={};void 0!==e.staticOndActive?n={zsOA:!0===e.staticOndActive?"true":"false",zsOD:e.staticOndDN||""}:void 0!==e.voicemailActive||void 0!==e.voicemailRingDuration?n={zvMA:"boolean"==typeof e.voicemailActive?e.voicemailActive.toString():void 0,zvMRD:e.voicemailRingDuration?e.voicemailRingDuration.toString():void 0}:(void 0!==e.mainRingDuration&&(n.zmRD=e.mainRingDuration.toString()||""),void 0!==e.clientRingDuration&&(n.zcRD=e.clientRingDuration.toString()||""),void 0!==e.cellRingDuration&&(n.zcpRD=e.cellRingDuration.toString()||""),void 0!==e.alternativeNumber&&(n.zcPN=e.alternativeNumber),void 0!==e.routeToCell&&(n.zrTCN=e.routeToCell?"true":"false"));0n&&(i=i*n/r,r=n):t"),we(m.onGetUserMediaException,{info:t}))},function(e){var t,n=e&&e.name||"Unspecified";if(o.videoResolution&&(n===an||n===sn))return $t.warn("[RtcSessionController]: Failed to access local media with HD constraints: ",p.video),o.videoResolution=a.shift(),he(o.videoResolution),p.video=_.getVideoOptions(o),void l();$t.warn("[RtcSessionController]: Failed to access local media: ",n),C&&(window.clearTimeout(C),C=null),t=dn.includes(n)?K.video?"res_AccessToMediaInputDevicesFailedPermissionDenied":"res_AccessToAudioInputDeviceFailedPermissionDenied":n===cn||n===ln?K.video?"res_AccessToMediaInputDevicesFailedInUse":"res_AccessToAudioInputDeviceFailedInUse":K.video?"res_AccessToMediaInputDevicesFailed":"res_AccessToAudioInputDeviceFailed",u(t)})};l(),$t.debug("[RtcSessionController]: Requested access to Local Media")})}catch(e){$t.error("[RtcSessionController]: Exception while handling getUserMedia: ",e),C&&(window.clearTimeout(C),C=null),u(K.video?"res_AccessToMediaInputDevicesFailed":"res_AccessToAudioInputDeviceFailed")}}function me(t,n,i){$t.debug("[RtcSessionController]: getUserMediaDesktop()");try{var e={audio:!1},r=Oe();e.video=_.getDesktopOptions(i.streamId||i.screenType,r),$t.info("[RtcSessionController]: Calling getUserMedia - constraints = ",e),_.getUserMedia(e,function(e){if($t.info("[RtcSessionController]: User has granted access for screen capture. Stream Id:",_.getStreamId(e)),ce)return $t.info("[RtcSessionController]: Session already terminated. Stop desktop MediaStream: ",_.getStreamId(e)),void lt(e);i&&(ee=i.isScreenControlled,te=ee,function(e){$t.debug("[RtcSessionController]: send ScreenSharePointerStatus event"),we(m.onScreenSharePointerStatus,{isSupported:!(!e||!e.isSupported),isEnabled:!(!e||!e.isEnabled)})}(i.pointer),ne=i),e.oninactive=fe.bind(null,e,!0),Et(e,u),t()},function(e){var t=e&&e.name||"Unspecified";$t.warn("[RtcSessionController]: Failed to access local media: ",t),dn.includes(t)?n(zt.ReturnCode.CHOOSE_DESKTOP_MEDIA_CANCELLED):n("res_AccessToDesktopFailed")}),$t.debug("[RtcSessionController]: Requested access for screen capture")}catch(e){$t.error("[RtcSessionController]: Exception while handling getUserMedia: ",e),n("res_AccessToDesktopFailed")}}function he(e){e||(K.hdVideo=!1),K.videoResolution=e}function Oe(){var e=K.hdDesktop?"hdScreenShare":"screenShare",t={frameRate:{min:Rn.sdpParameters[e].minFrameRate,max:Rn.sdpParameters[e].maxFrameRate}};return K.remoteControlEnabled&&(t.frameRate.min=Math.max(t.frameRate.min,Rn.sdpParameters.rcScreenShare.minFrameRate),t.frameRate.max=Math.max(t.frameRate.max,Rn.sdpParameters.rcScreenShare.maxFrameRate)),t}function De(e){if(e){if(c)return!0}else if(y)return!0;var t={};f&&(t.rtcpMuxPolicy=Rn.sdpParameters.rtcpMuxPolicy),E.length&&!oe?(t.iceServers=[{urls:E,credential:C.password,username:C.username}],Rn.allowOnlyRelayCandidates&&(t.iceTransportPolicy="relay")):(oe||$t.warn("[RtcSessionController]: No TURN server(s) provided."),t.iceServers=[]);var n=!!oe;oe=!1,Rn.webRTCIPHandlingPolicy&&$t.info("[RtcSessionController]: webRTCIPHandlingPolicy is set to ",Rn.webRTCIPHandlingPolicy),$t.debug("[RtcSessionController]: Creating RtcPeerConnections. config: ",t);var i={optional:[{DtlsSrtpKeyAgreement:!0},{googImprovedWifiBwe:!0},{googHighBitrate:!0},{googVeryHighBitrate:!0},{googDscp:!0}]};$t.debug("[RtcSessionController]: Creating peer connections. constraints:",i),h?($t.debug("[RtcSessionController]: Set number of extra video channels for direct calls to 0"),s=0):D?($t.debug("[RtcSessionController]: Set number of extra video channels for mobile clients to 0"),s=0):ie&&re?($t.debug("[RtcSessionController]: Set number of extra video channels for guests in large conference to 0."),s=0):Re||!J&&!$?(s="number"==typeof Rn.maxVideoExtraChannels?(s=Math.max(Rn.maxVideoExtraChannels,0),Math.min(s,pn)):Sn,$t.info("[RtcSessionController]: Set number of extra video channels to ",s)):($t.debug("[RtcSessionController]: Remote video is disabled. Set number of extra video channels to 0."),s=0);var r=s;K.video&&$&&_.unifiedPlanEnabled&&!Re&&($t.debug("[RtcSessionController]: Local video is enabled and we only allow remote screenshare. We need to setup an extra sendonly video channel."),r=1);var o,a={extraVideoChannels:r,createDesktopPc:!Rn.disableDesktopPc&&!h&&(!J||K.desktop||$),onlyRemoteScreenShare:$};$t.debug("[RtcSessionController]: Creating peer connections. options:",a);try{e||(Z=[]),(o=_.unifiedPlanEnabled?new Qt.RtcPeerConnectionsUnified(t,a):new Qt.RtcPeerConnections(t,i,a)).connectionBypassed=n,$t.debug("[RtcSessionController]: Created audio/video peer connections. Connection bypassed: ",n)}catch(e){return $t.error("[RtcSessionController]: Failed to create peer connections.",e),!1}return e?c=o:(d=[y=o,b],l=be([y]),Pe(y,l)),!0}function Pe(e,t){e&&(e.onicecandidate=function(e,t){if(!e||!d.includes(e))return void $e("Received icecandidate event for old PC");var n,i=je(e,"sdpStatus");if(t.candidate){if(!t.candidate.candidate)return void Je("Ignore empty candidate for mid "+t.candidate.sdpMid);var r=new Jt(t.candidate.candidate);if("udp"!==r.transport)return void Je("Ignore non UDP candidate");if(e===y&&"relay"===r.typ&&(e.hasRelayCandidates=!0),Je("New ICE candidate: ",t.candidate),et(e)){if(n=e.localDescription,!et(e,n.type))return;var o={candidate:t.candidate.candidate,sdpMid:t.candidate.sdpMid,sdpMLineIndex:t.candidate.sdpMLineIndex};!function(e,t){var n=Ke(e=e||y);if(!n)return!1;if(Rn.allowAllIceCandidatesScreenShare||t.sdpMid!==y.getScreenShareMediaId()||n.hasRelayRtpCandidate||n.sendAllCandidates)return!0;var i=new Jt(t.candidate);if(i.isTcpTlsRelay())return i.isRtp()&&($t.info("[RtcSessionController]: Found local relay candidate for TURN over TCP/TLS. Remove queued candidates."),n.hasRelayRtpCandidate=!0,delete n.queuedCandidates,n.relayRtpCandidateTimeout&&(window.clearTimeout(n.relayRtpCandidateTimeout),delete n.relayRtpCandidateTimeout)),!0;"udp"===i.transport&&(n.queuedCandidates||(n.queuedCandidates=[],$t.debug("[RtcSessionController]: Start timer to wait for relay candidate for TURN over TCP/TLS."),n.relayRtpCandidateTimeout=window.setTimeout(function(){$t.info("[RtcSessionController]: Timer expired. Stop waiting for relay candidate for TURN over TCP/TLS and send all pending candidates."),delete n.relayRtpCandidateTimeout,n.queuedCandidates&&(Ge(n.queuedCandidates,e),delete n.queuedCandidates),n.sendAllCandidates=!0},un)),n.queuedCandidates.push(t),$t.debug("[RtcSessionController]: Queue candidate in case there is no TURN over TCP/TLS relay candidate"));return!1}(e,o)||(i!==nn.None&&i!==nn.OfferPending&&i!==nn.AnswerPending?function(e,t){var n=Ke(t);if(!n)return;n.pendingCandidates||(n.pendingCandidates=[],$t.debug("[RtcSessionController]: Start timer to collect candidates before send."),n.collectCandidatesTimeout=window.setTimeout(function(){$t.debug("[RtcSessionController]: Timer expired. Send all pending candidates."),delete n.collectCandidatesTimeout,n.pendingCandidates&&(Ge(n.pendingCandidates,t),delete n.pendingCandidates)},on));n.pendingCandidates.push(e)}(o,e):Je("Ignore ICE candidate in state ",i))}}else if(Je("End of candidates. PC: ",Ue(e)),e.endOfCandidates=!0,e!==b&&it()){if(!(n=e.localDescription))return void Ze("End of candidates, but cannot access pc.localDescription");et(e,n.type)&&i!==nn.None&&i!==nn.OfferPending&&i!==nn.AnswerPending?function(e){var t=Ke(e);if(!t)return;var n=[];t.pendingCandidates&&($t.info("[RtcSessionController]: Send all pending candidates."),n=t.pendingCandidates);t.queuedCandidates&&($t.info("[RtcSessionController]: There was no relay candidate for TURN over TCP/TLS. Send all queued candidates."),Array.prototype.push.apply(n,t.queuedCandidates));n.push({candidate:"a=end-of-candidates\r\n"}),ze(e),Ge(n,e)}(e):ke(e,n)}je(e,"candidatesTimer")&&et(e)&&(i===nn.OfferPending||i===nn.AnswerPending)&&(n=e.localDescription,ke(e,n))}.bind(null,e),e.oniceconnectionstatechange=Le.bind(null,e),e.onaddstream=function(e,t){if(Je("Added Remote Stream"),I)return void Je("Renegotiation is in progress. Ignore AddStream event.");Tt([t.stream]),Fe()}.bind(null,e),e.onremovestream=function(e,t){$e("Removed Remote Stream"),function(e){if(!e)return;var n=!1,i=O?_.getVideoTrackId(e):_.getVideoStreamTrackId(e);i&&G.some(function(e,t){return e.streamId===i&&(G.splice(t,1),n=!0)});var t=O?_.getAudioTrackId(e):_.getAudioStreamTrackId(e);H&&H.streamId===t&&(n=!(H=null));n&&Ye()}(t.stream),Fe()}.bind(null,e)),t&&(t.onThresholdExceeded=function(e){we(m.onStatsThresholdExceeded,{cleared:e})},t.onNoOutgoingPackets=function(){we(m.onStatsNoOutgoingPackets,{})},t.onNetworkQuality=function(e){we(m.onNetworkQuality,{quality:e})})}function ye(e,t){e&&(e.onicecandidate=null,e.oniceconnectionstatechange=null,e.onaddstream=null,e.onremovestream=null),t&&(t.onThresholdExceeded=null,t.onNoOutgoingPackets=null,t.onNetworkQuality=null)}function be(e){return _.unifiedPlanEnabled&&Qt.CallStatsHandlerUnified?new Qt.CallStatsHandlerUnified(e,h):new Qt.CallStatsHandler(e)}function Ue(e){return e===y?"audio/video":"screen control"}function Le(e){if(e&&d.includes(e)){var t=Ue(e);switch(Je("Connection state change ("+t+"): ",e.iceConnectionState),!E.length||e!==y||e.connectionBypassed||"completed"!==e.iceConnectionState&&"failed"!==e.iceConnectionState||e.hasRelayCandidates||$e("[RtcSessionController]: No relay candidates were collected, please check connectivity to the TURN servers"),je(e,"sdpStatus")){case nn.Connected:switch(e.iceConnectionState){case"connected":case"completed":He(e,t);break;case"disconnected":e.connectionBypassed||function(e,t){if(e.iceDisconnectTimeout)return;e.iceDisconnectTimeout=window.setTimeout(function(){delete e.iceDisconnectTimeout,"disconnected"===e.iceConnectionState&&($t.debug("[RtcSessionController]: send IceDisconnected event pcType:",t),we(m.onIceDisconnected,{pcType:t}))},En)}(e,t);break;case"failed":e.connectionBypassed||(gt(nn.Disconnected,e),Ze("[RtcSessionController]: ICE connection has failed"),e!==b&&vt("res_CallMediaDisconnected"))}break;case nn.AnswerReceived:case nn.PrAnswerReceived:case nn.AnswerApplied:case nn.AnswerSent:switch(e.iceConnectionState){case"connected":case"completed":e.connected=!0,nt(e)&&(Xe(e),gt(nn.Connected,e),He(e,t));break;case"failed":Xe(e),ft(e)}}}else $e("Received iceconnectionstatechange event for old PC")}function Me(e,t){Je("RTCDTMFSender - ontonechange",t.tone?"":": finished"),function(e){$t.debug("[RtcSessionController]: send DTMFToneChanged event"),we(m.onDTMFToneChange,{tone:e})}(t.tone)}function we(e,t){if("function"==typeof e)try{e(t||{})}catch(e){$t.error(e)}}function Ge(e,t){var n=Ke(t);if(n&&e){var i=n.sentIceCandidates,r=!1;if(0<(e=e.filter(function(e){if(e.candidate.startsWith("a=end-of-candidates"))return r=!0;var t=e.candidate,n=i.some(function(e){return e.equals(t)});return n?$e("Ignore duplicate ICE candidate: ",e.candidate):i.push(new Jt(t)),!n})).length){$t.debug("[RtcSessionController]: Send IceCandidate event");var o={origin:function(e){if(!e)return"";var t=je(e,"localOrigin");if(!t){var n=e.localDescription;n&&(t=en.getOrigin(n.sdp),qe(e,"localOrigin",t))}return t}(t),candidates:e,endOfCandidates:r,isAudioVideo:"audio/video"===Ue(t)};we(m.onIceCandidate,o),rt(t)}}}function He(e,t){e.iceDisconnectTimeout&&(window.clearTimeout(e.iceDisconnectTimeout),delete e.iceDisconnectTimeout),$t.debug("[RtcSessionController]: send IceConnected event pcType:",t),we(m.onIceConnected,{pcType:t})}function ke(e,t){if(e){Qe(e);var n=je(e,"sdpStatus");"offer"===t.type?n===nn.OfferPending&&Ve(e,nn.OfferSent):n===nn.AnswerPending&&Ve(e,nn.AnswerSent)}else $e("Cannot send local description for non existing pc.")}function Ve(e,t){if(e){var n;if($t.info("[RtcSessionController]: sendSessionDescription - PC: ",Ue(e)),e===b){var i=b.localDescription;n={type:i.type,parsedSdp:en.parse(i.sdp)}}else{var r=e.localDescription,o=en.parse(r.sdp);if("answer"===r.type){$t.info("[RtcSessionController]: sendSessionDescription - Processing answer SDP");var a=je(y,"disabledRemoteOfferMLines");!y.desktopPeerConnection&&a.get(N.video)&&(o.m.splice(N.video,0,a.get(N.video)),a.remove(N.video))}if(e.desktopPeerConnection){$t.info("[RtcSessionController]: sendSessionDescription - Adjust screenshare m-line");var s=en.findMediaLineIndex(o,e.getScreenShareMediaId());if(0<=s){var c=o.m[s];if(c){c={m:[c]};var l=!h&&!Rn.allowAllIceCandidatesScreenShare;$t.info("[RtcSessionController]: Remove UDP video candidates for screenshare: ",l);var d=et(y,r.type)&&!y.endOfCandidates;en.validateIceCandidates(c,l,d)}}else $t.warn("[RtcSessionController]: Could not find screenshare m-line: no ICE validation was made.")}n={type:r.type,parsedSdp:o}}var u=et(e,n.type),E=n.parsedSdp;E=en.removeAudioLevelAttr(E),E=en.fixTrickleIceOption(E,u),u?it()&&(E=en.addEndOfCandidatesLine(E)):E=en.removeEndOfCandidatesLine(E),y.restoreAudioConnectionMode&&en.setConnectionMode(E,"audio",y.restoreAudioConnectionMode);var C=!D||v.canReceiveHdVideo?"maxBw":"maxBwMobile";(C=Rn.sdpParameters.receiveVideo[C])&&en.setVideoBandwidth(E,C,!0);var T=de||ue;if(0!==en.iceTotalCandidatesCount(E)||T)if(en.validateIceCandidates(E,!1,Ie)||u&&!it()||de){if(u&&!it()){var p=Ke(e);p&&(p.sentIceCandidates=en.getIceCandidates(E))}var S={type:n.type,sdp:en.stringify(E)};if(e===y&&e.desktopPeerConnection&&(S.screen=y.getScreenShareMediaId(),P[g])){var I=function(e){var t,n=P[e];n&&n.getVideoTracks().length&&(t=_.getVideoStreamTrackId(n));return t}(g);$t.info("[RtcSessionController]: Video streamId is ",I);var A=null;O&&I&&(A=_.unifiedPlanEnabled?function(e){var t,n=P[e];if(n){var i=n.getVideoTracks()[0];i&&(t=y&&y.getMediaId(i))}return t}(g):en.getMediaIds(E)[I]),S.video=A||I,qt()&&(S.videoSenderConfiguration=y.getAvailableVideoSenders(Ae))}$t.debug("[RtcSessionController]: send SessionDescription event"),de=!1,we(m.onSessionDescription,{sdp:S}),gt(t,e)}else $t.error("[RtcSessionController]: Failure: SDP contains at least one m line without IceCandidates"),vt();else if(u){var R=Ot();$t.debug("[RtcSessionController]: No ICE candidates collected yet. Waiting "+R+" more milliseconds.");var f=window.setTimeout(function(){qe(e,"candidatesTimer",null),vt("res_RestartBrowser")},R);qe(e,"candidatesTimer",f)}else vt("res_RestartBrowser")}else $e("Cannot send Session Description for non existing pc.")}function Fe(){$t.debug("[RtcSessionController]: send RemoteStreamUpdated event"),we(m.onRemoteStreamUpdated,{})}function Be(e){$t.debug("[RtcSessionController]: send Error event"),we(m.onRtcError,{error:e})}function xe(e){"function"==typeof m.onRtcError&&window.setTimeout(function(){Be(e)},0)}function We(){$t.debug("[RtcSessionController]: send MediaUpdate event"),we(m.onMediaUpdate,{})}function Ye(){$t.debug("[RtcSessionController]: send RemoteStreams event"),we(m.onRemoteStreams,{audio:H,video:G})}function Ke(e){return e?e===y?a.main:e===b?a.screenControl:null:null}function qe(e,t,n){e&&(e===y?a.main[t]=n:a.screenControl[t]=n)}function je(e,t){return e?e===y?a.main[t]:a.screenControl[t]:null}function Qe(e){var t=je(e,"candidatesTimer");t&&(window.clearTimeout(t),qe(e,"candidatesTimer",null))}function Xe(e){var t=je(e,"connectedTimer");t&&(window.clearTimeout(t),qe(e,"connectedTimer",null))}function ze(e){var t=Ke(e);t&&(t.collectCandidatesTimeout&&(window.clearTimeout(t.collectCandidatesTimeout),delete t.collectCandidatesTimeout),t.relayRtpCandidateTimeout&&(window.clearTimeout(t.relayRtpCandidateTimeout),delete t.relayRtpCandidateTimeout),t.sentIceCandidates=[],t.pendingCandidates&&delete t.pendingCandidates,t.queuedCandidates&&delete t.queuedCandidates,t.hasRelayRtpCandidate=!1,t.sendAllCandidates=!1)}function Je(e,t){$t.debug("[RtcSessionController]["+o+"]: "+e,t)}function $e(e,t){$t.warn("[RtcSessionController]["+o+"]: "+e,t)}function Ze(e,t){$t.error("[RtcSessionController]["+o+"]: "+e,t)}function et(e,t){return!!e&&(t?"offer"===t&&je(e,"trickleIceForOffer")||"answer"===t&&je(e,"trickleIceForAnswer"):je(e,"trickleIceForOffer")||je(e,"trickleIceForAnswer"))}function tt(e,t){var n=t&&en.isTrickleIceOption(t);return n&&$t.debug("[RtcSessionController]: SDP "+e+" indicates support for Trickle-ICE."),!!n}function nt(e){return e&&e===b?b.connected:!y||y.connected}function it(){return(!y||y.endOfCandidates)&&(!b||b.endOfCandidates)}function rt(t){if(t=t||y)if(Xe(t),nt(t))gt(nn.Connected,t);else{var e=z?r:i;$t.debug("[RtcSessionController]: Starting ICE CONNECTED timer");var n=window.setTimeout(function(){qe(t,"connectedTimer",null);var e=je(t,"sdpStatus");if("connected"===t.iceConnectionState||"completed"===t.iceConnectionState)return $t.debug("[RtcSessionController]: Missed iceConnectionState=connected event but media is connected"),t.connected=!0,gt(nn.Connected,t),void He(t,Ue(t));e!==nn.AnswerSent&&e!==nn.AnswerReceived&&e!==nn.AnswerApplied||nt(t)||(z?gt(nn.Connected,t):($t.warn("[RtcSessionController]: Timed out waiting for connected state."),ft(t)))},e);qe(t,"connectedTimer",n)}else $e("Terminating waitConnectedState for non existing pc.")}function ot(){c&&($t.debug("[RtcSessionController]: Closing the pre-allocated peer connection"),qe(y,"nextPcLocalSdpSetAt",0),at(c),c=null)}function at(e,t){ye(e,t),e&&(e.iceDisconnectTimeout&&(window.clearTimeout(e.iceDisconnectTimeout),delete e.iceDisconnectTimeout),_.closePc(e))}function st(e){if(!e)return!1;var t=e.getLocalStreams();if(!tn.isEmptyArray(t))return!0;$t.debug("[RtcSessionController]: Add local streams to "+(e===y?"existing":"next")+" peer connection");try{P[g]&&e.addStream(P[g],bt(),Ae),$t.debug("[RtcSessionController]: Added local audio/video stream"),P[u]&&(P[u].isScreen=!0,e.addStream(P[u],bt(),Ae),$t.debug("[RtcSessionController]: Added local screenshare stream"))}catch(e){return $t.error("[RtcSessionController]: Failed to add Local Streams ",e),!1}return!0}function ct(){$t.debug("[RtcSessionController]: Remove local streams from existing PeerConnections");try{[y].forEach(function(n){n&&n.getLocalStreams().forEach(function(e,t){e&&(n.removeStream(e),$t.debug("[RtcSessionController]: Removed PeerConnection Stream #",t))})})}catch(e){return $t.error("[RtcSessionController]: Failed to remove Local Streams ",e),!1}return!0}function lt(e){e&&(e.oninactive=null,0"),w=n[1],$t.debug("[RtcSessionController]: Set local desktop stream to ",_.getStreamId(w)||""),$t.debug("[RtcSessionController]: send LocalVideoStream event"),we(m.onLocalVideoStream,{stream:w||t,videoStream:t,desktopStream:w}),We())}function Et(e,t){if(t===g||t===u){if(P[t]!==e){var n,i,r;if(P[t]&<(P[t]),P[t]=e,t===g&&K.video){if(K.hdVideo){if(K.videoResolution){var o=Rn.sdpParameters.hdVideo[K.videoResolution];n=o&&o.maxBw}i="hdVideo",r=zt.VideoQuality.HIGH}else i="video",r=zt.VideoQuality.NORMAL;n||(n=Rn.sdpParameters[i].maxBw)}else t===u&&K.desktop&&(i=K.hdDesktop?"hdScreenShare":"screenShare",n=Rn.sdpParameters[i].maxBw,K.remoteControlEnabled&&(n=Math.max(n,Rn.sdpParameters.rcScreenShare.maxBw)));if(e&&0(p.minBitRate||0)&&(p=T,$t.debug("[RtcSessionController]: Using X-Google parameters from screenshare: ",p))}en.setXGoogle(t,p),C&&T&&!_.unifiedPlanEnabled&&en.setXGoogle(t,T,C)}if(en.setOpusParameters(t,Rn.sdpParameters.audio),F!==(F=!!en.isHold(t)&&("offer"===n||!B&&K.audio))&&(F?$t.info("[RtcSessionController]: The client has been held"):$t.info("[RtcSessionController]: The client has been retrieved")),f){var I=t.m[0];if(I&&"audio"===I.media)I.a.some(function(e){return"mid"===e.field})||(Se=Se||"audio",$t.debug("[RtcSessionController]: Adding a=mid:"+Se+" to SBC's answer SDP"),I.a.push({field:"mid",value:Se}))}var A=je(e,"sdpStatus");return"offer"!==n||A!==nn.Connected||B||F||(G.length&&!s?($t.debug("[RtcSessionController]: send RemoteVideoRemoved event"),we(m.onRemoteVideoRemoved,{})):!G.length&&s&&($t.debug("[RtcSessionController]: send RemoteVideoAdded event"),we(m.onRemoteVideoAdded,{}))),B||"answer"===n&&a||(k={audio:!0,video:s}),Ie=h&&"offer"===n&&en.isMultiplexEnabled(t),t}function Ot(){var e=Rn.candidatesTimeout||rn;return 0=i.Threshold[0]?n.rtt:-1,o.startTime,n,t),(t=t||n).isAudioChannel?(i=Z.GOOG_RTT,w(o,i,ne.AUDIO,n.rtt)):t.isVideoSendChannel&&(i=ee.GOOG_RTT,w(o,i,ne.VIDEO,n.rtt)),I[e]=r})}(e),t=V(e),function(n){Object.keys(n.channelInfo).forEach(function(e){var t=T[e]||{};T[e]=Object.assign(t,n.channelInfo[e])})}(e),function(e,t){if(!a)return;(f=f||{})[t]=f[t]||{qualityData:[]},f[t].trackId=e[t].trackId,v[t]&&v[t].count>=i?W(t):function(n,i){var r=v[i];r||(r={count:0},_.forEach(function(e){r[e.StatName]=0}),v[i]=r);_.forEach(function(e){var t=n[i][e.id]&&n[i][e.id].value||0;r[e.StatName]+=t}),r.count++,0===f[i].qualityData.length&&W(i)}(e,t)}(e.quality,ne.AUDIO),!t&&A&&(j.debug("[CallStatsHandlerUnified]: processRTPStats - No quality issues detected. Clear threshold exceeded error."),A=!1,N.onThresholdExceeded&&N.onThresholdExceeded(!0)),!A&&E%n!=0||function(i){var r,o;function a(e){return void 0===e||e<0?"n/a":e}Object.keys(i.channelInfo).forEach(function(n){var e=i.channelInfo[n];r="[CallStatsHandlerUnified]: statsReport: channelRtt="+(0<=e.rtt?e.rtt:"n/a"),Object.keys(i.audio.receive).forEach(function(e){var t=i.audio.receive[e];t.channelId===n&&(r+="\n audioReceive: id="+t.id+" pl="+a(t.pl)+" pr="+a(t.pr)+" or="+a(t.or)+" jr="+a(t.jr))}),Object.keys(i.audio.transmit).forEach(function(e){var t=i.audio.transmit[e];t.channelId===n&&(r+="\n audioTransmit: id="+t.id+" pl="+a(t.pl)+" ps="+a(t.ps)+" os="+a(t.os))}),Object.keys(i.video.receive).forEach(function(e){var t=i.video.receive[e];t.channelId===n&&(r+="\n videoReceive: id="+t.id+" pl="+a(t.pl)+" pr="+a(t.pr)+" or="+a(t.or)+" fwr="+t.fwr+" fhr="+t.fhr+" frd="+t.frd+" frr="+t.frr)}),Object.keys(i.video.transmit).forEach(function(e){var t=i.video.transmit[e];t.channelId===n&&(r+="\n videoTransmit: id="+t.id+" pl="+a(t.pl)+" ps="+a(t.ps)+" os="+a(t.os)+" fws="+t.fws+" fhs="+t.fhs+" frs="+t.frs+" abw="+(i.video.bw&&i.video.bw.abw||"N/A"))}),j.debug(r)}),r="[CallStatsHandlerUnified]: statsReport:\n",[p,S,I].forEach(function(n,e){switch(0=t.statObj.RecurrenceThreshold?t.reported?(delete n[e],j.debug("[CallStatsHandlerUnified]: issueCounter cleared=",e)):(t.reported=!0,t.counter=0,(r=r||{})[e]=!0):t.reported&&((r=r||{})[e]=!0)})}),r}function W(r){var o=function(e){var n=v[e];if(v[e]=null,!n||!n.count)return null;var i=n.count;return delete n.count,_.forEach(function(e){var t=n[e.StatName];e.StatName===Z.PACKET_LOSS_RECV.StatName&&(t*=100),n[e.StatName]=Math.round(t/i)}),n.timestamp=Date.now(),n}(r);o&&_.some(function(e){var t=e.StreamQualityThreshold,n=o[e.StatName]||0,i=function(e,t){var n=f[e].qualityData;return n&&n.length&&n[n.length-1][t.StatName]||0}(r,e);return(0===f[r].qualityData.length||Math.abs(i-n)>t)&&(j.debug("[CallStatsHandlerUnified]: Writing into clientStreamQualityData - ",o),f[r].qualityData.push(o),!0)})}this.start=function(){s||l||(j.debug("[CallStatsHandlerUnified]: Waiting to start collecting RTPstats"),s=window.setTimeout(function(){j.info("[CallStatsHandlerUnified]: Start collecting RTPStats"),s=null,E=0,B(),l=window.setInterval(function(){B()},X.COLLECTION_INTERVAL)},X.DELAY_UPON_ANSWER))},this.stop=function(){return function(){j.debug("[CallStatsHandlerUnified]: stopCollectingRTPStats ",f);var e=P(!0);return W(ne.AUDIO),s?(j.debug("[CallStatsHandlerUnified]: Cancel collecting RTP stats "),window.clearTimeout(s),s=null):l&&(j.debug("[CallStatsHandlerUnified]: Stop collecting RTP stats"),window.clearInterval(l),l=null,C&&j.debug("[CallStatsHandlerUnified]: savedRTPStats =",C),N.onThresholdExceeded&&N.onThresholdExceeded(!0),A=!1),e}()},this.onThresholdExceeded=null,this.onNoOutgoingPackets=null,this.onNetworkQuality=null,this.setOptions=function(e){e&&(c=e)},this.getLastSavedStats=function(){return C.channelInfo=T,C},this.getStreamQualityData=function(){return f},this.setTransmitVideoParams=function(t){if(t){if(t.mediaConstraints&&t.mediaConstraints.hdVideo){var e,n;switch(t.mediaConstraints.videoResolution||J.VIDEO_1080){case J.VIDEO_1080:e=1080,n=1920;break;case J.VIDEO_720:e=720,n=1280;break;default:e=480,n=853}g.FRAME_RATE_SENT.Threshold=[20,8,3],g.FRAME_HEIGHT_SENT.Threshold=[.9*e,.75*e,.5*e],g.FRAME_WIDTH_SENT.Threshold=[.9*n,.75*n,.5*n];var i=1e3*(t.bitRates.maxBitRate||0),r=1e3*(t.bitRates.minBitRate||0),o=.75*i;o=t.statObj.RecurrenceThreshold?t.reported?(delete n[e],y.debug("[CallStatsHandler]: issueCounter cleared=",e)):(t.reported=!0,t.counter=0,(i=i||{})[e]=!0):t.reported&&((i=i||{})[e]=!0)}),i}this.start=function(){n||i?(y.debug("[CallStatsHandler]: Restart collecting RTPStats"),C=E=d=null,T=!1):(y.debug("[CallStatsHandler]: Waiting to start collecting RTPstats"),n=window.setTimeout(function(){y.info("[CallStatsHandler]: Start collecting RTPStats"),n=null,I=0,c(),i=window.setInterval(function(){c()},U.COLLECTION_INTERVAL)},U.DELAY_UPON_ANSWER))},this.stop=function(){return new l(function(t){a(!0).then(function(e){t(e)}),n?(y.debug("[CallStatsHandler]: cancel collecting RTPStats "),window.clearTimeout(n),n=null):i&&(y.debug("[CallStatsHandler]: stop collecting RTPStats"),window.clearInterval(i),C=E=d=i=null,T=!1,A&&y.debug("[CallStatsHandler]: savedRTPStats =",A),g.onThresholdExceeded&&g.onThresholdExceeded(!0),p=!1)})},this.onThresholdExceeded=null,this.onNoOutgoingPackets=null,this.onNetworkQuality=null,this.setOptions=function(e){e&&(S=e)},this.getLastSavedStats=function(){return A},this.getStreamQualityData=function(){return null},this.setTransmitVideoParams=function(){}}return t.overridePromise=function(e){void 0===l&&(l=e)},P.CallStats=d,P.CallStatsHandler=t,P}((Circuit=function(d){"use strict";var u=d.AppMessagingHandlerSingleton,E=d.ChromeExtension,C=d.Constants,T=d.logger,p=d.Utils,S=d.TemasysAdapter,e=function(){var i=u?u.getInstance():null,e={getScreen:function(e,t){t&&t("NOT_SUPPORTED")},setControllingScreen:function(e,t){t&&t("NOT_SUPPORTED")},unregEvtHandlers:function(){},isScreensharingAvailable:function(){return!1},isFirefoxLegacy:function(){return!1},installExtension:function(){},injectExtensionSvc:function(){},injectTemasysSvc:function(){}},t=p.getBrowserInfo();function n(t,n){navigator.mediaDevices.getDisplayMedia({video:!0}).then(function(e){t({mediaStream:e})}).catch(function(e){"NotAllowedError"!==e.name||e.message&&"permission denied by system"===e.message.toLowerCase()?n(e):n(C.ReturnCode.CHOOSE_DESKTOP_MEDIA_CANCELLED)})}if(d.isElectron)e.getScreen=function(i,r,e){var t=require("electron").ipcRenderer;t.once("screenshare-chooser",function(e,t,n){"share"===t?(T.info("[ScreenSharingController]: Got screen share stream. Stream id: ",n.display.streamId),i&&i({screenIndex:n.display.screenIndex,streamId:n.display.streamId,pointer:n.pointer,screenControlSupported:n.screenControlSupported})):"cancel"===t&&(T.info("[ScreenSharingController]: User canceled screen share"),r&&r(C.ReturnCode.CHOOSE_DESKTOP_MEDIA_CANCELLED))}),T.info("[ScreenSharingController]: Request screen in Electron"),t.send("screenshare-chooser","open",e)},e.isScreensharingAvailable=function(){return!0},e.setControllingScreen=function(){require("electron").ipcRenderer.send("screenshare-chooser","setControllingScreen")};else if(d.isVdiApp)e.getScreen=function(t,n){i.sendInternalMessage({method:"showwindow"}),window.setTimeout(function(){chrome.desktopCapture.chooseDesktopMedia(["screen"],null,function(e){i.sendInternalMessage({method:"minimizewindow"}),e?t&&t({streamId:e}):n&&n(C.ReturnCode.CHOOSE_DESKTOP_MEDIA_CANCELLED)})},0)},e.isScreensharingAvailable=function(){return!0};else if(t.chrome)if(navigator.mediaDevices.getDisplayMedia)e.getScreen=n,e.isScreensharingAvailable=function(){return!0};else{var r,o,a,s=function(e){e&&e===o&&r&&o&&(r.removeEventListener(E.BgTarget.SCREEN_SHARE,o),o=null)},c=function(e,t){return r?(s(o),o=function(e,t,n){var i=n.data;switch(n.suppressLog||T.info("[ScreenSharingController]: Received screenshare event from extension - ",i.type),i.type){case E.BgScreenShareMsgType.CHOOSE_DESKTOP_MEDIA_DONE:T.info("[ScreenSharingController]: CHOOSE_DESKTOP_MEDIA done. Stream Id:",i.streamId),s(o),e&&e({streamId:i.streamId});break;case E.BgScreenShareMsgType.CHOOSE_DESKTOP_MEDIA_CANCELLED:T.info("[ScreenSharingController]: CHOOSE_DESKTOP_MEDIA cancelled"),s(o),t(C.ReturnCode.CHOOSE_DESKTOP_MEDIA_CANCELLED)}}.bind(null,e,t),r.addEventListener(E.BgTarget.SCREEN_SHARE,o),o):null};e.getScreen=function(e,t){var n=null;return a&&a.isExtensionRunning()?(n=c(e,t),r.getScreenShareUserMedia(function(e){e&&(T.warn("[ScreenSharingController]: Error starting screen share using chrome extension: ",e),s(n),t("res_AccessToExtensionFailed"))})):t("res_AccessToExtensionFailed"),n},e.isScreensharingAvailable=function(){return!!a&&a.isExtensionRunning()},e.installExtension=function(){a&&(T.debug("[ScreenSharingController]: Install Chrome extension"),a.installExtension(!0).then(function(){T.info("[ScreenSharingController]: Chrome extension was successfully installed")}).catch(function(e){T.warn("[ScreenSharingController]: Failed to install Chrome extension. ",e)}))},e.injectExtensionSvc=function(e,t){a=e,r=t},e.unregEvtHandlers=s}else if(t.msie){var l;e.getScreen=function(e,t){S&&S.isScreensharingAvailable()?e&&e():t&&t("NOT_AVAILABLE")},e.isScreensharingAvailable=function(){return!!S&&S.isScreensharingAvailable()},e.installExtension=function(){l&&l.showPopup()},e.injectTemasysSvc=function(e){l=e}}else t.firefox?(navigator.mediaDevices.getDisplayMedia?e.getScreen=n:(e.getScreen=function(e){e&&e()},e.isFirefoxLegacy=function(){return!0}),e.isScreensharingAvailable=function(){return!0}):"Android"!==window.navigator.platform&&"iOS"!==window.navigator.platform||(e.getScreen=function(e){e&&e()},e.isScreensharingAvailable=function(){return!0});return e}();return d.ScreenSharingController=e,d}((Circuit=function(w){"use strict";var G=w.logger,e=w.BaseCall,H=w.Enums.CallState,k=w.Constants,t=w.Enums.CstaCallState,V=w.Constants.IncomingVideoContentType,n=w.Enums.ParticipantState,F=w.Constants.RealtimeMediaType,B=w.Utils,i=Object.freeze({SERVER_ENDED_PRFX:"SERVER_ENDED:"}),r=Object.freeze({CLIENT_ENDED_PRFX:"CLIENT_ENDED:",ANOTHER_CLIENT_ANSWERED:"ANOTHER_CLIENT_ANSWERED",ANOTHER_CLIENT_REJECTED:"ANOTHER_CLIENT_REJECTED",ANOTHER_CLIENT_PULLED_CALL:"ANOTHER_CLIENT_PULLED_CALL",CALL_MOVED_TO_ANOTHER_CONV:"CALL_MOVED_TO_ANOTHER_CONV",CALLER_LEFT_CONFERENCE:"CALLER_LEFT_CONFERENCE",ENDED_BY_ANOTHER_USER:"ENDED_BY_ANOTHER_USER",LOST_WEBSOCKET_CONNECTION:"LOST_WEBSOCKET_CONNECTION",NO_USERS_LEFT:"NO_USERS_LEFT",REQUEST_TO_SERVER_FAILED:"REQUEST_TO_SERVER_FAILED",RTC_SESSION_START_FAILED:"RTC_SESSION_START_FAILED",SET_REMOTE_SDP_FAILED:"SET_REMOTE_SDP_FAILED",USER_ENDED:"USER_ENDED",LOST_MEDIA_STREAM:"LOST_MEDIA_STREAM",ICE_TIMED_OUT:"ICE_TIMED_OUT",USER_LOGGED_OUT:"USER_LOGGED_OUT",PAGE_UNLOADED:"PAGE_UNLOADED",DISCONNECTED:"WS_DISCONNECTED",FAILED_TO_SEND:"WS_FAILED_TO_SEND",REQUEST_TIMEOUT:"WS_REQUEST_TIMEOUT",MEDIA_RENEGOTIATION:"MEDIA_RENEGOTIATION"}),x=B.isMobile();function W(e,t){var o=w.WebRTCAdapter;t=t||{};var a=w.RtcSessionController;if(!e||!e.rtcSessionId)throw new Error("Cannot create LocalCall object without a valid conversation");W.parent.constructor.call(this,e,!1);var s=this,r=null,n=!1,i=null,c=!1,l=!1,d=!1,u=!1,E=!1,C=!1,T=!1,p=!1,S=null,I=null,A=null,R=null,f=!1,v=[],_=[],g=[],N="",m="",h=!1,O={},D=null;function P(){r?(G.debug("[LocalCall]: RtcSessionController - onMediaUpdate: callId =",s.callId),s.activeMediaType=r.getActiveMediaType(),G.debug("[LocalCall]: Set active media type to ",s.activeMediaType),s.localMediaType=r.getMediaConstraints(),G.debug("[LocalCall]: Set local media type to ",s.localMediaType),s.updateMediaType(),s.updateCallState(),L(F.VIDEO),L(F.DESKTOP_SHARING)):G.debug("[LocalCall]: session controller not available - onMediaUpdate: callId =",s.callId)}function y(e){G.debug("[LocalCall]: RtcSessionController - onLocalVideoStream: callId =",s.callId),s.localVideoStream=e.stream,s.localStreams.desktop=e.desktopStream,s.localStreams.video=e.videoStream,N="",G.debug("[LocalCall]: Set local video stream to ",e.videoStream&&e.videoStream.id||""),G.debug("[LocalCall]: Set local desktop stream to ",e.desktopStream&&e.desktopStream.id||"")}function b(e){G.debug("[LocalCall]: RtcSessionController - onScreenSharePointerStatus",e),s.pointer={isSupported:e.isSupported,isEnabled:e.isEnabled}}function U(e){G.debug("[LocalCall]: RtcSessionController - onRemoteStreams: callId =",s.callId),s.remoteAudioStream=e.audio&&e.audio.stream||null,m="",G.debug("[LocalCall]: Set remote audio stream to",s.remoteAudioStream&&s.remoteAudioStream.id||""),s.remoteVideoStreams=e.video||[],G.debug("[LocalCall]: Set remote video streams to",e.video||""),s.participants.forEach(function(e){s.setParticipantRemoteVideoStream(e)}),s.checkForActiveRemoteVideo()}function L(e){var t=r.getAvailableVideoReceivers(e),n=[],i=O[e]||[];t.forEach(function(t){var e=i.find(function(e){return e.id===t.id});e||((e=t).pinnedUser=null,e.quality=k.VideoQuality.NORMAL,e.disabled=!1),n.push(e)}),O[e]=n,G.debug("[LocalCall] Updated video receiver configuration for media type "+e+" is ",n)}function M(){var n=[];return Object.keys(O).forEach(function(e){var t=O[e];t&&((d||e===F.VIDEO&&u)&&(t=JSON.parse(JSON.stringify(t))).forEach(function(e){e.disabled=!0}),Array.prototype.push.apply(n,t))}),n}Object.defineProperties(this,{sessionCtrl:{get:function(){return r},enumerable:!0,configurable:!1},isVdi:{get:function(){return!(!r||!r.isRemoteController)},enumerable:!0,configurable:!1},locallyMuted:{get:function(){return!(!r||!r.isMuted())},enumerable:!0,configurable:!1},remoteVideoDisabled:{get:function(){return d},enumerable:!0,configurable:!1},remoteVideoScreenOnlyAllowed:{get:function(){return u},enumerable:!0,configurable:!1},remoteAudioDisabled:{get:function(){return E},enumerable:!0,configurable:!1},isMocked:{get:function(){return T},enumerable:!0,configurable:!1},isMeetingPointInvited:{get:function(){return p},enumerable:!0,configurable:!1},hasActiveRemoteScreenShareOnly:{get:function(){return l},enumerable:!0,configurable:!1},ringAllAllowed:{get:function(){return!!(this.peerUsers&&0this.RTP_QUALITY_LOW.threshold?this.RTP_QUALITY_LOW:e>this.RTP_QUALITY_MEDIUM.threshold?this.RTP_QUALITY_MEDIUM:this.RTP_QUALITY_HIGH}}),l={COLLECTION_INTERVAL:5e3,DELAY_UPON_ANSWER:e.isMobile()?0:5e3,DELAY_RTT_PROCESSING:3},v=function(e){if(e)try{e.oninactive=null;var t=function(e){return"function"==typeof e.getTracks?e.getTracks():e.getAudioTracks().concat(e.getVideoTracks())}(e);t.length&&t[0].stop?t.forEach(function(e){e.stop(),R.debug("[WebRTCAdapter]: Media track has been stopped:",e.label)}):e.stop&&e.stop(),R.info("[WebRTCAdapter]: Media stream has been stopped. Stream ID:",e.id)}catch(e){R.error("[WebRTCAdapter]: Failed to stop media stream. ",e)}},_=function(e){if(e)try{var t=e.getVideoTracks();t?t.forEach(function(e){e.stop&&"video"===e.kind&&!e.remote&&e.stop()}):R.info("[WebRTCAdapter]: No video tracks to be changed")}catch(e){R.error("[WebRTCAdapter]: Failed to disable local video tracks. ",e)}},g=function(e){try{e.close(),R.debug("[WebRTCAdapter]: RTCPeerConnection has been closed")}catch(e){R.error(e)}},N=function(){return!!navigator.mediaDevices&&"function"==typeof navigator.mediaDevices.enumerateDevices&&"undefined"!=typeof HTMLMediaElement&&"function"==typeof HTMLMediaElement.prototype.setSinkId},d=[],u=null,E=null,m=function(e){if("function"==typeof e){var i,r,o;if(R.debug("[WebRTCAdapter]: Get audio output, microphone and camera devices"),!navigator.mediaDevices||!navigator.mediaDevices.enumerateDevices)return i=[{kind:"audio",id:"default",label:"",facing:""}],o=[{kind:"video",id:"default",label:"",facing:""}],void window.setTimeout(function(){e(i,o,null)},0);if(0Date.now())return R.debug("[WebRTCAdapter]: Return cached devices"),i=E.audioSources,r=E.audioOutputs,o=E.videoSources,void window.setTimeout(function(){e(i,o,r)},0);var t=function(t,n,i){a();var e=d;d=[],e.forEach(function(e){try{e(t||[],n||[],i||null)}catch(e){}})}.bind(null);d.push(e),R.debug("[WebRTCAdapter]: Invoke MediaDevices.enumerateDevices()"),a(),u=window.setTimeout(function(){u=null,d.length&&(E?(R.error("[WebRTCAdapter]: MediaDevices.enumerateDevices timed out. Return cached devices."),i=E.audioSources,r=E.audioOutputs,o=E.videoSources):R.error("[WebRTCAdapter]: MediaDevices.enumerateDevices timed out. Device cache is empty, no devices available!"),t(i,o,r),t=null)},3e3),navigator.mediaDevices.enumerateDevices().then(function(e){e=e||[],i=[],r=[],o=[],R.info("[WebRTCAdapter]: MediaDevices.enumerateDevices returned "+e.length+" device(s)"),e.forEach(function(e){var t={id:e.deviceId,groupId:e.groupId,kind:e.kind,label:e.label};if(t.label){var n=t.label.match(/(.*)\s\(.*:.*\)/);t.label=n&&n[1]||t.label}switch(I.isElectron&&("default"!==t.id||t.label||(t.label="res_DefaultDeviceLabel")),t.kind){case"audioinput":i.push(t);break;case"audiooutput":r.push(t);break;case"videoinput":o.push(t)}}),0!==r.length&&N()||(r=null),R.debug("[WebRTCAdapter]: Update DeviceInfos cache"),E={audioSources:i,audioOutputs:r,videoSources:o},i.length?!i.some(function(e){return e.label})||o.length&&!o.some(function(e){return e.label})?(R.debug("[WebRTCAdapter]: User hasn't authorized access to audio and/or video input devices yet"),E.validTimestamp=0):E.validTimestamp=Date.now()+6e4:E.validTimestamp=0,t&&t(i,o,r)}).catch(function(e){R.error("[WebRTCAdapter]: Failed to enumerate devices. ",e),t&&t()})}},h=function(){R.debug("[WebRTCAdapter]: Cleared device info cache"),E=null},O=function(e){if(e&&e.iceServers){var n=[];e.iceServers.forEach(function(t){t.url?n.push(t):t.urls&&t.urls.forEach(function(e){n.push({url:e,credential:t.credential,username:t.username})})}),e.iceServers=n}},D=function(e,t){var n=[{autoGainControl:!!(e=e||{}).enableAudioAGC},{echoCancellation:!0}];return t?{advanced:n}:{optional:n}},P=function(e){return{optional:[{echoCancellation:!0},{googEchoCancellation:!0},{googEchoCancellation2:!0},{autoGainControl:!!(e=e||{}).enableAudioAGC},{googAutoGainControl:!!e.enableAudioAGC},{googAutoGainControl2:!!e.enableAudioAGC},{noiseSuppression:!0},{googNoiseSuppression:!0},{googNoiseSuppression2:!0},{googHighpassFilter:!0}]}},y=function(e){if(I.WebRTCAdapter.useNewConstraintSyntax)return function(e){var t;if(e&&e.videoResolution){switch(t={aspectRatio:{min:1.77,max:1.78},frameRate:{min:24,max:30}},e.minFrameRate&&(t.frameRate.min=Math.min(e.minFrameRate,t.frameRate.max)),e.sourceId&&(t.deviceId={exact:e.sourceId}),e.videoResolution){case c.VIDEO_1080:t.width={min:1920},t.height={min:1080};break;case c.VIDEO_720:t.width={min:1280},t.height={min:720};break;case c.VIDEO_480:t.width={min:854},t.height={min:480}}return t}return t={aspectRatio:{min:1.77,max:1.78}},e.sourceId&&(t.deviceId=e.sourceId),t}(e);var t={mandatory:{minAspectRatio:1.77,maxAspectRatio:1.78},optional:[{googNoiseReduction:!0}]};if(e)if(e.videoResolution)switch(t.mandatory.minFrameRate=24,t.mandatory.maxFrameRate=30,e.minFrameRate&&(t.mandatory.minFrameRate=Math.min(e.minFrameRate,t.mandatory.maxFrameRate)),e.sourceId&&(t.mandatory.sourceId=e.sourceId),e.videoResolution){case c.VIDEO_1080:t.mandatory.minWidth=1920,t.mandatory.maxWidth=1920,t.mandatory.minHeight=1080,t.mandatory.maxHeight=1080;break;case c.VIDEO_720:t.mandatory.minWidth=1280,t.mandatory.maxWidth=1280,t.mandatory.minHeight=720,t.mandatory.maxHeight=720;break;case c.VIDEO_480:t.mandatory.minWidth=853,t.mandatory.maxWidth=854,t.mandatory.minHeight=480,t.mandatory.maxHeight=480}else e.sourceId&&t.optional.push({sourceId:e.sourceId});return t},b=function(e,t){var n=e&&e.getAudioTracks();return!(!n||!n[0])&&(n[0].enabled=!!t,!0)},U=function(a,s,c){if(c=c||function(){},R.debug("[WebRTCAdapter]: Attach sinkId to audio element"),a)return s&&s.length?void(void 0!==a.sinkId&&I.WebRTCAdapter?(R.debug("[WebRTCAdapter]: Get media sources to find available device"),I.WebRTCAdapter.getMediaSources(function(e,t,n){var i=I.Utils.selectMediaDevice(n,s),r=i&&i.id||"";if(R.debug("[WebRTCAdapter]: Found audio output device to attach as sinkId. deviceId = ",r||"NONE"),a.sinkId===r)return R.debug("[WebRTCAdapter]: Audio output device is already attached to element"),void c();r||R.warn("[WebRTCAdapter]: A previously selected output device could not be found. Fallback to browser's default. Device not found: ",a.sinkId);var o=window.setTimeout(function(){o=null,R.error("[WebRTCAdapter]: Timed out attaching audio output device: ",r||""),c("timed out")},3e3);a.setSinkId(r).then(function(){o&&(window.clearTimeout(o),R.debug("[WebRTCAdapter]: Success, audio output device attached: ",r||""),c())}).catch(function(e){if(o){window.clearTimeout(o);var t=(e=e||{}).message||"unknown error";"SecurityError"===e.name&&(t="You need to use HTTPS for selecting audio output device."),R.error("[WebRTCAdapter]: Failed to attach output device. Device Id:"+r+" - ",t),c(t)}}),R.debug("[WebRTCAdapter]: setSinkId has been invoked")})):c("setSinkId not available")):(R.debug("[WebRTCAdapter]: There is no audio output device selected"),void c());c("Invalid parameters")},L=function(e){var t={offerToReceiveAudio:1,offerToReceiveVideo:1};return e&&(e.mandatory&&(e.mandatory.hasOwnProperty("OfferToReceiveAudio")&&(t.offerToReceiveAudio=e.mandatory.OfferToReceiveAudio?1:0),e.mandatory.hasOwnProperty("OfferToReceiveVideo")&&(t.offerToReceiveVideo=e.mandatory.OfferToReceiveVideo?1:0)),e.optional&&e.optional.some(function(e){return!!e.hasOwnProperty("VoiceActivityDetection")&&(t.voiceActivityDetection=!!e.VoiceActivityDetection,!0)})),t},M=function(r,o,a,s,c){function e(t){var e=function(e,t,n,i){if(!e||!e[t])return e;var r=e[t];if(r.mandatory){var o=r.mandatory[n];if(o){var a=(e=Object.create(e))[t];a.optional=a.optional||[];var s={};s[n]=o,a.optional.push(s),delete a.mandatory}}else{var c=r[i];c&&c.exact&&((e=Object.create(e))[t][i]=c.exact)}return e}(a,"audio","sourceId","deviceId");if(e!==a){R.warn("[WebRTCAdapter]: First getUserMedia attempt with required audio sourceId/deviceId failed. Falling back to optional.");var n=function(e){s(e,t)},i=r.apply(o,[e,n,c]);i&&i.then&&i.then(n).catch(c)}else c&&c(t)}var t=r.apply(o,[a,s,e]);t&&t.then&&t.then(s).catch(e)},w=function(t,n,i,r,o){var a=null,s=I.isElectron?1:3,c=0;function l(e){R.warn("[WebRTCAdapter]: Get user media failed: ",e&&e.name||e),a&&window.clearTimeout(a),a=null,o&&o(e),o=r=null}!function e(){R.info("[WebRTCAdapter]: Get user media attempt #:",c),a=null,c!==s?(++c,M(t,n,i,function(e,t){!function(e,t){R.info("[WebRTCAdapter]: Get user media succeeded"),r?r(e,t):v(e),o=r=null}(e,t),a&&window.clearTimeout(a),a=null},l),a=window.setTimeout(e,1e4)):l("Timeout")}()},G=function(e,t){if(e&&t&&t.isScreenControlled)if(R.info("[WebRTCAdapter]: Data channel will be created for supporting screen control"),t.isScreenOwner){var n=(new Date).toISOString(),i=t.screenControlChannelName+"_"+n,r=e.createDataChannel(i,o);s(r,!0),e.ondatachannel=null}else e.ondatachannel=function(e){s(e.channel,!1),this.dataChannel=e.channel,this.sendDataMessage=function(e){if(this.dataChannel&&"open"===this.dataChannel.readyState){var t;return e&&"object"==typeof e?(t=JSON.stringify(e),this.dataChannel.bufferedAmount+t.length=l&&(e+=d-(Date.now()-O[0])),c.info("[CONN]: Start throttle timeout with delay = ",e),P=window.setTimeout(function(){P=null,function(){c.info("[CONN]: Dequeue throttled messages. Number of queued messages = ",D.length),W();var e=0;for(;0=l&&W(),O.length=E?c.error("[CONN]: Throttling queue is full. Drop the message."):(D.push(e),c.info("[CONN]: Queued message #",D.length))}(e),Y())),!0):(c.error("[CONN]: Data is missing. Cannot send message."),!1)},this.injectHasActiveCall=function(e){y="function"==typeof e?e:null}},q.Enums=q.Enums||{},q.Enums.ConnectionState=X,q}((Circuit=function(e){"use strict";var n=e.Utils,i=Object.freeze({TLS:{name:"tls",start:0,end:11e6},TCP:{name:"tcp",start:12e6,end:31e6},UDP:{name:"udp",start:35e6,end:6e7}}),t=Object.freeze({VP8:"VP8",VP9:"VP9",H264:"H264"});function d(e){if(e){var t=(e=e.replace(/(a=)*candidate:([^\r]+)(\r\n)*/i,"$2")).split(" ");if(t.length<7)throw new Error("Invalid candidate: "+e);this.foundation=parseInt(t[0],10),this.componentId=parseInt(t[1],10),this.transport=t[2].toLowerCase(),this.priority=parseInt(t[3],10),this.address=t[4],this.port=parseInt(t[5],10),this.typ=t[7],this.optional=[];for(var n=8;n=e.start&&n<=e.end&&(t=e.name,!0)})}return t},d.prototype.getValue=function(){for(var e=this.foundation+" "+this.componentId+" "+this.transport+" "+this.priority+" "+this.address+" "+this.port+" typ "+this.typ,t=0;t|<]*(?:shortcut|abbr)="(\S*)"[^/?>]*\/?)>/gi;function n(e,t,n){var i=r.EMOTICON_MAPPING[n];return i?String.fromCodePoint(i):""}return r.standardizeEmoticon=function(e){return e?e.replace(t,n):""},r.removeMentionHtml=function(e){var i=0;return e.replace(/()|(<\/span>)/gi,function(e,t,n){return t?t.match(/class="mention"/i)?"":(i++,t):n&&i?(i--,n):""})},e}((Circuit=function(a){"use strict";a.__server="",a.__domain="",a.isElectron=!(a.isSDK||"undefined"==typeof process||!process.versions||!process.versions.electron);var t,c=a.logger,l=a.Emoticons,d=a.Emoji;if(a.isElectron){var e=(t=require("electron").remote).getCurrentWindow();a.__server=e._domain||"",a.__sotelUser=!!e._sotelUser,a.productName=e._productName||"Circuit",a.productBrand=e._productBrand||""}else a.productName="string"==typeof __productName?__productName:"Circuit",a.productBrand="string"==typeof __productBrand?__productBrand:"";"undefined"!=typeof Skype&&(a.SkypeSDK=Skype,Skype=null);var u="https://",E="circuit://",C=/<(img[^>|<]*(?:shortcut|abbr)="(\S*)"[^/?>]*\/?)>/gi,T=a.Utils||{};var n="(?:[\\w@'^=$%&\\/~+\\{\\}\\-\\|.,?!:\\[\\]\\(\\)#]*[\\w@'^=$%&\\/~+\\{\\}\\-\\|#])?",i=["items","parents","peerUsers","previousMembers"];T.trimCallForMobile=function(e){var t;return e&&(t=T.flattenObj(e)),t},T.trimConvForMobile=function(e){var t;return e&&(t=T.flattenObj(e),i.forEach(function(e){delete t[e]}),t.call=T.trimCallForMobile(e.call)),t},T.isPromise=function(e){return!(!e||"function"!=typeof e.then)},T.convertVersionToNumber=function(e){if("string"!=typeof e)return 0;var t=e.split("."),n=parseInt(t[0],10)||0,i=parseInt(t[1],10)||0;i=Math.min(i,99);var r=parseInt(t[2],10)||0;return(r=Math.min(r,9999))+1e4*i+1e6*n},T.trimTextWithEmoticonsBeforeMatch=function(e,t,n){for(var i=e.indexOf(t),r=e.slice(i),o=e.slice(0,i),a=String.fromCharCode(17),s=String.fromCharCode(18),c=o.replace(C,function(e,t){return a+t+s}),l=!0,d=c.length-1,u=c.length-1,E=u;o.length-1-d<=n&&0<=u;)18===c.charCodeAt(u)?(c=c.replaceAt(u,">"),l=!1):17===c.charCodeAt(u)&&(c=c.replaceAt(u,"<"),l=!0),E=u,u--,l&&d--;return(o=0/i)||0<=e.search(/<[^>]*?style=[^>]*?mso-[^<]+?>/i)||0<=e.search(/]*?Microsoft/i)},T.isXCodeDoc=function(e){return 0<=e.search(/]*?Cocoa[^<]+?>/)},T.isYourCircuitDomain=function(){var e=a.isElectron?a.__server:window.location.host;return-1!==["eu.yourcircuit.com","na.yourcircuit.com"].indexOf(e)},T.isIntegrationsSupported=function(){var e=a.isElectron?a.__server.split(":")[0]:window.location.hostname;return["tandi.circuitsandbox.net","adfs01.circuitsandbox.net","circuitsandbox.net","beta.circuit.com","eu.yourcircuit.com","na.yourcircuit.com","circuitdev.unify.com"].includes(e)},T.sanitizer=null,T.sanitize=function(t){if(!t||!T.sanitizer)return t||"";try{t=(t=(t=(t=t.replace(/style="background-color: rgb\(212, 239, 181\);"/gi,'class="rich-text-highlight"')).replace(/<[^>]+background-color: rgb\(212, 239, 181\);.*?>/gi,function(e){return e.includes("class=")?e.replace(/class=".*?"/gi,function(e){return e.includes("rich-text-highlight")?e:e.replace(/[^=]\s*(.*)/gi,function(e){return e.slice(0,-1)+" rich-text-highlight"})}):e.replace(">",function(e){return' class="rich-text-highlight" '+e})})).replace(/]*class="(emoticon-icon|emojione-icon))[^>]*>/gi,"")).replace(/]*>([\s\S]*?)<\/title>/gi,""),t=(t=(t=(t=(t=l?l.normalizeEmoticonHtml(t):t).replace(/]*>|<\/font>/gi,"")).replace(/(<\s*hr\s*><\s*\/hr\s*>|<\s*hr\s*>)/gi,"
")).replace(/(\r|\n)+(?=[^<]*?>)/gi," ")).replace(/\r\n|\r|\n/g,"
"),"function"==typeof T.sanitizer&&(t=T.sanitizer(t));var e=t.split(/<\/?div.*?>|<\/?p.*?>/g).filter(function(e){return!!e}),n=e.length,i="";if(1(?![\s\S]*
)(?=(<[^/][^>]*><\/[^>]*>)*$|(<\/[^>]*>)*$|$)/i,s=0;s)|()|())*(
|)(<\/span>|<\/b>|<\/i>)*/g,"
"),!o||o.endsWith("")||o.endsWith("")||a.test(o)||(i+="
"),i+=r,o=r;else i=e[0];t=i}catch(e){return c.error("[Utils]: Error sanitizing content. ",e),c.error("[Utils]: Unexpected content: ",t),""}return t||""},T.sanitizeSymbols=function(e){return T.isMobile()&&"undefined"!=typeof he?e&&he.encode(e,{allowUnsafeSymbols:!0,decimal:!0}):e},T.convertSymbolCodes=function(e){return T.isMobile()?e&&e.replace(d.HTML_ENTITY_REGEX,function(e){return function(e){var t=e.replace(/[&#;]/g,"");if(!/^[0-9]+$/.test(t)||55296<=t&&t<=57343||1114111>>10&1023|55296),t=56320|1023&t),n+=String.fromCharCode(t)}(e)}):e},T.retrieveTextOnly=function(e,t){if(!e||"PLAIN"===t)return e;e=(e=(e=(e=(e=e.replace(Circuit.Emoticons.HTML_REGEX,"")).replace(/&#\d+;/g,"")).replace(/.*?>/g,"")).replace(T.URL_PATTERN,"")).replace(T.PSEUDO_URL_PATTERN,"");var n=document.createElement("div");return n.innerHTML=e.replace(/<(br[/]?|\/li|hr[/]?)>/gi," "),n.textContent.trim()},T.toPlainText=function(e,t){if(!e||t&&"RICH"!==t)return e;l&&(e=e.replace(l.HTML_REGEX,function(e,t){return l.isEmoticonContent(e)?t:e}));var n=document.createElement("div");return n.innerHTML=e.replace(/<(br[/]?|\/li|hr[/]?)>/gi," "),n.textContent},T.toPlainTextWithEmoticonHtml=function(e,t){if(!e||t&&"RICH"!==t)return e;var n=String.fromCharCode(17),i=String.fromCharCode(18);e=e.replace(l.HTML_REGEX,function(e,t){return l.isEmoticonContent(e)?n+t+i:e}),e=d.convertEmojis(e);var r=String.fromCharCode(19),o=String.fromCharCode(20);e=e.replace(d.HTML_REGEX,function(e,t){return d.isEmojiContent(e)?r+t+o:e});var a=document.createElement("div");a.innerHTML=e.replace(/<(br[/]?|\/li|hr[/]?)>/gi," ");var s=T.textToHtmlEscaped(a.textContent,!0);return(s=s.replace(/\x11([^\x11\x12]*)\x12/gim,function(e,t){return l.getHtmlFromShortcut(t,!1,!0,!0)})).replace(/\x13([^\x13\x14]*)\x14/gim,function(e,t){return d.convertEmojis(t.replace(/&/g,"&"))})},T.truncateFileName=function(e){return!e||e.length<=22?e:e.substring(0,10)+" ..."+e.substring(e.length-8,e.length)},T.convertItemText=function(e,t,n){return e?n?T.toPlainTextWithEmoticonHtml(e,t):T.toPlainText(e,t):""},T.createMentionedUsersArray=function(e,n){for(var t=[],i=//g,r=i.exec(e);null!==r;){var o=T.ABBR_PATTERN.exec(r[0]);o=o&&o[1],-1===t.indexOf(o)&&t.push(o),r=i.exec(e)}return n&&(t=t.filter(function(t){return n.some(function(e){return e.userId===t})})),t},T.DEFAULT_HELP_URL="https://www.circuit.com/support",T.DEFAULT_FAQ_URL="https://www.circuit.com/unifyportalfaqdetail",T.SEPARATORS_PATTERN="!-/:-@[-^{-~\\s",T.NUMERIC_PATTERN="^[0-9]*$",T.NUMERIC_SIGN_PATTERN="^[*+]?[0-9]*$",T.ALPHANUMERIC_PATTERN="^[a-zA-Z0-9_]*$",T.URL_SEPARATORS_PATTERN=/(?=[.,;!]?\s+|[.,;!]$)/,T.URL_PATTERN=new RegExp("(http|ftp|https|circuit):\\/\\/[\\w-]+?((\\.|:)[\\w-]+?)*?"+n,"gim"),T.EXACT_URL_PATTERN=new RegExp("^"+T.URL_PATTERN.source+"$","i"),T.PSEUDO_URL_PATTERN=new RegExp("www\\.+[\\w-]+?(\\.[\\w-]+?)+?"+n,"gim"),T.PROTOCOL_PATTERN=/^(?:http|https|ftp):\/\//,T.TABBABLE_ELEMENTS_PATTERN="a[href], area[href], input:not([disabled]):not([tabindex='-1']), button:not([disabled]):not([tabindex='-1']),select:not([disabled]):not([tabindex='-1']), textarea:not([disabled]):not([tabindex='-1']), iframe, object, embed, *[tabindex]:not([tabindex='-1']), *[contenteditable=true]",T.RICH_TEXT_LINK_CLASS="text-linkDarkGreen",T.ABBR_PATTERN=/abbr=["'](.*?)["']/,T.SPACE_HASHTAGS_PATTERN=/]*class=["']hashtag["'][^>]*>/gim,T.SPACE_HASHTAG_PATTERN=/^([a-zA-Z\u0080-\u009f\u00a1-\uffff0-9_]+)$/g,T.EMAIL_ADDRESS_INCLUDED_PATTERN=/[\w*+\-$?^{!#%&'/=`|}~]+?(?:\.[\w*+\-$?^{!#%&'/=`|}~]+?)*?@[a-z\d-]+?(?:\.[a-z\d-]{2,})+/gim,T.EMAIL_ADDRESS_PATTERN=new RegExp("^"+T.EMAIL_ADDRESS_INCLUDED_PATTERN.source+"$","i"),a.isElectron&&t&&(T.SSO_EMAIL_DOMAINS_MAPPING=t.getGlobal("constants").SSO_EMAIL_DOMAINS_MAPPING||[],T.SSO_PATTERN="[_a-z0-9-]+?@(("+T.SSO_EMAIL_DOMAINS_MAPPING.join(")|(")+"))",T.SSO_EMAIL_ADDRESS_PATTERN=new RegExp(T.SSO_PATTERN,"i")),T.CIRCUIT_CONVERSATION_HASH_PATTERN=/#\/(conversation|open|muted)\/[0-9\-a-z]+?(\?((user=(\d)+?)|(item=([0-9\-a-z])+?(&user=(\d)+?)?)))?$/gim,T.CIRCUIT_SPACE_HASH_PATTERN=/#\/space\/[0-9\-a-z]+?(\?topic=[0-9\-a-z]+?(&reply=[0-9\-a-z]+?)?)?$/gim,T.CIRCUIT_LINKS_HASH_PATTERN=/#\/(profile|phone|user|search)\/[0-9\-a-z]+?$/gim,T.CIRCUIT_HASH_TAG_SEARCH_PATTERN=/#\/search\/[a-zA-Z\u0080-\u009f\u00a1-\uffff0-9_]+/gim,T.CIRCUIT_EMAIL_HASH_PATTERN=new RegExp("#\\/email\\/"+T.EMAIL_ADDRESS_INCLUDED_PATTERN.source+"$","gim"),T.PHONE_PATTERN=/^(\+\s*)?\d+(\s*\(\s*\d+\s*\)\s*\d+)?((\s*-?\s*\d+)*|(\s*\.\s*\d+)*)$/,T.GNF_PHONE_PATTERN=/^((\+)|(\+\s*\d+(\s*\(\s*\d+\s*\)\s*\d+)?((\s*-?\s*\d+)*|(\s*\.\s*\d+)*)))$/,T.PHONE_PAC=/^([#*]+[#*()\-\s+\d]*)$/,T.PHONE_DIAL_PATTERN=/^([#*()\\/\-.\s+\d,]*)$/,T.PHONE_DIAL_WITH_PIN_PATTERN=/^([#*()\\/\-.\s+\d]*)(,+[,\d#*]+)$/,T.PHONE_WITH_EXTENSION_PATTERN=/^([#*()\\/\-.\s+\d]*)(\s*(x|X|ext\.)\s*\d+)$/,T.TIME_PATTERN=/^((([0-1]?[0-9]|2[0-3]):[0-5][0-9]\s*)|((0?[1-9]|1[0-2]):[0-5][0-9]\s*(PM|AM)))$/,T.IPV4_ADDRESS_PATTERN=/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/,T.TCP_PORT_NUMBERS_PATTERN=/^(0|([1-9]\d{0,3}|[1-5]\d{4}|[6][0-5][0-5]([0-2]\d|[3][0-5])))$/,T.FQDN_PATTERN=/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])$/,T.matchPhonePattern=function(e){return e&&"string"==typeof e?e.match(T.PHONE_PATTERN):null},T.matchUrlPattern=function(e){return e&&"string"==typeof e?e.match(T.URL_PATTERN)||e.match(T.PSEUDO_URL_PATTERN):null},T.matchEmailPattern=function(e){return e&&"string"==typeof e?e.match(T.EMAIL_ADDRESS_INCLUDED_PATTERN):null},T.getEmails=function(e){var t=e&&e.split(/[;,]\s*|\s+/i);return(t=t&&t.map(function(e){var t=e.match(T.EMAIL_ADDRESS_INCLUDED_PATTERN);return t&&t[0]}).filter(function(e){return!!e}))||[]},T.getTags=function(e){return e&&e.split(/[;,]\s*/i).reduce(function(e,t){var n=t.trim();return n.length&&e.push(n),e},[])},T.matchNames=function(e,t,n){if(!e||"string"!=typeof e||!t)return!1;var i=new RegExp("^"+RegExp.escape(t),n||"i");return i.test(e)||e.split(" ").some(function(e){return i.test(e)})},T.matchIpOrFqdnPattern=function(e){return e&&"string"==typeof e?e.match(T.IPV4_ADDRESS_PATTERN)||e.match(T.FQDN_PATTERN):null},T.compareStrings=function(e,t){return"string"==typeof e&&"string"==typeof t&&new RegExp("^"+RegExp.escape(e)+"$","i").test(t)},T.rstring=function(){return Math.floor(1e9*Math.random()).toString()},T.randomNumber=function(e,t){return Math.floor(Math.random()*(t-e+1))+e},T.randomBoolean=function(){return Math.random()<.5},T.createTransactionId=function(){for(var e=[],t="0123456789abcdef",n=0;n<36;n++)e[n]=t.substr(Math.floor(16*Math.random()),1);return e[14]="4",e[19]=t.substr(e[19]?3:8,1),e[8]=e[13]=e[18]=e[23]="-",e.join("")},T.getLegalRegion=function(e){switch(e){case"europe":var t=(navigator.language||navigator.browserLanguage).split("-");return"de"===T.lastArrayElement(t).toLowerCase()?"de":"uk";case"americas":case"apac":default:return"us"}},T.getBrowserInfo=function(){if("iOS"===window.navigator.platform)return{ios:!0,type:"ios"};if("Android"===window.navigator.platform)return{android:!0,type:"android"};if("node"===window.navigator.platform)return{node:!0,type:"node"};if(Circuit.isElectron)return{chrome:!0,type:"chrome",version:process.versions.chrome};if(window.cordova&&"ios"===window.cordova.platformId)return{cordovaios:!0,type:"cordovaios"};var e,t={},n=navigator.userAgent.toLowerCase(),i=/(msie|trident)(?: |.*rv:)([\d.]+)/.exec(n)||/(opera|opr)\/(?:.*version\/|)([\d.]+)/.exec(n)||/(firefox)\/([\d.]+)/.exec(n)||/(edge)\/([\d.]+)/.exec(n)||/(edg)\/([\d.]+)/.exec(n)||/(chrome)\/([\d.]+)/.exec(n)||/version\/([\d.]+).*(safari)/.exec(n)||/(phantomjs)\/([\d.]+)/.exec(n)||[],r=i[1]||"",o=i[2]||0;if("safari"===o)r=i[2],o=i[1];else switch(r){case"trident":r="msie";break;case"opr":r="opera";break;case"edg":r="chrome",e="edge"}return t[r]=!0,t.type=r,t.version=o,e&&(t.subType=e),t};var r=[{s:"Windows 10",r:/(Windows.* 10|Windows 10.0|Windows[ _]NT.* 10.0)/},{s:"Windows 8.1",r:/(Windows.* 8.1|Windows[ _]NT.* 6.3)/},{s:"Windows 8",r:/(Windows.* 8|Windows[ _]NT.* 6.2)/},{s:"Windows 7",r:/(Windows.* 7|Windows[ _]NT.* 6.1)/},{s:"Windows Vista",r:/(Windows.* Vista|Windows[ _]NT.* 6.0)/},{s:"Windows Server 2003",r:/(Windows Server 2003|Windows[ _]NT.* 5.2)/},{s:"Windows XP",r:/(Windows[ _]NT.* 5.1|Windows XP)/},{s:"Windows 2000",r:/(Windows[ _]NT.* 5.0|Windows 2000)/},{s:"Windows ME",r:/(Win 9x 4.90|Windows ME)/},{s:"Windows 98",r:/(Windows 98|Win98)/},{s:"Windows 95",r:/(Windows 95|Win95|Windows_95)/},{s:"Windows NT 4.0",r:/(Windows NT 4.0|WinNT4.0|WinNT|Windows NT)/},{s:"Windows CE",r:/Windows CE/},{s:"Windows 3.11",r:/Windows 3.11|Win16/},{s:"Android",r:/Android/},{s:"Open BSD",r:/Open BSD|OpenBSD/},{s:"Sun OS",r:/Sun OS|SunOS/},{s:"Linux",r:/(Linux|X11)/},{s:"iOS",r:/(iOS|iPhone|iPad|iPod)/},{s:"Mac OS X",r:/Mac OS X/},{s:"Mac OS",r:/(Mac OS|MacPPC|MacIntel|Mac_PowerPC|Macintosh|Darwin)/},{s:"QNX",r:/QNX/},{s:"UNIX",r:/UNIX/},{s:"BeOS",r:/BeOS/},{s:"OS/2",r:/OS\/2/},{s:"Search Bot",r:/(Search Bot|nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/}];function o(e){if(!e)return"";var t=document.createElement("div"),n=document.createElement("div");e=e.replace(/\$/gm,"$$$$");var i=0;return e=e.replace(/()|(<\/span>)/gi,function(e,t,n){return t?t.match(/class="mention"/i)?e.replace(/.*abbr="(.*?)".*?>/gi,''):t.match(/class="hashtag"/i)?e.replace(/.*abbr="(.*?)".*?>/gi,''):(i++,t):n?i?(i--,n):"":""}),T.isMobile()||(e=d.convertEmojis(e)),t.innerHTML=e,function e(t,n){if(!t||!t.childNodes||!t.childNodes.length)return t;var i;for(var r=0,o=t.childNodes.length;r";return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">").replace(/\r\n|\r|\n/gm,n)},T.escapedHtmlToText=function(e){return e?e.replace(/&/g,"&").replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/ /g," ").replace(//g,"\r\n"):""},T.stripParenthesis=function(e){for(var t=(e=e.trim()).match(/\(/g)||[],n=e.match(/\)/g)||[],i=0;"("===e[i];)i++;return e.slice(i,e.length-Math.abs(t.length-i-n.length))},T.linkifyText=function(e,t){t||(e=e.replace(/\xA0| |\x0A|\x0D/gim," "));for(var a=String.fromCharCode(17),s=String.fromCharCode(18),c=String.fromCharCode(19),n=function(e){var t="",n="",i=p(),r=T.getCircuitRelativeLink(i,e);if(!r){var o=!0;if((r=e).startsWith(E))new RegExp(i.replace(u,"")+"\\/guest\\?token=","i").exec(e)?r=e.replace(E,u):o=!1;else T.PROTOCOL_PATTERN.exec(e)||(r="http://"+r);t=o?" target="+c+"_blank"+c:"",n=" rel="+c+"noopener noreferrer"+c}return a+"a href="+c+r+c+t+n+s+e+a+"/a"+s},i=e.split(T.URL_SEPARATORS_PATTERN),r=0;r").replace(/\x13/gi,"'")},T.linkifyContent=function(e,t){if(!e)return"";return 5e4t.clientHeight}return!1},T.isDescendantOrEqual=function(e,t){if(e===t)return!0;for(var n=e;n;)if((n=n.parentElement)===t)return!0;return!1},T.isSupportedImage=function(e){return/^image\/(jpeg|gif|bmp|png)$/i.test(e)},T.isVideoSupportedByBrowser=function(e){return/^video\/(quicktime|mp4|webm)$/i.test(e)},T.shallowCopy=function(e){if(!e||"object"!=typeof e)return e;if(Array.isArray(e))return e.slice();var t=T.flattenObj(e),n={};for(var i in t)t.hasOwnProperty(i)&&(n[i]=t[i]);return n},T.normalizeLocaleProto=function(e){var t;return e&&5<=e.length&&(t=e.replace(/-/g,"_").toUpperCase()),t},T.normalizeLocale=function(e){var t;return e&&5<=e.length&&(t=e.substr(0,2).toLowerCase()+e.substr(2,e.length-2).replace(/_/g,"-")),t},T.getLocalTime=function(e){var t=new Date;return null==e||t.setTime(t.getTime()+60*(t.getTimezoneOffset()-e)*1e3),t.getTime()},T.delayOrTimestamp=function(e,t){return 0e.length&&t.startsWith(e)){var r=t.slice(e.length),o=r.match(T.CIRCUIT_CONVERSATION_HASH_PATTERN);return o?o[0].replace(/\/(muted|open)/gim,"/conversation"):(o=r.match(T.CIRCUIT_SPACE_HASH_PATTERN))?o[0]:(o=r.match(T.CIRCUIT_LINKS_HASH_PATTERN)||r.match(T.CIRCUIT_EMAIL_HASH_PATTERN)||r.match(T.CIRCUIT_HASH_TAG_SEARCH_PATTERN))&&o[0]}return""},T.isCircuitLink=function(e,t){return!!T.getCircuitRelativeLink(e,t)},T.throttle=function(n,i,r){var o,a,s,c=null,l=0;r=r||{};function d(){l=!1===r.leading?0:Date.now(),c=null,s=n.apply(o,a),o=a=null}return function(){var e=Date.now();l||!1!==r.leading||(l=e);var t=i-(e-l);return o=this,a=arguments,t<=0?(c&&(window.clearTimeout(c),c=null),l=e,s=n.apply(o,a),o=a=null):c||!1===r.trailing||(c=window.setTimeout(d,t)),s}},T.hasEmptyPrototype=function(e){return!(!e||"object"!=typeof e)&&T.isEmptyObject(Object.getPrototypeOf(e))},T.compareElements=function(e,t){if(e===t)return!0;if(!e||!t)return!1;if("object"!=typeof e||"object"!=typeof t)return!1;if(e instanceof Array&&t instanceof Array){if(e.length!==t.length)return!1;var i=t.slice();return e.every(function(n){return i.some(function(e,t){return!!T.compareElements(n,e)&&(i.splice(t,1),!0)})})}if(!T.hasEmptyPrototype(e)||!T.hasEmptyPrototype(t))return!1;for(var n in e)if(e.hasOwnProperty(n)&&0!==n.indexOf("$$")&&!T.compareElements(e[n],t[n]))return!1;return!0},T.copyToClipboard=function(e,t,n){var i,r,o,a,s;if(e)try{r=document.createRange(),i=window.getSelection(),a=document.body.style.overflow,s=this.getBrowserInfo().msie,o=n?document.createElement("textarea"):document.createElement("div"),n||(e=e.replace(/\r\n/gi,"
")),o.style.backgroundColor="#fff",o.style.font="normal normal 15px Calibri, sans-serif",o.style["white-space"]="pre-wrap",n?(o.value=e,o.setAttribute("readonly",""),o.style.position="absolute",o.style.left="-9999px",document.body.appendChild(o),i.removeAllRanges(),o.select(),o.setSelectionRange(0,e.length)):(o.innerHTML=e,document.body.appendChild(o),r.selectNode(o),i.removeAllRanges(),i.addRange(r)),s&&(document.body.style.overflow="hidden"),document.execCommand("copy")?t&&t():t&&t("Failed to copy")}catch(e){c.error("[Utils]: Copy to clipboard failed"),t&&t("Internal error")}finally{i&&("function"!=typeof i.removeRange||n?i.removeAllRanges():i.removeRange(r)),s&&(document.body.style.overflow=a),o&&document.body.removeChild(o)}},T.toCamelCase=function(e){if(!e||"string"!=typeof e)return"";for(var t=e.toLowerCase().split(/[_-]/),n=1;n=e.length||n<0||t===n)){for(var i=e.length;i<=n;i++)e.push(void 0);e.splice(n,0,e.splice(t,1)[0])}},T.emptyArray=function(e){if(e.length)for(;0>>0,r=arguments[1],o=0;o>>0,r=arguments[1],o=0;o