{"version":3,"sources":["webpack://JitsiMeetJS/webpack/universalModuleDefinition","webpack://JitsiMeetJS/webpack/bootstrap","webpack://JitsiMeetJS/./service/xmpp/XMPPEvents.js","webpack://JitsiMeetJS/../strophe.js/strophe.js","webpack://JitsiMeetJS/./JitsiConferenceEvents.js","webpack://JitsiMeetJS/./modules/browser/index.js","webpack://JitsiMeetJS/../jitsi-meet-logger/lib/index.js","webpack://JitsiMeetJS/./modules/statistics/statistics.js","webpack://JitsiMeetJS/./modules/xmpp/SDPUtil.js","webpack://JitsiMeetJS/./service/statistics/AnalyticsEvents.js","webpack://JitsiMeetJS/./service/RTC/RTCEvents.js","webpack://JitsiMeetJS/./service/RTC/MediaType.js","webpack://JitsiMeetJS/./modules/RTC/RTCUtils.js","webpack://JitsiMeetJS/./modules/util/GlobalOnErrorHandler.js","webpack://JitsiMeetJS/./JitsiTrackErrors.js","webpack://JitsiMeetJS/./modules/RTC/RTC.js","webpack://JitsiMeetJS/./service/RTC/VideoType.js","webpack://JitsiMeetJS/./JitsiTrackError.js","webpack://JitsiMeetJS/./JitsiTrackEvents.js","webpack://JitsiMeetJS/./JitsiConferenceErrors.js","webpack://JitsiMeetJS/./modules/xmpp/SDP.js","webpack://JitsiMeetJS/./node_modules/js-utils/browser-detection/browsers.js","webpack://JitsiMeetJS/./node_modules/js-utils/browser-detection/BrowserDetection.js","webpack://JitsiMeetJS/./node_modules/js-utils/index.js","webpack://JitsiMeetJS/./modules/videosipgw/VideoSIPGWConstants.js","webpack://JitsiMeetJS/./JitsiConnectionEvents.js","webpack://JitsiMeetJS/../sdp-transform/lib/index.js","webpack://JitsiMeetJS/./service/statistics/Events.js","webpack://JitsiMeetJS/./modules/util/Listenable.js","webpack://JitsiMeetJS/./service/connectivity/ConnectionQualityEvents.js","webpack://JitsiMeetJS/./modules/xmpp/SdpTransformUtil.js","webpack://JitsiMeetJS/./modules/proxyconnection/constants.js","webpack://JitsiMeetJS/../events/events.js","webpack://JitsiMeetJS/./service/RTC/Resolutions.js","webpack://JitsiMeetJS/./modules/xmpp/JingleSessionState.js","webpack://JitsiMeetJS/./modules/statistics/CallStats.js","webpack://JitsiMeetJS/./modules/settings/Settings.js","webpack://JitsiMeetJS/./modules/util/RandomUtil.js","webpack://JitsiMeetJS/./modules/xmpp/ConnectionPlugin.js","webpack://JitsiMeetJS/./modules/xmpp/xmpp.js","webpack://JitsiMeetJS/./JitsiConnectionErrors.js","webpack://JitsiMeetJS/./service/RTC/SignalingEvents.js","webpack://JitsiMeetJS/../webrtc-adapter/src/js/utils.js","webpack://JitsiMeetJS/./service/RTC/CameraFacingMode.js","webpack://JitsiMeetJS/./modules/RTC/ScreenObtainer.js","webpack://JitsiMeetJS/./modules/connectivity/ParticipantConnectionStatus.js","webpack://JitsiMeetJS/./modules/recording/recordingXMLUtils.js","webpack://JitsiMeetJS/../webpack/buildin/global.js","webpack://JitsiMeetJS/./modules/xmpp/JingleSessionPC.js","webpack://JitsiMeetJS/./JitsiMediaDevicesEvents.js","webpack://JitsiMeetJS/../bowser/src/bowser.js","webpack://JitsiMeetJS/./modules/xmpp/SDPDiffer.js","webpack://JitsiMeetJS/../process/browser.js","webpack://JitsiMeetJS/./service/e2eping/E2ePingEvents.js","webpack://JitsiMeetJS/./modules/statistics/LocalStatsCollector.js","webpack://JitsiMeetJS/./modules/util/ScriptUtil.js","webpack://JitsiMeetJS/./JitsiTranscriptionStatus.js","webpack://JitsiMeetJS/./modules/RTC/JitsiTrack.js","webpack://JitsiMeetJS/./modules/util/MathUtil.js","webpack://JitsiMeetJS/./modules/statistics/SpeakerStats.js","webpack://JitsiMeetJS/./service/authentication/AuthenticationEvents.js","webpack://JitsiMeetJS/./modules/RTC/JitsiLocalTrack.js","webpack://JitsiMeetJS/./modules/recording/JibriSession.js","webpack://JitsiMeetJS/./JitsiMediaDevices.js","webpack://JitsiMeetJS/../jitsi-meet-logger/lib/Logger.js","webpack://JitsiMeetJS/../webpack/buildin/module.js","webpack://JitsiMeetJS/../sdp/sdp.js","webpack://JitsiMeetJS/../sdp-transform/lib/grammar.js","webpack://JitsiMeetJS/./modules/transcription/audioRecorder.js","webpack://JitsiMeetJS/./modules/util/AuthUtil.js","webpack://JitsiMeetJS/./JitsiConnection.js","webpack://JitsiMeetJS/./JitsiConference.js","webpack://JitsiMeetJS/../lodash.isequal/index.js","webpack://JitsiMeetJS/./JitsiConferenceEventManager.js","webpack://JitsiMeetJS/./modules/util/EventEmitterForwarder.js","webpack://JitsiMeetJS/./modules/statistics/AnalyticsAdapter.js","webpack://JitsiMeetJS/./modules/browser/BrowserCapabilities.js","webpack://JitsiMeetJS/./node_modules/js-md5/src/md5.js","webpack://JitsiMeetJS/./modules/statistics/RTPStatsCollector.js","webpack://JitsiMeetJS/./JitsiParticipant.js","webpack://JitsiMeetJS/./authenticateAndUpgradeRole.js","webpack://JitsiMeetJS/./modules/xmpp/strophe.emuc.js","webpack://JitsiMeetJS/./modules/xmpp/ChatRoom.js","webpack://JitsiMeetJS/./modules/xmpp/moderator.js","webpack://JitsiMeetJS/./modules/util/UsernameGenerator.js","webpack://JitsiMeetJS/./modules/xmpp/strophe.jingle.js","webpack://JitsiMeetJS/./modules/util/StringUtils.js","webpack://JitsiMeetJS/./modules/xmpp/JingleSession.js","webpack://JitsiMeetJS/./modules/xmpp/SignalingLayerImpl.js","webpack://JitsiMeetJS/./service/RTC/SignalingLayer.js","webpack://JitsiMeetJS/./modules/util/AsyncQueue.js","webpack://JitsiMeetJS/../async/lib/async.js","webpack://JitsiMeetJS/./modules/xmpp/strophe.util.js","webpack://JitsiMeetJS/./modules/xmpp/strophe.ping.js","webpack://JitsiMeetJS/./modules/xmpp/strophe.rayo.js","webpack://JitsiMeetJS/./modules/xmpp/strophe.logger.js","webpack://JitsiMeetJS/./modules/xmpp/StropheBoshLastSuccess.js","webpack://JitsiMeetJS/./modules/xmpp/Caps.js","webpack://JitsiMeetJS/./modules/P2PDominantSpeakerDetection.js","webpack://JitsiMeetJS/./modules/RTC/BridgeChannel.js","webpack://JitsiMeetJS/./modules/RTC/TraceablePeerConnection.js","webpack://JitsiMeetJS/./modules/RTC/JitsiRemoteTrack.js","webpack://JitsiMeetJS/./modules/RTC/LocalSdpMunger.js","webpack://JitsiMeetJS/./modules/xmpp/RtxModifier.js","webpack://JitsiMeetJS/./modules/xmpp/SdpConsistency.js","webpack://JitsiMeetJS/./modules/TalkMutedDetection.js","webpack://JitsiMeetJS/./modules/connectivity/ConnectionQuality.js","webpack://JitsiMeetJS/./modules/connectivity/IceFailedNotification.js","webpack://JitsiMeetJS/./modules/e2eping/e2eping.js","webpack://JitsiMeetJS/./modules/event/Jvb121EventGenerator.js","webpack://JitsiMeetJS/./modules/recording/RecordingManager.js","webpack://JitsiMeetJS/./modules/rttmonitor/rttmonitor.js","webpack://JitsiMeetJS/./modules/statistics/AvgRTPStatsReporter.js","webpack://JitsiMeetJS/./modules/statistics/AudioOutputProblemDetector.js","webpack://JitsiMeetJS/./modules/statistics/SpeakerStatsCollector.js","webpack://JitsiMeetJS/./modules/transcription/transcriber.js","webpack://JitsiMeetJS/./modules/version/ComponentsVersions.js","webpack://JitsiMeetJS/./modules/videosipgw/VideoSIPGW.js","webpack://JitsiMeetJS/./modules/videosipgw/JitsiVideoSIPGWSession.js","webpack://JitsiMeetJS/./modules/recording/recordingConstants.js","webpack://JitsiMeetJS/./modules/proxyconnection/ProxyConnectionService.js","webpack://JitsiMeetJS/./modules/proxyconnection/ProxyConnectionPC.js","webpack://JitsiMeetJS/./index.js","webpack://JitsiMeetJS/./JitsiMeetJS.js","webpack://JitsiMeetJS/../jitsi-meet-logger/lib/LogCollector.js","webpack://JitsiMeetJS/../webpack/buildin/amd-define.js","webpack://JitsiMeetJS/../webpack/buildin/amd-options.js","webpack://JitsiMeetJS/../current-executing-script/dist/currentExecutingScript.js","webpack://JitsiMeetJS/./service/statistics/constants.js","webpack://JitsiMeetJS/../src/strophe.disco.js","webpack://JitsiMeetJS/../timers-browserify/main.js","webpack://JitsiMeetJS/../setimmediate/setImmediate.js","webpack://JitsiMeetJS/../webrtc-adapter/src/js/adapter_core.js","webpack://JitsiMeetJS/../webrtc-adapter/src/js/adapter_factory.js","webpack://JitsiMeetJS/../webrtc-adapter/src/js/chrome/chrome_shim.js","webpack://JitsiMeetJS/../webrtc-adapter/src/js/chrome/getusermedia.js","webpack://JitsiMeetJS/../webrtc-adapter/src/js/edge/edge_shim.js","webpack://JitsiMeetJS/../rtcpeerconnection-shim/rtcpeerconnection.js","webpack://JitsiMeetJS/../webrtc-adapter/src/js/edge/getusermedia.js","webpack://JitsiMeetJS/../webrtc-adapter/src/js/firefox/firefox_shim.js","webpack://JitsiMeetJS/../webrtc-adapter/src/js/firefox/getusermedia.js","webpack://JitsiMeetJS/../webrtc-adapter/src/js/safari/safari_shim.js","webpack://JitsiMeetJS/../webrtc-adapter/src/js/common_shim.js","webpack://JitsiMeetJS/../sdp-transform/lib/parser.js","webpack://JitsiMeetJS/../sdp-transform/lib/writer.js","webpack://JitsiMeetJS/../@jitsi/sdp-interop/lib/index.js","webpack://JitsiMeetJS/../@jitsi/sdp-interop/lib/interop.js","webpack://JitsiMeetJS/../@jitsi/sdp-interop/lib/transform.js","webpack://JitsiMeetJS/../@jitsi/sdp-interop/lib/array-equals.js","webpack://JitsiMeetJS/../@jitsi/sdp-simulcast/lib/index.js","webpack://JitsiMeetJS/../@jitsi/sdp-simulcast/lib/transform-utils.js","webpack://JitsiMeetJS/./modules/transcription/recordingResult.js","webpack://JitsiMeetJS/./modules/transcription/transcriptionServices/SphinxTranscriptionService.js","webpack://JitsiMeetJS/./modules/transcription/transcriptionServices/AbstractTranscriptionService.js","webpack://JitsiMeetJS/./modules/transcription/word.js"],"names":["root","factory","exports","module","define","amd","window","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","ADD_ICE_CANDIDATE_FAILED","AUDIO_MUTED_BY_FOCUS","AUTHENTICATION_REQUIRED","BRIDGE_DOWN","CALL_ACCEPTED","CALL_INCOMING","CALL_ENDED","CHAT_ERROR_RECEIVED","CONFERENCE_PROPERTIES_CHANGED","CONNECTION_ESTABLISHED","CONNECTION_FAILED","CONNECTION_INTERRUPTED","CONNECTION_RESTORED","CONNECTION_ICE_FAILED","CONNECTION_STATUS_CHANGED","DISPLAY_NAME_CHANGED","EMUC_ROOM_ADDED","EMUC_ROOM_REMOVED","ETHERPAD","FOCUS_DISCONNECTED","FOCUS_LEFT","GRACEFUL_SHUTDOWN","ICE_RESTARTING","ICE_RESTART_SUCCESS","KICKED","LOCAL_ROLE_CHANGED","MESSAGE_RECEIVED","PRIVATE_MESSAGE_RECEIVED","MUC_MEMBER_BOT_TYPE_CHANGED","MUC_DESTROYED","MUC_JOINED","MUC_MEMBER_JOINED","MUC_MEMBER_LEFT","MUC_LEFT","MUC_ROLE_CHANGED","MUC_LOCK_CHANGED","PARTICIPANT_AUDIO_MUTED","PARTICIPANT_VIDEO_MUTED","PARTICIPANT_VIDEO_TYPE_CHANGED","PARTCIPANT_FEATURES_CHANGED","PASSWORD_REQUIRED","PEERCONNECTION_READY","PHONE_NUMBER_CHANGED","PRESENCE_RECEIVED","PRESENCE_STATUS","PROMPT_FOR_LOGIN","READY_TO_JOIN","RECORDER_STATE_CHANGED","REMOTE_STATS","RENEGOTIATION_FAILED","RESERVATION_ERROR","ROOM_CONNECT_ERROR","ROOM_CONNECT_NOT_ALLOWED_ERROR","ROOM_JOIN_ERROR","ROOM_MAX_USERS_ERROR","SENDING_CHAT_MESSAGE","SENDING_PRIVATE_CHAT_MESSAGE","SESSION_ACCEPT_TIMEOUT","SPEAKER_STATS_RECEIVED","START_MUTED_FROM_FOCUS","SUBJECT_CHANGED","SUSPEND_DETECTED","TRANSCRIPTION_STATUS_CHANGED","TRANSPORT_INFO","VIDEO_SIP_GW_AVAILABILITY_CHANGED","VIDEO_SIP_GW_SESSION_STATE_CHANGED","ICE_CONNECTION_STATE_CHANGED","JSON_MESSAGE_RECEIVED","requirejs","require","undef","main","req","makeMap","handlers","defined","waiting","config","defining","hasOwn","aps","slice","jsSuffixRegExp","hasProp","obj","prop","normalize","baseName","nameParts","nameSegment","mapValue","foundMap","lastIndex","foundI","foundStarMap","starI","j","part","baseParts","split","map","starMap","length","nodeIdCompat","test","replace","charAt","concat","splice","join","makeRequire","relName","forceSync","args","arguments","push","apply","makeLoad","depName","callDep","Error","splitPrefix","prefix","index","indexOf","substring","makeRelParts","makeConfig","relParts","plugin","parts","relResourceName","f","pr","e","id","uri","deps","callback","cjsModule","ret","usingExports","callbackType","load","undefined","alt","setTimeout","cfg","_defined","jQuery","this","Function","func","_slice","Array","_concat","_args","isArray","arg","toString","elt","len","from","Number","Math","ceil","floor","forEach","thisArg","T","k","TypeError","O","kValue","keyStr","btoa","input","chr1","chr2","chr3","enc1","enc2","enc3","enc4","output","charCodeAt","isNaN","atob","String","fromCharCode","core_sha1","x","olda","oldb","oldc","oldd","olde","w","a","b","rol","safe_add","sha1_ft","sha1_kt","core_hmac_sha1","data","bkey","str2binb","ipad","opad","hash","y","lsw","num","cnt","str","bin","binb2str","binb2b64","binarray","triplet","b64_hmac_sha1","b64_sha1","str_hmac_sha1","str_sha1","SHA1","MD5","str2binl","md5_cmn","q","md5_ff","md5_gg","md5_hh","md5_ii","core_md5","hexdigest","binl2hex","binl2str","stropheUtils","utf16to8","out","addCookies","cookies","cookieName","cookieObj","isObj","cookieValue","expires","domain","path","escape","unescape","document","cookie","Strophe","$build","$iq","$msg","$pres","utils","attrs","Builder","VERSION","NS","HTTPBIND","BOSH","CLIENT","AUTH","ROSTER","PROFILE","DISCO_INFO","DISCO_ITEMS","MUC","SASL","STREAM","FRAMING","BIND","SESSION","STANZAS","XHTML_IM","XHTML","tags","attributes","css","validTag","tag","validAttribute","attribute","validCSS","style","Status","ERROR","CONNECTING","CONNFAIL","AUTHENTICATING","AUTHFAIL","CONNECTED","DISCONNECTED","DISCONNECTING","ATTACHED","REDIRECT","CONNTIMEOUT","ErrorCondition","BAD_FORMAT","CONFLICT","MISSING_JID_NODE","NO_AUTH_MECH","UNKNOWN_REASON","LogLevel","DEBUG","INFO","WARN","FATAL","ElementType","NORMAL","TEXT","CDATA","FRAGMENT","TIMEOUT","SECONDARY_TIMEOUT","addNamespace","forEachChild","elem","elemName","childNode","childNodes","nodeType","isTagEqual","el","tagName","_xmlGenerator","_makeGenerator","doc","implementation","createDocument","documentMode","_getIEXmlDom","appendChild","createElement","xmlGenerator","docStrings","ActiveXObject","xmlElement","node","xmlTextNode","sort","attr","setAttribute","xmlescape","text","xmlunescape","createTextNode","xmlHtmlNode","html","DOMParser","parseFromString","async","loadXML","getText","nodeValue","copyElement","nodeName","createHtml","cssAttrs","cssName","cssValue","toLowerCase","getAttribute","cssText","createDocumentFragment","escapeNode","unescapeNode","getNodeFromJid","jid","getDomainFromJid","bare","getBareJidFromJid","getResourceFromJid","_handleError","stack","fatal","sourceURL","handler","line","message","fileName","lineNumber","log","level","msg","console","error","debug","info","warn","serialize","result","tree","child","_requestId","_connectionPlugins","addConnectionPlugin","ptype","xmlns","nodeTree","up","parentNode","moreattrs","removeAttribute","cnode","impNode","xmlGen","importNode","newElem","h","fragment","innerHTML","xhtml","Handler","type","options","matchBare","matchBareFromJid","user","getNamespace","elNamespace","ignoreNamespaceFragment","namespaceMatch","nsMatch","that","isMatch","elem_type","run","TimedHandler","period","lastCalled","Date","getTime","reset","Connection","service","proto","protocol","_proto","Websocket","Bosh","features","_sasl_data","do_session","do_bind","timedHandlers","removeTimeds","removeHandlers","addTimeds","addHandlers","protocolErrorHandlers","_idleTimeout","_disconnectTimeout","authenticated","connected","disconnecting","do_authentication","paused","restored","_data","_uniqueId","_sasl_success_handler","_sasl_failure_handler","_sasl_challenge_handler","maxRetries","_onIdle","registerSASLMechanisms","mechanisms","F","init","_reset","_requests","pause","resume","getUniqueId","suffix","uuid","random","addProtocolErrorHandler","status_code","connect","pass","wait","hold","route","authcid","authzid","servtype","connect_callback","_changeConnectStatus","_connect","attach","sid","rid","wind","_attach","restore","_sessionCachingSupported","_restore","JSON","sessionStorage","setItem","removeItem","xmlInput","xmlOutput","rawInput","rawOutput","nextValidRid","send","_queueData","_send","flush","clearTimeout","sendPresence","errback","timeout","timeoutHandler","addHandler","stanza","deleteTimedHandler","addTimedHandler","deleteHandler","sendIQ","iqtype","element","_sendRestart","thand","handRef","hand","SASLAnonymous","SASLExternal","SASLMD5","SASLOAuthBearer","SASLXOAuth2","SASLPlain","SASLSHA1","registerSASLMechanism","mechanism","disconnect","reason","pres","_addSysTimedHandler","_onDisconnectTimeout","_disconnect","_abortAllRequests","_doDisconnect","status","condition","statusChanged","err","_dataRecv","raw","_reqToData","strip","pop","_emptyQueue","cond","conflict","getElementsByTagName","UNKOWN_REASON","newList","_connect_cb","_callback","bodyWrap","getElementsByTagNameNS","mech","matched","authenticate","_no_auth_received","sortMechanismsByPriority","higher","swap","priority","_attemptSASLAuth","mechanism_found","_addSysHandler","_sasl_success_cb","_sasl_failure_cb","_sasl_challenge_cb","_sasl_mechanism","onStart","request_auth_exchange","isClientFirst","response","onChallenge","_attemptLegacyAuth","_auth1_cb","challenge","iq","_auth2_cb","serverSignature","matches","match","onSuccess","streamfeature_handlers","wrapper","_sasl_auth1_cb","_sasl_bind_cb","resource","jidNode","_sasl_session_cb","onFailure","now","SASLMechanism","connection","_connection","auth_str","test_cnonce","cnonce","nonce","salt","iter","Hi","U","U_old","clientKey","serverKey","clientSignature","responseText","authMessage","attribMatch","substr","_quote","realm","host","digest_uri","cred","A1","A2","core","Request","sends","xmlData","origFunc","date","NaN","abort","dead","age","timeDead","xhr","_newXHR","getResponse","responseXML","documentElement","querySelector","textContent","XMLHttpRequest","overrideMimeType","onreadystatechange","_conn","errors","inactivity","lastResponseHeaders","_buildBody","keepalive","_cacheSession","body","to","content","ver","_onRequestStateChange","_throttledRequestHandler","session","parse","getItem","stringify","typ","parseInt","_sendTerminate","_callProtocolErrorHandlers","err_callback","reqStatus","_getRequestStatus","HTTP","_hitError","time_elapsed","def","readyState","getAllResponseHeaders","valid_request","too_many_retries","_removeRequest","reqIs0","_restartRequest","_processRequest","self","primaryTimeout","secondaryTimeout","requestCompletedWithServerError","contentType","open","sync","setRequestHeader","withCredentials","e2","sendFunc","customHeaders","headers","header","backoff","min","pow","abs","new_service","location","pathname","_buildStream","_check_streamerror","connectstatus","errorString","_closeSocket","socket","WebSocket","onopen","_onOpen","onerror","_onError","onclose","_onClose","onmessage","_connect_cb_wrapper","_handleStreamStart","streamStart","parsedMessage","see_uri","string","_streamWrap","_onMessage","CLOSED","close","closeString","code","rawStanza","search","firstChild","start","startString","AUTH_STATUS_CHANGED","AVATAR_CHANGED","BEFORE_STATISTICS_DISPOSED","CONFERENCE_ERROR","CONFERENCE_FAILED","CONFERENCE_JOINED","CONFERENCE_LEFT","DATA_CHANNEL_OPENED","DOMINANT_SPEAKER_CHANGED","DTMF_SUPPORT_CHANGED","ENDPOINT_MESSAGE_RECEIVED","JVB121_STATUS","PARTICIPANT_KICKED","LAST_N_ENDPOINTS_CHANGED","LOCK_STATE_CHANGED","SERVER_REGION_CHANGED","PARTICIPANT_CONN_STATUS_CHANGED","PARTICIPANT_PROPERTY_CHANGED","P2P_STATUS","PROPERTIES_CHANGED","START_MUTED_POLICY_CHANGED","STARTED_MUTED","TALK_WHILE_MUTED","TRACK_ADDED","TRACK_AUDIO_LEVEL_CHANGED","TRACK_MUTE_CHANGED","TRACK_REMOVED","USER_JOINED","USER_LEFT","USER_ROLE_CHANGED","USER_STATUS_CHANGED","BOT_TYPE_CHANGED","BrowserCapabilities","Logger","LogCollector","idLoggers","loggers","curLevel","levels","TRACE","addGlobalTransport","transport","removeGlobalTransport","setGlobalOptions","getLogger","transports","logger","setLogLevelById","setLevel","setLogLevel","_instances","__filename","isCallstatsLoaded","_initCallStatsBackend","CallStats","isBackendInitialized","initBackend","callStatsID","callStatsSecret","userName","aliasName","applicationName","getWiFiStatsMethod","confID","Statistics","xmpp","rtpStatsMap","Map","eventEmitter","EventEmitter","callStatsIntegrationEnabled","disableThirdPartyRequests","browser","isReactNative","ScriptUtil","loadScript","customScriptUrl","loadCallStatsAPI","callStatsConfIDNamespace","callsStatsInstances","instances","add","audioLevelsEnabled","disableAudioLevels","audioLevelsInterval","analytics","Set","startRemoteStats","peerconnection","stopRemoteStats","rtpStats","RTPStats","set","localStats","startLocalStats","stream","LocalStats","addAudioLevelListener","listener","on","StatisticsEvents","removeAudioLevelListener","removeListener","addBeforeDisposedListener","removeBeforeDisposedListener","addConnectionStatsListener","removeConnectionStatsListener","addByteSentStatsListener","removeByteSentStatsListener","dispose","size","emit","values","callStats","stopCallStats","tpc","keys","tpcId","_stopRemoteStats","removeAllListeners","delete","stopLocalStats","stop","startCallStats","remoteUserID","has","newInstance","_getCallStatsConfID","_getAllCallStatsInstances","csInstances","statistics","cs","roomName","callStatsInstance","sendTerminateEvent","isCallstatsEnabled","sendConnectionResumeOrHoldEvent","isResume","instance","sendResumeOrHoldEvent","sendIceConnectionFailedEvent","sendMuteEvent","muted","sendScreenSharingEvent","ssrc","sendDominantSpeakerEvent","roomJid","sendActiveDeviceListEvent","devicesData","globalSet","associateStreamWithVideoTag","isLocal","userId","usageLabel","containerId","sendGetUserMediaFailed","JitsiTrackError","gum","constraintName","constraints","formatJitsiTrackErrorForCallStats","sendCreateOfferFailed","sendCreateAnswerFailed","sendSetLocalDescFailed","sendSetRemoteDescFailed","sendAddIceCandidateFailed","sendLog","globalSubSet","stats","next","csPerStats","sendApplicationLog","sendFeedback","overall","comment","sendEvent","FEEDBACK","rating","LOCAL_JID","reportGlobalError","sendAnalyticsAndLog","event","eventToLog","properties","sendAnalytics","eventName","SDPUtil","filterSpecialChars","iceparams","mediadesc","sessiondesc","pwd","ufrag","findLine","parseICEUfrag","parseICEPwd","buildICEUfrag","frag","buildICEPwd","parseMID","parseMLine","media","shift","port","fmt","buildMLine","mline","parseRTPMap","clockrate","channels","parseSCTPMap","buildRTPMap","parseCrypto","parseFingerprint","fingerprint","parseFmtp","parseICECandidate","candidate","elems","foundation","component","ip","generation","tcptype","network","buildICECandidate","cand","hasOwnAttribute","parseSSRC","desc","lines","parseRTCPFB","pt","params","parseExtmap","direction","haystack","needle","sessionpart","findLines","needles","candidateToJingle","candidateFromJingle","isFirefox","parsePrimaryVideoSsrc","videoMLine","numSsrcs","ssrcs","ssrcInfo","filter","array","numGroups","ssrcGroups","primarySsrc","fidGroup","find","group","semantics","simGroup","generateSsrc","RandomUtil","randomInt","getSsrcAttribute","mLine","attributeName","ssrcLine","parseGroupSsrcs","ssrcGroup","ssrcStr","getMedia","sdp","getUfrag","ufragLines","startsWith","preferVideoCodec","codecName","payloadType","rtp","codec","payload","payloadTypes","payloads","payloadIndex","unshift","stripVideoCodec","removePts","rtxApts","item","rtxPts","fmtp","keepPts","rtcpFb","TYPE_OPERATIONAL","TYPE_PAGE","TYPE_TRACK","TYPE_UI","ACTION_JINGLE_RESTART","ACTION_JINGLE_SA_TIMEOUT","ACTION_JINGLE_SI_RECEIVED","ACTION_JINGLE_SI_TIMEOUT","ACTION_JINGLE_TERMINATE","ACTION_JINGLE_TR_RECEIVED","ACTION_JINGLE_TR_SUCCESS","ACTION_P2P_DECLINED","ACTION_P2P_ESTABLISHED","ACTION_P2P_FAILED","ACTION_P2P_SWITCH_TO_JVB","AVAILABLE_DEVICE","CONNECTION_DISCONNECTED","ICE_DURATION","ICE_ESTABLISHMENT_DURATION_DIFF","ICE_STATE_CHANGED","NO_BYTES_SENT","TRACK_UNMUTED","createBridgeDownEvent","action","actionSubject","createConnectionFailedEvent","errorType","errorMessage","details","createConnectionStageReachedEvent","stage","source","createE2eRttEvent","participantId","region","rtt","createFocusLeftEvent","createGetUserMediaEvent","createParticipantConnectionStatusEvent","createJingleEvent","createNoDataFromSourceEvent","mediaType","createP2PEvent","createRemotelyMutedEvent","createRtpStatsEvent","createRttByRegionEvent","createAudioOutputProblemEvent","userID","localAudioLevels","remoteAudioLevels","createBridgeChannelClosedEvent","createTtfmEvent","CREATE_ANSWER_FAILED","CREATE_OFFER_FAILED","DATA_CHANNEL_OPEN","ENDPOINT_CONN_STATUS_CHANGED","LASTN_ENDPOINT_CHANGED","GRANTED_PERMISSIONS","IS_SELECTED_CHANGED","LASTN_VALUE_CHANGED","LOCAL_TRACK_SSRC_UPDATED","TRACK_ATTACHED","REMOTE_TRACK_ADDED","REMOTE_TRACK_MUTE","REMOTE_TRACK_REMOVED","REMOTE_TRACK_UNMUTE","SET_LOCAL_DESCRIPTION_FAILED","SET_REMOTE_DESCRIPTION_FAILED","AUDIO_OUTPUT_DEVICE_CHANGED","DEVICE_LIST_CHANGED","DEVICE_LIST_WILL_CHANGE","DEVICE_LIST_AVAILABLE","LOCAL_UFRAG_CHANGED","REMOTE_UFRAG_CHANGED","AUDIO","VIDEO","usesAdapter","availableDevices","availableDevicesPollTimer","OLD_GUM_DEFAULT_DEVICES","DEFAULT_CONSTRAINTS","video","aspectRatio","height","ideal","max","SS_DEFAULT_FRAME_RATE","audioOutputDeviceId","audioOutputChanged","disableAP","disableAEC","disableNS","disableAGC","disableHPF","featureDetectionAudioEl","isAudioOutputDeviceChangeAvailable","setSinkId","initEnumerateDevicesWithCallback","navigator","mediaDevices","enumerateDevices","then","getConstraints","um","audio","isNewStyleConstraintsSupported","isSafariWithVP8","isEdge","mandatory","optional","cameraDeviceId","deviceId","sourceId","facingMode","CameraFacingMode","USER","minFps","maxFps","fps","minFrameRate","maxFrameRate","resolution","Resolutions","width","minWidth","minHeight","maxWidth","maxHeight","setResolutionConstraints","micDeviceId","echoCancellation","googEchoCancellation","googAutoGainControl","googNoiseSuppression","googHighpassFilter","googNoiseSuppression2","googEchoCancellation2","googAutoGainControl2","isChrome","getSSConstraints","mozMediaSource","mediaSource","frameRate","errmsg","GlobalOnErrorHandler","callErrorHandler","bandwidth","firefox_fake_device","fake","desktopStream","chromeMediaSource","screen","chromeMediaSourceId","getTrackSSConstraints","desktopSharingFrameRate","updateGrantedPermissions","audioTracksReceived","Boolean","getAudioTracks","videoTracksReceived","getVideoTracks","grantedPermissions","RTCEvents","compareAvailableMediaDevices","newDevices","mediaDeviceInfoToJSON","kind","groupId","label","facing","sendDeviceListToAnalytics","deviceList","audioInputDeviceCount","audioOutputDeviceCount","videoInputDeviceCount","videoOutputDeviceCount","device","onMediaDevicesListChanged","devicesReceived","handleLocalStream","streams","audioStream","videoStream","res","audioVideo","audioTracks","MediaStream","addTrack","videoTracks","desktop","sourceType","track","MediaType","videoType","VideoType","DESKTOP","CAMERA","defaultSetVideoSrc","src","srcObjectPropertyName","jitsiObjectURL","URL","createObjectURL","rtcUtils","clearInterval","usesNewGumFlow","RTCPeerConnectionType","RTCPeerConnection","attachMediaStream","wrapAttachMediaStream","srcObject","getStreamID","getTrackID","isChromiumBased","_initPCConstraints","screenObtainer","getUserMediaWithConstraints","isDeviceListAvailable","ds","updateKnownDevices","pds","supportsDeviceChangeEvent","addEventListener","setInterval","pcConstraints","googHighStartBitrate","googPayloadPadding","googScreencastMinBitrate","googCpuOveruseDetection","googCpuOveruseEncodeUsage","googCpuUnderuseThreshold","googCpuOveruseThreshold","useIPv6","googIPv6","p2pPcConstraints","Promise","resolve","reject","getUserMedia","catch","umDevices","isSupported","supportsVideo","obtainStream","_parseDesktopSharingOptions","devices","requestingDesktop","includes","_getAudioAndVideoStreams","avStream","missingTracks","_getMissingTracks","stopMediaStream","desktopSharingSourceDevice","requestedDevices","missingDevices","audioDeviceRequested","videoDeviceRequested","desktopSharingExtensionExternalInstallation","desktopSharingSources","gumOptions","trackOptions","mediaStreamsMetaData","maybeRequestDesktopDevice","matchingDevice","exact","_newGetUserMediaWithConstraints","getTracks","applyConstraints","_newGetDesktopMedia","maybeRequestCaptureDevices","requestedCaptureDevices","newGetConstraints","effects","deviceType","mediaStream","release","url","revokeObjectURL","isDeviceChangeAvailable","deviceData","enable","googSuspendBelowMinBitrate","Listenable","origAttachMediaStream","getAudioOutputDevice","ex","callUnhandledRejectionHandler","promise","oldOnErrorHandler","oldOnUnhandledRejection","onunhandledrejection","errHandler","CHROME_EXTENSION_GENERIC_ERROR","CHROME_EXTENSION_INSTALLATION_ERROR","CHROME_EXTENSION_USER_GESTURE_REQUIRED","CHROME_EXTENSION_USER_CANCELED","CONSTRAINT_FAILED","ELECTRON_DESKTOP_PICKER_ERROR","ELECTRON_DESKTOP_PICKER_NOT_FOUND","FIREFOX_EXTENSION_NEEDED","GENERAL","NOT_FOUND","PERMISSION_DENIED","TRACK_IS_DISPOSED","TRACK_NO_STREAM_FOUND","UNSUPPORTED_RESOLUTION","peerConnectionIdCounter","rtcTrackIdCounter","createLocalTracks","tracksInfo","newTracks","trackInfo","safeCounterIncrement","localTrack","JitsiLocalTrack","rtcId","_newCreateLocalTracks","metaData","getSettings","RTC","conference","peerConnections","localTracks","_channel","_channelOpen","_lastN","_lastNEndpoints","_maxFrameHeight","_pinnedEndpoint","_selectedEndpoints","_lastNChangeListener","_onLastNChanged","_onDeviceListChanged","_updateAudioOutputForAudioTracks","RTCUtils","addListener","newObtainAudioAndVideoPermissions","obtainAudioAndVideoPermissions","eventType","isP2P","elSelector","getCurrentlyAvailableMediaDevices","getEventDataForActiveDevice","setAudioOutputDevice","isUserStreamById","streamId","isDesktopSharingEnabled","_channelOpenListener","wsUrl","BridgeChannel","sendPinnedEndpointMessage","sendSelectedEndpointsMessage","sendReceiverVideoConstraintMessage","_selectedEndpoint","sendSetLastNMessage","lastNEndpoints","oldLastNEndpoints","leavingLastNEndpoints","enteringLastNEndpoints","isInLastN","JitsiConferenceEvents","maxFrameHeight","ids","signaling","iceConfig","getPCConstraints","abtestSuspendVideo","setSuspendVideo","addPermanentProperties","supportsSdpSemantics","sdpSemantics","newConnection","TraceablePeerConnection","traceablePeerConnection","localVideo","getLocalTracks","localAudio","tracks","getType","remoteTracks","pcRemoteTracks","getRemoteTracks","mutePromises","audioTrack","mute","unmute","all","pos","owner","removedTracks","pcRemovedTracks","removeRemoteTracks","audioLevel","getTrackBySSRC","isAudioTrack","setAudioLevel","sendMessage","remoteAudioTracks","setAudioOutput","TRACK_ERROR_TO_MESSAGE_MAP","JitsiTrackErrors","constraint","failedConstraintName","getResolutionFromFailedConstraint","constructor","LOCAL_TRACK_STOPPED","TRACK_AUDIO_OUTPUT_CHANGED","TRACK_VIDEOTYPE_CHANGED","NO_DATA_FROM_SOURCE","CHAT_ERROR","CONFERENCE_DESTROYED","CONFERENCE_MAX_USERS","CONNECTION_ERROR","NOT_ALLOWED_ERROR","INCOMPATIBLE_SERVER_VERSIONS","OFFER_ANSWER_FAILED","PASSWORD_NOT_SUPPORTED","SETUP_FAILED","VIDEOBRIDGE_NOT_AVAILABLE","SDP","mediaI","failICE","removeTcpCandidates","removeUdpCandidates","getMediaSsrcMap","tmp","mediaSSRCs","mediaindex","mid","linessrc","idx","containsSSRC","medias","mangle","newdesc","rtpmap","removeSessionLines","removeMediaLines","toJingle","thecreator","assrcline","creator","amidline","afmtpline","rtcpFbToJingle","crypto","required","ssrcMap","availableSsrc","ssrcParameters","ssrcSdpLine","kv","v","ridLines","rids","ridLine","ridInfo","senders","transportToJingle","sctpmap","sctpAttrs","number","setup","payloadtype","rtcpFbFromJingle","each","$","fromJingle","jingle","groups","contents","_","jingle2media","sctp","streamCount","CHROME","OPERA","FIREFOX","INTERNET_EXPLORER","EDGE","SAFARI","NWJS","ELECTRON","REACT_NATIVE","UNKNOWN","bowserNameToJitsiName","_detectElectron","userAgent","version","_detectNWJS","_detectReactNative","product","_detect","browserInfo","detectors","bowser","chrome","_detectChromiumBased","BrowserDetection","detectedBrowserInfo","_name","_version","compareVersions","compareVersion","STATUS_AVAILABLE","STATUS_UNDEFINED","STATUS_BUSY","STATE_ON","STATE_OFF","STATE_PENDING","STATE_RETRYING","STATE_FAILED","ERROR_NO_CONNECTION","ERROR_SESSION_EXISTS","WRONG_STATE","parser","writer","write","parseFmtpConfig","parseParams","parsePayloads","parseRemoteCandidates","parseImageAttributes","parseSimulcastStreamList","AUDIO_LEVEL","BEFORE_DISPOSED","BYTE_SENT_STATS","CONNECTION_STATS","removeEventListener","off","LOCAL_STATS_UPDATED","REMOTE_STATS_UPDATED","parsePrimarySSRC","parseSecondarySSRC","_getSSRCCount","MLineWrap","ssrcNumber","attrName","ssrcObj","ssrcNum","primarySSRC","msid","findGroup","fecGroup","findGroupByPrimarySSRC","videoSSRCs","getSSRCs","ssrcGroupInfo","secondarySsrc","groupInfo","oldSSRC","newSSRC","SdpTransformWrap","rawSDP","parsedSDP","transform","selectedMLine","ACTIONS","ACCEPT","INITIATE","TERMINATE","UNAVAILABLE","ReflectOwnKeys","R","Reflect","ReflectApply","target","receiver","ownKeys","getOwnPropertySymbols","getOwnPropertyNames","NumberIsNaN","_events","_eventsCount","_maxListeners","defaultMaxListeners","$getMaxListeners","_addListener","prepend","events","existing","warning","newListener","warned","emitter","count","onceWrapper","fired","wrapFn","_onceWrap","state","wrapped","_listeners","unwrap","evlistener","arr","unwrapListeners","arrayClone","listenerCount","copy","RangeError","getPrototypeOf","setMaxListeners","getMaxListeners","doError","er","context","listeners","prependListener","once","prependOnceListener","list","position","originalListener","spliceOne","rawListeners","eventNames","order","PENDING","ACTIVE","ENDED","_fabrics","wrtcFuncNames","fabricEvent","DEFAULT_REMOTE_USER","reportType","hasFabric","fabrics","backendInitialized","_addNewFabric","_emptyReportQueue","backend","atLeastOneFabric","defaultInstance","csInstance","defaultConfID","defaultPC","reportsQueue","report","errorData","_reportError","pc","eventData","sendFabricEvent","associateMstWithUserID","callStatsId","_error","reportError","theBackend","tryCatchMethods","methodName","originalMethod","theArguments","debugMethods","originalReportError","exception","configParams","CallStatsBackend","callstats","_traceAndCatchBackendCalls","applicationVersion","getName","siteID","initialize","_initCallback","attachWifiStatsHandler","addresses","_reportEvent","conferenceID","sendUserFeedback","fabricAttributes","remoteEndpointType","endpointType","peer","server","addNewFabric","fabricUsage","multiplex","_addNewFabricCallback","success","streamEndpointId","fabricTerminated","_callStatsUserName","_machineId","getLocalStorage","storage","localStorage","_p8","username","UsernameGenerator","generateUsername","jitsiMeetId","sessionId","ALPHANUM","randomElement","randomHexDigit","randomHexString","randomAlphanumStr","getConnectionPluginDefinition","ConnectionPluginListenable","DEFAULT_STUN_SERVERS","urls","JITSI_MEET_MUC_TYPE","XMPP","token","disconnectInProgress","connectionTimes","authenticatedUser","_initStrophePlugins","bosh","conn","createConnection","_lastSuccessTracker","LastSuccessTracker","startTracking","caps","Caps","clientNode","initFeaturesList","ev","addFeature","disableRtx","supportsRtx","enableLipSync","rayo","_pingSupported","credentials","performance","statusStr","getStatusString","XMPPEvents","useStunTurn","p2p","getStunAndTurnCredentials","pingJid","getFeaturesAndIdentities","identities","PING","ping","startInterval","identity","speakerStatsComponentAddress","_onPrivateMessage","password","JitsiConnectionEvents","anonymousConnectionFailed","connectionFailed","lastErrorMsg","JitsiConnectionErrors","stopInterval","wasIntentionalDisconnect","errMsg","_getConnectionFailedReasonDetails","lastErrorStatus","getLastErrorStatus","connectionHandler","attaching","hosts","anonymousdomain","configDomain","hostname","onCreateResource","roomjid","muc","mucNickname","emuc","createRoom","getLog","dial","isPingSupported","sessions","disconnectListener","evType","sendBeacon","jvb","iceServers","p2pStunServers","stunServers","iceTransportPolicy","initEmuc","initJingle","initStropheUtil","initPing","initRayo","initStropheLogger","deploymentInfo","shard","headersArr","trim","shard_changed","suspend_time","getPingSuspendTime","time_since_last_success","getTimeSinceLastSuccess","room","jsonString","json","jsonMessage","parsedJson","tryParseJSONAndVerify","users","CONNECTION_DROPPED_ERROR","OTHER_ERROR","SERVER_ERROR","PEER_MUTED_CHANGED","PEER_VIDEO_TYPE_CHANGED","logDisabled_","deprecationWarnings_","disableLog","bool","disableWarnings","deprecated","oldMethod","newMethod","extractVersion","uastring","expr","detectBrowser","mozGetUserMedia","webkitGetUserMedia","webkitRTCPeerConnection","shimCreateObjectURL","ENVIRONMENT","chromeExtInstalled","chromeExtUpdateRequired","gumFunction","ScreenObtainer","intChromeExtPromise","desktopSharingChromeDisabled","desktopSharingChromeExtId","desktopSharingFirefoxDisabled","_createObtainStreamMethod","isNWJS","JitsiMeetNW","obtainDesktopStream","jitsiError","isElectron","obtainScreenOnElectron","isOpera","supportsGetDisplayMedia","obtainScreenFromGetDisplayMedia","append","getWebStoreInstallUrl","initInlineInstalls","checkChromeExtInstalled","installed","updateRequired","initChromeExtension","obtainScreenFromExtension","obtainScreenOnFirefox","errorCallback","streamCallback","failCallback","obtainWebRTCScreen","JitsiMeetScreenObtainer","openDesktopPicker","desktopSharingChromeSources","streamType","onGetStreamResponse","doGetStreamFromExtensionOptions","runtime","getStream","sources","lastError","doGetStreamFromExtension","alert","handleExternalInstall","webStoreInstallUrl","checkForChromeExtensionOnInterval","checkAgain","waitInterval","retries","currentRetries","interval","waitForExtensionAfterInstall","getDisplayMedia","getVersion","extVersion","minVersion","s1","s2","n1","n2","isUpdateRequired","desktopSharingChromeMinExtVersion","DEFAULT_NOT_IN_LAST_N_TIMEOUT","DEFAULT_RTC_MUTE_TIMEOUT","ParticipantConnectionStatus","INACTIVE","INTERRUPTED","RESTORING","ParticipantConnectionStatusHandler","rtc","trackTimers","connStatusFromJvb","outOfLastNTimeout","rtcMuteTimeout","rtcMutedTimestamp","enteredLastNTimestamp","restoringTimers","connectionStatusMap","isConnectionActiveByJvb","isRestoringTimedout","isVideoMuted","isVideoTrackFrozen","supportsVideoMuteOnConnInterrupted","_onEndpointConnStatusChanged","onEndpointConnStatusChanged","_onP2PStatus","refreshConnectionStatusForAll","_onUserLeft","onUserLeft","_onTrackRtcMuted","onTrackRtcMuted","_onTrackRtcUnmuted","onTrackRtcUnmuted","_onRemoteTrackAdded","onRemoteTrackAdded","_onRemoteTrackRemoved","onRemoteTrackRemoved","_onSignallingMuteChanged","onSignallingMuteChanged","_onTrackVideoTypeChanged","onTrackVideoTypeChanged","_onLastNValueChanged","participantIds","clearRtcMutedTimestamp","endpointId","isActive","myUserId","figureOutConnectionStatus","participant","newStatus","getConnectionStatus","getId","_setConnectionStatus","remoteTrack","getParticipantId","JitsiTrackEvents","hasAnyVideoRTCMuted","hasAnyVideoTrackWebRTCMuted","_getVideoFrozenTimeout","participants","getParticipants","getParticipantById","inP2PMode","isP2PActive","isRestoringTimedOut","_isRestoringTimedout","audioOnlyMode","getLastN","isConnActiveByJvb","newState","_getNewStateForP2PMode","_getNewStateForJvbMode","_clearRestoringTimer","oldConnectionStatus","connectionStatus","nowMs","maybeSendParticipantConnectionStatusEvent","startedMs","getTracksByMediaType","_changeConnectionStatus","participantConnectionStatus","leavingLastN","enteringLastN","rTimer","isMuted","getFocusRecordingUpdate","presence","jibriStatus","initiator","recordingMode","sessionID","getHiddenDomainUpdate","liveStreamViewURLContainer","liveStreamViewURL","modeContainer","sessionIDContainer","getSessionIdFromIq","jibri","getSessionId","sessionIdContainer","isFromFocus","g","JingleSessionPC","localJid","remoteJid","mediaConstraints","isInitiator","_bridgeSessionId","_iceCheckingStartedTimestamp","_gatheringStartedTimestamp","_localVideoActive","_remoteVideoActive","_gatheringReported","lasticecandidate","closed","signalingLayer","SignalingLayerImpl","modificationQueue","AsyncQueue","wasConnected","establishmentDuration","jingleContents","videoContents","JingleSessionState","isReconnect","wasstable","webrtcIceUdpDisable","webrtcIceTcpDisable","pcOptions","gatherStats","maxstats","capScreenshareBitrate","disableSimulcast","disableH264","preferH264","_abtestSuspendVideoEnabled","enableFirefoxSimulcast","testing","enableLayerSuspension","startSilent","createPeerConnection","onicecandidate","phase","sendIceCandidate","onsignalingstatechange","signalingState","connectionState","oniceconnectionstatechange","iceConnectionState","reconnect","iceStarted","onnegotiationneeded","setChatRoom","isSelected","setIsSelected","finishedCallback","_renegotiate","localSDP","localDescription","ice","sdpMLineIndex","jcand","usedrip","dripContainer","sendIceCandidates","candidates","_assertNotEnded","initiatorJid","cands","sdpMid","fingerprintLine","newJingleErrorHandler","sessionInfo","iceCandidates","rtcCandidate","RTCIceCandidate","iceCandidate","addIceCandidate","outerHTML","ssrcElement","setSSRCOwner","i3","ssrcInfoElement","generateRecvonlySsrc","jingleOffer","failure","setOfferAnswerCycle","sendSessionAccept","createOffer","offerSdp","setLocalDescription","sendSessionInitiate","jingleAnswer","jingleOfferAnswerIq","newRemoteSdp","_processNewJingleOfferIq","oldLocalSdp","bridgeSessionId","sendContentModify","newLocalSdp","notifyMySSRCUpdate","jingleOfferElem","originalOffer","clone","remove","newFingerprint","sendTransportAccept","accept","responder","responderJid","videoTransferActive","newSendersValue","sessionModify","transportAccept","medialines","transportReject","sendSessionTerminate","sessionTerminate","reasonDescription","terminate","reasonCondition","reasonText","sourceAddElem","currentRemoteSdp","addSsrcInfo","i1","i2","_addOrRemoveRemoteStream","isAdd","logPrefix","readSsrcInfo","remoteDescription","addOrRemoveSsrcInfo","_parseSsrcInfoFromSourceAdd","_parseSsrcInfoFromSourceRemove","_processRemoteAddSource","_processRemoteRemoveSource","offerIq","remoteSdp","removeSsrcInfo","optionalRemoteSdp","RTCSessionDescription","_initiatorRenegotiate","_responderRenegotiate","setRemoteDescription","createAnswer","answer","offer","oldTrack","newTrack","workFunction","isVideoTrack","clearRecvonlySsrc","replaceTrack","shouldRenegotiate","newLocalSDP","setMaxBitRate","sourceRemoveElem","ssrcLines","operationName","oldSDP","currentLocalSDP","sdpDiff","SDPDiffer","addedMedia","getNewMedia","removedMedia","_addRemoveTrackAsMuteUnmute","isMute","oldLocalSDP","removeTrackMute","addTrackUnmute","_verifyNoSSRCChanged","audioActive","videoActive","logAudioStr","logVideoStr","isSessionActive","audioActiveChanged","setAudioTransferActive","pcVideoActiveChanged","setVideoTransferActive","newVideoSenders","parseVideoSenders","_modifyRemoteVideoActive","remoteVideoSenders","isRemoteVideoActive","newSDP","sdpDiffer","request","failureCb","errResponse","errorElSel","errorReasonSel","errorMsgSel","clear","finishCallback","shutdown","abTesting","enableSuspendVideoTest","_getInitiatorJid","integerHash","JingleSession","PERMISSION_PROMPT_IS_SHOWN","definition","detect","ua","getFirstMatch","regex","getSecondMatch","iosdevice","android","nexusMobile","nexusTablet","chromeos","silk","sailfish","tizen","webos","windowsphone","windows","mac","linux","edgeVersion","versionIdentifier","tablet","mobile","xbox","opera","samsungBrowser","coast","yandexbrowser","ucbrowser","maxthon","epiphany","puffin","sleipnir","kMeleon","osname","msedge","msie","chromeBook","vivaldi","seamonkey","firefox","firefoxos","phantom","slimer","blackberry","touchpad","bada","qupzilla","chromium","safari","googlebot","blink","webkit","gecko","ios","osVersion","getWindowsVersion","osversion","osMajorVersion","getVersionPrecision","iterator","versions","precision","chunks","delta","chunk","reverse","isUnsupportedBrowser","minVersions","strictMode","_bowser","browserList","browserItem","check","arrayEquals","array1","array2","equals","mySDP","otherSDP","myMedias","othersMedias","newMedia","othersMediaIdx","myMedia","othersMedia","otherSsrcGroup","mySsrcGroup","modify","sdpMediaSsrcs","modified","mediaSsrc","nv","cachedSetTimeout","cachedClearTimeout","process","defaultSetTimout","defaultClearTimeout","runTimeout","fun","currentQueue","queue","draining","queueIndex","cleanUpNextTick","drainQueue","marker","runClearTimeout","Item","noop","nextTick","title","env","argv","binding","cwd","chdir","dir","umask","E2E_RTT_CHANGED","AudioContext","webkitAudioContext","LocalStatsCollector","intervalId","intervalMilis","suspend","isLocalStatsSupported","analyser","createAnalyser","smoothingTimeConstant","fftSize","createMediaStreamSource","Uint8Array","frequencyBinCount","getByteTimeDomainData","newLevel","lastLevel","diff","samples","maxVolume","parseFloat","toFixed","timeDomainDataToAudioLevel","currentExecutingScript","relativeURL","loadCallback","script","referenceNode","scriptEl","scriptSrc","baseScriptSrc","lastIndexOf","onload","insertBefore","ON","OFF","trackHandler2Prop","addMediaStreamInactiveHandler","oninactive","JitsiTrack","streamInactiveHandler","trackMediaType","containers","disposed","_streamInactiveHandler","_setStream","_setHandler","container","_onTrackAttach","_maybeFireTrackAttached","_attachTTFMTracker","_onTrackDetach","active","getStreamId","trackId","getTrackId","nextValue","MAX_SAFE_INTEGER","SpeakerStats","displayName","isLocalStats","_userId","setDisplayName","_isLocalStats","setDominantSpeaker","totalDominantSpeakerTime","_dominantSpeakerStart","_hasLeft","newName","isNowDominantSpeaker","isDominantSpeaker","timeElapsed","total","IDENTITY_UPDATED","_setEffectInProgress","effect","isEnabled","_startStreamEffect","_constraints","_prevSetMuted","_facingMode","_trackEnded","_hasSentData","_testDataSent","_realDeviceId","_trackMutedTS","_onDeviceListWillChange","oldRealDeviceId","_setRealDeviceIdFromDeviceList","getTrack","_onAudioOutputDeviceChanged","_initNoDataFromSourceHandlers","_isNoDataFromSourceEventsEnabled","_fireNoDataFromSourceEvent","isReceivingData","storedMSID","getMSID","_streamEffect","_originalStream","startEffect","stopEffect","_stopStreamEffect","removeTrack","_switchStreamEffect","cont","_queueSetMuted","setMuted","_setMuted","logMuteInfo","doesVideoMuteByStreamRemove","enabled","_removeStreamFromConferenceAsMute","_unregisterHandlers","stopStream","streamOptions","getDeviceId","getCameraFacingMode","assign","streamsInfo","streamInfo","_addStreamToConferenceAsUnmute","_sendMuteStatus","_addLocalTrackAsUnmute","successCallback","_removeLocalTrackAsMute","detach","bytesSent","getConnectionState","trackSettings","_stopStreamInProgress","_switchCamera","_effectEnabled","some","JibriSession","_mode","_setSessionID","setStatus","_sessionID","_initiator","_liveStreamViewURL","_status","_terminator","appData","broadcastId","focusMucJid","_createIQ","recordingXMLUtils","_setErrorFromIq","errorIq","setError","children","VIDEO_PERMISSION_NAME","JitsiMediaDevices","_eventEmitter","_grantedPermissions","JitsiMediaDevicesEvents","_logOutputDevice","_handleGrantedPermissions","_permissionsApiSupported","permissions","query","deviceID","supported","promises","results","every","permissionStatus","consoleTransport","globalTransports","transportIdx","globalOptions","callerInfo","disableCallerInfo","fileLocation","column","getCallerInfo","logPrefixes","toISOString","fullLogParts","methods","LOG","webpackPolyfill","deprecate","paths","SDPUtils","localCName","generateIdentifier","splitLines","blob","splitSections","getDescription","sections","getMediaSections","matchPrefix","parseCandidate","address","relatedAddress","relatedPort","tcpType","usernameFragment","writeCandidate","toUpperCase","parseIceOptions","parseRtpMap","parsed","clockRate","numChannels","writeRtpMap","preferredPayloadType","writeExtmap","headerExtension","preferredId","writeFmtp","parameters","param","parseRtcpFb","parameter","writeRtcpFb","rtcpFeedback","fb","parseSsrcMedia","sp","colon","parseSsrcGroup","getMid","mediaSection","algorithm","getDtlsParameters","role","fingerprints","writeDtlsParameters","setupType","fp","getIceParameters","writeIceParameters","parseRtpParameters","description","codecs","headerExtensions","fecMechanisms","rtcp","rtpmapline","fmtps","writeRtpDescription","maxptime","extension","parseRtpEncodingParameters","encodingParameters","hasRed","hasUlpfec","flows","apt","encParam","codecPayloadType","rtx","fec","maxBitrate","parseRtcpParameters","rtcpParameters","remoteSsrc","cname","rsize","reducedSize","compound","mux","parseMsid","spec","planB","msidParts","parseSctpDescription","maxMessageSize","maxSizeLine","sctpPort","writeSctpDescription","generateSessionId","writeSessionBoilerplate","sessId","sessVer","sessUser","writeMediaSection","transceiver","iceGatherer","getLocalParameters","dtlsTransport","rtpSender","rtpReceiver","sendEncodingParameters","getDirection","getKind","isRejected","parseOLine","sessionVersion","netType","addressType","isValidSDP","grammar","reg","names","format","u","z","encoding","rate","subtype","sessionConfig","raddr","RegExp","dir2","RecordingResult","AUDIO_WEBM","AUDIO_OGG","TrackRecorder","recorder","startTime","startRecorder","trackRecorder","stopRecorder","determineCorrectFileType","MediaRecorder","isTypeSupported","AudioRecorder","jitsiConference","recorders","fileType","isRecording","instantiateTrackRecorder","updateNames","originalStream","getOriginalStream","createEmptyStream","mimeType","ondataavailable","dataEvent","recorderToRemove","getDisplayName","download","Blob","href","click","getRecordingResults","getFileType","getTokenAuthUrl","urlPattern","roleUpgrade","JitsiConnection","appID","errType","ANALYTICS_CONNECTION_DISCONNECTED","getJid","setToken","initJitsiConference","JitsiConference","getConnectionTimes","feature","submit","removeFeature","eventManager","JitsiConferenceEventManager","_init","componentsVersions","ComponentsVersions","jvbJingleSession","lastDominantSpeaker","dtmfManager","somebodySupportsDTMF","authEnabled","startAudioMuted","startVideoMuted","startMutedPolicy","isMutedByFocus","mutedByFocusActor","wasStopped","connectionQuality","ConnectionQuality","avgRtpStatsReporter","AvgRTPStatsReporter","avgRtpStatsN","_audioOutputProblemDetector","AudioOutputProblemDetector","isJvbConnectionInterrupted","speakerStatsCollector","SpeakerStatsCollector","deferredStartP2PTask","delay","backToP2PDelay","isP2PConnectionInterrupted","p2pJingleSession","videoSIPGWHandler","VideoSIPGW","recordingManager","RecordingManager","resourceCreator","isAuthenticatedUser","setupXMPPListeners","statsCurrentId","statisticsId","Settings","callStatsUserName","statsId","_onIceConnectionInterrupted","_onIceConnectionRestored","_onIceConnectionEstablished","_updateProperties","rttMonitor","RttMonitor","e2eping","E2ePing","setupRTCListeners","_peerConnStatusRtcMuteTimeout","_peerConnStatusOutOfLastNTimeout","statisticsDisplayName","callStatsCustomScriptUrl","setupChatRoomListeners","setupStatisticsListeners","enableTalkWhileMuted","TalkMutedDetection","setLastN","channelLastN","jvb121Status","Jvb121EventGenerator","p2pDominantSpeakerDetection","P2PDominantSpeakerDetection","userRegion","setLocalParticipantProperty","_maybeSetSITimeout","authenticateAndUpgradeRole","isJoined","joined","isP2PEnabled","isP2PTestModeEnabled","p2pTestMode","leave","onLocalTrackRemoved","closeBridgeChannel","_delayedIceFailed","cancel","removeXMPPListeners","destroy","onMemberLeft","getConnection","isAuthEnabled","isLoggedIn","authIdentity","getAuthLogin","isExternalAuthEnabled","moderator","getExternalAuthUrl","urlForPopup","getPopupLoginUrl","getLoginUrl","getLocalAudioTrack","getLocalVideoTrack","eventId","addCommandListener","command","addPresenceListener","removeCommandListener","removePresenceListener","sendTextMessage","elementName","getFromPresence","sendPrivateTextMessage","sendPrivateMessage","sendCommand","addToPresence","sendCommandOnce","removeCommand","removeFromPresence","setSubject","subject","isModerator","getTranscriber","transcriber","Transcriber","localAudioTracks","getTranscriptionStatus","transcriptionStatus","localVideoTrack","_fireAudioLevelChangeEvent","activeTpc","getActivePeerConnection","_fireMuteChangeEvent","actorParticipant","muteParticipant","myroomjid","actorId","_setConference","removeLocalTrack","muteHandler","audioLevelHandler","_doReplaceTrack","_setupNewTrack","replaceTrackPromises","addLocalTrack","setAudioMute","setVideoMute","addAsUnmutePromises","addTrackAsUnmute","removeAsMutePromises","removeTrackAsMute","getRole","isHidden","hiddenDomain","lock","lockRoom","JitsiConferenceErrors","unlock","selectParticipant","selectParticipants","selectEndpoints","pinParticipant","pinEndpoint","lastN","isInteger","isVideoActive","setMediaTransferActive","getParticipantCount","countHidden","kickParticipant","kick","_maybeClearSITimeout","_sessionInitiateTimeout","onMemberJoined","nick","statsID","botType","JitsiParticipant","_role","_botType","_updateFeatures","_maybeStartOrStopP2P","getFeatures","_supportsDTMF","updateDTMFSupport","setProperty","_onMemberBotTypeChanged","botParticipant","onMemberKicked","isSelfPresence","kickedParticipantId","kickedParticipant","onLocalRoleChanged","onUserRoleChanged","onDisplayNameChanged","_displayName","_tracks","onCallAccepted","setAnswer","onTransportInfo","transportInfo","addIceCandidates","removedTrack","_onIncomingCallP2P","jingleSession","rejectReason","supportsP2P","errorMsg","_shouldBeInP2PMode","_rejectIncomingCall","_acceptP2PIncomingCall","onIncomingCall","isFocus","_acceptJvbIncomingCall","serverRegion","_setBridgeChannel","acceptOffer","_suspendMediaTransferForJvbConnection","bridgeChannelType","webSocket","first","openBridgeChannel","supportsDataChannels","initializeBridgeChannel","onCallEnded","forceJvb121","p2pFailed","_stopP2PSession","onSuspendDetected","supportsDTMF","isDTMFSupported","sendTones","tones","duration","peerConnection","startRecording","stopRecording","isSIPCallingSupported","hangup","startTranscriber","stopTranscriber","getPhoneNumber","getPhonePin","setStartMutedPolicy","policy","getStartMutedPolicy","isStartAudioMuted","isStartVideoMuted","getLogs","getJingleLog","metadata","time","getXmppLog","removeLocalParticipantProperty","getLocalParticipantProperty","presMap","nodes","overallFeedback","detailedFeedback","remoteUserId","getLocalSSRC","getSSRC","getUsageLabel","_isFocus","mucJid","_fireIncompatibleVersionsEvent","sendEndpointMessage","sendChannelMessage","broadcastEndpointMessage","sendThroughVideobridge","messageType","messageToSend","isConnectionInterrupted","_onIceConnectionFailed","IceFailedNotification","sendIceFailedNotification","remoteID","getStatsID","_addRemoteJVBTracks","_addRemoteTracks","_addRemoteP2PTracks","logName","p2pEstablishmentDuration","jvbEstablishmentDuration","done","forceJVB121Ratio","establishmentDurationDiff","_setP2PStatus","_removeRemoteJVBTracks","changed","isEqual","analyticsKeys","getProperty","_maybeClearDeferredStartP2P","_removeRemoteTracks","_removeRemoteP2PTracks","sessionNickname","_resumeMediaTransferForJvbConnection","_startP2PSession","newP2PJingleSession","invite","userLeftEvent","peers","peerCount","shouldBeInP2P","myId","peersId","hasBotPeer","wasP2PEstablished","getP2PConnectionState","startP2PSession","peerJid","stopP2PSession","getSpeakerStats","getStats","setReceiverVideoConstraint","createVideoSIPGWSession","sipAddress","VideoSIPGWConstants","LARGE_ARRAY_SIZE","HASH_UNDEFINED","COMPARE_PARTIAL_FLAG","COMPARE_UNORDERED_FLAG","argsTag","arrayTag","asyncTag","boolTag","dateTag","errorTag","funcTag","genTag","mapTag","numberTag","nullTag","objectTag","proxyTag","regexpTag","setTag","stringTag","symbolTag","undefinedTag","arrayBufferTag","dataViewTag","reIsHostCtor","reIsUint","typedArrayTags","freeGlobal","global","freeSelf","freeExports","freeModule","moduleExports","freeProcess","nodeUtil","nodeIsTypedArray","isTypedArray","arraySome","predicate","mapToArray","setToArray","uid","arrayProto","funcProto","objectProto","coreJsData","funcToString","maskSrcKey","exec","IE_PROTO","nativeObjectToString","reIsNative","Buffer","propertyIsEnumerable","symToStringTag","nativeGetSymbols","nativeIsBuffer","isBuffer","nativeKeys","DataView","getNative","WeakMap","nativeCreate","dataViewCtorString","toSource","mapCtorString","promiseCtorString","setCtorString","weakMapCtorString","symbolProto","symbolValueOf","valueOf","Hash","entries","entry","ListCache","MapCache","SetCache","__data__","Stack","arrayLikeKeys","inherited","isArr","isArg","isArguments","isBuff","isType","skipIndexes","iteratee","baseTimes","isIndex","assocIndexOf","eq","baseGetTag","isOwn","unmasked","getRawTag","objectToString","baseIsArguments","isObjectLike","baseIsEqual","other","bitmask","customizer","equalFunc","objIsArr","othIsArr","objTag","getTag","othTag","objIsObj","othIsObj","isSameTag","equalArrays","byteLength","byteOffset","buffer","convert","isPartial","stacked","equalByTag","objIsWrapped","othIsWrapped","objUnwrapped","othUnwrapped","objProps","getAllKeys","objLength","othLength","skipCtor","objValue","othValue","compared","objCtor","othCtor","equalObjects","baseIsEqualDeep","baseIsNative","isObject","isMasked","isFunction","baseKeys","Ctor","arrLength","seen","arrValue","othIndex","keysFunc","symbolsFunc","offset","arrayPush","baseGetAllKeys","getSymbols","getMapData","getValue","pairs","resIndex","arrayFilter","symbol","ArrayBuffer","ctorString","isLength","baseUnary","xmppListeners","chatRoom","chatRoomForwarder","EventEmitterForwarder","actor","forward","getStatus","setTerminator","setInitiator","setParticipantPropertyListener","recorderSession","logObject","getError","AuthenticationEvents","txt","myJid","ts","updated","featuresChangedListener","_addConferenceXMPPListener","audioMuted","videoMuted","ignoreStartMuted","_onByteSentStatsReceived","dest","srcEvent","AnalyticsAdapter","analyticsHandlers","cache","permanentProperties","conferenceName","setAnalyticsHandlers","_setUserProperties","_sendEvent","setUserProperties","_verifyRequiredFields","objectType","containerType","objectId","_maybeCacheEvent","isSafariWithWebrtc","isSafari","isVersionLessThan","ondevicechange","usesUnifiedPlan","usesPlanB","RTCRtpTransceiver","_getChromiumBasedVersion","WINDOW","JS_MD5_NO_WINDOW","WEB_WORKER","NODE_JS","JS_MD5_NO_NODE_JS","COMMON_JS","JS_MD5_NO_COMMON_JS","AMD","ARRAY_BUFFER","JS_MD5_NO_ARRAY_BUFFER","HEX_CHARS","EXTRA","SHIFT","OUTPUT_TYPES","BASE64_ENCODE_CHAR","blocks","buffer8","Uint32Array","JS_MD5_NO_ARRAY_BUFFER_IS_VIEW","isView","createOutputMethod","outputType","Md5","update","createMethod","method","nodeWrap","eval","nodeMethod","createHash","digest","sharedMemory","h0","h1","h2","h3","bytes","hBytes","finalized","hashed","notString","lastByteIndex","finalize","bc","da","hex","arrayBuffer","base64","v1","v2","v3","base64Str","md5","KEYS_BY_BROWSER_TYPE","calculatePacketLoss","lostPackets","totalPackets","round","SsrcStats","loss","bitrate","upload","framerate","ConferenceStats","packetLoss","StatsCollector","statsInterval","_browserType","_usesPromiseGetStats","_getStatValue","_defineNewGetStatValueMethod","_defineGetStatValueMethod","baselineAudioLevelsReport","currentAudioLevelsReport","currentStatsReport","previousStatsReport","audioLevelReportHistory","audioLevelsIntervalId","conferenceStats","audioLevelsIntervalMilis","statsIntervalId","statsIntervalMilis","ssrc2stats","browsers","setLoss","setResolution","addBitrate","resetBitrate","setFramerate","startAudioLevelStats","processNewAudioLevelReport","processAudioLevelReport","supportsRtpStatistics","processNewStatsReport","processStatsReport","itemStatByKey","stat","pair","keyFromName","getNonNegativeStat","getStatValue","byteSentStats","receiveBandwidth","sendBandwidth","localCandidateType","localip","remoteCandidateType","conferenceStatsTransport","selected","local","localCandidateId","remote","remoteCandidateId","ipAddress","portNumber","candidateType","msType","remoteAddress","localAddress","before","ssrcIds","isRemote","remoteSource","ssrcStats","isDownloadStream","packetsNow","packetsBefore","packetsDiff","packetsLostNow","packetsLostBefore","packetsLostDiff","packetsTotal","packetsLost","bytesReceivedNow","bytesReceivedBefore","bytesReceived","nowBytesTransmitted","timeMs","timestamp","bitrateReceivedKbps","bitrateSentKbps","_processAndEmitReport","bitrateDownload","bitrateUpload","resolutions","framerates","audioBitrateDownload","audioBitrateUpload","videoBitrateDownload","videoBitrateUpload","userResolutions","userFramerates","localAvgAudioLevels","avgAudioLevels","avgAudioLevel","reduce","sum","currentValue","getNonNegativeValue","_calculateBitrate","fieldName","bytesNow","bytesBefore","bytesProcessed","bitrateKbps","nominated","availableIncomingBitrate","availableOutgoingBitrate","remoteUsedCandidate","localUsedCandidate","remoteIpAddress","remotePort","localIpAddress","localPort","localIp","networkType","currentRoundTripTime","framerateMean","frameHeight","frameWidth","framesPerSecond","framesSent","trackIdentifier","getSsrcByTrackId","hidden","_jid","_id","_conference","_hidden","_statsID","_connectionStatus","_properties","_identity","jitsiTrack","isWebRTCTrackMuted","oldValue","_isMediaTypeMuted","rejectPromise","onLoginSuccessful","roomPassword","canceled","authenticationError","connectionError","MucConnectionPlugin","rooms","onPresence","onPresenceUnavailable","onPresenceError","onMessage","onMute","ChatRoom","createNonAnonymousRoom","packet2JSON","json2packet","packet","filterNodeFromPresenceJSON","members","presHandlers","noBridgeAvailable","Moderator","initPresenceMap","lastPresences","phoneNumber","phonePin","participantPropertyListener","locked","JitsiTranscriptionStatus","xns","addVideoInfoToPresence","disableFocus","allocateConferenceFocus","fromJoin","getInfo","getForm","form","formSubmit","member","statusEl","hasStatusUpdate","hasVersionUpdate","xElement","mucUserItem","affiliation","getFocusUserJid","isHiddenDomain","fromHiddenDomain","xEl","extractIdentityInformation","userInfo","newRole","_initFocus","memberOfThis","displayJids","att","phone","pin","processNode","tagHandlers","nickname","skipEvents","onMucMemberLeft","reasonSelect","doLeave","isKick","membersKeys","actorNick","actorSelect","onParticipantLeft","subjectText","stamp","dateParts","discoRoomInfo","kickIQ","onError","onNotSupported","formsubmit","handlerIdx","sendVideoInfoPresence","sendAudioInfoPresence","addAudioInfoToPresence","mutedNode","videoTypeNode","isSipGatewayEnabled","iqToFocus","onMucLeft","doReject","createExpBackoffTimer","step","origin","xmppService","getNextTimeout","getNextErrorTimeout","externalAuthEnabled","sipGatewayEnabled","call_control","attachEvent","setFocusUserJid","focusJid","focusUserJid","getFocusComponent","focusComponent","focus","createConferenceIq","openSctp","machineUID","machineId","enforcedBridge","enableTcc","enableRemb","minParticipants","audioPacketDelay","startBitrate","minBitrate","octo","probability","stereo","useRoomAsSharedDocumentName","parseSessionId","resultIq","parseConfigOptions","authenticationEnabled","_allocateConferenceFocusSuccess","_allocateConferenceFocusError","invalidSession","reservationErr","errorCode","errorTextNode","waitMs","retrySec","urlCallback","failureCallback","_getLoginUrl","popup","urlCb","decodeURIComponent","logout","logoutUrl","JingleConnectionPlugin","jvbIceConfig","p2pIceConfig","offerToReceiveAudio","offerToReceiveVideo","onJingle","fromJid","ack","sess","startMuted","modifyContents","replaceTransport","successTime","sendTransportReject","addRemoteStream","removeRemoteStream","me","onTerminated","iceservers","dict","credential","updateLog","ConnectionPlugin","doInitialize","ssrcOwners","oldChatRoom","_audioMuteHandler","_videoMuteHandler","_videoTypeHandler","SignalingEvents","getMediaPresenceInfo","SignalingLayer","_queue","_processQueueTasks","_stopped","kill","task","previous_async","only_once","fn","called","noConflict","_toString","_isArray","_each","_map","_keys","setImmediate","completed","eachSeries","iterate","forEachSeries","eachLimit","limit","_eachLimit","forEachLimit","started","running","replenish","doParallel","doSeries","_asyncMap","eachfn","mapSeries","mapLimit","_mapLimit","doParallelLimit","memo","inject","foldl","reduceRight","reversed","foldr","_filter","filterSeries","select","selectSeries","_reject","rejectSeries","main_callback","detectSeries","any","sortBy","criteria","left","right","auto","tasks","remainingTasks","taskComplete","theCallback","taskCallback","safeResults","rkey","requires","ready","retry","times","attempts","wrappedTask","wrappedCallback","wrappedResults","retryAttempt","finalAttempt","seriesCallback","series","waterfall","wrapIterator","_parallel","parallel","parallelLimit","makeCallback","cb","concatSeries","whilst","doWhilst","until","doUntil","worker","concurrency","_insert","drain","saturated","workers","empty","idle","priorityQueue","_compareTasks","sequence","compare","beg","end","_binarySearch","cargo","working","drained","_console_fn","memoize","hasher","queues","memoized","unmemoized","unmemoize","counter","timesSeries","seq","fns","newargs","nextargs","compose","_applyEach","go","applyEach","applyEachSeries","forever","resetLastErrorStatusRegExpr","lastErrorStatusRegExpr","trace","errStatusCapture","PING_TIMESTAMPS_TO_KEEP","PingConnectionPlugin","failedPings","pingExecIntervals","_addPingExecutionTimestamp","pingIntervals","maxInterval","previousTS","currentInterval","RayoConnectionPlugin","onRayo","roomPass","callResource","StropheLogger","logIncoming","logOutgoing","LastRequestTracker","_nextValidRid","_lastSuccess","stropheConnection","IDENTITY_PROPERTIES","IDENTITY_PROPERTIES_FOR_COMPARE","compareIdentities","generateSha","sortedIdentities","accumulatedValue","sortedFeatures","disco","versionToCapabilities","jidToVersion","_addChatRoom","_removeChatRoom","CAPS","_handleCaps","_onMucMemberLeft","_removeJidToVersionEntry","_generateVersion","_getDiscoInfo","sha","receivedNode","category","_fixChatRoomPresenceMap","_identities","_features","_notifyVersionChanged","oldVersion","_audioLevel","myUserID","_areRetriesEnabled","_closedFromClient","datachannel","createDataChannel","_handleChannel","_wsUrl","_initWebSocket","ws","timeoutS","_retryTimeout","reload","isOpen","closeEvent","_stopConnectionRetries","_startConnectionRetries","OPEN","colibriClass","msgPayload","jsonObject","pinnedEndpoint","endpointIds","selectedEndpoints","maxFrameHeightPixels","channel","dominantSpeakerEndpoint","endpoint","_retryWebSocketConnection","SIMULCAST_LAYERS","SIM_LAYER_RIDS","SIM_LAYER_BITRATES_BPS","audioTransferActive","_dtmfSender","_dtmfTonesQueue","_addedStreams","localSSRCs","localUfrag","remoteUfrag","_peerVideoTypeChanged","_peerMutedChanged","statsinterval","Interop","interop","Simulcast","simulcast","numOfLayers","explodeRemoteSimulcast","sdpConsistency","SdpConsistency","localSdpMunger","LocalSdpMunger","rtxModifier","RtxModifier","what","onaddstream","_remoteStreamAdded","onremovestream","_remoteStreamRemoved","ondatachannel","_processStat","statValue","endTime","dumpSDP","_getDesiredMediaDirection","mediaTransferActive","hasAnyTracksOfType","isSimulcastOn","supportsSimulcast","videoTrack","_setVideoType","setMute","endpoints","endpointTrackMap","mediaTrack","findTrackById","onaddtrack","_remoteTrackAdded","onremovetrack","_remoteTrackRemoved","streamAudioTracks","streamVideoTracks","mediaLines","mls","trackSsrc","ownerEndpointId","getSSRCOwner","peerMediaInfo","getPeerMediaInfo","_createRemoteTrack","remoteTracksMap","existingTrack","JitsiRemoteTrack","isUserStream","_removeRemoteTrackById","_getRemoteTrackById","removedAudioTrack","removedVideoTrack","_removeRemoteTrack","toBeRemoved","normalizePlanB","firstSsrcs","newSsrcLines","isVersionGreaterThan","filteredLines","ssrcId","cnameLine","replaceDefaultUnifiedPlanMsid","resStr","_getSSRC","_injectSsrcGroupForUnifiedSimulcast","simulcast_03","getters","toPlanB","maybeAddMutedLocalVideoTracksToSDP","transformer","audioMedia","selectMedia","videoMedia","toRawSDP","enforceSendRecv","transformStreamIdentifiers","webrtcStream","_addStream","generateNewStreamSSRCInfo","setPrimarySsrc","setSsrcCache","fidGroups","rtxSsrcMapping","rtxSsrc","_assertTrackBelongs","webRtcStream","addStream","_removeStream","supportsRtpSender","_handleSenderRemoveStream","removeStream","doesBelong","isMediaStreamInPc","findSenderByStream","getSenders","sender","extractPrimarySSRC","opts","_ensureSimulcastGroupIsLast","localSdp","sdpStr","videoStartIndex","simStartIndex","otherStartIndex","simEndIndex","simStr","otherEndIndex","sdpHead","simStrTrimmed","sdpTail","_adjustLocalMediaDirection","modifiedDirection","desiredAudioDirection","desiredVideoDirection","parsedSdp","toUnifiedPlan","_insertUnifiedPlanSimulcastReceive","getParameters","encodings","setParameters","mungeRemoteDescription","stripRtx","_injectH264IfNotPresent","dummyPayloadType","payloadsArray","interToneGap","dtmf","localAudioTrack","createDTMFSender","ontonechange","_onToneChange","toneBuffer","insertDTMF","tone","clearVideoSsrcCache","peerTracks","_removePeerConnection","hasCameraTrack","simParams","scaleResolutionDownBy","_createOfferOrAnswer","isOffer","handleSuccess","resultSdp","resolveFn","rejectFn","hasPrimarySsrcCached","makeVideoPrimarySsrcsConsistent","mungeLocalDescription","modifyRtxSsrcs","groupsMap","groupSSRCs","extractSSRCMap","_processLocalSSRCsMap","handleFailure","trackMSID","newSSRCNum","oldSSRCNum","currNumSsrcs","videoSender","simIndex","handleLayerSuspension","ttfmTrackerAudioAttached","ttfmTrackerVideoAttached","containerEvents","hasBeenMuted","_bindTrackHandlers","_containerHandlers","_containerEventHandler","_onTrackMute","_onTrackUnmute","gumStart","gumEnd","gumDuration","ttfm","_playCallback","_getStatus","localVideos","isInPeerConnection","shouldFakeSdp","requiredSSRCs","ssrcCache","cachedPrimarySsrc","primaryCname","removeSSRC","addSSRCAttribute","addSSRCGroup","modifyRtxSsrcs2","pcId","streamAndTrackIDs","_addMutedLocalVideoTracksToSDP","sessionDesc","audioMLine","_transformMediaIdentifiers","updateAssociatedRtxStream","primarySsrcInfo","primarySsrcMsid","primarySsrcCname","previousRtxSSRC","getRtxSSRC","dumpSSRCGroups","removeGroupsWithSSRC","correspondingRtxSsrcs","ssrcMapping","sdpTransformer","getSSRCCount","primaryVideoSsrcs","getPrimaryVideoSSRCs","getSSRCAttrValue","correspondingRtxSsrc","previousAssociatedRtxStream","containsAnySSRCGroups","findGroups","removeGroupsBySemantics","injectRecvOnly","newPrimarySsrc","getPrimaryVideoSsrc","replaceSSRC","_eventFired","_trackMuteChanged","_trackAdded","_isLocalAudioTrack","STATS_MESSAGE_TYPE","kSimulcastFormats","layers","videoBitrateCap","getTarget","millisSinceStart","simulcastFormat","targetHeight","pixels","rampUp","_localStats","jvbRTT","_lastConnectionQualityUpdate","_remoteStats","_timeIceConnected","_timeVideoUnmuted","_timeLastBwCapRemoved","ConferenceEvents","_updateLocalConnectionQuality","ConnectionQualityEvents","_broadcastLocalStats","_updateRemoteStats","_updateLocalStats","_maybeUpdateUnmuteTime","bridgeCount","resolutionName","quality","activeTPC","newVideoBitrateCap","bandwidthLimiter","getBandwidthLimit","prevConnectionQuality","diffSeconds","updateLocalConnectionQuality","_calculateConnectionQuality","_canceled","_iceFailedTimeout","ParticipantWrapper","requests","lastRequestId","clearIntervals","sendRequest","handleResponse","maybeSendAnalytics","isDataChannelOpen","pingInterval","pingIntervalMs","analyticsInterval","analyticsIntervalMs","requestId","requestMessage","timeSent","E2ePingEvents","Infinity","participantJoined","participantLeft","messageReceived","dataChannelOpened","participantWrapper","handleRequest","_jvb121","evaluateStatus","oldStatus","_sessions","_chatRoom","_handleFocusPresence","_handleJibriPresence","getSession","getID","_addSession","_emitSessionUpdate","_createSession","setLiveStreamViewURL","offerOptions","PCMonitor","getStatsIntervalMs","getStatsInterval","rtts","stopped","startStatsInterval","handleCandidateRtt","rttTotal","candidateKey","responsesReceived","requestsSent","rttTotalDiff","responsesReceivedDiff","requestsResponsesDiff","supportsLocalCandidateRttStatistics","pcMonitors","startPCMonitors","initialDelay","AverageStatReport","calculate","ConnectionAvgStats","_n","_sampleIdx","_avgRTT","_avgRemoteRTTMap","_avgRtpStatsReporter","_avgEnd2EndRTT","_onConnectionStats","_calculateAvgStats","_onRemoteStatsUpdated","_processRemoteStats","supportsRTTStatistics","addNext","batchReport","appendReport","jvbEnd2EndRTT","jvbStatsMonitor","avgRemoteRTT","_calculateAvgRemoteRTT","avgLocalRTT","_resetAvgStats","remoteAvg","avg","validData","rttAvg","_avgAudioBitrateUp","_avgAudioBitrateDown","_avgVideoBitrateUp","_avgVideoBitrateDown","_avgBandwidthUp","_avgBandwidthDown","_avgPacketLossTotal","_avgPacketLossUp","_avgPacketLossDown","_avgRemoteFPS","_avgRemoteScreenFPS","_avgLocalFPS","_avgLocalScreenFPS","_avgRemoteCameraPixels","_avgRemoteScreenPixels","_avgLocalCameraPixels","_avgLocalScreenPixels","_avgCQ","_onLocalStatsUpdated","_onP2PStatusChanged","p2pStatsMonitor","_onJvb121StatusChanged","_resetAvgJvbStats","confSize","supportsBandwidthStatistics","_calculateAvgVideoFps","_calculateAvgVideoPixels","peerResolutions","peerPixelsSum","myID","peerID","videosResolution","peerAvgPixels","_calculatePeerAvgVideoPixels","videos","peerSsrcCount","peerSsrcPixels","peerFpsSum","videosFps","peerAvgFPS","_calculatePeerAvgVideoFps","peerSsrcFps","_localAudioLevelCache","_reportedParticipants","_audioProblemCandidates","_numberOfRemoteAudioLevelsReceived","_onLocalAudioLevelsReport","_onRemoteAudioLevelReceived","_clearUserData","numberOfReports","isAudioMuted","localAudioLevelsString","dominantSpeakerId","_onDominantSpeaker","_onUserJoin","_onUserLeave","_onDisplayNameChange","_updateStats","oldDominantSpeaker","newDominantSpeaker","savedUser","markAsHasLeft","newStats","speakerStatsToUpdate","SphinxService","BEFORE_STATE","audioRecorder","transcriptionService","transcription","lineLength","blobCallBack","wordArray","getUTCMilliseconds","wordObject","begin","word","maybeMerge","hasPopulatedArrays","twoDimensionalArray","callBack","recordingResult","merge","arrays","potentialWords","pushWordToSortedArray","lowestWordArray","wordToAdd","updateTranscription","foundSmaller","wordToCompare","getTranscription","getState","processVersions","mucResource","getComponentVersion","componentName","sessionStateChangeListener","sessionStateChanged","handleJibriSIPState","Constants","sipaddress","setState","failure_reason","JitsiVideoSIPGWSession","addStateListener","removeStateListener","_sendJibriIQ","failureReason","oldState","displayname","BUSY","RESOURCE_CONSTRAINT","SERVICE_UNAVAILABLE","FILE","ProxyConnectionService","jitsiConnection","otherOptions","_options","_peerConnection","_onFatalError","_onSendMessage","_onRemoteStream","getPeerJid","_convertStringToXML","$jingle","_createPeerConnection","receiveVideo","processMessage","_selfCloseConnection","xml","xmlDom","onRemoteStream","onSendMessage","ProxyConnectionPC","jitsiRemoteTrack","isVideo","convertVideoToDesktop","jitsiLocalTracks","newCreateLocalTracks","stringifiedIq","XMLSerializer","serializeToString","onConnectionClosed","receiveAudio","_onSessionAccept","_onSessionInitiate","_onSessionTerminate","_onTransportInfo","connectionStub","iceConfigStub","roomStub","_rtc","default","getLowerResolution","resName","getAnalyticsAttributesFromOptions","video_requested","_mergeNamespaceAndModule","JitsiMeetJS","constants","recording","recordingConstants","sipVideoGW","errorTypes","logLevels","enableAnalyticsLogging","enableWindowOnErrorHandler","getGlobalOnErrorHandler","aprops","isWebRtcSupported","addGlobalLogTransport","globalTransport","removeGlobalLogTransport","setGlobalLogOptions","firePermissionPromptIsShownEvent","originalOptions","promiseFulfilled","emitEvent","mStream","currentlyAvailableMediaDevices","setVideoTrackContentHints","oldResolution","newResolution","isMultipleAudioInputSupported","isCollectingLocalStats","lineno","colno","hint","contentHint","util","AuthUtil","logStorage","stringifyObjects","storeInterval","maxEntryLength","logLevel","_log","storeLogsIntervalID","totalLen","outputCache","someObject","formatLogMessage","prevMessage","prevMessageText","_flush","_reschedulePublishInterval","force","reschedule","isReady","cachedQueue","storeLogs","__webpack_amd_options__","scriptReadyRegex","fullPageUrl","pageUrl","scripts","supportsScriptReadyState","isNotOpera","hasNativeCurrentScriptAccessor","stackTraceLimit","hasStackBeforeThrowing","hasStackAfterThrowing","_nearestExecutingScript","eligibleScripts","skipStackDepth","getScriptFromUrl","getScriptUrlFromStack","ignoreMessage","hasAttribute","getSoleInlineScript","currentScript","thrownErr","near","far","_items","_onDiscoInfo","_onDiscoItems","addIdentity","lang","var_name","addItem","call_back","items","_buildIQResult","query_attrs","iqresult","scope","Timeout","clearFn","_clearFn","unref","ref","enroll","msecs","_idleTimeoutId","unenroll","_unrefActive","_onTimeout","clearImmediate","registerImmediate","messagePrefix","onGlobalMessage","nextHandle","tasksByHandle","currentlyRunningATask","attachTo","handle","runIfPresent","postMessage","importScripts","postMessageIsAsynchronous","oldOnMessage","canUsePostMessage","MessageChannel","port1","port2","removeChild","adapterFactory","dependencies","shimChrome","shimFirefox","shimEdge","shimSafari","logging","browserDetails","adapter","chromeShim","edgeShim","firefoxShim","safariShim","commonShim","shimPeerConnection","browserShim","shimGetUserMedia","shimMediaStream","shimSourceObject","shimOnTrack","shimAddTrackRemoveTrack","shimGetSendersWithDtmf","shimRTCIceCandidate","shimReplaceTrack","shimRTCIceServerUrls","shimCallbacksAPI","shimLocalStreamsAPI","shimRemoteStreamsAPI","shimTrackEventTransceiver","shimCreateOfferLegacy","webkitMediaStream","_ontrack","origSetRemoteDescription","_ontrackpoly","te","getReceivers","Event","dispatchEvent","shimSenderWithDtmf","_dtmf","_pc","_senders","origAddTrack","origRemoveTrack","origAddStream","origRemoveStream","RTCRtpSender","origGetSenders","HTMLMediaElement","_srcObject","origGetLocalStreams","getLocalStreams","nativeStreams","_reverseStreams","_streams","DOMException","newStream","alreadyExists","oldStream","nativeMethod","isLegacyCall","replaceInternalStreamId","origSetLocalDescription","replaceExternalStreamId","origLocalDescription","getOwnPropertyDescriptor","streamid","internalId","externalStream","internalStream","OrigPeerConnection","pcConfig","newIceServers","generateCertificate","iceTransports","origGetStats","selector","fixChromeStats_","standardReport","standardStats","localcandidate","remotecandidate","makeMapStats","successCallbackWrapper_","nativeAddIceCandidate","constraintsToChrome_","cc","oldname_","oc","mix","advanced","shimConstraints_","remap","face","getSupportedFacingModeLies","getSupportedConstraints","dev","shimError_","PermissionDeniedError","InvalidStateError","DevicesNotFoundError","ConstraintNotSatisfiedError","TrackStartError","MediaDeviceFailedDueToShutdown","MediaDeviceKillSwitchOn","getUserMediaPromise_","kinds","MediaStreamTrack","getSources","origGetUserMedia","shimRTCPeerConnection","RTCIceGatherer","origMSTEnabled","RTCDtmfSender","setTrack","dtlsRole","_initialTrackId","getCommonCapabilities","localCapabilities","remoteCapabilities","commonCapabilities","findCodecByPayloadType","rtxCapabilityMatches","lRtx","rRtx","lCodecs","rCodecs","lCodec","rCodec","lHeaderExtension","rHeaderExtension","isActionAllowedInSignalingState","maybeAddCandidate","iceTransport","alreadyAdded","getRemoteCandidates","remoteCandidate","addRemoteCandidate","makeError","NotSupportedError","InvalidAccessError","OperationError","addTrackToStreamAndFireEvent","MediaStreamTrackEvent","fireAddTrack","trackEvent","_dispatchEvent","_eventTarget","canTrickleIceCandidates","needNegotiation","localStreams","remoteStreams","_localDescription","_remoteDescription","iceGatheringState","usingBundle","bundlePolicy","rtcpMuxPolicy","hasTurn","isString","filterIceServers","_iceGatherers","iceCandidatePoolSize","gatherPolicy","_config","transceivers","_sdpSessionId","_sdpSessionVersion","_dtlsRole","_isClosed","configurable","ontrack","onconnectionstatechange","onicegatheringstatechange","_emitGatheringStateChange","getConfiguration","getRemoteStreams","_createTransceiver","doNotAdd","hasBundleTransport","recvEncodingParameters","associatedRemoteMediaStreams","wantReceive","_createIceAndDtlsTransports","_maybeFireNegotiationNeeded","clonedStream","clonedTrack","_createIceGatherer","writable","bufferedCandidateEvents","bufferCandidates","_gather","onlocalcandidate","evt","serializedCandidate","toJSON","complete","RTCIceTransport","onicestatechange","_updateIceConnectionState","_updateConnectionState","RTCDtlsTransport","ondtlsstatechange","_disposeIceAndDtlsTransports","_transceive","recv","receive","isIceLite","rejected","remoteIceParameters","remoteDtlsParameters","_updateSignalingState","receiverList","iceOptions","remoteMsid","isComplete","setTransport","setRemoteCandidates","RTCRtpReceiver","getCapabilities","isNewTrack","nativeTrack","removeTrackFromStreamAndFireEvent","states","checking","disconnected","failed","new","connecting","numAudioTracks","numVideoTracks","remoteCodec","hdrExt","rHdrExt","getLocalCandidates","mediaSectionsInOffer","candidateString","senderOrReceiver","allStats","ortcObjectName","nativeGetstats","nativeStats","mapStats","inboundrtp","outboundrtp","candidatepair","RTCTrackEvent","mozSrcObject","mozRTCPeerConnection","newServer","mozRTCSessionDescription","mozRTCIceCandidate","modernStatsTypes","nativeGetStats","onSucc","onErr","InternalError","SecurityError","getUserMedia_","constraintsToFF37_","orgEnumerateDevices","nativeGetUserMedia","nativeGetSettings","nativeApplyConstraints","_localStreams","getStreamById","_remoteStreams","_addTrack","_onaddstream","_onaddstreampoly","withCallback","errcb","RTCTransceiver","origCreateOffer","audioTransceiver","getTransceivers","setDirection","addTransceiver","videoTransceiver","NativeRTCIceCandidate","nativeCandidate","parsedCandidate","augmentedCandidate","eventNameToWrap","nativeAddEventListener","nativeEventName","_eventMap","nativeRemoveEventListener","unwrappedCb","wrapPeerConnectionEvent","nativeCreateObjectURL","nativeRevokeObjectURL","newId","dsc","nativeSetAttribute","toIntIfInt","parseReg","needsBlank","keyLocation","rawName","attachProperties","validLine","paramReducer","acc","scid","formatRegExp","formatStr","makeLine","defaultOuterOrder","defaultInnerOrder","outerOrder","innerOrder","midToString","mlB2UMap","mlU2BMap","candidateToUnifiedPlan","candidateToPlanB","getFirstSendingIndexFromAnswer","rewrite","type2bl","types","directionResult","uLine","rtcpMux","directionMasks","bundleOnly","mids","msidSemantic","semantic","cached","hasBundle","recvonlySsrcs","mid2ul","bIdx","uIdx","bLine","uLineData","iceUfrag","icePwd","ssrc2group","ssrc2ml","related","transformUtils","parseSsrcs","writeSsrcs","DEFAULT_NUM_OF_LAYERS","processVideo","validateDescription","clearSsrcCache","_parseSimLayers","_buildNewToOldSsrcMap","newSsrcList","oldSsrcList","newSsrc","oldSsrc","_fillInSourceDataFromCache","newSimSsrcs","newMsid","newCname","ssrcsToReplace","ssrcsToAdd","_generateSourceData","addAssociatedStream","simSsrcs","simSsrc","_restoreSimulcast","simulcastSsrcs","relatedGroup","relatedSsrcs","relatedSSRC","simulcastGroup","nuke","implodeRemoteSimulcast","invalid","assertGoogConference","TranscriptionService","Word","sphinxURL","toReturn","getURL","audioFileBlob","DONE","formatResponse","objects","filler","verify","audioBlob","getWord","getBeginTime","getEndTime"],"mappings":"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","file":"lib-jitsi-meet.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"JitsiMeetJS\"] = factory();\n\telse\n\t\troot[\"JitsiMeetJS\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 118);\n","const XMPPEvents = {\n /**\n * Indicates error while adding ice candidate.\n */\n ADD_ICE_CANDIDATE_FAILED: 'xmpp.add_ice_candidate_failed',\n\n // Designates an event indicating that the focus has asked us to mute our\n // audio.\n AUDIO_MUTED_BY_FOCUS: 'xmpp.audio_muted_by_focus',\n AUTHENTICATION_REQUIRED: 'xmpp.authentication_required',\n BRIDGE_DOWN: 'xmpp.bridge_down',\n\n /**\n * Triggered when 'session-accept' is received from the responder.\n */\n CALL_ACCEPTED: 'xmpp.callaccepted.jingle',\n\n // Designates an event indicating that an offer (e.g. Jingle\n // session-initiate) was received.\n CALL_INCOMING: 'xmpp.callincoming.jingle',\n\n // Triggered when Jicofo kills our media session, this can happen while\n // we're still in the MUC, when it decides to terminate the media session.\n // For example when the session is idle for too long, because we're the only\n // person in the conference room.\n CALL_ENDED: 'xmpp.callended.jingle',\n CHAT_ERROR_RECEIVED: 'xmpp.chat_error_received',\n\n // The conference properties (as advertised by jicofo) have changed\n CONFERENCE_PROPERTIES_CHANGED: 'xmpp.conference_properties_changed',\n\n /**\n * This event is triggered when the ICE connects for the first time.\n */\n CONNECTION_ESTABLISHED: 'xmpp.connection.connected',\n\n // Designates an event indicating that the connection to the XMPP server\n // failed.\n CONNECTION_FAILED: 'xmpp.connection.failed',\n\n // Designates an event indicating that the media (ICE) connection was\n // interrupted. This should go to the RTC module.\n CONNECTION_INTERRUPTED: 'xmpp.connection.interrupted',\n\n // Designates an event indicating that the media (ICE) connection was\n // restored. This should go to the RTC module.\n CONNECTION_RESTORED: 'xmpp.connection.restored',\n\n // Designates an event indicating that the media (ICE) connection failed.\n // This should go to the RTC module.\n CONNECTION_ICE_FAILED: 'xmpp.connection.ice.failed',\n\n /**\n * Designates an event indicating connection status changes.\n */\n CONNECTION_STATUS_CHANGED: 'xmpp.connection.status.changed',\n\n // Designates an event indicating that the display name of a participant\n // has changed.\n DISPLAY_NAME_CHANGED: 'xmpp.display_name_changed',\n\n /**\n * Chat room instance have been added to Strophe.emuc plugin.\n */\n EMUC_ROOM_ADDED: 'xmpp.emuc_room_added',\n\n /**\n * Chat room instance have been removed from Strophe.emuc plugin.\n */\n EMUC_ROOM_REMOVED: 'xmpp.emuc_room_removed',\n ETHERPAD: 'xmpp.etherpad',\n FOCUS_DISCONNECTED: 'xmpp.focus_disconnected',\n FOCUS_LEFT: 'xmpp.focus_left',\n GRACEFUL_SHUTDOWN: 'xmpp.graceful_shutdown',\n\n /**\n * Event fired when 'transport-replace' Jingle message has been received,\n * before the new offer is set on the PeerConnection.\n */\n ICE_RESTARTING: 'rtc.ice_restarting',\n\n /**\n * Event fired after the 'transport-replace' message has been processed\n * and the new offer has been set successfully.\n */\n ICE_RESTART_SUCCESS: 'rtc.ice_restart_success',\n\n /**\n * Designates an event indicating that we were kicked from the XMPP MUC.\n * @param {boolean} isSelfPresence - whether it is for local participant\n * or another participant.\n * @param {string} actorJid - the jid of the participant who was initator\n * of the kick.\n * @param {?string} participantJid - when it is not a kick for local participant,\n * this is the jid of the participant which was kicked.\n */\n KICKED: 'xmpp.kicked',\n\n // Designates an event indicating that our role in the XMPP MUC has changed.\n LOCAL_ROLE_CHANGED: 'xmpp.localrole_changed',\n\n // Designates an event indicating that an XMPP message in the MUC was\n // received.\n MESSAGE_RECEIVED: 'xmpp.message_received',\n\n // Designates an event indicating that a private XMPP message in the MUC was\n // received.\n PRIVATE_MESSAGE_RECEIVED: 'xmpp.private_message_received',\n\n // Designates an event indicating that a bot participant type had changed\n MUC_MEMBER_BOT_TYPE_CHANGED: 'xmpp.muc_member_bot_type_changed',\n\n // Designates an event indicating that the XMPP MUC was destroyed.\n MUC_DESTROYED: 'xmpp.muc_destroyed',\n\n // Designates an event indicating that we have joined the XMPP MUC.\n MUC_JOINED: 'xmpp.muc_joined',\n\n // Designates an event indicating that a participant joined the XMPP MUC.\n MUC_MEMBER_JOINED: 'xmpp.muc_member_joined',\n\n // Designates an event indicating that a participant left the XMPP MUC.\n MUC_MEMBER_LEFT: 'xmpp.muc_member_left',\n\n // Designates an event indicating that local participant left the muc\n MUC_LEFT: 'xmpp.muc_left',\n\n // Designates an event indicating that the MUC role of a participant has\n // changed.\n MUC_ROLE_CHANGED: 'xmpp.muc_role_changed',\n\n // Designates an event indicating that the MUC has been locked or unlocked.\n MUC_LOCK_CHANGED: 'xmpp.muc_lock_changed',\n\n // Designates an event indicating that a participant in the XMPP MUC has\n // advertised that they have audio muted (or unmuted).\n PARTICIPANT_AUDIO_MUTED: 'xmpp.audio_muted',\n\n // Designates an event indicating that a participant in the XMPP MUC has\n // advertised that they have video muted (or unmuted).\n PARTICIPANT_VIDEO_MUTED: 'xmpp.video_muted',\n\n // Designates an event indicating that the video type (e.g. 'camera' or\n // 'screen') for a participant has changed.\n // Note: currently this event fires every time we receive presence from\n // someone (regardless of whether or not the \"video type\" changed).\n PARTICIPANT_VIDEO_TYPE_CHANGED: 'xmpp.video_type',\n\n /**\n * Indicates that the features of the participant has been changed.\n */\n PARTCIPANT_FEATURES_CHANGED: 'xmpp.partcipant_features_changed',\n PASSWORD_REQUIRED: 'xmpp.password_required',\n PEERCONNECTION_READY: 'xmpp.peerconnection_ready',\n\n /**\n * Indicates that phone number changed.\n */\n PHONE_NUMBER_CHANGED: 'conference.phoneNumberChanged',\n PRESENCE_RECEIVED: 'xmpp.presence_received',\n PRESENCE_STATUS: 'xmpp.presence_status',\n PROMPT_FOR_LOGIN: 'xmpp.prompt_for_login',\n\n // xmpp is connected and obtained user media\n READY_TO_JOIN: 'xmpp.ready_to_join',\n\n /**\n * Indicates that recording state changed.\n */\n RECORDER_STATE_CHANGED: 'xmpp.recorderStateChanged',\n\n // Designates an event indicating that we received statistics from a\n // participant in the MUC.\n REMOTE_STATS: 'xmpp.remote_stats',\n\n /**\n * Indicates that the offer / answer renegotiation has failed.\n */\n RENEGOTIATION_FAILED: 'xmpp.renegotiation_failed',\n RESERVATION_ERROR: 'xmpp.room_reservation_error',\n ROOM_CONNECT_ERROR: 'xmpp.room_connect_error',\n ROOM_CONNECT_NOT_ALLOWED_ERROR: 'xmpp.room_connect_error.not_allowed',\n ROOM_JOIN_ERROR: 'xmpp.room_join_error',\n\n /**\n * Indicates that max users limit has been reached.\n */\n ROOM_MAX_USERS_ERROR: 'xmpp.room_max_users_error',\n\n // Designates an event indicating that we sent an XMPP message to the MUC.\n SENDING_CHAT_MESSAGE: 'xmpp.sending_chat_message',\n\n // Designates an event indicating that we sent a private XMPP message to\n // a specific user of the muc.\n SENDING_PRIVATE_CHAT_MESSAGE: 'xmpp.sending_private_chat_message',\n\n /**\n * Event fired when we do not get our 'session-accept' acknowledged by\n * Jicofo. It most likely means that there is serious problem with our\n * connection or XMPP server and we should reload the conference.\n *\n * We have seen that to happen in BOSH requests race condition when the BOSH\n * request table containing the 'session-accept' was discarded by Prosody.\n * Jicofo does send the RESULT immediately without any condition, so missing\n * packets means that most likely it has never seen our IQ.\n */\n SESSION_ACCEPT_TIMEOUT: 'xmpp.session_accept_timeout',\n\n /**\n * Event fired when speaker stats update message is received.\n */\n SPEAKER_STATS_RECEIVED: 'xmpp.speaker_stats_received',\n\n // Designates an event indicating that we should join the conference with\n // audio and/or video muted.\n START_MUTED_FROM_FOCUS: 'xmpp.start_muted_from_focus',\n\n // Designates an event indicating that the subject of the XMPP MUC has\n // changed.\n SUBJECT_CHANGED: 'xmpp.subject_changed',\n\n // FIXME: how does it belong to XMPP ? - it's detected by the PeerConnection\n // suspending detected\n SUSPEND_DETECTED: 'xmpp.suspend_detected',\n\n /**\n * Notifies for transcription status changes. The event provides the\n * following parameters to its listeners:\n *\n * @param {String} status - The new status.\n */\n TRANSCRIPTION_STATUS_CHANGED: 'xmpp.transcription_status_changed',\n\n /**\n * Event fired when 'transport-info' with new ICE candidates is received.\n */\n TRANSPORT_INFO: 'xmpp.transportinfo.jingle',\n\n /**\n * Indicates that video SIP GW state changed.\n *\n * @param {VideoSIPGWConstants} status - Any of the following statuses:\n * STATUS_BUSY, STATUS_AVAILABLE or STATUS_UNDEFINED.\n */\n VIDEO_SIP_GW_AVAILABILITY_CHANGED: 'xmpp.videoSIPGWAvailabilityChanged',\n\n /**\n * Indicates that video SIP GW Session state changed.\n * The statuses are any of the following statuses:\n * STATE_ON, STATE_OFF, STATE_PENDING, STATE_RETRYING, STATE_FAILED.\n * {@see VideoSIPGWConstants}\n *\n * @param {options} event - {address, oldState, newState, displayName}.\n */\n VIDEO_SIP_GW_SESSION_STATE_CHANGED:\n 'xmpp.videoSIPGWSessionStateChanged',\n\n // Designates an event indicating that the local ICE connection state has\n // changed.\n ICE_CONNECTION_STATE_CHANGED: 'xmpp.ice_connection_state_changed',\n\n /**\n * Event which is emitted when the body in an XMPP message in the MUC\n * contains JSON\n */\n JSON_MESSAGE_RECEIVED: 'xmmp.json_message_received'\n};\n\nmodule.exports = XMPPEvents;\n","/** File: strophe.js\n * A JavaScript library for writing XMPP clients.\n *\n * This library uses either Bidirectional-streams Over Synchronous HTTP (BOSH)\n * to emulate a persistent, stateful, two-way connection to an XMPP server or\n * alternatively WebSockets.\n *\n * More information on BOSH can be found in XEP 124.\n * For more information on XMPP-over WebSocket see this RFC:\n * http://tools.ietf.org/html/rfc7395\n */\n\n/* All of the Strophe globals are defined in this special function below so\n * that references to the globals become closures. This will ensure that\n * on page reload, these references will still be available to callbacks\n * that are still executing.\n */\n\n/* jshint ignore:start */\n(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n //Allow using this built library as an AMD module\n //in another project. That other project will only\n //see this AMD call, not the internal modules in\n //the closure below.\n define([], factory);\n } else {\n //Browser globals case.\n var wrapper = factory();\n root.Strophe = wrapper.Strophe;\n root.$build = wrapper.$build;\n root.$iq = wrapper.$iq;\n root.$msg = wrapper.$msg;\n root.$pres = wrapper.$pres;\n root.SHA1 = wrapper.SHA1;\n root.MD5 = wrapper.MD5;\n root.b64_hmac_sha1 = wrapper.b64_hmac_sha1;\n root.b64_sha1 = wrapper.b64_sha1;\n root.str_hmac_sha1 = wrapper.str_hmac_sha1;\n root.str_sha1 = wrapper.str_sha1;\n }\n}(this, function () {\n //almond, and your modules will be inlined here\n/* jshint ignore:end */\n/**\n * @license almond 0.3.3 Copyright jQuery Foundation and other contributors.\n * Released under MIT license, http://github.com/requirejs/almond/LICENSE\n */\n//Going sloppy to avoid 'use strict' string cost, but strict practices should\n//be followed.\n/*global setTimeout: false */\n\nvar requirejs, require, define;\n(function (undef) {\n var main, req, makeMap, handlers,\n defined = {},\n waiting = {},\n config = {},\n defining = {},\n hasOwn = Object.prototype.hasOwnProperty,\n aps = [].slice,\n jsSuffixRegExp = /\\.js$/;\n\n function hasProp(obj, prop) {\n return hasOwn.call(obj, prop);\n }\n\n /**\n * Given a relative module name, like ./something, normalize it to\n * a real name that can be mapped to a path.\n * @param {String} name the relative name\n * @param {String} baseName a real name that the name arg is relative\n * to.\n * @returns {String} normalized name\n */\n function normalize(name, baseName) {\n var nameParts, nameSegment, mapValue, foundMap, lastIndex,\n foundI, foundStarMap, starI, i, j, part, normalizedBaseParts,\n baseParts = baseName && baseName.split(\"/\"),\n map = config.map,\n starMap = (map && map['*']) || {};\n\n //Adjust any relative paths.\n if (name) {\n name = name.split('/');\n lastIndex = name.length - 1;\n\n // If wanting node ID compatibility, strip .js from end\n // of IDs. Have to do this here, and not in nameToUrl\n // because node allows either .js or non .js to map\n // to same file.\n if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {\n name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');\n }\n\n // Starts with a '.' so need the baseName\n if (name[0].charAt(0) === '.' && baseParts) {\n //Convert baseName to array, and lop off the last part,\n //so that . matches that 'directory' and not name of the baseName's\n //module. For instance, baseName of 'one/two/three', maps to\n //'one/two/three.js', but we want the directory, 'one/two' for\n //this normalization.\n normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);\n name = normalizedBaseParts.concat(name);\n }\n\n //start trimDots\n for (i = 0; i < name.length; i++) {\n part = name[i];\n if (part === '.') {\n name.splice(i, 1);\n i -= 1;\n } else if (part === '..') {\n // If at the start, or previous value is still ..,\n // keep them so that when converted to a path it may\n // still work when converted to a path, even though\n // as an ID it is less than ideal. In larger point\n // releases, may be better to just kick out an error.\n if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') {\n continue;\n } else if (i > 0) {\n name.splice(i - 1, 2);\n i -= 2;\n }\n }\n }\n //end trimDots\n\n name = name.join('/');\n }\n\n //Apply map config if available.\n if ((baseParts || starMap) && map) {\n nameParts = name.split('/');\n\n for (i = nameParts.length; i > 0; i -= 1) {\n nameSegment = nameParts.slice(0, i).join(\"/\");\n\n if (baseParts) {\n //Find the longest baseName segment match in the config.\n //So, do joins on the biggest to smallest lengths of baseParts.\n for (j = baseParts.length; j > 0; j -= 1) {\n mapValue = map[baseParts.slice(0, j).join('/')];\n\n //baseName segment has config, find if it has one for\n //this name.\n if (mapValue) {\n mapValue = mapValue[nameSegment];\n if (mapValue) {\n //Match, update name to the new value.\n foundMap = mapValue;\n foundI = i;\n break;\n }\n }\n }\n }\n\n if (foundMap) {\n break;\n }\n\n //Check for a star map match, but just hold on to it,\n //if there is a shorter segment match later in a matching\n //config, then favor over this star map.\n if (!foundStarMap && starMap && starMap[nameSegment]) {\n foundStarMap = starMap[nameSegment];\n starI = i;\n }\n }\n\n if (!foundMap && foundStarMap) {\n foundMap = foundStarMap;\n foundI = starI;\n }\n\n if (foundMap) {\n nameParts.splice(0, foundI, foundMap);\n name = nameParts.join('/');\n }\n }\n\n return name;\n }\n\n function makeRequire(relName, forceSync) {\n return function () {\n //A version of a require function that passes a moduleName\n //value for items that may need to\n //look up paths relative to the moduleName\n var args = aps.call(arguments, 0);\n\n //If first arg is not require('string'), and there is only\n //one arg, it is the array form without a callback. Insert\n //a null so that the following concat is correct.\n if (typeof args[0] !== 'string' && args.length === 1) {\n args.push(null);\n }\n return req.apply(undef, args.concat([relName, forceSync]));\n };\n }\n\n function makeNormalize(relName) {\n return function (name) {\n return normalize(name, relName);\n };\n }\n\n function makeLoad(depName) {\n return function (value) {\n defined[depName] = value;\n };\n }\n\n function callDep(name) {\n if (hasProp(waiting, name)) {\n var args = waiting[name];\n delete waiting[name];\n defining[name] = true;\n main.apply(undef, args);\n }\n\n if (!hasProp(defined, name) && !hasProp(defining, name)) {\n throw new Error('No ' + name);\n }\n return defined[name];\n }\n\n //Turns a plugin!resource to [plugin, resource]\n //with the plugin being undefined if the name\n //did not have a plugin prefix.\n function splitPrefix(name) {\n var prefix,\n index = name ? name.indexOf('!') : -1;\n if (index > -1) {\n prefix = name.substring(0, index);\n name = name.substring(index + 1, name.length);\n }\n return [prefix, name];\n }\n\n //Creates a parts array for a relName where first part is plugin ID,\n //second part is resource ID. Assumes relName has already been normalized.\n function makeRelParts(relName) {\n return relName ? splitPrefix(relName) : [];\n }\n\n /**\n * Makes a name map, normalizing the name, and using a plugin\n * for normalization if necessary. Grabs a ref to plugin\n * too, as an optimization.\n */\n makeMap = function (name, relParts) {\n var plugin,\n parts = splitPrefix(name),\n prefix = parts[0],\n relResourceName = relParts[1];\n\n name = parts[1];\n\n if (prefix) {\n prefix = normalize(prefix, relResourceName);\n plugin = callDep(prefix);\n }\n\n //Normalize according\n if (prefix) {\n if (plugin && plugin.normalize) {\n name = plugin.normalize(name, makeNormalize(relResourceName));\n } else {\n name = normalize(name, relResourceName);\n }\n } else {\n name = normalize(name, relResourceName);\n parts = splitPrefix(name);\n prefix = parts[0];\n name = parts[1];\n if (prefix) {\n plugin = callDep(prefix);\n }\n }\n\n //Using ridiculous property names for space reasons\n return {\n f: prefix ? prefix + '!' + name : name, //fullName\n n: name,\n pr: prefix,\n p: plugin\n };\n };\n\n function makeConfig(name) {\n return function () {\n return (config && config.config && config.config[name]) || {};\n };\n }\n\n handlers = {\n require: function (name) {\n return makeRequire(name);\n },\n exports: function (name) {\n var e = defined[name];\n if (typeof e !== 'undefined') {\n return e;\n } else {\n return (defined[name] = {});\n }\n },\n module: function (name) {\n return {\n id: name,\n uri: '',\n exports: defined[name],\n config: makeConfig(name)\n };\n }\n };\n\n main = function (name, deps, callback, relName) {\n var cjsModule, depName, ret, map, i, relParts,\n args = [],\n callbackType = typeof callback,\n usingExports;\n\n //Use name if no relName\n relName = relName || name;\n relParts = makeRelParts(relName);\n\n //Call the callback to define the module, if necessary.\n if (callbackType === 'undefined' || callbackType === 'function') {\n //Pull out the defined dependencies and pass the ordered\n //values to the callback.\n //Default to [require, exports, module] if no deps\n deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;\n for (i = 0; i < deps.length; i += 1) {\n map = makeMap(deps[i], relParts);\n depName = map.f;\n\n //Fast path CommonJS standard dependencies.\n if (depName === \"require\") {\n args[i] = handlers.require(name);\n } else if (depName === \"exports\") {\n //CommonJS module spec 1.1\n args[i] = handlers.exports(name);\n usingExports = true;\n } else if (depName === \"module\") {\n //CommonJS module spec 1.1\n cjsModule = args[i] = handlers.module(name);\n } else if (hasProp(defined, depName) ||\n hasProp(waiting, depName) ||\n hasProp(defining, depName)) {\n args[i] = callDep(depName);\n } else if (map.p) {\n map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});\n args[i] = defined[depName];\n } else {\n throw new Error(name + ' missing ' + depName);\n }\n }\n\n ret = callback ? callback.apply(defined[name], args) : undefined;\n\n if (name) {\n //If setting exports via \"module\" is in play,\n //favor that over return value and exports. After that,\n //favor a non-undefined return value over exports use.\n if (cjsModule && cjsModule.exports !== undef &&\n cjsModule.exports !== defined[name]) {\n defined[name] = cjsModule.exports;\n } else if (ret !== undef || !usingExports) {\n //Use the return value from the function.\n defined[name] = ret;\n }\n }\n } else if (name) {\n //May just be an object definition for the module. Only\n //worry about defining if have a module name.\n defined[name] = callback;\n }\n };\n\n requirejs = require = req = function (deps, callback, relName, forceSync, alt) {\n if (typeof deps === \"string\") {\n if (handlers[deps]) {\n //callback in this case is really relName\n return handlers[deps](callback);\n }\n //Just return the module wanted. In this scenario, the\n //deps arg is the module name, and second arg (if passed)\n //is just the relName.\n //Normalize module name, if it contains . or ..\n return callDep(makeMap(deps, makeRelParts(callback)).f);\n } else if (!deps.splice) {\n //deps is a config object, not an array.\n config = deps;\n if (config.deps) {\n req(config.deps, config.callback);\n }\n if (!callback) {\n return;\n }\n\n if (callback.splice) {\n //callback is an array, which means it is a dependency list.\n //Adjust args if there are dependencies\n deps = callback;\n callback = relName;\n relName = null;\n } else {\n deps = undef;\n }\n }\n\n //Support require(['a'])\n callback = callback || function () {};\n\n //If relName is a function, it is an errback handler,\n //so remove it.\n if (typeof relName === 'function') {\n relName = forceSync;\n forceSync = alt;\n }\n\n //Simulate async callback;\n if (forceSync) {\n main(undef, deps, callback, relName);\n } else {\n //Using a non-zero value because of concern for what old browsers\n //do, and latest browsers \"upgrade\" to 4 if lower value is used:\n //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:\n //If want a value immediately, use require('id') instead -- something\n //that works in almond on the global level, but not guaranteed and\n //unlikely to work in other AMD implementations.\n setTimeout(function () {\n main(undef, deps, callback, relName);\n }, 4);\n }\n\n return req;\n };\n\n /**\n * Just drops the config on the floor, but returns req in case\n * the config return value is used.\n */\n req.config = function (cfg) {\n return req(cfg);\n };\n\n /**\n * Expose module registry for debugging and tooling\n */\n requirejs._defined = defined;\n\n define = function (name, deps, callback) {\n if (typeof name !== 'string') {\n throw new Error('See almond README: incorrect module build, no module name');\n }\n\n //This module may not have dependencies\n if (!deps.splice) {\n //deps is not an array, so probably means\n //an object literal or factory function for\n //the value. Adjust args.\n callback = deps;\n deps = [];\n }\n\n if (!hasProp(defined, name) && !hasProp(waiting, name)) {\n waiting[name] = [name, deps, callback];\n }\n };\n\n define.amd = {\n jQuery: true\n };\n}());\n\ndefine(\"node_modules/almond/almond.js\", function(){});\n\n/*\n This program is distributed under the terms of the MIT license.\n Please see the LICENSE file for details.\n\n Copyright 2006-2008, OGG, LLC\n*/\n/* jshint undef: true, unused: true:, noarg: true, latedef: true */\n/* global define */\n\n(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n define('strophe-polyfill',[], function () {\n return factory(root);\n });\n } else {\n // Browser globals\n return factory(root);\n }\n}(this, function (root) {\n\n/** Function: Function.prototype.bind\n * Bind a function to an instance.\n *\n * This Function object extension method creates a bound method similar\n * to those in Python. This means that the 'this' object will point\n * to the instance you want. See \n * and \n * for a complete explanation.\n *\n * This extension already exists in some browsers (namely, Firefox 3), but\n * we provide it to support those that don't.\n *\n * Parameters:\n * (Object) obj - The object that will become 'this' in the bound function.\n * (Object) argN - An option argument that will be prepended to the\n * arguments given for the function call\n *\n * Returns:\n * The bound function.\n */\nif (!Function.prototype.bind) {\n Function.prototype.bind = function (obj /*, arg1, arg2, ... */) {\n var func = this;\n var _slice = Array.prototype.slice;\n var _concat = Array.prototype.concat;\n var _args = _slice.call(arguments, 1);\n return function () {\n return func.apply(obj ? obj : this, _concat.call(_args, _slice.call(arguments, 0)));\n };\n };\n}\n\n/** Function: Array.isArray\n * This is a polyfill for the ES5 Array.isArray method.\n */\nif (!Array.isArray) {\n Array.isArray = function(arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n };\n}\n\n/** Function: Array.prototype.indexOf\n * Return the index of an object in an array.\n *\n * This function is not supplied by some JavaScript implementations, so\n * we provide it if it is missing. This code is from:\n * http://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Objects:Array:indexOf\n *\n * Parameters:\n * (Object) elt - The object to look for.\n * (Integer) from - The index from which to start looking. (optional).\n *\n * Returns:\n * The index of elt in the array or -1 if not found.\n */\nif (!Array.prototype.indexOf) {\n Array.prototype.indexOf = function(elt /*, from*/) {\n var len = this.length;\n var from = Number(arguments[1]) || 0;\n from = (from < 0) ? Math.ceil(from) : Math.floor(from);\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from++) {\n if (from in this && this[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n}\n\n/** Function: Array.prototype.forEach\n *\n * This function is not available in IE < 9\n *\n * See \n */\nif (!Array.prototype.forEach) {\n Array.prototype.forEach = function(callback, thisArg) {\n var T, k;\n if (this === null) {\n throw new TypeError(' this is null or not defined');\n }\n // 1. Let O be the result of calling toObject() passing the\n // |this| value as the argument.\n var O = Object(this);\n // 2. Let lenValue be the result of calling the Get() internal\n // method of O with the argument \"length\".\n // 3. Let len be toUint32(lenValue).\n var len = O.length >>> 0;\n // 4. If isCallable(callback) is false, throw a TypeError exception.\n // See: http://es5.github.com/#x9.11\n if (typeof callback !== \"function\") {\n throw new TypeError(callback + ' is not a function');\n }\n // 5. If thisArg was supplied, let T be thisArg; else let\n // T be undefined.\n if (arguments.length > 1) {\n T = thisArg;\n }\n // 6. Let k be 0\n k = 0;\n // 7. Repeat, while k < len\n while (k < len) {\n var kValue;\n // a. Let Pk be ToString(k).\n // This is implicit for LHS operands of the in operator\n // b. Let kPresent be the result of calling the HasProperty\n // internal method of O with argument Pk.\n // This step can be combined with c\n // c. If kPresent is true, then\n if (k in O) {\n // i. Let kValue be the result of calling the Get internal\n // method of O with argument Pk.\n kValue = O[k];\n // ii. Call the Call internal method of callback with T as\n // the this value and argument list containing kValue, k, and O.\n callback.call(T, kValue, k, O);\n }\n // d. Increase k by 1.\n k++;\n }\n // 8. return undefined\n };\n}\n\n// This code was written by Tyler Akins and has been placed in the\n// public domain. It would be nice if you left this header intact.\n// Base64 code from Tyler Akins -- http://rumkin.com\nvar keyStr = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\nif (!root.btoa) {\n root.btoa = function (input) {\n /**\n * Encodes a string in base64\n * @param {String} input The string to encode in base64.\n */\n var output = \"\";\n var chr1, chr2, chr3;\n var enc1, enc2, enc3, enc4;\n var i = 0;\n do {\n chr1 = input.charCodeAt(i++);\n chr2 = input.charCodeAt(i++);\n chr3 = input.charCodeAt(i++);\n\n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n\n if (isNaN(chr2)) {\n enc2 = ((chr1 & 3) << 4);\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) +\n keyStr.charAt(enc3) + keyStr.charAt(enc4);\n } while (i < input.length);\n return output;\n };\n}\n\nif (!root.atob) {\n root.atob = function (input) {\n /**\n * Decodes a base64 string.\n * @param {String} input The string to decode.\n */\n var output = \"\";\n var chr1, chr2, chr3;\n var enc1, enc2, enc3, enc4;\n var i = 0;\n // remove all characters that are not A-Z, a-z, 0-9, +, /, or =\n input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n do {\n enc1 = keyStr.indexOf(input.charAt(i++));\n enc2 = keyStr.indexOf(input.charAt(i++));\n enc3 = keyStr.indexOf(input.charAt(i++));\n enc4 = keyStr.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n\n output = output + String.fromCharCode(chr1);\n\n if (enc3 !== 64) {\n output = output + String.fromCharCode(chr2);\n }\n if (enc4 !== 64) {\n output = output + String.fromCharCode(chr3);\n }\n } while (i < input.length);\n return output;\n };\n}\n}));\n\n/*\n * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined\n * in FIPS PUB 180-1\n * Version 2.1a Copyright Paul Johnston 2000 - 2002.\n * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet\n * Distributed under the BSD License\n * See http://pajhome.org.uk/crypt/md5 for details.\n */\n\n/* jshint undef: true, unused: true:, noarg: true, latedef: false */\n/* global define */\n\n/* Some functions and variables have been stripped for use with Strophe */\n\n(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n define('strophe-sha1', [],function () {\n return factory();\n });\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n // Browser globals\n root.SHA1 = factory();\n }\n}(this, function () {\n\n/*\n * Calculate the SHA-1 of an array of big-endian words, and a bit length\n */\nfunction core_sha1(x, len)\n{\n /* append padding */\n x[len >> 5] |= 0x80 << (24 - len % 32);\n x[((len + 64 >> 9) << 4) + 15] = len;\n\n var w = new Array(80);\n var a = 1732584193;\n var b = -271733879;\n var c = -1732584194;\n var d = 271733878;\n var e = -1009589776;\n\n var i, j, t, olda, oldb, oldc, oldd, olde;\n for (i = 0; i < x.length; i += 16)\n {\n olda = a;\n oldb = b;\n oldc = c;\n oldd = d;\n olde = e;\n\n for (j = 0; j < 80; j++)\n {\n if (j < 16) { w[j] = x[i + j]; }\n else { w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); }\n t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),\n safe_add(safe_add(e, w[j]), sha1_kt(j)));\n e = d;\n d = c;\n c = rol(b, 30);\n b = a;\n a = t;\n }\n\n a = safe_add(a, olda);\n b = safe_add(b, oldb);\n c = safe_add(c, oldc);\n d = safe_add(d, oldd);\n e = safe_add(e, olde);\n }\n return [a, b, c, d, e];\n}\n\n/*\n * Perform the appropriate triplet combination function for the current\n * iteration\n */\nfunction sha1_ft(t, b, c, d)\n{\n if (t < 20) { return (b & c) | ((~b) & d); }\n if (t < 40) { return b ^ c ^ d; }\n if (t < 60) { return (b & c) | (b & d) | (c & d); }\n return b ^ c ^ d;\n}\n\n/*\n * Determine the appropriate additive constant for the current iteration\n */\nfunction sha1_kt(t)\n{\n return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :\n (t < 60) ? -1894007588 : -899497514;\n}\n\n/*\n * Calculate the HMAC-SHA1 of a key and some data\n */\nfunction core_hmac_sha1(key, data)\n{\n var bkey = str2binb(key);\n if (bkey.length > 16) { bkey = core_sha1(bkey, key.length * 8); }\n\n var ipad = new Array(16), opad = new Array(16);\n for (var i = 0; i < 16; i++)\n {\n ipad[i] = bkey[i] ^ 0x36363636;\n opad[i] = bkey[i] ^ 0x5C5C5C5C;\n }\n\n var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * 8);\n return core_sha1(opad.concat(hash), 512 + 160);\n}\n\n/*\n * Add integers, wrapping at 2^32. This uses 16-bit operations internally\n * to work around bugs in some JS interpreters.\n */\nfunction safe_add(x, y)\n{\n var lsw = (x & 0xFFFF) + (y & 0xFFFF);\n var msw = (x >> 16) + (y >> 16) + (lsw >> 16);\n return (msw << 16) | (lsw & 0xFFFF);\n}\n\n/*\n * Bitwise rotate a 32-bit number to the left.\n */\nfunction rol(num, cnt)\n{\n return (num << cnt) | (num >>> (32 - cnt));\n}\n\n/*\n * Convert an 8-bit or 16-bit string to an array of big-endian words\n * In 8-bit function, characters >255 have their hi-byte silently ignored.\n */\nfunction str2binb(str)\n{\n var bin = [];\n var mask = 255;\n for (var i = 0; i < str.length * 8; i += 8)\n {\n bin[i>>5] |= (str.charCodeAt(i / 8) & mask) << (24 - i%32);\n }\n return bin;\n}\n\n/*\n * Convert an array of big-endian words to a string\n */\nfunction binb2str(bin)\n{\n var str = \"\";\n var mask = 255;\n for (var i = 0; i < bin.length * 32; i += 8)\n {\n str += String.fromCharCode((bin[i>>5] >>> (24 - i%32)) & mask);\n }\n return str;\n}\n\n/*\n * Convert an array of big-endian words to a base-64 string\n */\nfunction binb2b64(binarray)\n{\n var tab = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n var str = \"\";\n var triplet, j;\n for (var i = 0; i < binarray.length * 4; i += 3)\n {\n triplet = (((binarray[i >> 2] >> 8 * (3 - i %4)) & 0xFF) << 16) |\n (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 ) |\n ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);\n for (j = 0; j < 4; j++)\n {\n if (i * 8 + j * 6 > binarray.length * 32) { str += \"=\"; }\n else { str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); }\n }\n }\n return str;\n}\n\n/*\n * These are the functions you'll usually want to call\n * They take string arguments and return either hex or base-64 encoded strings\n */\nreturn {\n b64_hmac_sha1: function (key, data){ return binb2b64(core_hmac_sha1(key, data)); },\n b64_sha1: function (s) { return binb2b64(core_sha1(str2binb(s),s.length * 8)); },\n binb2str: binb2str,\n core_hmac_sha1: core_hmac_sha1,\n str_hmac_sha1: function (key, data){ return binb2str(core_hmac_sha1(key, data)); },\n str_sha1: function (s) { return binb2str(core_sha1(str2binb(s),s.length * 8)); },\n};\n}));\n\n/*\n * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message\n * Digest Algorithm, as defined in RFC 1321.\n * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.\n * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet\n * Distributed under the BSD License\n * See http://pajhome.org.uk/crypt/md5 for more info.\n */\n/*\n * Everything that isn't used by Strophe has been stripped here!\n */\n\n(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n define('strophe-md5',[], function () {\n return factory();\n });\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n // Browser globals\n root.MD5 = factory();\n }\n}(this, function () {\n /*\n * Add integers, wrapping at 2^32. This uses 16-bit operations internally\n * to work around bugs in some JS interpreters.\n */\n var safe_add = function (x, y) {\n var lsw = (x & 0xFFFF) + (y & 0xFFFF);\n var msw = (x >> 16) + (y >> 16) + (lsw >> 16);\n return (msw << 16) | (lsw & 0xFFFF);\n };\n\n /*\n * Bitwise rotate a 32-bit number to the left.\n */\n var bit_rol = function (num, cnt) {\n return (num << cnt) | (num >>> (32 - cnt));\n };\n\n /*\n * Convert a string to an array of little-endian words\n */\n var str2binl = function (str) {\n var bin = [];\n for(var i = 0; i < str.length * 8; i += 8)\n {\n bin[i>>5] |= (str.charCodeAt(i / 8) & 255) << (i%32);\n }\n return bin;\n };\n\n /*\n * Convert an array of little-endian words to a string\n */\n var binl2str = function (bin) {\n var str = \"\";\n for(var i = 0; i < bin.length * 32; i += 8)\n {\n str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & 255);\n }\n return str;\n };\n\n /*\n * Convert an array of little-endian words to a hex string.\n */\n var binl2hex = function (binarray) {\n var hex_tab = \"0123456789abcdef\";\n var str = \"\";\n for(var i = 0; i < binarray.length * 4; i++)\n {\n str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +\n hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF);\n }\n return str;\n };\n\n /*\n * These functions implement the four basic operations the algorithm uses.\n */\n var md5_cmn = function (q, a, b, x, s, t) {\n return safe_add(bit_rol(safe_add(safe_add(a, q),safe_add(x, t)), s),b);\n };\n\n var md5_ff = function (a, b, c, d, x, s, t) {\n return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);\n };\n\n var md5_gg = function (a, b, c, d, x, s, t) {\n return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);\n };\n\n var md5_hh = function (a, b, c, d, x, s, t) {\n return md5_cmn(b ^ c ^ d, a, b, x, s, t);\n };\n\n var md5_ii = function (a, b, c, d, x, s, t) {\n return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);\n };\n\n /*\n * Calculate the MD5 of an array of little-endian words, and a bit length\n */\n var core_md5 = function (x, len) {\n /* append padding */\n x[len >> 5] |= 0x80 << ((len) % 32);\n x[(((len + 64) >>> 9) << 4) + 14] = len;\n\n var a = 1732584193;\n var b = -271733879;\n var c = -1732584194;\n var d = 271733878;\n\n var olda, oldb, oldc, oldd;\n for (var i = 0; i < x.length; i += 16)\n {\n olda = a;\n oldb = b;\n oldc = c;\n oldd = d;\n\n a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);\n d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);\n c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);\n b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);\n a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);\n d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);\n c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);\n b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);\n a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);\n d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);\n c = md5_ff(c, d, a, b, x[i+10], 17, -42063);\n b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);\n a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);\n d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);\n c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);\n b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);\n\n a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);\n d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);\n c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);\n b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);\n a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);\n d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);\n c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);\n b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);\n a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);\n d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);\n c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);\n b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);\n a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);\n d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);\n c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);\n b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);\n\n a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);\n d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);\n c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);\n b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);\n a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);\n d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);\n c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);\n b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);\n a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);\n d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);\n c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);\n b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);\n a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);\n d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);\n c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);\n b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);\n\n a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);\n d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);\n c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);\n b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);\n a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);\n d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);\n c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);\n b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);\n a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);\n d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);\n c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);\n b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);\n a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);\n d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);\n c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);\n b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);\n\n a = safe_add(a, olda);\n b = safe_add(b, oldb);\n c = safe_add(c, oldc);\n d = safe_add(d, oldd);\n }\n return [a, b, c, d];\n };\n\n var obj = {\n /*\n * These are the functions you'll usually want to call.\n * They take string arguments and return either hex or base-64 encoded\n * strings.\n */\n hexdigest: function (s) {\n return binl2hex(core_md5(str2binl(s), s.length * 8));\n },\n\n hash: function (s) {\n return binl2str(core_md5(str2binl(s), s.length * 8));\n }\n };\n return obj;\n}));\n\n(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n define('strophe-utils',[], function () {\n return factory();\n });\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n // Browser globals\n root.stropheUtils = factory();\n }\n}(this, function () {\n\n var utils = {\n\n utf16to8: function (str) {\n var i, c;\n var out = \"\";\n var len = str.length;\n for (i = 0; i < len; i++) {\n c = str.charCodeAt(i);\n if ((c >= 0x0000) && (c <= 0x007F)) {\n out += str.charAt(i);\n } else if (c > 0x07FF) {\n out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));\n out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));\n out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));\n } else {\n out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));\n out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));\n }\n }\n return out;\n },\n\n addCookies: function (cookies) {\n /* Parameters:\n * (Object) cookies - either a map of cookie names\n * to string values or to maps of cookie values.\n *\n * For example:\n * { \"myCookie\": \"1234\" }\n *\n * or:\n * { \"myCookie\": {\n * \"value\": \"1234\",\n * \"domain\": \".example.org\",\n * \"path\": \"/\",\n * \"expires\": expirationDate\n * }\n * }\n *\n * These values get passed to Strophe.Connection via\n * options.cookies\n */\n var cookieName, cookieObj, isObj, cookieValue, expires, domain, path;\n for (cookieName in (cookies || {})) {\n expires = '';\n domain = '';\n path = '';\n cookieObj = cookies[cookieName];\n isObj = typeof cookieObj === \"object\";\n cookieValue = escape(unescape(isObj ? cookieObj.value : cookieObj));\n if (isObj) {\n expires = cookieObj.expires ? \";expires=\"+cookieObj.expires : '';\n domain = cookieObj.domain ? \";domain=\"+cookieObj.domain : '';\n path = cookieObj.path ? \";path=\"+cookieObj.path : '';\n }\n document.cookie =\n cookieName+'='+cookieValue + expires + domain + path;\n }\n }\n };\n return utils;\n}));\n\n/*\n This program is distributed under the terms of the MIT license.\n Please see the LICENSE file for details.\n\n Copyright 2006-2008, OGG, LLC\n*/\n\n/* jshint undef: true, unused: true:, noarg: true, latedef: true */\n/*global define, document, sessionStorage, setTimeout, clearTimeout, ActiveXObject, DOMParser, btoa, atob */\n\n(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n define('strophe-core',[\n 'strophe-sha1',\n 'strophe-md5',\n 'strophe-utils'\n ], function () {\n return factory.apply(this, arguments);\n });\n } else if (typeof exports === 'object') {\n module.exports = factory(\n require('./sha1'),\n require('./md5'),\n require('./utils')\n );\n } else {\n // Browser globals\n var o = factory(root.SHA1, root.MD5, root.stropheUtils);\n root.Strophe = o.Strophe;\n root.$build = o.$build;\n root.$iq = o.$iq;\n root.$msg = o.$msg;\n root.$pres = o.$pres;\n root.SHA1 = o.SHA1;\n root.MD5 = o.MD5;\n root.b64_hmac_sha1 = o.SHA1.b64_hmac_sha1;\n root.b64_sha1 = o.SHA1.b64_sha1;\n root.str_hmac_sha1 = o.SHA1.str_hmac_sha1;\n root.str_sha1 = o.SHA1.str_sha1;\n }\n}(this, function (SHA1, MD5, utils) {\n\nvar Strophe;\n\n/** Function: $build\n * Create a Strophe.Builder.\n * This is an alias for 'new Strophe.Builder(name, attrs)'.\n *\n * Parameters:\n * (String) name - The root element name.\n * (Object) attrs - The attributes for the root element in object notation.\n *\n * Returns:\n * A new Strophe.Builder object.\n */\nfunction $build(name, attrs) { return new Strophe.Builder(name, attrs); }\n\n/** Function: $msg\n * Create a Strophe.Builder with a element as the root.\n *\n * Parameters:\n * (Object) attrs - The element attributes in object notation.\n *\n * Returns:\n * A new Strophe.Builder object.\n */\nfunction $msg(attrs) { return new Strophe.Builder(\"message\", attrs); }\n\n/** Function: $iq\n * Create a Strophe.Builder with an element as the root.\n *\n * Parameters:\n * (Object) attrs - The element attributes in object notation.\n *\n * Returns:\n * A new Strophe.Builder object.\n */\nfunction $iq(attrs) { return new Strophe.Builder(\"iq\", attrs); }\n\n/** Function: $pres\n * Create a Strophe.Builder with a element as the root.\n *\n * Parameters:\n * (Object) attrs - The element attributes in object notation.\n *\n * Returns:\n * A new Strophe.Builder object.\n */\nfunction $pres(attrs) { return new Strophe.Builder(\"presence\", attrs); }\n\n/** Class: Strophe\n * An object container for all Strophe library functions.\n *\n * This class is just a container for all the objects and constants\n * used in the library. It is not meant to be instantiated, but to\n * provide a namespace for library objects, constants, and functions.\n */\nStrophe = {\n /** Constant: VERSION */\n VERSION: \"1.2.16\",\n\n /** Constants: XMPP Namespace Constants\n * Common namespace constants from the XMPP RFCs and XEPs.\n *\n * NS.HTTPBIND - HTTP BIND namespace from XEP 124.\n * NS.BOSH - BOSH namespace from XEP 206.\n * NS.CLIENT - Main XMPP client namespace.\n * NS.AUTH - Legacy authentication namespace.\n * NS.ROSTER - Roster operations namespace.\n * NS.PROFILE - Profile namespace.\n * NS.DISCO_INFO - Service discovery info namespace from XEP 30.\n * NS.DISCO_ITEMS - Service discovery items namespace from XEP 30.\n * NS.MUC - Multi-User Chat namespace from XEP 45.\n * NS.SASL - XMPP SASL namespace from RFC 3920.\n * NS.STREAM - XMPP Streams namespace from RFC 3920.\n * NS.BIND - XMPP Binding namespace from RFC 3920.\n * NS.SESSION - XMPP Session namespace from RFC 3920.\n * NS.XHTML_IM - XHTML-IM namespace from XEP 71.\n * NS.XHTML - XHTML body namespace from XEP 71.\n */\n NS: {\n HTTPBIND: \"http://jabber.org/protocol/httpbind\",\n BOSH: \"urn:xmpp:xbosh\",\n CLIENT: \"jabber:client\",\n AUTH: \"jabber:iq:auth\",\n ROSTER: \"jabber:iq:roster\",\n PROFILE: \"jabber:iq:profile\",\n DISCO_INFO: \"http://jabber.org/protocol/disco#info\",\n DISCO_ITEMS: \"http://jabber.org/protocol/disco#items\",\n MUC: \"http://jabber.org/protocol/muc\",\n SASL: \"urn:ietf:params:xml:ns:xmpp-sasl\",\n STREAM: \"http://etherx.jabber.org/streams\",\n FRAMING: \"urn:ietf:params:xml:ns:xmpp-framing\",\n BIND: \"urn:ietf:params:xml:ns:xmpp-bind\",\n SESSION: \"urn:ietf:params:xml:ns:xmpp-session\",\n VERSION: \"jabber:iq:version\",\n STANZAS: \"urn:ietf:params:xml:ns:xmpp-stanzas\",\n XHTML_IM: \"http://jabber.org/protocol/xhtml-im\",\n XHTML: \"http://www.w3.org/1999/xhtml\"\n },\n\n /** Constants: XHTML_IM Namespace\n * contains allowed tags, tag attributes, and css properties.\n * Used in the createHtml function to filter incoming html into the allowed XHTML-IM subset.\n * See http://xmpp.org/extensions/xep-0071.html#profile-summary for the list of recommended\n * allowed tags and their attributes.\n */\n XHTML: {\n tags: ['a','blockquote','br','cite','em','img','li','ol','p','span','strong','ul','body'],\n attributes: {\n 'a': ['href'],\n 'blockquote': ['style'],\n 'br': [],\n 'cite': ['style'],\n 'em': [],\n 'img': ['src', 'alt', 'style', 'height', 'width'],\n 'li': ['style'],\n 'ol': ['style'],\n 'p': ['style'],\n 'span': ['style'],\n 'strong': [],\n 'ul': ['style'],\n 'body': []\n },\n css: ['background-color','color','font-family','font-size','font-style','font-weight','margin-left','margin-right','text-align','text-decoration'],\n /** Function: XHTML.validTag\n *\n * Utility method to determine whether a tag is allowed\n * in the XHTML_IM namespace.\n *\n * XHTML tag names are case sensitive and must be lower case.\n */\n validTag: function(tag) {\n for (var i = 0; i < Strophe.XHTML.tags.length; i++) {\n if (tag === Strophe.XHTML.tags[i]) {\n return true;\n }\n }\n return false;\n },\n /** Function: XHTML.validAttribute\n *\n * Utility method to determine whether an attribute is allowed\n * as recommended per XEP-0071\n *\n * XHTML attribute names are case sensitive and must be lower case.\n */\n validAttribute: function(tag, attribute) {\n if (typeof Strophe.XHTML.attributes[tag] !== 'undefined' && Strophe.XHTML.attributes[tag].length > 0) {\n for (var i = 0; i < Strophe.XHTML.attributes[tag].length; i++) {\n if (attribute === Strophe.XHTML.attributes[tag][i]) {\n return true;\n }\n }\n }\n return false;\n },\n validCSS: function(style) {\n for (var i = 0; i < Strophe.XHTML.css.length; i++) {\n if (style === Strophe.XHTML.css[i]) {\n return true;\n }\n }\n return false;\n }\n },\n\n /** Constants: Connection Status Constants\n * Connection status constants for use by the connection handler\n * callback.\n *\n * Status.ERROR - An error has occurred\n * Status.CONNECTING - The connection is currently being made\n * Status.CONNFAIL - The connection attempt failed\n * Status.AUTHENTICATING - The connection is authenticating\n * Status.AUTHFAIL - The authentication attempt failed\n * Status.CONNECTED - The connection has succeeded\n * Status.DISCONNECTED - The connection has been terminated\n * Status.DISCONNECTING - The connection is currently being terminated\n * Status.ATTACHED - The connection has been attached\n * Status.REDIRECT - The connection has been redirected\n * Status.CONNTIMEOUT - The connection has timed out\n */\n Status: {\n ERROR: 0,\n CONNECTING: 1,\n CONNFAIL: 2,\n AUTHENTICATING: 3,\n AUTHFAIL: 4,\n CONNECTED: 5,\n DISCONNECTED: 6,\n DISCONNECTING: 7,\n ATTACHED: 8,\n REDIRECT: 9,\n CONNTIMEOUT: 10\n },\n\n ErrorCondition: {\n BAD_FORMAT: \"bad-format\",\n CONFLICT: \"conflict\",\n MISSING_JID_NODE: \"x-strophe-bad-non-anon-jid\",\n NO_AUTH_MECH: \"no-auth-mech\",\n UNKNOWN_REASON: \"unknown\",\n },\n\n /** Constants: Log Level Constants\n * Logging level indicators.\n *\n * LogLevel.DEBUG - Debug output\n * LogLevel.INFO - Informational output\n * LogLevel.WARN - Warnings\n * LogLevel.ERROR - Errors\n * LogLevel.FATAL - Fatal errors\n */\n LogLevel: {\n DEBUG: 0,\n INFO: 1,\n WARN: 2,\n ERROR: 3,\n FATAL: 4\n },\n\n /** PrivateConstants: DOM Element Type Constants\n * DOM element types.\n *\n * ElementType.NORMAL - Normal element.\n * ElementType.TEXT - Text data element.\n * ElementType.FRAGMENT - XHTML fragment element.\n */\n ElementType: {\n NORMAL: 1,\n TEXT: 3,\n CDATA: 4,\n FRAGMENT: 11\n },\n\n /** PrivateConstants: Timeout Values\n * Timeout values for error states. These values are in seconds.\n * These should not be changed unless you know exactly what you are\n * doing.\n *\n * TIMEOUT - Timeout multiplier. A waiting request will be considered\n * failed after Math.floor(TIMEOUT * wait) seconds have elapsed.\n * This defaults to 1.1, and with default wait, 66 seconds.\n * SECONDARY_TIMEOUT - Secondary timeout multiplier. In cases where\n * Strophe can detect early failure, it will consider the request\n * failed if it doesn't return after\n * Math.floor(SECONDARY_TIMEOUT * wait) seconds have elapsed.\n * This defaults to 0.1, and with default wait, 6 seconds.\n */\n TIMEOUT: 1.1,\n SECONDARY_TIMEOUT: 0.1,\n\n /** Function: addNamespace\n * This function is used to extend the current namespaces in\n * Strophe.NS. It takes a key and a value with the key being the\n * name of the new namespace, with its actual value.\n * For example:\n * Strophe.addNamespace('PUBSUB', \"http://jabber.org/protocol/pubsub\");\n *\n * Parameters:\n * (String) name - The name under which the namespace will be\n * referenced under Strophe.NS\n * (String) value - The actual namespace.\n */\n addNamespace: function (name, value) {\n Strophe.NS[name] = value;\n },\n\n /** Function: forEachChild\n * Map a function over some or all child elements of a given element.\n *\n * This is a small convenience function for mapping a function over\n * some or all of the children of an element. If elemName is null, all\n * children will be passed to the function, otherwise only children\n * whose tag names match elemName will be passed.\n *\n * Parameters:\n * (XMLElement) elem - The element to operate on.\n * (String) elemName - The child element tag name filter.\n * (Function) func - The function to apply to each child. This\n * function should take a single argument, a DOM element.\n */\n forEachChild: function (elem, elemName, func) {\n var i, childNode;\n for (i = 0; i < elem.childNodes.length; i++) {\n childNode = elem.childNodes[i];\n if (childNode.nodeType === Strophe.ElementType.NORMAL &&\n (!elemName || this.isTagEqual(childNode, elemName))) {\n func(childNode);\n }\n }\n },\n\n /** Function: isTagEqual\n * Compare an element's tag name with a string.\n *\n * This function is case sensitive.\n *\n * Parameters:\n * (XMLElement) el - A DOM element.\n * (String) name - The element name.\n *\n * Returns:\n * true if the element's tag name matches _el_, and false\n * otherwise.\n */\n isTagEqual: function (el, name) {\n return el.tagName === name;\n },\n\n /** PrivateVariable: _xmlGenerator\n * _Private_ variable that caches a DOM document to\n * generate elements.\n */\n _xmlGenerator: null,\n\n /** PrivateFunction: _makeGenerator\n * _Private_ function that creates a dummy XML DOM document to serve as\n * an element and text node generator.\n */\n _makeGenerator: function () {\n var doc;\n // IE9 does implement createDocument(); however, using it will cause the browser to leak memory on page unload.\n // Here, we test for presence of createDocument() plus IE's proprietary documentMode attribute, which would be\n // less than 10 in the case of IE9 and below.\n if (document.implementation.createDocument === undefined ||\n document.implementation.createDocument && document.documentMode && document.documentMode < 10) {\n doc = this._getIEXmlDom();\n doc.appendChild(doc.createElement('strophe'));\n } else {\n doc = document.implementation\n .createDocument('jabber:client', 'strophe', null);\n }\n return doc;\n },\n\n /** Function: xmlGenerator\n * Get the DOM document to generate elements.\n *\n * Returns:\n * The currently used DOM document.\n */\n xmlGenerator: function () {\n if (!Strophe._xmlGenerator) {\n Strophe._xmlGenerator = Strophe._makeGenerator();\n }\n return Strophe._xmlGenerator;\n },\n\n /** PrivateFunction: _getIEXmlDom\n * Gets IE xml doc object\n *\n * Returns:\n * A Microsoft XML DOM Object\n * See Also:\n * http://msdn.microsoft.com/en-us/library/ms757837%28VS.85%29.aspx\n */\n _getIEXmlDom : function() {\n var doc = null;\n var docStrings = [\n \"Msxml2.DOMDocument.6.0\",\n \"Msxml2.DOMDocument.5.0\",\n \"Msxml2.DOMDocument.4.0\",\n \"MSXML2.DOMDocument.3.0\",\n \"MSXML2.DOMDocument\",\n \"MSXML.DOMDocument\",\n \"Microsoft.XMLDOM\"\n ];\n\n for (var d = 0; d < docStrings.length; d++) {\n if (doc === null) {\n try {\n doc = new ActiveXObject(docStrings[d]);\n } catch (e) {\n doc = null;\n }\n } else {\n break;\n }\n }\n return doc;\n },\n\n /** Function: xmlElement\n * Create an XML DOM element.\n *\n * This function creates an XML DOM element correctly across all\n * implementations. Note that these are not HTML DOM elements, which\n * aren't appropriate for XMPP stanzas.\n *\n * Parameters:\n * (String) name - The name for the element.\n * (Array|Object) attrs - An optional array or object containing\n * key/value pairs to use as element attributes. The object should\n * be in the format {'key': 'value'} or {key: 'value'}. The array\n * should have the format [['key1', 'value1'], ['key2', 'value2']].\n * (String) text - The text child data for the element.\n *\n * Returns:\n * A new XML DOM element.\n */\n xmlElement: function (name) {\n if (!name) { return null; }\n\n var node = Strophe.xmlGenerator().createElement(name);\n // FIXME: this should throw errors if args are the wrong type or\n // there are more than two optional args\n var a, i, k;\n for (a = 1; a < arguments.length; a++) {\n var arg = arguments[a];\n if (!arg) { continue; }\n if (typeof(arg) === \"string\" ||\n typeof(arg) === \"number\") {\n node.appendChild(Strophe.xmlTextNode(arg));\n } else if (typeof(arg) === \"object\" &&\n typeof(arg.sort) === \"function\") {\n for (i = 0; i < arg.length; i++) {\n var attr = arg[i];\n if (typeof(attr) === \"object\" &&\n typeof(attr.sort) === \"function\" &&\n attr[1] !== undefined &&\n attr[1] !== null) {\n node.setAttribute(attr[0], attr[1]);\n }\n }\n } else if (typeof(arg) === \"object\") {\n for (k in arg) {\n if (arg.hasOwnProperty(k)) {\n if (arg[k] !== undefined &&\n arg[k] !== null) {\n node.setAttribute(k, arg[k]);\n }\n }\n }\n }\n }\n\n return node;\n },\n\n /* Function: xmlescape\n * Excapes invalid xml characters.\n *\n * Parameters:\n * (String) text - text to escape.\n *\n * Returns:\n * Escaped text.\n */\n xmlescape: function(text) {\n text = text.replace(/\\&/g, \"&\");\n text = text.replace(//g, \">\");\n text = text.replace(/'/g, \"'\");\n text = text.replace(/\"/g, \""\");\n return text;\n },\n\n /* Function: xmlunescape\n * Unexcapes invalid xml characters.\n *\n * Parameters:\n * (String) text - text to unescape.\n *\n * Returns:\n * Unescaped text.\n */\n xmlunescape: function(text) {\n text = text.replace(/\\&/g, \"&\");\n text = text.replace(/</g, \"<\");\n text = text.replace(/>/g, \">\");\n text = text.replace(/'/g, \"'\");\n text = text.replace(/"/g, \"\\\"\");\n return text;\n },\n\n /** Function: xmlTextNode\n * Creates an XML DOM text node.\n *\n * Provides a cross implementation version of document.createTextNode.\n *\n * Parameters:\n * (String) text - The content of the text node.\n *\n * Returns:\n * A new XML DOM text node.\n */\n xmlTextNode: function (text) {\n return Strophe.xmlGenerator().createTextNode(text);\n },\n\n /** Function: xmlHtmlNode\n * Creates an XML DOM html node.\n *\n * Parameters:\n * (String) html - The content of the html node.\n *\n * Returns:\n * A new XML DOM text node.\n */\n xmlHtmlNode: function (html) {\n var node;\n //ensure text is escaped\n if (DOMParser) {\n var parser = new DOMParser();\n node = parser.parseFromString(html, \"text/xml\");\n } else {\n node = new ActiveXObject(\"Microsoft.XMLDOM\");\n node.async=\"false\";\n node.loadXML(html);\n }\n return node;\n },\n\n /** Function: getText\n * Get the concatenation of all text children of an element.\n *\n * Parameters:\n * (XMLElement) elem - A DOM element.\n *\n * Returns:\n * A String with the concatenated text of all text element children.\n */\n getText: function (elem) {\n if (!elem) { return null; }\n\n var str = \"\";\n if (elem.childNodes.length === 0 && elem.nodeType === Strophe.ElementType.TEXT) {\n str += elem.nodeValue;\n }\n\n for (var i = 0; i < elem.childNodes.length; i++) {\n if (elem.childNodes[i].nodeType === Strophe.ElementType.TEXT) {\n str += elem.childNodes[i].nodeValue;\n }\n }\n\n return Strophe.xmlescape(str);\n },\n\n /** Function: copyElement\n * Copy an XML DOM element.\n *\n * This function copies a DOM element and all its descendants and returns\n * the new copy.\n *\n * Parameters:\n * (XMLElement) elem - A DOM element.\n *\n * Returns:\n * A new, copied DOM element tree.\n */\n copyElement: function (elem) {\n var i, el;\n if (elem.nodeType === Strophe.ElementType.NORMAL) {\n el = Strophe.xmlElement(elem.tagName);\n\n for (i = 0; i < elem.attributes.length; i++) {\n el.setAttribute(elem.attributes[i].nodeName,\n elem.attributes[i].value);\n }\n\n for (i = 0; i < elem.childNodes.length; i++) {\n el.appendChild(Strophe.copyElement(elem.childNodes[i]));\n }\n } else if (elem.nodeType === Strophe.ElementType.TEXT) {\n el = Strophe.xmlGenerator().createTextNode(elem.nodeValue);\n }\n return el;\n },\n\n\n /** Function: createHtml\n * Copy an HTML DOM element into an XML DOM.\n *\n * This function copies a DOM element and all its descendants and returns\n * the new copy.\n *\n * Parameters:\n * (HTMLElement) elem - A DOM element.\n *\n * Returns:\n * A new, copied DOM element tree.\n */\n createHtml: function (elem) {\n var i, el, j, tag, attribute, value, css, cssAttrs, attr, cssName, cssValue;\n if (elem.nodeType === Strophe.ElementType.NORMAL) {\n tag = elem.nodeName.toLowerCase(); // XHTML tags must be lower case.\n if(Strophe.XHTML.validTag(tag)) {\n try {\n el = Strophe.xmlElement(tag);\n for(i = 0; i < Strophe.XHTML.attributes[tag].length; i++) {\n attribute = Strophe.XHTML.attributes[tag][i];\n value = elem.getAttribute(attribute);\n if(typeof value === 'undefined' || value === null || value === '' || value === false || value === 0) {\n continue;\n }\n if(attribute === 'style' && typeof value === 'object') {\n if(typeof value.cssText !== 'undefined') {\n value = value.cssText; // we're dealing with IE, need to get CSS out\n }\n }\n // filter out invalid css styles\n if(attribute === 'style') {\n css = [];\n cssAttrs = value.split(';');\n for(j = 0; j < cssAttrs.length; j++) {\n attr = cssAttrs[j].split(':');\n cssName = attr[0].replace(/^\\s*/, \"\").replace(/\\s*$/, \"\").toLowerCase();\n if(Strophe.XHTML.validCSS(cssName)) {\n cssValue = attr[1].replace(/^\\s*/, \"\").replace(/\\s*$/, \"\");\n css.push(cssName + ': ' + cssValue);\n }\n }\n if(css.length > 0) {\n value = css.join('; ');\n el.setAttribute(attribute, value);\n }\n } else {\n el.setAttribute(attribute, value);\n }\n }\n\n for (i = 0; i < elem.childNodes.length; i++) {\n el.appendChild(Strophe.createHtml(elem.childNodes[i]));\n }\n } catch(e) { // invalid elements\n el = Strophe.xmlTextNode('');\n }\n } else {\n el = Strophe.xmlGenerator().createDocumentFragment();\n for (i = 0; i < elem.childNodes.length; i++) {\n el.appendChild(Strophe.createHtml(elem.childNodes[i]));\n }\n }\n } else if (elem.nodeType === Strophe.ElementType.FRAGMENT) {\n el = Strophe.xmlGenerator().createDocumentFragment();\n for (i = 0; i < elem.childNodes.length; i++) {\n el.appendChild(Strophe.createHtml(elem.childNodes[i]));\n }\n } else if (elem.nodeType === Strophe.ElementType.TEXT) {\n el = Strophe.xmlTextNode(elem.nodeValue);\n }\n return el;\n },\n\n /** Function: escapeNode\n * Escape the node part (also called local part) of a JID.\n *\n * Parameters:\n * (String) node - A node (or local part).\n *\n * Returns:\n * An escaped node (or local part).\n */\n escapeNode: function (node) {\n if (typeof node !== \"string\") { return node; }\n return node.replace(/^\\s+|\\s+$/g, '')\n .replace(/\\\\/g, \"\\\\5c\")\n .replace(/ /g, \"\\\\20\")\n .replace(/\\\"/g, \"\\\\22\")\n .replace(/\\&/g, \"\\\\26\")\n .replace(/\\'/g, \"\\\\27\")\n .replace(/\\//g, \"\\\\2f\")\n .replace(/:/g, \"\\\\3a\")\n .replace(//g, \"\\\\3e\")\n .replace(/@/g, \"\\\\40\");\n },\n\n /** Function: unescapeNode\n * Unescape a node part (also called local part) of a JID.\n *\n * Parameters:\n * (String) node - A node (or local part).\n *\n * Returns:\n * An unescaped node (or local part).\n */\n unescapeNode: function (node) {\n if (typeof node !== \"string\") { return node; }\n return node.replace(/\\\\20/g, \" \")\n .replace(/\\\\22/g, '\"')\n .replace(/\\\\26/g, \"&\")\n .replace(/\\\\27/g, \"'\")\n .replace(/\\\\2f/g, \"/\")\n .replace(/\\\\3a/g, \":\")\n .replace(/\\\\3c/g, \"<\")\n .replace(/\\\\3e/g, \">\")\n .replace(/\\\\40/g, \"@\")\n .replace(/\\\\5c/g, \"\\\\\");\n },\n\n /** Function: getNodeFromJid\n * Get the node portion of a JID String.\n *\n * Parameters:\n * (String) jid - A JID.\n *\n * Returns:\n * A String containing the node.\n */\n getNodeFromJid: function (jid) {\n if (jid.indexOf(\"@\") < 0) { return null; }\n return jid.split(\"@\")[0];\n },\n\n /** Function: getDomainFromJid\n * Get the domain portion of a JID String.\n *\n * Parameters:\n * (String) jid - A JID.\n *\n * Returns:\n * A String containing the domain.\n */\n getDomainFromJid: function (jid) {\n var bare = Strophe.getBareJidFromJid(jid);\n if (bare.indexOf(\"@\") < 0) {\n return bare;\n } else {\n var parts = bare.split(\"@\");\n parts.splice(0, 1);\n return parts.join('@');\n }\n },\n\n /** Function: getResourceFromJid\n * Get the resource portion of a JID String.\n *\n * Parameters:\n * (String) jid - A JID.\n *\n * Returns:\n * A String containing the resource.\n */\n getResourceFromJid: function (jid) {\n var s = jid.split(\"/\");\n if (s.length < 2) { return null; }\n s.splice(0, 1);\n return s.join('/');\n },\n\n /** Function: getBareJidFromJid\n * Get the bare JID from a JID String.\n *\n * Parameters:\n * (String) jid - A JID.\n *\n * Returns:\n * A String containing the bare JID.\n */\n getBareJidFromJid: function (jid) {\n return jid ? jid.split(\"/\")[0] : null;\n },\n\n /** PrivateFunction: _handleError\n * _Private_ function that properly logs an error to the console\n */\n _handleError: function (e) {\n if (typeof e.stack !== \"undefined\") {\n Strophe.fatal(e.stack);\n }\n if (e.sourceURL) {\n Strophe.fatal(\"error: \" + this.handler + \" \" + e.sourceURL + \":\" +\n e.line + \" - \" + e.name + \": \" + e.message);\n } else if (e.fileName) {\n Strophe.fatal(\"error: \" + this.handler + \" \" +\n e.fileName + \":\" + e.lineNumber + \" - \" +\n e.name + \": \" + e.message);\n } else {\n Strophe.fatal(\"error: \" + e.message);\n }\n },\n\n /** Function: log\n * User overrideable logging function.\n *\n * This function is called whenever the Strophe library calls any\n * of the logging functions. The default implementation of this\n * function logs only fatal errors. If client code wishes to handle the logging\n * messages, it should override this with\n * > Strophe.log = function (level, msg) {\n * > (user code here)\n * > };\n *\n * Please note that data sent and received over the wire is logged\n * via Strophe.Connection.rawInput() and Strophe.Connection.rawOutput().\n *\n * The different levels and their meanings are\n *\n * DEBUG - Messages useful for debugging purposes.\n * INFO - Informational messages. This is mostly information like\n * 'disconnect was called' or 'SASL auth succeeded'.\n * WARN - Warnings about potential problems. This is mostly used\n * to report transient connection errors like request timeouts.\n * ERROR - Some error occurred.\n * FATAL - A non-recoverable fatal error occurred.\n *\n * Parameters:\n * (Integer) level - The log level of the log message. This will\n * be one of the values in Strophe.LogLevel.\n * (String) msg - The log message.\n */\n log: function (level, msg) {\n if (level === this.LogLevel.FATAL &&\n typeof window.console === 'object' &&\n typeof window.console.error === 'function') {\n window.console.error(msg);\n }\n },\n\n /** Function: debug\n * Log a message at the Strophe.LogLevel.DEBUG level.\n *\n * Parameters:\n * (String) msg - The log message.\n */\n debug: function(msg) {\n this.log(this.LogLevel.DEBUG, msg);\n },\n\n /** Function: info\n * Log a message at the Strophe.LogLevel.INFO level.\n *\n * Parameters:\n * (String) msg - The log message.\n */\n info: function (msg) {\n this.log(this.LogLevel.INFO, msg);\n },\n\n /** Function: warn\n * Log a message at the Strophe.LogLevel.WARN level.\n *\n * Parameters:\n * (String) msg - The log message.\n */\n warn: function (msg) {\n this.log(this.LogLevel.WARN, msg);\n },\n\n /** Function: error\n * Log a message at the Strophe.LogLevel.ERROR level.\n *\n * Parameters:\n * (String) msg - The log message.\n */\n error: function (msg) {\n this.log(this.LogLevel.ERROR, msg);\n },\n\n /** Function: fatal\n * Log a message at the Strophe.LogLevel.FATAL level.\n *\n * Parameters:\n * (String) msg - The log message.\n */\n fatal: function (msg) {\n this.log(this.LogLevel.FATAL, msg);\n },\n\n /** Function: serialize\n * Render a DOM element and all descendants to a String.\n *\n * Parameters:\n * (XMLElement) elem - A DOM element.\n *\n * Returns:\n * The serialized element tree as a String.\n */\n serialize: function (elem) {\n var result;\n\n if (!elem) { return null; }\n\n if (typeof(elem.tree) === \"function\") {\n elem = elem.tree();\n }\n\n var nodeName = elem.nodeName;\n var i, child;\n\n if (elem.getAttribute(\"_realname\")) {\n nodeName = elem.getAttribute(\"_realname\");\n }\n\n result = \"<\" + nodeName;\n for (i = 0; i < elem.attributes.length; i++) {\n if(elem.attributes[i].nodeName !== \"_realname\") {\n result += \" \" + elem.attributes[i].nodeName +\n \"='\" + Strophe.xmlescape(elem.attributes[i].value) + \"'\";\n }\n }\n\n if (elem.childNodes.length > 0) {\n result += \">\";\n for (i = 0; i < elem.childNodes.length; i++) {\n child = elem.childNodes[i];\n switch( child.nodeType ){\n case Strophe.ElementType.NORMAL:\n // normal element, so recurse\n result += Strophe.serialize(child);\n break;\n case Strophe.ElementType.TEXT:\n // text element to escape values\n result += Strophe.xmlescape(child.nodeValue);\n break;\n case Strophe.ElementType.CDATA:\n // cdata section so don't escape values\n result += \"\";\n }\n }\n result += \"\";\n } else {\n result += \"/>\";\n }\n\n return result;\n },\n\n /** PrivateVariable: _requestId\n * _Private_ variable that keeps track of the request ids for\n * connections.\n */\n _requestId: 0,\n\n /** PrivateVariable: Strophe.connectionPlugins\n * _Private_ variable Used to store plugin names that need\n * initialization on Strophe.Connection construction.\n */\n _connectionPlugins: {},\n\n /** Function: addConnectionPlugin\n * Extends the Strophe.Connection object with the given plugin.\n *\n * Parameters:\n * (String) name - The name of the extension.\n * (Object) ptype - The plugin's prototype.\n */\n addConnectionPlugin: function (name, ptype) {\n Strophe._connectionPlugins[name] = ptype;\n }\n};\n\n/** Class: Strophe.Builder\n * XML DOM builder.\n *\n * This object provides an interface similar to JQuery but for building\n * DOM elements easily and rapidly. All the functions except for toString()\n * and tree() return the object, so calls can be chained. Here's an\n * example using the $iq() builder helper.\n * > $iq({to: 'you', from: 'me', type: 'get', id: '1'})\n * > .c('query', {xmlns: 'strophe:example'})\n * > .c('example')\n * > .toString()\n *\n * The above generates this XML fragment\n * > \n * > \n * > \n * > \n * > \n * The corresponding DOM manipulations to get a similar fragment would be\n * a lot more tedious and probably involve several helper variables.\n *\n * Since adding children makes new operations operate on the child, up()\n * is provided to traverse up the tree. To add two children, do\n * > builder.c('child1', ...).up().c('child2', ...)\n * The next operation on the Builder will be relative to the second child.\n */\n\n/** Constructor: Strophe.Builder\n * Create a Strophe.Builder object.\n *\n * The attributes should be passed in object notation. For example\n * > var b = new Builder('message', {to: 'you', from: 'me'});\n * or\n * > var b = new Builder('messsage', {'xml:lang': 'en'});\n *\n * Parameters:\n * (String) name - The name of the root element.\n * (Object) attrs - The attributes for the root element in object notation.\n *\n * Returns:\n * A new Strophe.Builder.\n */\nStrophe.Builder = function (name, attrs) {\n // Set correct namespace for jabber:client elements\n if (name === \"presence\" || name === \"message\" || name === \"iq\") {\n if (attrs && !attrs.xmlns) {\n attrs.xmlns = Strophe.NS.CLIENT;\n } else if (!attrs) {\n attrs = {xmlns: Strophe.NS.CLIENT};\n }\n }\n\n // Holds the tree being built.\n this.nodeTree = Strophe.xmlElement(name, attrs);\n\n // Points to the current operation node.\n this.node = this.nodeTree;\n};\n\nStrophe.Builder.prototype = {\n /** Function: tree\n * Return the DOM tree.\n *\n * This function returns the current DOM tree as an element object. This\n * is suitable for passing to functions like Strophe.Connection.send().\n *\n * Returns:\n * The DOM tree as a element object.\n */\n tree: function () {\n return this.nodeTree;\n },\n\n /** Function: toString\n * Serialize the DOM tree to a String.\n *\n * This function returns a string serialization of the current DOM\n * tree. It is often used internally to pass data to a\n * Strophe.Request object.\n *\n * Returns:\n * The serialized DOM tree in a String.\n */\n toString: function () {\n return Strophe.serialize(this.nodeTree);\n },\n\n /** Function: up\n * Make the current parent element the new current element.\n *\n * This function is often used after c() to traverse back up the tree.\n * For example, to add two children to the same element\n * > builder.c('child1', {}).up().c('child2', {});\n *\n * Returns:\n * The Stophe.Builder object.\n */\n up: function () {\n this.node = this.node.parentNode;\n return this;\n },\n\n /** Function: root\n * Make the root element the new current element.\n *\n * When at a deeply nested element in the tree, this function can be used\n * to jump back to the root of the tree, instead of having to repeatedly\n * call up().\n *\n * Returns:\n * The Stophe.Builder object.\n */\n root: function () {\n this.node = this.nodeTree;\n return this;\n },\n\n /** Function: attrs\n * Add or modify attributes of the current element.\n *\n * The attributes should be passed in object notation. This function\n * does not move the current element pointer.\n *\n * Parameters:\n * (Object) moreattrs - The attributes to add/modify in object notation.\n *\n * Returns:\n * The Strophe.Builder object.\n */\n attrs: function (moreattrs) {\n for (var k in moreattrs) {\n if (moreattrs.hasOwnProperty(k)) {\n if (moreattrs[k] === undefined) {\n this.node.removeAttribute(k);\n } else {\n this.node.setAttribute(k, moreattrs[k]);\n }\n }\n }\n return this;\n },\n\n /** Function: c\n * Add a child to the current element and make it the new current\n * element.\n *\n * This function moves the current element pointer to the child,\n * unless text is provided. If you need to add another child, it\n * is necessary to use up() to go back to the parent in the tree.\n *\n * Parameters:\n * (String) name - The name of the child.\n * (Object) attrs - The attributes of the child in object notation.\n * (String) text - The text to add to the child.\n *\n * Returns:\n * The Strophe.Builder object.\n */\n c: function (name, attrs, text) {\n var child = Strophe.xmlElement(name, attrs, text);\n this.node.appendChild(child);\n if (typeof text !== \"string\" && typeof text !==\"number\") {\n this.node = child;\n }\n return this;\n },\n\n /** Function: cnode\n * Add a child to the current element and make it the new current\n * element.\n *\n * This function is the same as c() except that instead of using a\n * name and an attributes object to create the child it uses an\n * existing DOM element object.\n *\n * Parameters:\n * (XMLElement) elem - A DOM element.\n *\n * Returns:\n * The Strophe.Builder object.\n */\n cnode: function (elem) {\n var impNode;\n var xmlGen = Strophe.xmlGenerator();\n try {\n impNode = (xmlGen.importNode !== undefined);\n } catch (e) {\n impNode = false;\n }\n var newElem = impNode ?\n xmlGen.importNode(elem, true) :\n Strophe.copyElement(elem);\n this.node.appendChild(newElem);\n this.node = newElem;\n return this;\n },\n\n /** Function: t\n * Add a child text element.\n *\n * This *does not* make the child the new current element since there\n * are no children of text elements.\n *\n * Parameters:\n * (String) text - The text data to append to the current element.\n *\n * Returns:\n * The Strophe.Builder object.\n */\n t: function (text) {\n var child = Strophe.xmlTextNode(text);\n this.node.appendChild(child);\n return this;\n },\n\n /** Function: h\n * Replace current element contents with the HTML passed in.\n *\n * This *does not* make the child the new current element\n *\n * Parameters:\n * (String) html - The html to insert as contents of current element.\n *\n * Returns:\n * The Strophe.Builder object.\n */\n h: function (html) {\n var fragment = document.createElement('body');\n\n // force the browser to try and fix any invalid HTML tags\n fragment.innerHTML = html;\n\n // copy cleaned html into an xml dom\n var xhtml = Strophe.createHtml(fragment);\n\n while(xhtml.childNodes.length > 0) {\n this.node.appendChild(xhtml.childNodes[0]);\n }\n return this;\n }\n};\n\n/** PrivateClass: Strophe.Handler\n * _Private_ helper class for managing stanza handlers.\n *\n * A Strophe.Handler encapsulates a user provided callback function to be\n * executed when matching stanzas are received by the connection.\n * Handlers can be either one-off or persistant depending on their\n * return value. Returning true will cause a Handler to remain active, and\n * returning false will remove the Handler.\n *\n * Users will not use Strophe.Handler objects directly, but instead they\n * will use Strophe.Connection.addHandler() and\n * Strophe.Connection.deleteHandler().\n */\n\n/** PrivateConstructor: Strophe.Handler\n * Create and initialize a new Strophe.Handler.\n *\n * Parameters:\n * (Function) handler - A function to be executed when the handler is run.\n * (String) ns - The namespace to match.\n * (String) name - The element name to match.\n * (String) type - The element type to match.\n * (String) id - The element id attribute to match.\n * (String) from - The element from attribute to match.\n * (Object) options - Handler options\n *\n * Returns:\n * A new Strophe.Handler object.\n */\nStrophe.Handler = function (handler, ns, name, type, id, from, options) {\n this.handler = handler;\n this.ns = ns;\n this.name = name;\n this.type = type;\n this.id = id;\n this.options = options || {'matchBareFromJid': false, 'ignoreNamespaceFragment': false};\n // BBB: Maintain backward compatibility with old `matchBare` option\n if (this.options.matchBare) {\n Strophe.warn('The \"matchBare\" option is deprecated, use \"matchBareFromJid\" instead.');\n this.options.matchBareFromJid = this.options.matchBare;\n delete this.options.matchBare;\n }\n\n if (this.options.matchBareFromJid) {\n this.from = from ? Strophe.getBareJidFromJid(from) : null;\n } else {\n this.from = from;\n }\n // whether the handler is a user handler or a system handler\n this.user = true;\n};\n\nStrophe.Handler.prototype = {\n /** PrivateFunction: getNamespace\n * Returns the XML namespace attribute on an element.\n * If `ignoreNamespaceFragment` was passed in for this handler, then the\n * URL fragment will be stripped.\n *\n * Parameters:\n * (XMLElement) elem - The XML element with the namespace.\n *\n * Returns:\n * The namespace, with optionally the fragment stripped.\n */\n getNamespace: function (elem) {\n var elNamespace = elem.getAttribute(\"xmlns\");\n if (elNamespace && this.options.ignoreNamespaceFragment) {\n elNamespace = elNamespace.split('#')[0];\n }\n return elNamespace;\n },\n\n /** PrivateFunction: namespaceMatch\n * Tests if a stanza matches the namespace set for this Strophe.Handler.\n *\n * Parameters:\n * (XMLElement) elem - The XML element to test.\n *\n * Returns:\n * true if the stanza matches and false otherwise.\n */\n namespaceMatch: function (elem) {\n var nsMatch = false;\n if (!this.ns) {\n return true;\n } else {\n var that = this;\n Strophe.forEachChild(elem, null, function (elem) {\n if (that.getNamespace(elem) === that.ns) {\n nsMatch = true;\n }\n });\n nsMatch = nsMatch || this.getNamespace(elem) === this.ns;\n }\n return nsMatch;\n },\n\n /** PrivateFunction: isMatch\n * Tests if a stanza matches the Strophe.Handler.\n *\n * Parameters:\n * (XMLElement) elem - The XML element to test.\n *\n * Returns:\n * true if the stanza matches and false otherwise.\n */\n isMatch: function (elem) {\n var from = elem.getAttribute('from');\n if (this.options.matchBareFromJid) {\n from = Strophe.getBareJidFromJid(from);\n }\n var elem_type = elem.getAttribute(\"type\");\n if (this.namespaceMatch(elem) &&\n (!this.name || Strophe.isTagEqual(elem, this.name)) &&\n (!this.type || (Array.isArray(this.type) ? this.type.indexOf(elem_type) !== -1 : elem_type === this.type)) &&\n (!this.id || elem.getAttribute(\"id\") === this.id) &&\n (!this.from || from === this.from)) {\n return true;\n }\n return false;\n },\n\n /** PrivateFunction: run\n * Run the callback on a matching stanza.\n *\n * Parameters:\n * (XMLElement) elem - The DOM element that triggered the\n * Strophe.Handler.\n *\n * Returns:\n * A boolean indicating if the handler should remain active.\n */\n run: function (elem) {\n var result = null;\n try {\n result = this.handler(elem);\n } catch (e) {\n Strophe._handleError(e);\n throw e;\n }\n return result;\n },\n\n /** PrivateFunction: toString\n * Get a String representation of the Strophe.Handler object.\n *\n * Returns:\n * A String.\n */\n toString: function () {\n return \"{Handler: \" + this.handler + \"(\" + this.name + \",\" +\n this.id + \",\" + this.ns + \")}\";\n }\n};\n\n/** PrivateClass: Strophe.TimedHandler\n * _Private_ helper class for managing timed handlers.\n *\n * A Strophe.TimedHandler encapsulates a user provided callback that\n * should be called after a certain period of time or at regular\n * intervals. The return value of the callback determines whether the\n * Strophe.TimedHandler will continue to fire.\n *\n * Users will not use Strophe.TimedHandler objects directly, but instead\n * they will use Strophe.Connection.addTimedHandler() and\n * Strophe.Connection.deleteTimedHandler().\n */\n\n/** PrivateConstructor: Strophe.TimedHandler\n * Create and initialize a new Strophe.TimedHandler object.\n *\n * Parameters:\n * (Integer) period - The number of milliseconds to wait before the\n * handler is called.\n * (Function) handler - The callback to run when the handler fires. This\n * function should take no arguments.\n *\n * Returns:\n * A new Strophe.TimedHandler object.\n */\nStrophe.TimedHandler = function (period, handler) {\n this.period = period;\n this.handler = handler;\n this.lastCalled = new Date().getTime();\n this.user = true;\n};\n\nStrophe.TimedHandler.prototype = {\n /** PrivateFunction: run\n * Run the callback for the Strophe.TimedHandler.\n *\n * Returns:\n * true if the Strophe.TimedHandler should be called again, and false\n * otherwise.\n */\n run: function () {\n this.lastCalled = new Date().getTime();\n return this.handler();\n },\n\n /** PrivateFunction: reset\n * Reset the last called time for the Strophe.TimedHandler.\n */\n reset: function () {\n this.lastCalled = new Date().getTime();\n },\n\n /** PrivateFunction: toString\n * Get a string representation of the Strophe.TimedHandler object.\n *\n * Returns:\n * The string representation.\n */\n toString: function () {\n return \"{TimedHandler: \" + this.handler + \"(\" + this.period +\")}\";\n }\n};\n\n/** Class: Strophe.Connection\n * XMPP Connection manager.\n *\n * This class is the main part of Strophe. It manages a BOSH or websocket\n * connection to an XMPP server and dispatches events to the user callbacks\n * as data arrives. It supports SASL PLAIN, SASL DIGEST-MD5, SASL SCRAM-SHA1\n * and legacy authentication.\n *\n * After creating a Strophe.Connection object, the user will typically\n * call connect() with a user supplied callback to handle connection level\n * events like authentication failure, disconnection, or connection\n * complete.\n *\n * The user will also have several event handlers defined by using\n * addHandler() and addTimedHandler(). These will allow the user code to\n * respond to interesting stanzas or do something periodically with the\n * connection. These handlers will be active once authentication is\n * finished.\n *\n * To send data to the connection, use send().\n */\n\n/** Constructor: Strophe.Connection\n * Create and initialize a Strophe.Connection object.\n *\n * The transport-protocol for this connection will be chosen automatically\n * based on the given service parameter. URLs starting with \"ws://\" or\n * \"wss://\" will use WebSockets, URLs starting with \"http://\", \"https://\"\n * or without a protocol will use BOSH.\n *\n * To make Strophe connect to the current host you can leave out the protocol\n * and host part and just pass the path, e.g.\n *\n * > var conn = new Strophe.Connection(\"/http-bind/\");\n *\n * Options common to both Websocket and BOSH:\n * ------------------------------------------\n *\n * cookies:\n *\n * The *cookies* option allows you to pass in cookies to be added to the\n * document. These cookies will then be included in the BOSH XMLHttpRequest\n * or in the websocket connection.\n *\n * The passed in value must be a map of cookie names and string values.\n *\n * > { \"myCookie\": {\n * > \"value\": \"1234\",\n * > \"domain\": \".example.org\",\n * > \"path\": \"/\",\n * > \"expires\": expirationDate\n * > }\n * > }\n *\n * Note that cookies can't be set in this way for other domains (i.e. cross-domain).\n * Those cookies need to be set under those domains, for example they can be\n * set server-side by making a XHR call to that domain to ask it to set any\n * necessary cookies.\n *\n * mechanisms:\n *\n * The *mechanisms* option allows you to specify the SASL mechanisms that this\n * instance of Strophe.Connection (and therefore your XMPP client) will\n * support.\n *\n * The value must be an array of objects with Strophe.SASLMechanism\n * prototypes.\n *\n * If nothing is specified, then the following mechanisms (and their\n * priorities) are registered:\n *\n * SCRAM-SHA1 - 70\n * DIGEST-MD5 - 60\n * PLAIN - 50\n * OAUTH-BEARER - 40\n * OAUTH-2 - 30\n * ANONYMOUS - 20\n * EXTERNAL - 10\n *\n * WebSocket options:\n * ------------------\n *\n * If you want to connect to the current host with a WebSocket connection you\n * can tell Strophe to use WebSockets through a \"protocol\" attribute in the\n * optional options parameter. Valid values are \"ws\" for WebSocket and \"wss\"\n * for Secure WebSocket.\n * So to connect to \"wss://CURRENT_HOSTNAME/xmpp-websocket\" you would call\n *\n * > var conn = new Strophe.Connection(\"/xmpp-websocket/\", {protocol: \"wss\"});\n *\n * Note that relative URLs _NOT_ starting with a \"/\" will also include the path\n * of the current site.\n *\n * Also because downgrading security is not permitted by browsers, when using\n * relative URLs both BOSH and WebSocket connections will use their secure\n * variants if the current connection to the site is also secure (https).\n *\n * BOSH options:\n * -------------\n *\n * By adding \"sync\" to the options, you can control if requests will\n * be made synchronously or not. The default behaviour is asynchronous.\n * If you want to make requests synchronous, make \"sync\" evaluate to true.\n * > var conn = new Strophe.Connection(\"/http-bind/\", {sync: true});\n *\n * You can also toggle this on an already established connection.\n * > conn.options.sync = true;\n *\n * The *customHeaders* option can be used to provide custom HTTP headers to be\n * included in the XMLHttpRequests made.\n *\n * The *keepalive* option can be used to instruct Strophe to maintain the\n * current BOSH session across interruptions such as webpage reloads.\n *\n * It will do this by caching the sessions tokens in sessionStorage, and when\n * \"restore\" is called it will check whether there are cached tokens with\n * which it can resume an existing session.\n *\n * The *withCredentials* option should receive a Boolean value and is used to\n * indicate wether cookies should be included in ajax requests (by default\n * they're not).\n * Set this value to true if you are connecting to a BOSH service\n * and for some reason need to send cookies to it.\n * In order for this to work cross-domain, the server must also enable\n * credentials by setting the Access-Control-Allow-Credentials response header\n * to \"true\". For most usecases however this setting should be false (which\n * is the default).\n * Additionally, when using Access-Control-Allow-Credentials, the\n * Access-Control-Allow-Origin header can't be set to the wildcard \"*\", but\n * instead must be restricted to actual domains.\n *\n * The *contentType* option can be set to change the default Content-Type\n * of \"text/xml; charset=utf-8\", which can be useful to reduce the amount of\n * CORS preflight requests that are sent to the server.\n *\n * Parameters:\n * (String) service - The BOSH or WebSocket service URL.\n * (Object) options - A hash of configuration options\n *\n * Returns:\n * A new Strophe.Connection object.\n */\nStrophe.Connection = function (service, options) {\n // The service URL\n this.service = service;\n // Configuration options\n this.options = options || {};\n var proto = this.options.protocol || \"\";\n\n // Select protocal based on service or options\n if (service.indexOf(\"ws:\") === 0 || service.indexOf(\"wss:\") === 0 ||\n proto.indexOf(\"ws\") === 0) {\n this._proto = new Strophe.Websocket(this);\n } else {\n this._proto = new Strophe.Bosh(this);\n }\n\n /* The connected JID. */\n this.jid = \"\";\n /* the JIDs domain */\n this.domain = null;\n /* stream:features */\n this.features = null;\n\n // SASL\n this._sasl_data = {};\n this.do_session = false;\n this.do_bind = false;\n\n // handler lists\n this.timedHandlers = [];\n this.handlers = [];\n this.removeTimeds = [];\n this.removeHandlers = [];\n this.addTimeds = [];\n this.addHandlers = [];\n this.protocolErrorHandlers = {\n 'HTTP': {},\n 'websocket': {}\n };\n\n this._idleTimeout = null;\n this._disconnectTimeout = null;\n\n this.authenticated = false;\n this.connected = false;\n this.disconnecting = false;\n this.do_authentication = true;\n this.paused = false;\n this.restored = false;\n\n this._data = [];\n this._uniqueId = 0;\n\n this._sasl_success_handler = null;\n this._sasl_failure_handler = null;\n this._sasl_challenge_handler = null;\n\n // Max retries before disconnecting\n this.maxRetries = 5;\n\n // Call onIdle callback every 1/10th of a second\n // XXX: setTimeout should be called only with function expressions (23974bc1)\n this._idleTimeout = setTimeout(function() {\n this._onIdle();\n }.bind(this), 100);\n\n utils.addCookies(this.options.cookies);\n this.registerSASLMechanisms(this.options.mechanisms);\n\n // initialize plugins\n for (var k in Strophe._connectionPlugins) {\n if (Strophe._connectionPlugins.hasOwnProperty(k)) {\n var ptype = Strophe._connectionPlugins[k];\n // jslint complaints about the below line, but this is fine\n var F = function () {}; // jshint ignore:line\n F.prototype = ptype;\n this[k] = new F();\n this[k].init(this);\n }\n }\n};\n\nStrophe.Connection.prototype = {\n /** Function: reset\n * Reset the connection.\n *\n * This function should be called after a connection is disconnected\n * before that connection is reused.\n */\n reset: function () {\n this._proto._reset();\n\n // SASL\n this.do_session = false;\n this.do_bind = false;\n\n // handler lists\n this.timedHandlers = [];\n this.handlers = [];\n this.removeTimeds = [];\n this.removeHandlers = [];\n this.addTimeds = [];\n this.addHandlers = [];\n\n this.authenticated = false;\n this.connected = false;\n this.disconnecting = false;\n this.restored = false;\n\n this._data = [];\n this._requests = [];\n this._uniqueId = 0;\n },\n\n /** Function: pause\n * Pause the request manager.\n *\n * This will prevent Strophe from sending any more requests to the\n * server. This is very useful for temporarily pausing\n * BOSH-Connections while a lot of send() calls are happening quickly.\n * This causes Strophe to send the data in a single request, saving\n * many request trips.\n */\n pause: function () {\n this.paused = true;\n },\n\n /** Function: resume\n * Resume the request manager.\n *\n * This resumes after pause() has been called.\n */\n resume: function () {\n this.paused = false;\n },\n\n /** Function: getUniqueId\n * Generate a unique ID for use in elements.\n *\n * All stanzas are required to have unique id attributes. This\n * function makes creating these easy. Each connection instance has\n * a counter which starts from zero, and the value of this counter\n * plus a colon followed by the suffix becomes the unique id. If no\n * suffix is supplied, the counter is used as the unique id.\n *\n * Suffixes are used to make debugging easier when reading the stream\n * data, and their use is recommended. The counter resets to 0 for\n * every new connection for the same reason. For connections to the\n * same server that authenticate the same way, all the ids should be\n * the same, which makes it easy to see changes. This is useful for\n * automated testing as well.\n *\n * Parameters:\n * (String) suffix - A optional suffix to append to the id.\n *\n * Returns:\n * A unique string to be used for the id attribute.\n */\n getUniqueId: function(suffix) {\n var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n var r = Math.random() * 16 | 0,\n v = c === 'x' ? r : r & 0x3 | 0x8;\n return v.toString(16);\n });\n if (typeof(suffix) === \"string\" || typeof(suffix) === \"number\") {\n return uuid + \":\" + suffix;\n } else {\n return uuid + \"\";\n }\n },\n\n /** Function: addProtocolErrorHandler\n * Register a handler function for when a protocol (websocker or HTTP)\n * error occurs.\n *\n * NOTE: Currently only HTTP errors for BOSH requests are handled.\n * Patches that handle websocket errors would be very welcome.\n *\n * Parameters:\n * (String) protocol - 'HTTP' or 'websocket'\n * (Integer) status_code - Error status code (e.g 500, 400 or 404)\n * (Function) callback - Function that will fire on Http error\n *\n * Example:\n * function onError(err_code){\n * //do stuff\n * }\n *\n * var conn = Strophe.connect('http://example.com/http-bind');\n * conn.addProtocolErrorHandler('HTTP', 500, onError);\n * // Triggers HTTP 500 error and onError handler will be called\n * conn.connect('user_jid@incorrect_jabber_host', 'secret', onConnect);\n */\n addProtocolErrorHandler: function(protocol, status_code, callback){\n this.protocolErrorHandlers[protocol][status_code] = callback;\n },\n\n\n /** Function: connect\n * Starts the connection process.\n *\n * As the connection process proceeds, the user supplied callback will\n * be triggered multiple times with status updates. The callback\n * should take two arguments - the status code and the error condition.\n *\n * The status code will be one of the values in the Strophe.Status\n * constants. The error condition will be one of the conditions\n * defined in RFC 3920 or the condition 'strophe-parsererror'.\n *\n * The Parameters _wait_, _hold_ and _route_ are optional and only relevant\n * for BOSH connections. Please see XEP 124 for a more detailed explanation\n * of the optional parameters.\n *\n * Parameters:\n * (String) jid - The user's JID. This may be a bare JID,\n * or a full JID. If a node is not supplied, SASL OAUTHBEARER or\n * SASL ANONYMOUS authentication will be attempted (OAUTHBEARER will\n * process the provided password value as an access token).\n * (String) pass - The user's password.\n * (Function) callback - The connect callback function.\n * (Integer) wait - The optional HTTPBIND wait value. This is the\n * time the server will wait before returning an empty result for\n * a request. The default setting of 60 seconds is recommended.\n * (Integer) hold - The optional HTTPBIND hold value. This is the\n * number of connections the server will hold at one time. This\n * should almost always be set to 1 (the default).\n * (String) route - The optional route value.\n * (String) authcid - The optional alternative authentication identity\n * (username) if intending to impersonate another user.\n * When using the SASL-EXTERNAL authentication mechanism, for example\n * with client certificates, then the authcid value is used to\n * determine whether an authorization JID (authzid) should be sent to\n * the server. The authzid should not be sent to the server if the\n * authzid and authcid are the same. So to prevent it from being sent\n * (for example when the JID is already contained in the client\n * certificate), set authcid to that same JID. See XEP-178 for more\n * details.\n */\n connect: function (jid, pass, callback, wait, hold, route, authcid) {\n this.jid = jid;\n /** Variable: authzid\n * Authorization identity.\n */\n this.authzid = Strophe.getBareJidFromJid(this.jid);\n\n /** Variable: authcid\n * Authentication identity (User name).\n */\n this.authcid = authcid || Strophe.getNodeFromJid(this.jid);\n\n /** Variable: pass\n * Authentication identity (User password).\n */\n this.pass = pass;\n\n /** Variable: servtype\n * Digest MD5 compatibility.\n */\n this.servtype = \"xmpp\";\n\n this.connect_callback = callback;\n this.disconnecting = false;\n this.connected = false;\n this.authenticated = false;\n this.restored = false;\n\n // parse jid for domain\n this.domain = Strophe.getDomainFromJid(this.jid);\n\n this._changeConnectStatus(Strophe.Status.CONNECTING, null);\n\n this._proto._connect(wait, hold, route);\n },\n\n /** Function: attach\n * Attach to an already created and authenticated BOSH session.\n *\n * This function is provided to allow Strophe to attach to BOSH\n * sessions which have been created externally, perhaps by a Web\n * application. This is often used to support auto-login type features\n * without putting user credentials into the page.\n *\n * Parameters:\n * (String) jid - The full JID that is bound by the session.\n * (String) sid - The SID of the BOSH session.\n * (String) rid - The current RID of the BOSH session. This RID\n * will be used by the next request.\n * (Function) callback The connect callback function.\n * (Integer) wait - The optional HTTPBIND wait value. This is the\n * time the server will wait before returning an empty result for\n * a request. The default setting of 60 seconds is recommended.\n * Other settings will require tweaks to the Strophe.TIMEOUT value.\n * (Integer) hold - The optional HTTPBIND hold value. This is the\n * number of connections the server will hold at one time. This\n * should almost always be set to 1 (the default).\n * (Integer) wind - The optional HTTBIND window value. This is the\n * allowed range of request ids that are valid. The default is 5.\n */\n attach: function (jid, sid, rid, callback, wait, hold, wind) {\n if (this._proto instanceof Strophe.Bosh) {\n this._proto._attach(jid, sid, rid, callback, wait, hold, wind);\n } else {\n throw {\n name: 'StropheSessionError',\n message: 'The \"attach\" method can only be used with a BOSH connection.'\n };\n }\n },\n\n /** Function: restore\n * Attempt to restore a cached BOSH session.\n *\n * This function is only useful in conjunction with providing the\n * \"keepalive\":true option when instantiating a new Strophe.Connection.\n *\n * When \"keepalive\" is set to true, Strophe will cache the BOSH tokens\n * RID (Request ID) and SID (Session ID) and then when this function is\n * called, it will attempt to restore the session from those cached\n * tokens.\n *\n * This function must therefore be called instead of connect or attach.\n *\n * For an example on how to use it, please see examples/restore.js\n *\n * Parameters:\n * (String) jid - The user's JID. This may be a bare JID or a full JID.\n * (Function) callback - The connect callback function.\n * (Integer) wait - The optional HTTPBIND wait value. This is the\n * time the server will wait before returning an empty result for\n * a request. The default setting of 60 seconds is recommended.\n * (Integer) hold - The optional HTTPBIND hold value. This is the\n * number of connections the server will hold at one time. This\n * should almost always be set to 1 (the default).\n * (Integer) wind - The optional HTTBIND window value. This is the\n * allowed range of request ids that are valid. The default is 5.\n */\n restore: function (jid, callback, wait, hold, wind) {\n if (this._sessionCachingSupported()) {\n this._proto._restore(jid, callback, wait, hold, wind);\n } else {\n throw {\n name: 'StropheSessionError',\n message: 'The \"restore\" method can only be used with a BOSH connection.'\n };\n }\n },\n\n /** PrivateFunction: _sessionCachingSupported\n * Checks whether sessionStorage and JSON are supported and whether we're\n * using BOSH.\n */\n _sessionCachingSupported: function () {\n if (this._proto instanceof Strophe.Bosh) {\n if (!JSON) { return false; }\n try {\n sessionStorage.setItem('_strophe_', '_strophe_');\n sessionStorage.removeItem('_strophe_');\n } catch (e) {\n return false;\n }\n return true;\n }\n return false;\n },\n\n /** Function: xmlInput\n * User overrideable function that receives XML data coming into the\n * connection.\n *\n * The default function does nothing. User code can override this with\n * > Strophe.Connection.xmlInput = function (elem) {\n * > (user code)\n * > };\n *\n * Due to limitations of current Browsers' XML-Parsers the opening and closing\n * tag for WebSocket-Connoctions will be passed as selfclosing here.\n *\n * BOSH-Connections will have all stanzas wrapped in a tag. See\n * if you want to strip this tag.\n *\n * Parameters:\n * (XMLElement) elem - The XML data received by the connection.\n */\n /* jshint unused:false */\n xmlInput: function (elem) {\n return;\n },\n /* jshint unused:true */\n\n /** Function: xmlOutput\n * User overrideable function that receives XML data sent to the\n * connection.\n *\n * The default function does nothing. User code can override this with\n * > Strophe.Connection.xmlOutput = function (elem) {\n * > (user code)\n * > };\n *\n * Due to limitations of current Browsers' XML-Parsers the opening and closing\n * tag for WebSocket-Connoctions will be passed as selfclosing here.\n *\n * BOSH-Connections will have all stanzas wrapped in a tag. See\n * if you want to strip this tag.\n *\n * Parameters:\n * (XMLElement) elem - The XMLdata sent by the connection.\n */\n /* jshint unused:false */\n xmlOutput: function (elem) {\n return;\n },\n /* jshint unused:true */\n\n /** Function: rawInput\n * User overrideable function that receives raw data coming into the\n * connection.\n *\n * The default function does nothing. User code can override this with\n * > Strophe.Connection.rawInput = function (data) {\n * > (user code)\n * > };\n *\n * Parameters:\n * (String) data - The data received by the connection.\n */\n /* jshint unused:false */\n rawInput: function (data) {\n return;\n },\n /* jshint unused:true */\n\n /** Function: rawOutput\n * User overrideable function that receives raw data sent to the\n * connection.\n *\n * The default function does nothing. User code can override this with\n * > Strophe.Connection.rawOutput = function (data) {\n * > (user code)\n * > };\n *\n * Parameters:\n * (String) data - The data sent by the connection.\n */\n /* jshint unused:false */\n rawOutput: function (data) {\n return;\n },\n /* jshint unused:true */\n\n /** Function: nextValidRid\n * User overrideable function that receives the new valid rid.\n *\n * The default function does nothing. User code can override this with\n * > Strophe.Connection.nextValidRid = function (rid) {\n * > (user code)\n * > };\n *\n * Parameters:\n * (Number) rid - The next valid rid\n */\n /* jshint unused:false */\n nextValidRid: function (rid) {\n return;\n },\n /* jshint unused:true */\n\n /** Function: send\n * Send a stanza.\n *\n * This function is called to push data onto the send queue to\n * go out over the wire. Whenever a request is sent to the BOSH\n * server, all pending data is sent and the queue is flushed.\n *\n * Parameters:\n * (XMLElement |\n * [XMLElement] |\n * Strophe.Builder) elem - The stanza to send.\n */\n send: function (elem) {\n if (elem === null) { return ; }\n if (typeof(elem.sort) === \"function\") {\n for (var i = 0; i < elem.length; i++) {\n this._queueData(elem[i]);\n }\n } else if (typeof(elem.tree) === \"function\") {\n this._queueData(elem.tree());\n } else {\n this._queueData(elem);\n }\n\n this._proto._send();\n },\n\n /** Function: flush\n * Immediately send any pending outgoing data.\n *\n * Normally send() queues outgoing data until the next idle period\n * (100ms), which optimizes network use in the common cases when\n * several send()s are called in succession. flush() can be used to\n * immediately send all pending data.\n */\n flush: function () {\n // cancel the pending idle period and run the idle function\n // immediately\n clearTimeout(this._idleTimeout);\n this._onIdle();\n },\n\n /** Function: sendPresence\n * Helper function to send presence stanzas. The main benefit is for\n * sending presence stanzas for which you expect a responding presence\n * stanza with the same id (for example when leaving a chat room).\n *\n * Parameters:\n * (XMLElement) elem - The stanza to send.\n * (Function) callback - The callback function for a successful request.\n * (Function) errback - The callback function for a failed or timed\n * out request. On timeout, the stanza will be null.\n * (Integer) timeout - The time specified in milliseconds for a\n * timeout to occur.\n *\n * Returns:\n * The id used to send the presence.\n */\n sendPresence: function(elem, callback, errback, timeout) {\n var timeoutHandler = null;\n var that = this;\n if (typeof(elem.tree) === \"function\") {\n elem = elem.tree();\n }\n var id = elem.getAttribute('id');\n if (!id) { // inject id if not found\n id = this.getUniqueId(\"sendPresence\");\n elem.setAttribute(\"id\", id);\n }\n\n if (typeof callback === \"function\" || typeof errback === \"function\") {\n var handler = this.addHandler(function (stanza) {\n // remove timeout handler if there is one\n if (timeoutHandler) {\n that.deleteTimedHandler(timeoutHandler);\n }\n var type = stanza.getAttribute('type');\n if (type === 'error') {\n if (errback) {\n errback(stanza);\n }\n } else if (callback) {\n callback(stanza);\n }\n }, null, 'presence', null, id);\n\n // if timeout specified, set up a timeout handler.\n if (timeout) {\n timeoutHandler = this.addTimedHandler(timeout, function () {\n // get rid of normal handler\n that.deleteHandler(handler);\n // call errback on timeout with null stanza\n if (errback) {\n errback(null);\n }\n return false;\n });\n }\n }\n this.send(elem);\n return id;\n },\n\n /** Function: sendIQ\n * Helper function to send IQ stanzas.\n *\n * Parameters:\n * (XMLElement) elem - The stanza to send.\n * (Function) callback - The callback function for a successful request.\n * (Function) errback - The callback function for a failed or timed\n * out request. On timeout, the stanza will be null.\n * (Integer) timeout - The time specified in milliseconds for a\n * timeout to occur.\n *\n * Returns:\n * The id used to send the IQ.\n */\n sendIQ: function(elem, callback, errback, timeout) {\n var timeoutHandler = null;\n var that = this;\n if (typeof(elem.tree) === \"function\") {\n elem = elem.tree();\n }\n var id = elem.getAttribute('id');\n if (!id) { // inject id if not found\n id = this.getUniqueId(\"sendIQ\");\n elem.setAttribute(\"id\", id);\n }\n\n if (typeof callback === \"function\" || typeof errback === \"function\") {\n var handler = this.addHandler(function (stanza) {\n // remove timeout handler if there is one\n if (timeoutHandler) {\n that.deleteTimedHandler(timeoutHandler);\n }\n var iqtype = stanza.getAttribute('type');\n if (iqtype === 'result') {\n if (callback) {\n callback(stanza);\n }\n } else if (iqtype === 'error') {\n if (errback) {\n errback(stanza);\n }\n } else {\n throw {\n name: \"StropheError\",\n message: \"Got bad IQ type of \" + iqtype\n };\n }\n }, null, 'iq', ['error', 'result'], id);\n\n // if timeout specified, set up a timeout handler.\n if (timeout) {\n timeoutHandler = this.addTimedHandler(timeout, function () {\n // get rid of normal handler\n that.deleteHandler(handler);\n // call errback on timeout with null stanza\n if (errback) {\n errback(null);\n }\n return false;\n });\n }\n }\n this.send(elem);\n return id;\n },\n\n /** PrivateFunction: _queueData\n * Queue outgoing data for later sending. Also ensures that the data\n * is a DOMElement.\n */\n _queueData: function (element) {\n if (element === null ||\n !element.tagName ||\n !element.childNodes) {\n throw {\n name: \"StropheError\",\n message: \"Cannot queue non-DOMElement.\"\n };\n }\n this._data.push(element);\n },\n\n /** PrivateFunction: _sendRestart\n * Send an xmpp:restart stanza.\n */\n _sendRestart: function () {\n this._data.push(\"restart\");\n this._proto._sendRestart();\n // XXX: setTimeout should be called only with function expressions (23974bc1)\n this._idleTimeout = setTimeout(function() {\n this._onIdle();\n }.bind(this), 100);\n },\n\n /** Function: addTimedHandler\n * Add a timed handler to the connection.\n *\n * This function adds a timed handler. The provided handler will\n * be called every period milliseconds until it returns false,\n * the connection is terminated, or the handler is removed. Handlers\n * that wish to continue being invoked should return true.\n *\n * Because of method binding it is necessary to save the result of\n * this function if you wish to remove a handler with\n * deleteTimedHandler().\n *\n * Note that user handlers are not active until authentication is\n * successful.\n *\n * Parameters:\n * (Integer) period - The period of the handler.\n * (Function) handler - The callback function.\n *\n * Returns:\n * A reference to the handler that can be used to remove it.\n */\n addTimedHandler: function (period, handler) {\n var thand = new Strophe.TimedHandler(period, handler);\n this.addTimeds.push(thand);\n return thand;\n },\n\n /** Function: deleteTimedHandler\n * Delete a timed handler for a connection.\n *\n * This function removes a timed handler from the connection. The\n * handRef parameter is *not* the function passed to addTimedHandler(),\n * but is the reference returned from addTimedHandler().\n *\n * Parameters:\n * (Strophe.TimedHandler) handRef - The handler reference.\n */\n deleteTimedHandler: function (handRef) {\n // this must be done in the Idle loop so that we don't change\n // the handlers during iteration\n this.removeTimeds.push(handRef);\n },\n\n /** Function: addHandler\n * Add a stanza handler for the connection.\n *\n * This function adds a stanza handler to the connection. The\n * handler callback will be called for any stanza that matches\n * the parameters. Note that if multiple parameters are supplied,\n * they must all match for the handler to be invoked.\n *\n * The handler will receive the stanza that triggered it as its argument.\n * *The handler should return true if it is to be invoked again;\n * returning false will remove the handler after it returns.*\n *\n * As a convenience, the ns parameters applies to the top level element\n * and also any of its immediate children. This is primarily to make\n * matching /iq/query elements easy.\n *\n * Options\n * ~~~~~~~\n * With the options argument, you can specify boolean flags that affect how\n * matches are being done.\n *\n * Currently two flags exist:\n *\n * - matchBareFromJid:\n * When set to true, the from parameter and the\n * from attribute on the stanza will be matched as bare JIDs instead\n * of full JIDs. To use this, pass {matchBareFromJid: true} as the\n * value of options. The default value for matchBareFromJid is false.\n *\n * - ignoreNamespaceFragment:\n * When set to true, a fragment specified on the stanza's namespace\n * URL will be ignored when it's matched with the one configured for\n * the handler.\n *\n * This means that if you register like this:\n * > connection.addHandler(\n * > handler,\n * > 'http://jabber.org/protocol/muc',\n * > null, null, null, null,\n * > {'ignoreNamespaceFragment': true}\n * > );\n *\n * Then a stanza with XML namespace of\n * 'http://jabber.org/protocol/muc#user' will also be matched. If\n * 'ignoreNamespaceFragment' is false, then only stanzas with\n * 'http://jabber.org/protocol/muc' will be matched.\n *\n * Deleting the handler\n * ~~~~~~~~~~~~~~~~~~~~\n * The return value should be saved if you wish to remove the handler\n * with deleteHandler().\n *\n * Parameters:\n * (Function) handler - The user callback.\n * (String) ns - The namespace to match.\n * (String) name - The stanza name to match.\n * (String|Array) type - The stanza type (or types if an array) to match.\n * (String) id - The stanza id attribute to match.\n * (String) from - The stanza from attribute to match.\n * (String) options - The handler options\n *\n * Returns:\n * A reference to the handler that can be used to remove it.\n */\n addHandler: function (handler, ns, name, type, id, from, options) {\n var hand = new Strophe.Handler(handler, ns, name, type, id, from, options);\n this.addHandlers.push(hand);\n return hand;\n },\n\n /** Function: deleteHandler\n * Delete a stanza handler for a connection.\n *\n * This function removes a stanza handler from the connection. The\n * handRef parameter is *not* the function passed to addHandler(),\n * but is the reference returned from addHandler().\n *\n * Parameters:\n * (Strophe.Handler) handRef - The handler reference.\n */\n deleteHandler: function (handRef) {\n // this must be done in the Idle loop so that we don't change\n // the handlers during iteration\n this.removeHandlers.push(handRef);\n // If a handler is being deleted while it is being added,\n // prevent it from getting added\n var i = this.addHandlers.indexOf(handRef);\n if (i >= 0) {\n this.addHandlers.splice(i, 1);\n }\n },\n\n /** Function: registerSASLMechanisms\n *\n * Register the SASL mechanisms which will be supported by this instance of\n * Strophe.Connection (i.e. which this XMPP client will support).\n *\n * Parameters:\n * (Array) mechanisms - Array of objects with Strophe.SASLMechanism prototypes\n *\n */\n registerSASLMechanisms: function (mechanisms) {\n this.mechanisms = {};\n mechanisms = mechanisms || [\n Strophe.SASLAnonymous,\n Strophe.SASLExternal,\n Strophe.SASLMD5,\n Strophe.SASLOAuthBearer,\n Strophe.SASLXOAuth2,\n Strophe.SASLPlain,\n Strophe.SASLSHA1\n ];\n mechanisms.forEach(this.registerSASLMechanism.bind(this));\n },\n\n /** Function: registerSASLMechanism\n *\n * Register a single SASL mechanism, to be supported by this client.\n *\n * Parameters:\n * (Object) mechanism - Object with a Strophe.SASLMechanism prototype\n *\n */\n registerSASLMechanism: function (mechanism) {\n this.mechanisms[mechanism.prototype.name] = mechanism;\n },\n\n /** Function: disconnect\n * Start the graceful disconnection process.\n *\n * This function starts the disconnection process. This process starts\n * by sending unavailable presence and sending BOSH body of type\n * terminate. A timeout handler makes sure that disconnection happens\n * even if the BOSH server does not respond.\n * If the Connection object isn't connected, at least tries to abort all pending requests\n * so the connection object won't generate successful requests (which were already opened).\n *\n * The user supplied connection callback will be notified of the\n * progress as this process happens.\n *\n * Parameters:\n * (String) reason - The reason the disconnect is occuring.\n */\n disconnect: function (reason) {\n this._changeConnectStatus(Strophe.Status.DISCONNECTING, reason);\n\n Strophe.info(\"Disconnect was called because: \" + reason);\n if (this.connected) {\n var pres = false;\n this.disconnecting = true;\n if (this.authenticated) {\n pres = $pres({\n xmlns: Strophe.NS.CLIENT,\n type: 'unavailable'\n });\n }\n // setup timeout handler\n this._disconnectTimeout = this._addSysTimedHandler(\n 3000, this._onDisconnectTimeout.bind(this));\n this._proto._disconnect(pres);\n } else {\n Strophe.info(\"Disconnect was called before Strophe connected to the server\");\n this._proto._abortAllRequests();\n this._doDisconnect();\n }\n },\n\n /** PrivateFunction: _changeConnectStatus\n * _Private_ helper function that makes sure plugins and the user's\n * callback are notified of connection status changes.\n *\n * Parameters:\n * (Integer) status - the new connection status, one of the values\n * in Strophe.Status\n * (String) condition - the error condition or null\n * (XMLElement) elem - The triggering stanza.\n */\n _changeConnectStatus: function (status, condition, elem) {\n // notify all plugins listening for status changes\n for (var k in Strophe._connectionPlugins) {\n if (Strophe._connectionPlugins.hasOwnProperty(k)) {\n var plugin = this[k];\n if (plugin.statusChanged) {\n try {\n plugin.statusChanged(status, condition);\n } catch (err) {\n Strophe.error(\"\" + k + \" plugin caused an exception \" +\n \"changing status: \" + err);\n }\n }\n }\n }\n\n // notify the user's callback\n if (this.connect_callback) {\n try {\n this.connect_callback(status, condition, elem);\n } catch (e) {\n Strophe._handleError(e);\n Strophe.error(\n \"User connection callback caused an \"+\"exception: \"+e);\n }\n }\n },\n\n /** PrivateFunction: _doDisconnect\n * _Private_ function to disconnect.\n *\n * This is the last piece of the disconnection logic. This resets the\n * connection and alerts the user's connection callback.\n */\n _doDisconnect: function (condition) {\n if (typeof this._idleTimeout === \"number\") {\n clearTimeout(this._idleTimeout);\n }\n\n // Cancel Disconnect Timeout\n if (this._disconnectTimeout !== null) {\n this.deleteTimedHandler(this._disconnectTimeout);\n this._disconnectTimeout = null;\n }\n\n Strophe.info(\"_doDisconnect was called\");\n this._proto._doDisconnect();\n\n this.authenticated = false;\n this.disconnecting = false;\n this.restored = false;\n\n // delete handlers\n this.handlers = [];\n this.timedHandlers = [];\n this.removeTimeds = [];\n this.removeHandlers = [];\n this.addTimeds = [];\n this.addHandlers = [];\n\n // tell the parent we disconnected\n this._changeConnectStatus(Strophe.Status.DISCONNECTED, condition);\n this.connected = false;\n },\n\n /** PrivateFunction: _dataRecv\n * _Private_ handler to processes incoming data from the the connection.\n *\n * Except for _connect_cb handling the initial connection request,\n * this function handles the incoming data for all requests. This\n * function also fires stanza handlers that match each incoming\n * stanza.\n *\n * Parameters:\n * (Strophe.Request) req - The request that has data ready.\n * (string) req - The stanza a raw string (optiona).\n */\n _dataRecv: function (req, raw) {\n Strophe.info(\"_dataRecv called\");\n var elem = this._proto._reqToData(req);\n if (elem === null) { return; }\n\n if (this.xmlInput !== Strophe.Connection.prototype.xmlInput) {\n if (elem.nodeName === this._proto.strip && elem.childNodes.length) {\n this.xmlInput(elem.childNodes[0]);\n } else {\n this.xmlInput(elem);\n }\n }\n if (this.rawInput !== Strophe.Connection.prototype.rawInput) {\n if (raw) {\n this.rawInput(raw);\n } else {\n this.rawInput(Strophe.serialize(elem));\n }\n }\n\n // remove handlers scheduled for deletion\n var i, hand;\n while (this.removeHandlers.length > 0) {\n hand = this.removeHandlers.pop();\n i = this.handlers.indexOf(hand);\n if (i >= 0) {\n this.handlers.splice(i, 1);\n }\n }\n\n // add handlers scheduled for addition\n while (this.addHandlers.length > 0) {\n this.handlers.push(this.addHandlers.pop());\n }\n\n // handle graceful disconnect\n if (this.disconnecting && this._proto._emptyQueue()) {\n this._doDisconnect();\n return;\n }\n\n var type = elem.getAttribute(\"type\");\n var cond, conflict;\n if (type !== null && type === \"terminate\") {\n // Don't process stanzas that come in after disconnect\n if (this.disconnecting) {\n return;\n }\n\n // an error occurred\n cond = elem.getAttribute(\"condition\");\n conflict = elem.getElementsByTagName(\"conflict\");\n if (cond !== null) {\n if (cond === \"remote-stream-error\" && conflict.length > 0) {\n cond = \"conflict\";\n }\n this._changeConnectStatus(Strophe.Status.CONNFAIL, cond);\n } else {\n this._changeConnectStatus(\n Strophe.Status.CONNFAIL,\n Strophe.ErrorCondition.UNKOWN_REASON\n );\n }\n this._doDisconnect(cond);\n return;\n }\n\n // send each incoming stanza through the handler chain\n var that = this;\n Strophe.forEachChild(elem, null, function (child) {\n var i, newList;\n // process handlers\n newList = that.handlers;\n that.handlers = [];\n for (i = 0; i < newList.length; i++) {\n var hand = newList[i];\n // encapsulate 'handler.run' not to lose the whole handler list if\n // one of the handlers throws an exception\n try {\n if (hand.isMatch(child) &&\n (that.authenticated || !hand.user)) {\n if (hand.run(child)) {\n that.handlers.push(hand);\n }\n } else {\n that.handlers.push(hand);\n }\n } catch(e) {\n // if the handler throws an exception, we consider it as false\n Strophe.warn('Removing Strophe handlers due to uncaught exception: '+e.message);\n }\n }\n });\n },\n\n\n /** Attribute: mechanisms\n * SASL Mechanisms available for Connection.\n */\n mechanisms: {},\n\n /** PrivateFunction: _connect_cb\n * _Private_ handler for initial connection request.\n *\n * This handler is used to process the initial connection request\n * response from the BOSH server. It is used to set up authentication\n * handlers and start the authentication process.\n *\n * SASL authentication will be attempted if available, otherwise\n * the code will fall back to legacy authentication.\n *\n * Parameters:\n * (Strophe.Request) req - The current request.\n * (Function) _callback - low level (xmpp) connect callback function.\n * Useful for plugins with their own xmpp connect callback (when they\n * want to do something special).\n */\n _connect_cb: function (req, _callback, raw) {\n Strophe.info(\"_connect_cb was called\");\n this.connected = true;\n\n var bodyWrap;\n try {\n bodyWrap = this._proto._reqToData(req);\n } catch (e) {\n if (e !== \"badformat\") { throw e; }\n this._changeConnectStatus(\n Strophe.Status.CONNFAIL,\n Strophe.ErrorCondition.BAD_FORMAT\n );\n this._doDisconnect(Strophe.ErrorCondition.BAD_FORMAT);\n }\n if (!bodyWrap) { return; }\n\n if (this.xmlInput !== Strophe.Connection.prototype.xmlInput) {\n if (bodyWrap.nodeName === this._proto.strip && bodyWrap.childNodes.length) {\n this.xmlInput(bodyWrap.childNodes[0]);\n } else {\n this.xmlInput(bodyWrap);\n }\n }\n if (this.rawInput !== Strophe.Connection.prototype.rawInput) {\n if (raw) {\n this.rawInput(raw);\n } else {\n this.rawInput(Strophe.serialize(bodyWrap));\n }\n }\n\n var conncheck = this._proto._connect_cb(bodyWrap);\n if (conncheck === Strophe.Status.CONNFAIL) {\n return;\n }\n\n // Check for the stream:features tag\n var hasFeatures;\n if (bodyWrap.getElementsByTagNameNS) {\n hasFeatures = bodyWrap.getElementsByTagNameNS(Strophe.NS.STREAM, \"features\").length > 0;\n } else {\n hasFeatures = bodyWrap.getElementsByTagName(\"stream:features\").length > 0 ||\n bodyWrap.getElementsByTagName(\"features\").length > 0;\n }\n if (!hasFeatures) {\n this._proto._no_auth_received(_callback);\n return;\n }\n\n var matched = [], i, mech;\n var mechanisms = bodyWrap.getElementsByTagName(\"mechanism\");\n if (mechanisms.length > 0) {\n for (i = 0; i < mechanisms.length; i++) {\n mech = Strophe.getText(mechanisms[i]);\n if (this.mechanisms[mech]) matched.push(this.mechanisms[mech]);\n }\n }\n if (matched.length === 0) {\n if (bodyWrap.getElementsByTagName(\"auth\").length === 0) {\n // There are no matching SASL mechanisms and also no legacy\n // auth available.\n this._proto._no_auth_received(_callback);\n return;\n }\n }\n if (this.do_authentication !== false) {\n this.authenticate(matched);\n }\n },\n\n /** Function: sortMechanismsByPriority\n *\n * Sorts an array of objects with prototype SASLMechanism according to\n * their priorities.\n *\n * Parameters:\n * (Array) mechanisms - Array of SASL mechanisms.\n *\n */\n sortMechanismsByPriority: function (mechanisms) {\n // Sorting mechanisms according to priority.\n var i, j, higher, swap;\n for (i = 0; i < mechanisms.length - 1; ++i) {\n higher = i;\n for (j = i + 1; j < mechanisms.length; ++j) {\n if (mechanisms[j].prototype.priority > mechanisms[higher].prototype.priority) {\n higher = j;\n }\n }\n if (higher !== i) {\n swap = mechanisms[i];\n mechanisms[i] = mechanisms[higher];\n mechanisms[higher] = swap;\n }\n }\n return mechanisms;\n },\n\n /** PrivateFunction: _attemptSASLAuth\n *\n * Iterate through an array of SASL mechanisms and attempt authentication\n * with the highest priority (enabled) mechanism.\n *\n * Parameters:\n * (Array) mechanisms - Array of SASL mechanisms.\n *\n * Returns:\n * (Boolean) mechanism_found - true or false, depending on whether a\n * valid SASL mechanism was found with which authentication could be\n * started.\n */\n _attemptSASLAuth: function (mechanisms) {\n mechanisms = this.sortMechanismsByPriority(mechanisms || []);\n var i = 0, mechanism_found = false;\n for (i = 0; i < mechanisms.length; ++i) {\n if (!mechanisms[i].prototype.test(this)) {\n continue;\n }\n this._sasl_success_handler = this._addSysHandler(\n this._sasl_success_cb.bind(this), null,\n \"success\", null, null);\n this._sasl_failure_handler = this._addSysHandler(\n this._sasl_failure_cb.bind(this), null,\n \"failure\", null, null);\n this._sasl_challenge_handler = this._addSysHandler(\n this._sasl_challenge_cb.bind(this), null,\n \"challenge\", null, null);\n\n this._sasl_mechanism = new mechanisms[i]();\n this._sasl_mechanism.onStart(this);\n\n var request_auth_exchange = $build(\"auth\", {\n xmlns: Strophe.NS.SASL,\n mechanism: this._sasl_mechanism.name\n });\n if (this._sasl_mechanism.isClientFirst) {\n var response = this._sasl_mechanism.onChallenge(this, null);\n request_auth_exchange.t(btoa(response));\n }\n this.send(request_auth_exchange.tree());\n mechanism_found = true;\n break;\n }\n return mechanism_found;\n },\n\n /** PrivateFunction: _attemptLegacyAuth\n *\n * Attempt legacy (i.e. non-SASL) authentication.\n *\n */\n _attemptLegacyAuth: function () {\n if (Strophe.getNodeFromJid(this.jid) === null) {\n // we don't have a node, which is required for non-anonymous\n // client connections\n this._changeConnectStatus(\n Strophe.Status.CONNFAIL,\n Strophe.ErrorCondition.MISSING_JID_NODE\n );\n this.disconnect(Strophe.ErrorCondition.MISSING_JID_NODE);\n } else {\n // Fall back to legacy authentication\n this._changeConnectStatus(Strophe.Status.AUTHENTICATING, null);\n this._addSysHandler(\n this._auth1_cb.bind(this),\n null, null, null, \"_auth_1\"\n );\n this.send($iq({\n 'type': \"get\",\n 'to': this.domain,\n 'id': \"_auth_1\"\n }).c(\"query\", {xmlns: Strophe.NS.AUTH})\n .c(\"username\", {}).t(Strophe.getNodeFromJid(this.jid))\n .tree());\n }\n },\n\n /** Function: authenticate\n * Set up authentication\n *\n * Continues the initial connection request by setting up authentication\n * handlers and starting the authentication process.\n *\n * SASL authentication will be attempted if available, otherwise\n * the code will fall back to legacy authentication.\n *\n * Parameters:\n * (Array) matched - Array of SASL mechanisms supported.\n *\n */\n authenticate: function (matched) {\n if (!this._attemptSASLAuth(matched)) {\n this._attemptLegacyAuth();\n }\n },\n\n /** PrivateFunction: _sasl_challenge_cb\n * _Private_ handler for the SASL challenge\n *\n */\n _sasl_challenge_cb: function(elem) {\n var challenge = atob(Strophe.getText(elem));\n var response = this._sasl_mechanism.onChallenge(this, challenge);\n var stanza = $build('response', {\n 'xmlns': Strophe.NS.SASL\n });\n if (response !== \"\") {\n stanza.t(btoa(response));\n }\n this.send(stanza.tree());\n return true;\n },\n\n /** PrivateFunction: _auth1_cb\n * _Private_ handler for legacy authentication.\n *\n * This handler is called in response to the initial \n * for legacy authentication. It builds an authentication and\n * sends it, creating a handler (calling back to _auth2_cb()) to\n * handle the result\n *\n * Parameters:\n * (XMLElement) elem - The stanza that triggered the callback.\n *\n * Returns:\n * false to remove the handler.\n */\n /* jshint unused:false */\n _auth1_cb: function (elem) {\n // build plaintext auth iq\n var iq = $iq({type: \"set\", id: \"_auth_2\"})\n .c('query', {xmlns: Strophe.NS.AUTH})\n .c('username', {}).t(Strophe.getNodeFromJid(this.jid))\n .up()\n .c('password').t(this.pass);\n\n if (!Strophe.getResourceFromJid(this.jid)) {\n // since the user has not supplied a resource, we pick\n // a default one here. unlike other auth methods, the server\n // cannot do this for us.\n this.jid = Strophe.getBareJidFromJid(this.jid) + '/strophe';\n }\n iq.up().c('resource', {}).t(Strophe.getResourceFromJid(this.jid));\n\n this._addSysHandler(this._auth2_cb.bind(this), null,\n null, null, \"_auth_2\");\n this.send(iq.tree());\n return false;\n },\n /* jshint unused:true */\n\n /** PrivateFunction: _sasl_success_cb\n * _Private_ handler for succesful SASL authentication.\n *\n * Parameters:\n * (XMLElement) elem - The matching stanza.\n *\n * Returns:\n * false to remove the handler.\n */\n _sasl_success_cb: function (elem) {\n if (this._sasl_data[\"server-signature\"]) {\n var serverSignature;\n var success = atob(Strophe.getText(elem));\n var attribMatch = /([a-z]+)=([^,]+)(,|$)/;\n var matches = success.match(attribMatch);\n if (matches[1] === \"v\") {\n serverSignature = matches[2];\n }\n\n if (serverSignature !== this._sasl_data[\"server-signature\"]) {\n // remove old handlers\n this.deleteHandler(this._sasl_failure_handler);\n this._sasl_failure_handler = null;\n if (this._sasl_challenge_handler) {\n this.deleteHandler(this._sasl_challenge_handler);\n this._sasl_challenge_handler = null;\n }\n\n this._sasl_data = {};\n return this._sasl_failure_cb(null);\n }\n }\n Strophe.info(\"SASL authentication succeeded.\");\n\n if (this._sasl_mechanism) {\n this._sasl_mechanism.onSuccess();\n }\n\n // remove old handlers\n this.deleteHandler(this._sasl_failure_handler);\n this._sasl_failure_handler = null;\n if (this._sasl_challenge_handler) {\n this.deleteHandler(this._sasl_challenge_handler);\n this._sasl_challenge_handler = null;\n }\n\n var streamfeature_handlers = [];\n var wrapper = function(handlers, elem) {\n while (handlers.length) {\n this.deleteHandler(handlers.pop());\n }\n this._sasl_auth1_cb.bind(this)(elem);\n return false;\n };\n streamfeature_handlers.push(this._addSysHandler(function(elem) {\n wrapper.bind(this)(streamfeature_handlers, elem);\n }.bind(this), null, \"stream:features\", null, null));\n streamfeature_handlers.push(this._addSysHandler(function(elem) {\n wrapper.bind(this)(streamfeature_handlers, elem);\n }.bind(this), Strophe.NS.STREAM, \"features\", null, null));\n\n // we must send an xmpp:restart now\n this._sendRestart();\n\n return false;\n },\n\n /** PrivateFunction: _sasl_auth1_cb\n * _Private_ handler to start stream binding.\n *\n * Parameters:\n * (XMLElement) elem - The matching stanza.\n *\n * Returns:\n * false to remove the handler.\n */\n _sasl_auth1_cb: function (elem) {\n // save stream:features for future usage\n this.features = elem;\n var i, child;\n for (i = 0; i < elem.childNodes.length; i++) {\n child = elem.childNodes[i];\n if (child.nodeName === 'bind') {\n this.do_bind = true;\n }\n\n if (child.nodeName === 'session') {\n this.do_session = true;\n }\n }\n\n if (!this.do_bind) {\n this._changeConnectStatus(Strophe.Status.AUTHFAIL, null);\n return false;\n } else {\n this._addSysHandler(this._sasl_bind_cb.bind(this), null, null,\n null, \"_bind_auth_2\");\n\n var resource = Strophe.getResourceFromJid(this.jid);\n if (resource) {\n this.send($iq({type: \"set\", id: \"_bind_auth_2\"})\n .c('bind', {xmlns: Strophe.NS.BIND})\n .c('resource', {}).t(resource).tree());\n } else {\n this.send($iq({type: \"set\", id: \"_bind_auth_2\"})\n .c('bind', {xmlns: Strophe.NS.BIND})\n .tree());\n }\n }\n return false;\n },\n\n /** PrivateFunction: _sasl_bind_cb\n * _Private_ handler for binding result and session start.\n *\n * Parameters:\n * (XMLElement) elem - The matching stanza.\n *\n * Returns:\n * false to remove the handler.\n */\n _sasl_bind_cb: function (elem) {\n if (elem.getAttribute(\"type\") === \"error\") {\n Strophe.info(\"SASL binding failed.\");\n var conflict = elem.getElementsByTagName(\"conflict\"), condition;\n if (conflict.length > 0) {\n condition = Strophe.ErrorCondition.CONFLICT;\n }\n this._changeConnectStatus(Strophe.Status.AUTHFAIL, condition, elem);\n return false;\n }\n\n // TODO - need to grab errors\n var bind = elem.getElementsByTagName(\"bind\");\n var jidNode;\n if (bind.length > 0) {\n // Grab jid\n jidNode = bind[0].getElementsByTagName(\"jid\");\n if (jidNode.length > 0) {\n this.jid = Strophe.getText(jidNode[0]);\n\n if (this.do_session) {\n this._addSysHandler(this._sasl_session_cb.bind(this),\n null, null, null, \"_session_auth_2\");\n\n this.send($iq({type: \"set\", id: \"_session_auth_2\"})\n .c('session', {xmlns: Strophe.NS.SESSION})\n .tree());\n } else {\n this.authenticated = true;\n this._changeConnectStatus(Strophe.Status.CONNECTED, null);\n }\n }\n } else {\n Strophe.info(\"SASL binding failed.\");\n this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem);\n return false;\n }\n },\n\n /** PrivateFunction: _sasl_session_cb\n * _Private_ handler to finish successful SASL connection.\n *\n * This sets Connection.authenticated to true on success, which\n * starts the processing of user handlers.\n *\n * Parameters:\n * (XMLElement) elem - The matching stanza.\n *\n * Returns:\n * false to remove the handler.\n */\n _sasl_session_cb: function (elem) {\n if (elem.getAttribute(\"type\") === \"result\") {\n this.authenticated = true;\n this._changeConnectStatus(Strophe.Status.CONNECTED, null);\n } else if (elem.getAttribute(\"type\") === \"error\") {\n Strophe.info(\"Session creation failed.\");\n this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem);\n return false;\n }\n return false;\n },\n\n /** PrivateFunction: _sasl_failure_cb\n * _Private_ handler for SASL authentication failure.\n *\n * Parameters:\n * (XMLElement) elem - The matching stanza.\n *\n * Returns:\n * false to remove the handler.\n */\n /* jshint unused:false */\n _sasl_failure_cb: function (elem) {\n // delete unneeded handlers\n if (this._sasl_success_handler) {\n this.deleteHandler(this._sasl_success_handler);\n this._sasl_success_handler = null;\n }\n if (this._sasl_challenge_handler) {\n this.deleteHandler(this._sasl_challenge_handler);\n this._sasl_challenge_handler = null;\n }\n\n if(this._sasl_mechanism)\n this._sasl_mechanism.onFailure();\n this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem);\n return false;\n },\n /* jshint unused:true */\n\n /** PrivateFunction: _auth2_cb\n * _Private_ handler to finish legacy authentication.\n *\n * This handler is called when the result from the jabber:iq:auth\n * stanza is returned.\n *\n * Parameters:\n * (XMLElement) elem - The stanza that triggered the callback.\n *\n * Returns:\n * false to remove the handler.\n */\n _auth2_cb: function (elem) {\n if (elem.getAttribute(\"type\") === \"result\") {\n this.authenticated = true;\n this._changeConnectStatus(Strophe.Status.CONNECTED, null);\n } else if (elem.getAttribute(\"type\") === \"error\") {\n this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem);\n this.disconnect('authentication failed');\n }\n return false;\n },\n\n /** PrivateFunction: _addSysTimedHandler\n * _Private_ function to add a system level timed handler.\n *\n * This function is used to add a Strophe.TimedHandler for the\n * library code. System timed handlers are allowed to run before\n * authentication is complete.\n *\n * Parameters:\n * (Integer) period - The period of the handler.\n * (Function) handler - The callback function.\n */\n _addSysTimedHandler: function (period, handler) {\n var thand = new Strophe.TimedHandler(period, handler);\n thand.user = false;\n this.addTimeds.push(thand);\n return thand;\n },\n\n /** PrivateFunction: _addSysHandler\n * _Private_ function to add a system level stanza handler.\n *\n * This function is used to add a Strophe.Handler for the\n * library code. System stanza handlers are allowed to run before\n * authentication is complete.\n *\n * Parameters:\n * (Function) handler - The callback function.\n * (String) ns - The namespace to match.\n * (String) name - The stanza name to match.\n * (String) type - The stanza type attribute to match.\n * (String) id - The stanza id attribute to match.\n */\n _addSysHandler: function (handler, ns, name, type, id) {\n var hand = new Strophe.Handler(handler, ns, name, type, id);\n hand.user = false;\n this.addHandlers.push(hand);\n return hand;\n },\n\n /** PrivateFunction: _onDisconnectTimeout\n * _Private_ timeout handler for handling non-graceful disconnection.\n *\n * If the graceful disconnect process does not complete within the\n * time allotted, this handler finishes the disconnect anyway.\n *\n * Returns:\n * false to remove the handler.\n */\n _onDisconnectTimeout: function () {\n Strophe.info(\"_onDisconnectTimeout was called\");\n this._changeConnectStatus(Strophe.Status.CONNTIMEOUT, null);\n this._proto._onDisconnectTimeout();\n // actually disconnect\n this._doDisconnect();\n return false;\n },\n\n /** PrivateFunction: _onIdle\n * _Private_ handler to process events during idle cycle.\n *\n * This handler is called every 100ms to fire timed handlers that\n * are ready and keep poll requests going.\n */\n _onIdle: function () {\n var i, thand, since, newList;\n\n // add timed handlers scheduled for addition\n // NOTE: we add before remove in the case a timed handler is\n // added and then deleted before the next _onIdle() call.\n while (this.addTimeds.length > 0) {\n this.timedHandlers.push(this.addTimeds.pop());\n }\n\n // remove timed handlers that have been scheduled for deletion\n while (this.removeTimeds.length > 0) {\n thand = this.removeTimeds.pop();\n i = this.timedHandlers.indexOf(thand);\n if (i >= 0) {\n this.timedHandlers.splice(i, 1);\n }\n }\n\n // call ready timed handlers\n var now = new Date().getTime();\n newList = [];\n for (i = 0; i < this.timedHandlers.length; i++) {\n thand = this.timedHandlers[i];\n if (this.authenticated || !thand.user) {\n since = thand.lastCalled + thand.period;\n if (since - now <= 0) {\n if (thand.run()) {\n newList.push(thand);\n }\n } else {\n newList.push(thand);\n }\n }\n }\n this.timedHandlers = newList;\n\n clearTimeout(this._idleTimeout);\n\n this._proto._onIdle();\n\n // reactivate the timer only if connected\n if (this.connected) {\n // XXX: setTimeout should be called only with function expressions (23974bc1)\n this._idleTimeout = setTimeout(function() {\n this._onIdle();\n }.bind(this), 100);\n }\n }\n};\n\n/** Class: Strophe.SASLMechanism\n *\n * encapsulates SASL authentication mechanisms.\n *\n * User code may override the priority for each mechanism or disable it completely.\n * See for information about changing priority and for informatian on\n * how to disable a mechanism.\n *\n * By default, all mechanisms are enabled and the priorities are\n *\n * OAUTHBEARER - 60\n * SCRAM-SHA1 - 50\n * DIGEST-MD5 - 40\n * PLAIN - 30\n * ANONYMOUS - 20\n * EXTERNAL - 10\n *\n * See: Strophe.Connection.addSupportedSASLMechanisms\n */\n\n/**\n * PrivateConstructor: Strophe.SASLMechanism\n * SASL auth mechanism abstraction.\n *\n * Parameters:\n * (String) name - SASL Mechanism name.\n * (Boolean) isClientFirst - If client should send response first without challenge.\n * (Number) priority - Priority.\n *\n * Returns:\n * A new Strophe.SASLMechanism object.\n */\nStrophe.SASLMechanism = function(name, isClientFirst, priority) {\n /** PrivateVariable: name\n * Mechanism name.\n */\n this.name = name;\n /** PrivateVariable: isClientFirst\n * If client sends response without initial server challenge.\n */\n this.isClientFirst = isClientFirst;\n /** Variable: priority\n * Determines which is chosen for authentication (Higher is better).\n * Users may override this to prioritize mechanisms differently.\n *\n * In the default configuration the priorities are\n *\n * SCRAM-SHA1 - 40\n * DIGEST-MD5 - 30\n * Plain - 20\n *\n * Example: (This will cause Strophe to choose the mechanism that the server sent first)\n *\n * > Strophe.SASLMD5.priority = Strophe.SASLSHA1.priority;\n *\n * See for a list of available mechanisms.\n *\n */\n this.priority = priority;\n};\n\nStrophe.SASLMechanism.prototype = {\n /**\n * Function: test\n * Checks if mechanism able to run.\n * To disable a mechanism, make this return false;\n *\n * To disable plain authentication run\n * > Strophe.SASLPlain.test = function() {\n * > return false;\n * > }\n *\n * See for a list of available mechanisms.\n *\n * Parameters:\n * (Strophe.Connection) connection - Target Connection.\n *\n * Returns:\n * (Boolean) If mechanism was able to run.\n */\n /* jshint unused:false */\n test: function(connection) {\n return true;\n },\n /* jshint unused:true */\n\n /** PrivateFunction: onStart\n * Called before starting mechanism on some connection.\n *\n * Parameters:\n * (Strophe.Connection) connection - Target Connection.\n */\n onStart: function(connection) {\n this._connection = connection;\n },\n\n /** PrivateFunction: onChallenge\n * Called by protocol implementation on incoming challenge. If client is\n * first (isClientFirst === true) challenge will be null on the first call.\n *\n * Parameters:\n * (Strophe.Connection) connection - Target Connection.\n * (String) challenge - current challenge to handle.\n *\n * Returns:\n * (String) Mechanism response.\n */\n /* jshint unused:false */\n onChallenge: function(connection, challenge) {\n throw new Error(\"You should implement challenge handling!\");\n },\n /* jshint unused:true */\n\n /** PrivateFunction: onFailure\n * Protocol informs mechanism implementation about SASL failure.\n */\n onFailure: function() {\n this._connection = null;\n },\n\n /** PrivateFunction: onSuccess\n * Protocol informs mechanism implementation about SASL success.\n */\n onSuccess: function() {\n this._connection = null;\n }\n};\n\n /** Constants: SASL mechanisms\n * Available authentication mechanisms\n *\n * Strophe.SASLAnonymous - SASL ANONYMOUS authentication.\n * Strophe.SASLPlain - SASL PLAIN authentication.\n * Strophe.SASLMD5 - SASL DIGEST-MD5 authentication\n * Strophe.SASLSHA1 - SASL SCRAM-SHA1 authentication\n * Strophe.SASLOAuthBearer - SASL OAuth Bearer authentication\n * Strophe.SASLExternal - SASL EXTERNAL authentication\n * Strophe.SASLXOAuth2 - SASL X-OAuth2 authentication\n */\n\n// Building SASL callbacks\n\n/** PrivateConstructor: SASLAnonymous\n * SASL ANONYMOUS authentication.\n */\nStrophe.SASLAnonymous = function() {};\nStrophe.SASLAnonymous.prototype = new Strophe.SASLMechanism(\"ANONYMOUS\", false, 20);\n\nStrophe.SASLAnonymous.prototype.test = function(connection) {\n return connection.authcid === null;\n};\n\n\n/** PrivateConstructor: SASLPlain\n * SASL PLAIN authentication.\n */\nStrophe.SASLPlain = function() {};\nStrophe.SASLPlain.prototype = new Strophe.SASLMechanism(\"PLAIN\", true, 50);\n\nStrophe.SASLPlain.prototype.test = function(connection) {\n return connection.authcid !== null;\n};\n\nStrophe.SASLPlain.prototype.onChallenge = function(connection) {\n var auth_str = connection.authzid;\n auth_str = auth_str + \"\\u0000\";\n auth_str = auth_str + connection.authcid;\n auth_str = auth_str + \"\\u0000\";\n auth_str = auth_str + connection.pass;\n return utils.utf16to8(auth_str);\n};\n\n\n/** PrivateConstructor: SASLSHA1\n * SASL SCRAM SHA 1 authentication.\n */\nStrophe.SASLSHA1 = function() {};\nStrophe.SASLSHA1.prototype = new Strophe.SASLMechanism(\"SCRAM-SHA-1\", true, 70);\n\nStrophe.SASLSHA1.prototype.test = function(connection) {\n return connection.authcid !== null;\n};\n\nStrophe.SASLSHA1.prototype.onChallenge = function(connection, challenge, test_cnonce) {\n var cnonce = test_cnonce || MD5.hexdigest(Math.random() * 1234567890);\n var auth_str = \"n=\" + utils.utf16to8(connection.authcid);\n auth_str += \",r=\";\n auth_str += cnonce;\n connection._sasl_data.cnonce = cnonce;\n connection._sasl_data[\"client-first-message-bare\"] = auth_str;\n\n auth_str = \"n,,\" + auth_str;\n\n this.onChallenge = function (connection, challenge) {\n var nonce, salt, iter, Hi, U, U_old, i, k, pass;\n var clientKey, serverKey, clientSignature;\n var responseText = \"c=biws,\";\n var authMessage = connection._sasl_data[\"client-first-message-bare\"] + \",\" +\n challenge + \",\";\n var cnonce = connection._sasl_data.cnonce;\n var attribMatch = /([a-z]+)=([^,]+)(,|$)/;\n\n while (challenge.match(attribMatch)) {\n var matches = challenge.match(attribMatch);\n challenge = challenge.replace(matches[0], \"\");\n switch (matches[1]) {\n case \"r\":\n nonce = matches[2];\n break;\n case \"s\":\n salt = matches[2];\n break;\n case \"i\":\n iter = matches[2];\n break;\n }\n }\n\n if (nonce.substr(0, cnonce.length) !== cnonce) {\n connection._sasl_data = {};\n return connection._sasl_failure_cb();\n }\n\n responseText += \"r=\" + nonce;\n authMessage += responseText;\n\n salt = atob(salt);\n salt += \"\\x00\\x00\\x00\\x01\";\n\n pass = utils.utf16to8(connection.pass);\n Hi = U_old = SHA1.core_hmac_sha1(pass, salt);\n for (i = 1; i < iter; i++) {\n U = SHA1.core_hmac_sha1(pass, SHA1.binb2str(U_old));\n for (k = 0; k < 5; k++) {\n Hi[k] ^= U[k];\n }\n U_old = U;\n }\n Hi = SHA1.binb2str(Hi);\n\n clientKey = SHA1.core_hmac_sha1(Hi, \"Client Key\");\n serverKey = SHA1.str_hmac_sha1(Hi, \"Server Key\");\n clientSignature = SHA1.core_hmac_sha1(SHA1.str_sha1(SHA1.binb2str(clientKey)), authMessage);\n connection._sasl_data[\"server-signature\"] = SHA1.b64_hmac_sha1(serverKey, authMessage);\n\n for (k = 0; k < 5; k++) {\n clientKey[k] ^= clientSignature[k];\n }\n\n responseText += \",p=\" + btoa(SHA1.binb2str(clientKey));\n return responseText;\n }.bind(this);\n\n return auth_str;\n};\n\n\n/** PrivateConstructor: SASLMD5\n * SASL DIGEST MD5 authentication.\n */\nStrophe.SASLMD5 = function() {};\nStrophe.SASLMD5.prototype = new Strophe.SASLMechanism(\"DIGEST-MD5\", false, 60);\n\nStrophe.SASLMD5.prototype.test = function(connection) {\n return connection.authcid !== null;\n};\n\n/** PrivateFunction: _quote\n * _Private_ utility function to backslash escape and quote strings.\n *\n * Parameters:\n * (String) str - The string to be quoted.\n *\n * Returns:\n * quoted string\n */\nStrophe.SASLMD5.prototype._quote = function (str) {\n return '\"' + str.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"') + '\"';\n //\" end string workaround for emacs\n};\n\nStrophe.SASLMD5.prototype.onChallenge = function(connection, challenge, test_cnonce) {\n var attribMatch = /([a-z]+)=(\"[^\"]+\"|[^,\"]+)(?:,|$)/;\n var cnonce = test_cnonce || MD5.hexdigest(\"\" + (Math.random() * 1234567890));\n var realm = \"\";\n var host = null;\n var nonce = \"\";\n var qop = \"\";\n var matches;\n\n while (challenge.match(attribMatch)) {\n matches = challenge.match(attribMatch);\n challenge = challenge.replace(matches[0], \"\");\n matches[2] = matches[2].replace(/^\"(.+)\"$/, \"$1\");\n switch (matches[1]) {\n case \"realm\":\n realm = matches[2];\n break;\n case \"nonce\":\n nonce = matches[2];\n break;\n case \"qop\":\n qop = matches[2];\n break;\n case \"host\":\n host = matches[2];\n break;\n }\n }\n\n var digest_uri = connection.servtype + \"/\" + connection.domain;\n if (host !== null) {\n digest_uri = digest_uri + \"/\" + host;\n }\n\n var cred = utils.utf16to8(connection.authcid + \":\" + realm + \":\" + this._connection.pass);\n var A1 = MD5.hash(cred) + \":\" + nonce + \":\" + cnonce;\n var A2 = 'AUTHENTICATE:' + digest_uri;\n\n var responseText = \"\";\n responseText += 'charset=utf-8,';\n responseText += 'username=' + this._quote(utils.utf16to8(connection.authcid)) + ',';\n responseText += 'realm=' + this._quote(realm) + ',';\n responseText += 'nonce=' + this._quote(nonce) + ',';\n responseText += 'nc=00000001,';\n responseText += 'cnonce=' + this._quote(cnonce) + ',';\n responseText += 'digest-uri=' + this._quote(digest_uri) + ',';\n responseText += 'response=' + MD5.hexdigest(MD5.hexdigest(A1) + \":\" +\n nonce + \":00000001:\" +\n cnonce + \":auth:\" +\n MD5.hexdigest(A2)) + \",\";\n responseText += 'qop=auth';\n\n this.onChallenge = function () {\n return \"\";\n };\n return responseText;\n};\n\n\n/** PrivateConstructor: SASLOAuthBearer\n * SASL OAuth Bearer authentication.\n */\nStrophe.SASLOAuthBearer = function() {};\nStrophe.SASLOAuthBearer.prototype = new Strophe.SASLMechanism(\"OAUTHBEARER\", true, 40);\n\nStrophe.SASLOAuthBearer.prototype.test = function(connection) {\n return connection.pass !== null;\n};\n\nStrophe.SASLOAuthBearer.prototype.onChallenge = function(connection) {\n var auth_str = 'n,';\n if (connection.authcid !== null) {\n auth_str = auth_str + 'a=' + connection.authzid;\n }\n auth_str = auth_str + ',';\n auth_str = auth_str + \"\\u0001\";\n auth_str = auth_str + 'auth=Bearer ';\n auth_str = auth_str + connection.pass;\n auth_str = auth_str + \"\\u0001\";\n auth_str = auth_str + \"\\u0001\";\n\n return utils.utf16to8(auth_str);\n};\n\n\n/** PrivateConstructor: SASLExternal\n * SASL EXTERNAL authentication.\n *\n * The EXTERNAL mechanism allows a client to request the server to use\n * credentials established by means external to the mechanism to\n * authenticate the client. The external means may be, for instance,\n * TLS services.\n */\nStrophe.SASLExternal = function() {};\nStrophe.SASLExternal.prototype = new Strophe.SASLMechanism(\"EXTERNAL\", true, 10);\n\nStrophe.SASLExternal.prototype.onChallenge = function(connection) {\n /** According to XEP-178, an authzid SHOULD NOT be presented when the\n * authcid contained or implied in the client certificate is the JID (i.e.\n * authzid) with which the user wants to log in as.\n *\n * To NOT send the authzid, the user should therefore set the authcid equal\n * to the JID when instantiating a new Strophe.Connection object.\n */\n return connection.authcid === connection.authzid ? '' : connection.authzid;\n};\n\n\n/** PrivateConstructor: SASLXOAuth2\n * SASL X-OAuth2 authentication.\n */\nStrophe.SASLXOAuth2 = function () { };\nStrophe.SASLXOAuth2.prototype = new Strophe.SASLMechanism(\"X-OAUTH2\", true, 30);\n\nStrophe.SASLXOAuth2.prototype.test = function (connection) {\n return connection.pass !== null;\n};\n\nStrophe.SASLXOAuth2.prototype.onChallenge = function (connection) {\n var auth_str = '\\u0000';\n if (connection.authcid !== null) {\n auth_str = auth_str + connection.authzid;\n }\n auth_str = auth_str + \"\\u0000\";\n auth_str = auth_str + connection.pass;\n\n return utils.utf16to8(auth_str);\n};\n\n\nreturn {\n 'Strophe': Strophe,\n '$build': $build,\n '$iq': $iq,\n '$msg': $msg,\n '$pres': $pres,\n 'SHA1': SHA1,\n 'MD5': MD5,\n 'b64_hmac_sha1': SHA1.b64_hmac_sha1,\n 'b64_sha1': SHA1.b64_sha1,\n 'str_hmac_sha1': SHA1.str_hmac_sha1,\n 'str_sha1': SHA1.str_sha1\n};\n}));\n\n/*\n This program is distributed under the terms of the MIT license.\n Please see the LICENSE file for details.\n\n Copyright 2006-2008, OGG, LLC\n*/\n\n/* jshint undef: true, unused: true:, noarg: true, latedef: true */\n/* global define, window, setTimeout, clearTimeout, XMLHttpRequest, ActiveXObject, Strophe, $build */\n\n(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n define('strophe-bosh',['strophe-core'], function (core) {\n return factory(\n core.Strophe,\n core.$build\n );\n });\n } else if (typeof exports === 'object') {\n var core = require('./core');\n\n module.exports = factory(core.Strophe, core.$build);\n } else {\n // Browser globals\n return factory(Strophe, $build);\n }\n}(this, function (Strophe, $build) {\n\n/** PrivateClass: Strophe.Request\n * _Private_ helper class that provides a cross implementation abstraction\n * for a BOSH related XMLHttpRequest.\n *\n * The Strophe.Request class is used internally to encapsulate BOSH request\n * information. It is not meant to be used from user's code.\n */\n\n/** PrivateConstructor: Strophe.Request\n * Create and initialize a new Strophe.Request object.\n *\n * Parameters:\n * (XMLElement) elem - The XML data to be sent in the request.\n * (Function) func - The function that will be called when the\n * XMLHttpRequest readyState changes.\n * (Integer) rid - The BOSH rid attribute associated with this request.\n * (Integer) sends - The number of times this same request has been sent.\n */\nStrophe.Request = function (elem, func, rid, sends) {\n this.id = ++Strophe._requestId;\n this.xmlData = elem;\n this.data = Strophe.serialize(elem);\n // save original function in case we need to make a new request\n // from this one.\n this.origFunc = func;\n this.func = func;\n this.rid = rid;\n this.date = NaN;\n this.sends = sends || 0;\n this.abort = false;\n this.dead = null;\n\n this.age = function () {\n if (!this.date) { return 0; }\n var now = new Date();\n return (now - this.date) / 1000;\n };\n this.timeDead = function () {\n if (!this.dead) { return 0; }\n var now = new Date();\n return (now - this.dead) / 1000;\n };\n this.xhr = this._newXHR();\n};\n\nStrophe.Request.prototype = {\n /** PrivateFunction: getResponse\n * Get a response from the underlying XMLHttpRequest.\n *\n * This function attempts to get a response from the request and checks\n * for errors.\n *\n * Throws:\n * \"parsererror\" - A parser error occured.\n * \"badformat\" - The entity has sent XML that cannot be processed.\n *\n * Returns:\n * The DOM element tree of the response.\n */\n getResponse: function () {\n var node = null;\n if (this.xhr.responseXML && this.xhr.responseXML.documentElement) {\n node = this.xhr.responseXML.documentElement;\n if (node.tagName === \"parsererror\") {\n Strophe.error(\"invalid response received\");\n Strophe.error(\"responseText: \" + this.xhr.responseText);\n Strophe.error(\"responseXML: \" +\n Strophe.serialize(this.xhr.responseXML));\n throw \"parsererror\";\n }\n } else if (this.xhr.responseText) {\n // In React Native, we may get responseText but no responseXML. We can try to parse it manually.\n Strophe.debug(\"Got responseText but no responseXML; attempting to parse it with DOMParser...\");\n node = new DOMParser().parseFromString(this.xhr.responseText, 'application/xml').documentElement;\n if (!node) {\n throw new Error('Parsing produced null node');\n } else if (node.querySelector('parsererror')) {\n Strophe.error(\"invalid response received: \" + node.querySelector('parsererror').textContent);\n Strophe.error(\"responseText: \" + this.xhr.responseText);\n throw \"badformat\";\n }\n }\n return node;\n },\n\n /** PrivateFunction: _newXHR\n * _Private_ helper function to create XMLHttpRequests.\n *\n * This function creates XMLHttpRequests across all implementations.\n *\n * Returns:\n * A new XMLHttpRequest.\n */\n _newXHR: function () {\n var xhr = null;\n if (window.XMLHttpRequest) {\n xhr = new XMLHttpRequest();\n if (xhr.overrideMimeType) {\n xhr.overrideMimeType(\"text/xml; charset=utf-8\");\n }\n } else if (window.ActiveXObject) {\n xhr = new ActiveXObject(\"Microsoft.XMLHTTP\");\n }\n // use Function.bind() to prepend ourselves as an argument\n xhr.onreadystatechange = this.func.bind(null, this);\n return xhr;\n }\n};\n\n/** Class: Strophe.Bosh\n * _Private_ helper class that handles BOSH Connections\n *\n * The Strophe.Bosh class is used internally by Strophe.Connection\n * to encapsulate BOSH sessions. It is not meant to be used from user's code.\n */\n\n/** File: bosh.js\n * A JavaScript library to enable BOSH in Strophejs.\n *\n * this library uses Bidirectional-streams Over Synchronous HTTP (BOSH)\n * to emulate a persistent, stateful, two-way connection to an XMPP server.\n * More information on BOSH can be found in XEP 124.\n */\n\n/** PrivateConstructor: Strophe.Bosh\n * Create and initialize a Strophe.Bosh object.\n *\n * Parameters:\n * (Strophe.Connection) connection - The Strophe.Connection that will use BOSH.\n *\n * Returns:\n * A new Strophe.Bosh object.\n */\nStrophe.Bosh = function(connection) {\n this._conn = connection;\n /* request id for body tags */\n this.rid = Math.floor(Math.random() * 4294967295);\n /* The current session ID. */\n this.sid = null;\n\n // default BOSH values\n this.hold = 1;\n this.wait = 60;\n this.window = 5;\n this.errors = 0;\n this.inactivity = null;\n\n this.lastResponseHeaders = null;\n\n this._requests = [];\n};\n\nStrophe.Bosh.prototype = {\n /** Variable: strip\n *\n * BOSH-Connections will have all stanzas wrapped in a tag when\n * passed to or .\n * To strip this tag, User code can set to \"body\":\n *\n * > Strophe.Bosh.prototype.strip = \"body\";\n *\n * This will enable stripping of the body tag in both\n * and .\n */\n strip: null,\n\n /** PrivateFunction: _buildBody\n * _Private_ helper function to generate the wrapper for BOSH.\n *\n * Returns:\n * A Strophe.Builder with a element.\n */\n _buildBody: function () {\n var bodyWrap = $build('body', {\n rid: this.rid++,\n xmlns: Strophe.NS.HTTPBIND\n });\n if (this.sid !== null) {\n bodyWrap.attrs({sid: this.sid});\n }\n if (this._conn.options.keepalive && this._conn._sessionCachingSupported()) {\n this._cacheSession();\n }\n return bodyWrap;\n },\n\n /** PrivateFunction: _reset\n * Reset the connection.\n *\n * This function is called by the reset function of the Strophe Connection\n */\n _reset: function () {\n this.rid = Math.floor(Math.random() * 4294967295);\n this.sid = null;\n this.errors = 0;\n if (this._conn._sessionCachingSupported()) {\n window.sessionStorage.removeItem('strophe-bosh-session');\n }\n\n this._conn.nextValidRid(this.rid);\n },\n\n /** PrivateFunction: _connect\n * _Private_ function that initializes the BOSH connection.\n *\n * Creates and sends the Request that initializes the BOSH connection.\n */\n _connect: function (wait, hold, route) {\n this.wait = wait || this.wait;\n this.hold = hold || this.hold;\n this.errors = 0;\n\n // build the body tag\n var body = this._buildBody().attrs({\n to: this._conn.domain,\n \"xml:lang\": \"en\",\n wait: this.wait,\n hold: this.hold,\n content: \"text/xml; charset=utf-8\",\n ver: \"1.6\",\n \"xmpp:version\": \"1.0\",\n \"xmlns:xmpp\": Strophe.NS.BOSH\n });\n\n if(route){\n body.attrs({\n route: route\n });\n }\n\n var _connect_cb = this._conn._connect_cb;\n\n this._requests.push(\n new Strophe.Request(body.tree(),\n this._onRequestStateChange.bind(\n this, _connect_cb.bind(this._conn)),\n body.tree().getAttribute(\"rid\")));\n this._throttledRequestHandler();\n },\n\n /** PrivateFunction: _attach\n * Attach to an already created and authenticated BOSH session.\n *\n * This function is provided to allow Strophe to attach to BOSH\n * sessions which have been created externally, perhaps by a Web\n * application. This is often used to support auto-login type features\n * without putting user credentials into the page.\n *\n * Parameters:\n * (String) jid - The full JID that is bound by the session.\n * (String) sid - The SID of the BOSH session.\n * (String) rid - The current RID of the BOSH session. This RID\n * will be used by the next request.\n * (Function) callback The connect callback function.\n * (Integer) wait - The optional HTTPBIND wait value. This is the\n * time the server will wait before returning an empty result for\n * a request. The default setting of 60 seconds is recommended.\n * Other settings will require tweaks to the Strophe.TIMEOUT value.\n * (Integer) hold - The optional HTTPBIND hold value. This is the\n * number of connections the server will hold at one time. This\n * should almost always be set to 1 (the default).\n * (Integer) wind - The optional HTTBIND window value. This is the\n * allowed range of request ids that are valid. The default is 5.\n */\n _attach: function (jid, sid, rid, callback, wait, hold, wind) {\n this._conn.jid = jid;\n this.sid = sid;\n this.rid = rid;\n\n this._conn.connect_callback = callback;\n\n this._conn.domain = Strophe.getDomainFromJid(this._conn.jid);\n\n this._conn.authenticated = true;\n this._conn.connected = true;\n\n this.wait = wait || this.wait;\n this.hold = hold || this.hold;\n this.window = wind || this.window;\n\n this._conn._changeConnectStatus(Strophe.Status.ATTACHED, null);\n },\n\n /** PrivateFunction: _restore\n * Attempt to restore a cached BOSH session\n *\n * Parameters:\n * (String) jid - The full JID that is bound by the session.\n * This parameter is optional but recommended, specifically in cases\n * where prebinded BOSH sessions are used where it's important to know\n * that the right session is being restored.\n * (Function) callback The connect callback function.\n * (Integer) wait - The optional HTTPBIND wait value. This is the\n * time the server will wait before returning an empty result for\n * a request. The default setting of 60 seconds is recommended.\n * Other settings will require tweaks to the Strophe.TIMEOUT value.\n * (Integer) hold - The optional HTTPBIND hold value. This is the\n * number of connections the server will hold at one time. This\n * should almost always be set to 1 (the default).\n * (Integer) wind - The optional HTTBIND window value. This is the\n * allowed range of request ids that are valid. The default is 5.\n */\n _restore: function (jid, callback, wait, hold, wind) {\n var session = JSON.parse(window.sessionStorage.getItem('strophe-bosh-session'));\n if (typeof session !== \"undefined\" &&\n session !== null &&\n session.rid &&\n session.sid &&\n session.jid &&\n ( typeof jid === \"undefined\" ||\n jid === null ||\n Strophe.getBareJidFromJid(session.jid) === Strophe.getBareJidFromJid(jid) ||\n // If authcid is null, then it's an anonymous login, so\n // we compare only the domains:\n ((Strophe.getNodeFromJid(jid) === null) && (Strophe.getDomainFromJid(session.jid) === jid))\n )\n ) {\n this._conn.restored = true;\n this._attach(session.jid, session.sid, session.rid, callback, wait, hold, wind);\n } else {\n throw { name: \"StropheSessionError\", message: \"_restore: no restoreable session.\" };\n }\n },\n\n /** PrivateFunction: _cacheSession\n * _Private_ handler for the beforeunload event.\n *\n * This handler is used to process the Bosh-part of the initial request.\n * Parameters:\n * (Strophe.Request) bodyWrap - The received stanza.\n */\n _cacheSession: function () {\n if (this._conn.authenticated) {\n if (this._conn.jid && this.rid && this.sid) {\n window.sessionStorage.setItem('strophe-bosh-session', JSON.stringify({\n 'jid': this._conn.jid,\n 'rid': this.rid,\n 'sid': this.sid\n }));\n }\n } else {\n window.sessionStorage.removeItem('strophe-bosh-session');\n }\n },\n\n /** PrivateFunction: _connect_cb\n * _Private_ handler for initial connection request.\n *\n * This handler is used to process the Bosh-part of the initial request.\n * Parameters:\n * (Strophe.Request) bodyWrap - The received stanza.\n */\n _connect_cb: function (bodyWrap) {\n var typ = bodyWrap.getAttribute(\"type\");\n var cond, conflict;\n if (typ !== null && typ === \"terminate\") {\n // an error occurred\n cond = bodyWrap.getAttribute(\"condition\");\n Strophe.error(\"BOSH-Connection failed: \" + cond);\n conflict = bodyWrap.getElementsByTagName(\"conflict\");\n if (cond !== null) {\n if (cond === \"remote-stream-error\" && conflict.length > 0) {\n cond = \"conflict\";\n }\n this._conn._changeConnectStatus(Strophe.Status.CONNFAIL, cond);\n } else {\n this._conn._changeConnectStatus(Strophe.Status.CONNFAIL, \"unknown\");\n }\n this._conn._doDisconnect(cond);\n return Strophe.Status.CONNFAIL;\n }\n\n // check to make sure we don't overwrite these if _connect_cb is\n // called multiple times in the case of missing stream:features\n if (!this.sid) {\n this.sid = bodyWrap.getAttribute(\"sid\");\n }\n var wind = bodyWrap.getAttribute('requests');\n if (wind) { this.window = parseInt(wind, 10); }\n var hold = bodyWrap.getAttribute('hold');\n if (hold) { this.hold = parseInt(hold, 10); }\n var wait = bodyWrap.getAttribute('wait');\n if (wait) { this.wait = parseInt(wait, 10); }\n var inactivity = bodyWrap.getAttribute('inactivity');\n if (inactivity) { this.inactivity = parseInt(inactivity, 10); }\n },\n\n /** PrivateFunction: _disconnect\n * _Private_ part of Connection.disconnect for Bosh\n *\n * Parameters:\n * (Request) pres - This stanza will be sent before disconnecting.\n */\n _disconnect: function (pres) {\n this._sendTerminate(pres);\n },\n\n /** PrivateFunction: _doDisconnect\n * _Private_ function to disconnect.\n *\n * Resets the SID and RID.\n */\n _doDisconnect: function () {\n this.sid = null;\n this.rid = Math.floor(Math.random() * 4294967295);\n if (this._conn._sessionCachingSupported()) {\n window.sessionStorage.removeItem('strophe-bosh-session');\n }\n\n this._conn.nextValidRid(this.rid);\n },\n\n /** PrivateFunction: _emptyQueue\n * _Private_ function to check if the Request queue is empty.\n *\n * Returns:\n * True, if there are no Requests queued, False otherwise.\n */\n _emptyQueue: function () {\n return this._requests.length === 0;\n },\n\n /** PrivateFunction: _callProtocolErrorHandlers\n * _Private_ function to call error handlers registered for HTTP errors.\n *\n * Parameters:\n * (Strophe.Request) req - The request that is changing readyState.\n */\n _callProtocolErrorHandlers: function (req) {\n var reqStatus = this._getRequestStatus(req),\n err_callback;\n err_callback = this._conn.protocolErrorHandlers.HTTP[reqStatus];\n if (err_callback) {\n err_callback.call(this, reqStatus);\n }\n },\n\n /** PrivateFunction: _hitError\n * _Private_ function to handle the error count.\n *\n * Requests are resent automatically until their error count reaches\n * 5. Each time an error is encountered, this function is called to\n * increment the count and disconnect if the count is too high.\n *\n * Parameters:\n * (Integer) reqStatus - The request status.\n */\n _hitError: function (reqStatus) {\n this.errors++;\n Strophe.warn(\"request errored, status: \" + reqStatus +\n \", number of errors: \" + this.errors);\n if (this.errors > 4) {\n this._conn._onDisconnectTimeout();\n }\n },\n\n /** PrivateFunction: _no_auth_received\n *\n * Called on stream start/restart when no stream:features\n * has been received and sends a blank poll request.\n */\n _no_auth_received: function (callback) {\n Strophe.warn(\"Server did not yet offer a supported authentication \"+\n \"mechanism. Sending a blank poll request.\");\n if (callback) {\n callback = callback.bind(this._conn);\n } else {\n callback = this._conn._connect_cb.bind(this._conn);\n }\n var body = this._buildBody();\n this._requests.push(\n new Strophe.Request(\n body.tree(),\n this._onRequestStateChange.bind(this, callback),\n body.tree().getAttribute(\"rid\")\n )\n );\n this._throttledRequestHandler();\n },\n\n /** PrivateFunction: _onDisconnectTimeout\n * _Private_ timeout handler for handling non-graceful disconnection.\n *\n * Cancels all remaining Requests and clears the queue.\n */\n _onDisconnectTimeout: function () {\n this._abortAllRequests();\n },\n\n /** PrivateFunction: _abortAllRequests\n * _Private_ helper function that makes sure all pending requests are aborted.\n */\n _abortAllRequests: function _abortAllRequests() {\n var req;\n while (this._requests.length > 0) {\n req = this._requests.pop();\n req.abort = true;\n req.xhr.abort();\n // jslint complains, but this is fine. setting to empty func\n // is necessary for IE6\n req.xhr.onreadystatechange = function () {}; // jshint ignore:line\n }\n },\n\n /** PrivateFunction: _onIdle\n * _Private_ handler called by Strophe.Connection._onIdle\n *\n * Sends all queued Requests or polls with empty Request if there are none.\n */\n _onIdle: function () {\n var data = this._conn._data;\n // if no requests are in progress, poll\n if (this._conn.authenticated && this._requests.length === 0 &&\n data.length === 0 && !this._conn.disconnecting) {\n Strophe.info(\"no requests during idle cycle, sending \" +\n \"blank request\");\n data.push(null);\n }\n\n if (this._conn.paused) {\n return;\n }\n\n if (this._requests.length < 2 && data.length > 0) {\n var body = this._buildBody();\n for (var i = 0; i < data.length; i++) {\n if (data[i] !== null) {\n if (data[i] === \"restart\") {\n body.attrs({\n to: this._conn.domain,\n \"xml:lang\": \"en\",\n \"xmpp:restart\": \"true\",\n \"xmlns:xmpp\": Strophe.NS.BOSH\n });\n } else {\n body.cnode(data[i]).up();\n }\n }\n }\n delete this._conn._data;\n this._conn._data = [];\n this._requests.push(\n new Strophe.Request(body.tree(),\n this._onRequestStateChange.bind(\n this, this._conn._dataRecv.bind(this._conn)),\n body.tree().getAttribute(\"rid\")));\n this._throttledRequestHandler();\n }\n\n if (this._requests.length > 0) {\n var time_elapsed = this._requests[0].age();\n if (this._requests[0].dead !== null) {\n if (this._requests[0].timeDead() >\n Math.floor(Strophe.SECONDARY_TIMEOUT * this.wait)) {\n this._throttledRequestHandler();\n }\n }\n\n if (time_elapsed > Math.floor(Strophe.TIMEOUT * this.wait)) {\n Strophe.warn(\"Request \" +\n this._requests[0].id +\n \" timed out, over \" + Math.floor(Strophe.TIMEOUT * this.wait) +\n \" seconds since last activity\");\n this._throttledRequestHandler();\n }\n }\n },\n\n /** PrivateFunction: _getRequestStatus\n *\n * Returns the HTTP status code from a Strophe.Request\n *\n * Parameters:\n * (Strophe.Request) req - The Strophe.Request instance.\n * (Integer) def - The default value that should be returned if no\n * status value was found.\n */\n _getRequestStatus: function (req, def) {\n var reqStatus;\n if (req.xhr.readyState === 4) {\n try {\n reqStatus = req.xhr.status;\n } catch (e) {\n // ignore errors from undefined status attribute. Works\n // around a browser bug\n Strophe.error(\n \"Caught an error while retrieving a request's status, \" +\n \"reqStatus: \" + reqStatus);\n }\n }\n if (typeof(reqStatus) === \"undefined\") {\n reqStatus = typeof def === 'number' ? def : 0;\n }\n return reqStatus;\n },\n\n /** PrivateFunction: _onRequestStateChange\n * _Private_ handler for Strophe.Request state changes.\n *\n * This function is called when the XMLHttpRequest readyState changes.\n * It contains a lot of error handling logic for the many ways that\n * requests can fail, and calls the request callback when requests\n * succeed.\n *\n * Parameters:\n * (Function) func - The handler for the request.\n * (Strophe.Request) req - The request that is changing readyState.\n */\n _onRequestStateChange: function (func, req) {\n Strophe.debug(\"request id \"+req.id+\".\"+req.sends+\n \" state changed to \"+req.xhr.readyState);\n if (req.abort) {\n req.abort = false;\n return;\n }\n if (req.xhr.readyState !== 4) {\n // The request is not yet complete\n return;\n }\n var reqStatus = this._getRequestStatus(req);\n this.lastResponseHeaders = req.xhr.getAllResponseHeaders();\n if (this.disconnecting && reqStatus >= 400) {\n this._hitError(reqStatus);\n this._callProtocolErrorHandlers(req);\n return;\n }\n\n var valid_request = reqStatus > 0 && reqStatus < 500;\n var too_many_retries = req.sends > this._conn.maxRetries;\n if (valid_request || too_many_retries) {\n // remove from internal queue\n this._removeRequest(req);\n Strophe.debug(\"request id \"+req.id+\" should now be removed\");\n }\n\n if (reqStatus === 200) {\n // request succeeded\n var reqIs0 = (this._requests[0] === req);\n var reqIs1 = (this._requests[1] === req);\n // if request 1 finished, or request 0 finished and request\n // 1 is over Strophe.SECONDARY_TIMEOUT seconds old, we need to\n // restart the other - both will be in the first spot, as the\n // completed request has been removed from the queue already\n if (reqIs1 ||\n (reqIs0 && this._requests.length > 0 &&\n this._requests[0].age() > Math.floor(Strophe.SECONDARY_TIMEOUT * this.wait))) {\n this._restartRequest(0);\n }\n this._conn.nextValidRid(Number(req.rid) + 1);\n Strophe.debug(\"request id \"+req.id+\".\"+req.sends+\" got 200\");\n func(req); // call handler\n this.errors = 0;\n } else if (reqStatus === 0 ||\n (reqStatus >= 400 && reqStatus < 600) ||\n reqStatus >= 12000) {\n // request failed\n Strophe.error(\"request id \"+req.id+\".\"+req.sends+\" error \"+reqStatus+\" happened\");\n this._hitError(reqStatus);\n this._callProtocolErrorHandlers(req);\n if (reqStatus >= 400 && reqStatus < 500) {\n this._conn._changeConnectStatus(Strophe.Status.DISCONNECTING, null);\n this._conn._doDisconnect();\n }\n } else {\n Strophe.error(\"request id \"+req.id+\".\"+req.sends+\" error \"+reqStatus+\" happened\");\n }\n\n if (!valid_request && !too_many_retries) {\n this._throttledRequestHandler();\n } else if (too_many_retries && !this._conn.connected) {\n this._conn._changeConnectStatus(Strophe.Status.CONNFAIL, \"giving-up\");\n }\n },\n\n /** PrivateFunction: _processRequest\n * _Private_ function to process a request in the queue.\n *\n * This function takes requests off the queue and sends them and\n * restarts dead requests.\n *\n * Parameters:\n * (Integer) i - The index of the request in the queue.\n */\n _processRequest: function (i) {\n var self = this;\n var req = this._requests[i];\n var reqStatus = this._getRequestStatus(req, -1);\n\n // make sure we limit the number of retries\n if (req.sends > this._conn.maxRetries) {\n this._conn._onDisconnectTimeout();\n return;\n }\n\n var time_elapsed = req.age();\n var primaryTimeout = (!isNaN(time_elapsed) &&\n time_elapsed > Math.floor(Strophe.TIMEOUT * this.wait));\n var secondaryTimeout = (req.dead !== null &&\n req.timeDead() > Math.floor(Strophe.SECONDARY_TIMEOUT * this.wait));\n var requestCompletedWithServerError = (req.xhr.readyState === 4 &&\n (reqStatus < 1 || reqStatus >= 500));\n if (primaryTimeout || secondaryTimeout ||\n requestCompletedWithServerError) {\n if (secondaryTimeout) {\n Strophe.error(\"Request \" + this._requests[i].id +\n \" timed out (secondary), restarting\");\n }\n req.abort = true;\n req.xhr.abort();\n // setting to null fails on IE6, so set to empty function\n req.xhr.onreadystatechange = function () {};\n this._requests[i] = new Strophe.Request(req.xmlData,\n req.origFunc,\n req.rid,\n req.sends);\n req = this._requests[i];\n }\n\n if (req.xhr.readyState === 0) {\n Strophe.debug(\"request id \"+req.id+\".\"+req.sends+\" posting\");\n\n try {\n var contentType = this._conn.options.contentType || \"text/xml; charset=utf-8\";\n req.xhr.open(\"POST\", this._conn.service, this._conn.options.sync ? false : true);\n if (typeof req.xhr.setRequestHeader !== 'undefined') {\n // IE9 doesn't have setRequestHeader\n req.xhr.setRequestHeader(\"Content-Type\", contentType);\n }\n if (this._conn.options.withCredentials) {\n req.xhr.withCredentials = true;\n }\n } catch (e2) {\n Strophe.error(\"XHR open failed: \" + e2.toString());\n if (!this._conn.connected) {\n this._conn._changeConnectStatus(\n Strophe.Status.CONNFAIL, \"bad-service\");\n }\n this._conn.disconnect();\n return;\n }\n\n // Fires the XHR request -- may be invoked immediately\n // or on a gradually expanding retry window for reconnects\n var sendFunc = function () {\n req.date = new Date();\n if (self._conn.options.customHeaders){\n var headers = self._conn.options.customHeaders;\n for (var header in headers) {\n if (headers.hasOwnProperty(header)) {\n req.xhr.setRequestHeader(header, headers[header]);\n }\n }\n }\n req.xhr.send(req.data);\n };\n\n // Implement progressive backoff for reconnects --\n // First retry (send === 1) should also be instantaneous\n if (req.sends > 1) {\n // Using a cube of the retry number creates a nicely\n // expanding retry window\n var backoff = Math.min(Math.floor(Strophe.TIMEOUT * this.wait),\n Math.pow(req.sends, 3)) * 1000;\n setTimeout(function() {\n // XXX: setTimeout should be called only with function expressions (23974bc1)\n sendFunc();\n }, backoff);\n } else {\n sendFunc();\n }\n\n req.sends++;\n\n if (this._conn.xmlOutput !== Strophe.Connection.prototype.xmlOutput) {\n if (req.xmlData.nodeName === this.strip && req.xmlData.childNodes.length) {\n this._conn.xmlOutput(req.xmlData.childNodes[0]);\n } else {\n this._conn.xmlOutput(req.xmlData);\n }\n }\n if (this._conn.rawOutput !== Strophe.Connection.prototype.rawOutput) {\n this._conn.rawOutput(req.data);\n }\n } else {\n Strophe.debug(\"_processRequest: \" +\n (i === 0 ? \"first\" : \"second\") +\n \" request has readyState of \" +\n req.xhr.readyState);\n }\n },\n\n /** PrivateFunction: _removeRequest\n * _Private_ function to remove a request from the queue.\n *\n * Parameters:\n * (Strophe.Request) req - The request to remove.\n */\n _removeRequest: function (req) {\n Strophe.debug(\"removing request\");\n var i;\n for (i = this._requests.length - 1; i >= 0; i--) {\n if (req === this._requests[i]) {\n this._requests.splice(i, 1);\n }\n }\n // IE6 fails on setting to null, so set to empty function\n req.xhr.onreadystatechange = function () {};\n this._throttledRequestHandler();\n },\n\n /** PrivateFunction: _restartRequest\n * _Private_ function to restart a request that is presumed dead.\n *\n * Parameters:\n * (Integer) i - The index of the request in the queue.\n */\n _restartRequest: function (i) {\n var req = this._requests[i];\n if (req.dead === null) {\n req.dead = new Date();\n }\n\n this._processRequest(i);\n },\n\n /** PrivateFunction: _reqToData\n * _Private_ function to get a stanza out of a request.\n *\n * Tries to extract a stanza out of a Request Object.\n * When this fails the current connection will be disconnected.\n *\n * Parameters:\n * (Object) req - The Request.\n *\n * Returns:\n * The stanza that was passed.\n */\n _reqToData: function (req) {\n try {\n return req.getResponse();\n } catch (e) {\n if (e !== \"parsererror\") { throw e; }\n this._conn.disconnect(\"strophe-parsererror\");\n }\n },\n\n /** PrivateFunction: _sendTerminate\n * _Private_ function to send initial disconnect sequence.\n *\n * This is the first step in a graceful disconnect. It sends\n * the BOSH server a terminate body and includes an unavailable\n * presence if authentication has completed.\n */\n _sendTerminate: function (pres) {\n Strophe.info(\"_sendTerminate was called\");\n var body = this._buildBody().attrs({type: \"terminate\"});\n if (pres) {\n body.cnode(pres.tree());\n }\n var req = new Strophe.Request(\n body.tree(),\n this._onRequestStateChange.bind(\n this, this._conn._dataRecv.bind(this._conn)),\n body.tree().getAttribute(\"rid\")\n );\n this._requests.push(req);\n this._throttledRequestHandler();\n },\n\n /** PrivateFunction: _send\n * _Private_ part of the Connection.send function for BOSH\n *\n * Just triggers the RequestHandler to send the messages that are in the queue\n */\n _send: function () {\n clearTimeout(this._conn._idleTimeout);\n this._throttledRequestHandler();\n\n // XXX: setTimeout should be called only with function expressions (23974bc1)\n this._conn._idleTimeout = setTimeout(function() {\n this._onIdle();\n }.bind(this._conn), 100);\n },\n\n /** PrivateFunction: _sendRestart\n *\n * Send an xmpp:restart stanza.\n */\n _sendRestart: function () {\n this._throttledRequestHandler();\n clearTimeout(this._conn._idleTimeout);\n },\n\n /** PrivateFunction: _throttledRequestHandler\n * _Private_ function to throttle requests to the connection window.\n *\n * This function makes sure we don't send requests so fast that the\n * request ids overflow the connection window in the case that one\n * request died.\n */\n _throttledRequestHandler: function () {\n if (!this._requests) {\n Strophe.debug(\"_throttledRequestHandler called with \" +\n \"undefined requests\");\n } else {\n Strophe.debug(\"_throttledRequestHandler called with \" +\n this._requests.length + \" requests\");\n }\n\n if (!this._requests || this._requests.length === 0) {\n return;\n }\n\n if (this._requests.length > 0) {\n this._processRequest(0);\n }\n\n if (this._requests.length > 1 &&\n Math.abs(this._requests[0].rid -\n this._requests[1].rid) < this.window) {\n this._processRequest(1);\n }\n }\n};\nreturn Strophe;\n}));\n\n/*\n This program is distributed under the terms of the MIT license.\n Please see the LICENSE file for details.\n\n Copyright 2006-2008, OGG, LLC\n*/\n\n/* jshint undef: true, unused: true:, noarg: true, latedef: true */\n/* global define, window, clearTimeout, WebSocket, DOMParser, Strophe, $build */\n\n(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n define('strophe-websocket',['strophe-core'], function (core) {\n return factory(\n core.Strophe,\n core.$build\n );\n });\n } else if (typeof exports === 'object') {\n var core = require('./core');\n\n module.exports = factory(core.Strophe, core.$build);\n } else {\n // Browser globals\n return factory(Strophe, $build);\n }\n}(this, function (Strophe, $build) {\n\n/** Class: Strophe.WebSocket\n * _Private_ helper class that handles WebSocket Connections\n *\n * The Strophe.WebSocket class is used internally by Strophe.Connection\n * to encapsulate WebSocket sessions. It is not meant to be used from user's code.\n */\n\n/** File: websocket.js\n * A JavaScript library to enable XMPP over Websocket in Strophejs.\n *\n * This file implements XMPP over WebSockets for Strophejs.\n * If a Connection is established with a Websocket url (ws://...)\n * Strophe will use WebSockets.\n * For more information on XMPP-over-WebSocket see RFC 7395:\n * http://tools.ietf.org/html/rfc7395\n *\n * WebSocket support implemented by Andreas Guth (andreas.guth@rwth-aachen.de)\n */\n\n/** PrivateConstructor: Strophe.Websocket\n * Create and initialize a Strophe.WebSocket object.\n * Currently only sets the connection Object.\n *\n * Parameters:\n * (Strophe.Connection) connection - The Strophe.Connection that will use WebSockets.\n *\n * Returns:\n * A new Strophe.WebSocket object.\n */\nStrophe.Websocket = function(connection) {\n this._conn = connection;\n this.strip = \"wrapper\";\n\n var service = connection.service;\n if (service.indexOf(\"ws:\") !== 0 && service.indexOf(\"wss:\") !== 0) {\n // If the service is not an absolute URL, assume it is a path and put the absolute\n // URL together from options, current URL and the path.\n var new_service = \"\";\n\n if (connection.options.protocol === \"ws\" && window.location.protocol !== \"https:\") {\n new_service += \"ws\";\n } else {\n new_service += \"wss\";\n }\n\n new_service += \"://\" + window.location.host;\n\n if (service.indexOf(\"/\") !== 0) {\n new_service += window.location.pathname + service;\n } else {\n new_service += service;\n }\n\n connection.service = new_service;\n }\n};\n\nStrophe.Websocket.prototype = {\n /** PrivateFunction: _buildStream\n * _Private_ helper function to generate the start tag for WebSockets\n *\n * Returns:\n * A Strophe.Builder with a element.\n */\n _buildStream: function () {\n return $build(\"open\", {\n \"xmlns\": Strophe.NS.FRAMING,\n \"to\": this._conn.domain,\n \"version\": '1.0'\n });\n },\n\n /** PrivateFunction: _check_streamerror\n * _Private_ checks a message for stream:error\n *\n * Parameters:\n * (Strophe.Request) bodyWrap - The received stanza.\n * connectstatus - The ConnectStatus that will be set on error.\n * Returns:\n * true if there was a streamerror, false otherwise.\n */\n _check_streamerror: function (bodyWrap, connectstatus) {\n var errors;\n if (bodyWrap.getElementsByTagNameNS) {\n errors = bodyWrap.getElementsByTagNameNS(Strophe.NS.STREAM, \"error\");\n } else {\n errors = bodyWrap.getElementsByTagName(\"stream:error\");\n }\n if (errors.length === 0) {\n return false;\n }\n var error = errors[0];\n\n var condition = \"\";\n var text = \"\";\n\n var ns = \"urn:ietf:params:xml:ns:xmpp-streams\";\n for (var i = 0; i < error.childNodes.length; i++) {\n var e = error.childNodes[i];\n if (e.getAttribute(\"xmlns\") !== ns) {\n break;\n } if (e.nodeName === \"text\") {\n text = e.textContent;\n } else {\n condition = e.nodeName;\n }\n }\n\n var errorString = \"WebSocket stream error: \";\n\n if (condition) {\n errorString += condition;\n } else {\n errorString += \"unknown\";\n }\n\n if (text) {\n errorString += \" - \" + text;\n }\n\n Strophe.error(errorString);\n\n // close the connection on stream_error\n this._conn._changeConnectStatus(connectstatus, condition);\n this._conn._doDisconnect();\n return true;\n },\n\n /** PrivateFunction: _reset\n * Reset the connection.\n *\n * This function is called by the reset function of the Strophe Connection.\n * Is not needed by WebSockets.\n */\n _reset: function () {\n return;\n },\n\n /** PrivateFunction: _connect\n * _Private_ function called by Strophe.Connection.connect\n *\n * Creates a WebSocket for a connection and assigns Callbacks to it.\n * Does nothing if there already is a WebSocket.\n */\n _connect: function () {\n // Ensure that there is no open WebSocket from a previous Connection.\n this._closeSocket();\n\n // Create the new WobSocket\n this.socket = new WebSocket(this._conn.service, \"xmpp\");\n this.socket.onopen = this._onOpen.bind(this);\n this.socket.onerror = this._onError.bind(this);\n this.socket.onclose = this._onClose.bind(this);\n this.socket.onmessage = this._connect_cb_wrapper.bind(this);\n },\n\n /** PrivateFunction: _connect_cb\n * _Private_ function called by Strophe.Connection._connect_cb\n *\n * checks for stream:error\n *\n * Parameters:\n * (Strophe.Request) bodyWrap - The received stanza.\n */\n _connect_cb: function(bodyWrap) {\n var error = this._check_streamerror(bodyWrap, Strophe.Status.CONNFAIL);\n if (error) {\n return Strophe.Status.CONNFAIL;\n }\n },\n\n /** PrivateFunction: _handleStreamStart\n * _Private_ function that checks the opening tag for errors.\n *\n * Disconnects if there is an error and returns false, true otherwise.\n *\n * Parameters:\n * (Node) message - Stanza containing the tag.\n */\n _handleStreamStart: function(message) {\n var error = false;\n\n // Check for errors in the tag\n var ns = message.getAttribute(\"xmlns\");\n if (typeof ns !== \"string\") {\n error = \"Missing xmlns in \";\n } else if (ns !== Strophe.NS.FRAMING) {\n error = \"Wrong xmlns in : \" + ns;\n }\n\n var ver = message.getAttribute(\"version\");\n if (typeof ver !== \"string\") {\n error = \"Missing version in \";\n } else if (ver !== \"1.0\") {\n error = \"Wrong version in : \" + ver;\n }\n\n if (error) {\n this._conn._changeConnectStatus(Strophe.Status.CONNFAIL, error);\n this._conn._doDisconnect();\n return false;\n }\n\n return true;\n },\n\n /** PrivateFunction: _connect_cb_wrapper\n * _Private_ function that handles the first connection messages.\n *\n * On receiving an opening stream tag this callback replaces itself with the real\n * message handler. On receiving a stream error the connection is terminated.\n */\n _connect_cb_wrapper: function(message) {\n if (message.data.indexOf(\"\\s*)*/, \"\");\n if (data === '') return;\n\n var streamStart = new DOMParser().parseFromString(data, \"text/xml\").documentElement;\n this._conn.xmlInput(streamStart);\n this._conn.rawInput(message.data);\n\n //_handleStreamSteart will check for XML errors and disconnect on error\n if (this._handleStreamStart(streamStart)) {\n //_connect_cb will check for stream:error and disconnect on error\n this._connect_cb(streamStart);\n }\n } else if (message.data.indexOf(\"\n // Parse the raw string to an XML element\n var parsedMessage = new DOMParser().parseFromString(message.data, \"text/xml\").documentElement;\n // Report this input to the raw and xml handlers\n this._conn.xmlInput(parsedMessage);\n this._conn.rawInput(message.data);\n var see_uri = parsedMessage.getAttribute(\"see-other-uri\");\n if (see_uri) {\n var service = this._conn.service;\n // Valid scenarios: WSS->WSS, WS->ANY\n var isSecureRedirect = (service.indexOf(\"wss:\") >= 0 && see_uri.indexOf(\"wss:\") >= 0) || (service.indexOf(\"ws:\") >= 0);\n if(isSecureRedirect) {\n this._conn._changeConnectStatus(\n Strophe.Status.REDIRECT,\n \"Received see-other-uri, resetting connection\"\n );\n this._conn.reset();\n this._conn.service = see_uri;\n this._connect();\n }\n } else {\n this._conn._changeConnectStatus(\n Strophe.Status.CONNFAIL,\n \"Received closing stream\"\n );\n this._conn._doDisconnect();\n }\n } else {\n var string = this._streamWrap(message.data);\n var elem = new DOMParser().parseFromString(string, \"text/xml\").documentElement;\n this.socket.onmessage = this._onMessage.bind(this);\n this._conn._connect_cb(elem, null, message.data);\n }\n },\n\n /** PrivateFunction: _disconnect\n * _Private_ function called by Strophe.Connection.disconnect\n *\n * Disconnects and sends a last stanza if one is given\n *\n * Parameters:\n * (Request) pres - This stanza will be sent before disconnecting.\n */\n _disconnect: function (pres) {\n if (this.socket && this.socket.readyState !== WebSocket.CLOSED) {\n if (pres) {\n this._conn.send(pres);\n }\n var close = $build(\"close\", { \"xmlns\": Strophe.NS.FRAMING });\n this._conn.xmlOutput(close.tree());\n var closeString = Strophe.serialize(close);\n this._conn.rawOutput(closeString);\n try {\n this.socket.send(closeString);\n } catch (e) {\n Strophe.info(\"Couldn't send tag.\");\n }\n }\n this._conn._doDisconnect();\n },\n\n /** PrivateFunction: _doDisconnect\n * _Private_ function to disconnect.\n *\n * Just closes the Socket for WebSockets\n */\n _doDisconnect: function () {\n Strophe.info(\"WebSockets _doDisconnect was called\");\n this._closeSocket();\n },\n\n /** PrivateFunction _streamWrap\n * _Private_ helper function to wrap a stanza in a tag.\n * This is used so Strophe can process stanzas from WebSockets like BOSH\n */\n _streamWrap: function (stanza) {\n return \"\" + stanza + '';\n },\n\n\n /** PrivateFunction: _closeSocket\n * _Private_ function to close the WebSocket.\n *\n * Closes the socket if it is still open and deletes it\n */\n _closeSocket: function () {\n if (this.socket) { try {\n this.socket.onerror = null;\n this.socket.close();\n } catch (e) {} }\n this.socket = null;\n },\n\n /** PrivateFunction: _emptyQueue\n * _Private_ function to check if the message queue is empty.\n *\n * Returns:\n * True, because WebSocket messages are send immediately after queueing.\n */\n _emptyQueue: function () {\n return true;\n },\n\n /** PrivateFunction: _onClose\n * _Private_ function to handle websockets closing.\n *\n * Nothing to do here for WebSockets\n */\n _onClose: function(e) {\n if(this._conn.connected && !this._conn.disconnecting) {\n Strophe.error(\"Websocket closed unexpectedly\");\n this._conn._doDisconnect();\n } else if (e && e.code === 1006 && !this._conn.connected && this.socket) {\n // in case the onError callback was not called (Safari 10 does not\n // call onerror when the initial connection fails) we need to\n // dispatch a CONNFAIL status update to be consistent with the\n // behavior on other browsers.\n Strophe.error(\"Websocket closed unexcectedly\");\n this._conn._changeConnectStatus(\n Strophe.Status.CONNFAIL,\n \"The WebSocket connection could not be established or was disconnected.\"\n );\n this._conn._doDisconnect();\n } else {\n Strophe.info(\"Websocket closed\");\n }\n },\n\n /** PrivateFunction: _no_auth_received\n *\n * Called on stream start/restart when no stream:features\n * has been received.\n */\n _no_auth_received: function (callback) {\n Strophe.error(\"Server did not offer a supported authentication mechanism\");\n this._changeConnectStatus(\n Strophe.Status.CONNFAIL,\n Strophe.ErrorCondition.NO_AUTH_MECH\n );\n if (callback) {\n callback.call(this._conn);\n }\n this._conn._doDisconnect();\n },\n\n /** PrivateFunction: _onDisconnectTimeout\n * _Private_ timeout handler for handling non-graceful disconnection.\n *\n * This does nothing for WebSockets\n */\n _onDisconnectTimeout: function () {},\n\n /** PrivateFunction: _abortAllRequests\n * _Private_ helper function that makes sure all pending requests are aborted.\n */\n _abortAllRequests: function () {},\n\n /** PrivateFunction: _onError\n * _Private_ function to handle websockets errors.\n *\n * Parameters:\n * (Object) error - The websocket error.\n */\n _onError: function(error) {\n Strophe.error(\"Websocket error \" + error);\n this._conn._changeConnectStatus(\n Strophe.Status.CONNFAIL,\n \"The WebSocket connection could not be established or was disconnected.\"\n );\n this._disconnect();\n },\n\n /** PrivateFunction: _onIdle\n * _Private_ function called by Strophe.Connection._onIdle\n *\n * sends all queued stanzas\n */\n _onIdle: function () {\n var data = this._conn._data;\n if (data.length > 0 && !this._conn.paused) {\n for (var i = 0; i < data.length; i++) {\n if (data[i] !== null) {\n var stanza, rawStanza;\n if (data[i] === \"restart\") {\n stanza = this._buildStream().tree();\n } else {\n stanza = data[i];\n }\n rawStanza = Strophe.serialize(stanza);\n this._conn.xmlOutput(stanza);\n this._conn.rawOutput(rawStanza);\n this.socket.send(rawStanza);\n }\n }\n this._conn._data = [];\n }\n },\n\n /** PrivateFunction: _onMessage\n * _Private_ function to handle websockets messages.\n *\n * This function parses each of the messages as if they are full documents.\n * [TODO : We may actually want to use a SAX Push parser].\n *\n * Since all XMPP traffic starts with\n * \n *\n * The first stanza will always fail to be parsed.\n *\n * Additionally, the seconds stanza will always be with\n * the stream NS defined in the previous stanza, so we need to 'force'\n * the inclusion of the NS in this stanza.\n *\n * Parameters:\n * (string) message - The websocket message.\n */\n _onMessage: function(message) {\n var elem, data;\n // check for closing stream\n var close = '';\n if (message.data === close) {\n this._conn.rawInput(close);\n this._conn.xmlInput(message);\n if (!this._conn.disconnecting) {\n this._conn._doDisconnect();\n }\n return;\n } else if (message.data.search(\" tag before we close the connection\n return;\n }\n this._conn._dataRecv(elem, message.data);\n },\n\n /** PrivateFunction: _onOpen\n * _Private_ function to handle websockets connection setup.\n *\n * The opening stream tag is sent here.\n */\n _onOpen: function() {\n Strophe.info(\"Websocket open\");\n var start = this._buildStream();\n this._conn.xmlOutput(start.tree());\n\n var startString = Strophe.serialize(start);\n this._conn.rawOutput(startString);\n this.socket.send(startString);\n },\n\n /** PrivateFunction: _reqToData\n * _Private_ function to get a stanza out of a request.\n *\n * WebSockets don't use requests, so the passed argument is just returned.\n *\n * Parameters:\n * (Object) stanza - The stanza.\n *\n * Returns:\n * The stanza that was passed.\n */\n _reqToData: function (stanza) {\n return stanza;\n },\n\n /** PrivateFunction: _send\n * _Private_ part of the Connection.send function for WebSocket\n *\n * Just flushes the messages that are in the queue\n */\n _send: function () {\n this._conn.flush();\n },\n\n /** PrivateFunction: _sendRestart\n *\n * Send an xmpp:restart stanza.\n */\n _sendRestart: function () {\n clearTimeout(this._conn._idleTimeout);\n this._conn._onIdle.bind(this._conn)();\n }\n};\nreturn Strophe;\n}));\n\n(function(root){\n if(typeof define === 'function' && define.amd){\n define('strophe',[\n \"strophe-core\",\n \"strophe-bosh\",\n \"strophe-websocket\"\n ], function (wrapper) {\n return wrapper;\n });\n } else if (typeof exports === 'object') {\n var core = require('./core');\n require('./bosh');\n require('./websocket');\n module.exports = core;\n }\n})(this);\n\n\nrequire([\"strophe-polyfill\"]);\n/* jshint ignore:start */\n //The modules for your project will be inlined above\n //this snippet. Ask almond to synchronously require the\n //module value for 'main' here and return it as the\n //value to use for the public API for the built file.\n return require('strophe');\n}));\n/* jshint ignore:end */\n","/**\n * The events for the conference.\n */\n\n/**\n * Indicates that authentication status changed.\n */\nexport const AUTH_STATUS_CHANGED = 'conference.auth_status_changed';\n\n/**\n * A participant avatar has changed.\n */\nexport const AVATAR_CHANGED = 'conference.avatarChanged';\n\n/**\n * Fired just before the statistics module is disposed and it's the last chance\n * to submit some logs to the statistics service (ex. CallStats if enabled),\n * before it's disconnected.\n */\nexport const BEFORE_STATISTICS_DISPOSED = 'conference.beforeStatisticsDisposed';\n\n/**\n * Indicates that an error occured.\n */\nexport const CONFERENCE_ERROR = 'conference.error';\n\n/**\n * Indicates that conference failed.\n */\nexport const CONFERENCE_FAILED = 'conference.failed';\n\n/**\n * Indicates that conference has been joined. The event does NOT provide any\n * parameters to its listeners.\n */\nexport const CONFERENCE_JOINED = 'conference.joined';\n\n/**\n * Indicates that conference has been left.\n */\nexport const CONFERENCE_LEFT = 'conference.left';\n\n/**\n * Indicates that the connection to the conference has been established\n * XXX This is currently fired whenVthe *ICE* connection enters 'connected'\n * state for the first time.\n */\nexport const CONNECTION_ESTABLISHED = 'conference.connectionEstablished';\n\n/**\n * Indicates that the connection to the conference has been interrupted for some\n * reason.\n * XXX This is currently fired when the *ICE* connection is interrupted.\n */\nexport const CONNECTION_INTERRUPTED = 'conference.connectionInterrupted';\n\n/**\n * Indicates that the connection to the conference has been restored.\n * XXX This is currently fired when the *ICE* connection is restored.\n */\nexport const CONNECTION_RESTORED = 'conference.connectionRestored';\n\n/**\n * A connection to the video bridge's data channel has been established.\n */\nexport const DATA_CHANNEL_OPENED = 'conference.dataChannelOpened';\n\n/**\n * A user has changed it display name\n */\nexport const DISPLAY_NAME_CHANGED = 'conference.displayNameChanged';\n\n/**\n * The dominant speaker was changed.\n */\nexport const DOMINANT_SPEAKER_CHANGED = 'conference.dominantSpeaker';\n\n/**\n * Indicates that DTMF support changed.\n */\nexport const DTMF_SUPPORT_CHANGED = 'conference.dtmfSupportChanged';\n\n/**\n * Indicates that a message from another participant is received on data\n * channel.\n */\nexport const ENDPOINT_MESSAGE_RECEIVED = 'conference.endpoint_message_received';\n\n/**\n * NOTE This is lib-jitsi-meet internal event and can be removed at any time !\n *\n * Event emitted when conference transits, between one to one and multiparty JVB\n * conference. If the conference switches to P2P it's neither one to one nor\n * a multiparty JVB conference, but P2P (the status argument of this event will\n * be false).\n *\n * The first argument is a boolean which carries the previous value and\n * the seconds argument is a boolean with the new status. The event is emitted\n * only if the previous and the new values are different.\n *\n * @type {string}\n */\nexport const JVB121_STATUS = 'conference.jvb121Status';\n\n/**\n * You are kicked from the conference.\n * @param {JitsiParticipant} the participant that initiated the kick.\n */\nexport const KICKED = 'conference.kicked';\n\n/**\n * Participant was kicked from the conference.\n * @param {JitsiParticipant} the participant that initiated the kick.\n * @param {JitsiParticipant} the participant that was kicked.\n */\nexport const PARTICIPANT_KICKED = 'conference.participant_kicked';\n\n/**\n * The Last N set is changed.\n *\n * @param {Array|null} leavingEndpointIds the ids of all the endpoints\n * which are leaving Last N\n * @param {Array|null} enteringEndpointIds the ids of all the endpoints\n * which are entering Last N\n */\nexport const LAST_N_ENDPOINTS_CHANGED = 'conference.lastNEndpointsChanged';\n\n/**\n * Indicates that the room has been locked or unlocked.\n */\nexport const LOCK_STATE_CHANGED = 'conference.lock_state_changed';\n\n/**\n * Indicates that the region of the media server (jitsi-videobridge) that we\n * are connected to changed (or was initially set).\n * @type {string} the region.\n */\nexport const SERVER_REGION_CHANGED = 'conference.server_region_changed';\n\n/**\n * New text message was received.\n */\nexport const MESSAGE_RECEIVED = 'conference.messageReceived';\n\n/**\n * New private text message was received.\n */\nexport const PRIVATE_MESSAGE_RECEIVED = 'conference.privateMessageReceived';\n\n/**\n * Event fired when JVB sends notification about interrupted/restored user's\n * ICE connection status or we detect local problem with the video track.\n * First argument is the ID of the participant and\n * the seconds is a string indicating if the connection is currently\n * - active - the connection is active\n * - inactive - the connection is inactive, was intentionally interrupted by\n * the bridge\n * - interrupted - a network problem occurred\n * - restoring - the connection was inactive and is restoring now\n *\n * The current status value can be obtained by calling\n * JitsiParticipant.getConnectionStatus().\n */\nexport const PARTICIPANT_CONN_STATUS_CHANGED\n = 'conference.participant_conn_status_changed';\n\n/**\n * Indicates that the features of the participant has been changed.\n */\nexport const PARTCIPANT_FEATURES_CHANGED\n = 'conference.partcipant_features_changed';\n\n/**\n * Indicates that a the value of a specific property of a specific participant\n * has changed.\n */\nexport const PARTICIPANT_PROPERTY_CHANGED\n = 'conference.participant_property_changed';\n\n/**\n * Indicates that the conference has switched between JVB and P2P connections.\n * The first argument of this event is a boolean which when set to\n * true means that the conference is running on the P2P connection.\n */\nexport const P2P_STATUS = 'conference.p2pStatus';\n\n/**\n * Indicates that phone number changed.\n */\nexport const PHONE_NUMBER_CHANGED = 'conference.phoneNumberChanged';\n\n/**\n * The conference properties changed.\n * @type {string}\n */\nexport const PROPERTIES_CHANGED = 'conference.propertiesChanged';\n\n/**\n * Indicates that recording state changed.\n */\nexport const RECORDER_STATE_CHANGED = 'conference.recorderStateChanged';\n\n/**\n * Indicates that video SIP GW state changed.\n * @param {VideoSIPGWConstants} status.\n */\nexport const VIDEO_SIP_GW_AVAILABILITY_CHANGED\n = 'conference.videoSIPGWAvailabilityChanged';\n\n/**\n * Indicates that video SIP GW Session state changed.\n * @param {options} event - {\n * {string} address,\n * {VideoSIPGWConstants} oldState,\n * {VideoSIPGWConstants} newState,\n * {string} displayName}\n * }.\n */\nexport const VIDEO_SIP_GW_SESSION_STATE_CHANGED\n = 'conference.videoSIPGWSessionStateChanged';\n\n/**\n * Indicates that start muted settings changed.\n */\nexport const START_MUTED_POLICY_CHANGED\n = 'conference.start_muted_policy_changed';\n\n/**\n * Indicates that the local user has started muted.\n */\nexport const STARTED_MUTED = 'conference.started_muted';\n\n/**\n * Indicates that subject of the conference has changed.\n */\nexport const SUBJECT_CHANGED = 'conference.subjectChanged';\n\n/**\n * Indicates that DTMF support changed.\n */\nexport const SUSPEND_DETECTED = 'conference.suspendDetected';\n\n/**\n * Event indicates that local user is talking while he muted himself\n */\nexport const TALK_WHILE_MUTED = 'conference.talk_while_muted';\n\n/**\n * A new media track was added to the conference. The event provides the\n * following parameters to its listeners:\n *\n * @param {JitsiTrack} track the added JitsiTrack\n */\nexport const TRACK_ADDED = 'conference.trackAdded';\n\n/**\n * Audio levels of a media track ( attached to the conference) was changed.\n */\nexport const TRACK_AUDIO_LEVEL_CHANGED = 'conference.audioLevelsChanged';\n\n/**\n * A media track ( attached to the conference) mute status was changed.\n * @param {JitsiParticipant|null} the participant that initiated the mute\n * if it is a remote mute.\n */\nexport const TRACK_MUTE_CHANGED = 'conference.trackMuteChanged';\n\n/**\n * The media track was removed from the conference. The event provides the\n * following parameters to its listeners:\n *\n * @param {JitsiTrack} track the removed JitsiTrack\n */\nexport const TRACK_REMOVED = 'conference.trackRemoved';\n\n/**\n * Notifies for transcription status changes. The event provides the\n * following parameters to its listeners:\n *\n * @param {String} status - The new status.\n */\nexport const TRANSCRIPTION_STATUS_CHANGED\n = 'conference.transcriptionStatusChanged';\n\n\n/**\n * A new user joined the conference.\n */\nexport const USER_JOINED = 'conference.userJoined';\n\n/**\n * A user has left the conference.\n */\nexport const USER_LEFT = 'conference.userLeft';\n\n/**\n * User role changed.\n */\nexport const USER_ROLE_CHANGED = 'conference.roleChanged';\n\n/**\n * User status changed.\n */\nexport const USER_STATUS_CHANGED = 'conference.statusChanged';\n\n/**\n * Event indicates that the bot participant type changed.\n */\nexport const BOT_TYPE_CHANGED = 'conference.bot_type_changed';\n","import BrowserCapabilities from './BrowserCapabilities';\n\nexport default new BrowserCapabilities();\n","/* Copyright @ 2015-present 8x8, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nvar Logger = require(\"./Logger\");\nvar LogCollector = require(\"./LogCollector\");\n\n/**\n * Definition of the log method\n * @name log_method\n * @function\n * @param {...*} log_args the arguments to be logged\n */\n/**\n * The logger's transport type definition.\n *\n * @typedef {object} LoggerTransport\n *\n * @property {log_method} trace method called to log on {@link Logger.levels.TRACE} logging level\n * @property {log_method} debug method called to log on {@link Logger.levels.DEBUG} logging level\n * @property {log_method} info method called to log on {@link Logger.levels.INFO} logging level\n * @property {log_method} log method called to log on {@link Logger.levels.LOG} logging level\n * @property {log_method} warn method called to log on {@link Logger.levels.WARN} logging level\n * @property {log_method} error method called to log on {@link Logger.levels.ERROR} logging level\n */\n\n/**\n * Map with the created loggers with ID.\n */\nvar idLoggers = {};\n\n/**\n * Array with the loggers without id.\n */\nvar loggers = [];\n\n/**\n * Log level for the lbrary.\n */\nvar curLevel = Logger.levels.TRACE;\n\n\nmodule.exports = {\n /**\n * Adds given {@link LoggerTransport} instance to the list of global\n * transports which means that it'll be used by all {@link Logger}s\n * @param {LoggerTransport} transport\n */\n addGlobalTransport: function(transport) {\n Logger.addGlobalTransport(transport);\n },\n /**\n * Removes given {@link LoggerTransport} instance from the list of global\n * transports\n * @param {LoggerTransport} transport\n */\n removeGlobalTransport: function(transport) {\n Logger.removeGlobalTransport(transport);\n },\n /**\n * Sets global options which will be used by all loggers. Changing these\n * works even after other loggers are created.\n */\n setGlobalOptions: function(options) {\n Logger.setGlobalOptions(options);\n },\n /**\n * Creates new logger.\n * @arguments the same as Logger constructor\n */\n getLogger: function(id, transports, options) {\n var logger = new Logger(curLevel, id, transports, options);\n if(id) {\n idLoggers[id] = idLoggers[id] || [];\n idLoggers[id].push(logger);\n } else {\n loggers.push(logger);\n }\n return logger;\n },\n /**\n * Changes the log level for the existing loggers by id.\n * @param level the new log level.\n * @param id if specified the level will be changed only for loggers with the\n * same id. Otherwise the operation will affect all loggers that don't\n * have id.\n */\n setLogLevelById: function(level, id) {\n var l = id? (idLoggers[id] || []) : loggers;\n for(var i = 0; i < l.length; i++) {\n l[i].setLevel(level);\n }\n },\n /**\n * Changes the log level for all existing loggers.\n * @param level the new log level.\n */\n setLogLevel: function (level) {\n curLevel = level;\n var i = 0;\n for(; i < loggers.length; i++) {\n loggers[i].setLevel(level);\n }\n\n for(var id in idLoggers) {\n var l = idLoggers[id] || [];\n for(i = 0; i < l.length; i++) {\n l[i].setLevel(level);\n }\n }\n },\n /**\n * The supported log levels.\n */\n levels: Logger.levels,\n /**\n * Exports the LogCollector.\n */\n LogCollector: LogCollector\n};\n","import EventEmitter from 'events';\n\nimport { FEEDBACK } from '../../service/statistics/AnalyticsEvents';\nimport analytics from './AnalyticsAdapter';\nimport CallStats from './CallStats';\nimport LocalStats from './LocalStatsCollector';\nimport RTPStats from './RTPStatsCollector';\n\nimport browser from '../browser';\nimport ScriptUtil from '../util/ScriptUtil';\nimport JitsiTrackError from '../../JitsiTrackError';\nimport * as StatisticsEvents from '../../service/statistics/Events';\n\nconst logger = require('jitsi-meet-logger').getLogger(__filename);\n\n/**\n * Stores all active {@link Statistics} instances.\n * @type {Set}\n */\nlet _instances;\n\n/**\n * True if callstats API is loaded\n */\nlet isCallstatsLoaded = false;\n\n/**\n * Since callstats.io is a third party, we cannot guarantee the quality of their\n * service. More specifically, their server may take noticeably long time to\n * respond. Consequently, it is in our best interest (in the sense that the\n * intergration of callstats.io is pretty important to us but not enough to\n * allow it to prevent people from joining a conference) to (1) start\n * downloading their API as soon as possible and (2) do the downloading\n * asynchronously.\n *\n * @param {StatisticsOptions} options - Options to use for downloading and\n * initializing callstats backend.\n */\nfunction loadCallStatsAPI(options) {\n if (!isCallstatsLoaded) {\n ScriptUtil.loadScript(\n options.customScriptUrl\n || 'https://api.callstats.io/static/callstats-ws.min.js',\n /* async */ true,\n /* prepend */ true,\n /* relativeURL */ undefined,\n /* loadCallback */ () => _initCallStatsBackend(options)\n );\n isCallstatsLoaded = true;\n }\n}\n\n/**\n * Initializes Callstats backend.\n *\n * @param {StatisticsOptions} options - The options to use for initializing\n * callstats backend.\n * @private\n */\nfunction _initCallStatsBackend(options) {\n if (CallStats.isBackendInitialized()) {\n return;\n }\n\n if (!CallStats.initBackend({\n callStatsID: options.callStatsID,\n callStatsSecret: options.callStatsSecret,\n userName: options.userName,\n aliasName: options.aliasName,\n applicationName: options.applicationName,\n getWiFiStatsMethod: options.getWiFiStatsMethod,\n confID: options.confID\n })) {\n logger.error('CallStats Backend initialization failed bad');\n }\n}\n\n/**\n * callstats strips any additional fields from Error except for \"name\", \"stack\",\n * \"message\" and \"constraintName\". So we need to bundle additional information\n * from JitsiTrackError into error passed to callstats to preserve valuable\n * information about error.\n * @param {JitsiTrackError} error\n */\nfunction formatJitsiTrackErrorForCallStats(error) {\n const err = new Error();\n\n // Just copy original stack from error\n err.stack = error.stack;\n\n // Combine name from error's name plus (possibly) name of original GUM error\n err.name = (error.name || 'Unknown error') + (error.gum && error.gum.error\n && error.gum.error.name ? ` - ${error.gum.error.name}` : '');\n\n // Put all constraints into this field. For constraint failed errors we will\n // still know which exactly constraint failed as it will be a part of\n // message.\n err.constraintName = error.gum && error.gum.constraints\n ? JSON.stringify(error.gum.constraints) : '';\n\n // Just copy error's message.\n err.message = error.message;\n\n return err;\n}\n\n/**\n * Init statistic options\n * @param options\n */\nStatistics.init = function(options) {\n Statistics.audioLevelsEnabled = !options.disableAudioLevels;\n\n if (typeof options.audioLevelsInterval === 'number') {\n Statistics.audioLevelsInterval = options.audioLevelsInterval;\n }\n\n Statistics.disableThirdPartyRequests = options.disableThirdPartyRequests;\n};\n\n/**\n * The options to configure Statistics.\n * @typedef {Object} StatisticsOptions\n * @property {string} applicationName - The application name to pass to\n * callstats.\n * @property {string} aliasName - The alias name to use when initializing callstats.\n * @property {string} userName - The user name to use when initializing callstats.\n * @property {string} callStatsConfIDNamespace - A namespace to prepend the\n * callstats conference ID with.\n * @property {string} confID - The callstats conference ID to use.\n * @property {string} callStatsID - Callstats credentials - the id.\n * @property {string} callStatsSecret - Callstats credentials - the secret.\n * @property {string} customScriptUrl - A custom lib url to use when downloading\n * callstats library.\n * @property {string} roomName - The room name we are currently in.\n */\n/**\n *\n * @param xmpp\n * @param {StatisticsOptions} options - The options to use creating the\n * Statistics.\n */\nexport default function Statistics(xmpp, options) {\n /**\n * {@link RTPStats} mapped by {@link TraceablePeerConnection.id} which\n * collect RTP statistics for each peerconnection.\n * @type {Map}\n */\n this.callsStatsInstances = new Map();\n\n Statistics.instances.add(this);\n}\nStatistics.audioLevelsEnabled = false;\nStatistics.audioLevelsInterval = 200;\nStatistics.disableThirdPartyRequests = false;\nStatistics.analytics = analytics;\n\nObject.defineProperty(Statistics, 'instances', {\n /**\n * Returns the Set holding all active {@link Statistics} instances. Lazily\n * initializes the Set to allow any Set polyfills to be applied.\n * @type {Set}\n */\n get() {\n if (!_instances) {\n _instances = new Set();\n }\n\n return _instances;\n }\n});\n\n/**\n * Starts collecting RTP stats for given peerconnection.\n * @param {TraceablePeerConnection} peerconnection\n */\nStatistics.prototype.startRemoteStats = function(peerconnection) {\n this.stopRemoteStats(peerconnection);\n\n try {\n const rtpStats\n = new RTPStats(\n peerconnection,\n Statistics.audioLevelsInterval,\n 2000,\n this.eventEmitter);\n\n rtpStats.start(Statistics.audioLevelsEnabled);\n this.rtpStatsMap.set(peerconnection.id, rtpStats);\n } catch (e) {\n logger.error(`Failed to start collecting remote statistics: ${e}`);\n }\n};\n\nStatistics.localStats = [];\n\nStatistics.startLocalStats = function(stream, callback) {\n if (!Statistics.audioLevelsEnabled) {\n return;\n }\n const localStats = new LocalStats(stream, Statistics.audioLevelsInterval,\n callback);\n\n this.localStats.push(localStats);\n localStats.start();\n};\n\nStatistics.prototype.addAudioLevelListener = function(listener) {\n if (!Statistics.audioLevelsEnabled) {\n return;\n }\n this.eventEmitter.on(StatisticsEvents.AUDIO_LEVEL, listener);\n};\n\nStatistics.prototype.removeAudioLevelListener = function(listener) {\n if (!Statistics.audioLevelsEnabled) {\n return;\n }\n this.eventEmitter.removeListener(StatisticsEvents.AUDIO_LEVEL, listener);\n};\n\nStatistics.prototype.addBeforeDisposedListener = function(listener) {\n this.eventEmitter.on(StatisticsEvents.BEFORE_DISPOSED, listener);\n};\n\nStatistics.prototype.removeBeforeDisposedListener = function(listener) {\n this.eventEmitter.removeListener(\n StatisticsEvents.BEFORE_DISPOSED, listener);\n};\n\nStatistics.prototype.addConnectionStatsListener = function(listener) {\n this.eventEmitter.on(StatisticsEvents.CONNECTION_STATS, listener);\n};\n\nStatistics.prototype.removeConnectionStatsListener = function(listener) {\n this.eventEmitter.removeListener(\n StatisticsEvents.CONNECTION_STATS,\n listener);\n};\n\nStatistics.prototype.addByteSentStatsListener = function(listener) {\n this.eventEmitter.on(StatisticsEvents.BYTE_SENT_STATS, listener);\n};\n\nStatistics.prototype.removeByteSentStatsListener = function(listener) {\n this.eventEmitter.removeListener(StatisticsEvents.BYTE_SENT_STATS,\n listener);\n};\n\nStatistics.prototype.dispose = function() {\n try {\n // NOTE Before reading this please see the comment in stopCallStats...\n //\n // Here we prevent from emitting the event twice in case it will be\n // triggered from stopCallStats.\n // If the event is triggered from here it means that the logs will not\n // be submitted anyway (because there is no CallStats instance), but\n // we're doing that for the sake of some kind of consistency.\n if (!this.callsStatsInstances.size) {\n this.eventEmitter.emit(StatisticsEvents.BEFORE_DISPOSED);\n }\n for (const callStats of this.callsStatsInstances.values()) {\n this.stopCallStats(callStats.tpc);\n }\n for (const tpcId of this.rtpStatsMap.keys()) {\n this._stopRemoteStats(tpcId);\n }\n if (this.eventEmitter) {\n this.eventEmitter.removeAllListeners();\n }\n } finally {\n Statistics.instances.delete(this);\n }\n};\n\nStatistics.stopLocalStats = function(stream) {\n if (!Statistics.audioLevelsEnabled) {\n return;\n }\n\n for (let i = 0; i < Statistics.localStats.length; i++) {\n if (Statistics.localStats[i].stream === stream) {\n const localStats = Statistics.localStats.splice(i, 1);\n\n localStats[0].stop();\n break;\n }\n }\n};\n\n/**\n * Stops remote RTP stats for given peerconnection ID.\n * @param {string} tpcId {@link TraceablePeerConnection.id}\n * @private\n */\nStatistics.prototype._stopRemoteStats = function(tpcId) {\n const rtpStats = this.rtpStatsMap.get(tpcId);\n\n if (rtpStats) {\n rtpStats.stop();\n this.rtpStatsMap.delete(tpcId);\n }\n};\n\n/**\n * Stops collecting RTP stats for given peerconnection\n * @param {TraceablePeerConnection} tpc\n */\nStatistics.prototype.stopRemoteStats = function(tpc) {\n this._stopRemoteStats(tpc.id);\n};\n\n// CALSTATS METHODS\n\n/**\n * Initializes the callstats.io API.\n * @param {TraceablePeerConnection} tpc the {@link TraceablePeerConnection}\n * instance for which CalStats will be started.\n * @param {string} remoteUserID\n */\nStatistics.prototype.startCallStats = function(tpc, remoteUserID) {\n if (!this.callStatsIntegrationEnabled) {\n return;\n } else if (this.callsStatsInstances.has(tpc.id)) {\n logger.error('CallStats instance for ${tpc} exists already');\n\n return;\n }\n\n logger.info(`Starting CallStats for ${tpc}...`);\n\n const newInstance\n = new CallStats(\n tpc,\n {\n confID: this._getCallStatsConfID(),\n remoteUserID\n });\n\n this.callsStatsInstances.set(tpc.id, newInstance);\n};\n\n/**\n * Obtains the list of *all* {@link CallStats} instances collected from every\n * valid {@link Statistics} instance.\n * @return {Set}\n * @private\n */\nStatistics._getAllCallStatsInstances = function() {\n const csInstances = new Set();\n\n for (const statistics of Statistics.instances) {\n for (const cs of statistics.callsStatsInstances.values()) {\n csInstances.add(cs);\n }\n }\n\n return csInstances;\n};\n\n/**\n * Constructs the CallStats conference ID based on the options currently\n * configured in this instance.\n * @return {string}\n * @private\n */\nStatistics.prototype._getCallStatsConfID = function() {\n // The conference ID is case sensitive!!!\n return this.options.callStatsConfIDNamespace\n ? `${this.options.callStatsConfIDNamespace}/${this.options.roomName}`\n : this.options.roomName;\n};\n\n/**\n * Removes the callstats.io instances.\n */\nStatistics.prototype.stopCallStats = function(tpc) {\n const callStatsInstance = this.callsStatsInstances.get(tpc.id);\n\n if (callStatsInstance) {\n // FIXME the original purpose of adding BEFORE_DISPOSED event was to be\n // able to submit the last log batch from jitsi-meet to CallStats. After\n // recent changes we dispose the CallStats earlier\n // (before Statistics.dispose), so we need to emit this event here to\n // give this last chance for final log batch submission.\n //\n // Eventually there should be a separate module called \"log storage\"\n // which should emit proper events when it's underlying\n // CallStats instance is going away.\n if (this.callsStatsInstances.size === 1) {\n this.eventEmitter.emit(StatisticsEvents.BEFORE_DISPOSED);\n }\n this.callsStatsInstances.delete(tpc.id);\n\n // The fabric needs to be terminated when being stopped\n callStatsInstance.sendTerminateEvent();\n }\n};\n\n/**\n * Returns true if the callstats integration is enabled, otherwise returns\n * false.\n *\n * @returns true if the callstats integration is enabled, otherwise returns\n * false.\n */\nStatistics.prototype.isCallstatsEnabled = function() {\n return this.callStatsIntegrationEnabled;\n};\n\n/**\n * Logs either resume or hold event for the given peer connection.\n * @param {TraceablePeerConnection} tpc the connection for which event will be\n * reported\n * @param {boolean} isResume true for resume or false for hold\n */\nStatistics.prototype.sendConnectionResumeOrHoldEvent = function(tpc, isResume) {\n const instance = this.callsStatsInstances.get(tpc.id);\n\n if (instance) {\n instance.sendResumeOrHoldEvent(isResume);\n }\n};\n\n/**\n * Notifies CallStats and analytics (if present) for ice connection failed\n * @param {TraceablePeerConnection} tpc connection on which failure occurred.\n */\nStatistics.prototype.sendIceConnectionFailedEvent = function(tpc) {\n const instance = this.callsStatsInstances.get(tpc.id);\n\n if (instance) {\n instance.sendIceConnectionFailedEvent();\n }\n};\n\n/**\n * Notifies CallStats for mute events\n * @param {TraceablePeerConnection} tpc connection on which failure occurred.\n * @param {boolean} muted true for muted and false for not muted\n * @param {String} type \"audio\"/\"video\"\n */\nStatistics.prototype.sendMuteEvent = function(tpc, muted, type) {\n const instance = tpc && this.callsStatsInstances.get(tpc.id);\n\n CallStats.sendMuteEvent(muted, type, instance);\n};\n\n/**\n * Notifies CallStats for screen sharing events\n * @param start {boolean} true for starting screen sharing and\n * false for not stopping\n * @param {string|null} ssrc - optional ssrc value, used only when\n * starting screen sharing.\n */\nStatistics.prototype.sendScreenSharingEvent\n = function(start, ssrc) {\n for (const cs of this.callsStatsInstances.values()) {\n cs.sendScreenSharingEvent(start, ssrc);\n }\n };\n\n/**\n * Notifies the statistics module that we are now the dominant speaker of the\n * conference.\n * @param {String} roomJid - The room jid where the speaker event occurred.\n */\nStatistics.prototype.sendDominantSpeakerEvent = function(roomJid) {\n for (const cs of this.callsStatsInstances.values()) {\n cs.sendDominantSpeakerEvent();\n }\n\n // xmpp send dominant speaker event\n this.xmpp.sendDominantSpeakerEvent(roomJid);\n};\n\n/**\n * Notifies about active device.\n * @param {{deviceList: {String:String}}} devicesData - list of devices with\n * their data\n */\nStatistics.sendActiveDeviceListEvent = function(devicesData) {\n const globalSet = Statistics._getAllCallStatsInstances();\n\n if (globalSet.size) {\n for (const cs of globalSet) {\n CallStats.sendActiveDeviceListEvent(devicesData, cs);\n }\n } else {\n CallStats.sendActiveDeviceListEvent(devicesData, null);\n }\n};\n\n/* eslint-disable max-params */\n\n/**\n * Lets the underlying statistics module know where is given SSRC rendered by\n * providing renderer tag ID.\n * @param {TraceablePeerConnection} tpc the connection to which the stream\n * belongs to\n * @param {number} ssrc the SSRC of the stream\n * @param {boolean} isLocal\n * @param {string} userId\n * @param {string} usageLabel meaningful usage label of this stream like\n * 'microphone', 'camera' or 'screen'.\n * @param {string} containerId the id of media 'audio' or 'video' tag which\n * renders the stream.\n */\nStatistics.prototype.associateStreamWithVideoTag = function(\n tpc,\n ssrc,\n isLocal,\n userId,\n usageLabel,\n containerId) {\n const instance = this.callsStatsInstances.get(tpc.id);\n\n if (instance) {\n instance.associateStreamWithVideoTag(\n ssrc,\n isLocal,\n userId,\n usageLabel,\n containerId);\n }\n};\n\n/* eslint-enable max-params */\n\n/**\n * Notifies CallStats that getUserMedia failed.\n *\n * @param {Error} e error to send\n */\nStatistics.sendGetUserMediaFailed = function(e) {\n const error\n = e instanceof JitsiTrackError\n ? formatJitsiTrackErrorForCallStats(e) : e;\n const globalSet = Statistics._getAllCallStatsInstances();\n\n if (globalSet.size) {\n for (const cs of globalSet) {\n CallStats.sendGetUserMediaFailed(error, cs);\n }\n } else {\n CallStats.sendGetUserMediaFailed(error, null);\n }\n};\n\n/**\n * Notifies CallStats that peer connection failed to create offer.\n *\n * @param {Error} e error to send\n * @param {TraceablePeerConnection} tpc connection on which failure occurred.\n */\nStatistics.prototype.sendCreateOfferFailed = function(e, tpc) {\n const instance = this.callsStatsInstances.get(tpc.id);\n\n if (instance) {\n instance.sendCreateOfferFailed(e);\n }\n};\n\n/**\n * Notifies CallStats that peer connection failed to create answer.\n *\n * @param {Error} e error to send\n * @param {TraceablePeerConnection} tpc connection on which failure occured.\n */\nStatistics.prototype.sendCreateAnswerFailed = function(e, tpc) {\n const instance = this.callsStatsInstances.get(tpc.id);\n\n if (instance) {\n instance.sendCreateAnswerFailed(e);\n }\n};\n\n/**\n * Notifies CallStats that peer connection failed to set local description.\n *\n * @param {Error} e error to send\n * @param {TraceablePeerConnection} tpc connection on which failure occurred.\n */\nStatistics.prototype.sendSetLocalDescFailed = function(e, tpc) {\n const instance = this.callsStatsInstances.get(tpc.id);\n\n if (instance) {\n instance.sendSetLocalDescFailed(e);\n }\n};\n\n/**\n * Notifies CallStats that peer connection failed to set remote description.\n *\n * @param {Error} e error to send\n * @param {TraceablePeerConnection} tpc connection on which failure occurred.\n */\nStatistics.prototype.sendSetRemoteDescFailed = function(e, tpc) {\n const instance = this.callsStatsInstances.get(tpc.id);\n\n if (instance) {\n instance.sendSetRemoteDescFailed(e);\n }\n};\n\n/**\n * Notifies CallStats that peer connection failed to add ICE candidate.\n *\n * @param {Error} e error to send\n * @param {TraceablePeerConnection} tpc connection on which failure occurred.\n */\nStatistics.prototype.sendAddIceCandidateFailed = function(e, tpc) {\n const instance = this.callsStatsInstances.get(tpc.id);\n\n if (instance) {\n instance.sendAddIceCandidateFailed(e);\n }\n};\n\n/**\n * Adds to CallStats an application log.\n *\n * @param {String} m a log message to send or an {Error} object to be reported\n */\nStatistics.sendLog = function(m) {\n const globalSubSet = new Set();\n\n // FIXME we don't want to duplicate logs over P2P instance, but\n // here we should go over instances and call this method for each\n // unique conference ID rather than selecting the first one.\n // We don't have such use case though, so leaving as is for now.\n for (const stats of Statistics.instances) {\n if (stats.callsStatsInstances.size) {\n globalSubSet.add(stats.callsStatsInstances.values().next().value);\n }\n }\n\n if (globalSubSet.size) {\n for (const csPerStats of globalSubSet) {\n CallStats.sendApplicationLog(m, csPerStats);\n }\n } else {\n CallStats.sendApplicationLog(m, null);\n }\n};\n\n/**\n * Sends the given feedback through CallStats.\n *\n * @param overall an integer between 1 and 5 indicating the user's rating.\n * @param comment the comment from the user.\n * @returns {Promise} Resolves when callstats feedback has been submitted\n * successfully.\n */\nStatistics.prototype.sendFeedback = function(overall, comment) {\n // Statistics.analytics.sendEvent is currently fire and forget, without\n // confirmation of successful send.\n Statistics.analytics.sendEvent(\n FEEDBACK,\n {\n rating: overall,\n comment\n });\n\n return CallStats.sendFeedback(this._getCallStatsConfID(), overall, comment);\n};\n\nStatistics.LOCAL_JID = require('../../service/statistics/constants').LOCAL_JID;\n\n/**\n * Reports global error to CallStats.\n *\n * @param {Error} error\n */\nStatistics.reportGlobalError = function(error) {\n if (error instanceof JitsiTrackError && error.gum) {\n Statistics.sendGetUserMediaFailed(error);\n } else {\n Statistics.sendLog(error);\n }\n};\n\n/**\n * Sends event to analytics and logs a message to the logger/console. Console\n * messages might also be logged to callstats automatically.\n *\n * @param {string | Object} event the event name, or an object which\n * represents the entire event.\n * @param {Object} properties properties to attach to the event (if an event\n * name as opposed to an event object is provided).\n */\nStatistics.sendAnalyticsAndLog = function(event, properties = {}) {\n if (!event) {\n logger.warn('No event or event name given.');\n\n return;\n }\n\n let eventToLog;\n\n // Also support an API with a single object as an event.\n if (typeof event === 'object') {\n eventToLog = event;\n } else {\n eventToLog = {\n name: event,\n properties\n };\n }\n\n logger.log(JSON.stringify(eventToLog));\n\n // We do this last, because it may modify the object which is passed.\n this.analytics.sendEvent(event, properties);\n};\n\n/**\n * Sends event to analytics.\n *\n * @param {string | Object} eventName the event name, or an object which\n * represents the entire event.\n * @param {Object} properties properties to attach to the event\n */\nStatistics.sendAnalytics = function(eventName, properties = {}) {\n this.analytics.sendEvent(eventName, properties);\n};\n","import { getLogger } from 'jitsi-meet-logger';\nconst logger = getLogger(__filename);\n\nimport RandomUtil from '../util/RandomUtil';\nimport browser from '../browser';\n\nconst SDPUtil = {\n filterSpecialChars(text) {\n // XXX Neither one of the falsy values (e.g. null, undefined, false,\n // \"\", etc.) \"contain\" special chars.\n // eslint-disable-next-line no-useless-escape\n return text ? text.replace(/[\\\\\\/\\{,\\}\\+]/g, '') : text;\n },\n iceparams(mediadesc, sessiondesc) {\n let data = null;\n let pwd, ufrag;\n\n if ((ufrag = SDPUtil.findLine(mediadesc, 'a=ice-ufrag:', sessiondesc))\n && (pwd\n = SDPUtil.findLine(\n mediadesc,\n 'a=ice-pwd:',\n sessiondesc))) {\n data = {\n ufrag: SDPUtil.parseICEUfrag(ufrag),\n pwd: SDPUtil.parseICEPwd(pwd)\n };\n }\n\n return data;\n },\n parseICEUfrag(line) {\n return line.substring(12);\n },\n buildICEUfrag(frag) {\n return `a=ice-ufrag:${frag}`;\n },\n parseICEPwd(line) {\n return line.substring(10);\n },\n buildICEPwd(pwd) {\n return `a=ice-pwd:${pwd}`;\n },\n parseMID(line) {\n return line.substring(6);\n },\n parseMLine(line) {\n const data = {};\n const parts = line.substring(2).split(' ');\n\n data.media = parts.shift();\n data.port = parts.shift();\n data.proto = parts.shift();\n if (parts[parts.length - 1] === '') { // trailing whitespace\n parts.pop();\n }\n data.fmt = parts;\n\n return data;\n },\n buildMLine(mline) {\n return (\n `m=${mline.media} ${mline.port} ${mline.proto} ${\n mline.fmt.join(' ')}`);\n },\n parseRTPMap(line) {\n const data = {};\n let parts = line.substring(9).split(' ');\n\n data.id = parts.shift();\n parts = parts[0].split('/');\n data.name = parts.shift();\n data.clockrate = parts.shift();\n data.channels = parts.length ? parts.shift() : '1';\n\n return data;\n },\n\n /**\n * Parses SDP line \"a=sctpmap:...\" and extracts SCTP port from it.\n * @param line eg. \"a=sctpmap:5000 webrtc-datachannel\"\n * @returns [SCTP port number, protocol, streams]\n */\n parseSCTPMap(line) {\n const parts = line.substring(10).split(' ');\n const sctpPort = parts[0];\n const protocol = parts[1];\n\n // Stream count is optional\n const streamCount = parts.length > 2 ? parts[2] : null;\n\n\n return [ sctpPort, protocol, streamCount ];// SCTP port\n },\n buildRTPMap(el) {\n let line\n = `a=rtpmap:${el.getAttribute('id')} ${el.getAttribute('name')}/${\n el.getAttribute('clockrate')}`;\n\n if (el.getAttribute('channels')\n && el.getAttribute('channels') !== '1') {\n line += `/${el.getAttribute('channels')}`;\n }\n\n return line;\n },\n parseCrypto(line) {\n const data = {};\n const parts = line.substring(9).split(' ');\n\n data.tag = parts.shift();\n data['crypto-suite'] = parts.shift();\n data['key-params'] = parts.shift();\n if (parts.length) {\n data['session-params'] = parts.join(' ');\n }\n\n return data;\n },\n parseFingerprint(line) { // RFC 4572\n const data = {};\n const parts = line.substring(14).split(' ');\n\n data.hash = parts.shift();\n data.fingerprint = parts.shift();\n\n // TODO assert that fingerprint satisfies 2UHEX *(\":\" 2UHEX) ?\n return data;\n },\n parseFmtp(line) {\n const data = [];\n let parts = line.split(' ');\n\n parts.shift();\n parts = parts.join(' ').split(';');\n for (let i = 0; i < parts.length; i++) {\n let key = parts[i].split('=')[0];\n\n while (key.length && key[0] === ' ') {\n key = key.substring(1);\n }\n const value = parts[i].split('=')[1];\n\n if (key && value) {\n data.push({ name: key,\n value });\n } else if (key) {\n // rfc 4733 (DTMF) style stuff\n data.push({ name: '',\n value: key });\n }\n }\n\n return data;\n },\n parseICECandidate(line) {\n const candidate = {};\n const elems = line.split(' ');\n\n candidate.foundation = elems[0].substring(12);\n candidate.component = elems[1];\n candidate.protocol = elems[2].toLowerCase();\n candidate.priority = elems[3];\n candidate.ip = elems[4];\n candidate.port = elems[5];\n\n // elems[6] => \"typ\"\n candidate.type = elems[7];\n candidate.generation = 0; // default value, may be overwritten below\n for (let i = 8; i < elems.length; i += 2) {\n switch (elems[i]) {\n case 'raddr':\n candidate['rel-addr'] = elems[i + 1];\n break;\n case 'rport':\n candidate['rel-port'] = elems[i + 1];\n break;\n case 'generation':\n candidate.generation = elems[i + 1];\n break;\n case 'tcptype':\n candidate.tcptype = elems[i + 1];\n break;\n default: // TODO\n logger.log(\n `parseICECandidate not translating \"${\n elems[i]}\" = \"${elems[i + 1]}\"`);\n }\n }\n candidate.network = '1';\n\n // not applicable to SDP -- FIXME: should be unique, not just random\n // eslint-disable-next-line newline-per-chained-call\n candidate.id = Math.random().toString(36).substr(2, 10);\n\n return candidate;\n },\n buildICECandidate(cand) {\n let line = [\n `a=candidate:${cand.foundation}`,\n cand.component,\n cand.protocol,\n cand.priority,\n cand.ip,\n cand.port,\n 'typ',\n cand.type\n ].join(' ');\n\n line += ' ';\n switch (cand.type) {\n case 'srflx':\n case 'prflx':\n case 'relay':\n if (cand.hasOwnAttribute('rel-addr')\n && cand.hasOwnAttribute('rel-port')) {\n line += 'raddr';\n line += ' ';\n line += cand['rel-addr'];\n line += ' ';\n line += 'rport';\n line += ' ';\n line += cand['rel-port'];\n line += ' ';\n }\n break;\n }\n if (cand.hasOwnAttribute('tcptype')) {\n line += 'tcptype';\n line += ' ';\n line += cand.tcptype;\n line += ' ';\n }\n line += 'generation';\n line += ' ';\n line += cand.hasOwnAttribute('generation') ? cand.generation : '0';\n\n return line;\n },\n parseSSRC(desc) {\n // proprietary mapping of a=ssrc lines\n // TODO: see \"Jingle RTP Source Description\" by Juberti and P. Thatcher\n // on google docs and parse according to that\n const data = new Map();\n const lines = desc.split('\\r\\n');\n\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].substring(0, 7) === 'a=ssrc:') {\n // FIXME: Use regex to smartly find the ssrc.\n const ssrc = lines[i].split('a=ssrc:')[1].split(' ')[0];\n\n if (!data.get(ssrc)) {\n data.set(ssrc, []);\n }\n\n data.get(ssrc).push(lines[i]);\n }\n }\n\n return data;\n },\n parseRTCPFB(line) {\n const parts = line.substr(10).split(' ');\n const data = {};\n\n data.pt = parts.shift();\n data.type = parts.shift();\n data.params = parts;\n\n return data;\n },\n parseExtmap(line) {\n const parts = line.substr(9).split(' ');\n const data = {};\n\n data.value = parts.shift();\n if (data.value.indexOf('/') === -1) {\n data.direction = 'both';\n } else {\n data.direction = data.value.substr(data.value.indexOf('/') + 1);\n data.value = data.value.substr(0, data.value.indexOf('/'));\n }\n data.uri = parts.shift();\n data.params = parts;\n\n return data;\n },\n findLine(haystack, needle, sessionpart) {\n let lines = haystack.split('\\r\\n');\n\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].substring(0, needle.length) === needle) {\n return lines[i];\n }\n }\n if (!sessionpart) {\n return false;\n }\n\n // search session part\n lines = sessionpart.split('\\r\\n');\n for (let j = 0; j < lines.length; j++) {\n if (lines[j].substring(0, needle.length) === needle) {\n return lines[j];\n }\n }\n\n return false;\n },\n findLines(haystack, needle, sessionpart) {\n let lines = haystack.split('\\r\\n');\n const needles = [];\n\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].substring(0, needle.length) === needle) {\n needles.push(lines[i]);\n }\n }\n if (needles.length || !sessionpart) {\n return needles;\n }\n\n // search session part\n lines = sessionpart.split('\\r\\n');\n for (let j = 0; j < lines.length; j++) {\n if (lines[j].substring(0, needle.length) === needle) {\n needles.push(lines[j]);\n }\n }\n\n return needles;\n },\n candidateToJingle(line) {\n // a=candidate:2979166662 1 udp 2113937151 192.168.2.100 57698 typ host\n // generation 0\n // \n if (line.indexOf('candidate:') === 0) {\n // eslint-disable-next-line no-param-reassign\n line = `a=${line}`;\n } else if (line.substring(0, 12) !== 'a=candidate:') {\n logger.log(\n 'parseCandidate called with a line that is not a candidate'\n + ' line');\n logger.log(line);\n\n return null;\n }\n if (line.substring(line.length - 2) === '\\r\\n') { // chomp it\n // eslint-disable-next-line no-param-reassign\n line = line.substring(0, line.length - 2);\n }\n const candidate = {};\n const elems = line.split(' ');\n\n if (elems[6] !== 'typ') {\n logger.log('did not find typ in the right place');\n logger.log(line);\n\n return null;\n }\n candidate.foundation = elems[0].substring(12);\n candidate.component = elems[1];\n candidate.protocol = elems[2].toLowerCase();\n candidate.priority = elems[3];\n candidate.ip = elems[4];\n candidate.port = elems[5];\n\n // elems[6] => \"typ\"\n candidate.type = elems[7];\n\n candidate.generation = '0'; // default, may be overwritten below\n for (let i = 8; i < elems.length; i += 2) {\n switch (elems[i]) {\n case 'raddr':\n candidate['rel-addr'] = elems[i + 1];\n break;\n case 'rport':\n candidate['rel-port'] = elems[i + 1];\n break;\n case 'generation':\n candidate.generation = elems[i + 1];\n break;\n case 'tcptype':\n candidate.tcptype = elems[i + 1];\n break;\n default: // TODO\n logger.log(`not translating \"${elems[i]}\" = \"${elems[i + 1]}\"`);\n }\n }\n candidate.network = '1';\n\n // not applicable to SDP -- FIXME: should be unique, not just random\n // eslint-disable-next-line newline-per-chained-call\n candidate.id = Math.random().toString(36).substr(2, 10);\n\n return candidate;\n },\n candidateFromJingle(cand) {\n let line = 'a=candidate:';\n\n line += cand.getAttribute('foundation');\n line += ' ';\n line += cand.getAttribute('component');\n line += ' ';\n\n let protocol = cand.getAttribute('protocol');\n\n // use tcp candidates for FF\n\n if (browser.isFirefox() && protocol.toLowerCase() === 'ssltcp') {\n protocol = 'tcp';\n }\n\n line += protocol; // .toUpperCase(); // chrome M23 doesn't like this\n line += ' ';\n line += cand.getAttribute('priority');\n line += ' ';\n line += cand.getAttribute('ip');\n line += ' ';\n line += cand.getAttribute('port');\n line += ' ';\n line += 'typ';\n line += ` ${cand.getAttribute('type')}`;\n line += ' ';\n switch (cand.getAttribute('type')) {\n case 'srflx':\n case 'prflx':\n case 'relay':\n if (cand.getAttribute('rel-addr')\n && cand.getAttribute('rel-port')) {\n line += 'raddr';\n line += ' ';\n line += cand.getAttribute('rel-addr');\n line += ' ';\n line += 'rport';\n line += ' ';\n line += cand.getAttribute('rel-port');\n line += ' ';\n }\n break;\n }\n if (protocol.toLowerCase() === 'tcp') {\n line += 'tcptype';\n line += ' ';\n line += cand.getAttribute('tcptype');\n line += ' ';\n }\n line += 'generation';\n line += ' ';\n line += cand.getAttribute('generation') || '0';\n\n return `${line}\\r\\n`;\n },\n\n /**\n * Parse the 'most' primary video ssrc from the given m line\n * @param {object} mLine object as parsed from transform.parse\n * @return {number} the primary video ssrc from the given m line\n */\n parsePrimaryVideoSsrc(videoMLine) {\n const numSsrcs = videoMLine.ssrcs\n .map(ssrcInfo => ssrcInfo.id)\n .filter((ssrc, index, array) => array.indexOf(ssrc) === index)\n .length;\n const numGroups\n = (videoMLine.ssrcGroups && videoMLine.ssrcGroups.length) || 0;\n\n if (numSsrcs > 1 && numGroups === 0) {\n // Ambiguous, can't figure out the primary\n return;\n }\n let primarySsrc = null;\n\n if (numSsrcs === 1) {\n primarySsrc = videoMLine.ssrcs[0].id;\n } else if (numSsrcs === 2) {\n // Can figure it out if there's an FID group\n const fidGroup\n = videoMLine.ssrcGroups.find(\n group => group.semantics === 'FID');\n\n if (fidGroup) {\n primarySsrc = fidGroup.ssrcs.split(' ')[0];\n }\n } else if (numSsrcs >= 3) {\n // Can figure it out if there's a sim group\n const simGroup\n = videoMLine.ssrcGroups.find(\n group => group.semantics === 'SIM');\n\n if (simGroup) {\n primarySsrc = simGroup.ssrcs.split(' ')[0];\n }\n }\n\n return primarySsrc;\n },\n\n /**\n * Generate an ssrc\n * @returns {number} an ssrc\n */\n generateSsrc() {\n return RandomUtil.randomInt(1, 0xffffffff);\n },\n\n /**\n * Get an attribute for the given ssrc with the given attributeName\n * from the given mline\n * @param {object} mLine an mLine object as parsed from transform.parse\n * @param {number} ssrc the ssrc for which an attribtue is desired\n * @param {string} attributeName the name of the desired attribute\n * @returns {string} the value corresponding to the given ssrc\n * and attributeName\n */\n getSsrcAttribute(mLine, ssrc, attributeName) {\n for (let i = 0; i < mLine.ssrcs.length; ++i) {\n const ssrcLine = mLine.ssrcs[i];\n\n if (ssrcLine.id === ssrc\n && ssrcLine.attribute === attributeName) {\n return ssrcLine.value;\n }\n }\n },\n\n /**\n * Parses the ssrcs from the group sdp line and\n * returns them as a list of numbers\n * @param {object} the ssrcGroup object as parsed from\n * sdp-transform\n * @returns {list} a list of the ssrcs in the group\n * parsed as numbers\n */\n parseGroupSsrcs(ssrcGroup) {\n return ssrcGroup\n .ssrcs\n .split(' ')\n .map(ssrcStr => parseInt(ssrcStr, 10));\n },\n\n /**\n * Get the mline of the given type from the given sdp\n * @param {object} sdp sdp as parsed from transform.parse\n * @param {string} type the type of the desired mline (e.g. \"video\")\n * @returns {object} a media object\n */\n getMedia(sdp, type) {\n return sdp.media.find(m => m.type === type);\n },\n\n /**\n * Extracts the ICE username fragment from an SDP string.\n * @param {string} sdp the SDP in raw text format\n */\n getUfrag(sdp) {\n const ufragLines\n = sdp.split('\\n').filter(line => line.startsWith('a=ice-ufrag:'));\n\n if (ufragLines.length > 0) {\n return ufragLines[0].substr('a=ice-ufrag:'.length);\n }\n },\n\n /**\n * Sets the given codecName as the preferred codec by\n * moving it to the beginning of the payload types\n * list (modifies the given mline in place). If there\n * are multiple options within the same codec (multiple h264\n * profiles, for instance), this will prefer the first one\n * that is found.\n * @param {object} videoMLine the video mline object from\n * an sdp as parsed by transform.parse\n * @param {string} codecName the name of the preferred codec\n */\n preferVideoCodec(videoMLine, codecName) {\n let payloadType = null;\n\n if (!videoMLine || !codecName) {\n return;\n }\n\n for (let i = 0; i < videoMLine.rtp.length; ++i) {\n const rtp = videoMLine.rtp[i];\n\n if (rtp.codec\n && rtp.codec.toLowerCase() === codecName.toLowerCase()) {\n payloadType = rtp.payload;\n break;\n }\n }\n if (payloadType) {\n // Call toString() on payloads to get around an issue within\n // SDPTransform that sets payloads as a number, instead of a string,\n // when there is only one payload.\n const payloadTypes\n = videoMLine.payloads\n .toString()\n .split(' ')\n .map(p => parseInt(p, 10));\n const payloadIndex = payloadTypes.indexOf(payloadType);\n\n payloadTypes.splice(payloadIndex, 1);\n payloadTypes.unshift(payloadType);\n videoMLine.payloads = payloadTypes.join(' ');\n }\n },\n\n /**\n * Strips the given codec from the given mline. All related RTX payload\n * types are also stripped. If the resulting mline would have no codecs,\n * it's disabled.\n *\n * @param {object} videoMLine the video mline object from an sdp as parsed\n * by transform.parse.\n * @param {string} codecName the name of the codec which will be stripped.\n */\n stripVideoCodec(videoMLine, codecName) {\n if (!videoMLine || !codecName) {\n return;\n }\n\n const removePts = [];\n\n for (const rtp of videoMLine.rtp) {\n if (rtp.codec\n && rtp.codec.toLowerCase() === codecName.toLowerCase()) {\n removePts.push(rtp.payload);\n }\n }\n\n if (removePts.length > 0) {\n // We also need to remove the payload types that are related to RTX\n // for the codecs we want to disable.\n const rtxApts = removePts.map(item => `apt=${item}`);\n const rtxPts = videoMLine.fmtp.filter(\n item => rtxApts.indexOf(item.config) !== -1);\n\n removePts.push(...rtxPts.map(item => item.payload));\n\n // Call toString() on payloads to get around an issue within\n // SDPTransform that sets payloads as a number, instead of a string,\n // when there is only one payload.\n const allPts = videoMLine.payloads\n .toString()\n .split(' ')\n .map(Number);\n const keepPts = allPts.filter(pt => removePts.indexOf(pt) === -1);\n\n if (keepPts.length === 0) {\n // There are no other video codecs, disable the stream.\n videoMLine.port = 0;\n videoMLine.direction = 'inactive';\n videoMLine.payloads = '*';\n } else {\n videoMLine.payloads = keepPts.join(' ');\n }\n\n videoMLine.rtp = videoMLine.rtp.filter(\n item => keepPts.indexOf(item.payload) !== -1);\n videoMLine.fmtp = videoMLine.fmtp.filter(\n item => keepPts.indexOf(item.payload) !== -1);\n if (videoMLine.rtcpFb) {\n videoMLine.rtcpFb = videoMLine.rtcpFb.filter(\n item => keepPts.indexOf(item.payload) !== -1);\n }\n }\n }\n};\n\nexport default SDPUtil;\n","/**\n * This class exports constants and factory methods related to the analytics\n * API provided by AnalyticsAdapter. In order for entries in a database to be\n * somewhat easily traceable back to the code which produced them, events sent\n * through analytics should be defined here.\n *\n * Since the AnalyticsAdapter API can be used in different ways, for some events\n * it is more convenient to just define the event name as a constant. For other\n * events a factory function is easier.\n *\n * A general approach for adding a new event:\n * 1. Determine the event type: track, UI, page, or operational. If in doubt use\n * operational.\n * 2. Determine whether the event is related to other existing events, and\n * which fields are desired to be set: name, action, actionSubject, source.\n * 3. If the name is sufficient (the other fields are not important), use a\n * constant. Otherwise use a factory function.\n *\n * Note that the AnalyticsAdapter uses the events passed to its functions for\n * its own purposes, and might modify them. Because of this, factory functions\n * should create new objects.\n *\n */\n\n/**\n * The constant which identifies an event of type \"operational\".\n * @type {string}\n */\nexport const TYPE_OPERATIONAL = 'operational';\n\n/**\n * The constant which identifies an event of type \"page\".\n * @type {string}\n */\nexport const TYPE_PAGE = 'page';\n\n/**\n * The constant which identifies an event of type \"track\".\n * @type {string}\n */\nexport const TYPE_TRACK = 'track';\n\n/**\n * The constant which identifies an event of type \"ui\".\n * @type {string}\n */\nexport const TYPE_UI = 'ui';\n\n/**\n * The \"action\" value for Jingle events which indicates that the Jingle session\n * was restarted (TODO: verify/fix the documentation)\n * @type {string}\n */\nexport const ACTION_JINGLE_RESTART = 'restart';\n\n/**\n * The \"action\" value for Jingle events which indicates that a session-accept\n * timed out (TODO: verify/fix the documentation)\n * @type {string}\n */\nexport const ACTION_JINGLE_SA_TIMEOUT = 'session-accept.timeout';\n\n/**\n * The \"action\" value for Jingle events which indicates that a session-initiate\n * was received.\n * @type {string}\n */\nexport const ACTION_JINGLE_SI_RECEIVED = 'session-initiate.received';\n\n/**\n * The \"action\" value for Jingle events which indicates that a session-initiate\n * not arrived within a timeout (the value is specified in\n * the {@link JingleSessionPC}.\n * @type {string}\n */\nexport const ACTION_JINGLE_SI_TIMEOUT = 'session-initiate.timeout';\n\n/**\n * A constant for the \"terminate\" action for Jingle events. TODO: verify/fix\n * the documentation)\n * @type {string}\n */\nexport const ACTION_JINGLE_TERMINATE = 'terminate';\n\n/**\n * The \"action\" value for Jingle events which indicates that a transport-replace\n * was received.\n * @type {string}\n */\nexport const ACTION_JINGLE_TR_RECEIVED\n = 'transport-replace.received';\n\n/**\n * The \"action\" value for Jingle events which indicates that a transport-replace\n * succeeded (TODO: verify/fix the documentation)\n * @type {string}\n */\nexport const ACTION_JINGLE_TR_SUCCESS\n = 'transport-replace.success';\n\n/**\n * The \"action\" value for P2P events which indicates that P2P session initiate message has been rejected by the client\n * because the mandatory requirements were not met.\n * @type {string}\n */\nexport const ACTION_P2P_DECLINED = 'decline';\n\n/**\n * The \"action\" value for P2P events which indicates that a connection was\n * established (TODO: verify/fix the documentation)\n * @type {string}\n */\nexport const ACTION_P2P_ESTABLISHED = 'established';\n\n/**\n * The \"action\" value for P2P events which indicates that something failed.\n * @type {string}\n */\nexport const ACTION_P2P_FAILED = 'failed';\n\n/**\n * The \"action\" value for P2P events which indicates that a switch to\n * jitsi-videobridge happened.\n * @type {string}\n */\nexport const ACTION_P2P_SWITCH_TO_JVB = 'switch.to.jvb';\n\n/**\n * The name of an event which indicates an available device. We send one such\n * event per available device once when the available devices are first known,\n * and every time that they change\n * @type {string}\n *\n * Properties:\n * audio_input_device_count: the number of audio input devices available at\n * the time the event was sent.\n * audio_output_device_count: the number of audio output devices available\n * at the time the event was sent.\n * video_input_device_count: the number of video input devices available at\n * the time the event was sent.\n * video_output_device_count: the number of video output devices available\n * at the time the event was sent.\n * device_id: an identifier of the device described in this event.\n * device_group_id:\n * device_kind: one of 'audioinput', 'audiooutput', 'videoinput' or\n * 'videooutput'.\n * device_label: a string which describes the device.\n */\nexport const AVAILABLE_DEVICE = 'available.device';\n\n/**\n * This appears to be fired only in certain cases when the XMPP connection\n * disconnects (and it was intentional?). It is currently never observed to\n * fire in production.\n *\n * TODO: document\n *\n * Properties:\n * message: an error message\n */\nexport const CONNECTION_DISCONNECTED = 'connection.disconnected';\n\n/**\n * Indicates that the user of the application provided feedback in terms of a\n * rating (an integer from 1 to 5) and an optional comment.\n * Properties:\n * value: the user's rating (an integer from 1 to 5)\n * comment: the user's comment\n */\nexport const FEEDBACK = 'feedback';\n\n/**\n * Indicates the duration of a particular phase of the ICE connectivity\n * establishment.\n *\n * Properties:\n * phase: the ICE phase (e.g. 'gathering', 'checking', 'establishment')\n * value: the duration in milliseconds.\n * p2p: whether the associated ICE connection is p2p or towards a\n * jitsi-videobridge\n * initiator: whether the local Jingle peer is the initiator or responder\n * in the Jingle session. XXX we probably actually care about the ICE\n * role (controlling vs controlled), and we assume that this correlates\n * with the Jingle initiator.\n */\nexport const ICE_DURATION = 'ice.duration';\n\n/**\n * Indicates the difference in milliseconds between the ICE establishment time\n * for the P2P and JVB connections (e.g. a value of 10 would indicate that the\n * P2P connection took 10ms more than JVB connection to establish).\n *\n * Properties:\n * value: the difference in establishment durations in milliseconds.\n *\n */\nexport const ICE_ESTABLISHMENT_DURATION_DIFF\n = 'ice.establishment.duration.diff';\n\n/**\n * Indicates that the ICE state has changed.\n *\n * Properties:\n * state: the ICE state which was entered (e.g. 'checking', 'connected',\n * 'completed', etc).\n * value: the time in milliseconds (as reported by\n * window.performance.now()) that the state change occurred.\n * p2p: whether the associated ICE connection is p2p or towards a\n * jitsi-videobridge\n * signalingState: The signaling state of the associated PeerConnection\n * reconnect: whether the associated Jingle session is in the process of\n * reconnecting (or is it ICE? TODO: verify/fix the documentation)\n */\nexport const ICE_STATE_CHANGED = 'ice.state.changed';\n\n/**\n * Indicates that no bytes have been sent for the track.\n *\n * Properties:\n * mediaType: the media type of the local track ('audio' or 'video').\n */\nexport const NO_BYTES_SENT = 'track.no-bytes-sent';\n\n/**\n * Indicates that a track was unmuted (?).\n *\n * Properties:\n * mediaType: the media type of the local track ('audio' or 'video').\n * trackType: the type of the track ('local' or 'remote').\n * value: TODO: document\n */\nexport const TRACK_UNMUTED = 'track.unmuted';\n\n/**\n * Creates an operational event which indicates that we have received a\n * \"bridge down\" event from jicofo.\n */\nexport const createBridgeDownEvent = function() {\n const bridgeDown = 'bridge.down';\n\n return {\n action: bridgeDown,\n actionSubject: bridgeDown,\n type: TYPE_OPERATIONAL\n };\n};\n\n/**\n * Creates an event which indicates that the XMPP connection failed\n * @param errorType TODO\n * @param errorMessage TODO\n * @param detail connection failed details.\n */\nexport const createConnectionFailedEvent\n = function(errorType, errorMessage, details) {\n return {\n type: TYPE_OPERATIONAL,\n action: 'connection.failed',\n attributes: {\n 'error_type': errorType,\n 'error_message': errorMessage,\n ...details\n }\n };\n };\n\n/**\n * Creates an operational event which indicates that a particular connection\n * stage was reached (i.e. the XMPP connection transitioned to the \"connected\"\n * state).\n *\n * @param stage the stage which was reached\n * @param attributes additional attributes for the event. This should be an\n * object with a \"value\" property indicating a timestamp in milliseconds\n * relative to the beginning of the document's lifetime.\n *\n */\nexport const createConnectionStageReachedEvent = function(stage, attributes) {\n const action = 'connection.stage.reached';\n\n return {\n action,\n actionSubject: stage,\n attributes,\n source: action,\n type: TYPE_OPERATIONAL\n };\n};\n\n/**\n * Creates an operational event for the end-to-end round trip time to a\n * specific remote participant.\n * @param participantId the ID of the remote participant.\n * @param region the region of the remote participant\n * @param rtt the rtt\n */\nexport const createE2eRttEvent = function(participantId, region, rtt) {\n const attributes = {\n 'participant_id': participantId,\n region,\n rtt\n };\n\n return {\n attributes,\n name: 'e2e_rtt',\n type: TYPE_OPERATIONAL\n };\n};\n\n/**\n * Creates an event which indicates that the focus has left the MUC.\n */\nexport const createFocusLeftEvent = function() {\n const action = 'focus.left';\n\n return {\n action,\n actionSubject: action,\n type: TYPE_OPERATIONAL\n };\n};\n\n/**\n * Creates an event related to a getUserMedia call.\n *\n * @param action the type of the result that the event represents: 'error',\n * 'success', 'warning', etc.\n * @param attributes the attributes to attach to the event.\n * @returns {{type: string, source: string, name: string}}\n */\nexport const createGetUserMediaEvent = function(action, attributes = {}) {\n return {\n type: TYPE_OPERATIONAL,\n source: 'get.user.media',\n action,\n attributes\n };\n};\n\n/**\n * Creates an event related to remote participant connection status changes.\n *\n * @param attributes the attributes to attach to the event.\n * @returns {{type: string, source: string, name: string}}\n */\nexport const createParticipantConnectionStatusEvent = function(attributes = {}) {\n const action = 'duration';\n\n return {\n type: TYPE_OPERATIONAL,\n source: 'peer.conn.status',\n action,\n attributes\n };\n};\n\n/**\n * Creates an event for a Jingle-related event.\n * @param action the action of the event\n * @param attributes attributes to add to the event.\n */\nexport const createJingleEvent = function(action, attributes = {}) {\n return {\n type: TYPE_OPERATIONAL,\n action,\n source: 'jingle',\n attributes\n };\n};\n\n/**\n * Creates an event which indicates that a local track was not able to read\n * data from its source (a camera or a microphone).\n *\n * @param mediaType {String} the media type of the local track ('audio' or\n * 'video').\n */\nexport const createNoDataFromSourceEvent = function(mediaType, value) {\n return {\n attributes: {\n 'media_type': mediaType,\n value\n },\n action: 'track.no.data.from.source',\n type: TYPE_OPERATIONAL\n };\n};\n\n/**\n * Creates an event for a p2p-related event.\n * @param action the action of the event\n * @param attributes attributes to add to the event.\n */\nexport const createP2PEvent = function(action, attributes = {}) {\n return {\n type: TYPE_OPERATIONAL,\n action,\n source: 'p2p',\n attributes\n };\n};\n\n/**\n * Indicates that we received a remote command to mute.\n */\nexport const createRemotelyMutedEvent = function() {\n return {\n type: TYPE_OPERATIONAL,\n action: 'remotely.muted'\n };\n};\n\n/**\n * Creates an event which contains RTP statistics such as RTT and packet loss.\n *\n * All average RTP stats are currently reported under 1 event name, but with\n * different properties that allows to distinguish between a P2P call, a\n * call relayed through TURN or the JVB, and multiparty vs 1:1.\n *\n * The structure of the event is:\n *\n * {\n * p2p: true,\n * conferenceSize: 2,\n * localCandidateType: \"relay\",\n * remoteCandidateType: \"relay\",\n * transportType: \"udp\",\n *\n * // Average RTT of 200ms\n * \"rtt.avg\": 200,\n * \"rtt.samples\": \"[100, 200, 300]\",\n *\n * // Average packet loss of 10%\n * \"packet.loss.avg\": 10,\n * \"packet.loss.samples\": '[5, 10, 15]'\n *\n * // Difference in milliseconds in the end-to-end RTT between p2p and jvb.\n * // The e2e RTT through jvb is 15ms shorter:\n * \"rtt.diff\": 15,\n *\n * // End-to-end RTT through JVB is ms.\n * \"end2end.rtt.avg\" = 100\n * }\n *\n * Note that the value of the \"samples\" properties are (JSON encoded) strings,\n * and not JSON arrays, as events' attributes can not be nested. The samples are\n * currently included for debug purposes only and can be removed anytime soon\n * from the structure.\n *\n * Also note that not all of values are present in each event, as values are\n * obtained and calculated as part of different process/event pipe. For example\n * {@link ConnectionAvgStats} instances are doing the reports for each\n * {@link TraceablePeerConnection} and work independently from the main stats\n * pipe.\n */\nexport const createRtpStatsEvent = function(attributes) {\n return {\n type: TYPE_OPERATIONAL,\n action: 'rtp.stats',\n attributes\n };\n};\n\n/**\n * Creates an event which contains the round trip time (RTT) to a set of\n * regions.\n *\n * @param attributes\n * @returns {{type: string, action: string, attributes: *}}\n */\nexport const createRttByRegionEvent = function(attributes) {\n return {\n type: TYPE_OPERATIONAL,\n action: 'rtt.by.region',\n attributes\n };\n};\n\n/**\n * Creates an event which contains information about the audio output problem (the user id of the affected participant,\n * the local audio levels and the remote audio levels that triggered the event).\n *\n * @param {string} userID - The user id of the affected participant.\n * @param {*} localAudioLevels - The local audio levels.\n * @param {*} remoteAudioLevels - The audio levels received from the participant.\n */\nexport function createAudioOutputProblemEvent(userID, localAudioLevels, remoteAudioLevels) {\n return {\n type: TYPE_OPERATIONAL,\n action: 'audio.output.problem',\n attributes: {\n userID,\n localAudioLevels,\n remoteAudioLevels\n }\n };\n}\n\n/**\n * Creates an event which contains an information related to the bridge channel close event.\n *\n * @param {string} code - A code from {@link https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent}\n * @param {string} reason - A string which describes the reason for closing the bridge channel.\n * @returns {{type: string, action: string, attributes: { code: string, reason: string }}}\n */\nexport const createBridgeChannelClosedEvent = function(code, reason) {\n return {\n type: TYPE_OPERATIONAL,\n action: 'bridge-channel.error',\n attributes: {\n code,\n reason\n }\n };\n};\n\n/**\n * Creates an event which indicates the Time To First Media (TTFM).\n * It is measured in milliseconds relative to the beginning of the document's\n * lifetime (i.e. the origin used by window.performance.now()), and it excludes\n * the following:\n * 1. The delay due to getUserMedia()\n * 2. The period between the MUC being joined and the reception of the Jingle\n * session-initiate from jicofo. This is because jicofo will not start a Jingle\n * session until there are at least 2 participants in the room.\n *\n * @param attributes the attributes to add to the event. Currently used fields:\n * mediaType: the media type of the local track ('audio' or 'video').\n * muted: whether the track has ever been muted (?)\n * value: the TTMF in milliseconds.\n */\nexport const createTtfmEvent = function(attributes) {\n return createConnectionStageReachedEvent('ttfm', attributes);\n};\n","const RTCEvents = {\n /**\n * Indicates error while create answer call.\n */\n CREATE_ANSWER_FAILED: 'rtc.create_answer_failed',\n\n /**\n * Indicates error while create offer call.\n */\n CREATE_OFFER_FAILED: 'rtc.create_offer_failed',\n DATA_CHANNEL_OPEN: 'rtc.data_channel_open',\n ENDPOINT_CONN_STATUS_CHANGED: 'rtc.endpoint_conn_status_changed',\n DOMINANT_SPEAKER_CHANGED: 'rtc.dominant_speaker_changed',\n LASTN_ENDPOINT_CHANGED: 'rtc.lastn_endpoint_changed',\n\n /**\n * Event emitted when the user granted a permission for the camera / mic.\n * Used to keep track of the granted permissions on browsers which don't\n * support the Permissions API.\n */\n GRANTED_PERMISSIONS: 'rtc.granted_permissions',\n\n IS_SELECTED_CHANGED: 'rtc.is_selected_change',\n\n /**\n * Event emitted when {@link RTC.setLastN} method is called to update with\n * the new value set.\n * The first argument is the value passed to {@link RTC.setLastN}.\n */\n LASTN_VALUE_CHANGED: 'rtc.lastn_value_changed',\n\n /**\n * Event emitted when ssrc for a local track is extracted and stored\n * in {@link TraceablePeerConnection}.\n * @param {JitsiLocalTrack} track which ssrc was updated\n * @param {string} ssrc that was stored\n */\n LOCAL_TRACK_SSRC_UPDATED: 'rtc.local_track_ssrc_updated',\n\n TRACK_ATTACHED: 'rtc.track_attached',\n\n /**\n * Event fired when we remote track is added to the conference.\n * 1st event argument is the added JitsiRemoteTrack instance.\n **/\n REMOTE_TRACK_ADDED: 'rtc.remote_track_added',\n\n // FIXME get rid of this event in favour of NO_DATA_FROM_SOURCE event\n // (currently implemented for local tracks only)\n REMOTE_TRACK_MUTE: 'rtc.remote_track_mute',\n\n /**\n * Indicates that the remote track has been removed from the conference.\n * 1st event argument is the removed {@link JitsiRemoteTrack} instance.\n */\n REMOTE_TRACK_REMOVED: 'rtc.remote_track_removed',\n\n // FIXME get rid of this event in favour of NO_DATA_FROM_SOURCE event\n // (currently implemented for local tracks only)\n REMOTE_TRACK_UNMUTE: 'rtc.remote_track_unmute',\n\n /**\n * Indicates error while set local description.\n */\n SET_LOCAL_DESCRIPTION_FAILED: 'rtc.set_local_description_failed',\n\n /**\n * Indicates error while set remote description.\n */\n SET_REMOTE_DESCRIPTION_FAILED: 'rtc.set_remote_description_failed',\n AUDIO_OUTPUT_DEVICE_CHANGED: 'rtc.audio_output_device_changed',\n DEVICE_LIST_CHANGED: 'rtc.device_list_changed',\n\n /**\n * Indicates that the list with available devices will change.\n */\n DEVICE_LIST_WILL_CHANGE: 'rtc.device_list_will_change',\n DEVICE_LIST_AVAILABLE: 'rtc.device_list_available',\n\n /**\n * Indicates that a message from another participant is received on\n * data channel.\n */\n ENDPOINT_MESSAGE_RECEIVED: 'rtc.endpoint_message_received',\n\n /**\n * Designates an event indicating that the local ICE username fragment of\n * the jingle session has changed.\n * The first argument of the vent is TraceablePeerConnection which\n * is the source of the event.\n * The second argument is the actual \"ufrag\" string.\n */\n LOCAL_UFRAG_CHANGED: 'rtc.local_ufrag_changed',\n\n /**\n * Designates an event indicating that the local ICE username fragment of\n * the jingle session has changed.\n * The first argument of the vent is TraceablePeerConnection which\n * is the source of the event.\n * The second argument is the actual \"ufrag\" string.\n */\n REMOTE_UFRAG_CHANGED: 'rtc.remote_ufrag_changed'\n};\n\nmodule.exports = RTCEvents;\n","/**\n * The audio type.\n */\nexport const AUDIO = 'audio';\n\n/**\n * The video type.\n */\nexport const VIDEO = 'video';\n","/* global\n __filename,\n MediaStreamTrack,\n RTCIceCandidate: true,\n RTCPeerConnection,\n RTCSessionDescription: true\n*/\n\nimport { AVAILABLE_DEVICE } from '../../service/statistics/AnalyticsEvents';\nimport CameraFacingMode from '../../service/RTC/CameraFacingMode';\nimport EventEmitter from 'events';\nimport { getLogger } from 'jitsi-meet-logger';\nimport GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';\nimport JitsiTrackError from '../../JitsiTrackError';\nimport Listenable from '../util/Listenable';\nimport * as MediaType from '../../service/RTC/MediaType';\nimport Resolutions from '../../service/RTC/Resolutions';\nimport browser from '../browser';\nimport RTCEvents from '../../service/RTC/RTCEvents';\nimport screenObtainer from './ScreenObtainer';\nimport SDPUtil from '../xmpp/SDPUtil';\nimport Statistics from '../statistics/statistics';\nimport VideoType from '../../service/RTC/VideoType';\n\nconst logger = getLogger(__filename);\n\n// Require adapter only for certain browsers. This is being done for\n// react-native, which has its own shims, and while browsers are being migrated\n// over to use adapter's shims.\nif (browser.usesAdapter()) {\n require('webrtc-adapter');\n}\n\nconst eventEmitter = new EventEmitter();\n\nconst AVAILABLE_DEVICES_POLL_INTERVAL_TIME = 3000; // ms\n\n/**\n * Default resolution to obtain for video tracks if no resolution is specified.\n * This default is used for old gum flow only, as new gum flow uses\n * {@link DEFAULT_CONSTRAINTS}.\n */\nconst OLD_GUM_DEFAULT_RESOLUTION = 720;\n\n/**\n * Default devices to obtain when no specific devices are specified. This\n * default is used for old gum flow only.\n */\nconst OLD_GUM_DEFAULT_DEVICES = [ 'audio', 'video' ];\n\n/**\n * Default MediaStreamConstraints to use for calls to getUserMedia.\n *\n * @private\n */\nconst DEFAULT_CONSTRAINTS = {\n video: {\n aspectRatio: 16 / 9,\n height: {\n ideal: 720,\n max: 720,\n min: 240\n }\n }\n};\n\n/**\n * The default frame rate for Screen Sharing.\n */\nconst SS_DEFAULT_FRAME_RATE = 5;\n\n// Currently audio output device change is supported only in Chrome and\n// default output always has 'default' device ID\nlet audioOutputDeviceId = 'default'; // default device\n// whether user has explicitly set a device to use\nlet audioOutputChanged = false;\n\n// Disables all audio processing\nlet disableAP = false;\n\n// Disables Acoustic Echo Cancellation\nlet disableAEC = false;\n\n// Disables Noise Suppression\nlet disableNS = false;\n\n// Disables Automatic Gain Control\nlet disableAGC = false;\n\n// Disables Highpass Filter\nlet disableHPF = false;\n\nconst featureDetectionAudioEl = document.createElement('audio');\nconst isAudioOutputDeviceChangeAvailable\n = typeof featureDetectionAudioEl.setSinkId !== 'undefined';\n\nlet availableDevices;\nlet availableDevicesPollTimer;\n\n/**\n * Initialize wrapper function for enumerating devices.\n * TODO: remove this, it should no longer be needed.\n *\n * @returns {?Function}\n */\nfunction initEnumerateDevicesWithCallback() {\n if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {\n return callback => {\n navigator.mediaDevices.enumerateDevices()\n .then(callback, () => callback([]));\n };\n }\n}\n\n/**\n *\n * @param constraints\n * @param isNewStyleConstraintsSupported\n * @param resolution\n */\nfunction setResolutionConstraints(\n constraints,\n isNewStyleConstraintsSupported,\n resolution) {\n if (Resolutions[resolution]) {\n if (isNewStyleConstraintsSupported) {\n constraints.video.width = {\n ideal: Resolutions[resolution].width\n };\n constraints.video.height = {\n ideal: Resolutions[resolution].height\n };\n }\n\n constraints.video.mandatory.minWidth = Resolutions[resolution].width;\n constraints.video.mandatory.minHeight = Resolutions[resolution].height;\n }\n\n if (constraints.video.mandatory.minWidth) {\n constraints.video.mandatory.maxWidth\n = constraints.video.mandatory.minWidth;\n }\n\n if (constraints.video.mandatory.minHeight) {\n constraints.video.mandatory.maxHeight\n = constraints.video.mandatory.minHeight;\n }\n}\n\n/**\n * @param {string[]} um required user media types\n *\n * @param {Object} [options={}] optional parameters\n * @param {string} options.resolution\n * @param {number} options.bandwidth\n * @param {number} options.fps\n * @param {string} options.desktopStream\n * @param {string} options.cameraDeviceId\n * @param {string} options.micDeviceId\n * @param {CameraFacingMode} options.facingMode\n * @param {bool} firefox_fake_device\n * @param {Object} options.frameRate - used only for dekstop sharing.\n * @param {Object} options.frameRate.min - Minimum fps\n * @param {Object} options.frameRate.max - Maximum fps\n */\nfunction getConstraints(um, options = {}) {\n const constraints = {\n audio: false,\n video: false\n };\n\n // Don't mix new and old style settings for Chromium as this leads\n // to TypeError in new Chromium versions. @see\n // https://bugs.chromium.org/p/chromium/issues/detail?id=614716\n // This is a temporary solution, in future we will fully split old and\n // new style constraints when new versions of Chromium and Firefox will\n // have stable support of new constraints format. For more information\n // @see https://github.com/jitsi/lib-jitsi-meet/pull/136\n const isNewStyleConstraintsSupported\n = browser.isFirefox()\n || browser.isSafariWithVP8()\n || browser.isEdge()\n || browser.isReactNative();\n\n if (um.indexOf('video') >= 0) {\n // same behaviour as true\n constraints.video = { mandatory: {},\n optional: [] };\n\n if (options.cameraDeviceId) {\n if (isNewStyleConstraintsSupported) {\n // New style of setting device id.\n constraints.video.deviceId = options.cameraDeviceId;\n }\n\n // Old style.\n constraints.video.mandatory.sourceId = options.cameraDeviceId;\n } else {\n // Prefer the front i.e. user-facing camera (to the back i.e.\n // environment-facing camera, for example).\n // TODO: Maybe use \"exact\" syntax if options.facingMode is defined,\n // but this probably needs to be decided when updating other\n // constraints, as we currently don't use \"exact\" syntax anywhere.\n const facingMode = options.facingMode || CameraFacingMode.USER;\n\n if (isNewStyleConstraintsSupported) {\n constraints.video.facingMode = facingMode;\n }\n constraints.video.optional.push({\n facingMode\n });\n }\n\n if (options.minFps || options.maxFps || options.fps) {\n // for some cameras it might be necessary to request 30fps\n // so they choose 30fps mjpg over 10fps yuy2\n if (options.minFps || options.fps) {\n // Fall back to options.fps for backwards compatibility\n options.minFps = options.minFps || options.fps;\n constraints.video.mandatory.minFrameRate = options.minFps;\n }\n if (options.maxFps) {\n constraints.video.mandatory.maxFrameRate = options.maxFps;\n }\n }\n\n setResolutionConstraints(\n constraints, isNewStyleConstraintsSupported, options.resolution);\n }\n if (um.indexOf('audio') >= 0) {\n if (browser.isReactNative()) {\n // The react-native-webrtc project that we're currently using\n // expects the audio constraint to be a boolean.\n constraints.audio = true;\n } else if (browser.isFirefox()) {\n if (options.micDeviceId) {\n constraints.audio = {\n mandatory: {},\n deviceId: options.micDeviceId, // new style\n optional: [ {\n sourceId: options.micDeviceId // old style\n } ] };\n } else {\n constraints.audio = true;\n }\n } else {\n // same behaviour as true\n constraints.audio = { mandatory: {},\n optional: [] };\n if (options.micDeviceId) {\n if (isNewStyleConstraintsSupported) {\n // New style of setting device id.\n constraints.audio.deviceId = options.micDeviceId;\n }\n\n // Old style.\n constraints.audio.optional.push({\n sourceId: options.micDeviceId\n });\n }\n\n // if it is good enough for hangouts...\n constraints.audio.optional.push(\n { echoCancellation: !disableAEC && !disableAP },\n { googEchoCancellation: !disableAEC && !disableAP },\n { googAutoGainControl: !disableAGC && !disableAP },\n { googNoiseSuppression: !disableNS && !disableAP },\n { googHighpassFilter: !disableHPF && !disableAP },\n { googNoiseSuppression2: !disableNS && !disableAP },\n { googEchoCancellation2: !disableAEC && !disableAP },\n { googAutoGainControl2: !disableAGC && !disableAP }\n );\n }\n }\n if (um.indexOf('screen') >= 0) {\n if (browser.isChrome()) {\n constraints.video = {\n mandatory: getSSConstraints({\n ...options,\n source: 'screen'\n }),\n optional: []\n };\n\n } else if (browser.isFirefox()) {\n constraints.video = {\n mozMediaSource: 'window',\n mediaSource: 'window',\n frameRate: options.frameRate || {\n min: SS_DEFAULT_FRAME_RATE,\n max: SS_DEFAULT_FRAME_RATE\n }\n };\n\n } else {\n const errmsg\n = '\\'screen\\' WebRTC media source is supported only in Chrome'\n + ' and Firefox';\n\n GlobalOnErrorHandler.callErrorHandler(new Error(errmsg));\n logger.error(errmsg);\n }\n }\n if (um.indexOf('desktop') >= 0) {\n constraints.video = {\n mandatory: getSSConstraints({\n ...options,\n source: 'desktop'\n }),\n optional: []\n };\n }\n\n if (options.bandwidth) {\n if (!constraints.video) {\n // same behaviour as true\n constraints.video = { mandatory: {},\n optional: [] };\n }\n constraints.video.optional.push({ bandwidth: options.bandwidth });\n }\n\n // we turn audio for both audio and video tracks, the fake audio & video\n // seems to work only when enabled in one getUserMedia call, we cannot get\n // fake audio separate by fake video this later can be a problem with some\n // of the tests\n if (browser.isFirefox() && options.firefox_fake_device) {\n // seems to be fixed now, removing this experimental fix, as having\n // multiple audio tracks brake the tests\n // constraints.audio = true;\n constraints.fake = true;\n }\n\n return constraints;\n}\n\n/**\n * Creates a constraints object to be passed into a call to getUserMedia.\n *\n * @param {Array} um - An array of user media types to get. The accepted\n * types are \"video\", \"audio\", and \"desktop.\"\n * @param {Object} options - Various values to be added to the constraints.\n * @param {string} options.cameraDeviceId - The device id for the video\n * capture device to get video from.\n * @param {Object} options.constraints - Default constraints object to use\n * as a base for the returned constraints.\n * @param {Object} options.desktopStream - The desktop source id from which\n * to capture a desktop sharing video.\n * @param {string} options.facingMode - Which direction the camera is\n * pointing to.\n * @param {string} options.micDeviceId - The device id for the audio capture\n * device to get audio from.\n * @param {Object} options.frameRate - used only for dekstop sharing.\n * @param {Object} options.frameRate.min - Minimum fps\n * @param {Object} options.frameRate.max - Maximum fps\n * @private\n * @returns {Object}\n */\nfunction newGetConstraints(um = [], options = {}) {\n // Create a deep copy of the constraints to avoid any modification of\n // the passed in constraints object.\n const constraints = JSON.parse(JSON.stringify(\n options.constraints || DEFAULT_CONSTRAINTS));\n\n if (um.indexOf('video') >= 0) {\n if (!constraints.video) {\n constraints.video = {};\n }\n\n if (options.cameraDeviceId) {\n constraints.video.deviceId = options.cameraDeviceId;\n } else {\n const facingMode = options.facingMode || CameraFacingMode.USER;\n\n constraints.video.facingMode = facingMode;\n }\n } else {\n constraints.video = false;\n }\n\n if (um.indexOf('audio') >= 0) {\n if (!constraints.audio || typeof constraints.audio === 'boolean') {\n constraints.audio = {};\n }\n\n // NOTE(brian): the new-style ('advanced' instead of 'optional')\n // doesn't seem to carry through the googXXX constraints\n // Changing back to 'optional' here (even with video using\n // the 'advanced' style) allows them to be passed through\n // but also requires the device id to capture to be set in optional\n // as sourceId otherwise the constraints are considered malformed.\n if (!constraints.audio.optional) {\n constraints.audio.optional = [];\n }\n\n constraints.audio.optional.push(\n { sourceId: options.micDeviceId },\n { echoCancellation: !disableAEC && !disableAP },\n { googEchoCancellation: !disableAEC && !disableAP },\n { googAutoGainControl: !disableAGC && !disableAP },\n { googNoiseSuppression: !disableNS && !disableAP },\n { googHighpassFilter: !disableHPF && !disableAP },\n { googNoiseSuppression2: !disableNS && !disableAP },\n { googEchoCancellation2: !disableAEC && !disableAP },\n { googAutoGainControl2: !disableAGC && !disableAP }\n );\n } else {\n constraints.audio = false;\n }\n\n if (um.indexOf('desktop') >= 0) {\n if (!constraints.video || typeof constraints.video === 'boolean') {\n constraints.video = {};\n }\n\n constraints.video = {\n mandatory: getSSConstraints({\n ...options,\n source: 'desktop'\n })\n };\n }\n\n return constraints;\n}\n\n/**\n * Generates GUM constraints for screen sharing.\n *\n * @param {Object} options - The options passed to\n * obtainAudioAndVideoPermissions.\n * @returns {Object} - GUM constraints.\n *\n * TODO: Currently only the new GUM flow and Chrome is using the method. We\n * should make it work for all use cases.\n */\nfunction getSSConstraints(options = {}) {\n const {\n desktopStream,\n frameRate = {\n min: SS_DEFAULT_FRAME_RATE,\n max: SS_DEFAULT_FRAME_RATE\n }\n } = options;\n const { max, min } = frameRate;\n\n const constraints = {\n chromeMediaSource: options.source,\n maxWidth: window.screen.width,\n maxHeight: window.screen.height\n };\n\n if (typeof min === 'number') {\n constraints.minFrameRate = min;\n }\n\n if (typeof max === 'number') {\n constraints.maxFrameRate = max;\n }\n\n if (typeof desktopStream !== 'undefined') {\n constraints.chromeMediaSourceId = desktopStream;\n }\n\n return constraints;\n}\n\n/**\n * Generates constraints for screen sharing when using getDisplayMedia.\n * The constraints(MediaTrackConstraints) are applied to the resulting track.\n *\n * @returns {Object} - MediaTrackConstraints constraints.\n */\nfunction getTrackSSConstraints(options = {}) {\n // we used to set height and width in the constraints, but this can lead\n // to inconsistencies if the browser is on a lower resolution screen\n // and we share a screen with bigger resolution, so they are now not set\n const constraints = {\n frameRate: SS_DEFAULT_FRAME_RATE\n };\n const { desktopSharingFrameRate } = options;\n\n if (desktopSharingFrameRate && desktopSharingFrameRate.max) {\n constraints.frameRate = desktopSharingFrameRate.max;\n }\n\n return constraints;\n}\n\n/**\n * Updates the granted permissions based on the options we requested and the\n * streams we received.\n * @param um the options we requested to getUserMedia.\n * @param stream the stream we received from calling getUserMedia.\n */\nfunction updateGrantedPermissions(um, stream) {\n const audioTracksReceived\n = Boolean(stream) && stream.getAudioTracks().length > 0;\n const videoTracksReceived\n = Boolean(stream) && stream.getVideoTracks().length > 0;\n const grantedPermissions = {};\n\n if (um.indexOf('video') !== -1) {\n grantedPermissions.video = videoTracksReceived;\n }\n if (um.indexOf('audio') !== -1) {\n grantedPermissions.audio = audioTracksReceived;\n }\n\n eventEmitter.emit(RTCEvents.GRANTED_PERMISSIONS, grantedPermissions);\n}\n\n/**\n * Checks if new list of available media devices differs from previous one.\n * @param {MediaDeviceInfo[]} newDevices - list of new devices.\n * @returns {boolean} - true if list is different, false otherwise.\n */\nfunction compareAvailableMediaDevices(newDevices) {\n if (newDevices.length !== availableDevices.length) {\n return true;\n }\n\n /* eslint-disable newline-per-chained-call */\n\n return (\n newDevices.map(mediaDeviceInfoToJSON).sort().join('')\n !== availableDevices\n .map(mediaDeviceInfoToJSON).sort().join(''));\n\n /* eslint-enable newline-per-chained-call */\n\n /**\n *\n * @param info\n */\n function mediaDeviceInfoToJSON(info) {\n return JSON.stringify({\n kind: info.kind,\n deviceId: info.deviceId,\n groupId: info.groupId,\n label: info.label,\n facing: info.facing\n });\n }\n}\n\n/**\n * Sends analytics event with the passed device list.\n *\n * @param {Array} deviceList - List with info about the\n * available devices.\n * @returns {void}\n */\nfunction sendDeviceListToAnalytics(deviceList) {\n const audioInputDeviceCount\n = deviceList.filter(d => d.kind === 'audioinput').length;\n const audioOutputDeviceCount\n = deviceList.filter(d => d.kind === 'audiooutput').length;\n const videoInputDeviceCount\n = deviceList.filter(d => d.kind === 'videoinput').length;\n const videoOutputDeviceCount\n = deviceList.filter(d => d.kind === 'videooutput').length;\n\n deviceList.forEach(device => {\n const attributes = {\n 'audio_input_device_count': audioInputDeviceCount,\n 'audio_output_device_count': audioOutputDeviceCount,\n 'video_input_device_count': videoInputDeviceCount,\n 'video_output_device_count': videoOutputDeviceCount,\n 'device_id': device.deviceId,\n 'device_group_id': device.groupId,\n 'device_kind': device.kind,\n 'device_label': device.label\n };\n\n Statistics.sendAnalytics(AVAILABLE_DEVICE, attributes);\n });\n}\n\n/**\n * Event handler for the 'devicechange' event.\n *\n * @param {MediaDeviceInfo[]} devices - list of media devices.\n * @emits RTCEvents.DEVICE_LIST_CHANGED\n */\nfunction onMediaDevicesListChanged(devicesReceived) {\n availableDevices = devicesReceived.slice(0);\n logger.info(\n 'list of media devices has changed:',\n availableDevices);\n\n sendDeviceListToAnalytics(availableDevices);\n\n // Used by tracks to update the real device id before the consumer of lib-jitsi-meet receives the new device list.\n eventEmitter.emit(RTCEvents.DEVICE_LIST_WILL_CHANGE, devicesReceived);\n\n eventEmitter.emit(RTCEvents.DEVICE_LIST_CHANGED, devicesReceived);\n}\n\n/**\n * Handles the newly created Media Streams.\n * @param streams the new Media Streams\n * @param resolution the resolution of the video streams\n * @returns {*[]} object that describes the new streams\n */\nfunction handleLocalStream(streams, resolution) {\n let audioStream, desktopStream, videoStream;\n const res = [];\n\n // XXX The function obtainAudioAndVideoPermissions has examined the type of\n // the browser, its capabilities, etc. and has taken the decision whether to\n // invoke getUserMedia per device (e.g. Firefox) or once for both audio and\n // video (e.g. Chrome). In order to not duplicate the logic here, examine\n // the specified streams and figure out what we've received based on\n // obtainAudioAndVideoPermissions' decision.\n if (streams) {\n // As mentioned above, certian types of browser (e.g. Chrome) support\n // (with a result which meets our requirements expressed bellow) calling\n // getUserMedia once for both audio and video.\n const audioVideo = streams.audioVideo;\n\n if (audioVideo) {\n const audioTracks = audioVideo.getAudioTracks();\n\n if (audioTracks.length) {\n audioStream = new MediaStream();\n for (let i = 0; i < audioTracks.length; i++) {\n audioStream.addTrack(audioTracks[i]);\n }\n }\n\n const videoTracks = audioVideo.getVideoTracks();\n\n if (videoTracks.length) {\n videoStream = new MediaStream();\n for (let j = 0; j < videoTracks.length; j++) {\n videoStream.addTrack(videoTracks[j]);\n }\n }\n } else {\n // On other types of browser (e.g. Firefox) we choose (namely,\n // obtainAudioAndVideoPermissions) to call getUserMedia per device\n // (type).\n audioStream = streams.audio;\n videoStream = streams.video;\n }\n\n desktopStream = streams.desktop;\n }\n\n if (desktopStream) {\n const { stream, sourceId, sourceType } = desktopStream;\n\n res.push({\n stream,\n sourceId,\n sourceType,\n track: stream.getVideoTracks()[0],\n mediaType: MediaType.VIDEO,\n videoType: VideoType.DESKTOP\n });\n }\n if (audioStream) {\n res.push({\n stream: audioStream,\n track: audioStream.getAudioTracks()[0],\n mediaType: MediaType.AUDIO,\n videoType: null\n });\n }\n if (videoStream) {\n res.push({\n stream: videoStream,\n track: videoStream.getVideoTracks()[0],\n mediaType: MediaType.VIDEO,\n videoType: VideoType.CAMERA,\n resolution\n });\n }\n\n return res;\n}\n\n/**\n * Represents a default implementation of setting a MediaStream as the\n * source of a video element that tries to be browser-agnostic through feature\n * checking. Note though that it was not completely clear from the predating\n * browser-specific implementations what "videoSrc" was because one\n * implementation of {@link RTCUtils#getVideoSrc} would return\n * MediaStream (e.g. Firefox), another a string representation\n * of the URL of the MediaStream (e.g. Chrome) and the return\n * value was only used by {@link RTCUIHelper#getVideoId} which itself did not\n * appear to be used anywhere. Generally, the implementation will try to follow\n * the related standards i.e. work with the srcObject and src\n * properties of the specified element taking into account vender\n * prefixes.\n *\n * @param element the element whose video source/src is to be set to the\n * specified stream\n * @param {MediaStream} stream the MediaStream to set as the video\n * source/src of element\n */\nfunction defaultSetVideoSrc(element, stream) {\n // srcObject\n let srcObjectPropertyName = 'srcObject';\n\n if (!(srcObjectPropertyName in element)) {\n srcObjectPropertyName = 'mozSrcObject';\n if (!(srcObjectPropertyName in element)) {\n srcObjectPropertyName = null;\n }\n }\n if (srcObjectPropertyName) {\n element[srcObjectPropertyName] = stream;\n\n return;\n }\n\n // src\n let src;\n\n if (stream) {\n src = stream.jitsiObjectURL;\n\n // Save the created URL for stream so we can reuse it and not keep\n // creating URLs.\n if (!src) {\n stream.jitsiObjectURL = src = URL.createObjectURL(stream);\n }\n }\n element.src = src || '';\n}\n\n/**\n *\n */\nclass RTCUtils extends Listenable {\n /**\n *\n */\n constructor() {\n super(eventEmitter);\n }\n\n /**\n * Depending on the browser, sets difference instance methods for\n * interacting with user media and adds methods to native WebRTC-related\n * objects. Also creates an instance variable for peer connection\n * constraints.\n *\n * @param {Object} options\n * @returns {void}\n */\n init(options = {}) {\n if (typeof options.disableAEC === 'boolean') {\n disableAEC = options.disableAEC;\n logger.info(`Disable AEC: ${disableAEC}`);\n }\n if (typeof options.disableNS === 'boolean') {\n disableNS = options.disableNS;\n logger.info(`Disable NS: ${disableNS}`);\n }\n if (typeof options.disableAP === 'boolean') {\n disableAP = options.disableAP;\n logger.info(`Disable AP: ${disableAP}`);\n }\n if (typeof options.disableAGC === 'boolean') {\n disableAGC = options.disableAGC;\n logger.info(`Disable AGC: ${disableAGC}`);\n }\n if (typeof options.disableHPF === 'boolean') {\n disableHPF = options.disableHPF;\n logger.info(`Disable HPF: ${disableHPF}`);\n }\n\n availableDevices = undefined;\n window.clearInterval(availableDevicesPollTimer);\n availableDevicesPollTimer = undefined;\n\n this.enumerateDevices = initEnumerateDevicesWithCallback();\n\n if (browser.usesNewGumFlow()) {\n this.RTCPeerConnectionType = RTCPeerConnection;\n\n this.attachMediaStream\n = wrapAttachMediaStream((element, stream) => {\n if (element) {\n element.srcObject = stream;\n }\n });\n\n this.getStreamID = ({ id }) => id;\n this.getTrackID = ({ id }) => id;\n } else if (browser.isChromiumBased() // this is chrome < 61\n || browser.isReactNative()) {\n\n this.RTCPeerConnectionType = RTCPeerConnection;\n\n this.attachMediaStream\n = wrapAttachMediaStream((element, stream) => {\n defaultSetVideoSrc(element, stream);\n\n return element;\n });\n\n this.getStreamID = function({ id }) {\n // A. MediaStreams from FF endpoints have the characters '{' and\n // '}' that make jQuery choke.\n // B. The react-native-webrtc implementation that we use at the\n // time of this writing returns a number for the id of\n // MediaStream. Let's just say that a number contains no special\n // characters.\n return (\n typeof id === 'number'\n ? id\n : SDPUtil.filterSpecialChars(id));\n };\n this.getTrackID = ({ id }) => id;\n\n if (!MediaStream.prototype.getVideoTracks) {\n MediaStream.prototype.getVideoTracks = function() {\n return this.videoTracks;\n };\n }\n if (!MediaStream.prototype.getAudioTracks) {\n MediaStream.prototype.getAudioTracks = function() {\n return this.audioTracks;\n };\n }\n } else {\n const message = 'Endpoint does not appear to be WebRTC-capable';\n\n logger.error(message);\n throw new Error(message);\n }\n\n this._initPCConstraints(options);\n\n screenObtainer.init(\n options,\n this.getUserMediaWithConstraints.bind(this));\n\n if (this.isDeviceListAvailable()) {\n this.enumerateDevices(ds => {\n availableDevices = ds.splice(0);\n\n logger.debug('Available devices: ', availableDevices);\n sendDeviceListToAnalytics(availableDevices);\n\n eventEmitter.emit(\n RTCEvents.DEVICE_LIST_AVAILABLE,\n availableDevices);\n\n\n // Use a shared callback to handle both the devicechange event\n // and the polling implementations. This prevents duplication\n // and works around a chrome bug (verified to occur on 68) where\n // devicechange fires twice in a row, which can cause async post\n // devicechange processing to collide.\n const updateKnownDevices = () => this.enumerateDevices(pds => {\n if (compareAvailableMediaDevices(pds)) {\n onMediaDevicesListChanged(pds);\n }\n });\n\n if (browser.supportsDeviceChangeEvent()) {\n navigator.mediaDevices.addEventListener(\n 'devicechange',\n updateKnownDevices);\n } else {\n // Periodically poll enumerateDevices() method to check if\n // list of media devices has changed.\n availableDevicesPollTimer = window.setInterval(\n updateKnownDevices,\n AVAILABLE_DEVICES_POLL_INTERVAL_TIME);\n }\n });\n }\n }\n\n /**\n * Creates instance objects for peer connection constraints both for p2p\n * and outside of p2p.\n *\n * @params {Object} options - Configuration for setting RTCUtil's instance\n * objects for peer connection constraints.\n * @params {boolean} options.useIPv6 - Set to true if IPv6 should be used.\n * @params {Object} options.testing - Additional configuration for work in\n * development.\n * @params {Object} options.testing.forceP2PSuspendVideoRatio - True if\n * video should become suspended if bandwidth estimation becomes low while\n * in peer to peer connection mode.\n */\n _initPCConstraints(options) {\n if (browser.isFirefox()) {\n this.pcConstraints = {};\n } else if (browser.isChromiumBased() || browser.isReactNative()) {\n this.pcConstraints = { optional: [\n { googHighStartBitrate: 0 },\n { googPayloadPadding: true },\n { googScreencastMinBitrate: 100 },\n { googCpuOveruseDetection: true },\n { googCpuOveruseEncodeUsage: true },\n { googCpuUnderuseThreshold: 55 },\n { googCpuOveruseThreshold: 85 }\n ] };\n\n if (options.useIPv6) {\n // https://code.google.com/p/webrtc/issues/detail?id=2828\n this.pcConstraints.optional.push({ googIPv6: true });\n }\n\n this.p2pPcConstraints\n = JSON.parse(JSON.stringify(this.pcConstraints));\n }\n\n this.p2pPcConstraints = this.p2pPcConstraints || this.pcConstraints;\n }\n\n /* eslint-disable max-params */\n\n /**\n * @param {string[]} um required user media types\n * @param {Object} [options] optional parameters\n * @param {string} options.resolution\n * @param {number} options.bandwidth\n * @param {number} options.fps\n * @param {string} options.desktopStream\n * @param {string} options.cameraDeviceId\n * @param {string} options.micDeviceId\n * @param {Object} options.frameRate - used only for dekstop sharing.\n * @param {Object} options.frameRate.min - Minimum fps\n * @param {Object} options.frameRate.max - Maximum fps\n * @returns {Promise} Returns a media stream on success or a JitsiTrackError\n * on failure.\n **/\n getUserMediaWithConstraints(um, options = {}) {\n const constraints = getConstraints(um, options);\n\n logger.info('Get media constraints', constraints);\n\n return new Promise((resolve, reject) => {\n navigator.mediaDevices.getUserMedia(constraints)\n .then(stream => {\n logger.log('onUserMediaSuccess');\n updateGrantedPermissions(um, stream);\n resolve(stream);\n })\n .catch(error => {\n logger.warn('Failed to get access to local media. '\n + ` ${error} ${constraints} `);\n updateGrantedPermissions(um, undefined);\n reject(new JitsiTrackError(error, constraints, um));\n });\n });\n }\n\n /**\n * Acquires a media stream via getUserMedia that\n * matches the given constraints\n *\n * @param {array} umDevices which devices to acquire (e.g. audio, video)\n * @param {Object} constraints - Stream specifications to use.\n * @returns {Promise}\n */\n _newGetUserMediaWithConstraints(umDevices, constraints = {}) {\n return new Promise((resolve, reject) => {\n navigator.mediaDevices.getUserMedia(constraints)\n .then(stream => {\n logger.log('onUserMediaSuccess');\n updateGrantedPermissions(umDevices, stream);\n resolve(stream);\n })\n .catch(error => {\n logger.warn('Failed to get access to local media. '\n + ` ${error} ${constraints} `);\n updateGrantedPermissions(umDevices, undefined);\n reject(new JitsiTrackError(error, constraints, umDevices));\n });\n });\n }\n\n /**\n * Acquire a display stream via the screenObtainer. This requires extra\n * logic compared to use screenObtainer versus normal device capture logic\n * in RTCUtils#_newGetUserMediaWithConstraints.\n *\n * @param {Object} options\n * @param {Object} options.desktopSharingExtensionExternalInstallation\n * @param {string[]} options.desktopSharingSources\n * @param {Object} options.desktopSharingFrameRate\n * @param {Object} options.desktopSharingFrameRate.min - Minimum fps\n * @param {Object} options.desktopSharingFrameRate.max - Maximum fps\n * @returns {Promise} A promise which will be resolved with an object which\n * contains the acquired display stream. If desktop sharing is not supported\n * then a rejected promise will be returned.\n */\n _newGetDesktopMedia(options) {\n if (!screenObtainer.isSupported() || !browser.supportsVideo()) {\n return Promise.reject(\n new Error('Desktop sharing is not supported!'));\n }\n\n return new Promise((resolve, reject) => {\n screenObtainer.obtainStream(\n this._parseDesktopSharingOptions(options),\n stream => {\n resolve(stream);\n },\n error => {\n reject(error);\n });\n });\n }\n\n /* eslint-enable max-params */\n\n /**\n * Creates the local MediaStreams.\n * @param {Object} [options] optional parameters\n * @param {Array} options.devices the devices that will be requested\n * @param {string} options.resolution resolution constraints\n * @param {string} options.cameraDeviceId\n * @param {string} options.micDeviceId\n * @param {Object} options.desktopSharingFrameRate\n * @param {Object} options.desktopSharingFrameRate.min - Minimum fps\n * @param {Object} options.desktopSharingFrameRate.max - Maximum fps\n * @returns {*} Promise object that will receive the new JitsiTracks\n */\n obtainAudioAndVideoPermissions(options = {}) {\n options.devices = options.devices || [ ...OLD_GUM_DEFAULT_DEVICES ];\n options.resolution = options.resolution || OLD_GUM_DEFAULT_RESOLUTION;\n\n const requestingDesktop = options.devices.includes('desktop');\n\n if (requestingDesktop && !screenObtainer.isSupported()) {\n return Promise.reject(\n new Error('Desktop sharing is not supported!'));\n }\n\n return this._getAudioAndVideoStreams(options).then(streams =>\n handleLocalStream(streams, options.resolution));\n }\n\n /**\n * Performs one call to getUserMedia for audio and/or video and another call\n * for desktop.\n *\n * @param {Object} options - An object describing how the gUM request should\n * be executed. See {@link obtainAudioAndVideoPermissions} for full options.\n * @returns {*} Promise object that will receive the new JitsiTracks on\n * success or a JitsiTrackError on failure.\n */\n _getAudioAndVideoStreams(options) {\n const requestingDesktop = options.devices.includes('desktop');\n\n options.devices = options.devices.filter(device =>\n device !== 'desktop');\n\n const gumPromise = options.devices.length\n ? this.getUserMediaWithConstraints(options.devices, options)\n : Promise.resolve(null);\n\n return gumPromise\n .then(avStream => {\n // If any requested devices are missing, call gum again in\n // an attempt to obtain the actual error. For example, the\n // requested video device is missing or permission was\n // denied.\n const missingTracks\n = this._getMissingTracks(options.devices, avStream);\n\n if (missingTracks.length) {\n this.stopMediaStream(avStream);\n\n return this.getUserMediaWithConstraints(\n missingTracks, options)\n\n // GUM has already failed earlier and this success\n // handling should not be reached.\n .then(() => Promise.reject(new JitsiTrackError(\n { name: 'UnknownError' },\n getConstraints(options.devices, options),\n missingTracks)));\n }\n\n return avStream;\n })\n .then(audioVideo => {\n if (!requestingDesktop) {\n return { audioVideo };\n }\n\n if (options.desktopSharingSourceDevice) {\n this.stopMediaStream(audioVideo);\n\n throw new Error('Using a camera as screenshare source is'\n + 'not supported on this browser.');\n }\n\n return new Promise((resolve, reject) => {\n screenObtainer.obtainStream(\n this._parseDesktopSharingOptions(options),\n desktop => resolve({\n audioVideo,\n desktop\n }),\n error => {\n if (audioVideo) {\n this.stopMediaStream(audioVideo);\n }\n reject(error);\n });\n });\n });\n }\n\n /**\n * Private utility for determining if the passed in MediaStream contains\n * tracks of the type(s) specified in the requested devices.\n *\n * @param {string[]} requestedDevices - The track types that are expected to\n * be includes in the stream.\n * @param {MediaStream} stream - The MediaStream to check if it has the\n * expected track types.\n * @returns {string[]} An array of string with the missing track types. The\n * array will be empty if all requestedDevices are found in the stream.\n */\n _getMissingTracks(requestedDevices = [], stream) {\n const missingDevices = [];\n\n const audioDeviceRequested = requestedDevices.includes('audio');\n const audioTracksReceived\n = stream && stream.getAudioTracks().length > 0;\n\n if (audioDeviceRequested && !audioTracksReceived) {\n missingDevices.push('audio');\n }\n\n const videoDeviceRequested = requestedDevices.includes('video');\n const videoTracksReceived\n = stream && stream.getVideoTracks().length > 0;\n\n if (videoDeviceRequested && !videoTracksReceived) {\n missingDevices.push('video');\n }\n\n return missingDevices;\n }\n\n /**\n * Returns an object formatted for specifying desktop sharing parameters.\n *\n * @param {Object} options - Takes in the same options object as\n * {@link obtainAudioAndVideoPermissions}.\n * @returns {Object}\n */\n _parseDesktopSharingOptions(options) {\n return {\n ...options.desktopSharingExtensionExternalInstallation,\n desktopSharingSources: options.desktopSharingSources,\n gumOptions: {\n frameRate: options.desktopSharingFrameRate\n },\n trackOptions: getTrackSSConstraints(options)\n };\n }\n\n /**\n * Gets streams from specified device types. This function intentionally\n * ignores errors for upstream to catch and handle instead.\n *\n * @param {Object} options - A hash describing what devices to get and\n * relevant constraints.\n * @param {string[]} options.devices - The types of media to capture. Valid\n * values are \"desktop\", \"audio\", and \"video\".\n * @param {Object} options.desktopSharingFrameRate\n * @param {Object} options.desktopSharingFrameRate.min - Minimum fps\n * @param {Object} options.desktopSharingFrameRate.max - Maximum fps\n * @param {String} options.desktopSharingSourceDevice - The device id or\n * label for a video input source that should be used for screensharing.\n * @returns {Promise} The promise, when successful, will return an array of\n * meta data for the requested device type, which includes the stream and\n * track. If an error occurs, it will be deferred to the caller for\n * handling.\n */\n newObtainAudioAndVideoPermissions(options) {\n logger.info('Using the new gUM flow');\n\n const mediaStreamsMetaData = [];\n\n // Declare private functions to be used in the promise chain below.\n // These functions are declared in the scope of this function because\n // they are not being used anywhere else, so only this function needs to\n // know about them.\n\n /**\n * Executes a request for desktop media if specified in options.\n *\n * @returns {Promise}\n */\n const maybeRequestDesktopDevice = function() {\n const umDevices = options.devices || [];\n const isDesktopDeviceRequested\n = umDevices.indexOf('desktop') !== -1;\n\n if (!isDesktopDeviceRequested) {\n return Promise.resolve();\n }\n\n const {\n desktopSharingExtensionExternalInstallation,\n desktopSharingSourceDevice,\n desktopSharingSources,\n desktopSharingFrameRate\n } = options;\n\n // Attempt to use a video input device as a screenshare source if\n // the option is defined.\n if (desktopSharingSourceDevice) {\n const matchingDevice\n = availableDevices && availableDevices.find(device =>\n device.kind === 'videoinput'\n && (device.deviceId === desktopSharingSourceDevice\n || device.label === desktopSharingSourceDevice));\n const requestedDevices = [ 'video' ];\n\n // Leverage the helper used by {@link _newGetDesktopMedia} to\n // get constraints for the desktop stream.\n const { gumOptions, trackOptions }\n = this._parseDesktopSharingOptions(options);\n\n // Create a custom constraints object to use exact device\n // matching to make sure there is no fallthrough to another\n // camera device. If a matching device could not be found, try\n // anyways and let the caller handle errors.\n const constraints = {\n video: {\n ...gumOptions,\n deviceId: {\n exact: (matchingDevice && matchingDevice.deviceId)\n || desktopSharingSourceDevice\n }\n }\n };\n\n return this._newGetUserMediaWithConstraints(\n requestedDevices, constraints)\n .then(stream => {\n const track = stream && stream.getTracks()[0];\n const applyConstrainsPromise\n = track && track.applyConstraints\n ? track.applyConstraints(trackOptions)\n : Promise.resolve();\n\n return applyConstrainsPromise\n .then(() => {\n return {\n sourceType: 'device',\n stream\n };\n });\n });\n }\n\n return this._newGetDesktopMedia({\n desktopSharingExtensionExternalInstallation,\n desktopSharingSources,\n desktopSharingFrameRate\n });\n }.bind(this);\n\n /**\n * Creates a meta data object about the passed in desktopStream and\n * pushes the meta data to the internal array mediaStreamsMetaData to be\n * returned later.\n *\n * @param {MediaStreamTrack} desktopStream - A track for a desktop\n * capture.\n * @returns {void}\n */\n const maybeCreateAndAddDesktopTrack = function(desktopStream) {\n if (!desktopStream) {\n return;\n }\n\n const { stream, sourceId, sourceType } = desktopStream;\n\n mediaStreamsMetaData.push({\n stream,\n sourceId,\n sourceType,\n track: stream.getVideoTracks()[0],\n videoType: VideoType.DESKTOP\n });\n };\n\n /**\n * Executes a request for audio and/or video, as specified in options.\n * By default both audio and video will be captured if options.devices\n * is not defined.\n *\n * @returns {Promise}\n */\n const maybeRequestCaptureDevices = function() {\n const umDevices = options.devices || [ 'audio', 'video' ];\n const requestedCaptureDevices = umDevices.filter(device =>\n device === 'audio'\n || (device === 'video' && browser.supportsVideo()));\n\n if (!requestedCaptureDevices.length) {\n return Promise.resolve();\n }\n\n const constraints = newGetConstraints(\n requestedCaptureDevices, options);\n\n logger.info('Got media constraints: ', constraints);\n\n return this._newGetUserMediaWithConstraints(\n requestedCaptureDevices, constraints);\n }.bind(this);\n\n /**\n * Splits the passed in media stream into separate audio and video\n * streams and creates meta data objects for each and pushes them to the\n * internal array mediaStreamsMetaData to be returned later.\n *\n * @param {MediaStreamTrack} avStream - A track for with audio and/or\n * video track.\n * @returns {void}\n */\n const maybeCreateAndAddAVTracks = function(avStream) {\n if (!avStream) {\n return;\n }\n\n const audioTracks = avStream.getAudioTracks();\n\n if (audioTracks.length) {\n const audioStream = new MediaStream(audioTracks);\n\n mediaStreamsMetaData.push({\n stream: audioStream,\n track: audioStream.getAudioTracks()[0],\n effects: options.effects\n });\n }\n\n const videoTracks = avStream.getVideoTracks();\n\n if (videoTracks.length) {\n const videoStream = new MediaStream(videoTracks);\n\n mediaStreamsMetaData.push({\n stream: videoStream,\n track: videoStream.getVideoTracks()[0],\n videoType: VideoType.CAMERA,\n effects: options.effects\n });\n }\n };\n\n return maybeRequestDesktopDevice()\n .then(maybeCreateAndAddDesktopTrack)\n .then(maybeRequestCaptureDevices)\n .then(maybeCreateAndAddAVTracks)\n .then(() => mediaStreamsMetaData)\n .catch(error => {\n mediaStreamsMetaData.forEach(({ stream }) => {\n this.stopMediaStream(stream);\n });\n\n return Promise.reject(error);\n });\n }\n\n /**\n * Checks whether it is possible to enumerate available cameras/microphones.\n *\n * @returns {boolean} {@code true} if the device listing is available;\n * {@code false}, otherwise.\n */\n isDeviceListAvailable() {\n return Boolean(\n navigator.mediaDevices\n && navigator.mediaDevices.enumerateDevices);\n }\n\n /**\n * Returns true if changing the input (camera / microphone) or output\n * (audio) device is supported and false if not.\n * @params {string} [deviceType] - type of device to change. Default is\n * undefined or 'input', 'output' - for audio output device change.\n * @returns {boolean} true if available, false otherwise.\n */\n isDeviceChangeAvailable(deviceType) {\n return deviceType === 'output' || deviceType === 'audiooutput'\n ? isAudioOutputDeviceChangeAvailable\n : browser.isChromiumBased()\n || browser.isFirefox() || browser.isEdge();\n }\n\n /**\n * A method to handle stopping of the stream.\n * One point to handle the differences in various implementations.\n * @param mediaStream MediaStream object to stop.\n */\n stopMediaStream(mediaStream) {\n if (!mediaStream) {\n return;\n }\n\n mediaStream.getTracks().forEach(track => {\n if (track.stop) {\n track.stop();\n }\n });\n\n // leave stop for implementation still using it\n if (mediaStream.stop) {\n mediaStream.stop();\n }\n\n // The MediaStream implementation of the react-native-webrtc project has\n // an explicit release method that is to be invoked in order to release\n // used resources such as memory.\n if (mediaStream.release) {\n mediaStream.release();\n }\n\n // if we have done createObjectURL, lets clean it\n const url = mediaStream.jitsiObjectURL;\n\n if (url) {\n delete mediaStream.jitsiObjectURL;\n URL.revokeObjectURL(url);\n }\n }\n\n /**\n * Returns whether the desktop sharing is enabled or not.\n * @returns {boolean}\n */\n isDesktopSharingEnabled() {\n return screenObtainer.isSupported();\n }\n\n /**\n * Sets current audio output device.\n * @param {string} deviceId - id of 'audiooutput' device from\n * navigator.mediaDevices.enumerateDevices(), 'default' for default\n * device\n * @returns {Promise} - resolves when audio output is changed, is rejected\n * otherwise\n */\n setAudioOutputDevice(deviceId) {\n if (!this.isDeviceChangeAvailable('output')) {\n return Promise.reject(\n new Error('Audio output device change is not supported'));\n }\n\n return featureDetectionAudioEl.setSinkId(deviceId)\n .then(() => {\n audioOutputDeviceId = deviceId;\n audioOutputChanged = true;\n\n logger.log(`Audio output device set to ${deviceId}`);\n\n eventEmitter.emit(RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED,\n deviceId);\n });\n }\n\n /**\n * Returns currently used audio output device id, '' stands for default\n * device\n * @returns {string}\n */\n getAudioOutputDevice() {\n return audioOutputDeviceId;\n }\n\n /**\n * Returns list of available media devices if its obtained, otherwise an\n * empty array is returned/\n * @returns {Array} list of available media devices.\n */\n getCurrentlyAvailableMediaDevices() {\n return availableDevices;\n }\n\n /**\n * Returns event data for device to be reported to stats.\n * @returns {MediaDeviceInfo} device.\n */\n getEventDataForActiveDevice(device) {\n const deviceList = [];\n const deviceData = {\n 'deviceId': device.deviceId,\n 'kind': device.kind,\n 'label': device.label,\n 'groupId': device.groupId\n };\n\n deviceList.push(deviceData);\n\n return { deviceList };\n }\n\n /**\n * Configures the given PeerConnection constraints to either enable or\n * disable (according to the value of the 'enable' parameter) the\n * 'googSuspendBelowMinBitrate' option.\n * @param constraints the constraints on which to operate.\n * @param enable {boolean} whether to enable or disable the suspend video\n * option.\n */\n setSuspendVideo(constraints, enable) {\n if (!constraints.optional) {\n constraints.optional = [];\n }\n\n // Get rid of all \"googSuspendBelowMinBitrate\" constraints (we assume\n // that the elements of constraints.optional contain a single property).\n constraints.optional\n = constraints.optional.filter(\n c => !c.hasOwnProperty('googSuspendBelowMinBitrate'));\n\n if (enable) {\n constraints.optional.push({ googSuspendBelowMinBitrate: 'true' });\n }\n }\n}\n\nconst rtcUtils = new RTCUtils();\n\n/**\n * Wraps original attachMediaStream function to set current audio output device\n * if this is supported.\n * @param {Function} origAttachMediaStream\n * @returns {Function}\n */\nfunction wrapAttachMediaStream(origAttachMediaStream) {\n return function(element, stream) {\n // eslint-disable-next-line prefer-rest-params\n const res = origAttachMediaStream.apply(rtcUtils, arguments);\n\n if (stream\n && rtcUtils.isDeviceChangeAvailable('output')\n && stream.getAudioTracks\n && stream.getAudioTracks().length\n\n // we skip setting audio output if there was no explicit change\n && audioOutputChanged) {\n element.setSinkId(rtcUtils.getAudioOutputDevice())\n .catch(function(ex) {\n const err\n = new JitsiTrackError(ex, null, [ 'audiooutput' ]);\n\n GlobalOnErrorHandler.callUnhandledRejectionHandler({\n promise: this, // eslint-disable-line no-invalid-this\n reason: err\n });\n\n logger.warn(\n 'Failed to set audio output device for the element.'\n + ' Default audio output device will be used'\n + ' instead',\n element,\n err);\n });\n }\n\n return res;\n };\n}\n\nexport default rtcUtils;\n","/**\n * This utility class defines custom onerror and onunhandledrejection functions.\n * The custom error handlers respect the previously-defined error handlers.\n * GlobalOnErrorHandler class provides utilities to add many custom error\n * handlers and to execute the error handlers directly.\n */\n\n\n/**\n * List with global error handlers that will be executed.\n */\nconst handlers = [];\n\n// If an old handler exists, also fire its events.\nconst oldOnErrorHandler = window.onerror;\n\n/**\n * Custom error handler that calls the old global error handler and executes\n * all handlers that were previously added.\n */\nfunction JitsiGlobalErrorHandler(...args) {\n handlers.forEach(handler => handler(...args));\n oldOnErrorHandler && oldOnErrorHandler(...args);\n}\n\n// If an old handler exists, also fire its events.\nconst oldOnUnhandledRejection = window.onunhandledrejection;\n\n/**\n * Custom handler that calls the old global handler and executes all handlers\n * that were previously added. This handler handles rejected Promises.\n */\nfunction JitsiGlobalUnhandledRejection(event) {\n handlers.forEach(handler => handler(null, null, null, null, event.reason));\n oldOnUnhandledRejection && oldOnUnhandledRejection(event);\n}\n\n// Setting the custom error handlers.\nwindow.onerror = JitsiGlobalErrorHandler;\nwindow.onunhandledrejection = JitsiGlobalUnhandledRejection;\n\nconst GlobalOnErrorHandler = {\n /**\n * Adds new error handlers.\n * @param handler the new handler.\n */\n addHandler(handler) {\n handlers.push(handler);\n },\n\n /**\n * Calls the global error handler if there is one.\n * @param error the error to pass to the error handler\n */\n callErrorHandler(error) {\n const errHandler = window.onerror;\n\n if (!errHandler) {\n return;\n }\n errHandler(null, null, null, null, error);\n },\n\n /**\n * Calls the global rejection handler if there is one.\n * @param error the error to pass to the rejection handler.\n */\n callUnhandledRejectionHandler(error) {\n const errHandler = window.onunhandledrejection;\n\n if (!errHandler) {\n return;\n }\n errHandler(error);\n }\n};\n\n\nmodule.exports = GlobalOnErrorHandler;\n","/**\n * The errors for the JitsiTrack objects.\n */\n\n/**\n * Generic error for jidesha extension for Chrome.\n */\nexport const CHROME_EXTENSION_GENERIC_ERROR\n = 'gum.chrome_extension_generic_error';\n\n/**\n * An error which indicates that the jidesha extension for Chrome is\n * failed to install.\n */\nexport const CHROME_EXTENSION_INSTALLATION_ERROR\n = 'gum.chrome_extension_installation_error';\n\n/**\n * This error indicates that the attempt to start screensharing was initiated by\n * a script which did not originate in user gesture handler. It means that\n * you should to trigger the action again in response to a button click for\n * example.\n * @type {string}\n */\nexport const CHROME_EXTENSION_USER_GESTURE_REQUIRED\n = 'gum.chrome_extension_user_gesture_required';\n\n/**\n * An error which indicates that user canceled screen sharing window\n * selection dialog in jidesha extension for Chrome.\n */\nexport const CHROME_EXTENSION_USER_CANCELED\n = 'gum.chrome_extension_user_canceled';\n\n/**\n * An error which indicates that some of requested constraints in\n * getUserMedia call were not satisfied.\n */\nexport const CONSTRAINT_FAILED = 'gum.constraint_failed';\n\n/**\n * A generic error which indicates an error occurred while selecting\n * a DesktopCapturerSource from the electron app.\n */\nexport const ELECTRON_DESKTOP_PICKER_ERROR\n = 'gum.electron_desktop_picker_error';\n\n/**\n * An error which indicates a custom desktop picker could not be detected\n * for the electron app.\n */\nexport const ELECTRON_DESKTOP_PICKER_NOT_FOUND\n = 'gum.electron_desktop_picker_not_found';\n\n/**\n * An error which indicates that the jidesha extension for Firefox is\n * needed to proceed with screen sharing, and that it is not installed.\n */\nexport const FIREFOX_EXTENSION_NEEDED = 'gum.firefox_extension_needed';\n\n/**\n * Generic getUserMedia error.\n */\nexport const GENERAL = 'gum.general';\n\n/**\n * An error which indicates that requested device was not found.\n */\nexport const NOT_FOUND = 'gum.not_found';\n\n/**\n * An error which indicates that user denied permission to share requested\n * device.\n */\nexport const PERMISSION_DENIED = 'gum.permission_denied';\n\n/**\n * An error which indicates that track has been already disposed and cannot\n * be longer used.\n */\nexport const TRACK_IS_DISPOSED = 'track.track_is_disposed';\n\n/**\n * An error which indicates that track has no MediaStream associated.\n */\nexport const TRACK_NO_STREAM_FOUND = 'track.no_stream_found';\n\n/**\n * An error which indicates that requested video resolution is not supported\n * by a webcam.\n */\nexport const UNSUPPORTED_RESOLUTION = 'gum.unsupported_resolution';\n","/* global __filename */\n\nimport { getLogger } from 'jitsi-meet-logger';\n\nimport BridgeChannel from './BridgeChannel';\nimport GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';\nimport * as JitsiConferenceEvents from '../../JitsiConferenceEvents';\nimport JitsiLocalTrack from './JitsiLocalTrack';\nimport Listenable from '../util/Listenable';\nimport { safeCounterIncrement } from '../util/MathUtil';\nimport * as MediaType from '../../service/RTC/MediaType';\nimport browser from '../browser';\nimport RTCEvents from '../../service/RTC/RTCEvents';\nimport RTCUtils from './RTCUtils';\nimport Statistics from '../statistics/statistics';\nimport TraceablePeerConnection from './TraceablePeerConnection';\nimport VideoType from '../../service/RTC/VideoType';\n\nconst logger = getLogger(__filename);\n\n/**\n * The counter used to generated id numbers assigned to peer connections\n * @type {number}\n */\nlet peerConnectionIdCounter = 0;\n\n/**\n * The counter used to generate id number for the local\n * MediaStreamTracks.\n * @type {number}\n */\nlet rtcTrackIdCounter = 0;\n\n/**\n *\n * @param tracksInfo\n * @param options\n */\nfunction createLocalTracks(tracksInfo, options) {\n const newTracks = [];\n let deviceId = null;\n\n tracksInfo.forEach(trackInfo => {\n if (trackInfo.mediaType === MediaType.AUDIO) {\n deviceId = options.micDeviceId;\n } else if (trackInfo.videoType === VideoType.CAMERA) {\n deviceId = options.cameraDeviceId;\n }\n rtcTrackIdCounter = safeCounterIncrement(rtcTrackIdCounter);\n const localTrack = new JitsiLocalTrack({\n ...trackInfo,\n deviceId,\n facingMode: options.facingMode,\n rtcId: rtcTrackIdCounter,\n effects: options.effects\n });\n\n newTracks.push(localTrack);\n });\n\n return newTracks;\n}\n\n/**\n * Creates {@code JitsiLocalTrack} instances from the passed in meta information\n * about MedieaTracks.\n *\n * @param {Object[]} mediaStreamMetaData - An array of meta information with\n * MediaTrack instances. Each can look like:\n * {{\n * stream: MediaStream instance that holds a track with audio or video,\n * track: MediaTrack within the MediaStream,\n * videoType: \"camera\" or \"desktop\" or falsy,\n * sourceId: ID of the desktopsharing source,\n * sourceType: The desktopsharing source type,\n * effects: Array of effect types\n * }}\n */\nfunction _newCreateLocalTracks(mediaStreamMetaData = []) {\n return mediaStreamMetaData.map(metaData => {\n const {\n sourceId,\n sourceType,\n stream,\n track,\n videoType,\n effects\n } = metaData;\n\n const { deviceId, facingMode } = track.getSettings();\n\n // FIXME Move rtcTrackIdCounter to a static method in JitsiLocalTrack\n // so RTC does not need to handle ID management. This move would be\n // safer to do once the old createLocalTracks is removed.\n rtcTrackIdCounter = safeCounterIncrement(rtcTrackIdCounter);\n\n return new JitsiLocalTrack({\n deviceId,\n facingMode,\n mediaType: track.kind,\n rtcId: rtcTrackIdCounter,\n sourceId,\n sourceType,\n stream,\n track,\n videoType: videoType || null,\n effects\n });\n });\n}\n\n/**\n *\n */\nexport default class RTC extends Listenable {\n /**\n *\n * @param conference\n * @param options\n */\n constructor(conference, options = {}) {\n super();\n this.conference = conference;\n\n /**\n * A map of active TraceablePeerConnection.\n * @type {Map.}\n */\n this.peerConnections = new Map();\n\n this.localTracks = [];\n\n this.options = options;\n\n // BridgeChannel instance.\n // @private\n // @type {BridgeChannel}\n this._channel = null;\n\n // A flag whether we had received that the channel had opened we can\n // get this flag out of sync if for some reason channel got closed\n // from server, a desired behaviour so we can see errors when this\n // happen.\n // @private\n // @type {boolean}\n this._channelOpen = false;\n\n /**\n * The value specified to the last invocation of setLastN before the\n * channel completed opening. If non-null, the value will be sent\n * through a channel (once) as soon as it opens and will then be\n * discarded.\n * @private\n * @type {number}\n */\n this._lastN = -1;\n\n /**\n * Defines the last N endpoints list. It can be null or an array once\n * initialised with a channel last N event.\n * @type {Array|null}\n * @private\n */\n this._lastNEndpoints = null;\n\n /**\n * The number representing the maximum video height the local client\n * should receive from the bridge.\n *\n * @type {number|undefined}\n * @private\n */\n this._maxFrameHeight = undefined;\n\n /**\n * The endpoint ID of currently pinned participant or null if\n * no user is pinned.\n * @type {string|null}\n * @private\n */\n this._pinnedEndpoint = null;\n\n /**\n * The endpoint IDs of currently selected participants.\n *\n * @type {Array}\n * @private\n */\n this._selectedEndpoints = [];\n\n // The last N change listener.\n this._lastNChangeListener = this._onLastNChanged.bind(this);\n\n this._onDeviceListChanged = this._onDeviceListChanged.bind(this);\n this._updateAudioOutputForAudioTracks\n = this._updateAudioOutputForAudioTracks.bind(this);\n\n // Switch audio output device on all remote audio tracks. Local audio\n // tracks handle this event by themselves.\n if (RTCUtils.isDeviceChangeAvailable('output')) {\n RTCUtils.addListener(\n RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED,\n this._updateAudioOutputForAudioTracks\n );\n\n RTCUtils.addListener(\n RTCEvents.DEVICE_LIST_CHANGED,\n this._onDeviceListChanged\n );\n }\n }\n\n /**\n * Removes any listeners and stored state from this {@code RTC} instance.\n *\n * @returns {void}\n */\n destroy() {\n RTCUtils.removeListener(\n RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED,\n this._updateAudioOutputForAudioTracks\n );\n\n RTCUtils.removeListener(\n RTCEvents.DEVICE_LIST_CHANGED,\n this._onDeviceListChanged\n );\n\n this.removeListener(\n RTCEvents.LASTN_ENDPOINT_CHANGED,\n this._lastNChangeListener\n );\n\n if (this._channelOpenListener) {\n this.removeListener(\n RTCEvents.DATA_CHANNEL_OPEN,\n this._channelOpenListener\n );\n }\n }\n\n /**\n * Exposes the private helper for converting a WebRTC MediaStream to a\n * JitsiLocalTrack.\n *\n * @param {Array} tracksInfo\n * @returns {Array}\n */\n static newCreateLocalTracks(tracksInfo) {\n return _newCreateLocalTracks(tracksInfo);\n }\n\n /**\n * Creates the local MediaStreams.\n * @param {object} [options] Optional parameters.\n * @param {array} options.devices The devices that will be requested.\n * @param {string} options.resolution Resolution constraints.\n * @param {string} options.cameraDeviceId\n * @param {string} options.micDeviceId\n * @returns {*} Promise object that will receive the new JitsiTracks\n */\n static obtainAudioAndVideoPermissions(options) {\n const usesNewGumFlow = browser.usesNewGumFlow();\n const obtainMediaPromise = usesNewGumFlow\n ? RTCUtils.newObtainAudioAndVideoPermissions(options)\n : RTCUtils.obtainAudioAndVideoPermissions(options);\n\n return obtainMediaPromise.then(tracksInfo => {\n if (usesNewGumFlow) {\n return _newCreateLocalTracks(tracksInfo);\n }\n\n return createLocalTracks(tracksInfo, options);\n });\n }\n\n /**\n * Initializes the bridge channel of this instance.\n * At least one of both, peerconnection or wsUrl parameters, must be\n * given.\n * @param {RTCPeerConnection} [peerconnection] WebRTC peer connection\n * instance.\n * @param {string} [wsUrl] WebSocket URL.\n */\n initializeBridgeChannel(peerconnection, wsUrl) {\n this._channel = new BridgeChannel(\n peerconnection, wsUrl, this.eventEmitter);\n\n this._channelOpenListener = () => {\n // Mark that channel as opened.\n this._channelOpen = true;\n\n // When the channel becomes available, tell the bridge about\n // video selections so that it can do adaptive simulcast,\n // we want the notification to trigger even if userJid\n // is undefined, or null.\n try {\n this._channel.sendPinnedEndpointMessage(\n this._pinnedEndpoint);\n this._channel.sendSelectedEndpointsMessage(\n this._selectedEndpoints);\n\n if (typeof this._maxFrameHeight !== 'undefined') {\n this._channel.sendReceiverVideoConstraintMessage(\n this._maxFrameHeight);\n }\n } catch (error) {\n GlobalOnErrorHandler.callErrorHandler(error);\n logger.error(\n `Cannot send selected(${this._selectedEndpoint})`\n + `pinned(${this._pinnedEndpoint})`\n + `frameHeight(${this._maxFrameHeight}) endpoint message`,\n error);\n }\n\n this.removeListener(RTCEvents.DATA_CHANNEL_OPEN,\n this._channelOpenListener);\n this._channelOpenListener = null;\n\n // If setLastN was invoked before the bridge channel completed\n // opening, apply the specified value now that the channel\n // is open. NOTE that -1 is the default value assumed by both\n // RTC module and the JVB.\n if (this._lastN !== -1) {\n this._channel.sendSetLastNMessage(this._lastN);\n }\n };\n\n this.addListener(RTCEvents.DATA_CHANNEL_OPEN,\n this._channelOpenListener);\n\n // Add Last N change listener.\n this.addListener(RTCEvents.LASTN_ENDPOINT_CHANGED,\n this._lastNChangeListener);\n }\n\n /**\n * Callback invoked when the list of known audio and video devices has\n * been updated. Attempts to update the known available audio output\n * devices.\n *\n * @private\n * @returns {void}\n */\n _onDeviceListChanged() {\n this._updateAudioOutputForAudioTracks(RTCUtils.getAudioOutputDevice());\n }\n\n /**\n * Receives events when Last N had changed.\n * @param {array} lastNEndpoints The new Last N endpoints.\n * @private\n */\n _onLastNChanged(lastNEndpoints = []) {\n const oldLastNEndpoints = this._lastNEndpoints || [];\n let leavingLastNEndpoints = [];\n let enteringLastNEndpoints = [];\n\n this._lastNEndpoints = lastNEndpoints;\n\n leavingLastNEndpoints = oldLastNEndpoints.filter(\n id => !this.isInLastN(id));\n\n enteringLastNEndpoints = lastNEndpoints.filter(\n id => oldLastNEndpoints.indexOf(id) === -1);\n\n this.conference.eventEmitter.emit(\n JitsiConferenceEvents.LAST_N_ENDPOINTS_CHANGED,\n leavingLastNEndpoints,\n enteringLastNEndpoints);\n }\n\n /**\n * Should be called when current media session ends and after the\n * PeerConnection has been closed using PeerConnection.close() method.\n */\n onCallEnded() {\n if (this._channel) {\n // The BridgeChannel is not explicitly closed as the PeerConnection\n // is closed on call ended which triggers datachannel onclose\n // events. If using a WebSocket, the channel must be closed since\n // it is not managed by the PeerConnection.\n // The reference is cleared to disable any logic related to the\n // channel.\n if (this._channel && this._channel.mode === 'websocket') {\n this._channel.close();\n }\n\n this._channel = null;\n this._channelOpen = false;\n }\n }\n\n /**\n * Sets the maximum video size the local participant should receive from\n * remote participants. Will cache the value and send it through the channel\n * once it is created.\n *\n * @param {number} maxFrameHeightPixels the maximum frame height, in pixels,\n * this receiver is willing to receive.\n * @returns {void}\n */\n setReceiverVideoConstraint(maxFrameHeight) {\n this._maxFrameHeight = maxFrameHeight;\n\n if (this._channel && this._channelOpen) {\n this._channel.sendReceiverVideoConstraintMessage(maxFrameHeight);\n }\n }\n\n /**\n * Elects the participants with the given ids to be the selected\n * participants in order to always receive video for this participant (even\n * when last n is enabled). If there is no channel we store it and send it\n * through the channel once it is created.\n *\n * @param {Array} ids - The user ids.\n * @throws NetworkError or InvalidStateError or Error if the operation\n * fails.\n * @returns {void}\n */\n selectEndpoints(ids) {\n this._selectedEndpoints = ids;\n\n if (this._channel && this._channelOpen) {\n this._channel.sendSelectedEndpointsMessage(ids);\n }\n }\n\n /**\n * Elects the participant with the given id to be the pinned participant in\n * order to always receive video for this participant (even when last n is\n * enabled).\n * @param {stirng} id The user id.\n * @throws NetworkError or InvalidStateError or Error if the operation\n * fails.\n */\n pinEndpoint(id) {\n // Cache the value if channel is missing, till we open it.\n this._pinnedEndpoint = id;\n if (this._channel && this._channelOpen) {\n this._channel.sendPinnedEndpointMessage(id);\n }\n }\n\n /**\n *\n * @param eventType\n * @param listener\n */\n static addListener(eventType, listener) {\n RTCUtils.addListener(eventType, listener);\n }\n\n /**\n *\n * @param eventType\n * @param listener\n */\n static removeListener(eventType, listener) {\n RTCUtils.removeListener(eventType, listener);\n }\n\n /**\n *\n * @param options\n */\n static init(options = {}) {\n this.options = options;\n\n return RTCUtils.init(this.options);\n }\n\n /* eslint-disable max-params */\n\n /**\n * Creates new TraceablePeerConnection\n * @param {SignalingLayer} signaling The signaling layer that will\n * provide information about the media or participants which is not\n * carried over SDP.\n * @param {object} iceConfig An object describing the ICE config like\n * defined in the WebRTC specification.\n * @param {boolean} isP2P Indicates whether or not the new TPC will be used\n * in a peer to peer type of session.\n * @param {object} options The config options.\n * @param {boolean} options.disableSimulcast If set to 'true' will disable\n * the simulcast.\n * @param {boolean} options.disableRtx If set to 'true' will disable the\n * RTX.\n * @param {boolean} options.disableH264 If set to 'true' H264 will be\n * disabled by removing it from the SDP.\n * @param {boolean} options.preferH264 If set to 'true' H264 will be\n * preferred over other video codecs.\n * @param {boolean} options.startSilent If set to 'true' no audio will be sent or received.\n * @return {TraceablePeerConnection}\n */\n createPeerConnection(signaling, iceConfig, isP2P, options) {\n const pcConstraints = RTC.getPCConstraints(isP2P);\n\n if (typeof options.abtestSuspendVideo !== 'undefined') {\n RTCUtils.setSuspendVideo(pcConstraints, options.abtestSuspendVideo);\n\n Statistics.analytics.addPermanentProperties(\n { abtestSuspendVideo: options.abtestSuspendVideo });\n }\n\n // FIXME: We should rename iceConfig to pcConfig.\n if (browser.supportsSdpSemantics()) {\n iceConfig.sdpSemantics = 'plan-b';\n }\n\n peerConnectionIdCounter = safeCounterIncrement(peerConnectionIdCounter);\n\n const newConnection\n = new TraceablePeerConnection(\n this,\n peerConnectionIdCounter,\n signaling,\n iceConfig, pcConstraints,\n isP2P, options);\n\n this.peerConnections.set(newConnection.id, newConnection);\n\n return newConnection;\n }\n\n /* eslint-enable max-params */\n\n /**\n * Removed given peer connection from this RTC module instance.\n * @param {TraceablePeerConnection} traceablePeerConnection\n * @return {boolean} true if the given peer connection was removed\n * successfully or false if there was no peer connection mapped in\n * this RTC instance.\n */\n _removePeerConnection(traceablePeerConnection) {\n const id = traceablePeerConnection.id;\n\n if (this.peerConnections.has(id)) {\n // NOTE Remote tracks are not removed here.\n this.peerConnections.delete(id);\n\n return true;\n }\n\n return false;\n\n }\n\n /**\n *\n * @param track\n */\n addLocalTrack(track) {\n if (!track) {\n throw new Error('track must not be null nor undefined');\n }\n\n this.localTracks.push(track);\n\n track.conference = this.conference;\n }\n\n /**\n * Returns the current value for \"lastN\" - the amount of videos are going\n * to be delivered. When set to -1 for unlimited or all available videos.\n * @return {number}\n */\n getLastN() {\n return this._lastN;\n }\n\n /**\n * Get local video track.\n * @returns {JitsiLocalTrack|undefined}\n */\n getLocalVideoTrack() {\n const localVideo = this.getLocalTracks(MediaType.VIDEO);\n\n\n return localVideo.length ? localVideo[0] : undefined;\n }\n\n /**\n * Get local audio track.\n * @returns {JitsiLocalTrack|undefined}\n */\n getLocalAudioTrack() {\n const localAudio = this.getLocalTracks(MediaType.AUDIO);\n\n\n return localAudio.length ? localAudio[0] : undefined;\n }\n\n /**\n * Returns the local tracks of the given media type, or all local tracks if\n * no specific type is given.\n * @param {MediaType} [mediaType] Optional media type filter.\n * (audio or video).\n */\n getLocalTracks(mediaType) {\n let tracks = this.localTracks.slice();\n\n if (mediaType !== undefined) {\n tracks = tracks.filter(\n track => track.getType() === mediaType);\n }\n\n return tracks;\n }\n\n /**\n * Obtains all remote tracks currently known to this RTC module instance.\n * @param {MediaType} [mediaType] The remote tracks will be filtered\n * by their media type if this argument is specified.\n * @return {Array}\n */\n getRemoteTracks(mediaType) {\n let remoteTracks = [];\n\n for (const tpc of this.peerConnections.values()) {\n const pcRemoteTracks = tpc.getRemoteTracks(undefined, mediaType);\n\n if (pcRemoteTracks) {\n remoteTracks = remoteTracks.concat(pcRemoteTracks);\n }\n }\n\n return remoteTracks;\n }\n\n /**\n * Set mute for all local audio streams attached to the conference.\n * @param value The mute value.\n * @returns {Promise}\n */\n setAudioMute(value) {\n const mutePromises = [];\n\n this.getLocalTracks(MediaType.AUDIO).forEach(audioTrack => {\n // this is a Promise\n mutePromises.push(value ? audioTrack.mute() : audioTrack.unmute());\n });\n\n // We return a Promise from all Promises so we can wait for their\n // execution.\n return Promise.all(mutePromises);\n }\n\n /**\n *\n * @param track\n */\n removeLocalTrack(track) {\n const pos = this.localTracks.indexOf(track);\n\n if (pos === -1) {\n return;\n }\n\n this.localTracks.splice(pos, 1);\n }\n\n /**\n * Removes all JitsiRemoteTracks associated with given MUC nickname\n * (resource part of the JID). Returns array of removed tracks.\n *\n * @param {string} Owner The resource part of the MUC JID.\n * @returns {JitsiRemoteTrack[]}\n */\n removeRemoteTracks(owner) {\n let removedTracks = [];\n\n for (const tpc of this.peerConnections.values()) {\n const pcRemovedTracks = tpc.removeRemoteTracks(owner);\n\n removedTracks = removedTracks.concat(pcRemovedTracks);\n }\n\n logger.debug(\n `Removed remote tracks for ${owner}`\n + ` count: ${removedTracks.length}`);\n\n return removedTracks;\n }\n\n /**\n *\n */\n static getPCConstraints(isP2P) {\n const pcConstraints\n = isP2P ? RTCUtils.p2pPcConstraints : RTCUtils.pcConstraints;\n\n if (!pcConstraints) {\n return {};\n }\n\n return JSON.parse(JSON.stringify(pcConstraints));\n }\n\n /**\n *\n * @param elSelector\n * @param stream\n */\n static attachMediaStream(elSelector, stream) {\n return RTCUtils.attachMediaStream(elSelector, stream);\n }\n\n /**\n * Returns the id of the given stream.\n * @param {MediaStream} stream\n */\n static getStreamID(stream) {\n return RTCUtils.getStreamID(stream);\n }\n\n /**\n * Returns the id of the given track.\n * @param {MediaStreamTrack} track\n */\n static getTrackID(track) {\n return RTCUtils.getTrackID(track);\n }\n\n /**\n * Returns true if retrieving the the list of input devices is supported\n * and false if not.\n */\n static isDeviceListAvailable() {\n return RTCUtils.isDeviceListAvailable();\n }\n\n /**\n * Returns true if changing the input (camera / microphone) or output\n * (audio) device is supported and false if not.\n * @param {string} [deviceType] Type of device to change. Default is\n * undefined or 'input', 'output' - for audio output device change.\n * @returns {boolean} true if available, false otherwise.\n */\n static isDeviceChangeAvailable(deviceType) {\n return RTCUtils.isDeviceChangeAvailable(deviceType);\n }\n\n /**\n * Returns whether the current execution environment supports WebRTC (for\n * use within this library).\n *\n * @returns {boolean} {@code true} if WebRTC is supported in the current\n * execution environment (for use within this library); {@code false},\n * otherwise.\n */\n static isWebRtcSupported() {\n return browser.isSupported();\n }\n\n /**\n * Returns currently used audio output device id, '' stands for default\n * device\n * @returns {string}\n */\n static getAudioOutputDevice() {\n return RTCUtils.getAudioOutputDevice();\n }\n\n /**\n * Returns list of available media devices if its obtained, otherwise an\n * empty array is returned/\n * @returns {array} list of available media devices.\n */\n static getCurrentlyAvailableMediaDevices() {\n return RTCUtils.getCurrentlyAvailableMediaDevices();\n }\n\n /**\n * Returns event data for device to be reported to stats.\n * @returns {MediaDeviceInfo} device.\n */\n static getEventDataForActiveDevice(device) {\n return RTCUtils.getEventDataForActiveDevice(device);\n }\n\n /**\n * Sets current audio output device.\n * @param {string} deviceId Id of 'audiooutput' device from\n * navigator.mediaDevices.enumerateDevices().\n * @returns {Promise} resolves when audio output is changed, is rejected\n * otherwise\n */\n static setAudioOutputDevice(deviceId) {\n return RTCUtils.setAudioOutputDevice(deviceId);\n }\n\n /**\n * Returns true if given WebRTC MediaStream is considered a valid\n * \"user\" stream which means that it's not a \"receive only\" stream nor a\n * \"mixed\" JVB stream.\n *\n * Clients that implement Unified Plan, such as Firefox use recvonly\n * \"streams/channels/tracks\" for receiving remote stream/tracks, as opposed\n * to Plan B where there are only 3 channels: audio, video and data.\n *\n * @param {MediaStream} stream The WebRTC MediaStream instance.\n * @returns {boolean}\n */\n static isUserStream(stream) {\n return RTC.isUserStreamById(RTCUtils.getStreamID(stream));\n }\n\n /**\n * Returns true if a WebRTC MediaStream identified by given stream\n * ID is considered a valid \"user\" stream which means that it's not a\n * \"receive only\" stream nor a \"mixed\" JVB stream.\n *\n * Clients that implement Unified Plan, such as Firefox use recvonly\n * \"streams/channels/tracks\" for receiving remote stream/tracks, as opposed\n * to Plan B where there are only 3 channels: audio, video and data.\n *\n * @param {string} streamId The id of WebRTC MediaStream.\n * @returns {boolean}\n */\n static isUserStreamById(streamId) {\n return streamId && streamId !== 'mixedmslabel'\n && streamId !== 'default';\n }\n\n /**\n * Allows to receive list of available cameras/microphones.\n * @param {function} callback Would receive array of devices as an\n * argument.\n */\n static enumerateDevices(callback) {\n RTCUtils.enumerateDevices(callback);\n }\n\n /**\n * A method to handle stopping of the stream.\n * One point to handle the differences in various implementations.\n * @param {MediaStream} mediaStream MediaStream object to stop.\n */\n static stopMediaStream(mediaStream) {\n RTCUtils.stopMediaStream(mediaStream);\n }\n\n /**\n * Returns whether the desktop sharing is enabled or not.\n * @returns {boolean}\n */\n static isDesktopSharingEnabled() {\n return RTCUtils.isDesktopSharingEnabled();\n }\n\n /**\n * Closes the currently opened bridge channel.\n */\n closeBridgeChannel() {\n if (this._channel) {\n this._channel.close();\n this._channelOpen = false;\n\n this.removeListener(RTCEvents.LASTN_ENDPOINT_CHANGED,\n this._lastNChangeListener);\n }\n }\n\n /* eslint-disable max-params */\n /**\n *\n * @param {TraceablePeerConnection} tpc\n * @param {number} ssrc\n * @param {number} audioLevel\n * @param {boolean} isLocal\n */\n setAudioLevel(tpc, ssrc, audioLevel, isLocal) {\n const track = tpc.getTrackBySSRC(ssrc);\n\n if (!track) {\n return;\n } else if (!track.isAudioTrack()) {\n logger.warn(`Received audio level for non-audio track: ${ssrc}`);\n\n return;\n } else if (track.isLocal() !== isLocal) {\n logger.error(\n `${track} was expected to ${isLocal ? 'be' : 'not be'} local`);\n }\n\n track.setAudioLevel(audioLevel, tpc);\n }\n\n /* eslint-enable max-params */\n\n /**\n * Sends message via the bridge channel.\n * @param {string} to The id of the endpoint that should receive the\n * message. If \"\" the message will be sent to all participants.\n * @param {object} payload The payload of the message.\n * @throws NetworkError or InvalidStateError or Error if the operation\n * fails or there is no data channel created.\n */\n sendChannelMessage(to, payload) {\n if (this._channel) {\n this._channel.sendMessage(to, payload);\n } else {\n throw new Error('Channel support is disabled!');\n }\n }\n\n /**\n * Selects a new value for \"lastN\". The requested amount of videos are going\n * to be delivered after the value is in effect. Set to -1 for unlimited or\n * all available videos.\n * @param {number} value the new value for lastN.\n */\n setLastN(value) {\n if (this._lastN !== value) {\n this._lastN = value;\n if (this._channel && this._channelOpen) {\n this._channel.sendSetLastNMessage(value);\n }\n this.eventEmitter.emit(RTCEvents.LASTN_VALUE_CHANGED, value);\n }\n }\n\n /**\n * Indicates if the endpoint id is currently included in the last N.\n * @param {string} id The endpoint id that we check for last N.\n * @returns {boolean} true if the endpoint id is in the last N or if we\n * don't have bridge channel support, otherwise we return false.\n */\n isInLastN(id) {\n return !this._lastNEndpoints // lastNEndpoints not initialised yet.\n || this._lastNEndpoints.indexOf(id) > -1;\n }\n\n /**\n * Updates the target audio output device for all remote audio tracks.\n *\n * @param {string} deviceId - The device id of the audio ouput device to\n * use for all remote tracks.\n * @private\n * @returns {void}\n */\n _updateAudioOutputForAudioTracks(deviceId) {\n const remoteAudioTracks = this.getRemoteTracks(MediaType.AUDIO);\n\n for (const track of remoteAudioTracks) {\n track.setAudioOutput(deviceId);\n }\n }\n}\n","/* global module */\n/**\n * Enumeration of the video types\n * @type {{CAMERA: string, DESKTOP: string}}\n */\nconst VideoType = {\n /**\n * The camera video type.\n */\n CAMERA: 'camera',\n\n /**\n * The desktop video type.\n */\n DESKTOP: 'desktop'\n};\n\nmodule.exports = VideoType;\n","import * as JitsiTrackErrors from './JitsiTrackErrors';\n\nconst TRACK_ERROR_TO_MESSAGE_MAP = {};\n\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.UNSUPPORTED_RESOLUTION]\n = 'Video resolution is not supported: ';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.CHROME_EXTENSION_INSTALLATION_ERROR]\n = 'Failed to install Chrome extension';\nTRACK_ERROR_TO_MESSAGE_MAP[\n JitsiTrackErrors.CHROME_EXTENSION_USER_GESTURE_REQUIRED]\n = 'Failed to install Chrome extension - installations can only be initiated'\n + ' by a user gesture.';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.CHROME_EXTENSION_USER_CANCELED]\n = 'User canceled Chrome\\'s screen sharing prompt';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.CHROME_EXTENSION_GENERIC_ERROR]\n = 'Unknown error from Chrome extension';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.ELECTRON_DESKTOP_PICKER_ERROR]\n = 'Unkown error from desktop picker';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.ELECTRON_DESKTOP_PICKER_NOT_FOUND]\n = 'Failed to detect desktop picker';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.GENERAL]\n = 'Generic getUserMedia error';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.PERMISSION_DENIED]\n = 'User denied permission to use device(s): ';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.NOT_FOUND]\n = 'Requested device(s) was/were not found: ';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.CONSTRAINT_FAILED]\n = 'Constraint could not be satisfied: ';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.TRACK_IS_DISPOSED]\n = 'Track has been already disposed';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.TRACK_NO_STREAM_FOUND]\n = 'Track does not have an associated Media Stream';\n\n// FIXME: Using prototype inheritance because otherwise instanceof is not\n// working properly (see https://github.com/babel/babel/issues/3083)\n\n/**\n *\n * Represents an error that occurred to a JitsiTrack. Can represent various\n * types of errors. For error descriptions (@see JitsiTrackErrors).\n *\n * @extends Error\n *\n *\n * @constructor\n * @param {Object|string} error - error object or error name\n * @param {Object|string} (options) - getUserMedia constraints object or\n * error message\n * @param {('audio'|'video'|'desktop'|'screen'|'audiooutput')[]} (devices) -\n * list of getUserMedia requested devices\n */\nfunction JitsiTrackError(error, options, devices) {\n if (typeof error === 'object' && typeof error.name !== 'undefined') {\n /**\n * Additional information about original getUserMedia error\n * and constraints.\n * @type {{\n * error: Object,\n * constraints: Object,\n * devices: Array.<'audio'|'video'|'desktop'|'screen'>\n * }}\n */\n this.gum = {\n error,\n constraints: options,\n devices: devices && Array.isArray(devices)\n ? devices.slice(0)\n : undefined\n };\n\n switch (error.name) {\n case 'NotAllowedError':\n case 'PermissionDeniedError':\n case 'SecurityError':\n this.name = JitsiTrackErrors.PERMISSION_DENIED;\n this.message\n = TRACK_ERROR_TO_MESSAGE_MAP[this.name]\n + (this.gum.devices || []).join(', ');\n break;\n case 'DevicesNotFoundError':\n case 'NotFoundError':\n this.name = JitsiTrackErrors.NOT_FOUND;\n this.message\n = TRACK_ERROR_TO_MESSAGE_MAP[this.name]\n + (this.gum.devices || []).join(', ');\n break;\n case 'ConstraintNotSatisfiedError':\n case 'OverconstrainedError': {\n const constraintName = error.constraintName || error.constraint;\n\n // we treat deviceId as unsupported resolution, as we want to\n // retry and finally if everything fails to remove deviceId from\n // mandatory constraints\n if (options\n && options.video\n && (!devices || devices.indexOf('video') > -1)\n && (constraintName === 'minWidth'\n || constraintName === 'maxWidth'\n || constraintName === 'minHeight'\n || constraintName === 'maxHeight'\n || constraintName === 'width'\n || constraintName === 'height'\n || constraintName === 'deviceId')) {\n this.name = JitsiTrackErrors.UNSUPPORTED_RESOLUTION;\n this.message\n = TRACK_ERROR_TO_MESSAGE_MAP[this.name]\n + getResolutionFromFailedConstraint(\n constraintName,\n options);\n } else {\n this.name = JitsiTrackErrors.CONSTRAINT_FAILED;\n this.message\n = TRACK_ERROR_TO_MESSAGE_MAP[this.name]\n + error.constraintName;\n }\n break;\n }\n\n default:\n this.name = JitsiTrackErrors.GENERAL;\n this.message\n = error.message || TRACK_ERROR_TO_MESSAGE_MAP[this.name];\n break;\n }\n } else if (typeof error === 'string') {\n if (TRACK_ERROR_TO_MESSAGE_MAP[error]) {\n this.name = error;\n this.message = options || TRACK_ERROR_TO_MESSAGE_MAP[error];\n } else {\n // this is some generic error that do not fit any of our\n // pre-defined errors, so don't give it any specific name, just\n // store message\n this.message = error;\n }\n } else {\n throw new Error('Invalid arguments');\n }\n\n this.stack = error.stack || (new Error()).stack;\n}\n\nJitsiTrackError.prototype = Object.create(Error.prototype);\nJitsiTrackError.prototype.constructor = JitsiTrackError;\n\n/**\n * Gets failed resolution constraint from corresponding object.\n * @param {string} failedConstraintName\n * @param {Object} constraints\n * @returns {string|number}\n */\nfunction getResolutionFromFailedConstraint(failedConstraintName, constraints) {\n if (constraints && constraints.video && constraints.video.mandatory) {\n switch (failedConstraintName) {\n case 'width':\n return constraints.video.mandatory.minWidth;\n case 'height':\n return constraints.video.mandatory.minHeight;\n default:\n return constraints.video.mandatory[failedConstraintName] || '';\n }\n }\n\n return '';\n}\n\nexport default JitsiTrackError;\n","/**\n * The media track was removed to the conference.\n */\nexport const LOCAL_TRACK_STOPPED = 'track.stopped';\n\n/**\n * Audio levels of a this track was changed.\n * The first argument is a number with audio level value in range [0, 1].\n * The second argument is a TraceablePeerConnection which is the peer\n * connection which measured the audio level (one audio track can be added\n * to multiple peer connection at the same time). This argument is optional for\n * local tracks for which we can measure audio level without the peer\n * connection (the value will be undefined).\n *\n * NOTE The second argument should be treated as library internal and can be\n * removed at any time.\n */\nexport const TRACK_AUDIO_LEVEL_CHANGED = 'track.audioLevelsChanged';\n\n/**\n * The audio output of the track was changed.\n */\nexport const TRACK_AUDIO_OUTPUT_CHANGED = 'track.audioOutputChanged';\n\n/**\n * A media track mute status was changed.\n */\nexport const TRACK_MUTE_CHANGED = 'track.trackMuteChanged';\n\n/**\n * The video type(\"camera\" or \"desktop\") of the track was changed.\n */\nexport const TRACK_VIDEOTYPE_CHANGED = 'track.videoTypeChanged';\n\n/**\n * Indicates that the track is not receiving any data even though we expect it\n * to receive data (i.e. the stream is not stopped).\n */\nexport const NO_DATA_FROM_SOURCE = 'track.no_data_from_source';\n","/**\n * The errors for the conference.\n */\n\n/**\n * Indicates that client must be authenticated to create the conference.\n */\nexport const AUTHENTICATION_REQUIRED = 'conference.authenticationRequired';\n\n/**\n * Indicates that chat error occurred.\n */\nexport const CHAT_ERROR = 'conference.chatError';\n\n/**\n * Indicates that conference has been destroyed.\n */\nexport const CONFERENCE_DESTROYED = 'conference.destroyed';\n\n/**\n * Indicates that max users limit has been reached.\n */\nexport const CONFERENCE_MAX_USERS = 'conference.max_users';\n\n/**\n * Indicates that a connection error occurred when trying to join a conference.\n */\nexport const CONNECTION_ERROR = 'conference.connectionError';\n\n/**\n * Indicates that a connection error is due to not allowed,\n * occurred when trying to join a conference.\n */\nexport const NOT_ALLOWED_ERROR = 'conference.connectionError.notAllowed';\n\n/**\n * Indicates that focus error happened.\n */\nexport const FOCUS_DISCONNECTED = 'conference.focusDisconnected';\n\n/**\n * Indicates that focus left the conference.\n */\nexport const FOCUS_LEFT = 'conference.focusLeft';\n\n/**\n * Indicates that graceful shutdown happened.\n */\nexport const GRACEFUL_SHUTDOWN = 'conference.gracefulShutdown';\n\n/**\n * Indicates that the versions of the server side components are incompatible\n * with the client side.\n */\nexport const INCOMPATIBLE_SERVER_VERSIONS\n = 'conference.incompatible_server_versions';\n\n/**\n * Indicates that offer/answer had failed.\n */\nexport const OFFER_ANSWER_FAILED = 'conference.offerAnswerFailed';\n\n/**\n * Indicates that password cannot be set for this conference.\n */\nexport const PASSWORD_NOT_SUPPORTED = 'conference.passwordNotSupported';\n\n/**\n * Indicates that a password is required in order to join the conference.\n */\nexport const PASSWORD_REQUIRED = 'conference.passwordRequired';\n\n/**\n * Indicates that reservation system returned error.\n */\nexport const RESERVATION_ERROR = 'conference.reservationError';\n\n/**\n * Indicates that the conference setup failed.\n */\nexport const SETUP_FAILED = 'conference.setup_failed';\n\n/**\n * Indicates that there is no available videobridge.\n */\nexport const VIDEOBRIDGE_NOT_AVAILABLE = 'conference.videobridgeNotAvailable';\n","/* global $ */\n\nimport SDPUtil from './SDPUtil';\n\n/**\n *\n * @param sdp\n */\nexport default function SDP(sdp) {\n const media = sdp.split('\\r\\nm=');\n\n for (let i = 1, length = media.length; i < length; i++) {\n let mediaI = `m=${media[i]}`;\n\n if (i !== length - 1) {\n mediaI += '\\r\\n';\n }\n media[i] = mediaI;\n }\n const session = `${media.shift()}\\r\\n`;\n\n this.media = media;\n this.raw = session + media.join('');\n this.session = session;\n}\n\n/**\n * A flag will make {@link transportToJingle} and {@link jingle2media} replace\n * ICE candidates IPs with invalid value of '1.1.1.1' which will cause ICE\n * failure. The flag is used in the automated testing.\n * @type {boolean}\n */\nSDP.prototype.failICE = false;\n\n/**\n * Whether or not to remove TCP ice candidates when translating from/to jingle.\n * @type {boolean}\n */\nSDP.prototype.removeTcpCandidates = false;\n\n/**\n * Whether or not to remove UDP ice candidates when translating from/to jingle.\n * @type {boolean}\n */\nSDP.prototype.removeUdpCandidates = false;\n\n/**\n * Returns map of MediaChannel mapped per channel idx.\n */\nSDP.prototype.getMediaSsrcMap = function() {\n const self = this;\n const mediaSSRCs = {};\n let tmp;\n\n for (let mediaindex = 0; mediaindex < self.media.length; mediaindex++) {\n tmp = SDPUtil.findLines(self.media[mediaindex], 'a=ssrc:');\n const mid\n = SDPUtil.parseMID(\n SDPUtil.findLine(self.media[mediaindex], 'a=mid:'));\n const media = {\n mediaindex,\n mid,\n ssrcs: {},\n ssrcGroups: []\n };\n\n mediaSSRCs[mediaindex] = media;\n tmp.forEach(line => {\n const linessrc = line.substring(7).split(' ')[0];\n\n // allocate new ChannelSsrc\n\n if (!media.ssrcs[linessrc]) {\n media.ssrcs[linessrc] = {\n ssrc: linessrc,\n lines: []\n };\n }\n media.ssrcs[linessrc].lines.push(line);\n });\n tmp = SDPUtil.findLines(self.media[mediaindex], 'a=ssrc-group:');\n tmp.forEach(line => {\n const idx = line.indexOf(' ');\n const semantics = line.substr(0, idx).substr(13);\n const ssrcs = line.substr(14 + semantics.length).split(' ');\n\n if (ssrcs.length) {\n media.ssrcGroups.push({\n semantics,\n ssrcs\n });\n }\n });\n }\n\n return mediaSSRCs;\n};\n\n/**\n * Returns true if this SDP contains given SSRC.\n * @param ssrc the ssrc to check.\n * @returns {boolean} true if this SDP contains given SSRC.\n */\nSDP.prototype.containsSSRC = function(ssrc) {\n // FIXME this code is really strange - improve it if you can\n const medias = this.getMediaSsrcMap();\n let result = false;\n\n Object.keys(medias).forEach(mediaindex => {\n if (result) {\n return;\n }\n if (medias[mediaindex].ssrcs[ssrc]) {\n result = true;\n }\n });\n\n return result;\n};\n\n// remove iSAC and CN from SDP\nSDP.prototype.mangle = function() {\n let i, j, lines, mline, newdesc, rtpmap;\n\n for (i = 0; i < this.media.length; i++) {\n lines = this.media[i].split('\\r\\n');\n lines.pop(); // remove empty last element\n mline = SDPUtil.parseMLine(lines.shift());\n if (mline.media !== 'audio') {\n continue; // eslint-disable-line no-continue\n }\n newdesc = '';\n mline.fmt.length = 0;\n for (j = 0; j < lines.length; j++) {\n if (lines[j].substr(0, 9) === 'a=rtpmap:') {\n rtpmap = SDPUtil.parseRTPMap(lines[j]);\n if (rtpmap.name === 'CN' || rtpmap.name === 'ISAC') {\n continue; // eslint-disable-line no-continue\n }\n mline.fmt.push(rtpmap.id);\n }\n newdesc += `${lines[j]}\\r\\n`;\n }\n this.media[i] = `${SDPUtil.buildMLine(mline)}\\r\\n${newdesc}`;\n }\n this.raw = this.session + this.media.join('');\n};\n\n// remove lines matching prefix from session section\nSDP.prototype.removeSessionLines = function(prefix) {\n const self = this;\n const lines = SDPUtil.findLines(this.session, prefix);\n\n lines.forEach(line => {\n self.session = self.session.replace(`${line}\\r\\n`, '');\n });\n this.raw = this.session + this.media.join('');\n\n return lines;\n};\n\n// remove lines matching prefix from a media section specified by mediaindex\n// TODO: non-numeric mediaindex could match mid\nSDP.prototype.removeMediaLines = function(mediaindex, prefix) {\n const self = this;\n const lines = SDPUtil.findLines(this.media[mediaindex], prefix);\n\n lines.forEach(line => {\n self.media[mediaindex]\n = self.media[mediaindex].replace(`${line}\\r\\n`, '');\n });\n this.raw = this.session + this.media.join('');\n\n return lines;\n};\n\n// add content's to a jingle element\nSDP.prototype.toJingle = function(elem, thecreator) {\n let i, j, k, lines, mline, rtpmap, ssrc, tmp;\n\n // new bundle plan\n\n lines = SDPUtil.findLines(this.session, 'a=group:');\n if (lines.length) {\n for (i = 0; i < lines.length; i++) {\n tmp = lines[i].split(' ');\n const semantics = tmp.shift().substr(8);\n\n elem.c('group', { xmlns: 'urn:xmpp:jingle:apps:grouping:0',\n semantics });\n for (j = 0; j < tmp.length; j++) {\n elem.c('content', { name: tmp[j] }).up();\n }\n elem.up();\n }\n }\n for (i = 0; i < this.media.length; i++) {\n mline = SDPUtil.parseMLine(this.media[i].split('\\r\\n')[0]);\n if (!(mline.media === 'audio'\n || mline.media === 'video'\n || mline.media === 'application')) {\n continue; // eslint-disable-line no-continue\n }\n const assrcline = SDPUtil.findLine(this.media[i], 'a=ssrc:');\n\n if (assrcline) {\n ssrc = assrcline.substring(7).split(' ')[0]; // take the first\n } else {\n ssrc = false;\n }\n\n elem.c('content', { creator: thecreator,\n name: mline.media });\n const amidline = SDPUtil.findLine(this.media[i], 'a=mid:');\n\n if (amidline) {\n // prefer identifier from a=mid if present\n const mid = SDPUtil.parseMID(amidline);\n\n elem.attrs({ name: mid });\n }\n\n if (SDPUtil.findLine(this.media[i], 'a=rtpmap:').length) {\n elem.c('description',\n { xmlns: 'urn:xmpp:jingle:apps:rtp:1',\n media: mline.media });\n if (ssrc) {\n elem.attrs({ ssrc });\n }\n for (j = 0; j < mline.fmt.length; j++) {\n rtpmap\n = SDPUtil.findLine(\n this.media[i],\n `a=rtpmap:${mline.fmt[j]}`);\n elem.c('payload-type', SDPUtil.parseRTPMap(rtpmap));\n\n // put any 'a=fmtp:' + mline.fmt[j] lines into \n const afmtpline\n = SDPUtil.findLine(\n this.media[i],\n `a=fmtp:${mline.fmt[j]}`);\n\n if (afmtpline) {\n tmp = SDPUtil.parseFmtp(afmtpline);\n\n // eslint-disable-next-line max-depth\n for (k = 0; k < tmp.length; k++) {\n elem.c('parameter', tmp[k]).up();\n }\n }\n\n // XEP-0293 -- map a=rtcp-fb\n this.rtcpFbToJingle(i, elem, mline.fmt[j]);\n\n elem.up();\n }\n const crypto\n = SDPUtil.findLines(this.media[i], 'a=crypto:', this.session);\n\n if (crypto.length) {\n elem.c('encryption', { required: 1 });\n crypto.forEach(\n line => elem.c('crypto', SDPUtil.parseCrypto(line)).up());\n elem.up(); // end of encryption\n }\n\n if (ssrc) {\n const ssrcMap = SDPUtil.parseSSRC(this.media[i]);\n\n for (const [ availableSsrc, ssrcParameters ] of ssrcMap) {\n elem.c('source', {\n ssrc: availableSsrc,\n xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0'\n });\n\n ssrcParameters.forEach(ssrcSdpLine => {\n // get everything after first space\n const idx = ssrcSdpLine.indexOf(' ');\n const kv = ssrcSdpLine.substr(idx + 1);\n\n elem.c('parameter');\n if (kv.indexOf(':') === -1) {\n elem.attrs({ name: kv });\n } else {\n const name = kv.split(':', 2)[0];\n\n elem.attrs({ name });\n\n let v = kv.split(':', 2)[1];\n\n v = SDPUtil.filterSpecialChars(v);\n elem.attrs({ value: v });\n }\n elem.up();\n });\n\n elem.up();\n }\n\n // XEP-0339 handle ssrc-group attributes\n const ssrcGroupLines\n = SDPUtil.findLines(this.media[i], 'a=ssrc-group:');\n\n ssrcGroupLines.forEach(line => {\n const idx = line.indexOf(' ');\n const semantics = line.substr(0, idx).substr(13);\n const ssrcs = line.substr(14 + semantics.length).split(' ');\n\n if (ssrcs.length) {\n elem.c('ssrc-group', { semantics,\n xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0' });\n ssrcs.forEach(s => elem.c('source', { ssrc: s }).up());\n elem.up();\n }\n });\n }\n\n const ridLines = SDPUtil.findLines(this.media[i], 'a=rid');\n\n if (ridLines.length) {\n // Map a line which looks like \"a=rid:2 send\" to just\n // the rid (\"2\")\n const rids = ridLines\n .map(ridLine => ridLine.split(':')[1])\n .map(ridInfo => ridInfo.split(' ')[0]);\n\n rids.forEach(rid => {\n elem.c('source', {\n rid,\n xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0'\n });\n elem.up();\n });\n const unifiedSimulcast\n = SDPUtil.findLine(this.media[i], 'a=simulcast');\n\n if (unifiedSimulcast) {\n elem.c('rid-group', {\n semantics: 'SIM',\n xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0'\n });\n rids.forEach(rid => {\n elem.c('source', { rid }).up();\n });\n elem.up();\n }\n }\n\n if (SDPUtil.findLine(this.media[i], 'a=rtcp-mux')) {\n elem.c('rtcp-mux').up();\n }\n\n // XEP-0293 -- map a=rtcp-fb:*\n this.rtcpFbToJingle(i, elem, '*');\n\n // XEP-0294\n lines = SDPUtil.findLines(this.media[i], 'a=extmap:');\n if (lines.length) {\n for (j = 0; j < lines.length; j++) {\n tmp = SDPUtil.parseExtmap(lines[j]);\n elem.c('rtp-hdrext', {\n xmlns: 'urn:xmpp:jingle:apps:rtp:rtp-hdrext:0',\n uri: tmp.uri,\n id: tmp.value\n });\n\n // eslint-disable-next-line max-depth\n if (tmp.hasOwnProperty('direction')) {\n\n // eslint-disable-next-line max-depth\n switch (tmp.direction) {\n case 'sendonly':\n elem.attrs({ senders: 'responder' });\n break;\n case 'recvonly':\n elem.attrs({ senders: 'initiator' });\n break;\n case 'sendrecv':\n elem.attrs({ senders: 'both' });\n break;\n case 'inactive':\n elem.attrs({ senders: 'none' });\n break;\n }\n }\n\n // TODO: handle params\n elem.up();\n }\n }\n elem.up(); // end of description\n }\n\n // map ice-ufrag/pwd, dtls fingerprint, candidates\n this.transportToJingle(i, elem);\n\n const m = this.media[i];\n\n if (SDPUtil.findLine(m, 'a=sendrecv', this.session)) {\n elem.attrs({ senders: 'both' });\n } else if (SDPUtil.findLine(m, 'a=sendonly', this.session)) {\n elem.attrs({ senders: 'initiator' });\n } else if (SDPUtil.findLine(m, 'a=recvonly', this.session)) {\n elem.attrs({ senders: 'responder' });\n } else if (SDPUtil.findLine(m, 'a=inactive', this.session)) {\n elem.attrs({ senders: 'none' });\n }\n if (mline.port === '0') {\n // estos hack to reject an m-line\n elem.attrs({ senders: 'rejected' });\n }\n elem.up(); // end of content\n }\n elem.up();\n\n return elem;\n};\n\nSDP.prototype.transportToJingle = function(mediaindex, elem) {\n let tmp;\n const self = this;\n\n elem.c('transport');\n\n // XEP-0343 DTLS/SCTP\n const sctpmap\n = SDPUtil.findLine(this.media[mediaindex], 'a=sctpmap:', self.session);\n\n if (sctpmap) {\n const sctpAttrs = SDPUtil.parseSCTPMap(sctpmap);\n\n elem.c('sctpmap', {\n xmlns: 'urn:xmpp:jingle:transports:dtls-sctp:1',\n number: sctpAttrs[0], /* SCTP port */\n protocol: sctpAttrs[1] /* protocol */\n });\n\n // Optional stream count attribute\n if (sctpAttrs.length > 2) {\n elem.attrs({ streams: sctpAttrs[2] });\n }\n elem.up();\n }\n\n // XEP-0320\n const fingerprints\n = SDPUtil.findLines(\n this.media[mediaindex],\n 'a=fingerprint:',\n this.session);\n\n fingerprints.forEach(line => {\n tmp = SDPUtil.parseFingerprint(line);\n tmp.xmlns = 'urn:xmpp:jingle:apps:dtls:0';\n elem.c('fingerprint').t(tmp.fingerprint);\n delete tmp.fingerprint;\n\n // eslint-disable-next-line no-param-reassign\n line\n = SDPUtil.findLine(\n self.media[mediaindex],\n 'a=setup:',\n self.session);\n if (line) {\n tmp.setup = line.substr(8);\n }\n elem.attrs(tmp);\n elem.up(); // end of fingerprint\n });\n tmp = SDPUtil.iceparams(this.media[mediaindex], this.session);\n if (tmp) {\n tmp.xmlns = 'urn:xmpp:jingle:transports:ice-udp:1';\n elem.attrs(tmp);\n\n // XEP-0176\n const lines\n = SDPUtil.findLines(\n this.media[mediaindex],\n 'a=candidate:',\n this.session);\n\n if (lines.length) { // add any a=candidate lines\n lines.forEach(line => {\n const candidate = SDPUtil.candidateToJingle(line);\n\n if (self.failICE) {\n candidate.ip = '1.1.1.1';\n }\n const protocol\n = candidate && typeof candidate.protocol === 'string'\n ? candidate.protocol.toLowerCase()\n : '';\n\n if ((self.removeTcpCandidates\n && (protocol === 'tcp' || protocol === 'ssltcp'))\n || (self.removeUdpCandidates && protocol === 'udp')) {\n return;\n }\n elem.c('candidate', candidate).up();\n });\n }\n }\n elem.up(); // end of transport\n};\n\n// XEP-0293\nSDP.prototype.rtcpFbToJingle = function(mediaindex, elem, payloadtype) {\n const lines\n = SDPUtil.findLines(\n this.media[mediaindex],\n `a=rtcp-fb:${payloadtype}`);\n\n lines.forEach(line => {\n const tmp = SDPUtil.parseRTCPFB(line);\n\n if (tmp.type === 'trr-int') {\n elem.c('rtcp-fb-trr-int', {\n xmlns: 'urn:xmpp:jingle:apps:rtp:rtcp-fb:0',\n value: tmp.params[0]\n });\n elem.up();\n } else {\n elem.c('rtcp-fb', {\n xmlns: 'urn:xmpp:jingle:apps:rtp:rtcp-fb:0',\n type: tmp.type\n });\n if (tmp.params.length > 0) {\n elem.attrs({ 'subtype': tmp.params[0] });\n }\n elem.up();\n }\n });\n};\n\nSDP.prototype.rtcpFbFromJingle = function(elem, payloadtype) { // XEP-0293\n let media = '';\n let tmp\n = elem.find(\n '>rtcp-fb-trr-int[xmlns=\"urn:xmpp:jingle:apps:rtp:rtcp-fb:0\"]');\n\n if (tmp.length) {\n media += 'a=rtcp-fb:* trr-int ';\n if (tmp.attr('value')) {\n media += tmp.attr('value');\n } else {\n media += '0';\n }\n media += '\\r\\n';\n }\n tmp = elem.find('>rtcp-fb[xmlns=\"urn:xmpp:jingle:apps:rtp:rtcp-fb:0\"]');\n tmp.each(function() {\n /* eslint-disable no-invalid-this */\n media += `a=rtcp-fb:${payloadtype} ${$(this).attr('type')}`;\n if ($(this).attr('subtype')) {\n media += ` ${$(this).attr('subtype')}`;\n }\n media += '\\r\\n';\n\n /* eslint-enable no-invalid-this */\n });\n\n return media;\n};\n\n// construct an SDP from a jingle stanza\nSDP.prototype.fromJingle = function(jingle) {\n const self = this;\n\n this.raw = 'v=0\\r\\n'\n + 'o=- 1923518516 2 IN IP4 0.0.0.0\\r\\n'// FIXME\n + 's=-\\r\\n'\n + 't=0 0\\r\\n';\n\n // http://tools.ietf.org/html/draft-ietf-mmusic-sdp-bundle-negotiation-04\n // #section-8\n const groups\n = $(jingle).find('>group[xmlns=\"urn:xmpp:jingle:apps:grouping:0\"]');\n\n if (groups.length) {\n groups.each((idx, group) => {\n const contents\n = $(group)\n .find('>content')\n .map((_, content) => content.getAttribute('name'))\n .get();\n\n if (contents.length > 0) {\n self.raw\n += `a=group:${\n group.getAttribute('semantics')\n || group.getAttribute('type')} ${\n contents.join(' ')}\\r\\n`;\n }\n });\n }\n\n this.session = this.raw;\n jingle.find('>content').each(function() {\n // eslint-disable-next-line no-invalid-this\n const m = self.jingle2media($(this));\n\n self.media.push(m);\n });\n\n // reconstruct msid-semantic -- apparently not necessary\n /*\n var msid = SDPUtil.parseSSRC(this.raw);\n if (msid.hasOwnProperty('mslabel')) {\n this.session += \"a=msid-semantic: WMS \" + msid.mslabel + \"\\r\\n\";\n }\n */\n\n this.raw = this.session + this.media.join('');\n};\n\n// translate a jingle content element into an an SDP media part\nSDP.prototype.jingle2media = function(content) {\n const desc = content.find('description');\n let media = '';\n const self = this;\n const sctp = content.find(\n '>transport>sctpmap[xmlns=\"urn:xmpp:jingle:transports:dtls-sctp:1\"]');\n\n let tmp = { media: desc.attr('media') };\n\n tmp.port = '1';\n if (content.attr('senders') === 'rejected') {\n // estos hack to reject an m-line.\n tmp.port = '0';\n }\n if (content.find('>transport>fingerprint').length\n || desc.find('encryption').length) {\n tmp.proto = sctp.length ? 'DTLS/SCTP' : 'RTP/SAVPF';\n } else {\n tmp.proto = 'RTP/AVPF';\n }\n if (sctp.length) {\n media += `m=application ${tmp.port} DTLS/SCTP ${\n sctp.attr('number')}\\r\\n`;\n media += `a=sctpmap:${sctp.attr('number')} ${sctp.attr('protocol')}`;\n\n const streamCount = sctp.attr('streams');\n\n if (streamCount) {\n media += ` ${streamCount}\\r\\n`;\n } else {\n media += '\\r\\n';\n }\n } else {\n tmp.fmt\n = desc\n .find('payload-type')\n .map(function() {\n // eslint-disable-next-line no-invalid-this\n return this.getAttribute('id');\n })\n .get();\n media += `${SDPUtil.buildMLine(tmp)}\\r\\n`;\n }\n\n media += 'c=IN IP4 0.0.0.0\\r\\n';\n if (!sctp.length) {\n media += 'a=rtcp:1 IN IP4 0.0.0.0\\r\\n';\n }\n tmp\n = content.find(\n '>transport[xmlns=\"urn:xmpp:jingle:transports:ice-udp:1\"]');\n if (tmp.length) {\n if (tmp.attr('ufrag')) {\n media += `${SDPUtil.buildICEUfrag(tmp.attr('ufrag'))}\\r\\n`;\n }\n if (tmp.attr('pwd')) {\n media += `${SDPUtil.buildICEPwd(tmp.attr('pwd'))}\\r\\n`;\n }\n tmp.find('>fingerprint').each(function() {\n /* eslint-disable no-invalid-this */\n // FIXME: check namespace at some point\n media += `a=fingerprint:${this.getAttribute('hash')}`;\n media += ` ${$(this).text()}`;\n media += '\\r\\n';\n if (this.getAttribute('setup')) {\n media += `a=setup:${this.getAttribute('setup')}\\r\\n`;\n }\n\n /* eslint-enable no-invalid-this */\n });\n }\n switch (content.attr('senders')) {\n case 'initiator':\n media += 'a=sendonly\\r\\n';\n break;\n case 'responder':\n media += 'a=recvonly\\r\\n';\n break;\n case 'none':\n media += 'a=inactive\\r\\n';\n break;\n case 'both':\n media += 'a=sendrecv\\r\\n';\n break;\n }\n media += `a=mid:${content.attr('name')}\\r\\n`;\n\n // \n // see http://code.google.com/p/libjingle/issues/detail?id=309 -- no spec\n // though\n // and http://mail.jabber.org/pipermail/jingle/2011-December/001761.html\n if (desc.find('rtcp-mux').length) {\n media += 'a=rtcp-mux\\r\\n';\n }\n\n if (desc.find('encryption').length) {\n desc.find('encryption>crypto').each(function() {\n /* eslint-disable no-invalid-this */\n media += `a=crypto:${this.getAttribute('tag')}`;\n media += ` ${this.getAttribute('crypto-suite')}`;\n media += ` ${this.getAttribute('key-params')}`;\n if (this.getAttribute('session-params')) {\n media += ` ${this.getAttribute('session-params')}`;\n }\n media += '\\r\\n';\n\n /* eslint-enable no-invalid-this */\n });\n }\n desc.find('payload-type').each(function() {\n /* eslint-disable no-invalid-this */\n media += `${SDPUtil.buildRTPMap(this)}\\r\\n`;\n if ($(this).find('>parameter').length) {\n media += `a=fmtp:${this.getAttribute('id')} `;\n media\n += $(this)\n .find('parameter')\n .map(function() {\n const name = this.getAttribute('name');\n\n return (\n (name ? `${name}=` : '')\n + this.getAttribute('value'));\n })\n .get()\n .join('; ');\n media += '\\r\\n';\n }\n\n // xep-0293\n media += self.rtcpFbFromJingle($(this), this.getAttribute('id'));\n\n /* eslint-enable no-invalid-this */\n });\n\n // xep-0293\n media += self.rtcpFbFromJingle(desc, '*');\n\n // xep-0294\n tmp\n = desc.find(\n '>rtp-hdrext[xmlns=\"urn:xmpp:jingle:apps:rtp:rtp-hdrext:0\"]');\n tmp.each(function() {\n /* eslint-disable no-invalid-this */\n media\n += `a=extmap:${this.getAttribute('id')} ${\n this.getAttribute('uri')}\\r\\n`;\n\n /* eslint-enable no-invalid-this */\n });\n\n content\n .find(\n '>transport[xmlns=\"urn:xmpp:jingle:transports:ice-udp:1\"]'\n + '>candidate')\n .each(function() {\n /* eslint-disable no-invalid-this */\n let protocol = this.getAttribute('protocol');\n\n protocol\n = typeof protocol === 'string' ? protocol.toLowerCase() : '';\n\n if ((self.removeTcpCandidates\n && (protocol === 'tcp' || protocol === 'ssltcp'))\n || (self.removeUdpCandidates && protocol === 'udp')) {\n return;\n } else if (self.failICE) {\n this.setAttribute('ip', '1.1.1.1');\n }\n\n media += SDPUtil.candidateFromJingle(this);\n\n /* eslint-enable no-invalid-this */\n });\n\n // XEP-0339 handle ssrc-group attributes\n content\n .find('description>ssrc-group[xmlns=\"urn:xmpp:jingle:apps:rtp:ssma:0\"]')\n .each(function() {\n /* eslint-disable no-invalid-this */\n const semantics = this.getAttribute('semantics');\n const ssrcs\n = $(this)\n .find('>source')\n .map(function() {\n return this.getAttribute('ssrc');\n })\n .get();\n\n if (ssrcs.length) {\n media += `a=ssrc-group:${semantics} ${ssrcs.join(' ')}\\r\\n`;\n }\n\n /* eslint-enable no-invalid-this */\n });\n\n tmp\n = content.find(\n 'description>source[xmlns=\"urn:xmpp:jingle:apps:rtp:ssma:0\"]');\n tmp.each(function() {\n /* eslint-disable no-invalid-this */\n const ssrc = this.getAttribute('ssrc');\n\n // eslint-disable-next-line newline-per-chained-call\n $(this).find('>parameter').each(function() {\n const name = this.getAttribute('name');\n let value = this.getAttribute('value');\n\n value = SDPUtil.filterSpecialChars(value);\n media += `a=ssrc:${ssrc} ${name}`;\n if (value && value.length) {\n media += `:${value}`;\n }\n media += '\\r\\n';\n });\n\n /* eslint-enable no-invalid-this */\n });\n\n return media;\n};\n","// TODO: Maybe fix the values to 'Chrome', 'Internet Explorer', etc. Currently\n// this values needs to be as they are becuse they are going to analytics,\n// callstats, etc.\n\nexport const CHROME = 'chrome';\n\nexport const OPERA = 'opera';\n\nexport const FIREFOX = 'firefox';\n\nexport const INTERNET_EXPLORER = 'iexplorer';\n\nexport const EDGE = 'edge';\n\nexport const SAFARI = 'safari';\n\nexport const NWJS = 'nwjs';\n\nexport const ELECTRON = 'electron';\n\nexport const REACT_NATIVE = 'react-native';\n\nexport const UNKNOWN = 'unknown';\n","import bowser from 'bowser';\n\nimport {\n CHROME,\n OPERA,\n FIREFOX,\n INTERNET_EXPLORER,\n EDGE,\n SAFARI,\n NWJS,\n ELECTRON,\n REACT_NATIVE,\n UNKNOWN\n} from './browsers';\n\n/**\n * Maps the names of the browsers from bowser to the internal names defined in\n * ./browsers.js\n */\nconst bowserNameToJitsiName = {\n 'Chrome': CHROME,\n 'Chromium': CHROME,\n 'Opera': OPERA,\n 'Firefox': FIREFOX,\n 'Internet Explorer': INTERNET_EXPLORER,\n 'Microsoft Edge': EDGE,\n 'Safari': SAFARI\n};\n\n/**\n * Detects a Chromium based environent.\n * \n * NOTE: Here we cannot check solely for \"Chrome\" in the UA string and the\n * \"window.chrome\" property, because Edge has both, so we add an explicit\n * check for NOT Edge.\n *\n * @returns {Object|undefined} - The name (CHROME) and version.\n */\nfunction _detectChromiumBased() {\n const userAgent = navigator.userAgent;\n\n if (Boolean(window.chrome)\n && !userAgent.match(/Edge/) && userAgent.match(/Chrome/)) {\n const version = userAgent.match(/Chrome\\/([\\d.]+)/)[1];\n\n return {\n name: CHROME,\n version\n };\n }\n}\n\n/**\n * Detects Electron environment.\n *\n * @returns {Object|undefined} - The name (ELECTRON) and version.\n */\nfunction _detectElectron() {\n const userAgent = navigator.userAgent;\n\n if (userAgent.match(/Electron/)) {\n const version = userAgent.match(/Electron\\/([\\d.]+)/)[1];\n\n return {\n name: ELECTRON,\n version\n };\n }\n}\n\n/**\n * Detects NWJS environment.\n *\n * @returns {Object|undefined} - The name (NWJS) and version.\n */\nfunction _detectNWJS() {\n const userAgent = navigator.userAgent;\n\n if (userAgent.match(/JitsiMeetNW/)) {\n const version = userAgent.match(/JitsiMeetNW\\/([\\d.]+)/)[1];\n\n return {\n name: NWJS,\n version\n };\n }\n}\n\n/**\n * Detects React Native environment.\n * @returns {Object|undefined} - The name (REACT_NATIVE) and version.\n */\nfunction _detectReactNative() {\n const match\n = navigator.userAgent.match(/\\b(react[ \\t_-]*native)(?:\\/(\\S+))?/i);\n let version;\n\n // If we're remote debugging a React Native app, it may be treated as\n // Chrome. Check navigator.product as well and always return some version\n // even if we can't get the real one.\n\n if (match || navigator.product === 'ReactNative') {\n let name;\n\n if (match && match.length > 2) {\n name = match[1];\n version = match[2];\n }\n name || (name = 'react-native');\n version || (version = 'unknown');\n\n return {\n name: REACT_NATIVE,\n version\n };\n }\n}\n\n/**\n * Returns information about the current browser.\n *\n * @returns {Object} - The name and version of the browser.\n */\nfunction _detect() {\n let browserInfo;\n const detectors = [\n _detectReactNative,\n _detectElectron,\n _detectNWJS\n ];\n\n // Try all browser detectors\n for (let i = 0; i < detectors.length; i++) {\n browserInfo = detectors[i]();\n if (browserInfo) {\n return browserInfo;\n }\n }\n\n const { name, version } = bowser;\n\n if (name in bowserNameToJitsiName) {\n return {\n name: bowserNameToJitsiName[name],\n version\n };\n }\n\n // Detect other browsers with the Chrome engine, such as Vivaldi.\n browserInfo = _detectChromiumBased();\n if (browserInfo) {\n return browserInfo;\n }\n\n return {\n name: UNKNOWN,\n version: undefined\n };\n}\n\n/**\n * Implements browser detection.\n */\nexport default class BrowserDetection {\n /**\n * Creates new BrowserDetection instance.\n *\n * @param {Object} [browserInfo] - Information about the browser.\n * @param {string} browserInfo.name - The name of the browser.\n * @param {string} browserInfo.version - The version of the browser.\n */\n constructor(browserInfo) {\n let name, version;\n\n if (typeof browserInfo === 'undefined') {\n const detectedBrowserInfo = _detect();\n\n name = detectedBrowserInfo.name;\n version = detectedBrowserInfo.version;\n } else if (browserInfo.name in bowserNameToJitsiName) {\n name = bowserNameToJitsiName[browserInfo.name];\n version = browserInfo.version;\n } else {\n name = UNKNOWN;\n version = undefined;\n }\n\n this._name = name;\n this._version = version;\n }\n\n /**\n * Gets current browser name.\n * @returns {string}\n */\n getName() {\n return this._name;\n }\n\n /**\n * Checks if current browser is Chrome.\n * @returns {boolean}\n */\n isChrome() {\n return this._name === CHROME;\n }\n\n /**\n * Checks if current browser is Opera.\n * @returns {boolean}\n */\n isOpera() {\n return this._name === OPERA;\n }\n\n /**\n * Checks if current browser is Firefox.\n * @returns {boolean}\n */\n isFirefox() {\n return this._name === FIREFOX;\n }\n\n /**\n * Checks if current browser is Internet Explorer.\n * @returns {boolean}\n */\n isIExplorer() {\n return this._name === INTERNET_EXPLORER;\n }\n\n /**\n * Checks if current browser is Microsoft Edge.\n * @returns {boolean}\n */\n isEdge() {\n return this._name === EDGE;\n }\n\n /**\n * Checks if current browser is Safari.\n * @returns {boolean}\n */\n isSafari() {\n return this._name === SAFARI;\n }\n\n /**\n * Checks if current environment is NWJS.\n * @returns {boolean}\n */\n isNWJS() {\n return this._name === NWJS;\n }\n\n /**\n * Checks if current environment is Electron.\n * @returns {boolean}\n */\n isElectron() {\n return this._name === ELECTRON;\n }\n\n /**\n * Checks if current environment is React Native.\n * @returns {boolean}\n */\n isReactNative() {\n return this._name === REACT_NATIVE;\n }\n\n /**\n * Returns the version of the current browser.\n * @returns {string}\n */\n getVersion() {\n return this._version;\n }\n\n /**\n * Compares the passed version with the current browser version.\n * {@see https://github.com/lancedikson/bowser}\n */\n static compareVersions = bowser.compareVersions;\n\n /**\n * Compares the passed version with the current browser version.\n *\n * @param {*} version - The version to compare with. Anything different\n * than string will be converted to string.\n * @returns {number|undefined} - Returns 0 if the version is equal to the\n * current one, 1 if the version is greater than the current one, -1 if the\n * version is lower than the current one and undefined if the current\n * browser version is unknown.\n */\n compareVersion(version) {\n if (this._version) {\n return bowser.compareVersions([ String(version), this._version ]);\n }\n }\n\n /**\n * Compares the passed version with the current browser version.\n *\n * @param {*} version - The version to compare with. Anything different\n * than string will be converted to string.\n * @returns {boolean|undefined} - Returns true if the current version is\n * greater than the passed version and false otherwise. Returns undefined if\n * the current browser version is unknown.\n */\n isVersionGreaterThan(version) {\n return this.compareVersion(version) === -1;\n }\n\n /**\n * Compares the passed version with the current browser version.\n *\n * @param {*} version - The version to compare with. Anything different\n * than string will be converted to string.\n * @returns {boolean|undefined} - Returns true if the current version is\n * lower than the passed version and false otherwise. Returns undefined if\n * the current browser version is unknown.\n */\n isVersionLessThan(version) {\n return this.compareVersion(version) === 1;\n }\n\n /**\n * Compares the passed version with the current browser version.\n *\n * @param {*} version - The version to compare with. Anything different\n * than string will be converted to string.\n * @returns {boolean|undefined} - Returns true if the current version is\n * equal to the passed version and false otherwise. Returns undefined if\n * the current browser version is unknown.\n */\n isVersionEqualTo(version) {\n return this.compareVersion(version) === 0;\n }\n}\n","export * from './browser-capabilities';\nexport * from './browser-detection';\nexport * from './avatar';\n","/**\n * Status that video SIP GW service is available.\n * @type {string}\n */\nexport const STATUS_AVAILABLE = 'available';\n\n/**\n * Status that video SIP GW service is not available.\n * @type {string}\n */\nexport const STATUS_UNDEFINED = 'undefined';\n\n/**\n * Status that video SIP GW service is available but there are no free nodes\n * at the moment to serve new requests.\n * @type {string}\n */\nexport const STATUS_BUSY = 'busy';\n\n/**\n * Video SIP GW session state, currently running.\n * @type {string}\n */\nexport const STATE_ON = 'on';\n\n/**\n * Video SIP GW session state, currently stopped and not running.\n * @type {string}\n */\nexport const STATE_OFF = 'off';\n\n/**\n * Video SIP GW session state, currently is starting.\n * @type {string}\n */\nexport const STATE_PENDING = 'pending';\n\n/**\n * Video SIP GW session state, has observed some issues and is retrying at the\n * moment.\n * @type {string}\n */\nexport const STATE_RETRYING = 'retrying';\n\n/**\n * Video SIP GW session state, tried to start but it failed.\n * @type {string}\n */\nexport const STATE_FAILED = 'failed';\n\n/**\n * Error on trying to create video SIP GW session in conference where\n * there is no room connection (hasn't joined or has left the room).\n * @type {string}\n */\nexport const ERROR_NO_CONNECTION = 'error_no_connection';\n\n/**\n * Error on trying to create video SIP GW session with address for which\n * there is an already created session.\n * @type {string}\n */\nexport const ERROR_SESSION_EXISTS = 'error_session_already_exists';\n","/**\n * The events for the connection.\n */\n\n/**\n * Indicates that the connection has been disconnected. The event provides\n * the following parameters to its listeners:\n *\n * @param msg {string} a message associated with the disconnect such as the\n * last (known) error message\n */\nexport const CONNECTION_DISCONNECTED = 'connection.connectionDisconnected';\n\n/**\n * Indicates that the connection has been established. The event provides\n * the following parameters to its listeners:\n *\n * @param id {string} the ID of the local endpoint/participant/peer (within\n * the context of the established connection)\n */\nexport const CONNECTION_ESTABLISHED = 'connection.connectionEstablished';\n\n/**\n * Indicates that the connection has been failed for some reason. The event\n * provides the following parameters to its listeners:\n *\n * @param errType {JitsiConnectionErrors} the type of error associated with\n * the failure\n * @param errReason {string} the error (message) associated with the failure\n * @param credentials {object} the credentials used to connect (if any)\n * @param errReasonDetails {object} an optional object with details about\n * the error, like shard moving, suspending. Used for analytics purposes.\n */\nexport const CONNECTION_FAILED = 'connection.connectionFailed';\n\n/**\n * Indicates that the performed action cannot be executed because the\n * connection is not in the correct state(connected, disconnected, etc.)\n */\nexport const WRONG_STATE = 'connection.wrongState';\n","var parser = require('./parser');\nvar writer = require('./writer');\n\nexports.write = writer;\nexports.parse = parser.parse;\nexports.parseFmtpConfig = parser.parseFmtpConfig;\nexports.parseParams = parser.parseParams;\nexports.parsePayloads = parser.parsePayloads;\nexports.parseRemoteCandidates = parser.parseRemoteCandidates;\nexports.parseImageAttributes = parser.parseImageAttributes;\nexports.parseSimulcastStreamList = parser.parseSimulcastStreamList;\n","/**\n * Notifies about audio level in RTP statistics by SSRC.\n *\n * @param ssrc - The synchronization source identifier (SSRC) of the\n * endpoint/participant whose audio level is being reported.\n * @param {number} audioLevel - The audio level of ssrc according to\n * RTP statistics.\n * @param {boolean} isLocal - true if ssrc identifies the\n * local endpoint/participant; otherwise, false.\n */\nexport const AUDIO_LEVEL = 'statistics.audioLevel';\n\n/**\n * An event fired just before the statistics module gets disposes and it's\n * the last chance to submit some logs that will end up in stats services like\n * CallStats (if enabled).\n */\nexport const BEFORE_DISPOSED = 'statistics.before_disposed';\n\n/**\n * An event carrying all statistics by ssrc.\n */\nexport const BYTE_SENT_STATS = 'statistics.byte_sent_stats';\n\n/**\n * An event carrying connection statistics.\n *\n * @param {object} connectionStats - The connection statistics carried by the\n * event such as bandwidth, bitrate, packetLoss,\n * resolution, and transport.\n */\nexport const CONNECTION_STATS = 'statistics.connectionstats';\n","import EventEmitter from 'events';\n\n/**\n * The class implements basic event operations - add/remove listener.\n * NOTE: The purpose of the class is to be extended in order to add\n * this functionality to other classes.\n */\nexport default class Listenable {\n /**\n * Creates new instance.\n * @param {EventEmitter} eventEmitter\n * @constructor\n */\n constructor(eventEmitter = new EventEmitter()) {\n this.eventEmitter = eventEmitter;\n\n // aliases for addListener/removeListener\n this.addEventListener = this.on = this.addListener;\n this.removeEventListener = this.off = this.removeListener;\n }\n\n /**\n * Adds new listener.\n * @param {String} eventName the name of the event\n * @param {Function} listener the listener.\n */\n addListener(eventName, listener) {\n this.eventEmitter.addListener(eventName, listener);\n }\n\n /**\n * Removes listener.\n * @param {String} eventName the name of the event that triggers the\n * listener\n * @param {Function} listener the listener.\n */\n removeListener(eventName, listener) {\n this.eventEmitter.removeListener(eventName, listener);\n }\n}\n","/**\n * Indicates that the local connection statistics were updated.\n */\nexport const LOCAL_STATS_UPDATED = 'cq.local_stats_updated';\n\n/**\n * Indicates that the connection statistics for a particular remote participant\n * were updated.\n */\nexport const REMOTE_STATS_UPDATED = 'cq.remote_stats_updated';\n","import * as transform from 'sdp-transform';\n\n/**\n * Parses the primary SSRC of given SSRC group.\n * @param {object} group the SSRC group object as defined by the 'sdp-transform'\n * @return {Number} the primary SSRC number\n */\nexport function parsePrimarySSRC(group) {\n return parseInt(group.ssrcs.split(' ')[0], 10);\n}\n\n/**\n * Parses the secondary SSRC of given SSRC group.\n * @param {object} group the SSRC group object as defined by the 'sdp-transform'\n * @return {Number} the secondary SSRC number\n */\nexport function parseSecondarySSRC(group) {\n return parseInt(group.ssrcs.split(' ')[1], 10);\n}\n\n/**\n * Tells how many distinct SSRCs are contained in given media line.\n * @param {Object} mLine the media line object as defined by 'sdp-transform' lib\n * @return {number}\n */\nfunction _getSSRCCount(mLine) {\n if (!mLine.ssrcs) {\n return 0;\n }\n\n return mLine.ssrcs\n .map(ssrcInfo => ssrcInfo.id)\n .filter((ssrc, index, array) => array.indexOf(ssrc) === index)\n .length;\n}\n\n/**\n * A wrapper around 'sdp-transform' media description object which provides\n * utility methods for common SDP/SSRC related operations.\n */\nclass MLineWrap {\n\n /**\n * Creates new MLineWrap>\n * @param {Object} mLine the media line object as defined by 'sdp-transform'\n * lib.\n */\n constructor(mLine) {\n if (!mLine) {\n throw new Error('mLine is undefined');\n }\n\n this.mLine = mLine;\n }\n\n /**\n * Getter for the mLine's \"ssrcs\" array. If the array was undefined an empty\n * one will be preassigned.\n *\n * @return {Array} an array of 'sdp-transform' SSRC attributes\n * objects.\n */\n get ssrcs() {\n if (!this.mLine.ssrcs) {\n this.mLine.ssrcs = [];\n }\n\n return this.mLine.ssrcs;\n }\n\n /**\n * Setter for the mLine's \"ssrcs\" array.\n *\n * @param {Array} ssrcs an array of 'sdp-transform' SSRC attributes\n * objects.\n */\n set ssrcs(ssrcs) {\n this.mLine.ssrcs = ssrcs;\n }\n\n /**\n * Returns the direction of the underlying media description.\n * @return {string} the media direction name as defined in the SDP.\n */\n get direction() {\n return this.mLine.direction;\n }\n\n /**\n * Modifies the direction of the underlying media description.\n * @param {string} direction the new direction to be set\n */\n set direction(direction) {\n this.mLine.direction = direction;\n }\n\n /**\n * Exposes the SSRC group array of the underlying media description object.\n * @return {Array.}\n */\n get ssrcGroups() {\n if (!this.mLine.ssrcGroups) {\n this.mLine.ssrcGroups = [];\n }\n\n return this.mLine.ssrcGroups;\n }\n\n /**\n * Modifies the SSRC groups array of the underlying media description\n * object.\n * @param {Array.} ssrcGroups\n */\n set ssrcGroups(ssrcGroups) {\n this.mLine.ssrcGroups = ssrcGroups;\n }\n\n /**\n * Obtains value from SSRC attribute.\n * @param {number} ssrcNumber the SSRC number for which attribute is to be\n * found\n * @param {string} attrName the name of the SSRC attribute to be found.\n * @return {string|undefined} the value of SSRC attribute or\n * undefined if no such attribute exists.\n */\n getSSRCAttrValue(ssrcNumber, attrName) {\n const attribute = this.ssrcs.find(\n ssrcObj => ssrcObj.id === ssrcNumber\n && ssrcObj.attribute === attrName);\n\n\n return attribute && attribute.value;\n }\n\n /**\n * Removes all attributes for given SSRC number.\n * @param {number} ssrcNum the SSRC number for which all attributes will be\n * removed.\n */\n removeSSRC(ssrcNum) {\n if (!this.mLine.ssrcs || !this.mLine.ssrcs.length) {\n return;\n }\n\n this.mLine.ssrcs\n = this.mLine.ssrcs.filter(ssrcObj => ssrcObj.id !== ssrcNum);\n }\n\n /**\n * Adds SSRC attribute\n * @param {object} ssrcObj the SSRC attribute object as defined in\n * the 'sdp-transform' lib.\n */\n addSSRCAttribute(ssrcObj) {\n this.ssrcs.push(ssrcObj);\n }\n\n /**\n * Finds a SSRC group matching both semantics and SSRCs in order.\n * @param {string} semantics the name of the semantics\n * @param {string} [ssrcs] group SSRCs as a string (like it's defined in\n * SSRC group object of the 'sdp-transform' lib) e.g. \"1232546 342344 25434\"\n * @return {object|undefined} the SSRC group object or undefined if\n * not found.\n */\n findGroup(semantics, ssrcs) {\n return this.ssrcGroups.find(\n group =>\n group.semantics === semantics\n && (!ssrcs || ssrcs === group.ssrcs));\n }\n\n /**\n * Finds all groups matching given semantic's name.\n * @param {string} semantics the name of the semantics\n * @return {Array.} an array of SSRC group objects as defined by\n * the 'sdp-transform' lib.\n */\n findGroups(semantics) {\n return this.ssrcGroups.filter(\n group => group.semantics === semantics);\n }\n\n /**\n * Finds all groups matching given semantic's name and group's primary SSRC.\n * @param {string} semantics the name of the semantics\n * @param {number} primarySSRC the primary SSRC number to be matched\n * @return {Object} SSRC group object as defined by the 'sdp-transform' lib.\n */\n findGroupByPrimarySSRC(semantics, primarySSRC) {\n return this.ssrcGroups.find(\n group => group.semantics === semantics\n && parsePrimarySSRC(group) === primarySSRC);\n }\n\n /**\n * @param {string|null} msid the media stream id or null to match\n * the first SSRC object with any 'msid' value.\n * @return {Object|undefined} the SSRC object as defined by 'sdp-transform'\n * lib.\n */\n findSSRCByMSID(msid) {\n return this.ssrcs.find(\n ssrcObj => ssrcObj.attribute === 'msid'\n && (msid === null || ssrcObj.value === msid));\n }\n\n /**\n * Gets the SSRC count for the underlying media description.\n * @return {number}\n */\n getSSRCCount() {\n return _getSSRCCount(this.mLine);\n }\n\n /**\n * Checks whether the underlying media description contains any SSRC groups.\n * @return {boolean} true if there are any SSRC groups or\n * false otherwise.\n */\n containsAnySSRCGroups() {\n return this.mLine.ssrcGroups !== undefined;\n }\n\n /**\n * Finds the primary video SSRC.\n * @returns {number|undefined} the primary video ssrc\n * @throws Error if the underlying media description is not a video\n */\n getPrimaryVideoSsrc() {\n const mediaType = this.mLine.type;\n\n if (mediaType !== 'video') {\n throw new Error(\n `getPrimarySsrc doesn't work with '${mediaType}'`);\n }\n\n const numSsrcs = _getSSRCCount(this.mLine);\n\n if (numSsrcs === 1) {\n // Not using \"ssrcs\" getter on purpose here\n return this.mLine.ssrcs[0].id;\n }\n\n // Look for a SIM, FID, or FEC-FR group\n if (this.mLine.ssrcGroups) {\n const simGroup = this.findGroup('SIM');\n\n if (simGroup) {\n return parsePrimarySSRC(simGroup);\n }\n const fidGroup = this.findGroup('FID');\n\n if (fidGroup) {\n return parsePrimarySSRC(fidGroup);\n }\n const fecGroup = this.findGroup('FEC-FR');\n\n if (fecGroup) {\n return parsePrimarySSRC(fecGroup);\n }\n }\n\n }\n\n /**\n * Obtains RTX SSRC from the underlying video description (the\n * secondary SSRC of the first \"FID\" group found)\n * @param {number} primarySsrc the video ssrc for which to find the\n * corresponding rtx ssrc\n * @returns {number|undefined} the rtx ssrc (or undefined if there isn't\n * one)\n */\n getRtxSSRC(primarySsrc) {\n const fidGroup = this.findGroupByPrimarySSRC('FID', primarySsrc);\n\n\n return fidGroup && parseSecondarySSRC(fidGroup);\n }\n\n /**\n * Obtains all SSRCs contained in the underlying media description.\n * @return {Array.} an array with all SSRC as numbers.\n */\n getSSRCs() {\n return this.ssrcs\n .map(ssrcInfo => ssrcInfo.id)\n .filter((ssrc, index, array) => array.indexOf(ssrc) === index);\n }\n\n /**\n * Obtains primary video SSRCs.\n * @return {Array.} an array of all primary video SSRCs as numbers.\n * @throws Error if the wrapped media description is not a video.\n */\n getPrimaryVideoSSRCs() {\n const mediaType = this.mLine.type;\n\n if (mediaType !== 'video') {\n throw new Error(\n `getPrimaryVideoSSRCs doesn't work with ${mediaType}`);\n }\n\n const videoSSRCs = this.getSSRCs();\n\n for (const ssrcGroupInfo of this.ssrcGroups) {\n // Right now, FID and FEC-FR groups are the only ones we parse to\n // disqualify streams. If/when others arise we'll\n // need to add support for them here\n if (ssrcGroupInfo.semantics === 'FID'\n || ssrcGroupInfo.semantics === 'FEC-FR') {\n // secondary streams should be filtered out\n const secondarySsrc = parseSecondarySSRC(ssrcGroupInfo);\n\n videoSSRCs.splice(\n videoSSRCs.indexOf(secondarySsrc), 1);\n }\n }\n\n return videoSSRCs;\n }\n\n /**\n * Dumps all SSRC groups of this media description to JSON.\n */\n dumpSSRCGroups() {\n return JSON.stringify(this.mLine.ssrcGroups);\n }\n\n /**\n * Removes all SSRC groups which contain given SSRC number at any position.\n * @param {number} ssrc the SSRC for which all matching groups are to be\n * removed.\n */\n removeGroupsWithSSRC(ssrc) {\n if (!this.mLine.ssrcGroups) {\n return;\n }\n\n this.mLine.ssrcGroups = this.mLine.ssrcGroups\n .filter(groupInfo => groupInfo.ssrcs.indexOf(`${ssrc}`) === -1);\n }\n\n /**\n * Removes groups that match given semantics.\n * @param {string} semantics e.g. \"SIM\" or \"FID\"\n */\n removeGroupsBySemantics(semantics) {\n if (!this.mLine.ssrcGroups) {\n return;\n }\n\n this.mLine.ssrcGroups\n = this.mLine.ssrcGroups\n .filter(groupInfo => groupInfo.semantics !== semantics);\n }\n\n /**\n * Replaces SSRC (does not affect SSRC groups, but only attributes).\n * @param {number} oldSSRC the old SSRC number\n * @param {number} newSSRC the new SSRC number\n */\n replaceSSRC(oldSSRC, newSSRC) {\n if (this.mLine.ssrcs) {\n this.mLine.ssrcs.forEach(ssrcInfo => {\n if (ssrcInfo.id === oldSSRC) {\n ssrcInfo.id = newSSRC;\n }\n });\n }\n }\n\n /**\n * Adds given SSRC group to this media description.\n * @param {object} group the SSRC group object as defined by\n * the 'sdp-transform' lib.\n */\n addSSRCGroup(group) {\n this.ssrcGroups.push(group);\n }\n}\n\n/**\n * Utility class for SDP manipulation using the 'sdp-transform' library.\n *\n * Typical use usage scenario:\n *\n * const transformer = new SdpTransformWrap(rawSdp);\n * const videoMLine = transformer.selectMedia('video);\n * if (videoMLine) {\n * videoMLiner.addSSRCAttribute({\n * id: 2342343,\n * attribute: \"cname\",\n * value: \"someCname\"\n * });\n * rawSdp = transformer.toRawSdp();\n * }\n */\nexport class SdpTransformWrap {\n\n /**\n * Creates new instance and parses the raw SDP into objects using\n * 'sdp-transform' lib.\n * @param {string} rawSDP the SDP in raw text format.\n */\n constructor(rawSDP) {\n this.parsedSDP = transform.parse(rawSDP);\n }\n\n /**\n * Selects the first media SDP of given name.\n * @param {string} mediaType the name of the media e.g. 'audio', 'video',\n * 'data'.\n * @return {MLineWrap|null} return {@link MLineWrap} instance for the media\n * line or null if not found. The object returned references\n * the underlying SDP state held by this SdpTransformWrap instance\n * (it's not a copy).\n */\n selectMedia(mediaType) {\n const selectedMLine\n = this.parsedSDP.media.find(mLine => mLine.type === mediaType);\n\n return selectedMLine ? new MLineWrap(selectedMLine) : null;\n }\n\n /**\n * Converts the currently stored SDP state in this instance to raw text SDP\n * format.\n * @return {string}\n */\n toRawSDP() {\n return transform.write(this.parsedSDP);\n }\n}\n","/**\n * The know jingle actions that can be sent and should be acted upon by\n * {@code ProxyConnectionService} and {@code ProxyConnectionPC}.\n */\nexport const ACTIONS = {\n ACCEPT: 'session-accept',\n CONNECTION_ERROR: 'connection-error-encountered',\n INITIATE: 'session-initiate',\n TERMINATE: 'session-terminate',\n TRANSPORT_INFO: 'transport-info',\n UNAVAILABLE: 'unavailable'\n};\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\nvar R = typeof Reflect === 'object' ? Reflect : null\nvar ReflectApply = R && typeof R.apply === 'function'\n ? R.apply\n : function ReflectApply(target, receiver, args) {\n return Function.prototype.apply.call(target, receiver, args);\n }\n\nvar ReflectOwnKeys\nif (R && typeof R.ownKeys === 'function') {\n ReflectOwnKeys = R.ownKeys\n} else if (Object.getOwnPropertySymbols) {\n ReflectOwnKeys = function ReflectOwnKeys(target) {\n return Object.getOwnPropertyNames(target)\n .concat(Object.getOwnPropertySymbols(target));\n };\n} else {\n ReflectOwnKeys = function ReflectOwnKeys(target) {\n return Object.getOwnPropertyNames(target);\n };\n}\n\nfunction ProcessEmitWarning(warning) {\n if (console && console.warn) console.warn(warning);\n}\n\nvar NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {\n return value !== value;\n}\n\nfunction EventEmitter() {\n EventEmitter.init.call(this);\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._eventsCount = 0;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nvar defaultMaxListeners = 10;\n\nObject.defineProperty(EventEmitter, 'defaultMaxListeners', {\n enumerable: true,\n get: function() {\n return defaultMaxListeners;\n },\n set: function(arg) {\n if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {\n throw new RangeError('The value of \"defaultMaxListeners\" is out of range. It must be a non-negative number. Received ' + arg + '.');\n }\n defaultMaxListeners = arg;\n }\n});\n\nEventEmitter.init = function() {\n\n if (this._events === undefined ||\n this._events === Object.getPrototypeOf(this)._events) {\n this._events = Object.create(null);\n this._eventsCount = 0;\n }\n\n this._maxListeners = this._maxListeners || undefined;\n};\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {\n if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {\n throw new RangeError('The value of \"n\" is out of range. It must be a non-negative number. Received ' + n + '.');\n }\n this._maxListeners = n;\n return this;\n};\n\nfunction $getMaxListeners(that) {\n if (that._maxListeners === undefined)\n return EventEmitter.defaultMaxListeners;\n return that._maxListeners;\n}\n\nEventEmitter.prototype.getMaxListeners = function getMaxListeners() {\n return $getMaxListeners(this);\n};\n\nEventEmitter.prototype.emit = function emit(type) {\n var args = [];\n for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);\n var doError = (type === 'error');\n\n var events = this._events;\n if (events !== undefined)\n doError = (doError && events.error === undefined);\n else if (!doError)\n return false;\n\n // If there is no 'error' event listener then throw.\n if (doError) {\n var er;\n if (args.length > 0)\n er = args[0];\n if (er instanceof Error) {\n // Note: The comments on the `throw` lines are intentional, they show\n // up in Node's output if this results in an unhandled exception.\n throw er; // Unhandled 'error' event\n }\n // At least give some kind of context to the user\n var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));\n err.context = er;\n throw err; // Unhandled 'error' event\n }\n\n var handler = events[type];\n\n if (handler === undefined)\n return false;\n\n if (typeof handler === 'function') {\n ReflectApply(handler, this, args);\n } else {\n var len = handler.length;\n var listeners = arrayClone(handler, len);\n for (var i = 0; i < len; ++i)\n ReflectApply(listeners[i], this, args);\n }\n\n return true;\n};\n\nfunction _addListener(target, type, listener, prepend) {\n var m;\n var events;\n var existing;\n\n if (typeof listener !== 'function') {\n throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n }\n\n events = target._events;\n if (events === undefined) {\n events = target._events = Object.create(null);\n target._eventsCount = 0;\n } else {\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (events.newListener !== undefined) {\n target.emit('newListener', type,\n listener.listener ? listener.listener : listener);\n\n // Re-assign `events` because a newListener handler could have caused the\n // this._events to be assigned to a new object\n events = target._events;\n }\n existing = events[type];\n }\n\n if (existing === undefined) {\n // Optimize the case of one listener. Don't need the extra array object.\n existing = events[type] = listener;\n ++target._eventsCount;\n } else {\n if (typeof existing === 'function') {\n // Adding the second element, need to change to array.\n existing = events[type] =\n prepend ? [listener, existing] : [existing, listener];\n // If we've already got an array, just append.\n } else if (prepend) {\n existing.unshift(listener);\n } else {\n existing.push(listener);\n }\n\n // Check for listener leak\n m = $getMaxListeners(target);\n if (m > 0 && existing.length > m && !existing.warned) {\n existing.warned = true;\n // No error code for this since it is a Warning\n // eslint-disable-next-line no-restricted-syntax\n var w = new Error('Possible EventEmitter memory leak detected. ' +\n existing.length + ' ' + String(type) + ' listeners ' +\n 'added. Use emitter.setMaxListeners() to ' +\n 'increase limit');\n w.name = 'MaxListenersExceededWarning';\n w.emitter = target;\n w.type = type;\n w.count = existing.length;\n ProcessEmitWarning(w);\n }\n }\n\n return target;\n}\n\nEventEmitter.prototype.addListener = function addListener(type, listener) {\n return _addListener(this, type, listener, false);\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.prependListener =\n function prependListener(type, listener) {\n return _addListener(this, type, listener, true);\n };\n\nfunction onceWrapper() {\n var args = [];\n for (var i = 0; i < arguments.length; i++) args.push(arguments[i]);\n if (!this.fired) {\n this.target.removeListener(this.type, this.wrapFn);\n this.fired = true;\n ReflectApply(this.listener, this.target, args);\n }\n}\n\nfunction _onceWrap(target, type, listener) {\n var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };\n var wrapped = onceWrapper.bind(state);\n wrapped.listener = listener;\n state.wrapFn = wrapped;\n return wrapped;\n}\n\nEventEmitter.prototype.once = function once(type, listener) {\n if (typeof listener !== 'function') {\n throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n }\n this.on(type, _onceWrap(this, type, listener));\n return this;\n};\n\nEventEmitter.prototype.prependOnceListener =\n function prependOnceListener(type, listener) {\n if (typeof listener !== 'function') {\n throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n }\n this.prependListener(type, _onceWrap(this, type, listener));\n return this;\n };\n\n// Emits a 'removeListener' event if and only if the listener was removed.\nEventEmitter.prototype.removeListener =\n function removeListener(type, listener) {\n var list, events, position, i, originalListener;\n\n if (typeof listener !== 'function') {\n throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n }\n\n events = this._events;\n if (events === undefined)\n return this;\n\n list = events[type];\n if (list === undefined)\n return this;\n\n if (list === listener || list.listener === listener) {\n if (--this._eventsCount === 0)\n this._events = Object.create(null);\n else {\n delete events[type];\n if (events.removeListener)\n this.emit('removeListener', type, list.listener || listener);\n }\n } else if (typeof list !== 'function') {\n position = -1;\n\n for (i = list.length - 1; i >= 0; i--) {\n if (list[i] === listener || list[i].listener === listener) {\n originalListener = list[i].listener;\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (position === 0)\n list.shift();\n else {\n spliceOne(list, position);\n }\n\n if (list.length === 1)\n events[type] = list[0];\n\n if (events.removeListener !== undefined)\n this.emit('removeListener', type, originalListener || listener);\n }\n\n return this;\n };\n\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\n\nEventEmitter.prototype.removeAllListeners =\n function removeAllListeners(type) {\n var listeners, events, i;\n\n events = this._events;\n if (events === undefined)\n return this;\n\n // not listening for removeListener, no need to emit\n if (events.removeListener === undefined) {\n if (arguments.length === 0) {\n this._events = Object.create(null);\n this._eventsCount = 0;\n } else if (events[type] !== undefined) {\n if (--this._eventsCount === 0)\n this._events = Object.create(null);\n else\n delete events[type];\n }\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n var keys = Object.keys(events);\n var key;\n for (i = 0; i < keys.length; ++i) {\n key = keys[i];\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = Object.create(null);\n this._eventsCount = 0;\n return this;\n }\n\n listeners = events[type];\n\n if (typeof listeners === 'function') {\n this.removeListener(type, listeners);\n } else if (listeners !== undefined) {\n // LIFO order\n for (i = listeners.length - 1; i >= 0; i--) {\n this.removeListener(type, listeners[i]);\n }\n }\n\n return this;\n };\n\nfunction _listeners(target, type, unwrap) {\n var events = target._events;\n\n if (events === undefined)\n return [];\n\n var evlistener = events[type];\n if (evlistener === undefined)\n return [];\n\n if (typeof evlistener === 'function')\n return unwrap ? [evlistener.listener || evlistener] : [evlistener];\n\n return unwrap ?\n unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);\n}\n\nEventEmitter.prototype.listeners = function listeners(type) {\n return _listeners(this, type, true);\n};\n\nEventEmitter.prototype.rawListeners = function rawListeners(type) {\n return _listeners(this, type, false);\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n if (typeof emitter.listenerCount === 'function') {\n return emitter.listenerCount(type);\n } else {\n return listenerCount.call(emitter, type);\n }\n};\n\nEventEmitter.prototype.listenerCount = listenerCount;\nfunction listenerCount(type) {\n var events = this._events;\n\n if (events !== undefined) {\n var evlistener = events[type];\n\n if (typeof evlistener === 'function') {\n return 1;\n } else if (evlistener !== undefined) {\n return evlistener.length;\n }\n }\n\n return 0;\n}\n\nEventEmitter.prototype.eventNames = function eventNames() {\n return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];\n};\n\nfunction arrayClone(arr, n) {\n var copy = new Array(n);\n for (var i = 0; i < n; ++i)\n copy[i] = arr[i];\n return copy;\n}\n\nfunction spliceOne(list, index) {\n for (; index + 1 < list.length; index++)\n list[index] = list[index + 1];\n list.pop();\n}\n\nfunction unwrapListeners(arr) {\n var ret = new Array(arr.length);\n for (var i = 0; i < ret.length; ++i) {\n ret[i] = arr[i].listener || arr[i];\n }\n return ret;\n}\n","const Resolutions = {\n '1080': {\n width: 1920,\n height: 1080,\n order: 8\n },\n 'fullhd': {\n width: 1920,\n height: 1080,\n order: 8\n },\n '720': {\n width: 1280,\n height: 720,\n order: 7\n },\n 'hd': {\n width: 1280,\n height: 720,\n order: 7\n },\n '960': {\n width: 960,\n height: 720,\n order: 6\n },\n '540': {\n width: 960,\n height: 540,\n order: 5\n },\n 'qhd': {\n width: 960,\n height: 540,\n order: 5\n },\n\n // 16:9 resolution first.\n '360': {\n width: 640,\n height: 360,\n order: 4\n },\n '640': {\n width: 640,\n height: 480,\n order: 3\n },\n 'vga': {\n width: 640,\n height: 480,\n order: 3\n },\n\n // 16:9 resolution first.\n '180': {\n width: 320,\n height: 180,\n order: 2\n },\n '320': {\n width: 320,\n height: 240,\n order: 1\n }\n};\n\nmodule.exports = Resolutions;\n","/**\n * The pending Jingle session state which means the session as defined in\n * XEP-0166(before 'session-invite/session-accept' took place).\n *\n * @type {string}\n */\nexport const PENDING = 'pending';\n\n/**\n * The active Jingle session state as defined in XEP-0166\n * (after 'session-invite'/'session-accept').\n *\n * @type {string}\n */\nexport const ACTIVE = 'active';\n\n/**\n * The ended Jingle session state as defined in XEP-0166\n * (after 'session-terminate').\n * @type {string}\n */\nexport const ENDED = 'ended';\n","/* global callstats */\n\nimport browser from '../browser';\nimport GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';\n\nconst logger = require('jitsi-meet-logger').getLogger(__filename);\n\n/**\n * We define enumeration of wrtcFuncNames as we need them before\n * callstats is initialized to queue events.\n * @const\n * @see http://www.callstats.io/api/#enumeration-of-wrtcfuncnames\n */\nconst wrtcFuncNames = {\n createOffer: 'createOffer',\n createAnswer: 'createAnswer',\n setLocalDescription: 'setLocalDescription',\n setRemoteDescription: 'setRemoteDescription',\n addIceCandidate: 'addIceCandidate',\n getUserMedia: 'getUserMedia',\n iceConnectionFailure: 'iceConnectionFailure',\n signalingError: 'signalingError',\n applicationLog: 'applicationLog'\n};\n\n/**\n * We define enumeration of fabricEvent as we need them before\n * callstats is initialized to queue events.\n * @const\n * @see http://www.callstats.io/api/#enumeration-of-fabricevent\n */\nconst fabricEvent = {\n fabricHold: 'fabricHold',\n fabricResume: 'fabricResume',\n audioMute: 'audioMute',\n audioUnmute: 'audioUnmute',\n videoPause: 'videoPause',\n videoResume: 'videoResume',\n fabricUsageEvent: 'fabricUsageEvent',\n fabricStats: 'fabricStats',\n fabricTerminated: 'fabricTerminated',\n screenShareStart: 'screenShareStart',\n screenShareStop: 'screenShareStop',\n dominantSpeaker: 'dominantSpeaker',\n activeDeviceList: 'activeDeviceList'\n};\n\n/**\n * The user id to report to callstats as destination.\n * @type {string}\n */\nconst DEFAULT_REMOTE_USER = 'jitsi';\n\n/**\n * Type of pending reports, can be event or an error.\n * @type {{ERROR: string, EVENT: string}}\n */\nconst reportType = {\n ERROR: 'error',\n EVENT: 'event',\n MST_WITH_USERID: 'mstWithUserID'\n};\n\n/**\n * Set of currently existing {@link CallStats} instances.\n * @type {Set}\n */\nlet _fabrics;\n\n/**\n * An instance of this class is a wrapper for the CallStats API fabric. A fabric\n * reports one peer connection the the CallStats backend and is allocated with\n * {@link callstats.addNewFabric}. It has a bunch of instance methods for\n * reporting various events. A fabric is considered disposed when\n * {@link CallStats.sendTerminateEvent} is executed.\n *\n * Currently only one backend instance can be created ever and it's done using\n * {@link CallStats.initBackend}. At the time of this writing there is no way to\n * explicitly shutdown the backend, but it's supposed to close it's connection\n * automatically, after all fabrics have been terminated.\n */\nexport default class CallStats {\n /**\n * A callback passed to {@link callstats.addNewFabric}.\n * @param {string} error 'success' means ok\n * @param {string} msg some more details\n * @private\n */\n static _addNewFabricCallback(error, msg) {\n if (CallStats.backend && error !== 'success') {\n logger.error(`Monitoring status: ${error} msg: ${msg}`);\n }\n }\n\n /**\n * Callback passed to {@link callstats.initialize} (backend initialization)\n * @param {string} error 'success' means ok\n * @param {String} msg\n * @private\n */\n static _initCallback(error, msg) {\n logger.log(`CallStats Status: err=${error} msg=${msg}`);\n\n // there is no lib, nothing to report to\n if (error !== 'success') {\n return;\n }\n\n CallStats.backendInitialized = true;\n\n // I hate that\n let atLeastOneFabric = false;\n let defaultInstance = null;\n\n for (const callStatsInstance of CallStats.fabrics.values()) {\n if (!callStatsInstance.hasFabric) {\n logger.debug('addNewFabric - initCallback');\n if (callStatsInstance._addNewFabric()) {\n atLeastOneFabric = true;\n if (!defaultInstance) {\n defaultInstance = callStatsInstance;\n }\n }\n }\n }\n\n if (!atLeastOneFabric) {\n return;\n }\n\n CallStats._emptyReportQueue(defaultInstance);\n }\n\n /**\n * Empties report queue.\n *\n * @param {CallStats} csInstance - The callstats instance.\n * @private\n */\n static _emptyReportQueue(csInstance) {\n // There is no conference ID nor a PeerConnection available when some of\n // the events are scheduled on the reportsQueue, so those will be\n // reported on the first initialized fabric.\n const defaultConfID = csInstance.confID;\n const defaultPC = csInstance.peerconnection;\n\n // notify callstats about failures if there were any\n for (const report of CallStats.reportsQueue) {\n if (report.type === reportType.ERROR) {\n const errorData = report.data;\n\n CallStats._reportError(\n csInstance,\n errorData.type,\n errorData.error,\n errorData.pc || defaultPC);\n } else if (report.type === reportType.EVENT) {\n // if we have and event to report and we failed to add\n // fabric this event will not be reported anyway, returning\n // an error\n const eventData = report.data;\n\n CallStats.backend.sendFabricEvent(\n report.pc || defaultPC,\n eventData.event,\n defaultConfID,\n eventData.eventData);\n } else if (report.type === reportType.MST_WITH_USERID) {\n const data = report.data;\n\n CallStats.backend.associateMstWithUserID(\n report.pc || defaultPC,\n data.callStatsId,\n defaultConfID,\n data.ssrc,\n data.usageLabel,\n data.containerId\n );\n }\n }\n CallStats.reportsQueue.length = 0;\n }\n\n /* eslint-disable max-params */\n /**\n * Reports an error to callstats.\n *\n * @param {CallStats} [cs]\n * @param type the type of the error, which will be one of the wrtcFuncNames\n * @param error the error\n * @param pc the peerconnection\n * @private\n */\n static _reportError(cs, type, error, pc) {\n let _error = error;\n\n if (!_error) {\n logger.warn('No error is passed!');\n _error = new Error('Unknown error');\n }\n if (CallStats.backendInitialized && cs) {\n CallStats.backend.reportError(pc, cs.confID, type, _error);\n } else {\n CallStats.reportsQueue.push({\n type: reportType.ERROR,\n data: {\n error: _error,\n pc,\n type\n }\n });\n }\n\n // else just ignore it\n }\n\n /* eslint-enable max-params */\n\n /**\n * Reports an error to callstats.\n *\n * @param {CallStats} cs\n * @param event the type of the event, which will be one of the fabricEvent\n * @param eventData additional data to pass to event\n * @private\n */\n static _reportEvent(cs, event, eventData) {\n const pc = cs && cs.peerconnection;\n const confID = cs && cs.confID;\n\n if (CallStats.backendInitialized && cs) {\n CallStats.backend.sendFabricEvent(pc, event, confID, eventData);\n } else {\n CallStats.reportsQueue.push({\n confID,\n pc,\n type: reportType.EVENT,\n data: { event,\n eventData }\n });\n }\n }\n\n /**\n * Wraps some of the CallStats API method and logs their calls with\n * arguments on the debug logging level. Also wraps some of the backend\n * methods execution into try catch blocks to not crash the app in case\n * there is a problem with the backend itself.\n * @param {callstats} theBackend\n * @private\n */\n static _traceAndCatchBackendCalls(theBackend) {\n const tryCatchMethods = [\n 'associateMstWithUserID',\n 'sendFabricEvent',\n 'sendUserFeedback'\n\n // 'reportError', - this one needs special handling - see code below\n ];\n\n for (const methodName of tryCatchMethods) {\n const originalMethod = theBackend[methodName];\n\n theBackend[methodName] = function(...theArguments) {\n try {\n return originalMethod.apply(theBackend, theArguments);\n } catch (e) {\n GlobalOnErrorHandler.callErrorHandler(e);\n }\n };\n }\n const debugMethods = [\n 'associateMstWithUserID',\n 'sendFabricEvent',\n 'sendUserFeedback'\n\n // 'reportError', - this one needs special handling - see code below\n ];\n\n for (const methodName of debugMethods) {\n const originalMethod = theBackend[methodName];\n\n theBackend[methodName] = function(...theArguments) {\n logger.debug(methodName, theArguments);\n originalMethod.apply(theBackend, theArguments);\n };\n }\n const originalReportError = theBackend.reportError;\n\n /* eslint-disable max-params */\n theBackend.reportError = function(pc, cs, type, ...args) {\n // Logs from the logger are submitted on the applicationLog event\n // \"type\". Logging the arguments on the logger will create endless\n // loop, because it will put all the logs to the logger queue again.\n if (type === wrtcFuncNames.applicationLog) {\n // NOTE otherArguments are not logged to the console on purpose\n // to not log the whole log batch\n // FIXME check the current logging level (currently not exposed\n // by the logger implementation)\n // NOTE it is not safe to log whole objects on react-native as\n // those contain too many circular references and may crash\n // the app.\n if (!browser.isReactNative()) {\n console && console.debug('reportError', pc, cs, type);\n }\n } else {\n logger.debug('reportError', pc, cs, type, ...args);\n }\n try {\n originalReportError.call(theBackend, pc, cs, type, ...args);\n } catch (exception) {\n if (type === wrtcFuncNames.applicationLog) {\n console && console.error('reportError', exception);\n } else {\n GlobalOnErrorHandler.callErrorHandler(exception);\n }\n }\n };\n\n /* eslint-enable max-params */\n }\n\n /**\n * Returns the Set with the currently existing {@link CallStats} instances.\n * Lazily initializes the Set to allow any Set polyfills to be applied.\n * @type {Set}\n */\n static get fabrics() {\n if (!_fabrics) {\n _fabrics = new Set();\n }\n\n return _fabrics;\n }\n\n /**\n * Initializes the CallStats backend. Should be called only if\n * {@link CallStats.isBackendInitialized} returns false.\n * @param {object} options\n * @param {String} options.callStatsID CallStats credentials - ID\n * @param {String} options.callStatsSecret CallStats credentials - secret\n * @param {string} options.aliasName the aliasName part of\n * the userID aka endpoint ID, see CallStats docs for more info.\n * @param {string} options.userName the userName part of\n * the userID aka display name, see CallStats docs for more info.\n *\n */\n static initBackend(options) {\n if (CallStats.backend) {\n throw new Error('CallStats backend has been initialized already!');\n }\n try {\n const CallStatsBackend = callstats;\n\n CallStats.backend = new CallStatsBackend();\n CallStats._traceAndCatchBackendCalls(CallStats.backend);\n CallStats.userID = {\n aliasName: options.aliasName,\n userName: options.userName\n };\n CallStats.callStatsID = options.callStatsID;\n CallStats.callStatsSecret = options.callStatsSecret;\n\n let configParams;\n\n if (options.applicationName) {\n configParams = {\n applicationVersion:\n `${options.applicationName} (${\n browser.getName()})`\n };\n }\n\n if (options.confID) {\n // we first check is there a tenant in the confID\n const match = options.confID.match(/.*\\/(.*)\\/.*/);\n\n // if there is no tenant, we will just set '/'\n configParams.siteID = (match && match[1]) || '/';\n }\n\n // userID is generated or given by the origin server\n CallStats.backend.initialize(\n CallStats.callStatsID,\n CallStats.callStatsSecret,\n CallStats.userID,\n CallStats._initCallback,\n undefined,\n configParams);\n\n const getWiFiStatsMethod = options.getWiFiStatsMethod;\n\n if (getWiFiStatsMethod) {\n CallStats.backend.attachWifiStatsHandler(getWiFiStatsMethod);\n\n getWiFiStatsMethod().then(result => {\n if (result) {\n logger.info('Reported wifi addresses:'\n , JSON.parse(result).addresses);\n }\n })\n .catch(() => {});// eslint-disable-line no-empty-function\n }\n\n return true;\n } catch (e) {\n // The callstats.io API failed to initialize (e.g. because its\n // download did not succeed in general or on time). Further attempts\n // to utilize it cannot possibly succeed.\n GlobalOnErrorHandler.callErrorHandler(e);\n CallStats.backend = null;\n logger.error(e);\n\n return false;\n }\n }\n\n /**\n * Checks if the CallStats backend has been created. It does not mean that\n * it has been initialized, but only that the API instance has been\n * allocated successfully.\n * @return {boolean} true if backend exists or false\n * otherwise\n */\n static isBackendInitialized() {\n return Boolean(CallStats.backend);\n }\n\n /**\n * Notifies CallStats about active device.\n * @param {{deviceList: {String:String}}} devicesData list of devices with\n * their data\n * @param {CallStats} cs callstats instance related to the event\n */\n static sendActiveDeviceListEvent(devicesData, cs) {\n CallStats._reportEvent(cs, fabricEvent.activeDeviceList, devicesData);\n }\n\n /**\n * Notifies CallStats that there is a log we want to report.\n *\n * @param {Error} e error to send or {String} message\n * @param {CallStats} cs callstats instance related to the error (optional)\n */\n static sendApplicationLog(e, cs) {\n try {\n CallStats._reportError(\n cs,\n wrtcFuncNames.applicationLog,\n e,\n cs && cs.peerconnection);\n } catch (error) {\n // If sendApplicationLog fails it should not be printed to\n // the logger, because it will try to push the logs again\n // (through sendApplicationLog) and an endless loop is created.\n if (console && (typeof console.error === 'function')) {\n // FIXME send analytics event as well\n console.error('sendApplicationLog failed', error);\n }\n }\n }\n\n /**\n * Sends the given feedback through CallStats.\n *\n * @param {string} conferenceID the conference ID for which the feedback\n * will be reported.\n * @param overall an integer between 1 and 5 indicating the\n * user feedback\n * @param comment detailed feedback from the user.\n */\n static sendFeedback(conferenceID, overall, comment) {\n return new Promise((resolve, reject) => {\n if (CallStats.backend) {\n CallStats.backend.sendUserFeedback(\n conferenceID,\n {\n userID: CallStats.userID,\n overall,\n comment\n },\n (status, message) => {\n if (status === 'success') {\n resolve(message);\n } else {\n reject(message);\n }\n });\n } else {\n const reason = 'Failed to submit feedback to CallStats - no backend';\n\n logger.error(reason);\n reject(reason);\n }\n });\n }\n\n /**\n * Notifies CallStats that getUserMedia failed.\n *\n * @param {Error} e error to send\n * @param {CallStats} cs callstats instance related to the error (optional)\n */\n static sendGetUserMediaFailed(e, cs) {\n CallStats._reportError(cs, wrtcFuncNames.getUserMedia, e, null);\n }\n\n /**\n * Notifies CallStats for mute events\n * @param mute {boolean} true for muted and false for not muted\n * @param type {String} \"audio\"/\"video\"\n * @param {CallStats} cs callstats instance related to the event\n */\n static sendMuteEvent(mute, type, cs) {\n let event;\n\n if (type === 'video') {\n event = mute ? fabricEvent.videoPause : fabricEvent.videoResume;\n } else {\n event = mute ? fabricEvent.audioMute : fabricEvent.audioUnmute;\n }\n\n CallStats._reportEvent(cs, event);\n }\n\n /**\n * Creates new CallStats instance that handles all callstats API calls for\n * given {@link TraceablePeerConnection}. Each instance is meant to handle\n * one CallStats fabric added with 'addFabric' API method for the\n * {@link TraceablePeerConnection} instance passed in the constructor.\n * @param {TraceablePeerConnection} tpc\n * @param {Object} options\n * @param {string} options.confID the conference ID that wil be used to\n * report the session.\n * @param {string} [options.remoteUserID='jitsi'] the remote user ID to\n * which given tpc is connected.\n */\n constructor(tpc, options) {\n this.confID = options.confID;\n this.tpc = tpc;\n this.peerconnection = tpc.peerconnection;\n this.remoteUserID = options.remoteUserID || DEFAULT_REMOTE_USER;\n this.hasFabric = false;\n\n CallStats.fabrics.add(this);\n\n if (CallStats.backendInitialized) {\n this._addNewFabric();\n\n // if this is the first fabric let's try to empty the\n // report queue. Reports all events that we recorded between\n // backend initialization and receiving the first fabric\n if (CallStats.fabrics.size === 1) {\n CallStats._emptyReportQueue(this);\n }\n }\n }\n\n /**\n * Initializes CallStats fabric by calling \"addNewFabric\" for\n * the peer connection associated with this instance.\n * @return {boolean} true if the call was successful or false otherwise.\n */\n _addNewFabric() {\n logger.info('addNewFabric', this.remoteUserID);\n try {\n const fabricAttributes = {\n remoteEndpointType:\n this.tpc.isP2P\n ? CallStats.backend.endpointType.peer\n : CallStats.backend.endpointType.server\n };\n const ret\n = CallStats.backend.addNewFabric(\n this.peerconnection,\n this.remoteUserID,\n CallStats.backend.fabricUsage.multiplex,\n this.confID,\n fabricAttributes,\n CallStats._addNewFabricCallback);\n\n this.hasFabric = true;\n\n const success = ret.status === 'success';\n\n if (!success) {\n logger.error('callstats fabric not initilized', ret.message);\n }\n\n return success;\n\n } catch (error) {\n GlobalOnErrorHandler.callErrorHandler(error);\n\n return false;\n }\n }\n\n /* eslint-disable max-params */\n\n /**\n * Lets CallStats module know where is given SSRC rendered by providing\n * renderer tag ID.\n * If the lib is not initialized yet queue the call for later, when it's\n * ready.\n * @param {number} ssrc the SSRC of the stream\n * @param {boolean} isLocal indicates whether this the stream is local\n * @param {string|null} streamEndpointId if the stream is not local the it\n * needs to contain the stream owner's ID\n * @param {string} usageLabel meaningful usage label of this stream like\n * 'microphone', 'camera' or 'screen'.\n * @param {string} containerId the id of media 'audio' or 'video' tag which\n * renders the stream.\n */\n associateStreamWithVideoTag(\n ssrc,\n isLocal,\n streamEndpointId,\n usageLabel,\n containerId) {\n if (!CallStats.backend) {\n return;\n }\n\n const callStatsId = isLocal ? CallStats.userID : streamEndpointId;\n\n if (CallStats.backendInitialized) {\n CallStats.backend.associateMstWithUserID(\n this.peerconnection,\n callStatsId,\n this.confID,\n ssrc,\n usageLabel,\n containerId);\n } else {\n CallStats.reportsQueue.push({\n type: reportType.MST_WITH_USERID,\n pc: this.peerconnection,\n data: {\n callStatsId,\n containerId,\n ssrc,\n usageLabel\n }\n });\n }\n }\n\n /* eslint-enable max-params */\n\n /**\n * Notifies CallStats that we are the new dominant speaker in the\n * conference.\n */\n sendDominantSpeakerEvent() {\n CallStats._reportEvent(this, fabricEvent.dominantSpeaker);\n }\n\n /**\n * Notifies CallStats that the fabric for the underlying peerconnection was\n * closed and no evens should be reported, after this call.\n */\n sendTerminateEvent() {\n if (CallStats.backendInitialized) {\n CallStats.backend.sendFabricEvent(\n this.peerconnection,\n CallStats.backend.fabricEvent.fabricTerminated,\n this.confID);\n }\n CallStats.fabrics.delete(this);\n }\n\n /**\n * Notifies CallStats for ice connection failed\n */\n sendIceConnectionFailedEvent() {\n CallStats._reportError(\n this,\n wrtcFuncNames.iceConnectionFailure,\n null,\n this.peerconnection);\n }\n\n /**\n * Notifies CallStats that peer connection failed to create offer.\n *\n * @param {Error} e error to send\n */\n sendCreateOfferFailed(e) {\n CallStats._reportError(\n this, wrtcFuncNames.createOffer, e, this.peerconnection);\n }\n\n /**\n * Notifies CallStats that peer connection failed to create answer.\n *\n * @param {Error} e error to send\n */\n sendCreateAnswerFailed(e) {\n CallStats._reportError(\n this, wrtcFuncNames.createAnswer, e, this.peerconnection);\n }\n\n /**\n * Sends either resume or hold event for the fabric associated with\n * the underlying peerconnection.\n * @param {boolean} isResume true to resume or false to hold\n */\n sendResumeOrHoldEvent(isResume) {\n CallStats._reportEvent(\n this,\n isResume ? fabricEvent.fabricResume : fabricEvent.fabricHold);\n }\n\n /**\n * Notifies CallStats for screen sharing events\n * @param {boolean} start true for starting screen sharing and\n * false for not stopping\n * @param {string|null} ssrc - optional ssrc value, used only when\n * starting screen sharing.\n */\n sendScreenSharingEvent(start, ssrc) {\n let eventData;\n\n if (ssrc) {\n eventData = { ssrc };\n }\n\n CallStats._reportEvent(\n this,\n start ? fabricEvent.screenShareStart : fabricEvent.screenShareStop,\n eventData);\n }\n\n /**\n * Notifies CallStats that peer connection failed to set local description.\n *\n * @param {Error} e error to send\n */\n sendSetLocalDescFailed(e) {\n CallStats._reportError(\n this, wrtcFuncNames.setLocalDescription, e, this.peerconnection);\n }\n\n /**\n * Notifies CallStats that peer connection failed to set remote description.\n *\n * @param {Error} e error to send\n */\n sendSetRemoteDescFailed(e) {\n CallStats._reportError(\n this, wrtcFuncNames.setRemoteDescription, e, this.peerconnection);\n }\n\n /**\n * Notifies CallStats that peer connection failed to add ICE candidate.\n *\n * @param {Error} e error to send\n */\n sendAddIceCandidateFailed(e) {\n CallStats._reportError(\n this, wrtcFuncNames.addIceCandidate, e, this.peerconnection);\n }\n}\n\n/**\n * The CallStats API backend instance\n * @type {callstats}\n */\nCallStats.backend = null;\n\n// some errors/events may happen before CallStats init\n// in this case we accumulate them in this array\n// and send them to callstats on init\nCallStats.reportsQueue = [];\n\n/**\n * Whether the library was successfully initialized(the backend) using its\n * initialize method.\n * @type {boolean}\n */\nCallStats.backendInitialized = false;\n\n/**\n * Part of the CallStats credentials - application ID\n * @type {string}\n */\nCallStats.callStatsID = null;\n\n/**\n * Part of the CallStats credentials - application secret\n * @type {string}\n */\nCallStats.callStatsSecret = null;\n\n/**\n * Local CallStats user ID structure. Can be set only once when\n * {@link backend} is initialized, so it's static for the time being.\n * See CallStats API for more info:\n * https://www.callstats.io/api/#userid\n * @type {object}\n */\nCallStats.userID = null;\n","import { getLogger } from 'jitsi-meet-logger';\nconst logger = getLogger(__filename);\n\nimport UsernameGenerator from '../util/UsernameGenerator';\n\nlet _callStatsUserName;\n\nlet _machineId;\n\n/**\n *\n */\nexport default {\n /**\n * Returns fake username for callstats\n * @returns {string} fake username for callstats\n */\n get callStatsUserName() {\n if (!_callStatsUserName) {\n const localStorage = getLocalStorage();\n\n if (localStorage) {\n _callStatsUserName = localStorage.getItem('callStatsUserName');\n }\n if (!_callStatsUserName) {\n _callStatsUserName = generateCallStatsUserName();\n if (localStorage) {\n localStorage.setItem(\n 'callStatsUserName',\n _callStatsUserName);\n }\n }\n }\n\n return _callStatsUserName;\n },\n\n /**\n * Returns current machine id.\n * @returns {string} machine id\n */\n get machineId() {\n if (!_machineId) {\n const localStorage = getLocalStorage();\n\n if (localStorage) {\n _machineId = localStorage.getItem('jitsiMeetId');\n }\n if (!_machineId) {\n _machineId = generateJitsiMeetId();\n if (localStorage) {\n localStorage.setItem('jitsiMeetId', _machineId);\n }\n }\n }\n\n return _machineId;\n },\n\n /**\n * Returns current session id.\n * @returns {string} current session id\n */\n get sessionId() {\n // We may update sessionId in localStorage from another JitsiConference\n // instance and that's why we should always re-read it.\n const localStorage = getLocalStorage();\n\n return localStorage ? localStorage.getItem('sessionId') : undefined;\n },\n\n /**\n * Save current session id.\n * @param {string} sessionId session id\n */\n set sessionId(sessionId) {\n const localStorage = getLocalStorage();\n\n if (localStorage) {\n if (sessionId) {\n localStorage.setItem('sessionId', sessionId);\n } else {\n localStorage.removeItem('sessionId');\n }\n }\n }\n};\n\n/**\n * Generate fake username for callstats.\n * @returns {string} fake random username\n */\nfunction generateCallStatsUserName() {\n const username = UsernameGenerator.generateUsername();\n\n logger.log('generated callstats uid', username);\n\n return username;\n}\n\n/**\n * Generate unique id.\n * @returns {string} random unique id\n */\nfunction generateJitsiMeetId() {\n const jitsiMeetId = generateUniqueId();\n\n logger.log('generated id', jitsiMeetId);\n\n return jitsiMeetId;\n}\n\n/**\n * Gets the localStorage of the browser. (Technically, gets the localStorage of\n * the global object because there may be no browser but React Native for\n * example).\n * @returns {Storage} the local Storage object (if any)\n */\nfunction getLocalStorage() {\n let storage;\n\n try {\n // eslint-disable-next-line no-invalid-this\n storage = (window || this).localStorage;\n } catch (error) {\n logger.error(error);\n }\n\n return storage;\n}\n\n/**\n *\n */\nfunction generateUniqueId() {\n return _p8() + _p8() + _p8() + _p8();\n}\n\n/**\n *\n */\nfunction _p8() {\n return `${Math.random().toString(16)}000000000`.substr(2, 8);\n}\n","/**\n * @const\n */\nconst ALPHANUM\n = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n\n/**\n * Hexadecimal digits.\n * @const\n */\nconst HEX_DIGITS = '0123456789abcdef';\n\n/**\n * Generates random int within the range [min, max]\n * @param min the minimum value for the generated number\n * @param max the maximum value for the generated number\n * @returns random int number\n */\nfunction randomInt(min, max) {\n return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n\n/**\n * Get random element from array or string.\n * @param {Array|string} arr source\n * @returns array element or string character\n */\nfunction randomElement(arr) {\n return arr[randomInt(0, arr.length - 1)];\n}\n\n/**\n * Generate random alphanumeric string.\n * @param {number} length expected string length\n * @returns {string} random string of specified length\n */\nfunction randomAlphanumStr(length) {\n let result = '';\n\n for (let i = 0; i < length; i += 1) {\n result += randomElement(ALPHANUM);\n }\n\n return result;\n}\n\n/**\n * Exported interface.\n */\nconst RandomUtil = {\n /**\n * Returns a random hex digit.\n * @returns {*}\n */\n randomHexDigit() {\n return randomElement(HEX_DIGITS);\n },\n\n /**\n * Returns a random string of hex digits with length 'len'.\n * @param len the length.\n */\n randomHexString(len) {\n let ret = '';\n\n while (len--) { // eslint-disable-line no-param-reassign\n ret += this.randomHexDigit();\n }\n\n return ret;\n },\n randomElement,\n randomAlphanumStr,\n randomInt\n};\n\nmodule.exports = RandomUtil;\n","import Listenable from '../util/Listenable';\n\n/**\n * Creates ConnectionPlugin class that extends the passed class.\n * @param {Class} base the definition of the class that will be extended by\n * ConnectionPlugin\n */\nfunction getConnectionPluginDefinition(base = class {}) {\n /**\n * Base class for strophe connection plugins.\n */\n return class extends base {\n /**\n *\n */\n constructor(...args) {\n super(...args);\n this.connection = null;\n }\n\n /**\n *\n * @param connection\n */\n init(connection) {\n this.connection = connection;\n }\n };\n}\n\n/**\n * ConnectionPlugin class.\n */\nexport default getConnectionPluginDefinition();\n\n/**\n * ConnectionPlugin class that extends Listenable.\n */\nexport const ConnectionPluginListenable\n = getConnectionPluginDefinition(Listenable);\n","/* global $ */\n\nimport { getLogger } from 'jitsi-meet-logger';\nimport { $msg, $pres, Strophe } from 'strophe.js';\nimport 'strophejs-plugin-disco';\n\nimport RandomUtil from '../util/RandomUtil';\nimport * as JitsiConnectionErrors from '../../JitsiConnectionErrors';\nimport * as JitsiConnectionEvents from '../../JitsiConnectionEvents';\nimport browser from '../browser';\nimport initEmuc from './strophe.emuc';\nimport initJingle from './strophe.jingle';\nimport initStropheUtil from './strophe.util';\nimport initPing from './strophe.ping';\nimport initRayo from './strophe.rayo';\nimport initStropheLogger from './strophe.logger';\nimport LastSuccessTracker from './StropheBoshLastSuccess';\nimport Listenable from '../util/Listenable';\nimport Caps from './Caps';\nimport GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';\nimport XMPPEvents from '../../service/xmpp/XMPPEvents';\n\nconst logger = getLogger(__filename);\n\n/**\n *\n * @param token\n * @param bosh\n */\nfunction createConnection(token, bosh = '/http-bind') {\n // Append token as URL param\n if (token) {\n // eslint-disable-next-line no-param-reassign\n bosh += `${bosh.indexOf('?') === -1 ? '?' : '&'}token=${token}`;\n }\n\n const conn = new Strophe.Connection(bosh);\n\n // The default maxRetries is 5, which is too long.\n conn.maxRetries = 3;\n\n return conn;\n}\n\n// FIXME: remove once we have a default config template. -saghul\n/**\n * A list of ice servers to use by default for P2P.\n */\nexport const DEFAULT_STUN_SERVERS = [\n { urls: 'stun:stun.l.google.com:19302' },\n { urls: 'stun:stun1.l.google.com:19302' },\n { urls: 'stun:stun2.l.google.com:19302' }\n];\n\n/**\n * The name of the field used to recognize a chat message as carrying a JSON\n * payload from another endpoint.\n * If the json-message of a chat message contains a valid JSON object, and\n * the JSON has this key, then it is a valid json-message to be sent.\n */\nexport const JITSI_MEET_MUC_TYPE = 'type';\n\n/**\n *\n */\nexport default class XMPP extends Listenable {\n /**\n * FIXME describe all options\n * @param {Object} options\n * @param {Array} options.p2pStunServers see\n * {@link JingleConnectionPlugin} for more details.\n * @param token\n */\n constructor(options, token) {\n super();\n this.connection = null;\n this.disconnectInProgress = false;\n this.connectionTimes = {};\n this.options = options;\n this.token = token;\n this.authenticatedUser = false;\n this._initStrophePlugins(this);\n\n this.connection = createConnection(token, options.bosh);\n\n this._lastSuccessTracker = new LastSuccessTracker();\n this._lastSuccessTracker.startTracking(this.connection);\n\n this.caps = new Caps(this.connection, this.options.clientNode);\n\n // Initialize features advertised in disco-info\n this.initFeaturesList();\n\n // Setup a disconnect on unload as a way to facilitate API consumers. It\n // sounds like they would want that. A problem for them though may be if\n // they wanted to utilize the connected connection in an unload handler\n // of their own. However, it should be fairly easy for them to do that\n // by registering their unload handler before us.\n $(window).on('beforeunload unload', ev => {\n this.disconnect(ev).catch(() => {\n // ignore errors in order to not brake the unload.\n });\n });\n }\n\n /**\n * Initializes the list of feature advertised through the disco-info\n * mechanism.\n */\n initFeaturesList() {\n // http://xmpp.org/extensions/xep-0167.html#support\n // http://xmpp.org/extensions/xep-0176.html#support\n this.caps.addFeature('urn:xmpp:jingle:1');\n this.caps.addFeature('urn:xmpp:jingle:apps:rtp:1');\n this.caps.addFeature('urn:xmpp:jingle:transports:ice-udp:1');\n this.caps.addFeature('urn:xmpp:jingle:apps:dtls:0');\n this.caps.addFeature('urn:xmpp:jingle:transports:dtls-sctp:1');\n this.caps.addFeature('urn:xmpp:jingle:apps:rtp:audio');\n this.caps.addFeature('urn:xmpp:jingle:apps:rtp:video');\n\n if (!this.options.disableRtx && browser.supportsRtx()) {\n this.caps.addFeature('urn:ietf:rfc:4588');\n }\n\n // this is dealt with by SDP O/A so we don't need to announce this\n // XEP-0293\n // this.caps.addFeature('urn:xmpp:jingle:apps:rtp:rtcp-fb:0');\n // XEP-0294\n // this.caps.addFeature('urn:xmpp:jingle:apps:rtp:rtp-hdrext:0');\n\n this.caps.addFeature('urn:ietf:rfc:5761'); // rtcp-mux\n this.caps.addFeature('urn:ietf:rfc:5888'); // a=group, e.g. bundle\n\n // this.caps.addFeature('urn:ietf:rfc:5576'); // a=ssrc\n\n // Enable Lipsync ?\n if (browser.isChrome() && this.options.enableLipSync !== false) {\n logger.info('Lip-sync enabled !');\n this.caps.addFeature('http://jitsi.org/meet/lipsync');\n }\n\n if (this.connection.rayo) {\n this.caps.addFeature('urn:xmpp:rayo:client:1');\n }\n }\n\n /**\n * Returns {@code true} if the PING functionality is supported by the server\n * or {@code false} otherwise.\n * @returns {boolean}\n */\n isPingSupported() {\n return this._pingSupported !== false;\n }\n\n /**\n *\n */\n getConnection() {\n return this.connection;\n }\n\n /**\n * Receive connection status changes and handles them.\n *\n * @param {Object} credentials\n * @param {string} credentials.jid - The user's XMPP ID passed to the\n * connect method. For example, 'user@xmpp.com'.\n * @param {string} credentials.password - The password passed to the connect\n * method.\n * @param {string} status - One of Strophe's connection status strings.\n * @param {string} [msg] - The connection error message provided by Strophe.\n */\n connectionHandler(credentials = {}, status, msg) {\n const now = window.performance.now();\n const statusStr = Strophe.getStatusString(status).toLowerCase();\n\n this.connectionTimes[statusStr] = now;\n logger.log(\n `(TIME) Strophe ${statusStr}${msg ? `[${msg}]` : ''}:\\t`,\n now);\n\n this.eventEmitter.emit(XMPPEvents.CONNECTION_STATUS_CHANGED, credentials, status, msg);\n if (status === Strophe.Status.CONNECTED\n || status === Strophe.Status.ATTACHED) {\n if (this.options.useStunTurn\n || (this.options.p2p && this.options.p2p.useStunTurn)) {\n this.connection.jingle.getStunAndTurnCredentials();\n }\n\n logger.info(`My Jabber ID: ${this.connection.jid}`);\n\n // Schedule ping ?\n const pingJid = this.connection.domain;\n\n this.caps.getFeaturesAndIdentities(pingJid)\n .then(({ features, identities }) => {\n if (features.has(Strophe.NS.PING)) {\n this._pingSupported = true;\n this.connection.ping.startInterval(pingJid);\n } else {\n logger.warn(`Ping NOT supported by ${pingJid}`);\n }\n\n // check for speakerstats\n identities.forEach(identity => {\n if (identity.type === 'speakerstats') {\n this.speakerStatsComponentAddress = identity.name;\n\n this.connection.addHandler(\n this._onPrivateMessage.bind(this), null,\n 'message', null, null);\n }\n });\n })\n .catch(error => {\n const errmsg = 'Feature discovery error';\n\n GlobalOnErrorHandler.callErrorHandler(\n new Error(`${errmsg}: ${error}`));\n logger.error(errmsg, error);\n });\n\n if (credentials.password) {\n this.authenticatedUser = true;\n }\n if (this.connection && this.connection.connected\n && Strophe.getResourceFromJid(this.connection.jid)) {\n // .connected is true while connecting?\n // this.connection.send($pres());\n this.eventEmitter.emit(\n JitsiConnectionEvents.CONNECTION_ESTABLISHED,\n Strophe.getResourceFromJid(this.connection.jid));\n }\n } else if (status === Strophe.Status.CONNFAIL) {\n if (msg === 'x-strophe-bad-non-anon-jid') {\n this.anonymousConnectionFailed = true;\n } else {\n this.connectionFailed = true;\n }\n this.lastErrorMsg = msg;\n if (msg === 'giving-up') {\n this.eventEmitter.emit(\n JitsiConnectionEvents.CONNECTION_FAILED,\n JitsiConnectionErrors.OTHER_ERROR, msg);\n }\n } else if (status === Strophe.Status.DISCONNECTED) {\n // Stop ping interval\n this.connection.ping.stopInterval();\n const wasIntentionalDisconnect = this.disconnectInProgress;\n const errMsg = msg || this.lastErrorMsg;\n\n this.disconnectInProgress = false;\n if (this.anonymousConnectionFailed) {\n // prompt user for username and password\n this.eventEmitter.emit(\n JitsiConnectionEvents.CONNECTION_FAILED,\n JitsiConnectionErrors.PASSWORD_REQUIRED);\n } else if (this.connectionFailed) {\n this.eventEmitter.emit(\n JitsiConnectionEvents.CONNECTION_FAILED,\n JitsiConnectionErrors.OTHER_ERROR,\n errMsg,\n undefined, /* credentials */\n this._getConnectionFailedReasonDetails());\n } else if (wasIntentionalDisconnect) {\n this.eventEmitter.emit(\n JitsiConnectionEvents.CONNECTION_DISCONNECTED, errMsg);\n } else {\n // XXX if Strophe drops the connection while not being asked to,\n // it means that most likely some serious error has occurred.\n // One currently known case is when a BOSH request fails for\n // more than 4 times. The connection is dropped without\n // supplying a reason(error message/event) through the API.\n logger.error('XMPP connection dropped!');\n\n // XXX if the last request error is within 5xx range it means it\n // was a server failure\n const lastErrorStatus = Strophe.getLastErrorStatus();\n\n if (lastErrorStatus >= 500 && lastErrorStatus < 600) {\n this.eventEmitter.emit(\n JitsiConnectionEvents.CONNECTION_FAILED,\n JitsiConnectionErrors.SERVER_ERROR,\n errMsg || 'server-error',\n /* credentials */ undefined,\n this._getConnectionFailedReasonDetails());\n } else {\n this.eventEmitter.emit(\n JitsiConnectionEvents.CONNECTION_FAILED,\n JitsiConnectionErrors.CONNECTION_DROPPED_ERROR,\n errMsg || 'connection-dropped-error',\n /* credentials */ undefined,\n this._getConnectionFailedReasonDetails());\n }\n }\n } else if (status === Strophe.Status.AUTHFAIL) {\n // wrong password or username, prompt user\n this.eventEmitter.emit(\n JitsiConnectionEvents.CONNECTION_FAILED,\n JitsiConnectionErrors.PASSWORD_REQUIRED,\n msg,\n credentials);\n }\n }\n\n /**\n *\n * @param jid\n * @param password\n */\n _connect(jid, password) {\n // connection.connect() starts the connection process.\n //\n // As the connection process proceeds, the user supplied callback will\n // be triggered multiple times with status updates. The callback should\n // take two arguments - the status code and the error condition.\n //\n // The status code will be one of the values in the Strophe.Status\n // constants. The error condition will be one of the conditions defined\n // in RFC 3920 or the condition ‘strophe-parsererror’.\n //\n // The Parameters wait, hold and route are optional and only relevant\n // for BOSH connections. Please see XEP 124 for a more detailed\n // explanation of the optional parameters.\n //\n // Connection status constants for use by the connection handler\n // callback.\n //\n // Status.ERROR - An error has occurred (websockets specific)\n // Status.CONNECTING - The connection is currently being made\n // Status.CONNFAIL - The connection attempt failed\n // Status.AUTHENTICATING - The connection is authenticating\n // Status.AUTHFAIL - The authentication attempt failed\n // Status.CONNECTED - The connection has succeeded\n // Status.DISCONNECTED - The connection has been terminated\n // Status.DISCONNECTING - The connection is currently being terminated\n // Status.ATTACHED - The connection has been attached\n\n this.anonymousConnectionFailed = false;\n this.connectionFailed = false;\n this.lastErrorMsg = undefined;\n this.connection.connect(\n jid,\n password,\n this.connectionHandler.bind(this, {\n jid,\n password\n }));\n }\n\n /**\n * Attach to existing connection. Can be used for optimizations. For\n * example: if the connection is created on the server we can attach to it\n * and start using it.\n *\n * @param options {object} connecting options - rid, sid, jid and password.\n */\n attach(options) {\n const now = this.connectionTimes.attaching = window.performance.now();\n\n logger.log(`(TIME) Strophe Attaching\\t:${now}`);\n this.connection.attach(options.jid, options.sid,\n parseInt(options.rid, 10) + 1,\n this.connectionHandler.bind(this, {\n jid: options.jid,\n password: options.password\n }));\n }\n\n /**\n *\n * @param jid\n * @param password\n */\n connect(jid, password) {\n if (!jid) {\n const { anonymousdomain, domain } = this.options.hosts;\n let configDomain = anonymousdomain || domain;\n\n // Force authenticated domain if room is appended with '?login=true'\n // or if we're joining with the token\n\n // FIXME Do not rely on window.location because (1) React Native\n // does not have a window.location by default and (2) here we cannot\n // know for sure that query/search has not be stripped from\n // window.location by the time the following executes.\n const { location } = window;\n\n if (anonymousdomain) {\n const search = location && location.search;\n\n if ((search && search.indexOf('login=true') !== -1)\n || this.token) {\n configDomain = domain;\n }\n }\n\n // eslint-disable-next-line no-param-reassign\n jid = configDomain || (location && location.hostname);\n }\n\n return this._connect(jid, password);\n }\n\n /**\n * Joins or creates a muc with the provided jid, created from the passed\n * in room name and muc host and onCreateResource result.\n *\n * @param {string} roomName - The name of the muc to join.\n * @param {Object} options - Configuration for how to join the muc.\n * @param {Function} [onCreateResource] - Callback to invoke when a resource\n * is to be added to the jid.\n * @returns {Promise} Resolves with an instance of a strophe muc.\n */\n createRoom(roomName, options, onCreateResource) {\n let roomjid = `${roomName}@${this.options.hosts.muc}/`;\n\n const mucNickname = onCreateResource\n ? onCreateResource(this.connection.jid, this.authenticatedUser)\n : RandomUtil.randomHexString(8).toLowerCase();\n\n logger.info(`JID ${this.connection.jid} using MUC nickname ${mucNickname}`);\n roomjid += mucNickname;\n\n return this.connection.emuc.createRoom(roomjid, null, options);\n }\n\n /**\n * Returns the jid of the participant associated with the Strophe connection.\n *\n * @returns {string} The jid of the participant.\n */\n getJid() {\n return this.connection.jid;\n }\n\n /**\n * Returns the logs from strophe.jingle.\n * @returns {Object}\n */\n getJingleLog() {\n const jingle = this.connection.jingle;\n\n\n return jingle ? jingle.getLog() : {};\n }\n\n /**\n * Returns the logs from strophe.\n */\n getXmppLog() {\n return (this.connection.logger || {}).log || null;\n }\n\n /**\n *\n */\n dial(...args) {\n this.connection.rayo.dial(...args);\n }\n\n /**\n * Pings the server. Remember to check {@link isPingSupported} before using\n * this method.\n * @param timeout how many ms before a timeout should occur.\n * @returns {Promise} resolved on ping success and reject on an error or\n * a timeout.\n */\n ping(timeout) {\n return new Promise((resolve, reject) => {\n if (this.isPingSupported()) {\n this.connection.ping\n .ping(this.connection.domain, resolve, reject, timeout);\n } else {\n reject('PING operation is not supported by the server');\n }\n });\n }\n\n /**\n *\n */\n getSessions() {\n return this.connection.jingle.sessions;\n }\n\n /**\n * Disconnects this from the XMPP server (if this is connected).\n *\n * @param {Object} ev - Optionally, the event which triggered the necessity to\n * disconnect from the XMPP server (e.g. beforeunload, unload).\n * @returns {Promise} - Resolves when the disconnect process is finished or rejects with an error.\n */\n disconnect(ev) {\n if (this.disconnectInProgress || !this.connection) {\n this.eventEmitter.emit(JitsiConnectionEvents.WRONG_STATE);\n\n return Promise.reject(new Error('Wrong connection state!'));\n }\n\n this.disconnectInProgress = true;\n\n return new Promise(resolve => {\n const disconnectListener = (credentials, status) => {\n if (status === Strophe.Status.DISCONNECTED) {\n resolve();\n this.eventEmitter.removeListener(XMPPEvents.CONNECTION_STATUS_CHANGED, disconnectListener);\n }\n };\n\n this.eventEmitter.on(XMPPEvents.CONNECTION_STATUS_CHANGED, disconnectListener);\n\n // XXX Strophe is asynchronously sending by default. Unfortunately, that\n // means that there may not be enough time to send an unavailable\n // presence or disconnect at all. Switching Strophe to synchronous\n // sending is not much of an option because it may lead to a noticeable\n // delay in navigating away from the current location. As a compromise,\n // we will try to increase the chances of sending an unavailable\n // presence and/or disconecting within the short time span that we have\n // upon unloading by invoking flush() on the connection. We flush() once\n // before disconnect() in order to attemtp to have its unavailable\n // presence at the top of the send queue. We flush() once more after\n // disconnect() in order to attempt to have its unavailable presence\n // sent as soon as possible.\n this.connection.flush();\n\n if (ev !== null && typeof ev !== 'undefined') {\n const evType = ev.type;\n\n if (evType === 'beforeunload' || evType === 'unload') {\n // XXX Whatever we said above, synchronous sending is the best\n // (known) way to properly disconnect from the XMPP server.\n // Consequently, it may be fine to have the source code and\n // comment it in or out depending on whether we want to run with\n // it for some time.\n this.connection.options.sync = true;\n\n // This is needed in some browsers where sync xhr sending\n // is disabled by default on unload\n if (navigator.sendBeacon && !this.connection.disconnecting\n && this.connection.connected) {\n this.connection._changeConnectStatus(Strophe.Status.DISCONNECTING);\n this.connection.disconnecting = true;\n\n const body = this.connection._proto._buildBody()\n .attrs({\n type: 'terminate'\n });\n const pres = $pres({\n xmlns: Strophe.NS.CLIENT,\n type: 'unavailable'\n });\n\n body.cnode(pres.tree());\n\n const res = navigator.sendBeacon(\n `https:${this.connection.service}`,\n Strophe.serialize(body.tree()));\n\n logger.info(`Successfully send unavailable beacon ${res}`);\n\n this.connection._proto._abortAllRequests();\n this.connection._doDisconnect();\n\n return;\n }\n }\n }\n\n this.connection.disconnect();\n\n if (this.connection.options.sync !== true) {\n this.connection.flush();\n }\n });\n }\n\n /**\n *\n */\n _initStrophePlugins() {\n const iceConfig = {\n jvb: { iceServers: [ ] },\n p2p: { iceServers: [ ] }\n };\n\n const p2pStunServers = (this.options.p2p\n && this.options.p2p.stunServers) || DEFAULT_STUN_SERVERS;\n\n if (Array.isArray(p2pStunServers)) {\n logger.info('P2P STUN servers: ', p2pStunServers);\n iceConfig.p2p.iceServers = p2pStunServers;\n }\n\n if (this.options.p2p && this.options.p2p.iceTransportPolicy) {\n logger.info('P2P ICE transport policy: ',\n this.options.p2p.iceTransportPolicy);\n\n iceConfig.p2p.iceTransportPolicy\n = this.options.p2p.iceTransportPolicy;\n }\n\n initEmuc(this);\n initJingle(this, this.eventEmitter, iceConfig);\n initStropheUtil();\n initPing(this);\n initRayo();\n initStropheLogger();\n }\n\n /**\n * Returns details about connection failure. Shard change or is it after\n * suspend.\n * @returns {object} contains details about a connection failure.\n * @private\n */\n _getConnectionFailedReasonDetails() {\n const details = {};\n\n // check for moving between shard if information is available\n if (this.options.deploymentInfo\n && this.options.deploymentInfo.shard\n && this.connection._proto\n && this.connection._proto.lastResponseHeaders) {\n\n // split headers by line\n const headersArr = this.connection._proto.lastResponseHeaders\n .trim().split(/[\\r\\n]+/);\n const headers = {};\n\n headersArr.forEach(line => {\n const parts = line.split(': ');\n const header = parts.shift();\n const value = parts.join(': ');\n\n headers[header] = value;\n });\n\n /* eslint-disable camelcase */\n details.shard_changed\n = this.options.deploymentInfo.shard\n !== headers['x-jitsi-shard'];\n /* eslint-enable camelcase */\n }\n\n /* eslint-disable camelcase */\n // check for possible suspend\n details.suspend_time = this.connection.ping.getPingSuspendTime();\n details.time_since_last_success = this._lastSuccessTracker.getTimeSinceLastSuccess();\n /* eslint-enable camelcase */\n\n return details;\n }\n\n /**\n * Notifies speaker stats component if available that we are the new\n * dominant speaker in the conference.\n * @param {String} roomJid - The room jid where the speaker event occurred.\n */\n sendDominantSpeakerEvent(roomJid) {\n // no speaker stats component advertised\n if (!this.speakerStatsComponentAddress || !roomJid) {\n return;\n }\n\n const msg = $msg({ to: this.speakerStatsComponentAddress });\n\n msg.c('speakerstats', {\n xmlns: 'http://jitsi.org/jitmeet',\n room: roomJid })\n .up();\n\n this.connection.send(msg);\n }\n\n /**\n * Check if the given argument is a valid JSON ENDPOINT_MESSAGE string by\n * parsing it and checking if it has a field called 'type'.\n *\n * @param {string} jsonString check if this string is a valid json string\n * and contains the special structure.\n * @returns {boolean, object} if given object is a valid JSON string, return\n * the json object. Otherwise, returns false.\n */\n tryParseJSONAndVerify(jsonString) {\n try {\n const json = JSON.parse(jsonString);\n\n // Handle non-exception-throwing cases:\n // Neither JSON.parse(false) or JSON.parse(1234) throw errors,\n // hence the type-checking,\n // but... JSON.parse(null) returns null, and\n // typeof null === \"object\",\n // so we must check for that, too.\n // Thankfully, null is falsey, so this suffices:\n if (json && typeof json === 'object') {\n const type = json[JITSI_MEET_MUC_TYPE];\n\n if (typeof type !== 'undefined') {\n return json;\n }\n\n logger.debug('parsing valid json but does not have correct '\n + 'structure', 'topic: ', type);\n }\n } catch (e) {\n return false;\n }\n\n return false;\n }\n\n /**\n * A private message is received, message that is not addressed to the muc.\n * We expect private message coming from speaker stats component if it is\n * enabled and running.\n *\n * @param {string} msg - The message.\n */\n _onPrivateMessage(msg) {\n const from = msg.getAttribute('from');\n\n if (!this.speakerStatsComponentAddress\n || from !== this.speakerStatsComponentAddress) {\n return;\n }\n\n const jsonMessage = $(msg).find('>json-message')\n .text();\n const parsedJson = this.tryParseJSONAndVerify(jsonMessage);\n\n if (parsedJson\n && parsedJson[JITSI_MEET_MUC_TYPE] === 'speakerstats'\n && parsedJson.users) {\n this.eventEmitter.emit(\n XMPPEvents.SPEAKER_STATS_RECEIVED, parsedJson.users);\n }\n\n return true;\n }\n}\n","/**\n * The errors for the connection.\n */\n\n/**\n * Indicates that the connection was dropped with an error which was most likely\n * caused by some networking issues. The dropped term in this context means that\n * the connection was closed unexpectedly (not on user's request).\n *\n * One example is 'item-not-found' error thrown by Prosody when the BOSH session\n * times out after 60 seconds of inactivity. On the other hand 'item-not-found'\n * could also happen when BOSH request is sent to the server with the session-id\n * that is not know to the server. But this should not happen in lib-jitsi-meet\n * case as long as the service is configured correctly (there is no bug).\n */\nexport const CONNECTION_DROPPED_ERROR = 'connection.droppedError';\n\n/**\n * Not specified errors.\n */\nexport const OTHER_ERROR = 'connection.otherError';\n\n/**\n * Indicates that a password is required in order to join the conference.\n */\nexport const PASSWORD_REQUIRED = 'connection.passwordRequired';\n\n/**\n * Indicates that the connection was dropped, because of too many 5xx HTTP\n * errors on BOSH requests.\n */\nexport const SERVER_ERROR = 'connection.serverError';\n","/**\n * Event triggered when participant's muted status changes.\n * @param {string} endpointId the track owner's identifier (MUC nickname)\n * @param {MediaType} mediaType \"audio\" or \"video\"\n * @param {boolean} isMuted the new muted state\n */\nexport const PEER_MUTED_CHANGED = 'signaling.peerMuted';\n\n/**\n * Event triggered when participant's video type changes.\n * @param {string} endpointId the video owner's ID (MUC nickname)\n * @param {VideoType} videoType the new value\n */\nexport const PEER_VIDEO_TYPE_CHANGED = 'signaling.peerVideoType';\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n /* eslint-env node */\n'use strict';\n\nvar logDisabled_ = true;\nvar deprecationWarnings_ = true;\n\n// Utility methods.\nvar utils = {\n disableLog: function(bool) {\n if (typeof bool !== 'boolean') {\n return new Error('Argument type: ' + typeof bool +\n '. Please use a boolean.');\n }\n logDisabled_ = bool;\n return (bool) ? 'adapter.js logging disabled' :\n 'adapter.js logging enabled';\n },\n\n /**\n * Disable or enable deprecation warnings\n * @param {!boolean} bool set to true to disable warnings.\n */\n disableWarnings: function(bool) {\n if (typeof bool !== 'boolean') {\n return new Error('Argument type: ' + typeof bool +\n '. Please use a boolean.');\n }\n deprecationWarnings_ = !bool;\n return 'adapter.js deprecation warnings ' + (bool ? 'disabled' : 'enabled');\n },\n\n log: function() {\n if (typeof window === 'object') {\n if (logDisabled_) {\n return;\n }\n if (typeof console !== 'undefined' && typeof console.log === 'function') {\n console.log.apply(console, arguments);\n }\n }\n },\n\n /**\n * Shows a deprecation warning suggesting the modern and spec-compatible API.\n */\n deprecated: function(oldMethod, newMethod) {\n if (!deprecationWarnings_) {\n return;\n }\n console.warn(oldMethod + ' is deprecated, please use ' + newMethod +\n ' instead.');\n },\n\n /**\n * Extract browser version out of the provided user agent string.\n *\n * @param {!string} uastring userAgent string.\n * @param {!string} expr Regular expression used as match criteria.\n * @param {!number} pos position in the version string to be returned.\n * @return {!number} browser version.\n */\n extractVersion: function(uastring, expr, pos) {\n var match = uastring.match(expr);\n return match && match.length >= pos && parseInt(match[pos], 10);\n },\n\n /**\n * Browser detector.\n *\n * @return {object} result containing browser and version\n * properties.\n */\n detectBrowser: function(window) {\n var navigator = window && window.navigator;\n\n // Returned result object.\n var result = {};\n result.browser = null;\n result.version = null;\n\n // Fail early if it's not a browser\n if (typeof window === 'undefined' || !window.navigator) {\n result.browser = 'Not a browser.';\n return result;\n }\n\n // Firefox.\n if (navigator.mozGetUserMedia) {\n result.browser = 'firefox';\n result.version = this.extractVersion(navigator.userAgent,\n /Firefox\\/(\\d+)\\./, 1);\n } else if (navigator.webkitGetUserMedia) {\n // Chrome, Chromium, Webview, Opera, all use the chrome shim for now\n if (window.webkitRTCPeerConnection) {\n result.browser = 'chrome';\n result.version = this.extractVersion(navigator.userAgent,\n /Chrom(e|ium)\\/(\\d+)\\./, 2);\n } else { // Safari (in an unpublished version) or unknown webkit-based.\n if (navigator.userAgent.match(/Version\\/(\\d+).(\\d+)/)) {\n result.browser = 'safari';\n result.version = this.extractVersion(navigator.userAgent,\n /AppleWebKit\\/(\\d+)\\./, 1);\n } else { // unknown webkit-based browser.\n result.browser = 'Unsupported webkit-based browser ' +\n 'with GUM support but no WebRTC support.';\n return result;\n }\n }\n } else if (navigator.mediaDevices &&\n navigator.userAgent.match(/Edge\\/(\\d+).(\\d+)$/)) { // Edge.\n result.browser = 'edge';\n result.version = this.extractVersion(navigator.userAgent,\n /Edge\\/(\\d+).(\\d+)$/, 2);\n } else if (navigator.mediaDevices &&\n navigator.userAgent.match(/AppleWebKit\\/(\\d+)\\./)) {\n // Safari, with webkitGetUserMedia removed.\n result.browser = 'safari';\n result.version = this.extractVersion(navigator.userAgent,\n /AppleWebKit\\/(\\d+)\\./, 1);\n } else { // Default fallthrough: not supported.\n result.browser = 'Not a supported browser.';\n return result;\n }\n\n return result;\n },\n\n};\n\n// Export.\nmodule.exports = {\n log: utils.log,\n deprecated: utils.deprecated,\n disableLog: utils.disableLog,\n disableWarnings: utils.disableWarnings,\n extractVersion: utils.extractVersion,\n shimCreateObjectURL: utils.shimCreateObjectURL,\n detectBrowser: utils.detectBrowser.bind(utils)\n};\n","/**\n * The possible camera facing modes. For now support only 'user' and\n * 'environment' because 'left' and 'right' are not used anywhere in our\n * projects at the time of this writing. For more information please refer to\n * https://w3c.github.io/mediacapture-main/getusermedia.html\n * #def-constraint-facingMode.\n *\n * @enum {string}\n */\nconst CameraFacingMode = {\n /**\n * The mode which specifies the environment-facing camera.\n */\n ENVIRONMENT: 'environment',\n\n /**\n * The mode which specifies the user-facing camera.\n */\n USER: 'user'\n};\n\nmodule.exports = CameraFacingMode;\n","/* global chrome, $, alert */\n\nimport JitsiTrackError from '../../JitsiTrackError';\nimport * as JitsiTrackErrors from '../../JitsiTrackErrors';\nimport browser from '../browser';\n\nconst logger = require('jitsi-meet-logger').getLogger(__filename);\nconst GlobalOnErrorHandler = require('../util/GlobalOnErrorHandler');\n\n/**\n * Indicates whether the Chrome desktop sharing extension is installed.\n * @type {boolean}\n */\nlet chromeExtInstalled = false;\n\n/**\n * Indicates whether an update of the Chrome desktop sharing extension is\n * required.\n * @type {boolean}\n */\nlet chromeExtUpdateRequired = false;\n\nlet gumFunction = null;\n\n/**\n * The error message returned by chrome when the extension is installed.\n */\nconst CHROME_NO_EXTENSION_ERROR_MSG // eslint-disable-line no-unused-vars\n = 'Could not establish connection. Receiving end does not exist.';\n\n/**\n * Handles obtaining a stream from a screen capture on different browsers.\n */\nconst ScreenObtainer = {\n /**\n * If not null it means that the initialization process is still in\n * progress. It is used to make desktop stream request wait and continue\n * after it's done.\n * {@type Promise|null}\n */\n intChromeExtPromise: null,\n\n obtainStream: null,\n\n /**\n * Initializes the function used to obtain a screen capture\n * (this.obtainStream).\n *\n * @param {object} options\n * @param {boolean} [options.desktopSharingChromeDisabled]\n * @param {boolean} [options.desktopSharingChromeExtId]\n * @param {boolean} [options.desktopSharingFirefoxDisabled]\n * @param {Function} gum GUM method\n */\n init(options = {\n desktopSharingChromeDisabled: false,\n desktopSharingChromeExtId: null,\n desktopSharingFirefoxDisabled: false\n }, gum) {\n this.options = options;\n gumFunction = gum;\n\n this.obtainStream = this._createObtainStreamMethod(options);\n\n if (!this.obtainStream) {\n logger.info('Desktop sharing disabled');\n }\n },\n\n /**\n * Returns a method which will be used to obtain the screen sharing stream\n * (based on the browser type).\n *\n * @param {object} options passed from {@link init} - check description\n * there\n * @returns {Function}\n * @private\n */\n _createObtainStreamMethod(options) {\n if (browser.isNWJS()) {\n return (_, onSuccess, onFailure) => {\n window.JitsiMeetNW.obtainDesktopStream(\n onSuccess,\n (error, constraints) => {\n let jitsiError;\n\n // FIXME:\n // This is very very dirty fix for recognising that the\n // user have clicked the cancel button from the Desktop\n // sharing pick window. The proper solution would be to\n // detect this in the NWJS application by checking the\n // streamId === \"\". Even better solution would be to\n // stop calling GUM from the NWJS app and just pass the\n // streamId to lib-jitsi-meet. This way the desktop\n // sharing implementation for NWJS and chrome extension\n // will be the same and lib-jitsi-meet will be able to\n // control the constraints, check the streamId, etc.\n //\n // I cannot find documentation about \"InvalidStateError\"\n // but this is what we are receiving from GUM when the\n // streamId for the desktop sharing is \"\".\n\n if (error && error.name === 'InvalidStateError') {\n jitsiError = new JitsiTrackError(\n JitsiTrackErrors.CHROME_EXTENSION_USER_CANCELED\n );\n } else {\n jitsiError = new JitsiTrackError(\n error, constraints, [ 'desktop' ]);\n }\n (typeof onFailure === 'function')\n && onFailure(jitsiError);\n });\n };\n } else if (browser.isElectron()) {\n return this.obtainScreenOnElectron;\n } else if (browser.isChrome() || browser.isOpera()) {\n if (browser.supportsGetDisplayMedia()\n && !options.desktopSharingChromeDisabled) {\n\n return this.obtainScreenFromGetDisplayMedia;\n } else if (options.desktopSharingChromeDisabled\n || !options.desktopSharingChromeExtId) {\n\n return null;\n }\n\n logger.info('Using Chrome extension for desktop sharing');\n this.intChromeExtPromise\n = initChromeExtension(options).then(() => {\n this.intChromeExtPromise = null;\n });\n\n return this.obtainScreenFromExtension;\n } else if (browser.isFirefox()) {\n if (options.desktopSharingFirefoxDisabled) {\n return null;\n } else if (browser.supportsGetDisplayMedia()) {\n // Firefox 66 support getDisplayMedia\n return this.obtainScreenFromGetDisplayMedia;\n }\n\n // Legacy Firefox\n return this.obtainScreenOnFirefox;\n } else if (browser.isEdge() && browser.supportsGetDisplayMedia()) {\n return this.obtainScreenFromGetDisplayMedia;\n }\n\n logger.log(\n 'Screen sharing not supported by the current browser: ',\n browser.getName());\n\n return null;\n },\n\n /**\n * Checks whether obtaining a screen capture is supported in the current\n * environment.\n * @returns {boolean}\n */\n isSupported() {\n return this.obtainStream !== null;\n },\n\n /**\n * Obtains a screen capture stream on Firefox.\n * @param callback\n * @param errorCallback\n */\n obtainScreenOnFirefox(options, callback, errorCallback) {\n obtainWebRTCScreen(options.gumOptions, callback, errorCallback);\n },\n\n /**\n * Obtains a screen capture stream on Electron.\n *\n * @param {Object} [options] - Screen sharing options.\n * @param {Array} [options.desktopSharingSources] - Array with the\n * sources that have to be displayed in the desktop picker window ('screen',\n * 'window', etc.).\n * @param onSuccess - Success callback.\n * @param onFailure - Failure callback.\n */\n obtainScreenOnElectron(options = {}, onSuccess, onFailure) {\n if (window.JitsiMeetScreenObtainer\n && window.JitsiMeetScreenObtainer.openDesktopPicker) {\n const { desktopSharingSources, gumOptions } = options;\n\n window.JitsiMeetScreenObtainer.openDesktopPicker(\n {\n desktopSharingSources: desktopSharingSources\n || this.options.desktopSharingChromeSources\n },\n (streamId, streamType) =>\n onGetStreamResponse(\n {\n response: {\n streamId,\n streamType\n },\n gumOptions\n },\n onSuccess,\n onFailure\n ),\n err => onFailure(new JitsiTrackError(\n JitsiTrackErrors.ELECTRON_DESKTOP_PICKER_ERROR,\n err\n ))\n );\n } else {\n onFailure(new JitsiTrackError(\n JitsiTrackErrors.ELECTRON_DESKTOP_PICKER_NOT_FOUND));\n }\n },\n\n /**\n * Asks Chrome extension to call chooseDesktopMedia and gets chrome\n * 'desktop' stream for returned stream token.\n */\n obtainScreenFromExtension(options, streamCallback, failCallback) {\n if (this.intChromeExtPromise !== null) {\n this.intChromeExtPromise.then(() => {\n this.obtainScreenFromExtension(\n options, streamCallback, failCallback);\n });\n\n return;\n }\n\n const {\n desktopSharingChromeExtId,\n desktopSharingChromeSources\n } = this.options;\n\n const {\n gumOptions\n } = options;\n\n const doGetStreamFromExtensionOptions = {\n desktopSharingChromeExtId,\n desktopSharingChromeSources:\n options.desktopSharingSources || desktopSharingChromeSources,\n gumOptions\n };\n\n if (chromeExtInstalled) {\n doGetStreamFromExtension(\n doGetStreamFromExtensionOptions,\n streamCallback,\n failCallback);\n } else {\n if (chromeExtUpdateRequired) {\n /* eslint-disable no-alert */\n alert(\n 'Jitsi Desktop Streamer requires update. '\n + 'Changes will take effect after next Chrome restart.');\n\n /* eslint-enable no-alert */\n }\n\n this.handleExternalInstall(options, streamCallback,\n failCallback);\n }\n },\n\n /* eslint-disable max-params */\n\n handleExternalInstall(options, streamCallback, failCallback, e) {\n const webStoreInstallUrl = getWebStoreInstallUrl(this.options);\n\n options.listener('waitingForExtension', webStoreInstallUrl);\n this.checkForChromeExtensionOnInterval(options, streamCallback,\n failCallback, e);\n },\n\n /* eslint-enable max-params */\n\n checkForChromeExtensionOnInterval(options, streamCallback, failCallback) {\n if (options.checkAgain() === false) {\n failCallback(new JitsiTrackError(\n JitsiTrackErrors.CHROME_EXTENSION_INSTALLATION_ERROR));\n\n return;\n }\n waitForExtensionAfterInstall(this.options, options.interval, 1)\n .then(() => {\n chromeExtInstalled = true;\n options.listener('extensionFound');\n this.obtainScreenFromExtension(options,\n streamCallback, failCallback);\n })\n .catch(() => {\n this.checkForChromeExtensionOnInterval(options,\n streamCallback, failCallback);\n });\n },\n\n /**\n * Obtains a screen capture stream using getDisplayMedia.\n *\n * @param callback - The success callback.\n * @param errorCallback - The error callback.\n */\n obtainScreenFromGetDisplayMedia(options, callback, errorCallback) {\n logger.info('Using getDisplayMedia for screen sharing');\n\n let getDisplayMedia;\n\n if (navigator.getDisplayMedia) {\n getDisplayMedia = navigator.getDisplayMedia.bind(navigator);\n } else {\n // eslint-disable-next-line max-len\n getDisplayMedia = navigator.mediaDevices.getDisplayMedia.bind(navigator.mediaDevices);\n }\n\n getDisplayMedia({ video: true })\n .then(stream => {\n let applyConstraintsPromise;\n\n if (stream\n && stream.getTracks()\n && stream.getTracks().length > 0) {\n applyConstraintsPromise = stream.getTracks()[0]\n .applyConstraints(options.trackOptions);\n } else {\n applyConstraintsPromise = Promise.resolve();\n }\n\n applyConstraintsPromise.then(() =>\n callback({\n stream,\n sourceId: stream.id\n }));\n })\n .catch(() =>\n errorCallback(new JitsiTrackError(JitsiTrackErrors\n .CHROME_EXTENSION_USER_CANCELED)));\n }\n};\n\n/**\n * Obtains a desktop stream using getUserMedia.\n * For this to work on Chrome, the\n * 'chrome://flags/#enable-usermedia-screen-capture' flag must be enabled.\n *\n * On firefox, the document's domain must be white-listed in the\n * 'media.getusermedia.screensharing.allowed_domains' preference in\n * 'about:config'.\n */\nfunction obtainWebRTCScreen(options, streamCallback, failCallback) {\n gumFunction([ 'screen' ], options)\n .then(stream => streamCallback({ stream }), failCallback);\n}\n\n/**\n * Constructs inline install URL for Chrome desktop streaming extension.\n * The 'chromeExtensionId' must be defined in options parameter.\n * @param options supports \"desktopSharingChromeExtId\"\n * @returns {string}\n */\nfunction getWebStoreInstallUrl(options) {\n return (\n `https://chrome.google.com/webstore/detail/${\n options.desktopSharingChromeExtId}`);\n}\n\n/**\n * Checks whether an update of the Chrome extension is required.\n * @param minVersion minimal required version\n * @param extVersion current extension version\n * @returns {boolean}\n */\nfunction isUpdateRequired(minVersion, extVersion) {\n try {\n const s1 = minVersion.split('.');\n const s2 = extVersion.split('.');\n\n const len = Math.max(s1.length, s2.length);\n\n for (let i = 0; i < len; i++) {\n let n1 = 0,\n n2 = 0;\n\n if (i < s1.length) {\n n1 = parseInt(s1[i], 10);\n }\n if (i < s2.length) {\n n2 = parseInt(s2[i], 10);\n }\n\n if (isNaN(n1) || isNaN(n2)) {\n return true;\n } else if (n1 !== n2) {\n return n1 > n2;\n }\n }\n\n // will happen if both versions have identical numbers in\n // their components (even if one of them is longer, has more components)\n return false;\n } catch (e) {\n GlobalOnErrorHandler.callErrorHandler(e);\n logger.error('Failed to parse extension version', e);\n\n return true;\n }\n}\n\n/**\n *\n * @param callback\n * @param options\n */\nfunction checkChromeExtInstalled(callback, options) {\n if (typeof chrome === 'undefined' || !chrome || !chrome.runtime) {\n // No API, so no extension for sure\n callback(false, false);\n\n return;\n }\n chrome.runtime.sendMessage(\n options.desktopSharingChromeExtId,\n { getVersion: true },\n response => {\n if (!response || !response.version) {\n // Communication failure - assume that no endpoint exists\n logger.warn(\n 'Extension not installed?: ', chrome.runtime.lastError);\n callback(false, false);\n\n return;\n }\n\n // Check installed extension version\n const extVersion = response.version;\n\n logger.log(`Extension version is: ${extVersion}`);\n const updateRequired\n = isUpdateRequired(\n options.desktopSharingChromeMinExtVersion,\n extVersion);\n\n callback(!updateRequired, updateRequired);\n }\n );\n}\n\n/**\n *\n * @param options\n * @param streamCallback\n * @param failCallback\n */\nfunction doGetStreamFromExtension(options, streamCallback, failCallback) {\n const {\n desktopSharingChromeSources,\n desktopSharingChromeExtId,\n gumOptions\n } = options;\n\n // Sends 'getStream' msg to the extension.\n // Extension id must be defined in the config.\n chrome.runtime.sendMessage(\n desktopSharingChromeExtId,\n {\n getStream: true,\n sources: desktopSharingChromeSources\n },\n response => {\n if (!response) {\n // possibly re-wraping error message to make code consistent\n const lastError = chrome.runtime.lastError;\n\n failCallback(lastError instanceof Error\n ? lastError\n : new JitsiTrackError(\n JitsiTrackErrors.CHROME_EXTENSION_GENERIC_ERROR,\n lastError));\n\n return;\n }\n logger.log('Response from extension: ', response);\n onGetStreamResponse(\n {\n response,\n gumOptions\n },\n streamCallback,\n failCallback\n );\n }\n );\n}\n\n/**\n * Initializes with extension id set in\n * config.js to support inline installs. Host site must be selected as main\n * website of published extension.\n * @param options supports \"desktopSharingChromeExtId\"\n */\nfunction initInlineInstalls(options) {\n if ($('link[rel=chrome-webstore-item]').length === 0) {\n $('head').append('');\n }\n $('link[rel=chrome-webstore-item]').attr('href',\n getWebStoreInstallUrl(options));\n}\n\n/**\n *\n * @param options\n *\n * @return {Promise} - a Promise resolved once the initialization process is\n * finished.\n */\nfunction initChromeExtension(options) {\n // Initialize Chrome extension inline installs\n initInlineInstalls(options);\n\n return new Promise(resolve => {\n // Check if extension is installed\n checkChromeExtInstalled((installed, updateRequired) => {\n chromeExtInstalled = installed;\n chromeExtUpdateRequired = updateRequired;\n logger.info(\n `Chrome extension installed: ${\n chromeExtInstalled} updateRequired: ${\n chromeExtUpdateRequired}`);\n resolve();\n }, options);\n });\n}\n\n/**\n * Checks \"retries\" times on every \"waitInterval\"ms whether the ext is alive.\n * @param {Object} options the options passed to ScreanObtainer.obtainStream\n * @param {int} waitInterval the number of ms between retries\n * @param {int} retries the number of retries\n * @returns {Promise} returns promise that will be resolved when the extension\n * is alive and rejected if the extension is not alive even after \"retries\"\n * checks\n */\nfunction waitForExtensionAfterInstall(options, waitInterval, retries) {\n if (retries === 0) {\n return Promise.reject();\n }\n\n return new Promise((resolve, reject) => {\n let currentRetries = retries;\n const interval = window.setInterval(() => {\n checkChromeExtInstalled(installed => {\n if (installed) {\n window.clearInterval(interval);\n resolve();\n } else {\n currentRetries--;\n if (currentRetries === 0) {\n reject();\n window.clearInterval(interval);\n }\n }\n }, options);\n }, waitInterval);\n });\n}\n\n/**\n * Handles response from external application / extension and calls GUM to\n * receive the desktop streams or reports error.\n * @param {object} options\n * @param {object} options.response\n * @param {string} options.response.streamId - the streamId for the desktop\n * stream.\n * @param {string} options.response.error - error to be reported.\n * @param {object} options.gumOptions - options passed to GUM.\n * @param {Function} onSuccess - callback for success.\n * @param {Function} onFailure - callback for failure.\n * @param {object} gumOptions - options passed to GUM.\n */\nfunction onGetStreamResponse(\n options = {\n response: {},\n gumOptions: {}\n },\n onSuccess,\n onFailure) {\n const { streamId, streamType, error } = options.response || {};\n\n if (streamId) {\n const gumOptions = {\n desktopStream: streamId,\n ...options.gumOptions\n };\n\n gumFunction([ 'desktop' ], gumOptions)\n .then(stream => onSuccess({\n stream,\n sourceId: streamId,\n sourceType: streamType\n }), onFailure);\n } else {\n // As noted in Chrome Desktop Capture API:\n // If user didn't select any source (i.e. canceled the prompt)\n // then the callback is called with an empty streamId.\n if (streamId === '') {\n onFailure(new JitsiTrackError(\n JitsiTrackErrors.CHROME_EXTENSION_USER_CANCELED));\n\n return;\n }\n\n onFailure(new JitsiTrackError(\n JitsiTrackErrors.CHROME_EXTENSION_GENERIC_ERROR,\n error));\n }\n}\n\nexport default ScreenObtainer;\n","/* global __filename */\nimport { getLogger } from 'jitsi-meet-logger';\nimport * as JitsiConferenceEvents from '../../JitsiConferenceEvents';\nimport * as JitsiTrackEvents from '../../JitsiTrackEvents';\nimport * as MediaType from '../../service/RTC/MediaType';\nimport browser from '../browser';\nimport RTCEvents from '../../service/RTC/RTCEvents';\nimport Statistics from '../statistics/statistics';\nimport { createParticipantConnectionStatusEvent } from '../../service/statistics/AnalyticsEvents';\n\nconst logger = getLogger(__filename);\n\n/**\n * Default value of 500 milliseconds for\n * {@link ParticipantConnectionStatus.outOfLastNTimeout}.\n *\n * @type {number}\n */\nconst DEFAULT_NOT_IN_LAST_N_TIMEOUT = 500;\n\n/**\n * Default value of 2000 milliseconds for\n * {@link ParticipantConnectionStatus.rtcMuteTimeout}.\n *\n * @type {number}\n */\nconst DEFAULT_RTC_MUTE_TIMEOUT = 10000;\n\n/**\n * The time to wait a track to be restored. Track which was out of lastN\n * should be inactive and when entering lastN it becomes restoring and when\n * data is received from bridge it will become active, but if no data is\n * received for some time we set status of that participant connection to\n * interrupted.\n * @type {number}\n */\nconst DEFAULT_RESTORING_TIMEOUT = 10000;\n\n/**\n * Participant connection statuses.\n *\n * @type {{\n * ACTIVE: string,\n * INACTIVE: string,\n * INTERRUPTED: string,\n * RESTORING: string\n * }}\n */\nexport const ParticipantConnectionStatus = {\n /**\n * Status indicating that connection is currently active.\n */\n ACTIVE: 'active',\n\n /**\n * Status indicating that connection is currently inactive.\n * Inactive means the connection was stopped on purpose from the bridge,\n * like exiting lastN or adaptivity decided to drop video because of not\n * enough bandwidth.\n */\n INACTIVE: 'inactive',\n\n /**\n * Status indicating that connection is currently interrupted.\n */\n INTERRUPTED: 'interrupted',\n\n /**\n * Status indicating that connection is currently restoring.\n */\n RESTORING: 'restoring'\n};\n\n/**\n * Class is responsible for emitting\n * JitsiConferenceEvents.PARTICIPANT_CONN_STATUS_CHANGED events.\n */\nexport default class ParticipantConnectionStatusHandler {\n /* eslint-disable max-params*/\n /**\n * Calculates the new {@link ParticipantConnectionStatus} based on\n * the values given for some specific remote user. It is assumed that\n * the conference is currently in the JVB mode (in contrary to the P2P mode)\n * @param {boolean} isConnectionActiveByJvb true if the JVB did not get any\n * data from the user for the last 15 seconds.\n * @param {boolean} isInLastN indicates whether the user is in the last N\n * set. When set to false it means that JVB is not sending any video for\n * the user.\n * @param {boolean} isRestoringTimedout if true it means that the user has\n * been outside of last N too long to be considered\n * {@link ParticipantConnectionStatus.RESTORING}.\n * @param {boolean} isVideoMuted true if the user is video muted and we\n * should not expect to receive any video.\n * @param {boolean} isVideoTrackFrozen if the current browser support video\n * frozen detection then it will be set to true when the video track is\n * frozen. If the current browser does not support frozen detection the it's\n * always false.\n * @return {ParticipantConnectionStatus} the new connection status for\n * the user for whom the values above were provided.\n * @private\n */\n static _getNewStateForJvbMode(\n isConnectionActiveByJvb,\n isInLastN,\n isRestoringTimedout,\n isVideoMuted,\n isVideoTrackFrozen) {\n if (!isConnectionActiveByJvb) {\n // when there is a connection problem signaled from jvb\n // it means no media was flowing for at least 15secs, so both audio\n // and video are most likely interrupted\n return ParticipantConnectionStatus.INTERRUPTED;\n } else if (isVideoMuted) {\n // If the connection is active according to JVB and the user is\n // video muted there is no way for the connection to be inactive,\n // because the detection logic below only makes sense for video.\n return ParticipantConnectionStatus.ACTIVE;\n }\n\n // Logic when isVideoTrackFrozen is supported\n if (browser.supportsVideoMuteOnConnInterrupted()) {\n if (!isVideoTrackFrozen) {\n // If the video is playing we're good\n return ParticipantConnectionStatus.ACTIVE;\n } else if (isInLastN) {\n return isRestoringTimedout\n ? ParticipantConnectionStatus.INTERRUPTED\n : ParticipantConnectionStatus.RESTORING;\n }\n\n return ParticipantConnectionStatus.INACTIVE;\n }\n\n // Because this browser is incapable of detecting frozen video we must\n // rely on the lastN value\n return isInLastN\n ? ParticipantConnectionStatus.ACTIVE\n : ParticipantConnectionStatus.INACTIVE;\n }\n\n /* eslint-enable max-params*/\n\n /**\n * In P2P mode we don't care about any values coming from the JVB and\n * the connection status can be only active or interrupted.\n * @param {boolean} isVideoMuted the user if video muted\n * @param {boolean} isVideoTrackFrozen true if the video track for\n * the remote user is currently frozen. If the current browser does not\n * support video frozen detection then it's always false.\n * @return {ParticipantConnectionStatus}\n * @private\n */\n static _getNewStateForP2PMode(isVideoMuted, isVideoTrackFrozen) {\n if (!browser.supportsVideoMuteOnConnInterrupted()) {\n // There's no way to detect problems in P2P when there's no video\n // track frozen detection...\n return ParticipantConnectionStatus.ACTIVE;\n }\n\n return isVideoMuted || !isVideoTrackFrozen\n ? ParticipantConnectionStatus.ACTIVE\n : ParticipantConnectionStatus.INTERRUPTED;\n }\n\n /**\n * Creates new instance of ParticipantConnectionStatus.\n *\n * @constructor\n * @param {RTC} rtc the RTC service instance\n * @param {JitsiConference} conference parent conference instance\n * @param {Object} options\n * @param {number} [options.rtcMuteTimeout=2000] custom value for\n * {@link ParticipantConnectionStatus.rtcMuteTimeout}.\n * @param {number} [options.outOfLastNTimeout=500] custom value for\n * {@link ParticipantConnectionStatus.outOfLastNTimeout}.\n */\n constructor(rtc, conference, options) {\n this.rtc = rtc;\n this.conference = conference;\n\n /**\n * A map of the \"endpoint ID\"(which corresponds to the resource part\n * of MUC JID(nickname)) to the timeout callback IDs scheduled using\n * window.setTimeout.\n * @type {Object.}\n */\n this.trackTimers = {};\n\n /**\n * This map holds the endpoint connection status received from the JVB\n * (as it might be different than the one stored in JitsiParticipant).\n * Required for getting back in sync when remote video track is removed.\n * @type {Object.}\n */\n this.connStatusFromJvb = { };\n\n /**\n * If video track frozen detection through RTC mute event is supported,\n * we wait some time until video track is considered frozen. But because\n * when the user falls out of last N it is expected for the video to\n * freeze this timeout must be significantly reduced in \"out of last N\"\n * case.\n *\n * Basically this value is used instead of {@link rtcMuteTimeout} when\n * user is not in last N.\n * @type {number}\n */\n this.outOfLastNTimeout\n = typeof options.outOfLastNTimeout === 'number'\n ? options.outOfLastNTimeout : DEFAULT_NOT_IN_LAST_N_TIMEOUT;\n\n /**\n * How long we're going to wait after the RTC video track muted event\n * for the corresponding signalling mute event, before the connection\n * interrupted is fired. The default value is\n * {@link DEFAULT_RTC_MUTE_TIMEOUT}.\n *\n * @type {number} amount of time in milliseconds\n */\n this.rtcMuteTimeout\n = typeof options.rtcMuteTimeout === 'number'\n ? options.rtcMuteTimeout : DEFAULT_RTC_MUTE_TIMEOUT;\n\n /**\n * This map holds a timestamp indicating when participant's video track\n * was RTC muted (it is assumed that each participant can have only 1\n * video track at a time). The purpose of storing the timestamp is to\n * avoid the transition to disconnected status in case of legitimate\n * video mute operation where the signalling video muted event can\n * arrive shortly after RTC muted event.\n *\n * The key is participant's ID which is the same as endpoint id in\n * the Colibri conference allocated on the JVB.\n *\n * The value is a timestamp measured in milliseconds obtained with\n * Date.now().\n *\n * FIXME merge this logic with NO_DATA_FROM_SOURCE event\n * implemented in JitsiLocalTrack by extending the event to\n * the remote track and allowing to set different timeout for\n * local and remote tracks.\n *\n * @type {Object.}\n */\n this.rtcMutedTimestamp = { };\n logger.info(`RtcMuteTimeout set to: ${this.rtcMuteTimeout}`);\n\n /**\n * This map holds the timestamps indicating when participant's video\n * entered lastN set. Participants entering lastN will have connection\n * status restoring and when we start receiving video will become\n * active, but if video is not received for certain time\n * {@link DEFAULT_RESTORING_TIMEOUT} that participant connection status\n * will become interrupted.\n *\n * @type {Map}\n */\n this.enteredLastNTimestamp = new Map();\n\n /**\n * A map of the \"endpoint ID\"(which corresponds to the resource part\n * of MUC JID(nickname)) to the restoring timeout callback IDs\n * scheduled using window.setTimeout.\n *\n * @type {Map}\n */\n this.restoringTimers = new Map();\n\n /**\n * A map that holds the current connection status (along with all the internal events that happen\n * while in that state).\n *\n * The goal is to send this information to the analytics backend for post-mortem analysis.\n */\n this.connectionStatusMap = new Map();\n }\n\n /**\n * Gets the video frozen timeout for given user.\n * @param {string} id endpoint/participant ID\n * @return {number} how long are we going to wait since RTC video muted\n * even, before a video track is considered frozen.\n * @private\n */\n _getVideoFrozenTimeout(id) {\n return this.rtc.isInLastN(id)\n ? this.rtcMuteTimeout : this.outOfLastNTimeout;\n }\n\n /**\n * Initializes ParticipantConnectionStatus and bind required event\n * listeners.\n */\n init() {\n\n this._onEndpointConnStatusChanged\n = this.onEndpointConnStatusChanged.bind(this);\n\n this.rtc.addListener(\n RTCEvents.ENDPOINT_CONN_STATUS_CHANGED,\n this._onEndpointConnStatusChanged);\n\n // Handles P2P status changes\n this._onP2PStatus = this.refreshConnectionStatusForAll.bind(this);\n this.conference.on(JitsiConferenceEvents.P2P_STATUS, this._onP2PStatus);\n\n // Used to send analytics events for the participant that left the call.\n this._onUserLeft = this.onUserLeft.bind(this);\n this.conference.on(JitsiConferenceEvents.USER_LEFT, this._onUserLeft);\n\n // On some browsers MediaStreamTrack trigger \"onmute\"/\"onunmute\"\n // events for video type tracks when they stop receiving data which is\n // often a sign that remote user is having connectivity issues\n if (browser.supportsVideoMuteOnConnInterrupted()) {\n\n this._onTrackRtcMuted = this.onTrackRtcMuted.bind(this);\n this.rtc.addListener(\n RTCEvents.REMOTE_TRACK_MUTE, this._onTrackRtcMuted);\n\n this._onTrackRtcUnmuted = this.onTrackRtcUnmuted.bind(this);\n this.rtc.addListener(\n RTCEvents.REMOTE_TRACK_UNMUTE, this._onTrackRtcUnmuted);\n\n // Track added/removed listeners are used to bind \"mute\"/\"unmute\"\n // event handlers\n this._onRemoteTrackAdded = this.onRemoteTrackAdded.bind(this);\n this.conference.on(\n JitsiConferenceEvents.TRACK_ADDED,\n this._onRemoteTrackAdded);\n\n this._onRemoteTrackRemoved = this.onRemoteTrackRemoved.bind(this);\n this.conference.on(\n JitsiConferenceEvents.TRACK_REMOVED,\n this._onRemoteTrackRemoved);\n\n // Listened which will be bound to JitsiRemoteTrack to listen for\n // signalling mute/unmute events.\n this._onSignallingMuteChanged\n = this.onSignallingMuteChanged.bind(this);\n\n // Used to send an analytics event when the video type changes.\n this._onTrackVideoTypeChanged\n = this.onTrackVideoTypeChanged.bind(this);\n }\n\n this._onLastNChanged = this._onLastNChanged.bind(this);\n this.conference.on(\n JitsiConferenceEvents.LAST_N_ENDPOINTS_CHANGED,\n this._onLastNChanged);\n\n this._onLastNValueChanged\n = this.refreshConnectionStatusForAll.bind(this);\n this.rtc.on(\n RTCEvents.LASTN_VALUE_CHANGED, this._onLastNValueChanged);\n }\n\n /**\n * Removes all event listeners and disposes of all resources held by this\n * instance.\n */\n dispose() {\n\n this.rtc.removeListener(\n RTCEvents.ENDPOINT_CONN_STATUS_CHANGED,\n this._onEndpointConnStatusChanged);\n\n if (browser.supportsVideoMuteOnConnInterrupted()) {\n this.rtc.removeListener(\n RTCEvents.REMOTE_TRACK_MUTE,\n this._onTrackRtcMuted);\n this.rtc.removeListener(\n RTCEvents.REMOTE_TRACK_UNMUTE,\n this._onTrackRtcUnmuted);\n\n this.conference.off(\n JitsiConferenceEvents.TRACK_ADDED,\n this._onRemoteTrackAdded);\n this.conference.off(\n JitsiConferenceEvents.TRACK_REMOVED,\n this._onRemoteTrackRemoved);\n }\n\n this.conference.off(\n JitsiConferenceEvents.LAST_N_ENDPOINTS_CHANGED,\n this._onLastNChanged);\n\n this.rtc.removeListener(\n RTCEvents.LASTN_VALUE_CHANGED, this._onLastNValueChanged);\n\n this.conference.off(\n JitsiConferenceEvents.P2P_STATUS, this._onP2PStatus);\n\n this.conference.off(\n JitsiConferenceEvents.USER_LEFT, this._onUserLeft);\n\n const participantIds = Object.keys(this.trackTimers);\n\n for (const participantId of participantIds) {\n this.clearTimeout(participantId);\n this.clearRtcMutedTimestamp(participantId);\n }\n\n for (const id in this.connectionStatusMap) {\n if (this.connectionStatusMap.hasOwnProperty(id)) {\n this.onUserLeft(id);\n }\n }\n\n // Clear RTC connection status cache\n this.connStatusFromJvb = {};\n }\n\n /**\n * Handles RTCEvents.ENDPOINT_CONN_STATUS_CHANGED triggered when we receive\n * notification over the data channel from the bridge about endpoint's\n * connection status update.\n * @param {string} endpointId - The endpoint ID(MUC nickname/resource JID).\n * @param {boolean} isActive - true if the connection is OK or false otherwise.\n */\n onEndpointConnStatusChanged(endpointId, isActive) {\n\n logger.debug(\n `Detector RTCEvents.ENDPOINT_CONN_STATUS_CHANGED(${Date.now()}): ${\n endpointId}: ${isActive}`);\n\n // Filter out events for the local JID for now\n if (endpointId !== this.conference.myUserId()) {\n // Store the status received over the data channels\n this.connStatusFromJvb[endpointId] = isActive;\n this.figureOutConnectionStatus(endpointId);\n }\n }\n\n /**\n * Changes connection status.\n * @param {JitsiParticipant} participant\n * @param newStatus\n */\n _changeConnectionStatus(participant, newStatus) {\n if (participant.getConnectionStatus() !== newStatus) {\n\n const endpointId = participant.getId();\n\n participant._setConnectionStatus(newStatus);\n\n logger.debug(\n `Emit endpoint conn status(${Date.now()}) ${endpointId}: ${\n newStatus}`);\n\n // Log the event on CallStats\n Statistics.sendLog(\n JSON.stringify({\n id: 'peer.conn.status',\n participant: endpointId,\n status: newStatus\n }));\n\n\n this.conference.eventEmitter.emit(\n JitsiConferenceEvents.PARTICIPANT_CONN_STATUS_CHANGED,\n endpointId, newStatus);\n }\n }\n\n /**\n * Reset the postponed \"connection interrupted\" event which was previously\n * scheduled as a timeout on RTC 'onmute' event.\n *\n * @param {string} participantId - The participant for which the \"connection\n * interrupted\" timeout was scheduled.\n */\n clearTimeout(participantId) {\n if (this.trackTimers[participantId]) {\n window.clearTimeout(this.trackTimers[participantId]);\n this.trackTimers[participantId] = null;\n }\n }\n\n /**\n * Clears the timestamp of the RTC muted event for participant's video track\n * @param {string} participantId the id of the conference participant which\n * is the same as the Colibri endpoint ID of the video channel allocated for\n * the user on the videobridge.\n */\n clearRtcMutedTimestamp(participantId) {\n this.rtcMutedTimestamp[participantId] = null;\n }\n\n /**\n * Bind signalling mute event listeners for video {JitsiRemoteTrack} when\n * a new one is added to the conference.\n *\n * @param {JitsiTrack} remoteTrack - The {JitsiTrack} which is being added to\n * the conference.\n */\n onRemoteTrackAdded(remoteTrack) {\n if (!remoteTrack.isLocal()\n && remoteTrack.getType() === MediaType.VIDEO) {\n\n logger.debug(\n `Detector on remote track added for: ${\n remoteTrack.getParticipantId()}`);\n\n remoteTrack.on(\n JitsiTrackEvents.TRACK_MUTE_CHANGED,\n this._onSignallingMuteChanged);\n remoteTrack.on(\n JitsiTrackEvents.TRACK_VIDEOTYPE_CHANGED,\n videoType => this._onTrackVideoTypeChanged(remoteTrack, videoType));\n }\n }\n\n /**\n * Removes all event listeners bound to the remote video track and clears\n * any related timeouts.\n *\n * @param {JitsiRemoteTrack} remoteTrack - The remote track which is being\n * removed from the conference.\n */\n onRemoteTrackRemoved(remoteTrack) {\n if (!remoteTrack.isLocal()\n && remoteTrack.getType() === MediaType.VIDEO) {\n\n const endpointId = remoteTrack.getParticipantId();\n\n logger.debug(`Detector on remote track removed: ${endpointId}`);\n\n remoteTrack.off(\n JitsiTrackEvents.TRACK_MUTE_CHANGED,\n this._onSignallingMuteChanged);\n\n this.clearTimeout(endpointId);\n this.clearRtcMutedTimestamp(endpointId);\n\n this.figureOutConnectionStatus(endpointId);\n }\n }\n\n /**\n * Checks if given participant's video is considered frozen.\n * @param {JitsiParticipant} participant - The participant.\n * @return {boolean} true if the video has frozen for given\n * participant or false when it's either not considered frozen\n * (yet) or if freeze detection is not supported by the current browser.\n *\n * FIXME merge this logic with NO_DATA_FROM_SOURCE event\n * implemented in JitsiLocalTrack by extending the event to\n * the remote track and allowing to set different timeout for\n * local and remote tracks.\n *\n */\n isVideoTrackFrozen(participant) {\n if (!browser.supportsVideoMuteOnConnInterrupted()) {\n return false;\n }\n\n const id = participant.getId();\n const hasAnyVideoRTCMuted = participant.hasAnyVideoTrackWebRTCMuted();\n const rtcMutedTimestamp = this.rtcMutedTimestamp[id];\n const timeout = this._getVideoFrozenTimeout(id);\n\n return hasAnyVideoRTCMuted\n && typeof rtcMutedTimestamp === 'number'\n && (Date.now() - rtcMutedTimestamp) >= timeout;\n }\n\n /**\n * Goes over every participant and updates connectivity status.\n * Should be called when a parameter which affects all of the participants\n * is changed (P2P for example).\n */\n refreshConnectionStatusForAll() {\n const participants = this.conference.getParticipants();\n\n for (const participant of participants) {\n this.figureOutConnectionStatus(participant.getId());\n }\n }\n\n /**\n * Figures out (and updates) the current connectivity status for\n * the participant identified by the given id.\n *\n * @param {string} id - The participant's id (MUC nickname or Colibri endpoint ID).\n */\n figureOutConnectionStatus(id) {\n const participant = this.conference.getParticipantById(id);\n\n if (!participant) {\n // Probably the participant is no longer in the conference\n // (at the time of writing this code, participant is\n // detached from the conference and TRACK_REMOVED events are\n // fired),\n // so we don't care, but let's print a log message for debugging purposes.\n logger.debug(`figure out conn status - no participant for: ${id}`);\n\n return;\n }\n\n const inP2PMode = this.conference.isP2PActive();\n const isRestoringTimedOut = this._isRestoringTimedout(id);\n const audioOnlyMode = this.rtc.getLastN() === 0;\n\n // NOTE Overriding videoMuted to true for audioOnlyMode should disable\n // any detection based on video playback or the last N.\n const isVideoMuted = participant.isVideoMuted() || audioOnlyMode;\n const isVideoTrackFrozen = this.isVideoTrackFrozen(participant);\n const isInLastN = this.rtc.isInLastN(id);\n let isConnActiveByJvb = this.connStatusFromJvb[id];\n\n if (typeof isConnActiveByJvb !== 'boolean') {\n // If no status was received from the JVB it means that it's active\n // (the bridge does not send notification unless there is a problem)\n logger.debug('Assuming connection active by JVB - no notification');\n isConnActiveByJvb = true;\n }\n\n const newState\n = inP2PMode\n ? ParticipantConnectionStatusHandler._getNewStateForP2PMode(\n isVideoMuted,\n isVideoTrackFrozen)\n : ParticipantConnectionStatusHandler._getNewStateForJvbMode(\n isConnActiveByJvb,\n isInLastN,\n isRestoringTimedOut,\n isVideoMuted,\n isVideoTrackFrozen);\n\n // if the new state is not restoring clear timers and timestamps\n // that we use to track the restoring state\n if (newState !== ParticipantConnectionStatus.RESTORING) {\n this._clearRestoringTimer(id);\n }\n\n logger.debug(\n `Figure out conn status for ${id}, is video muted: ${\n isVideoMuted} is active(jvb): ${\n isConnActiveByJvb} video track frozen: ${\n isVideoTrackFrozen} p2p mode: ${\n inP2PMode} is in last N: ${\n isInLastN} currentStatus => newStatus: ${\n participant.getConnectionStatus()} => ${newState}`);\n\n const oldConnectionStatus = this.connectionStatusMap[id] || {};\n\n // Send an analytics event (guard on either the p2p flag or the connection status has changed\n // since the last time this code block run).\n if (!('p2p' in oldConnectionStatus)\n || !('connectionStatus' in oldConnectionStatus)\n || oldConnectionStatus.p2p !== inP2PMode\n || oldConnectionStatus.connectionStatus !== newState) {\n\n const nowMs = Date.now();\n\n this.maybeSendParticipantConnectionStatusEvent(id, nowMs);\n\n this.connectionStatusMap[id] = {\n ...oldConnectionStatus,\n connectionStatus: newState,\n p2p: inP2PMode,\n startedMs: nowMs\n };\n\n // sometimes (always?) we're late to hook the TRACK_VIDEOTYPE_CHANGED event and the\n // video type is not in oldConnectionStatus.\n if (!('videoType' in this.connectionStatusMap[id])) {\n const videoTracks = participant.getTracksByMediaType(MediaType.VIDEO);\n\n if (Array.isArray(videoTracks) && videoTracks.length !== 0) {\n this.connectionStatusMap[id].videoType = videoTracks[0].videoType;\n }\n }\n }\n this._changeConnectionStatus(participant, newState);\n }\n\n /**\n * Computes the duration of the current connection status for the participant with the specified id (i.e. 15 seconds\n * in the INTERRUPTED state) and sends a participant connection status event.\n * @param {string} id - The jid of the participant.\n * @param {Number} nowMs - The current time (in millis).\n * @returns {void}\n */\n maybeSendParticipantConnectionStatusEvent(id, nowMs) {\n const participantConnectionStatus = this.connectionStatusMap[id];\n\n if (participantConnectionStatus\n && 'startedMs' in participantConnectionStatus\n && 'videoType' in participantConnectionStatus\n && 'connectionStatus' in participantConnectionStatus\n && 'p2p' in participantConnectionStatus) {\n participantConnectionStatus.value = nowMs - participantConnectionStatus.startedMs;\n Statistics.sendAnalytics(\n createParticipantConnectionStatusEvent(participantConnectionStatus));\n }\n }\n\n /**\n * On change in Last N set check all leaving and entering participants to\n * change their corresponding statuses.\n *\n * @param {Array} leavingLastN - The array of ids leaving lastN.\n * @param {Array} enteringLastN - The array of ids entering lastN.\n * @private\n */\n _onLastNChanged(leavingLastN = [], enteringLastN = []) {\n const now = Date.now();\n\n logger.debug(\n 'leaving/entering lastN', leavingLastN, enteringLastN, now);\n\n for (const id of leavingLastN) {\n this.enteredLastNTimestamp.delete(id);\n this._clearRestoringTimer(id);\n this.figureOutConnectionStatus(id);\n }\n for (const id of enteringLastN) {\n // store the timestamp this id is entering lastN\n this.enteredLastNTimestamp.set(id, now);\n this.figureOutConnectionStatus(id);\n }\n }\n\n /**\n * Clears the restoring timer for participant's video track and the\n * timestamp for entering lastN.\n *\n * @param {string} participantId - The id of the conference participant which\n * is the same as the Colibri endpoint ID of the video channel allocated for\n * the user on the videobridge.\n */\n _clearRestoringTimer(participantId) {\n const rTimer = this.restoringTimers.get(participantId);\n\n if (rTimer) {\n clearTimeout(rTimer);\n this.restoringTimers.delete(participantId);\n }\n }\n\n /**\n * Checks whether a track had stayed enough in restoring state, compares\n * current time and the time the track entered in lastN. If it hasn't\n * timedout and there is no timer added, add new timer in order to give it\n * more time to become active or mark it as interrupted on next check.\n *\n * @param {string} participantId - The id of the conference participant which\n * is the same as the Colibri endpoint ID of the video channel allocated for\n * the user on the videobridge.\n * @returns {boolean} true if the track was in restoring state\n * more than the timeout ({@link DEFAULT_RESTORING_TIMEOUT}.) in order to\n * set its status to interrupted.\n * @private\n */\n _isRestoringTimedout(participantId) {\n const enteredLastNTimestamp\n = this.enteredLastNTimestamp.get(participantId);\n\n if (enteredLastNTimestamp\n && (Date.now() - enteredLastNTimestamp)\n >= DEFAULT_RESTORING_TIMEOUT) {\n return true;\n }\n\n // still haven't reached timeout, if there is no timer scheduled,\n // schedule one so we can track the restoring state and change it after\n // reaching the timeout\n const rTimer = this.restoringTimers.get(participantId);\n\n if (!rTimer) {\n this.restoringTimers.set(participantId, setTimeout(\n () => this.figureOutConnectionStatus(participantId),\n DEFAULT_RESTORING_TIMEOUT));\n }\n\n return false;\n }\n\n /**\n * Sends a last/final participant connection status event for the participant that left the conference.\n * @param {string} id - The id of the participant that left the conference.\n * @returns {void}\n */\n onUserLeft(id) {\n this.maybeSendParticipantConnectionStatusEvent(id, Date.now());\n delete this.connectionStatusMap[id];\n }\n\n /**\n * Handles RTC 'onmute' event for the video track.\n *\n * @param {JitsiRemoteTrack} track - The video track for which 'onmute' event\n * will be processed.\n */\n onTrackRtcMuted(track) {\n const participantId = track.getParticipantId();\n const participant = this.conference.getParticipantById(participantId);\n\n logger.debug(`Detector track RTC muted: ${participantId}`, Date.now());\n if (!participant) {\n logger.error(`No participant for id: ${participantId}`);\n\n return;\n }\n this.rtcMutedTimestamp[participantId] = Date.now();\n if (!participant.isVideoMuted()) {\n // If the user is not muted according to the signalling we'll give\n // it some time, before the connection interrupted event is\n // triggered.\n this.clearTimeout(participantId);\n\n // The timeout is reduced when user is not in the last N\n const timeout = this._getVideoFrozenTimeout(participantId);\n\n this.trackTimers[participantId] = window.setTimeout(() => {\n logger.debug(\n `Set RTC mute timeout for: ${participantId}\\\n of ${timeout} ms`);\n this.clearTimeout(participantId);\n this.figureOutConnectionStatus(participantId);\n }, timeout);\n }\n }\n\n /**\n * Handles RTC 'onunmute' event for the video track.\n *\n * @param {JitsiRemoteTrack} track - The video track for which 'onunmute'\n * event will be processed.\n */\n onTrackRtcUnmuted(track) {\n const participantId = track.getParticipantId();\n\n logger.debug(\n `Detector track RTC unmuted: ${participantId}`, Date.now());\n\n this.clearTimeout(participantId);\n this.clearRtcMutedTimestamp(participantId);\n\n this.figureOutConnectionStatus(participantId);\n }\n\n /**\n * Here the signalling \"mute\"/\"unmute\" events are processed.\n *\n * @param {JitsiRemoteTrack} track - The remote video track for which\n * the signalling mute/unmute event will be processed.\n */\n onSignallingMuteChanged(track) {\n const participantId = track.getParticipantId();\n\n logger.debug(\n `Detector on track signalling mute changed: ${participantId}`,\n track.isMuted());\n\n this.figureOutConnectionStatus(participantId);\n }\n\n /**\n * Sends a participant connection status event as a result of the video type\n * changing.\n * @param {JitsiRemoteTrack} track - The track.\n * @param {VideoType} type - The video type.\n * @returns {void}\n */\n onTrackVideoTypeChanged(track, type) {\n const id = track.getParticipantId();\n const nowMs = Date.now();\n\n this.maybeSendParticipantConnectionStatusEvent(id, nowMs);\n\n this.connectionStatusMap[id] = {\n ...this.connectionStatusMap[id] || {},\n videoType: type,\n startedMs: nowMs\n };\n }\n}\n","/**\n * A collection of utility functions for taking in XML and parsing it to return\n * certain values.\n */\nexport default {\n /**\n * Parses the presence update of the focus and returns an object with the\n * statuses related to recording.\n *\n * @param {Node} presence - An XMPP presence update.\n * @returns {Object} The current presence values related to recording.\n */\n getFocusRecordingUpdate(presence) {\n const jibriStatus = presence\n && presence.getElementsByTagName('jibri-recording-status')[0];\n\n if (!jibriStatus) {\n return;\n }\n\n return {\n error: jibriStatus.getAttribute('failure_reason'),\n initiator: jibriStatus.getAttribute('initiator'),\n recordingMode: jibriStatus.getAttribute('recording_mode'),\n sessionID: jibriStatus.getAttribute('session_id'),\n status: jibriStatus.getAttribute('status')\n };\n },\n\n /**\n * Parses the presence update from a hidden domain participant and returns\n * an object with the statuses related to recording.\n *\n * @param {Node} presence - An XMPP presence update.\n * @returns {Object} The current presence values related to recording.\n */\n getHiddenDomainUpdate(presence) {\n const liveStreamViewURLContainer\n = presence.getElementsByTagName('live-stream-view-url')[0];\n const liveStreamViewURL = liveStreamViewURLContainer\n && liveStreamViewURLContainer.textContent;\n const modeContainer\n = presence.getElementsByTagName('mode')[0];\n const mode = modeContainer\n && modeContainer.textContent\n && modeContainer.textContent.toLowerCase();\n const sessionIDContainer\n = presence.getElementsByTagName('session_id')[0];\n const sessionID\n = sessionIDContainer && sessionIDContainer.textContent;\n\n return {\n liveStreamViewURL,\n mode,\n sessionID\n };\n },\n\n /**\n * Returns the recording session ID from a successful IQ.\n *\n * @param {Node} response - The response from the IQ.\n * @returns {string} The session ID of the recording session.\n */\n getSessionIdFromIq(response) {\n const jibri = response && response.getElementsByTagName('jibri')[0];\n\n return jibri && jibri.getAttribute('session_id');\n },\n\n /**\n * Returns the recording session ID from a presence, if it exists.\n *\n * @param {Node} presence - An XMPP presence update.\n * @returns {string|undefined} The session ID of the recording session.\n */\n getSessionId(presence) {\n const sessionIdContainer\n = presence.getElementsByTagName('session_id')[0];\n const sessionId = sessionIdContainer && sessionIdContainer.textContent;\n\n return sessionId;\n },\n\n /**\n * Returns whether or not a presence is from the focus.\n *\n * @param {Node} presence - An XMPP presence update.\n * @returns {boolean} True if the presence is from the focus.\n */\n isFromFocus(presence) {\n return presence.getAttribute('from').includes('focus');\n }\n};\n","var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n","/* global __filename, $ */\n\nimport {\n ICE_DURATION,\n ICE_STATE_CHANGED\n} from '../../service/statistics/AnalyticsEvents';\nimport { getLogger } from 'jitsi-meet-logger';\nimport { $iq, Strophe } from 'strophe.js';\nimport { integerHash } from '../util/StringUtils';\n\nimport JingleSession from './JingleSession';\nimport * as JingleSessionState from './JingleSessionState';\nimport SDP from './SDP';\nimport SDPDiffer from './SDPDiffer';\nimport SDPUtil from './SDPUtil';\nimport SignalingLayerImpl from './SignalingLayerImpl';\n\nimport RTCEvents from '../../service/RTC/RTCEvents';\nimport Statistics from '../statistics/statistics';\nimport XMPPEvents from '../../service/xmpp/XMPPEvents';\nimport AsyncQueue from '../util/AsyncQueue';\nimport GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';\n\nconst logger = getLogger(__filename);\n\n/**\n * Constant tells how long we're going to wait for IQ response, before timeout\n * error is triggered.\n * @type {number}\n */\nconst IQ_TIMEOUT = 10000;\n\n/*\n * The default number of samples (per stat) to keep when webrtc stats gathering\n * is enabled in TraceablePeerConnection.\n */\nconst DEFAULT_MAX_STATS = 300;\n\n/**\n * @typedef {Object} JingleSessionPCOptions\n * @property {Object} abTesting - A/B testing related options (ask George).\n * @property {boolean} abTesting.enableSuspendVideoTest - enables the suspend\n * video test ?(ask George).\n * @property {boolean} disableH264 - Described in the config.js[1].\n * @property {boolean} disableRtx - Described in the config.js[1].\n * @property {boolean} disableSimulcast - Described in the config.js[1].\n * @property {boolean} enableLayerSuspension - Described in the config.js[1].\n * @property {boolean} failICE - it's an option used in the tests. Set to\n * true to block any real candidates and make the ICE fail.\n * @property {boolean} gatherStats - Described in the config.js[1].\n * @property {object} p2p - Peer to peer related options (FIXME those could be\n * fetched from config.p2p on the upper level).\n * @property {boolean} p2p.disableH264 - Described in the config.js[1].\n * @property {boolean} p2p.preferH264 - Described in the config.js[1].\n * @property {boolean} preferH264 - Described in the config.js[1].\n * @property {Object} testing - Testing and/or experimental options.\n * @property {boolean} testing.enableFirefoxSimulcast - Described in the\n * config.js[1].\n * @property {boolean} webrtcIceUdpDisable - Described in the config.js[1].\n * @property {boolean} webrtcIceTcpDisable - Described in the config.js[1].\n *\n * [1]: https://github.com/jitsi/jitsi-meet/blob/master/config.js\n */\n/**\n *\n */\nexport default class JingleSessionPC extends JingleSession {\n /**\n * Parses 'senders' attribute of the video content.\n * @param {jQuery} jingleContents\n * @return {string|null} one of the values of content \"senders\" attribute\n * defined by Jingle. If there is no \"senders\" attribute or if the value is\n * invalid then null will be returned.\n * @private\n */\n static parseVideoSenders(jingleContents) {\n const videoContents = jingleContents.find('>content[name=\"video\"]');\n\n if (videoContents.length) {\n const senders = videoContents[0].getAttribute('senders');\n\n if (senders === 'both'\n || senders === 'initiator'\n || senders === 'responder'\n || senders === 'none') {\n return senders;\n }\n }\n\n return null;\n }\n\n /* eslint-disable max-params */\n\n /**\n * Creates new JingleSessionPC\n * @param {string} sid the Jingle Session ID - random string which\n * identifies the session\n * @param {string} localJid our JID\n * @param {string} remoteJid remote peer JID\n * @param {Strophe.Connection} connection Strophe XMPP connection instance\n * used to send packets.\n * @param mediaConstraints the media constraints object passed to\n * createOffer/Answer, as defined by the WebRTC standard\n * @param iceConfig the ICE servers config object as defined by the WebRTC\n * standard.\n * @param {boolean} isP2P indicates whether this instance is\n * meant to be used in a direct, peer to peer connection or false\n * if it's a JVB connection.\n * @param {boolean} isInitiator indicates if it will be the side which\n * initiates the session.\n * @constructor\n *\n * @implements {SignalingLayer}\n */\n constructor(\n sid,\n localJid,\n remoteJid,\n connection,\n mediaConstraints,\n iceConfig,\n isP2P,\n isInitiator) {\n super(\n sid,\n localJid,\n remoteJid, connection, mediaConstraints, iceConfig, isInitiator);\n\n /**\n * The bridge session's identifier. One Jingle session can during\n * it's lifetime participate in multiple bridge sessions managed by\n * Jicofo. A new bridge session is started whenever Jicofo sends\n * 'session-initiate' or 'transport-replace'.\n *\n * @type {?string}\n * @private\n */\n this._bridgeSessionId = null;\n\n /**\n * Stores result of {@link window.performance.now()} at the time when\n * ICE enters 'checking' state.\n * @type {number|null} null if no value has been stored yet\n * @private\n */\n this._iceCheckingStartedTimestamp = null;\n\n /**\n * Stores result of {@link window.performance.now()} at the time when\n * first ICE candidate is spawned by the peerconnection to mark when\n * ICE gathering started. That's, because ICE gathering state changed\n * events are not supported by most of the browsers, so we try something\n * that will work everywhere. It may not be as accurate, but given that\n * 'host' candidate usually comes first, the delay should be minimal.\n * @type {number|null} null if no value has been stored yet\n * @private\n */\n this._gatheringStartedTimestamp = null;\n\n /**\n * Indicates whether or not this session is willing to send/receive\n * video media. When set to false the underlying peer\n * connection will disable local video transfer and the remote peer will\n * be will be asked to stop sending video via 'content-modify' IQ\n * (the senders attribute of video contents will be adjusted\n * accordingly). Note that this notification is sent only in P2P\n * session, because Jicofo does not support it yet. Obviously when\n * the value is changed from false to true another\n * notification will be sent to resume video transfer on the remote\n * side.\n * @type {boolean}\n * @private\n */\n this._localVideoActive = true;\n\n /**\n * Indicates whether or not the remote peer has video transfer active.\n * When set to true it means that remote peer is neither\n * sending nor willing to receive video. In such case we'll ask\n * our peerconnection to stop sending video by calling\n * {@link TraceablePeerConnection.setVideoTransferActive} with\n * false.\n * @type {boolean}\n * @private\n */\n this._remoteVideoActive = true;\n\n /**\n * Marks that ICE gathering duration has been reported already. That\n * prevents reporting it again, after eventual 'transport-replace' (JVB\n * conference migration/ICE restart).\n * @type {boolean}\n * @private\n */\n this._gatheringReported = false;\n\n this.lasticecandidate = false;\n this.closed = false;\n\n /**\n * Indicates whether or not this JingleSessionPC is used in\n * a peer to peer type of session.\n * @type {boolean} true if it's a peer to peer\n * session or false if it's a JVB session\n */\n this.isP2P = isP2P;\n\n /**\n * The signaling layer implementation.\n * @type {SignalingLayerImpl}\n */\n this.signalingLayer = new SignalingLayerImpl();\n\n /**\n * The queue used to serialize operations done on the peerconnection.\n *\n * @type {AsyncQueue}\n */\n this.modificationQueue = new AsyncQueue();\n\n /**\n * Flag used to guarantee that the connection established event is\n * triggered just once.\n * @type {boolean}\n */\n this.wasConnected = false;\n\n /**\n * Keeps track of how long (in ms) it took from ICE start to ICE\n * connect.\n *\n * @type {number}\n */\n this.establishmentDuration = undefined;\n }\n\n /* eslint-enable max-params */\n\n /**\n * Checks whether or not this session instance is still operational.\n * @private\n * @returns {boolean} {@code true} if operation or {@code false} otherwise.\n */\n _assertNotEnded() {\n return this.state !== JingleSessionState.ENDED;\n }\n\n /**\n * @inheritDoc\n * @param {JingleSessionPCOptions} options - a set of config options.\n */\n doInitialize(options) {\n this.failICE = Boolean(options.failICE);\n this.lasticecandidate = false;\n this.options = options;\n\n /**\n * {@code true} if reconnect is in progress.\n * @type {boolean}\n */\n this.isReconnect = false;\n\n /**\n * Set to {@code true} if the connection was ever stable\n * @type {boolean}\n */\n this.wasstable = false;\n this.webrtcIceUdpDisable = Boolean(options.webrtcIceUdpDisable);\n this.webrtcIceTcpDisable = Boolean(options.webrtcIceTcpDisable);\n\n const pcOptions = { disableRtx: options.disableRtx };\n\n if (options.gatherStats) {\n pcOptions.maxstats = DEFAULT_MAX_STATS;\n }\n pcOptions.capScreenshareBitrate = false;\n if (this.isP2P) {\n // simulcast needs to be disabled for P2P (121) calls\n pcOptions.disableSimulcast = true;\n pcOptions.disableH264 = options.p2p && options.p2p.disableH264;\n pcOptions.preferH264 = options.p2p && options.p2p.preferH264;\n\n const abtestSuspendVideo = this._abtestSuspendVideoEnabled(options);\n\n if (typeof abtestSuspendVideo !== 'undefined') {\n pcOptions.abtestSuspendVideo = abtestSuspendVideo;\n }\n } else {\n // H264 does not support simulcast, so it needs to be disabled.\n pcOptions.disableSimulcast\n = options.disableSimulcast\n || (options.preferH264 && !options.disableH264);\n pcOptions.preferH264 = options.preferH264;\n pcOptions.enableFirefoxSimulcast\n = options.testing && options.testing.enableFirefoxSimulcast;\n pcOptions.enableLayerSuspension = options.enableLayerSuspension;\n\n // disable simulcast for screenshare and set the max bitrate to\n // 500Kbps if the testing flag is present in config.js.\n if (options.testing\n && options.testing.capScreenshareBitrate\n && typeof options.testing.capScreenshareBitrate === 'number') {\n pcOptions.capScreenshareBitrate\n = Math.random()\n < options.testing.capScreenshareBitrate;\n\n // add the capScreenshareBitrate to the permanent properties so\n // that it's included with every event that we send to the\n // analytics backend.\n Statistics.analytics.addPermanentProperties({ capScreenshareBitrate: pcOptions.capScreenshareBitrate });\n }\n }\n\n if (options.startSilent) {\n pcOptions.startSilent = true;\n }\n\n this.peerconnection\n = this.rtc.createPeerConnection(\n this.signalingLayer,\n this.iceConfig,\n this.isP2P,\n pcOptions);\n\n this.peerconnection.onicecandidate = ev => {\n if (!ev) {\n // There was an incomplete check for ev before which left\n // the last line of the function unprotected from a potential\n // throw of an exception. Consequently, it may be argued that\n // the check is unnecessary. Anyway, I'm leaving it and making\n // the check complete.\n return;\n }\n\n // XXX this is broken, candidate is not parsed.\n const candidate = ev.candidate;\n const now = window.performance.now();\n\n if (candidate) {\n if (this._gatheringStartedTimestamp === null) {\n this._gatheringStartedTimestamp = now;\n }\n\n // Discard candidates of disabled protocols.\n let protocol = candidate.protocol;\n\n if (typeof protocol === 'string') {\n protocol = protocol.toLowerCase();\n if (protocol === 'tcp' || protocol === 'ssltcp') {\n if (this.webrtcIceTcpDisable) {\n return;\n }\n } else if (protocol === 'udp') {\n if (this.webrtcIceUdpDisable) {\n return;\n }\n }\n }\n } else if (!this._gatheringReported) {\n // End of gathering\n Statistics.sendAnalytics(\n ICE_DURATION,\n {\n phase: 'gathering',\n value: now - this._gatheringStartedTimestamp,\n p2p: this.isP2P,\n initiator: this.isInitiator\n });\n this._gatheringReported = true;\n }\n this.sendIceCandidate(candidate);\n };\n\n // Note there is a change in the spec about closed:\n // This value moved into the RTCPeerConnectionState enum in\n // the May 13, 2016 draft of the specification, as it reflects the state\n // of the RTCPeerConnection, not the signaling connection. You now\n // detect a closed connection by checking for connectionState to be\n // \"closed\" instead.\n // I suppose at some point this will be moved to onconnectionstatechange\n this.peerconnection.onsignalingstatechange = () => {\n if (this.peerconnection.signalingState === 'stable') {\n this.wasstable = true;\n } else if (this.peerconnection.signalingState === 'closed'\n || this.peerconnection.connectionState === 'closed') {\n this.room.eventEmitter.emit(XMPPEvents.SUSPEND_DETECTED, this);\n }\n };\n\n /**\n * The oniceconnectionstatechange event handler contains the code to\n * execute when the iceconnectionstatechange event, of type Event,\n * is received by this RTCPeerConnection. Such an event is sent when\n * the value of RTCPeerConnection.iceConnectionState changes.\n */\n this.peerconnection.oniceconnectionstatechange = () => {\n const now = window.performance.now();\n\n if (!this.isP2P) {\n this.room.connectionTimes[\n `ice.state.${this.peerconnection.iceConnectionState}`]\n = now;\n }\n logger.log(\n `(TIME) ICE ${this.peerconnection.iceConnectionState}`\n + ` P2P? ${this.isP2P}:\\t`,\n now);\n\n Statistics.sendAnalytics(\n ICE_STATE_CHANGED,\n {\n p2p: this.isP2P,\n state: this.peerconnection.iceConnectionState,\n 'signaling_state': this.peerconnection.signalingState,\n reconnect: this.isReconnect,\n value: now\n });\n\n this.room.eventEmitter.emit(\n XMPPEvents.ICE_CONNECTION_STATE_CHANGED,\n this,\n this.peerconnection.iceConnectionState);\n switch (this.peerconnection.iceConnectionState) {\n case 'checking':\n this._iceCheckingStartedTimestamp = now;\n break;\n case 'connected':\n // Informs interested parties that the connection has been\n // restored.\n if (this.peerconnection.signalingState === 'stable') {\n if (this.isReconnect) {\n this.room.eventEmitter.emit(\n XMPPEvents.CONNECTION_RESTORED, this);\n }\n }\n\n if (!this.wasConnected && this.wasstable) {\n\n Statistics.sendAnalytics(\n ICE_DURATION,\n {\n phase: 'checking',\n value: now - this._iceCheckingStartedTimestamp,\n p2p: this.isP2P,\n initiator: this.isInitiator\n });\n\n // Switch between ICE gathering and ICE checking whichever\n // started first (scenarios are different for initiator\n // vs responder)\n const iceStarted\n = Math.min(\n this._iceCheckingStartedTimestamp,\n this._gatheringStartedTimestamp);\n\n this.establishmentDuration = now - iceStarted;\n\n Statistics.sendAnalytics(\n ICE_DURATION,\n {\n phase: 'establishment',\n value: this.establishmentDuration,\n p2p: this.isP2P,\n initiator: this.isInitiator\n });\n\n this.wasConnected = true;\n this.room.eventEmitter.emit(\n XMPPEvents.CONNECTION_ESTABLISHED, this);\n }\n this.isReconnect = false;\n break;\n case 'disconnected':\n this.isReconnect = true;\n\n // Informs interested parties that the connection has been\n // interrupted.\n if (this.wasstable) {\n this.room.eventEmitter.emit(\n XMPPEvents.CONNECTION_INTERRUPTED, this);\n }\n break;\n case 'failed':\n this.room.eventEmitter.emit(\n XMPPEvents.CONNECTION_ICE_FAILED, this);\n break;\n }\n };\n this.peerconnection.onnegotiationneeded = () => {\n this.room.eventEmitter.emit(XMPPEvents.PEERCONNECTION_READY, this);\n };\n\n // The signaling layer will bind it's listeners at this point\n this.signalingLayer.setChatRoom(this.room);\n\n if (!this.isP2P && options.enableLayerSuspension) {\n // If this is the bridge session, we'll listen for\n // IS_SELECTED_CHANGED events and notify the peer connection\n this.rtc.addListener(RTCEvents.IS_SELECTED_CHANGED,\n isSelected => {\n this.peerconnection.setIsSelected(isSelected);\n logger.info('Doing local O/A due to '\n + 'IS_SELECTED_CHANGED event');\n this.modificationQueue.push(finishedCallback => {\n this._renegotiate()\n .then(finishedCallback)\n .catch(finishedCallback);\n });\n }\n );\n }\n }\n\n /**\n * Sends given candidate in Jingle 'transport-info' message.\n * @param {RTCIceCandidate} candidate the WebRTC ICE candidate instance\n * @private\n */\n sendIceCandidate(candidate) {\n const localSDP = new SDP(this.peerconnection.localDescription.sdp);\n\n if (candidate && !this.lasticecandidate) {\n const ice\n = SDPUtil.iceparams(\n localSDP.media[candidate.sdpMLineIndex], localSDP.session);\n const jcand = SDPUtil.candidateToJingle(candidate.candidate);\n\n if (!(ice && jcand)) {\n const errorMesssage = 'failed to get ice && jcand';\n\n GlobalOnErrorHandler.callErrorHandler(new Error(errorMesssage));\n logger.error(errorMesssage);\n\n return;\n }\n ice.xmlns = 'urn:xmpp:jingle:transports:ice-udp:1';\n\n if (this.usedrip) {\n if (this.dripContainer.length === 0) {\n // start 20ms callout\n setTimeout(() => {\n if (this.dripContainer.length === 0) {\n return;\n }\n this.sendIceCandidates(this.dripContainer);\n this.dripContainer = [];\n }, 20);\n }\n this.dripContainer.push(candidate);\n } else {\n this.sendIceCandidates([ candidate ]);\n }\n } else {\n logger.log('sendIceCandidate: last candidate.');\n\n // FIXME: remember to re-think in ICE-restart\n this.lasticecandidate = true;\n }\n }\n\n /**\n * Sends given candidates in Jingle 'transport-info' message.\n * @param {Array} candidates an array of the WebRTC ICE\n * candidate instances\n * @private\n */\n sendIceCandidates(candidates) {\n if (!this._assertNotEnded('sendIceCandidates')) {\n\n return;\n }\n\n logger.log('sendIceCandidates', candidates);\n const cand = $iq({ to: this.remoteJid,\n type: 'set' })\n .c('jingle', { xmlns: 'urn:xmpp:jingle:1',\n action: 'transport-info',\n initiator: this.initiatorJid,\n sid: this.sid });\n\n const localSDP = new SDP(this.peerconnection.localDescription.sdp);\n\n for (let mid = 0; mid < localSDP.media.length; mid++) {\n const cands = candidates.filter(el => el.sdpMLineIndex === mid);\n const mline\n = SDPUtil.parseMLine(localSDP.media[mid].split('\\r\\n')[0]);\n\n if (cands.length > 0) {\n const ice\n = SDPUtil.iceparams(localSDP.media[mid], localSDP.session);\n\n ice.xmlns = 'urn:xmpp:jingle:transports:ice-udp:1';\n cand.c('content', {\n creator: this.initiatorJid === this.localJid\n ? 'initiator' : 'responder',\n name: cands[0].sdpMid ? cands[0].sdpMid : mline.media\n }).c('transport', ice);\n for (let i = 0; i < cands.length; i++) {\n const candidate\n = SDPUtil.candidateToJingle(cands[i].candidate);\n\n // Mangle ICE candidate if 'failICE' test option is enabled\n\n if (this.failICE) {\n candidate.ip = '1.1.1.1';\n }\n cand.c('candidate', candidate).up();\n }\n\n // add fingerprint\n const fingerprintLine\n = SDPUtil.findLine(\n localSDP.media[mid],\n 'a=fingerprint:', localSDP.session);\n\n if (fingerprintLine) {\n const tmp = SDPUtil.parseFingerprint(fingerprintLine);\n\n tmp.required = true;\n cand.c(\n 'fingerprint',\n { xmlns: 'urn:xmpp:jingle:apps:dtls:0' })\n .t(tmp.fingerprint);\n delete tmp.fingerprint;\n cand.attrs(tmp);\n cand.up();\n }\n cand.up(); // transport\n cand.up(); // content\n }\n }\n\n // might merge last-candidate notification into this, but it is called\n // a lot later. See webrtc issue #2340\n // logger.log('was this the last candidate', this.lasticecandidate);\n this.connection.sendIQ(\n cand, null, this.newJingleErrorHandler(cand), IQ_TIMEOUT);\n }\n\n /**\n * Sends Jingle 'session-info' message which includes custom Jitsi Meet\n * 'ice-state' element with the text value 'failed' to let Jicofo know\n * that the ICE connection has entered the failed state. It can then\n * choose to re-create JVB channels and send 'transport-replace' to\n * retry the connection.\n */\n sendIceFailedNotification() {\n const sessionInfo\n = $iq({\n to: this.remoteJid,\n type: 'set' })\n .c('jingle', { xmlns: 'urn:xmpp:jingle:1',\n action: 'session-info',\n initiator: this.initiatorJid,\n sid: this.sid })\n .c('ice-state', { xmlns: 'http://jitsi.org/protocol/focus' })\n .t('failed')\n .up();\n\n this._bridgeSessionId\n && sessionInfo.c(\n 'bridge-session', {\n xmlns: 'http://jitsi.org/protocol/focus',\n id: this._bridgeSessionId\n });\n\n this.connection.sendIQ(\n sessionInfo,\n null,\n this.newJingleErrorHandler(sessionInfo),\n /*\n * This message will be often sent when there are connectivity\n * issues, so make it slightly longer than Prosody's default BOSH\n * inactivity timeout of 60 seconds.\n */ 65);\n }\n\n /**\n * {@inheritDoc}\n */\n addIceCandidates(elem) {\n if (this.peerconnection.signalingState === 'closed') {\n logger.warn('Ignored add ICE candidate when in closed state');\n\n return;\n }\n\n const iceCandidates = [];\n\n elem.find('>content>transport>candidate')\n .each((idx, candidate) => {\n let line = SDPUtil.candidateFromJingle(candidate);\n\n line = line.replace('\\r\\n', '').replace('a=', '');\n\n // FIXME this code does not care to handle\n // non-bundle transport\n const rtcCandidate = new RTCIceCandidate({\n sdpMLineIndex: 0,\n\n // FF comes up with more complex names like audio-23423,\n // Given that it works on both Chrome and FF without\n // providing it, let's leave it like this for the time\n // being...\n // sdpMid: 'audio',\n sdpMid: '',\n candidate: line\n });\n\n iceCandidates.push(rtcCandidate);\n });\n\n if (!iceCandidates.length) {\n logger.error(\n 'No ICE candidates to add ?', elem[0] && elem[0].outerHTML);\n\n return;\n }\n\n // We want to have this task queued, so that we know it is executed,\n // after the initial sRD/sLD offer/answer cycle was done (based on\n // the assumption that candidates are spawned after the offer/answer\n // and XMPP preserves order).\n const workFunction = finishedCallback => {\n for (const iceCandidate of iceCandidates) {\n this.peerconnection.addIceCandidate(iceCandidate)\n .then(\n () => logger.debug('addIceCandidate ok!'),\n err => logger.error('addIceCandidate failed!', err));\n }\n\n finishedCallback();\n };\n\n logger.debug(\n `Queued add (${iceCandidates.length}) ICE candidates task...`);\n this.modificationQueue.push(workFunction);\n }\n\n /**\n *\n * @param contents\n */\n readSsrcInfo(contents) {\n const ssrcs\n = $(contents).find(\n '>description>'\n + 'source[xmlns=\"urn:xmpp:jingle:apps:rtp:ssma:0\"]');\n\n ssrcs.each((i, ssrcElement) => {\n const ssrc = Number(ssrcElement.getAttribute('ssrc'));\n\n if (this.isP2P) {\n // In P2P all SSRCs are owner by the remote peer\n this.signalingLayer.setSSRCOwner(\n ssrc, Strophe.getResourceFromJid(this.remoteJid));\n } else {\n $(ssrcElement)\n .find('>ssrc-info[xmlns=\"http://jitsi.org/jitmeet\"]')\n .each((i3, ssrcInfoElement) => {\n const owner = ssrcInfoElement.getAttribute('owner');\n\n if (owner && owner.length) {\n if (isNaN(ssrc) || ssrc < 0) {\n logger.warn(\n `Invalid SSRC ${ssrc} value received`\n + ` for ${owner}`);\n } else {\n this.signalingLayer.setSSRCOwner(\n ssrc,\n Strophe.getResourceFromJid(owner));\n }\n }\n });\n }\n });\n }\n\n /**\n * Makes the underlying TraceablePeerConnection generate new SSRC for\n * the recvonly video stream.\n * @deprecated\n */\n generateRecvonlySsrc() {\n if (this.peerconnection) {\n this.peerconnection.generateRecvonlySsrc();\n } else {\n logger.error(\n 'Unable to generate recvonly SSRC - no peerconnection');\n }\n }\n\n /* eslint-disable max-params */\n /**\n * Accepts incoming Jingle 'session-initiate' and should send\n * 'session-accept' in result.\n * @param jingleOffer jQuery selector pointing to the jingle element of\n * the offer IQ\n * @param success callback called when we accept incoming session\n * successfully and receive RESULT packet to 'session-accept' sent.\n * @param failure function(error) called if for any reason we fail to accept\n * the incoming offer. 'error' argument can be used to log some details\n * about the error.\n * @param {Array} [localTracks] the optional list of\n * the local tracks that will be added, before the offer/answer cycle\n * executes. We allow the localTracks to optionally be passed in so that\n * the addition of the local tracks and the processing of the initial offer\n * can all be done atomically. We want to make sure that any other\n * operations which originate in the XMPP Jingle messages related with\n * this session to be executed with an assumption that the initial\n * offer/answer cycle has been executed already.\n */\n acceptOffer(jingleOffer, success, failure, localTracks) {\n this.setOfferAnswerCycle(\n jingleOffer,\n () => {\n // FIXME we may not care about RESULT packet for session-accept\n // then we should either call 'success' here immediately or\n // modify sendSessionAccept method to do that\n this.sendSessionAccept(success, failure);\n },\n failure,\n localTracks);\n }\n\n /* eslint-enable max-params */\n\n /**\n * Creates an offer and sends Jingle 'session-initiate' to the remote peer.\n * @param {Array} localTracks the local tracks that will be\n * added, before the offer/answer cycle executes (for the local track\n * addition to be an atomic operation together with the offer/answer).\n */\n invite(localTracks) {\n if (!this.isInitiator) {\n throw new Error('Trying to invite from the responder session');\n }\n const workFunction = finishedCallback => {\n for (const localTrack of localTracks) {\n this.peerconnection.addTrack(localTrack);\n }\n this.peerconnection.createOffer(this.mediaConstraints)\n .then(offerSdp => {\n this.peerconnection.setLocalDescription(offerSdp)\n .then(() => {\n // NOTE that the offer is obtained from\n // the localDescription getter as it needs to go\n // though the transformation chain.\n this.sendSessionInitiate(\n this.peerconnection.localDescription.sdp);\n finishedCallback();\n }, error => {\n logger.error(\n 'Failed to set local SDP', error, offerSdp);\n finishedCallback(error);\n });\n }, error => {\n logger.error(\n 'Failed to create an offer',\n error,\n this.mediaConstraints);\n finishedCallback(error);\n });\n };\n\n this.modificationQueue.push(\n workFunction,\n error => {\n if (error) {\n logger.error('invite error', error);\n } else {\n logger.debug('invite executed - OK');\n }\n });\n }\n\n /**\n * Sends 'session-initiate' to the remote peer.\n *\n * NOTE this method is synchronous and we're not waiting for the RESULT\n * response which would delay the startup process.\n *\n * @param {string} offerSdp - The local session description which will be\n * used to generate an offer.\n * @private\n */\n sendSessionInitiate(offerSdp) {\n let init = $iq({\n to: this.remoteJid,\n type: 'set'\n }).c('jingle', {\n xmlns: 'urn:xmpp:jingle:1',\n action: 'session-initiate',\n initiator: this.initiatorJid,\n sid: this.sid\n });\n\n new SDP(offerSdp).toJingle(\n init,\n this.isInitiator ? 'initiator' : 'responder');\n init = init.tree();\n logger.info('Session-initiate: ', init);\n this.connection.sendIQ(init,\n () => {\n logger.info('Got RESULT for \"session-initiate\"');\n },\n error => {\n logger.error('\"session-initiate\" error', error);\n },\n IQ_TIMEOUT);\n }\n\n /**\n * Sets the answer received from the remote peer.\n * @param jingleAnswer\n */\n setAnswer(jingleAnswer) {\n if (!this.isInitiator) {\n throw new Error('Trying to set an answer on the responder session');\n }\n this.setOfferAnswerCycle(\n jingleAnswer,\n () => {\n logger.info('setAnswer - succeeded');\n },\n error => {\n logger.error('setAnswer failed: ', error);\n });\n }\n\n /* eslint-disable max-params */\n /**\n * This is a setRemoteDescription/setLocalDescription cycle which starts at\n * converting Strophe Jingle IQ into remote offer SDP. Once converted\n * setRemoteDescription, createAnswer and setLocalDescription calls follow.\n * @param jingleOfferAnswerIq jQuery selector pointing to the jingle element\n * of the offer (or answer) IQ\n * @param success callback called when sRD/sLD cycle finishes successfully.\n * @param failure callback called with an error object as an argument if we\n * fail at any point during setRD, createAnswer, setLD.\n * @param {Array} [localTracks] the optional list of\n * the local tracks that will be added, before the offer/answer cycle\n * executes (for the local track addition to be an atomic operation together\n * with the offer/answer).\n */\n setOfferAnswerCycle(jingleOfferAnswerIq, success, failure, localTracks) {\n const workFunction = finishedCallback => {\n\n if (localTracks) {\n for (const track of localTracks) {\n this.peerconnection.addTrack(track);\n }\n }\n\n const newRemoteSdp\n = this._processNewJingleOfferIq(jingleOfferAnswerIq);\n const oldLocalSdp\n = this.peerconnection.localDescription.sdp;\n\n const bridgeSession\n = $(jingleOfferAnswerIq)\n .find('>bridge-session['\n + 'xmlns=\"http://jitsi.org/protocol/focus\"]');\n const bridgeSessionId = bridgeSession.attr('id');\n\n if (bridgeSessionId !== this._bridgeSessionId) {\n this._bridgeSessionId = bridgeSessionId;\n }\n\n this._renegotiate(newRemoteSdp.raw)\n .then(() => {\n if (this.state === JingleSessionState.PENDING) {\n this.state = JingleSessionState.ACTIVE;\n\n // Sync up video transfer active/inactive only after\n // the initial O/A cycle. We want to adjust the video\n // media direction only in the local SDP and the Jingle\n // contents direction included in the initial\n // offer/answer is mapped to the remote SDP. Jingle\n // 'content-modify' IQ is processed in a way that it\n // will only modify local SDP when remote peer is no\n // longer interested in receiving video content.\n // Changing media direction in the remote SDP will mess\n // up our SDP translation chain (simulcast, video mute,\n // RTX etc.)\n if (this.isP2P && !this._localVideoActive) {\n this.sendContentModify(this._localVideoActive);\n }\n }\n\n // Old local SDP will be available when we're setting answer\n // for the first time, but not when offer and it's fine\n // since we're generating an answer now it will contain all\n // our SSRCs\n if (oldLocalSdp) {\n const newLocalSdp\n = new SDP(this.peerconnection.localDescription.sdp);\n\n this.notifyMySSRCUpdate(\n new SDP(oldLocalSdp), newLocalSdp);\n }\n\n finishedCallback();\n }, error => {\n logger.error(\n `Error renegotiating after setting new remote ${\n this.isInitiator ? 'answer: ' : 'offer: '}${error}`,\n newRemoteSdp);\n\n finishedCallback(error);\n });\n };\n\n this.modificationQueue.push(\n workFunction,\n error => {\n error ? failure(error) : success();\n });\n }\n\n /* eslint-enable max-params */\n\n /**\n * Although it states \"replace transport\" it does accept full Jingle offer\n * which should contain new ICE transport details.\n * @param jingleOfferElem an element Jingle IQ that contains new offer and\n * transport info.\n * @param success callback called when we succeed to accept new offer.\n * @param failure function(error) called when we fail to accept new offer.\n */\n replaceTransport(jingleOfferElem, success, failure) {\n this.room.eventEmitter.emit(XMPPEvents.ICE_RESTARTING, this);\n\n // We need to first reject the 'data' section to have the SCTP stack\n // cleaned up to signal the known data channel is now invalid. After\n // that the original offer is set to have the SCTP connection\n // established with the new bridge.\n const originalOffer = jingleOfferElem.clone();\n\n jingleOfferElem\n .find('>content[name=\\'data\\']')\n .attr('senders', 'rejected');\n\n // Remove all remote sources in order to reset the client's state\n // for the remote MediaStreams. When a conference is moved to\n // another bridge it will start streaming with a sequence number\n // that is not in sync with the most recently seen by the client.\n // The symptoms include frozen or black video and lots of \"failed to\n // unprotect SRTP packets\" in Chrome logs.\n jingleOfferElem\n .find('>content>description>source')\n .remove();\n jingleOfferElem\n .find('>content>description>ssrc-group')\n .remove();\n\n // On the JVB it's not a real ICE restart and all layers are re-initialized from scratch as Jicofo does\n // the restart by re-allocating new channels. Chrome (or WebRTC stack) needs to have the DTLS transport layer\n // reset to start a new handshake with fresh DTLS transport on the bridge. Make it think that the DTLS\n // fingerprint has changed by setting an all zeros key.\n const newFingerprint = jingleOfferElem.find('>content>transport>fingerprint');\n\n newFingerprint.attr('hash', 'sha-1');\n newFingerprint.text('00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00');\n\n // First set an offer with a rejected 'data' section\n this.setOfferAnswerCycle(\n jingleOfferElem,\n () => {\n // Now set the original offer(with the 'data' section)\n this.setOfferAnswerCycle(\n originalOffer,\n () => {\n const localSDP\n = new SDP(this.peerconnection.localDescription.sdp);\n\n this.sendTransportAccept(localSDP, success, failure);\n\n this.room.eventEmitter.emit(\n XMPPEvents.ICE_RESTART_SUCCESS,\n this,\n originalOffer);\n },\n failure);\n },\n failure\n );\n }\n\n /**\n * Sends Jingle 'session-accept' message.\n * @param {function()} success callback called when we receive 'RESULT'\n * packet for the 'session-accept'\n * @param {function(error)} failure called when we receive an error response\n * or when the request has timed out.\n * @private\n */\n sendSessionAccept(success, failure) {\n // NOTE: since we're just reading from it, we don't need to be within\n // the modification queue to access the local description\n const localSDP = new SDP(this.peerconnection.localDescription.sdp);\n let accept = $iq({ to: this.remoteJid,\n type: 'set' })\n .c('jingle', { xmlns: 'urn:xmpp:jingle:1',\n action: 'session-accept',\n initiator: this.initiatorJid,\n responder: this.responderJid,\n sid: this.sid });\n\n if (this.webrtcIceTcpDisable) {\n localSDP.removeTcpCandidates = true;\n }\n if (this.webrtcIceUdpDisable) {\n localSDP.removeUdpCandidates = true;\n }\n if (this.failICE) {\n localSDP.failICE = true;\n }\n localSDP.toJingle(\n accept,\n this.initiatorJid === this.localJid ? 'initiator' : 'responder',\n null);\n\n // Calling tree() to print something useful\n accept = accept.tree();\n logger.info('Sending session-accept', accept);\n this.connection.sendIQ(accept,\n success,\n this.newJingleErrorHandler(accept, error => {\n failure(error);\n\n // 'session-accept' is a critical timeout and we'll\n // have to restart\n this.room.eventEmitter.emit(\n XMPPEvents.SESSION_ACCEPT_TIMEOUT, this);\n }),\n IQ_TIMEOUT);\n\n // XXX Videobridge needs WebRTC's answer (ICE ufrag and pwd, DTLS\n // fingerprint and setup) ASAP in order to start the connection\n // establishment.\n //\n // FIXME Flushing the connection at this point triggers an issue with\n // BOSH request handling in Prosody on slow connections.\n //\n // The problem is that this request will be quite large and it may take\n // time before it reaches Prosody. In the meantime Strophe may decide\n // to send the next one. And it was observed that a small request with\n // 'transport-info' usually follows this one. It does reach Prosody\n // before the previous one was completely received. 'rid' on the server\n // is increased and Prosody ignores the request with 'session-accept'.\n // It will never reach Jicofo and everything in the request table is\n // lost. Removing the flush does not guarantee it will never happen, but\n // makes it much less likely('transport-info' is bundled with\n // 'session-accept' and any immediate requests).\n //\n // this.connection.flush();\n }\n\n /**\n * Will send 'content-modify' IQ in order to ask the remote peer to\n * either stop or resume sending video media.\n * @param {boolean} videoTransferActive false to let the other peer\n * know that we're not sending nor interested in receiving video contents.\n * When set to true remote peer will be asked to resume video\n * transfer.\n * @private\n */\n sendContentModify(videoTransferActive) {\n const newSendersValue = videoTransferActive ? 'both' : 'none';\n\n const sessionModify\n = $iq({\n to: this.remoteJid,\n type: 'set'\n })\n .c('jingle', {\n xmlns: 'urn:xmpp:jingle:1',\n action: 'content-modify',\n initiator: this.initiatorJid,\n sid: this.sid\n })\n .c('content', {\n name: 'video',\n senders: newSendersValue\n });\n\n logger.info(\n `Sending content-modify, video senders: ${newSendersValue}`);\n\n this.connection.sendIQ(\n sessionModify,\n null,\n this.newJingleErrorHandler(sessionModify),\n IQ_TIMEOUT);\n }\n\n /**\n * Sends Jingle 'transport-accept' message which is a response to\n * 'transport-replace'.\n * @param localSDP the 'SDP' object with local session description\n * @param success callback called when we receive 'RESULT' packet for\n * 'transport-replace'\n * @param failure function(error) called when we receive an error response\n * or when the request has timed out.\n * @private\n */\n sendTransportAccept(localSDP, success, failure) {\n let transportAccept = $iq({ to: this.remoteJid,\n type: 'set' })\n .c('jingle', {\n xmlns: 'urn:xmpp:jingle:1',\n action: 'transport-accept',\n initiator: this.initiatorJid,\n sid: this.sid\n });\n\n localSDP.media.forEach((medialines, idx) => {\n const mline = SDPUtil.parseMLine(medialines.split('\\r\\n')[0]);\n\n transportAccept.c('content',\n {\n creator:\n this.initiatorJid === this.localJid\n ? 'initiator'\n : 'responder',\n name: mline.media\n }\n );\n localSDP.transportToJingle(idx, transportAccept);\n transportAccept.up();\n });\n\n // Calling tree() to print something useful to the logger\n transportAccept = transportAccept.tree();\n logger.info('Sending transport-accept: ', transportAccept);\n\n this.connection.sendIQ(transportAccept,\n success,\n this.newJingleErrorHandler(transportAccept, failure),\n IQ_TIMEOUT);\n }\n\n /**\n * Sends Jingle 'transport-reject' message which is a response to\n * 'transport-replace'.\n * @param success callback called when we receive 'RESULT' packet for\n * 'transport-replace'\n * @param failure function(error) called when we receive an error response\n * or when the request has timed out.\n *\n * FIXME method should be marked as private, but there's some spaghetti that\n * needs to be fixed prior doing that\n */\n sendTransportReject(success, failure) {\n // Send 'transport-reject', so that the focus will\n // know that we've failed\n let transportReject = $iq({ to: this.remoteJid,\n type: 'set' })\n .c('jingle', {\n xmlns: 'urn:xmpp:jingle:1',\n action: 'transport-reject',\n initiator: this.initiatorJid,\n sid: this.sid\n });\n\n transportReject = transportReject.tree();\n logger.info('Sending \\'transport-reject', transportReject);\n\n this.connection.sendIQ(transportReject,\n success,\n this.newJingleErrorHandler(transportReject, failure),\n IQ_TIMEOUT);\n }\n\n /**\n * @inheritDoc\n */\n terminate(success, failure, options) {\n if (this.state === JingleSessionState.ENDED) {\n return;\n }\n\n if (!options || Boolean(options.sendSessionTerminate)) {\n let sessionTerminate\n = $iq({\n to: this.remoteJid,\n type: 'set'\n })\n .c('jingle', {\n xmlns: 'urn:xmpp:jingle:1',\n action: 'session-terminate',\n initiator: this.initiatorJid,\n sid: this.sid\n })\n .c('reason')\n .c((options && options.reason) || 'success');\n\n if (options && options.reasonDescription) {\n sessionTerminate.up()\n .c('text')\n .t(options.reasonDescription);\n }\n\n // Calling tree() to print something useful\n sessionTerminate = sessionTerminate.tree();\n logger.info('Sending session-terminate', sessionTerminate);\n this.connection.sendIQ(\n sessionTerminate,\n success,\n this.newJingleErrorHandler(sessionTerminate, failure),\n IQ_TIMEOUT);\n } else {\n logger.info(`Skipped sending session-terminate for ${this}`);\n }\n\n // this should result in 'onTerminated' being called by strope.jingle.js\n this.connection.jingle.terminate(this.sid);\n }\n\n /**\n *\n * @param reasonCondition\n * @param reasonText\n */\n onTerminated(reasonCondition, reasonText) {\n // Do something with reason and reasonCondition when we start to care\n // this.reasonCondition = reasonCondition;\n // this.reasonText = reasonText;\n logger.info(`Session terminated ${this}`, reasonCondition, reasonText);\n\n this.close();\n }\n\n /**\n * Parse the information from the xml sourceAddElem and translate it\n * into sdp lines\n * @param {jquery xml element} sourceAddElem the source-add\n * element from jingle\n * @param {SDP object} currentRemoteSdp the current remote\n * sdp (as of this new source-add)\n * @returns {list} a list of SDP line strings that should\n * be added to the remote SDP\n */\n _parseSsrcInfoFromSourceAdd(sourceAddElem, currentRemoteSdp) {\n const addSsrcInfo = [];\n\n $(sourceAddElem).each((i1, content) => {\n const name = $(content).attr('name');\n let lines = '';\n\n $(content)\n .find('ssrc-group[xmlns=\"urn:xmpp:jingle:apps:rtp:ssma:0\"]')\n .each(function() {\n // eslint-disable-next-line no-invalid-this\n const semantics = this.getAttribute('semantics');\n const ssrcs\n = $(this) // eslint-disable-line no-invalid-this\n .find('>source')\n .map(function() {\n // eslint-disable-next-line no-invalid-this\n return this.getAttribute('ssrc');\n })\n .get();\n\n if (ssrcs.length) {\n lines\n += `a=ssrc-group:${semantics} ${\n ssrcs.join(' ')}\\r\\n`;\n }\n });\n\n // handles both >source and >description>source\n const tmp\n = $(content).find(\n 'source[xmlns=\"urn:xmpp:jingle:apps:rtp:ssma:0\"]');\n\n /* eslint-disable no-invalid-this */\n tmp.each(function() {\n const ssrc = $(this).attr('ssrc');\n\n if (currentRemoteSdp.containsSSRC(ssrc)) {\n logger.warn(\n `Source-add request for existing SSRC: ${ssrc}`);\n\n return;\n }\n\n // eslint-disable-next-line newline-per-chained-call\n $(this).find('>parameter').each(function() {\n lines += `a=ssrc:${ssrc} ${$(this).attr('name')}`;\n if ($(this).attr('value') && $(this).attr('value').length) {\n lines += `:${$(this).attr('value')}`;\n }\n lines += '\\r\\n';\n });\n });\n\n /* eslint-enable no-invalid-this */\n currentRemoteSdp.media.forEach((media, i2) => {\n if (!SDPUtil.findLine(media, `a=mid:${name}`)) {\n return;\n }\n if (!addSsrcInfo[i2]) {\n addSsrcInfo[i2] = '';\n }\n addSsrcInfo[i2] += lines;\n });\n });\n\n return addSsrcInfo;\n }\n\n /**\n * Handles a Jingle source-add message for this Jingle session.\n * @param elem An array of Jingle \"content\" elements.\n */\n addRemoteStream(elem) {\n this._addOrRemoveRemoteStream(true /* add */, elem);\n }\n\n /**\n * Handles a Jingle source-remove message for this Jingle session.\n * @param elem An array of Jingle \"content\" elements.\n */\n removeRemoteStream(elem) {\n this._addOrRemoveRemoteStream(false /* remove */, elem);\n }\n\n /**\n * Handles either Jingle 'source-add' or 'source-remove' message for this\n * Jingle session.\n * @param {boolean} isAdd true for 'source-add' or false\n * otherwise.\n * @param {Array} elem an array of Jingle \"content\" elements.\n * @private\n */\n _addOrRemoveRemoteStream(isAdd, elem) {\n const logPrefix = isAdd ? 'addRemoteStream' : 'removeRemoteStream';\n\n if (isAdd) {\n this.readSsrcInfo(elem);\n }\n\n const workFunction = finishedCallback => {\n if (!this.peerconnection.localDescription\n || !this.peerconnection.localDescription.sdp) {\n const errMsg = `${logPrefix} - localDescription not ready yet`;\n\n logger.error(errMsg);\n finishedCallback(errMsg);\n\n return;\n }\n\n logger.log(`Processing ${logPrefix}`);\n logger.log(\n 'ICE connection state: ',\n this.peerconnection.iceConnectionState);\n\n const oldLocalSdp\n = new SDP(this.peerconnection.localDescription.sdp);\n const sdp = new SDP(this.peerconnection.remoteDescription.sdp);\n const addOrRemoveSsrcInfo\n = isAdd\n ? this._parseSsrcInfoFromSourceAdd(elem, sdp)\n : this._parseSsrcInfoFromSourceRemove(elem, sdp);\n const newRemoteSdp\n = isAdd\n ? this._processRemoteAddSource(addOrRemoveSsrcInfo)\n : this._processRemoteRemoveSource(addOrRemoveSsrcInfo);\n\n this._renegotiate(newRemoteSdp.raw)\n .then(() => {\n const newLocalSdp\n = new SDP(this.peerconnection.localDescription.sdp);\n\n logger.log(\n `${logPrefix} - OK, SDPs: `, oldLocalSdp, newLocalSdp);\n this.notifyMySSRCUpdate(oldLocalSdp, newLocalSdp);\n finishedCallback();\n }, error => {\n logger.error(`${logPrefix} failed:`, error);\n finishedCallback(error);\n });\n };\n\n // Queue and execute\n this.modificationQueue.push(workFunction);\n }\n\n /**\n * Takes in a jingle offer iq, returns the new sdp offer\n * @param {jquery xml element} offerIq the incoming offer\n * @returns {SDP object} the jingle offer translated to SDP\n */\n _processNewJingleOfferIq(offerIq) {\n const remoteSdp = new SDP('');\n\n if (this.webrtcIceTcpDisable) {\n remoteSdp.removeTcpCandidates = true;\n }\n if (this.webrtcIceUdpDisable) {\n remoteSdp.removeUdpCandidates = true;\n }\n if (this.failICE) {\n remoteSdp.failICE = true;\n }\n\n remoteSdp.fromJingle(offerIq);\n this.readSsrcInfo($(offerIq).find('>content'));\n\n return remoteSdp;\n }\n\n /**\n * Remove the given ssrc lines from the current remote sdp\n * @param {list} removeSsrcInfo a list of SDP line strings that\n * should be removed from the remote SDP\n * @returns type {SDP Object} the new remote SDP (after removing the lines\n * in removeSsrcInfo\n */\n _processRemoteRemoveSource(removeSsrcInfo) {\n const remoteSdp = new SDP(this.peerconnection.remoteDescription.sdp);\n\n removeSsrcInfo.forEach((lines, idx) => {\n // eslint-disable-next-line no-param-reassign\n lines = lines.split('\\r\\n');\n lines.pop(); // remove empty last element;\n lines.forEach(line => {\n remoteSdp.media[idx]\n = remoteSdp.media[idx].replace(`${line}\\r\\n`, '');\n });\n });\n remoteSdp.raw = remoteSdp.session + remoteSdp.media.join('');\n\n return remoteSdp;\n }\n\n /**\n * Add the given ssrc lines to the current remote sdp\n * @param {list} addSsrcInfo a list of SDP line strings that\n * should be added to the remote SDP\n * @returns type {SDP Object} the new remote SDP (after removing the lines\n * in removeSsrcInfo\n */\n _processRemoteAddSource(addSsrcInfo) {\n const remoteSdp = new SDP(this.peerconnection.remoteDescription.sdp);\n\n addSsrcInfo.forEach((lines, idx) => {\n remoteSdp.media[idx] += lines;\n });\n remoteSdp.raw = remoteSdp.session + remoteSdp.media.join('');\n\n return remoteSdp;\n }\n\n /**\n * Do a new o/a flow using the existing remote description\n * @param {string} [optionalRemoteSdp] optional, raw remote sdp\n * to use. If not provided, the remote sdp from the\n * peerconnection will be used\n * @returns {Promise} promise which resolves when the\n * o/a flow is complete with no arguments or\n * rejects with an error {string}\n */\n _renegotiate(optionalRemoteSdp) {\n if (this.peerconnection.signalingState === 'closed') {\n const error = new Error('Attempted to renegotiate in state closed');\n\n this.room.eventEmitter.emit(XMPPEvents.RENEGOTIATION_FAILED, error, this);\n\n return Promise.reject(error);\n }\n\n const remoteSdp\n = optionalRemoteSdp || this.peerconnection.remoteDescription.sdp;\n\n if (!remoteSdp) {\n const error = new Error(`Can not renegotiate without remote description, current state: ${this.state}`);\n\n this.room.eventEmitter.emit(XMPPEvents.RENEGOTIATION_FAILED, error, this);\n\n return Promise.reject(error);\n }\n\n const remoteDescription = new RTCSessionDescription({\n type: this.isInitiator ? 'answer' : 'offer',\n sdp: remoteSdp\n });\n\n if (this.isInitiator) {\n return this._initiatorRenegotiate(remoteDescription);\n }\n\n return this._responderRenegotiate(remoteDescription);\n }\n\n /**\n * Renegotiate cycle implementation for the responder case.\n * @param {object} remoteDescription the SDP object as defined by the WebRTC\n * which will be used as remote description in the cycle.\n * @private\n */\n _responderRenegotiate(remoteDescription) {\n logger.debug('Renegotiate: setting remote description');\n\n return this.peerconnection.setRemoteDescription(remoteDescription)\n .then(() => {\n logger.debug('Renegotiate: creating answer');\n\n return this.peerconnection.createAnswer(this.mediaConstraints)\n .then(answer => {\n logger.debug('Renegotiate: setting local description');\n\n return this.peerconnection.setLocalDescription(answer);\n });\n });\n }\n\n /**\n * Renegotiate cycle implementation for the initiator's case.\n * @param {object} remoteDescription the SDP object as defined by the WebRTC\n * which will be used as remote description in the cycle.\n * @private\n */\n _initiatorRenegotiate(remoteDescription) {\n if (this.peerconnection.signalingState === 'have-local-offer') {\n // Skip createOffer and setLocalDescription or FF will fail\n logger.debug(\n 'Renegotiate: setting remote description');\n\n /* eslint-disable arrow-body-style */\n\n return this.peerconnection.setRemoteDescription(remoteDescription)\n .then(() => {\n // In case when the answer is being set for the first time,\n // full sRD/sLD cycle is required to have the local\n // description updated and SSRCs synchronized correctly.\n // Otherwise SSRCs for streams added after invite, but\n // before the answer was accepted will not be detected.\n // The reason for that is that renegotiate can not be called\n // when adding tracks and they will not be reflected in\n // the local SDP.\n return this._initiatorRenegotiate(remoteDescription);\n });\n /* eslint-enable arrow-body-style */\n }\n\n logger.debug('Renegotiate: creating offer');\n\n return this.peerconnection.createOffer(this.mediaConstraints)\n .then(offer => {\n logger.debug('Renegotiate: setting local description');\n\n return this.peerconnection.setLocalDescription(offer)\n .then(() => {\n logger.debug(\n 'Renegotiate: setting remote description');\n\n // eslint-disable-next-line max-len\n return this.peerconnection.setRemoteDescription(remoteDescription);\n });\n });\n }\n\n /**\n * Replaces oldTrack with newTrack and performs a single\n * offer/answer cycle after both operations are done. Either\n * oldTrack or newTrack can be null; replacing a valid\n * oldTrack with a null newTrack effectively just removes\n * oldTrack\n * @param {JitsiLocalTrack|null} oldTrack the current track in use to be\n * replaced\n * @param {JitsiLocalTrack|null} newTrack the new track to use\n * @returns {Promise} which resolves once the replacement is complete\n * with no arguments or rejects with an error {string}\n */\n replaceTrack(oldTrack, newTrack) {\n const workFunction = finishedCallback => {\n const oldLocalSdp = this.peerconnection.localDescription.sdp;\n\n // NOTE the code below assumes that no more than 1 video track\n // can be added to the peer connection.\n // Transition from camera to desktop share\n // or transition from one camera source to another.\n if (this.peerconnection.options.capScreenshareBitrate\n && oldTrack && newTrack && newTrack.isVideoTrack()) {\n // Clearing current primary SSRC will make\n // the SdpConsistency generate a new one which will result\n // with:\n // 1. source-remove for the old video stream.\n // 2. source-add for the new video stream.\n this.peerconnection.clearRecvonlySsrc();\n }\n\n // Transition from no video to video (unmute).\n if (!oldTrack && newTrack && newTrack.isVideoTrack()) {\n // Clearing current primary SSRC will make\n // the SdpConsistency generate a new one which will result\n // with:\n // 1. source-remove for the recvonly\n // 2. source-add for the new video stream\n this.peerconnection.clearRecvonlySsrc();\n\n // Transition from video to no video\n } else if (oldTrack && oldTrack.isVideoTrack() && !newTrack) {\n // Clearing current primary SSRC and generating the recvonly\n // will result in:\n // 1. source-remove for the old video stream\n // 2. source-add for the recvonly stream\n this.peerconnection.clearRecvonlySsrc();\n this.peerconnection.generateRecvonlySsrc();\n }\n\n this.peerconnection.replaceTrack(oldTrack, newTrack)\n .then(shouldRenegotiate => {\n if (shouldRenegotiate\n && (oldTrack || newTrack)\n && this.state === JingleSessionState.ACTIVE) {\n this._renegotiate()\n .then(() => {\n const newLocalSDP\n = new SDP(\n this.peerconnection.localDescription.sdp);\n\n this.notifyMySSRCUpdate(\n new SDP(oldLocalSdp), newLocalSDP);\n\n // configure max bitrate only when media is routed\n // through JVB. For p2p case, browser takes care of\n // adjusting the uplink based on the feedback it\n // gets from the peer.\n if (newTrack && !this.isP2P) {\n this.peerconnection.setMaxBitRate(newTrack);\n }\n finishedCallback();\n },\n finishedCallback /* will be called with en error */);\n } else {\n finishedCallback();\n }\n });\n };\n\n return new Promise((resolve, reject) => {\n this.modificationQueue.push(\n workFunction,\n error => {\n if (error) {\n logger.error('Replace track error:', error);\n reject(error);\n } else {\n logger.info('Replace track done!');\n resolve();\n }\n });\n });\n }\n\n /**\n * Parse the information from the xml sourceRemoveElem and translate it\n * into sdp lines\n * @param {jquery xml element} sourceRemoveElem the source-remove\n * element from jingle\n * @param {SDP object} currentRemoteSdp the current remote\n * sdp (as of this new source-remove)\n * @returns {list} a list of SDP line strings that should\n * be removed from the remote SDP\n */\n _parseSsrcInfoFromSourceRemove(sourceRemoveElem, currentRemoteSdp) {\n const removeSsrcInfo = [];\n\n $(sourceRemoveElem).each((i1, content) => {\n const name = $(content).attr('name');\n let lines = '';\n\n $(content)\n .find('ssrc-group[xmlns=\"urn:xmpp:jingle:apps:rtp:ssma:0\"]')\n .each(function() {\n /* eslint-disable no-invalid-this */\n const semantics = this.getAttribute('semantics');\n const ssrcs\n = $(this)\n .find('>source')\n .map(function() {\n return this.getAttribute('ssrc');\n })\n .get();\n\n if (ssrcs.length) {\n lines\n += `a=ssrc-group:${semantics} ${\n ssrcs.join(' ')}\\r\\n`;\n }\n\n /* eslint-enable no-invalid-this */\n });\n const ssrcs = [];\n\n // handles both >source and >description>source versions\n const tmp\n = $(content).find(\n 'source[xmlns=\"urn:xmpp:jingle:apps:rtp:ssma:0\"]');\n\n tmp.each(function() {\n // eslint-disable-next-line no-invalid-this\n const ssrc = $(this).attr('ssrc');\n\n ssrcs.push(ssrc);\n });\n currentRemoteSdp.media.forEach((media, i2) => {\n if (!SDPUtil.findLine(media, `a=mid:${name}`)) {\n return;\n }\n if (!removeSsrcInfo[i2]) {\n removeSsrcInfo[i2] = '';\n }\n ssrcs.forEach(ssrc => {\n const ssrcLines\n = SDPUtil.findLines(media, `a=ssrc:${ssrc}`);\n\n if (ssrcLines.length) {\n removeSsrcInfo[i2] += `${ssrcLines.join('\\r\\n')}\\r\\n`;\n }\n });\n removeSsrcInfo[i2] += lines;\n });\n });\n\n return removeSsrcInfo;\n }\n\n /**\n * Will print an error if there is any difference, between the SSRCs given\n * in the oldSDP and the ones currently described in\n * the peerconnection's local description.\n * @param {string} operationName the operation's name which will be printed\n * in the error message.\n * @param {SDP} oldSDP the old local SDP which will be compared with\n * the current one.\n * @return {boolean} true if there was any change or false\n * otherwise.\n * @private\n */\n _verifyNoSSRCChanged(operationName, oldSDP) {\n const currentLocalSDP\n = new SDP(this.peerconnection.localDescription.sdp);\n let sdpDiff = new SDPDiffer(oldSDP, currentLocalSDP);\n const addedMedia = sdpDiff.getNewMedia();\n\n if (Object.keys(addedMedia).length) {\n logger.error(\n `${this} - some SSRC were added on ${operationName}`,\n addedMedia);\n\n return false;\n }\n\n sdpDiff = new SDPDiffer(currentLocalSDP, oldSDP);\n const removedMedia = sdpDiff.getNewMedia();\n\n if (Object.keys(removedMedia).length) {\n logger.error(\n `${this} - some SSRCs were removed on ${operationName}`,\n removedMedia);\n\n return false;\n }\n\n return true;\n }\n\n /**\n * Adds local track back to this session, as part of the unmute operation.\n * @param {JitsiLocalTrack} track\n * @return {Promise} a promise that will resolve once the local track is\n * added back to this session and renegotiation succeeds. Will be rejected\n * with a string that provides some error details in case something\n * goes wrong.\n */\n addTrackAsUnmute(track) {\n return this._addRemoveTrackAsMuteUnmute(\n false /* add as unmute */, track);\n }\n\n /**\n * Remove local track as part of the mute operation.\n * @param {JitsiLocalTrack} track the local track to be removed\n * @return {Promise} a promise which will be resolved once the local track\n * is removed from this session and the renegotiation is performed.\n * The promise will be rejected with a string that the describes\n * the error if anything goes wrong.\n */\n removeTrackAsMute(track) {\n return this._addRemoveTrackAsMuteUnmute(\n true /* remove as mute */, track);\n }\n\n /**\n * See {@link addTrackAsUnmute} and {@link removeTrackAsMute}.\n * @param {boolean} isMute true for \"remove as mute\" or\n * false for \"add as unmute\".\n * @param {JitsiLocalTrack} track the track that will be added/removed\n * @private\n */\n _addRemoveTrackAsMuteUnmute(isMute, track) {\n if (!track) {\n return Promise.reject('invalid \"track\" argument value');\n }\n const operationName = isMute ? 'removeTrackMute' : 'addTrackUnmute';\n const workFunction = finishedCallback => {\n const tpc = this.peerconnection;\n\n if (!tpc) {\n finishedCallback(\n `Error: tried ${operationName} track with no active peer`\n + 'connection');\n\n return;\n }\n const oldLocalSDP = tpc.localDescription.sdp;\n const tpcOperation\n = isMute\n ? tpc.removeTrackMute.bind(tpc, track)\n : tpc.addTrackUnmute.bind(tpc, track);\n\n if (!tpcOperation()) {\n finishedCallback(`${operationName} failed!`);\n } else if (!oldLocalSDP || !tpc.remoteDescription.sdp) {\n finishedCallback();\n } else {\n this._renegotiate()\n .then(() => {\n // The results are ignored, as this check failure is not\n // enough to fail the whole operation. It will log\n // an error inside.\n this._verifyNoSSRCChanged(\n operationName, new SDP(oldLocalSDP));\n finishedCallback();\n },\n finishedCallback /* will be called with an error */);\n }\n };\n\n return new Promise((resolve, reject) => {\n this.modificationQueue.push(\n workFunction,\n error => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n }\n\n /**\n * Resumes or suspends media transfer over the underlying peer connection.\n * @param {boolean} audioActive true to enable audio media\n * transfer or false to suspend audio media transmission.\n * @param {boolean} videoActive true to enable video media\n * transfer or false to suspend video media transmission.\n * @return {Promise} a Promise which will resolve once\n * the operation is done. It will be rejected with an error description as\n * a string in case anything goes wrong.\n */\n setMediaTransferActive(audioActive, videoActive) {\n if (!this.peerconnection) {\n return Promise.reject(\n 'Can not modify transfer active state,'\n + ' before \"initialize\" is called');\n }\n\n const logAudioStr = audioActive ? 'audio active' : 'audio inactive';\n const logVideoStr = videoActive ? 'video active' : 'video inactive';\n\n logger.info(`Queued make ${logVideoStr}, ${logAudioStr} task...`);\n\n const workFunction = finishedCallback => {\n const isSessionActive = this.state === JingleSessionState.ACTIVE;\n\n // Because the value is modified on the queue it's impossible to\n // check it's final value reliably prior to submitting the task.\n // The rule here is that the last submitted state counts.\n // Check the values here to avoid unnecessary renegotiation cycle.\n const audioActiveChanged\n = this.peerconnection.setAudioTransferActive(audioActive);\n\n if (this._localVideoActive !== videoActive) {\n this._localVideoActive = videoActive;\n\n // Do only for P2P - Jicofo will reply with 'bad-request'\n // We don't want to send 'content-modify', before the initial\n // O/A (state === JingleSessionState.ACTIVE), because that will\n // mess up video media direction in the remote SDP.\n // 'content-modify' when processed only affects the media\n // direction in the local SDP. We're doing that, because setting\n // 'inactive' on video media in remote SDP will mess up our SDP\n // translation chain (simulcast, RTX, video mute etc.).\n if (this.isP2P && isSessionActive) {\n this.sendContentModify(videoActive);\n }\n }\n\n const pcVideoActiveChanged\n = this.peerconnection.setVideoTransferActive(\n this._localVideoActive && this._remoteVideoActive);\n\n // Will do the sRD/sLD cycle to update SDPs and adjust the media\n // direction\n if (isSessionActive\n && (audioActiveChanged || pcVideoActiveChanged)) {\n this._renegotiate()\n .then(\n finishedCallback,\n finishedCallback /* will be called with an error */);\n } else {\n finishedCallback();\n }\n };\n\n return new Promise((resolve, reject) => {\n this.modificationQueue.push(\n workFunction,\n error => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n }\n\n /**\n * Will put and execute on the queue a session modify task. Currently it\n * only checks the senders attribute of the video content in order to figure\n * out if the remote peer has video in the inactive state (stored locally\n * in {@link _remoteVideoActive} - see field description for more info).\n * @param {jQuery} jingleContents jQuery selector pointing to the jingle\n * element of the session modify IQ.\n * @see {@link _remoteVideoActive}\n * @see {@link _localVideoActive}\n */\n modifyContents(jingleContents) {\n const newVideoSenders\n = JingleSessionPC.parseVideoSenders(jingleContents);\n\n if (newVideoSenders === null) {\n logger.error(\n `${this} - failed to parse video \"senders\" attribute in`\n + '\"content-modify\" action');\n\n return;\n }\n\n const workFunction = finishedCallback => {\n if (this._assertNotEnded('content-modify')\n && this._modifyRemoteVideoActive(newVideoSenders)) {\n // Will do the sRD/sLD cycle to update SDPs and adjust\n // the media direction\n this._renegotiate()\n .then(finishedCallback, finishedCallback /* (error) */);\n } else {\n finishedCallback();\n }\n };\n\n logger.debug(\n `${this} queued \"content-modify\" task`\n + `(video senders=\"${newVideoSenders}\")`);\n\n this.modificationQueue.push(\n workFunction,\n error => {\n if (error) {\n logger.error('\"content-modify\" failed', error);\n }\n });\n }\n\n /**\n * Processes new value of remote video \"senders\" Jingle attribute and tries\n * to apply it for {@link _remoteVideoActive}.\n * @param {string} remoteVideoSenders the value of \"senders\" attribute of\n * Jingle video content element advertised by remote peer.\n * @return {boolean} true if the change affected state of\n * the underlying peerconnection and renegotiation is required for\n * the changes to take effect.\n * @private\n */\n _modifyRemoteVideoActive(remoteVideoSenders) {\n const isRemoteVideoActive\n = remoteVideoSenders === 'both'\n || (remoteVideoSenders === 'initiator' && this.isInitiator)\n || (remoteVideoSenders === 'responder' && !this.isInitiator);\n\n if (isRemoteVideoActive !== this._remoteVideoActive) {\n logger.debug(\n `${this} new remote video active: ${isRemoteVideoActive}`);\n this._remoteVideoActive = isRemoteVideoActive;\n }\n\n return this.peerconnection.setVideoTransferActive(\n this._localVideoActive && this._remoteVideoActive);\n }\n\n /**\n * Figures out added/removed ssrcs and send update IQs.\n * @param oldSDP SDP object for old description.\n * @param newSDP SDP object for new description.\n */\n notifyMySSRCUpdate(oldSDP, newSDP) {\n\n if (this.state !== JingleSessionState.ACTIVE) {\n logger.warn(`Skipping SSRC update in '${this.state} ' state.`);\n\n return;\n }\n\n // send source-remove IQ.\n let sdpDiffer = new SDPDiffer(newSDP, oldSDP);\n const remove = $iq({ to: this.remoteJid,\n type: 'set' })\n .c('jingle', {\n xmlns: 'urn:xmpp:jingle:1',\n action: 'source-remove',\n initiator: this.initiatorJid,\n sid: this.sid\n }\n );\n const removedAnySSRCs = sdpDiffer.toJingle(remove);\n\n if (removedAnySSRCs) {\n logger.info('Sending source-remove', remove.tree());\n this.connection.sendIQ(\n remove, null,\n this.newJingleErrorHandler(remove), IQ_TIMEOUT);\n } else {\n logger.log('removal not necessary');\n }\n\n // send source-add IQ.\n sdpDiffer = new SDPDiffer(oldSDP, newSDP);\n const add = $iq({ to: this.remoteJid,\n type: 'set' })\n .c('jingle', {\n xmlns: 'urn:xmpp:jingle:1',\n action: 'source-add',\n initiator: this.initiatorJid,\n sid: this.sid\n }\n );\n\n const containsNewSSRCs = sdpDiffer.toJingle(add);\n\n if (containsNewSSRCs) {\n logger.info('Sending source-add', add.tree());\n this.connection.sendIQ(\n add, null, this.newJingleErrorHandler(add), IQ_TIMEOUT);\n } else {\n logger.log('addition not necessary');\n }\n }\n\n /**\n * Method returns function(errorResponse) which is a callback to be passed\n * to Strophe connection.sendIQ method. An 'error' structure is created that\n * is passed as 1st argument to given failureCb. The format of this\n * structure is as follows:\n * {\n * code: {XMPP error response code}\n * reason: {the name of XMPP error reason element or 'timeout' if the\n * request has timed out within IQ_TIMEOUT milliseconds}\n * source: {request.tree() that provides original request}\n * session: {this JingleSessionPC.toString()}\n * }\n * @param request Strophe IQ instance which is the request to be dumped into\n * the error structure\n * @param failureCb function(error) called when error response was returned\n * or when a timeout has occurred.\n * @returns {function(this:JingleSessionPC)}\n */\n newJingleErrorHandler(request, failureCb) {\n return errResponse => {\n\n const error = {};\n\n // Get XMPP error code and condition(reason)\n const errorElSel = $(errResponse).find('error');\n\n if (errorElSel.length) {\n error.code = errorElSel.attr('code');\n const errorReasonSel = $(errResponse).find('error :first');\n\n if (errorReasonSel.length) {\n error.reason = errorReasonSel[0].tagName;\n }\n\n const errorMsgSel = errorElSel.find('>text');\n\n if (errorMsgSel.length) {\n error.msg = errorMsgSel.text();\n }\n }\n\n if (!errResponse) {\n error.reason = 'timeout';\n }\n\n error.session = this.toString();\n\n if (failureCb) {\n failureCb(error);\n } else if (this.state === JingleSessionState.ENDED\n && error.reason === 'item-not-found') {\n // When remote peer decides to terminate the session, but it\n // still have few messages on the queue for processing,\n // it will first send us 'session-terminate' (we enter ENDED)\n // and then follow with 'item-not-found' for the queued requests\n // We don't want to have that logged on error level.\n logger.debug(`Jingle error: ${JSON.stringify(error)}`);\n } else {\n GlobalOnErrorHandler.callErrorHandler(\n new Error(\n `Jingle error: ${JSON.stringify(error)}`));\n }\n };\n }\n\n /**\n * Returns the ice connection state for the peer connection.\n * @returns the ice connection state for the peer connection.\n */\n getIceConnectionState() {\n return this.peerconnection.iceConnectionState;\n }\n\n /**\n * Closes the peerconnection.\n */\n close() {\n this.state = JingleSessionState.ENDED;\n this.establishmentDuration = undefined;\n\n if (this.peerconnection) {\n this.peerconnection.onicecandidate = null;\n this.peerconnection.oniceconnectionstatechange = null;\n this.peerconnection.onnegotiationneeded = null;\n this.peerconnection.onsignalingstatechange = null;\n }\n\n // Remove any pending tasks from the queue\n this.modificationQueue.clear();\n\n this.modificationQueue.push(finishCallback => {\n // The signaling layer will remove it's listeners\n this.signalingLayer.setChatRoom(null);\n\n // do not try to close if already closed.\n this.peerconnection && this.peerconnection.close();\n finishCallback();\n });\n\n // No more tasks can go in after the close task\n this.modificationQueue.shutdown();\n }\n\n /**\n * Converts to string with minor summary.\n * @return {string}\n */\n toString() {\n return `JingleSessionPC[p2p=${this.isP2P},`\n + `initiator=${this.isInitiator},sid=${this.sid}]`;\n }\n\n /**\n * If the A/B test for suspend video is disabled according to the room's\n * configuration, returns undefined. Otherwise returns a boolean which\n * indicates whether the suspend video option should be enabled or disabled.\n * @param {JingleSessionPCOptions} options - The config options.\n */\n _abtestSuspendVideoEnabled({ abTesting }) {\n if (!abTesting || !abTesting.enableSuspendVideoTest) {\n return;\n }\n\n // We want the two participants in a P2P call to agree on the value of\n // the \"suspend\" option. We use the JID of the initiator, because it is\n // both randomly selected and agreed upon by both participants.\n const jid = this._getInitiatorJid();\n\n return integerHash(jid) % 2 === 0;\n }\n}\n","/**\n * The events for the media devices.\n */\n\n/**\n * Indicates that the list of available media devices has been changed. The\n * event provides the following parameters to its listeners:\n *\n * @param {MediaDeviceInfo[]} devices - array of MediaDeviceInfo or\n * MediaDeviceInfo-like objects that are currently connected.\n * @see https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo\n */\nexport const DEVICE_LIST_CHANGED = 'mediaDevices.devicechange';\n\n/**\n * Indicates that the environment is currently showing permission prompt to\n * access camera and/or microphone. The event provides the following\n * parameters to its listeners:\n *\n * @param {'chrome'|'opera'|'firefox'|'safari'|'nwjs'\n * |'react-native'|'android'} environmentType - type of browser or\n * other execution environment.\n */\nexport const PERMISSION_PROMPT_IS_SHOWN\n = 'mediaDevices.permissionPromptIsShown';\n","/*!\n * Bowser - a browser detector\n * https://github.com/ded/bowser\n * MIT License | (c) Dustin Diaz 2015\n */\n\n!function (root, name, definition) {\n if (typeof module != 'undefined' && module.exports) module.exports = definition()\n else if (typeof define == 'function' && define.amd) define(name, definition)\n else root[name] = definition()\n}(this, 'bowser', function () {\n /**\n * See useragents.js for examples of navigator.userAgent\n */\n\n var t = true\n\n function detect(ua) {\n\n function getFirstMatch(regex) {\n var match = ua.match(regex);\n return (match && match.length > 1 && match[1]) || '';\n }\n\n function getSecondMatch(regex) {\n var match = ua.match(regex);\n return (match && match.length > 1 && match[2]) || '';\n }\n\n var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase()\n , likeAndroid = /like android/i.test(ua)\n , android = !likeAndroid && /android/i.test(ua)\n , nexusMobile = /nexus\\s*[0-6]\\s*/i.test(ua)\n , nexusTablet = !nexusMobile && /nexus\\s*[0-9]+/i.test(ua)\n , chromeos = /CrOS/.test(ua)\n , silk = /silk/i.test(ua)\n , sailfish = /sailfish/i.test(ua)\n , tizen = /tizen/i.test(ua)\n , webos = /(web|hpw)os/i.test(ua)\n , windowsphone = /windows phone/i.test(ua)\n , samsungBrowser = /SamsungBrowser/i.test(ua)\n , windows = !windowsphone && /windows/i.test(ua)\n , mac = !iosdevice && !silk && /macintosh/i.test(ua)\n , linux = !android && !sailfish && !tizen && !webos && /linux/i.test(ua)\n , edgeVersion = getSecondMatch(/edg([ea]|ios)\\/(\\d+(\\.\\d+)?)/i)\n , versionIdentifier = getFirstMatch(/version\\/(\\d+(\\.\\d+)?)/i)\n , tablet = /tablet/i.test(ua) && !/tablet pc/i.test(ua)\n , mobile = !tablet && /[^-]mobi/i.test(ua)\n , xbox = /xbox/i.test(ua)\n , result\n\n if (/opera/i.test(ua)) {\n // an old Opera\n result = {\n name: 'Opera'\n , opera: t\n , version: versionIdentifier || getFirstMatch(/(?:opera|opr|opios)[\\s\\/](\\d+(\\.\\d+)?)/i)\n }\n } else if (/opr\\/|opios/i.test(ua)) {\n // a new Opera\n result = {\n name: 'Opera'\n , opera: t\n , version: getFirstMatch(/(?:opr|opios)[\\s\\/](\\d+(\\.\\d+)?)/i) || versionIdentifier\n }\n }\n else if (/SamsungBrowser/i.test(ua)) {\n result = {\n name: 'Samsung Internet for Android'\n , samsungBrowser: t\n , version: versionIdentifier || getFirstMatch(/(?:SamsungBrowser)[\\s\\/](\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/coast/i.test(ua)) {\n result = {\n name: 'Opera Coast'\n , coast: t\n , version: versionIdentifier || getFirstMatch(/(?:coast)[\\s\\/](\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/yabrowser/i.test(ua)) {\n result = {\n name: 'Yandex Browser'\n , yandexbrowser: t\n , version: versionIdentifier || getFirstMatch(/(?:yabrowser)[\\s\\/](\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/ucbrowser/i.test(ua)) {\n result = {\n name: 'UC Browser'\n , ucbrowser: t\n , version: getFirstMatch(/(?:ucbrowser)[\\s\\/](\\d+(?:\\.\\d+)+)/i)\n }\n }\n else if (/mxios/i.test(ua)) {\n result = {\n name: 'Maxthon'\n , maxthon: t\n , version: getFirstMatch(/(?:mxios)[\\s\\/](\\d+(?:\\.\\d+)+)/i)\n }\n }\n else if (/epiphany/i.test(ua)) {\n result = {\n name: 'Epiphany'\n , epiphany: t\n , version: getFirstMatch(/(?:epiphany)[\\s\\/](\\d+(?:\\.\\d+)+)/i)\n }\n }\n else if (/puffin/i.test(ua)) {\n result = {\n name: 'Puffin'\n , puffin: t\n , version: getFirstMatch(/(?:puffin)[\\s\\/](\\d+(?:\\.\\d+)?)/i)\n }\n }\n else if (/sleipnir/i.test(ua)) {\n result = {\n name: 'Sleipnir'\n , sleipnir: t\n , version: getFirstMatch(/(?:sleipnir)[\\s\\/](\\d+(?:\\.\\d+)+)/i)\n }\n }\n else if (/k-meleon/i.test(ua)) {\n result = {\n name: 'K-Meleon'\n , kMeleon: t\n , version: getFirstMatch(/(?:k-meleon)[\\s\\/](\\d+(?:\\.\\d+)+)/i)\n }\n }\n else if (windowsphone) {\n result = {\n name: 'Windows Phone'\n , osname: 'Windows Phone'\n , windowsphone: t\n }\n if (edgeVersion) {\n result.msedge = t\n result.version = edgeVersion\n }\n else {\n result.msie = t\n result.version = getFirstMatch(/iemobile\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/msie|trident/i.test(ua)) {\n result = {\n name: 'Internet Explorer'\n , msie: t\n , version: getFirstMatch(/(?:msie |rv:)(\\d+(\\.\\d+)?)/i)\n }\n } else if (chromeos) {\n result = {\n name: 'Chrome'\n , osname: 'Chrome OS'\n , chromeos: t\n , chromeBook: t\n , chrome: t\n , version: getFirstMatch(/(?:chrome|crios|crmo)\\/(\\d+(\\.\\d+)?)/i)\n }\n } else if (/edg([ea]|ios)/i.test(ua)) {\n result = {\n name: 'Microsoft Edge'\n , msedge: t\n , version: edgeVersion\n }\n }\n else if (/vivaldi/i.test(ua)) {\n result = {\n name: 'Vivaldi'\n , vivaldi: t\n , version: getFirstMatch(/vivaldi\\/(\\d+(\\.\\d+)?)/i) || versionIdentifier\n }\n }\n else if (sailfish) {\n result = {\n name: 'Sailfish'\n , osname: 'Sailfish OS'\n , sailfish: t\n , version: getFirstMatch(/sailfish\\s?browser\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/seamonkey\\//i.test(ua)) {\n result = {\n name: 'SeaMonkey'\n , seamonkey: t\n , version: getFirstMatch(/seamonkey\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/firefox|iceweasel|fxios/i.test(ua)) {\n result = {\n name: 'Firefox'\n , firefox: t\n , version: getFirstMatch(/(?:firefox|iceweasel|fxios)[ \\/](\\d+(\\.\\d+)?)/i)\n }\n if (/\\((mobile|tablet);[^\\)]*rv:[\\d\\.]+\\)/i.test(ua)) {\n result.firefoxos = t\n result.osname = 'Firefox OS'\n }\n }\n else if (silk) {\n result = {\n name: 'Amazon Silk'\n , silk: t\n , version : getFirstMatch(/silk\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/phantom/i.test(ua)) {\n result = {\n name: 'PhantomJS'\n , phantom: t\n , version: getFirstMatch(/phantomjs\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/slimerjs/i.test(ua)) {\n result = {\n name: 'SlimerJS'\n , slimer: t\n , version: getFirstMatch(/slimerjs\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/blackberry|\\bbb\\d+/i.test(ua) || /rim\\stablet/i.test(ua)) {\n result = {\n name: 'BlackBerry'\n , osname: 'BlackBerry OS'\n , blackberry: t\n , version: versionIdentifier || getFirstMatch(/blackberry[\\d]+\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (webos) {\n result = {\n name: 'WebOS'\n , osname: 'WebOS'\n , webos: t\n , version: versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\\/(\\d+(\\.\\d+)?)/i)\n };\n /touchpad\\//i.test(ua) && (result.touchpad = t)\n }\n else if (/bada/i.test(ua)) {\n result = {\n name: 'Bada'\n , osname: 'Bada'\n , bada: t\n , version: getFirstMatch(/dolfin\\/(\\d+(\\.\\d+)?)/i)\n };\n }\n else if (tizen) {\n result = {\n name: 'Tizen'\n , osname: 'Tizen'\n , tizen: t\n , version: getFirstMatch(/(?:tizen\\s?)?browser\\/(\\d+(\\.\\d+)?)/i) || versionIdentifier\n };\n }\n else if (/qupzilla/i.test(ua)) {\n result = {\n name: 'QupZilla'\n , qupzilla: t\n , version: getFirstMatch(/(?:qupzilla)[\\s\\/](\\d+(?:\\.\\d+)+)/i) || versionIdentifier\n }\n }\n else if (/chromium/i.test(ua)) {\n result = {\n name: 'Chromium'\n , chromium: t\n , version: getFirstMatch(/(?:chromium)[\\s\\/](\\d+(?:\\.\\d+)?)/i) || versionIdentifier\n }\n }\n else if (/chrome|crios|crmo/i.test(ua)) {\n result = {\n name: 'Chrome'\n , chrome: t\n , version: getFirstMatch(/(?:chrome|crios|crmo)\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (android) {\n result = {\n name: 'Android'\n , version: versionIdentifier\n }\n }\n else if (/safari|applewebkit/i.test(ua)) {\n result = {\n name: 'Safari'\n , safari: t\n }\n if (versionIdentifier) {\n result.version = versionIdentifier\n }\n }\n else if (iosdevice) {\n result = {\n name : iosdevice == 'iphone' ? 'iPhone' : iosdevice == 'ipad' ? 'iPad' : 'iPod'\n }\n // WTF: version is not part of user agent in web apps\n if (versionIdentifier) {\n result.version = versionIdentifier\n }\n }\n else if(/googlebot/i.test(ua)) {\n result = {\n name: 'Googlebot'\n , googlebot: t\n , version: getFirstMatch(/googlebot\\/(\\d+(\\.\\d+))/i) || versionIdentifier\n }\n }\n else {\n result = {\n name: getFirstMatch(/^(.*)\\/(.*) /),\n version: getSecondMatch(/^(.*)\\/(.*) /)\n };\n }\n\n // set webkit or gecko flag for browsers based on these engines\n if (!result.msedge && /(apple)?webkit/i.test(ua)) {\n if (/(apple)?webkit\\/537\\.36/i.test(ua)) {\n result.name = result.name || \"Blink\"\n result.blink = t\n } else {\n result.name = result.name || \"Webkit\"\n result.webkit = t\n }\n if (!result.version && versionIdentifier) {\n result.version = versionIdentifier\n }\n } else if (!result.opera && /gecko\\//i.test(ua)) {\n result.name = result.name || \"Gecko\"\n result.gecko = t\n result.version = result.version || getFirstMatch(/gecko\\/(\\d+(\\.\\d+)?)/i)\n }\n\n // set OS flags for platforms that have multiple browsers\n if (!result.windowsphone && (android || result.silk)) {\n result.android = t\n result.osname = 'Android'\n } else if (!result.windowsphone && iosdevice) {\n result[iosdevice] = t\n result.ios = t\n result.osname = 'iOS'\n } else if (mac) {\n result.mac = t\n result.osname = 'macOS'\n } else if (xbox) {\n result.xbox = t\n result.osname = 'Xbox'\n } else if (windows) {\n result.windows = t\n result.osname = 'Windows'\n } else if (linux) {\n result.linux = t\n result.osname = 'Linux'\n }\n\n function getWindowsVersion (s) {\n switch (s) {\n case 'NT': return 'NT'\n case 'XP': return 'XP'\n case 'NT 5.0': return '2000'\n case 'NT 5.1': return 'XP'\n case 'NT 5.2': return '2003'\n case 'NT 6.0': return 'Vista'\n case 'NT 6.1': return '7'\n case 'NT 6.2': return '8'\n case 'NT 6.3': return '8.1'\n case 'NT 10.0': return '10'\n default: return undefined\n }\n }\n\n // OS version extraction\n var osVersion = '';\n if (result.windows) {\n osVersion = getWindowsVersion(getFirstMatch(/Windows ((NT|XP)( \\d\\d?.\\d)?)/i))\n } else if (result.windowsphone) {\n osVersion = getFirstMatch(/windows phone (?:os)?\\s?(\\d+(\\.\\d+)*)/i);\n } else if (result.mac) {\n osVersion = getFirstMatch(/Mac OS X (\\d+([_\\.\\s]\\d+)*)/i);\n osVersion = osVersion.replace(/[_\\s]/g, '.');\n } else if (iosdevice) {\n osVersion = getFirstMatch(/os (\\d+([_\\s]\\d+)*) like mac os x/i);\n osVersion = osVersion.replace(/[_\\s]/g, '.');\n } else if (android) {\n osVersion = getFirstMatch(/android[ \\/-](\\d+(\\.\\d+)*)/i);\n } else if (result.webos) {\n osVersion = getFirstMatch(/(?:web|hpw)os\\/(\\d+(\\.\\d+)*)/i);\n } else if (result.blackberry) {\n osVersion = getFirstMatch(/rim\\stablet\\sos\\s(\\d+(\\.\\d+)*)/i);\n } else if (result.bada) {\n osVersion = getFirstMatch(/bada\\/(\\d+(\\.\\d+)*)/i);\n } else if (result.tizen) {\n osVersion = getFirstMatch(/tizen[\\/\\s](\\d+(\\.\\d+)*)/i);\n }\n if (osVersion) {\n result.osversion = osVersion;\n }\n\n // device type extraction\n var osMajorVersion = !result.windows && osVersion.split('.')[0];\n if (\n tablet\n || nexusTablet\n || iosdevice == 'ipad'\n || (android && (osMajorVersion == 3 || (osMajorVersion >= 4 && !mobile)))\n || result.silk\n ) {\n result.tablet = t\n } else if (\n mobile\n || iosdevice == 'iphone'\n || iosdevice == 'ipod'\n || android\n || nexusMobile\n || result.blackberry\n || result.webos\n || result.bada\n ) {\n result.mobile = t\n }\n\n // Graded Browser Support\n // http://developer.yahoo.com/yui/articles/gbs\n if (result.msedge ||\n (result.msie && result.version >= 10) ||\n (result.yandexbrowser && result.version >= 15) ||\n\t\t (result.vivaldi && result.version >= 1.0) ||\n (result.chrome && result.version >= 20) ||\n (result.samsungBrowser && result.version >= 4) ||\n (result.firefox && result.version >= 20.0) ||\n (result.safari && result.version >= 6) ||\n (result.opera && result.version >= 10.0) ||\n (result.ios && result.osversion && result.osversion.split(\".\")[0] >= 6) ||\n (result.blackberry && result.version >= 10.1)\n || (result.chromium && result.version >= 20)\n ) {\n result.a = t;\n }\n else if ((result.msie && result.version < 10) ||\n (result.chrome && result.version < 20) ||\n (result.firefox && result.version < 20.0) ||\n (result.safari && result.version < 6) ||\n (result.opera && result.version < 10.0) ||\n (result.ios && result.osversion && result.osversion.split(\".\")[0] < 6)\n || (result.chromium && result.version < 20)\n ) {\n result.c = t\n } else result.x = t\n\n return result\n }\n\n var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent || '' : '')\n\n bowser.test = function (browserList) {\n for (var i = 0; i < browserList.length; ++i) {\n var browserItem = browserList[i];\n if (typeof browserItem=== 'string') {\n if (browserItem in bowser) {\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * Get version precisions count\n *\n * @example\n * getVersionPrecision(\"1.10.3\") // 3\n *\n * @param {string} version\n * @return {number}\n */\n function getVersionPrecision(version) {\n return version.split(\".\").length;\n }\n\n /**\n * Array::map polyfill\n *\n * @param {Array} arr\n * @param {Function} iterator\n * @return {Array}\n */\n function map(arr, iterator) {\n var result = [], i;\n if (Array.prototype.map) {\n return Array.prototype.map.call(arr, iterator);\n }\n for (i = 0; i < arr.length; i++) {\n result.push(iterator(arr[i]));\n }\n return result;\n }\n\n /**\n * Calculate browser version weight\n *\n * @example\n * compareVersions(['1.10.2.1', '1.8.2.1.90']) // 1\n * compareVersions(['1.010.2.1', '1.09.2.1.90']); // 1\n * compareVersions(['1.10.2.1', '1.10.2.1']); // 0\n * compareVersions(['1.10.2.1', '1.0800.2']); // -1\n *\n * @param {Array} versions versions to compare\n * @return {Number} comparison result\n */\n function compareVersions(versions) {\n // 1) get common precision for both versions, for example for \"10.0\" and \"9\" it should be 2\n var precision = Math.max(getVersionPrecision(versions[0]), getVersionPrecision(versions[1]));\n var chunks = map(versions, function (version) {\n var delta = precision - getVersionPrecision(version);\n\n // 2) \"9\" -> \"9.0\" (for precision = 2)\n version = version + new Array(delta + 1).join(\".0\");\n\n // 3) \"9.0\" -> [\"000000000\"\", \"000000009\"]\n return map(version.split(\".\"), function (chunk) {\n return new Array(20 - chunk.length).join(\"0\") + chunk;\n }).reverse();\n });\n\n // iterate in reverse order by reversed chunks array\n while (--precision >= 0) {\n // 4) compare: \"000000009\" > \"000000010\" = false (but \"9\" > \"10\" = true)\n if (chunks[0][precision] > chunks[1][precision]) {\n return 1;\n }\n else if (chunks[0][precision] === chunks[1][precision]) {\n if (precision === 0) {\n // all version chunks are same\n return 0;\n }\n }\n else {\n return -1;\n }\n }\n }\n\n /**\n * Check if browser is unsupported\n *\n * @example\n * bowser.isUnsupportedBrowser({\n * msie: \"10\",\n * firefox: \"23\",\n * chrome: \"29\",\n * safari: \"5.1\",\n * opera: \"16\",\n * phantom: \"534\"\n * });\n *\n * @param {Object} minVersions map of minimal version to browser\n * @param {Boolean} [strictMode = false] flag to return false if browser wasn't found in map\n * @param {String} [ua] user agent string\n * @return {Boolean}\n */\n function isUnsupportedBrowser(minVersions, strictMode, ua) {\n var _bowser = bowser;\n\n // make strictMode param optional with ua param usage\n if (typeof strictMode === 'string') {\n ua = strictMode;\n strictMode = void(0);\n }\n\n if (strictMode === void(0)) {\n strictMode = false;\n }\n if (ua) {\n _bowser = detect(ua);\n }\n\n var version = \"\" + _bowser.version;\n for (var browser in minVersions) {\n if (minVersions.hasOwnProperty(browser)) {\n if (_bowser[browser]) {\n if (typeof minVersions[browser] !== 'string') {\n throw new Error('Browser version in the minVersion map should be a string: ' + browser + ': ' + String(minVersions));\n }\n\n // browser version and min supported version.\n return compareVersions([version, minVersions[browser]]) < 0;\n }\n }\n }\n\n return strictMode; // not found\n }\n\n /**\n * Check if browser is supported\n *\n * @param {Object} minVersions map of minimal version to browser\n * @param {Boolean} [strictMode = false] flag to return false if browser wasn't found in map\n * @param {String} [ua] user agent string\n * @return {Boolean}\n */\n function check(minVersions, strictMode, ua) {\n return !isUnsupportedBrowser(minVersions, strictMode, ua);\n }\n\n bowser.isUnsupportedBrowser = isUnsupportedBrowser;\n bowser.compareVersions = compareVersions;\n bowser.check = check;\n\n /*\n * Set our detect method to the main bowser object so we can\n * reuse it to test other user agents.\n * This is needed to implement future tests.\n */\n bowser._detect = detect;\n\n /*\n * Set our detect public method to the main bowser object\n * This is needed to implement bowser in server side\n */\n bowser.detect = detect;\n return bowser\n});\n","import SDPUtil from './SDPUtil';\n\n// this could be useful in Array.prototype.\n/**\n *\n * @param array1\n * @param array2\n */\nfunction arrayEquals(array1, array2) {\n // if the other array is a falsy value, return\n if (!array2) {\n return false;\n }\n\n // compare lengths - can save a lot of time\n if (array1.length !== array2.length) {\n return false;\n }\n\n for (let i = 0, l = array1.length; i < l; i++) {\n // Check if we have nested arrays\n if (array1[i] instanceof Array && array2[i] instanceof Array) {\n // recurse into the nested arrays\n if (!array1[i].equals(array2[i])) {\n return false;\n }\n } else if (array1[i] !== array2[i]) {\n // Warning - two different object instances will never be\n // equal: {x:20} != {x:20}\n return false;\n }\n }\n\n return true;\n}\n\n/**\n *\n * @param mySDP\n * @param otherSDP\n */\nexport default function SDPDiffer(mySDP, otherSDP) {\n this.mySDP = mySDP;\n this.otherSDP = otherSDP;\n if (!mySDP) {\n throw new Error('\"mySDP\" is undefined!');\n } else if (!otherSDP) {\n throw new Error('\"otherSDP\" is undefined!');\n }\n}\n\n/**\n * Returns map of MediaChannel that contains media contained in\n * 'mySDP', but not contained in 'otherSdp'. Mapped by channel idx.\n */\nSDPDiffer.prototype.getNewMedia = function() {\n\n const myMedias = this.mySDP.getMediaSsrcMap();\n const othersMedias = this.otherSDP.getMediaSsrcMap();\n const newMedia = {};\n\n Object.keys(othersMedias).forEach(othersMediaIdx => {\n const myMedia = myMedias[othersMediaIdx];\n const othersMedia = othersMedias[othersMediaIdx];\n\n if (!myMedia && othersMedia) {\n // Add whole channel\n newMedia[othersMediaIdx] = othersMedia;\n\n return;\n }\n\n // Look for new ssrcs across the channel\n Object.keys(othersMedia.ssrcs).forEach(ssrc => {\n if (Object.keys(myMedia.ssrcs).indexOf(ssrc) === -1) {\n // Allocate channel if we've found ssrc that doesn't exist in\n // our channel\n if (!newMedia[othersMediaIdx]) {\n newMedia[othersMediaIdx] = {\n mediaindex: othersMedia.mediaindex,\n mid: othersMedia.mid,\n ssrcs: {},\n ssrcGroups: []\n };\n }\n newMedia[othersMediaIdx].ssrcs[ssrc] = othersMedia.ssrcs[ssrc];\n } else if (othersMedia.ssrcs[ssrc].lines\n && myMedia.ssrcs[ssrc].lines) {\n // we want to detect just changes in adding/removing msid\n const myContainMsid = myMedia.ssrcs[ssrc].lines.find(\n line => line.indexOf('msid') !== -1) !== undefined;\n const newContainMsid = othersMedia.ssrcs[ssrc].lines.find(\n line => line.indexOf('msid') !== -1) !== undefined;\n\n if (myContainMsid !== newContainMsid) {\n if (!newMedia[othersMediaIdx]) {\n newMedia[othersMediaIdx] = {\n mediaindex: othersMedia.mediaindex,\n mid: othersMedia.mid,\n ssrcs: {},\n ssrcGroups: []\n };\n }\n newMedia[othersMediaIdx].ssrcs[ssrc]\n = othersMedia.ssrcs[ssrc];\n }\n }\n });\n\n // Look for new ssrc groups across the channels\n othersMedia.ssrcGroups.forEach(otherSsrcGroup => {\n\n // try to match the other ssrc-group with an ssrc-group of ours\n let matched = false;\n\n for (let i = 0; i < myMedia.ssrcGroups.length; i++) {\n const mySsrcGroup = myMedia.ssrcGroups[i];\n\n if (otherSsrcGroup.semantics === mySsrcGroup.semantics\n && arrayEquals(otherSsrcGroup.ssrcs, mySsrcGroup.ssrcs)) {\n\n matched = true;\n break;\n }\n }\n\n if (!matched) {\n // Allocate channel if we've found an ssrc-group that doesn't\n // exist in our channel\n\n if (!newMedia[othersMediaIdx]) {\n newMedia[othersMediaIdx] = {\n mediaindex: othersMedia.mediaindex,\n mid: othersMedia.mid,\n ssrcs: {},\n ssrcGroups: []\n };\n }\n newMedia[othersMediaIdx].ssrcGroups.push(otherSsrcGroup);\n }\n });\n });\n\n return newMedia;\n};\n\n/**\n * TODO: document!\n */\nSDPDiffer.prototype.toJingle = function(modify) {\n const sdpMediaSsrcs = this.getNewMedia();\n\n let modified = false;\n\n Object.keys(sdpMediaSsrcs).forEach(mediaindex => {\n modified = true;\n const media = sdpMediaSsrcs[mediaindex];\n\n modify.c('content', { name: media.mid });\n\n modify.c('description',\n { xmlns: 'urn:xmpp:jingle:apps:rtp:1',\n media: media.mid });\n\n // FIXME: not completely sure this operates on blocks and / or handles\n // different ssrcs correctly\n // generate sources from lines\n Object.keys(media.ssrcs).forEach(ssrcNum => {\n const mediaSsrc = media.ssrcs[ssrcNum];\n\n modify.c('source', { xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0' });\n modify.attrs({ ssrc: mediaSsrc.ssrc });\n\n // iterate over ssrc lines\n mediaSsrc.lines.forEach(line => {\n const idx = line.indexOf(' ');\n const kv = line.substr(idx + 1);\n\n modify.c('parameter');\n if (kv.indexOf(':') === -1) {\n modify.attrs({ name: kv });\n } else {\n const nv = kv.split(':', 2);\n const name = nv[0];\n const value = SDPUtil.filterSpecialChars(nv[1]);\n\n modify.attrs({ name });\n modify.attrs({ value });\n }\n modify.up(); // end of parameter\n });\n modify.up(); // end of source\n });\n\n // generate source groups from lines\n media.ssrcGroups.forEach(ssrcGroup => {\n if (ssrcGroup.ssrcs.length) {\n\n modify.c('ssrc-group', {\n semantics: ssrcGroup.semantics,\n xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0'\n });\n\n ssrcGroup.ssrcs.forEach(ssrc => {\n modify.c('source', { ssrc })\n .up(); // end of source\n });\n modify.up(); // end of ssrc-group\n }\n });\n\n modify.up(); // end of description\n modify.up(); // end of content\n });\n\n return modified;\n};\n","// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n","/**\n * Indicates that the end-to-end round-trip-time for a participant has changed.\n */\nexport const E2E_RTT_CHANGED = 'e2eping.e2e_rtt_changed';\n","/**\n * Provides statistics for the local stream.\n */\n\n/**\n * Size of the webaudio analyzer buffer.\n * @type {number}\n */\nconst WEBAUDIO_ANALYZER_FFT_SIZE = 2048;\n\n/**\n * Value of the webaudio analyzer smoothing time parameter.\n * @type {number}\n */\nconst WEBAUDIO_ANALYZER_SMOOTING_TIME = 0.8;\n\nwindow.AudioContext = window.AudioContext || window.webkitAudioContext;\n\nlet context = null;\n\nif (window.AudioContext) {\n context = new AudioContext();\n\n // XXX Not all browsers define a suspend method on AudioContext. As the\n // invocation is at the (ES6 module) global execution level, it breaks the\n // loading of the lib-jitsi-meet library in such browsers and, consequently,\n // the loading of the very Web app that uses the lib-jitsi-meet library. For\n // example, Google Chrome 40 on Android does not define the method but we\n // still want to be able to load the lib-jitsi-meet library there and\n // display a page which notifies the user that the Web app is not supported\n // there.\n context.suspend && context.suspend();\n}\n\n/**\n * Converts time domain data array to audio level.\n * @param samples the time domain data array.\n * @returns {number} the audio level\n */\nfunction timeDomainDataToAudioLevel(samples) {\n\n let maxVolume = 0;\n\n const length = samples.length;\n\n for (let i = 0; i < length; i++) {\n if (maxVolume < samples[i]) {\n maxVolume = samples[i];\n }\n }\n\n return parseFloat(((maxVolume - 127) / 128).toFixed(3));\n}\n\n/**\n * Animates audio level change\n * @param newLevel the new audio level\n * @param lastLevel the last audio level\n * @returns {Number} the audio level to be set\n */\nfunction animateLevel(newLevel, lastLevel) {\n let value = 0;\n const diff = lastLevel - newLevel;\n\n if (diff > 0.2) {\n value = lastLevel - 0.2;\n } else if (diff < -0.4) {\n value = lastLevel + 0.4;\n } else {\n value = newLevel;\n }\n\n return parseFloat(value.toFixed(3));\n}\n\n\n/**\n * LocalStatsCollector calculates statistics for the local stream.\n *\n * @param stream the local stream\n * @param interval stats refresh interval given in ms.\n * @param callback function that receives the audio levels.\n * @constructor\n */\nexport default function LocalStatsCollector(stream, interval, callback) {\n this.stream = stream;\n this.intervalId = null;\n this.intervalMilis = interval;\n this.audioLevel = 0;\n this.callback = callback;\n}\n\n/**\n * Starts the collecting the statistics.\n */\nLocalStatsCollector.prototype.start = function() {\n if (!LocalStatsCollector.isLocalStatsSupported()) {\n return;\n }\n context.resume();\n const analyser = context.createAnalyser();\n\n analyser.smoothingTimeConstant = WEBAUDIO_ANALYZER_SMOOTING_TIME;\n analyser.fftSize = WEBAUDIO_ANALYZER_FFT_SIZE;\n\n const source = context.createMediaStreamSource(this.stream);\n\n source.connect(analyser);\n\n\n const self = this;\n\n this.intervalId = setInterval(\n () => {\n const array = new Uint8Array(analyser.frequencyBinCount);\n\n analyser.getByteTimeDomainData(array);\n const audioLevel = timeDomainDataToAudioLevel(array);\n\n if (audioLevel !== self.audioLevel) {\n self.audioLevel = animateLevel(audioLevel, self.audioLevel);\n self.callback(self.audioLevel);\n }\n },\n this.intervalMilis\n );\n};\n\n/**\n * Stops collecting the statistics.\n */\nLocalStatsCollector.prototype.stop = function() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n};\n\n/**\n * Checks if the environment has the necessary conditions to support\n * collecting stats from local streams.\n *\n * @returns {boolean}\n */\nLocalStatsCollector.isLocalStatsSupported = function() {\n return Boolean(context);\n};\n","const currentExecutingScript = require('current-executing-script');\n\n/* eslint-disable max-params */\n\n/**\n * Implements utility functions which facilitate the dealing with scripts such\n * as the download and execution of a JavaScript file.\n */\nconst ScriptUtil = {\n /**\n * Loads a script from a specific source.\n *\n * @param src the source from the which the script is to be (down)loaded\n * @param async true to asynchronously load the script or false to\n * synchronously load the script\n * @param prepend true to schedule the loading of the script as soon as\n * possible or false to schedule the loading of the script at the end of the\n * scripts known at the time\n * @param relativeURL whether we need load the library from url relative\n * to the url that lib-jitsi-meet was loaded. Useful when sourcing the\n * library from different location than the app that is using it\n * @param loadCallback on load callback function\n * @param errorCallback callback to be called on error loading the script\n */\n loadScript(\n src,\n async,\n prepend,\n relativeURL,\n loadCallback,\n errorCallback) {\n const d = document;\n const tagName = 'script';\n const script = d.createElement(tagName);\n const referenceNode = d.getElementsByTagName(tagName)[0];\n\n script.async = async;\n\n if (relativeURL) {\n // finds the src url of the current loaded script\n // and use it as base of the src supplied argument\n const scriptEl = currentExecutingScript();\n\n if (scriptEl) {\n const scriptSrc = scriptEl.src;\n const baseScriptSrc\n = scriptSrc.substring(0, scriptSrc.lastIndexOf('/') + 1);\n\n if (scriptSrc && baseScriptSrc) {\n // eslint-disable-next-line no-param-reassign\n src = baseScriptSrc + src;\n }\n }\n }\n\n if (loadCallback) {\n script.onload = loadCallback;\n }\n if (errorCallback) {\n script.onerror = errorCallback;\n }\n\n script.src = src;\n if (prepend) {\n referenceNode.parentNode.insertBefore(script, referenceNode);\n } else {\n referenceNode.parentNode.appendChild(script);\n }\n }\n};\n\n/* eslint-enable max-params */\n\nmodule.exports = ScriptUtil;\n","/**\n * The transciption is on.\n *\n * @type {String}\n */\nexport const ON = 'on';\n\n/**\n * The transciption is off.\n *\n * @type {String}\n */\nexport const OFF = 'off';\n","/* global __filename, module */\nimport EventEmitter from 'events';\nimport { getLogger } from 'jitsi-meet-logger';\nimport * as JitsiTrackEvents from '../../JitsiTrackEvents';\nimport * as MediaType from '../../service/RTC/MediaType';\nimport RTCUtils from './RTCUtils';\n\nconst logger = getLogger(__filename);\n\n/**\n * Maps our handler types to MediaStreamTrack properties.\n */\nconst trackHandler2Prop = {\n 'track_mute': 'onmute', // Not supported on FF\n 'track_unmute': 'onunmute',\n 'track_ended': 'onended'\n};\n\n/**\n * Adds onended/oninactive handler to a MediaStream.\n * @param mediaStream a MediaStream to attach onended/oninactive handler\n * @param handler the handler\n */\nfunction addMediaStreamInactiveHandler(mediaStream, handler) {\n mediaStream.oninactive = handler;\n}\n\n/**\n * Represents a single media track (either audio or video).\n */\nexport default class JitsiTrack extends EventEmitter {\n /* eslint-disable max-params */\n /**\n * Represents a single media track (either audio or video).\n * @constructor\n * @param conference the rtc instance\n * @param stream the WebRTC MediaStream instance\n * @param track the WebRTC MediaStreamTrack instance, must be part of\n * the given stream.\n * @param streamInactiveHandler the function that will handle\n * onended/oninactive events of the stream.\n * @param trackMediaType the media type of the JitsiTrack\n * @param videoType the VideoType for this track if any\n */\n constructor(\n conference,\n stream,\n track,\n streamInactiveHandler,\n trackMediaType,\n videoType) {\n super();\n\n // aliases for addListener/removeListener\n this.addEventListener = this.addListener;\n this.removeEventListener = this.off = this.removeListener;\n\n /**\n * Array with the HTML elements that are displaying the streams.\n * @type {Array}\n */\n this.containers = [];\n this.conference = conference;\n this.audioLevel = -1;\n this.type = trackMediaType;\n this.track = track;\n this.videoType = videoType;\n this.handlers = new Map();\n\n /**\n * Indicates whether this JitsiTrack has been disposed. If true, this\n * JitsiTrack is to be considered unusable and operations involving it\n * are to fail (e.g. {@link JitsiConference#addTrack(JitsiTrack)},\n * {@link JitsiConference#removeTrack(JitsiTrack)}).\n * @type {boolean}\n */\n this.disposed = false;\n\n /**\n * The inactive handler which will be triggered when the underlying\n * MediaStream ends.\n *\n * @private\n * @type {Function}\n */\n this._streamInactiveHandler = streamInactiveHandler;\n\n this._setStream(stream);\n }\n\n /* eslint-enable max-params */\n\n /**\n * Sets handler to the WebRTC MediaStream or MediaStreamTrack object\n * depending on the passed type.\n * @param {string} type the type of the handler that is going to be set\n * @param {Function} handler the handler.\n */\n _setHandler(type, handler) {\n if (!trackHandler2Prop.hasOwnProperty(type)) {\n logger.error(`Invalid handler type ${type}`);\n\n return;\n }\n if (handler) {\n this.handlers.set(type, handler);\n } else {\n this.handlers.delete(type);\n }\n\n if (this.stream) {\n for (const track of this.stream.getTracks()) {\n track[trackHandler2Prop[type]] = handler;\n }\n }\n }\n\n /**\n * Unregisters all event handlers bound to the underlying media stream/track\n * @private\n */\n _unregisterHandlers() {\n if (!this.stream) {\n logger.warn(\n `${this}: unable to unregister handlers - no stream object`);\n\n return;\n }\n\n for (const type of this.handlers.keys()) {\n // FIXME Why only video tracks?\n for (const videoTrack of this.stream.getVideoTracks()) {\n videoTrack[trackHandler2Prop[type]] = undefined;\n }\n }\n if (this._streamInactiveHandler) {\n addMediaStreamInactiveHandler(this.stream, undefined);\n }\n }\n\n /**\n * Sets the stream property of JitsiTrack object and sets all stored\n * handlers to it.\n *\n * @param {MediaStream} stream the new stream.\n * @protected\n */\n _setStream(stream) {\n if (this.stream === stream) {\n return;\n }\n\n this.stream = stream;\n\n // TODO Practically, that's like the opposite of _unregisterHandlers\n // i.e. may be abstracted into a function/method called\n // _registerHandlers for clarity and easing the maintenance of the two\n // pieces of source code.\n if (this.stream) {\n for (const type of this.handlers.keys()) {\n this._setHandler(type, this.handlers.get(type));\n }\n if (this._streamInactiveHandler) {\n addMediaStreamInactiveHandler(\n this.stream, this._streamInactiveHandler);\n }\n }\n }\n\n /**\n * Returns the type (audio or video) of this track.\n */\n getType() {\n return this.type;\n }\n\n /**\n * Check if this is an audio track.\n */\n isAudioTrack() {\n return this.getType() === MediaType.AUDIO;\n }\n\n /**\n * Checks whether the underlying WebRTC MediaStreamTrack is muted\n * according to it's 'muted' field status.\n * @return {boolean} true if the underlying\n * MediaStreamTrack is muted or false otherwise.\n */\n isWebRTCTrackMuted() {\n return this.track && this.track.muted;\n }\n\n /**\n * Check if this is a video track.\n */\n isVideoTrack() {\n return this.getType() === MediaType.VIDEO;\n }\n\n /**\n * Checks whether this is a local track.\n * @abstract\n * @return {boolean} 'true' if it's a local track or 'false' otherwise.\n */\n isLocal() {\n throw new Error('Not implemented by subclass');\n }\n\n /**\n * Returns the WebRTC MediaStream instance.\n */\n getOriginalStream() {\n return this.stream;\n }\n\n /**\n * Returns the ID of the underlying WebRTC Media Stream(if any)\n * @returns {String|null}\n */\n getStreamId() {\n return this.stream ? this.stream.id : null;\n }\n\n /**\n * Return the underlying WebRTC MediaStreamTrack\n * @returns {MediaStreamTrack}\n */\n getTrack() {\n return this.track;\n }\n\n /**\n * Returns the ID of the underlying WebRTC MediaStreamTrack(if any)\n * @returns {String|null}\n */\n getTrackId() {\n return this.track ? this.track.id : null;\n }\n\n /**\n * Return meaningful usage label for this track depending on it's media and\n * eventual video type.\n * @returns {string}\n */\n getUsageLabel() {\n if (this.isAudioTrack()) {\n return 'mic';\n }\n\n return this.videoType ? this.videoType : 'default';\n }\n\n /**\n * Eventually will trigger RTCEvents.TRACK_ATTACHED event.\n * @param container the video/audio container to which this stream is\n * attached and for which event will be fired.\n * @private\n */\n _maybeFireTrackAttached(container) {\n if (this.conference && container) {\n this.conference._onTrackAttach(this, container);\n }\n }\n\n /**\n * Attaches the MediaStream of this track to an HTML container.\n * Adds the container to the list of containers that are displaying the\n * track.\n *\n * @param container the HTML container which can be 'video' or 'audio'\n * element.\n *\n * @returns {void}\n */\n attach(container) {\n if (this.stream) {\n this._onTrackAttach(container);\n RTCUtils.attachMediaStream(container, this.stream);\n }\n this.containers.push(container);\n this._maybeFireTrackAttached(container);\n this._attachTTFMTracker(container);\n }\n\n /**\n * Removes this JitsiTrack from the passed HTML container.\n *\n * @param container the HTML container to detach from this JitsiTrack. If\n * null or undefined, all containers are removed. A\n * container can be a 'video', 'audio' or 'object' HTML element instance to\n * which this JitsiTrack is currently attached.\n */\n detach(container) {\n for (let cs = this.containers, i = cs.length - 1; i >= 0; --i) {\n const c = cs[i];\n\n if (!container) {\n this._onTrackDetach(c);\n RTCUtils.attachMediaStream(c, null);\n }\n if (!container || c === container) {\n cs.splice(i, 1);\n }\n }\n\n if (container) {\n this._onTrackDetach(container);\n RTCUtils.attachMediaStream(container, null);\n }\n }\n\n /**\n * Called when the track has been attached to a new container.\n *\n * @param {HTMLElement} container the HTML container which can be 'video' or\n * 'audio' element.\n * @private\n */\n _onTrackAttach(container) { // eslint-disable-line no-unused-vars\n // Should be defined by the classes that are extending JitsiTrack\n }\n\n /**\n * Called when the track has been detached from a container.\n *\n * @param {HTMLElement} container the HTML container which can be 'video' or\n * 'audio' element.\n * @private\n */\n _onTrackDetach(container) { // eslint-disable-line no-unused-vars\n // Should be defined by the classes that are extending JitsiTrack\n }\n\n /**\n * Attach time to first media tracker only if there is conference and only\n * for the first element.\n *\n * @param {HTMLElement} container the HTML container which can be 'video' or\n * 'audio' element.\n * @private\n */\n _attachTTFMTracker(container) { // eslint-disable-line no-unused-vars\n // Should be defined by the classes that are extending JitsiTrack\n }\n\n /**\n * Removes attached event listeners.\n *\n * @returns {Promise}\n */\n dispose() {\n this.removeAllListeners();\n\n this.disposed = true;\n\n return Promise.resolve();\n }\n\n /**\n * Returns true if this is a video track and the source of the video is a\n * screen capture as opposed to a camera.\n */\n isScreenSharing() {\n // FIXME: Should be fixed or removed.\n }\n\n /**\n * Returns id of the track.\n * @returns {string|null} id of the track or null if this is fake track.\n */\n getId() {\n if (this.stream) {\n return RTCUtils.getStreamID(this.stream);\n }\n\n return null;\n }\n\n /**\n * Checks whether the MediaStream is active/not ended.\n * When there is no check for active we don't have information and so\n * will return that stream is active (in case of FF).\n * @returns {boolean} whether MediaStream is active.\n */\n isActive() {\n if (typeof this.stream.active !== 'undefined') {\n return this.stream.active;\n }\n\n return true;\n }\n\n /**\n * Sets the audio level for the stream\n * @param {number} audioLevel value between 0 and 1\n * @param {TraceablePeerConnection} [tpc] the peerconnection instance which\n * is source for the audio level. It can be undefined for\n * a local track if the audio level was measured outside of the\n * peerconnection (see /modules/statistics/LocalStatsCollector.js).\n */\n setAudioLevel(audioLevel, tpc) {\n if (this.audioLevel !== audioLevel) {\n this.audioLevel = audioLevel;\n this.emit(\n JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,\n audioLevel,\n tpc);\n }\n }\n\n /**\n * Returns the msid of the stream attached to the JitsiTrack object or null\n * if no stream is attached.\n */\n getMSID() {\n const streamId = this.getStreamId();\n const trackId = this.getTrackId();\n\n return streamId && trackId ? `${streamId} ${trackId}` : null;\n }\n\n /**\n * Sets new audio output device for track's DOM elements. Video tracks are\n * ignored.\n * @param {string} audioOutputDeviceId - id of 'audiooutput' device from\n * navigator.mediaDevices.enumerateDevices(), '' for default device\n * @emits JitsiTrackEvents.TRACK_AUDIO_OUTPUT_CHANGED\n * @returns {Promise}\n */\n setAudioOutput(audioOutputDeviceId) {\n if (!RTCUtils.isDeviceChangeAvailable('output')) {\n return Promise.reject(\n new Error('Audio output device change is not supported'));\n }\n\n // All audio communication is done through audio tracks, so ignore\n // changing audio output for video tracks at all.\n if (this.isVideoTrack()) {\n return Promise.resolve();\n }\n\n return (\n Promise.all(\n this.containers.map(\n element =>\n element.setSinkId(audioOutputDeviceId)\n .catch(error => {\n logger.warn(\n 'Failed to change audio output device on'\n + ' element. Default or previously set'\n + ' audio output device will be used.',\n element,\n error);\n throw error;\n }))\n )\n .then(() => {\n this.emit(\n JitsiTrackEvents.TRACK_AUDIO_OUTPUT_CHANGED,\n audioOutputDeviceId);\n }));\n }\n}\n","\n\n/**\n * The method will increase the given number by 1. If the given counter is equal\n * or greater to {@link Number.MAX_SAFE_INTEGER} then it will be rolled back to\n * 1.\n * @param {number} number - An integer counter value to be incremented.\n * @return {number} the next counter value increased by 1 (see the description\n * above for exception).\n */\nexport function safeCounterIncrement(number) {\n let nextValue = number;\n\n if (number >= Number.MAX_SAFE_INTEGER) {\n nextValue = 0;\n }\n\n return nextValue + 1;\n}\n","/**\n * A model for keeping track of each user's total\n * time as a dominant speaker. The model also\n * keeps track of the user's last known name\n * in case the user has left the meeting,\n * which is also tracked.\n */\nclass SpeakerStats {\n /**\n * Initializes a new SpeakerStats instance.\n *\n * @constructor\n * @param {string} userId - The id of the user being tracked.\n * @param {string} displayName - The name of the user being tracked.\n * @param {boolean} isLocalStats - True if the stats model tracks\n * the local user.\n * @returns {void}\n */\n constructor(userId, displayName, isLocalStats) {\n this._userId = userId;\n this.setDisplayName(displayName);\n this._isLocalStats = isLocalStats || false;\n this.setDominantSpeaker(false);\n this.totalDominantSpeakerTime = 0;\n this._dominantSpeakerStart = 0;\n this._hasLeft = false;\n }\n\n /**\n * Get the user id being tracked.\n *\n * @returns {string} The user id.\n */\n getUserId() {\n return this._userId;\n }\n\n /**\n * Get the name of the user being tracked.\n *\n * @returns {string} The user name.\n */\n getDisplayName() {\n return this.displayName;\n }\n\n /**\n * Updates the last known name of the user being tracked.\n *\n * @param {string} - The user name.\n * @returns {void}\n */\n setDisplayName(newName) {\n this.displayName = newName;\n }\n\n /**\n * Returns true if the stats are tracking the local user.\n *\n * @returns {boolean}\n */\n isLocalStats() {\n return this._isLocalStats;\n }\n\n /**\n * Returns true if the tracked user is currently a dominant speaker.\n *\n * @returns {boolean}\n */\n isDominantSpeaker() {\n return this._dominantSpeakerStart > 0;\n }\n\n /**\n * Returns true if the tracked user is currently a dominant speaker.\n *\n * @param {boolean} - If true, the user will being accumulating time\n * as dominant speaker. If false, the user will not accumulate time\n * and will record any time accumulated since starting as dominant speaker.\n * @returns {void}\n */\n setDominantSpeaker(isNowDominantSpeaker) {\n if (!this.isDominantSpeaker() && isNowDominantSpeaker) {\n this._dominantSpeakerStart = Date.now();\n } else if (this.isDominantSpeaker() && !isNowDominantSpeaker) {\n const now = Date.now();\n const timeElapsed = now - this._dominantSpeakerStart;\n\n this.totalDominantSpeakerTime += timeElapsed;\n this._dominantSpeakerStart = 0;\n }\n }\n\n /**\n * Get how long the tracked user has been dominant speaker.\n *\n * @returns {number} - The speaker time in milliseconds.\n */\n getTotalDominantSpeakerTime() {\n let total = this.totalDominantSpeakerTime;\n\n if (this.isDominantSpeaker()) {\n total += Date.now() - this._dominantSpeakerStart;\n }\n\n return total;\n }\n\n /**\n * Get whether or not the user is still in the meeting.\n *\n * @returns {boolean} True if the user is no longer in the meeting.\n */\n hasLeft() {\n return this._hasLeft;\n }\n\n /**\n * Set the user as having left the meeting.\n *\n * @returns {void}\n */\n markAsHasLeft() {\n this._hasLeft = true;\n this.setDominantSpeaker(false);\n }\n}\n\nmodule.exports = SpeakerStats;\n","const AuthenticationEvents = {\n /**\n * Event callback arguments:\n * function(authenticationEnabled, userIdentity)\n * authenticationEnabled - indicates whether authentication has been enabled\n * in this session\n * userIdentity - if user has been logged in then it contains user name. If\n * contains 'null' or 'undefined' then user is not logged in.\n */\n IDENTITY_UPDATED: 'authentication.identity_updated'\n};\n\nmodule.exports = AuthenticationEvents;\n","/* global __filename, Promise */\n\nimport { getLogger } from 'jitsi-meet-logger';\nimport JitsiTrack from './JitsiTrack';\nimport JitsiTrackError from '../../JitsiTrackError';\nimport {\n TRACK_IS_DISPOSED,\n TRACK_NO_STREAM_FOUND\n} from '../../JitsiTrackErrors';\nimport {\n LOCAL_TRACK_STOPPED,\n NO_DATA_FROM_SOURCE,\n TRACK_MUTE_CHANGED\n} from '../../JitsiTrackEvents';\nimport browser from '../browser';\nimport RTCUtils from './RTCUtils';\nimport CameraFacingMode from '../../service/RTC/CameraFacingMode';\nimport * as MediaType from '../../service/RTC/MediaType';\nimport RTCEvents from '../../service/RTC/RTCEvents';\nimport VideoType from '../../service/RTC/VideoType';\nimport {\n NO_BYTES_SENT,\n TRACK_UNMUTED,\n createNoDataFromSourceEvent\n} from '../../service/statistics/AnalyticsEvents';\nimport Statistics from '../statistics/statistics';\n\nconst logger = getLogger(__filename);\n\n/**\n * Represents a single media track(either audio or video).\n * One JitsiLocalTrack corresponds to one WebRTC MediaStreamTrack.\n */\nexport default class JitsiLocalTrack extends JitsiTrack {\n /**\n * Constructs new JitsiLocalTrack instance.\n *\n * @constructor\n * @param {Object} trackInfo\n * @param {number} trackInfo.rtcId the ID assigned by the RTC module\n * @param trackInfo.stream WebRTC MediaStream, parent of the track\n * @param trackInfo.track underlying WebRTC MediaStreamTrack for new\n * JitsiRemoteTrack\n * @param trackInfo.mediaType the MediaType of the JitsiRemoteTrack\n * @param trackInfo.videoType the VideoType of the JitsiRemoteTrack\n * @param trackInfo.effects the effects array contains the effect instance to use\n * @param trackInfo.resolution the video resolution if it's a video track\n * @param trackInfo.deviceId the ID of the local device for this track\n * @param trackInfo.facingMode the camera facing mode used in getUserMedia\n * call\n * @param {sourceId} trackInfo.sourceId - The id of the desktop sharing\n * source. NOTE: defined for desktop sharing tracks only.\n */\n constructor({\n deviceId,\n facingMode,\n mediaType,\n resolution,\n rtcId,\n sourceId,\n sourceType,\n stream,\n track,\n videoType,\n effects = []\n }) {\n super(\n /* conference */ null,\n stream,\n track,\n /* streamInactiveHandler */ () => this.emit(LOCAL_TRACK_STOPPED),\n mediaType,\n videoType);\n\n this._setEffectInProgress = false;\n const effect = effects.find(e => e.isEnabled(this));\n\n if (effect) {\n this._startStreamEffect(effect);\n }\n\n /**\n * The ID assigned by the RTC module on instance creation.\n *\n * @type {number}\n */\n this.rtcId = rtcId;\n this.sourceId = sourceId;\n this.sourceType = sourceType;\n\n if (browser.usesNewGumFlow()) {\n // Get the resolution from the track itself because it cannot be\n // certain which resolution webrtc has fallen back to using.\n this.resolution = track.getSettings().height;\n\n // Cache the constraints of the track in case of any this track\n // model needs to call getUserMedia again, such as when unmuting.\n this._constraints = track.getConstraints();\n } else {\n // FIXME Currently, Firefox is ignoring our constraints about\n // resolutions so we do not store it, to avoid wrong reporting of\n // local track resolution.\n this.resolution = browser.isFirefox() ? null : resolution;\n }\n\n this.deviceId = deviceId;\n\n /**\n * The Promise which represents the progress of a previously\n * queued/scheduled {@link _setMuted} (from the point of view of\n * {@link _queueSetMuted}).\n *\n * @private\n * @type {Promise}\n */\n this._prevSetMuted = Promise.resolve();\n\n /**\n * The facing mode of the camera from which this JitsiLocalTrack\n * instance was obtained.\n *\n * @private\n * @type {CameraFacingMode|undefined}\n */\n this._facingMode = facingMode;\n\n // Currently there is no way to know the MediaStreamTrack ended due to\n // to device disconnect in Firefox through e.g. \"readyState\" property.\n // Instead we will compare current track's label with device labels from\n // enumerateDevices() list.\n this._trackEnded = false;\n\n /**\n * Indicates whether data has been sent or not.\n */\n this._hasSentData = false;\n\n /**\n * Used only for detection of audio problems. We want to check only once\n * whether the track is sending data ot not. This flag is set to false\n * after the check.\n */\n this._testDataSent = true;\n\n // Currently there is no way to determine with what device track was\n // created (until getConstraints() support), however we can associate\n // tracks with real devices obtained from enumerateDevices() call as\n // soon as it's called.\n // NOTE: this.deviceId corresponds to the device id specified in GUM constraints and this._realDeviceId seems to\n // correspond to the id of a matching device from the available device list.\n this._realDeviceId = this.deviceId === '' ? undefined : this.deviceId;\n\n this._trackMutedTS = 0;\n\n this._onDeviceListWillChange = devices => {\n const oldRealDeviceId = this._realDeviceId;\n\n this._setRealDeviceIdFromDeviceList(devices);\n\n if (\n // Mark track as ended for those browsers that do not support\n // \"readyState\" property. We do not touch tracks created with\n // default device ID \"\".\n (typeof this.getTrack().readyState === 'undefined'\n && typeof this._realDeviceId !== 'undefined'\n && !devices.find(d => d.deviceId === this._realDeviceId))\n\n // If there was an associated realDeviceID and after the device change the realDeviceId is undefined\n // then the associated device has been disconnected and the _trackEnded flag needs to be set. In\n // addition on some Chrome versions the readyState property is set after the device change event is\n // triggered which causes issues in jitsi-meet with the selection of a new device because we don't\n // detect that the old one was removed.\n || (typeof oldRealDeviceId !== 'undefined' && typeof this._realDeviceId === 'undefined')\n ) {\n this._trackEnded = true;\n }\n };\n\n // Subscribe each created local audio track to\n // RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED event. This is different from\n // handling this event for remote tracks (which are handled in RTC.js),\n // because there might be local tracks not attached to a conference.\n if (this.isAudioTrack() && RTCUtils.isDeviceChangeAvailable('output')) {\n this._onAudioOutputDeviceChanged = this.setAudioOutput.bind(this);\n RTCUtils.addListener(\n RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED,\n this._onAudioOutputDeviceChanged);\n }\n\n RTCUtils.addListener(RTCEvents.DEVICE_LIST_WILL_CHANGE, this._onDeviceListWillChange);\n\n this._initNoDataFromSourceHandlers();\n }\n\n /**\n * Returns if associated MediaStreamTrack is in the 'ended' state\n *\n * @returns {boolean}\n */\n isEnded() {\n if (this.isVideoTrack() && this.isMuted()) {\n // If a video track is muted the readyState will be ended, that's why we need to rely only on the\n // _trackEnded flag.\n return this._trackEnded;\n }\n\n return this.getTrack().readyState === 'ended' || this._trackEnded;\n }\n\n /**\n * Sets handlers to the MediaStreamTrack object that will detect camera\n * issues.\n */\n _initNoDataFromSourceHandlers() {\n if (!this._isNoDataFromSourceEventsEnabled()) {\n return;\n }\n\n this._setHandler('track_mute', () => {\n this._trackMutedTS = window.performance.now();\n this._fireNoDataFromSourceEvent();\n });\n\n this._setHandler('track_unmute', () => {\n this._fireNoDataFromSourceEvent();\n Statistics.sendAnalyticsAndLog(\n TRACK_UNMUTED,\n {\n 'media_type': this.getType(),\n 'track_type': 'local',\n value: window.performance.now() - this._trackMutedTS\n });\n });\n\n if (this.isVideoTrack() && this.videoType === VideoType.CAMERA) {\n this._setHandler('track_ended', () => {\n if (!this.isReceivingData()) {\n this._fireNoDataFromSourceEvent();\n }\n });\n }\n }\n\n /**\n * Returns true if no data from source events are enabled for this JitsiLocalTrack and false otherwise.\n *\n * @returns {boolean} - True if no data from source events are enabled for this JitsiLocalTrack and false otherwise.\n */\n _isNoDataFromSourceEventsEnabled() {\n // Disable the events for screen sharing.\n return !this.isVideoTrack() || this.videoType !== VideoType.DESKTOP;\n }\n\n /**\n * Fires NO_DATA_FROM_SOURCE event and logs it to analytics and callstats.\n */\n _fireNoDataFromSourceEvent() {\n const value = !this.isReceivingData();\n\n this.emit(NO_DATA_FROM_SOURCE, value);\n\n // FIXME: Should we report all of those events\n Statistics.sendAnalytics(createNoDataFromSourceEvent(this.getType(), value));\n Statistics.sendLog(JSON.stringify({\n name: NO_DATA_FROM_SOURCE,\n log: value\n }));\n }\n\n /**\n * Sets real device ID by comparing track information with device\n * information. This is temporary solution until getConstraints() method\n * will be implemented in browsers.\n *\n * @param {MediaDeviceInfo[]} devices - list of devices obtained from\n * enumerateDevices() call\n */\n _setRealDeviceIdFromDeviceList(devices) {\n const track = this.getTrack();\n const kind = `${track.kind}input`;\n let device = devices.find(d => d.kind === kind && d.label === track.label);\n\n if (!device && this._realDeviceId === 'default') { // the default device has been changed.\n // If the default device was 'A' and the default device is changed to 'B' the label for the track will\n // remain 'Default - A' but the label for the device in the device list will be updated to 'A'. That's\n // why in order to match it we need to remove the 'Default - ' part.\n const label = (track.label || '').replace('Default - ', '');\n\n device = devices.find(d => d.kind === kind && d.label === label);\n }\n\n if (device) {\n this._realDeviceId = device.deviceId;\n } else {\n this._realDeviceId = undefined;\n }\n }\n\n /**\n * Sets the stream property of JitsiLocalTrack object and sets all stored\n * handlers to it.\n *\n * @param {MediaStream} stream the new stream.\n * @protected\n */\n _setStream(stream) {\n super._setStream(stream);\n\n if (stream) {\n // Store the MSID for video mute/unmute purposes.\n this.storedMSID = this.getMSID();\n logger.debug(`Setting new MSID: ${this.storedMSID} on ${this}`);\n } else {\n logger.debug(`Setting 'null' stream on ${this}`);\n }\n }\n\n /**\n * Starts the effect process and returns the modified stream.\n *\n * @private\n * @param {*} effect - Represents effect instance\n * @returns {void}\n */\n _startStreamEffect(effect) {\n this._streamEffect = effect;\n this._originalStream = this.stream;\n this._setStream(this._streamEffect.startEffect(this._originalStream));\n }\n\n /**\n * Stops the effect process and returns the original stream.\n *\n * @private\n * @returns {void}\n */\n _stopStreamEffect() {\n if (this._streamEffect) {\n this._streamEffect.stopEffect();\n this._setStream(this._originalStream);\n this._originalStream = undefined;\n }\n }\n\n /**\n * Stops the currently used effect (if there is one) and starts the passed effect (if there is one).\n *\n * @param {Object|undefined} effect - The new effect to be set.\n */\n _switchStreamEffect(effect) {\n if (this._streamEffect) {\n this._stopStreamEffect();\n this._streamEffect = undefined;\n }\n if (effect) {\n this._startStreamEffect(effect);\n }\n }\n\n /**\n * Sets the effect and switches between the modified stream and original one.\n *\n * @param {Object} effect - Represents the effect instance to be used.\n * @returns {Promise}\n */\n setEffect(effect) {\n if (typeof this._streamEffect === 'undefined' && typeof effect === 'undefined') {\n return Promise.resolve();\n }\n\n if (typeof effect !== 'undefined' && !effect.isEnabled(this)) {\n return Promise.reject(new Error('Incompatible effect instance!'));\n }\n\n if (this._setEffectInProgress === true) {\n return Promise.reject(new Error('setEffect already in progress!'));\n }\n\n if (this.isMuted()) {\n this._streamEffect = effect;\n\n return Promise.resolve();\n }\n\n const conference = this.conference;\n\n if (!conference) {\n this._switchStreamEffect(effect);\n\n return Promise.resolve();\n }\n\n this._setEffectInProgress = true;\n\n // TODO: Create new JingleSessionPC method for replacing a stream in JitsiLocalTrack without offer answer.\n return conference.removeTrack(this)\n .then(() => {\n this._switchStreamEffect(effect);\n if (this.isVideoTrack()) {\n this.containers.forEach(cont => RTCUtils.attachMediaStream(cont, this.stream));\n }\n\n return conference.addTrack(this);\n })\n .then(() => {\n this._setEffectInProgress = false;\n })\n .catch(error => {\n // Any error will be not recovarable and will trigger CONFERENCE_FAILED event. But let's try to cleanup\n // everyhting related to the effect functionality.\n this._setEffectInProgress = false;\n this._switchStreamEffect();\n logger.error('Failed to switch to the new stream!', error);\n throw error;\n });\n }\n\n /**\n * Asynchronously mutes this track.\n *\n * @returns {Promise}\n */\n mute() {\n return this._queueSetMuted(true);\n }\n\n /**\n * Asynchronously unmutes this track.\n *\n * @returns {Promise}\n */\n unmute() {\n return this._queueSetMuted(false);\n }\n\n /**\n * Initializes a new Promise to execute {@link #_setMuted}. May be called\n * multiple times in a row and the invocations of {@link #_setMuted} and,\n * consequently, {@link #mute} and/or {@link #unmute} will be resolved in a\n * serialized fashion.\n *\n * @param {boolean} muted - The value to invoke _setMuted with.\n * @returns {Promise}\n */\n _queueSetMuted(muted) {\n const setMuted = this._setMuted.bind(this, muted);\n\n this._prevSetMuted = this._prevSetMuted.then(setMuted, setMuted);\n\n return this._prevSetMuted;\n }\n\n /**\n * Mutes / unmutes this track.\n *\n * @param {boolean} muted - If true, this track will be muted;\n * otherwise, this track will be unmuted.\n * @private\n * @returns {Promise}\n */\n _setMuted(muted) {\n if (this.isMuted() === muted) {\n return Promise.resolve();\n }\n\n if (this.disposed) {\n return Promise.reject(new JitsiTrackError(TRACK_IS_DISPOSED));\n }\n\n let promise = Promise.resolve();\n\n // A function that will print info about muted status transition\n const logMuteInfo = () => logger.info(`Mute ${this}: ${muted}`);\n\n if (this.isAudioTrack()\n || this.videoType === VideoType.DESKTOP\n || !browser.doesVideoMuteByStreamRemove()) {\n logMuteInfo();\n if (this.track) {\n this.track.enabled = !muted;\n }\n } else if (muted) {\n promise = new Promise((resolve, reject) => {\n logMuteInfo();\n this._removeStreamFromConferenceAsMute(\n () => {\n if (this._streamEffect) {\n this._stopStreamEffect();\n }\n\n // FIXME: Maybe here we should set the SRC for the\n // containers to something\n // We don't want any events to be fired on this stream\n this._unregisterHandlers();\n this.stopStream();\n this._setStream(null);\n resolve();\n },\n reject);\n });\n } else {\n logMuteInfo();\n\n // This path is only for camera.\n const streamOptions = {\n cameraDeviceId: this.getDeviceId(),\n devices: [ MediaType.VIDEO ],\n effects: this._streamEffect ? [ this._streamEffect ] : [],\n facingMode: this.getCameraFacingMode()\n };\n\n if (browser.usesNewGumFlow()) {\n promise\n = RTCUtils.newObtainAudioAndVideoPermissions(Object.assign(\n {},\n streamOptions,\n { constraints: { video: this._constraints } }));\n } else {\n if (this.resolution) {\n streamOptions.resolution = this.resolution;\n }\n\n promise\n = RTCUtils.obtainAudioAndVideoPermissions(streamOptions);\n }\n\n promise.then(streamsInfo => {\n const mediaType = this.getType();\n const streamInfo\n = browser.usesNewGumFlow()\n ? streamsInfo.find(\n info => info.track.kind === mediaType)\n : streamsInfo.find(\n info => info.mediaType === mediaType);\n\n if (streamInfo) {\n this._setStream(streamInfo.stream);\n this.track = streamInfo.track;\n\n // This is not good when video type changes after\n // unmute, but let's not crash here\n if (this.videoType !== streamInfo.videoType) {\n logger.warn(\n `${this}: video type has changed after unmute!`,\n this.videoType, streamInfo.videoType);\n this.videoType = streamInfo.videoType;\n }\n } else {\n throw new JitsiTrackError(TRACK_NO_STREAM_FOUND);\n }\n\n if (this._streamEffect) {\n this._startStreamEffect(this._streamEffect);\n }\n\n this.containers.map(\n cont => RTCUtils.attachMediaStream(cont, this.stream));\n\n return this._addStreamToConferenceAsUnmute();\n });\n }\n\n return promise\n .then(() => this._sendMuteStatus(muted))\n .then(() => this.emit(TRACK_MUTE_CHANGED, this));\n }\n\n /**\n * Adds stream to conference and marks it as \"unmute\" operation.\n *\n * @private\n * @returns {Promise}\n */\n _addStreamToConferenceAsUnmute() {\n if (!this.conference) {\n return Promise.resolve();\n }\n\n // FIXME it would be good to not included conference as part of this\n // process. Only TraceablePeerConnections to which the track is attached\n // should care about this action. The TPCs to which the track is not\n // attached can sync up when track is re-attached.\n // A problem with that is that the \"modify sources\" queue is part of\n // the JingleSessionPC and it would be excluded from the process. One\n // solution would be to extract class between TPC and JingleSessionPC\n // which would contain the queue and would notify the signaling layer\n // when local SSRCs are changed. This would help to separate XMPP from\n // the RTC module.\n return new Promise((resolve, reject) => {\n this.conference._addLocalTrackAsUnmute(this)\n .then(resolve, error => reject(new Error(error)));\n });\n }\n\n /**\n * Removes stream from conference and marks it as \"mute\" operation.\n *\n * @param {Function} successCallback will be called on success\n * @param {Function} errorCallback will be called on error\n * @private\n */\n _removeStreamFromConferenceAsMute(successCallback, errorCallback) {\n if (!this.conference) {\n successCallback();\n\n return;\n }\n this.conference._removeLocalTrackAsMute(this).then(\n successCallback,\n error => errorCallback(new Error(error)));\n }\n\n /**\n * Sends mute status for a track to conference if any.\n *\n * @param {boolean} mute - If track is muted.\n * @private\n * @returns {Promise}\n */\n _sendMuteStatus(mute) {\n if (!this.conference || !this.conference.room) {\n return Promise.resolve();\n }\n\n return new Promise(resolve => {\n this.conference.room[\n this.isAudioTrack()\n ? 'setAudioMute'\n : 'setVideoMute'](mute, resolve);\n });\n }\n\n /**\n * @inheritdoc\n *\n * Stops sending the media track. And removes it from the HTML.\n * NOTE: Works for local tracks only.\n *\n * @extends JitsiTrack#dispose\n * @returns {Promise}\n */\n dispose() {\n this._switchStreamEffect();\n\n let promise = Promise.resolve();\n\n if (this.conference) {\n promise = this.conference.removeTrack(this);\n }\n\n if (this.stream) {\n this.stopStream();\n this.detach();\n }\n\n RTCUtils.removeListener(RTCEvents.DEVICE_LIST_WILL_CHANGE, this._onDeviceListWillChange);\n\n if (this._onAudioOutputDeviceChanged) {\n RTCUtils.removeListener(RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED,\n this._onAudioOutputDeviceChanged);\n }\n\n return promise.then(() => super.dispose());\n }\n\n /**\n * Returns true - if the stream is muted and false\n * otherwise.\n *\n * @returns {boolean} true - if the stream is muted and\n * false otherwise.\n */\n isMuted() {\n // this.stream will be null when we mute local video on Chrome\n if (!this.stream) {\n return true;\n }\n if (this.isVideoTrack() && !this.isActive()) {\n return true;\n }\n\n return !this.track || !this.track.enabled;\n }\n\n /**\n * Sets the JitsiConference object associated with the track. This is temp\n * solution.\n *\n * @param conference the JitsiConference object\n */\n _setConference(conference) {\n this.conference = conference;\n\n // We want to keep up with postponed events which should have been fired\n // on \"attach\" call, but for local track we not always have the\n // conference before attaching. However this may result in duplicated\n // events if they have been triggered on \"attach\" already.\n for (let i = 0; i < this.containers.length; i++) {\n this._maybeFireTrackAttached(this.containers[i]);\n }\n }\n\n /**\n * Returns true.\n *\n * @returns {boolean} true\n */\n isLocal() {\n return true;\n }\n\n /**\n * Returns device id associated with track.\n *\n * @returns {string}\n */\n getDeviceId() {\n return this._realDeviceId || this.deviceId;\n }\n\n /**\n * Returns the participant id which owns the track.\n *\n * @returns {string} the id of the participants. It corresponds to the\n * Colibri endpoint id/MUC nickname in case of Jitsi-meet.\n */\n getParticipantId() {\n return this.conference && this.conference.myUserId();\n }\n\n /**\n * Handles bytes sent statistics.\n *\n * @param {TraceablePeerConnection} tpc the source of the \"bytes sent\" stat\n * @param {number} bytesSent the new value\n * NOTE: used only for audio tracks to detect audio issues.\n */\n _onByteSentStatsReceived(tpc, bytesSent) {\n if (bytesSent > 0) {\n this._hasSentData = true;\n }\n const iceConnectionState = tpc.getConnectionState();\n\n if (this._testDataSent && iceConnectionState === 'connected') {\n setTimeout(() => {\n if (!this._hasSentData) {\n logger.warn(`${this} 'bytes sent' <= 0: \\\n ${bytesSent}`);\n\n Statistics.analytics.sendEvent(NO_BYTES_SENT, { 'media_type': this.getType() });\n }\n }, 3000);\n this._testDataSent = false;\n }\n }\n\n /**\n * Returns facing mode for video track from camera. For other cases (e.g.\n * audio track or 'desktop' video track) returns undefined.\n *\n * @returns {CameraFacingMode|undefined}\n */\n getCameraFacingMode() {\n if (this.isVideoTrack() && this.videoType === VideoType.CAMERA) {\n // MediaStreamTrack#getSettings() is not implemented in many\n // browsers, so we need feature checking here. Progress on the\n // respective browser's implementation can be tracked at\n // https://bugs.chromium.org/p/webrtc/issues/detail?id=2481 for\n // Chromium and https://bugzilla.mozilla.org/show_bug.cgi?id=1213517\n // for Firefox. Even if a browser implements getSettings() already,\n // it might still not return anything for 'facingMode'.\n let trackSettings;\n\n try {\n trackSettings = this.track.getSettings();\n } catch (e) {\n // XXX React-native-webrtc, for example, defines\n // MediaStreamTrack#getSettings() but the implementation throws\n // a \"Not implemented\" Error.\n }\n if (trackSettings && 'facingMode' in trackSettings) {\n return trackSettings.facingMode;\n }\n\n if (typeof this._facingMode !== 'undefined') {\n return this._facingMode;\n }\n\n // In most cases we are showing a webcam. So if we've gotten here,\n // it should be relatively safe to assume that we are probably\n // showing the user-facing camera.\n return CameraFacingMode.USER;\n }\n\n return undefined;\n }\n\n /**\n * Stops the associated MediaStream.\n */\n stopStream() {\n /**\n * Indicates that we are executing {@link #stopStream} i.e.\n * {@link RTCUtils#stopMediaStream} for the MediaStream\n * associated with this JitsiTrack instance.\n *\n * @private\n * @type {boolean}\n */\n this._stopStreamInProgress = true;\n\n try {\n RTCUtils.stopMediaStream(this.stream);\n } finally {\n this._stopStreamInProgress = false;\n }\n }\n\n /**\n * Switches the camera facing mode if the WebRTC implementation supports the\n * custom MediaStreamTrack._switchCamera method. Currently, the method in\n * question is implemented in react-native-webrtc only. When such a WebRTC\n * implementation is executing, the method is the preferred way to switch\n * between the front/user-facing and the back/environment-facing cameras\n * because it will likely be (as is the case of react-native-webrtc)\n * noticeably faster that creating a new MediaStreamTrack via a new\n * getUserMedia call with the switched facingMode constraint value.\n * Moreover, the approach with a new getUserMedia call may not even work:\n * WebRTC on Android and iOS is either very slow to open the camera a second\n * time or plainly freezes attempting to do that.\n */\n _switchCamera() {\n if (this.isVideoTrack()\n && this.videoType === VideoType.CAMERA\n && typeof this.track._switchCamera === 'function') {\n this.track._switchCamera();\n\n this._facingMode\n = this._facingMode === CameraFacingMode.ENVIRONMENT\n ? CameraFacingMode.USER\n : CameraFacingMode.ENVIRONMENT;\n }\n }\n\n /**\n * Checks whether the attached MediaStream is receiving data from source or\n * not. If the stream property is null(because of mute or another reason)\n * this method will return false.\n * NOTE: This method doesn't indicate problem with the streams directly.\n * For example in case of video mute the method will return false or if the\n * user has disposed the track.\n *\n * @returns {boolean} true if the stream is receiving data and false\n * this otherwise.\n */\n isReceivingData() {\n if (this.isVideoTrack()\n && (this.isMuted() || this._stopStreamInProgress || this.videoType === VideoType.DESKTOP)) {\n return true;\n }\n\n if (!this.stream) {\n return false;\n }\n\n // In older version of the spec there is no muted property and\n // readyState can have value muted. In the latest versions\n // readyState can have values \"live\" and \"ended\" and there is\n // muted boolean property. If the stream is muted that means that\n // we aren't receiving any data from the source. We want to notify\n // the users for error if the stream is muted or ended on it's\n // creation.\n\n // For video blur enabled use the original video stream\n const stream = this._effectEnabled ? this._originalStream : this.stream;\n\n return stream.getTracks().some(track =>\n (!('readyState' in track) || track.readyState === 'live')\n && (!('muted' in track) || track.muted !== true));\n }\n\n /**\n * Creates a text representation of this local track instance.\n *\n * @return {string}\n */\n toString() {\n return `LocalTrack[${this.rtcId},${this.getType()}]`;\n }\n}\n","import { $iq } from 'strophe.js';\n\nimport recordingXMLUtils from './recordingXMLUtils';\n\n/**\n * Represents a recording session.\n */\nexport default class JibriSession {\n /**\n * Initializes a new JibriSession instance.\n *\n * @constructor\n */\n constructor(options = {}) {\n this._connection = options.connection;\n this._mode = options.mode;\n\n this._setSessionID(options.sessionID);\n this.setStatus(options.status);\n }\n\n /**\n * Returns the error related to the session instance, if any.\n *\n * @returns {string|undefined}\n */\n getError() {\n return this._error;\n }\n\n /**\n * Returns the session ID of the session instance.\n *\n * @returns {string|undefined}\n */\n getID() {\n return this._sessionID;\n }\n\n /**\n * Returns the initiator of the session instance.\n *\n * @returns {JitsiParticipant|undefined} The participant that started the session.\n */\n getInitiator() {\n return this._initiator;\n }\n\n /**\n * Returns the streaming URL of the session.\n *\n * @returns {string|undefined}\n */\n getLiveStreamViewURL() {\n return this._liveStreamViewURL;\n }\n\n /**\n * Returns the current status of the session.\n *\n * @returns {string|undefined}\n */\n getStatus() {\n return this._status;\n }\n\n /**\n * Returns the jid of the participant that stopped the session.\n *\n * @returns {JitsiParticipant|undefined} The participant that stopped the session.\n */\n getTerminator() {\n return this._terminator;\n }\n\n /**\n * Returns the current recording mode of the session, such as \"file\".\n *\n * @returns {string}\n */\n getMode() {\n return this._mode;\n }\n\n /**\n * Sets the last known error message related to the session.\n *\n * @param {string} error - The error string explaining why the session\n * entered an error state.\n * @returns {void}\n */\n setError(error) {\n this._error = error;\n }\n\n /**\n * Sets the last live stream URL for the session instance. Usually this is\n * a YouTube URL and usually this is only set for \"stream\" sessions.\n *\n * @param {string} url - The live stream URL associated with the session.\n * @returns {void}\n */\n setLiveStreamViewURL(url) {\n this._liveStreamViewURL = url;\n }\n\n /**\n * Sets the last known status for this recording session.\n *\n * @param {string} status - The new status to set.\n * @returns {void}\n */\n setStatus(status) {\n this._status = status;\n }\n\n /**\n * Sets the creator's jid of the session.\n * @param {JitsiParticipant} participant - The creator of the session.\n */\n setInitiator(participant) {\n this._initiator = participant;\n }\n\n /**\n * Sets the jid of the participant that stopped the session.\n * @param {JitsiParticipant} participant - The participant's jid,\n * that stopped the session.\n */\n setTerminator(participant) {\n this._terminator = participant;\n }\n\n /**\n * Sends a message to start the actual recording.\n *\n * @param {Object} options - Additional arguments for starting the\n * recording.\n * @param {string} [options.appData] - Data specific to the app/service that\n * the result file will be uploaded.\n * @param {string} [options.broadcastId] - The broadcast ID of an\n * associated YouTube stream, used for knowing the URL from which the stream\n * can be viewed.\n * @param {string} options.focusMucJid - The JID of the focus participant\n * that controls recording.\n * @param {streamId} options.streamId - Necessary for live streaming, this\n * is the the stream key needed to start a live streaming session with the\n * streaming service provider.\n * @returns Promise\n */\n start({ appData, broadcastId, focusMucJid, streamId }) {\n return new Promise((resolve, reject) => {\n this._connection.sendIQ(\n this._createIQ({\n action: 'start',\n appData,\n focusMucJid,\n broadcastId,\n streamId\n }),\n result => {\n // All users will eventually receive the 'pending' status\n // from the backend, but for the user initiating the session\n // it's better to give some instant feedback that recording\n // is starting so fire 'pending' here manually.\n this.setStatus('pending');\n this._setSessionID(\n recordingXMLUtils.getSessionIdFromIq(result));\n\n resolve();\n },\n error => {\n this._setErrorFromIq(error);\n\n reject(error);\n });\n });\n }\n\n /**\n * Sends a message to actually stop the recording session.\n *\n * @param {Object} options - Additional arguments for stopping the\n * recording.\n * @param {Object} options.focusMucJid - The JID of the focus participant\n * that controls recording.\n * @returns Promise\n */\n stop({ focusMucJid }) {\n return new Promise((resolve, reject) => {\n this._connection.sendIQ(\n this._createIQ({\n action: 'stop',\n focusMucJid\n }),\n resolve,\n reject);\n });\n }\n\n /**\n * Generates the message to change the status of the recording session.\n *\n * @param {string} status - The new status to which the recording session\n * should transition.\n * @param {string} [options.appData] - Data specific to the app/service that\n * the result file will be uploaded.\n * @param {string} [options.broadcastId] - The broadcast ID of an\n * associated YouTube stream, used for knowing the URL from which the stream\n * can be viewed.\n * @param {string} options.focusMucJid - The JID of the focus participant\n * that controls recording.\n * @param {streamId} options.streamId - Necessary for live streaming, this\n * is the the stream key needed to start a live streaming session with the\n * streaming service provider.\n * @returns Object - The XMPP IQ message.\n */\n _createIQ({ action, appData, broadcastId, focusMucJid, streamId }) {\n return $iq({\n to: focusMucJid,\n type: 'set'\n })\n .c('jibri', {\n 'xmlns': 'http://jitsi.org/protocol/jibri',\n 'action': action,\n 'app_data': appData,\n 'recording_mode': this._mode,\n 'streamid': streamId,\n 'you_tube_broadcast_id': broadcastId\n })\n .up();\n }\n\n /**\n * Handles the error from an iq and stores the error.\n *\n * @param {Node} errorIq - The error response from an Iq.\n * @private\n * @returns {void}\n */\n _setErrorFromIq(errorIq) {\n const error = errorIq.getElementsByTagName('error')[0];\n\n this.setError(error.children[0].tagName);\n }\n\n /**\n * Sets the known session ID for this recording session.\n *\n * @param {string} sessionID\n * @private\n * @returns {void}\n */\n _setSessionID(sessionID) {\n this._sessionID = sessionID;\n }\n}\n","import EventEmitter from 'events';\n\nimport * as MediaType from './service/RTC/MediaType';\nimport browser from './modules/browser';\nimport RTC from './modules/RTC/RTC';\nimport RTCEvents from './service/RTC/RTCEvents';\nimport Statistics from './modules/statistics/statistics';\n\nimport * as JitsiMediaDevicesEvents from './JitsiMediaDevicesEvents';\n\nconst AUDIO_PERMISSION_NAME = 'microphone';\nconst PERMISSION_GRANTED_STATUS = 'granted';\nconst VIDEO_PERMISSION_NAME = 'camera';\n\n/**\n * Media devices utilities for Jitsi.\n */\nclass JitsiMediaDevices {\n /**\n * Initializes a {@code JitsiMediaDevices} object. There will be a single\n * instance of this class.\n */\n constructor() {\n this._eventEmitter = new EventEmitter();\n this._grantedPermissions = {};\n\n RTC.addListener(\n RTCEvents.DEVICE_LIST_CHANGED,\n devices =>\n this._eventEmitter.emit(\n JitsiMediaDevicesEvents.DEVICE_LIST_CHANGED,\n devices));\n RTC.addListener(\n RTCEvents.DEVICE_LIST_AVAILABLE,\n devices =>\n this._logOutputDevice(\n this.getAudioOutputDevice(),\n devices));\n RTC.addListener(\n RTCEvents.GRANTED_PERMISSIONS,\n grantedPermissions =>\n this._handleGrantedPermissions(grantedPermissions));\n\n // Test if the W3C Permissions API is implemented and the 'camera' and\n // 'microphone' permissions are implemented. (Testing for at least one\n // of them seems sufficient).\n this._permissionsApiSupported = new Promise(resolve => {\n if (!navigator.permissions) {\n resolve(false);\n\n return;\n }\n\n navigator.permissions.query({ name: VIDEO_PERMISSION_NAME })\n .then(() => resolve(true), () => resolve(false));\n });\n }\n\n /**\n * Updated the local granted permissions cache. A permissions might be\n * granted, denied, or undefined. This is represented by having its media\n * type key set to {@code true} or {@code false} respectively.\n *\n * @param {Object} grantedPermissions - Array with the permissions\n * which were granted.\n */\n _handleGrantedPermissions(grantedPermissions) {\n this._grantedPermissions = {\n ...this._grantedPermissions,\n ...grantedPermissions\n };\n }\n\n /**\n * Gathers data and sends it to statistics.\n * @param deviceID the device id to log\n * @param devices list of devices\n */\n _logOutputDevice(deviceID, devices) {\n const device\n = devices.find(\n d => d.kind === 'audiooutput' && d.deviceId === deviceID);\n\n if (device) {\n Statistics.sendActiveDeviceListEvent(\n RTC.getEventDataForActiveDevice(device));\n }\n }\n\n /**\n * Executes callback with list of media devices connected.\n * @param {function} callback\n */\n enumerateDevices(callback) {\n RTC.enumerateDevices(callback);\n }\n\n /**\n * Checks if its possible to enumerate available cameras/micropones.\n * @returns {Promise} a Promise which will be resolved only once\n * the WebRTC stack is ready, either with true if the device listing is\n * available available or with false otherwise.\n */\n isDeviceListAvailable() {\n return RTC.isDeviceListAvailable();\n }\n\n /**\n * Returns true if changing the input (camera / microphone) or output\n * (audio) device is supported and false if not.\n * @param {string} [deviceType] - type of device to change. Default is\n * undefined or 'input', 'output' - for audio output device change.\n * @returns {boolean} true if available, false otherwise.\n */\n isDeviceChangeAvailable(deviceType) {\n return RTC.isDeviceChangeAvailable(deviceType);\n }\n\n /**\n * Checks if the permission for the given device was granted.\n *\n * @param {'audio'|'video'} [type] - type of devices to check,\n * undefined stands for both 'audio' and 'video' together\n * @returns {Promise}\n */\n isDevicePermissionGranted(type) {\n return new Promise(resolve => {\n // Shortcut: first check if we already know the permission was\n // granted.\n if (type in this._grantedPermissions) {\n resolve(this._grantedPermissions[type]);\n\n return;\n }\n\n // Check using the Permissions API.\n this._permissionsApiSupported.then(supported => {\n if (!supported) {\n resolve(false);\n\n return;\n }\n\n const promises = [];\n\n switch (type) {\n case MediaType.VIDEO:\n promises.push(\n navigator.permissions.query({\n name: VIDEO_PERMISSION_NAME\n }));\n break;\n case MediaType.AUDIO:\n promises.push(\n navigator.permissions.query({\n name: AUDIO_PERMISSION_NAME\n }));\n break;\n default:\n promises.push(\n navigator.permissions.query({\n name: VIDEO_PERMISSION_NAME\n }));\n promises.push(\n navigator.permissions.query({\n name: AUDIO_PERMISSION_NAME\n }));\n }\n\n Promise.all(promises).then(\n results => resolve(results.every(permissionStatus => {\n // The status attribute is deprecated, and state\n // should be used instead, but check both for now\n // for backwards compatibility.\n const grantStatus = permissionStatus.state\n || permissionStatus.status;\n\n return grantStatus === PERMISSION_GRANTED_STATUS;\n })),\n () => resolve(false)\n );\n });\n });\n }\n\n /**\n * Returns true if it is possible to be simultaneously capturing audio\n * from more than one device.\n *\n * @returns {boolean}\n */\n isMultipleAudioInputSupported() {\n return !browser.isFirefox();\n }\n\n /**\n * Returns currently used audio output device id, 'default' stands\n * for default device\n * @returns {string}\n */\n getAudioOutputDevice() {\n return RTC.getAudioOutputDevice();\n }\n\n /**\n * Sets current audio output device.\n * @param {string} deviceId - id of 'audiooutput' device from\n * navigator.mediaDevices.enumerateDevices(), 'default' is for\n * default device\n * @returns {Promise} - resolves when audio output is changed, is rejected\n * otherwise\n */\n setAudioOutputDevice(deviceId) {\n const availableDevices = RTC.getCurrentlyAvailableMediaDevices();\n\n if (availableDevices && availableDevices.length > 0) {\n // if we have devices info report device to stats\n // normally this will not happen on startup as this method is called\n // too early. This will happen only on user selection of new device\n this._logOutputDevice(\n deviceId, RTC.getCurrentlyAvailableMediaDevices());\n }\n\n return RTC.setAudioOutputDevice(deviceId);\n }\n\n /**\n * Adds an event handler.\n * @param {string} event - event name\n * @param {function} handler - event handler\n */\n addEventListener(event, handler) {\n this._eventEmitter.addListener(event, handler);\n }\n\n /**\n * Removes event handler.\n * @param {string} event - event name\n * @param {function} handler - event handler\n */\n removeEventListener(event, handler) {\n this._eventEmitter.removeListener(event, handler);\n }\n\n /**\n * Emits an event.\n * @param {string} event - event name\n */\n emitEvent(event, ...args) {\n this._eventEmitter.emit(event, ...args);\n }\n\n /**\n * Returns whether or not the current browser can support capturing video,\n * be it camera or desktop, and displaying received video.\n *\n * @returns {boolean}\n */\n supportsVideo() {\n // Defer to the browser capabilities to allow exposure of the api to the\n // consumer but prevent other files from having to import\n // JitsiMediaDevices.\n return browser.supportsVideo();\n }\n}\n\nexport default new JitsiMediaDevices();\n","/* Copyright @ 2015-present 8x8, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/*jslint latedef:false*/\n\n/**\n * Ordered log levels.\n */\nvar levels = {\n \"trace\": 0,\n \"debug\": 1,\n \"info\": 2,\n \"log\": 3,\n \"warn\": 4,\n \"error\": 5\n};\n\n/**\n * The default transport - console\n * @type LoggerTransport\n */\nLogger.consoleTransport = console;\n\n/**\n * The array which stores currently registered global transports.\n * @type {[LoggerTransport]}\n */\nvar globalTransports = [ Logger.consoleTransport ];\n\n/**\n * Adds given {@link LoggerTransport} instance to the list of global\n * transports which means that it'll be used by all {@link Logger}s\n * @param {LoggerTransport} transport\n */\nLogger.addGlobalTransport = function(transport) {\n if (globalTransports.indexOf(transport) === -1) {\n globalTransports.push(transport);\n }\n};\n\n/**\n * Removes given {@link LoggerTransport} instance from the list of global\n * transports\n * @param {LoggerTransport} transport\n */\nLogger.removeGlobalTransport = function(transport) {\n var transportIdx = globalTransports.indexOf(transport);\n if (transportIdx !== -1) {\n globalTransports.splice(transportIdx, 1);\n }\n};\n\n/**\n * The global configuration options.\n */\nvar globalOptions = {};\n\n/**\n * Sets global options which will be used by all loggers. Changing these works\n * even after other loggers are created.\n */\nLogger.setGlobalOptions = function(options) {\n globalOptions = options || {};\n};\n\n/**\n * Parses Error's object stack trace and extracts information about the last\n * caller before the log method was called.\n * @returns JS object with info about the caller - method name, file location,\n * line and column.\n */\nfunction getCallerInfo() {\n var callerInfo = {\n methodName: \"\",\n fileLocation: \"\",\n line: null,\n column: null\n };\n //gets the part of the stack without the logger wrappers\n var error = new Error();\n var stack = error.stack? error.stack.split(\"\\n\") : [];\n if(!stack || stack.length < 1) {\n return callerInfo;\n }\n var m = null;\n if(stack[3]) {\n m = stack[3].match(/\\s*at\\s*(.+?)\\s*\\((\\S*)\\s*:(\\d*)\\s*:(\\d*)\\)/);\n }\n if(!m || m.length <= 4) {\n //Firefox && Safari\n if(stack[2].indexOf(\"log@\") === 0){\n //Safari\n callerInfo.methodName = stack[3].substr(0, stack[3].indexOf(\"@\"));\n } else {\n //Firefox\n callerInfo.methodName = stack[2].substr(0, stack[2].indexOf(\"@\"));\n }\n return callerInfo;\n }\n\n callerInfo.methodName = m[1];\n callerInfo.fileLocation = m[2];\n callerInfo.line = m[3];\n callerInfo.column = m[4];\n return callerInfo;\n}\n\n/**\n * Logs messages using the transports and level from the logger.\n * @param logger a logger instance.\n * @param level the log level of the message. See the levels variable.\n * @param arguments array with arguments that will be logged.\n */\nfunction log() {\n var logger = arguments[0], level = arguments[1],\n args = Array.prototype.slice.call(arguments, 2);\n if(levels[level] < logger.level) {\n return;\n }\n\n var callerInfo\n = !(logger.options.disableCallerInfo || globalOptions.disableCallerInfo) &&\n getCallerInfo();\n var transports = globalTransports.concat(logger.transports);\n for(var i = 0; i < transports.length; i++) {\n var t = transports[i];\n var l = t[level];\n if(l && typeof(l) === \"function\") {\n var logPrefixes = [];\n\n logPrefixes.push(new Date().toISOString());\n\n if (logger.id) {\n logPrefixes.push(\"[\" + logger.id + \"]\");\n }\n\n if (callerInfo && callerInfo.methodName.length > 1) {\n logPrefixes.push(\"<\" + callerInfo.methodName + \">: \");\n }\n\n var fullLogParts = logPrefixes.concat(args);\n\n l.bind(t).apply(t, fullLogParts);\n }\n }\n}\n\n/**\n *\n * Constructs new logger object.\n * @param level the logging level for the new logger\n * @param id optional identifier for the logger instance.\n * @param {LoggerTransport} transports optional list of handlers(objects) for\n * the logs. The handlers must support - log, warn, error, debug, info, trace.\n * @param options optional configuration file for how the logger should behave.\n * @param {boolean} options.disableCallerInfo Whether the call site of a logger\n * method invocation should be included in the log. Defaults to false, so the\n * call site will be included.\n */\nfunction Logger(level, id, transports, options) {\n this.id = id;\n this.options = options || {};\n this.transports = transports;\n if(!this.transports) {\n this.transports = [];\n }\n this.level = levels[level];\n var methods = Object.keys(levels);\n for(var i = 0; i < methods.length; i++){\n this[methods[i]] =\n log.bind(null, this, methods[i]);\n }\n}\n\n/**\n * Sets the log level for the logger.\n * @param level the new log level.\n */\nLogger.prototype.setLevel = function (level) {\n this.level = levels[level];\n};\nmodule.exports = Logger;\n\n/**\n * Enum for the supported log levels.\n */\nLogger.levels = {\n TRACE: \"trace\",\n DEBUG: \"debug\",\n INFO: \"info\",\n LOG: \"log\",\n WARN: \"warn\",\n ERROR: \"error\"\n};\n","module.exports = function(module) {\n\tif (!module.webpackPolyfill) {\n\t\tmodule.deprecate = function() {};\n\t\tmodule.paths = [];\n\t\t// module.parent = undefined by default\n\t\tif (!module.children) module.children = [];\n\t\tObject.defineProperty(module, \"loaded\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.l;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"id\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.i;\n\t\t\t}\n\t\t});\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n};\n","/* eslint-env node */\n'use strict';\n\n// SDP helpers.\nvar SDPUtils = {};\n\n// Generate an alphanumeric identifier for cname or mids.\n// TODO: use UUIDs instead? https://gist.github.com/jed/982883\nSDPUtils.generateIdentifier = function() {\n return Math.random().toString(36).substr(2, 10);\n};\n\n// The RTCP CNAME used by all peerconnections from the same JS.\nSDPUtils.localCName = SDPUtils.generateIdentifier();\n\n// Splits SDP into lines, dealing with both CRLF and LF.\nSDPUtils.splitLines = function(blob) {\n return blob.trim().split('\\n').map(function(line) {\n return line.trim();\n });\n};\n// Splits SDP into sessionpart and mediasections. Ensures CRLF.\nSDPUtils.splitSections = function(blob) {\n var parts = blob.split('\\nm=');\n return parts.map(function(part, index) {\n return (index > 0 ? 'm=' + part : part).trim() + '\\r\\n';\n });\n};\n\n// returns the session description.\nSDPUtils.getDescription = function(blob) {\n var sections = SDPUtils.splitSections(blob);\n return sections && sections[0];\n};\n\n// returns the individual media sections.\nSDPUtils.getMediaSections = function(blob) {\n var sections = SDPUtils.splitSections(blob);\n sections.shift();\n return sections;\n};\n\n// Returns lines that start with a certain prefix.\nSDPUtils.matchPrefix = function(blob, prefix) {\n return SDPUtils.splitLines(blob).filter(function(line) {\n return line.indexOf(prefix) === 0;\n });\n};\n\n// Parses an ICE candidate line. Sample input:\n// candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8\n// rport 55996\"\nSDPUtils.parseCandidate = function(line) {\n var parts;\n // Parse both variants.\n if (line.indexOf('a=candidate:') === 0) {\n parts = line.substring(12).split(' ');\n } else {\n parts = line.substring(10).split(' ');\n }\n\n var candidate = {\n foundation: parts[0],\n component: parseInt(parts[1], 10),\n protocol: parts[2].toLowerCase(),\n priority: parseInt(parts[3], 10),\n ip: parts[4],\n address: parts[4], // address is an alias for ip.\n port: parseInt(parts[5], 10),\n // skip parts[6] == 'typ'\n type: parts[7]\n };\n\n for (var i = 8; i < parts.length; i += 2) {\n switch (parts[i]) {\n case 'raddr':\n candidate.relatedAddress = parts[i + 1];\n break;\n case 'rport':\n candidate.relatedPort = parseInt(parts[i + 1], 10);\n break;\n case 'tcptype':\n candidate.tcpType = parts[i + 1];\n break;\n case 'ufrag':\n candidate.ufrag = parts[i + 1]; // for backward compability.\n candidate.usernameFragment = parts[i + 1];\n break;\n default: // extension handling, in particular ufrag\n candidate[parts[i]] = parts[i + 1];\n break;\n }\n }\n return candidate;\n};\n\n// Translates a candidate object into SDP candidate attribute.\nSDPUtils.writeCandidate = function(candidate) {\n var sdp = [];\n sdp.push(candidate.foundation);\n sdp.push(candidate.component);\n sdp.push(candidate.protocol.toUpperCase());\n sdp.push(candidate.priority);\n sdp.push(candidate.address || candidate.ip);\n sdp.push(candidate.port);\n\n var type = candidate.type;\n sdp.push('typ');\n sdp.push(type);\n if (type !== 'host' && candidate.relatedAddress &&\n candidate.relatedPort) {\n sdp.push('raddr');\n sdp.push(candidate.relatedAddress);\n sdp.push('rport');\n sdp.push(candidate.relatedPort);\n }\n if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') {\n sdp.push('tcptype');\n sdp.push(candidate.tcpType);\n }\n if (candidate.usernameFragment || candidate.ufrag) {\n sdp.push('ufrag');\n sdp.push(candidate.usernameFragment || candidate.ufrag);\n }\n return 'candidate:' + sdp.join(' ');\n};\n\n// Parses an ice-options line, returns an array of option tags.\n// a=ice-options:foo bar\nSDPUtils.parseIceOptions = function(line) {\n return line.substr(14).split(' ');\n};\n\n// Parses an rtpmap line, returns RTCRtpCoddecParameters. Sample input:\n// a=rtpmap:111 opus/48000/2\nSDPUtils.parseRtpMap = function(line) {\n var parts = line.substr(9).split(' ');\n var parsed = {\n payloadType: parseInt(parts.shift(), 10) // was: id\n };\n\n parts = parts[0].split('/');\n\n parsed.name = parts[0];\n parsed.clockRate = parseInt(parts[1], 10); // was: clockrate\n parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1;\n // legacy alias, got renamed back to channels in ORTC.\n parsed.numChannels = parsed.channels;\n return parsed;\n};\n\n// Generate an a=rtpmap line from RTCRtpCodecCapability or\n// RTCRtpCodecParameters.\nSDPUtils.writeRtpMap = function(codec) {\n var pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n var channels = codec.channels || codec.numChannels || 1;\n return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate +\n (channels !== 1 ? '/' + channels : '') + '\\r\\n';\n};\n\n// Parses an a=extmap line (headerextension from RFC 5285). Sample input:\n// a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\n// a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset\nSDPUtils.parseExtmap = function(line) {\n var parts = line.substr(9).split(' ');\n return {\n id: parseInt(parts[0], 10),\n direction: parts[0].indexOf('/') > 0 ? parts[0].split('/')[1] : 'sendrecv',\n uri: parts[1]\n };\n};\n\n// Generates a=extmap line from RTCRtpHeaderExtensionParameters or\n// RTCRtpHeaderExtension.\nSDPUtils.writeExtmap = function(headerExtension) {\n return 'a=extmap:' + (headerExtension.id || headerExtension.preferredId) +\n (headerExtension.direction && headerExtension.direction !== 'sendrecv'\n ? '/' + headerExtension.direction\n : '') +\n ' ' + headerExtension.uri + '\\r\\n';\n};\n\n// Parses an ftmp line, returns dictionary. Sample input:\n// a=fmtp:96 vbr=on;cng=on\n// Also deals with vbr=on; cng=on\nSDPUtils.parseFmtp = function(line) {\n var parsed = {};\n var kv;\n var parts = line.substr(line.indexOf(' ') + 1).split(';');\n for (var j = 0; j < parts.length; j++) {\n kv = parts[j].trim().split('=');\n parsed[kv[0].trim()] = kv[1];\n }\n return parsed;\n};\n\n// Generates an a=ftmp line from RTCRtpCodecCapability or RTCRtpCodecParameters.\nSDPUtils.writeFmtp = function(codec) {\n var line = '';\n var pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n if (codec.parameters && Object.keys(codec.parameters).length) {\n var params = [];\n Object.keys(codec.parameters).forEach(function(param) {\n if (codec.parameters[param]) {\n params.push(param + '=' + codec.parameters[param]);\n } else {\n params.push(param);\n }\n });\n line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\\r\\n';\n }\n return line;\n};\n\n// Parses an rtcp-fb line, returns RTCPRtcpFeedback object. Sample input:\n// a=rtcp-fb:98 nack rpsi\nSDPUtils.parseRtcpFb = function(line) {\n var parts = line.substr(line.indexOf(' ') + 1).split(' ');\n return {\n type: parts.shift(),\n parameter: parts.join(' ')\n };\n};\n// Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters.\nSDPUtils.writeRtcpFb = function(codec) {\n var lines = '';\n var pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n if (codec.rtcpFeedback && codec.rtcpFeedback.length) {\n // FIXME: special handling for trr-int?\n codec.rtcpFeedback.forEach(function(fb) {\n lines += 'a=rtcp-fb:' + pt + ' ' + fb.type +\n (fb.parameter && fb.parameter.length ? ' ' + fb.parameter : '') +\n '\\r\\n';\n });\n }\n return lines;\n};\n\n// Parses an RFC 5576 ssrc media attribute. Sample input:\n// a=ssrc:3735928559 cname:something\nSDPUtils.parseSsrcMedia = function(line) {\n var sp = line.indexOf(' ');\n var parts = {\n ssrc: parseInt(line.substr(7, sp - 7), 10)\n };\n var colon = line.indexOf(':', sp);\n if (colon > -1) {\n parts.attribute = line.substr(sp + 1, colon - sp - 1);\n parts.value = line.substr(colon + 1);\n } else {\n parts.attribute = line.substr(sp + 1);\n }\n return parts;\n};\n\nSDPUtils.parseSsrcGroup = function(line) {\n var parts = line.substr(13).split(' ');\n return {\n semantics: parts.shift(),\n ssrcs: parts.map(function(ssrc) {\n return parseInt(ssrc, 10);\n })\n };\n};\n\n// Extracts the MID (RFC 5888) from a media section.\n// returns the MID or undefined if no mid line was found.\nSDPUtils.getMid = function(mediaSection) {\n var mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0];\n if (mid) {\n return mid.substr(6);\n }\n};\n\nSDPUtils.parseFingerprint = function(line) {\n var parts = line.substr(14).split(' ');\n return {\n algorithm: parts[0].toLowerCase(), // algorithm is case-sensitive in Edge.\n value: parts[1]\n };\n};\n\n// Extracts DTLS parameters from SDP media section or sessionpart.\n// FIXME: for consistency with other functions this should only\n// get the fingerprint line as input. See also getIceParameters.\nSDPUtils.getDtlsParameters = function(mediaSection, sessionpart) {\n var lines = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=fingerprint:');\n // Note: a=setup line is ignored since we use the 'auto' role.\n // Note2: 'algorithm' is not case sensitive except in Edge.\n return {\n role: 'auto',\n fingerprints: lines.map(SDPUtils.parseFingerprint)\n };\n};\n\n// Serializes DTLS parameters to SDP.\nSDPUtils.writeDtlsParameters = function(params, setupType) {\n var sdp = 'a=setup:' + setupType + '\\r\\n';\n params.fingerprints.forEach(function(fp) {\n sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\\r\\n';\n });\n return sdp;\n};\n// Parses ICE information from SDP media section or sessionpart.\n// FIXME: for consistency with other functions this should only\n// get the ice-ufrag and ice-pwd lines as input.\nSDPUtils.getIceParameters = function(mediaSection, sessionpart) {\n var lines = SDPUtils.splitLines(mediaSection);\n // Search in session part, too.\n lines = lines.concat(SDPUtils.splitLines(sessionpart));\n var iceParameters = {\n usernameFragment: lines.filter(function(line) {\n return line.indexOf('a=ice-ufrag:') === 0;\n })[0].substr(12),\n password: lines.filter(function(line) {\n return line.indexOf('a=ice-pwd:') === 0;\n })[0].substr(10)\n };\n return iceParameters;\n};\n\n// Serializes ICE parameters to SDP.\nSDPUtils.writeIceParameters = function(params) {\n return 'a=ice-ufrag:' + params.usernameFragment + '\\r\\n' +\n 'a=ice-pwd:' + params.password + '\\r\\n';\n};\n\n// Parses the SDP media section and returns RTCRtpParameters.\nSDPUtils.parseRtpParameters = function(mediaSection) {\n var description = {\n codecs: [],\n headerExtensions: [],\n fecMechanisms: [],\n rtcp: []\n };\n var lines = SDPUtils.splitLines(mediaSection);\n var mline = lines[0].split(' ');\n for (var i = 3; i < mline.length; i++) { // find all codecs from mline[3..]\n var pt = mline[i];\n var rtpmapline = SDPUtils.matchPrefix(\n mediaSection, 'a=rtpmap:' + pt + ' ')[0];\n if (rtpmapline) {\n var codec = SDPUtils.parseRtpMap(rtpmapline);\n var fmtps = SDPUtils.matchPrefix(\n mediaSection, 'a=fmtp:' + pt + ' ');\n // Only the first a=fmtp: is considered.\n codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {};\n codec.rtcpFeedback = SDPUtils.matchPrefix(\n mediaSection, 'a=rtcp-fb:' + pt + ' ')\n .map(SDPUtils.parseRtcpFb);\n description.codecs.push(codec);\n // parse FEC mechanisms from rtpmap lines.\n switch (codec.name.toUpperCase()) {\n case 'RED':\n case 'ULPFEC':\n description.fecMechanisms.push(codec.name.toUpperCase());\n break;\n default: // only RED and ULPFEC are recognized as FEC mechanisms.\n break;\n }\n }\n }\n SDPUtils.matchPrefix(mediaSection, 'a=extmap:').forEach(function(line) {\n description.headerExtensions.push(SDPUtils.parseExtmap(line));\n });\n // FIXME: parse rtcp.\n return description;\n};\n\n// Generates parts of the SDP media section describing the capabilities /\n// parameters.\nSDPUtils.writeRtpDescription = function(kind, caps) {\n var sdp = '';\n\n // Build the mline.\n sdp += 'm=' + kind + ' ';\n sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs.\n sdp += ' UDP/TLS/RTP/SAVPF ';\n sdp += caps.codecs.map(function(codec) {\n if (codec.preferredPayloadType !== undefined) {\n return codec.preferredPayloadType;\n }\n return codec.payloadType;\n }).join(' ') + '\\r\\n';\n\n sdp += 'c=IN IP4 0.0.0.0\\r\\n';\n sdp += 'a=rtcp:9 IN IP4 0.0.0.0\\r\\n';\n\n // Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb.\n caps.codecs.forEach(function(codec) {\n sdp += SDPUtils.writeRtpMap(codec);\n sdp += SDPUtils.writeFmtp(codec);\n sdp += SDPUtils.writeRtcpFb(codec);\n });\n var maxptime = 0;\n caps.codecs.forEach(function(codec) {\n if (codec.maxptime > maxptime) {\n maxptime = codec.maxptime;\n }\n });\n if (maxptime > 0) {\n sdp += 'a=maxptime:' + maxptime + '\\r\\n';\n }\n sdp += 'a=rtcp-mux\\r\\n';\n\n if (caps.headerExtensions) {\n caps.headerExtensions.forEach(function(extension) {\n sdp += SDPUtils.writeExtmap(extension);\n });\n }\n // FIXME: write fecMechanisms.\n return sdp;\n};\n\n// Parses the SDP media section and returns an array of\n// RTCRtpEncodingParameters.\nSDPUtils.parseRtpEncodingParameters = function(mediaSection) {\n var encodingParameters = [];\n var description = SDPUtils.parseRtpParameters(mediaSection);\n var hasRed = description.fecMechanisms.indexOf('RED') !== -1;\n var hasUlpfec = description.fecMechanisms.indexOf('ULPFEC') !== -1;\n\n // filter a=ssrc:... cname:, ignore PlanB-msid\n var ssrcs = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(function(line) {\n return SDPUtils.parseSsrcMedia(line);\n })\n .filter(function(parts) {\n return parts.attribute === 'cname';\n });\n var primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc;\n var secondarySsrc;\n\n var flows = SDPUtils.matchPrefix(mediaSection, 'a=ssrc-group:FID')\n .map(function(line) {\n var parts = line.substr(17).split(' ');\n return parts.map(function(part) {\n return parseInt(part, 10);\n });\n });\n if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) {\n secondarySsrc = flows[0][1];\n }\n\n description.codecs.forEach(function(codec) {\n if (codec.name.toUpperCase() === 'RTX' && codec.parameters.apt) {\n var encParam = {\n ssrc: primarySsrc,\n codecPayloadType: parseInt(codec.parameters.apt, 10)\n };\n if (primarySsrc && secondarySsrc) {\n encParam.rtx = {ssrc: secondarySsrc};\n }\n encodingParameters.push(encParam);\n if (hasRed) {\n encParam = JSON.parse(JSON.stringify(encParam));\n encParam.fec = {\n ssrc: primarySsrc,\n mechanism: hasUlpfec ? 'red+ulpfec' : 'red'\n };\n encodingParameters.push(encParam);\n }\n }\n });\n if (encodingParameters.length === 0 && primarySsrc) {\n encodingParameters.push({\n ssrc: primarySsrc\n });\n }\n\n // we support both b=AS and b=TIAS but interpret AS as TIAS.\n var bandwidth = SDPUtils.matchPrefix(mediaSection, 'b=');\n if (bandwidth.length) {\n if (bandwidth[0].indexOf('b=TIAS:') === 0) {\n bandwidth = parseInt(bandwidth[0].substr(7), 10);\n } else if (bandwidth[0].indexOf('b=AS:') === 0) {\n // use formula from JSEP to convert b=AS to TIAS value.\n bandwidth = parseInt(bandwidth[0].substr(5), 10) * 1000 * 0.95\n - (50 * 40 * 8);\n } else {\n bandwidth = undefined;\n }\n encodingParameters.forEach(function(params) {\n params.maxBitrate = bandwidth;\n });\n }\n return encodingParameters;\n};\n\n// parses http://draft.ortc.org/#rtcrtcpparameters*\nSDPUtils.parseRtcpParameters = function(mediaSection) {\n var rtcpParameters = {};\n\n // Gets the first SSRC. Note tha with RTX there might be multiple\n // SSRCs.\n var remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(function(line) {\n return SDPUtils.parseSsrcMedia(line);\n })\n .filter(function(obj) {\n return obj.attribute === 'cname';\n })[0];\n if (remoteSsrc) {\n rtcpParameters.cname = remoteSsrc.value;\n rtcpParameters.ssrc = remoteSsrc.ssrc;\n }\n\n // Edge uses the compound attribute instead of reducedSize\n // compound is !reducedSize\n var rsize = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-rsize');\n rtcpParameters.reducedSize = rsize.length > 0;\n rtcpParameters.compound = rsize.length === 0;\n\n // parses the rtcp-mux attrіbute.\n // Note that Edge does not support unmuxed RTCP.\n var mux = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-mux');\n rtcpParameters.mux = mux.length > 0;\n\n return rtcpParameters;\n};\n\n// parses either a=msid: or a=ssrc:... msid lines and returns\n// the id of the MediaStream and MediaStreamTrack.\nSDPUtils.parseMsid = function(mediaSection) {\n var parts;\n var spec = SDPUtils.matchPrefix(mediaSection, 'a=msid:');\n if (spec.length === 1) {\n parts = spec[0].substr(7).split(' ');\n return {stream: parts[0], track: parts[1]};\n }\n var planB = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(function(line) {\n return SDPUtils.parseSsrcMedia(line);\n })\n .filter(function(msidParts) {\n return msidParts.attribute === 'msid';\n });\n if (planB.length > 0) {\n parts = planB[0].value.split(' ');\n return {stream: parts[0], track: parts[1]};\n }\n};\n\n// SCTP\n// parses draft-ietf-mmusic-sctp-sdp-26 first and falls back\n// to draft-ietf-mmusic-sctp-sdp-05\nSDPUtils.parseSctpDescription = function(mediaSection) {\n var mline = SDPUtils.parseMLine(mediaSection);\n var maxSizeLine = SDPUtils.matchPrefix(mediaSection, 'a=max-message-size:');\n var maxMessageSize;\n if (maxSizeLine.length > 0) {\n maxMessageSize = parseInt(maxSizeLine[0].substr(19), 10);\n }\n if (isNaN(maxMessageSize)) {\n maxMessageSize = 65536;\n }\n var sctpPort = SDPUtils.matchPrefix(mediaSection, 'a=sctp-port:');\n if (sctpPort.length > 0) {\n return {\n port: parseInt(sctpPort[0].substr(12), 10),\n protocol: mline.fmt,\n maxMessageSize: maxMessageSize\n };\n }\n var sctpMapLines = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:');\n if (sctpMapLines.length > 0) {\n var parts = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:')[0]\n .substr(10)\n .split(' ');\n return {\n port: parseInt(parts[0], 10),\n protocol: parts[1],\n maxMessageSize: maxMessageSize\n };\n }\n};\n\n// SCTP\n// outputs the draft-ietf-mmusic-sctp-sdp-26 version that all browsers\n// support by now receiving in this format, unless we originally parsed\n// as the draft-ietf-mmusic-sctp-sdp-05 format (indicated by the m-line\n// protocol of DTLS/SCTP -- without UDP/ or TCP/)\nSDPUtils.writeSctpDescription = function(media, sctp) {\n var output = [];\n if (media.protocol !== 'DTLS/SCTP') {\n output = [\n 'm=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.protocol + '\\r\\n',\n 'c=IN IP4 0.0.0.0\\r\\n',\n 'a=sctp-port:' + sctp.port + '\\r\\n'\n ];\n } else {\n output = [\n 'm=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.port + '\\r\\n',\n 'c=IN IP4 0.0.0.0\\r\\n',\n 'a=sctpmap:' + sctp.port + ' ' + sctp.protocol + ' 65535\\r\\n'\n ];\n }\n if (sctp.maxMessageSize !== undefined) {\n output.push('a=max-message-size:' + sctp.maxMessageSize + '\\r\\n');\n }\n return output.join('');\n};\n\n// Generate a session ID for SDP.\n// https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1\n// recommends using a cryptographically random +ve 64-bit value\n// but right now this should be acceptable and within the right range\nSDPUtils.generateSessionId = function() {\n return Math.random().toString().substr(2, 21);\n};\n\n// Write boilder plate for start of SDP\n// sessId argument is optional - if not supplied it will\n// be generated randomly\n// sessVersion is optional and defaults to 2\n// sessUser is optional and defaults to 'thisisadapterortc'\nSDPUtils.writeSessionBoilerplate = function(sessId, sessVer, sessUser) {\n var sessionId;\n var version = sessVer !== undefined ? sessVer : 2;\n if (sessId) {\n sessionId = sessId;\n } else {\n sessionId = SDPUtils.generateSessionId();\n }\n var user = sessUser || 'thisisadapterortc';\n // FIXME: sess-id should be an NTP timestamp.\n return 'v=0\\r\\n' +\n 'o=' + user + ' ' + sessionId + ' ' + version +\n ' IN IP4 127.0.0.1\\r\\n' +\n 's=-\\r\\n' +\n 't=0 0\\r\\n';\n};\n\nSDPUtils.writeMediaSection = function(transceiver, caps, type, stream) {\n var sdp = SDPUtils.writeRtpDescription(transceiver.kind, caps);\n\n // Map ICE parameters (ufrag, pwd) to SDP.\n sdp += SDPUtils.writeIceParameters(\n transceiver.iceGatherer.getLocalParameters());\n\n // Map DTLS parameters to SDP.\n sdp += SDPUtils.writeDtlsParameters(\n transceiver.dtlsTransport.getLocalParameters(),\n type === 'offer' ? 'actpass' : 'active');\n\n sdp += 'a=mid:' + transceiver.mid + '\\r\\n';\n\n if (transceiver.direction) {\n sdp += 'a=' + transceiver.direction + '\\r\\n';\n } else if (transceiver.rtpSender && transceiver.rtpReceiver) {\n sdp += 'a=sendrecv\\r\\n';\n } else if (transceiver.rtpSender) {\n sdp += 'a=sendonly\\r\\n';\n } else if (transceiver.rtpReceiver) {\n sdp += 'a=recvonly\\r\\n';\n } else {\n sdp += 'a=inactive\\r\\n';\n }\n\n if (transceiver.rtpSender) {\n // spec.\n var msid = 'msid:' + stream.id + ' ' +\n transceiver.rtpSender.track.id + '\\r\\n';\n sdp += 'a=' + msid;\n\n // for Chrome.\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc +\n ' ' + msid;\n if (transceiver.sendEncodingParameters[0].rtx) {\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc +\n ' ' + msid;\n sdp += 'a=ssrc-group:FID ' +\n transceiver.sendEncodingParameters[0].ssrc + ' ' +\n transceiver.sendEncodingParameters[0].rtx.ssrc +\n '\\r\\n';\n }\n }\n // FIXME: this should be written by writeRtpDescription.\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc +\n ' cname:' + SDPUtils.localCName + '\\r\\n';\n if (transceiver.rtpSender && transceiver.sendEncodingParameters[0].rtx) {\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc +\n ' cname:' + SDPUtils.localCName + '\\r\\n';\n }\n return sdp;\n};\n\n// Gets the direction from the mediaSection or the sessionpart.\nSDPUtils.getDirection = function(mediaSection, sessionpart) {\n // Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv.\n var lines = SDPUtils.splitLines(mediaSection);\n for (var i = 0; i < lines.length; i++) {\n switch (lines[i]) {\n case 'a=sendrecv':\n case 'a=sendonly':\n case 'a=recvonly':\n case 'a=inactive':\n return lines[i].substr(2);\n default:\n // FIXME: What should happen here?\n }\n }\n if (sessionpart) {\n return SDPUtils.getDirection(sessionpart);\n }\n return 'sendrecv';\n};\n\nSDPUtils.getKind = function(mediaSection) {\n var lines = SDPUtils.splitLines(mediaSection);\n var mline = lines[0].split(' ');\n return mline[0].substr(2);\n};\n\nSDPUtils.isRejected = function(mediaSection) {\n return mediaSection.split(' ', 2)[1] === '0';\n};\n\nSDPUtils.parseMLine = function(mediaSection) {\n var lines = SDPUtils.splitLines(mediaSection);\n var parts = lines[0].substr(2).split(' ');\n return {\n kind: parts[0],\n port: parseInt(parts[1], 10),\n protocol: parts[2],\n fmt: parts.slice(3).join(' ')\n };\n};\n\nSDPUtils.parseOLine = function(mediaSection) {\n var line = SDPUtils.matchPrefix(mediaSection, 'o=')[0];\n var parts = line.substr(2).split(' ');\n return {\n username: parts[0],\n sessionId: parts[1],\n sessionVersion: parseInt(parts[2], 10),\n netType: parts[3],\n addressType: parts[4],\n address: parts[5]\n };\n};\n\n// a very naive interpretation of a valid SDP.\nSDPUtils.isValidSDP = function(blob) {\n if (typeof blob !== 'string' || blob.length === 0) {\n return false;\n }\n var lines = SDPUtils.splitLines(blob);\n for (var i = 0; i < lines.length; i++) {\n if (lines[i].length < 2 || lines[i].charAt(1) !== '=') {\n return false;\n }\n // TODO: check the modifier a bit more.\n }\n return true;\n};\n\n// Expose public methods.\nif (typeof module === 'object') {\n module.exports = SDPUtils;\n}\n","var grammar = module.exports = {\n v: [{\n name: 'version',\n reg: /^(\\d*)$/\n }],\n o: [{ //o=- 20518 0 IN IP4 203.0.113.1\n // NB: sessionId will be a String in most cases because it is huge\n name: 'origin',\n reg: /^(\\S*) (\\d*) (\\d*) (\\S*) IP(\\d) (\\S*)/,\n names: ['username', 'sessionId', 'sessionVersion', 'netType', 'ipVer', 'address'],\n format: '%s %s %d %s IP%d %s'\n }],\n // default parsing of these only (though some of these feel outdated)\n s: [{ name: 'name' }],\n i: [{ name: 'description' }],\n u: [{ name: 'uri' }],\n e: [{ name: 'email' }],\n p: [{ name: 'phone' }],\n z: [{ name: 'timezones' }], // TODO: this one can actually be parsed properly..\n r: [{ name: 'repeats' }], // TODO: this one can also be parsed properly\n //k: [{}], // outdated thing ignored\n t: [{ //t=0 0\n name: 'timing',\n reg: /^(\\d*) (\\d*)/,\n names: ['start', 'stop'],\n format: '%d %d'\n }],\n c: [{ //c=IN IP4 10.47.197.26\n name: 'connection',\n reg: /^IN IP(\\d) (\\S*)/,\n names: ['version', 'ip'],\n format: 'IN IP%d %s'\n }],\n b: [{ //b=AS:4000\n push: 'bandwidth',\n reg: /^(TIAS|AS|CT|RR|RS):(\\d*)/,\n names: ['type', 'limit'],\n format: '%s:%s'\n }],\n m: [{ //m=video 51744 RTP/AVP 126 97 98 34 31\n // NB: special - pushes to session\n // TODO: rtp/fmtp should be filtered by the payloads found here?\n reg: /^(\\w*) (\\d*) ([\\w\\/]*)(?: (.*))?/,\n names: ['type', 'port', 'protocol', 'payloads'],\n format: '%s %d %s %s'\n }],\n a: [\n { //a=rtpmap:110 opus/48000/2\n push: 'rtp',\n reg: /^rtpmap:(\\d*) ([\\w\\-\\.]*)(?:\\s*\\/(\\d*)(?:\\s*\\/(\\S*))?)?/,\n names: ['payload', 'codec', 'rate', 'encoding'],\n format: function (o) {\n return (o.encoding) ?\n 'rtpmap:%d %s/%s/%s':\n o.rate ?\n 'rtpmap:%d %s/%s':\n 'rtpmap:%d %s';\n }\n },\n { //a=fmtp:108 profile-level-id=24;object=23;bitrate=64000\n //a=fmtp:111 minptime=10; useinbandfec=1\n push: 'fmtp',\n reg: /^fmtp:(\\d*) ([\\S| ]*)/,\n names: ['payload', 'config'],\n format: 'fmtp:%d %s'\n },\n { //a=control:streamid=0\n name: 'control',\n reg: /^control:(.*)/,\n format: 'control:%s'\n },\n { //a=rtcp:65179 IN IP4 193.84.77.194\n name: 'rtcp',\n reg: /^rtcp:(\\d*)(?: (\\S*) IP(\\d) (\\S*))?/,\n names: ['port', 'netType', 'ipVer', 'address'],\n format: function (o) {\n return (o.address != null) ?\n 'rtcp:%d %s IP%d %s':\n 'rtcp:%d';\n }\n },\n { //a=rtcp-fb:98 trr-int 100\n push: 'rtcpFbTrrInt',\n reg: /^rtcp-fb:(\\*|\\d*) trr-int (\\d*)/,\n names: ['payload', 'value'],\n format: 'rtcp-fb:%d trr-int %d'\n },\n { //a=rtcp-fb:98 nack rpsi\n push: 'rtcpFb',\n reg: /^rtcp-fb:(\\*|\\d*) ([\\w-_]*)(?: ([\\w-_]*))?/,\n names: ['payload', 'type', 'subtype'],\n format: function (o) {\n return (o.subtype != null) ?\n 'rtcp-fb:%s %s %s':\n 'rtcp-fb:%s %s';\n }\n },\n { //a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\n //a=extmap:1/recvonly URI-gps-string\n push: 'ext',\n reg: /^extmap:(\\d+)(?:\\/(\\w+))? (\\S*)(?: (\\S*))?/,\n names: ['value', 'direction', 'uri', 'config'],\n format: function (o) {\n return 'extmap:%d' + (o.direction ? '/%s' : '%v') + ' %s' + (o.config ? ' %s' : '');\n }\n },\n { //a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32\n push: 'crypto',\n reg: /^crypto:(\\d*) ([\\w_]*) (\\S*)(?: (\\S*))?/,\n names: ['id', 'suite', 'config', 'sessionConfig'],\n format: function (o) {\n return (o.sessionConfig != null) ?\n 'crypto:%d %s %s %s':\n 'crypto:%d %s %s';\n }\n },\n { //a=setup:actpass\n name: 'setup',\n reg: /^setup:(\\w*)/,\n format: 'setup:%s'\n },\n { //a=mid:1\n name: 'mid',\n reg: /^mid:([^\\s]*)/,\n format: 'mid:%s'\n },\n { //a=msid:0c8b064d-d807-43b4-b434-f92a889d8587 98178685-d409-46e0-8e16-7ef0db0db64a\n name: 'msid',\n reg: /^msid:(.*)/,\n format: 'msid:%s'\n },\n { //a=ptime:20\n name: 'ptime',\n reg: /^ptime:(\\d*)/,\n format: 'ptime:%d'\n },\n { //a=maxptime:60\n name: 'maxptime',\n reg: /^maxptime:(\\d*)/,\n format: 'maxptime:%d'\n },\n { //a=sendrecv\n name: 'direction',\n reg: /^(sendrecv|recvonly|sendonly|inactive)/\n },\n { //a=ice-lite\n name: 'icelite',\n reg: /^(ice-lite)/\n },\n { //a=ice-ufrag:F7gI\n name: 'iceUfrag',\n reg: /^ice-ufrag:(\\S*)/,\n format: 'ice-ufrag:%s'\n },\n { //a=ice-pwd:x9cml/YzichV2+XlhiMu8g\n name: 'icePwd',\n reg: /^ice-pwd:(\\S*)/,\n format: 'ice-pwd:%s'\n },\n { //a=fingerprint:SHA-1 00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33\n name: 'fingerprint',\n reg: /^fingerprint:(\\S*) (\\S*)/,\n names: ['type', 'hash'],\n format: 'fingerprint:%s %s'\n },\n { //a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host\n //a=candidate:1162875081 1 udp 2113937151 192.168.34.75 60017 typ host generation 0 network-id 3 network-cost 10\n //a=candidate:3289912957 2 udp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 generation 0 network-id 3 network-cost 10\n //a=candidate:229815620 1 tcp 1518280447 192.168.150.19 60017 typ host tcptype active generation 0 network-id 3 network-cost 10\n //a=candidate:3289912957 2 tcp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 tcptype passive generation 0 network-id 3 network-cost 10\n push:'candidates',\n reg: /^candidate:(\\S*) (\\d*) (\\S*) (\\d*) (\\S*) (\\d*) typ (\\S*)(?: raddr (\\S*) rport (\\d*))?(?: tcptype (\\S*))?(?: generation (\\d*))?(?: network-id (\\d*))?(?: network-cost (\\d*))?/,\n names: ['foundation', 'component', 'transport', 'priority', 'ip', 'port', 'type', 'raddr', 'rport', 'tcptype', 'generation', 'network-id', 'network-cost'],\n format: function (o) {\n var str = 'candidate:%s %d %s %d %s %d typ %s';\n\n str += (o.raddr != null) ? ' raddr %s rport %d' : '%v%v';\n\n // NB: candidate has three optional chunks, so %void middles one if it's missing\n str += (o.tcptype != null) ? ' tcptype %s' : '%v';\n\n if (o.generation != null) {\n str += ' generation %d';\n }\n\n str += (o['network-id'] != null) ? ' network-id %d' : '%v';\n str += (o['network-cost'] != null) ? ' network-cost %d' : '%v';\n return str;\n }\n },\n { //a=end-of-candidates (keep after the candidates line for readability)\n name: 'endOfCandidates',\n reg: /^(end-of-candidates)/\n },\n { //a=remote-candidates:1 203.0.113.1 54400 2 203.0.113.1 54401 ...\n name: 'remoteCandidates',\n reg: /^remote-candidates:(.*)/,\n format: 'remote-candidates:%s'\n },\n { //a=ice-options:google-ice\n name: 'iceOptions',\n reg: /^ice-options:(\\S*)/,\n format: 'ice-options:%s'\n },\n { //a=ssrc:2566107569 cname:t9YU8M1UxTF8Y1A1\n push: 'ssrcs',\n reg: /^ssrc:(\\d*) ([\\w_]*)(?::(.*))?/,\n names: ['id', 'attribute', 'value'],\n format: function (o) {\n var str = 'ssrc:%d';\n if (o.attribute != null) {\n str += ' %s';\n if (o.value != null) {\n str += ':%s';\n }\n }\n return str;\n }\n },\n { //a=ssrc-group:FEC 1 2\n //a=ssrc-group:FEC-FR 3004364195 1080772241\n push: 'ssrcGroups',\n // token-char = %x21 / %x23-27 / %x2A-2B / %x2D-2E / %x30-39 / %x41-5A / %x5E-7E\n reg: /^ssrc-group:([\\x21\\x23\\x24\\x25\\x26\\x27\\x2A\\x2B\\x2D\\x2E\\w]*) (.*)/,\n names: ['semantics', 'ssrcs'],\n format: 'ssrc-group:%s %s'\n },\n { //a=msid-semantic: WMS Jvlam5X3SX1OP6pn20zWogvaKJz5Hjf9OnlV\n name: 'msidSemantic',\n reg: /^msid-semantic:\\s?(\\w*) (\\S*)/,\n names: ['semantic', 'token'],\n format: 'msid-semantic: %s %s' // space after ':' is not accidental\n },\n { //a=group:BUNDLE audio video\n push: 'groups',\n reg: /^group:(\\w*) (.*)/,\n names: ['type', 'mids'],\n format: 'group:%s %s'\n },\n { //a=rtcp-mux\n name: 'rtcpMux',\n reg: /^(rtcp-mux)/\n },\n { //a=rtcp-rsize\n name: 'rtcpRsize',\n reg: /^(rtcp-rsize)/\n },\n { //a=sctpmap:5000 webrtc-datachannel 1024\n name: 'sctpmap',\n reg: /^sctpmap:([\\w_\\/]*) (\\S*)(?: (\\S*))?/,\n names: ['sctpmapNumber', 'app', 'maxMessageSize'],\n format: function (o) {\n return (o.maxMessageSize != null) ?\n 'sctpmap:%s %s %s' :\n 'sctpmap:%s %s';\n }\n },\n { //a=x-google-flag:conference\n name: 'xGoogleFlag',\n reg: /^x-google-flag:([^\\s]*)/,\n format: 'x-google-flag:%s'\n },\n { //a=rid:1 send max-width=1280;max-height=720;max-fps=30;depend=0\n push: 'rids',\n reg: /^rid:([\\d\\w]+) (\\w+)(?: ([\\S| ]*))?/,\n names: ['id', 'direction', 'params'],\n format: function (o) {\n return (o.params) ? 'rid:%s %s %s' : 'rid:%s %s';\n }\n },\n { //a=imageattr:97 send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320] recv [x=330,y=250]\n //a=imageattr:* send [x=800,y=640] recv *\n //a=imageattr:100 recv [x=320,y=240]\n push: 'imageattrs',\n reg: new RegExp(\n //a=imageattr:97\n '^imageattr:(\\\\d+|\\\\*)' +\n //send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320]\n '[\\\\s\\\\t]+(send|recv)[\\\\s\\\\t]+(\\\\*|\\\\[\\\\S+\\\\](?:[\\\\s\\\\t]+\\\\[\\\\S+\\\\])*)' +\n //recv [x=330,y=250]\n '(?:[\\\\s\\\\t]+(recv|send)[\\\\s\\\\t]+(\\\\*|\\\\[\\\\S+\\\\](?:[\\\\s\\\\t]+\\\\[\\\\S+\\\\])*))?'\n ),\n names: ['pt', 'dir1', 'attrs1', 'dir2', 'attrs2'],\n format: function (o) {\n return 'imageattr:%s %s %s' + (o.dir2 ? ' %s %s' : '');\n }\n },\n { //a=simulcast:send 1,2,3;~4,~5 recv 6;~7,~8\n //a=simulcast:recv 1;4,5 send 6;7\n name: 'simulcast',\n reg: new RegExp(\n //a=simulcast:\n '^simulcast:' +\n //send 1,2,3;~4,~5\n '(send|recv) ([a-zA-Z0-9\\\\-_~;,]+)' +\n //space + recv 6;~7,~8\n '(?:\\\\s?(send|recv) ([a-zA-Z0-9\\\\-_~;,]+))?' +\n //end\n '$'\n ),\n names: ['dir1', 'list1', 'dir2', 'list2'],\n format: function (o) {\n return 'simulcast:%s %s' + (o.dir2 ? ' %s %s' : '');\n }\n },\n { //Old simulcast draft 03 (implemented by Firefox)\n // https://tools.ietf.org/html/draft-ietf-mmusic-sdp-simulcast-03\n //a=simulcast: recv pt=97;98 send pt=97\n //a=simulcast: send rid=5;6;7 paused=6,7\n name: 'simulcast_03',\n reg: /^simulcast:[\\s\\t]+([\\S+\\s\\t]+)$/,\n names: ['value'],\n format: 'simulcast: %s'\n },\n {\n //a=framerate:25\n //a=framerate:29.97\n name: 'framerate',\n reg: /^framerate:(\\d+(?:$|\\.\\d+))/,\n format: 'framerate:%s'\n },\n { // any a= that we don't understand is kepts verbatim on media.invalid\n push: 'invalid',\n names: ['value']\n }\n ]\n};\n\n// set sensible defaults to avoid polluting the grammar with boring details\nObject.keys(grammar).forEach(function (key) {\n var objs = grammar[key];\n objs.forEach(function (obj) {\n if (!obj.reg) {\n obj.reg = /(.*)/;\n }\n if (!obj.format) {\n obj.format = '%s';\n }\n });\n});\n","/* global MediaRecorder, MediaStream */\n\nconst RecordingResult = require('./recordingResult');\n\n/**\n * Possible audio formats MIME types\n */\nconst AUDIO_WEBM = 'audio/webm'; // Supported in chrome\nconst AUDIO_OGG = 'audio/ogg'; // Supported in firefox\n\n/**\n * A TrackRecorder object holds all the information needed for recording a\n * single JitsiTrack (either remote or local)\n * @param track The JitsiTrack the object is going to hold\n */\nconst TrackRecorder = function(track) {\n // The JitsiTrack holding the stream\n this.track = track;\n\n // The MediaRecorder recording the stream\n this.recorder = null;\n\n // The array of data chunks recorded from the stream\n // acts as a buffer until the data is stored on disk\n this.data = null;\n\n // the name of the person of the JitsiTrack. This can be undefined and/or\n // not unique\n this.name = null;\n\n // the time of the start of the recording\n this.startTime = null;\n};\n\n/**\n * Starts the recording of a JitsiTrack in a TrackRecorder object.\n * This will also define the timestamp and try to update the name\n * @param trackRecorder the TrackRecorder to start\n */\nfunction startRecorder(trackRecorder) {\n if (trackRecorder.recorder === undefined) {\n throw new Error('Passed an object to startRecorder which is not a '\n + 'TrackRecorder object');\n }\n trackRecorder.recorder.start();\n trackRecorder.startTime = new Date();\n}\n\n/**\n * Stops the recording of a JitsiTrack in a TrackRecorder object.\n * This will also try to update the name\n * @param trackRecorder the TrackRecorder to stop\n */\nfunction stopRecorder(trackRecorder) {\n if (trackRecorder.recorder === undefined) {\n throw new Error('Passed an object to stopRecorder which is not a '\n + 'TrackRecorder object');\n }\n trackRecorder.recorder.stop();\n}\n\n/**\n * Determines which kind of audio recording the browser supports\n * chrome supports \"audio/webm\" and firefox supports \"audio/ogg\"\n */\nfunction determineCorrectFileType() {\n if (MediaRecorder.isTypeSupported(AUDIO_WEBM)) {\n return AUDIO_WEBM;\n } else if (MediaRecorder.isTypeSupported(AUDIO_OGG)) {\n return AUDIO_OGG;\n }\n throw new Error(\n 'unable to create a MediaRecorder with the right mimetype!');\n}\n\n/**\n * main exported object of the file, holding all\n * relevant functions and variables for the outside world\n * @param jitsiConference the jitsiConference which this object\n * is going to record\n */\nfunction AudioRecorder(jitsiConference) {\n // array of TrackRecorders, where each trackRecorder\n // holds the JitsiTrack, MediaRecorder and recorder data\n this.recorders = [];\n\n // get which file type is supported by the current browser\n this.fileType = determineCorrectFileType();\n\n // boolean flag for active recording\n this.isRecording = false;\n\n // the jitsiconference the object is recording\n this.jitsiConference = jitsiConference;\n}\n\n/**\n * Add the the exported module so that it can be accessed by other files\n */\nAudioRecorder.determineCorrectFileType = determineCorrectFileType;\n\n/**\n * Adds a new TrackRecorder object to the array.\n *\n * @param track the track potentially holding an audio stream\n */\nAudioRecorder.prototype.addTrack = function(track) {\n if (track.isAudioTrack()) {\n // create the track recorder\n const trackRecorder = this.instantiateTrackRecorder(track);\n\n // push it to the local array of all recorders\n\n this.recorders.push(trackRecorder);\n\n // update the name of the trackRecorders\n this.updateNames();\n\n // If we're already recording, immediately start recording this new\n // track.\n if (this.isRecording) {\n startRecorder(trackRecorder);\n }\n }\n};\n\n/**\n * Creates a TrackRecorder object. Also creates the MediaRecorder and\n * data array for the trackRecorder.\n * @param track the JitsiTrack holding the audio MediaStream(s)\n */\nAudioRecorder.prototype.instantiateTrackRecorder = function(track) {\n const trackRecorder = new TrackRecorder(track);\n\n // Create a new stream which only holds the audio track\n const originalStream = trackRecorder.track.getOriginalStream();\n const stream = createEmptyStream();\n\n originalStream.getAudioTracks().forEach(t => stream.addTrack(t));\n\n // Create the MediaRecorder\n trackRecorder.recorder = new MediaRecorder(stream,\n { mimeType: this.fileType });\n\n // array for holding the recorder data. Resets it when\n // audio already has been recorder once\n trackRecorder.data = [];\n\n // function handling a dataEvent, e.g the stream gets new data\n trackRecorder.recorder.ondataavailable = function(dataEvent) {\n if (dataEvent.data.size > 0) {\n trackRecorder.data.push(dataEvent.data);\n }\n };\n\n return trackRecorder;\n};\n\n/**\n * Notifies the module that a specific track has stopped, e.g participant left\n * the conference.\n * if the recording has not started yet, the TrackRecorder will be removed from\n * the array. If the recording has started, the recorder will stop recording\n * but not removed from the array so that the recorded stream can still be\n * accessed\n *\n * @param {JitsiTrack} track the JitsiTrack to remove from the recording session\n */\nAudioRecorder.prototype.removeTrack = function(track) {\n if (track.isVideoTrack()) {\n return;\n }\n\n const array = this.recorders;\n let i;\n\n for (i = 0; i < array.length; i++) {\n if (array[i].track.getParticipantId() === track.getParticipantId()) {\n const recorderToRemove = array[i];\n\n if (this.isRecording) {\n stopRecorder(recorderToRemove);\n } else {\n // remove the TrackRecorder from the array\n array.splice(i, 1);\n }\n }\n }\n\n // make sure the names are up to date\n this.updateNames();\n};\n\n/**\n * Tries to update the name value of all TrackRecorder in the array.\n * If it hasn't changed,it will keep the exiting name. If it changes to a\n * undefined value, the old value will also be kept.\n */\nAudioRecorder.prototype.updateNames = function() {\n const conference = this.jitsiConference;\n\n this.recorders.forEach(trackRecorder => {\n if (trackRecorder.track.isLocal()) {\n trackRecorder.name = 'the transcriber';\n } else {\n const id = trackRecorder.track.getParticipantId();\n const participant = conference.getParticipantById(id);\n const newName = participant.getDisplayName();\n\n if (newName !== 'undefined') {\n trackRecorder.name = newName;\n }\n }\n });\n};\n\n/**\n * Starts the audio recording of every local and remote track\n */\nAudioRecorder.prototype.start = function() {\n if (this.isRecording) {\n throw new Error('audiorecorder is already recording');\n }\n\n // set boolean isRecording flag to true so if new participants join the\n // conference, that track can instantly start recording as well\n this.isRecording = true;\n\n // start all the mediaRecorders\n this.recorders.forEach(trackRecorder => startRecorder(trackRecorder));\n\n // log that recording has started\n console.log(\n `Started the recording of the audio. There are currently ${\n this.recorders.length} recorders active.`);\n};\n\n/**\n * Stops the audio recording of every local and remote track\n */\nAudioRecorder.prototype.stop = function() {\n // set the boolean flag to false\n this.isRecording = false;\n\n // stop all recorders\n this.recorders.forEach(trackRecorder => stopRecorder(trackRecorder));\n console.log('stopped recording');\n};\n\n/**\n * link hacking to download all recorded audio streams\n */\nAudioRecorder.prototype.download = function() {\n this.recorders.forEach(trackRecorder => {\n const blob = new Blob(trackRecorder.data, { type: this.fileType });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n\n document.body.appendChild(a);\n a.style = 'display: none';\n a.href = url;\n a.download = `test.${this.fileType.split('/')[1]}`;\n a.click();\n window.URL.revokeObjectURL(url);\n });\n};\n\n/**\n * returns the audio files of all recorders as an array of objects,\n * which include the name of the owner of the track and the starting time stamp\n * @returns {Array} an array of RecordingResult objects\n */\nAudioRecorder.prototype.getRecordingResults = function() {\n if (this.isRecording) {\n throw new Error(\n 'cannot get blobs because the AudioRecorder is still recording!');\n }\n\n // make sure the names are up to date before sending them off\n this.updateNames();\n\n const array = [];\n\n this.recorders.forEach(\n recorder =>\n array.push(\n new RecordingResult(\n new Blob(recorder.data, { type: this.fileType }),\n recorder.name,\n recorder.startTime)));\n\n return array;\n};\n\n/**\n * Gets the mime type of the recorder audio\n * @returns {String} the mime type of the recorder audio\n */\nAudioRecorder.prototype.getFileType = function() {\n return this.fileType;\n};\n\n/**\n * Creates a empty MediaStream object which can be used\n * to add MediaStreamTracks to\n * @returns MediaStream\n */\nfunction createEmptyStream() {\n if (typeof MediaStream !== 'undefined') {\n return new MediaStream();\n }\n throw new Error('cannot create a clean mediaStream');\n}\n\n/**\n * export the main object AudioRecorder\n */\nmodule.exports = AudioRecorder;\n","const AuthUtil = {\n /**\n * Creates the URL pointing to JWT token authentication service. It is\n * formatted from the 'urlPattern' argument which can contain the following\n * constants:\n * '{room}' - name of the conference room passed as roomName\n * argument to this method.\n * '{roleUpgrade}' - will contain 'true' if the URL will be used for\n * the role upgrade scenario, where user connects from anonymous domain and\n * then gets upgraded to the moderator by logging-in from the popup window.\n *\n * @param urlPattern a URL pattern pointing to the login service\n * @param roomName the name of the conference room for which the user will\n * be authenticated\n * @param {bool} roleUpgrade true if the URL will be used for role\n * upgrade scenario, where the user logs-in from the popup window in order\n * to have the moderator rights granted\n *\n * @returns {string|null} the URL pointing to JWT login service or\n * null if 'urlPattern' is not a string and the URL can not be\n * constructed.\n */\n getTokenAuthUrl(urlPattern, roomName, roleUpgrade) {\n const url = urlPattern;\n\n if (typeof url !== 'string') {\n return null;\n }\n\n return url.replace('{room}', roomName)\n .replace('{roleUpgrade}', roleUpgrade === true);\n }\n};\n\nmodule.exports = AuthUtil;\n","import {\n CONNECTION_DISCONNECTED as ANALYTICS_CONNECTION_DISCONNECTED,\n createConnectionFailedEvent\n} from './service/statistics/AnalyticsEvents';\nimport JitsiConference from './JitsiConference';\nimport * as JitsiConnectionEvents from './JitsiConnectionEvents';\nimport Statistics from './modules/statistics/statistics';\nimport XMPP from './modules/xmpp/xmpp';\n\n/**\n * Creates a new connection object for the Jitsi Meet server side video\n * conferencing service. Provides access to the JitsiConference interface.\n * @param appID identification for the provider of Jitsi Meet video conferencing\n * services.\n * @param token the JWT token used to authenticate with the server(optional)\n * @param options Object with properties / settings related to connection with\n * the server.\n * @constructor\n */\nexport default function JitsiConnection(appID, token, options) {\n this.appID = appID;\n this.token = token;\n this.options = options;\n this.xmpp = new XMPP(options, token);\n\n /* eslint-disable max-params */\n this.addEventListener(JitsiConnectionEvents.CONNECTION_FAILED,\n (errType, msg, credentials, details) => {\n Statistics.sendAnalyticsAndLog(\n createConnectionFailedEvent(errType, msg, details));\n });\n /* eslint-enable max-params */\n\n this.addEventListener(JitsiConnectionEvents.CONNECTION_DISCONNECTED,\n msg => {\n // we can see disconnects from normal tab closing of the browser\n // and then there are no msgs, but we want to log only disconnects\n // when there is real error\n // XXX Do we need the difference in handling between the log and\n // analytics event here?\n if (msg) {\n Statistics.sendAnalytics(\n ANALYTICS_CONNECTION_DISCONNECTED,\n { message: msg });\n }\n Statistics.sendLog(\n JSON.stringify(\n {\n id: ANALYTICS_CONNECTION_DISCONNECTED,\n msg\n }));\n });\n}\n\n/**\n * Connect the client with the server.\n * @param options {object} connecting options\n * (for example authentications parameters).\n */\nJitsiConnection.prototype.connect = function(options = {}) {\n this.xmpp.connect(options.id, options.password);\n};\n\n/**\n * Attach to existing connection. Can be used for optimizations. For example:\n * if the connection is created on the server we can attach to it and start\n * using it.\n *\n * @param options {object} connecting options - rid, sid and jid.\n */\nJitsiConnection.prototype.attach = function(options) {\n this.xmpp.attach(options);\n};\n\n/**\n * Disconnect the client from the server.\n * @returns {Promise} - Resolves when the disconnect process is finished or rejects with an error.\n */\nJitsiConnection.prototype.disconnect = function(...args) {\n // XXX Forward any arguments passed to JitsiConnection.disconnect to\n // XMPP.disconnect. For example, the caller of JitsiConnection.disconnect\n // may optionally pass the event which triggered the disconnect in order to\n // provide the implementation with finer-grained context.\n return this.xmpp.disconnect(...args);\n};\n\n/**\n * Returns the jid of the participant associated with the XMPP connection.\n *\n * @returns {string} The jid of the participant.\n */\nJitsiConnection.prototype.getJid = function() {\n return this.xmpp.getJid();\n};\n\n/**\n * This method allows renewal of the tokens if they are expiring.\n * @param token the new token.\n */\nJitsiConnection.prototype.setToken = function(token) {\n this.token = token;\n};\n\n/**\n * Creates and joins new conference.\n * @param name the name of the conference; if null - a generated name will be\n * provided from the api\n * @param options Object with properties / settings related to the conference\n * that will be created.\n * @returns {JitsiConference} returns the new conference object.\n */\nJitsiConnection.prototype.initJitsiConference = function(name, options) {\n return new JitsiConference({\n name,\n config: options,\n connection: this\n });\n};\n\n/**\n * Subscribes the passed listener to the event.\n * @param event {JitsiConnectionEvents} the connection event.\n * @param listener {Function} the function that will receive the event\n */\nJitsiConnection.prototype.addEventListener = function(event, listener) {\n this.xmpp.addListener(event, listener);\n};\n\n/**\n * Unsubscribes the passed handler.\n * @param event {JitsiConnectionEvents} the connection event.\n * @param listener {Function} the function that will receive the event\n */\nJitsiConnection.prototype.removeEventListener = function(event, listener) {\n this.xmpp.removeListener(event, listener);\n};\n\n/**\n * Returns measured connectionTimes.\n */\nJitsiConnection.prototype.getConnectionTimes = function() {\n return this.xmpp.connectionTimes;\n};\n\n/**\n * Adds new feature to the list of supported features for the local\n * participant.\n * @param {String} feature the name of the feature.\n * @param {boolean} submit if true - the new list of features will be\n * immediately submitted to the others.\n */\nJitsiConnection.prototype.addFeature = function(feature, submit = false) {\n return this.xmpp.caps.addFeature(feature, submit);\n};\n\n/**\n * Removes a feature from the list of supported features for the local\n * participant\n * @param {String} feature the name of the feature.\n * @param {boolean} submit if true - the new list of features will be\n * immediately submitted to the others.\n */\nJitsiConnection.prototype.removeFeature = function(feature, submit = false) {\n return this.xmpp.caps.removeFeature(feature, submit);\n};\n","/* global __filename, $, Promise */\nimport { Strophe } from 'strophe.js';\n\nimport EventEmitter from 'events';\nimport { getLogger } from 'jitsi-meet-logger';\nimport isEqual from 'lodash.isequal';\n\nimport * as JitsiConferenceErrors from './JitsiConferenceErrors';\nimport JitsiConferenceEventManager from './JitsiConferenceEventManager';\nimport * as JitsiConferenceEvents from './JitsiConferenceEvents';\nimport JitsiParticipant from './JitsiParticipant';\nimport JitsiTrackError from './JitsiTrackError';\nimport * as JitsiTrackErrors from './JitsiTrackErrors';\nimport * as JitsiTrackEvents from './JitsiTrackEvents';\nimport authenticateAndUpgradeRole from './authenticateAndUpgradeRole';\nimport P2PDominantSpeakerDetection from './modules/P2PDominantSpeakerDetection';\nimport RTC from './modules/RTC/RTC';\nimport TalkMutedDetection from './modules/TalkMutedDetection';\nimport browser from './modules/browser';\nimport ConnectionQuality from './modules/connectivity/ConnectionQuality';\nimport IceFailedNotification\n from './modules/connectivity/IceFailedNotification';\nimport ParticipantConnectionStatusHandler\n from './modules/connectivity/ParticipantConnectionStatus';\nimport E2ePing from './modules/e2eping/e2eping';\nimport Jvb121EventGenerator from './modules/event/Jvb121EventGenerator';\nimport RecordingManager from './modules/recording/RecordingManager';\nimport RttMonitor from './modules/rttmonitor/rttmonitor';\nimport Settings from './modules/settings/Settings';\nimport AvgRTPStatsReporter from './modules/statistics/AvgRTPStatsReporter';\nimport AudioOutputProblemDetector from './modules/statistics/AudioOutputProblemDetector';\nimport SpeakerStatsCollector from './modules/statistics/SpeakerStatsCollector';\nimport Statistics from './modules/statistics/statistics';\nimport Transcriber from './modules/transcription/transcriber';\nimport GlobalOnErrorHandler from './modules/util/GlobalOnErrorHandler';\nimport RandomUtil from './modules/util/RandomUtil';\nimport ComponentsVersions from './modules/version/ComponentsVersions';\nimport VideoSIPGW from './modules/videosipgw/VideoSIPGW';\nimport * as VideoSIPGWConstants from './modules/videosipgw/VideoSIPGWConstants';\nimport { JITSI_MEET_MUC_TYPE } from './modules/xmpp/xmpp';\nimport * as MediaType from './service/RTC/MediaType';\nimport * as RTCEvents from './service/RTC/RTCEvents';\nimport VideoType from './service/RTC/VideoType';\nimport {\n ACTION_JINGLE_RESTART,\n ACTION_JINGLE_SI_RECEIVED,\n ACTION_JINGLE_SI_TIMEOUT,\n ACTION_JINGLE_TERMINATE,\n ACTION_P2P_DECLINED,\n ACTION_P2P_ESTABLISHED,\n ACTION_P2P_FAILED,\n ACTION_P2P_SWITCH_TO_JVB,\n ICE_ESTABLISHMENT_DURATION_DIFF,\n createJingleEvent,\n createP2PEvent\n} from './service/statistics/AnalyticsEvents';\nimport * as XMPPEvents from './service/xmpp/XMPPEvents';\n\nconst logger = getLogger(__filename);\n\n/**\n * How long since Jicofo is supposed to send a session-initiate, before\n * {@link ACTION_JINGLE_SI_TIMEOUT} analytics event is sent (in ms).\n * @type {number}\n */\nconst JINGLE_SI_TIMEOUT = 5000;\n\n/**\n * Creates a JitsiConference object with the given name and properties.\n * Note: this constructor is not a part of the public API (objects should be\n * created using JitsiConnection.createConference).\n * @param options.config properties / settings related to the conference that\n * will be created.\n * @param options.name the name of the conference\n * @param options.connection the JitsiConnection object for this\n * JitsiConference.\n * @param {number} [options.config.avgRtpStatsN=15] how many samples are to be\n * collected by {@link AvgRTPStatsReporter}, before arithmetic mean is\n * calculated and submitted to the analytics module.\n * @param {boolean} [options.config.p2p.enabled] when set to true\n * the peer to peer mode will be enabled. It means that when there are only 2\n * participants in the conference an attempt to make direct connection will be\n * made. If the connection succeeds the conference will stop sending data\n * through the JVB connection and will use the direct one instead.\n * @param {number} [options.config.p2p.backToP2PDelay=5] a delay given in\n * seconds, before the conference switches back to P2P, after the 3rd\n * participant has left the room.\n * @param {number} [options.config.channelLastN=-1] The requested amount of\n * videos are going to be delivered after the value is in effect. Set to -1 for\n * unlimited or all available videos.\n * @param {number} [options.config.forceJVB121Ratio]\n * \"Math.random() < forceJVB121Ratio\" will determine whether a 2 people\n * conference should be moved to the JVB instead of P2P. The decision is made on\n * the responder side, after ICE succeeds on the P2P connection.\n * @param {*} [options.config.openBridgeChannel] Which kind of communication to\n * open with the videobridge. Values can be \"datachannel\", \"websocket\", true\n * (treat it as \"datachannel\"), undefined (treat it as \"datachannel\") and false\n * (don't open any channel).\n * @constructor\n *\n * FIXME Make all methods which are called from lib-internal classes\n * to non-public (use _). To name a few:\n * {@link JitsiConference.onLocalRoleChanged}\n * {@link JitsiConference.onUserRoleChanged}\n * {@link JitsiConference.onMemberLeft}\n * and so on...\n */\nexport default function JitsiConference(options) {\n if (!options.name || options.name.toLowerCase() !== options.name) {\n const errmsg\n = 'Invalid conference name (no conference name passed or it '\n + 'contains invalid characters like capital letters)!';\n\n logger.error(errmsg);\n throw new Error(errmsg);\n }\n this.eventEmitter = new EventEmitter();\n this.options = options;\n this.eventManager = new JitsiConferenceEventManager(this);\n this.participants = {};\n this._init(options);\n this.componentsVersions = new ComponentsVersions(this);\n\n /**\n * Jingle session instance for the JVB connection.\n * @type {JingleSessionPC}\n */\n this.jvbJingleSession = null;\n this.lastDominantSpeaker = null;\n this.dtmfManager = null;\n this.somebodySupportsDTMF = false;\n this.authEnabled = false;\n this.startAudioMuted = false;\n this.startVideoMuted = false;\n this.startMutedPolicy = {\n audio: false,\n video: false\n };\n this.isMutedByFocus = false;\n\n // when muted by focus we receive the jid of the initiator of the mute\n this.mutedByFocusActor = null;\n\n // Flag indicates if the 'onCallEnded' method was ever called on this\n // instance. Used to log extra analytics event for debugging purpose.\n // We need to know if the potential issue happened before or after\n // the restart.\n this.wasStopped = false;\n\n // Conference properties, maintained by jicofo.\n this.properties = {};\n\n /**\n * The object which monitors local and remote connection statistics (e.g.\n * sending bitrate) and calculates a number which represents the connection\n * quality.\n */\n this.connectionQuality\n = new ConnectionQuality(this, this.eventEmitter, options);\n\n /**\n * Reports average RTP statistics to the analytics module.\n * @type {AvgRTPStatsReporter}\n */\n this.avgRtpStatsReporter\n = new AvgRTPStatsReporter(this, options.config.avgRtpStatsN || 15);\n\n /**\n * Detects issues with the audio of remote participants.\n * @type {AudioOutputProblemDetector}\n */\n this._audioOutputProblemDetector = new AudioOutputProblemDetector(this);\n\n /**\n * Indicates whether the connection is interrupted or not.\n */\n this.isJvbConnectionInterrupted = false;\n\n /**\n * The object which tracks active speaker times\n */\n this.speakerStatsCollector = new SpeakerStatsCollector(this);\n\n /* P2P related fields below: */\n\n /**\n * Stores reference to deferred start P2P task. It's created when 3rd\n * participant leaves the room in order to avoid ping pong effect (it\n * could be just a page reload).\n * @type {number|null}\n */\n this.deferredStartP2PTask = null;\n\n const delay\n = parseInt(options.config.p2p && options.config.p2p.backToP2PDelay, 10);\n\n /**\n * A delay given in seconds, before the conference switches back to P2P\n * after the 3rd participant has left.\n * @type {number}\n */\n this.backToP2PDelay = isNaN(delay) ? 5 : delay;\n logger.info(`backToP2PDelay: ${this.backToP2PDelay}`);\n\n /**\n * If set to true it means the P2P ICE is no longer connected.\n * When false it means that P2P ICE (media) connection is up\n * and running.\n * @type {boolean}\n */\n this.isP2PConnectionInterrupted = false;\n\n /**\n * Flag set to true when P2P session has been established\n * (ICE has been connected) and this conference is currently in the peer to\n * peer mode (P2P connection is the active one).\n * @type {boolean}\n */\n this.p2p = false;\n\n /**\n * A JingleSession for the direct peer to peer connection.\n * @type {JingleSessionPC}\n */\n this.p2pJingleSession = null;\n\n this.videoSIPGWHandler = new VideoSIPGW(this.room);\n this.recordingManager = new RecordingManager(this.room);\n}\n\n// FIXME convert JitsiConference to ES6 - ASAP !\nJitsiConference.prototype.constructor = JitsiConference;\n\n/**\n * Create a resource for the a jid. We use the room nickname (the resource part\n * of the occupant JID, see XEP-0045) as the endpoint ID in colibri. We require\n * endpoint IDs to be 8 hex digits because in some cases they get serialized\n * into a 32bit field.\n *\n * @param {string} jid - The id set onto the XMPP connection.\n * @param {boolean} isAuthenticatedUser - Whether or not the user has connected\n * to the XMPP service with a password.\n * @returns {string}\n * @static\n */\nJitsiConference.resourceCreator = function(jid, isAuthenticatedUser) {\n let mucNickname;\n\n if (isAuthenticatedUser) {\n // For authenticated users generate a random ID.\n mucNickname = RandomUtil.randomHexString(8).toLowerCase();\n } else {\n // We try to use the first part of the node (which for anonymous users\n // on prosody is a UUID) to match the previous behavior (and maybe make\n // debugging easier).\n mucNickname = Strophe.getNodeFromJid(jid).substr(0, 8)\n .toLowerCase();\n\n // But if this doesn't have the required format we just generate a new\n // random nickname.\n const re = /[0-9a-f]{8}/g;\n\n if (!re.test(mucNickname)) {\n mucNickname = RandomUtil.randomHexString(8).toLowerCase();\n }\n }\n\n return mucNickname;\n};\n\n/**\n * Initializes the conference object properties\n * @param options {object}\n * @param options.connection {JitsiConnection} overrides this.connection\n */\nJitsiConference.prototype._init = function(options = {}) {\n // Override connection and xmpp properties (Useful if the connection\n // reloaded)\n if (options.connection) {\n this.connection = options.connection;\n this.xmpp = this.connection.xmpp;\n\n // Setup XMPP events only if we have new connection object.\n this.eventManager.setupXMPPListeners();\n }\n\n const { config } = this.options;\n const statsCurrentId = config.statisticsId ? config.statisticsId : Settings.callStatsUserName;\n\n this.room = this.xmpp.createRoom(\n this.options.name, {\n ...config,\n statsId: statsCurrentId\n },\n JitsiConference.resourceCreator\n );\n\n // Connection interrupted/restored listeners\n this._onIceConnectionInterrupted\n = this._onIceConnectionInterrupted.bind(this);\n this.room.addListener(\n XMPPEvents.CONNECTION_INTERRUPTED, this._onIceConnectionInterrupted);\n\n this._onIceConnectionRestored = this._onIceConnectionRestored.bind(this);\n this.room.addListener(\n XMPPEvents.CONNECTION_RESTORED, this._onIceConnectionRestored);\n\n this._onIceConnectionEstablished\n = this._onIceConnectionEstablished.bind(this);\n this.room.addListener(\n XMPPEvents.CONNECTION_ESTABLISHED, this._onIceConnectionEstablished);\n\n this._updateProperties = this._updateProperties.bind(this);\n this.room.addListener(XMPPEvents.CONFERENCE_PROPERTIES_CHANGED,\n this._updateProperties);\n\n this.rttMonitor = new RttMonitor(config.rttMonitor || {});\n\n this.e2eping = new E2ePing(\n this,\n config,\n (message, to) => {\n try {\n this.sendMessage(\n message, to, true /* sendThroughVideobridge */);\n } catch (error) {\n logger.warn('Failed to send a ping request or response.');\n }\n });\n\n if (!this.rtc) {\n this.rtc = new RTC(this, options);\n this.eventManager.setupRTCListeners();\n }\n\n this.participantConnectionStatus\n = new ParticipantConnectionStatusHandler(\n this.rtc,\n this,\n {\n // Both these options are not public API, leaving it here only\n // as an entry point through config for tuning up purposes.\n // Default values should be adjusted as soon as optimal values\n // are discovered.\n rtcMuteTimeout: config._peerConnStatusRtcMuteTimeout,\n outOfLastNTimeout: config._peerConnStatusOutOfLastNTimeout\n });\n this.participantConnectionStatus.init();\n\n if (!this.statistics) {\n this.statistics = new Statistics(this.xmpp, {\n aliasName: statsCurrentId,\n userName: config.statisticsDisplayName ? config.statisticsDisplayName : this.myUserId(),\n callStatsConfIDNamespace: this.connection.options.hosts.domain,\n confID: config.confID || `${this.connection.options.hosts.domain}/${this.options.name}`,\n customScriptUrl: config.callStatsCustomScriptUrl,\n callStatsID: config.callStatsID,\n callStatsSecret: config.callStatsSecret,\n roomName: this.options.name,\n applicationName: config.applicationName,\n getWiFiStatsMethod: config.getWiFiStatsMethod\n });\n Statistics.analytics.addPermanentProperties({\n 'callstats_name': statsCurrentId\n });\n }\n\n this.eventManager.setupChatRoomListeners();\n\n // Always add listeners because on reload we are executing leave and the\n // listeners are removed from statistics module.\n this.eventManager.setupStatisticsListeners();\n\n if (config.enableTalkWhileMuted) {\n // eslint-disable-next-line no-new\n new TalkMutedDetection(\n this,\n () =>\n this.eventEmitter.emit(JitsiConferenceEvents.TALK_WHILE_MUTED));\n }\n\n if ('channelLastN' in config) {\n this.setLastN(config.channelLastN);\n }\n\n /**\n * Emits {@link JitsiConferenceEvents.JVB121_STATUS}.\n * @type {Jvb121EventGenerator}\n */\n this.jvb121Status = new Jvb121EventGenerator(this);\n\n // creates dominant speaker detection that works only in p2p mode\n this.p2pDominantSpeakerDetection = new P2PDominantSpeakerDetection(this);\n\n if (config && config.deploymentInfo && config.deploymentInfo.userRegion) {\n this.setLocalParticipantProperty(\n 'region', config.deploymentInfo.userRegion);\n }\n};\n\n/**\n * Joins the conference.\n * @param password {string} the password\n */\nJitsiConference.prototype.join = function(password) {\n if (this.room) {\n this.room.join(password).then(() => this._maybeSetSITimeout());\n }\n};\n\n/**\n * Authenticates and upgrades the role of the local participant/user.\n *\n * @returns {Object} A thenable which (1) settles when the process of\n * authenticating and upgrading the role of the local participant/user finishes\n * and (2) has a cancel method that allows the caller to interrupt the\n * process.\n */\nJitsiConference.prototype.authenticateAndUpgradeRole = function(options) {\n return authenticateAndUpgradeRole.call(this, {\n ...options,\n onCreateResource: JitsiConference.resourceCreator\n });\n};\n\n/**\n * Check if joined to the conference.\n */\nJitsiConference.prototype.isJoined = function() {\n return this.room && this.room.joined;\n};\n\n/**\n * Tells whether or not the P2P mode is enabled in the configuration.\n * @return {boolean}\n */\nJitsiConference.prototype.isP2PEnabled = function() {\n return Boolean(this.options.config.p2p && this.options.config.p2p.enabled)\n\n // FIXME: remove once we have a default config template. -saghul\n || typeof this.options.config.p2p === 'undefined';\n};\n\n/**\n * When in P2P test mode, the conference will not automatically switch to P2P\n * when there 2 participants.\n * @return {boolean}\n */\nJitsiConference.prototype.isP2PTestModeEnabled = function() {\n return Boolean(this.options.config.testing\n && this.options.config.testing.p2pTestMode);\n};\n\n/**\n * Leaves the conference.\n * @returns {Promise}\n */\nJitsiConference.prototype.leave = function() {\n if (this.participantConnectionStatus) {\n this.participantConnectionStatus.dispose();\n this.participantConnectionStatus = null;\n }\n if (this.avgRtpStatsReporter) {\n this.avgRtpStatsReporter.dispose();\n this.avgRtpStatsReporter = null;\n }\n\n if (this._audioOutputProblemDetector) {\n this._audioOutputProblemDetector.dispose();\n this._audioOutputProblemDetector = null;\n }\n\n if (this.rttMonitor) {\n this.rttMonitor.stop();\n this.rttMonitor = null;\n }\n\n if (this.e2eping) {\n this.e2eping.stop();\n this.e2eping = null;\n }\n\n this.getLocalTracks().forEach(track => this.onLocalTrackRemoved(track));\n\n this.rtc.closeBridgeChannel();\n if (this.statistics) {\n this.statistics.dispose();\n }\n\n this._delayedIceFailed && this._delayedIceFailed.cancel();\n\n // Close both JVb and P2P JingleSessions\n if (this.jvbJingleSession) {\n this.jvbJingleSession.close();\n this.jvbJingleSession = null;\n }\n if (this.p2pJingleSession) {\n this.p2pJingleSession.close();\n this.p2pJingleSession = null;\n }\n\n // leave the conference\n if (this.room) {\n const room = this.room;\n\n // Unregister connection state listeners\n room.removeListener(\n XMPPEvents.CONNECTION_INTERRUPTED,\n this._onIceConnectionInterrupted);\n room.removeListener(\n XMPPEvents.CONNECTION_RESTORED,\n this._onIceConnectionRestored);\n room.removeListener(\n XMPPEvents.CONNECTION_ESTABLISHED,\n this._onIceConnectionEstablished);\n\n room.removeListener(\n XMPPEvents.CONFERENCE_PROPERTIES_CHANGED,\n this._updateProperties);\n\n this.eventManager.removeXMPPListeners();\n\n this.room = null;\n\n return room.leave()\n .then(() => {\n if (this.rtc) {\n this.rtc.destroy();\n }\n })\n .catch(error => {\n // remove all participants because currently the conference\n // won't be usable anyway. This is done on success automatically\n // by the ChatRoom instance.\n this.getParticipants().forEach(\n participant => this.onMemberLeft(participant.getJid()));\n\n throw error;\n });\n }\n\n // If this.room == null we are calling second time leave().\n return Promise.reject(\n new Error('The conference is has been already left'));\n};\n\n/**\n * Returns name of this conference.\n */\nJitsiConference.prototype.getName = function() {\n return this.options.name;\n};\n\n/**\n * Returns the {@link JitsiConnection} used by this this conference.\n */\nJitsiConference.prototype.getConnection = function() {\n return this.connection;\n};\n\n/**\n * Check if authentication is enabled for this conference.\n */\nJitsiConference.prototype.isAuthEnabled = function() {\n return this.authEnabled;\n};\n\n/**\n * Check if user is logged in.\n */\nJitsiConference.prototype.isLoggedIn = function() {\n return Boolean(this.authIdentity);\n};\n\n/**\n * Get authorized login.\n */\nJitsiConference.prototype.getAuthLogin = function() {\n return this.authIdentity;\n};\n\n/**\n * Check if external authentication is enabled for this conference.\n */\nJitsiConference.prototype.isExternalAuthEnabled = function() {\n return this.room && this.room.moderator.isExternalAuthEnabled();\n};\n\n/**\n * Get url for external authentication.\n * @param {boolean} [urlForPopup] if true then return url for login popup,\n * else url of login page.\n * @returns {Promise}\n */\nJitsiConference.prototype.getExternalAuthUrl = function(urlForPopup) {\n return new Promise((resolve, reject) => {\n if (!this.isExternalAuthEnabled()) {\n reject();\n\n return;\n }\n if (urlForPopup) {\n this.room.moderator.getPopupLoginUrl(resolve, reject);\n } else {\n this.room.moderator.getLoginUrl(resolve, reject);\n }\n });\n};\n\n/**\n * Returns the local tracks of the given media type, or all local tracks if no\n * specific type is given.\n * @param {MediaType} [mediaType] Optional media type (audio or video).\n */\nJitsiConference.prototype.getLocalTracks = function(mediaType) {\n let tracks = [];\n\n if (this.rtc) {\n tracks = this.rtc.getLocalTracks(mediaType);\n }\n\n return tracks;\n};\n\n/**\n * Obtains local audio track.\n * @return {JitsiLocalTrack|null}\n */\nJitsiConference.prototype.getLocalAudioTrack = function() {\n return this.rtc ? this.rtc.getLocalAudioTrack() : null;\n};\n\n/**\n * Obtains local video track.\n * @return {JitsiLocalTrack|null}\n */\nJitsiConference.prototype.getLocalVideoTrack = function() {\n return this.rtc ? this.rtc.getLocalVideoTrack() : null;\n};\n\n/**\n * Attaches a handler for events(For example - \"participant joined\".) in the\n * conference. All possible event are defined in JitsiConferenceEvents.\n * @param eventId the event ID.\n * @param handler handler for the event.\n *\n * Note: consider adding eventing functionality by extending an EventEmitter\n * impl, instead of rolling ourselves\n */\nJitsiConference.prototype.on = function(eventId, handler) {\n if (this.eventEmitter) {\n this.eventEmitter.on(eventId, handler);\n }\n};\n\n/**\n * Removes event listener\n * @param eventId the event ID.\n * @param [handler] optional, the specific handler to unbind\n *\n * Note: consider adding eventing functionality by extending an EventEmitter\n * impl, instead of rolling ourselves\n */\nJitsiConference.prototype.off = function(eventId, handler) {\n if (this.eventEmitter) {\n this.eventEmitter.removeListener(eventId, handler);\n }\n};\n\n// Common aliases for event emitter\nJitsiConference.prototype.addEventListener = JitsiConference.prototype.on;\nJitsiConference.prototype.removeEventListener = JitsiConference.prototype.off;\n\n/**\n * Receives notifications from other participants about commands / custom events\n * (sent by sendCommand or sendCommandOnce methods).\n * @param command {String} the name of the command\n * @param handler {Function} handler for the command\n */\nJitsiConference.prototype.addCommandListener = function(command, handler) {\n if (this.room) {\n this.room.addPresenceListener(command, handler);\n }\n};\n\n/**\n * Removes command listener\n * @param command {String} the name of the command\n * @param handler {Function} handler to remove for the command\n */\nJitsiConference.prototype.removeCommandListener = function(command, handler) {\n if (this.room) {\n this.room.removePresenceListener(command, handler);\n }\n};\n\n/**\n * Sends text message to the other participants in the conference\n * @param message the text message.\n * @param elementName the element name to encapsulate the message.\n * @deprecated Use 'sendMessage' instead. TODO: this should be private.\n */\nJitsiConference.prototype.sendTextMessage = function(\n message, elementName = 'body') {\n if (this.room) {\n const displayName = (this.room.getFromPresence('nick') || {}).value;\n\n this.room.sendMessage(message, elementName, displayName);\n }\n};\n\n/**\n * Send private text message to another participant of the conference\n * @param id the id of the participant to send a private message.\n * @param message the text message.\n * @param elementName the element name to encapsulate the message.\n * @deprecated Use 'sendMessage' instead. TODO: this should be private.\n */\nJitsiConference.prototype.sendPrivateTextMessage = function(\n id, message, elementName = 'body') {\n if (this.room) {\n this.room.sendPrivateMessage(id, message, elementName);\n }\n};\n\n/**\n * Send presence command.\n * @param name {String} the name of the command.\n * @param values {Object} with keys and values that will be sent.\n **/\nJitsiConference.prototype.sendCommand = function(name, values) {\n if (this.room) {\n this.room.addToPresence(name, values);\n this.room.sendPresence();\n } else {\n logger.warn('Not sending a command, room not initialized.');\n }\n\n};\n\n/**\n * Send presence command one time.\n * @param name {String} the name of the command.\n * @param values {Object} with keys and values that will be sent.\n **/\nJitsiConference.prototype.sendCommandOnce = function(name, values) {\n this.sendCommand(name, values);\n this.removeCommand(name);\n};\n\n/**\n * Removes presence command.\n * @param name {String} the name of the command.\n **/\nJitsiConference.prototype.removeCommand = function(name) {\n if (this.room) {\n this.room.removeFromPresence(name);\n }\n};\n\n/**\n * Sets the display name for this conference.\n * @param name the display name to set\n */\nJitsiConference.prototype.setDisplayName = function(name) {\n if (this.room) {\n // remove previously set nickname\n this.room.removeFromPresence('nick');\n\n this.room.addToPresence('nick', {\n attributes: { xmlns: 'http://jabber.org/protocol/nick' },\n value: name\n });\n this.room.sendPresence();\n }\n};\n\n/**\n * Set new subject for this conference. (available only for moderator)\n * @param {string} subject new subject\n */\nJitsiConference.prototype.setSubject = function(subject) {\n if (this.room && this.isModerator()) {\n this.room.setSubject(subject);\n }\n};\n\n/**\n * Get a transcriber object for all current participants in this conference\n * @return {Transcriber} the transcriber object\n */\nJitsiConference.prototype.getTranscriber = function() {\n if (this.transcriber === undefined) {\n this.transcriber = new Transcriber();\n\n // add all existing local audio tracks to the transcriber\n const localAudioTracks = this.getLocalTracks(MediaType.AUDIO);\n\n for (const localAudio of localAudioTracks) {\n this.transcriber.addTrack(localAudio);\n }\n\n // and all remote audio tracks\n const remoteAudioTracks = this.rtc.getRemoteTracks(MediaType.AUDIO);\n\n for (const remoteTrack of remoteAudioTracks) {\n this.transcriber.addTrack(remoteTrack);\n }\n }\n\n return this.transcriber;\n};\n\n/**\n * Returns the transcription status.\n *\n * @returns {String} \"on\" or \"off\".\n */\nJitsiConference.prototype.getTranscriptionStatus = function() {\n return this.room.transcriptionStatus;\n};\n\n/**\n * Adds JitsiLocalTrack object to the conference.\n * @param track the JitsiLocalTrack object.\n * @returns {Promise}\n * @throws {Error} if the specified track is a video track and there is already\n * another video track in the conference.\n */\nJitsiConference.prototype.addTrack = function(track) {\n if (track.isVideoTrack()) {\n // Ensure there's exactly 1 local video track in the conference.\n const localVideoTrack = this.rtc.getLocalVideoTrack();\n\n if (localVideoTrack) {\n // Don't be excessively harsh and severe if the API client happens\n // to attempt to add the same local video track twice.\n if (track === localVideoTrack) {\n return Promise.resolve(track);\n }\n\n return Promise.reject(new Error(\n 'cannot add second video track to the conference'));\n\n }\n }\n\n return this.replaceTrack(null, track);\n};\n\n/**\n * Fires TRACK_AUDIO_LEVEL_CHANGED change conference event (for local tracks).\n * @param {number} audioLevel the audio level\n * @param {TraceablePeerConnection} [tpc]\n */\nJitsiConference.prototype._fireAudioLevelChangeEvent = function(\n audioLevel,\n tpc) {\n const activeTpc = this.getActivePeerConnection();\n\n // There will be no TraceablePeerConnection if audio levels do not come from\n // a peerconnection. LocalStatsCollector.js measures audio levels using Web\n // Audio Analyser API and emits local audio levels events through\n // JitsiTrack.setAudioLevel, but does not provide TPC instance which is\n // optional.\n if (!tpc || activeTpc === tpc) {\n this.eventEmitter.emit(\n JitsiConferenceEvents.TRACK_AUDIO_LEVEL_CHANGED,\n this.myUserId(), audioLevel);\n }\n};\n\n/**\n * Fires TRACK_MUTE_CHANGED change conference event.\n * @param track the JitsiTrack object related to the event.\n */\nJitsiConference.prototype._fireMuteChangeEvent = function(track) {\n // check if track was muted by focus and now is unmuted by user\n if (this.isMutedByFocus && track.isAudioTrack() && !track.isMuted()) {\n this.isMutedByFocus = false;\n\n // unmute local user on server\n this.room.muteParticipant(this.room.myroomjid, false);\n }\n\n let actorParticipant;\n\n if (this.mutedByFocusActor) {\n const actorId = Strophe.getResourceFromJid(this.mutedByFocusActor);\n\n actorParticipant = this.participants[actorId];\n }\n\n this.eventEmitter.emit(JitsiConferenceEvents.TRACK_MUTE_CHANGED, track, actorParticipant);\n};\n\n/**\n * Clear JitsiLocalTrack properties and listeners.\n * @param track the JitsiLocalTrack object.\n */\nJitsiConference.prototype.onLocalTrackRemoved = function(track) {\n track._setConference(null);\n this.rtc.removeLocalTrack(track);\n track.removeEventListener(JitsiTrackEvents.TRACK_MUTE_CHANGED,\n track.muteHandler);\n track.removeEventListener(JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,\n track.audioLevelHandler);\n\n // send event for stopping screen sharing\n // FIXME: we assume we have only one screen sharing track\n // if we change this we need to fix this check\n if (track.isVideoTrack() && track.videoType === VideoType.DESKTOP) {\n this.statistics.sendScreenSharingEvent(false);\n }\n\n this.eventEmitter.emit(JitsiConferenceEvents.TRACK_REMOVED, track);\n};\n\n/**\n * Removes JitsiLocalTrack from the conference and performs\n * a new offer/answer cycle.\n * @param {JitsiLocalTrack} track\n * @returns {Promise}\n */\nJitsiConference.prototype.removeTrack = function(track) {\n return this.replaceTrack(track, null);\n};\n\n/**\n * Replaces oldTrack with newTrack and performs a single offer/answer\n * cycle after both operations are done. Either oldTrack or newTrack\n * can be null; replacing a valid 'oldTrack' with a null 'newTrack'\n * effectively just removes 'oldTrack'\n * @param {JitsiLocalTrack} oldTrack the current stream in use to be replaced\n * @param {JitsiLocalTrack} newTrack the new stream to use\n * @returns {Promise} resolves when the replacement is finished\n */\nJitsiConference.prototype.replaceTrack = function(oldTrack, newTrack) {\n // First do the removal of the oldTrack at the JitsiConference level\n if (oldTrack) {\n if (oldTrack.disposed) {\n return Promise.reject(\n new JitsiTrackError(JitsiTrackErrors.TRACK_IS_DISPOSED));\n }\n }\n if (newTrack) {\n if (newTrack.disposed) {\n return Promise.reject(\n new JitsiTrackError(JitsiTrackErrors.TRACK_IS_DISPOSED));\n }\n }\n\n // Now replace the stream at the lower levels\n return this._doReplaceTrack(oldTrack, newTrack)\n .then(() => {\n if (oldTrack) {\n this.onLocalTrackRemoved(oldTrack);\n }\n if (newTrack) {\n // Now handle the addition of the newTrack at the\n // JitsiConference level\n this._setupNewTrack(newTrack);\n }\n\n return Promise.resolve();\n }, error => Promise.reject(new Error(error)));\n};\n\n/**\n * Replaces the tracks at the lower level by going through the Jingle session\n * and WebRTC peer connection. The method will resolve immediately if there is\n * currently no JingleSession started.\n * @param {JitsiLocalTrack|null} oldTrack the track to be removed during\n * the process or null if the method should act as \"add track\"\n * @param {JitsiLocalTrack|null} newTrack the new track to be added or\n * null if the method should act as \"remove track\"\n * @return {Promise} resolved when the process is done or rejected with a string\n * which describes the error.\n * @private\n */\nJitsiConference.prototype._doReplaceTrack = function(oldTrack, newTrack) {\n const replaceTrackPromises = [];\n\n if (this.jvbJingleSession) {\n replaceTrackPromises.push(\n this.jvbJingleSession.replaceTrack(oldTrack, newTrack));\n } else {\n logger.info('_doReplaceTrack - no JVB JingleSession');\n }\n\n if (this.p2pJingleSession) {\n replaceTrackPromises.push(\n this.p2pJingleSession.replaceTrack(oldTrack, newTrack));\n } else {\n logger.info('_doReplaceTrack - no P2P JingleSession');\n }\n\n return Promise.all(replaceTrackPromises);\n};\n\n/**\n * Operations related to creating a new track\n * @param {JitsiLocalTrack} newTrack the new track being created\n */\nJitsiConference.prototype._setupNewTrack = function(newTrack) {\n if (newTrack.isAudioTrack() || (newTrack.isVideoTrack()\n && newTrack.videoType !== VideoType.DESKTOP)) {\n // Report active device to statistics\n const devices = RTC.getCurrentlyAvailableMediaDevices();\n const device\n = devices.find(\n d =>\n d.kind === `${newTrack.getTrack().kind}input`\n && d.label === newTrack.getTrack().label);\n\n if (device) {\n Statistics.sendActiveDeviceListEvent(\n RTC.getEventDataForActiveDevice(device));\n }\n }\n if (newTrack.isVideoTrack()) {\n this.removeCommand('videoType');\n this.sendCommand('videoType', {\n value: newTrack.videoType,\n attributes: {\n xmlns: 'http://jitsi.org/jitmeet/video'\n }\n });\n }\n this.rtc.addLocalTrack(newTrack);\n\n // ensure that we're sharing proper \"is muted\" state\n if (newTrack.isAudioTrack()) {\n this.room.setAudioMute(newTrack.isMuted());\n } else {\n this.room.setVideoMute(newTrack.isMuted());\n }\n\n newTrack.muteHandler = this._fireMuteChangeEvent.bind(this, newTrack);\n newTrack.audioLevelHandler = this._fireAudioLevelChangeEvent.bind(this);\n newTrack.addEventListener(\n JitsiTrackEvents.TRACK_MUTE_CHANGED,\n newTrack.muteHandler);\n newTrack.addEventListener(\n JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,\n newTrack.audioLevelHandler);\n\n newTrack._setConference(this);\n\n this.eventEmitter.emit(JitsiConferenceEvents.TRACK_ADDED, newTrack);\n};\n\n/**\n * Method called by the {@link JitsiLocalTrack} (a video one) in order to add\n * back the underlying WebRTC MediaStream to the PeerConnection (which has\n * removed on video mute).\n * @param {JitsiLocalTrack} track the local track that will be added as part of\n * the unmute operation.\n * @return {Promise} resolved when the process is done or rejected with a string\n * which describes the error.\n */\nJitsiConference.prototype._addLocalTrackAsUnmute = function(track) {\n const addAsUnmutePromises = [];\n\n if (this.jvbJingleSession) {\n addAsUnmutePromises.push(this.jvbJingleSession.addTrackAsUnmute(track));\n } else {\n logger.info(\n 'Add local MediaStream as unmute -'\n + ' no JVB Jingle session started yet');\n }\n\n if (this.p2pJingleSession) {\n addAsUnmutePromises.push(this.p2pJingleSession.addTrackAsUnmute(track));\n } else {\n logger.info(\n 'Add local MediaStream as unmute -'\n + ' no P2P Jingle session started yet');\n }\n\n return Promise.all(addAsUnmutePromises);\n};\n\n/**\n * Method called by the {@link JitsiLocalTrack} (a video one) in order to remove\n * the underlying WebRTC MediaStream from the PeerConnection. The purpose of\n * that is to stop sending any data and turn off the HW camera device.\n * @param {JitsiLocalTrack} track the local track that will be removed.\n * @return {Promise}\n */\nJitsiConference.prototype._removeLocalTrackAsMute = function(track) {\n const removeAsMutePromises = [];\n\n if (this.jvbJingleSession) {\n removeAsMutePromises.push(\n this.jvbJingleSession.removeTrackAsMute(track));\n } else {\n logger.info(\n 'Remove local MediaStream - no JVB JingleSession started yet');\n }\n if (this.p2pJingleSession) {\n removeAsMutePromises.push(\n this.p2pJingleSession.removeTrackAsMute(track));\n } else {\n logger.info(\n 'Remove local MediaStream - no P2P JingleSession started yet');\n }\n\n return Promise.all(removeAsMutePromises);\n};\n\n/**\n * Get role of the local user.\n * @returns {string} user role: 'moderator' or 'none'\n */\nJitsiConference.prototype.getRole = function() {\n return this.room.role;\n};\n\n/**\n * Returns whether or not the current conference has been joined as a hidden\n * user.\n *\n * @returns {boolean|null} True if hidden, false otherwise. Will return null if\n * no connection is active.\n */\nJitsiConference.prototype.isHidden = function() {\n if (!this.connection) {\n return null;\n }\n\n return Strophe.getDomainFromJid(this.connection.getJid())\n === this.options.config.hiddenDomain;\n};\n\n/**\n * Check if local user is moderator.\n * @returns {boolean|null} true if local user is moderator, false otherwise. If\n * we're no longer in the conference room then null is returned.\n */\nJitsiConference.prototype.isModerator = function() {\n return this.room ? this.room.isModerator() : null;\n};\n\n/**\n * Set password for the room.\n * @param {string} password new password for the room.\n * @returns {Promise}\n */\nJitsiConference.prototype.lock = function(password) {\n if (!this.isModerator()) {\n return Promise.reject(new Error('You are not moderator.'));\n }\n\n return new Promise((resolve, reject) => {\n this.room.lockRoom(\n password || '',\n () => resolve(),\n err => reject(err),\n () => reject(JitsiConferenceErrors.PASSWORD_NOT_SUPPORTED));\n });\n};\n\n/**\n * Remove password from the room.\n * @returns {Promise}\n */\nJitsiConference.prototype.unlock = function() {\n return this.lock();\n};\n\n/**\n * Elects the participant with the given id to be the selected participant in\n * order to receive higher video quality (if simulcast is enabled).\n * Or cache it if channel is not created and send it once channel is available.\n * @param participantId the identifier of the participant\n * @throws NetworkError or InvalidStateError or Error if the operation fails.\n * @returns {void}\n */\nJitsiConference.prototype.selectParticipant = function(participantId) {\n this.selectParticipants([ participantId ]);\n};\n\n/*\n * Elects participants with given ids to be the selected participants in order\n * to receive higher video quality (if simulcast is enabled). The argument\n * should be an array of participant id strings or an empty array; an error will\n * be thrown if a non-array is passed in. The error is thrown as a layer of\n * protection against passing an invalid argument, as the error will happen in\n * the bridge and may not be visible in the client.\n *\n * @param {Array} participantIds - An array of identifiers for\n * participants.\n * @returns {void}\n */\nJitsiConference.prototype.selectParticipants = function(participantIds) {\n if (!Array.isArray(participantIds)) {\n throw new Error('Invalid argument; participantIds must be an array.');\n }\n\n this.rtc.selectEndpoints(participantIds);\n};\n\n/**\n * Elects the participant with the given id to be the pinned participant in\n * order to always receive video for this participant (even when last n is\n * enabled).\n * @param participantId the identifier of the participant\n * @throws NetworkError or InvalidStateError or Error if the operation fails.\n */\nJitsiConference.prototype.pinParticipant = function(participantId) {\n this.rtc.pinEndpoint(participantId);\n};\n\n/**\n * Obtains the current value for \"lastN\". See {@link setLastN} for more info.\n * @returns {number}\n */\nJitsiConference.prototype.getLastN = function() {\n return this.rtc.getLastN();\n};\n\n/**\n * Selects a new value for \"lastN\". The requested amount of videos are going\n * to be delivered after the value is in effect. Set to -1 for unlimited or\n * all available videos.\n * @param lastN the new number of videos the user would like to receive.\n * @throws Error or RangeError if the given value is not a number or is smaller\n * than -1.\n */\nJitsiConference.prototype.setLastN = function(lastN) {\n if (!Number.isInteger(lastN) && !Number.parseInt(lastN, 10)) {\n throw new Error(`Invalid value for lastN: ${lastN}`);\n }\n const n = Number(lastN);\n\n if (n < -1) {\n throw new RangeError('lastN cannot be smaller than -1');\n }\n this.rtc.setLastN(n);\n\n // If the P2P session is not fully established yet, we wait until it gets\n // established.\n if (this.p2pJingleSession) {\n const isVideoActive = n !== 0;\n\n this.p2pJingleSession\n .setMediaTransferActive(true, isVideoActive)\n .catch(error => {\n logger.error(\n `Failed to adjust video transfer status (${isVideoActive})`,\n error);\n });\n }\n};\n\n/**\n * Checks if the participant given by participantId is currently included in\n * the last N.\n * @param {string} participantId the identifier of the participant we would\n * like to check.\n * @return {boolean} true if the participant with id is in the last N set or\n * if there's no last N set, false otherwise.\n * @deprecated this method should never be used to figure out the UI, but\n * {@link ParticipantConnectionStatus} should be used instead.\n */\nJitsiConference.prototype.isInLastN = function(participantId) {\n return this.rtc.isInLastN(participantId);\n};\n\n/**\n * @return Array an array of all participants in this\n * conference.\n */\nJitsiConference.prototype.getParticipants = function() {\n return Object.keys(this.participants).map(function(key) {\n return this.participants[key];\n }, this);\n};\n\n/**\n * Returns the number of participants in the conference, including the local\n * participant.\n * @param countHidden {boolean} Whether or not to include hidden participants\n * in the count. Default: false.\n **/\nJitsiConference.prototype.getParticipantCount\n = function(countHidden = false) {\n\n let participants = this.getParticipants();\n\n if (!countHidden) {\n participants = participants.filter(p => !p.isHidden());\n }\n\n // Add one for the local participant.\n return participants.length + 1;\n };\n\n/**\n * @returns {JitsiParticipant} the participant in this conference with the\n * specified id (or undefined if there isn't one).\n * @param id the id of the participant.\n */\nJitsiConference.prototype.getParticipantById = function(id) {\n return this.participants[id];\n};\n\n/**\n * Kick participant from this conference.\n * @param {string} id id of the participant to kick\n */\nJitsiConference.prototype.kickParticipant = function(id) {\n const participant = this.getParticipantById(id);\n\n if (!participant) {\n return;\n }\n this.room.kick(participant.getJid());\n};\n\n/**\n * Maybe clears the timeout which emits {@link ACTION_JINGLE_SI_TIMEOUT}\n * analytics event.\n * @private\n */\nJitsiConference.prototype._maybeClearSITimeout = function() {\n if (this._sessionInitiateTimeout\n && (this.jvbJingleSession || this.getParticipantCount() < 2)) {\n window.clearTimeout(this._sessionInitiateTimeout);\n this._sessionInitiateTimeout = null;\n }\n};\n\n/**\n * Sets a timeout which will emit {@link ACTION_JINGLE_SI_TIMEOUT} analytics\n * event.\n * @private\n */\nJitsiConference.prototype._maybeSetSITimeout = function() {\n // Jicofo is supposed to invite if there are at least 2 participants\n if (!this.jvbJingleSession\n && this.getParticipantCount() >= 2\n && !this._sessionInitiateTimeout) {\n this._sessionInitiateTimeout = window.setTimeout(() => {\n this._sessionInitiateTimeout = null;\n Statistics.sendAnalytics(createJingleEvent(\n ACTION_JINGLE_SI_TIMEOUT,\n {\n p2p: false,\n value: JINGLE_SI_TIMEOUT\n }));\n }, JINGLE_SI_TIMEOUT);\n }\n};\n\n/**\n * Mutes a participant.\n * @param {string} id The id of the participant to mute.\n */\nJitsiConference.prototype.muteParticipant = function(id) {\n const participant = this.getParticipantById(id);\n\n if (!participant) {\n return;\n }\n this.room.muteParticipant(participant.getJid(), true);\n};\n\n/* eslint-disable max-params */\n\n/**\n * Notifies this JitsiConference that a new member has joined its chat room.\n *\n * FIXME This should NOT be exposed!\n *\n * @param jid the jid of the participant in the MUC\n * @param nick the display name of the participant\n * @param role the role of the participant in the MUC\n * @param isHidden indicates if this is a hidden participant (system\n * participant for example a recorder).\n * @param statsID the participant statsID (optional)\n * @param status the initial status if any\n * @param identity the member identity, if any\n * @param botType the member botType, if any\n */\nJitsiConference.prototype.onMemberJoined = function(\n jid, nick, role, isHidden, statsID, status, identity, botType) {\n const id = Strophe.getResourceFromJid(jid);\n\n if (id === 'focus' || this.myUserId() === id) {\n return;\n }\n\n const participant\n = new JitsiParticipant(jid, this, nick, isHidden, statsID, status, identity);\n\n participant._role = role;\n participant._botType = botType;\n this.participants[id] = participant;\n this.eventEmitter.emit(\n JitsiConferenceEvents.USER_JOINED,\n id,\n participant);\n\n this._updateFeatures(participant);\n\n this._maybeStartOrStopP2P();\n this._maybeSetSITimeout();\n};\n\n/* eslint-enable max-params */\n\n/**\n * Updates features for a participant.\n * @param {JitsiParticipant} participant - The participant to query for features.\n * @returns {void}\n * @private\n */\nJitsiConference.prototype._updateFeatures = function(participant) {\n participant.getFeatures()\n .then(features => {\n participant._supportsDTMF = features.has('urn:xmpp:jingle:dtmf:0');\n this.updateDTMFSupport();\n\n if (features.has('http://jitsi.org/protocol/jigasi')) {\n participant.setProperty('features_jigasi', true);\n }\n })\n .catch(() => false);\n};\n\n/**\n * Get notified when member bot type had changed.\n * @param jid the member jid\n * @param botType the new botType value\n * @private\n */\nJitsiConference.prototype._onMemberBotTypeChanged = function(jid, botType) {\n\n // find the participant and mark it as non bot, as the real one will join\n // in a moment\n const peers = this.getParticipants();\n const botParticipant = peers.find(p => p.getJid() === jid);\n\n if (botParticipant) {\n botParticipant._botType = botType;\n const id = Strophe.getResourceFromJid(jid);\n\n this.eventEmitter.emit(\n JitsiConferenceEvents.BOT_TYPE_CHANGED,\n id,\n botType);\n }\n\n // if botType changed to undefined, botType was removed, in case of\n // poltergeist mode this is the moment when the poltergeist had exited and\n // the real participant had already replaced it.\n // In this case we can check and try p2p\n if (!botParticipant._botType) {\n this._maybeStartOrStopP2P();\n }\n};\n\nJitsiConference.prototype.onMemberLeft = function(jid) {\n const id = Strophe.getResourceFromJid(jid);\n\n if (id === 'focus' || this.myUserId() === id) {\n return;\n }\n\n const participant = this.participants[id];\n\n delete this.participants[id];\n\n const removedTracks = this.rtc.removeRemoteTracks(id);\n\n removedTracks.forEach(\n track =>\n this.eventEmitter.emit(JitsiConferenceEvents.TRACK_REMOVED, track));\n\n // there can be no participant in case the member that left is focus\n if (participant) {\n this.eventEmitter.emit(\n JitsiConferenceEvents.USER_LEFT, id, participant);\n }\n\n this._maybeStartOrStopP2P(true /* triggered by user left event */);\n this._maybeClearSITimeout();\n};\n\n/**\n * Designates an event indicating that we were kicked from the XMPP MUC.\n * @param {boolean} isSelfPresence - whether it is for local participant\n * or another participant.\n * @param {string} actorId - the id of the participant who was initiator\n * of the kick.\n * @param {string?} kickedParticipantId - when it is not a kick for local participant,\n * this is the id of the participant which was kicked.\n */\nJitsiConference.prototype.onMemberKicked = function(isSelfPresence, actorId, kickedParticipantId) {\n const actorParticipant = this.participants[actorId];\n\n if (isSelfPresence) {\n this.eventEmitter.emit(\n JitsiConferenceEvents.KICKED, actorParticipant);\n\n this.leave();\n\n return;\n }\n\n const kickedParticipant = this.participants[kickedParticipantId];\n\n this.eventEmitter.emit(\n JitsiConferenceEvents.PARTICIPANT_KICKED, actorParticipant, kickedParticipant);\n};\n\n/**\n * Method called on local MUC role change.\n * @param {string} role the name of new user's role as defined by XMPP MUC.\n */\nJitsiConference.prototype.onLocalRoleChanged = function(role) {\n // Emit role changed for local JID\n this.eventEmitter.emit(\n JitsiConferenceEvents.USER_ROLE_CHANGED, this.myUserId(), role);\n};\n\nJitsiConference.prototype.onUserRoleChanged = function(jid, role) {\n const id = Strophe.getResourceFromJid(jid);\n const participant = this.getParticipantById(id);\n\n if (!participant) {\n return;\n }\n participant._role = role;\n this.eventEmitter.emit(JitsiConferenceEvents.USER_ROLE_CHANGED, id, role);\n};\n\nJitsiConference.prototype.onDisplayNameChanged = function(jid, displayName) {\n const id = Strophe.getResourceFromJid(jid);\n const participant = this.getParticipantById(id);\n\n if (!participant) {\n return;\n }\n\n if (participant._displayName === displayName) {\n return;\n }\n\n participant._displayName = displayName;\n this.eventEmitter.emit(\n JitsiConferenceEvents.DISPLAY_NAME_CHANGED,\n id,\n displayName);\n};\n\n/**\n * Notifies this JitsiConference that a JitsiRemoteTrack was added into\n * the conference.\n *\n * @param {JitsiRemoteTrack} track the JitsiRemoteTrack which was added to this\n * JitsiConference\n */\nJitsiConference.prototype.onRemoteTrackAdded = function(track) {\n if (track.isP2P && !this.isP2PActive()) {\n logger.info(\n 'Trying to add remote P2P track, when not in P2P - IGNORED');\n\n return;\n } else if (!track.isP2P && this.isP2PActive()) {\n logger.info(\n 'Trying to add remote JVB track, when in P2P - IGNORED');\n\n return;\n }\n\n const id = track.getParticipantId();\n const participant = this.getParticipantById(id);\n\n if (!participant) {\n logger.error(`No participant found for id: ${id}`);\n\n return;\n }\n\n // Add track to JitsiParticipant.\n participant._tracks.push(track);\n\n if (this.transcriber) {\n this.transcriber.addTrack(track);\n }\n\n const emitter = this.eventEmitter;\n\n track.addEventListener(\n JitsiTrackEvents.TRACK_MUTE_CHANGED,\n () => emitter.emit(JitsiConferenceEvents.TRACK_MUTE_CHANGED, track));\n track.addEventListener(\n JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,\n (audioLevel, tpc) => {\n const activeTPC = this.getActivePeerConnection();\n\n if (activeTPC === tpc) {\n emitter.emit(\n JitsiConferenceEvents.TRACK_AUDIO_LEVEL_CHANGED,\n id,\n audioLevel);\n }\n }\n );\n\n emitter.emit(JitsiConferenceEvents.TRACK_ADDED, track);\n};\n\n/**\n * Callback called by the Jingle plugin when 'session-answer' is received.\n * @param {JingleSessionPC} session the Jingle session for which an answer was\n * received.\n * @param {jQuery} answer a jQuery selector pointing to 'jingle' IQ element\n */\n// eslint-disable-next-line no-unused-vars\nJitsiConference.prototype.onCallAccepted = function(session, answer) {\n if (this.p2pJingleSession === session) {\n logger.info('P2P setAnswer');\n this.p2pJingleSession.setAnswer(answer);\n }\n};\n\n/**\n * Callback called by the Jingle plugin when 'transport-info' is received.\n * @param {JingleSessionPC} session the Jingle session for which the IQ was\n * received\n * @param {jQuery} transportInfo a jQuery selector pointing to 'jingle' IQ\n * element\n */\n// eslint-disable-next-line no-unused-vars\nJitsiConference.prototype.onTransportInfo = function(session, transportInfo) {\n if (this.p2pJingleSession === session) {\n logger.info('P2P addIceCandidates');\n this.p2pJingleSession.addIceCandidates(transportInfo);\n }\n};\n\n/**\n * Notifies this JitsiConference that a JitsiRemoteTrack was removed from\n * the conference.\n *\n * @param {JitsiRemoteTrack} removedTrack\n */\nJitsiConference.prototype.onRemoteTrackRemoved = function(removedTrack) {\n this.getParticipants().forEach(participant => {\n const tracks = participant.getTracks();\n\n for (let i = 0; i < tracks.length; i++) {\n if (tracks[i] === removedTrack) {\n // Since the tracks have been compared and are\n // considered equal the result of splice can be ignored.\n participant._tracks.splice(i, 1);\n\n this.eventEmitter.emit(\n JitsiConferenceEvents.TRACK_REMOVED, removedTrack);\n\n if (this.transcriber) {\n this.transcriber.removeTrack(removedTrack);\n }\n\n break;\n }\n }\n }, this);\n};\n\n/**\n * Handles an incoming call event for the P2P jingle session.\n */\nJitsiConference.prototype._onIncomingCallP2P = function(\n jingleSession,\n jingleOffer) {\n\n let rejectReason;\n\n if (!browser.supportsP2P()) {\n rejectReason = {\n reason: 'unsupported-applications',\n reasonDescription: 'P2P not supported',\n errorMsg: 'This client does not support P2P connections'\n };\n } else if (!this.isP2PEnabled() && !this.isP2PTestModeEnabled()) {\n rejectReason = {\n reason: 'decline',\n reasonDescription: 'P2P disabled',\n errorMsg: 'P2P mode disabled in the configuration'\n };\n } else if (this.p2pJingleSession) {\n // Reject incoming P2P call (already in progress)\n rejectReason = {\n reason: 'busy',\n reasonDescription: 'P2P already in progress',\n errorMsg: 'Duplicated P2P \"session-initiate\"'\n };\n } else if (!this._shouldBeInP2PMode()) {\n rejectReason = {\n reason: 'decline',\n reasonDescription: 'P2P requirements not met',\n errorMsg: 'Received P2P \"session-initiate\" when should not be in P2P mode'\n };\n Statistics.sendAnalytics(createJingleEvent(ACTION_P2P_DECLINED));\n }\n\n if (rejectReason) {\n this._rejectIncomingCall(jingleSession, rejectReason);\n } else {\n this._acceptP2PIncomingCall(jingleSession, jingleOffer);\n }\n};\n\n/**\n * Handles an incoming call event.\n */\nJitsiConference.prototype.onIncomingCall = function(\n jingleSession,\n jingleOffer,\n now) {\n // Handle incoming P2P call\n if (jingleSession.isP2P) {\n this._onIncomingCallP2P(jingleSession, jingleOffer);\n } else {\n if (!this.room.isFocus(jingleSession.remoteJid)) {\n const description = 'Rejecting session-initiate from non-focus.';\n\n this._rejectIncomingCall(\n jingleSession, {\n reason: 'security-error',\n reasonDescription: description,\n errorMsg: description\n });\n\n return;\n }\n this._acceptJvbIncomingCall(jingleSession, jingleOffer, now);\n }\n};\n\n/**\n * Accepts an incoming call event for the JVB jingle session.\n */\nJitsiConference.prototype._acceptJvbIncomingCall = function(\n jingleSession,\n jingleOffer,\n now) {\n\n // Accept incoming call\n this.jvbJingleSession = jingleSession;\n this.room.connectionTimes['session.initiate'] = now;\n\n if (this.wasStopped) {\n Statistics.sendAnalyticsAndLog(\n createJingleEvent(ACTION_JINGLE_RESTART, { p2p: false }));\n }\n\n const serverRegion\n = $(jingleOffer)\n .find('>bridge-session[xmlns=\"http://jitsi.org/protocol/focus\"]')\n .attr('region');\n\n this.eventEmitter.emit(\n JitsiConferenceEvents.SERVER_REGION_CHANGED,\n serverRegion);\n\n this._maybeClearSITimeout();\n Statistics.sendAnalytics(createJingleEvent(\n ACTION_JINGLE_SI_RECEIVED,\n {\n p2p: false,\n value: now\n }));\n try {\n jingleSession.initialize(this.room, this.rtc, this.options.config);\n } catch (error) {\n GlobalOnErrorHandler.callErrorHandler(error);\n }\n\n // Open a channel with the videobridge.\n this._setBridgeChannel(jingleOffer, jingleSession.peerconnection);\n\n // Add local tracks to the session\n try {\n jingleSession.acceptOffer(\n jingleOffer,\n () => {\n // If for any reason invite for the JVB session arrived after\n // the P2P has been established already the media transfer needs\n // to be turned off here.\n if (this.isP2PActive() && this.jvbJingleSession) {\n this._suspendMediaTransferForJvbConnection();\n }\n },\n error => {\n GlobalOnErrorHandler.callErrorHandler(error);\n logger.error(\n 'Failed to accept incoming Jingle session', error);\n },\n this.getLocalTracks()\n );\n\n // Start callstats as soon as peerconnection is initialized,\n // do not wait for XMPPEvents.PEERCONNECTION_READY, as it may never\n // happen in case if user doesn't have or denied permission to\n // both camera and microphone.\n logger.info('Starting CallStats for JVB connection...');\n this.statistics.startCallStats(\n this.jvbJingleSession.peerconnection,\n 'jitsi' /* Remote user ID for JVB is 'jitsi' */);\n this.statistics.startRemoteStats(this.jvbJingleSession.peerconnection);\n } catch (e) {\n GlobalOnErrorHandler.callErrorHandler(e);\n logger.error(e);\n }\n};\n\n/**\n * Sets the BridgeChannel.\n *\n * @param {jQuery} offerIq a jQuery selector pointing to the jingle element of\n * the offer IQ which may carry the WebSocket URL for the 'websocket'\n * BridgeChannel mode.\n * @param {TraceablePeerConnection} pc the peer connection which will be used\n * to listen for new WebRTC Data Channels (in the 'datachannel' mode).\n */\nJitsiConference.prototype._setBridgeChannel = function(offerIq, pc) {\n let wsUrl = null;\n const webSocket\n = $(offerIq)\n .find('>content>transport>web-socket')\n .first();\n\n if (webSocket.length === 1) {\n wsUrl = webSocket[0].getAttribute('url');\n }\n\n let bridgeChannelType;\n\n switch (this.options.config.openBridgeChannel) {\n case 'datachannel':\n case true:\n case undefined:\n bridgeChannelType = 'datachannel';\n break;\n case 'websocket':\n bridgeChannelType = 'websocket';\n break;\n }\n\n if (bridgeChannelType === 'datachannel'\n && !browser.supportsDataChannels()) {\n bridgeChannelType = 'websocket';\n }\n\n if (bridgeChannelType === 'datachannel') {\n this.rtc.initializeBridgeChannel(pc, null);\n } else if (bridgeChannelType === 'websocket' && wsUrl) {\n this.rtc.initializeBridgeChannel(null, wsUrl);\n }\n};\n\n/**\n * Rejects incoming Jingle call.\n * @param {JingleSessionPC} jingleSession the session instance to be rejected.\n * @param {object} [options]\n * @param {string} options.reason the name of the reason element as defined\n * by Jingle\n * @param {string} options.reasonDescription the reason description which will\n * be included in Jingle 'session-terminate' message.\n * @param {string} options.errorMsg an error message to be logged on global\n * error handler\n * @private\n */\nJitsiConference.prototype._rejectIncomingCall = function(\n jingleSession,\n options) {\n if (options && options.errorMsg) {\n GlobalOnErrorHandler.callErrorHandler(new Error(options.errorMsg));\n }\n\n // Terminate the jingle session with a reason\n jingleSession.terminate(\n null /* success callback => we don't care */,\n error => {\n logger.warn(\n 'An error occurred while trying to terminate'\n + ' invalid Jingle session', error);\n }, {\n reason: options && options.reason,\n reasonDescription: options && options.reasonDescription,\n sendSessionTerminate: true\n });\n};\n\n/**\n * Handles the call ended event.\n * XXX is this due to the remote side terminating the Jingle session?\n *\n * @param {JingleSessionPC} jingleSession the jingle session which has been\n * terminated.\n * @param {String} reasonCondition the Jingle reason condition.\n * @param {String|null} reasonText human readable reason text which may provide\n * more details about why the call has been terminated.\n */\nJitsiConference.prototype.onCallEnded = function(\n jingleSession,\n reasonCondition,\n reasonText) {\n logger.info(\n `Call ended: ${reasonCondition} - ${reasonText} P2P ?${\n jingleSession.isP2P}`);\n if (jingleSession === this.jvbJingleSession) {\n this.wasStopped = true;\n\n Statistics.sendAnalytics(\n createJingleEvent(ACTION_JINGLE_TERMINATE, { p2p: false }));\n\n // Stop the stats\n if (this.statistics) {\n this.statistics.stopRemoteStats(\n this.jvbJingleSession.peerconnection);\n logger.info('Stopping JVB CallStats');\n this.statistics.stopCallStats(\n this.jvbJingleSession.peerconnection);\n }\n\n // Current JVB JingleSession is no longer valid, so set it to null\n this.jvbJingleSession = null;\n\n // Let the RTC service do any cleanups\n this.rtc.onCallEnded();\n } else if (jingleSession === this.p2pJingleSession) {\n // It's the responder who decides to enforce JVB mode, so that both\n // initiator and responder are aware if it was intentional.\n if (reasonCondition === 'decline' && reasonText === 'force JVB121') {\n logger.info('In forced JVB 121 mode...');\n Statistics.analytics.addPermanentProperties({ forceJvb121: true });\n } else if (reasonCondition === 'connectivity-error'\n && reasonText === 'ICE FAILED') {\n // It can happen that the other peer detects ICE failed and\n // terminates the session, before we get the event on our side.\n // But we are able to parse the reason and mark it here.\n Statistics.analytics.addPermanentProperties({ p2pFailed: true });\n }\n this._stopP2PSession();\n } else {\n logger.error(\n 'Received onCallEnded for invalid session',\n jingleSession.sid,\n jingleSession.remoteJid,\n reasonCondition,\n reasonText);\n }\n};\n\n/**\n * Handles the suspend detected event. Leaves the room and fires suspended.\n * @param {JingleSessionPC} jingleSession\n */\nJitsiConference.prototype.onSuspendDetected = function(jingleSession) {\n if (!jingleSession.isP2P) {\n this.leave();\n this.eventEmitter.emit(JitsiConferenceEvents.SUSPEND_DETECTED);\n }\n};\n\nJitsiConference.prototype.updateDTMFSupport = function() {\n let somebodySupportsDTMF = false;\n const participants = this.getParticipants();\n\n // check if at least 1 participant supports DTMF\n for (let i = 0; i < participants.length; i += 1) {\n if (participants[i].supportsDTMF()) {\n somebodySupportsDTMF = true;\n break;\n }\n }\n if (somebodySupportsDTMF !== this.somebodySupportsDTMF) {\n this.somebodySupportsDTMF = somebodySupportsDTMF;\n this.eventEmitter.emit(\n JitsiConferenceEvents.DTMF_SUPPORT_CHANGED,\n somebodySupportsDTMF);\n }\n};\n\n/**\n * Allows to check if there is at least one user in the conference\n * that supports DTMF.\n * @returns {boolean} true if somebody supports DTMF, false otherwise\n */\nJitsiConference.prototype.isDTMFSupported = function() {\n return this.somebodySupportsDTMF;\n};\n\n/**\n * Returns the local user's ID\n * @return {string} local user's ID\n */\nJitsiConference.prototype.myUserId = function() {\n return (\n this.room && this.room.myroomjid\n ? Strophe.getResourceFromJid(this.room.myroomjid)\n : null);\n};\n\nJitsiConference.prototype.sendTones = function(tones, duration, pause) {\n const peerConnection = this.getActivePeerConnection();\n\n if (peerConnection) {\n peerConnection.sendTones(tones, duration, pause);\n } else {\n logger.warn('cannot sendTones: no peer connection');\n }\n};\n\n/**\n * Starts recording the current conference.\n *\n * @param {Object} options - Configuration for the recording. See\n * {@link Chatroom#startRecording} for more info.\n * @returns {Promise} See {@link Chatroom#startRecording} for more info.\n */\nJitsiConference.prototype.startRecording = function(options) {\n if (this.room) {\n return this.recordingManager.startRecording(options);\n }\n\n return Promise.reject(new Error('The conference is not created yet!'));\n};\n\n/**\n * Stop a recording session.\n *\n * @param {string} sessionID - The ID of the recording session that\n * should be stopped.\n * @returns {Promise} See {@link Chatroom#stopRecording} for more info.\n */\nJitsiConference.prototype.stopRecording = function(sessionID) {\n if (this.room) {\n return this.recordingManager.stopRecording(sessionID);\n }\n\n return Promise.reject(new Error('The conference is not created yet!'));\n};\n\n/**\n * Returns true if the SIP calls are supported and false otherwise\n */\nJitsiConference.prototype.isSIPCallingSupported = function() {\n if (this.room) {\n return this.room.isSIPCallingSupported();\n }\n\n return false;\n};\n\n/**\n * Dials a number.\n * @param number the number\n */\nJitsiConference.prototype.dial = function(number) {\n if (this.room) {\n return this.room.dial(number);\n }\n\n return new Promise((resolve, reject) => {\n reject(new Error('The conference is not created yet!'));\n });\n};\n\n/**\n * Hangup an existing call\n */\nJitsiConference.prototype.hangup = function() {\n if (this.room) {\n return this.room.hangup();\n }\n\n return new Promise((resolve, reject) => {\n reject(new Error('The conference is not created yet!'));\n });\n};\n\n/**\n * Starts the transcription service.\n */\nJitsiConference.prototype.startTranscriber = function() {\n return this.dial('jitsi_meet_transcribe');\n};\n\n\n/**\n * Stops the transcription service.\n */\nJitsiConference.prototype.stopTranscriber = JitsiConference.prototype.hangup;\n\n/**\n * Returns the phone number for joining the conference.\n */\nJitsiConference.prototype.getPhoneNumber = function() {\n if (this.room) {\n return this.room.getPhoneNumber();\n }\n\n return null;\n};\n\n/**\n * Returns the pin for joining the conference with phone.\n */\nJitsiConference.prototype.getPhonePin = function() {\n if (this.room) {\n return this.room.getPhonePin();\n }\n\n return null;\n};\n\n/**\n * Will return P2P or JVB TraceablePeerConnection depending on\n * which connection is currently active.\n *\n * @return {TraceablePeerConnection|null} null if there isn't any active\n * TraceablePeerConnection currently available.\n * @public (FIXME how to make package local ?)\n */\nJitsiConference.prototype.getActivePeerConnection = function() {\n if (this.isP2PActive()) {\n return this.p2pJingleSession.peerconnection;\n }\n\n return this.jvbJingleSession ? this.jvbJingleSession.peerconnection : null;\n};\n\n/**\n * Returns the connection state for the current room. Its ice connection state\n * for its session.\n * NOTE that \"completed\" ICE state which can appear on the P2P connection will\n * be converted to \"connected\".\n * @return {string|null} ICE state name or null if there is no active\n * peer connection at this time.\n */\nJitsiConference.prototype.getConnectionState = function() {\n const peerConnection = this.getActivePeerConnection();\n\n return peerConnection ? peerConnection.getConnectionState() : null;\n};\n\n/**\n * Make all new participants mute their audio/video on join.\n * @param policy {Object} object with 2 boolean properties for video and audio:\n * @param {boolean} audio if audio should be muted.\n * @param {boolean} video if video should be muted.\n */\nJitsiConference.prototype.setStartMutedPolicy = function(policy) {\n if (!this.isModerator()) {\n return;\n }\n this.startMutedPolicy = policy;\n this.room.removeFromPresence('startmuted');\n this.room.addToPresence('startmuted', {\n attributes: {\n audio: policy.audio,\n video: policy.video,\n xmlns: 'http://jitsi.org/jitmeet/start-muted'\n }\n });\n this.room.sendPresence();\n};\n\n/**\n * Returns current start muted policy\n * @returns {Object} with 2 properties - audio and video.\n */\nJitsiConference.prototype.getStartMutedPolicy = function() {\n return this.startMutedPolicy;\n};\n\n/**\n * Check if audio is muted on join.\n */\nJitsiConference.prototype.isStartAudioMuted = function() {\n return this.startAudioMuted;\n};\n\n/**\n * Check if video is muted on join.\n */\nJitsiConference.prototype.isStartVideoMuted = function() {\n return this.startVideoMuted;\n};\n\n/**\n * Get object with internal logs.\n */\nJitsiConference.prototype.getLogs = function() {\n const data = this.xmpp.getJingleLog();\n\n const metadata = {};\n\n metadata.time = new Date();\n metadata.url = window.location.href;\n metadata.ua = navigator.userAgent;\n\n const log = this.xmpp.getXmppLog();\n\n if (log) {\n metadata.xmpp = log;\n }\n\n data.metadata = metadata;\n\n return data;\n};\n\n/**\n * Returns measured connectionTimes.\n */\nJitsiConference.prototype.getConnectionTimes = function() {\n return this.room.connectionTimes;\n};\n\n/**\n * Sets a property for the local participant.\n */\nJitsiConference.prototype.setLocalParticipantProperty = function(name, value) {\n this.sendCommand(`jitsi_participant_${name}`, { value });\n};\n\n/**\n * Removes a property for the local participant and sends the updated presence.\n */\nJitsiConference.prototype.removeLocalParticipantProperty = function(name) {\n this.removeCommand(`jitsi_participant_${name}`);\n this.room.sendPresence();\n};\n\n/**\n * Gets a local participant property.\n *\n * @return value of the local participant property if the tagName exists in the\n * list of properties, otherwise returns undefined.\n */\nJitsiConference.prototype.getLocalParticipantProperty = function(name) {\n const property = this.room.presMap.nodes.find(prop =>\n prop.tagName === `jitsi_participant_${name}`\n );\n\n return property ? property.value : undefined;\n};\n\n/**\n * Sends the given feedback through CallStats if enabled.\n *\n * @param overallFeedback an integer between 1 and 5 indicating the\n * user feedback\n * @param detailedFeedback detailed feedback from the user. Not yet used\n * @returns {Promise} Resolves if feedback is submitted successfully.\n */\nJitsiConference.prototype.sendFeedback = function(\n overallFeedback,\n detailedFeedback) {\n return this.statistics.sendFeedback(overallFeedback, detailedFeedback);\n};\n\n/**\n * Returns true if the callstats integration is enabled, otherwise returns\n * false.\n *\n * @returns true if the callstats integration is enabled, otherwise returns\n * false.\n */\nJitsiConference.prototype.isCallstatsEnabled = function() {\n return this.statistics.isCallstatsEnabled();\n};\n\n\n/**\n * Handles track attached to container (Calls associateStreamWithVideoTag method\n * from statistics module)\n * @param {JitsiLocalTrack|JitsiRemoteTrack} track the track\n * @param container the container\n */\nJitsiConference.prototype._onTrackAttach = function(track, container) {\n const isLocal = track.isLocal();\n let ssrc = null;\n const isP2P = track.isP2P;\n const remoteUserId = isP2P ? track.getParticipantId() : 'jitsi';\n const peerConnection\n = isP2P\n ? this.p2pJingleSession && this.p2pJingleSession.peerconnection\n : this.jvbJingleSession && this.jvbJingleSession.peerconnection;\n\n if (isLocal) {\n // Local tracks have SSRC stored on per peer connection basis\n if (peerConnection) {\n ssrc = peerConnection.getLocalSSRC(track);\n }\n } else {\n ssrc = track.getSSRC();\n }\n if (!container.id || !ssrc || !peerConnection) {\n return;\n }\n\n this.statistics.associateStreamWithVideoTag(\n peerConnection,\n ssrc,\n isLocal,\n remoteUserId,\n track.getUsageLabel(),\n container.id);\n};\n\n/**\n * Logs an \"application log\" message.\n * @param message {string} The message to log. Note that while this can be a\n * generic string, the convention used by lib-jitsi-meet and jitsi-meet is to\n * log valid JSON strings, with an \"id\" field used for distinguishing between\n * message types. E.g.: {id: \"recorder_status\", status: \"off\"}\n */\nJitsiConference.prototype.sendApplicationLog = function(message) {\n Statistics.sendLog(message);\n};\n\n/**\n * Checks if the user identified by given mucJid is the conference\n * focus.\n * @param mucJid the full MUC address of the user to be checked.\n * @returns {boolean|null} true if MUC user is the conference focus,\n * false when is not. null if we're not in the MUC anymore and\n * are unable to figure out the status or if given mucJid is invalid.\n */\nJitsiConference.prototype._isFocus = function(mucJid) {\n return this.room ? this.room.isFocus(mucJid) : null;\n};\n\n/**\n * Fires CONFERENCE_FAILED event with INCOMPATIBLE_SERVER_VERSIONS parameter\n */\nJitsiConference.prototype._fireIncompatibleVersionsEvent = function() {\n this.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.INCOMPATIBLE_SERVER_VERSIONS);\n};\n\n/**\n * Sends a message via the data channel.\n * @param to {string} the id of the endpoint that should receive the message.\n * If \"\" the message will be sent to all participants.\n * @param payload {object} the payload of the message.\n * @throws NetworkError or InvalidStateError or Error if the operation fails.\n * @deprecated Use 'sendMessage' instead. TODO: this should be private.\n */\nJitsiConference.prototype.sendEndpointMessage = function(to, payload) {\n this.rtc.sendChannelMessage(to, payload);\n};\n\n/**\n * Sends a broadcast message via the data channel.\n * @param payload {object} the payload of the message.\n * @throws NetworkError or InvalidStateError or Error if the operation fails.\n * @deprecated Use 'sendMessage' instead. TODO: this should be private.\n */\nJitsiConference.prototype.broadcastEndpointMessage = function(payload) {\n this.sendEndpointMessage('', payload);\n};\n\n/**\n * Sends a message to a given endpoint (if 'to' is a non-empty string), or\n * broadcasts it to all endpoints in the conference.\n * @param {string} to The ID of the endpoint/participant which is to receive\n * the message, or '' to broadcast the message to all endpoints in the\n * conference.\n * @param {string|object} message the message to send. If this is of type\n * 'string' it will be sent as a chat message. If it is of type 'object', it\n * will be encapsulated in a format recognized by jitsi-meet and converted to\n * JSON before being sent.\n * @param {boolean} sendThroughVideobridge Whether to send the message through\n * jitsi-videobridge (via the COLIBRI data channel or web socket), or through\n * the XMPP MUC. Currently only objects can be sent through jitsi-videobridge.\n */\nJitsiConference.prototype.sendMessage = function(\n message,\n to = '',\n sendThroughVideobridge = false) {\n const messageType = typeof message;\n\n // Through videobridge we support only objects. Through XMPP we support\n // objects (encapsulated in a specific JSON format) and strings (i.e.\n // regular chat messages).\n if (messageType !== 'object'\n && (sendThroughVideobridge || messageType !== 'string')) {\n logger.error(`Can not send a message of type ${messageType}`);\n\n return;\n }\n\n if (sendThroughVideobridge) {\n this.sendEndpointMessage(to, message);\n } else {\n let messageToSend = message;\n\n // Name of packet extension of message stanza to send the required\n // message in.\n let elementName = 'body';\n\n if (messageType === 'object') {\n elementName = 'json-message';\n\n // Mark as valid JSON message if not already\n if (!messageToSend.hasOwnProperty(JITSI_MEET_MUC_TYPE)) {\n messageToSend[JITSI_MEET_MUC_TYPE] = '';\n }\n\n try {\n messageToSend = JSON.stringify(messageToSend);\n } catch (e) {\n logger.error('Can not send a message, stringify failed: ', e);\n\n return;\n }\n }\n\n if (to) {\n this.sendPrivateTextMessage(to, messageToSend, elementName);\n } else {\n // Broadcast\n this.sendTextMessage(messageToSend, elementName);\n }\n }\n\n};\n\nJitsiConference.prototype.isConnectionInterrupted = function() {\n return this.isP2PActive()\n ? this.isP2PConnectionInterrupted : this.isJvbConnectionInterrupted;\n};\n\n/**\n * Handles {@link XMPPEvents.CONNECTION_INTERRUPTED}\n * @param {JingleSessionPC} session\n * @private\n */\nJitsiConference.prototype._onIceConnectionInterrupted = function(session) {\n if (session.isP2P) {\n this.isP2PConnectionInterrupted = true;\n } else {\n this.isJvbConnectionInterrupted = true;\n }\n if (session.isP2P === this.isP2PActive()) {\n this.eventEmitter.emit(JitsiConferenceEvents.CONNECTION_INTERRUPTED);\n }\n};\n\n/**\n * Handles {@link XMPPEvents.CONNECTION_ICE_FAILED}\n * @param {JingleSessionPC} session\n * @private\n */\nJitsiConference.prototype._onIceConnectionFailed = function(session) {\n // We do nothing for the JVB connection, because it's up to the Jicofo to\n // eventually come up with the new offer (at least for the time being).\n if (session.isP2P) {\n // Add p2pFailed property to analytics to distinguish, between \"good\"\n // and \"bad\" connection\n Statistics.analytics.addPermanentProperties({ p2pFailed: true });\n\n if (this.p2pJingleSession) {\n Statistics.sendAnalyticsAndLog(\n createP2PEvent(\n ACTION_P2P_FAILED,\n {\n initiator: this.p2pJingleSession.isInitiator\n }));\n\n }\n this._stopP2PSession('connectivity-error', 'ICE FAILED');\n } else if (session && this.jvbJingleSession === session) {\n if (this.xmpp.isPingSupported()) {\n this._delayedIceFailed = new IceFailedNotification(this);\n this._delayedIceFailed.start(session);\n } else {\n // Let Jicofo know that the JVB's ICE connection has failed\n logger.info('PING not supported - sending ICE failed immediately');\n session.sendIceFailedNotification();\n }\n }\n};\n\n/**\n * Handles {@link XMPPEvents.CONNECTION_RESTORED}\n * @param {JingleSessionPC} session\n * @private\n */\nJitsiConference.prototype._onIceConnectionRestored = function(session) {\n if (session.isP2P) {\n this.isP2PConnectionInterrupted = false;\n } else {\n this.isJvbConnectionInterrupted = false;\n this._delayedIceFailed && this._delayedIceFailed.cancel();\n }\n\n if (session.isP2P === this.isP2PActive()) {\n this.eventEmitter.emit(JitsiConferenceEvents.CONNECTION_RESTORED);\n }\n};\n\n/**\n * Accept incoming P2P Jingle call.\n * @param {JingleSessionPC} jingleSession the session instance\n * @param {jQuery} jingleOffer a jQuery selector pointing to 'jingle' IQ element\n * @private\n */\nJitsiConference.prototype._acceptP2PIncomingCall = function(\n jingleSession,\n jingleOffer) {\n this.isP2PConnectionInterrupted = false;\n\n // Accept the offer\n this.p2pJingleSession = jingleSession;\n\n this.p2pJingleSession.initialize(this.room, this.rtc, this.options.config);\n\n logger.info('Starting CallStats for P2P connection...');\n\n let remoteID = Strophe.getResourceFromJid(this.p2pJingleSession.remoteJid);\n\n const participant = this.participants[remoteID];\n\n if (participant) {\n remoteID = participant.getStatsID() || remoteID;\n }\n\n this.statistics.startCallStats(\n this.p2pJingleSession.peerconnection,\n remoteID);\n\n const localTracks = this.getLocalTracks();\n\n this.p2pJingleSession.acceptOffer(\n jingleOffer,\n () => {\n logger.debug('Got RESULT for P2P \"session-accept\"');\n },\n error => {\n logger.error(\n 'Failed to accept incoming P2P Jingle session', error);\n },\n localTracks);\n};\n\n/**\n * Adds remote tracks to the conference associated with the JVB session.\n * @private\n */\nJitsiConference.prototype._addRemoteJVBTracks = function() {\n this._addRemoteTracks(\n 'JVB', this.jvbJingleSession.peerconnection.getRemoteTracks());\n};\n\n/**\n * Adds remote tracks to the conference associated with the P2P session.\n * @private\n */\nJitsiConference.prototype._addRemoteP2PTracks = function() {\n this._addRemoteTracks(\n 'P2P', this.p2pJingleSession.peerconnection.getRemoteTracks());\n};\n\n/**\n * Generates fake \"remote track added\" events for given Jingle session.\n * @param {string} logName the session's nickname which will appear in log\n * messages.\n * @param {Array} remoteTracks the tracks that will be added\n * @private\n */\nJitsiConference.prototype._addRemoteTracks = function(logName, remoteTracks) {\n for (const track of remoteTracks) {\n logger.info(`Adding remote ${logName} track: ${track}`);\n this.rtc.eventEmitter.emit(RTCEvents.REMOTE_TRACK_ADDED, track);\n }\n};\n\n/**\n * Called when {@link XMPPEvents.CONNECTION_ESTABLISHED} event is\n * triggered for a {@link JingleSessionPC}. Switches the conference to use\n * the P2P connection if the event comes from the P2P session.\n * @param {JingleSessionPC} jingleSession the session instance.\n * @private\n */\nJitsiConference.prototype._onIceConnectionEstablished = function(\n jingleSession) {\n if (this.p2pJingleSession !== null) {\n // store the establishment time of the p2p session as a field of the\n // JitsiConference because the p2pJingleSession might get disposed (thus\n // the value is lost).\n this.p2pEstablishmentDuration\n = this.p2pJingleSession.establishmentDuration;\n }\n\n if (this.jvbJingleSession !== null) {\n this.jvbEstablishmentDuration\n = this.jvbJingleSession.establishmentDuration;\n }\n\n let done = false;\n const forceJVB121Ratio = this.options.config.forceJVB121Ratio;\n\n // We don't care about the JVB case, there's nothing to be done\n if (!jingleSession.isP2P) {\n done = true;\n } else if (this.p2pJingleSession !== jingleSession) {\n logger.error('CONNECTION_ESTABLISHED - wrong P2P session instance ?!');\n\n done = true;\n } else if (!jingleSession.isInitiator\n && typeof forceJVB121Ratio === 'number'\n && Math.random() < forceJVB121Ratio) {\n logger.info(`Forcing JVB 121 mode (ratio=${forceJVB121Ratio})...`);\n Statistics.analytics.addPermanentProperties({ forceJvb121: true });\n this._stopP2PSession('decline', 'force JVB121');\n\n done = true;\n }\n\n if (!isNaN(this.p2pEstablishmentDuration)\n && !isNaN(this.jvbEstablishmentDuration)) {\n const establishmentDurationDiff\n = this.p2pEstablishmentDuration - this.jvbEstablishmentDuration;\n\n Statistics.sendAnalytics(\n ICE_ESTABLISHMENT_DURATION_DIFF,\n { value: establishmentDurationDiff });\n }\n\n if (jingleSession.isP2P === this.isP2PActive()) {\n this.eventEmitter.emit(JitsiConferenceEvents.CONNECTION_ESTABLISHED);\n }\n\n if (done) {\n\n return;\n }\n\n // Update P2P status and emit events\n this._setP2PStatus(true);\n\n // Remove remote tracks\n if (this.jvbJingleSession) {\n this._removeRemoteJVBTracks();\n } else {\n logger.info('Not removing remote JVB tracks - no session yet');\n }\n\n this._addRemoteP2PTracks();\n\n // Stop media transfer over the JVB connection\n if (this.jvbJingleSession) {\n this._suspendMediaTransferForJvbConnection();\n }\n\n logger.info('Starting remote stats with p2p connection');\n this.statistics.startRemoteStats(this.p2pJingleSession.peerconnection);\n\n Statistics.sendAnalyticsAndLog(\n createP2PEvent(\n ACTION_P2P_ESTABLISHED,\n {\n initiator: this.p2pJingleSession.isInitiator\n }));\n\n};\n\n/**\n * Called when the chat room reads a new list of properties from jicofo's\n * presence. The properties may have changed, but they don't have to.\n *\n * @param {Object} properties - The properties keyed by the property name\n * ('key').\n * @private\n */\nJitsiConference.prototype._updateProperties = function(properties = {}) {\n const changed = !isEqual(properties, this.properties);\n\n this.properties = properties;\n if (changed) {\n this.eventEmitter.emit(\n JitsiConferenceEvents.PROPERTIES_CHANGED,\n this.properties);\n\n // Some of the properties need to be added to analytics events.\n const analyticsKeys = [\n\n // The number of jitsi-videobridge instances currently used for the\n // conference.\n 'bridge-count',\n\n // The conference creation time (set by jicofo).\n 'created-ms',\n 'octo-enabled'\n ];\n\n analyticsKeys.forEach(key => {\n if (properties[key] !== undefined) {\n Statistics.analytics.addPermanentProperties({\n [key.replace('-', '_')]: properties[key]\n });\n }\n });\n }\n};\n\n/**\n * Gets a conference property with a given key.\n *\n * @param {string} key - The key.\n * @returns {*} The value\n */\nJitsiConference.prototype.getProperty = function(key) {\n return this.properties[key];\n};\n\n/**\n * Clears the deferred start P2P task if it has been scheduled.\n * @private\n */\nJitsiConference.prototype._maybeClearDeferredStartP2P = function() {\n if (this.deferredStartP2PTask) {\n logger.info('Cleared deferred start P2P task');\n clearTimeout(this.deferredStartP2PTask);\n this.deferredStartP2PTask = null;\n }\n};\n\n/**\n * Removes from the conference remote tracks associated with the JVB\n * connection.\n * @private\n */\nJitsiConference.prototype._removeRemoteJVBTracks = function() {\n this._removeRemoteTracks(\n 'JVB', this.jvbJingleSession.peerconnection.getRemoteTracks());\n};\n\n/**\n * Removes from the conference remote tracks associated with the P2P\n * connection.\n * @private\n */\nJitsiConference.prototype._removeRemoteP2PTracks = function() {\n this._removeRemoteTracks(\n 'P2P', this.p2pJingleSession.peerconnection.getRemoteTracks());\n};\n\n/**\n * Generates fake \"remote track removed\" events for given Jingle session.\n * @param {string} sessionNickname the session's nickname which will appear in\n * log messages.\n * @param {Array} remoteTracks the tracks that will be removed\n * @private\n */\nJitsiConference.prototype._removeRemoteTracks = function(\n sessionNickname,\n remoteTracks) {\n for (const track of remoteTracks) {\n logger.info(`Removing remote ${sessionNickname} track: ${track}`);\n this.rtc.eventEmitter.emit(RTCEvents.REMOTE_TRACK_REMOVED, track);\n }\n};\n\n/**\n * Resumes media transfer over the JVB connection.\n * @private\n */\nJitsiConference.prototype._resumeMediaTransferForJvbConnection = function() {\n logger.info('Resuming media transfer over the JVB connection...');\n this.jvbJingleSession.setMediaTransferActive(true, true).then(\n () => {\n logger.info('Resumed media transfer over the JVB connection!');\n },\n error => {\n logger.error(\n 'Failed to resume media transfer over the JVB connection:',\n error);\n });\n};\n\n/**\n * Sets new P2P status and updates some events/states hijacked from\n * the JitsiConference.\n * @param {boolean} newStatus the new P2P status value, true means that\n * P2P is now in use, false means that the JVB connection is now in use\n * @private\n */\nJitsiConference.prototype._setP2PStatus = function(newStatus) {\n if (this.p2p === newStatus) {\n logger.debug(`Called _setP2PStatus with the same status: ${newStatus}`);\n\n return;\n }\n this.p2p = newStatus;\n if (newStatus) {\n logger.info('Peer to peer connection established!');\n\n // When we end up in a valid P2P session need to reset the properties\n // in case they have persisted, after session with another peer.\n Statistics.analytics.addPermanentProperties({\n p2pFailed: false,\n forceJvb121: false\n });\n\n // Sync up video transfer active in case p2pJingleSession not existed\n // when the lastN value was being adjusted.\n const isVideoActive = this.rtc.getLastN() !== 0;\n\n this.p2pJingleSession\n .setMediaTransferActive(true, isVideoActive)\n .catch(error => {\n logger.error(\n 'Failed to sync up P2P video transfer status'\n + `(${isVideoActive})`, error);\n });\n } else {\n logger.info('Peer to peer connection closed!');\n }\n\n // Put the JVB connection on hold/resume\n if (this.jvbJingleSession) {\n this.statistics.sendConnectionResumeOrHoldEvent(\n this.jvbJingleSession.peerconnection, !newStatus);\n }\n\n // Clear dtmfManager, so that it can be recreated with new connection\n this.dtmfManager = null;\n\n // Update P2P status\n this.eventEmitter.emit(\n JitsiConferenceEvents.P2P_STATUS,\n this,\n this.p2p);\n\n // Refresh connection interrupted/restored\n this.eventEmitter.emit(\n this.isConnectionInterrupted()\n ? JitsiConferenceEvents.CONNECTION_INTERRUPTED\n : JitsiConferenceEvents.CONNECTION_RESTORED);\n};\n\n/**\n * Starts new P2P session.\n * @param {string} remoteJid the JID of the remote participant\n * @private\n */\nJitsiConference.prototype._startP2PSession = function(remoteJid) {\n this._maybeClearDeferredStartP2P();\n if (this.p2pJingleSession) {\n logger.error('P2P session already started!');\n\n return;\n }\n\n this.isP2PConnectionInterrupted = false;\n this.p2pJingleSession\n = this.xmpp.connection.jingle.newP2PJingleSession(\n this.room.myroomjid,\n remoteJid);\n logger.info(\n 'Created new P2P JingleSession', this.room.myroomjid, remoteJid);\n\n this.p2pJingleSession.initialize(this.room, this.rtc, this.options.config);\n\n logger.info('Starting CallStats for P2P connection...');\n\n let remoteID = Strophe.getResourceFromJid(this.p2pJingleSession.remoteJid);\n\n const participant = this.participants[remoteID];\n\n if (participant) {\n remoteID = participant.getStatsID() || remoteID;\n }\n\n this.statistics.startCallStats(\n this.p2pJingleSession.peerconnection,\n remoteID);\n\n // NOTE one may consider to start P2P with the local tracks detached,\n // but no data will be sent until ICE succeeds anyway. And we switch\n // immediately once the P2P ICE connects.\n const localTracks = this.getLocalTracks();\n\n this.p2pJingleSession.invite(localTracks);\n};\n\n/**\n * Suspends media transfer over the JVB connection.\n * @private\n */\nJitsiConference.prototype._suspendMediaTransferForJvbConnection = function() {\n logger.info('Suspending media transfer over the JVB connection...');\n this.jvbJingleSession.setMediaTransferActive(false, false).then(\n () => {\n logger.info('Suspended media transfer over the JVB connection !');\n },\n error => {\n logger.error(\n 'Failed to suspend media transfer over the JVB connection:',\n error);\n });\n};\n\n/**\n * Method when called will decide whether it's the time to start or stop\n * the P2P session.\n * @param {boolean} userLeftEvent if true it means that the call\n * originates from the user left event.\n * @private\n */\nJitsiConference.prototype._maybeStartOrStopP2P = function(userLeftEvent) {\n if (!browser.supportsP2P()\n || !this.isP2PEnabled()\n || this.isP2PTestModeEnabled()) {\n logger.info('Auto P2P disabled');\n\n return;\n }\n const peers = this.getParticipants();\n const peerCount = peers.length;\n\n // FIXME 1 peer and it must *support* P2P switching\n const shouldBeInP2P = this._shouldBeInP2PMode();\n\n // Clear deferred \"start P2P\" task\n if (!shouldBeInP2P && this.deferredStartP2PTask) {\n this._maybeClearDeferredStartP2P();\n }\n\n // Start peer to peer session\n if (!this.p2pJingleSession && shouldBeInP2P) {\n const peer = peerCount && peers[0];\n\n\n const myId = this.myUserId();\n const peersId = peer.getId();\n\n if (myId > peersId) {\n logger.debug(\n 'I\\'m the bigger peersId - '\n + 'the other peer should start P2P', myId, peersId);\n\n return;\n } else if (myId === peersId) {\n logger.error('The same IDs ? ', myId, peersId);\n\n return;\n }\n\n const jid = peer.getJid();\n\n if (userLeftEvent) {\n if (this.deferredStartP2PTask) {\n logger.error('Deferred start P2P task\\'s been set already!');\n\n return;\n }\n logger.info(\n `Will start P2P with: ${jid} after ${\n this.backToP2PDelay} seconds...`);\n this.deferredStartP2PTask = setTimeout(\n this._startP2PSession.bind(this, jid),\n this.backToP2PDelay * 1000);\n } else {\n logger.info(`Will start P2P with: ${jid}`);\n this._startP2PSession(jid);\n }\n } else if (this.p2pJingleSession && !shouldBeInP2P) {\n logger.info(`Will stop P2P with: ${this.p2pJingleSession.remoteJid}`);\n\n // Log that there will be a switch back to the JVB connection\n if (this.p2pJingleSession.isInitiator && peerCount > 1) {\n Statistics.sendAnalyticsAndLog(\n createP2PEvent(ACTION_P2P_SWITCH_TO_JVB));\n }\n this._stopP2PSession();\n }\n};\n\n/**\n * Tells whether or not this conference should be currently in the P2P mode.\n *\n * @private\n * @returns {boolean}\n */\nJitsiConference.prototype._shouldBeInP2PMode = function() {\n const peers = this.getParticipants();\n const peerCount = peers.length;\n const hasBotPeer = peers.find(p => p._botType === 'poltergeist') !== undefined;\n const shouldBeInP2P = peerCount === 1 && !hasBotPeer;\n\n logger.debug(`P2P? peerCount: ${peerCount}, hasBotPeer: ${hasBotPeer} => ${shouldBeInP2P}`);\n\n return shouldBeInP2P;\n};\n\n/**\n * Stops the current P2P session.\n * @param {string} [reason=\"success\"] one of the Jingle \"reason\" element\n * names as defined by https://xmpp.org/extensions/xep-0166.html#def-reason\n * @param {string} [reasonDescription=\"Turing off P2P session\"] text\n * description that will be included in the session terminate message\n * @private\n */\nJitsiConference.prototype._stopP2PSession = function(\n reason,\n reasonDescription) {\n if (!this.p2pJingleSession) {\n logger.error('No P2P session to be stopped!');\n\n return;\n }\n\n const wasP2PEstablished = this.isP2PActive();\n\n // Swap remote tracks, but only if the P2P has been fully established\n if (wasP2PEstablished) {\n if (this.jvbJingleSession) {\n this._resumeMediaTransferForJvbConnection();\n }\n\n // Remove remote P2P tracks\n this._removeRemoteP2PTracks();\n }\n\n // Stop P2P stats\n logger.info('Stopping remote stats for P2P connection');\n this.statistics.stopRemoteStats(this.p2pJingleSession.peerconnection);\n logger.info('Stopping CallStats for P2P connection');\n this.statistics.stopCallStats(this.p2pJingleSession.peerconnection);\n\n this.p2pJingleSession.terminate(\n () => {\n logger.info('P2P session terminate RESULT');\n },\n error => {\n // Because both initiator and responder are simultaneously\n // terminating their JingleSessions in case of the 'to JVB switch'\n // when 3rd participant joins, both will dispose their sessions and\n // reply with 'item-not-found' (see strophe.jingle.js). We don't\n // want to log this as an error since it's expected behaviour.\n //\n // We want them both to terminate, because in case of initiator's\n // crash the responder would stay in P2P mode until ICE fails which\n // could take up to 20 seconds.\n //\n // NOTE lack of 'reason' is considered as graceful session terminate\n // where both initiator and responder terminate their sessions\n // simultaneously.\n if (reason) {\n logger.error(\n 'An error occurred while trying to terminate'\n + ' P2P Jingle session', error);\n }\n }, {\n reason: reason ? reason : 'success',\n reasonDescription: reasonDescription\n ? reasonDescription : 'Turing off P2P session',\n sendSessionTerminate: this.room\n && this.getParticipantById(\n Strophe.getResourceFromJid(this.p2pJingleSession.remoteJid))\n });\n\n this.p2pJingleSession = null;\n\n // Update P2P status and other affected events/states\n this._setP2PStatus(false);\n\n if (wasP2PEstablished) {\n // Add back remote JVB tracks\n if (this.jvbJingleSession) {\n this._addRemoteJVBTracks();\n } else {\n logger.info('Not adding remote JVB tracks - no session yet');\n }\n }\n};\n\n/**\n * Checks whether or not the conference is currently in the peer to peer mode.\n * Being in peer to peer mode means that the direct connection has been\n * established and the P2P connection is being used for media transmission.\n * @return {boolean} true if in P2P mode or false otherwise.\n */\nJitsiConference.prototype.isP2PActive = function() {\n return this.p2p;\n};\n\n/**\n * Returns the current ICE state of the P2P connection.\n * NOTE: method is used by the jitsi-meet-torture tests.\n * @return {string|null} an ICE state or null if there's currently\n * no P2P connection.\n */\nJitsiConference.prototype.getP2PConnectionState = function() {\n if (this.isP2PActive()) {\n return this.p2pJingleSession.peerconnection.getConnectionState();\n }\n\n return null;\n};\n\n\n/**\n * Manually starts new P2P session (should be used only in the tests).\n */\nJitsiConference.prototype.startP2PSession = function() {\n const peers = this.getParticipants();\n\n // Start peer to peer session\n if (peers.length === 1) {\n const peerJid = peers[0].getJid();\n\n this._startP2PSession(peerJid);\n } else {\n throw new Error(\n 'There must be exactly 1 participant to start the P2P session !');\n }\n};\n\n/**\n * Manually stops the current P2P session (should be used only in the tests)\n */\nJitsiConference.prototype.stopP2PSession = function() {\n this._stopP2PSession();\n};\n\n/**\n * Get a summary of how long current participants have been the dominant speaker\n * @returns {object}\n */\nJitsiConference.prototype.getSpeakerStats = function() {\n return this.speakerStatsCollector.getStats();\n};\n\n/**\n * Sets the maximum video size the local participant should receive from remote\n * participants.\n *\n * @param {number} maxFrameHeightPixels the maximum frame height, in pixels,\n * this receiver is willing to receive.\n * @returns {void}\n */\nJitsiConference.prototype.setReceiverVideoConstraint = function(\n maxFrameHeight) {\n this.rtc.setReceiverVideoConstraint(maxFrameHeight);\n};\n\n/**\n * Creates a video SIP GW session and returns it if service is enabled. Before\n * creating a session one need to check whether video SIP GW service is\n * available in the system {@link JitsiConference.isVideoSIPGWAvailable}. Even\n * if there are available nodes to serve this request, after creating the\n * session those nodes can be taken and the request about using the\n * created session can fail.\n *\n * @param {string} sipAddress - The sip address to be used.\n * @param {string} displayName - The display name to be used for this session.\n * @returns {JitsiVideoSIPGWSession|Error} Returns null if conference is not\n * initialised and there is no room.\n */\nJitsiConference.prototype.createVideoSIPGWSession\n = function(sipAddress, displayName) {\n if (!this.room) {\n return new Error(VideoSIPGWConstants.ERROR_NO_CONNECTION);\n }\n\n return this.videoSIPGWHandler\n .createVideoSIPGWSession(sipAddress, displayName);\n };\n","/**\n * Lodash (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright JS Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n asyncTag = '[object AsyncFunction]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n nullTag = '[object Null]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n proxyTag = '[object Proxy]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]',\n undefinedTag = '[object Undefined]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/** Used to identify `toStringTag` values of typed arrays. */\nvar typedArrayTags = {};\ntypedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\ntypedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\ntypedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\ntypedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\ntypedArrayTags[uint32Tag] = true;\ntypedArrayTags[argsTag] = typedArrayTags[arrayTag] =\ntypedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\ntypedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\ntypedArrayTags[errorTag] = typedArrayTags[funcTag] =\ntypedArrayTags[mapTag] = typedArrayTags[numberTag] =\ntypedArrayTags[objectTag] = typedArrayTags[regexpTag] =\ntypedArrayTags[setTag] = typedArrayTags[stringTag] =\ntypedArrayTags[weakMapTag] = false;\n\n/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Detect free variable `process` from Node.js. */\nvar freeProcess = moduleExports && freeGlobal.process;\n\n/** Used to access faster Node.js helpers. */\nvar nodeUtil = (function() {\n try {\n return freeProcess && freeProcess.binding && freeProcess.binding('util');\n } catch (e) {}\n}());\n\n/* Node.js helper references. */\nvar nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\n/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\n/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\n/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\n/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\n/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\n/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\n/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\n/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype,\n funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined,\n Symbol = root.Symbol,\n Uint8Array = root.Uint8Array,\n propertyIsEnumerable = objectProto.propertyIsEnumerable,\n splice = arrayProto.splice,\n symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols,\n nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,\n nativeKeys = overArg(Object.keys, Object);\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView'),\n Map = getNative(root, 'Map'),\n Promise = getNative(root, 'Promise'),\n Set = getNative(root, 'Set'),\n WeakMap = getNative(root, 'WeakMap'),\n nativeCreate = getNative(Object, 'create');\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n this.size = 0;\n}\n\n/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n}\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n this.size += this.has(key) ? 0 : 1;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n --this.size;\n return true;\n}\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n}\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n ++this.size;\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.size = 0;\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n}\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n var result = getMapData(this, key)['delete'](key);\n this.size -= result ? 1 : 0;\n return result;\n}\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return getMapData(this, key).get(key);\n}\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n return getMapData(this, key).has(key);\n}\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n var data = getMapData(this, key),\n size = data.size;\n\n data.set(key, value);\n this.size += data.size == size ? 0 : 1;\n return this;\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\n/**\n *\n * Creates an array cache object to store unique values.\n *\n * @private\n * @constructor\n * @param {Array} [values] The values to cache.\n */\nfunction SetCache(values) {\n var index = -1,\n length = values == null ? 0 : values.length;\n\n this.__data__ = new MapCache;\n while (++index < length) {\n this.add(values[index]);\n }\n}\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\n/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\n// Add methods to `SetCache`.\nSetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\nSetCache.prototype.has = setCacheHas;\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n var data = this.__data__ = new ListCache(entries);\n this.size = data.size;\n}\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n this.__data__ = new ListCache;\n this.size = 0;\n}\n\n/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n}\n\n/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\n/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\n/**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n var data = this.__data__;\n if (data instanceof ListCache) {\n var pairs = data.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n this.size = ++data.size;\n return this;\n }\n data = this.__data__ = new MapCache(pairs);\n }\n data.set(key, value);\n this.size = data.size;\n return this;\n}\n\n// Add methods to `Stack`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\n/**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n var isArr = isArray(value),\n isArg = !isArr && isArguments(value),\n isBuff = !isArr && !isArg && isBuffer(value),\n isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n skipIndexes = isArr || isArg || isBuff || isType,\n result = skipIndexes ? baseTimes(value.length, String) : [],\n length = result.length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (\n // Safari 9 has enumerable `arguments.length` in strict mode.\n key == 'length' ||\n // Node.js 0.10 has enumerable non-index properties on buffers.\n (isBuff && (key == 'offset' || key == 'parent')) ||\n // PhantomJS 2 has enumerable non-index properties on typed arrays.\n (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n // Skip index properties.\n isIndex(key, length)\n ))) {\n result.push(key);\n }\n }\n return result;\n}\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\n/**\n * The base implementation of `_.isArguments`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n */\nfunction baseIsArguments(value) {\n return isObjectLike(value) && baseGetTag(value) == argsTag;\n}\n\n/**\n * The base implementation of `_.isEqual` which supports partial comparisons\n * and tracks traversed objects.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Unordered comparison\n * 2 - Partial comparison\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n */\nfunction baseIsEqual(value, other, bitmask, customizer, stack) {\n if (value === other) {\n return true;\n }\n if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n return value !== value && other !== other;\n }\n return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n}\n\n/**\n * A specialized version of `baseIsEqual` for arrays and objects which performs\n * deep comparisons and tracks traversed objects enabling objects with circular\n * references to be compared.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n var objIsArr = isArray(object),\n othIsArr = isArray(other),\n objTag = objIsArr ? arrayTag : getTag(object),\n othTag = othIsArr ? arrayTag : getTag(other);\n\n objTag = objTag == argsTag ? objectTag : objTag;\n othTag = othTag == argsTag ? objectTag : othTag;\n\n var objIsObj = objTag == objectTag,\n othIsObj = othTag == objectTag,\n isSameTag = objTag == othTag;\n\n if (isSameTag && isBuffer(object)) {\n if (!isBuffer(other)) {\n return false;\n }\n objIsArr = true;\n objIsObj = false;\n }\n if (isSameTag && !objIsObj) {\n stack || (stack = new Stack);\n return (objIsArr || isTypedArray(object))\n ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n }\n if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n if (objIsWrapped || othIsWrapped) {\n var objUnwrapped = objIsWrapped ? object.value() : object,\n othUnwrapped = othIsWrapped ? other.value() : other;\n\n stack || (stack = new Stack);\n return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n }\n }\n if (!isSameTag) {\n return false;\n }\n stack || (stack = new Stack);\n return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n}\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\n/**\n * The base implementation of `_.isTypedArray` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n */\nfunction baseIsTypedArray(value) {\n return isObjectLike(value) &&\n isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n}\n\n/**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n}\n\n/**\n * A specialized version of `baseIsEqualDeep` for arrays with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Array} array The array to compare.\n * @param {Array} other The other array to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `array` and `other` objects.\n * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n */\nfunction equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n arrLength = array.length,\n othLength = other.length;\n\n if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(array);\n if (stacked && stack.get(other)) {\n return stacked == other;\n }\n var index = -1,\n result = true,\n seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n stack.set(array, other);\n stack.set(other, array);\n\n // Ignore non-index properties.\n while (++index < arrLength) {\n var arrValue = array[index],\n othValue = other[index];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, arrValue, index, other, array, stack)\n : customizer(arrValue, othValue, index, array, other, stack);\n }\n if (compared !== undefined) {\n if (compared) {\n continue;\n }\n result = false;\n break;\n }\n // Recursively compare arrays (susceptible to call stack limits).\n if (seen) {\n if (!arraySome(other, function(othValue, othIndex) {\n if (!cacheHas(seen, othIndex) &&\n (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n return seen.push(othIndex);\n }\n })) {\n result = false;\n break;\n }\n } else if (!(\n arrValue === othValue ||\n equalFunc(arrValue, othValue, bitmask, customizer, stack)\n )) {\n result = false;\n break;\n }\n }\n stack['delete'](array);\n stack['delete'](other);\n return result;\n}\n\n/**\n * A specialized version of `baseIsEqualDeep` for comparing objects of\n * the same `toStringTag`.\n *\n * **Note:** This function only supports comparing values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The `toStringTag` of the objects to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n switch (tag) {\n case dataViewTag:\n if ((object.byteLength != other.byteLength) ||\n (object.byteOffset != other.byteOffset)) {\n return false;\n }\n object = object.buffer;\n other = other.buffer;\n\n case arrayBufferTag:\n if ((object.byteLength != other.byteLength) ||\n !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n return false;\n }\n return true;\n\n case boolTag:\n case dateTag:\n case numberTag:\n // Coerce booleans to `1` or `0` and dates to milliseconds.\n // Invalid dates are coerced to `NaN`.\n return eq(+object, +other);\n\n case errorTag:\n return object.name == other.name && object.message == other.message;\n\n case regexpTag:\n case stringTag:\n // Coerce regexes to strings and treat strings, primitives and objects,\n // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n // for more details.\n return object == (other + '');\n\n case mapTag:\n var convert = mapToArray;\n\n case setTag:\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n convert || (convert = setToArray);\n\n if (object.size != other.size && !isPartial) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked) {\n return stacked == other;\n }\n bitmask |= COMPARE_UNORDERED_FLAG;\n\n // Recursively compare objects (susceptible to call stack limits).\n stack.set(object, other);\n var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n stack['delete'](object);\n return result;\n\n case symbolTag:\n if (symbolValueOf) {\n return symbolValueOf.call(object) == symbolValueOf.call(other);\n }\n }\n return false;\n}\n\n/**\n * A specialized version of `baseIsEqualDeep` for objects with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n objProps = getAllKeys(object),\n objLength = objProps.length,\n othProps = getAllKeys(other),\n othLength = othProps.length;\n\n if (objLength != othLength && !isPartial) {\n return false;\n }\n var index = objLength;\n while (index--) {\n var key = objProps[index];\n if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n return false;\n }\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked && stack.get(other)) {\n return stacked == other;\n }\n var result = true;\n stack.set(object, other);\n stack.set(other, object);\n\n var skipCtor = isPartial;\n while (++index < objLength) {\n key = objProps[index];\n var objValue = object[key],\n othValue = other[key];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, objValue, key, other, object, stack)\n : customizer(objValue, othValue, key, object, other, stack);\n }\n // Recursively compare objects (susceptible to call stack limits).\n if (!(compared === undefined\n ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n : compared\n )) {\n result = false;\n break;\n }\n skipCtor || (skipCtor = key == 'constructor');\n }\n if (result && !skipCtor) {\n var objCtor = object.constructor,\n othCtor = other.constructor;\n\n // Non `Object` object instances with different constructors are not equal.\n if (objCtor != othCtor &&\n ('constructor' in object && 'constructor' in other) &&\n !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n result = false;\n }\n }\n stack['delete'](object);\n stack['delete'](other);\n return result;\n}\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n}\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\n/**\n * Creates an array of the own enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n if (object == null) {\n return [];\n }\n object = Object(object);\n return arrayFilter(nativeGetSymbols(object), function(symbol) {\n return propertyIsEnumerable.call(object, symbol);\n });\n};\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = baseGetTag(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : '';\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n length = length == null ? MAX_SAFE_INTEGER : length;\n return !!length &&\n (typeof value == 'number' || reIsUint.test(value)) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\n/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\n/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nvar isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n !propertyIsEnumerable.call(value, 'callee');\n};\n\n/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\n/**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = nativeIsBuffer || stubFalse;\n\n/**\n * Performs a deep comparison between two values to determine if they are\n * equivalent.\n *\n * **Note:** This method supports comparing arrays, array buffers, booleans,\n * date objects, error objects, maps, numbers, `Object` objects, regexes,\n * sets, strings, symbols, and typed arrays. `Object` objects are compared\n * by their own, not inherited, enumerable properties. Functions and DOM\n * nodes are compared by strict equality, i.e. `===`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.isEqual(object, other);\n * // => true\n *\n * object === other;\n * // => false\n */\nfunction isEqual(value, other) {\n return baseIsEqual(value, other);\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\n/**\n * Checks if `value` is classified as a typed array.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n * @example\n *\n * _.isTypedArray(new Uint8Array);\n * // => true\n *\n * _.isTypedArray([]);\n * // => false\n */\nvar isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\n/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\n/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nmodule.exports = isEqual;\n","/* global __filename */\nimport { Strophe } from 'strophe.js';\n\nimport {\n ACTION_JINGLE_SA_TIMEOUT,\n createBridgeDownEvent,\n createConnectionStageReachedEvent,\n createFocusLeftEvent,\n createJingleEvent,\n createRemotelyMutedEvent\n} from './service/statistics/AnalyticsEvents';\nimport AuthenticationEvents\n from './service/authentication/AuthenticationEvents';\nimport EventEmitterForwarder from './modules/util/EventEmitterForwarder';\nimport { getLogger } from 'jitsi-meet-logger';\nimport * as JitsiConferenceErrors from './JitsiConferenceErrors';\nimport * as JitsiConferenceEvents from './JitsiConferenceEvents';\nimport * as MediaType from './service/RTC/MediaType';\nimport RTCEvents from './service/RTC/RTCEvents';\nimport VideoType from './service/RTC/VideoType';\nimport Statistics from './modules/statistics/statistics';\nimport XMPPEvents from './service/xmpp/XMPPEvents';\n\nconst logger = getLogger(__filename);\n\n/**\n * Setups all event listeners related to conference\n * @param conference {JitsiConference} the conference\n */\nexport default function JitsiConferenceEventManager(conference) {\n this.conference = conference;\n this.xmppListeners = {};\n\n // Listeners related to the conference only\n conference.on(JitsiConferenceEvents.TRACK_MUTE_CHANGED,\n track => {\n if (!track.isLocal() || !conference.statistics) {\n return;\n }\n const session\n = track.isP2P\n ? conference.p2pJingleSession : conference.jvbJingleSession;\n\n // TPC will be null, before the conference starts, but the event\n // still should be queued\n const tpc = (session && session.peerconnection) || null;\n\n conference.statistics.sendMuteEvent(\n tpc,\n track.isMuted(),\n track.getType());\n });\n}\n\n/**\n * Setups event listeners related to conference.chatRoom\n */\nJitsiConferenceEventManager.prototype.setupChatRoomListeners = function() {\n const conference = this.conference;\n const chatRoom = conference.room;\n\n this.chatRoomForwarder = new EventEmitterForwarder(chatRoom,\n this.conference.eventEmitter);\n\n chatRoom.addListener(XMPPEvents.ICE_RESTARTING, jingleSession => {\n if (!jingleSession.isP2P) {\n // If using DataChannel as bridge channel, it must be closed\n // before ICE restart, otherwise Chrome will not trigger \"opened\"\n // event for the channel established with the new bridge.\n // TODO: This may be bypassed when using a WebSocket as bridge\n // channel.\n conference.rtc.closeBridgeChannel();\n }\n\n // else: there are no DataChannels in P2P session (at least for now)\n });\n\n chatRoom.addListener(\n XMPPEvents.ICE_RESTART_SUCCESS,\n (jingleSession, offerIq) => {\n // The JVB data chanel needs to be reopened in case the conference\n // has been moved to a new bridge.\n !jingleSession.isP2P\n && conference._setBridgeChannel(\n offerIq, jingleSession.peerconnection);\n });\n\n\n chatRoom.addListener(XMPPEvents.AUDIO_MUTED_BY_FOCUS,\n actor => {\n // TODO: Add a way to differentiate between commands which caused\n // us to mute and those that did not change our state (i.e. we were\n // already muted).\n Statistics.sendAnalytics(createRemotelyMutedEvent());\n\n conference.mutedByFocusActor = actor;\n\n // set isMutedByFocus when setAudioMute Promise ends\n conference.rtc.setAudioMute(true).then(\n () => {\n conference.isMutedByFocus = true;\n conference.mutedByFocusActor = null;\n })\n .catch(\n error => {\n conference.mutedByFocusActor = null;\n logger.warn(\n 'Error while audio muting due to focus request', error);\n });\n }\n );\n\n this.chatRoomForwarder.forward(XMPPEvents.SUBJECT_CHANGED,\n JitsiConferenceEvents.SUBJECT_CHANGED);\n\n this.chatRoomForwarder.forward(XMPPEvents.MUC_JOINED,\n JitsiConferenceEvents.CONFERENCE_JOINED);\n\n // send some analytics events\n chatRoom.addListener(XMPPEvents.MUC_JOINED,\n () => {\n this.conference.isJvbConnectionInterrupted = false;\n\n // TODO: Move all of the 'connectionTimes' logic to its own module.\n Object.keys(chatRoom.connectionTimes).forEach(key => {\n const event\n = createConnectionStageReachedEvent(\n `conference_${key}`,\n { value: chatRoom.connectionTimes[key] });\n\n Statistics.sendAnalytics(event);\n });\n\n // TODO: Move all of the 'connectionTimes' logic to its own module.\n Object.keys(chatRoom.xmpp.connectionTimes).forEach(key => {\n const event\n = createConnectionStageReachedEvent(\n `xmpp_${key}`,\n { value: chatRoom.xmpp.connectionTimes[key] });\n\n Statistics.sendAnalytics(event);\n });\n });\n\n chatRoom.addListener(XMPPEvents.RENEGOTIATION_FAILED, (e, session) => {\n if (!session.isP2P) {\n conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.OFFER_ANSWER_FAILED, e);\n }\n });\n\n this.chatRoomForwarder.forward(XMPPEvents.ROOM_JOIN_ERROR,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.CONNECTION_ERROR);\n\n this.chatRoomForwarder.forward(XMPPEvents.ROOM_CONNECT_ERROR,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.CONNECTION_ERROR);\n this.chatRoomForwarder.forward(XMPPEvents.ROOM_CONNECT_NOT_ALLOWED_ERROR,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.NOT_ALLOWED_ERROR);\n\n this.chatRoomForwarder.forward(XMPPEvents.ROOM_MAX_USERS_ERROR,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.CONFERENCE_MAX_USERS);\n\n this.chatRoomForwarder.forward(XMPPEvents.PASSWORD_REQUIRED,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.PASSWORD_REQUIRED);\n\n this.chatRoomForwarder.forward(XMPPEvents.AUTHENTICATION_REQUIRED,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.AUTHENTICATION_REQUIRED);\n\n this.chatRoomForwarder.forward(XMPPEvents.BRIDGE_DOWN,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE);\n chatRoom.addListener(\n XMPPEvents.BRIDGE_DOWN,\n () => Statistics.sendAnalytics(createBridgeDownEvent()));\n\n this.chatRoomForwarder.forward(XMPPEvents.RESERVATION_ERROR,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.RESERVATION_ERROR);\n\n this.chatRoomForwarder.forward(XMPPEvents.GRACEFUL_SHUTDOWN,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.GRACEFUL_SHUTDOWN);\n\n chatRoom.addListener(XMPPEvents.CONNECTION_ICE_FAILED,\n jingleSession => {\n conference._onIceConnectionFailed(jingleSession);\n });\n\n this.chatRoomForwarder.forward(XMPPEvents.MUC_DESTROYED,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.CONFERENCE_DESTROYED);\n\n this.chatRoomForwarder.forward(XMPPEvents.CHAT_ERROR_RECEIVED,\n JitsiConferenceEvents.CONFERENCE_ERROR,\n JitsiConferenceErrors.CHAT_ERROR);\n\n this.chatRoomForwarder.forward(XMPPEvents.FOCUS_DISCONNECTED,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.FOCUS_DISCONNECTED);\n\n chatRoom.addListener(XMPPEvents.FOCUS_LEFT,\n () => {\n Statistics.sendAnalytics(createFocusLeftEvent());\n conference.eventEmitter.emit(\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.FOCUS_LEFT);\n });\n\n chatRoom.addListener(XMPPEvents.SESSION_ACCEPT_TIMEOUT,\n jingleSession => {\n Statistics.sendAnalyticsAndLog(\n createJingleEvent(\n ACTION_JINGLE_SA_TIMEOUT,\n { p2p: jingleSession.isP2P }));\n });\n\n chatRoom.addListener(XMPPEvents.RECORDER_STATE_CHANGED,\n (session, jid) => {\n\n if (jid) {\n const participant = conference.getParticipantById(\n Strophe.getResourceFromJid(jid));\n\n if (session.getStatus() === 'off') {\n session.setTerminator(participant);\n } else if (session.getStatus() === 'on') {\n session.setInitiator(participant);\n }\n }\n\n conference.eventEmitter.emit(\n JitsiConferenceEvents.RECORDER_STATE_CHANGED,\n session);\n });\n\n this.chatRoomForwarder.forward(XMPPEvents.TRANSCRIPTION_STATUS_CHANGED,\n JitsiConferenceEvents.TRANSCRIPTION_STATUS_CHANGED);\n\n this.chatRoomForwarder.forward(XMPPEvents.VIDEO_SIP_GW_AVAILABILITY_CHANGED,\n JitsiConferenceEvents.VIDEO_SIP_GW_AVAILABILITY_CHANGED);\n\n this.chatRoomForwarder.forward(\n XMPPEvents.VIDEO_SIP_GW_SESSION_STATE_CHANGED,\n JitsiConferenceEvents.VIDEO_SIP_GW_SESSION_STATE_CHANGED);\n\n this.chatRoomForwarder.forward(XMPPEvents.PHONE_NUMBER_CHANGED,\n JitsiConferenceEvents.PHONE_NUMBER_CHANGED);\n\n chatRoom.setParticipantPropertyListener((node, from) => {\n const participant = conference.getParticipantById(from);\n\n if (!participant) {\n return;\n }\n\n participant.setProperty(\n node.tagName.substring('jitsi_participant_'.length),\n node.value);\n });\n\n chatRoom.addListener(XMPPEvents.KICKED,\n conference.onMemberKicked.bind(conference));\n chatRoom.addListener(XMPPEvents.SUSPEND_DETECTED,\n conference.onSuspendDetected.bind(conference));\n\n this.chatRoomForwarder.forward(XMPPEvents.MUC_LOCK_CHANGED,\n JitsiConferenceEvents.LOCK_STATE_CHANGED);\n\n chatRoom.addListener(XMPPEvents.MUC_MEMBER_JOINED,\n conference.onMemberJoined.bind(conference));\n chatRoom.addListener(XMPPEvents.MUC_MEMBER_BOT_TYPE_CHANGED,\n conference._onMemberBotTypeChanged.bind(conference));\n chatRoom.addListener(XMPPEvents.MUC_MEMBER_LEFT,\n conference.onMemberLeft.bind(conference));\n this.chatRoomForwarder.forward(XMPPEvents.MUC_LEFT,\n JitsiConferenceEvents.CONFERENCE_LEFT);\n\n chatRoom.addListener(XMPPEvents.DISPLAY_NAME_CHANGED,\n conference.onDisplayNameChanged.bind(conference));\n\n chatRoom.addListener(XMPPEvents.LOCAL_ROLE_CHANGED, role => {\n conference.onLocalRoleChanged(role);\n\n // log all events for the recorder operated by the moderator\n if (conference.statistics && conference.isModerator()) {\n conference.on(JitsiConferenceEvents.RECORDER_STATE_CHANGED,\n recorderSession => {\n const logObject = {\n error: recorderSession.getError(),\n id: 'recorder_status',\n status: recorderSession.getStatus()\n };\n\n Statistics.sendLog(JSON.stringify(logObject));\n });\n }\n });\n\n chatRoom.addListener(XMPPEvents.MUC_ROLE_CHANGED,\n conference.onUserRoleChanged.bind(conference));\n\n chatRoom.addListener(AuthenticationEvents.IDENTITY_UPDATED,\n (authEnabled, authIdentity) => {\n conference.authEnabled = authEnabled;\n conference.authIdentity = authIdentity;\n conference.eventEmitter.emit(\n JitsiConferenceEvents.AUTH_STATUS_CHANGED, authEnabled,\n authIdentity);\n });\n\n chatRoom.addListener(\n XMPPEvents.MESSAGE_RECEIVED,\n\n // eslint-disable-next-line max-params\n (jid, displayName, txt, myJid, ts) => {\n const id = Strophe.getResourceFromJid(jid);\n\n conference.eventEmitter.emit(\n JitsiConferenceEvents.MESSAGE_RECEIVED,\n id, txt, ts, displayName);\n });\n\n chatRoom.addListener(\n XMPPEvents.PRIVATE_MESSAGE_RECEIVED,\n\n // eslint-disable-next-line max-params\n (jid, displayName, txt, myJid, ts) => {\n const id = Strophe.getResourceFromJid(jid);\n\n conference.eventEmitter.emit(\n JitsiConferenceEvents.PRIVATE_MESSAGE_RECEIVED,\n id, txt, ts);\n });\n\n chatRoom.addListener(XMPPEvents.PRESENCE_STATUS,\n (jid, status) => {\n const id = Strophe.getResourceFromJid(jid);\n const participant = conference.getParticipantById(id);\n\n if (!participant || participant._status === status) {\n return;\n }\n participant._status = status;\n conference.eventEmitter.emit(\n JitsiConferenceEvents.USER_STATUS_CHANGED, id, status);\n });\n\n chatRoom.addListener(XMPPEvents.JSON_MESSAGE_RECEIVED,\n (from, payload) => {\n const id = Strophe.getResourceFromJid(from);\n const participant = conference.getParticipantById(id);\n\n if (participant) {\n conference.eventEmitter.emit(\n JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,\n participant, payload);\n } else {\n logger.warn(\n 'Ignored XMPPEvents.JSON_MESSAGE_RECEIVED for not existing '\n + `participant: ${from}`,\n payload);\n }\n });\n\n chatRoom.addPresenceListener('startmuted', (data, from) => {\n let isModerator = false;\n\n if (conference.myUserId() === from && conference.isModerator()) {\n isModerator = true;\n } else {\n const participant = conference.getParticipantById(from);\n\n if (participant && participant.isModerator()) {\n isModerator = true;\n }\n }\n\n if (!isModerator) {\n return;\n }\n\n const startAudioMuted = data.attributes.audio === 'true';\n const startVideoMuted = data.attributes.video === 'true';\n\n let updated = false;\n\n if (startAudioMuted !== conference.startMutedPolicy.audio) {\n conference.startMutedPolicy.audio = startAudioMuted;\n updated = true;\n }\n\n if (startVideoMuted !== conference.startMutedPolicy.video) {\n conference.startMutedPolicy.video = startVideoMuted;\n updated = true;\n }\n\n if (updated) {\n conference.eventEmitter.emit(\n JitsiConferenceEvents.START_MUTED_POLICY_CHANGED,\n conference.startMutedPolicy\n );\n }\n });\n\n if (conference.statistics) {\n // FIXME ICE related events should end up in RTCEvents eventually\n chatRoom.addListener(XMPPEvents.CONNECTION_ICE_FAILED,\n session => {\n conference.statistics.sendIceConnectionFailedEvent(\n session.peerconnection);\n });\n\n // FIXME XMPPEvents.ADD_ICE_CANDIDATE_FAILED is never emitted\n chatRoom.addListener(XMPPEvents.ADD_ICE_CANDIDATE_FAILED,\n (e, pc) => {\n conference.statistics.sendAddIceCandidateFailed(e, pc);\n });\n }\n};\n\n/**\n * Setups event listeners related to conference.rtc\n */\nJitsiConferenceEventManager.prototype.setupRTCListeners = function() {\n const conference = this.conference;\n const rtc = conference.rtc;\n\n rtc.addListener(\n RTCEvents.REMOTE_TRACK_ADDED,\n conference.onRemoteTrackAdded.bind(conference));\n\n rtc.addListener(\n RTCEvents.REMOTE_TRACK_REMOVED,\n conference.onRemoteTrackRemoved.bind(conference));\n\n rtc.addListener(RTCEvents.DOMINANT_SPEAKER_CHANGED,\n id => {\n if (conference.lastDominantSpeaker !== id && conference.room) {\n conference.lastDominantSpeaker = id;\n conference.eventEmitter.emit(\n JitsiConferenceEvents.DOMINANT_SPEAKER_CHANGED, id);\n\n if (conference.statistics && conference.myUserId() === id) {\n // We are the new dominant speaker.\n conference.statistics.sendDominantSpeakerEvent(\n conference.room.roomjid);\n }\n }\n });\n\n rtc.addListener(RTCEvents.DATA_CHANNEL_OPEN, () => {\n const now = window.performance.now();\n const key = 'data.channel.opened';\n\n // TODO: Move all of the 'connectionTimes' logic to its own module.\n logger.log(`(TIME) ${key}`, now);\n conference.room.connectionTimes[key] = now;\n Statistics.sendAnalytics(\n createConnectionStageReachedEvent(key, { value: now }));\n\n conference.eventEmitter.emit(JitsiConferenceEvents.DATA_CHANNEL_OPENED);\n });\n\n rtc.addListener(RTCEvents.ENDPOINT_MESSAGE_RECEIVED,\n (from, payload) => {\n const participant = conference.getParticipantById(from);\n\n if (participant) {\n conference.eventEmitter.emit(\n JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,\n participant, payload);\n } else {\n logger.warn(\n 'Ignored ENDPOINT_MESSAGE_RECEIVED for not existing '\n + `participant: ${from}`,\n payload);\n }\n });\n\n rtc.addListener(RTCEvents.LOCAL_UFRAG_CHANGED,\n (tpc, ufrag) => {\n if (!tpc.isP2P) {\n Statistics.sendLog(\n JSON.stringify({\n id: 'local_ufrag',\n value: ufrag\n }));\n }\n });\n rtc.addListener(RTCEvents.REMOTE_UFRAG_CHANGED,\n (tpc, ufrag) => {\n if (!tpc.isP2P) {\n Statistics.sendLog(\n JSON.stringify({\n id: 'remote_ufrag',\n value: ufrag\n }));\n }\n });\n\n rtc.addListener(RTCEvents.CREATE_ANSWER_FAILED,\n (e, tpc) => {\n conference.statistics.sendCreateAnswerFailed(e, tpc);\n if (!tpc.isP2P) {\n conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.OFFER_ANSWER_FAILED, e);\n }\n });\n\n rtc.addListener(RTCEvents.CREATE_OFFER_FAILED,\n (e, tpc) => {\n conference.statistics.sendCreateOfferFailed(e, tpc);\n if (!tpc.isP2P) {\n conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.OFFER_ANSWER_FAILED, e);\n }\n });\n\n rtc.addListener(RTCEvents.SET_LOCAL_DESCRIPTION_FAILED,\n (e, tpc) => {\n conference.statistics.sendSetLocalDescFailed(e, tpc);\n if (!tpc.isP2P) {\n conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.OFFER_ANSWER_FAILED, e);\n }\n });\n\n rtc.addListener(RTCEvents.SET_REMOTE_DESCRIPTION_FAILED,\n (e, tpc) => {\n conference.statistics.sendSetRemoteDescFailed(e, tpc);\n if (!tpc.isP2P) {\n conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.OFFER_ANSWER_FAILED, e);\n }\n });\n\n rtc.addListener(RTCEvents.LOCAL_TRACK_SSRC_UPDATED,\n (track, ssrc) => {\n // when starting screen sharing, the track is created and when\n // we do set local description and we process the ssrc we\n // will be notified for it and we will report it with the event\n // for screen sharing\n if (track.isVideoTrack() && track.videoType === VideoType.DESKTOP) {\n conference.statistics.sendScreenSharingEvent(true, ssrc);\n }\n });\n};\n\n/**\n * Removes event listeners related to conference.xmpp\n */\nJitsiConferenceEventManager.prototype.removeXMPPListeners = function() {\n const conference = this.conference;\n\n conference.xmpp.caps.removeListener(\n XMPPEvents.PARTCIPANT_FEATURES_CHANGED,\n this.xmppListeners[XMPPEvents.PARTCIPANT_FEATURES_CHANGED]);\n delete this.xmppListeners[XMPPEvents.PARTCIPANT_FEATURES_CHANGED];\n\n Object.keys(this.xmppListeners).forEach(eventName => {\n conference.xmpp.removeListener(\n eventName,\n this.xmppListeners[eventName]);\n });\n this.xmppListeners = {};\n};\n\n\n/**\n * Setups event listeners related to conference.xmpp\n */\nJitsiConferenceEventManager.prototype.setupXMPPListeners = function() {\n const conference = this.conference;\n\n const featuresChangedListener = from => {\n const participant\n = conference.getParticipantById(\n Strophe.getResourceFromJid(from));\n\n if (participant) {\n conference.eventEmitter.emit(\n JitsiConferenceEvents.PARTCIPANT_FEATURES_CHANGED,\n participant);\n }\n };\n\n conference.xmpp.caps.addListener(\n XMPPEvents.PARTCIPANT_FEATURES_CHANGED,\n featuresChangedListener);\n this.xmppListeners[XMPPEvents.PARTCIPANT_FEATURES_CHANGED]\n = featuresChangedListener;\n\n this._addConferenceXMPPListener(\n XMPPEvents.CALL_INCOMING,\n conference.onIncomingCall.bind(conference));\n this._addConferenceXMPPListener(\n XMPPEvents.CALL_ACCEPTED,\n conference.onCallAccepted.bind(conference));\n this._addConferenceXMPPListener(\n XMPPEvents.TRANSPORT_INFO,\n conference.onTransportInfo.bind(conference));\n this._addConferenceXMPPListener(\n XMPPEvents.CALL_ENDED,\n conference.onCallEnded.bind(conference));\n\n this._addConferenceXMPPListener(XMPPEvents.START_MUTED_FROM_FOCUS,\n (audioMuted, videoMuted) => {\n if (conference.options.config.ignoreStartMuted) {\n return;\n }\n\n conference.startAudioMuted = audioMuted;\n conference.startVideoMuted = videoMuted;\n\n // mute existing local tracks because this is initial mute from\n // Jicofo\n conference.getLocalTracks().forEach(track => {\n switch (track.getType()) {\n case MediaType.AUDIO:\n conference.startAudioMuted && track.mute();\n break;\n case MediaType.VIDEO:\n conference.startVideoMuted && track.mute();\n break;\n }\n });\n\n conference.eventEmitter.emit(JitsiConferenceEvents.STARTED_MUTED);\n });\n};\n\n/**\n * Add XMPP listener and save its reference for remove on leave conference.\n */\nJitsiConferenceEventManager.prototype._addConferenceXMPPListener = function(\n eventName, listener) {\n this.xmppListeners[eventName] = listener;\n this.conference.xmpp.addListener(eventName, listener);\n};\n\n/**\n * Setups event listeners related to conference.statistics\n */\nJitsiConferenceEventManager.prototype.setupStatisticsListeners = function() {\n const conference = this.conference;\n\n if (!conference.statistics) {\n return;\n }\n\n /* eslint-disable max-params */\n conference.statistics.addAudioLevelListener((tpc, ssrc, level, isLocal) => {\n conference.rtc.setAudioLevel(tpc, ssrc, level, isLocal);\n });\n\n /* eslint-enable max-params */\n\n // Forward the \"before stats disposed\" event\n conference.statistics.addBeforeDisposedListener(() => {\n conference.eventEmitter.emit(\n JitsiConferenceEvents.BEFORE_STATISTICS_DISPOSED);\n });\n\n // if we are in startSilent mode we will not be sending/receiving so nothing to detect\n if (!conference.options.config.startSilent) {\n conference.statistics.addByteSentStatsListener((tpc, stats) => {\n conference.getLocalTracks(MediaType.AUDIO).forEach(track => {\n const ssrc = tpc.getLocalSSRC(track);\n\n if (!ssrc || !stats.hasOwnProperty(ssrc)) {\n return;\n }\n\n track._onByteSentStatsReceived(tpc, stats[ssrc]);\n });\n });\n }\n};\n","/**\n * Implements utility to forward events from one eventEmitter to another.\n * @param src {object} instance of EventEmitter or another class that implements\n * addListener method which will register listener to EventEmitter instance.\n * @param dest {object} instance of EventEmitter or another class that\n * implements emit method which will emit an event.\n */\nfunction EventEmitterForwarder(src, dest) {\n if (!src || !dest || typeof src.addListener !== 'function'\n || typeof dest.emit !== 'function') {\n throw new Error('Invalid arguments passed to EventEmitterForwarder');\n }\n this.src = src;\n this.dest = dest;\n}\n\n/**\n * Adds event to be forwarded from src to dest.\n * @param srcEvent {string} the event that EventEmitterForwarder is listening\n * for.\n * @param dstEvent {string} the event that will be fired from dest.\n * @param arguments all other passed arguments are going to be fired with\n * dstEvent.\n */\nEventEmitterForwarder.prototype.forward = function(...args) {\n const srcEvent = args[0];\n\n // This will be the \"this\" value for emit function.\n\n args[0] = this.dest;\n\n // Using bind.apply to pass the arguments as Array-like object (\"arguments\")\n this.src.addListener(\n srcEvent,\n Function.prototype.bind.apply(this.dest.emit, args));\n};\n\nmodule.exports = EventEmitterForwarder;\n","import {\n TYPE_OPERATIONAL,\n TYPE_PAGE,\n TYPE_TRACK,\n TYPE_UI\n} from '../../service/statistics/AnalyticsEvents';\nimport { getLogger } from 'jitsi-meet-logger';\nimport browser from '../browser';\n\nconst MAX_CACHE_SIZE = 100;\n\n// eslist-disable-line no-undef\nconst logger = getLogger(__filename);\n\n/**\n * This class provides an API to lib-jitsi-meet and its users for sending\n * analytics events. It serves as a bridge to different backend implementations\n * (\"analytics handlers\") and a cache for events attempted to be sent before\n * the analytics handlers were enabled.\n *\n * The API is designed to be an easy replacement for the previous version of\n * this adapter, and is meant to be extended with more convenience methods.\n *\n *\n * The API calls are translated to objects with the following structure, which\n * are then passed to the sendEvent(event) function of the underlying handlers:\n *\n * {\n * type,\n *\n * action,\n * actionSubject,\n * actionSubjectId,\n * attributes,\n * categories,\n * containerId,\n * containerType,\n * name,\n * objectId,\n * objectType,\n * source,\n * tags\n * }\n *\n * The 'type' is one of 'operational', 'page', 'track' or 'ui', and some of the\n * other properties are considered required according to the type.\n *\n * For events with type 'page', the required properties are: name.\n *\n * For events with type 'operational' and 'ui', the required properties are:\n * action, actionSubject, source\n *\n * For events with type 'page', the required properties are:\n * action, actionSubject, source, containerType, containerId, objectType,\n * objectId\n */\nclass AnalyticsAdapter {\n /**\n * Creates new AnalyticsAdapter instance.\n */\n constructor() {\n this.reset();\n }\n\n /**\n * Reset the state to the initial one.\n *\n * @returns {void}\n */\n reset() {\n /**\n * Whether this AnalyticsAdapter has been disposed of or not. Once this\n * is set to true, the AnalyticsAdapter is disabled and does not accept\n * any more events, and it can not be re-enabled.\n * @type {boolean}\n */\n this.disposed = false;\n\n /**\n * The set of handlers to which events will be sent.\n * @type {Set}\n */\n this.analyticsHandlers = new Set();\n\n /**\n * The cache of events which are not sent yet. The cache is enabled\n * while this field is truthy, and disabled otherwise.\n * @type {Array}\n */\n this.cache = [];\n\n /**\n * Map of properties that will be added to every event. Note that the\n * keys will be prefixed with \"permanent.\".\n */\n this.permanentProperties = {};\n\n /**\n * The name of the conference that this AnalyticsAdapter is associated\n * with.\n * @type {null}\n */\n this.conferenceName = '';\n\n this.addPermanentProperties({\n 'user_agent': navigator.userAgent,\n 'browser_name': browser.getName()\n });\n }\n\n /**\n * Dispose analytics. Clears all handlers.\n */\n dispose() {\n logger.warn('Disposing of analytics adapter.');\n\n if (this.analyticsHandlers && this.analyticsHandlers.size > 0) {\n this.analyticsHandlers.forEach(handler => {\n if (typeof handler.dispose === 'function') {\n handler.dispose();\n }\n });\n }\n\n this.setAnalyticsHandlers([]);\n this.disposed = true;\n }\n\n /**\n * Sets the handlers that are going to be used to send analytics. Sends any\n * cached events.\n * @param {Array} handlers the handlers\n */\n setAnalyticsHandlers(handlers) {\n if (this.disposed) {\n return;\n }\n\n this.analyticsHandlers = new Set(handlers);\n\n this._setUserProperties();\n\n // Note that we disable the cache even if the set of handlers is empty.\n const cache = this.cache;\n\n this.cache = null;\n if (cache) {\n cache.forEach(event => this._sendEvent(event));\n }\n }\n\n /**\n * Set the user properties to the analytics handlers.\n *\n * @returns {void}\n */\n _setUserProperties() {\n this.analyticsHandlers.forEach(handler => {\n try {\n handler.setUserProperties(this.permanentProperties);\n } catch (error) {\n logger.warn('Error in setUserProperties method of one of the '\n + `analytics handlers: ${error}`);\n }\n });\n }\n\n /**\n * Adds a set of permanent properties to this this AnalyticsAdapter.\n * Permanent properties will be added as \"attributes\" to events sent to\n * the underlying \"analytics handlers\", and their keys will be prefixed\n * by \"permanent_\", i.e. adding a permanent property {key: \"value\"} will\n * result in {\"permanent_key\": \"value\"} object to be added to the\n * \"attributes\" field of events.\n *\n * @param {Object} properties the properties to add\n */\n addPermanentProperties(properties) {\n this.permanentProperties = {\n ...this.permanentProperties,\n ...properties\n };\n\n this._setUserProperties();\n }\n\n /**\n * Sets the name of the conference that this AnalyticsAdapter is associated\n * with.\n * @param name the name to set.\n */\n setConferenceName(name) {\n this.conferenceName = name;\n this.addPermanentProperties({ 'conference_name': name });\n }\n\n /**\n * Sends an event with a given name and given properties. The first\n * parameter is either a string or an object. If it is a string, it is used\n * as the event name and the second parameter is used at the attributes to\n * attach to the event. If it is an object, it represents the whole event,\n * including any desired attributes, and the second parameter is ignored.\n *\n * @param {String|Object} eventName either a string to be used as the name\n * of the event, or an event object. If an event object is passed, the\n * properties parameters is ignored.\n * @param {Object} properties the properties/attributes to attach to the\n * event, if eventName is a string.\n */\n sendEvent(eventName, properties = {}) {\n if (this.disposed) {\n return;\n }\n\n let event = null;\n\n if (typeof eventName === 'string') {\n event = {\n type: TYPE_OPERATIONAL,\n action: eventName,\n actionSubject: eventName,\n source: eventName,\n attributes: properties\n };\n } else if (typeof eventName === 'object') {\n event = eventName;\n }\n\n if (!this._verifyRequiredFields(event)) {\n logger.error(\n `Dropping a mis-formatted event: ${JSON.stringify(event)}`);\n\n return;\n }\n\n this._sendEvent(event);\n }\n\n /**\n * Checks whether an event has all of the required fields set, and tries\n * to fill in some of the missing fields with reasonable default values.\n * Returns true if after this operation the event has all of the required\n * fields set, and false otherwise (if some of the required fields were not\n * set and the attempt to fill them in with a default failed).\n *\n * @param event the event object.\n * @return {boolean} true if the event (after the call to this function)\n * contains all of the required fields, and false otherwise.\n * @private\n */\n _verifyRequiredFields(event) {\n if (!event) {\n return false;\n }\n\n if (!event.type) {\n event.type = TYPE_OPERATIONAL;\n }\n\n const type = event.type;\n\n if (type !== TYPE_OPERATIONAL && type !== TYPE_PAGE\n && type !== TYPE_UI && type !== TYPE_TRACK) {\n logger.error(`Unknown event type: ${type}`);\n\n return false;\n }\n\n if (type === TYPE_PAGE) {\n return Boolean(event.name);\n }\n\n // Try to set some reasonable default values in case some of the\n // parameters required by the handler API are missing.\n event.action = event.action || event.name || event.actionSubject;\n event.actionSubject = event.actionSubject || event.name || event.action;\n event.source = event.source || event.name || event.action\n || event.actionSubject;\n\n if (!event.action || !event.actionSubject || !event.source) {\n logger.error(\n 'Required field missing (action, actionSubject or source)');\n\n return false;\n }\n\n // Track events have additional required fields.\n if (type === TYPE_TRACK) {\n event.objectType = event.objectType || 'generic-object-type';\n event.containerType = event.containerType || 'conference';\n if (event.containerType === 'conference' && !event.containerId) {\n event.containerId = this.conferenceName;\n }\n\n\n if (!event.objectType || !event.objectId\n || !event.containerType || !event.containerId) {\n logger.error(\n 'Required field missing (containerId, containerType, '\n + 'objectId or objectType)');\n\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Saves an event to the cache, if the cache is enabled.\n * @param event the event to save.\n * @returns {boolean} true if the event was saved, and false otherwise (i.e.\n * if the cache was disabled).\n * @private\n */\n _maybeCacheEvent(event) {\n if (this.cache) {\n this.cache.push(event);\n\n // We limit the size of the cache, in case the user fails to ever\n // set the analytics handlers.\n if (this.cache.length > MAX_CACHE_SIZE) {\n this.cache.splice(0, 1);\n }\n\n return true;\n }\n\n return false;\n\n }\n\n /**\n *\n * @param event\n * @private\n */\n _sendEvent(event) {\n if (this._maybeCacheEvent(event)) {\n // The event was consumed by the cache.\n } else {\n this.analyticsHandlers.forEach(handler => {\n try {\n handler.sendEvent(event);\n } catch (e) {\n logger.warn(`Error sending analytics event: ${e}`);\n }\n });\n }\n }\n}\n\nexport default new AnalyticsAdapter();\n","import { getLogger } from 'jitsi-meet-logger';\nimport { BrowserDetection } from 'js-utils';\n\nconst logger = getLogger(__filename);\n\n// TODO: Move this code to js-utils.\n\n// NOTE: Now we are extending BrowserDetection in order to preserve\n// RTCBrowserType interface but maybe it worth exporting BrowserCapabilities\n// and BrowserDetection as separate objects in future.\n\n/**\n * Implements browser capabilities for lib-jitsi-meet.\n */\nexport default class BrowserCapabilities extends BrowserDetection {\n /**\n * Creates new BrowserCapabilities instance.\n */\n constructor() {\n super();\n logger.info(\n `This appears to be ${this.getName()}, ver: ${this.getVersion()}`);\n }\n\n /**\n * Tells whether or not the MediaStream/tt> is removed from\n * the PeerConnection and disposed on video mute (in order to turn\n * off the camera device).\n * @return {boolean} true if the current browser supports this\n * strategy or false otherwise.\n */\n doesVideoMuteByStreamRemove() {\n return !(\n this.isFirefox()\n || this.isEdge()\n || this.isReactNative()\n || this.isSafariWithWebrtc()\n );\n }\n\n /**\n * Check whether or not the current browser support peer to peer connections\n * @return {boolean} true if p2p is supported or false\n * otherwise.\n */\n supportsP2P() {\n return !this.isEdge() && !this.isFirefox();\n }\n\n /**\n * Checks if the current browser is Chromium based, that is, it's either\n * Chrome / Chromium or uses it as its engine, but doesn't identify as\n * Chrome.\n *\n * This includes the following browsers:\n * - Chrome and Chromium\n * - Other browsers which use the Chrome engine, but are detected as Chrome,\n * such as Brave and Vivaldi\n * - Browsers which are NOT Chrome but use it as their engine, and have\n * custom detection code: Opera, Electron and NW.JS\n */\n isChromiumBased() {\n return this.isChrome()\n || this.isElectron()\n || this.isNWJS()\n || this.isOpera();\n }\n\n /**\n * Checks if current browser is a Safari and a version of Safari that\n * supports native webrtc.\n *\n * @returns {boolean}\n */\n isSafariWithWebrtc() {\n return this.isSafari()\n && !this.isVersionLessThan('11');\n }\n\n /**\n * Checks if current browser is a Safari and a version of Safari that\n * supports VP8.\n *\n * @returns {boolean}\n */\n isSafariWithVP8() {\n return this.isSafari()\n && !this.isVersionLessThan('12.1');\n }\n\n /**\n * Checks if the current browser is supported.\n *\n * @returns {boolean} true if the browser is supported, false otherwise.\n */\n isSupported() {\n return this.isChromiumBased()\n || this.isFirefox()\n || this.isReactNative()\n || this.isSafariWithWebrtc();\n }\n\n /**\n * Returns whether or not the current environment needs a user interaction\n * with the page before any unmute can occur.\n *\n * @returns {boolean}\n */\n isUserInteractionRequiredForUnmute() {\n return (this.isFirefox() && this.isVersionLessThan('68')) || this.isSafari();\n }\n\n /**\n * Checks if the current browser triggers 'onmute'/'onunmute' events when\n * user's connection is interrupted and the video stops playback.\n * @returns {*|boolean} 'true' if the event is supported or 'false'\n * otherwise.\n */\n supportsVideoMuteOnConnInterrupted() {\n return this.isChromiumBased() || this.isReactNative()\n || this.isSafariWithVP8();\n }\n\n /**\n * Checks if the current browser reports upload and download bandwidth\n * statistics.\n * @return {boolean}\n */\n supportsBandwidthStatistics() {\n // FIXME bandwidth stats are currently not implemented for FF on our\n // side, but not sure if not possible ?\n return !this.isFirefox() && !this.isEdge()\n && !this.isSafariWithWebrtc();\n }\n\n /**\n * Checks if the current browser supports WebRTC datachannels.\n * @return {boolean}\n */\n supportsDataChannels() {\n // NOTE: Edge does not yet implement DataChannel.\n return !this.isEdge();\n }\n\n /**\n * Checks if the current browser support the device change event.\n * @return {boolean}\n */\n supportsDeviceChangeEvent() {\n return navigator.mediaDevices\n && typeof navigator.mediaDevices.ondevicechange !== 'undefined'\n && typeof navigator.mediaDevices.addEventListener !== 'undefined';\n }\n\n /**\n * Checks if the current browser supports RTP statictics collecting.\n * Required by {@link RTPStatsCollector}.\n *\n * @returns {boolean} true if they are supported, false otherwise.\n */\n supportsRtpStatistics() {\n return this.isChromiumBased()\n || this.isEdge()\n || this.isFirefox()\n || this.isReactNative()\n || this.isSafariWithWebrtc();\n }\n\n /**\n * Checks if the current browser supports RTT statistics for srflx local\n * candidates through the legacy getStats() API.\n */\n supportsLocalCandidateRttStatistics() {\n return this.isChromiumBased() || this.isReactNative()\n || this.isSafariWithVP8();\n }\n\n /**\n * Checks if the current browser reports round trip time statistics for\n * the ICE candidate pair.\n * @return {boolean}\n */\n supportsRTTStatistics() {\n // Firefox does not seem to report RTT for ICE candidate pair:\n // eslint-disable-next-line max-len\n // https://www.w3.org/TR/webrtc-stats/#dom-rtcicecandidatepairstats-currentroundtriptime\n // It does report mozRTT for RTP streams, but at the time of this\n // writing it's value does not make sense most of the time\n // (is reported as 1):\n // https://bugzilla.mozilla.org/show_bug.cgi?id=1241066\n // For Chrome and others we rely on 'googRtt'.\n return !this.isFirefox() && !this.isEdge();\n }\n\n /**\n * Checks whether the browser supports RTPSender.\n *\n * @returns {boolean}\n */\n supportsRtpSender() {\n return this.isFirefox() || this.isSafariWithVP8();\n }\n\n /**\n * Checks whether the browser supports RTX.\n *\n * @returns {boolean}\n */\n supportsRtx() {\n return !this.isFirefox() && !this.usesUnifiedPlan();\n }\n\n /**\n * Whether jitsi-meet supports simulcast on the current browser.\n * @returns {boolean}\n */\n supportsSimulcast() {\n return this.isChromiumBased() || this.isFirefox()\n || this.isSafariWithVP8() || this.isReactNative();\n }\n\n /**\n * Returns whether or not the current browser can support capturing video,\n * be it camera or desktop, and displaying received video.\n *\n * @returns {boolean}\n */\n supportsVideo() {\n // FIXME: Check if we can use supportsVideoOut and supportsVideoIn. I\n // leave the old implementation here in order not to brake something.\n\n // Older versions of Safari using webrtc/adapter do not support video\n // due in part to Safari only supporting H264 and the bridge sending VP8\n // Newer Safari support VP8 and other WebRTC features.\n return !this.isSafariWithWebrtc()\n || (this.isSafariWithVP8() && this.usesPlanB());\n }\n\n /**\n * Checks if the browser uses plan B.\n *\n * @returns {boolean}\n */\n usesPlanB() {\n return !this.usesUnifiedPlan();\n }\n\n /**\n * Checks if the browser uses unified plan.\n *\n * @returns {boolean}\n */\n usesUnifiedPlan() {\n if (this.isFirefox()) {\n return true;\n }\n\n if (this.isSafariWithVP8() && typeof window.RTCRtpTransceiver !== 'undefined') {\n // eslint-disable-next-line max-len\n // https://trac.webkit.org/changeset/236144/webkit/trunk/LayoutTests/webrtc/video-addLegacyTransceiver.html\n // eslint-disable-next-line no-undef\n return Object.keys(RTCRtpTransceiver.prototype)\n .indexOf('currentDirection') > -1;\n }\n\n return false;\n }\n\n /**\n * Returns whether or not the current browser should be using the new\n * getUserMedia flow, which utilizes the adapter shim. This method should\n * be temporary and used while migrating all browsers to use adapter and\n * the new getUserMedia.\n *\n * @returns {boolean}\n */\n usesNewGumFlow() {\n const REQUIRED_CHROME_VERSION = 61;\n\n if (this.isChrome()) {\n return !this.isVersionLessThan(REQUIRED_CHROME_VERSION);\n }\n\n if (this.isFirefox() || this.isSafariWithWebrtc()) {\n return true;\n }\n\n if (this.isChromiumBased()) {\n return this._getChromiumBasedVersion() >= REQUIRED_CHROME_VERSION;\n }\n\n return false;\n }\n\n /**\n * Checks if the browser uses webrtc-adapter. All browsers using the new\n * getUserMedia flow and Edge.\n *\n * @returns {boolean}\n */\n usesAdapter() {\n return this.usesNewGumFlow() || this.isEdge();\n }\n\n /**\n * Checks if the browser supports getDisplayMedia.\n * @returns {boolean} {@code true} if the browser supports getDisplayMedia.\n */\n supportsGetDisplayMedia() {\n return typeof navigator.getDisplayMedia !== 'undefined'\n || (typeof navigator.mediaDevices !== 'undefined'\n && typeof navigator.mediaDevices.getDisplayMedia\n !== 'undefined');\n }\n\n /**\n * Checks if the browser supports the \"sdpSemantics\" configuration option.\n * https://webrtc.org/web-apis/chrome/unified-plan/\n *\n * @returns {boolean}\n */\n supportsSdpSemantics() {\n return this.isChromiumBased() && this._getChromiumBasedVersion() >= 65;\n }\n\n /**\n * Returns the version of a Chromium based browser.\n *\n * @returns {Number}\n */\n _getChromiumBasedVersion() {\n if (this.isChromiumBased()) {\n // NW.JS doesn't expose the Chrome version in the UA string.\n if (this.isNWJS()) {\n // eslint-disable-next-line no-undef\n return Number.parseInt(process.versions.chromium, 10);\n }\n\n // Here we process all browsers which use the Chrome engine but\n // don't necessarily identify as Chrome. We cannot use the version\n // comparing functions because the Electron, Opera and NW.JS\n // versions are inconsequential here, as we need to know the actual\n // Chrome engine version.\n const ua = navigator.userAgent;\n\n if (ua.match(/Chrome/)) {\n const version\n = Number.parseInt(ua.match(/Chrome\\/([\\d.]+)/)[1], 10);\n\n return version;\n }\n }\n\n return -1;\n }\n}\n","/**\n * [js-md5]{@link https://github.com/emn178/js-md5}\n *\n * @namespace md5\n * @version 0.7.3\n * @author Chen, Yi-Cyuan [emn178@gmail.com]\n * @copyright Chen, Yi-Cyuan 2014-2017\n * @license MIT\n */\n(function () {\n 'use strict';\n\n var ERROR = 'input is invalid type';\n var WINDOW = typeof window === 'object';\n var root = WINDOW ? window : {};\n if (root.JS_MD5_NO_WINDOW) {\n WINDOW = false;\n }\n var WEB_WORKER = !WINDOW && typeof self === 'object';\n var NODE_JS = !root.JS_MD5_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;\n if (NODE_JS) {\n root = global;\n } else if (WEB_WORKER) {\n root = self;\n }\n var COMMON_JS = !root.JS_MD5_NO_COMMON_JS && typeof module === 'object' && module.exports;\n var AMD = typeof define === 'function' && define.amd;\n var ARRAY_BUFFER = !root.JS_MD5_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';\n var HEX_CHARS = '0123456789abcdef'.split('');\n var EXTRA = [128, 32768, 8388608, -2147483648];\n var SHIFT = [0, 8, 16, 24];\n var OUTPUT_TYPES = ['hex', 'array', 'digest', 'buffer', 'arrayBuffer', 'base64'];\n var BASE64_ENCODE_CHAR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');\n\n var blocks = [], buffer8;\n if (ARRAY_BUFFER) {\n var buffer = new ArrayBuffer(68);\n buffer8 = new Uint8Array(buffer);\n blocks = new Uint32Array(buffer);\n }\n\n if (root.JS_MD5_NO_NODE_JS || !Array.isArray) {\n Array.isArray = function (obj) {\n return Object.prototype.toString.call(obj) === '[object Array]';\n };\n }\n\n if (ARRAY_BUFFER && (root.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) {\n ArrayBuffer.isView = function (obj) {\n return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer;\n };\n }\n\n /**\n * @method hex\n * @memberof md5\n * @description Output hash as hex string\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {String} Hex string\n * @example\n * md5.hex('The quick brown fox jumps over the lazy dog');\n * // equal to\n * md5('The quick brown fox jumps over the lazy dog');\n */\n /**\n * @method digest\n * @memberof md5\n * @description Output hash as bytes array\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {Array} Bytes array\n * @example\n * md5.digest('The quick brown fox jumps over the lazy dog');\n */\n /**\n * @method array\n * @memberof md5\n * @description Output hash as bytes array\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {Array} Bytes array\n * @example\n * md5.array('The quick brown fox jumps over the lazy dog');\n */\n /**\n * @method arrayBuffer\n * @memberof md5\n * @description Output hash as ArrayBuffer\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {ArrayBuffer} ArrayBuffer\n * @example\n * md5.arrayBuffer('The quick brown fox jumps over the lazy dog');\n */\n /**\n * @method buffer\n * @deprecated This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.\n * @memberof md5\n * @description Output hash as ArrayBuffer\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {ArrayBuffer} ArrayBuffer\n * @example\n * md5.buffer('The quick brown fox jumps over the lazy dog');\n */\n /**\n * @method base64\n * @memberof md5\n * @description Output hash as base64 string\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {String} base64 string\n * @example\n * md5.base64('The quick brown fox jumps over the lazy dog');\n */\n var createOutputMethod = function (outputType) {\n return function (message) {\n return new Md5(true).update(message)[outputType]();\n };\n };\n\n /**\n * @method create\n * @memberof md5\n * @description Create Md5 object\n * @returns {Md5} Md5 object.\n * @example\n * var hash = md5.create();\n */\n /**\n * @method update\n * @memberof md5\n * @description Create and update Md5 object\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {Md5} Md5 object.\n * @example\n * var hash = md5.update('The quick brown fox jumps over the lazy dog');\n * // equal to\n * var hash = md5.create();\n * hash.update('The quick brown fox jumps over the lazy dog');\n */\n var createMethod = function () {\n var method = createOutputMethod('hex');\n if (NODE_JS) {\n method = nodeWrap(method);\n }\n method.create = function () {\n return new Md5();\n };\n method.update = function (message) {\n return method.create().update(message);\n };\n for (var i = 0; i < OUTPUT_TYPES.length; ++i) {\n var type = OUTPUT_TYPES[i];\n method[type] = createOutputMethod(type);\n }\n return method;\n };\n\n var nodeWrap = function (method) {\n var crypto = eval(\"require('crypto')\");\n var Buffer = eval(\"require('buffer').Buffer\");\n var nodeMethod = function (message) {\n if (typeof message === 'string') {\n return crypto.createHash('md5').update(message, 'utf8').digest('hex');\n } else {\n if (message === null || message === undefined) {\n throw ERROR;\n } else if (message.constructor === ArrayBuffer) {\n message = new Uint8Array(message);\n }\n }\n if (Array.isArray(message) || ArrayBuffer.isView(message) ||\n message.constructor === Buffer) {\n return crypto.createHash('md5').update(new Buffer(message)).digest('hex');\n } else {\n return method(message);\n }\n };\n return nodeMethod;\n };\n\n /**\n * Md5 class\n * @class Md5\n * @description This is internal class.\n * @see {@link md5.create}\n */\n function Md5(sharedMemory) {\n if (sharedMemory) {\n blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] =\n blocks[4] = blocks[5] = blocks[6] = blocks[7] =\n blocks[8] = blocks[9] = blocks[10] = blocks[11] =\n blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;\n this.blocks = blocks;\n this.buffer8 = buffer8;\n } else {\n if (ARRAY_BUFFER) {\n var buffer = new ArrayBuffer(68);\n this.buffer8 = new Uint8Array(buffer);\n this.blocks = new Uint32Array(buffer);\n } else {\n this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n }\n }\n this.h0 = this.h1 = this.h2 = this.h3 = this.start = this.bytes = this.hBytes = 0;\n this.finalized = this.hashed = false;\n this.first = true;\n }\n\n /**\n * @method update\n * @memberof Md5\n * @instance\n * @description Update hash\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {Md5} Md5 object.\n * @see {@link md5.update}\n */\n Md5.prototype.update = function (message) {\n if (this.finalized) {\n return;\n }\n\n var notString, type = typeof message;\n if (type !== 'string') {\n if (type === 'object') {\n if (message === null) {\n throw ERROR;\n } else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) {\n message = new Uint8Array(message);\n } else if (!Array.isArray(message)) {\n if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) {\n throw ERROR;\n }\n }\n } else {\n throw ERROR;\n }\n notString = true;\n }\n var code, index = 0, i, length = message.length, blocks = this.blocks;\n var buffer8 = this.buffer8;\n\n while (index < length) {\n if (this.hashed) {\n this.hashed = false;\n blocks[0] = blocks[16];\n blocks[16] = blocks[1] = blocks[2] = blocks[3] =\n blocks[4] = blocks[5] = blocks[6] = blocks[7] =\n blocks[8] = blocks[9] = blocks[10] = blocks[11] =\n blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;\n }\n\n if (notString) {\n if (ARRAY_BUFFER) {\n for (i = this.start; index < length && i < 64; ++index) {\n buffer8[i++] = message[index];\n }\n } else {\n for (i = this.start; index < length && i < 64; ++index) {\n blocks[i >> 2] |= message[index] << SHIFT[i++ & 3];\n }\n }\n } else {\n if (ARRAY_BUFFER) {\n for (i = this.start; index < length && i < 64; ++index) {\n code = message.charCodeAt(index);\n if (code < 0x80) {\n buffer8[i++] = code;\n } else if (code < 0x800) {\n buffer8[i++] = 0xc0 | (code >> 6);\n buffer8[i++] = 0x80 | (code & 0x3f);\n } else if (code < 0xd800 || code >= 0xe000) {\n buffer8[i++] = 0xe0 | (code >> 12);\n buffer8[i++] = 0x80 | ((code >> 6) & 0x3f);\n buffer8[i++] = 0x80 | (code & 0x3f);\n } else {\n code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));\n buffer8[i++] = 0xf0 | (code >> 18);\n buffer8[i++] = 0x80 | ((code >> 12) & 0x3f);\n buffer8[i++] = 0x80 | ((code >> 6) & 0x3f);\n buffer8[i++] = 0x80 | (code & 0x3f);\n }\n }\n } else {\n for (i = this.start; index < length && i < 64; ++index) {\n code = message.charCodeAt(index);\n if (code < 0x80) {\n blocks[i >> 2] |= code << SHIFT[i++ & 3];\n } else if (code < 0x800) {\n blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3];\n blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];\n } else if (code < 0xd800 || code >= 0xe000) {\n blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3];\n blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];\n blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];\n } else {\n code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));\n blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3];\n blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3];\n blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];\n blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];\n }\n }\n }\n }\n this.lastByteIndex = i;\n this.bytes += i - this.start;\n if (i >= 64) {\n this.start = i - 64;\n this.hash();\n this.hashed = true;\n } else {\n this.start = i;\n }\n }\n if (this.bytes > 4294967295) {\n this.hBytes += this.bytes / 4294967296 << 0;\n this.bytes = this.bytes % 4294967296;\n }\n return this;\n };\n\n Md5.prototype.finalize = function () {\n if (this.finalized) {\n return;\n }\n this.finalized = true;\n var blocks = this.blocks, i = this.lastByteIndex;\n blocks[i >> 2] |= EXTRA[i & 3];\n if (i >= 56) {\n if (!this.hashed) {\n this.hash();\n }\n blocks[0] = blocks[16];\n blocks[16] = blocks[1] = blocks[2] = blocks[3] =\n blocks[4] = blocks[5] = blocks[6] = blocks[7] =\n blocks[8] = blocks[9] = blocks[10] = blocks[11] =\n blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;\n }\n blocks[14] = this.bytes << 3;\n blocks[15] = this.hBytes << 3 | this.bytes >>> 29;\n this.hash();\n };\n\n Md5.prototype.hash = function () {\n var a, b, c, d, bc, da, blocks = this.blocks;\n\n if (this.first) {\n a = blocks[0] - 680876937;\n a = (a << 7 | a >>> 25) - 271733879 << 0;\n d = (-1732584194 ^ a & 2004318071) + blocks[1] - 117830708;\n d = (d << 12 | d >>> 20) + a << 0;\n c = (-271733879 ^ (d & (a ^ -271733879))) + blocks[2] - 1126478375;\n c = (c << 17 | c >>> 15) + d << 0;\n b = (a ^ (c & (d ^ a))) + blocks[3] - 1316259209;\n b = (b << 22 | b >>> 10) + c << 0;\n } else {\n a = this.h0;\n b = this.h1;\n c = this.h2;\n d = this.h3;\n a += (d ^ (b & (c ^ d))) + blocks[0] - 680876936;\n a = (a << 7 | a >>> 25) + b << 0;\n d += (c ^ (a & (b ^ c))) + blocks[1] - 389564586;\n d = (d << 12 | d >>> 20) + a << 0;\n c += (b ^ (d & (a ^ b))) + blocks[2] + 606105819;\n c = (c << 17 | c >>> 15) + d << 0;\n b += (a ^ (c & (d ^ a))) + blocks[3] - 1044525330;\n b = (b << 22 | b >>> 10) + c << 0;\n }\n\n a += (d ^ (b & (c ^ d))) + blocks[4] - 176418897;\n a = (a << 7 | a >>> 25) + b << 0;\n d += (c ^ (a & (b ^ c))) + blocks[5] + 1200080426;\n d = (d << 12 | d >>> 20) + a << 0;\n c += (b ^ (d & (a ^ b))) + blocks[6] - 1473231341;\n c = (c << 17 | c >>> 15) + d << 0;\n b += (a ^ (c & (d ^ a))) + blocks[7] - 45705983;\n b = (b << 22 | b >>> 10) + c << 0;\n a += (d ^ (b & (c ^ d))) + blocks[8] + 1770035416;\n a = (a << 7 | a >>> 25) + b << 0;\n d += (c ^ (a & (b ^ c))) + blocks[9] - 1958414417;\n d = (d << 12 | d >>> 20) + a << 0;\n c += (b ^ (d & (a ^ b))) + blocks[10] - 42063;\n c = (c << 17 | c >>> 15) + d << 0;\n b += (a ^ (c & (d ^ a))) + blocks[11] - 1990404162;\n b = (b << 22 | b >>> 10) + c << 0;\n a += (d ^ (b & (c ^ d))) + blocks[12] + 1804603682;\n a = (a << 7 | a >>> 25) + b << 0;\n d += (c ^ (a & (b ^ c))) + blocks[13] - 40341101;\n d = (d << 12 | d >>> 20) + a << 0;\n c += (b ^ (d & (a ^ b))) + blocks[14] - 1502002290;\n c = (c << 17 | c >>> 15) + d << 0;\n b += (a ^ (c & (d ^ a))) + blocks[15] + 1236535329;\n b = (b << 22 | b >>> 10) + c << 0;\n a += (c ^ (d & (b ^ c))) + blocks[1] - 165796510;\n a = (a << 5 | a >>> 27) + b << 0;\n d += (b ^ (c & (a ^ b))) + blocks[6] - 1069501632;\n d = (d << 9 | d >>> 23) + a << 0;\n c += (a ^ (b & (d ^ a))) + blocks[11] + 643717713;\n c = (c << 14 | c >>> 18) + d << 0;\n b += (d ^ (a & (c ^ d))) + blocks[0] - 373897302;\n b = (b << 20 | b >>> 12) + c << 0;\n a += (c ^ (d & (b ^ c))) + blocks[5] - 701558691;\n a = (a << 5 | a >>> 27) + b << 0;\n d += (b ^ (c & (a ^ b))) + blocks[10] + 38016083;\n d = (d << 9 | d >>> 23) + a << 0;\n c += (a ^ (b & (d ^ a))) + blocks[15] - 660478335;\n c = (c << 14 | c >>> 18) + d << 0;\n b += (d ^ (a & (c ^ d))) + blocks[4] - 405537848;\n b = (b << 20 | b >>> 12) + c << 0;\n a += (c ^ (d & (b ^ c))) + blocks[9] + 568446438;\n a = (a << 5 | a >>> 27) + b << 0;\n d += (b ^ (c & (a ^ b))) + blocks[14] - 1019803690;\n d = (d << 9 | d >>> 23) + a << 0;\n c += (a ^ (b & (d ^ a))) + blocks[3] - 187363961;\n c = (c << 14 | c >>> 18) + d << 0;\n b += (d ^ (a & (c ^ d))) + blocks[8] + 1163531501;\n b = (b << 20 | b >>> 12) + c << 0;\n a += (c ^ (d & (b ^ c))) + blocks[13] - 1444681467;\n a = (a << 5 | a >>> 27) + b << 0;\n d += (b ^ (c & (a ^ b))) + blocks[2] - 51403784;\n d = (d << 9 | d >>> 23) + a << 0;\n c += (a ^ (b & (d ^ a))) + blocks[7] + 1735328473;\n c = (c << 14 | c >>> 18) + d << 0;\n b += (d ^ (a & (c ^ d))) + blocks[12] - 1926607734;\n b = (b << 20 | b >>> 12) + c << 0;\n bc = b ^ c;\n a += (bc ^ d) + blocks[5] - 378558;\n a = (a << 4 | a >>> 28) + b << 0;\n d += (bc ^ a) + blocks[8] - 2022574463;\n d = (d << 11 | d >>> 21) + a << 0;\n da = d ^ a;\n c += (da ^ b) + blocks[11] + 1839030562;\n c = (c << 16 | c >>> 16) + d << 0;\n b += (da ^ c) + blocks[14] - 35309556;\n b = (b << 23 | b >>> 9) + c << 0;\n bc = b ^ c;\n a += (bc ^ d) + blocks[1] - 1530992060;\n a = (a << 4 | a >>> 28) + b << 0;\n d += (bc ^ a) + blocks[4] + 1272893353;\n d = (d << 11 | d >>> 21) + a << 0;\n da = d ^ a;\n c += (da ^ b) + blocks[7] - 155497632;\n c = (c << 16 | c >>> 16) + d << 0;\n b += (da ^ c) + blocks[10] - 1094730640;\n b = (b << 23 | b >>> 9) + c << 0;\n bc = b ^ c;\n a += (bc ^ d) + blocks[13] + 681279174;\n a = (a << 4 | a >>> 28) + b << 0;\n d += (bc ^ a) + blocks[0] - 358537222;\n d = (d << 11 | d >>> 21) + a << 0;\n da = d ^ a;\n c += (da ^ b) + blocks[3] - 722521979;\n c = (c << 16 | c >>> 16) + d << 0;\n b += (da ^ c) + blocks[6] + 76029189;\n b = (b << 23 | b >>> 9) + c << 0;\n bc = b ^ c;\n a += (bc ^ d) + blocks[9] - 640364487;\n a = (a << 4 | a >>> 28) + b << 0;\n d += (bc ^ a) + blocks[12] - 421815835;\n d = (d << 11 | d >>> 21) + a << 0;\n da = d ^ a;\n c += (da ^ b) + blocks[15] + 530742520;\n c = (c << 16 | c >>> 16) + d << 0;\n b += (da ^ c) + blocks[2] - 995338651;\n b = (b << 23 | b >>> 9) + c << 0;\n a += (c ^ (b | ~d)) + blocks[0] - 198630844;\n a = (a << 6 | a >>> 26) + b << 0;\n d += (b ^ (a | ~c)) + blocks[7] + 1126891415;\n d = (d << 10 | d >>> 22) + a << 0;\n c += (a ^ (d | ~b)) + blocks[14] - 1416354905;\n c = (c << 15 | c >>> 17) + d << 0;\n b += (d ^ (c | ~a)) + blocks[5] - 57434055;\n b = (b << 21 | b >>> 11) + c << 0;\n a += (c ^ (b | ~d)) + blocks[12] + 1700485571;\n a = (a << 6 | a >>> 26) + b << 0;\n d += (b ^ (a | ~c)) + blocks[3] - 1894986606;\n d = (d << 10 | d >>> 22) + a << 0;\n c += (a ^ (d | ~b)) + blocks[10] - 1051523;\n c = (c << 15 | c >>> 17) + d << 0;\n b += (d ^ (c | ~a)) + blocks[1] - 2054922799;\n b = (b << 21 | b >>> 11) + c << 0;\n a += (c ^ (b | ~d)) + blocks[8] + 1873313359;\n a = (a << 6 | a >>> 26) + b << 0;\n d += (b ^ (a | ~c)) + blocks[15] - 30611744;\n d = (d << 10 | d >>> 22) + a << 0;\n c += (a ^ (d | ~b)) + blocks[6] - 1560198380;\n c = (c << 15 | c >>> 17) + d << 0;\n b += (d ^ (c | ~a)) + blocks[13] + 1309151649;\n b = (b << 21 | b >>> 11) + c << 0;\n a += (c ^ (b | ~d)) + blocks[4] - 145523070;\n a = (a << 6 | a >>> 26) + b << 0;\n d += (b ^ (a | ~c)) + blocks[11] - 1120210379;\n d = (d << 10 | d >>> 22) + a << 0;\n c += (a ^ (d | ~b)) + blocks[2] + 718787259;\n c = (c << 15 | c >>> 17) + d << 0;\n b += (d ^ (c | ~a)) + blocks[9] - 343485551;\n b = (b << 21 | b >>> 11) + c << 0;\n\n if (this.first) {\n this.h0 = a + 1732584193 << 0;\n this.h1 = b - 271733879 << 0;\n this.h2 = c - 1732584194 << 0;\n this.h3 = d + 271733878 << 0;\n this.first = false;\n } else {\n this.h0 = this.h0 + a << 0;\n this.h1 = this.h1 + b << 0;\n this.h2 = this.h2 + c << 0;\n this.h3 = this.h3 + d << 0;\n }\n };\n\n /**\n * @method hex\n * @memberof Md5\n * @instance\n * @description Output hash as hex string\n * @returns {String} Hex string\n * @see {@link md5.hex}\n * @example\n * hash.hex();\n */\n Md5.prototype.hex = function () {\n this.finalize();\n\n var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3;\n\n return HEX_CHARS[(h0 >> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] +\n HEX_CHARS[(h0 >> 12) & 0x0F] + HEX_CHARS[(h0 >> 8) & 0x0F] +\n HEX_CHARS[(h0 >> 20) & 0x0F] + HEX_CHARS[(h0 >> 16) & 0x0F] +\n HEX_CHARS[(h0 >> 28) & 0x0F] + HEX_CHARS[(h0 >> 24) & 0x0F] +\n HEX_CHARS[(h1 >> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] +\n HEX_CHARS[(h1 >> 12) & 0x0F] + HEX_CHARS[(h1 >> 8) & 0x0F] +\n HEX_CHARS[(h1 >> 20) & 0x0F] + HEX_CHARS[(h1 >> 16) & 0x0F] +\n HEX_CHARS[(h1 >> 28) & 0x0F] + HEX_CHARS[(h1 >> 24) & 0x0F] +\n HEX_CHARS[(h2 >> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] +\n HEX_CHARS[(h2 >> 12) & 0x0F] + HEX_CHARS[(h2 >> 8) & 0x0F] +\n HEX_CHARS[(h2 >> 20) & 0x0F] + HEX_CHARS[(h2 >> 16) & 0x0F] +\n HEX_CHARS[(h2 >> 28) & 0x0F] + HEX_CHARS[(h2 >> 24) & 0x0F] +\n HEX_CHARS[(h3 >> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] +\n HEX_CHARS[(h3 >> 12) & 0x0F] + HEX_CHARS[(h3 >> 8) & 0x0F] +\n HEX_CHARS[(h3 >> 20) & 0x0F] + HEX_CHARS[(h3 >> 16) & 0x0F] +\n HEX_CHARS[(h3 >> 28) & 0x0F] + HEX_CHARS[(h3 >> 24) & 0x0F];\n };\n\n /**\n * @method toString\n * @memberof Md5\n * @instance\n * @description Output hash as hex string\n * @returns {String} Hex string\n * @see {@link md5.hex}\n * @example\n * hash.toString();\n */\n Md5.prototype.toString = Md5.prototype.hex;\n\n /**\n * @method digest\n * @memberof Md5\n * @instance\n * @description Output hash as bytes array\n * @returns {Array} Bytes array\n * @see {@link md5.digest}\n * @example\n * hash.digest();\n */\n Md5.prototype.digest = function () {\n this.finalize();\n\n var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3;\n return [\n h0 & 0xFF, (h0 >> 8) & 0xFF, (h0 >> 16) & 0xFF, (h0 >> 24) & 0xFF,\n h1 & 0xFF, (h1 >> 8) & 0xFF, (h1 >> 16) & 0xFF, (h1 >> 24) & 0xFF,\n h2 & 0xFF, (h2 >> 8) & 0xFF, (h2 >> 16) & 0xFF, (h2 >> 24) & 0xFF,\n h3 & 0xFF, (h3 >> 8) & 0xFF, (h3 >> 16) & 0xFF, (h3 >> 24) & 0xFF\n ];\n };\n\n /**\n * @method array\n * @memberof Md5\n * @instance\n * @description Output hash as bytes array\n * @returns {Array} Bytes array\n * @see {@link md5.array}\n * @example\n * hash.array();\n */\n Md5.prototype.array = Md5.prototype.digest;\n\n /**\n * @method arrayBuffer\n * @memberof Md5\n * @instance\n * @description Output hash as ArrayBuffer\n * @returns {ArrayBuffer} ArrayBuffer\n * @see {@link md5.arrayBuffer}\n * @example\n * hash.arrayBuffer();\n */\n Md5.prototype.arrayBuffer = function () {\n this.finalize();\n\n var buffer = new ArrayBuffer(16);\n var blocks = new Uint32Array(buffer);\n blocks[0] = this.h0;\n blocks[1] = this.h1;\n blocks[2] = this.h2;\n blocks[3] = this.h3;\n return buffer;\n };\n\n /**\n * @method buffer\n * @deprecated This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.\n * @memberof Md5\n * @instance\n * @description Output hash as ArrayBuffer\n * @returns {ArrayBuffer} ArrayBuffer\n * @see {@link md5.buffer}\n * @example\n * hash.buffer();\n */\n Md5.prototype.buffer = Md5.prototype.arrayBuffer;\n\n /**\n * @method base64\n * @memberof Md5\n * @instance\n * @description Output hash as base64 string\n * @returns {String} base64 string\n * @see {@link md5.base64}\n * @example\n * hash.base64();\n */\n Md5.prototype.base64 = function () {\n var v1, v2, v3, base64Str = '', bytes = this.array();\n for (var i = 0; i < 15;) {\n v1 = bytes[i++];\n v2 = bytes[i++];\n v3 = bytes[i++];\n base64Str += BASE64_ENCODE_CHAR[v1 >>> 2] +\n BASE64_ENCODE_CHAR[(v1 << 4 | v2 >>> 4) & 63] +\n BASE64_ENCODE_CHAR[(v2 << 2 | v3 >>> 6) & 63] +\n BASE64_ENCODE_CHAR[v3 & 63];\n }\n v1 = bytes[i];\n base64Str += BASE64_ENCODE_CHAR[v1 >>> 2] +\n BASE64_ENCODE_CHAR[(v1 << 4) & 63] +\n '==';\n return base64Str;\n };\n\n var exports = createMethod();\n\n if (COMMON_JS) {\n module.exports = exports;\n } else {\n /**\n * @method md5\b\n * @description Md5 hash function, export to global in browsers.\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {String} md5 hashes\n * @example\n * md5(''); // d41d8cd98f00b204e9800998ecf8427e\n * md5('The quick brown fox jumps over the lazy dog'); // 9e107d9d372bb6826bd81d3542a419d6\n * md5('The quick brown fox jumps over the lazy dog.'); // e4d909c290d0fb1ca068ffaddf22cbd0\n *\n * // It also supports UTF-8 encoding\n * md5('中文'); // a7bac2239fcdcb3a067903d8077c4a07\n *\n * // It also supports byte `Array`, `Uint8Array`, `ArrayBuffer`\n * md5([]); // d41d8cd98f00b204e9800998ecf8427e\n * md5(new Uint8Array([])); // d41d8cd98f00b204e9800998ecf8427e\n */\n root.md5 = exports;\n if (AMD) {\n define(function () {\n return exports;\n });\n }\n }\n})();\n","import browser from '../browser';\nimport { browsers } from 'js-utils';\n\nimport * as StatisticsEvents from '../../service/statistics/Events';\nimport * as MediaType from '../../service/RTC/MediaType';\n\nconst GlobalOnErrorHandler = require('../util/GlobalOnErrorHandler');\nconst logger = require('jitsi-meet-logger').getLogger(__filename);\n\n/**\n * The lib-jitsi-meet browser-agnostic names of the browser-specific keys\n * reported by RTCPeerConnection#getStats mapped by browser.\n */\nconst KEYS_BY_BROWSER_TYPE = {};\n\nKEYS_BY_BROWSER_TYPE[browsers.FIREFOX] = {\n 'ssrc': 'ssrc',\n 'packetsReceived': 'packetsReceived',\n 'packetsLost': 'packetsLost',\n 'packetsSent': 'packetsSent',\n 'bytesReceived': 'bytesReceived',\n 'bytesSent': 'bytesSent',\n 'framerateMean': 'framerateMean',\n 'ip': 'ipAddress',\n 'port': 'portNumber',\n 'protocol': 'transport'\n};\nKEYS_BY_BROWSER_TYPE[browsers.CHROME] = {\n 'receiveBandwidth': 'googAvailableReceiveBandwidth',\n 'sendBandwidth': 'googAvailableSendBandwidth',\n 'remoteAddress': 'googRemoteAddress',\n 'transportType': 'googTransportType',\n 'localAddress': 'googLocalAddress',\n 'activeConnection': 'googActiveConnection',\n 'ssrc': 'ssrc',\n 'packetsReceived': 'packetsReceived',\n 'packetsSent': 'packetsSent',\n 'packetsLost': 'packetsLost',\n 'bytesReceived': 'bytesReceived',\n 'bytesSent': 'bytesSent',\n 'googFrameHeightReceived': 'googFrameHeightReceived',\n 'googFrameWidthReceived': 'googFrameWidthReceived',\n 'googFrameHeightSent': 'googFrameHeightSent',\n 'googFrameWidthSent': 'googFrameWidthSent',\n 'googFrameRateReceived': 'googFrameRateReceived',\n 'googFrameRateSent': 'googFrameRateSent',\n 'audioInputLevel': 'audioInputLevel',\n 'audioOutputLevel': 'audioOutputLevel',\n 'currentRoundTripTime': 'googRtt',\n 'remoteCandidateType': 'googRemoteCandidateType',\n 'localCandidateType': 'googLocalCandidateType',\n 'ip': 'ip',\n 'port': 'port',\n 'protocol': 'protocol'\n};\nKEYS_BY_BROWSER_TYPE[browsers.EDGE] = {\n 'sendBandwidth': 'googAvailableSendBandwidth',\n 'remoteAddress': 'remoteAddress',\n 'transportType': 'protocol',\n 'localAddress': 'localAddress',\n 'activeConnection': 'activeConnection',\n 'ssrc': 'ssrc',\n 'packetsReceived': 'packetsReceived',\n 'packetsSent': 'packetsSent',\n 'packetsLost': 'packetsLost',\n 'bytesReceived': 'bytesReceived',\n 'bytesSent': 'bytesSent',\n 'googFrameHeightReceived': 'frameHeight',\n 'googFrameWidthReceived': 'frameWidth',\n 'googFrameHeightSent': 'frameHeight',\n 'googFrameWidthSent': 'frameWidth',\n 'googFrameRateReceived': 'framesPerSecond',\n 'googFrameRateSent': 'framesPerSecond',\n 'audioInputLevel': 'audioLevel',\n 'audioOutputLevel': 'audioLevel',\n 'currentRoundTripTime': 'roundTripTime'\n};\nKEYS_BY_BROWSER_TYPE[browsers.OPERA]\n = KEYS_BY_BROWSER_TYPE[browsers.CHROME];\nKEYS_BY_BROWSER_TYPE[browsers.NWJS]\n = KEYS_BY_BROWSER_TYPE[browsers.CHROME];\nKEYS_BY_BROWSER_TYPE[browsers.ELECTRON]\n = KEYS_BY_BROWSER_TYPE[browsers.CHROME];\nKEYS_BY_BROWSER_TYPE[browsers.SAFARI]\n = KEYS_BY_BROWSER_TYPE[browsers.CHROME];\nKEYS_BY_BROWSER_TYPE[browsers.REACT_NATIVE]\n = KEYS_BY_BROWSER_TYPE[browsers.CHROME];\n\n/**\n * Calculates packet lost percent using the number of lost packets and the\n * number of all packet.\n * @param lostPackets the number of lost packets\n * @param totalPackets the number of all packets.\n * @returns {number} packet loss percent\n */\nfunction calculatePacketLoss(lostPackets, totalPackets) {\n if (!totalPackets || totalPackets <= 0\n || !lostPackets || lostPackets <= 0) {\n return 0;\n }\n\n return Math.round((lostPackets / totalPackets) * 100);\n}\n\n/**\n * Holds \"statistics\" for a single SSRC.\n * @constructor\n */\nfunction SsrcStats() {\n this.loss = {};\n this.bitrate = {\n download: 0,\n upload: 0\n };\n this.resolution = {};\n this.framerate = 0;\n}\n\n/**\n * Sets the \"loss\" object.\n * @param loss the value to set.\n */\nSsrcStats.prototype.setLoss = function(loss) {\n this.loss = loss || {};\n};\n\n/**\n * Sets resolution that belong to the ssrc represented by this instance.\n * @param resolution new resolution value to be set.\n */\nSsrcStats.prototype.setResolution = function(resolution) {\n this.resolution = resolution || {};\n};\n\n/**\n * Adds the \"download\" and \"upload\" fields from the \"bitrate\" parameter to\n * the respective fields of the \"bitrate\" field of this object.\n * @param bitrate an object holding the values to add.\n */\nSsrcStats.prototype.addBitrate = function(bitrate) {\n this.bitrate.download += bitrate.download;\n this.bitrate.upload += bitrate.upload;\n};\n\n/**\n * Resets the bit rate for given ssrc that belong to the peer\n * represented by this instance.\n */\nSsrcStats.prototype.resetBitrate = function() {\n this.bitrate.download = 0;\n this.bitrate.upload = 0;\n};\n\n/**\n * Sets the \"framerate\".\n * @param framerate the value to set.\n */\nSsrcStats.prototype.setFramerate = function(framerate) {\n this.framerate = framerate || 0;\n};\n\n/**\n *\n */\nfunction ConferenceStats() {\n\n /**\n * The bandwidth\n * @type {{}}\n */\n this.bandwidth = {};\n\n /**\n * The bit rate\n * @type {{}}\n */\n this.bitrate = {};\n\n /**\n * The packet loss rate\n * @type {{}}\n */\n this.packetLoss = null;\n\n /**\n * Array with the transport information.\n * @type {Array}\n */\n this.transport = [];\n}\n\n/* eslint-disable max-params */\n\n/**\n * StatsCollector registers for stats updates of given\n * peerconnection in given interval. On each update particular\n * stats are extracted and put in {@link SsrcStats} objects. Once the processing\n * is done audioLevelsUpdateCallback is called with this\n * instance as an event source.\n *\n * @param peerconnection WebRTC PeerConnection object.\n * @param audioLevelsInterval\n * @param statsInterval stats refresh interval given in ms.\n * @param eventEmitter\n * @constructor\n */\nexport default function StatsCollector(\n peerconnection,\n audioLevelsInterval,\n statsInterval,\n eventEmitter) {\n // StatsCollector depends entirely on the format of the reports returned by\n // RTCPeerConnection#getStats. Given that the value of\n // browser#getName() is very unlikely to change at runtime, it\n // makes sense to discover whether StatsCollector supports the executing\n // browser as soon as possible. Otherwise, (1) getStatValue would have to\n // needlessly check a \"static\" condition multiple times very very often and\n // (2) the lack of support for the executing browser would be discovered and\n // reported multiple times very very often too late in the execution in some\n // totally unrelated callback.\n /**\n * The browser type supported by this StatsCollector. In other words, the\n * type of the browser which initialized this StatsCollector\n * instance.\n * @private\n */\n this._browserType = browser.getName();\n const keys = KEYS_BY_BROWSER_TYPE[this._browserType];\n\n if (!keys) {\n // eslint-disable-next-line no-throw-literal\n throw `The browser type '${this._browserType}' isn't supported!`;\n }\n\n /**\n * Whether to use the Promise-based getStats API or not.\n * @type {boolean}\n */\n this._usesPromiseGetStats\n = browser.isSafariWithWebrtc() || browser.isFirefox();\n\n /**\n * The function which is to be used to retrieve the value associated in a\n * report returned by RTCPeerConnection#getStats with a lib-jitsi-meet\n * browser-agnostic name/key.\n *\n * @function\n * @private\n */\n this._getStatValue\n = this._usesPromiseGetStats\n ? this._defineNewGetStatValueMethod(keys)\n : this._defineGetStatValueMethod(keys);\n\n this.peerconnection = peerconnection;\n this.baselineAudioLevelsReport = null;\n this.currentAudioLevelsReport = null;\n this.currentStatsReport = null;\n this.previousStatsReport = null;\n this.audioLevelReportHistory = {};\n this.audioLevelsIntervalId = null;\n this.eventEmitter = eventEmitter;\n this.conferenceStats = new ConferenceStats();\n\n // Updates stats interval\n this.audioLevelsIntervalMilis = audioLevelsInterval;\n\n this.statsIntervalId = null;\n this.statsIntervalMilis = statsInterval;\n\n /**\n * Maps SSRC numbers to {@link SsrcStats}.\n * @type {MapgetStats method.\n * @param error an error that occurred on getStats call.\n */\nStatsCollector.prototype.errorCallback = function(error) {\n GlobalOnErrorHandler.callErrorHandler(error);\n logger.error('Get stats error', error);\n this.stop();\n};\n\n/**\n * Starts stats updates.\n */\nStatsCollector.prototype.start = function(startAudioLevelStats) {\n const self = this;\n\n if (startAudioLevelStats) {\n this.audioLevelsIntervalId = setInterval(\n () => {\n // Interval updates\n self.peerconnection.getStats(\n report => {\n let results = null;\n\n if (!report || !report.result\n || typeof report.result !== 'function') {\n results = report;\n } else {\n results = report.result();\n }\n self.currentAudioLevelsReport = results;\n if (this._usesPromiseGetStats) {\n self.processNewAudioLevelReport();\n } else {\n self.processAudioLevelReport();\n }\n\n self.baselineAudioLevelsReport\n = self.currentAudioLevelsReport;\n },\n error => self.errorCallback(error)\n );\n },\n self.audioLevelsIntervalMilis\n );\n }\n\n if (browser.supportsRtpStatistics()) {\n this.statsIntervalId = setInterval(\n () => {\n // Interval updates\n self.peerconnection.getStats(\n report => {\n let results = null;\n\n if (!report || !report.result\n || typeof report.result !== 'function') {\n // firefox\n results = report;\n } else {\n // chrome\n results = report.result();\n }\n\n self.currentStatsReport = results;\n try {\n if (this._usesPromiseGetStats) {\n self.processNewStatsReport();\n } else {\n self.processStatsReport();\n }\n } catch (e) {\n GlobalOnErrorHandler.callErrorHandler(e);\n logger.error(`Unsupported key:${e}`, e);\n }\n\n self.previousStatsReport = self.currentStatsReport;\n },\n error => self.errorCallback(error)\n );\n },\n self.statsIntervalMilis\n );\n }\n};\n\n/**\n * Defines a function which (1) is to be used as a StatsCollector method and (2)\n * gets the value from a specific report returned by RTCPeerConnection#getStats\n * associated with a lib-jitsi-meet browser-agnostic name.\n *\n * @param {Object.} keys the map of LibJitsi browser-agnostic\n * names to RTCPeerConnection#getStats browser-specific keys\n */\nStatsCollector.prototype._defineGetStatValueMethod = function(keys) {\n // Define the function which converts a lib-jitsi-meet browser-asnostic name\n // to a browser-specific key of a report returned by\n // RTCPeerConnection#getStats.\n const keyFromName = function(name) {\n const key = keys[name];\n\n if (key) {\n return key;\n }\n\n // eslint-disable-next-line no-throw-literal\n throw `The property '${name}' isn't supported!`;\n };\n\n // Define the function which retrieves the value from a specific report\n // returned by RTCPeerConnection#getStats associated with a given\n // browser-specific key.\n let itemStatByKey;\n\n switch (this._browserType) {\n case browsers.CHROME:\n case browsers.OPERA:\n case browsers.NWJS:\n case browsers.ELECTRON:\n // TODO What about other types of browser which are based on Chrome such\n // as NW.js? Every time we want to support a new type browser we have to\n // go and add more conditions (here and in multiple other places).\n // Cannot we do a feature detection instead of a browser type check? For\n // example, if item has a stat property of type function, then it's very\n // likely that whoever defined it wanted you to call it in order to\n // retrieve the value associated with a specific key.\n itemStatByKey = (item, key) => item.stat(key);\n break;\n case browsers.REACT_NATIVE:\n // The implementation provided by react-native-webrtc follows the\n // Objective-C WebRTC API: RTCStatsReport has a values property of type\n // Array in which each element is a key-value pair.\n itemStatByKey = function(item, key) {\n let value;\n\n item.values.some(pair => {\n if (pair.hasOwnProperty(key)) {\n value = pair[key];\n\n return true;\n }\n\n return false;\n\n });\n\n return value;\n };\n break;\n case browsers.EDGE:\n itemStatByKey = (item, key) => item[key];\n break;\n default:\n itemStatByKey = (item, key) => item[key];\n }\n\n // Compose the 2 functions defined above to get a function which retrieves\n // the value from a specific report returned by RTCPeerConnection#getStats\n // associated with a specific lib-jitsi-meet browser-agnostic name.\n return (item, name) => itemStatByKey(item, keyFromName(name));\n};\n\n/**\n * Obtains a stat value from given stat and converts it to a non-negative\n * number. If the value is either invalid or negative then 0 will be returned.\n * @param report\n * @param {string} name\n * @return {number}\n * @private\n */\nStatsCollector.prototype.getNonNegativeStat = function(report, name) {\n let value = this._getStatValue(report, name);\n\n if (typeof value !== 'number') {\n value = Number(value);\n }\n\n if (isNaN(value)) {\n return 0;\n }\n\n return Math.max(0, value);\n};\n\n/* eslint-disable no-continue */\n\n/**\n * Stats processing logic.\n */\nStatsCollector.prototype.processStatsReport = function() {\n if (!this.previousStatsReport) {\n return;\n }\n\n const getStatValue = this._getStatValue;\n const byteSentStats = {};\n\n for (const idx in this.currentStatsReport) {\n if (!this.currentStatsReport.hasOwnProperty(idx)) {\n continue;\n }\n const now = this.currentStatsReport[idx];\n\n // The browser API may return \"undefined\" values in the array\n if (!now) {\n continue;\n }\n\n try {\n const receiveBandwidth = getStatValue(now, 'receiveBandwidth');\n const sendBandwidth = getStatValue(now, 'sendBandwidth');\n\n if (receiveBandwidth || sendBandwidth) {\n this.conferenceStats.bandwidth = {\n 'download': Math.round(receiveBandwidth / 1000),\n 'upload': Math.round(sendBandwidth / 1000)\n };\n }\n } catch (e) { /* not supported*/ }\n\n if (now.type === 'googCandidatePair') {\n let active, ip, localCandidateType, localip,\n remoteCandidateType, rtt, type;\n\n try {\n active = getStatValue(now, 'activeConnection');\n if (!active) {\n continue;\n }\n\n ip = getStatValue(now, 'remoteAddress');\n type = getStatValue(now, 'transportType');\n localip = getStatValue(now, 'localAddress');\n localCandidateType = getStatValue(now, 'localCandidateType');\n remoteCandidateType = getStatValue(now, 'remoteCandidateType');\n rtt = this.getNonNegativeStat(now, 'currentRoundTripTime');\n } catch (e) { /* not supported*/ }\n if (!ip || !type || !localip || active !== 'true') {\n continue;\n }\n\n // Save the address unless it has been saved already.\n const conferenceStatsTransport = this.conferenceStats.transport;\n\n if (!conferenceStatsTransport.some(\n t =>\n t.ip === ip\n && t.type === type\n && t.localip === localip)) {\n conferenceStatsTransport.push({\n ip,\n type,\n localip,\n p2p: this.peerconnection.isP2P,\n localCandidateType,\n remoteCandidateType,\n rtt\n });\n }\n continue;\n }\n\n if (now.type === 'candidatepair') {\n // we need succeeded and selected pairs only\n if (now.state !== 'succeeded' || !now.selected) {\n continue;\n }\n\n const local = this.currentStatsReport[now.localCandidateId];\n const remote = this.currentStatsReport[now.remoteCandidateId];\n\n this.conferenceStats.transport.push({\n ip: `${remote.ipAddress}:${remote.portNumber}`,\n type: local.transport,\n localip: `${local.ipAddress}:${local.portNumber}`,\n p2p: this.peerconnection.isP2P,\n localCandidateType: local.candidateType,\n remoteCandidateType: remote.candidateType\n });\n }\n\n // NOTE: Edge's proprietary stats via RTCIceTransport.msGetStats().\n if (now.msType === 'transportdiagnostics') {\n this.conferenceStats.transport.push({\n ip: now.remoteAddress,\n type: now.protocol,\n localip: now.localAddress,\n p2p: this.peerconnection.isP2P\n });\n }\n\n if (now.type !== 'ssrc' && now.type !== 'outboundrtp'\n && now.type !== 'inboundrtp' && now.type !== 'track') {\n continue;\n }\n\n // NOTE: In Edge, stats with type \"inboundrtp\" and \"outboundrtp\" are\n // completely useless, so ignore them.\n if (browser.isEdge()\n && (now.type === 'inboundrtp' || now.type === 'outboundrtp')) {\n continue;\n }\n\n const before = this.previousStatsReport[idx];\n let ssrc = this.getNonNegativeStat(now, 'ssrc');\n\n // If type=\"track\", take the first SSRC from ssrcIds.\n if (now.type === 'track' && Array.isArray(now.ssrcIds)) {\n ssrc = Number(now.ssrcIds[0]);\n }\n\n if (!before || !ssrc) {\n continue;\n }\n\n // isRemote is available only in FF and is ignored in case of chrome\n // according to the spec\n // https://www.w3.org/TR/webrtc-stats/#dom-rtcrtpstreamstats-isremote\n // when isRemote is true indicates that the measurements were done at\n // the remote endpoint and reported in an RTCP RR/XR.\n // Fixes a problem where we are calculating local stats wrong adding\n // the sent bytes to the local download bitrate.\n // In new W3 stats spec, type=\"track\" has a remoteSource boolean\n // property.\n // Edge uses the new format, so skip this check.\n if (!browser.isEdge()\n && (now.isRemote === true || now.remoteSource === true)) {\n continue;\n }\n\n let ssrcStats = this.ssrc2stats.get(ssrc);\n\n if (!ssrcStats) {\n ssrcStats = new SsrcStats();\n this.ssrc2stats.set(ssrc, ssrcStats);\n }\n\n let isDownloadStream = true;\n let key = 'packetsReceived';\n let packetsNow = getStatValue(now, key);\n\n if (typeof packetsNow === 'undefined'\n || packetsNow === null || packetsNow === '') {\n isDownloadStream = false;\n key = 'packetsSent';\n packetsNow = getStatValue(now, key);\n if (typeof packetsNow === 'undefined' || packetsNow === null) {\n logger.warn('No packetsReceived nor packetsSent stat found');\n }\n }\n if (!packetsNow || packetsNow < 0) {\n packetsNow = 0;\n }\n\n const packetsBefore = this.getNonNegativeStat(before, key);\n const packetsDiff = Math.max(0, packetsNow - packetsBefore);\n\n const packetsLostNow\n = this.getNonNegativeStat(now, 'packetsLost');\n const packetsLostBefore\n = this.getNonNegativeStat(before, 'packetsLost');\n const packetsLostDiff = Math.max(0, packetsLostNow - packetsLostBefore);\n\n ssrcStats.setLoss({\n packetsTotal: packetsDiff + packetsLostDiff,\n packetsLost: packetsLostDiff,\n isDownloadStream\n });\n\n const bytesReceivedNow\n = this.getNonNegativeStat(now, 'bytesReceived');\n const bytesReceivedBefore\n = this.getNonNegativeStat(before, 'bytesReceived');\n const bytesReceived\n = Math.max(0, bytesReceivedNow - bytesReceivedBefore);\n\n let bytesSent = 0;\n\n // TODO: clean this mess up!\n let nowBytesTransmitted = getStatValue(now, 'bytesSent');\n\n if (typeof nowBytesTransmitted === 'number'\n || typeof nowBytesTransmitted === 'string') {\n nowBytesTransmitted = Number(nowBytesTransmitted);\n if (!isNaN(nowBytesTransmitted)) {\n byteSentStats[ssrc] = nowBytesTransmitted;\n if (nowBytesTransmitted > 0) {\n bytesSent = nowBytesTransmitted\n - getStatValue(before, 'bytesSent');\n }\n }\n }\n bytesSent = Math.max(0, bytesSent);\n\n const timeMs = now.timestamp - before.timestamp;\n let bitrateReceivedKbps = 0, bitrateSentKbps = 0;\n\n if (timeMs > 0) {\n // TODO is there any reason to round here?\n bitrateReceivedKbps = Math.round((bytesReceived * 8) / timeMs);\n bitrateSentKbps = Math.round((bytesSent * 8) / timeMs);\n }\n\n ssrcStats.addBitrate({\n 'download': bitrateReceivedKbps,\n 'upload': bitrateSentKbps\n });\n\n const resolution = {\n height: null,\n width: null\n };\n\n try {\n let height, width;\n\n if ((height = getStatValue(now, 'googFrameHeightReceived'))\n && (width = getStatValue(now, 'googFrameWidthReceived'))) {\n resolution.height = height;\n resolution.width = width;\n } else if ((height = getStatValue(now, 'googFrameHeightSent'))\n && (width = getStatValue(now, 'googFrameWidthSent'))) {\n resolution.height = height;\n resolution.width = width;\n }\n } catch (e) { /* not supported*/ }\n\n // Tries to get frame rate\n let frameRate;\n\n try {\n frameRate = getStatValue(now, 'googFrameRateReceived')\n || getStatValue(now, 'googFrameRateSent') || 0;\n } catch (e) {\n // if it fails with previous properties(chrome),\n // let's try with another one (FF)\n try {\n frameRate = this.getNonNegativeStat(now, 'framerateMean');\n } catch (err) { /* not supported*/ }\n }\n ssrcStats.setFramerate(Math.round(frameRate || 0));\n\n if (resolution.height && resolution.width) {\n ssrcStats.setResolution(resolution);\n } else {\n ssrcStats.setResolution(null);\n }\n }\n\n this.eventEmitter.emit(\n StatisticsEvents.BYTE_SENT_STATS, this.peerconnection, byteSentStats);\n\n this._processAndEmitReport();\n};\n\n/**\n *\n */\nStatsCollector.prototype._processAndEmitReport = function() {\n // process stats\n const totalPackets = {\n download: 0,\n upload: 0\n };\n const lostPackets = {\n download: 0,\n upload: 0\n };\n let bitrateDownload = 0;\n let bitrateUpload = 0;\n const resolutions = {};\n const framerates = {};\n let audioBitrateDownload = 0;\n let audioBitrateUpload = 0;\n let videoBitrateDownload = 0;\n let videoBitrateUpload = 0;\n\n for (const [ ssrc, ssrcStats ] of this.ssrc2stats) {\n // process packet loss stats\n const loss = ssrcStats.loss;\n const type = loss.isDownloadStream ? 'download' : 'upload';\n\n totalPackets[type] += loss.packetsTotal;\n lostPackets[type] += loss.packetsLost;\n\n // process bitrate stats\n bitrateDownload += ssrcStats.bitrate.download;\n bitrateUpload += ssrcStats.bitrate.upload;\n\n // collect resolutions and framerates\n const track = this.peerconnection.getTrackBySSRC(ssrc);\n\n if (track) {\n if (track.isAudioTrack()) {\n audioBitrateDownload += ssrcStats.bitrate.download;\n audioBitrateUpload += ssrcStats.bitrate.upload;\n } else {\n videoBitrateDownload += ssrcStats.bitrate.download;\n videoBitrateUpload += ssrcStats.bitrate.upload;\n }\n\n const participantId = track.getParticipantId();\n\n if (participantId) {\n const resolution = ssrcStats.resolution;\n\n if (resolution.width\n && resolution.height\n && resolution.width !== -1\n && resolution.height !== -1) {\n const userResolutions = resolutions[participantId] || {};\n\n userResolutions[ssrc] = resolution;\n resolutions[participantId] = userResolutions;\n }\n if (ssrcStats.framerate !== 0) {\n const userFramerates = framerates[participantId] || {};\n\n userFramerates[ssrc] = ssrcStats.framerate;\n framerates[participantId] = userFramerates;\n }\n } else {\n logger.error(`No participant ID returned by ${track}`);\n }\n }\n\n ssrcStats.resetBitrate();\n }\n\n this.conferenceStats.bitrate = {\n 'upload': bitrateUpload,\n 'download': bitrateDownload\n };\n\n this.conferenceStats.bitrate.audio = {\n 'upload': audioBitrateUpload,\n 'download': audioBitrateDownload\n };\n\n this.conferenceStats.bitrate.video = {\n 'upload': videoBitrateUpload,\n 'download': videoBitrateDownload\n };\n\n this.conferenceStats.packetLoss = {\n total:\n calculatePacketLoss(\n lostPackets.download + lostPackets.upload,\n totalPackets.download + totalPackets.upload),\n download:\n calculatePacketLoss(lostPackets.download, totalPackets.download),\n upload:\n calculatePacketLoss(lostPackets.upload, totalPackets.upload)\n };\n\n const avgAudioLevels = {};\n let localAvgAudioLevels;\n\n Object.keys(this.audioLevelReportHistory).forEach(ssrc => {\n const { data, isLocal } = this.audioLevelReportHistory[ssrc];\n const avgAudioLevel = data.reduce((sum, currentValue) => sum + currentValue) / data.length;\n\n if (isLocal) {\n localAvgAudioLevels = avgAudioLevel;\n } else {\n const track = this.peerconnection.getTrackBySSRC(Number(ssrc));\n\n if (track) {\n const participantId = track.getParticipantId();\n\n if (participantId) {\n avgAudioLevels[participantId] = avgAudioLevel;\n }\n }\n }\n });\n this.audioLevelReportHistory = {};\n\n this.eventEmitter.emit(\n StatisticsEvents.CONNECTION_STATS,\n this.peerconnection,\n {\n 'bandwidth': this.conferenceStats.bandwidth,\n 'bitrate': this.conferenceStats.bitrate,\n 'packetLoss': this.conferenceStats.packetLoss,\n 'resolution': resolutions,\n 'framerate': framerates,\n 'transport': this.conferenceStats.transport,\n localAvgAudioLevels,\n avgAudioLevels\n });\n this.conferenceStats.transport = [];\n};\n\n/**\n * Stats processing logic.\n */\nStatsCollector.prototype.processAudioLevelReport = function() {\n if (!this.baselineAudioLevelsReport) {\n return;\n }\n\n const getStatValue = this._getStatValue;\n\n for (const idx in this.currentAudioLevelsReport) {\n if (!this.currentAudioLevelsReport.hasOwnProperty(idx)) {\n continue;\n }\n\n const now = this.currentAudioLevelsReport[idx];\n\n if (now.type !== 'ssrc' && now.type !== 'track') {\n continue;\n }\n\n const before = this.baselineAudioLevelsReport[idx];\n let ssrc = this.getNonNegativeStat(now, 'ssrc');\n\n if (!ssrc && Array.isArray(now.ssrcIds)) {\n ssrc = Number(now.ssrcIds[0]);\n }\n\n if (!before) {\n logger.warn(`${ssrc} not enough data`);\n continue;\n }\n\n if (!ssrc) {\n if ((Date.now() - now.timestamp) < 3000) {\n logger.warn('No ssrc: ');\n }\n continue;\n }\n\n // Audio level\n let audioLevel;\n\n try {\n audioLevel\n = getStatValue(now, 'audioInputLevel')\n || getStatValue(now, 'audioOutputLevel');\n } catch (e) { /* not supported*/\n logger.warn('Audio Levels are not available in the statistics.');\n clearInterval(this.audioLevelsIntervalId);\n\n return;\n }\n\n if (audioLevel) {\n let isLocal;\n\n // If type=\"ssrc\" (legacy) check whether they are received packets.\n if (now.type === 'ssrc') {\n isLocal = !getStatValue(now, 'packetsReceived');\n\n // If type=\"track\", check remoteSource boolean property.\n } else {\n isLocal = !now.remoteSource;\n }\n\n // According to the W3C WebRTC Stats spec, audioLevel should be in\n // 0..1 range (0 == silence). However browsers don't behave that\n // way so we must convert it to 0..1.\n //\n // In Edge the range is -100..0 (-100 == silence) measured in dB,\n // so convert to linear. The levels are set to 0 for remote tracks,\n // so don't convert those, since 0 means \"the maximum\" in Edge.\n if (browser.isEdge()) {\n audioLevel = audioLevel < 0 ? Math.pow(10, audioLevel / 20) : 0;\n\n // TODO: Can't find specs about what this value really is, but it\n // seems to vary between 0 and around 32k.\n } else {\n audioLevel = audioLevel / 32767;\n }\n\n if (!(ssrc in this.audioLevelReportHistory)) {\n this.audioLevelReportHistory[ssrc] = {\n isLocal,\n data: []\n };\n }\n this.audioLevelReportHistory[ssrc].data.push(audioLevel);\n\n this.eventEmitter.emit(\n StatisticsEvents.AUDIO_LEVEL,\n this.peerconnection,\n ssrc,\n audioLevel,\n isLocal);\n }\n }\n};\n\n/* eslint-enable no-continue */\n\n/**\n * New promised based getStats report processing.\n * Tested with chrome, firefox and safari. Not switching it on for chrome as\n * frameRate stat is missing and calculating it using framesSent,\n * gives values double the values seen in webrtc-internals.\n * https://w3c.github.io/webrtc-stats/\n */\n\n/**\n * Defines a function which (1) is to be used as a StatsCollector method and (2)\n * gets the value from a specific report returned by RTCPeerConnection#getStats\n * associated with a lib-jitsi-meet browser-agnostic name in case of using\n * Promised based getStats.\n *\n * @param {Object.} keys the map of LibJitsi browser-agnostic\n * names to RTCPeerConnection#getStats browser-specific keys\n */\nStatsCollector.prototype._defineNewGetStatValueMethod = function(keys) {\n // Define the function which converts a lib-jitsi-meet browser-asnostic name\n // to a browser-specific key of a report returned by\n // RTCPeerConnection#getStats.\n const keyFromName = function(name) {\n const key = keys[name];\n\n if (key) {\n return key;\n }\n\n // eslint-disable-next-line no-throw-literal\n throw `The property '${name}' isn't supported!`;\n };\n\n // Compose the 2 functions defined above to get a function which retrieves\n // the value from a specific report returned by RTCPeerConnection#getStats\n // associated with a specific lib-jitsi-meet browser-agnostic name.\n return (item, name) => item[keyFromName(name)];\n};\n\n/**\n * Converts the value to a non-negative number.\n * If the value is either invalid or negative then 0 will be returned.\n * @param {*} v\n * @return {number}\n * @private\n */\nStatsCollector.prototype.getNonNegativeValue = function(v) {\n let value = v;\n\n if (typeof value !== 'number') {\n value = Number(value);\n }\n\n if (isNaN(value)) {\n return 0;\n }\n\n return Math.max(0, value);\n};\n\n/**\n * Calculates bitrate between before and now using a supplied field name and its\n * value in the stats.\n * @param {RTCInboundRtpStreamStats|RTCSentRtpStreamStats} now the current stats\n * @param {RTCInboundRtpStreamStats|RTCSentRtpStreamStats} before the\n * previous stats.\n * @param fieldName the field to use for calculations.\n * @return {number} the calculated bitrate between now and before.\n * @private\n */\nStatsCollector.prototype._calculateBitrate = function(now, before, fieldName) {\n const bytesNow = this.getNonNegativeValue(now[fieldName]);\n const bytesBefore = this.getNonNegativeValue(before[fieldName]);\n const bytesProcessed = Math.max(0, bytesNow - bytesBefore);\n\n const timeMs = now.timestamp - before.timestamp;\n let bitrateKbps = 0;\n\n if (timeMs > 0) {\n // TODO is there any reason to round here?\n bitrateKbps = Math.round((bytesProcessed * 8) / timeMs);\n }\n\n return bitrateKbps;\n};\n\n/**\n * Stats processing new getStats logic.\n */\nStatsCollector.prototype.processNewStatsReport = function() {\n if (!this.previousStatsReport) {\n return;\n }\n\n const getStatValue = this._getStatValue;\n const byteSentStats = {};\n\n this.currentStatsReport.forEach(now => {\n\n // RTCIceCandidatePairStats\n // https://w3c.github.io/webrtc-stats/#candidatepair-dict*\n if (now.type === 'candidate-pair'\n && now.nominated\n && now.state === 'succeeded') {\n\n const availableIncomingBitrate = now.availableIncomingBitrate;\n const availableOutgoingBitrate = now.availableOutgoingBitrate;\n\n if (availableIncomingBitrate || availableOutgoingBitrate) {\n this.conferenceStats.bandwidth = {\n 'download': Math.round(availableIncomingBitrate / 1000),\n 'upload': Math.round(availableOutgoingBitrate / 1000)\n };\n }\n\n const remoteUsedCandidate\n = this.currentStatsReport.get(now.remoteCandidateId);\n const localUsedCandidate\n = this.currentStatsReport.get(now.localCandidateId);\n\n // RTCIceCandidateStats\n // https://w3c.github.io/webrtc-stats/#icecandidate-dict*\n // safari currently does not provide ice candidates in stats\n if (remoteUsedCandidate && localUsedCandidate) {\n // FF uses non-standard ipAddress, portNumber, transport\n // instead of ip, port, protocol\n const remoteIpAddress = getStatValue(remoteUsedCandidate, 'ip');\n const remotePort = getStatValue(remoteUsedCandidate, 'port');\n const ip = `${remoteIpAddress}:${remotePort}`;\n\n const localIpAddress = getStatValue(localUsedCandidate, 'ip');\n const localPort = getStatValue(localUsedCandidate, 'port');\n\n const localIp = `${localIpAddress}:${localPort}`;\n const type = getStatValue(remoteUsedCandidate, 'protocol');\n\n // Save the address unless it has been saved already.\n const conferenceStatsTransport = this.conferenceStats.transport;\n\n if (!conferenceStatsTransport.some(\n t =>\n t.ip === ip\n && t.type === type\n && t.localip === localIp)) {\n conferenceStatsTransport.push({\n ip,\n type,\n localIp,\n p2p: this.peerconnection.isP2P,\n localCandidateType: localUsedCandidate.candidateType,\n remoteCandidateType: remoteUsedCandidate.candidateType,\n networkType: localUsedCandidate.networkType,\n rtt: now.currentRoundTripTime * 1000\n });\n }\n }\n\n // RTCReceivedRtpStreamStats\n // https://w3c.github.io/webrtc-stats/#receivedrtpstats-dict*\n // RTCSentRtpStreamStats\n // https://w3c.github.io/webrtc-stats/#sentrtpstats-dict*\n } else if (now.type === 'inbound-rtp' || now.type === 'outbound-rtp') {\n const before = this.previousStatsReport.get(now.id);\n const ssrc = this.getNonNegativeValue(now.ssrc);\n\n if (!before || !ssrc) {\n return;\n }\n\n let ssrcStats = this.ssrc2stats.get(ssrc);\n\n if (!ssrcStats) {\n ssrcStats = new SsrcStats();\n this.ssrc2stats.set(ssrc, ssrcStats);\n }\n\n let isDownloadStream = true;\n let key = 'packetsReceived';\n\n if (now.type === 'outbound-rtp') {\n isDownloadStream = false;\n key = 'packetsSent';\n }\n\n let packetsNow = now[key];\n\n if (!packetsNow || packetsNow < 0) {\n packetsNow = 0;\n }\n\n const packetsBefore = this.getNonNegativeValue(before[key]);\n const packetsDiff = Math.max(0, packetsNow - packetsBefore);\n\n const packetsLostNow\n = this.getNonNegativeValue(now.packetsLost);\n const packetsLostBefore\n = this.getNonNegativeValue(before.packetsLost);\n const packetsLostDiff\n = Math.max(0, packetsLostNow - packetsLostBefore);\n\n ssrcStats.setLoss({\n packetsTotal: packetsDiff + packetsLostDiff,\n packetsLost: packetsLostDiff,\n isDownloadStream\n });\n\n if (now.type === 'inbound-rtp') {\n\n ssrcStats.addBitrate({\n 'download': this._calculateBitrate(\n now, before, 'bytesReceived'),\n 'upload': 0\n });\n\n // RTCInboundRtpStreamStats\n // https://w3c.github.io/webrtc-stats/#inboundrtpstats-dict*\n // TODO: can we use framesDecoded for frame rate, available\n // in chrome\n } else {\n byteSentStats[ssrc] = this.getNonNegativeValue(now.bytesSent);\n ssrcStats.addBitrate({\n 'download': 0,\n 'upload': this._calculateBitrate(\n now, before, 'bytesSent')\n });\n\n // RTCOutboundRtpStreamStats\n // https://w3c.github.io/webrtc-stats/#outboundrtpstats-dict*\n // TODO: can we use framesEncoded for frame rate, available\n // in chrome\n }\n\n // FF has framerateMean out of spec\n const framerateMean = now.framerateMean;\n\n if (framerateMean) {\n ssrcStats.setFramerate(Math.round(framerateMean || 0));\n }\n\n // track for resolution\n // RTCVideoHandlerStats\n // https://w3c.github.io/webrtc-stats/#vststats-dict*\n // RTCMediaHandlerStats\n // https://w3c.github.io/webrtc-stats/#mststats-dict*\n } else if (now.type === 'track') {\n\n const resolution = {\n height: now.frameHeight,\n width: now.frameWidth\n };\n\n // Tries to get frame rate\n let frameRate = now.framesPerSecond;\n\n if (!frameRate) {\n // we need to calculate it\n const before = this.previousStatsReport.get(now.id);\n\n if (before) {\n const timeMs = now.timestamp - before.timestamp;\n\n if (timeMs > 0 && now.framesSent) {\n const numberOfFramesSinceBefore\n = now.framesSent - before.framesSent;\n\n frameRate = (numberOfFramesSinceBefore / timeMs) * 1000;\n }\n }\n\n if (!frameRate) {\n return;\n }\n }\n\n const trackIdentifier = now.trackIdentifier;\n const ssrc = this.peerconnection.getSsrcByTrackId(trackIdentifier);\n let ssrcStats = this.ssrc2stats.get(ssrc);\n\n if (!ssrcStats) {\n ssrcStats = new SsrcStats();\n this.ssrc2stats.set(ssrc, ssrcStats);\n }\n ssrcStats.setFramerate(Math.round(frameRate || 0));\n\n if (resolution.height && resolution.width) {\n ssrcStats.setResolution(resolution);\n } else {\n ssrcStats.setResolution(null);\n }\n }\n });\n\n this.eventEmitter.emit(\n StatisticsEvents.BYTE_SENT_STATS, this.peerconnection, byteSentStats);\n\n this._processAndEmitReport();\n};\n\n/**\n * Stats processing logic.\n */\nStatsCollector.prototype.processNewAudioLevelReport = function() {\n if (!this.baselineAudioLevelsReport) {\n return;\n }\n\n this.currentAudioLevelsReport.forEach(now => {\n if (now.type !== 'track') {\n return;\n }\n\n // Audio level\n const audioLevel = now.audioLevel;\n\n if (!audioLevel) {\n return;\n }\n\n const trackIdentifier = now.trackIdentifier;\n const ssrc = this.peerconnection.getSsrcByTrackId(trackIdentifier);\n\n if (ssrc) {\n const isLocal\n = ssrc === this.peerconnection.getLocalSSRC(\n this.peerconnection.getLocalTracks(MediaType.AUDIO));\n\n this.eventEmitter.emit(\n StatisticsEvents.AUDIO_LEVEL,\n this.peerconnection,\n ssrc,\n audioLevel,\n isLocal);\n }\n });\n};\n\n/**\n * End new promised based getStats processing methods.\n */\n","\nimport { Strophe } from 'strophe.js';\n\nimport { getLogger } from 'jitsi-meet-logger';\n\nimport * as JitsiConferenceEvents from './JitsiConferenceEvents';\nimport { ParticipantConnectionStatus }\n from './modules/connectivity/ParticipantConnectionStatus';\nimport * as MediaType from './service/RTC/MediaType';\n\nconst logger = getLogger(__filename);\n\n/**\n * Represents a participant in (i.e. a member of) a conference.\n */\nexport default class JitsiParticipant {\n\n /* eslint-disable max-params */\n\n /**\n * Initializes a new JitsiParticipant instance.\n *\n * @constructor\n * @param jid the conference XMPP jid\n * @param conference\n * @param displayName\n * @param {Boolean} hidden - True if the new JitsiParticipant instance is to\n * represent a hidden participant; otherwise, false.\n * @param {string} statsID - optional participant statsID\n * @param {string} status - the initial status if any.\n * @param {object} identity - the xmpp identity\n */\n constructor(jid, conference, displayName, hidden, statsID, status, identity) {\n this._jid = jid;\n this._id = Strophe.getResourceFromJid(jid);\n this._conference = conference;\n this._displayName = displayName;\n this._supportsDTMF = false;\n this._tracks = [];\n this._role = 'none';\n this._status = status;\n this._hidden = hidden;\n this._statsID = statsID;\n this._connectionStatus = ParticipantConnectionStatus.ACTIVE;\n this._properties = {};\n this._identity = identity;\n }\n\n /* eslint-enable max-params */\n\n /**\n * @returns {JitsiConference} The conference that this participant belongs\n * to.\n */\n getConference() {\n return this._conference;\n }\n\n /**\n * Gets the value of a property of this participant.\n */\n getProperty(name) {\n return this._properties[name];\n }\n\n /**\n * Checks whether this JitsiParticipant has any video tracks which\n * are muted according to their underlying WebRTC MediaStreamTrack\n * muted status.\n * @return {boolean} true if this participant contains any\n * video JitsiTracks which are muted as defined in\n * {@link JitsiTrack.isWebRTCTrackMuted}.\n */\n hasAnyVideoTrackWebRTCMuted() {\n return (\n this.getTracks().some(\n jitsiTrack =>\n jitsiTrack.getType() === MediaType.VIDEO\n && jitsiTrack.isWebRTCTrackMuted()));\n }\n\n /**\n * Updates participant's connection status.\n * @param {string} state the current participant connection state.\n * {@link ParticipantConnectionStatus}.\n * @private\n */\n _setConnectionStatus(status) {\n this._connectionStatus = status;\n }\n\n /**\n * Return participant's connectivity status.\n *\n * @returns {string} the connection status\n * ParticipantConnectionStatus of the user.\n * {@link ParticipantConnectionStatus}.\n */\n getConnectionStatus() {\n return this._connectionStatus;\n }\n\n /**\n * Sets the value of a property of this participant, and fires an event if\n * the value has changed.\n * @name the name of the property.\n * @value the value to set.\n */\n setProperty(name, value) {\n const oldValue = this._properties[name];\n\n if (value !== oldValue) {\n this._properties[name] = value;\n this._conference.eventEmitter.emit(\n JitsiConferenceEvents.PARTICIPANT_PROPERTY_CHANGED,\n this,\n name,\n oldValue,\n value);\n }\n }\n\n /**\n * @returns {Array.} The list of media tracks for this\n * participant.\n */\n getTracks() {\n return this._tracks.slice();\n }\n\n /**\n * @param {MediaType} mediaType\n * @returns {Array.} an array of media tracks for this\n * participant, for given media type.\n */\n getTracksByMediaType(mediaType) {\n return this.getTracks().filter(track => track.getType() === mediaType);\n }\n\n /**\n * @returns {String} The ID of this participant.\n */\n getId() {\n return this._id;\n }\n\n /**\n * @returns {String} The JID of this participant.\n */\n getJid() {\n return this._jid;\n }\n\n /**\n * @returns {String} The human-readable display name of this participant.\n */\n getDisplayName() {\n return this._displayName;\n }\n\n /**\n * @returns {String} The stats ID of this participant.\n */\n getStatsID() {\n return this._statsID;\n }\n\n /**\n * @returns {String} The status of the participant.\n */\n getStatus() {\n return this._status;\n }\n\n /**\n * @returns {Boolean} Whether this participant is a moderator or not.\n */\n isModerator() {\n return this._role === 'moderator';\n }\n\n /**\n * @returns {Boolean} Whether this participant is a hidden participant. Some\n * special system participants may want to join hidden (like for example the\n * recorder).\n */\n isHidden() {\n return this._hidden;\n }\n\n /**\n * @returns {Boolean} Whether this participant has muted their audio.\n */\n isAudioMuted() {\n return this._isMediaTypeMuted(MediaType.AUDIO);\n }\n\n /**\n * Determines whether all JitsiTracks which are of a specific MediaType and\n * which belong to this JitsiParticipant are muted.\n *\n * @param {MediaType} mediaType - The MediaType of the JitsiTracks to be\n * checked.\n * @private\n * @returns {Boolean} True if all JitsiTracks which are of the specified\n * mediaType and which belong to this JitsiParticipant are muted; otherwise,\n * false.\n */\n _isMediaTypeMuted(mediaType) {\n return this.getTracks().reduce(\n (muted, track) =>\n muted && (track.getType() !== mediaType || track.isMuted()),\n true);\n }\n\n /**\n * @returns {Boolean} Whether this participant has muted their video.\n */\n isVideoMuted() {\n return this._isMediaTypeMuted(MediaType.VIDEO);\n }\n\n /**\n * @returns {String} The role of this participant.\n */\n getRole() {\n return this._role;\n }\n\n /**\n *\n */\n supportsDTMF() {\n return this._supportsDTMF;\n }\n\n /**\n * Returns a set with the features for the participant.\n * @param {int} timeout the timeout in ms for reply from the participant.\n * @returns {Promise, Error>}\n */\n getFeatures(timeout = 5000) {\n return this._conference.xmpp.caps.getFeatures(this._jid, timeout)\n .catch(error => {\n // when we detect version mismatch we return a string as error\n // we want to retry in such case\n if (error && error.constructor === String) {\n return this._conference.xmpp.caps.getFeatures(this._jid, timeout);\n }\n\n logger.warn(`Failed to discover features of ${this._jid}`, error);\n\n return Promise.reject(error);\n });\n }\n\n /**\n * Returns the bot type for the participant.\n *\n * @returns {string|undefined} - The bot type of the participant.\n */\n getBotType() {\n return this._botType;\n }\n}\n","import {\n CONNECTION_DISCONNECTED,\n CONNECTION_ESTABLISHED,\n CONNECTION_FAILED\n} from './JitsiConnectionEvents';\nimport XMPP from './modules/xmpp/xmpp';\n\n/**\n * @typedef {Object} UpgradeRoleError\n *\n * @property {JitsiConnectionErrors} [connectionError] - One of\n * {@link JitsiConnectionErrors} which occurred when trying to connect to the\n * XMPP server.\n * @property {String} [authenticationError] - One of XMPP error conditions\n * returned by Jicofo on authentication attempt. See\n * {@link https://xmpp.org/rfcs/rfc3920.html#streams-error}.\n * @property {String} [message] - More details about the error.\n * @property {Object} [credentials] - The credentials that failed the\n * authentication.\n * @property {String} [credentials.jid] - The XMPP ID part of the credentials\n * that failed the authentication.\n * @property {string} [credentials.password] - The password part of the\n * credentials that failed the authentication.\n *\n * NOTE If neither one of the errors is present, then the operation has been\n * canceled.\n */\n\n/* eslint-disable no-invalid-this */\n\n/**\n * Connects to the XMPP server using the specified credentials and contacts\n * Jicofo in order to obtain a session ID (which is then stored in the local\n * storage). The user's role of the parent conference will be upgraded to\n * moderator (by Jicofo). It's also used to join the conference when starting\n * from anonymous domain and only authenticated users are allowed to create new\n * rooms.\n *\n * @param {Object} options\n * @param {string} options.id - XMPP user's ID to log in. For example,\n * user@xmpp-server.com.\n * @param {string} options.password - XMPP user's password to log in with.\n * @param {string} [options.roomPassword] - The password to join the MUC with.\n * @param {Function} [options.onLoginSuccessful] - Callback called when logging\n * into the XMPP server was successful. The next step will be to obtain a new\n * session ID from Jicofo and join the MUC using it which will effectively\n * upgrade the user's role to moderator.\n * @returns {Object} A thenable which (1) settles when the process of\n * authenticating and upgrading the role of the specified XMPP user finishes and\n * (2) has a cancel method that allows the caller to interrupt the\n * process. If the process finishes successfully, the session ID has been stored\n * in the settings and the thenable is resolved. If the process\n * finishes with failure, the thenable is rejected with reason of type\n * {@link UpgradeRoleError} which will have either connectionError or\n * authenticationError property set depending on which of the steps has\n * failed. If cancel is called before the process finishes, then the\n * thenable will be rejected with an empty object (i.e. no error property will\n * be set on the rejection reason).\n */\nexport default function authenticateAndUpgradeRole({\n // 1. Log the specified XMPP user in.\n id,\n password,\n onCreateResource,\n\n // 2. Let the API client/consumer know as soon as the XMPP user has been\n // successfully logged in.\n onLoginSuccessful,\n\n // 3. Join the MUC.\n roomPassword\n}) {\n let canceled = false;\n let rejectPromise;\n let xmpp = new XMPP(this.connection.options);\n\n const process = new Promise((resolve, reject) => {\n // The process is represented by a Thenable with a cancel method. The\n // Thenable is implemented using Promise and the cancel using the\n // Promise's reject function.\n rejectPromise = reject;\n\n\n xmpp.addListener(\n CONNECTION_DISCONNECTED,\n () => {\n xmpp = undefined;\n });\n xmpp.addListener(\n CONNECTION_ESTABLISHED,\n () => {\n if (canceled) {\n return;\n }\n\n // Let the caller know that the XMPP login was successful.\n onLoginSuccessful && onLoginSuccessful();\n\n // Now authenticate with Jicofo and get a new session ID.\n const room = xmpp.createRoom(\n this.options.name,\n this.options.config,\n onCreateResource\n );\n\n room.moderator.authenticate()\n .then(() => {\n xmpp && xmpp.disconnect();\n\n if (canceled) {\n return;\n }\n\n // At this point we should have the new session ID\n // stored in the settings. Jicofo will allow to join the\n // room.\n this.join(roomPassword);\n\n resolve();\n })\n .catch(({ error, message }) => {\n xmpp.disconnect();\n\n reject({\n authenticationError: error,\n message\n });\n });\n });\n xmpp.addListener(\n CONNECTION_FAILED,\n (connectionError, message, credentials) => {\n reject({\n connectionError,\n credentials,\n message\n });\n xmpp = undefined;\n });\n\n canceled || xmpp.connect(id, password);\n });\n\n /**\n * Cancels the process, if it's in progress, of authenticating and upgrading\n * the role of the local participant/user.\n *\n * @public\n * @returns {void}\n */\n process.cancel = () => {\n canceled = true;\n rejectPromise({});\n xmpp && xmpp.disconnect();\n };\n\n return process;\n}\n\n/* eslint-enable no-invalid-this */\n","/* global $ */\n\nimport { getLogger } from 'jitsi-meet-logger';\nimport { Strophe } from 'strophe.js';\n\nimport ChatRoom from './ChatRoom';\nimport { ConnectionPluginListenable } from './ConnectionPlugin';\nimport XMPPEvents from '../../service/xmpp/XMPPEvents';\n\nconst logger = getLogger(__filename);\n\n/**\n * MUC connection plugin.\n */\nclass MucConnectionPlugin extends ConnectionPluginListenable {\n /**\n *\n * @param xmpp\n */\n constructor(xmpp) {\n super();\n this.xmpp = xmpp;\n this.rooms = {};\n }\n\n /**\n *\n * @param connection\n */\n init(connection) {\n super.init(connection);\n\n // add handlers (just once)\n this.connection.addHandler(this.onPresence.bind(this), null,\n 'presence', null, null, null, null);\n this.connection.addHandler(this.onPresenceUnavailable.bind(this),\n null, 'presence', 'unavailable', null);\n this.connection.addHandler(this.onPresenceError.bind(this), null,\n 'presence', 'error', null);\n this.connection.addHandler(this.onMessage.bind(this), null,\n 'message', null, null);\n this.connection.addHandler(this.onMute.bind(this),\n 'http://jitsi.org/jitmeet/audio', 'iq', 'set', null, null);\n }\n\n /**\n *\n * @param jid\n * @param password\n * @param options\n */\n createRoom(jid, password, options) {\n const roomJid = Strophe.getBareJidFromJid(jid);\n\n if (this.rooms[roomJid]) {\n const errmsg = 'You are already in the room!';\n\n logger.error(errmsg);\n throw new Error(errmsg);\n }\n this.rooms[roomJid] = new ChatRoom(this.connection, jid,\n password, this.xmpp, options);\n this.eventEmitter.emit(\n XMPPEvents.EMUC_ROOM_ADDED, this.rooms[roomJid]);\n\n return this.rooms[roomJid];\n }\n\n /**\n *\n * @param jid\n */\n doLeave(jid) {\n this.eventEmitter.emit(\n XMPPEvents.EMUC_ROOM_REMOVED, this.rooms[jid]);\n delete this.rooms[jid];\n }\n\n /**\n *\n * @param pres\n */\n onPresence(pres) {\n const from = pres.getAttribute('from');\n\n // What is this for? A workaround for something?\n if (pres.getAttribute('type')) {\n return true;\n }\n\n const room = this.rooms[Strophe.getBareJidFromJid(from)];\n\n if (!room) {\n return true;\n }\n\n // Parse status.\n if ($(pres).find('>x[xmlns=\"http://jabber.org/protocol/muc#user\"]'\n + '>status[code=\"201\"]').length) {\n room.createNonAnonymousRoom();\n }\n\n room.onPresence(pres);\n\n return true;\n }\n\n /**\n *\n * @param pres\n */\n onPresenceUnavailable(pres) {\n const from = pres.getAttribute('from');\n const room = this.rooms[Strophe.getBareJidFromJid(from)];\n\n if (!room) {\n return true;\n }\n\n room.onPresenceUnavailable(pres, from);\n\n return true;\n }\n\n /**\n *\n * @param pres\n */\n onPresenceError(pres) {\n const from = pres.getAttribute('from');\n const room = this.rooms[Strophe.getBareJidFromJid(from)];\n\n if (!room) {\n return true;\n }\n\n room.onPresenceError(pres, from);\n\n return true;\n }\n\n /**\n *\n * @param msg\n */\n onMessage(msg) {\n // FIXME: this is a hack. but jingle on muc makes nickchanges hard\n const from = msg.getAttribute('from');\n const room = this.rooms[Strophe.getBareJidFromJid(from)];\n\n if (!room) {\n return true;\n }\n\n room.onMessage(msg, from);\n\n return true;\n }\n\n /**\n * TODO: Document\n * @param iq\n */\n onMute(iq) {\n const from = iq.getAttribute('from');\n const room = this.rooms[Strophe.getBareJidFromJid(from)];\n\n // Returning false would result in the listener being deregistered by Strophe\n if (!room) {\n return true;\n }\n\n room.onMute(iq);\n\n return true;\n }\n}\n\n/**\n *\n * @param XMPP\n */\nexport default function(XMPP) {\n Strophe.addConnectionPlugin('emuc', new MucConnectionPlugin(XMPP));\n}\n","/* global $, __filename */\n\nimport { getLogger } from 'jitsi-meet-logger';\nimport { $iq, $msg, $pres, Strophe } from 'strophe.js';\n\nimport GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';\nimport * as JitsiTranscriptionStatus from '../../JitsiTranscriptionStatus';\nimport Listenable from '../util/Listenable';\nimport * as MediaType from '../../service/RTC/MediaType';\nimport XMPPEvents from '../../service/xmpp/XMPPEvents';\n\nimport Moderator from './moderator';\n\nconst logger = getLogger(__filename);\n\nexport const parser = {\n packet2JSON(xmlElement, nodes) {\n for (const child of Array.from(xmlElement.children)) {\n const node = {\n attributes: {},\n children: [],\n tagName: child.tagName\n };\n\n for (const attr of Array.from(child.attributes)) {\n node.attributes[attr.name] = attr.value;\n }\n const text = Strophe.getText(child);\n\n if (text) {\n // Using Strophe.getText will do work for traversing all direct\n // child text nodes but returns an escaped value, which is not\n // desirable at this point.\n node.value = Strophe.xmlunescape(text);\n }\n nodes.push(node);\n this.packet2JSON(child, node.children);\n }\n },\n json2packet(nodes, packet) {\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n\n if (node) {\n packet.c(node.tagName, node.attributes);\n if (node.value) {\n packet.t(node.value);\n }\n if (node.children) {\n this.json2packet(node.children, packet);\n }\n packet.up();\n }\n }\n\n // packet.up();\n }\n};\n\n/**\n * Returns array of JS objects from the presence JSON associated with the passed\n / nodeName\n * @param pres the presence JSON\n * @param nodeName the name of the node (videomuted, audiomuted, etc)\n */\nfunction filterNodeFromPresenceJSON(pres, nodeName) {\n const res = [];\n\n for (let i = 0; i < pres.length; i++) {\n if (pres[i].tagName === nodeName) {\n res.push(pres[i]);\n }\n }\n\n return res;\n}\n\n// XXX As ChatRoom constructs XMPP stanzas and Strophe is build around the idea\n// of chaining function calls, allow long function call chains.\n/* eslint-disable newline-per-chained-call */\n\n/**\n *\n */\nexport default class ChatRoom extends Listenable {\n\n /* eslint-disable max-params */\n\n /**\n *\n * @param connection\n * @param jid\n * @param password\n * @param XMPP\n * @param options\n * @param {boolean} options.disableFocus - when set to {@code false} will\n * not invite Jicofo into the room. This is intended to be used only by\n * jitsi-meet-spot.\n */\n constructor(connection, jid, password, XMPP, options) {\n super();\n this.xmpp = XMPP;\n this.connection = connection;\n this.roomjid = Strophe.getBareJidFromJid(jid);\n this.myroomjid = jid;\n this.password = password;\n logger.info(`Joined MUC as ${this.myroomjid}`);\n this.members = {};\n this.presMap = {};\n this.presHandlers = {};\n this.joined = false;\n this.role = null;\n this.focusMucJid = null;\n this.noBridgeAvailable = false;\n this.options = options || {};\n this.moderator\n = new Moderator(this.roomjid, this.xmpp, this.eventEmitter, {\n connection: this.xmpp.options,\n conference: this.options\n });\n this.initPresenceMap(options);\n this.lastPresences = {};\n this.phoneNumber = null;\n this.phonePin = null;\n this.connectionTimes = {};\n this.participantPropertyListener = null;\n\n this.locked = false;\n this.transcriptionStatus = JitsiTranscriptionStatus.OFF;\n }\n\n /* eslint-enable max-params */\n\n /**\n *\n */\n initPresenceMap(options = {}) {\n this.presMap.to = this.myroomjid;\n this.presMap.xns = 'http://jabber.org/protocol/muc';\n this.presMap.nodes = [];\n\n if (options.statsId) {\n this.presMap.nodes.push({\n 'tagName': 'stats-id',\n 'value': options.statsId\n });\n }\n\n // We need to broadcast 'videomuted' status from the beginning, cause\n // Jicofo makes decisions based on that. Initialize it with 'false'\n // here.\n this.addVideoInfoToPresence(false);\n\n if (options.deploymentInfo && options.deploymentInfo.userRegion) {\n this.presMap.nodes.push({\n 'tagName': 'region',\n 'attributes': {\n id: options.deploymentInfo.userRegion,\n xmlns: 'http://jitsi.org/jitsi-meet'\n }\n });\n }\n }\n\n /**\n * Joins the chat room.\n * @param password\n * @returns {Promise} - resolved when join completes. At the time of this\n * writing it's never rejected.\n */\n join(password) {\n this.password = password;\n\n return new Promise(resolve => {\n this.options.disableFocus\n && logger.info('Conference focus disabled');\n\n const preJoin\n = this.options.disableFocus\n ? Promise.resolve()\n : this.moderator.allocateConferenceFocus();\n\n preJoin.then(() => {\n this.sendPresence(true);\n resolve();\n });\n });\n }\n\n /**\n *\n * @param fromJoin\n */\n sendPresence(fromJoin) {\n const to = this.presMap.to;\n\n if (!to || (!this.joined && !fromJoin)) {\n // Too early to send presence - not initialized\n return;\n }\n\n const pres = $pres({ to });\n\n // xep-0045 defines: \"including in the initial presence stanza an empty\n // element qualified by the 'http://jabber.org/protocol/muc'\n // namespace\" and subsequent presences should not include that or it can\n // be considered as joining, and server can send us the message history\n // for the room on every presence\n if (fromJoin) {\n pres.c('x', { xmlns: this.presMap.xns });\n\n if (this.password) {\n pres.c('password').t(this.password).up();\n }\n pres.up();\n }\n\n parser.json2packet(this.presMap.nodes, pres);\n this.connection.send(pres);\n if (fromJoin) {\n // XXX We're pressed for time here because we're beginning a complex\n // and/or lengthy conference-establishment process which supposedly\n // involves multiple RTTs. We don't have the time to wait for\n // Strophe to decide to send our IQ.\n this.connection.flush();\n }\n }\n\n /**\n * Sends the presence unavailable, signaling the server\n * we want to leave the room.\n */\n doLeave() {\n logger.log('do leave', this.myroomjid);\n const pres = $pres({ to: this.myroomjid,\n type: 'unavailable' });\n\n this.presMap.length = 0;\n\n // XXX Strophe is asynchronously sending by default. Unfortunately, that\n // means that there may not be enough time to send the unavailable\n // presence. Switching Strophe to synchronous sending is not much of an\n // option because it may lead to a noticeable delay in navigating away\n // from the current location. As a compromise, we will try to increase\n // the chances of sending the unavailable presence within the short time\n // span that we have upon unloading by invoking flush() on the\n // connection. We flush() once before sending/queuing the unavailable\n // presence in order to attemtp to have the unavailable presence at the\n // top of the send queue. We flush() once more after sending/queuing the\n // unavailable presence in order to attempt to have it sent as soon as\n // possible.\n this.connection.flush();\n this.connection.send(pres);\n this.connection.flush();\n }\n\n /**\n *\n */\n discoRoomInfo() {\n // https://xmpp.org/extensions/xep-0045.html#disco-roominfo\n\n const getInfo\n = $iq({\n type: 'get',\n to: this.roomjid\n })\n .c('query', { xmlns: Strophe.NS.DISCO_INFO });\n\n this.connection.sendIQ(getInfo, result => {\n const locked\n = $(result).find('>query>feature[var=\"muc_passwordprotected\"]')\n .length\n === 1;\n\n if (locked !== this.locked) {\n this.eventEmitter.emit(XMPPEvents.MUC_LOCK_CHANGED, locked);\n this.locked = locked;\n }\n }, error => {\n GlobalOnErrorHandler.callErrorHandler(error);\n logger.error('Error getting room info: ', error);\n });\n }\n\n /**\n *\n */\n createNonAnonymousRoom() {\n // http://xmpp.org/extensions/xep-0045.html#createroom-reserved\n\n const getForm = $iq({ type: 'get',\n to: this.roomjid })\n .c('query', { xmlns: 'http://jabber.org/protocol/muc#owner' })\n .c('x', { xmlns: 'jabber:x:data',\n type: 'submit' });\n\n const self = this;\n\n this.connection.sendIQ(getForm, form => {\n if (!$(form).find(\n '>query>x[xmlns=\"jabber:x:data\"]'\n + '>field[var=\"muc#roomconfig_whois\"]').length) {\n const errmsg = 'non-anonymous rooms not supported';\n\n GlobalOnErrorHandler.callErrorHandler(new Error(errmsg));\n logger.error(errmsg);\n\n return;\n }\n\n const formSubmit = $iq({ to: self.roomjid,\n type: 'set' })\n .c('query', { xmlns: 'http://jabber.org/protocol/muc#owner' });\n\n formSubmit.c('x', { xmlns: 'jabber:x:data',\n type: 'submit' });\n\n formSubmit.c('field', { 'var': 'FORM_TYPE' })\n .c('value')\n .t('http://jabber.org/protocol/muc#roomconfig').up().up();\n\n formSubmit.c('field', { 'var': 'muc#roomconfig_whois' })\n .c('value').t('anyone').up().up();\n\n self.connection.sendIQ(formSubmit);\n\n }, error => {\n GlobalOnErrorHandler.callErrorHandler(error);\n logger.error('Error getting room configuration form: ', error);\n });\n }\n\n /**\n *\n * @param pres\n */\n onPresence(pres) {\n const from = pres.getAttribute('from');\n const member = {};\n const statusEl = pres.getElementsByTagName('status')[0];\n\n if (statusEl) {\n member.status = statusEl.textContent || '';\n }\n let hasStatusUpdate = false;\n let hasVersionUpdate = false;\n const xElement\n = pres.getElementsByTagNameNS(\n 'http://jabber.org/protocol/muc#user', 'x')[0];\n const mucUserItem\n = xElement && xElement.getElementsByTagName('item')[0];\n\n member.affiliation\n = mucUserItem && mucUserItem.getAttribute('affiliation');\n member.role = mucUserItem && mucUserItem.getAttribute('role');\n\n // Focus recognition\n const jid = mucUserItem && mucUserItem.getAttribute('jid');\n\n member.jid = jid;\n member.isFocus\n = jid && jid.indexOf(`${this.moderator.getFocusUserJid()}/`) === 0;\n member.isHiddenDomain\n = jid && jid.indexOf('@') > 0\n && this.options.hiddenDomain\n === jid.substring(jid.indexOf('@') + 1, jid.indexOf('/'));\n\n this.eventEmitter.emit(XMPPEvents.PRESENCE_RECEIVED, {\n fromHiddenDomain: member.isHiddenDomain,\n presence: pres\n });\n\n const xEl = pres.querySelector('x');\n\n if (xEl) {\n xEl.remove();\n }\n\n const nodes = [];\n\n parser.packet2JSON(pres, nodes);\n this.lastPresences[from] = nodes;\n\n // process nodes to extract data needed for MUC_JOINED and\n // MUC_MEMBER_JOINED events\n const extractIdentityInformation = node => {\n const identity = {};\n const userInfo = node.children.find(c => c.tagName === 'user');\n\n if (userInfo) {\n identity.user = {};\n for (const tag of [ 'id', 'name', 'avatar' ]) {\n const child\n = userInfo.children.find(c => c.tagName === tag);\n\n if (child) {\n identity.user[tag] = child.value;\n }\n }\n }\n const groupInfo = node.children.find(c => c.tagName === 'group');\n\n if (groupInfo) {\n identity.group = groupInfo.value;\n }\n\n return identity;\n };\n\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n\n switch (node.tagName) {\n case 'bot': {\n const { attributes } = node;\n\n if (!attributes) {\n break;\n }\n const { type } = attributes;\n\n member.botType = type;\n break;\n }\n case 'nick':\n member.nick = node.value;\n break;\n case 'userId':\n member.id = node.value;\n break;\n case 'stats-id':\n member.statsID = node.value;\n break;\n case 'identity':\n member.identity = extractIdentityInformation(node);\n break;\n case 'stat': {\n const { attributes } = node;\n\n if (!attributes) {\n break;\n }\n const { name } = attributes;\n\n if (name === 'version') {\n member.version = attributes.value;\n }\n break;\n }\n }\n }\n\n if (from === this.myroomjid) {\n const newRole\n = member.affiliation === 'owner' ? member.role : 'none';\n\n if (this.role !== newRole) {\n this.role = newRole;\n this.eventEmitter.emit(\n XMPPEvents.LOCAL_ROLE_CHANGED,\n this.role);\n }\n if (!this.joined) {\n this.joined = true;\n const now = this.connectionTimes['muc.joined']\n = window.performance.now();\n\n logger.log('(TIME) MUC joined:\\t', now);\n\n // set correct initial state of locked\n if (this.password) {\n this.locked = true;\n }\n\n // Re-send presence in case any presence updates were added,\n // but blocked from sending, during the join process.\n this.sendPresence();\n\n this.eventEmitter.emit(XMPPEvents.MUC_JOINED);\n }\n } else if (jid === undefined) {\n logger.info('Ignoring member with undefined JID');\n } else if (this.members[from] === undefined) {\n // new participant\n this.members[from] = member;\n logger.log('entered', from, member);\n hasStatusUpdate = member.status !== undefined;\n hasVersionUpdate = member.version !== undefined;\n if (member.isFocus) {\n this._initFocus(from, jid);\n } else {\n // identity is being added to member joined, so external\n // services can be notified for that (currently identity is\n // not used inside library)\n this.eventEmitter.emit(\n XMPPEvents.MUC_MEMBER_JOINED,\n from,\n member.nick,\n member.role,\n member.isHiddenDomain,\n member.statsID,\n member.status,\n member.identity,\n member.botType);\n\n // we are reporting the status with the join\n // so we do not want a second event about status update\n hasStatusUpdate = false;\n }\n } else {\n // Presence update for existing participant\n // Watch role change:\n const memberOfThis = this.members[from];\n\n if (memberOfThis.role !== member.role) {\n memberOfThis.role = member.role;\n this.eventEmitter.emit(\n XMPPEvents.MUC_ROLE_CHANGED, from, member.role);\n }\n\n // fire event that botType had changed\n if (memberOfThis.botType !== member.botType) {\n memberOfThis.botType = member.botType;\n this.eventEmitter.emit(\n XMPPEvents.MUC_MEMBER_BOT_TYPE_CHANGED,\n from,\n member.botType);\n }\n\n if (member.isFocus) {\n // From time to time first few presences of the focus are not\n // containing it's jid. That way we can mark later the focus\n // member instead of not marking it at all and not starting the\n // conference.\n // FIXME: Maybe there is a better way to handle this issue. It\n // seems there is some period of time in prosody that the\n // configuration form is received but not applied. And if any\n // participant joins during that period of time the first\n // presence from the focus won't contain\n // .\n memberOfThis.isFocus = true;\n this._initFocus(from, jid);\n }\n\n // store the new display name\n if (member.displayName) {\n memberOfThis.displayName = member.displayName;\n }\n\n // update stored status message to be able to detect changes\n if (memberOfThis.status !== member.status) {\n hasStatusUpdate = true;\n memberOfThis.status = member.status;\n }\n\n if (memberOfThis.version !== member.version) {\n hasVersionUpdate = true;\n memberOfThis.version = member.version;\n }\n }\n\n // after we had fired member or room joined events, lets fire events\n // for the rest info we got in presence\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n\n switch (node.tagName) {\n case 'nick':\n if (!member.isFocus) {\n const displayName\n = this.xmpp.options.displayJids\n ? Strophe.getResourceFromJid(from)\n : member.nick;\n\n this.eventEmitter.emit(\n XMPPEvents.DISPLAY_NAME_CHANGED,\n from,\n displayName);\n }\n break;\n case 'bridgeNotAvailable':\n if (member.isFocus && !this.noBridgeAvailable) {\n this.noBridgeAvailable = true;\n this.eventEmitter.emit(XMPPEvents.BRIDGE_DOWN);\n }\n break;\n case 'conference-properties':\n if (member.isFocus) {\n const properties = {};\n\n for (let j = 0; j < node.children.length; j++) {\n const { attributes } = node.children[j];\n\n if (attributes && attributes.key) {\n properties[attributes.key] = attributes.value;\n }\n }\n\n this.eventEmitter.emit(\n XMPPEvents.CONFERENCE_PROPERTIES_CHANGED, properties);\n }\n break;\n case 'transcription-status': {\n const { attributes } = node;\n\n if (!attributes) {\n break;\n }\n\n const { status } = attributes;\n\n if (status && status !== this.transcriptionStatus) {\n this.transcriptionStatus = status;\n this.eventEmitter.emit(\n XMPPEvents.TRANSCRIPTION_STATUS_CHANGED,\n status\n );\n }\n\n\n break;\n }\n case 'call-control': {\n const att = node.attributes;\n\n if (!att) {\n break;\n }\n this.phoneNumber = att.phone || null;\n this.phonePin = att.pin || null;\n this.eventEmitter.emit(XMPPEvents.PHONE_NUMBER_CHANGED);\n break;\n }\n default:\n this.processNode(node, from);\n }\n }\n\n // Trigger status message update if necessary\n if (hasStatusUpdate) {\n this.eventEmitter.emit(\n XMPPEvents.PRESENCE_STATUS,\n from,\n member.status);\n }\n\n if (hasVersionUpdate) {\n logger.info(`Received version for ${jid}: ${member.version}`);\n }\n }\n\n /**\n * Initialize some properties when the focus participant is verified.\n * @param from jid of the focus\n * @param mucJid the jid of the focus in the muc\n */\n _initFocus(from, mucJid) {\n this.focusMucJid = from;\n\n logger.info(`Ignore focus: ${from}, real JID: ${mucJid}`);\n }\n\n /**\n * Sets the special listener to be used for \"command\"s whose name starts\n * with \"jitsi_participant_\".\n */\n setParticipantPropertyListener(listener) {\n this.participantPropertyListener = listener;\n }\n\n /**\n *\n * @param node\n * @param from\n */\n processNode(node, from) {\n // make sure we catch all errors coming from any handler\n // otherwise we can remove the presence handler from strophe\n try {\n let tagHandlers = this.presHandlers[node.tagName];\n\n if (node.tagName.startsWith('jitsi_participant_')) {\n tagHandlers = [ this.participantPropertyListener ];\n }\n\n if (tagHandlers) {\n tagHandlers.forEach(handler => {\n handler(node, Strophe.getResourceFromJid(from), from);\n });\n }\n } catch (e) {\n GlobalOnErrorHandler.callErrorHandler(e);\n logger.error(`Error processing:${node.tagName} node.`, e);\n }\n }\n\n /**\n * Send text message to the other participants in the conference\n * @param message\n * @param elementName\n * @param nickname\n */\n sendMessage(message, elementName, nickname) {\n const msg = $msg({ to: this.roomjid,\n type: 'groupchat' });\n\n // We are adding the message in a packet extension. If this element\n // is different from 'body', we add a custom namespace.\n // e.g. for 'json-message' extension of message stanza.\n if (elementName === 'body') {\n msg.c(elementName, message).up();\n } else {\n msg.c(elementName, { xmlns: 'http://jitsi.org/jitmeet' }, message)\n .up();\n }\n if (nickname) {\n msg.c('nick', { xmlns: 'http://jabber.org/protocol/nick' })\n .t(nickname)\n .up()\n .up();\n }\n this.connection.send(msg);\n this.eventEmitter.emit(XMPPEvents.SENDING_CHAT_MESSAGE, message);\n }\n\n /* eslint-disable max-params */\n /**\n * Send private text message to another participant of the conference\n * @param id id/muc resource of the receiver\n * @param message\n * @param elementName\n * @param nickname\n */\n sendPrivateMessage(id, message, elementName, nickname) {\n const msg = $msg({ to: `${this.roomjid}/${id}`,\n type: 'chat' });\n\n // We are adding the message in packet. If this element is different\n // from 'body', we add our custom namespace for the same.\n // e.g. for 'json-message' message extension.\n if (elementName === 'body') {\n msg.c(elementName, message).up();\n } else {\n msg.c(elementName, { xmlns: 'http://jitsi.org/jitmeet' }, message)\n .up();\n }\n if (nickname) {\n msg.c('nick', { xmlns: 'http://jabber.org/protocol/nick' })\n .t(nickname)\n .up()\n .up();\n }\n\n this.connection.send(msg);\n this.eventEmitter.emit(\n XMPPEvents.SENDING_PRIVATE_CHAT_MESSAGE, message);\n }\n /* eslint-enable max-params */\n\n /**\n *\n * @param subject\n */\n setSubject(subject) {\n const msg = $msg({ to: this.roomjid,\n type: 'groupchat' });\n\n msg.c('subject', subject);\n this.connection.send(msg);\n }\n\n /**\n * Called when participant leaves.\n * @param jid the jid of the participant that leaves\n * @param skipEvents optional params to skip any events, including check\n * whether this is the focus that left\n */\n onParticipantLeft(jid, skipEvents) {\n delete this.lastPresences[jid];\n\n if (skipEvents) {\n return;\n }\n\n this.eventEmitter.emit(XMPPEvents.MUC_MEMBER_LEFT, jid);\n\n this.moderator.onMucMemberLeft(jid);\n }\n\n /**\n *\n * @param pres\n * @param from\n */\n onPresenceUnavailable(pres, from) {\n // ignore presence\n if ($(pres).find('>ignore[xmlns=\"http://jitsi.org/jitmeet/\"]').length) {\n return true;\n }\n\n // room destroyed ?\n if ($(pres).find('>x[xmlns=\"http://jabber.org/protocol/muc#user\"]'\n + '>destroy').length) {\n let reason;\n const reasonSelect\n = $(pres).find(\n '>x[xmlns=\"http://jabber.org/protocol/muc#user\"]'\n + '>destroy>reason');\n\n if (reasonSelect.length) {\n reason = reasonSelect.text();\n }\n\n this.eventEmitter.emit(XMPPEvents.MUC_DESTROYED, reason);\n this.connection.emuc.doLeave(this.roomjid);\n\n return true;\n }\n\n // Status code 110 indicates that this notification is \"self-presence\".\n const isSelfPresence\n = $(pres)\n .find(\n '>x[xmlns=\"http://jabber.org/protocol/muc#user\"]>'\n + 'status[code=\"110\"]')\n .length;\n const isKick\n = $(pres)\n .find(\n '>x[xmlns=\"http://jabber.org/protocol/muc#user\"]'\n + '>status[code=\"307\"]')\n .length;\n const membersKeys = Object.keys(this.members);\n\n if (isKick) {\n const actorSelect\n = $(pres)\n .find('>x[xmlns=\"http://jabber.org/protocol/muc#user\"]>item>actor');\n\n let actorNick;\n\n if (actorSelect.length) {\n actorNick = actorSelect.attr('nick');\n }\n\n // if no member is found this is the case we had kicked someone\n // and we are not in the list of members\n if (membersKeys.find(jid => Strophe.getResourceFromJid(jid) === actorNick)) {\n // we first fire the kicked so we can show the participant\n // who kicked, before notifying that participant left\n // we fire kicked for us and for any participant kicked\n this.eventEmitter.emit(\n XMPPEvents.KICKED,\n isSelfPresence,\n actorNick,\n Strophe.getResourceFromJid(from));\n }\n }\n\n if (!isSelfPresence) {\n delete this.members[from];\n this.onParticipantLeft(from, false);\n } else if (membersKeys.length > 0) {\n // If the status code is 110 this means we're leaving and we would\n // like to remove everyone else from our view, so we trigger the\n // event.\n membersKeys.forEach(jid => {\n const member = this.members[jid];\n\n delete this.members[jid];\n this.onParticipantLeft(jid, member.isFocus);\n });\n this.connection.emuc.doLeave(this.roomjid);\n\n // we fire muc_left only if this is not a kick,\n // kick has both statuses 110 and 307.\n if (!isKick) {\n this.eventEmitter.emit(XMPPEvents.MUC_LEFT);\n }\n }\n }\n\n /**\n *\n * @param msg\n * @param from\n */\n onMessage(msg, from) {\n const nick\n = $(msg).find('>nick[xmlns=\"http://jabber.org/protocol/nick\"]')\n .text()\n || Strophe.getResourceFromJid(from);\n\n const type = msg.getAttribute('type');\n\n if (type === 'error') {\n const errorMsg = $(msg).find('>error>text').text();\n\n this.eventEmitter.emit(XMPPEvents.CHAT_ERROR_RECEIVED, errorMsg);\n\n return true;\n }\n\n const txt = $(msg).find('>body').text();\n const subject = $(msg).find('>subject');\n\n if (subject.length) {\n const subjectText = subject.text();\n\n if (subjectText || subjectText === '') {\n this.eventEmitter.emit(XMPPEvents.SUBJECT_CHANGED, subjectText);\n logger.log(`Subject is changed to ${subjectText}`);\n }\n }\n\n // xep-0203 delay\n let stamp = $(msg).find('>delay').attr('stamp');\n\n if (!stamp) {\n // or xep-0091 delay, UTC timestamp\n stamp = $(msg).find('>[xmlns=\"jabber:x:delay\"]').attr('stamp');\n\n if (stamp) {\n // the format is CCYYMMDDThh:mm:ss\n const dateParts\n = stamp.match(/(\\d{4})(\\d{2})(\\d{2}T\\d{2}:\\d{2}:\\d{2})/);\n\n stamp = `${dateParts[1]}-${dateParts[2]}-${dateParts[3]}Z`;\n }\n }\n\n if (from === this.roomjid\n && $(msg)\n .find(\n '>x[xmlns=\"http://jabber.org/protocol/muc#user\"]'\n + '>status[code=\"104\"]')\n .length) {\n this.discoRoomInfo();\n }\n const jsonMessage = $(msg).find('>json-message').text();\n const parsedJson = this.xmpp.tryParseJSONAndVerify(jsonMessage);\n\n // We emit this event if the message is a valid json, and is not\n // delivered after a delay, i.e. stamp is undefined.\n // e.g. - subtitles should not be displayed if delayed.\n if (parsedJson && stamp === undefined) {\n this.eventEmitter.emit(XMPPEvents.JSON_MESSAGE_RECEIVED,\n from, parsedJson);\n\n return;\n }\n\n if (txt) {\n if (type === 'chat') {\n this.eventEmitter.emit(XMPPEvents.PRIVATE_MESSAGE_RECEIVED,\n from, nick, txt, this.myroomjid, stamp);\n } else if (type === 'groupchat') {\n this.eventEmitter.emit(XMPPEvents.MESSAGE_RECEIVED,\n from, nick, txt, this.myroomjid, stamp);\n }\n }\n }\n\n /**\n *\n * @param pres\n * @param from\n */\n onPresenceError(pres, from) {\n if ($(pres)\n .find(\n '>error[type=\"auth\"]'\n + '>not-authorized['\n + 'xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"]')\n .length) {\n logger.log('on password required', from);\n this.eventEmitter.emit(XMPPEvents.PASSWORD_REQUIRED);\n } else if ($(pres)\n .find(\n '>error[type=\"cancel\"]'\n + '>not-allowed['\n + 'xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"]')\n .length) {\n const toDomain = Strophe.getDomainFromJid(pres.getAttribute('to'));\n\n if (toDomain === this.xmpp.options.hosts.anonymousdomain) {\n // enter the room by replying with 'not-authorized'. This would\n // result in reconnection from authorized domain.\n // We're either missing Jicofo/Prosody config for anonymous\n // domains or something is wrong.\n this.eventEmitter.emit(XMPPEvents.ROOM_JOIN_ERROR);\n\n } else {\n logger.warn('onPresError ', pres);\n this.eventEmitter.emit(\n XMPPEvents.ROOM_CONNECT_NOT_ALLOWED_ERROR);\n }\n } else if ($(pres).find('>error>service-unavailable').length) {\n logger.warn('Maximum users limit for the room has been reached',\n pres);\n this.eventEmitter.emit(XMPPEvents.ROOM_MAX_USERS_ERROR);\n } else {\n logger.warn('onPresError ', pres);\n this.eventEmitter.emit(XMPPEvents.ROOM_CONNECT_ERROR);\n }\n }\n\n /**\n *\n * @param jid\n */\n kick(jid) {\n const kickIQ = $iq({ to: this.roomjid,\n type: 'set' })\n .c('query', { xmlns: 'http://jabber.org/protocol/muc#admin' })\n .c('item', { nick: Strophe.getResourceFromJid(jid),\n role: 'none' })\n .c('reason').t('You have been kicked.').up().up().up();\n\n this.connection.sendIQ(\n kickIQ,\n result => logger.log('Kick participant with jid: ', jid, result),\n error => logger.log('Kick participant error: ', error));\n }\n\n /* eslint-disable max-params */\n\n /**\n *\n * @param key\n * @param onSuccess\n * @param onError\n * @param onNotSupported\n */\n lockRoom(key, onSuccess, onError, onNotSupported) {\n // http://xmpp.org/extensions/xep-0045.html#roomconfig\n this.connection.sendIQ(\n $iq({\n to: this.roomjid,\n type: 'get'\n })\n .c('query', { xmlns: 'http://jabber.org/protocol/muc#owner' }),\n res => {\n if ($(res)\n .find(\n '>query>x[xmlns=\"jabber:x:data\"]'\n + '>field[var=\"muc#roomconfig_roomsecret\"]')\n .length) {\n const formsubmit\n = $iq({\n to: this.roomjid,\n type: 'set'\n })\n .c('query', {\n xmlns: 'http://jabber.org/protocol/muc#owner'\n });\n\n formsubmit.c('x', {\n xmlns: 'jabber:x:data',\n type: 'submit'\n });\n formsubmit\n .c('field', { 'var': 'FORM_TYPE' })\n .c('value')\n .t('http://jabber.org/protocol/muc#roomconfig')\n .up()\n .up();\n formsubmit\n .c('field', { 'var': 'muc#roomconfig_roomsecret' })\n .c('value')\n .t(key)\n .up()\n .up();\n\n // Fixes a bug in prosody 0.9.+\n // https://prosody.im/issues/issue/373\n formsubmit\n .c('field', { 'var': 'muc#roomconfig_whois' })\n .c('value')\n .t('anyone')\n .up()\n .up();\n\n // FIXME: is muc#roomconfig_passwordprotectedroom required?\n this.connection.sendIQ(formsubmit, onSuccess, onError);\n } else {\n onNotSupported();\n }\n },\n onError);\n }\n\n /* eslint-enable max-params */\n\n /**\n *\n * @param key\n * @param values\n */\n addToPresence(key, values) {\n values.tagName = key;\n this.removeFromPresence(key);\n this.presMap.nodes.push(values);\n }\n\n /**\n * Retreives a value from the presence map.\n *\n * @param {string} key - The key to find the value for.\n * @returns {Object?}\n */\n getFromPresence(key) {\n return this.presMap.nodes.find(node => key === node.tagName);\n }\n\n /**\n *\n * @param key\n */\n removeFromPresence(key) {\n const nodes = this.presMap.nodes.filter(node => key !== node.tagName);\n\n this.presMap.nodes = nodes;\n }\n\n /**\n *\n * @param name\n * @param handler\n */\n addPresenceListener(name, handler) {\n if (typeof handler !== 'function') {\n throw new Error('\"handler\" is not a function');\n }\n let tagHandlers = this.presHandlers[name];\n\n if (!tagHandlers) {\n this.presHandlers[name] = tagHandlers = [];\n }\n if (tagHandlers.indexOf(handler) === -1) {\n tagHandlers.push(handler);\n } else {\n logger.warn(\n `Trying to add the same handler more than once for: ${name}`);\n }\n }\n\n /**\n *\n * @param name\n * @param handler\n */\n removePresenceListener(name, handler) {\n const tagHandlers = this.presHandlers[name];\n const handlerIdx = tagHandlers ? tagHandlers.indexOf(handler) : -1;\n\n // eslint-disable-next-line no-negated-condition\n if (handlerIdx !== -1) {\n tagHandlers.splice(handlerIdx, 1);\n } else {\n logger.warn(`Handler for: ${name} was not registered`);\n }\n }\n\n /**\n * Checks if the user identified by given mucJid is the conference\n * focus.\n * @param mucJid the full MUC address of the user to be checked.\n * @returns {boolean|null} true if MUC user is the conference focus\n * or false if is not. When given mucJid does not exist in\n * the MUC then null is returned.\n */\n isFocus(mucJid) {\n const member = this.members[mucJid];\n\n if (member) {\n return member.isFocus;\n }\n\n return null;\n }\n\n /**\n *\n */\n isModerator() {\n return this.role === 'moderator';\n }\n\n /**\n *\n * @param peerJid\n */\n getMemberRole(peerJid) {\n if (this.members[peerJid]) {\n return this.members[peerJid].role;\n }\n\n return null;\n }\n\n /**\n *\n * @param mute\n * @param callback\n */\n setVideoMute(mute, callback) {\n this.sendVideoInfoPresence(mute);\n if (callback) {\n callback(mute);\n }\n }\n\n /**\n *\n * @param mute\n * @param callback\n */\n setAudioMute(mute, callback) {\n return this.sendAudioInfoPresence(mute, callback);\n }\n\n /**\n *\n * @param mute\n */\n addAudioInfoToPresence(mute) {\n this.removeFromPresence('audiomuted');\n this.addToPresence(\n 'audiomuted',\n {\n attributes: { 'xmlns': 'http://jitsi.org/jitmeet/audio' },\n value: mute.toString()\n });\n }\n\n /**\n *\n * @param mute\n * @param callback\n */\n sendAudioInfoPresence(mute, callback) {\n this.addAudioInfoToPresence(mute);\n if (this.connection) {\n this.sendPresence();\n }\n if (callback) {\n callback();\n }\n }\n\n /**\n *\n * @param mute\n */\n addVideoInfoToPresence(mute) {\n this.removeFromPresence('videomuted');\n this.addToPresence(\n 'videomuted',\n {\n attributes: { 'xmlns': 'http://jitsi.org/jitmeet/video' },\n value: mute.toString()\n });\n }\n\n /**\n *\n * @param mute\n */\n sendVideoInfoPresence(mute) {\n this.addVideoInfoToPresence(mute);\n if (!this.connection) {\n return;\n }\n this.sendPresence();\n }\n\n /**\n * Obtains the info about given media advertised in the MUC presence of\n * the participant identified by the given endpoint JID.\n * @param {string} endpointId the endpoint ID mapped to the participant\n * which corresponds to MUC nickname.\n * @param {MediaType} mediaType the type of the media for which presence\n * info will be obtained.\n * @return {PeerMediaInfo} presenceInfo an object with media presence\n * info or null either if there is no presence available or if\n * the media type given is invalid.\n */\n getMediaPresenceInfo(endpointId, mediaType) {\n // Will figure out current muted status by looking up owner's presence\n const pres = this.lastPresences[`${this.roomjid}/${endpointId}`];\n\n if (!pres) {\n // No presence available\n return null;\n }\n const data = {\n muted: false, // unmuted by default\n videoType: undefined // no video type by default\n };\n let mutedNode = null;\n\n if (mediaType === MediaType.AUDIO) {\n mutedNode = filterNodeFromPresenceJSON(pres, 'audiomuted');\n } else if (mediaType === MediaType.VIDEO) {\n mutedNode = filterNodeFromPresenceJSON(pres, 'videomuted');\n const videoTypeNode = filterNodeFromPresenceJSON(pres, 'videoType');\n\n if (videoTypeNode.length > 0) {\n data.videoType = videoTypeNode[0].value;\n }\n } else {\n logger.error(`Unsupported media type: ${mediaType}`);\n\n return null;\n }\n\n data.muted = mutedNode.length > 0 && mutedNode[0].value === 'true';\n\n return data;\n }\n\n /**\n * Returns true if the SIP calls are supported and false otherwise\n */\n isSIPCallingSupported() {\n if (this.moderator) {\n return this.moderator.isSipGatewayEnabled();\n }\n\n return false;\n }\n\n /**\n * Dials a number.\n * @param number the number\n */\n dial(number) {\n return this.connection.rayo.dial(number, 'fromnumber',\n Strophe.getBareJidFromJid(this.myroomjid), this.password,\n this.focusMucJid);\n }\n\n /**\n * Hangup an existing call\n */\n hangup() {\n return this.connection.rayo.hangup();\n }\n\n /**\n * Returns the phone number for joining the conference.\n */\n getPhoneNumber() {\n return this.phoneNumber;\n }\n\n /**\n * Returns the pin for joining the conference with phone.\n */\n getPhonePin() {\n return this.phonePin;\n }\n\n /**\n * Mutes remote participant.\n * @param jid of the participant\n * @param mute\n */\n muteParticipant(jid, mute) {\n logger.info('set mute', mute);\n const iqToFocus = $iq(\n { to: this.focusMucJid,\n type: 'set' })\n .c('mute', {\n xmlns: 'http://jitsi.org/jitmeet/audio',\n jid\n })\n .t(mute.toString())\n .up();\n\n this.connection.sendIQ(\n iqToFocus,\n result => logger.log('set mute', result),\n error => logger.log('set mute error', error));\n }\n\n /**\n * TODO: Document\n * @param iq\n */\n onMute(iq) {\n const from = iq.getAttribute('from');\n\n if (from !== this.focusMucJid) {\n logger.warn('Ignored mute from non focus peer');\n\n return;\n }\n const mute = $(iq).find('mute');\n\n if (mute.length && mute.text() === 'true') {\n this.eventEmitter.emit(XMPPEvents.AUDIO_MUTED_BY_FOCUS, mute.attr('actor'));\n } else {\n // XXX Why do we support anything but muting? Why do we encode the\n // value in the text of the element? Why do we use a separate XML\n // namespace?\n logger.warn('Ignoring a mute request which does not explicitly '\n + 'specify a positive mute command.');\n }\n }\n\n /**\n * Leaves the room. Closes the jingle session.\n * @returns {Promise} which is resolved if XMPPEvents.MUC_LEFT is received\n * less than 5s after sending presence unavailable. Otherwise the promise is\n * rejected.\n */\n leave() {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => onMucLeft(true), 5000);\n const eventEmitter = this.eventEmitter;\n\n /**\n *\n * @param doReject\n */\n function onMucLeft(doReject = false) {\n eventEmitter.removeListener(XMPPEvents.MUC_LEFT, onMucLeft);\n clearTimeout(timeout);\n if (doReject) {\n // the timeout expired\n reject(new Error('The timeout for the confirmation about '\n + 'leaving the room expired.'));\n } else {\n resolve();\n }\n }\n eventEmitter.on(XMPPEvents.MUC_LEFT, onMucLeft);\n this.doLeave();\n });\n }\n}\n\n/* eslint-enable newline-per-chained-call */\n","/* global $, Promise */\n\nconst logger = require('jitsi-meet-logger').getLogger(__filename);\n\nimport { $iq, Strophe } from 'strophe.js';\n\nconst XMPPEvents = require('../../service/xmpp/XMPPEvents');\nconst AuthenticationEvents\n = require('../../service/authentication/AuthenticationEvents');\nconst GlobalOnErrorHandler = require('../util/GlobalOnErrorHandler');\n\nimport browser from '../browser';\nimport Settings from '../settings/Settings';\n\n/**\n *\n * @param step\n */\nfunction createExpBackoffTimer(step) {\n let count = 1;\n\n return function(reset) {\n // Reset call\n if (reset) {\n count = 1;\n\n return;\n }\n\n // Calculate next timeout\n const timeout = Math.pow(2, count - 1);\n\n count += 1;\n\n return timeout * step;\n };\n}\n\n/* eslint-disable max-params */\n\n/**\n *\n * @param roomName\n * @param xmpp\n * @param emitter\n * @param options\n */\nexport default function Moderator(roomName, xmpp, emitter, options) {\n this.roomName = roomName;\n this.xmppService = xmpp;\n this.getNextTimeout = createExpBackoffTimer(1000);\n this.getNextErrorTimeout = createExpBackoffTimer(1000);\n\n // External authentication stuff\n this.externalAuthEnabled = false;\n this.options = options;\n\n // Sip gateway can be enabled by configuring Jigasi host in config.js or\n // it will be enabled automatically if focus detects the component through\n // service discovery.\n this.sipGatewayEnabled\n = this.options.connection.hosts\n && this.options.connection.hosts.call_control !== undefined;\n\n this.eventEmitter = emitter;\n\n this.connection = this.xmppService.connection;\n\n // FIXME: Message listener that talks to POPUP window\n /**\n *\n * @param event\n */\n function listener(event) {\n if (event.data && event.data.sessionId) {\n if (event.origin !== window.location.origin) {\n logger.warn(\n `Ignoring sessionId from different origin: ${\n event.origin}`);\n\n return;\n }\n Settings.sessionId = event.data.sessionId;\n\n // After popup is closed we will authenticate\n }\n }\n\n // Register\n if (window.addEventListener) {\n window.addEventListener('message', listener, false);\n } else {\n window.attachEvent('onmessage', listener);\n }\n}\n\n/* eslint-enable max-params */\n\nModerator.prototype.isExternalAuthEnabled = function() {\n return this.externalAuthEnabled;\n};\n\nModerator.prototype.isSipGatewayEnabled = function() {\n return this.sipGatewayEnabled;\n};\n\nModerator.prototype.onMucMemberLeft = function(jid) {\n logger.info(`Someone left is it focus ? ${jid}`);\n const resource = Strophe.getResourceFromJid(jid);\n\n if (resource === 'focus') {\n logger.info(\n 'Focus has left the room - leaving conference');\n this.eventEmitter.emit(XMPPEvents.FOCUS_LEFT);\n }\n};\n\nModerator.prototype.setFocusUserJid = function(focusJid) {\n if (!this.focusUserJid) {\n this.focusUserJid = focusJid;\n logger.info(`Focus jid set to: ${this.focusUserJid}`);\n }\n};\n\nModerator.prototype.getFocusUserJid = function() {\n return this.focusUserJid;\n};\n\nModerator.prototype.getFocusComponent = function() {\n // Get focus component address\n let focusComponent = this.options.connection.hosts.focus;\n\n // If not specified use default: 'focus.domain'\n\n if (!focusComponent) {\n focusComponent = `focus.${this.options.connection.hosts.domain}`;\n }\n\n return focusComponent;\n};\n\nModerator.prototype.createConferenceIq = function() {\n // Generate create conference IQ\n const elem = $iq({ to: this.getFocusComponent(),\n type: 'set' });\n\n // Session Id used for authentication\n const { sessionId } = Settings;\n const machineUID = Settings.machineId;\n const config = this.options.conference;\n\n logger.info(`Session ID: ${sessionId} machine UID: ${machineUID}`);\n\n elem.c('conference', {\n xmlns: 'http://jitsi.org/protocol/focus',\n room: this.roomName,\n 'machine-uid': machineUID\n });\n\n if (sessionId) {\n elem.attrs({ 'session-id': sessionId });\n }\n if (this.options.connection.enforcedBridge !== undefined) {\n elem.c(\n 'property', {\n name: 'enforcedBridge',\n value: this.options.connection.enforcedBridge\n }).up();\n }\n\n // Tell the focus we have Jigasi configured\n if (this.options.connection.hosts !== undefined\n && this.options.connection.hosts.call_control !== undefined) {\n elem.c(\n 'property', {\n name: 'call_control',\n value: this.options.connection.hosts.call_control\n }).up();\n }\n if (config.channelLastN !== undefined) {\n elem.c(\n 'property', {\n name: 'channelLastN',\n value: config.channelLastN\n }).up();\n }\n elem.c(\n 'property', {\n name: 'disableRtx',\n value: Boolean(config.disableRtx)\n }).up();\n\n if (config.enableTcc !== undefined) {\n elem.c(\n 'property', {\n name: 'enableTcc',\n value: Boolean(config.enableTcc)\n }).up();\n }\n if (config.enableRemb !== undefined) {\n elem.c(\n 'property', {\n name: 'enableRemb',\n value: Boolean(config.enableRemb)\n }).up();\n }\n if (config.minParticipants !== undefined) {\n elem.c(\n 'property', {\n name: 'minParticipants',\n value: config.minParticipants\n }).up();\n }\n\n elem.c(\n 'property', {\n name: 'enableLipSync',\n value: this.options.connection.enableLipSync !== false\n }).up();\n if (config.audioPacketDelay !== undefined) {\n elem.c(\n 'property', {\n name: 'audioPacketDelay',\n value: config.audioPacketDelay\n }).up();\n }\n if (config.startBitrate) {\n elem.c(\n 'property', {\n name: 'startBitrate',\n value: config.startBitrate\n }).up();\n }\n if (config.minBitrate) {\n elem.c(\n 'property', {\n name: 'minBitrate',\n value: config.minBitrate\n }).up();\n }\n if (config.testing && config.testing.octo\n && typeof config.testing.octo.probability === 'number') {\n if (Math.random() < config.testing.octo.probability) {\n elem.c(\n 'property', {\n name: 'octo',\n value: true\n }).up();\n }\n }\n\n let openSctp;\n\n switch (this.options.conference.openBridgeChannel) {\n case 'datachannel':\n case true:\n case undefined:\n openSctp = true;\n break;\n case 'websocket':\n openSctp = false;\n break;\n }\n\n if (openSctp && !browser.supportsDataChannels()) {\n openSctp = false;\n }\n\n elem.c(\n 'property', {\n name: 'openSctp',\n value: openSctp\n }).up();\n\n if (this.options.conference.startAudioMuted !== undefined) {\n elem.c(\n 'property', {\n name: 'startAudioMuted',\n value: this.options.conference.startAudioMuted\n }).up();\n }\n if (this.options.conference.startVideoMuted !== undefined) {\n elem.c(\n 'property', {\n name: 'startVideoMuted',\n value: this.options.conference.startVideoMuted\n }).up();\n }\n if (this.options.conference.stereo !== undefined) {\n elem.c(\n 'property', {\n name: 'stereo',\n value: this.options.conference.stereo\n }).up();\n }\n if (this.options.conference.useRoomAsSharedDocumentName !== undefined) {\n elem.c(\n 'property', {\n name: 'useRoomAsSharedDocumentName',\n value: this.options.conference.useRoomAsSharedDocumentName\n }).up();\n }\n elem.up();\n\n return elem;\n};\n\n\nModerator.prototype.parseSessionId = function(resultIq) {\n // eslint-disable-next-line newline-per-chained-call\n const sessionId = $(resultIq).find('conference').attr('session-id');\n\n if (sessionId) {\n logger.info(`Received sessionId: ${sessionId}`);\n Settings.sessionId = sessionId;\n }\n};\n\nModerator.prototype.parseConfigOptions = function(resultIq) {\n // eslint-disable-next-line newline-per-chained-call\n this.setFocusUserJid($(resultIq).find('conference').attr('focusjid'));\n\n const authenticationEnabled\n = $(resultIq).find(\n '>conference>property'\n + '[name=\\'authentication\\'][value=\\'true\\']').length > 0;\n\n logger.info(`Authentication enabled: ${authenticationEnabled}`);\n\n this.externalAuthEnabled = $(resultIq).find(\n '>conference>property'\n + '[name=\\'externalAuth\\'][value=\\'true\\']').length > 0;\n\n logger.info(\n `External authentication enabled: ${this.externalAuthEnabled}`);\n\n if (!this.externalAuthEnabled) {\n // We expect to receive sessionId in 'internal' authentication mode\n this.parseSessionId(resultIq);\n }\n\n // eslint-disable-next-line newline-per-chained-call\n const authIdentity = $(resultIq).find('>conference').attr('identity');\n\n this.eventEmitter.emit(AuthenticationEvents.IDENTITY_UPDATED,\n authenticationEnabled, authIdentity);\n\n // Check if focus has auto-detected Jigasi component(this will be also\n // included if we have passed our host from the config)\n if ($(resultIq).find(\n '>conference>property'\n + '[name=\\'sipGatewayEnabled\\'][value=\\'true\\']').length) {\n this.sipGatewayEnabled = true;\n }\n\n logger.info(`Sip gateway enabled: ${this.sipGatewayEnabled}`);\n};\n\n// FIXME We need to show the fact that we're waiting for the focus to the user\n// (or that the focus is not available)\n/**\n * Allocates the conference focus.\n *\n * @param {Function} callback - the function to be called back upon the\n * successful allocation of the conference focus\n * @returns {Promise} - Resolved when Jicofo allows to join the room. It's never\n * rejected and it'll keep on pinging Jicofo forever.\n */\nModerator.prototype.allocateConferenceFocus = function() {\n return new Promise(resolve => {\n // Try to use focus user JID from the config\n this.setFocusUserJid(this.options.connection.focusUserJid);\n\n // Send create conference IQ\n this.connection.sendIQ(\n this.createConferenceIq(),\n result => this._allocateConferenceFocusSuccess(result, resolve),\n error => this._allocateConferenceFocusError(error, resolve));\n\n // XXX We're pressed for time here because we're beginning a complex\n // and/or lengthy conference-establishment process which supposedly\n // involves multiple RTTs. We don't have the time to wait for Strophe to\n // decide to send our IQ.\n this.connection.flush();\n });\n};\n\n/**\n * Invoked by {@link #allocateConferenceFocus} upon its request receiving an\n * error result.\n *\n * @param error - the error result of the request that\n * {@link #allocateConferenceFocus} sent\n * @param {Function} callback - the function to be called back upon the\n * successful allocation of the conference focus\n */\nModerator.prototype._allocateConferenceFocusError = function(error, callback) {\n // If the session is invalid, remove and try again without session ID to get\n // a new one\n const invalidSession\n = $(error).find('>error>session-invalid').length\n || $(error).find('>error>not-acceptable').length;\n\n if (invalidSession) {\n logger.info('Session expired! - removing');\n Settings.sessionId = undefined;\n }\n if ($(error).find('>error>graceful-shutdown').length) {\n this.eventEmitter.emit(XMPPEvents.GRACEFUL_SHUTDOWN);\n\n return;\n }\n\n // Check for error returned by the reservation system\n const reservationErr = $(error).find('>error>reservation-error');\n\n if (reservationErr.length) {\n // Trigger error event\n const errorCode = reservationErr.attr('error-code');\n const errorTextNode = $(error).find('>error>text');\n let errorMsg;\n\n if (errorTextNode) {\n errorMsg = errorTextNode.text();\n }\n this.eventEmitter.emit(\n XMPPEvents.RESERVATION_ERROR,\n errorCode,\n errorMsg);\n\n return;\n }\n\n // Not authorized to create new room\n if ($(error).find('>error>not-authorized').length) {\n logger.warn('Unauthorized to start the conference', error);\n const toDomain = Strophe.getDomainFromJid(error.getAttribute('to'));\n\n if (toDomain !== this.options.connection.hosts.anonymousdomain) {\n // FIXME \"is external\" should come either from the focus or\n // config.js\n this.externalAuthEnabled = true;\n }\n this.eventEmitter.emit(XMPPEvents.AUTHENTICATION_REQUIRED);\n\n return;\n }\n const waitMs = this.getNextErrorTimeout();\n const errmsg = `Focus error, retry after ${waitMs}`;\n\n GlobalOnErrorHandler.callErrorHandler(new Error(errmsg));\n logger.error(errmsg, error);\n\n // Show message\n const focusComponent = this.getFocusComponent();\n const retrySec = waitMs / 1000;\n\n // FIXME: message is duplicated ? Do not show in case of session invalid\n // which means just a retry\n\n if (!invalidSession) {\n this.eventEmitter.emit(\n XMPPEvents.FOCUS_DISCONNECTED,\n focusComponent,\n retrySec);\n }\n\n // Reset response timeout\n this.getNextTimeout(true);\n window.setTimeout(\n () => this.allocateConferenceFocus().then(callback),\n waitMs);\n};\n\n/**\n * Invoked by {@link #allocateConferenceFocus} upon its request receiving a\n * success (i.e. non-error) result.\n *\n * @param result - the success (i.e. non-error) result of the request that\n * {@link #allocateConferenceFocus} sent\n * @param {Function} callback - the function to be called back upon the\n * successful allocation of the conference focus\n */\nModerator.prototype._allocateConferenceFocusSuccess = function(\n result,\n callback) {\n // Setup config options\n this.parseConfigOptions(result);\n\n // Reset the error timeout (because we haven't failed here).\n this.getNextErrorTimeout(true);\n\n // eslint-disable-next-line newline-per-chained-call\n if ($(result).find('conference').attr('ready') === 'true') {\n // Reset the non-error timeout (because we've succeeded here).\n this.getNextTimeout(true);\n\n // Exec callback\n callback();\n } else {\n const waitMs = this.getNextTimeout();\n\n logger.info(`Waiting for the focus... ${waitMs}`);\n window.setTimeout(\n () => this.allocateConferenceFocus().then(callback),\n waitMs);\n }\n};\n\nModerator.prototype.authenticate = function() {\n return new Promise((resolve, reject) => {\n this.connection.sendIQ(\n this.createConferenceIq(),\n result => {\n this.parseSessionId(result);\n resolve();\n },\n errorIq => reject({\n error: $(errorIq).find('iq>error :first')\n .prop('tagName'),\n message: $(errorIq).find('iq>error>text')\n .text()\n })\n );\n });\n};\n\nModerator.prototype.getLoginUrl = function(urlCallback, failureCallback) {\n this._getLoginUrl(/* popup */ false, urlCallback, failureCallback);\n};\n\n/**\n *\n * @param {boolean} popup false for {@link Moderator#getLoginUrl} or true for\n * {@link Moderator#getPopupLoginUrl}\n * @param urlCb\n * @param failureCb\n */\nModerator.prototype._getLoginUrl = function(popup, urlCb, failureCb) {\n const iq = $iq({ to: this.getFocusComponent(),\n type: 'get' });\n const attrs = {\n xmlns: 'http://jitsi.org/protocol/focus',\n room: this.roomName,\n 'machine-uid': Settings.machineId\n };\n let str = 'auth url'; // for logger\n\n if (popup) {\n attrs.popup = true;\n str = `POPUP ${str}`;\n }\n iq.c('login-url', attrs);\n\n /**\n * Implements a failure callback which reports an error message and an error\n * through (1) GlobalOnErrorHandler, (2) logger, and (3) failureCb.\n *\n * @param {string} errmsg the error messsage to report\n * @param {*} error the error to report (in addition to errmsg)\n */\n function reportError(errmsg, err) {\n GlobalOnErrorHandler.callErrorHandler(new Error(errmsg));\n logger.error(errmsg, err);\n failureCb(err);\n }\n this.connection.sendIQ(\n iq,\n result => {\n // eslint-disable-next-line newline-per-chained-call\n let url = $(result).find('login-url').attr('url');\n\n url = decodeURIComponent(url);\n if (url) {\n logger.info(`Got ${str}: ${url}`);\n urlCb(url);\n } else {\n reportError(`Failed to get ${str} from the focus`, result);\n }\n },\n reportError.bind(undefined, `Get ${str} error`)\n );\n};\n\nModerator.prototype.getPopupLoginUrl = function(urlCallback, failureCallback) {\n this._getLoginUrl(/* popup */ true, urlCallback, failureCallback);\n};\n\nModerator.prototype.logout = function(callback) {\n const iq = $iq({ to: this.getFocusComponent(),\n type: 'set' });\n const { sessionId } = Settings;\n\n if (!sessionId) {\n callback();\n\n return;\n }\n iq.c('logout', {\n xmlns: 'http://jitsi.org/protocol/focus',\n 'session-id': sessionId\n });\n this.connection.sendIQ(\n iq,\n result => {\n // eslint-disable-next-line newline-per-chained-call\n let logoutUrl = $(result).find('logout').attr('logout-url');\n\n if (logoutUrl) {\n logoutUrl = decodeURIComponent(logoutUrl);\n }\n logger.info(`Log out OK, url: ${logoutUrl}`, result);\n Settings.sessionId = undefined;\n callback(logoutUrl);\n },\n error => {\n const errmsg = 'Logout error';\n\n GlobalOnErrorHandler.callErrorHandler(new Error(errmsg));\n logger.error(errmsg, error);\n }\n );\n};\n","const RandomUtil = require('./RandomUtil');\n\n/**\n * from faker.js - Copyright (c) 2014-2015 Matthew Bergman & Marak Squires\n * MIT License\n * http://github.com/marak/faker.js/\n *\n * @const\n */\nconst names = [\n 'Aaliyah', 'Aaron', 'Abagail', 'Abbey', 'Abbie', 'Abbigail', 'Abby',\n 'Abdiel', 'Abdul', 'Abdullah', 'Abe', 'Abel', 'Abelardo', 'Abigail',\n 'Abigale', 'Abigayle', 'Abner', 'Abraham', 'Ada', 'Adah', 'Adalberto',\n 'Adaline', 'Adam', 'Adan', 'Addie', 'Addison', 'Adela', 'Adelbert', 'Adele',\n 'Adelia', 'Adeline', 'Adell', 'Adella', 'Adelle', 'Aditya', 'Adolf',\n 'Adolfo', 'Adolph', 'Adolphus', 'Adonis', 'Adrain', 'Adrian', 'Adriana',\n 'Adrianna', 'Adriel', 'Adrien', 'Adrienne', 'Afton', 'Aglae', 'Agnes',\n 'Agustin', 'Agustina', 'Ahmad', 'Ahmed', 'Aida', 'Aidan', 'Aiden', 'Aileen',\n 'Aisha', 'Aiyana', 'Akeem', 'Al', 'Alaina', 'Alan', 'Alana', 'Alanis',\n 'Alanna', 'Alayna', 'Alba', 'Albert', 'Alberta', 'Albertha', 'Alberto',\n 'Albin', 'Albina', 'Alda', 'Alden', 'Alec', 'Aleen', 'Alejandra',\n 'Alejandrin', 'Alek', 'Alena', 'Alene', 'Alessandra', 'Alessandro',\n 'Alessia', 'Aletha', 'Alex', 'Alexa', 'Alexander', 'Alexandra', 'Alexandre',\n 'Alexandrea', 'Alexandria', 'Alexandrine', 'Alexandro', 'Alexane',\n 'Alexanne', 'Alexie', 'Alexis', 'Alexys', 'Alexzander', 'Alf', 'Alfonso',\n 'Alfonzo', 'Alford', 'Alfred', 'Alfreda', 'Alfredo', 'Ali', 'Alia', 'Alice',\n 'Alicia', 'Alisa', 'Alisha', 'Alison', 'Alivia', 'Aliya', 'Aliyah', 'Aliza',\n 'Alize', 'Allan', 'Allen', 'Allene', 'Allie', 'Allison', 'Ally', 'Alphonso',\n 'Alta', 'Althea', 'Alva', 'Alvah', 'Alvena', 'Alvera', 'Alverta', 'Alvina',\n 'Alvis', 'Alyce', 'Alycia', 'Alysa', 'Alysha', 'Alyson', 'Alysson',\n 'Amalia', 'Amanda', 'Amani', 'Amara', 'Amari', 'Amaya', 'Amber', 'Ambrose',\n 'Amelia', 'Amelie', 'Amely', 'America', 'Americo', 'Amie', 'Amina', 'Amir',\n 'Amira', 'Amiya', 'Amos', 'Amparo', 'Amy', 'Amya', 'Ana', 'Anabel',\n 'Anabelle', 'Anahi', 'Anais', 'Anastacio', 'Anastasia', 'Anderson', 'Andre',\n 'Andreane', 'Andreanne', 'Andres', 'Andrew', 'Andy', 'Angel', 'Angela',\n 'Angelica', 'Angelina', 'Angeline', 'Angelita', 'Angelo', 'Angie', 'Angus',\n 'Anibal', 'Anika', 'Anissa', 'Anita', 'Aniya', 'Aniyah', 'Anjali', 'Anna',\n 'Annabel', 'Annabell', 'Annabelle', 'Annalise', 'Annamae', 'Annamarie',\n 'Anne', 'Annetta', 'Annette', 'Annie', 'Ansel', 'Ansley', 'Anthony',\n 'Antoinette', 'Antone', 'Antonetta', 'Antonette', 'Antonia', 'Antonietta',\n 'Antonina', 'Antonio', 'Antwan', 'Antwon', 'Anya', 'April', 'Ara',\n 'Araceli', 'Aracely', 'Arch', 'Archibald', 'Ardella', 'Arden', 'Ardith',\n 'Arely', 'Ari', 'Ariane', 'Arianna', 'Aric', 'Ariel', 'Arielle', 'Arjun',\n 'Arlene', 'Arlie', 'Arlo', 'Armand', 'Armando', 'Armani', 'Arnaldo', 'Arne',\n 'Arno', 'Arnold', 'Arnoldo', 'Arnulfo', 'Aron', 'Art', 'Arthur', 'Arturo',\n 'Arvel', 'Arvid', 'Arvilla', 'Aryanna', 'Asa', 'Asha', 'Ashlee', 'Ashleigh',\n 'Ashley', 'Ashly', 'Ashlynn', 'Ashton', 'Ashtyn', 'Asia', 'Assunta',\n 'Astrid', 'Athena', 'Aubree', 'Aubrey', 'Audie', 'Audra', 'Audreanne',\n 'Audrey', 'August', 'Augusta', 'Augustine', 'Augustus', 'Aurelia',\n 'Aurelie', 'Aurelio', 'Aurore', 'Austen', 'Austin', 'Austyn', 'Autumn',\n 'Ava', 'Avery', 'Avis', 'Axel', 'Ayana', 'Ayden', 'Ayla', 'Aylin', 'Baby',\n 'Bailee', 'Bailey', 'Barbara', 'Barney', 'Baron', 'Barrett', 'Barry',\n 'Bart', 'Bartholome', 'Barton', 'Baylee', 'Beatrice', 'Beau', 'Beaulah',\n 'Bell', 'Bella', 'Belle', 'Ben', 'Benedict', 'Benjamin', 'Bennett',\n 'Bennie', 'Benny', 'Benton', 'Berenice', 'Bernadette', 'Bernadine',\n 'Bernard', 'Bernardo', 'Berneice', 'Bernhard', 'Bernice', 'Bernie',\n 'Berniece', 'Bernita', 'Berry', 'Bert', 'Berta', 'Bertha', 'Bertram',\n 'Bertrand', 'Beryl', 'Bessie', 'Beth', 'Bethany', 'Bethel', 'Betsy',\n 'Bette', 'Bettie', 'Betty', 'Bettye', 'Beulah', 'Beverly', 'Bianka', 'Bill',\n 'Billie', 'Billy', 'Birdie', 'Blair', 'Blaise', 'Blake', 'Blanca',\n 'Blanche', 'Blaze', 'Bo', 'Bobbie', 'Bobby', 'Bonita', 'Bonnie', 'Boris',\n 'Boyd', 'Brad', 'Braden', 'Bradford', 'Bradley', 'Bradly', 'Brady',\n 'Braeden', 'Brain', 'Brandi', 'Brando', 'Brandon', 'Brandt', 'Brandy',\n 'Brandyn', 'Brannon', 'Branson', 'Brant', 'Braulio', 'Braxton', 'Brayan',\n 'Breana', 'Breanna', 'Breanne', 'Brenda', 'Brendan', 'Brenden', 'Brendon',\n 'Brenna', 'Brennan', 'Brennon', 'Brent', 'Bret', 'Brett', 'Bria', 'Brian',\n 'Briana', 'Brianne', 'Brice', 'Bridget', 'Bridgette', 'Bridie', 'Brielle',\n 'Brigitte', 'Brionna', 'Brisa', 'Britney', 'Brittany', 'Brock', 'Broderick',\n 'Brody', 'Brook', 'Brooke', 'Brooklyn', 'Brooks', 'Brown', 'Bruce',\n 'Bryana', 'Bryce', 'Brycen', 'Bryon', 'Buck', 'Bud', 'Buddy', 'Buford',\n 'Bulah', 'Burdette', 'Burley', 'Burnice', 'Buster', 'Cade', 'Caden',\n 'Caesar', 'Caitlyn', 'Cale', 'Caleb', 'Caleigh', 'Cali', 'Calista',\n 'Callie', 'Camden', 'Cameron', 'Camila', 'Camilla', 'Camille', 'Camren',\n 'Camron', 'Camryn', 'Camylle', 'Candace', 'Candelario', 'Candice',\n 'Candida', 'Candido', 'Cara', 'Carey', 'Carissa', 'Carlee', 'Carleton',\n 'Carley', 'Carli', 'Carlie', 'Carlo', 'Carlos', 'Carlotta', 'Carmel',\n 'Carmela', 'Carmella', 'Carmelo', 'Carmen', 'Carmine', 'Carol', 'Carolanne',\n 'Carole', 'Carolina', 'Caroline', 'Carolyn', 'Carolyne', 'Carrie',\n 'Carroll', 'Carson', 'Carter', 'Cary', 'Casandra', 'Casey', 'Casimer',\n 'Casimir', 'Casper', 'Cassandra', 'Cassandre', 'Cassidy', 'Cassie',\n 'Catalina', 'Caterina', 'Catharine', 'Catherine', 'Cathrine', 'Cathryn',\n 'Cathy', 'Cayla', 'Ceasar', 'Cecelia', 'Cecil', 'Cecile', 'Cecilia',\n 'Cedrick', 'Celestine', 'Celestino', 'Celia', 'Celine', 'Cesar', 'Chad',\n 'Chadd', 'Chadrick', 'Chaim', 'Chance', 'Chandler', 'Chanel', 'Chanelle',\n 'Charity', 'Charlene', 'Charles', 'Charley', 'Charlie', 'Charlotte',\n 'Chase', 'Chasity', 'Chauncey', 'Chaya', 'Chaz', 'Chelsea', 'Chelsey',\n 'Chelsie', 'Chesley', 'Chester', 'Chet', 'Cheyanne', 'Cheyenne', 'Chloe',\n 'Chris', 'Christ', 'Christa', 'Christelle', 'Christian', 'Christiana',\n 'Christina', 'Christine', 'Christop', 'Christophe', 'Christopher',\n 'Christy', 'Chyna', 'Ciara', 'Cicero', 'Cielo', 'Cierra', 'Cindy',\n 'Citlalli', 'Clair', 'Claire', 'Clara', 'Clarabelle', 'Clare', 'Clarissa',\n 'Clark', 'Claud', 'Claude', 'Claudia', 'Claudie', 'Claudine', 'Clay',\n 'Clemens', 'Clement', 'Clementina', 'Clementine', 'Clemmie', 'Cleo',\n 'Cleora', 'Cleta', 'Cletus', 'Cleve', 'Cleveland', 'Clifford', 'Clifton',\n 'Clint', 'Clinton', 'Clotilde', 'Clovis', 'Cloyd', 'Clyde', 'Coby', 'Cody',\n 'Colby', 'Cole', 'Coleman', 'Colin', 'Colleen', 'Collin', 'Colt', 'Colten',\n 'Colton', 'Columbus', 'Concepcion', 'Conner', 'Connie', 'Connor', 'Conor',\n 'Conrad', 'Constance', 'Constantin', 'Consuelo', 'Cooper', 'Cora',\n 'Coralie', 'Corbin', 'Cordelia', 'Cordell', 'Cordia', 'Cordie', 'Corene',\n 'Corine', 'Cornelius', 'Cornell', 'Corrine', 'Cortez', 'Cortney', 'Cory',\n 'Coty', 'Courtney', 'Coy', 'Craig', 'Crawford', 'Creola', 'Cristal',\n 'Cristian', 'Cristina', 'Cristobal', 'Cristopher', 'Cruz', 'Crystal',\n 'Crystel', 'Cullen', 'Curt', 'Curtis', 'Cydney', 'Cynthia', 'Cyril',\n 'Cyrus', 'Dagmar', 'Dahlia', 'Daija', 'Daisha', 'Daisy', 'Dakota', 'Dale',\n 'Dallas', 'Dallin', 'Dalton', 'Damaris', 'Dameon', 'Damian', 'Damien',\n 'Damion', 'Damon', 'Dan', 'Dana', 'Dandre', 'Dane', 'D\\'angelo', 'Dangelo',\n 'Danial', 'Daniela', 'Daniella', 'Danielle', 'Danika', 'Dannie', 'Danny',\n 'Dante', 'Danyka', 'Daphne', 'Daphnee', 'Daphney', 'Darby', 'Daren',\n 'Darian', 'Dariana', 'Darien', 'Dario', 'Darion', 'Darius', 'Darlene',\n 'Daron', 'Darrel', 'Darrell', 'Darren', 'Darrick', 'Darrin', 'Darrion',\n 'Darron', 'Darryl', 'Darwin', 'Daryl', 'Dashawn', 'Dasia', 'Dave', 'David',\n 'Davin', 'Davion', 'Davon', 'Davonte', 'Dawn', 'Dawson', 'Dax', 'Dayana',\n 'Dayna', 'Dayne', 'Dayton', 'Dean', 'Deangelo', 'Deanna', 'Deborah',\n 'Declan', 'Dedric', 'Dedrick', 'Dee', 'Deion', 'Deja', 'Dejah', 'Dejon',\n 'Dejuan', 'Delaney', 'Delbert', 'Delfina', 'Delia', 'Delilah', 'Dell',\n 'Della', 'Delmer', 'Delores', 'Delpha', 'Delphia', 'Delphine', 'Delta',\n 'Demarco', 'Demarcus', 'Demario', 'Demetris', 'Demetrius', 'Demond', 'Dena',\n 'Denis', 'Dennis', 'Deon', 'Deondre', 'Deontae', 'Deonte', 'Dereck',\n 'Derek', 'Derick', 'Deron', 'Derrick', 'Deshaun', 'Deshawn', 'Desiree',\n 'Desmond', 'Dessie', 'Destany', 'Destin', 'Destinee', 'Destiney', 'Destini',\n 'Destiny', 'Devan', 'Devante', 'Deven', 'Devin', 'Devon', 'Devonte',\n 'Devyn', 'Dewayne', 'Dewitt', 'Dexter', 'Diamond', 'Diana', 'Dianna',\n 'Diego', 'Dillan', 'Dillon', 'Dimitri', 'Dina', 'Dino', 'Dion', 'Dixie',\n 'Dock', 'Dolly', 'Dolores', 'Domenic', 'Domenica', 'Domenick', 'Domenico',\n 'Domingo', 'Dominic', 'Dominique', 'Don', 'Donald', 'Donato', 'Donavon',\n 'Donna', 'Donnell', 'Donnie', 'Donny', 'Dora', 'Dorcas', 'Dorian', 'Doris',\n 'Dorothea', 'Dorothy', 'Dorris', 'Dortha', 'Dorthy', 'Doug', 'Douglas',\n 'Dovie', 'Doyle', 'Drake', 'Drew', 'Duane', 'Dudley', 'Dulce', 'Duncan',\n 'Durward', 'Dustin', 'Dusty', 'Dwight', 'Dylan', 'Earl', 'Earlene',\n 'Earline', 'Earnest', 'Earnestine', 'Easter', 'Easton', 'Ebba', 'Ebony',\n 'Ed', 'Eda', 'Edd', 'Eddie', 'Eden', 'Edgar', 'Edgardo', 'Edison', 'Edmond',\n 'Edmund', 'Edna', 'Eduardo', 'Edward', 'Edwardo', 'Edwin', 'Edwina',\n 'Edyth', 'Edythe', 'Effie', 'Efrain', 'Efren', 'Eileen', 'Einar', 'Eino',\n 'Eladio', 'Elaina', 'Elbert', 'Elda', 'Eldon', 'Eldora', 'Eldred',\n 'Eldridge', 'Eleanora', 'Eleanore', 'Eleazar', 'Electa', 'Elena', 'Elenor',\n 'Elenora', 'Eleonore', 'Elfrieda', 'Eli', 'Elian', 'Eliane', 'Elias',\n 'Eliezer', 'Elijah', 'Elinor', 'Elinore', 'Elisa', 'Elisabeth', 'Elise',\n 'Eliseo', 'Elisha', 'Elissa', 'Eliza', 'Elizabeth', 'Ella', 'Ellen',\n 'Ellie', 'Elliot', 'Elliott', 'Ellis', 'Ellsworth', 'Elmer', 'Elmira',\n 'Elmo', 'Elmore', 'Elna', 'Elnora', 'Elody', 'Eloisa', 'Eloise', 'Elouise',\n 'Eloy', 'Elroy', 'Elsa', 'Else', 'Elsie', 'Elta', 'Elton', 'Elva', 'Elvera',\n 'Elvie', 'Elvis', 'Elwin', 'Elwyn', 'Elyse', 'Elyssa', 'Elza', 'Emanuel',\n 'Emelia', 'Emelie', 'Emely', 'Emerald', 'Emerson', 'Emery', 'Emie', 'Emil',\n 'Emile', 'Emilia', 'Emiliano', 'Emilie', 'Emilio', 'Emily', 'Emma',\n 'Emmalee', 'Emmanuel', 'Emmanuelle', 'Emmet', 'Emmett', 'Emmie', 'Emmitt',\n 'Emmy', 'Emory', 'Ena', 'Enid', 'Enoch', 'Enola', 'Enos', 'Enrico',\n 'Enrique', 'Ephraim', 'Era', 'Eriberto', 'Eric', 'Erica', 'Erich', 'Erick',\n 'Ericka', 'Erik', 'Erika', 'Erin', 'Erling', 'Erna', 'Ernest', 'Ernestina',\n 'Ernestine', 'Ernesto', 'Ernie', 'Ervin', 'Erwin', 'Eryn', 'Esmeralda',\n 'Esperanza', 'Esta', 'Esteban', 'Estefania', 'Estel', 'Estell', 'Estella',\n 'Estelle', 'Estevan', 'Esther', 'Estrella', 'Etha', 'Ethan', 'Ethel',\n 'Ethelyn', 'Ethyl', 'Ettie', 'Eudora', 'Eugene', 'Eugenia', 'Eula', 'Eulah',\n 'Eulalia', 'Euna', 'Eunice', 'Eusebio', 'Eva', 'Evalyn', 'Evan',\n 'Evangeline', 'Evans', 'Eve', 'Eveline', 'Evelyn', 'Everardo', 'Everett',\n 'Everette', 'Evert', 'Evie', 'Ewald', 'Ewell', 'Ezekiel', 'Ezequiel',\n 'Ezra', 'Fabian', 'Fabiola', 'Fae', 'Fannie', 'Fanny', 'Fatima', 'Faustino',\n 'Fausto', 'Favian', 'Fay', 'Faye', 'Federico', 'Felicia', 'Felicita',\n 'Felicity', 'Felipa', 'Felipe', 'Felix', 'Felton', 'Fermin', 'Fern',\n 'Fernando', 'Ferne', 'Fidel', 'Filiberto', 'Filomena', 'Finn', 'Fiona',\n 'Flavie', 'Flavio', 'Fleta', 'Fletcher', 'Flo', 'Florence', 'Florencio',\n 'Florian', 'Florida', 'Florine', 'Flossie', 'Floy', 'Floyd', 'Ford',\n 'Forest', 'Forrest', 'Foster', 'Frances', 'Francesca', 'Francesco',\n 'Francis', 'Francisca', 'Francisco', 'Franco', 'Frank', 'Frankie', 'Franz',\n 'Fred', 'Freda', 'Freddie', 'Freddy', 'Frederic', 'Frederick', 'Frederik',\n 'Frederique', 'Fredrick', 'Fredy', 'Freeda', 'Freeman', 'Freida', 'Frida',\n 'Frieda', 'Friedrich', 'Fritz', 'Furman', 'Gabe', 'Gabriel', 'Gabriella',\n 'Gabrielle', 'Gaetano', 'Gage', 'Gail', 'Gardner', 'Garett', 'Garfield',\n 'Garland', 'Garnet', 'Garnett', 'Garret', 'Garrett', 'Garrick', 'Garrison',\n 'Garry', 'Garth', 'Gaston', 'Gavin', 'Gay', 'Gayle', 'Gaylord', 'Gene',\n 'General', 'Genesis', 'Genevieve', 'Gennaro', 'Genoveva', 'Geo', 'Geoffrey',\n 'George', 'Georgette', 'Georgiana', 'Georgianna', 'Geovanni', 'Geovanny',\n 'Geovany', 'Gerald', 'Geraldine', 'Gerard', 'Gerardo', 'Gerda', 'Gerhard',\n 'Germaine', 'German', 'Gerry', 'Gerson', 'Gertrude', 'Gia', 'Gianni',\n 'Gideon', 'Gilbert', 'Gilberto', 'Gilda', 'Giles', 'Gillian', 'Gina',\n 'Gino', 'Giovani', 'Giovanna', 'Giovanni', 'Giovanny', 'Gisselle',\n 'Giuseppe', 'Gladyce', 'Gladys', 'Glen', 'Glenda', 'Glenna', 'Glennie',\n 'Gloria', 'Godfrey', 'Golda', 'Golden', 'Gonzalo', 'Gordon', 'Grace',\n 'Gracie', 'Graciela', 'Grady', 'Graham', 'Grant', 'Granville', 'Grayce',\n 'Grayson', 'Green', 'Greg', 'Gregg', 'Gregoria', 'Gregorio', 'Gregory',\n 'Greta', 'Gretchen', 'Greyson', 'Griffin', 'Grover', 'Guadalupe', 'Gudrun',\n 'Guido', 'Guillermo', 'Guiseppe', 'Gunnar', 'Gunner', 'Gus', 'Gussie',\n 'Gust', 'Gustave', 'Guy', 'Gwen', 'Gwendolyn', 'Hadley', 'Hailee', 'Hailey',\n 'Hailie', 'Hal', 'Haleigh', 'Haley', 'Halie', 'Halle', 'Hallie', 'Hank',\n 'Hanna', 'Hannah', 'Hans', 'Hardy', 'Harley', 'Harmon', 'Harmony', 'Harold',\n 'Harrison', 'Harry', 'Harvey', 'Haskell', 'Hassan', 'Hassie', 'Hattie',\n 'Haven', 'Hayden', 'Haylee', 'Hayley', 'Haylie', 'Hazel', 'Hazle', 'Heath',\n 'Heather', 'Heaven', 'Heber', 'Hector', 'Heidi', 'Helen', 'Helena',\n 'Helene', 'Helga', 'Hellen', 'Helmer', 'Heloise', 'Henderson', 'Henri',\n 'Henriette', 'Henry', 'Herbert', 'Herman', 'Hermann', 'Hermina', 'Herminia',\n 'Herminio', 'Hershel', 'Herta', 'Hertha', 'Hester', 'Hettie', 'Hilario',\n 'Hilbert', 'Hilda', 'Hildegard', 'Hillard', 'Hillary', 'Hilma', 'Hilton',\n 'Hipolito', 'Hiram', 'Hobart', 'Holden', 'Hollie', 'Hollis', 'Holly',\n 'Hope', 'Horace', 'Horacio', 'Hortense', 'Hosea', 'Houston', 'Howard',\n 'Howell', 'Hoyt', 'Hubert', 'Hudson', 'Hugh', 'Hulda', 'Humberto', 'Hunter',\n 'Hyman', 'Ian', 'Ibrahim', 'Icie', 'Ida', 'Idell', 'Idella', 'Ignacio',\n 'Ignatius', 'Ike', 'Ila', 'Ilene', 'Iliana', 'Ima', 'Imani', 'Imelda',\n 'Immanuel', 'Imogene', 'Ines', 'Irma', 'Irving', 'Irwin', 'Isaac', 'Isabel',\n 'Isabell', 'Isabella', 'Isabelle', 'Isac', 'Isadore', 'Isai', 'Isaiah',\n 'Isaias', 'Isidro', 'Ismael', 'Isobel', 'Isom', 'Israel', 'Issac', 'Itzel',\n 'Iva', 'Ivah', 'Ivory', 'Ivy', 'Izabella', 'Izaiah', 'Jabari', 'Jace',\n 'Jacey', 'Jacinthe', 'Jacinto', 'Jack', 'Jackeline', 'Jackie', 'Jacklyn',\n 'Jackson', 'Jacky', 'Jaclyn', 'Jacquelyn', 'Jacques', 'Jacynthe', 'Jada',\n 'Jade', 'Jaden', 'Jadon', 'Jadyn', 'Jaeden', 'Jaida', 'Jaiden', 'Jailyn',\n 'Jaime', 'Jairo', 'Jakayla', 'Jake', 'Jakob', 'Jaleel', 'Jalen', 'Jalon',\n 'Jalyn', 'Jamaal', 'Jamal', 'Jamar', 'Jamarcus', 'Jamel', 'Jameson',\n 'Jamey', 'Jamie', 'Jamil', 'Jamir', 'Jamison', 'Jammie', 'Jan', 'Jana',\n 'Janae', 'Jane', 'Janelle', 'Janessa', 'Janet', 'Janice', 'Janick', 'Janie',\n 'Janis', 'Janiya', 'Jannie', 'Jany', 'Jaquan', 'Jaquelin', 'Jaqueline',\n 'Jared', 'Jaren', 'Jarod', 'Jaron', 'Jarred', 'Jarrell', 'Jarret',\n 'Jarrett', 'Jarrod', 'Jarvis', 'Jasen', 'Jasmin', 'Jason', 'Jasper',\n 'Jaunita', 'Javier', 'Javon', 'Javonte', 'Jay', 'Jayce', 'Jaycee', 'Jayda',\n 'Jayde', 'Jayden', 'Jaydon', 'Jaylan', 'Jaylen', 'Jaylin', 'Jaylon',\n 'Jayme', 'Jayne', 'Jayson', 'Jazlyn', 'Jazmin', 'Jazmyn', 'Jazmyne', 'Jean',\n 'Jeanette', 'Jeanie', 'Jeanne', 'Jed', 'Jedediah', 'Jedidiah', 'Jeff',\n 'Jefferey', 'Jeffery', 'Jeffrey', 'Jeffry', 'Jena', 'Jenifer', 'Jennie',\n 'Jennifer', 'Jennings', 'Jennyfer', 'Jensen', 'Jerad', 'Jerald', 'Jeramie',\n 'Jeramy', 'Jerel', 'Jeremie', 'Jeremy', 'Jermain', 'Jermaine', 'Jermey',\n 'Jerod', 'Jerome', 'Jeromy', 'Jerrell', 'Jerrod', 'Jerrold', 'Jerry',\n 'Jess', 'Jesse', 'Jessica', 'Jessie', 'Jessika', 'Jessy', 'Jessyca',\n 'Jesus', 'Jett', 'Jettie', 'Jevon', 'Jewel', 'Jewell', 'Jillian', 'Jimmie',\n 'Jimmy', 'Jo', 'Joan', 'Joana', 'Joanie', 'Joanne', 'Joannie', 'Joanny',\n 'Joany', 'Joaquin', 'Jocelyn', 'Jodie', 'Jody', 'Joe', 'Joel', 'Joelle',\n 'Joesph', 'Joey', 'Johan', 'Johann', 'Johanna', 'Johathan', 'John',\n 'Johnathan', 'Johnathon', 'Johnnie', 'Johnny', 'Johnpaul', 'Johnson',\n 'Jolie', 'Jon', 'Jonas', 'Jonatan', 'Jonathan', 'Jonathon', 'Jordan',\n 'Jordane', 'Jordi', 'Jordon', 'Jordy', 'Jordyn', 'Jorge', 'Jose', 'Josefa',\n 'Josefina', 'Joseph', 'Josephine', 'Josh', 'Joshua', 'Joshuah', 'Josiah',\n 'Josiane', 'Josianne', 'Josie', 'Josue', 'Jovan', 'Jovani', 'Jovanny',\n 'Jovany', 'Joy', 'Joyce', 'Juana', 'Juanita', 'Judah', 'Judd', 'Jude',\n 'Judge', 'Judson', 'Judy', 'Jules', 'Julia', 'Julian', 'Juliana',\n 'Julianne', 'Julie', 'Julien', 'Juliet', 'Julio', 'Julius', 'June',\n 'Junior', 'Junius', 'Justen', 'Justice', 'Justina', 'Justine', 'Juston',\n 'Justus', 'Justyn', 'Juvenal', 'Juwan', 'Kacey', 'Kaci', 'Kacie', 'Kade',\n 'Kaden', 'Kadin', 'Kaela', 'Kaelyn', 'Kaia', 'Kailee', 'Kailey', 'Kailyn',\n 'Kaitlin', 'Kaitlyn', 'Kale', 'Kaleb', 'Kaleigh', 'Kaley', 'Kali', 'Kallie',\n 'Kameron', 'Kamille', 'Kamren', 'Kamron', 'Kamryn', 'Kane', 'Kara',\n 'Kareem', 'Karelle', 'Karen', 'Kari', 'Kariane', 'Karianne', 'Karina',\n 'Karine', 'Karl', 'Karlee', 'Karley', 'Karli', 'Karlie', 'Karolann',\n 'Karson', 'Kasandra', 'Kasey', 'Kassandra', 'Katarina', 'Katelin',\n 'Katelyn', 'Katelynn', 'Katharina', 'Katherine', 'Katheryn', 'Kathleen',\n 'Kathlyn', 'Kathryn', 'Kathryne', 'Katlyn', 'Katlynn', 'Katrina', 'Katrine',\n 'Kattie', 'Kavon', 'Kay', 'Kaya', 'Kaycee', 'Kayden', 'Kayla', 'Kaylah',\n 'Kaylee', 'Kayleigh', 'Kayley', 'Kayli', 'Kaylie', 'Kaylin', 'Keagan',\n 'Keanu', 'Keara', 'Keaton', 'Keegan', 'Keeley', 'Keely', 'Keenan', 'Keira',\n 'Keith', 'Kellen', 'Kelley', 'Kelli', 'Kellie', 'Kelly', 'Kelsi', 'Kelsie',\n 'Kelton', 'Kelvin', 'Ken', 'Kendall', 'Kendra', 'Kendrick', 'Kenna',\n 'Kennedi', 'Kennedy', 'Kenneth', 'Kennith', 'Kenny', 'Kenton', 'Kenya',\n 'Kenyatta', 'Kenyon', 'Keon', 'Keshaun', 'Keshawn', 'Keven', 'Kevin',\n 'Kevon', 'Keyon', 'Keyshawn', 'Khalid', 'Khalil', 'Kian', 'Kiana', 'Kianna',\n 'Kiara', 'Kiarra', 'Kiel', 'Kiera', 'Kieran', 'Kiley', 'Kim', 'Kimberly',\n 'King', 'Kip', 'Kira', 'Kirk', 'Kirsten', 'Kirstin', 'Kitty', 'Kobe',\n 'Koby', 'Kody', 'Kolby', 'Kole', 'Korbin', 'Korey', 'Kory', 'Kraig', 'Kris',\n 'Krista', 'Kristian', 'Kristin', 'Kristina', 'Kristofer', 'Kristoffer',\n 'Kristopher', 'Kristy', 'Krystal', 'Krystel', 'Krystina', 'Kurt', 'Kurtis',\n 'Kyla', 'Kyle', 'Kylee', 'Kyleigh', 'Kyler', 'Kylie', 'Kyra', 'Lacey',\n 'Lacy', 'Ladarius', 'Lafayette', 'Laila', 'Laisha', 'Lamar', 'Lambert',\n 'Lamont', 'Lance', 'Landen', 'Lane', 'Laney', 'Larissa', 'Laron', 'Larry',\n 'Larue', 'Laura', 'Laurel', 'Lauren', 'Laurence', 'Lauretta', 'Lauriane',\n 'Laurianne', 'Laurie', 'Laurine', 'Laury', 'Lauryn', 'Lavada', 'Lavern',\n 'Laverna', 'Laverne', 'Lavina', 'Lavinia', 'Lavon', 'Lavonne', 'Lawrence',\n 'Lawson', 'Layla', 'Layne', 'Lazaro', 'Lea', 'Leann', 'Leanna', 'Leanne',\n 'Leatha', 'Leda', 'Lee', 'Leif', 'Leila', 'Leilani', 'Lela', 'Lelah',\n 'Leland', 'Lelia', 'Lempi', 'Lemuel', 'Lenna', 'Lennie', 'Lenny', 'Lenora',\n 'Lenore', 'Leo', 'Leola', 'Leon', 'Leonard', 'Leonardo', 'Leone', 'Leonel',\n 'Leonie', 'Leonor', 'Leonora', 'Leopold', 'Leopoldo', 'Leora', 'Lera',\n 'Lesley', 'Leslie', 'Lesly', 'Lessie', 'Lester', 'Leta', 'Letha', 'Letitia',\n 'Levi', 'Lew', 'Lewis', 'Lexi', 'Lexie', 'Lexus', 'Lia', 'Liam', 'Liana',\n 'Libbie', 'Libby', 'Lila', 'Lilian', 'Liliana', 'Liliane', 'Lilla',\n 'Lillian', 'Lilliana', 'Lillie', 'Lilly', 'Lily', 'Lilyan', 'Lina',\n 'Lincoln', 'Linda', 'Lindsay', 'Lindsey', 'Linnea', 'Linnie', 'Linwood',\n 'Lionel', 'Lisa', 'Lisandro', 'Lisette', 'Litzy', 'Liza', 'Lizeth',\n 'Lizzie', 'Llewellyn', 'Lloyd', 'Logan', 'Lois', 'Lola', 'Lolita', 'Loma',\n 'Lon', 'London', 'Lonie', 'Lonnie', 'Lonny', 'Lonzo', 'Lora', 'Loraine',\n 'Loren', 'Lorena', 'Lorenz', 'Lorenza', 'Lorenzo', 'Lori', 'Lorine',\n 'Lorna', 'Lottie', 'Lou', 'Louie', 'Louisa', 'Lourdes', 'Louvenia',\n 'Lowell', 'Loy', 'Loyal', 'Loyce', 'Lucas', 'Luciano', 'Lucie', 'Lucienne',\n 'Lucile', 'Lucinda', 'Lucio', 'Lucious', 'Lucius', 'Lucy', 'Ludie',\n 'Ludwig', 'Lue', 'Luella', 'Luigi', 'Luis', 'Luisa', 'Lukas', 'Lula',\n 'Lulu', 'Luna', 'Lupe', 'Lura', 'Lurline', 'Luther', 'Luz', 'Lyda', 'Lydia',\n 'Lyla', 'Lynn', 'Lyric', 'Lysanne', 'Mabel', 'Mabelle', 'Mable', 'Mac',\n 'Macey', 'Maci', 'Macie', 'Mack', 'Mackenzie', 'Macy', 'Madaline',\n 'Madalyn', 'Maddison', 'Madeline', 'Madelyn', 'Madelynn', 'Madge', 'Madie',\n 'Madilyn', 'Madisen', 'Madison', 'Madisyn', 'Madonna', 'Madyson', 'Mae',\n 'Maegan', 'Maeve', 'Mafalda', 'Magali', 'Magdalen', 'Magdalena', 'Maggie',\n 'Magnolia', 'Magnus', 'Maia', 'Maida', 'Maiya', 'Major', 'Makayla',\n 'Makenna', 'Makenzie', 'Malachi', 'Malcolm', 'Malika', 'Malinda', 'Mallie',\n 'Mallory', 'Malvina', 'Mandy', 'Manley', 'Manuel', 'Manuela', 'Mara',\n 'Marc', 'Marcel', 'Marcelina', 'Marcelino', 'Marcella', 'Marcelle',\n 'Marcellus', 'Marcelo', 'Marcia', 'Marco', 'Marcos', 'Marcus', 'Margaret',\n 'Margarete', 'Margarett', 'Margaretta', 'Margarette', 'Margarita', 'Marge',\n 'Margie', 'Margot', 'Margret', 'Marguerite', 'Maria', 'Mariah', 'Mariam',\n 'Marian', 'Mariana', 'Mariane', 'Marianna', 'Marianne', 'Mariano',\n 'Maribel', 'Marie', 'Mariela', 'Marielle', 'Marietta', 'Marilie', 'Marilou',\n 'Marilyne', 'Marina', 'Mario', 'Marion', 'Marisa', 'Marisol', 'Maritza',\n 'Marjolaine', 'Marjorie', 'Marjory', 'Mark', 'Markus', 'Marlee', 'Marlen',\n 'Marlene', 'Marley', 'Marlin', 'Marlon', 'Marques', 'Marquis', 'Marquise',\n 'Marshall', 'Marta', 'Martin', 'Martina', 'Martine', 'Marty', 'Marvin',\n 'Mary', 'Maryam', 'Maryjane', 'Maryse', 'Mason', 'Mateo', 'Mathew',\n 'Mathias', 'Mathilde', 'Matilda', 'Matilde', 'Matt', 'Matteo', 'Mattie',\n 'Maud', 'Maude', 'Maudie', 'Maureen', 'Maurice', 'Mauricio', 'Maurine',\n 'Maverick', 'Mavis', 'Max', 'Maxie', 'Maxime', 'Maximilian', 'Maximillia',\n 'Maximillian', 'Maximo', 'Maximus', 'Maxine', 'Maxwell', 'May', 'Maya',\n 'Maybell', 'Maybelle', 'Maye', 'Maymie', 'Maynard', 'Mayra', 'Mazie',\n 'Mckayla', 'Mckenna', 'Mckenzie', 'Meagan', 'Meaghan', 'Meda', 'Megane',\n 'Meggie', 'Meghan', 'Mekhi', 'Melany', 'Melba', 'Melisa', 'Melissa',\n 'Mellie', 'Melody', 'Melvin', 'Melvina', 'Melyna', 'Melyssa', 'Mercedes',\n 'Meredith', 'Merl', 'Merle', 'Merlin', 'Merritt', 'Mertie', 'Mervin',\n 'Meta', 'Mia', 'Micaela', 'Micah', 'Michael', 'Michaela', 'Michale',\n 'Micheal', 'Michel', 'Michele', 'Michelle', 'Miguel', 'Mikayla', 'Mike',\n 'Mikel', 'Milan', 'Miles', 'Milford', 'Miller', 'Millie', 'Milo', 'Milton',\n 'Mina', 'Minerva', 'Minnie', 'Miracle', 'Mireille', 'Mireya', 'Misael',\n 'Missouri', 'Misty', 'Mitchel', 'Mitchell', 'Mittie', 'Modesta', 'Modesto',\n 'Mohamed', 'Mohammad', 'Mohammed', 'Moises', 'Mollie', 'Molly', 'Mona',\n 'Monica', 'Monique', 'Monroe', 'Monserrat', 'Monserrate', 'Montana',\n 'Monte', 'Monty', 'Morgan', 'Moriah', 'Morris', 'Mortimer', 'Morton',\n 'Mose', 'Moses', 'Moshe', 'Mossie', 'Mozell', 'Mozelle', 'Muhammad',\n 'Muriel', 'Murl', 'Murphy', 'Murray', 'Mustafa', 'Mya', 'Myah', 'Mylene',\n 'Myles', 'Myra', 'Myriam', 'Myrl', 'Myrna', 'Myron', 'Myrtice', 'Myrtie',\n 'Myrtis', 'Myrtle', 'Nadia', 'Nakia', 'Name', 'Nannie', 'Naomi', 'Naomie',\n 'Napoleon', 'Narciso', 'Nash', 'Nasir', 'Nat', 'Natalia', 'Natalie',\n 'Natasha', 'Nathan', 'Nathanael', 'Nathanial', 'Nathaniel', 'Nathen',\n 'Nayeli', 'Neal', 'Ned', 'Nedra', 'Neha', 'Neil', 'Nelda', 'Nella', 'Nelle',\n 'Nellie', 'Nels', 'Nelson', 'Neoma', 'Nestor', 'Nettie', 'Neva', 'Newell',\n 'Newton', 'Nia', 'Nicholas', 'Nicholaus', 'Nichole', 'Nick', 'Nicklaus',\n 'Nickolas', 'Nico', 'Nicola', 'Nicolas', 'Nicole', 'Nicolette', 'Nigel',\n 'Nikita', 'Nikki', 'Nikko', 'Niko', 'Nikolas', 'Nils', 'Nina', 'Noah',\n 'Noble', 'Noe', 'Noel', 'Noelia', 'Noemi', 'Noemie', 'Noemy', 'Nola',\n 'Nolan', 'Nona', 'Nora', 'Norbert', 'Norberto', 'Norene', 'Norma', 'Norris',\n 'Norval', 'Norwood', 'Nova', 'Novella', 'Nya', 'Nyah', 'Nyasia', 'Obie',\n 'Oceane', 'Ocie', 'Octavia', 'Oda', 'Odell', 'Odessa', 'Odie', 'Ofelia',\n 'Okey', 'Ola', 'Olaf', 'Ole', 'Olen', 'Oleta', 'Olga', 'Olin', 'Oliver',\n 'Ollie', 'Oma', 'Omari', 'Omer', 'Ona', 'Onie', 'Opal', 'Ophelia', 'Ora',\n 'Oral', 'Oran', 'Oren', 'Orie', 'Orin', 'Orion', 'Orland', 'Orlando',\n 'Orlo', 'Orpha', 'Orrin', 'Orval', 'Orville', 'Osbaldo', 'Osborne', 'Oscar',\n 'Osvaldo', 'Oswald', 'Oswaldo', 'Otha', 'Otho', 'Otilia', 'Otis', 'Ottilie',\n 'Ottis', 'Otto', 'Ova', 'Owen', 'Ozella', 'Pablo', 'Paige', 'Palma',\n 'Pamela', 'Pansy', 'Paolo', 'Paris', 'Parker', 'Pascale', 'Pasquale', 'Pat',\n 'Patience', 'Patricia', 'Patrick', 'Patsy', 'Pattie', 'Paul', 'Paula',\n 'Pauline', 'Paxton', 'Payton', 'Pearl', 'Pearlie', 'Pearline', 'Pedro',\n 'Peggie', 'Penelope', 'Percival', 'Percy', 'Perry', 'Pete', 'Peter',\n 'Petra', 'Peyton', 'Philip', 'Phoebe', 'Phyllis', 'Pierce', 'Pierre',\n 'Pietro', 'Pink', 'Pinkie', 'Piper', 'Polly', 'Porter', 'Precious',\n 'Presley', 'Preston', 'Price', 'Prince', 'Princess', 'Priscilla',\n 'Providenci', 'Prudence', 'Queen', 'Queenie', 'Quentin', 'Quincy', 'Quinn',\n 'Quinten', 'Quinton', 'Rachael', 'Rachel', 'Rachelle', 'Rae', 'Raegan',\n 'Rafael', 'Rafaela', 'Raheem', 'Rahsaan', 'Rahul', 'Raina', 'Raleigh',\n 'Ralph', 'Ramiro', 'Ramon', 'Ramona', 'Randal', 'Randall', 'Randi', 'Randy',\n 'Ransom', 'Raoul', 'Raphael', 'Raphaelle', 'Raquel', 'Rashad', 'Rashawn',\n 'Rasheed', 'Raul', 'Raven', 'Ray', 'Raymond', 'Raymundo', 'Reagan',\n 'Reanna', 'Reba', 'Rebeca', 'Rebecca', 'Rebeka', 'Rebekah', 'Reece', 'Reed',\n 'Reese', 'Regan', 'Reggie', 'Reginald', 'Reid', 'Reilly', 'Reina',\n 'Reinhold', 'Remington', 'Rene', 'Renee', 'Ressie', 'Reta', 'Retha',\n 'Retta', 'Reuben', 'Reva', 'Rex', 'Rey', 'Reyes', 'Reymundo', 'Reyna',\n 'Reynold', 'Rhea', 'Rhett', 'Rhianna', 'Rhiannon', 'Rhoda', 'Ricardo',\n 'Richard', 'Richie', 'Richmond', 'Rick', 'Rickey', 'Rickie', 'Ricky',\n 'Rico', 'Rigoberto', 'Riley', 'Rita', 'River', 'Robb', 'Robbie', 'Robert',\n 'Roberta', 'Roberto', 'Robin', 'Robyn', 'Rocio', 'Rocky', 'Rod', 'Roderick',\n 'Rodger', 'Rodolfo', 'Rodrick', 'Rodrigo', 'Roel', 'Rogelio', 'Roger',\n 'Rogers', 'Rolando', 'Rollin', 'Roma', 'Romaine', 'Roman', 'Ron', 'Ronaldo',\n 'Ronny', 'Roosevelt', 'Rory', 'Rosa', 'Rosalee', 'Rosalia', 'Rosalind',\n 'Rosalinda', 'Rosalyn', 'Rosamond', 'Rosanna', 'Rosario', 'Roscoe', 'Rose',\n 'Rosella', 'Roselyn', 'Rosemarie', 'Rosemary', 'Rosendo', 'Rosetta',\n 'Rosie', 'Rosina', 'Roslyn', 'Ross', 'Rossie', 'Rowan', 'Rowena', 'Rowland',\n 'Roxane', 'Roxanne', 'Roy', 'Royal', 'Royce', 'Rozella', 'Ruben', 'Rubie',\n 'Ruby', 'Rubye', 'Rudolph', 'Rudy', 'Rupert', 'Russ', 'Russel', 'Russell',\n 'Rusty', 'Ruth', 'Ruthe', 'Ruthie', 'Ryan', 'Ryann', 'Ryder', 'Rylan',\n 'Rylee', 'Ryleigh', 'Ryley', 'Sabina', 'Sabrina', 'Sabryna', 'Sadie',\n 'Sadye', 'Sage', 'Saige', 'Sallie', 'Sally', 'Salma', 'Salvador',\n 'Salvatore', 'Sam', 'Samanta', 'Samantha', 'Samara', 'Samir', 'Sammie',\n 'Sammy', 'Samson', 'Sandra', 'Sandrine', 'Sandy', 'Sanford', 'Santa',\n 'Santiago', 'Santina', 'Santino', 'Santos', 'Sarah', 'Sarai', 'Sarina',\n 'Sasha', 'Saul', 'Savanah', 'Savanna', 'Savannah', 'Savion', 'Scarlett',\n 'Schuyler', 'Scot', 'Scottie', 'Scotty', 'Seamus', 'Sean', 'Sebastian',\n 'Sedrick', 'Selena', 'Selina', 'Selmer', 'Serena', 'Serenity', 'Seth',\n 'Shad', 'Shaina', 'Shakira', 'Shana', 'Shane', 'Shanel', 'Shanelle',\n 'Shania', 'Shanie', 'Shaniya', 'Shanna', 'Shannon', 'Shanny', 'Shanon',\n 'Shany', 'Sharon', 'Shaun', 'Shawn', 'Shawna', 'Shaylee', 'Shayna',\n 'Shayne', 'Shea', 'Sheila', 'Sheldon', 'Shemar', 'Sheridan', 'Sherman',\n 'Sherwood', 'Shirley', 'Shyann', 'Shyanne', 'Sibyl', 'Sid', 'Sidney',\n 'Sienna', 'Sierra', 'Sigmund', 'Sigrid', 'Sigurd', 'Silas', 'Sim', 'Simeon',\n 'Simone', 'Sincere', 'Sister', 'Skye', 'Skyla', 'Skylar', 'Sofia',\n 'Soledad', 'Solon', 'Sonia', 'Sonny', 'Sonya', 'Sophia', 'Sophie',\n 'Spencer', 'Stacey', 'Stacy', 'Stan', 'Stanford', 'Stanley', 'Stanton',\n 'Stefan', 'Stefanie', 'Stella', 'Stephan', 'Stephania', 'Stephanie',\n 'Stephany', 'Stephen', 'Stephon', 'Sterling', 'Steve', 'Stevie', 'Stewart',\n 'Stone', 'Stuart', 'Summer', 'Sunny', 'Susan', 'Susana', 'Susanna', 'Susie',\n 'Suzanne', 'Sven', 'Syble', 'Sydnee', 'Sydney', 'Sydni', 'Sydnie', 'Sylvan',\n 'Sylvester', 'Sylvia', 'Tabitha', 'Tad', 'Talia', 'Talon', 'Tamara',\n 'Tamia', 'Tania', 'Tanner', 'Tanya', 'Tara', 'Taryn', 'Tate', 'Tatum',\n 'Tatyana', 'Taurean', 'Tavares', 'Taya', 'Taylor', 'Teagan', 'Ted', 'Telly',\n 'Terence', 'Teresa', 'Terrance', 'Terrell', 'Terrence', 'Terrill', 'Terry',\n 'Tess', 'Tessie', 'Tevin', 'Thad', 'Thaddeus', 'Thalia', 'Thea', 'Thelma',\n 'Theo', 'Theodora', 'Theodore', 'Theresa', 'Therese', 'Theresia', 'Theron',\n 'Thomas', 'Thora', 'Thurman', 'Tia', 'Tiana', 'Tianna', 'Tiara', 'Tierra',\n 'Tiffany', 'Tillman', 'Timmothy', 'Timmy', 'Timothy', 'Tina', 'Tito',\n 'Titus', 'Tobin', 'Toby', 'Tod', 'Tom', 'Tomas', 'Tomasa', 'Tommie',\n 'Toney', 'Toni', 'Tony', 'Torey', 'Torrance', 'Torrey', 'Toy', 'Trace',\n 'Tracey', 'Tracy', 'Travis', 'Travon', 'Tre', 'Tremaine', 'Tremayne',\n 'Trent', 'Trenton', 'Tressa', 'Tressie', 'Treva', 'Trever', 'Trevion',\n 'Trevor', 'Trey', 'Trinity', 'Trisha', 'Tristian', 'Tristin', 'Triston',\n 'Troy', 'Trudie', 'Trycia', 'Trystan', 'Turner', 'Twila', 'Tyler', 'Tyra',\n 'Tyree', 'Tyreek', 'Tyrel', 'Tyrell', 'Tyrese', 'Tyrique', 'Tyshawn',\n 'Tyson', 'Ubaldo', 'Ulices', 'Ulises', 'Una', 'Unique', 'Urban', 'Uriah',\n 'Uriel', 'Ursula', 'Vada', 'Valentin', 'Valentina', 'Valentine', 'Valerie',\n 'Vallie', 'Van', 'Vance', 'Vanessa', 'Vaughn', 'Veda', 'Velda', 'Vella',\n 'Velma', 'Velva', 'Vena', 'Verda', 'Verdie', 'Vergie', 'Verla', 'Verlie',\n 'Vern', 'Verna', 'Verner', 'Vernice', 'Vernie', 'Vernon', 'Verona',\n 'Veronica', 'Vesta', 'Vicenta', 'Vicente', 'Vickie', 'Vicky', 'Victor',\n 'Victoria', 'Vida', 'Vidal', 'Vilma', 'Vince', 'Vincent', 'Vincenza',\n 'Vincenzo', 'Vinnie', 'Viola', 'Violet', 'Violette', 'Virgie', 'Virgil',\n 'Virginia', 'Virginie', 'Vita', 'Vito', 'Viva', 'Vivian', 'Viviane',\n 'Vivianne', 'Vivien', 'Vivienne', 'Vladimir', 'Wade', 'Waino', 'Waldo',\n 'Walker', 'Wallace', 'Walter', 'Walton', 'Wanda', 'Ward', 'Warren',\n 'Watson', 'Wava', 'Waylon', 'Wayne', 'Webster', 'Weldon', 'Wellington',\n 'Wendell', 'Wendy', 'Werner', 'Westley', 'Weston', 'Whitney', 'Wilber',\n 'Wilbert', 'Wilburn', 'Wiley', 'Wilford', 'Wilfred', 'Wilfredo', 'Wilfrid',\n 'Wilhelm', 'Wilhelmine', 'Will', 'Willa', 'Willard', 'William', 'Willie',\n 'Willis', 'Willow', 'Willy', 'Wilma', 'Wilmer', 'Wilson', 'Wilton',\n 'Winfield', 'Winifred', 'Winnifred', 'Winona', 'Winston', 'Woodrow',\n 'Wyatt', 'Wyman', 'Xander', 'Xavier', 'Xzavier', 'Yadira', 'Yasmeen',\n 'Yasmin', 'Yasmine', 'Yazmin', 'Yesenia', 'Yessenia', 'Yolanda', 'Yoshiko',\n 'Yvette', 'Yvonne', 'Zachariah', 'Zachary', 'Zachery', 'Zack', 'Zackary',\n 'Zackery', 'Zakary', 'Zander', 'Zane', 'Zaria', 'Zechariah', 'Zelda',\n 'Zella', 'Zelma', 'Zena', 'Zetta', 'Zion', 'Zita', 'Zoe', 'Zoey', 'Zoie',\n 'Zoila', 'Zola', 'Zora', 'Zula'\n];\n\n/**\n * Generate random username.\n * @returns {string} random username\n */\nfunction generateUsername() {\n const name = RandomUtil.randomElement(names);\n const suffix = RandomUtil.randomAlphanumStr(3);\n\n return `${name}-${suffix}`;\n}\n\nmodule.exports = {\n generateUsername\n};\n","/* global $, __filename */\n\nimport {\n ACTION_JINGLE_TR_RECEIVED,\n ACTION_JINGLE_TR_SUCCESS,\n createJingleEvent\n} from '../../service/statistics/AnalyticsEvents';\nimport { getLogger } from 'jitsi-meet-logger';\nimport { $iq, Strophe } from 'strophe.js';\n\nimport XMPPEvents from '../../service/xmpp/XMPPEvents';\nimport GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';\nimport RandomUtil from '../util/RandomUtil';\nimport Statistics from '../statistics/statistics';\n\nimport JingleSessionPC from './JingleSessionPC';\nimport ConnectionPlugin from './ConnectionPlugin';\n\nconst logger = getLogger(__filename);\n\n// XXX Strophe is build around the idea of chaining function calls so allow long\n// function call chains.\n/* eslint-disable newline-per-chained-call */\n\n/**\n *\n */\nclass JingleConnectionPlugin extends ConnectionPlugin {\n /**\n * Creates new JingleConnectionPlugin\n * @param {XMPP} xmpp\n * @param {EventEmitter} eventEmitter\n * @param {Object} iceConfig an object that holds the iceConfig to be passed\n * to the p2p and the jvb PeerConnection.\n */\n constructor(xmpp, eventEmitter, iceConfig) {\n super();\n this.xmpp = xmpp;\n this.eventEmitter = eventEmitter;\n this.sessions = {};\n this.jvbIceConfig = iceConfig.jvb;\n this.p2pIceConfig = iceConfig.p2p;\n this.mediaConstraints = {\n offerToReceiveAudio: true,\n offerToReceiveVideo: true\n };\n }\n\n /**\n *\n * @param connection\n */\n init(connection) {\n super.init(connection);\n this.connection.addHandler(this.onJingle.bind(this),\n 'urn:xmpp:jingle:1', 'iq', 'set', null, null);\n }\n\n /**\n *\n * @param iq\n */\n onJingle(iq) {\n const sid = $(iq).find('jingle').attr('sid');\n const action = $(iq).find('jingle').attr('action');\n const fromJid = iq.getAttribute('from');\n\n // send ack first\n const ack = $iq({ type: 'result',\n to: fromJid,\n id: iq.getAttribute('id')\n });\n\n logger.log(`on jingle ${action} from ${fromJid}`, iq);\n let sess = this.sessions[sid];\n\n if (action !== 'session-initiate') {\n if (!sess) {\n ack.attrs({ type: 'error' });\n ack.c('error', { type: 'cancel' })\n .c('item-not-found', {\n xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas'\n })\n .up()\n .c('unknown-session', {\n xmlns: 'urn:xmpp:jingle:errors:1'\n });\n logger.warn('invalid session id', iq);\n this.connection.send(ack);\n\n return true;\n }\n\n // local jid is not checked\n if (fromJid !== sess.remoteJid) {\n logger.warn(\n 'jid mismatch for session id', sid, sess.remoteJid, iq);\n ack.attrs({ type: 'error' });\n ack.c('error', { type: 'cancel' })\n .c('item-not-found', {\n xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas'\n })\n .up()\n .c('unknown-session', {\n xmlns: 'urn:xmpp:jingle:errors:1'\n });\n this.connection.send(ack);\n\n return true;\n }\n } else if (sess !== undefined) {\n // Existing session with same session id. This might be out-of-order\n // if the sess.remoteJid is the same as from.\n ack.attrs({ type: 'error' });\n ack.c('error', { type: 'cancel' })\n .c('service-unavailable', {\n xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas'\n })\n .up();\n logger.warn('duplicate session id', sid, iq);\n this.connection.send(ack);\n\n return true;\n }\n const now = window.performance.now();\n\n // FIXME that should work most of the time, but we'd have to\n // think how secure it is to assume that user with \"focus\"\n // nickname is Jicofo.\n const isP2P = Strophe.getResourceFromJid(fromJid) !== 'focus';\n\n // see http://xmpp.org/extensions/xep-0166.html#concepts-session\n\n switch (action) {\n case 'session-initiate': {\n logger.log('(TIME) received session-initiate:\\t', now);\n const startMuted = $(iq).find('jingle>startmuted');\n\n if (startMuted && startMuted.length > 0) {\n const audioMuted = startMuted.attr('audio');\n const videoMuted = startMuted.attr('video');\n\n this.eventEmitter.emit(\n XMPPEvents.START_MUTED_FROM_FOCUS,\n audioMuted === 'true',\n videoMuted === 'true');\n }\n\n logger.info(\n `Marking session from ${fromJid\n } as ${isP2P ? '' : '*not*'} P2P`);\n sess\n = new JingleSessionPC(\n $(iq).find('jingle').attr('sid'),\n $(iq).attr('to'),\n fromJid,\n this.connection,\n this.mediaConstraints,\n isP2P ? this.p2pIceConfig : this.jvbIceConfig,\n isP2P,\n /* initiator */ false);\n\n this.sessions[sess.sid] = sess;\n\n this.eventEmitter.emit(XMPPEvents.CALL_INCOMING,\n sess, $(iq).find('>jingle'), now);\n break;\n }\n case 'session-accept': {\n this.eventEmitter.emit(\n XMPPEvents.CALL_ACCEPTED, sess, $(iq).find('>jingle'));\n break;\n }\n case 'content-modify': {\n sess.modifyContents($(iq).find('>jingle'));\n break;\n }\n case 'transport-info': {\n this.eventEmitter.emit(\n XMPPEvents.TRANSPORT_INFO, sess, $(iq).find('>jingle'));\n break;\n }\n case 'session-terminate': {\n logger.log('terminating...', sess.sid);\n let reasonCondition = null;\n let reasonText = null;\n\n if ($(iq).find('>jingle>reason').length) {\n reasonCondition\n = $(iq).find('>jingle>reason>:first')[0].tagName;\n reasonText = $(iq).find('>jingle>reason>text').text();\n }\n this.terminate(sess.sid, reasonCondition, reasonText);\n this.eventEmitter.emit(XMPPEvents.CALL_ENDED,\n sess, reasonCondition, reasonText);\n break;\n }\n case 'transport-replace':\n logger.info('(TIME) Start transport replace', now);\n Statistics.sendAnalytics(createJingleEvent(\n ACTION_JINGLE_TR_RECEIVED,\n {\n p2p: isP2P,\n value: now\n }));\n\n sess.replaceTransport($(iq).find('>jingle'), () => {\n const successTime = window.performance.now();\n\n logger.info('(TIME) Transport replace success!', successTime);\n Statistics.sendAnalytics(createJingleEvent(\n ACTION_JINGLE_TR_SUCCESS,\n {\n p2p: isP2P,\n value: successTime\n }));\n }, error => {\n GlobalOnErrorHandler.callErrorHandler(error);\n logger.error('Transport replace failed', error);\n sess.sendTransportReject();\n });\n break;\n case 'addsource': // FIXME: proprietary, un-jingleish\n case 'source-add': // FIXME: proprietary\n sess.addRemoteStream($(iq).find('>jingle>content'));\n break;\n case 'removesource': // FIXME: proprietary, un-jingleish\n case 'source-remove': // FIXME: proprietary\n sess.removeRemoteStream($(iq).find('>jingle>content'));\n break;\n default:\n logger.warn('jingle action not implemented', action);\n ack.attrs({ type: 'error' });\n ack.c('error', { type: 'cancel' })\n .c('bad-request',\n { xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas' })\n .up();\n break;\n }\n this.connection.send(ack);\n\n return true;\n }\n\n /**\n * Creates new JingleSessionPC meant to be used in a direct P2P\n * connection, configured as 'initiator'.\n * @param {string} me our JID\n * @param {string} peer remote participant's JID\n * @return {JingleSessionPC}\n */\n newP2PJingleSession(me, peer) {\n const sess\n = new JingleSessionPC(\n RandomUtil.randomHexString(12),\n me,\n peer,\n this.connection,\n this.mediaConstraints,\n this.p2pIceConfig,\n /* P2P */ true,\n /* initiator */ true);\n\n this.sessions[sess.sid] = sess;\n\n return sess;\n }\n\n /**\n *\n * @param sid\n * @param reasonCondition\n * @param reasonText\n */\n terminate(sid, reasonCondition, reasonText) {\n if (this.sessions.hasOwnProperty(sid)) {\n if (this.sessions[sid].state !== 'ended') {\n this.sessions[sid].onTerminated(reasonCondition, reasonText);\n }\n delete this.sessions[sid];\n }\n }\n\n /**\n *\n */\n getStunAndTurnCredentials() {\n // get stun and turn configuration from server via xep-0215\n // uses time-limited credentials as described in\n // http://tools.ietf.org/html/draft-uberti-behave-turn-rest-00\n //\n // See https://modules.prosody.im/mod_turncredentials.html\n // for a prosody module which implements this.\n //\n // Currently, this doesn't work with updateIce and therefore credentials\n // with a long validity have to be fetched before creating the\n // peerconnection.\n // TODO: implement refresh via updateIce as described in\n // https://code.google.com/p/webrtc/issues/detail?id=1650\n this.connection.sendIQ(\n $iq({ type: 'get',\n to: this.connection.domain })\n .c('services', { xmlns: 'urn:xmpp:extdisco:1' }),\n res => {\n const iceservers = [];\n\n $(res).find('>services>service').each((idx, el) => {\n // eslint-disable-next-line no-param-reassign\n el = $(el);\n const dict = {};\n const type = el.attr('type');\n\n switch (type) {\n case 'stun':\n dict.url = `stun:${el.attr('host')}`;\n if (el.attr('port')) {\n dict.url += `:${el.attr('port')}`;\n }\n iceservers.push(dict);\n break;\n case 'turn':\n case 'turns': {\n dict.url = `${type}:`;\n const username = el.attr('username');\n\n // https://code.google.com/p/webrtc/issues/detail\n // ?id=1508\n\n if (username) {\n const match\n = navigator.userAgent.match(\n /Chrom(e|ium)\\/([0-9]+)\\./);\n\n if (match && parseInt(match[2], 10) < 28) {\n dict.url += `${username}@`;\n } else {\n // only works in M28\n dict.username = username;\n }\n }\n dict.url += el.attr('host');\n const port = el.attr('port');\n\n if (port) {\n dict.url += `:${el.attr('port')}`;\n }\n const transport = el.attr('transport');\n\n if (transport && transport !== 'udp') {\n dict.url += `?transport=${transport}`;\n }\n\n dict.credential = el.attr('password')\n || dict.credential;\n iceservers.push(dict);\n break;\n }\n }\n });\n\n const options = this.xmpp.options;\n\n if (options.useStunTurn) {\n // we want to filter and leave only tcp/turns candidates\n // which make sense for the jvb connections\n this.jvbIceConfig.iceServers\n = iceservers.filter(s => s.url.startsWith('turns'));\n }\n\n if (options.p2p && options.p2p.useStunTurn) {\n this.p2pIceConfig.iceServers = iceservers;\n }\n\n }, err => {\n logger.warn('getting turn credentials failed', err);\n logger.warn('is mod_turncredentials or similar installed?');\n });\n\n // implement push?\n }\n\n /**\n * Returns the data saved in 'updateLog' in a format to be logged.\n */\n getLog() {\n const data = {};\n\n Object.keys(this.sessions).forEach(sid => {\n const session = this.sessions[sid];\n const pc = session.peerconnection;\n\n if (pc && pc.updateLog) {\n // FIXME: should probably be a .dump call\n data[`jingle_${sid}`] = {\n updateLog: pc.updateLog,\n stats: pc.stats,\n url: window.location.href\n };\n }\n });\n\n return data;\n }\n}\n\n/* eslint-enable newline-per-chained-call */\n\n/**\n *\n * @param XMPP\n * @param eventEmitter\n * @param iceConfig\n */\nexport default function initJingle(XMPP, eventEmitter, iceConfig) {\n Strophe.addConnectionPlugin(\n 'jingle',\n new JingleConnectionPlugin(XMPP, eventEmitter, iceConfig));\n}\n","/**\n * Implements a simple hash code for a string (see\n * https://en.wikipedia.org/wiki/Java_hashCode()).\n *\n * @param {string} The string to return a hash of.\n * @return {Number} the integer hash code of the string.\n */\nfunction integerHash(string) {\n if (!string) {\n return 0;\n }\n\n let char, hash = 0, i;\n\n for (i = 0; i < string.length; i++) {\n char = string.charCodeAt(i);\n hash += char * Math.pow(31, string.length - 1 - i);\n hash = Math.abs(hash | 0); // eslint-disable-line no-bitwise\n }\n\n return hash;\n}\n\nmodule.exports = { integerHash };\n","/* global __filename */\nimport { getLogger } from 'jitsi-meet-logger';\nimport * as JingleSessionState from './JingleSessionState';\n\nconst logger = getLogger(__filename);\n\n/**\n * JingleSession provides an API to manage a single Jingle session. We will\n * have different implementations depending on the underlying interface used\n * (i.e. WebRTC and ORTC) and here we hold the code common to all of them.\n */\nexport default class JingleSession {\n\n /* eslint-disable max-params */\n\n /**\n * Creates new JingleSession.\n * @param {string} sid the Jingle session identifier\n * @param {string} localJid our JID\n * @param {string} remoteJid the JID of the remote peer\n * @param {Strophe.Connection} connection the XMPP connection\n * @param {Object} mediaConstraints the media constraints object passed to\n * the PeerConnection onCreateAnswer/Offer as defined by the WebRTC.\n * @param {Object} iceConfig the ICE servers config object as defined by\n * the WebRTC. Passed to the PeerConnection's constructor.\n * @param {boolean} isInitiator indicates if it will be the side which\n * initiates the session.\n */\n constructor(\n sid,\n localJid,\n remoteJid,\n connection,\n mediaConstraints,\n iceConfig,\n isInitiator) {\n this.sid = sid;\n this.localJid = localJid;\n this.remoteJid = remoteJid;\n this.connection = connection;\n this.mediaConstraints = mediaConstraints;\n this.iceConfig = iceConfig;\n\n /**\n * Indicates whether this instance is an initiator or an answerer of\n * the Jingle session.\n * @type {boolean}\n */\n this.isInitiator = isInitiator;\n\n /**\n * Whether to use dripping or not. Dripping is sending trickle\n * candidates not one-by-one.\n */\n this.usedrip = true;\n\n /**\n * When dripping is used, stores ICE candidates which are to be sent.\n */\n this.dripContainer = [];\n\n /**\n * The chat room instance associated with the session.\n * @type {ChatRoom}\n */\n this.room = null;\n\n /**\n * Jingle session state - uninitialized until {@link initialize} is\n * called @type {JingleSessionState}\n */\n this.state = null;\n\n /**\n * The RTC service instance\n * @type {RTC}\n */\n this.rtc = null;\n }\n\n /**\n * Returns XMPP address of this session's initiator.\n * @return {string}\n */\n get initiatorJid() {\n return this.isInitiator ? this.localJid : this.remoteJid;\n }\n\n /**\n * Returns XMPP address of this session's responder.\n * @return {string}\n */\n get responderJid() {\n return this.isInitiator ? this.remoteJid : this.localJid;\n }\n\n /* eslint-enable max-params */\n\n /**\n * Prepares this object to initiate a session.\n * @param {ChatRoom} room the chat room for the conference associated with\n * this session\n * @param {RTC} rtc the RTC service instance\n * @param {object} options - the options, see implementing class's\n * {@link #doInitialize} description for more details.\n */\n initialize(room, rtc, options) {\n if (this.state !== null) {\n const errmsg\n = `attempt to initiate on session ${this.sid}\n in state ${this.state}`;\n\n logger.error(errmsg);\n throw new Error(errmsg);\n }\n this.room = room;\n this.rtc = rtc;\n this.state = JingleSessionState.PENDING;\n this.doInitialize(options);\n }\n\n /**\n * The implementing class finishes initialization here. Called at the end of\n * {@link initialize}.\n * @param {Object} options - The options specific to the implementing class.\n * @protected\n */\n doInitialize(options) { } // eslint-disable-line no-unused-vars, no-empty-function, max-len\n\n /* eslint-disable no-unused-vars, no-empty-function */\n\n /**\n * Adds the ICE candidates found in the 'contents' array as remote\n * candidates?\n * Note: currently only used on transport-info\n *\n * @param contents\n */\n addIceCandidates(contents) {}\n\n /* eslint-enable no-unused-vars, no-empty-function */\n\n /**\n * Returns current state of this JingleSession instance.\n * @returns {JingleSessionState} the current state of this session instance.\n */\n getState() {\n return this.state;\n }\n\n /* eslint-disable no-unused-vars, no-empty-function */\n\n /**\n * Handles an 'add-source' event.\n *\n * @param contents an array of Jingle 'content' elements.\n */\n addSources(contents) {}\n\n /**\n * Handles a 'remove-source' event.\n *\n * @param contents an array of Jingle 'content' elements.\n */\n removeSources(contents) {}\n\n /**\n * Terminates this Jingle session by sending session-terminate\n * @param success a callback called once the 'session-terminate' packet has\n * been acknowledged with RESULT.\n * @param failure a callback called when either timeout occurs or ERROR\n * response is received.\n * @param {Object} options\n * @param {string} [options.reason] XMPP Jingle error condition\n * @param {string} [options.reasonDescription] some meaningful error message\n * @param {boolean} [options.sendSessionTerminate=true] set to false to skip\n * sending session-terminate. It may not make sense to send it if the XMPP\n * connection has been closed already or if the remote peer has disconnected\n */\n terminate(success, failure, options) {}\n\n /**\n * Handles an offer from the remote peer (prepares to accept a session).\n * @param jingle the 'jingle' XML element.\n * @param success callback called when we the incoming session has been\n * accepted\n * @param failure callback called when we fail for any reason, will supply\n * error object with details(which is meant more to be printed to the logger\n * than analysed in the code, as the error is unrecoverable anyway)\n */\n acceptOffer(jingle, success, failure) {}\n\n /**\n * Returns the JID of the initiator of the jingle session.\n */\n _getInitiatorJid() {\n return this.isInitiator ? this.localJid : this.remoteJid;\n }\n\n /* eslint-enable no-unused-vars, no-empty-function */\n}\n","/* global __filename */\n\nimport { getLogger } from 'jitsi-meet-logger';\nimport * as MediaType from '../../service/RTC/MediaType';\nimport * as SignalingEvents from '../../service/RTC/SignalingEvents';\nimport SignalingLayer from '../../service/RTC/SignalingLayer';\n\nconst logger = getLogger(__filename);\n\n/**\n * Default XMPP implementation of the {@link SignalingLayer} interface. Obtains\n * the data from the MUC presence.\n */\nexport default class SignalingLayerImpl extends SignalingLayer {\n /**\n * Creates new instance.\n */\n constructor() {\n super();\n\n /**\n * A map that stores SSRCs of remote streams. And is used only locally\n * We store the mapping when jingle is received, and later is used\n * onaddstream webrtc event where we have only the ssrc\n * FIXME: This map got filled and never cleaned and can grow during long\n * conference\n * @type {Map} maps SSRC number to jid\n */\n this.ssrcOwners = new Map();\n\n /**\n *\n * @type {ChatRoom|null}\n */\n this.chatRoom = null;\n }\n\n /**\n * Sets the ChatRoom instance used and binds presence listeners.\n * @param {ChatRoom} room\n */\n setChatRoom(room) {\n const oldChatRoom = this.chatRoom;\n\n this.chatRoom = room;\n if (oldChatRoom) {\n oldChatRoom.removePresenceListener(\n 'audiomuted', this._audioMuteHandler);\n oldChatRoom.removePresenceListener(\n 'videomuted', this._videoMuteHandler);\n oldChatRoom.removePresenceListener(\n 'videoType', this._videoTypeHandler);\n }\n if (room) {\n // SignalingEvents\n this._audioMuteHandler = (node, from) => {\n this.eventEmitter.emit(\n SignalingEvents.PEER_MUTED_CHANGED,\n from, MediaType.AUDIO, node.value === 'true');\n };\n room.addPresenceListener('audiomuted', this._audioMuteHandler);\n\n this._videoMuteHandler = (node, from) => {\n this.eventEmitter.emit(\n SignalingEvents.PEER_MUTED_CHANGED,\n from, MediaType.VIDEO, node.value === 'true');\n };\n room.addPresenceListener('videomuted', this._videoMuteHandler);\n\n this._videoTypeHandler = (node, from) => {\n this.eventEmitter.emit(\n SignalingEvents.PEER_VIDEO_TYPE_CHANGED,\n from, node.value);\n };\n room.addPresenceListener('videoType', this._videoTypeHandler);\n }\n }\n\n /**\n * @inheritDoc\n */\n getPeerMediaInfo(owner, mediaType) {\n if (this.chatRoom) {\n return this.chatRoom.getMediaPresenceInfo(owner, mediaType);\n }\n logger.error('Requested peer media info, before room was set');\n }\n\n /**\n * @inheritDoc\n */\n getSSRCOwner(ssrc) {\n return this.ssrcOwners.get(ssrc);\n }\n\n /**\n * Set an SSRC owner.\n * @param {number} ssrc an SSRC to be owned\n * @param {string} endpointId owner's ID (MUC nickname)\n * @throws TypeError if ssrc is not a number\n */\n setSSRCOwner(ssrc, endpointId) {\n if (typeof ssrc !== 'number') {\n throw new TypeError(`SSRC(${ssrc}) must be a number`);\n }\n this.ssrcOwners.set(ssrc, endpointId);\n }\n}\n","\nimport Listenable from '../../modules/util/Listenable';\n\n/**\n * An object that carries the info about specific media type advertised by\n * participant in the signaling channel.\n * @typedef {Object} PeerMediaInfo\n * @property {boolean} muted indicates if the media is currently muted\n * @property {VideoType|undefined} videoType the type of the video if applicable\n */\n\n/**\n * Interface used to expose the information carried over the signaling channel\n * which is not available to the RTC module in the media SDP.\n *\n * @interface SignalingLayer\n */\nexport default class SignalingLayer extends Listenable {\n\n /**\n * Obtains the endpoint ID for given SSRC.\n * @param {number} ssrc the SSRC number.\n * @return {string|null} the endpoint ID for given media SSRC.\n */\n getSSRCOwner(ssrc) { // eslint-disable-line no-unused-vars\n throw new Error('not implemented');\n }\n\n /**\n * Obtains the info about given media advertised in the MUC presence of\n * the participant identified by the given MUC JID.\n * @param {string} owner the MUC jid of the participant for whom\n * {@link PeerMediaInfo} will be obtained.\n * @param {MediaType} mediaType the type of the media for which presence\n * info will be obtained.\n * @return {PeerMediaInfo|null} presenceInfo an object with media presence\n * info or null either if there is no presence available for given\n * JID or if the media type given is invalid.\n */\n getPeerMediaInfo(owner, mediaType) { // eslint-disable-line no-unused-vars\n throw new Error('not implemented');\n }\n}\n","import async from 'async';\n\n/**\n * A queue for async task execution.\n */\nexport default class AsyncQueue {\n /**\n * Creates new instance.\n */\n constructor() {\n this._queue = async.queue(this._processQueueTasks.bind(this), 1);\n this._stopped = false;\n }\n\n /**\n * Removes any pending tasks from the queue.\n */\n clear() {\n this._queue.kill();\n }\n\n /**\n * Internal task processing implementation which makes things work.\n */\n _processQueueTasks(task, finishedCallback) {\n task(finishedCallback);\n }\n\n /**\n * The 'task' function will be given a callback it MUST call with either:\n * 1) No arguments if it was successful or\n * 2) An error argument if there was an error\n * If the task wants to process the success or failure of the task, it\n * should pass the {@code callback} to the push function, e.g.:\n * queue.push(task, (err) => {\n * if (err) {\n * // error handling\n * } else {\n * // success handling\n * }\n * });\n *\n * @param {function} task - The task to be executed. See the description above.\n * @param {function} [callback] - Optional callback to be called after the task has been executed.\n */\n push(task, callback) {\n if (this._stopped) {\n callback && callback(new Error('The queue has been stopped'));\n\n return;\n }\n this._queue.push(task, callback);\n }\n\n /**\n * Shutdowns the queue. All already queued tasks will execute, but no future tasks can be added. If a task is added\n * after the queue has been shutdown then the callback will be called with an error.\n */\n shutdown() {\n this._stopped = true;\n }\n}\n","/*!\n * async\n * https://github.com/caolan/async\n *\n * Copyright 2010-2014 Caolan McMahon\n * Released under the MIT license\n */\n/*jshint onevar: false, indent:4 */\n/*global setImmediate: false, setTimeout: false, console: false */\n(function () {\n\n var async = {};\n\n // global on the server, window in the browser\n var root, previous_async;\n\n root = this;\n if (root != null) {\n previous_async = root.async;\n }\n\n async.noConflict = function () {\n root.async = previous_async;\n return async;\n };\n\n function only_once(fn) {\n var called = false;\n return function() {\n if (called) throw new Error(\"Callback was already called.\");\n called = true;\n fn.apply(root, arguments);\n }\n }\n\n //// cross-browser compatiblity functions ////\n\n var _toString = Object.prototype.toString;\n\n var _isArray = Array.isArray || function (obj) {\n return _toString.call(obj) === '[object Array]';\n };\n\n var _each = function (arr, iterator) {\n if (arr.forEach) {\n return arr.forEach(iterator);\n }\n for (var i = 0; i < arr.length; i += 1) {\n iterator(arr[i], i, arr);\n }\n };\n\n var _map = function (arr, iterator) {\n if (arr.map) {\n return arr.map(iterator);\n }\n var results = [];\n _each(arr, function (x, i, a) {\n results.push(iterator(x, i, a));\n });\n return results;\n };\n\n var _reduce = function (arr, iterator, memo) {\n if (arr.reduce) {\n return arr.reduce(iterator, memo);\n }\n _each(arr, function (x, i, a) {\n memo = iterator(memo, x, i, a);\n });\n return memo;\n };\n\n var _keys = function (obj) {\n if (Object.keys) {\n return Object.keys(obj);\n }\n var keys = [];\n for (var k in obj) {\n if (obj.hasOwnProperty(k)) {\n keys.push(k);\n }\n }\n return keys;\n };\n\n //// exported async module functions ////\n\n //// nextTick implementation with browser-compatible fallback ////\n if (typeof process === 'undefined' || !(process.nextTick)) {\n if (typeof setImmediate === 'function') {\n async.nextTick = function (fn) {\n // not a direct alias for IE10 compatibility\n setImmediate(fn);\n };\n async.setImmediate = async.nextTick;\n }\n else {\n async.nextTick = function (fn) {\n setTimeout(fn, 0);\n };\n async.setImmediate = async.nextTick;\n }\n }\n else {\n async.nextTick = process.nextTick;\n if (typeof setImmediate !== 'undefined') {\n async.setImmediate = function (fn) {\n // not a direct alias for IE10 compatibility\n setImmediate(fn);\n };\n }\n else {\n async.setImmediate = async.nextTick;\n }\n }\n\n async.each = function (arr, iterator, callback) {\n callback = callback || function () {};\n if (!arr.length) {\n return callback();\n }\n var completed = 0;\n _each(arr, function (x) {\n iterator(x, only_once(done) );\n });\n function done(err) {\n if (err) {\n callback(err);\n callback = function () {};\n }\n else {\n completed += 1;\n if (completed >= arr.length) {\n callback();\n }\n }\n }\n };\n async.forEach = async.each;\n\n async.eachSeries = function (arr, iterator, callback) {\n callback = callback || function () {};\n if (!arr.length) {\n return callback();\n }\n var completed = 0;\n var iterate = function () {\n iterator(arr[completed], function (err) {\n if (err) {\n callback(err);\n callback = function () {};\n }\n else {\n completed += 1;\n if (completed >= arr.length) {\n callback();\n }\n else {\n iterate();\n }\n }\n });\n };\n iterate();\n };\n async.forEachSeries = async.eachSeries;\n\n async.eachLimit = function (arr, limit, iterator, callback) {\n var fn = _eachLimit(limit);\n fn.apply(null, [arr, iterator, callback]);\n };\n async.forEachLimit = async.eachLimit;\n\n var _eachLimit = function (limit) {\n\n return function (arr, iterator, callback) {\n callback = callback || function () {};\n if (!arr.length || limit <= 0) {\n return callback();\n }\n var completed = 0;\n var started = 0;\n var running = 0;\n\n (function replenish () {\n if (completed >= arr.length) {\n return callback();\n }\n\n while (running < limit && started < arr.length) {\n started += 1;\n running += 1;\n iterator(arr[started - 1], function (err) {\n if (err) {\n callback(err);\n callback = function () {};\n }\n else {\n completed += 1;\n running -= 1;\n if (completed >= arr.length) {\n callback();\n }\n else {\n replenish();\n }\n }\n });\n }\n })();\n };\n };\n\n\n var doParallel = function (fn) {\n return function () {\n var args = Array.prototype.slice.call(arguments);\n return fn.apply(null, [async.each].concat(args));\n };\n };\n var doParallelLimit = function(limit, fn) {\n return function () {\n var args = Array.prototype.slice.call(arguments);\n return fn.apply(null, [_eachLimit(limit)].concat(args));\n };\n };\n var doSeries = function (fn) {\n return function () {\n var args = Array.prototype.slice.call(arguments);\n return fn.apply(null, [async.eachSeries].concat(args));\n };\n };\n\n\n var _asyncMap = function (eachfn, arr, iterator, callback) {\n arr = _map(arr, function (x, i) {\n return {index: i, value: x};\n });\n if (!callback) {\n eachfn(arr, function (x, callback) {\n iterator(x.value, function (err) {\n callback(err);\n });\n });\n } else {\n var results = [];\n eachfn(arr, function (x, callback) {\n iterator(x.value, function (err, v) {\n results[x.index] = v;\n callback(err);\n });\n }, function (err) {\n callback(err, results);\n });\n }\n };\n async.map = doParallel(_asyncMap);\n async.mapSeries = doSeries(_asyncMap);\n async.mapLimit = function (arr, limit, iterator, callback) {\n return _mapLimit(limit)(arr, iterator, callback);\n };\n\n var _mapLimit = function(limit) {\n return doParallelLimit(limit, _asyncMap);\n };\n\n // reduce only has a series version, as doing reduce in parallel won't\n // work in many situations.\n async.reduce = function (arr, memo, iterator, callback) {\n async.eachSeries(arr, function (x, callback) {\n iterator(memo, x, function (err, v) {\n memo = v;\n callback(err);\n });\n }, function (err) {\n callback(err, memo);\n });\n };\n // inject alias\n async.inject = async.reduce;\n // foldl alias\n async.foldl = async.reduce;\n\n async.reduceRight = function (arr, memo, iterator, callback) {\n var reversed = _map(arr, function (x) {\n return x;\n }).reverse();\n async.reduce(reversed, memo, iterator, callback);\n };\n // foldr alias\n async.foldr = async.reduceRight;\n\n var _filter = function (eachfn, arr, iterator, callback) {\n var results = [];\n arr = _map(arr, function (x, i) {\n return {index: i, value: x};\n });\n eachfn(arr, function (x, callback) {\n iterator(x.value, function (v) {\n if (v) {\n results.push(x);\n }\n callback();\n });\n }, function (err) {\n callback(_map(results.sort(function (a, b) {\n return a.index - b.index;\n }), function (x) {\n return x.value;\n }));\n });\n };\n async.filter = doParallel(_filter);\n async.filterSeries = doSeries(_filter);\n // select alias\n async.select = async.filter;\n async.selectSeries = async.filterSeries;\n\n var _reject = function (eachfn, arr, iterator, callback) {\n var results = [];\n arr = _map(arr, function (x, i) {\n return {index: i, value: x};\n });\n eachfn(arr, function (x, callback) {\n iterator(x.value, function (v) {\n if (!v) {\n results.push(x);\n }\n callback();\n });\n }, function (err) {\n callback(_map(results.sort(function (a, b) {\n return a.index - b.index;\n }), function (x) {\n return x.value;\n }));\n });\n };\n async.reject = doParallel(_reject);\n async.rejectSeries = doSeries(_reject);\n\n var _detect = function (eachfn, arr, iterator, main_callback) {\n eachfn(arr, function (x, callback) {\n iterator(x, function (result) {\n if (result) {\n main_callback(x);\n main_callback = function () {};\n }\n else {\n callback();\n }\n });\n }, function (err) {\n main_callback();\n });\n };\n async.detect = doParallel(_detect);\n async.detectSeries = doSeries(_detect);\n\n async.some = function (arr, iterator, main_callback) {\n async.each(arr, function (x, callback) {\n iterator(x, function (v) {\n if (v) {\n main_callback(true);\n main_callback = function () {};\n }\n callback();\n });\n }, function (err) {\n main_callback(false);\n });\n };\n // any alias\n async.any = async.some;\n\n async.every = function (arr, iterator, main_callback) {\n async.each(arr, function (x, callback) {\n iterator(x, function (v) {\n if (!v) {\n main_callback(false);\n main_callback = function () {};\n }\n callback();\n });\n }, function (err) {\n main_callback(true);\n });\n };\n // all alias\n async.all = async.every;\n\n async.sortBy = function (arr, iterator, callback) {\n async.map(arr, function (x, callback) {\n iterator(x, function (err, criteria) {\n if (err) {\n callback(err);\n }\n else {\n callback(null, {value: x, criteria: criteria});\n }\n });\n }, function (err, results) {\n if (err) {\n return callback(err);\n }\n else {\n var fn = function (left, right) {\n var a = left.criteria, b = right.criteria;\n return a < b ? -1 : a > b ? 1 : 0;\n };\n callback(null, _map(results.sort(fn), function (x) {\n return x.value;\n }));\n }\n });\n };\n\n async.auto = function (tasks, callback) {\n callback = callback || function () {};\n var keys = _keys(tasks);\n var remainingTasks = keys.length\n if (!remainingTasks) {\n return callback();\n }\n\n var results = {};\n\n var listeners = [];\n var addListener = function (fn) {\n listeners.unshift(fn);\n };\n var removeListener = function (fn) {\n for (var i = 0; i < listeners.length; i += 1) {\n if (listeners[i] === fn) {\n listeners.splice(i, 1);\n return;\n }\n }\n };\n var taskComplete = function () {\n remainingTasks--\n _each(listeners.slice(0), function (fn) {\n fn();\n });\n };\n\n addListener(function () {\n if (!remainingTasks) {\n var theCallback = callback;\n // prevent final callback from calling itself if it errors\n callback = function () {};\n\n theCallback(null, results);\n }\n });\n\n _each(keys, function (k) {\n var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];\n var taskCallback = function (err) {\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length <= 1) {\n args = args[0];\n }\n if (err) {\n var safeResults = {};\n _each(_keys(results), function(rkey) {\n safeResults[rkey] = results[rkey];\n });\n safeResults[k] = args;\n callback(err, safeResults);\n // stop subsequent errors hitting callback multiple times\n callback = function () {};\n }\n else {\n results[k] = args;\n async.setImmediate(taskComplete);\n }\n };\n var requires = task.slice(0, Math.abs(task.length - 1)) || [];\n var ready = function () {\n return _reduce(requires, function (a, x) {\n return (a && results.hasOwnProperty(x));\n }, true) && !results.hasOwnProperty(k);\n };\n if (ready()) {\n task[task.length - 1](taskCallback, results);\n }\n else {\n var listener = function () {\n if (ready()) {\n removeListener(listener);\n task[task.length - 1](taskCallback, results);\n }\n };\n addListener(listener);\n }\n });\n };\n\n async.retry = function(times, task, callback) {\n var DEFAULT_TIMES = 5;\n var attempts = [];\n // Use defaults if times not passed\n if (typeof times === 'function') {\n callback = task;\n task = times;\n times = DEFAULT_TIMES;\n }\n // Make sure times is a number\n times = parseInt(times, 10) || DEFAULT_TIMES;\n var wrappedTask = function(wrappedCallback, wrappedResults) {\n var retryAttempt = function(task, finalAttempt) {\n return function(seriesCallback) {\n task(function(err, result){\n seriesCallback(!err || finalAttempt, {err: err, result: result});\n }, wrappedResults);\n };\n };\n while (times) {\n attempts.push(retryAttempt(task, !(times-=1)));\n }\n async.series(attempts, function(done, data){\n data = data[data.length - 1];\n (wrappedCallback || callback)(data.err, data.result);\n });\n }\n // If a callback is passed, run this as a controll flow\n return callback ? wrappedTask() : wrappedTask\n };\n\n async.waterfall = function (tasks, callback) {\n callback = callback || function () {};\n if (!_isArray(tasks)) {\n var err = new Error('First argument to waterfall must be an array of functions');\n return callback(err);\n }\n if (!tasks.length) {\n return callback();\n }\n var wrapIterator = function (iterator) {\n return function (err) {\n if (err) {\n callback.apply(null, arguments);\n callback = function () {};\n }\n else {\n var args = Array.prototype.slice.call(arguments, 1);\n var next = iterator.next();\n if (next) {\n args.push(wrapIterator(next));\n }\n else {\n args.push(callback);\n }\n async.setImmediate(function () {\n iterator.apply(null, args);\n });\n }\n };\n };\n wrapIterator(async.iterator(tasks))();\n };\n\n var _parallel = function(eachfn, tasks, callback) {\n callback = callback || function () {};\n if (_isArray(tasks)) {\n eachfn.map(tasks, function (fn, callback) {\n if (fn) {\n fn(function (err) {\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length <= 1) {\n args = args[0];\n }\n callback.call(null, err, args);\n });\n }\n }, callback);\n }\n else {\n var results = {};\n eachfn.each(_keys(tasks), function (k, callback) {\n tasks[k](function (err) {\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length <= 1) {\n args = args[0];\n }\n results[k] = args;\n callback(err);\n });\n }, function (err) {\n callback(err, results);\n });\n }\n };\n\n async.parallel = function (tasks, callback) {\n _parallel({ map: async.map, each: async.each }, tasks, callback);\n };\n\n async.parallelLimit = function(tasks, limit, callback) {\n _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback);\n };\n\n async.series = function (tasks, callback) {\n callback = callback || function () {};\n if (_isArray(tasks)) {\n async.mapSeries(tasks, function (fn, callback) {\n if (fn) {\n fn(function (err) {\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length <= 1) {\n args = args[0];\n }\n callback.call(null, err, args);\n });\n }\n }, callback);\n }\n else {\n var results = {};\n async.eachSeries(_keys(tasks), function (k, callback) {\n tasks[k](function (err) {\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length <= 1) {\n args = args[0];\n }\n results[k] = args;\n callback(err);\n });\n }, function (err) {\n callback(err, results);\n });\n }\n };\n\n async.iterator = function (tasks) {\n var makeCallback = function (index) {\n var fn = function () {\n if (tasks.length) {\n tasks[index].apply(null, arguments);\n }\n return fn.next();\n };\n fn.next = function () {\n return (index < tasks.length - 1) ? makeCallback(index + 1): null;\n };\n return fn;\n };\n return makeCallback(0);\n };\n\n async.apply = function (fn) {\n var args = Array.prototype.slice.call(arguments, 1);\n return function () {\n return fn.apply(\n null, args.concat(Array.prototype.slice.call(arguments))\n );\n };\n };\n\n var _concat = function (eachfn, arr, fn, callback) {\n var r = [];\n eachfn(arr, function (x, cb) {\n fn(x, function (err, y) {\n r = r.concat(y || []);\n cb(err);\n });\n }, function (err) {\n callback(err, r);\n });\n };\n async.concat = doParallel(_concat);\n async.concatSeries = doSeries(_concat);\n\n async.whilst = function (test, iterator, callback) {\n if (test()) {\n iterator(function (err) {\n if (err) {\n return callback(err);\n }\n async.whilst(test, iterator, callback);\n });\n }\n else {\n callback();\n }\n };\n\n async.doWhilst = function (iterator, test, callback) {\n iterator(function (err) {\n if (err) {\n return callback(err);\n }\n var args = Array.prototype.slice.call(arguments, 1);\n if (test.apply(null, args)) {\n async.doWhilst(iterator, test, callback);\n }\n else {\n callback();\n }\n });\n };\n\n async.until = function (test, iterator, callback) {\n if (!test()) {\n iterator(function (err) {\n if (err) {\n return callback(err);\n }\n async.until(test, iterator, callback);\n });\n }\n else {\n callback();\n }\n };\n\n async.doUntil = function (iterator, test, callback) {\n iterator(function (err) {\n if (err) {\n return callback(err);\n }\n var args = Array.prototype.slice.call(arguments, 1);\n if (!test.apply(null, args)) {\n async.doUntil(iterator, test, callback);\n }\n else {\n callback();\n }\n });\n };\n\n async.queue = function (worker, concurrency) {\n if (concurrency === undefined) {\n concurrency = 1;\n }\n function _insert(q, data, pos, callback) {\n if (!q.started){\n q.started = true;\n }\n if (!_isArray(data)) {\n data = [data];\n }\n if(data.length == 0) {\n // call drain immediately if there are no tasks\n return async.setImmediate(function() {\n if (q.drain) {\n q.drain();\n }\n });\n }\n _each(data, function(task) {\n var item = {\n data: task,\n callback: typeof callback === 'function' ? callback : null\n };\n\n if (pos) {\n q.tasks.unshift(item);\n } else {\n q.tasks.push(item);\n }\n\n if (q.saturated && q.tasks.length === q.concurrency) {\n q.saturated();\n }\n async.setImmediate(q.process);\n });\n }\n\n var workers = 0;\n var q = {\n tasks: [],\n concurrency: concurrency,\n saturated: null,\n empty: null,\n drain: null,\n started: false,\n paused: false,\n push: function (data, callback) {\n _insert(q, data, false, callback);\n },\n kill: function () {\n q.drain = null;\n q.tasks = [];\n },\n unshift: function (data, callback) {\n _insert(q, data, true, callback);\n },\n process: function () {\n if (!q.paused && workers < q.concurrency && q.tasks.length) {\n var task = q.tasks.shift();\n if (q.empty && q.tasks.length === 0) {\n q.empty();\n }\n workers += 1;\n var next = function () {\n workers -= 1;\n if (task.callback) {\n task.callback.apply(task, arguments);\n }\n if (q.drain && q.tasks.length + workers === 0) {\n q.drain();\n }\n q.process();\n };\n var cb = only_once(next);\n worker(task.data, cb);\n }\n },\n length: function () {\n return q.tasks.length;\n },\n running: function () {\n return workers;\n },\n idle: function() {\n return q.tasks.length + workers === 0;\n },\n pause: function () {\n if (q.paused === true) { return; }\n q.paused = true;\n q.process();\n },\n resume: function () {\n if (q.paused === false) { return; }\n q.paused = false;\n q.process();\n }\n };\n return q;\n };\n \n async.priorityQueue = function (worker, concurrency) {\n \n function _compareTasks(a, b){\n return a.priority - b.priority;\n };\n \n function _binarySearch(sequence, item, compare) {\n var beg = -1,\n end = sequence.length - 1;\n while (beg < end) {\n var mid = beg + ((end - beg + 1) >>> 1);\n if (compare(item, sequence[mid]) >= 0) {\n beg = mid;\n } else {\n end = mid - 1;\n }\n }\n return beg;\n }\n \n function _insert(q, data, priority, callback) {\n if (!q.started){\n q.started = true;\n }\n if (!_isArray(data)) {\n data = [data];\n }\n if(data.length == 0) {\n // call drain immediately if there are no tasks\n return async.setImmediate(function() {\n if (q.drain) {\n q.drain();\n }\n });\n }\n _each(data, function(task) {\n var item = {\n data: task,\n priority: priority,\n callback: typeof callback === 'function' ? callback : null\n };\n \n q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);\n\n if (q.saturated && q.tasks.length === q.concurrency) {\n q.saturated();\n }\n async.setImmediate(q.process);\n });\n }\n \n // Start with a normal queue\n var q = async.queue(worker, concurrency);\n \n // Override push to accept second parameter representing priority\n q.push = function (data, priority, callback) {\n _insert(q, data, priority, callback);\n };\n \n // Remove unshift function\n delete q.unshift;\n\n return q;\n };\n\n async.cargo = function (worker, payload) {\n var working = false,\n tasks = [];\n\n var cargo = {\n tasks: tasks,\n payload: payload,\n saturated: null,\n empty: null,\n drain: null,\n drained: true,\n push: function (data, callback) {\n if (!_isArray(data)) {\n data = [data];\n }\n _each(data, function(task) {\n tasks.push({\n data: task,\n callback: typeof callback === 'function' ? callback : null\n });\n cargo.drained = false;\n if (cargo.saturated && tasks.length === payload) {\n cargo.saturated();\n }\n });\n async.setImmediate(cargo.process);\n },\n process: function process() {\n if (working) return;\n if (tasks.length === 0) {\n if(cargo.drain && !cargo.drained) cargo.drain();\n cargo.drained = true;\n return;\n }\n\n var ts = typeof payload === 'number'\n ? tasks.splice(0, payload)\n : tasks.splice(0, tasks.length);\n\n var ds = _map(ts, function (task) {\n return task.data;\n });\n\n if(cargo.empty) cargo.empty();\n working = true;\n worker(ds, function () {\n working = false;\n\n var args = arguments;\n _each(ts, function (data) {\n if (data.callback) {\n data.callback.apply(null, args);\n }\n });\n\n process();\n });\n },\n length: function () {\n return tasks.length;\n },\n running: function () {\n return working;\n }\n };\n return cargo;\n };\n\n var _console_fn = function (name) {\n return function (fn) {\n var args = Array.prototype.slice.call(arguments, 1);\n fn.apply(null, args.concat([function (err) {\n var args = Array.prototype.slice.call(arguments, 1);\n if (typeof console !== 'undefined') {\n if (err) {\n if (console.error) {\n console.error(err);\n }\n }\n else if (console[name]) {\n _each(args, function (x) {\n console[name](x);\n });\n }\n }\n }]));\n };\n };\n async.log = _console_fn('log');\n async.dir = _console_fn('dir');\n /*async.info = _console_fn('info');\n async.warn = _console_fn('warn');\n async.error = _console_fn('error');*/\n\n async.memoize = function (fn, hasher) {\n var memo = {};\n var queues = {};\n hasher = hasher || function (x) {\n return x;\n };\n var memoized = function () {\n var args = Array.prototype.slice.call(arguments);\n var callback = args.pop();\n var key = hasher.apply(null, args);\n if (key in memo) {\n async.nextTick(function () {\n callback.apply(null, memo[key]);\n });\n }\n else if (key in queues) {\n queues[key].push(callback);\n }\n else {\n queues[key] = [callback];\n fn.apply(null, args.concat([function () {\n memo[key] = arguments;\n var q = queues[key];\n delete queues[key];\n for (var i = 0, l = q.length; i < l; i++) {\n q[i].apply(null, arguments);\n }\n }]));\n }\n };\n memoized.memo = memo;\n memoized.unmemoized = fn;\n return memoized;\n };\n\n async.unmemoize = function (fn) {\n return function () {\n return (fn.unmemoized || fn).apply(null, arguments);\n };\n };\n\n async.times = function (count, iterator, callback) {\n var counter = [];\n for (var i = 0; i < count; i++) {\n counter.push(i);\n }\n return async.map(counter, iterator, callback);\n };\n\n async.timesSeries = function (count, iterator, callback) {\n var counter = [];\n for (var i = 0; i < count; i++) {\n counter.push(i);\n }\n return async.mapSeries(counter, iterator, callback);\n };\n\n async.seq = function (/* functions... */) {\n var fns = arguments;\n return function () {\n var that = this;\n var args = Array.prototype.slice.call(arguments);\n var callback = args.pop();\n async.reduce(fns, args, function (newargs, fn, cb) {\n fn.apply(that, newargs.concat([function () {\n var err = arguments[0];\n var nextargs = Array.prototype.slice.call(arguments, 1);\n cb(err, nextargs);\n }]))\n },\n function (err, results) {\n callback.apply(that, [err].concat(results));\n });\n };\n };\n\n async.compose = function (/* functions... */) {\n return async.seq.apply(null, Array.prototype.reverse.call(arguments));\n };\n\n var _applyEach = function (eachfn, fns /*args...*/) {\n var go = function () {\n var that = this;\n var args = Array.prototype.slice.call(arguments);\n var callback = args.pop();\n return eachfn(fns, function (fn, cb) {\n fn.apply(that, args.concat([cb]));\n },\n callback);\n };\n if (arguments.length > 2) {\n var args = Array.prototype.slice.call(arguments, 2);\n return go.apply(this, args);\n }\n else {\n return go;\n }\n };\n async.applyEach = doParallel(_applyEach);\n async.applyEachSeries = doSeries(_applyEach);\n\n async.forever = function (fn, callback) {\n function next(err) {\n if (err) {\n if (callback) {\n return callback(err);\n }\n throw err;\n }\n fn(next);\n }\n next();\n };\n\n // Node.js\n if (typeof module !== 'undefined' && module.exports) {\n module.exports = async;\n }\n // AMD / RequireJS\n else if (typeof define !== 'undefined' && define.amd) {\n define([], function () {\n return async;\n });\n }\n // included directly via \n // \n if (hasNativeCurrentScriptAccessor) {\n script = document.currentScript;\n }\n }\n\n if (!script) {\n // Inaccuracies:\n // - If script currently being synchronously evaluated by the parser is the\n // originator of this call stack but NOT the source script of the caller/invocation\n // e.g.\n // ```html\n // \n // \n if (isNotOpera && supportsScriptReadyState) {\n for (i = eligibleScripts.length; i--; ) {\n if (eligibleScripts[i].readyState === \"interactive\") {\n script = eligibleScripts[i];\n break;\n }\n }\n }\n }\n\n if (!script) {\n // Inaccuracies:\n // - If a script is created dynamically and appended to some position\n // other than the very end of the document.\n // - If multiple scripts are created dynamically and all appended to the\n // same position within the document (and do not have their `async` attributes\n // set to `false`, at least in browsers that support async script evaluation.\n // other than the very end of the document.\n // - If any scripts are added with the `async` attribute set to `true` in a browser\n // that supports it.\n // - May get confused by `script` elements within `svg` elements\n // - If script currently being synchronously evaluated by the parser is the\n // originator of this call stack but NOT the source script of the caller/invocation\n // e.g.\n // ```html\n // \n // \n // ```\n script = eligibleScripts[eligibleScripts.length - 1] || null;\n }\n\n return script;\n}\n\n// Default stack depth to skip over when analyzing call stack frames\n_nearestExecutingScript.skipStackDepth = 1;\n\n\n\n //\n // Export the API\n //\n var currentExecutingScript = _nearestExecutingScript; // default\n currentExecutingScript.near = _nearestExecutingScript;\n currentExecutingScript.far = _farthestExecutingScript;\n currentExecutingScript.origin = _originatingExecutingScript;\n\n\n // Just return a value to define the module export.\n // This example returns an object, but the module\n // can return a function as the exported value.\n return currentExecutingScript;\n })\n);\n","const Constants = {\n LOCAL_JID: 'local'\n};\n\nmodule.exports = Constants;\n","import { $iq, Strophe } from 'strophe.js';\n\nStrophe.addConnectionPlugin('disco',\n{\n _connection: null,\n _identities : [],\n _features : [],\n _items : [],\n /** Function: init\n * Plugin init\n *\n * Parameters:\n * (Strophe.Connection) conn - Strophe connection\n */\n init: function(conn)\n {\n this._connection = conn;\n this._identities = [];\n this._features = [];\n this._items = [];\n // disco info\n conn.addHandler(this._onDiscoInfo.bind(this), Strophe.NS.DISCO_INFO, 'iq', 'get', null, null);\n // disco items\n conn.addHandler(this._onDiscoItems.bind(this), Strophe.NS.DISCO_ITEMS, 'iq', 'get', null, null);\n },\n /** Function: addIdentity\n * See http://xmpp.org/registrar/disco-categories.html\n * Parameters:\n * (String) category - category of identity (like client, automation, etc ...)\n * (String) type - type of identity (like pc, web, bot , etc ...)\n * (String) name - name of identity in natural language\n * (String) lang - lang of name parameter\n *\n * Returns:\n * Boolean\n */\n addIdentity: function(category, type, name, lang)\n {\n for (var i=0; i= 0) {\n item._idleTimeoutId = setTimeout(function onTimeout() {\n if (item._onTimeout)\n item._onTimeout();\n }, msecs);\n }\n};\n\n// setimmediate attaches itself to the global object\nrequire(\"setimmediate\");\n// On some exotic environments, it's not clear which object `setimmediate` was\n// able to install onto. Search each possibility in the same order as the\n// `setimmediate` library.\nexports.setImmediate = (typeof self !== \"undefined\" && self.setImmediate) ||\n (typeof global !== \"undefined\" && global.setImmediate) ||\n (this && this.setImmediate);\nexports.clearImmediate = (typeof self !== \"undefined\" && self.clearImmediate) ||\n (typeof global !== \"undefined\" && global.clearImmediate) ||\n (this && this.clearImmediate);\n","(function (global, undefined) {\n \"use strict\";\n\n if (global.setImmediate) {\n return;\n }\n\n var nextHandle = 1; // Spec says greater than zero\n var tasksByHandle = {};\n var currentlyRunningATask = false;\n var doc = global.document;\n var registerImmediate;\n\n function setImmediate(callback) {\n // Callback can either be a function or a string\n if (typeof callback !== \"function\") {\n callback = new Function(\"\" + callback);\n }\n // Copy function arguments\n var args = new Array(arguments.length - 1);\n for (var i = 0; i < args.length; i++) {\n args[i] = arguments[i + 1];\n }\n // Store and register the task\n var task = { callback: callback, args: args };\n tasksByHandle[nextHandle] = task;\n registerImmediate(nextHandle);\n return nextHandle++;\n }\n\n function clearImmediate(handle) {\n delete tasksByHandle[handle];\n }\n\n function run(task) {\n var callback = task.callback;\n var args = task.args;\n switch (args.length) {\n case 0:\n callback();\n break;\n case 1:\n callback(args[0]);\n break;\n case 2:\n callback(args[0], args[1]);\n break;\n case 3:\n callback(args[0], args[1], args[2]);\n break;\n default:\n callback.apply(undefined, args);\n break;\n }\n }\n\n function runIfPresent(handle) {\n // From the spec: \"Wait until any invocations of this algorithm started before this one have completed.\"\n // So if we're currently running a task, we'll need to delay this invocation.\n if (currentlyRunningATask) {\n // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a\n // \"too much recursion\" error.\n setTimeout(runIfPresent, 0, handle);\n } else {\n var task = tasksByHandle[handle];\n if (task) {\n currentlyRunningATask = true;\n try {\n run(task);\n } finally {\n clearImmediate(handle);\n currentlyRunningATask = false;\n }\n }\n }\n }\n\n function installNextTickImplementation() {\n registerImmediate = function(handle) {\n process.nextTick(function () { runIfPresent(handle); });\n };\n }\n\n function canUsePostMessage() {\n // The test against `importScripts` prevents this implementation from being installed inside a web worker,\n // where `global.postMessage` means something completely different and can't be used for this purpose.\n if (global.postMessage && !global.importScripts) {\n var postMessageIsAsynchronous = true;\n var oldOnMessage = global.onmessage;\n global.onmessage = function() {\n postMessageIsAsynchronous = false;\n };\n global.postMessage(\"\", \"*\");\n global.onmessage = oldOnMessage;\n return postMessageIsAsynchronous;\n }\n }\n\n function installPostMessageImplementation() {\n // Installs an event handler on `global` for the `message` event: see\n // * https://developer.mozilla.org/en/DOM/window.postMessage\n // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages\n\n var messagePrefix = \"setImmediate$\" + Math.random() + \"$\";\n var onGlobalMessage = function(event) {\n if (event.source === global &&\n typeof event.data === \"string\" &&\n event.data.indexOf(messagePrefix) === 0) {\n runIfPresent(+event.data.slice(messagePrefix.length));\n }\n };\n\n if (global.addEventListener) {\n global.addEventListener(\"message\", onGlobalMessage, false);\n } else {\n global.attachEvent(\"onmessage\", onGlobalMessage);\n }\n\n registerImmediate = function(handle) {\n global.postMessage(messagePrefix + handle, \"*\");\n };\n }\n\n function installMessageChannelImplementation() {\n var channel = new MessageChannel();\n channel.port1.onmessage = function(event) {\n var handle = event.data;\n runIfPresent(handle);\n };\n\n registerImmediate = function(handle) {\n channel.port2.postMessage(handle);\n };\n }\n\n function installReadyStateChangeImplementation() {\n var html = doc.documentElement;\n registerImmediate = function(handle) {\n // Create a